Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .claude-plugin/marketplace.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,13 @@
"name": "work-system",
"source": "./plugins/work-system",
"description": "Generic task and worktree workflow system for Claude Code. Keep tasks as GitHub issues or local markdown files, run them in isolated git worktrees with a choice of worker agent (Claude, codex, grok, kimi, or a PATH-detected cc-harness agent), and track progress across the define/kickoff/continue/status/close lifecycle.",
"version": "1.28.1"
"version": "1.29.0"
},
{
"name": "pr-flow",
"source": "./plugins/pr-flow",
"description": "PR review feedback loop for Claude Code. Create PRs with readiness checks, commit + push + trigger @claude review, inspect status, and work through review issues interactively.",
"version": "1.8.1"
"version": "1.9.0"
},
{
"name": "swarm",
Expand Down
2 changes: 1 addition & 1 deletion .claude/knowledge/_index.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
- `features/github-issues-task-backend.md` — `task-store.py` as the one backlog path: `tasks.backend` auto|github|local (local files win until migrated; an installed-but-failing gh is exit 4, never a silent local fallback), label + body-marker identity, copy-not-link TASK.md, network-free statusline counts lanes
- `features/task-archiving-on-close.md` — `/close` archives (not deletes) the task file; adaptive commit + ff-push to main; per-repo `.claude/work-system-close-autocommit` opt-in skips the ask; why the archive takes no caller-supplied note
- `features/swarm-backend-adapter.md` — External adapter contract: jailed read+web, egress guard, out-of-band transport, schema normalization, readiness, telemetry, adapter-owned config; per-run Grok selection with a measured, cached schema probe (no version allowlist); Kimi uses ACP with denied permissions + local fail-closed validation
- `features/worker-autonomy-mandate.md` — `MANDATE.md` as the lane's authorization record: frontmatter-only consent (task prose never grants), the 0/1/3 `allows` contract (denied vs. never-asked), a review budget counted in-file so it survives a resume, pr-flow's soft-coupled shim answering "unknown" not "no", plus bot-detection before recommending a review; the `reviewed`/`fixed`/`covered` local-review merge gate (recorded on a finished review, normalized diff hash not patch-id, masked manifest versions, user-only `acknowledged` delta, why the classifier needs it)
- `features/worker-autonomy-mandate.md` — `MANDATE.md` as the lane's authorization record: frontmatter-only consent (task prose never grants), the 0/1/3 `allows` contract (denied vs. never-asked), a review budget counted in-file so it survives a resume, pr-flow's soft-coupled shim answering "unknown" not "no", plus bot-detection before recommending a review; the `reviewed`/`fixed`/`covered` local-review merge gate (recorded on a finished review, normalized diff hash not patch-id, masked manifest versions, user-only `acknowledged` delta (from a per-file summary), why the classifier needs it)
- `features/swarm-review-pipeline.md` — `/swarm:review`: 11 lenses/5 clusters across Claude + codex/grok/kimi; four-family consensus; verify, `--fix`/`--loop`, deterministic `--pr` publishing; fail-closed voice accounting (resolved != reviewed) + the marker/mutation test seam
- `features/insights-lifecycle-producers.md` — work-system's `/continue` + `/land` handoff and `/close` reports: absent vs. installed-but-unusable as distinct exit codes, report between merge gate and removal and never a gate, idempotency from the store itself, why the archived-task-file fallback was struck before merge, trigger ≠ task_status, contract path from the helper, prose ordering guarded by an assertion test; plus three shell traps (subshell array append, `${arr[@]/pat}`, `--date=format:` timezone); a review run that committed to the branch
- `features/insights-report-store.md` — insights.py as sole report write/read path: main-checkout identity, strict Fact shapes, link()-based no-overwrite publish, refuse-not-chmod store dirs, file drafts not heredocs, fixpoint redaction exempting identifiers, anchored URL parse, skeleton that fails until filled
Expand Down
39 changes: 37 additions & 2 deletions .claude/knowledge/features/worker-autonomy-mandate.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
---
title: "Worker Autonomy Mandate (MANDATE.md)"
createdAt: 2026-09-07
updatedAt: 2026-10-22
updatedAt: 2026-10-26
createdFrom: "branch: task/extend-worker-autonomy"
updatedFrom: "branch: task/harden-mandate-diff-id-and-round-lock"
updatedFrom: "branch: task/summarize-merge-delta-ack"
pluginVersion: 1.9.0
prime: false
---
Expand Down Expand Up @@ -497,6 +497,41 @@ covers. Why it is built this way:
(checked on a temp file with `tr -d '\000' | cmp`). The script cannot
see who asks, so "interactive user only" lives in the callers' prose; like
`reviewed`, it is not a boundary against a worker determined to bypass it.
- **The ack is decided from a summary, not a raw diff** (2026-10-26, after
#91's ~278-line delta was acked unread: "I am not a robot"). An ack
text that claims "I have read this delta" records something that did not
happen, so the prompt is `[a]cknowledge — merge this change without a
re-review / [d]iff / [r]e-review / [s]top`, and the model reads the full
delta itself and summarizes it per file. The summary stands on mechanical
facts, not on hunk reading: a diff-of-diffs hunk often has its file header
outside its 3 context lines, so `delta` prints `delta_file=` lines computed
per file from the two raw lane diffs — `lane=` (delta lines whose inner
prefix is the lane's own `+`/`-`) vs. `context=` (main's lines, headers), so
`lane=0` provably means "only moved with main", and `versions_only=` (equal
after the version mask). The kind labels are gated on those facts ("from
main" only at `lane=0`, "agreed fix" only with `includes_agreed_fixes=yes`
and only for the hunks shown to be one); everything else is `new code` or
`unclear`. The list sits above `delta_begin`, outside the hashed text, so
the `ack_id` and every refusal are unchanged. Review round 1 (swarm) found
three traps: `awk -v h="$header"` expands the backslashes of a C-quoted
name (`"a/\303\244.sh"`), so the lookup missed and new lane code read
`new lane=0` — join both indexes in one awk pass instead, never pass
lane-derived text through `-v`; `versions_only` must follow the gate's
`version_paths` policy, or a dependency downgrade elsewhere reads as a
renumbering; and a lane-chosen path printed raw can forge `key=value`
fields, so it goes last, `%q`-quoted. The model reads the delta from a
file (`--max-lines all`, Read in ranges to the last line): a single Bash
result is capped by the harness while the header still says
`truncated=no`. Kind labels other than the two mechanical ones are the
model's reading of the code, never of what the lane text calls itself.
Round 2: an unbounded `--max-lines all` made `ack_id` prove only that the
text was printed, so a delta over `ACK_MAX_LINES` (2000) — or, round 3,
with a line over 1000 bytes, which the Read tool cuts — gets none and
`acknowledged` refuses it (`too-large`); `%q` alone leaves multibyte bidi
characters raw under `core.quotePath=false`, so the path is `cat -v`-escaped
first; `FNR == NR` joins break when the first file is empty (use
`FILENAME == ARGV[1]`); and pr-flow's shim rewrites `all` to a number for
a work-system older than it, or a version skew blocks every merge.
- **`fixed` is an attestation, so once per review, bound by `--after <sha>`**
to the review the caller ran. Repeatable or unbound, it would let any later
edit be stamped as covered.
Expand Down
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,10 @@ entries are grouped per plugin, newest first.

## work-system

### 1.29.0 — 2026-10-26
- `/land` decides a post-review delta from a plain-language summary, not a raw diff: per file the kind of change, its size and whether it touches the reviewed logic, then `[a]cknowledge` (merge without a re-review) / `[d]iff` / `[r]e-review` / `[s]top`. The ack wording no longer claims the diff was read; `acknowledged --ack-id` and every refusal are unchanged.
- `mandate.sh delta` prints `delta_files=` and one `delta_file=<new|gone|changed> lane= context= versions_only= path=` line per file, computed from the two raw lane diffs (lane vs. main context lines; `versions_only` only for files on `version_paths`; the path shell-quoted), outside the acked text. `--max-lines all` prints the delta uncut. A delta over 2000 lines, or with a line over 1000 bytes, is `too_large=yes`: no `ack_id`, and `acknowledged` refuses it (`reason=too-large`) — it needs a review.

### 1.28.1 — 2026-10-22
- The merge gate's lane diff id hashes only the lane's own lines: a `-U0` diff, whose place is the file, the hunk order and git's function context. A rebase over main edits next to a lane hunk keeps `covered=yes` (#89 asked to re-review lines the lane never touched). A lane line that changes or moves (under another header, or past another lane hunk) still flips it. A main edit to the hunk's function-context line still asks for a review. Accepted residuals: a lane line moved within one function past no other lane hunk keeps the id, and so does a main edit that changes what a lane hunk means (deleting a guard right above it). Reviews recorded by 1.28.0 (`diff_id_form=context`) or earlier (`legacy`; `context` when no manifest is touched, the same text) keep matching their unchanged lane, also under a non-default diff config, and `delta` still shows context. `delta`'s `diff_form=masked` is now `context-free` (or `context`/`legacy` for an older record).
- `mandate.sh round` (and the other record writers) no longer exit 4 when a concurrent booker releases the lock between a failed `mkdir` and the check: only a `mkdir` error other than "File exists" is a lock that cannot be created. The lock's pid is written atomically, so a partial pid never marks a live lock stale, and a file or symlink at the lock path exits 4 at once with a hint instead of waiting 5 s and blaming another process.
Expand Down Expand Up @@ -330,6 +334,9 @@ entries are grouped per plugin, newest first.

## pr-flow

### 1.9.0 — 2026-10-26
- `/merge` step 6b: on `changed-since-review` the delta is read in full from a file and summarized per file (kind, size, reviewed-logic impact) instead of printed; the prompt is `[a]cknowledge — merge this change without a re-review / [d]iff / [r]e-review / [s]top`. Kind labels other than version renumbering and from-main are the model's reading of the code, never taken from what the lane text says about itself. With an older work-system the shim passes `--max-lines 2000` (the ack ceiling) instead of `all`, and the summary says the file list is missing.

### 1.8.1 — 2026-10-22
- Trim the `/open` skill description to the word budget; the readiness-check list lives in the skill body.

Expand Down
4 changes: 2 additions & 2 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ This is a **Claude Code plugin marketplace** (monorepo) containing plugins that
## Current Plugins

- **knowledge-system** (v1.9.x) — Knowledge management with three layers: Rules, Knowledge, Memory. Skills: `/init`, `/query`, `/curate`, `/reindex`, `/backfill-knowledge`, `/migrate`, `/statusline`
- **work-system** (v1.28.x) — Task and worktree workflow; backlog in GitHub Issues or `tasks/` files via `task-store.py` (`tasks.backend`); workers: Claude/codex/grok/kimi or PATH-detected cc-harness; `/kickoff` records the lane's autonomy mandate in `MANDATE.md`, `/continue` works from it; a worktree `/close` can delegate its teardown to the Manager session, and `/continue` pings it at milestones; `/land` composes `/pr-flow:merge` + `/close --delegate`; the Manager runs, asks or records (ROADMAP) a closed lane's follow-ups and owns deploys; with the optional `insights` plugin, `/continue` reports at its terminal gate, `/land` when landing, and `/close` before teardown; `/sessions` reloads idle herdr sessions running stale plugin code; `herdr-shell.sh` drives interactive programs in temp herdr tabs. Skills: `/define`, `/kickoff`, `/adopt`, `/continue`, `/status`, `/close`, `/land`, `/list`, `/sessions`, `/statusline`
- **pr-flow** (v1.8.x) — PR review feedback loop; mandate-aware and review-bot-aware (route remembered per repo); defers deploys to the Manager inside a lane unless `deploy.by = "worker"`. Skills: `/open`, `/cycle`, `/check`, `/fix`, `/rebase`, `/merge`
- **work-system** (v1.29.x) — Task and worktree workflow; backlog in GitHub Issues or `tasks/` files via `task-store.py` (`tasks.backend`); workers: Claude/codex/grok/kimi or PATH-detected cc-harness; `/kickoff` records the lane's autonomy mandate in `MANDATE.md`, `/continue` works from it; a worktree `/close` can delegate its teardown to the Manager session, and `/continue` pings it at milestones; `/land` composes `/pr-flow:merge` + `/close --delegate`; the Manager runs, asks or records (ROADMAP) a closed lane's follow-ups and owns deploys; with the optional `insights` plugin, `/continue` reports at its terminal gate, `/land` when landing, and `/close` before teardown; `/sessions` reloads idle herdr sessions running stale plugin code; `herdr-shell.sh` drives interactive programs in temp herdr tabs. Skills: `/define`, `/kickoff`, `/adopt`, `/continue`, `/status`, `/close`, `/land`, `/list`, `/sessions`, `/statusline`
- **pr-flow** (v1.9.x) — PR review feedback loop; mandate-aware and review-bot-aware (route remembered per repo); defers deploys to the Manager inside a lane unless `deploy.by = "worker"`. Skills: `/open`, `/cycle`, `/check`, `/fix`, `/rebase`, `/merge`
- **swarm** (v0.16.x) — Local mixture-of-agents code review (external `codex`/`grok` CLIs, `kimi` opt-in, plus Claude lenses: 11 in 5 clusters). Profile-based cluster/lens fan-out; externals get read + web research under an OS secret-jail. P2: `/swarm:review` pipeline (scope→fan-out→merge→verify); P5: `--fix`/`--loop` apply the findings you agreed with. Skills: `/swarm:review`, `/swarm:agents`
- **settings** (v0.1.x) — Per-plugin TOML config resolved over schema defaults; each plugin owns its `schema/settings.schema.json`. Skill: `/settings` (list/show/get/set/validate). First consumer: pr-flow `review.route`.
- **insights** (v0.1.x) — Private local task/plugin insight reports (`insights.report/v1`, one helper for write/read/list). Skill: `/insights:report [text]`. work-system's `/continue`, `/land` and `/close` are its lifecycle producers.
Expand Down
Loading
Loading