@sabaiway/agent-workflow-kit 5.11.2 → 6.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -4,6 +4,52 @@ Semantically versioned ([semver](https://semver.org)), newest first. The `versio
4
4
  is the current release. `upgrade` mode reads a project's `docs/ai/.workflow-version` and applies
5
5
  every `migrations/<version>-<slug>.md` newer than it, in semver order.
6
6
 
7
+ ## 6.0.0 — `grounding --plan` follows the canon it grounds: the three literal headings (AD-104; ships with engine 3.0.0 / memory 4.5.2)
8
+
9
+ **The tool required a heading the canon had deleted.** `grounding --plan` demanded `## Approach` —
10
+ the unbudgeted free-prose section engine **3.0.0** removes — so a plan written to the new capped
11
+ shape STOPped at the grounding step, and the author was pushed back into re-adding the very section
12
+ that grew the last plan to 690 lines.
13
+
14
+ > ### ⚠ BREAKING — an input that exited 0 now exits 1, and two exported symbols changed shape
15
+ >
16
+ > `grounding --plan <file>` on a plan written to any earlier canon now STOPs with exit 1, naming the
17
+ > missing heading. There is no deprecation window and no compatibility shim, which is the same shape
18
+ > this package twice sized as MAJOR — **4.0.0** (a receipt that used to be accepted is refused) and
19
+ > **5.0.0** (a `--check` that silently passed can now refuse). **5.6.0** is the converse precedent:
20
+ > it stayed a MINOR precisely because it kept the old result field as an alias, and nothing here
21
+ > keeps an alias. The incompatibility is created by the reader, so the kit takes a MAJOR for it in
22
+ > its own right — engine **3.0.0** takes one for the canon it rewrote, and the two are independent.
23
+ >
24
+ > For a programmatic consumer of `tools/grounding.mjs`: exported `PLAN_SECTIONS` changed from
25
+ > `[{ heading, optional }, …]` to a plain `string[]`, and `sliceSection(text, heading, { optional,
26
+ > label })` is now `sliceSection(text, heading, { label })`. Read the array as headings, and drop
27
+ > the `optional` option — there is no third state left for it to express.
28
+
29
+ - **`tools/grounding.mjs` — `PLAN_SECTIONS` is now the canon's three literal headings:**
30
+ `## Goal and boundary`, `## Module ledger`, `## Verification`. Each is REQUIRED; a missing or
31
+ duplicate heading is a loud STOP naming the heading it wanted. `## Approach` and
32
+ `## Decisions (locked)` are gone with the canon that named them.
33
+ - **`sliceSection`'s `optional` arm went with the optional heading.** A section the canon does not
34
+ name cannot be sliced, and one it does name cannot be absent — so the third state had no caller
35
+ left. `sliceSection(text, heading, { label })` is the whole signature.
36
+ - Red-first: `tools/grounding.test.mjs` was rewritten to a canon-shaped fixture and a
37
+ `core-evidence red-proof` was minted on the pre-fix tree for
38
+ `grounding.test.mjs#extracts Goal and boundary` before the fix landed.
39
+ - The module header, `--help`, `references/modes/grounding.md` and the README row now say the same
40
+ thing — one contract, four surfaces, each updated with the code.
41
+ - **`tools/procedures.mjs`** — the advisor's review-loop header pointed at `planning.md §9`, a
42
+ numbered section that no longer exists; it now names the `procedures.md` *Fold + loop* anchor. The
43
+ plan-time line "every Step that CREATES a file…" is DELETED with the Step vocabulary it belonged
44
+ to — the declared source-size practice still rides every named-activity render, and the plan's
45
+ *Module ledger* is where the layout is now cut to it.
46
+ - **`tools/inject-methodology.mjs`** — the outgoing methodology-slot text is appended to
47
+ `KNOWN_PRIOR_METHODOLOGY_SLOT`, so an `AGENTS.md` still carrying the pre-rewrite pointer is
48
+ recognised and refreshed instead of being flagged as a custom edit.
49
+ - **`references/templates/agent_rules.md`** — the lens fragment re-rendered through
50
+ `reconcileLensText`: two per-Step clauses became per-row, and the session-continuity sentence went
51
+ with the heuristic the canon dropped.
52
+
7
53
  ## 5.11.2 — the record vocabulary becomes a facade over five leaves (AD-103)
8
54
 
9
55
  **Nothing you import changes, and that is the whole claim — now certified rather than asserted.**
package/README.md CHANGED
@@ -237,7 +237,7 @@ file), or run the guarded `/agent-workflow-kit uninstall`.
237
237
  | `/agent-workflow-kit set-recipe` | any time | **config writer** for `docs/ai/orchestration.json`: tell the agent your preference in plain language and it maps it to explicit `--set <activity>.<slot>=<recipe>` / `--unset` ops; the kit validates, **previews by default**, and writes only on `--write` (deployment-gated, atomic, symlink/TOCTOU-safe), resolving the effective recipe vs live readiness. Writes **only** that file — **never runs a backend, never commits**; hand-editing stays fully supported. |
238
238
  | `/agent-workflow-kit review-state` | any time | **read-only review-receipt checker** — makes "reviewed ≠ shipped" detectable: the bridge review wrappers append a receipt per successful review (into a file inside the git dir — never committable); this checks that every backend your configured `plan-execution.review` recipe names holds a **fresh, grounded receipt for the current uncommitted tree** (any later edit moves the fingerprint and stales the receipt; a review continuation never re-attests a folded tree). `--check` gives a gate exit code to declare in `docs/ai/gates.json` **by hand or via the consent-gated seeder** (preview → your explicit yes; never without consent). `--await [--timeout <s>]` (AD-049) BLOCKS until every recipe-named backend has receipted the current tree — the durable completion signal is the receipt, never a process event — so you wait for the bridges instead of hand-polling. Never writes, never commits, never runs a subscription CLI; it spawns read-only `git` queries to fingerprint the tree — and `git commit --no-verify` stays possible (discipline, not a sandbox). |
239
239
  | `/agent-workflow-kit sandbox-masks` | any time | **cosmetic exclude lane for sandbox device masks** — an OS sandbox (Claude Code) injects character-device masks into the work tree as untracked `git status` noise; the review domain already ignores them **by construction** (never-committable untracked classes — char/block devices, FIFOs, sockets — are excluded from the fingerprint, the assembled review payload, and the clean checks). This mode hides them from `git status` too: flagless = read-only probe (derives the CURRENT mask set from the unfiltered walk + lstat — never a frozen list — and revalidates fenced entries, loudly flagging one that became a real path); `--apply` = consent-gated FULL-BLOCK replace of its own fenced block in `git rev-parse --git-path info/exclude` (stale masks drop by construction; `--clear` always means REMOVE the block — it takes precedence over the derivation). Writes ONLY its fence — never `.gitignore`, never global config; symlinked/non-regular exclude paths and malformed fences fail closed. Watch note: a real file at an excluded path is silently skipped by bulk staging (`git add -A`/`git add .`) — delete the stale line first; the probe flags exactly this case. |
240
- | `/agent-workflow-kit grounding` | any time | **grounded-review facts assembler** — mechanizes populating `agy-review --facts @f`: slices your entry-point's **Hard Constraints** section verbatim (exactly one match, else a loud stop) and/or a plan's decision-bearing sections (`## Approach` + `## Verification` required, `## Decisions (locked)` when present; duplicates stop), under the same byte budget the agy wrapper enforces (minus `--reserve-bytes` for the artifact share), with a loud tail-trim on overflow. `--autonomy` (AD-044) appends the COMPUTED effective autonomy policy from the git-top `docs/ai/autonomy.json` (every red-line + per-activity level, stated source line; absent file → the computed defaults ARE the policy, exit 0; a malformed policy fails CLOSED, exit 1). `--extra <text|@file>` (repeatable) appends your own facts **byte-verbatim** after the mechanical sections, so the merge is a tool input rather than a shell append — an `@file` must sit inside the proven git work tree (never the git dir) or the system temp surface, and is read through a no-follow descriptor (a FIFO cannot block it, a symlink leaf cannot substitute its target). Prints to stdout; `--out` writes **one scratch file only** — system-temp outside the repo ($TMPDIR / /tmp, rewritable) or a **fresh** gitignored in-repo path (create-only, exclusive write; an existing in-repo file, even gitignored, is refused — the `.env` clobber class); tracked, not-ignored-in-repo, other outside-repo, and symlink/non-regular destinations are all refused. Never commits, never runs a subscription CLI. |
240
+ | `/agent-workflow-kit grounding` | any time | **grounded-review facts assembler** — mechanizes populating `agy-review --facts @f`: slices your entry-point's **Hard Constraints** section verbatim (exactly one match, else a loud stop) and/or a plan's three canon sections (`## Goal and boundary` + `## Module ledger` + `## Verification`, each required; duplicates stop), under the same byte budget the agy wrapper enforces (minus `--reserve-bytes` for the artifact share), with a loud tail-trim on overflow. `--autonomy` (AD-044) appends the COMPUTED effective autonomy policy from the git-top `docs/ai/autonomy.json` (every red-line + per-activity level, stated source line; absent file → the computed defaults ARE the policy, exit 0; a malformed policy fails CLOSED, exit 1). `--extra <text|@file>` (repeatable) appends your own facts **byte-verbatim** after the mechanical sections, so the merge is a tool input rather than a shell append — an `@file` must sit inside the proven git work tree (never the git dir) or the system temp surface, and is read through a no-follow descriptor (a FIFO cannot block it, a symlink leaf cannot substitute its target). Prints to stdout; `--out` writes **one scratch file only** — system-temp outside the repo ($TMPDIR / /tmp, rewritable) or a **fresh** gitignored in-repo path (create-only, exclusive write; an existing in-repo file, even gitignored, is refused — the `.env` clobber class); tracked, not-ignored-in-repo, other outside-repo, and symlink/non-regular destinations are all refused. Never commits, never runs a subscription CLI. |
241
241
  | `/agent-workflow-kit core-evidence` | any time | **the ONE loop-evidence writer** (strip-the-kit) — every core evidence record lands in a single append-only JSONL store inside the git dir (never committable; versioned schema, latest-per-key supersession, byte-identical duplicates refused, malformed lines fail every reader closed). `red-proof "<file>#<pattern>"` declares an observed-red **BEFORE a bugfix** (N/N red runs + content custody + base + the pre-fix fingerprint; green/mixed/timeout are DISTINGUISHED refusals — nothing written); `degrade --backend --reason` is the ONLY escape for an unavailable review backend (per-tree, never all backends); `summary` renders the whole loop state statelessly (gate result · per-backend verdicts · red-proofs · degrades) — no ledger, no rounds, nothing remembered. Honest residual: records are forgeable — self-discipline, not a security boundary. Never commits, never runs a subscription CLI. |
242
242
  | `/agent-workflow-kit coverage-check` | any time | **the final-run checker** (D3(c)+(d)) — **certifies coverage ONLY inside the `--final` run that owns the lcov** (ownership is exclusive by CONVENTION over the fixed path, not enforced — a concurrent writer to it is a stated residual, queued as LCOV-EXCLUSIVE-OWNERSHIP): an artifact on disk proves nothing about the tree it came from, so a standalone run prints its findings and states `attested=no` / `NO VERDICT` rather than a PASS (an lcov that predates an edit would otherwise certify a line the suite never executed). `attested=` claims a verdict was ISSUED, pass or fail — a run over uncovered lines still reads `attested=yes` and still exits 1, and a run whose coverage arm never executed (no lcov) reads `attested=no` even inside `--final`, because nothing was read and nothing is certified. The runner passes a nonce whose one-way commitment over `{nonce, fingerprint, base}` is the `final-start.attempt` it recorded; a context describing another tree, or matching no recorded attempt, is a REFUSAL, never a verdict. Findings are unchanged — reads the lcov the declared `unit-tests` gate produced at the FIXED git-dir path and fails on any uncovered CHANGED executable Node line (listed `file:line`; a changed file absent from the map is a file-level red; out-of-domain/unsupported files are LISTED — the claim narrowed honestly); VERIFIES every current-base red-proof declaration (bound test exists · custody hash unchanged · green N/N now · pre-fix fingerprint differs); prints `lcov-sha256=<hex|none>` of the exact bytes it consumed — the sha the `--final` receipt binds and re-hashes. An absent lcov is a LOUD `skipped-no-lcov`; a symlinked path is a refusal. `--check` is the gate exit code — declare it as the LAST gate (`run-gates --final` refuses otherwise). Read-only. |
243
243
  | `/agent-workflow-kit commit-guard` | any time | **the read-only pre-commit guard** (D10) — makes the commit capture the whole current working tree, so «verified» and «about to be committed» are the same bytes (the receipt itself has a stated residual — see the mode doc). FIRST it refuses an **INDEX that lags the verified working tree** (the gates and the fingerprint describe the WORKING tree while `git commit` takes the INDEX alone, and the fingerprint cannot tell them apart — so a lagging index used to ship a strict subset of what was verified): unstaged tracked paths or reviewable untracked-not-ignored paths, named up to a bounded cap with the remainder stated, a dirty tracked **submodule** named separately with its own recovery, and fail-closed on an undecidable probe. This deliberately blocks a partial commit. Then it binds the LATEST completed `run-gates --final` receipt to the EXACT current tree: refuses on a missing/red/stale receipt, fingerprint drift under the run, a dangling later attempt, declaration content drift, evidence-hash or lcov drift, or unsatisfied review obligations (the same review-state decision, recomputed over a sanitized env — forged out-of-repo stores never satisfy). Re-runs NO gate or test. Wire it into `.git/hooks/pre-commit` (the installer writes the RESOLVED invocation). `git commit --no-verify` stays the stated residual. |
@@ -266,7 +266,7 @@ It **never auto-commits** and **never overwrites** an existing `AGENTS.md` witho
266
266
  - **Layered, lazy loading** — *always-loaded* = `AGENTS.md` + `index.md` (~160 lines, cache-warm). *On-demand* = open a `docs/ai/` file only when its "Read When" applies. *Hierarchical* = subdir `AGENTS.md` loads when you work in that folder. *Archive* = old history rolls out of the hot files.
267
267
  - **Caps + freshness** — every doc declares a `maxLines` cap; a pre-commit hook blocks commits that bust a cap or let the auto-generated index go stale.
268
268
  - **3-tier rolling archive** — `changelog.md` (HOT, last days) → `history/recent.md` (WARM) → per-month COLD + a one-line condensed index. Hot files stay small forever.
269
- - **Plan lifecycle** — Plan Phase Step Substep, ephemeral plan files, a mandatory Cleanup phase, and a session-continuity heuristic tuned for large-context models (e.g. Claude Opus).
269
+ - **Plan lifecycle** — a capped plan (goal and boundary, module ledger, verification), ephemeral plan files, and a mandatory Cleanup phase.
270
270
  - **No silent failures** — every guard that rejects an action logs structured context.
271
271
 
272
272
  Enforcement ships as dependency-free **Node** scripts (`node --test`, no package manager assumed). Non-Node projects follow the same policy by hand.
package/SKILL.md CHANGED
@@ -3,7 +3,7 @@ name: agent-workflow-kit
3
3
  description: Deploy or upgrade a portable AI-agent memory-and-workflow system in any project. Use when the user wants to bootstrap `docs/ai/` + an entry-point `AGENTS.md` (+ `CLAUDE.md` alias) + cap/archive/index enforcement in a new or existing repo, set up the Memory Map and session protocols, install the docs-rotation pre-commit hook, or run `/agent-workflow-kit` / `/agent-workflow-kit upgrade`. Triggers on phrases like "set up the memory system", "deploy the AI workflow here", "bootstrap docs/ai", "upgrade the workflow".
4
4
  disable-model-invocation: true
5
5
  metadata:
6
- version: '5.11.2'
6
+ version: '6.0.0'
7
7
  ---
8
8
 
9
9
  # agent-workflow-kit
package/capability.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "schema": 1,
4
4
  "name": "agent-workflow-kit",
5
5
  "kind": "composition-root",
6
- "version": "5.11.2",
6
+ "version": "6.0.0",
7
7
  "provides": [],
8
8
  "roles": {},
9
9
  "detect": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sabaiway/agent-workflow-kit",
3
- "version": "5.11.2",
3
+ "version": "6.0.0",
4
4
  "description": "Portable, cross-agent memory & workflow for AI coding agents — Claude Code, Codex, Cursor, Devin Desktop. One command deploys an AGENTS.md entry point + docs/ai context with cap/archive/index enforcement into any repo.",
5
5
  "keywords": [
6
6
  "ai-agents",
@@ -8,7 +8,7 @@ Run `node ${CLAUDE_SKILL_DIR}/tools/grounding.mjs [--constraints] [--autonomy] [
8
8
 
9
9
  1. **`--constraints`** — slice the root `AGENTS.md` **Hard Constraints** section, verbatim and whole (exactly ONE matching heading; zero or several is a loud STOP, never a guess — the marker-slot discipline).
10
10
  2. **`--autonomy`** (AD-044 Plan 3) — append the COMPUTED effective autonomy policy: the shared resolver (`resolveAutonomy`) over the **git-top** `docs/ai/autonomy.json` renders every red-line + per-activity level with a stated source line. An ABSENT file is exit 0 — the computed defaults ARE the effective policy (unlike `velocity-profile --autonomy`, which writes settings and refuses an undeclared policy); a malformed/unreadable policy fails CLOSED (exit 1). Informational for the reviewing backend — enforcement stays the OS sandbox + the orchestrator. Rides between the constraints and the plan sections.
11
- 3. **`--plan <path>`** — extract the plan's decision-bearing canonical sections, verbatim + whole: `## Approach` (REQUIRED its "What we are NOT doing" text rides inside; it is not a heading in canon) and `## Verification` (REQUIRED STOP if missing), plus `## Decisions (locked)` when present (the optional engine §7 heading); a DUPLICATE heading is always a STOP.
11
+ 3. **`--plan <path>`** — extract the plan's three canon sections, verbatim + whole: `## Goal and boundary`, `## Module ledger`, `## Verification` (the engine `planning.md` literal headings; each REQUIRED a missing or DUPLICATE heading is always a STOP).
12
12
  4. **`--extra <text|@file>`** (corpus #88/#95 — the fourth firing of the same pre-dispatch append step) — append orchestrator-supplied facts byte-VERBATIM after the mechanical sections (repeatable, argv order; the `agy-review --facts` convention: literal text, or `@path` read whole through a race-free descriptor). An `@file` must resolve inside the PROVEN git work tree (rev-parse success — no cwd fallback; the git dir itself is refused) or the system temp surface — anything else refuses loudly (the exfil class: this tool is bridge-tier auto-allowable), as does a missing, EMPTY, or non-regular file (a FIFO cannot block the read). The merge happens INSIDE the tool, so the promptless lane is the invocation itself.
13
13
  5. **Byte budget** — the output honors the same `AGY_MAX_PROMPT_BYTES` contract the agy wrapper enforces (override may only tighten; the OS argv ceiling is rejected), MINUS **`--reserve-bytes <n>`** — the artifact share the caller expects `agy-review` to add around these facts. Overflow is trimmed tail-first with a loud in-band marker + stderr report — never a silent cut.
14
14
  6. Feed the result to the wrapper: `agy-review code --facts @<out>`. The `procedures` advisor renders this invocation as a concrete pre-step whenever the resolved review dispatch includes agy — populated with the in-flight plan path when exactly one plan is in flight.
@@ -2,12 +2,12 @@
2
2
 
3
3
  <!-- opt-in-capability: none — an inspection surface that configures nothing -->
4
4
 
5
- Read-only **activity-procedures advisor**. Answers *"what are the steps of this named activity, and which recipe applies at each slot here?"* It composes the orchestration recipes (`${CLAUDE_SKILL_DIR}/references/modes/recipes.md`) into **named activities** with **typed recipe slots**. It **never writes, never commits, never runs a subscription CLI** — the deterministic resolution lives in the kit; the orchestrator runs the resolved recipe via the bridge skills and **owns any commit when the activity has a commit boundary** (a backend never commits). Not every activity commits: `plan-authoring` ends at approval and produces no commit (plans are ephemeral, never committed); `plan-execution` commits per Step.
5
+ Read-only **activity-procedures advisor**. Answers *"what are the steps of this named activity, and which recipe applies at each slot here?"* It composes the orchestration recipes (`${CLAUDE_SKILL_DIR}/references/modes/recipes.md`) into **named activities** with **typed recipe slots**. It **never writes, never commits, never runs a subscription CLI** — the deterministic resolution lives in the kit; the orchestrator runs the resolved recipe via the bridge skills and **owns any commit when the activity has a commit boundary** (a backend never commits). Not every activity commits: `plan-authoring` ends at approval and produces no commit (plans are ephemeral, never committed); `plan-execution` commits per ledger row.
6
6
 
7
7
  The two v1 activities (canon in the **installed engine**, `references/procedures.md`):
8
8
 
9
9
  - **`plan-authoring`** (slot: `review`) — research → draft → self-review → **review {recipe}** → fold/loop → present for approval; enforce the mandatory Cleanup.
10
- - **`plan-execution`** (slots: `execute`, `review`) — per Step: resolve the recipe → if Delegated, dispatch execution first → implement → self-review → **review {recipe}** → gates → commit boundary.
10
+ - **`plan-execution`** (slots: `execute`, `review`) — per ledger row: resolve the recipe → if Delegated, dispatch execution first → implement → self-review → **review {recipe}** → gates → commit boundary; after the last row, the project-declared stages and Phase: Cleanup run as rows of their own.
11
11
 
12
12
  Run **`node ${CLAUDE_SKILL_DIR}/tools/procedures.mjs <activity> [--override <slot>=<recipe>]… [--json]`**. It reads the activity's steps live from the engine and prints them **verbatim**, then the **resolved effective recipe per slot** from the per-project config + the read-only backend detector:
13
13
 
@@ -17,7 +17,7 @@ Run **`node ${CLAUDE_SKILL_DIR}/tools/procedures.mjs <activity> [--override <slo
17
17
 
18
18
  **Flow armed-halves block (session-start read side).** When the config carries a `flow` block, the advisor also renders `Flow (schema 1) — armed halves (config · chain · bookkeeping):` — the **config half** (preset · councilRounds · kitMinVersion), the **chain half** (a light read-only probe of the flow store on the checker's fixed path: ARMED at an adoption record, UNARMED for an absent or unadopted store, fail-closed BROKEN wording for a malformed one), and the **bookkeeping half** (each declared path: declared non-excluded — the tracked-file floor verifies on the `set-flow` arming path — vs loudly DECLARED-EXCLUDED). A config with no `flow` block renders byte-identically to before and pays no store probe.
19
19
 
20
- **Declared source-size practice block (upfront knowledge, D-17 U1).** When the project declares a source-size practice in `docs/ai/source-size.json`, the advisor also renders `Declared source-size practice (docs/ai/source-size.json) — known BEFORE the code is written:` — the caps, what is recorded, the canonical WHY sentence and the plan-time rung (every Step that creates a file names the file and its single responsibility, and the planned layout fits the caps). `--json` carries the SAME lines under **`declaredPractice`** (an empty array when nothing is declared), so the human and structured renders never diverge. The four config states each read as themselves: **ABSENT** renders nothing at all (a project declaring no practice is handed no invented limits), **AUTHORED** and **INCOMPLETE** are pre-mint (the second names the half-written machine key), **MINTED** carries the recorded counts. A declaration that cannot be read (malformed, unknown-keyed, a dangling symlink) renders ONE loud `UNREADABLE` line and the advisor **still exits 0** — the practice's own checker owns the exit code for its config (exit 2 there) and its declared gate reds the gate matrix. Read through the practice's pure read core, so this advisor never reaches its writer half.
20
+ **Declared source-size practice block (upfront knowledge, D-17 U1).** When the project declares a source-size practice in `docs/ai/source-size.json`, the advisor also renders `Declared source-size practice (docs/ai/source-size.json) — known BEFORE the code is written:` — the caps, what is recorded and the canonical WHY sentence (the plan-time layout itself is the planning canon's Module ledger). `--json` carries the SAME lines under **`declaredPractice`** (an empty array when nothing is declared), so the human and structured renders never diverge. The four config states each read as themselves: **ABSENT** renders nothing at all (a project declaring no practice is handed no invented limits), **AUTHORED** and **INCOMPLETE** are pre-mint (the second names the half-written machine key), **MINTED** carries the recorded counts. A declaration that cannot be read (malformed, unknown-keyed, a dangling symlink) renders ONE loud `UNREADABLE` line and the advisor **still exits 0** — the practice's own checker owns the exit code for its config (exit 2 there) and its declared gate reds the gate matrix. Read through the practice's pure read core, so this advisor never reaches its writer half.
21
21
 
22
22
  **Cap-soft-skip degradation (the feature's only AUTO route).** The activity procedures are auto-discoverable only through the one-line **`workflow:methodology`** pointer (this kit + the engine carry `disable-model-invocation:true`, so NL like "write a plan" does **not** auto-load this skill). On a deployment whose methodology pointer was cap-soft-skipped — or whose pre-existing customized pointer lacks the procedures clause — the procedures are still reachable by **explicitly** invoking `/agent-workflow-kit procedures`; surface that plainly rather than treating it as a gap.
23
23
 
@@ -77,11 +77,11 @@ Apply this as part of §2 before any user-facing summary:
77
77
  Apply these when authoring a plan, reviewing, folding a finding, or editing code — the layer read **before any code change**. (Full canon: the project's planning / workflow-methodology + orchestration canon. This section is rendered from that canon and refreshed on upgrade; a custom edit is preserved verbatim, but flagged.)
78
78
  - **Fold by code, not prose.** Before folding a code-touching finding into a plan or change, read the cited `file:line` and cite it — a prose fold drifts from the code and seeds the next bug.
79
79
  - **Right altitude.** Pin intent + invariants + acceptance criteria (named tests); leave fine code-mechanics to Execute, where prose cannot diverge from reality.
80
- - **No code-mechanics in the plan.** A Step still carries its exact paths + commands (the plan-structure / self-review canon) — checked syntax: the plan's own Verification runs them against an explicit expected outcome or gate; the only other syntax a plan may carry is a literal fixture/schema fragment a named test copies or validates. Un-run, logic-bearing syntax — control-flow, a regex, a glob, a grammar, an algorithm body, a mini-DSL — never lives in plan prose, however plausible or shell-verified it looks: a fold or draft that wants one is the trigger to write the test instead.
80
+ - **No code-mechanics in the plan.** A ledger row carries its path and anchor, and Verification carries the exact commands (the plan-shape canon) — checked syntax: the plan's own Verification runs them against an explicit expected outcome or gate; the only other syntax a plan may carry is a literal fixture/schema fragment a named test copies or validates. Un-run, logic-bearing syntax — control-flow, a regex, a glob, a grammar, an algorithm body, a mini-DSL — never lives in plan prose, however plausible or shell-verified it looks: a fold or draft that wants one is the trigger to write the test instead.
81
81
  - **Test-as-spec.** Fold a code-touching finding into a red→green TEST, not a prose paragraph — the gate is the only deterministic checker; a paragraph cannot self-check.
82
82
  - **Characterize-first.** Before editing UNCOVERED code, pin its current behavior in a green test, then edit — any unintended change goes red. Never edit what has no checker; first give it one. Keep edits atomic/reversible; prefer SUBTRACTIVE folds.
83
83
  - **Fold minimally — prose has no checker.** An ephemeral, gitignored plan is prose with no executable checker; fold **minimally, in ONE place** and run a **self-consistency** read across the plan before every re-review — a fold that drifts several prose spots is what turns a 2-round review into churn.
84
- - **Heavy review at the diff.** Plan-review settles architecture only (≤2 rounds, stop at the pre-existing→fold-induced crossover); the exhaustive per-Step review runs against real compiling code + the full suite, where a regression fails a gate immediately. **Backend divergence** (one backend grounded-ships while another keeps revising mechanics) IS that crossover — resolve at altitude, don't exhaust the strictest backend; route an all-mechanics/CI or prose-only artifact to a **thin plan + diff-review**.
84
+ - **Heavy review at the diff.** Plan-review settles architecture only (≤2 rounds, stop at the pre-existing→fold-induced crossover); the exhaustive per-row review runs against real compiling code + the full suite, where a regression fails a gate immediately. **Backend divergence** (one backend grounded-ships while another keeps revising mechanics) IS that crossover — resolve at altitude, don't exhaust the strictest backend; route an all-mechanics/CI or prose-only artifact to a **thin plan + diff-review**.
85
85
  - **Convergence bar.** A review loop is CLEAN only when one round returns **0 blockers + 0 majors** from EVERY backend the recipe names (nits + a ship verdict is the stop). Folding ≠ convergence — re-review after folding.
86
86
  - **Per-round emission.** Every review round emits **{round N · finding-origin tally · per-backend verdict}** so the crossover is a computed, visible signal, not a remembered rule.
87
87
  - **Recipe fidelity.** Council runs every backend the recipe names, **every round**; silently dropping a ready backend for quota/convenience is a forbidden downgrade — an unavailable backend is a LOUD, stated degrade, never a quiet drop.
@@ -96,8 +96,7 @@ Split a complex task across sessions for **focus and review hygiene**, not becau
96
96
 
97
97
  - **Split (separate sessions)** when the *change* is large enough to deserve an isolated review checkpoint: creates/deletes a source or test file, touches several files, alters a dependency / core config / data model / routes, or needs new E2E tests. These are review-hygiene triggers, independent of context size.
98
98
  - **Run inline** for small, self-contained work: a few files, no new files, no dependency/schema/route change, light discussion (typos, tweaks, single-line fixes, test additions).
99
- - **Context size is a soft, secondary signal** — split only when the working context is genuinely large *relative to the window* or you notice degraded recall, never at a fixed token count. Prefer the planning skill's **session-continuity heuristic**: keep going in-session when the accumulated context IS the execution payload (targeted-deep reads of the exact files you'll edit); split when it was broad fan-out noise.
100
-
99
+ - **Context size is a soft, secondary signal** — split only when the working context is genuinely large *relative to the window* or you notice degraded recall, never at a fixed token count.
101
100
  ---
102
101
 
103
102
  ## 4. User Interaction
@@ -109,4 +108,4 @@ Split a complex task across sessions for **focus and review hygiene**, not becau
109
108
 
110
109
  ## 5. Planning Workflow
111
110
 
112
- All plan-file rules — vocabulary (Plan Phase Step → Substep), lifecycle (`docs/plans/<slug>.md`, gitignored, never committed), the mandatory final **Phase: Cleanup**, the `docs/plans/queue.md` series-index, "all work in plans", the plan-then-execute split — live in the project's planning skill. It is the single source of truth and overrides the generic `writing-plans` skill.
111
+ All plan-file rules — shape (goal and boundary, module ledger, verification), lifecycle (`docs/plans/<slug>.md`, gitignored, never committed), the mandatory final **Phase: Cleanup**, the `docs/plans/queue.md` series-index, "all work in plans" — live in the project's planning skill. It is the single source of truth and overrides the generic `writing-plans` skill.
@@ -6,11 +6,9 @@
6
6
  //
7
7
  // --constraints slice the root AGENTS.md `## 🚫 Hard Constraints` section, verbatim
8
8
  // (exactly-one-match — 0 or >1 headings is a loud STOP, never a guess);
9
- // --plan <path> extract the plan's decision-bearing canonical sections, verbatim + whole:
10
- // `## Approach` (REQUIRED its "What we are NOT doing" text rides inside;
11
- // it is not a heading in canon) and `## Verification` (REQUIRED STOP if
12
- // missing), plus `## Decisions (locked)` (optional-if-absent, the engine §7
13
- // heading this release adds); a DUPLICATE heading is always a STOP.
9
+ // --plan <path> extract the plan's three canon sections, verbatim + whole — `## Goal and
10
+ // boundary`, `## Module ledger`, `## Verification` (the engine planning.md
11
+ // literal headings; each REQUIRED a missing or DUPLICATE heading is a STOP).
14
12
  // --extra <text|@file> append orchestrator-supplied facts verbatim AFTER the mechanical halves
15
13
  // (repeatable; @file reads are confined to the work tree + the system temp
16
14
  // surface — the merge happens INSIDE the tool, corpus #88/#95).
@@ -46,18 +44,14 @@ export const DEFAULT_MAX_PROMPT_BYTES = 120000;
46
44
  export const ARGV_HARD_MAX = 131000;
47
45
 
48
46
  export const CONSTRAINTS_HEADING = /^## .*Hard Constraints$/;
49
- export const PLAN_SECTIONS = [
50
- { heading: '## Approach', optional: false },
51
- { heading: '## Verification', optional: false },
52
- { heading: '## Decisions (locked)', optional: true },
53
- ];
47
+ export const PLAN_SECTIONS = ['## Goal and boundary', '## Module ledger', '## Verification'];
54
48
 
55
49
  // ── pure section slicing (exactly-one-match; the inject-methodology discipline) ────────
56
50
 
57
51
  // Slice ONE `## `-level section (its heading line through the line before the next `## ` heading),
58
52
  // verbatim. `heading` is a string (trimmed-line equality) or a RegExp over the trimmed line.
59
- // 0 matches → null when optional, else STOP; >1 matches → always STOP (never guess which).
60
- export const sliceSection = (text, heading, { optional = false, label = 'document' } = {}) => {
53
+ // 0 matches → STOP; >1 matches → STOP (never guess which).
54
+ export const sliceSection = (text, heading, { label = 'document' } = {}) => {
61
55
  const lines = text.split('\n');
62
56
  const matchesAt = [];
63
57
  for (let i = 0; i < lines.length; i += 1) {
@@ -66,7 +60,6 @@ export const sliceSection = (text, heading, { optional = false, label = 'documen
66
60
  }
67
61
  const shown = typeof heading === 'string' ? heading : String(heading);
68
62
  if (matchesAt.length === 0) {
69
- if (optional) return null;
70
63
  throw fail(1, `${label}: required section "${shown}" not found — STOP (nothing sliced)`);
71
64
  }
72
65
  if (matchesAt.length > 1) {
@@ -95,10 +88,7 @@ export const assembleGrounding = ({ constraintsText = null, autonomyText = null,
95
88
  // how autonomous this session is → what this plan decides).
96
89
  if (autonomyText != null) parts.push(autonomyText);
97
90
  if (planText != null) {
98
- for (const { heading, optional } of PLAN_SECTIONS) {
99
- const section = sliceSection(planText, heading, { optional, label: planLabel });
100
- if (section != null) parts.push(section);
101
- }
91
+ for (const heading of PLAN_SECTIONS) parts.push(sliceSection(planText, heading, { label: planLabel }));
102
92
  }
103
93
  // Orchestrator extras ride LAST, verbatim in argv order — live judgment facts read after the
104
94
  // mechanical slices, and the merge happens INSIDE the tool (corpus #88/#95: a shell append onto
@@ -268,9 +258,9 @@ Usage:
268
258
  stated source line; absent file → the computed defaults ARE the policy
269
259
  (exit 0); malformed/unreadable → fail-closed STOP (exit 1); informational —
270
260
  enforcement stays the sandbox + the orchestrator
271
- --plan <path> extract the plan's decision-bearing sections verbatim + whole:
272
- "## Approach" + "## Verification" (REQUIRED — STOP if missing),
273
- "## Decisions (locked)" when present; a duplicate heading is a STOP
261
+ --plan <path> extract the plan's three canon sections verbatim + whole: "## Goal and
262
+ boundary", "## Module ledger", "## Verification" (each REQUIRED — a
263
+ missing or duplicate heading is a STOP)
274
264
  --extra <text|@file> append orchestrator-supplied extra facts byte-verbatim AFTER the
275
265
  mechanical sections (repeatable, argv order; the agy-review --facts
276
266
  convention: literal text, or @path read whole through a race-free
@@ -84,6 +84,8 @@ export const AUTONOMY_EMPTY_SLOT = `${AUTONOMY_START_MARKER}\n${AUTONOMY_END_MAR
84
84
  export const KNOWN_PRIOR_METHODOLOGY_SLOT = [
85
85
  // v1.3.0 — pre-communication-contract methodology pointer (procedures route, no §1.9 clause).
86
86
  '> **Workflow methodology** — plan → execute → review. Plans are ephemeral `docs/plans/*.md` (gitignored, **never committed**); every Plan ends with a mandatory **Phase: Cleanup**; series order lives in `docs/plans/queue.md`. Full vocabulary, lifecycle, and the plan-then-execute split live in the project\'s **planning skill** (it overrides the generic `writing-plans`); summary in `docs/ai/agent_rules.md` §5. Named activities (plan-authoring, plan-execution) have procedures — see `/agent-workflow-kit procedures <activity>` for the steps + resolved recipe.',
87
+ // engine 2.1.0 — the pre-canon-rewrite pointer (vocabulary + plan-then-execute wording, with the communication contract).
88
+ '> **Workflow methodology** — plan → execute → review. Plans are ephemeral `docs/plans/*.md` (gitignored, **never committed**); every Plan ends with a mandatory **Phase: Cleanup**; series order lives in `docs/plans/queue.md`. Full vocabulary, lifecycle, and the plan-then-execute split live in the project\'s **planning skill** (it overrides the generic `writing-plans`); summary in `docs/ai/agent_rules.md` §5. Named activities (plan-authoring, plan-execution) have procedures — see `/agent-workflow-kit procedures <activity>` for the steps + resolved recipe. **Communication:** user-facing messages deliver the artifact inline (paste the prompt / diff / command — never "see §X" as a substitute), lead with the result, show exactly what was asked, and never read as mockery (a large artifact: a real summary inline + a link).',
87
89
  ];
88
90
  export const KNOWN_PRIOR_ORCH_SLOT = [
89
91
  // v1.3.0 — pre-read-at-start orchestration pointer (recipes vocabulary, no orchestration.json clause).
@@ -208,8 +208,8 @@ const backendSetLabel = (backends) =>
208
208
  : ` → ${backends[0]}`;
209
209
 
210
210
  // The review-loop economics block (M1 + M6's firing half) — printed when the activity engages a review
211
- // backend (a slot resolving reviewed | council) and OMITTED for solo. It paraphrases the §9 +
212
- // orchestration §4 canon (no rival rule): the ≤2-round architecture cap, the bar met by RAISING a
211
+ // backend (a slot resolving reviewed | council) and OMITTED for solo. It paraphrases the procedures.md
212
+ // Fold + loop step + orchestration §4 canon (no rival rule): the ≤2-round architecture cap, the bar met by RAISING a
213
213
  // surviving major to an acceptance invariant (not exhausting prose), backend divergence = the crossover
214
214
  // stop, the thin-plan/diff-review carve-out, a self-consistency read before every re-review, and the
215
215
  // REQUIRED per-round structured emission {round N · finding-origin tally · per-backend verdict}. Only a
@@ -221,7 +221,7 @@ const REVIEW_RECIPES = new Set(['reviewed', 'council']);
221
221
  const reviewLoopAdvice = (slots, activity) =>
222
222
  slots.some((s) => REVIEW_RECIPES.has(s.recipe))
223
223
  ? [
224
- 'Review-loop economics (planning.md §9 · orchestration.md §4) — the review this recipe runs:',
224
+ 'Review-loop economics (procedures.md Fold + loop · orchestration.md §4) — the review this recipe runs:',
225
225
  ' • Cap architecture plan-review at ≤2 rounds; the bar is met by RAISING a surviving major to an acceptance invariant (or handing it to Execute/diff-review), never by exhausting the strictest backend.',
226
226
  ' • Backend divergence (one backend grounded-ships while another keeps revising mechanics) IS the crossover stop.',
227
227
  ' • Route an all-mechanics/CI or prose-only artifact to a thin plan + diff-review; run a self-consistency read before every re-review.',
@@ -299,7 +299,7 @@ const autonomyAdvice = (activity, facts) => {
299
299
  };
300
300
 
301
301
  // The cost-lane advisory block (cost-tiered execution — orchestration.md §5 canon, paraphrased
302
- // at the point of use like reviewLoopAdvice paraphrases §9/§4). Rendered UNCONDITIONALLY for
302
+ // at the point of use like reviewLoopAdvice paraphrases procedures.md Fold + loop / orchestration §4). Rendered UNCONDITIONALLY for
303
303
  // every activity — the lanes route EVERY step, review-backed or not (unlike reviewLoopAdvice,
304
304
  // which fires only when a review backend engages). It may name the kit's own GENERIC L0
305
305
  // surfaces (the gate runner, the rotation checks, the cheap-agents vehicles) — point-of-use
@@ -368,9 +368,9 @@ const flowHalvesAdvice = (flow, probe) => {
368
368
  };
369
369
 
370
370
  // ── the declared source-size practice (D-17 U1) ────────────────────────────────────
371
- // A practice the agent meets only when a gate refuses is a practice learned too late: the caps, their
372
- // reason and the plan-time rung ride EVERY named-activity render, so the layout is cut to them while
373
- // the plan is being written. Composed from the project's live declaration, never from constants here.
371
+ // A practice the agent meets only when a gate refuses is a practice learned too late: the caps and
372
+ // their reason ride EVERY named-activity render, so the plan's Module ledger is cut to them while the
373
+ // plan is being written. Composed from the project's live declaration, never from constants here.
374
374
  // Each config state speaks as itself: ABSENT renders NOTHING (a project that declares no practice must
375
375
  // not be handed invented limits); AUTHORED and INCOMPLETE render the declared caps plus the honest
376
376
  // "nothing is recorded yet" line — both are pre-mint states, and treating INCOMPLETE as MINTED would
@@ -406,7 +406,6 @@ const declaredPracticeAdvice = (cwd, readFile, lstat) => {
406
406
  ? ` recorded: ${facts.recordedFiles} file(s) carry a recorded size (debt, not permission) · aggregate ${facts.aggregateLines} line(s), EXACT — growth takes a reasoned bump, never free headroom.`
407
407
  : unmintedRecord,
408
408
  ` why: ${SOURCE_SIZE_WHY}`,
409
- ' at plan time: every Step that CREATES a file names the file and its single responsibility, and the planned layout fits these caps — the gate is the backstop, never the teacher.',
410
409
  ];
411
410
  };
412
411