@sabaiway/agent-workflow-kit 14.4.3 → 14.6.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,100 @@ 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
+ ## 14.6.0 — your rules file gains a Story sessions section, and the kit can now put a missing template section there for you (AD-152)
8
+
9
+ **A section you were told to add by hand is now one command.** Up to 14.5.0 a project's
10
+ `docs/ai/agent_rules.md` said nothing about how a story splits into sessions, so where the split belonged was
11
+ nobody's written rule; and when the upgrade found a template-owned section missing from your file, it said "add it
12
+ from the current template" and left you to copy it. 14.6.0 adds the section to the bundled template and adds the
13
+ tool that inserts a missing one — after naming, section by section, what it would add and what it would leave alone.
14
+ Story S2 of the epic `CONSUMERS-MOVE-ONTO-THE-FULL-FLOW`; contract `docs/ai/specs/kit/rules-regions/` (revision 2).
15
+
16
+ - **The new section.** `references/templates/agent_rules.md` (and its memory twin, byte-identical) gains
17
+ `### 2.7. Story sessions`, after §2.6 and before the `---` that closes §2: a story runs as five sessions — spec,
18
+ plan, tests, code, and diff review + release + record — each ending at its own review checkpoint, with tests and
19
+ code never sharing a session and a spec never sharing one with its plan. A split — moving code and its existing
20
+ cases into modules, with no new logic and no new case — is one session.
21
+ - **`tools/rules-insert.mjs --cwd <project> [--apply]`**. Inserts a template-owned section your rules file does not
22
+ have — Communication or Story sessions — after the last `### 2.<N>.` section, numbered after your highest one, with
23
+ the template's own bytes and your file's newline form. Without `--apply` it previews and writes nothing: one line
24
+ per section, `present` or `planned`. With `--apply` it writes in one atomic replacement, whole or nothing, and a
25
+ second `--apply` changes no byte. A section you already have keeps your wording, whatever it says. Every state it
26
+ cannot act on names itself on stderr and leaves your file byte-for-byte unchanged: the file absent, a symlink,
27
+ unreadable — bytes that do not survive a UTF-8 round trip included, since the tool reads your file as bytes and
28
+ proves it can give them back before it writes anything, so nothing outside the inserted section is ever rewritten
29
+ — the bundled template unusable, a heading occurring more than once, no numbered section to insert after, a
30
+ result over your file's own `maxLines`, or a failed write. A leading byte-order mark is not a refusal: it is
31
+ kept, and the section is inserted as in any other file. Exit 0 for a preview or an apply, 1 for a
32
+ refusal, 2 for a usage error — raised before anything is read.
33
+ - **The upgrade reconcile now judges three sections, not two.** `tools/lens-region.mjs reconcile <path>` reports the
34
+ Story sessions section from the same outcome set as Communication, and reports it BEFORE the engine-backed lens
35
+ section, so a missing or too-old engine can no longer hide that verdict. In 14.6.0 the section has no earlier
36
+ canon to recognise, so what you will actually see is *already current* when your body matches the template,
37
+ *custom edit preserved + note* whenever it does not — your wording is never overwritten — or *section absent*;
38
+ the refresh outcomes join once a first prior wording ships. Both "section absent"
39
+ notes now carry the preview command; an upgrade relays it as an offer and runs `--apply` only on your explicit yes.
40
+ A heading occurring more than once in a template-owned section is preserved with a note and nothing written.
41
+ - **Internals.** The region table, the one extraction rule and the insert judgement move to `tools/rules-regions.mjs`
42
+ (pure over text, reads no file, imports no writer); `tools/lens-region.mjs` keeps every export it had and shrinks
43
+ from 393 lines to 271. `tools/profile-gaps.mjs` holds the frozen registry of gap entries the Recommendations screen
44
+ will render, with the first entry, `story-sessions-section`.
45
+
46
+
47
+ ## 14.5.0 — an upgrade delivers its migration notes and entry-point blocks through two new tools, and `init` removes the files the package does not carry from an existing kit home (AD-151)
48
+
49
+ **Three things the upgrade already promised now run as code.** Up to 14.4.3 the upgrade mode asked the agent to pick
50
+ the migration notes newer than the project's stamp by itself and to paste two entry-point blocks by hand, and `init`
51
+ only added files, so a kit home kept every file a later package stopped shipping (except two paths the installer named
52
+ by hand). 14.5.0 adds two command-line tools and one library the installer calls. Story S1 of the epic
53
+ `CONSUMERS-MOVE-ONTO-THE-FULL-FLOW`; contract `docs/ai/specs/kit/upgrade-delivery/` (revision 1).
54
+
55
+ - **`tools/migration-notes.mjs --cwd <project>`** (read-only). Lists each note under `migrations/` whose version is
56
+ newer than the project's `docs/ai/.workflow-version` and not newer than the deployment-lineage head, in ascending
57
+ order, one stdout line each: `note <version> <path> :: <headline>`. A refusal is one stderr line that opens with its
58
+ name; a usage error exits 2 before anything is read.
59
+ - **`tools/migration-blocks.mjs --cwd <project> [--language <text>] [--attribution on|off] [--apply]`**. Places the
60
+ Communication language and Attribution blocks into the project's `AGENTS.md` from the kit's
61
+ `references/templates/AGENTS.md`, now the kit's only copy of their text. Without `--apply` it previews and writes
62
+ nothing; with `--apply` it writes every missing block in one atomic write, writes nothing when both blocks are
63
+ already present, and writes nothing when it refuses, naming the refusal in one stderr line.
64
+ - **`tools/payload-prune.mjs`** (library). After its copy, `init` compares each of the five folders it installs
65
+ (`references/`, `tools/`, `migrations/`, `launchers/`, `bridges/`) with the same folder in the kit home. A regular file the package does not carry is removed with one `removed` line, a file
66
+ you placed there yourself included; a directory or symlink the package does not carry is kept with a `kept` line
67
+ (the files inside such a directory are removed all the same). `init` now refuses an existing folder that is
68
+ neither empty nor a kit home (a `SKILL.md` whose frontmatter names `agent-workflow-kit`): it exits 1 before
69
+ writing anything. A kind mismatch or a failed enumeration
70
+ stops the prune before it removes anything; a failed removal is reported by path and the other files still go. When
71
+ the prune reports a failure, `init` prints a non-convergence line in place of the line that names the installed
72
+ version, still runs its launcher, bridge, memory and engine steps, and exits 1. The hand-kept `RETIRED_PATHS` list
73
+ is gone.
74
+ - **Upgrade mode.** Steps 6 and 7 of `references/modes/upgrade.md` run the notes tool and the blocks writer, relay
75
+ their lines and act on their exits: `stamp-absent` returns to step 1, `answer-missing` asks for the named answers
76
+ and re-runs once, any other refusal stops the upgrade before the stamp.
77
+ - **Notes and docs.** Notes 1.1.0 and 1.2.0 no longer carry block text; they name the writer. The
78
+ `.claude/settings.json` step of 1.2.0 stays a hand step, taken whenever the Attribution block reads `off`. The
79
+ migrations README names the notes tool as the only selection. The README and `init --help` no longer say `init` is
80
+ additive: it never deletes project settings, and in an existing kit home it removes each file in the kit's folders
81
+ that the package does not carry, one line each.
82
+ - **Reference profile.** `references/reference-profile.json` names the profile `full-flow`: ten items, each keyed to
83
+ the story that delivers it. `test/upgrade-full-flow.test.mjs` seeds an older kit home and project, upgrades them
84
+ once with the real tools and checks each landed story's items; S1's three items pass, and every story not yet landed
85
+ is asserted to show a gap.
86
+ - **Tests.** Suites for the three new modules; `test/package-content.test.mjs` pins 328 packed files and names the
87
+ four new ones; the legacy-path case and the two symlink cases of `bin/install.test.mjs` seed the kit's `SKILL.md`
88
+ their existing homes stand for.
89
+
90
+ **Upgrade criterion.** Nothing to do by hand, unless you keep a file of your own in the kit home's `references/`,
91
+ `tools/`, `migrations/`, `launchers/` or `bridges/` folders: move it out first. The first `init` of 14.5.0 over an
92
+ existing kit home (`~/.claude/skills/agent-workflow-kit/` by default) removes every file in those five folders that
93
+ the package does not carry, one `removed` line each; that is the intended cleanup. A home that an `init` before 1.15.2
94
+ wrote, or one copied by hand from the source tree, also loses the test files and fixtures under `tools/` that the
95
+ package does not ship, and the folders they leave empty are reported as `kept` on every run until you remove them. A
96
+ folder an earlier `init` wrote the kit's `SKILL.md` into counts as a kit home, a project folder included: if you once
97
+ pointed `--dir` at a project, delete the kit's `SKILL.md` there before you run `init` into it again, or the project's
98
+ own files in those five folders are removed. A `--dir` or `AGENT_WORKFLOW_KIT_DIR` that names an
99
+ existing folder which is neither empty nor a kit home is now refused; point it at a new or empty folder instead.
100
+
7
101
  ## 14.4.3 — cleanup after the two splits: one false doc pointer, a test title, a list order, comments and whitespace; nothing the kit decides, prints or records changes
8
102
 
9
103
  **Six small review findings from the review-state and core-evidence splits are fixed.** The only shipped doc change is in
package/README.md CHANGED
@@ -196,7 +196,8 @@ other agent). The manual path works identically but **isn't reflected in install
196
196
  <details>
197
197
  <summary><b>What <code>init</code> touches — and how to undo it</b></summary>
198
198
 
199
- `init` is **additive — it never deletes your settings.** It writes its own namespaced slots, then
199
+ `init` **never deletes your project settings**, and it installs only into a new or empty folder or an existing kit home: any other `--dir` is refused before anything is written. In an existing kit home it removes every file in the kit's
200
+ `references/`, `tools/`, `migrations/`, `launchers/` and `bridges/` folders that the package does not carry, a file you put there included, one reported line per file. It writes its own namespaced slots, then
200
201
  refreshes the other npm core members so a returning `init` leaves **no stale core member**:
201
202
 
202
203
  | Path | What |
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: '14.4.3'
6
+ version: '14.6.0'
7
7
  ---
8
8
 
9
9
  # agent-workflow-kit
package/bin/install.mjs CHANGED
@@ -30,13 +30,14 @@
30
30
  //
31
31
  // Dependency-free, Node >= 22.
32
32
 
33
- import { readFile, mkdir, rm } from 'node:fs/promises';
33
+ import { readFile, mkdir } from 'node:fs/promises';
34
34
  import { existsSync, lstatSync, realpathSync } from 'node:fs';
35
35
  import { dirname, resolve, sep } from 'node:path';
36
36
  import { fileURLToPath } from 'node:url';
37
37
  import { homedir } from 'node:os';
38
38
  import { spawnSync } from 'node:child_process';
39
39
  import { copyTreeRefresh } from '../tools/fs-safe.mjs';
40
+ import { assertInstallableHome, prunePayload } from '../tools/payload-prune.mjs';
40
41
  // Dependency-free semver, shared with the family registry's bridge freshness probe (one leaf, no
41
42
  // second drifting copy). The null-on-unparseable contract is load-bearing here: legacy installs
42
43
  // predate any version stamp, so an unparseable side means "no gate", never a false ordering.
@@ -75,12 +76,6 @@ const PAYLOAD = [
75
76
  'bridges',
76
77
  ];
77
78
 
78
- // Kit-owned files the package NO LONGER ships (Plan 3D retired the bundled methodology mirror). The
79
- // refresh copy is additive, so a 1.10.0→1.11.0 upgrade would leave these dead copies behind; remove
80
- // exactly these known kit paths from the target on install (never user content, never a dir/symlink),
81
- // so an upgraded install has the same single-source-of-truth shape as a fresh one.
82
- const RETIRED_PATHS = ['references/planning.md', 'tools/methodology-slot.md'];
83
-
84
79
  // Collapse only a LEADING homedir() to "~" — anchored at the string start (boundary-checked with
85
80
  // `sep`), never a mid-path occurrence (Issue-004 parity with the engine/memory installers).
86
81
  const tildify = (path) =>
@@ -305,7 +300,8 @@ Installs/refreshes the kit at ~/.claude/skills/agent-workflow-kit
305
300
  launcher file (backed up first). The bridges are never PLACED by init (first placement
306
301
  stays /agent-workflow-kit setup, opt-in); once placed, init refreshes them from the kit's
307
302
  own bundled copies — local files only, never a downgrade — and --no-bridges skips that
308
- refresh. init is additive — it never deletes your settings. If the
303
+ refresh. init never deletes your project settings; in an existing kit home it removes each
304
+ file in its folders that the package does not carry, one line each. If the
309
305
  installed kit is newer than the version you ran, init refuses (no network — it compares
310
306
  the version on disk) and points you at @latest; --allow-downgrade overrides that
311
307
  refusal (distinct from --force, which is launcher-only).
@@ -373,19 +369,14 @@ const main = async () => {
373
369
  process.exit(1);
374
370
  }
375
371
 
372
+ assertInstallableHome(target);
376
373
  await mkdir(target, { recursive: true });
377
374
  for (const entry of PAYLOAD.filter((e) => existsSync(resolve(PKG_ROOT, e)))) {
378
375
  copyTreeRefresh(resolve(PKG_ROOT, entry), resolve(target, entry), target);
379
376
  }
380
- // Remove the retired mirror files an older install may have left (additive refresh never deletes).
381
- // Only a regular file at the exact known path is removed — lstat (no-follow) so a dir/symlink is
382
- // left untouched, and the path is a hardcoded kit-owned constant (no traversal, never user content).
383
- for (const rel of RETIRED_PATHS) {
384
- const retired = resolve(target, rel);
385
- if (lstatNoFollow(retired)?.isFile()) {
386
- await rm(retired, { force: true });
387
- console.log(`[agent-workflow-kit] removed retired file ${tildify(retired)} (now read live from the engine).`);
388
- }
377
+ const prune = prunePayload({ packageRoot: PKG_ROOT, home: target, payload: PAYLOAD });
378
+ for (const line of prune.lines) {
379
+ console.log(line);
389
380
  }
390
381
  // Verb keyed on the OBSERVED version relation (cmp), never on mere presence: null (fresh install,
391
382
  // or a legacy/unstamped one whose prior version is unknowable) → "installed"; -1 → a real update;
@@ -397,7 +388,11 @@ const main = async () => {
397
388
  : cmp === 1 ? 'downgraded the kit to'
398
389
  : cmp === -1 ? 'updated the kit to'
399
390
  : 'installed';
400
- console.log(`[agent-workflow-kit] ${verb} v${version} -> ${tildify(target)}`);
391
+ if (prune.ok) {
392
+ console.log(`[agent-workflow-kit] ${verb} v${version} -> ${tildify(target)}`);
393
+ } else {
394
+ console.log(prune.nonConvergence);
395
+ }
401
396
 
402
397
  // F12 restart hint — any run over a PRE-EXISTING install (every cmp outcome, incl. the legacy
403
398
  // unstamped one) leaves an already-open agent session still holding the PREVIOUS kit files in
@@ -545,6 +540,9 @@ const main = async () => {
545
540
  console.log('[agent-workflow-kit] methodology engine installed.');
546
541
  }
547
542
 
543
+ // The non-convergence line already took the verb's place.
544
+ if (!prune.ok) process.exit(1);
545
+
548
546
  // This command (de)installed the *kit* globally. Deploying it into a project is a
549
547
  // separate, in-agent step — and which sub-command depends on whether that project
550
548
  // already has the kit. Spell both out so it's unambiguous (see README "Use").
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": "14.4.3",
6
+ "version": "14.6.0",
7
7
  "provides": [],
8
8
  "roles": {},
9
9
  "detect": {
@@ -20,21 +20,18 @@ translated either. This migration changes *one* doc block, nothing else.
20
20
  this migration is done; skip to Verification.
21
21
  3. **Ask the user** which language the agent should converse in (questions, explanations,
22
22
  summaries, status). Offer the language they're already writing in as the default.
23
- 4. Insert this block immediately **after the opening blockquote** (before `## 🧭 Memory Map`),
24
- replacing `<their language>` with the answer from step 3:
25
-
26
- ```markdown
27
- ---
28
-
29
- ## 🗣️ Communication language
30
-
31
- > **Talk to the user in <their language>** — every question, explanation, summary, and status update.
32
- > Keep code, identifiers, file paths, shell commands, log output, and abbreviations in their **source language** — translating them breaks copy-paste, search, and tooling.
33
- > This sets the **dialogue** language only — it does not translate the files in `docs/ai/` or this entry point, which stay in their source language (for cross-agent / cross-team portability).
34
- ```
35
-
36
- 5. Keep `AGENTS.md` within its ≤100-line budget (the block is ~6 lines; it fits). Do **not**
37
- touch any other section, and do **not** translate existing file contents.
23
+ Reuse an answer already collected by the upgrade's step-6 prompt; never re-ask it.
24
+ 4. Preview with `node ${CLAUDE_SKILL_DIR}/tools/migration-blocks.mjs --cwd <project>`; it writes nothing.
25
+ Then insert from the kit's `references/templates/AGENTS.md` with
26
+ `node ${CLAUDE_SKILL_DIR}/tools/migration-blocks.mjs --cwd <project> --apply --language <answer>`.
27
+ If the Attribution block is absent too, collect its answer and pass `--attribution <off|on>`
28
+ in the same run: both blocks land in one atomic write, only after all answers are collected.
29
+ Otherwise `answer-missing` on stderr withholds the write; ask only for the answers stdout
30
+ names and re-run apply once. A second withheld result stops the migration.
31
+ Any other named refusal on stderr stops the migration; relay it as worded before any stamp update.
32
+ The upgrade's step 7 runs this same command with the answers its step-6 prompt collected.
33
+ 5. The writer refuses with `cap` rather than push `AGENTS.md` past its 100-line budget.
34
+ Relay that refusal, trim `AGENTS.md`, then re-run the upgrade; do not translate existing contents.
38
35
 
39
36
  ## Verification
40
37
 
@@ -16,30 +16,26 @@ keeps it permanently via PR refs — so the safe default is "no mention anywhere
16
16
  ## Steps
17
17
 
18
18
  1. Open the project's entry point `AGENTS.md` (the real file; `CLAUDE.md` is a symlink to it).
19
- 2. **Idempotency check** — if it already contains a `## ✍️ Attribution` heading, skip to Verification.
20
- 3. **Ask the user**: may the agent attribute work to itself / AI anywhere (commits, PRs, code,
21
- comments, docs)? **Default to `off`** unless they opt in.
22
- 4. Insert this block immediately **after the *Communication language* block** (or, if that is
23
- absent, after the opening blockquote — before `## 🧭 Memory Map`), replacing `<off|on>` with
24
- the answer from step 3:
25
-
26
- ```markdown
27
- ---
28
-
29
- ## ✍️ Attribution
30
-
31
- > **Agent attribution: <off|on>** (chosen at setup).
32
- > **off** → never attribute work to the agent, AI, or the model: no `Co-Authored-By` trailers, no "Generated with …" footers, no AI/agent/model mentions in code, comments, commit messages, PR titles/bodies, branch names, or docs. Author everything as the human.
33
- > **on** → the agent may add its standard `Co-Authored-By` trailer / footer per your tooling defaults.
34
- > Claude Code also honours `includeCoAuthoredBy` in `.claude/settings.json`; this block binds every agent for everything written by hand.
35
- ```
36
-
37
- 5. **If the answer is `off` and the project uses Claude Code**, also set the harness flag so the
38
- automatic trailer stops (a doc directive cannot stop a harness-added trailer):
19
+ 2. **Idempotency check** — if it already contains a `## ✍️ Attribution` heading, skip step 4;
20
+ step 5 still applies.
21
+ 3. **Ask only for a missing block's answer not already collected**: may the agent attribute work
22
+ to itself / AI anywhere (commits, PRs, code, comments, docs)? **Default to `off`** unless opted in.
23
+ 4. Preview with `node ${CLAUDE_SKILL_DIR}/tools/migration-blocks.mjs --cwd <project>`; it writes nothing.
24
+ Re-run that command with `--apply --attribution <off|on>` to insert from the kit's template.
25
+ If the Communication language block is absent too, collect its answer and pass `--language <answer>`
26
+ in the same run: the writer places both blocks in ONE atomic write, or withholds with
27
+ `answer-missing` and writes nothing if an answer is missing.
28
+ Upgrade step 7 runs this same command with the answers its step-6 prompt collected; never re-ask them.
29
+ Relay the writer's lines; a named refusal on stderr stops the migration and is relayed as worded.
30
+ For `answer-missing`, ask exactly the missing answers and retry `--apply` once; a second withheld run stops.
31
+ 5. **Whenever the Attribution block reads `off`**, whether just inserted or already present,
32
+ keep this hand step outside the writer: for Claude Code, set the harness flag so the automatic
33
+ trailer stops (a doc directive cannot stop a harness-added trailer):
39
34
  - Ensure `.claude/settings.json` exists in the project root; create it as `{}` if absent.
40
35
  - Set `"includeCoAuthoredBy": false` (merge into the existing JSON; do not clobber other keys).
41
36
  - For other tools, disable their equivalent co-author / footer setting if present.
42
- 6. Keep `AGENTS.md` within its ≤100-line budget (the block is ~7 lines; it fits). Do **not**
37
+ 6. The writer refuses with `cap` rather than push `AGENTS.md` past its 100-line budget;
38
+ trim the entry point and re-run the upgrade. Do **not**
43
39
  retroactively rewrite existing git history here — that is a separate, deliberate operation.
44
40
 
45
41
  ## Verification
@@ -8,8 +8,13 @@ releases add files/templates, which `upgrade` reconciles without a migration.
8
8
  ## How `upgrade` applies them
9
9
 
10
10
  1. Read the project's stamped version from `docs/ai/.workflow-version`.
11
- 2. Select every migration whose `<version>` is **strictly newer** than the stamp.
12
- 3. Apply them in **ascending semver order**.
11
+ 2. Run `node ${CLAUDE_SKILL_DIR}/tools/migration-notes.mjs --cwd <project>` as the sole selector.
12
+ It lists every migration whose `<version>` is **strictly newer** than the stamp and not newer than the head.
13
+ Each line is `note <version> <path> :: <headline>`, with an absolute `<path>` under the running kit.
14
+ The headline is the note's first `# ` line, with that prefix removed and surrounding whitespace trimmed.
15
+ The upgrade must relay those stdout lines verbatim and apply exactly the listed notes.
16
+ A named refusal stops the upgrade, except `stamp-absent`, which routes it back to the upgrade's step 1.
17
+ 3. Apply them in the order the tool listed them (**ascending semver order**).
13
18
  4. Re-stamp `docs/ai/.workflow-version` to the **deployment-lineage head** (`3.0.0` today — the
14
19
  shared lineage, **not** this skill's npm package version). A stamp greater than the head → STOP.
15
20
 
@@ -19,6 +24,7 @@ releases add files/templates, which `upgrade` reconciles without a migration.
19
24
  - **Non-destructive** — never clobber project-authored content (their `decisions.md`, `known_issues.md`, page specs). Add/rename/restructure only what the kernel owns.
20
25
  - **Self-contained** — exact paths + commands, readable cold, like a mini-plan.
21
26
  - **Mention rollback** — note how to undo if the step is risky.
27
+ - **Template blocks** — a note never pastes entry-point block text; `tools/migration-blocks.mjs` places it from the kit's template.
22
28
 
23
29
  ## Template
24
30
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sabaiway/agent-workflow-kit",
3
- "version": "14.4.3",
3
+ "version": "14.6.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",
@@ -79,11 +79,15 @@ Requires: ${CLAUDE_SKILL_DIR}/references/shared/report-footer.md · ${CLAUDE_SKI
79
79
  file's line cap — refused** (trim the file, re-run). The section is found by its heading — no
80
80
  markers; a renamed heading is preserved + noted. A fully absent/invalid engine is the same hard
81
81
  STOP as (c). Exit 0 covers every soft outcome; only the STOP is non-zero. The same invocation
82
- also reconciles the **Communication (user-facing messages)** section from the kit's own bundled
83
- template canon (no engine involved) — relay its line too: *refreshed* / *already current* /
84
- *custom edit preserved + note* / *section absent — noted (never an insert)* / *over the line
85
- cap — refused*; an unreadable bundled template canon is its own loud STOP naming the kit
86
- reinstall command.
82
+ also reconciles the **Communication (user-facing messages)** and **story-sessions** sections
83
+ from the kit's own bundled template canon (no engine involved) — relay each section's line:
84
+ *refreshed* / *already current* / *custom edit preserved + note* / *section absent — noted* /
85
+ *over the file's line cap — refused*; an unreadable bundled template canon is its own loud STOP
86
+ naming the kit reinstall command.
87
+ A doubled heading in any of the three sections is preserved with a note and no write.
88
+ The **Communication and story-sessions** absent-section notes already carry the preview
89
+ command: relay the printed note verbatim as the offer.
90
+ Run the insert with `--apply` only on the user's explicit yes, as with `gates-migration`.
87
91
 
88
92
  **`bridge-settings` — bridge settings reconcile.** **Paste its outcome line(s)
89
93
  verbatim**: it validates the deployed host settings file's keys against the bundled manifests and
@@ -92,13 +96,13 @@ Requires: ${CLAUDE_SKILL_DIR}/references/shared/report-footer.md · ${CLAUDE_SKI
92
96
  **The LATE navigator finalizer — the AUTHORITATIVE run, after the last `docs/ai` mutation.** `lens` above rewrites `docs/ai/agent_rules.md`, so the step-3 index ensure is already behind by the time the run-list ends. Re-run that ONE op here, before the step-4 report: `node ${CLAUDE_SKILL_DIR}/tools/ensure-configs.mjs --reconcile --only index --cwd <project>`. Relay **this** line in the report (it supersedes the early one; an untouched tree reports `already-current`, a failure STOPs the upgrade like any other ensure). On the migrated path the same rung runs again at the END of step 7 — after the migrations, before the step-8 re-stamp.
93
97
  4. **Equal-head exit — a real successful-exit report, not a bare stop.** If the stamp **equals** the head, the lineage is up to date — but step 3 (the stamp-independent reconciles) ran first and may have changed things, so this is a proper exit report, not a no-op:
94
98
  - **A skip line that contradicts the observed tree is a FINDING, never pasted as neutral.** Every ensure skip names the fact it proved (the probes that answered absent, the layout it read); if the tree you can see disproves that reason — a "no Node" skip beside deployed Node scripts, a "not deployed" skip beside a stamped `docs/ai` — do not relay the line as an outcome: raise it in the report as a defect of the tool, with the contradicting fact named, and stop short of any step that would build on the skip.
95
- - **Report step 3's outcome in plain language** — for **each** `pointers` slot (workflow-methodology, orchestration-recipes and autonomy-policy) whether it was *added*, was *already present* (nothing changed), or was *skipped* (the soft-skip from step 3, with its reason — over the line limit / engine too old / the autonomy pointer's anchor absent); the **eight project-configuration ensure** (`configs`) lines exactly as the one ensure run composed them (the ensures and their outcome tokens are enumerated in step 3), each rendered in plain language: what was created, what was left exactly as the user wrote it, and — for a `failed` line — what stopped it; for the navigator, relay the **late** `--only index` line, not the early one; the **`gates-migration`** result — *nothing to migrate*, the shown plan *applied* on your explicit yes, or the plan *left unapplied* (consent not given), with any INERT checker or CUSTOMIZED entries named; the **placed-bridge refresh** (`bridges`) outcome — paste the tool's per-bridge lines verbatim (they are already plain: *refreshed* / *already current* / *skipped — not placed* / `skipped-readonly` with its re-scan verdict / *could not refresh* + recovery); the **agent-rules lens** (`lens`) outcome (*refreshed* / *already current* / *custom edit preserved + note* / *file absent* / *engine too old* / *over the line cap*) and the **Communication-section** outcome (its own set: refreshed / already current / custom preserved + note / section absent — noted / over the cap — refused); the **bridge-settings reconcile** (`bridge-settings`) outcome (paste the tool's line(s) verbatim); and, for a hidden deployment, whether the hidden-mode footprint (`footprint`) was *moved to project-local*, was *already project-local* (nothing changed), or needed a question (ambiguous visibility / a leftover machine-wide block). Plain wording only — never the reconcile/slot/anchor/marker terms (the never-leak-kit-internals Gotcha — `${CLAUDE_SKILL_DIR}/references/shared/deploy-tail.md`).
99
+ - **Report step 3's outcome in plain language** — for **each** `pointers` slot (workflow-methodology, orchestration-recipes and autonomy-policy) whether it was *added*, was *already present* (nothing changed), or was *skipped* (the soft-skip from step 3, with its reason — over the line limit / engine too old / the autonomy pointer's anchor absent); the **eight project-configuration ensure** (`configs`) lines exactly as the one ensure run composed them (the ensures and their outcome tokens are enumerated in step 3), each rendered in plain language: what was created, what was left exactly as the user wrote it, and — for a `failed` line — what stopped it; for the navigator, relay the **late** `--only index` line, not the early one; the **`gates-migration`** result — *nothing to migrate*, the shown plan *applied* on your explicit yes, or the plan *left unapplied* (consent not given), with any INERT checker or CUSTOMIZED entries named; the **placed-bridge refresh** (`bridges`) outcome — paste the tool's per-bridge lines verbatim (they are already plain: *refreshed* / *already current* / *skipped — not placed* / `skipped-readonly` with its re-scan verdict / *could not refresh* + recovery); the **agent-rules lens** (`lens`) outcome (*refreshed* / *already current* / *custom edit preserved + note* / *file absent* / *engine too old* / *over the line cap*) and the **Communication-section** outcome (its own set: refreshed / already current / custom preserved + note / section absent — noted / over the cap — refused) and the **story-sessions section** outcome (its own set: refreshed / already current / custom edit preserved + note / section absent — noted / over the file's line cap — refused); the **bridge-settings reconcile** (`bridge-settings`) outcome (paste the tool's line(s) verbatim); and, for a hidden deployment, whether the hidden-mode footprint (`footprint`) was *moved to project-local*, was *already project-local* (nothing changed), or needed a question (ambiguous visibility / a leftover machine-wide block). Plain wording only — never the reconcile/slot/anchor/marker terms (the never-leak-kit-internals Gotcha — `${CLAUDE_SKILL_DIR}/references/shared/deploy-tail.md`).
96
100
  - **Never surface the structure number on this exit.** Whatever step 3 did, do **not** recite the `docs/ai` structure version, the internal versioning vocabulary, or the two-axes note here — the number is inert on an equal-head exit; it belongs to *Version disclosure* in `${CLAUDE_SKILL_DIR}/references/shared/report-footer.md` (shown at the never-downgrade STOP, the explicit status view, or on an explicit ask). Frame the success itself per the final bullet: if step 3 changed anything, say **what changed** in plain human terms; only a pure zero-diff no-op is *settings already current — no update needed*.
97
101
  - **Render the mandatory Recommendations section — on this exit too, BEFORE the footer.** Run `node ${CLAUDE_SKILL_DIR}/tools/recommendations.mjs --cwd <project-root>` and PRESENT its output — from the `## Recommendations (agent-workflow)` header — in the user's conversational language: every fact, count and item from the tool, nothing added or dropped; commands, paths, hosts and rule strings byte-exact; show the raw tool block on request. The section is present-even-when-empty (with everything optimal the body is exactly `no recommendations — flow optimal.`) and VERDICT-FIRST — the composed verdict line renders from the frozen templates `{K} item(s) need attention` / `nothing is broken` / `{N} optional recommendation(s), apply any you want` / `optimality NOT attested — {M} probe check(s) skipped`. Then OFFER the consent-gated applies: the user picks items in plain language; surface each picked item's posture note, get the explicit confirm, then run EXACTLY the rendered one-liners (a HAND-APPLY item is never run by you) — the full lane in `${CLAUDE_SKILL_DIR}/references/modes/recommendations.md`. Pinned order on this exit: Recommendations block → optional applies → report footer → the commit ask (the advisor/apply lane never lands after the commit ask).
98
102
  - **Live host/session facts are tool-composed only.** Any claim this report makes about the current host or session state — prompts fired, sandbox scope, whether a bypass was needed, network reachability, approval counts — must trace to **live tool output** from **this session** (the lines you just composed, or a probe you ran this run); a memory/handover snapshot is **context, never report facts**, and a claim with no live signal is **omitted or explicitly marked unverified** — never asserted from recollection. Full clause: *Live host/session facts* in `${CLAUDE_SKILL_DIR}/references/shared/report-footer.md`.
99
103
  - **Print the report footer** in the canonical order (version block → one-line backend-status line → welcome mat — the shared contracts in `${CLAUDE_SKILL_DIR}/references/shared/report-footer.md`; rendered from the helpers, same host-can't-run skip-with-reason). The welcome mat closes on **one** caveat-aware next step (a behind member first, else `setup` / `recipes` / `velocity` / `agents` / `hook`).
100
104
  - **Then ask before committing — never auto-commit.** If step 3 added the slot (or anything else changed), report it and ask. If step 3 was a pure zero-diff no-op and nothing else changed, give the plain **settings already current — no update needed** message (the *Success state* contract in `${CLAUDE_SKILL_DIR}/references/shared/report-footer.md`) and still print the read-only version block (installed package versions) + backend line — but **no `docs/ai` structure version and no two-axes note** (nothing changed, so the number is inert here).
101
105
  5. Show the relevant `${CLAUDE_SKILL_DIR}/CHANGELOG.md` diff (entries newer than the project's stamp).
102
- 6. **Collect the migration answers FIRST, then apply.** If `AGENTS.md` is missing BOTH the *Communication language* and *Attribution* blocks — i.e. both blocks are missing (a pre-1.1.0 deployment) — ask the two questions as ONE structured multi-question prompt; record each answer individually, write nothing until ALL are answered, and carry the answers into the migrations below: a migration whose answer was already collected never re-asks (its own "Ask the user" step is the standalone fallback); a single missing block keeps its single ask (step 7). Then apply `${CLAUDE_SKILL_DIR}/migrations/<version>-<slug>.md` in **semver order**, only those newer than the project's stamp. Migrations are **idempotent** — safe to re-run.
103
- 7. Reconcile drift: add any kernel files/scripts the project is missing; never clobber project-authored content (their `decisions.md`, `known_issues.md`, page specs stay). Any user question a migration raises follows the same rule as bootstrap — **structured multiple-choice where supported** (`AskUserQuestion` in Claude Code), otherwise prose. If `AGENTS.md` has no *Communication language* block (pre-1.1.0 deployment), **ask the user their conversational language** and insert the block — see `migrations/1.1.0-communication-language.md`. If it has no *Attribution* block (pre-1.2.0 deployment), **ask whether the agent may attribute work to itself / AI** and insert the block (defaulting to `off`) — see `migrations/1.2.0-agent-attribution.md`. (An answer already collected by the step-6 batched prompt is carried in — never re-asked here.) **Then, before the stamp, re-run the LATE navigator finalizer:** the migrations of steps 6–7 may have added or changed `docs/ai` files, so run the one op again — `node ${CLAUDE_SKILL_DIR}/tools/ensure-configs.mjs --reconcile --only index --cwd <project>` — and relay THAT line in the step-8 report (idempotent: an untouched tree reports `already-current`; a failure STOPs this upgrade like any other ensure).
104
- 8. Re-stamp `docs/ai/.workflow-version` to the **deployment-lineage head** (`3.0.0`, not the package version — mechanics unchanged: the atomic write to the stamp file). In the report, **describe what the upgrade changed in plain human terms** — which parts of their `docs/ai` are now different (the migrations that ran), plus the step-3 run-list outcomes, each as step 4 words it: the `pointers` slots, the `footprint` visibility verdict (and what a consented re-run migrated), the **eight project-configuration ensure** (`configs`) lines (enumerated in step 3) — the navigator one being the late `--only index` run at the end of step 7, the **`gates-migration`** result, the **placed-bridge refresh** (`bridges`) lines (pasted verbatim), the **agent-rules lens** (`lens`) + **Communication-section** outcomes (same outcome sets as step 4), and the **bridge-settings reconcile** (`bridge-settings`) outcome (line(s) pasted verbatim) — rather than reciting a version number; **omit the raw structure number**, and do **not** print the two-axes note here (it belongs to *Version disclosure* in `${CLAUDE_SKILL_DIR}/references/shared/report-footer.md`, on demand only). Then **render the mandatory Recommendations section**: run `node ${CLAUDE_SKILL_DIR}/tools/recommendations.mjs --cwd <project-root>` and PRESENT its output — from the `## Recommendations (agent-workflow)` header — in the user's conversational language (every fact, count and item, nothing added or dropped; commands, paths, hosts and rule strings byte-exact; raw tool block on request; present-even-when-empty: `no recommendations — flow optimal.`), then OFFER the consent-gated applies (per picked item: posture note → explicit confirm → run EXACTLY the rendered one-liner; a HAND-APPLY item is never run by you — `${CLAUDE_SKILL_DIR}/references/modes/recommendations.md`). **Every current host/session claim in this report is tool-composed only** — prompts fired, sandbox scope, whether a bypass was needed, network reachability and approval counts must trace to **live tool output** from **this session**, a memory/handover snapshot is **context, never report facts**, and an unbacked claim is **omitted or explicitly marked unverified** (full clause: *Live host/session facts* in `${CLAUDE_SKILL_DIR}/references/shared/report-footer.md`). Then **print the report footer** in the canonical order (version block → one-line backend-status line → welcome mat — the shared contracts in `${CLAUDE_SKILL_DIR}/references/shared/report-footer.md`; rendered from the helpers, same host-can't-run skip-with-reason; the welcome mat closes on one caveat-aware next step). Then **ask before committing** — the pinned order on this exit is: Recommendations block → optional applies → report footer → the commit ask.
106
+ 6. **Collect the migration answers FIRST, then apply.** Run `node ${CLAUDE_SKILL_DIR}/tools/migration-notes.mjs --cwd <project>` and relay its stdout lines verbatim, in order; a non-zero exit relays its one named line and STOPs, except `stamp-absent`, which routes back to step 1. Then run the preview `node ${CLAUDE_SKILL_DIR}/tools/migration-blocks.mjs --cwd <project>`. If its lines say both blocks are missing (pre-1.1.0), ask the two questions as ONE structured multi-question prompt; record each answer individually, write nothing until ALL are answered, and carry the answers into the migrations below: a migration whose answer was already collected never re-asks; a single missing block keeps its single ask (step 7). Then apply exactly the notes the tool listed, in its order ("only those newer than the project's stamp" is why, never a second selection). Migrations are **idempotent** — safe to re-run.
107
+ 7. Reconcile drift: add any kernel files/scripts the project is missing; never clobber project-authored content (their `decisions.md`, `known_issues.md`, page specs stay). Any user question a migration raises follows the same rule as bootstrap — **structured multiple-choice where supported** (`AskUserQuestion` in Claude Code), otherwise prose. For a block the preview names as needing its answer, **ask the user their conversational language** (`--language`) or **whether the agent may attribute work to itself / AI** (`--attribution`, defaulting to `off`), never re-asking a step-6 answer; then re-run the preview with `--apply` and the answers, relaying its lines. Exit 1 `answer-missing`: ask exactly what its lines name and re-run `--apply` once; a second one STOPs. Any other exit 1 is a named refusal: relay it with its recovery (`cap`: trim `AGENTS.md`, re-run) and STOP before the finalizer and the stamp. **Then, before the stamp, re-run the LATE navigator finalizer:** the migrations of steps 6–7 may have changed `docs/ai` files, so run the one op again — `node ${CLAUDE_SKILL_DIR}/tools/ensure-configs.mjs --reconcile --only index --cwd <project>` — and relay THAT line in the step-8 report (idempotent: an untouched tree reports `already-current`; a failure STOPs this upgrade like any other ensure).
108
+ 8. Re-stamp `docs/ai/.workflow-version` to the **deployment-lineage head** (`3.0.0`, not the package version — mechanics unchanged: the atomic write to the stamp file). In the report, **describe what the upgrade changed in plain human terms** — which parts of their `docs/ai` are now different (the migrations that ran), plus the step-3 run-list outcomes, each as step 4 words it: the `pointers` slots, the `footprint` visibility verdict (and what a consented re-run migrated), the **eight project-configuration ensure** (`configs`) lines (enumerated in step 3) — the navigator one being the late `--only index` run at the end of step 7, the **`gates-migration`** result, the **placed-bridge refresh** (`bridges`) lines (pasted verbatim), the **agent-rules lens** (`lens`) + **Communication-section** + **story-sessions section** outcomes (same outcome sets as step 4), and the **bridge-settings reconcile** (`bridge-settings`) outcome (line(s) pasted verbatim) — rather than reciting a version number; **omit the raw structure number**, and do **not** print the two-axes note here (it belongs to *Version disclosure* in `${CLAUDE_SKILL_DIR}/references/shared/report-footer.md`, on demand only). Then **render the mandatory Recommendations section**: run `node ${CLAUDE_SKILL_DIR}/tools/recommendations.mjs --cwd <project-root>` and PRESENT its output — from the `## Recommendations (agent-workflow)` header — in the user's conversational language (every fact, count and item, nothing added or dropped; commands, paths, hosts and rule strings byte-exact; raw tool block on request; present-even-when-empty: `no recommendations — flow optimal.`), then OFFER the consent-gated applies (per picked item: posture note → explicit confirm → run EXACTLY the rendered one-liner; a HAND-APPLY item is never run by you — `${CLAUDE_SKILL_DIR}/references/modes/recommendations.md`). **Every current host/session claim in this report is tool-composed only** — prompts fired, sandbox scope, whether a bypass was needed, network reachability and approval counts must trace to **live tool output** from **this session**, a memory/handover snapshot is **context, never report facts**, and an unbacked claim is **omitted or explicitly marked unverified** (full clause: *Live host/session facts* in `${CLAUDE_SKILL_DIR}/references/shared/report-footer.md`). Then **print the report footer** in the canonical order (version block → one-line backend-status line → welcome mat — the shared contracts in `${CLAUDE_SKILL_DIR}/references/shared/report-footer.md`; rendered from the helpers, same host-can't-run skip-with-reason; the welcome mat closes on one caveat-aware next step). Then **ask before committing** — the pinned order on this exit is: Recommendations block → optional applies → report footer → the commit ask.
@@ -0,0 +1,37 @@
1
+ {
2
+ "schema": 1,
3
+ "name": "full-flow",
4
+ "lineage": "4.0.0",
5
+ "items": [
6
+ { "id": "migration-notes-delivered",
7
+ "story": "S1",
8
+ "has": "An upgrade tells you every migration note your project's version selects, by path and headline." },
9
+ { "id": "migration-blocks-placed",
10
+ "story": "S1",
11
+ "has": "The entry point carries the communication-language and attribution blocks, placed from your answers." },
12
+ { "id": "payload-converged",
13
+ "story": "S1",
14
+ "has": "The installed kit holds no file the package stopped shipping." },
15
+ { "id": "story-sessions-section",
16
+ "story": "S2",
17
+ "has": "The project's rules carry the story-sessions section." },
18
+ { "id": "epic-task-slots",
19
+ "story": "S3",
20
+ "has": "The orchestration settings carry the epic and task slots, each resolved to your environment or to solo with the reason." },
21
+ { "id": "epic-store-seeded",
22
+ "story": "S3",
23
+ "has": "The epic store is seeded." },
24
+ { "id": "checker-gates-declared",
25
+ "story": "S4",
26
+ "has": "The kit-owned checker gates are declared." },
27
+ { "id": "session-close-rules",
28
+ "story": "S5",
29
+ "has": "The rules your project reads state the session-close value section and one task per session." },
30
+ { "id": "named-queue-row-seed",
31
+ "story": "S5",
32
+ "has": "A new work queue is seeded with the named row." },
33
+ { "id": "profile-gap-screen",
34
+ "story": "S6",
35
+ "has": "The Recommendations screen names every difference from this profile you have not declined, with the command for each." }
36
+ ]
37
+ }
@@ -54,11 +54,13 @@ current* (zero-diff). Relay its outcome in plain language (*refreshed* / *alread
54
54
  *custom edit preserved + note* / *file absent — skipped* / *engine too old — skipped* / *over the
55
55
  line cap — refused*); a fully absent/invalid engine is the same loud STOP + one-line install
56
56
  command as the pointer reconcile. The same invocation also reconciles the **Communication
57
- (user-facing messages)** section from the kit's own bundled template canon (no engine involved):
57
+ (user-facing messages)** and **story-sessions** sections from the kit's own bundled template canon (no engine involved):
58
58
  a body matching the current canon is reported *already current*; a body matching a known prior
59
- is refreshed; a custom body is preserved + noted; an absent section is a stated note (never an
60
- insert); an over-cap refresh is refused; and an unreadable bundled template canon is its own
61
- loud STOP naming the kit reinstall command.
59
+ is refreshed; a custom body is preserved + noted; an absent section is a stated note;
60
+ an over-cap refresh is refused; and an unreadable bundled template canon is its own
61
+ loud STOP naming the kit reinstall command. Relay both sections' outcome lines.
62
+ The printed absent-section note already carries the preview command: relaying it is the offer.
63
+ Run the insert with `--apply` only on the user's explicit yes.
62
64
 
63
65
  **Navigator finalizer (runs in BOTH paths, AFTER the lens reconcile above).** `docs/ai/index.md` is
64
66
  a GENERATED artifact the entry point declares always-loaded, and the reconcile above may have just
@@ -92,6 +92,9 @@ Apply these when authoring a plan, reviewing, folding a finding, or editing code
92
92
  - **ExitPlanMode ≠ execute.** A harness "approved — start coding" prompt authorizes the PLAN only; this methodology overrides it. Continue into execution only as a DELIBERATE transition after the plan + cold-start prompt exist, never an implicit slide.
93
93
  - **Cost lanes.** Route every step to the **cheapest adequate executor** — L0 deterministic script (the batched gate matrix over `gates.json`, the rotation `--check`s) · L1 cheap subagent (extraction/drafting only; the orchestrator verifies) · L2 subscription bridge · L3 frontier judgment. A step with **no named guardrail does not move down** a lane, and the **red lines never move down** (council review models · real code · ADR/handover/changelog-entry wording · persuasive copy · go/no-go · the approval asks). Own-error repair: salvage recorded state first (L0/L1, batched), never frontier re-derivation. **Prompt economy:** read-only fan-out (research/sweeps/extraction) runs ONLY on restricted-tool vehicles — a full-tool subagent for read-only work is a forbidden lane downgrade (invisible prompt-flood + blast radius), and a subagent is never told to shell out for facts obtainable read-only; the orchestrator's own shell form is ONE plain pipeline per call (a `;`/`&&` chain or env-prefixed invocation never matches a prefix allow rule); a fan-out launcher that gates per call yields to the agent-spawn lane — capability-gated: without restricted-tool vehicles (generic full-tool spawning does not count), read-only research stays in the orchestrator's own context, never a vehicle mandate a host cannot satisfy. Judgment, code, synthesis stay at the frontier lane (a task that genuinely runs/writes keeps a full-tool subagent); honest limit: no deterministic gate classifies a dispatch — canon at the point of use + placed vehicles + the retro loop. **Writer economy:** a stage's repeated WRITER commands batch — evidence declarations ride consecutive plain invocations of ONE allow-listed tool, other stage writers combine via one launcher per stage; never an unbatched writer scatter (each gated write is its own prompt).
94
94
 
95
+ ### 2.7. Story sessions
96
+ A story — one row of an epic's ledger, carried by one plan — runs as five sessions, each ending at its own review checkpoint: **spec** (the contract under `docs/ai/specs/`, drafted and reviewed on the `plan-authoring` recipe), **plan** (the ledger, same recipe), **tests** (one task per ledger row, red first), **code** (one task per row, to green), and **diff review, release and record** (the review of the staged tree on the `plan-execution` recipe, the release where the story ships one, then the changelog and handover entries and the plan's Phase: Cleanup). Tests and code never share a session, and a spec and its plan never share one either. A storyless plan runs the same five. **Exception — a split:** moving code and its existing cases into modules, with no new logic and no new case, is one session: a short spec (the Module list), the split, the diff review, the release, Cleanup.
97
+
95
98
  ---
96
99
 
97
100
  ## 3. Token & Session Optimization
@@ -89,7 +89,7 @@ export const handoffPlan = (delegate) =>
89
89
  memoryWrites: ['docs/ai/', 'AGENTS.md', 'docs/ai/.memory-version'],
90
90
  // The lens region runs AFTER the substrate deploy (its own precondition: the file exists)
91
91
  // — it converges a stale-memory seed to the installed engine's canon (AD-041).
92
- kitWrites: ['AGENTS.md pointer slots (methodology / orchestration / autonomy)', 'docs/ai/agent_rules.md lens + Communication regions', 'docs/ai/.workflow-version'],
92
+ kitWrites: ['AGENTS.md pointer slots (methodology / orchestration / autonomy)', 'docs/ai/agent_rules.md Communication, story-sessions and lens regions', 'docs/ai/.workflow-version'],
93
93
  stampsPresent: ['.memory-version', '.workflow-version'],
94
94
  memoryRaisesCommitGate: false,
95
95
  commitGate: 'kit-only-after-injection',
@@ -101,7 +101,7 @@ export const handoffPlan = (delegate) =>
101
101
  // the kit reconciles them (ensure-slot + inject-because-empty) exactly like the delegate
102
102
  // path — so both paths end with FILLED slots, not inline methodology. The lens region
103
103
  // runs after the fallback-template copy of docs/ai (same reconcile, both paths — AD-041).
104
- kitWrites: ['docs/ai/', 'AGENTS.md', 'AGENTS.md pointer slots (methodology / orchestration / autonomy)', 'docs/ai/agent_rules.md lens + Communication regions', 'docs/ai/.workflow-version'],
104
+ kitWrites: ['docs/ai/', 'AGENTS.md', 'AGENTS.md pointer slots (methodology / orchestration / autonomy)', 'docs/ai/agent_rules.md Communication, story-sessions and lens regions', 'docs/ai/.workflow-version'],
105
105
  stampsPresent: ['.workflow-version'],
106
106
  memoryRaisesCommitGate: false,
107
107
  commitGate: 'kit-only-after-injection',