@sabaiway/agent-workflow-memory 7.1.2 → 7.2.1

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,38 @@ All notable changes to the memory substrate. Versions are this **package's** npm
4
4
  they are distinct from the **deployment-lineage** stamp written into a project's
5
5
  `docs/ai/.memory-version` (which tracks the shared `agent-workflow` lineage, head `3.0.0`).
6
6
 
7
+ ## 7.2.1 — the orchestration seed's note names four activities (AD-132)
8
+
9
+ `references/templates/orchestration.json`: the `_README` is the kit's new canonical byte for byte —
10
+ four activities (`feedback-triage` with its one `review` slot), the seeded slots `solo`, a silent slot
11
+ its computed default (`feedback-triage.review` reviewed as soon as a review backend is ready, solo
12
+ until then). The seed's slot shape is unchanged (plan-authoring · plan-execution, every value `solo`),
13
+ so an older kit still accepts it; a deployed file carrying the outgoing note refreshes on the next
14
+ write. No script changed.
15
+
16
+ ## 7.2.0 — the standalone bootstrap offers enforcement on every project (AD-131)
17
+
18
+ `SKILL.md` steps 8–9 no longer decide by the stack recon ("Node projects" / "No Node runtime → skip
19
+ this + the hook"): the enforcement scripts + pre-commit hook are OFFERED on every project,
20
+ preview-first, with a one-line why — the dependency-free Node scripts are available because the
21
+ agent host already runs the skill-home navigator; the only skip condition is that the agent host
22
+ cannot run them; the residual is stated (a committer without `node` on PATH gets the hook's own loud
23
+ failure). On a yes the scripts are copied and the hook installed; on a no the docs command slots of
24
+ `env_commands.md` and `AGENTS.md` carry a note (the caps + index gate run from the agent's own skill
25
+ copy, the archive rotations need the scripts deployed) and never the skill's absolute path. The
26
+ Gotchas bullet points at step 8; the "non-Node stacks follow the policy manually" claim is gone.
27
+
28
+ **A declined offer leaves no false claim.** `references/contracts.md`'s visible bullet wires the
29
+ `package.json` scripts only when one exists and the enforcement offer was accepted (the
30
+ `.gitignore` either way); the seeded `templates/changelog.md`, `decisions.md` and `agent_rules.md`
31
+ say `installed on a yes` / `where installed` instead of asserting an install; the README's use line
32
+ says the same. The seed `adr/log.md` stays the generator's byte-exact output.
33
+
34
+ **Two characterization pins, no script change.** `references/scripts/install-git-hooks.test.mjs`
35
+ pins the hook marker's directory-basename fallback beside no or a malformed `package.json` (a named
36
+ `package.json` wins); `archiver-structure.test.mjs` pins the same fallback in the archivers' headings
37
+ through the copied four-file import closure. Mirrored byte-identically into the kit.
38
+
7
39
  ## 7.1.2 — the seed orchestration note names the fold slot (AD-125)
8
40
 
9
41
  `references/templates/orchestration.json`: the `_README` note lists `plan-authoring`'s third slot,
package/README.md CHANGED
@@ -32,7 +32,7 @@ Open your agent inside a project and run the skill:
32
32
 
33
33
  - **`/agent-workflow-memory`** — bootstrap a new or empty project. Asks the three setup
34
34
  questions (visibility, conversational language, agent attribution), then writes `docs/ai/`,
35
- `AGENTS.md`, the enforcement scripts + pre-commit hook, and stamps
35
+ `AGENTS.md`, offers the enforcement scripts + pre-commit hook (installed on a yes), and stamps
36
36
  `docs/ai/.memory-version`. The three pointer slots in `AGENTS.md` (the **methodology**,
37
37
  **orchestration** and **autonomy** pointers, filled later by the family composition root) are
38
38
  left **empty**.
package/SKILL.md CHANGED
@@ -3,7 +3,7 @@ name: agent-workflow-memory
3
3
  description: Deploy or upgrade a portable AI-agent memory substrate in any project — an entry-point `AGENTS.md` (+ `CLAUDE.md` alias) and a structured `docs/ai/` context store with cap/archive/index enforcement. Use when the user wants to bootstrap `docs/ai/`, set up the Memory Map and session protocols, install the docs-rotation pre-commit hook, or run `/agent-workflow-memory` / `/agent-workflow-memory upgrade`. Triggers on "set up the memory system", "deploy the AI memory here", "bootstrap docs/ai", "upgrade the memory substrate". This is the substrate only — the workflow methodology (plan→execute→review, queue, Cleanup) is owned elsewhere and injected into AGENTS.md by the family composition root.
4
4
  disable-model-invocation: true
5
5
  metadata:
6
- version: '7.1.2'
6
+ version: '7.2.1'
7
7
  ---
8
8
 
9
9
  # agent-workflow-memory
@@ -14,9 +14,9 @@ reconstruct project context in ~60 seconds, find the current task, and avoid rep
14
14
  mistakes.
15
15
 
16
16
  The substrate is **stack-agnostic memory** — `docs/ai/` structure, entry-point doc, session
17
- protocols, frontmatter caps, one-file-per-ADR archive, index-freshness gate. Enforcement ships as **Node
18
- `.mjs` scripts** (the reference implementation; non-Node stacks follow the same policy
19
- manually).
17
+ protocols, frontmatter caps, one-file-per-ADR archive, index-freshness gate. Enforcement ships as
18
+ dependency-free **Node `.mjs` scripts** with a pre-commit hook, offered on every project because
19
+ the agent host runs them.
20
20
 
21
21
  This skill is the **memory layer** of the `agent-workflow` family. It **knows nobody else** in
22
22
  the family. In particular it does **not** own the **workflow methodology** (the plan shape,
@@ -124,11 +124,22 @@ bootstrapping over a live system, but the user makes the final call.
124
124
  before reporting the deploy, since the navigator the entry point declares does not exist yet). The
125
125
  generator runs from the **skill home**, so a **No-Node target** is covered too: the operator's own
126
126
  host runs it, and step 8's copy is not a precondition.
127
- 8. **Install enforcement (Node projects).** Copy `${CLAUDE_SKILL_DIR}/references/scripts/*.mjs`
128
- (+ `*.test.mjs`) into the project's `scripts/`. **No Node runtime** → skip this + the hook;
129
- follow the cap/archive/index policy manually.
130
- 9. **Wire / hide** per visibility (see contract). Install the pre-commit hook (Node projects):
131
- `node scripts/install-git-hooks.mjs`. If it reports a pre-existing non-marker hook, stop and
127
+ 8. **Offer enforcement on every project, preview-first.** Explain in one line that the
128
+ dependency-free Node scripts are available because the agent host already runs the skill-home
129
+ navigator; the only skip condition is that the agent host cannot run them. Preview the source
130
+ and destination list and ask; on a yes copy
131
+ `${CLAUDE_SKILL_DIR}/references/scripts/*.mjs` (+ `*.test.mjs`) into the project's `scripts/`.
132
+ On a no, skip the hook in step 9 and say so; the docs command slots then name no project-local
133
+ command — fill `env_commands.md` and the `Docs caps + index freshness` row of `AGENTS.md` with
134
+ the same note: the caps + index gate run from the agent's own skill copy (the step-7
135
+ `--root=<target>` form) and the archive rotations need the scripts deployed. Never write the
136
+ skill's absolute path into a deployed doc. They self-configure
137
+ (project name from `package.json` or, without one, the directory basename). The hook calls
138
+ `node scripts/<x>.mjs` directly, so a committer without `node` on PATH gets the hook's own loud
139
+ failure.
140
+ 9. **Wire / hide** per visibility (see contract). When the user accepts the enforcement offer,
141
+ install the pre-commit hook: `node scripts/install-git-hooks.mjs`. If it reports a pre-existing
142
+ non-marker hook, stop and
132
143
  ask the user to merge it manually. **Hidden** → add memory's own artifact paths (the canonical
133
144
  anchored list in the [Visibility contract](references/contracts.md#visibility-contract)) to the
134
145
  **project-local** `.git/info/exclude` (resolve via `git rev-parse --git-path info/exclude`),
@@ -162,7 +173,7 @@ Fill strategy:
162
173
  | `tech_reference.md` | Carry over real configs/patterns found in deps. |
163
174
  | `active_plan.md`, `handover.md` | TODO seed. |
164
175
  | `decisions.md` | The HOT ADR window — seed `AD-001` (adopting this memory system), newest at the bottom. |
165
- | `adr/log.md` | The seed navigator — deployed as-is (the generator over the seeded HOT); regenerated by `archive-decisions.mjs`, never hand-edited. |
176
+ | `adr/log.md` | The seed navigator — deployed as-is (the generator over the seeded HOT); regenerated by `archive-decisions.mjs` where the enforcement scripts are deployed (installed on a yes), otherwise it stays the seed — never hand-edited either way. |
166
177
  | `known_issues.md`, `changelog.md`, `pages/shared-patterns.md` | Empty template / first bootstrap entry. |
167
178
 
168
179
  ### Mode: upgrade
@@ -333,7 +344,8 @@ memory substrate has none, so it relies on the STOP + the explicit ask — never
333
344
  artifacts as ignored.
334
345
  - **`CLAUDE.md` is a symlink, not a copy.** `ln -s AGENTS.md CLAUDE.md`.
335
346
  - **Never overwrite an existing entry point or hook.** Stop and ask to merge vs replace.
336
- - **No Node runtime → skip enforcement** (scripts + hook); follow the policy manually.
347
+ - **Enforcement is offered on every project.** See step 8 for the preview, the agent-host
348
+ criterion, and the committer-node residual.
337
349
  - **Never auto-commit.** Report quality-gate results and wait for explicit approval — both modes.
338
350
 
339
351
  ---
package/capability.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "schema": 1,
4
4
  "name": "agent-workflow-memory",
5
5
  "kind": "memory-substrate",
6
- "version": "7.1.2",
6
+ "version": "7.2.1",
7
7
  "provides": ["context"],
8
8
  "roles": {},
9
9
  "detect": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sabaiway/agent-workflow-memory",
3
- "version": "7.1.2",
3
+ "version": "7.2.1",
4
4
  "description": "Portable, cross-agent memory substrate for AI coding agents — an AGENTS.md entry point + docs/ai context with cap/archive/index enforcement, deployable standalone or as part of the agent-workflow family. The memory layer of the agent-workflow family.",
5
5
  "keywords": [
6
6
  "ai-agents",
@@ -17,7 +17,7 @@ The user chooses at bootstrap whether the AI artifacts are visible in the repo o
17
17
  **explicit up-front question** (bootstrap step 2), never an assumed default. The two modes then
18
18
  diverge:
19
19
 
20
- - **visible** — artifacts are committed. Wire the project's `package.json` scripts (`docs:check` / `docs:index` / `docs:index:check` / `docs:archive` / `docs:archive:check` / `docs:archive:issues` / `docs:archive:issues:check` / `prepare: node scripts/install-git-hooks.mjs`) and add a minimal `.gitignore` (`docs/plans/`, `.claude/settings.local.json`). This is the canonical model.
20
+ - **visible** — artifacts are committed. When a `package.json` exists and the enforcement offer was accepted, wire the project's `package.json` scripts (`docs:check` / `docs:index` / `docs:index:check` / `docs:archive` / `docs:archive:check` / `docs:archive:issues` / `docs:archive:issues:check` / `prepare: node scripts/install-git-hooks.mjs`); add a minimal `.gitignore` (`docs/plans/`, `.claude/settings.local.json`) either way. This is the canonical model.
21
21
  - **hidden** (in-tree) — same files on disk, but the repo "looks normal": add memory's OWN artifact paths to **one project-local ignore list, the repo's `.git/info/exclude`** — resolve it with `git rev-parse --git-path info/exclude` (worktree-safe) and **never** the machine-global `core.excludesFile`, which would silently affect every repo on the host (visibility is a *project* setting). Write each path **once**, in the **canonical anchored form** — `/AGENTS.md`, `/CLAUDE.md`, `/docs/ai/` (this subsumes `docs/ai/.memory-version` and any kit-fallback `docs/ai/.workflow-version` — do **not** list the stamps separately), the `/scripts/*.mjs` you added, `/docs/plans/`, `/.claude/settings.local.json`, and `/.claude/settings.json` (step-4 attribution can create it; a standalone hidden memory hides it too). Append only — never duplicate a line that is already present. **Verify `git status` shows the artifacts as ignored** afterwards. **Do not edit `package.json`** — that is a tracked change and would leak; the pre-commit hook (always untracked in `.git/hooks/`) calls the scripts via `node scripts/<x>.mjs` directly. *(In a family deploy the composition root then runs its hide tool, which absorbs these project-local lines into one canonical managed block and adds the external AI/agent footprint; memory writes no machine-global excludes at any step.)*
22
22
 
23
23
  **Visibility changes only what git sees, never how the agent works.** Both modes carry the same working memory and run the same session protocol — `docs/ai` is read at session start and maintained on task completion **identically** in hidden mode; "git-ignored / `git status` clean" is **not** "optional to update", the updates just live on disk and never enter a commit (the durable wording lives in `agent_rules.md` §1.3).
@@ -1,8 +1,9 @@
1
1
  import { describe, it } from 'node:test';
2
2
  import assert from 'node:assert/strict';
3
- import { readFileSync } from 'node:fs';
4
- import { dirname, resolve } from 'node:path';
5
- import { fileURLToPath } from 'node:url';
3
+ import { cpSync, mkdirSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from 'node:fs';
4
+ import { tmpdir } from 'node:os';
5
+ import { basename, dirname, join, resolve } from 'node:path';
6
+ import { fileURLToPath, pathToFileURL } from 'node:url';
6
7
 
7
8
  // Structural pin (green by construction, a tripwire not a proof): all three archivers read
8
9
  // documents through the ONE shared tokenizer. A fourth archiver — or a future edit that reaches
@@ -12,6 +13,50 @@ import { fileURLToPath } from 'node:url';
12
13
 
13
14
  const DIR = dirname(fileURLToPath(import.meta.url));
14
15
  const ARCHIVERS = ['archive-changelog.mjs', 'archive-issues.mjs', 'archive-decisions.mjs'];
16
+ const ARCHIVER_CLOSURE = ['archive-changelog.mjs', 'archive-issues.mjs', 'archive-caps.mjs', 'markdown-blocks.mjs'];
17
+ const FIXED_DATE = '2026-09-02';
18
+ const MALFORMED_PACKAGE_JSON = '{ not json';
19
+ const NAMED_PACKAGE_JSON = '{"name":"named-fixture"}';
20
+ const NAMED_FIXTURE = 'named-fixture';
21
+
22
+ const buildArchiveHeadings = async (packageJson) => {
23
+ const root = mkdtempSync(join(tmpdir(), 'archiver-name-'));
24
+ const scripts = join(root, 'scripts');
25
+ mkdirSync(scripts);
26
+ for (const name of ARCHIVER_CLOSURE) cpSync(join(DIR, name), join(scripts, name));
27
+ if (packageJson !== null) writeFileSync(join(root, 'package.json'), packageJson);
28
+ const changelog = await import(pathToFileURL(join(scripts, 'archive-changelog.mjs')).href);
29
+ const issues = await import(pathToFileURL(join(scripts, 'archive-issues.mjs')).href);
30
+ const result = {
31
+ fallback: basename(root),
32
+ changelog: changelog.buildRecent([], FIXED_DATE),
33
+ issues: issues.buildResolvedFile(null, [], FIXED_DATE),
34
+ };
35
+ rmSync(root, { recursive: true, force: true });
36
+ return result;
37
+ };
38
+
39
+ const assertArchiveHeadings = (result, projectName) => {
40
+ assert.ok(result.changelog.includes(`# Changelog WARM Archive \u2014 ${projectName}`));
41
+ assert.ok(result.issues.includes(`# Resolved Issues \u2014 ${projectName}`));
42
+ };
43
+
44
+ describe('the archivers head their archives with the directory basename when no package.json, or a malformed one, names the project', () => {
45
+ it('no package.json names the directory basename', async () => {
46
+ const result = await buildArchiveHeadings(null);
47
+ assertArchiveHeadings(result, result.fallback);
48
+ });
49
+
50
+ it('a malformed package.json names the directory basename', async () => {
51
+ const result = await buildArchiveHeadings(MALFORMED_PACKAGE_JSON);
52
+ assertArchiveHeadings(result, result.fallback);
53
+ });
54
+
55
+ it('a named package.json wins', async () => {
56
+ const result = await buildArchiveHeadings(NAMED_PACKAGE_JSON);
57
+ assertArchiveHeadings(result, NAMED_FIXTURE);
58
+ });
59
+ });
15
60
 
16
61
  describe('every archiver reads through the tokenizer — no raw scan survives', () => {
17
62
  for (const name of ARCHIVERS) {
@@ -8,12 +8,15 @@ import { describe, it } from 'node:test';
8
8
  import assert from 'node:assert/strict';
9
9
  import { mkdtempSync, mkdirSync, writeFileSync, readFileSync, rmSync, cpSync, existsSync } from 'node:fs';
10
10
  import { tmpdir } from 'node:os';
11
- import { join, dirname, resolve } from 'node:path';
11
+ import { basename, join, dirname, resolve } from 'node:path';
12
12
  import { fileURLToPath } from 'node:url';
13
13
  import { spawnSync } from 'node:child_process';
14
14
 
15
15
  const HERE = dirname(fileURLToPath(import.meta.url));
16
16
  const INSTALLER_SRC = join(HERE, 'install-git-hooks.mjs');
17
+ const MALFORMED_PACKAGE_JSON = '{ not json';
18
+ const NAMED_PACKAGE_JSON = '{"name":"named-fixture"}';
19
+ const NAMED_FIXTURE = 'named-fixture';
17
20
 
18
21
  // The installer anchors ROOT at <its dir>/.. — deploy it into a fixture's scripts/ like a consumer.
19
22
  const mkProject = () => {
@@ -39,6 +42,33 @@ const hooksPathOf = (root) => {
39
42
  return resolve(root, r.stdout.trim());
40
43
  };
41
44
 
45
+ const markerFor = (name) => `# ${name}:install-git-hooks.mjs`;
46
+ const readHook = (root) => readFileSync(join(hooksPathOf(root), 'pre-commit'), 'utf8');
47
+
48
+ describe('install-git-hooks \u2014 beside no package.json, or a malformed one, the marker names the directory basename', () => {
49
+ it('no package.json, then a MALFORMED one \u2014 the marker names the directory basename', () => {
50
+ const { root } = mkProject();
51
+ const expected = markerFor(basename(root));
52
+ const absent = runInstaller(root);
53
+ assert.equal(absent.status, 0, absent.stderr);
54
+ assert.ok(readHook(root).split('\n').includes(expected));
55
+ writeFileSync(join(root, 'package.json'), MALFORMED_PACKAGE_JSON);
56
+ const malformed = runInstaller(root);
57
+ assert.equal(malformed.status, 0, malformed.stderr);
58
+ assert.ok(readHook(root).split('\n').includes(expected));
59
+ rmSync(root, { recursive: true, force: true });
60
+ });
61
+
62
+ it('a named package.json wins \u2014 the marker carries its name', () => {
63
+ const { root } = mkProject();
64
+ writeFileSync(join(root, 'package.json'), NAMED_PACKAGE_JSON);
65
+ const result = runInstaller(root);
66
+ assert.equal(result.status, 0, result.stderr);
67
+ assert.ok(readHook(root).split('\n').includes(markerFor(NAMED_FIXTURE)));
68
+ rmSync(root, { recursive: true, force: true });
69
+ });
70
+ });
71
+
42
72
  describe('install-git-hooks — the hooks path comes from git plumbing (C7)', () => {
43
73
  it('a normal repo installs at the git-path hooks location', () => {
44
74
  const { root } = mkProject();
@@ -39,7 +39,7 @@ Read in order, then confirm before starting:
39
39
  Before claiming "done":
40
40
  1. Run all quality gates (lint + type-check + tests) — all green.
41
41
  2. Update docs: `current_state.md` (feature ready), `changelog.md` (entry), `handover.md` (**REPLACE** the last-session block — session delta, never append; older deltas live in `changelog.md` → `history/`), `pages/<page>.md` (matches implementation), the governing spec (its revision lands with the code: `draft` -> `live` on the landing row). Only bump "Last Updated" when content actually changed.
42
- 3. Run the docs cap-validator + index-freshness gate (pre-commit also enforces). On failure: trim the offending file, or run the changelog rotation if the offender is `changelog.md`.
42
+ 3. Run the docs cap-validator + index-freshness gate (the pre-commit hook also enforces it where installed). On failure: trim the offending file, or run the changelog rotation if the offender is `changelog.md`.
43
43
  4. If the work executed a plan file — complete it per the project's **planning skill / methodology** (the `workflow:methodology` slot in `AGENTS.md` points to it; see §5). Without completing that step the plan is not done. (The methodology, including any mandatory final cleanup, is defined there — not in this substrate.)
44
44
  5. **Ask before committing** (§4): report lint / type-check / test counts + docs status, then wait for explicit approval. DO NOT auto-commit.
45
45
 
@@ -20,7 +20,7 @@ maxLines: 700
20
20
  **Changes:**
21
21
  - Created `AGENTS.md` (entry point) + `CLAUDE.md` symlink.
22
22
  - Created `docs/ai/` with the spec files + `pages/`.
23
- - Installed the docs cap-validator / index-freshness / archive scripts + pre-commit hook.
23
+ - Offered the docs cap-validator / index-freshness / archive scripts + pre-commit hook (installed on a yes).
24
24
  - Recorded the real stack, scripts, and architecture into the relevant files.
25
25
 
26
26
  **Quality gates:** n/a (no code changes).
@@ -13,7 +13,7 @@ maxLines: 500
13
13
  > consequences, newest at the bottom. Link related ADRs with `[[AD-XXX]]`; retrieval is by the
14
14
  > `AD-NNN` id (filename), grep over the flat store, or the `[[AD-NNN]]` supersession chain.
15
15
 
16
- > **Archive:** older ADRs are stored one immutable file per record under [`adr/`](./adr/) — see the active-set navigator [`adr/log.md`](./adr/log.md). `archive-decisions.mjs` explodes the oldest entries beyond this window automatically; no cap is ever raised and there is no monolithic ledger.
16
+ > **Archive:** older ADRs are stored one immutable file per record under [`adr/`](./adr/) — see the active-set navigator [`adr/log.md`](./adr/log.md). `archive-decisions.mjs` explodes the oldest entries beyond this window automatically where the enforcement scripts are deployed (installed on a yes); no cap is ever raised and there is no monolithic ledger.
17
17
 
18
18
  ## AD-001 — Adopt AI-agent memory system (`docs/ai/`)
19
19
 
@@ -22,7 +22,7 @@ maxLines: 500
22
22
 
23
23
  **Context.** Multi-session AI work loses context between runs. Without a structured handover, each new session re-reads code, re-discovers decisions, and repeats past mistakes.
24
24
 
25
- **Decision.** Adopt a Memory Map in `AGENTS.md` (entry point — the cross-agent standard; tool aliases like `CLAUDE.md` symlink to it) + structured files under `docs/ai/`. Define three protocols (Start / During / Complete). Enforce frontmatter caps + index freshness + a one-file-per-ADR archive via a pre-commit hook. Deployed via the `agent-workflow-memory` substrate (standalone, or as part of the agent-workflow family).
25
+ **Decision.** Adopt a Memory Map in `AGENTS.md` (entry point — the cross-agent standard; tool aliases like `CLAUDE.md` symlink to it) + structured files under `docs/ai/`. Define three protocols (Start / During / Complete). Enforce frontmatter caps + index freshness + a one-file-per-ADR archive via the deployed scripts + pre-commit hook (offered on every project, installed on a yes). Deployed via the `agent-workflow-memory` substrate (standalone, or as part of the agent-workflow family).
26
26
 
27
27
  **Rationale.** Single entry + structured spec files = constant boot-up cost regardless of project size. ADRs prevent litigating the same decision twice. `pages/<page>.md` keeps behaviour canonical (docs > assumptions). Caps + one-file-per-ADR archival keep every record scannable as the decision history grows without bound.
28
28
 
@@ -1,5 +1,5 @@
1
1
  {
2
- "_README": "Per-project orchestration config: the recipe used at each step (slot) of each named activity. Easiest: tell the agent in plain language and run the `set-recipe` writer — it interprets your intent, previews the change, and writes valid JSON for you. You can still hand-edit this file directly whenever you prefer; that option never goes away. Three activities are configured independently, and so is each slot within them: 'plan-authoring' (slots author, fold, review), 'plan-execution' (slots execute, review) and 'routine' (slots carrier, parallel). A slot's value is a recipe: a 'review' slot accepts solo | reviewed | council (you self-review / one backend reviews / both review and you synthesize), or an explicit roster array such as [\"codex-review\", \"agy-review\", \"review-lens\"] in hand-edit form; an 'execute' slot accepts solo | delegated | subagent (you implement / a backend runs a bounded sub-task / a full-tool frontier subagent carries a bounded slice you verify); the carrier slots 'plan-authoring.author', 'plan-authoring.fold' and 'routine.carrier' accept solo | subagent. 'routine.parallel' is a flag rather than a recipe: it accepts on | off and decides whether file-disjoint subagent slices dispatch concurrently. The default below is 'solo' for every recipe and carrier slot, and 'on' for the parallel switch — no execution backend required. Raise a slot to reviewed or council for a second opinion, or to delegated to hand off execution; those need an execution backend set up first. 'subagent' needs the executor vehicle placed in this project — the composition root's `agents` writer places it; without it the slot resolves to solo with the reason stated. Remove a slot's line, or a whole activity block (or run `set-recipe --unset <activity>.<slot>`), to fall back to the computed default: reviewed when a review backend is ready and otherwise solo for a review slot, solo for author, fold, execute and carrier, on for parallel. Run the read-only procedures advisor to see an activity's steps plus the recipe resolved for your environment. Strict JSON — no comments.",
2
+ "_README": "Per-project orchestration config: the recipe used at each step (slot) of each named activity. Easiest: tell the agent in plain language and run the `set-recipe` writer — it interprets your intent, previews the change, and writes valid JSON for you. You can still hand-edit this file directly whenever you prefer; that option never goes away. Four activities are configured independently, and so is each slot within them: 'plan-authoring' (slots author, fold, review), 'plan-execution' (slots execute, review), 'routine' (slots carrier, parallel) and 'feedback-triage' (slot review). A slot's value is a recipe: a 'review' slot accepts solo | reviewed | council (you self-review / one backend reviews / both review and you synthesize), or an explicit roster array such as [\"codex-review\", \"agy-review\", \"review-lens\"] in hand-edit form; an 'execute' slot accepts solo | delegated | subagent (you implement / a backend runs a bounded sub-task / a full-tool frontier subagent carries a bounded slice you verify); the carrier slots 'plan-authoring.author', 'plan-authoring.fold' and 'routine.carrier' accept solo | subagent. 'routine.parallel' is a flag rather than a recipe: it accepts on | off and decides whether file-disjoint subagent slices dispatch concurrently. Every slot seeded below is 'solo' — no execution backend required. A slot the seed leaves silent takes the computed default stated further down: 'feedback-triage.review' is reviewed as soon as a review backend is ready (solo until then); 'plan-authoring.author', 'plan-authoring.fold' and 'routine.carrier' stay 'solo', and 'routine.parallel' stays 'on'. Raise a slot to reviewed or council for a second opinion, or to delegated to hand off execution; those need an execution backend set up first. 'subagent' needs the executor vehicle placed in this project — the composition root's `agents` writer places it; without it the slot resolves to solo with the reason stated. Remove a slot's line, or a whole activity block (or run `set-recipe --unset <activity>.<slot>`), to fall back to the computed default: reviewed when a review backend is ready and otherwise solo for a review slot, solo for author, fold, execute and carrier, on for parallel. Run the read-only procedures advisor to see an activity's steps plus the recipe resolved for your environment. Strict JSON — no comments.",
3
3
  "plan-authoring": {
4
4
  "review": "solo"
5
5
  },