@sabaiway/agent-workflow-kit 14.20.0 → 14.22.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 +87 -0
- package/README.md +2 -2
- package/SKILL.md +1 -1
- package/bridges/antigravity-cli-bridge/SKILL.md +38 -50
- package/bridges/antigravity-cli-bridge/bin/agy-model-posture.test.mjs +257 -0
- package/bridges/antigravity-cli-bridge/bin/agy-review-harness.test.mjs +10 -3
- package/bridges/antigravity-cli-bridge/bin/agy-review-honesty.test.mjs +20 -21
- package/bridges/antigravity-cli-bridge/bin/agy-review-model-screen.test.mjs +4 -4
- package/bridges/antigravity-cli-bridge/bin/agy-review.sh +120 -48
- package/bridges/antigravity-cli-bridge/bin/agy-review.test.mjs +22 -62
- package/bridges/antigravity-cli-bridge/bin/agy.sh +109 -16
- package/bridges/antigravity-cli-bridge/bin/agy.test.mjs +5 -5
- package/bridges/antigravity-cli-bridge/capability.json +14 -7
- package/bridges/antigravity-cli-bridge/references/driving-agy.md +16 -20
- package/bridges/antigravity-cli-bridge/references/models-and-flags.md +10 -27
- package/bridges/codex-cli-bridge/SKILL.md +51 -49
- package/bridges/codex-cli-bridge/bin/codex-exec.sh +145 -46
- package/bridges/codex-cli-bridge/bin/codex-exec.test.mjs +28 -55
- package/bridges/codex-cli-bridge/bin/codex-model-posture.test.mjs +371 -0
- package/bridges/codex-cli-bridge/bin/codex-review.sh +134 -36
- package/bridges/codex-cli-bridge/bin/codex-review.test.mjs +33 -45
- package/bridges/codex-cli-bridge/capability.json +22 -8
- package/bridges/codex-cli-bridge/references/driving-codex.md +18 -15
- package/bridges/codex-cli-bridge/references/sandbox-and-flags.md +16 -12
- package/bridges/codex-cli-bridge/setup/README.md +3 -3
- package/capability.json +1 -1
- package/package.json +1 -1
- package/references/authoring/TASK_TEMPLATE.md +11 -16
- package/references/modes/agents.md +2 -2
- package/references/modes/bridge-settings.md +10 -7
- package/references/modes/procedures.md +7 -7
- package/references/modes/recipes.md +2 -2
- package/references/modes/review-state.md +1 -1
- package/references/modes/set-recipe.md +1 -1
- package/references/modes/tier.md +1 -1
- package/references/modes/velocity.md +1 -1
- package/references/reference-profile.json +1 -1
- package/references/templates/SPEC_TEMPLATE.md +2 -1
- package/references/templates/agent_rules.md +7 -7
- package/tools/bridge-catalog.mjs +114 -0
- package/tools/bridge-posture.mjs +11 -2
- package/tools/bridge-settings-read.mjs +41 -5
- package/tools/bridge-settings.mjs +111 -23
- package/tools/carriers.mjs +6 -4
- package/tools/cheap-agents.mjs +1 -1
- package/tools/detect-backends.mjs +6 -6
- package/tools/family-registry.mjs +3 -3
- package/tools/held-session.mjs +1 -33
- package/tools/manifest/schema.md +1 -1
- package/tools/manifest/validate.mjs +3 -2
- package/tools/procedures.mjs +86 -116
- package/tools/recipes.mjs +2 -2
- package/tools/review-state.mjs +1 -1
- package/tools/rules-regions.mjs +2 -1
- package/tools/tier-guide-facts.mjs +145 -159
- package/tools/tier-guide.mjs +8 -14
|
@@ -18,26 +18,29 @@ judgment.
|
|
|
18
18
|
4. Let codex run; then **review its diff yourself** and re-run the project's gates.
|
|
19
19
|
5. **Commit yourself** — codex never commits (a git-write shim enforces it; see below).
|
|
20
20
|
|
|
21
|
-
##
|
|
22
|
-
|
|
23
|
-
Delegated codex work
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
(
|
|
21
|
+
## Model & effort: the host posture
|
|
22
|
+
|
|
23
|
+
Delegated codex work runs on the host posture: `CODEX_MODEL` / `CODEX_EFFORT` from the bridge settings
|
|
24
|
+
file, else the built-in default `gpt-6.1-sol` / `high`, checked against the installed CLI's catalog
|
|
25
|
+
before any spend. `/agent-workflow-kit bridge-settings` shows the models the installed codex offers and
|
|
26
|
+
sets the host posture. An environment value off the host posture is a one-off and is **refused** (exit 2)
|
|
27
|
+
with the settings-file remedy unless `CODEX_PROBE=1` — do not "tune down" the model or effort per call;
|
|
28
|
+
a weaker model is the user's choice in the setting. Whether the default is the strongest selectable
|
|
29
|
+
model is a hand-checked claim with no automated gate and no recorded date — see SKILL.md. Quota is
|
|
30
|
+
metered in **messages** (rolling 5h + weekly), so economy comes from removing waste (clean capture, the
|
|
31
|
+
precomputed review diff, resume), never from a per-call downgrade. A probe (`CODEX_PROBE=1`, loud) is
|
|
32
|
+
the one route to a one-off — never use its output as real work; its review receipt never attests.
|
|
31
33
|
|
|
32
34
|
## Posture banners — quote them verbatim
|
|
33
35
|
|
|
34
36
|
Every dispatch states its ACTUAL posture on ONE stderr line: `codex-exec` emits
|
|
35
|
-
`exec posture: model=… effort=… tier=… sandbox=workspace-write session=fresh|resume:<id> timeout=…`
|
|
37
|
+
`exec posture: model=… effort=… tier=… sandbox=workspace-write session=fresh|resume:<id> source=… timeout=…`
|
|
36
38
|
(fresh and resume alike, only after the resume id is resolved and validated), `codex-review` emits
|
|
37
|
-
`review posture: model=… effort=… tier=… timeout=…`. When you label a dispatch for a user or a
|
|
39
|
+
`review posture: model=… effort=… tier=… source=… timeout=…`. When you label a dispatch for a user or a
|
|
38
40
|
record, **quote the posture banner verbatim** — the banner is the machine-stated posture; a prose
|
|
39
|
-
re-type drifts. The `
|
|
40
|
-
`
|
|
41
|
+
re-type drifts. The `source=` field (`model:<s>,effort:<s>`, each `default`, `setting` or
|
|
42
|
+
`environment`) and the `timeout=` field are **banner-only** (`timeout=` is exactly the duration handed
|
|
43
|
+
to `timeout(1)`; on exec `uncapped` when no capping binary is on PATH, while `codex-review` fails
|
|
41
44
|
CLOSED pre-spend there) — informational, never part of a receipt or the banner↔receipt parity.
|
|
42
45
|
|
|
43
46
|
## Exec vs review
|
|
@@ -92,7 +95,7 @@ codex-exec --resume <session-id> <file|-> # explicit session id
|
|
|
92
95
|
|
|
93
96
|
Resume continues the SAME codex session, so you avoid re-sending the original context. It runs through
|
|
94
97
|
the wrapper, which **re-establishes every invariant** (subscription-only `*_API_KEY` scrub,
|
|
95
|
-
`--ignore-user-config`, the
|
|
98
|
+
`--ignore-user-config`, the host posture's model/effort) and **restates the full posture via `-c`** —
|
|
96
99
|
because `codex exec resume` resets the sandbox/approval/network posture and rejects `-s`/`--add-dir`/`-C`,
|
|
97
100
|
the wrapper passes `-c sandbox_mode=workspace-write -c approval_policy=never -c
|
|
98
101
|
sandbox_workspace_write.network_access=false` explicitly. A resume takes no passthrough flags and an
|
|
@@ -47,7 +47,7 @@ carries the session id) into the run trace, with stderr merged into it; `--color
|
|
|
47
47
|
`--color`, which stays on the fresh lane), so the resume lane is no longer the odd one out: it used
|
|
48
48
|
to print its final message straight to stdout with the event stream nowhere, which left the very
|
|
49
49
|
mode a nested-sandbox incident fired on without a structured evidence surface. Net effect: the wrapper prints just the final answer. **Reasoning still runs at
|
|
50
|
-
the
|
|
50
|
+
the run's effort** — quality is unchanged; only the *noise* is dropped. On success `codex-exec` extracts the
|
|
51
51
|
session id from the trace and records it to `${CODEX_SESSION_FILE:-./.codex-last-session}` (so
|
|
52
52
|
`--resume-last` can find it) and echoes `session: <id>` to stderr. On a missing/empty final-message
|
|
53
53
|
file it falls back to the trace tail (loud, never silent).
|
|
@@ -61,13 +61,16 @@ well-formed item is simply not evidence, never a parse error. See the dual polic
|
|
|
61
61
|
its loose whole-trace rule, and the successful-run arm demands both tokens inside ONE item whose
|
|
62
62
|
failure is proven.
|
|
63
63
|
|
|
64
|
-
##
|
|
64
|
+
## Host posture (model & effort)
|
|
65
65
|
|
|
66
|
-
The wrappers
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
66
|
+
The wrappers run on the host posture: `CODEX_MODEL` / `CODEX_EFFORT` from the bridge settings file, else
|
|
67
|
+
the built-in default `gpt-6.1-sol` / `high`, checked pre-spend against the installed CLI's catalog
|
|
68
|
+
(`codex debug models`); `/agent-workflow-kit bridge-settings` shows the models offered and sets one. A model or effort the catalog does not offer, and an environment value off the
|
|
69
|
+
host posture (a one-off), are **refused** (exit 2, loud) with the settings-file remedy; a weaker model
|
|
70
|
+
is the user's choice in the setting, never a per-call downgrade. (Whether the default is the strongest
|
|
71
|
+
selectable model is a hand-checked claim with no automated gate — see SKILL.md.) `CODEX_PROBE=1` is the
|
|
72
|
+
one route to a one-off, for a throwaway probe only (echoed loudly; a nonced `codex-exec` probe one-off
|
|
73
|
+
is refused), and a probe still runs on the subscription, in the sandbox, with clean capture.
|
|
71
74
|
|
|
72
75
|
## Passthrough guard (two tiers, after a literal `--`)
|
|
73
76
|
|
|
@@ -75,7 +78,7 @@ a probe still runs on the subscription, in the sandbox, with clean capture.
|
|
|
75
78
|
|
|
76
79
|
- **Tier 1 — ALWAYS rejected, even under `CODEX_PROBE=1`:** anything that would defeat the policy or the
|
|
77
80
|
capture — `-c`/`--config`, `-s`/`--sandbox`, `--full-auto`, `--dangerously-bypass-*`, `--oss`,
|
|
78
|
-
`--local-provider`, `-p`/`--profile`, `-m`/`--model` (the model is
|
|
81
|
+
`--local-provider`, `-p`/`--profile`, `-m`/`--model` (the model is the host posture or `CODEX_MODEL`), and the
|
|
79
82
|
capture flags `-o`/`--output-last-message`/`--json`/`--color`/`--output-schema`/`--ephemeral`.
|
|
80
83
|
- **Tier 2 — context/discovery knobs, rejected for a real run but allowed under `CODEX_PROBE=1`:**
|
|
81
84
|
`--add-dir`, `-C`/`--cd`, `--skip-git-repo-check`, `--ignore-rules`, `--enable`/`--disable`.
|
|
@@ -155,7 +158,7 @@ run starts, so the failure is loud and costs no quota; the wrapper's own test pi
|
|
|
155
158
|
(`RESUME_ACCEPTED_FLAGS`) precisely because the hermetic fake CLI accepts any argv and cannot answer
|
|
156
159
|
this question. The `codex-exec --resume`/`--resume-last` entrypoint handles the reset: it restates
|
|
157
160
|
the entire policy via `-c` (`sandbox_mode=workspace-write`, `approval_policy=never`,
|
|
158
|
-
`sandbox_workspace_write.network_access=false`) plus the
|
|
161
|
+
`sandbox_workspace_write.network_access=false`) plus the host posture's `-m`/effort and
|
|
159
162
|
`--ignore-user-config`, reads the session id from the sidecar (or an argument), and applies the same
|
|
160
163
|
EVIDENCE posture as a fresh run — `-o` for the final message, `--json` into the trace. Only a *raw*
|
|
161
164
|
`codex exec resume` outside the wrapper loses the posture.
|
|
@@ -164,7 +167,7 @@ EVIDENCE posture as a fresh run — `-o` for the final message, `--json` into th
|
|
|
164
167
|
|
|
165
168
|
A backgrounded/hung run survives otherwise, so both wrappers wrap codex in `timeout`/`gtimeout`
|
|
166
169
|
(`--kill-after=15s`): `CODEX_HARD_TIMEOUT` defaults to **3600s (exec)** / **1800s (review)**, sized for a
|
|
167
|
-
slow run at the
|
|
170
|
+
slow run at the host posture's effort. Exit 124/137 ⇒ "exceeded the hard cap" (raise the cap or narrow the task). If neither
|
|
168
171
|
`timeout` nor `gtimeout` is on `PATH`, `codex-exec` **warns loudly and runs uncapped** — never a silent
|
|
169
172
|
no-op — while `codex-review` **refuses pre-spend** (the fail-closed hard-timeout preflight).
|
|
170
173
|
|
|
@@ -205,8 +208,9 @@ exec` over the precomputed diff instead, keeping every invariant intact.
|
|
|
205
208
|
| `-o, --output-last-message <f>` | write ONLY the final message (clean capture) |
|
|
206
209
|
| `--json` | structured event stream (`thread.started` ⇒ session id) |
|
|
207
210
|
| `--output-schema <f>` | constrain output to a JSON schema (`CODEX_REVIEW_SCHEMA=1`) |
|
|
208
|
-
| `-m <model>` | model (
|
|
209
|
-
| `-c model_reasoning_effort=<effort>` | reasoning effort (
|
|
211
|
+
| `-m <model>` | model (the host posture: the `CODEX_MODEL` setting, else `gpt-6.1-sol`) |
|
|
212
|
+
| `-c model_reasoning_effort=<effort>` | reasoning effort (the host posture: the `CODEX_EFFORT` setting, else `high`) |
|
|
213
|
+
| `codex debug models` | the model catalog as JSON `models[]` (`slug`, `visibility`, `priority`, `supported_reasoning_levels`, `default_reasoning_level`) — the wrappers' pre-spend check; reads no stdin (probed on 0.160.0) |
|
|
210
214
|
| `--ignore-user-config` | do NOT load `$CODEX_HOME/config.toml`; auth still uses `CODEX_HOME` |
|
|
211
215
|
| `--color never` | disable ANSI colour in output |
|
|
212
216
|
|
|
@@ -70,9 +70,9 @@ if it reports a missing git work tree or root `AGENTS.md`, run it from a project
|
|
|
70
70
|
|
|
71
71
|
- The wrappers are **subscription-only** by design and will not use api-key billing.
|
|
72
72
|
- `codex-exec` runs a **workspace-write** sandbox with **network OFF**; `codex-review` runs
|
|
73
|
-
**read-only**. They also
|
|
74
|
-
|
|
75
|
-
|
|
73
|
+
**read-only**. They also run on the host posture — `CODEX_MODEL` / `CODEX_EFFORT` from the
|
|
74
|
+
bridge settings file, else `gpt-6.1-sol` / `high` — checked against the installed CLI's catalog,
|
|
75
|
+
and refuse a one-off model or effort unless `CODEX_PROBE=1` (see `../SKILL.md`), enforce a hard
|
|
76
76
|
timeout, capture only codex's final message, and block codex from writing git via a shim — see
|
|
77
77
|
[`../references/sandbox-and-flags.md`](../references/sandbox-and-flags.md) and the knob table in
|
|
78
78
|
[`../SKILL.md`](../SKILL.md#environment-knobs). No setup is needed to enable these — they are on by
|
package/capability.json
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sabaiway/agent-workflow-kit",
|
|
3
|
-
"version": "14.
|
|
3
|
+
"version": "14.22.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",
|
|
@@ -1,23 +1,18 @@
|
|
|
1
1
|
# Task: {{TASK_NAME}}
|
|
2
|
-
Story: {{STORY_ID}} of {{EPIC_ID}}
|
|
3
|
-
|
|
4
|
-
## Slice
|
|
5
2
|
Plan: {{PLAN_PATH}}
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
3
|
+
|
|
4
|
+
## Row
|
|
5
|
+
{{ROW_LINE}}
|
|
6
|
+
|
|
7
|
+
## Files
|
|
8
|
+
- {{FILE_PATH}}
|
|
11
9
|
|
|
12
10
|
## Reads
|
|
11
|
+
- {{SCENARIO_LINE}}
|
|
13
12
|
- {{PLAN_PATH}}
|
|
14
13
|
|
|
15
|
-
##
|
|
16
|
-
- {{
|
|
17
|
-
|
|
18
|
-
## Negative cases
|
|
19
|
-
- {{NEGATIVE_CASE}} :: {{NEGATIVE_OUTCOME}}
|
|
14
|
+
## Run
|
|
15
|
+
- {{RUN_COMMAND}}
|
|
20
16
|
|
|
21
|
-
##
|
|
22
|
-
- {{
|
|
23
|
-
- {{MODULE_PATH}} :: {{MODULE_MAX_LINES}}
|
|
17
|
+
## Do not run
|
|
18
|
+
- {{FORBIDDEN_COMMAND}}
|
|
@@ -8,11 +8,11 @@ The opt-in **subagent-vehicle writer** — the family's second `.claude/` writer
|
|
|
8
8
|
**Every READ-ONLY vehicle grants READ-ONLY tools and NO `Bash`** — that is the load-bearing property, not a detail. A read-only fan-out on a full-tool vehicle shells out for facts it could have read, and each shelled command is an approval prompt the maintainer never needed to see; a vehicle with no shell structurally cannot do that. Two lanes ride on it:
|
|
9
9
|
|
|
10
10
|
- **cheap lane** (`model: haiku`, `effort: low`) — `mechanical-sweep`, `changelog-skeleton`, `gate-triage`: extraction sweeps, changelog fact-skeletons, gate-failure triage. Extraction/drafting only; the orchestrator applies judgment and verifies the output.
|
|
11
|
-
- **review lens** (`review-lens`, review-capable model) — an ADDITIONAL independent read-only opinion on code the configured review backends have already seen. It exists because a third lens otherwise has **no vehicle at all**: the cheap vehicles are scoped away from judgment, and a review-capable full-tool subagent is the prompt-flood shape. It never replaces the configured review recipe, and it is advisory like every other review.
|
|
11
|
+
- **review lens** (`review-lens`, review-capable model) — an ADDITIONAL independent read-only opinion on code the configured review backends have already seen. It exists because a third lens otherwise has **no vehicle at all**: the cheap vehicles are scoped away from judgment, and a review-capable full-tool subagent is the prompt-flood shape. It never replaces the configured review recipe of a plan or a diff — an epic's rendered brief is reviewed by the lens alone, whatever `epic.review` resolves to — and it is advisory like every other review.
|
|
12
12
|
|
|
13
13
|
Writing code, running gates, and user-facing copy never move to these four vehicles.
|
|
14
14
|
|
|
15
|
-
**The fifth vehicle, `executor`, is the ONE full-tool one** (model and effort from `docs/ai/vehicles.json` — `opus` / `high` by default — and every tool, a shell included). It is the instrument behind the **Subagent** recipe, dispatched ONLY for a **bounded, file-disjoint slice** the orchestrator verifies afterwards by running its suites: a slice of execution (`plan-execution.execute`), a plan/contract authoring brief (`plan-authoring.author`), an authoring-round fold (`plan-authoring.fold`), a bounded chore (`routine.carrier`), an epic brief (`epic.author`),
|
|
15
|
+
**The fifth vehicle, `executor`, is the ONE full-tool one** (model and effort from `docs/ai/vehicles.json` — `opus` / `high` by default — and every tool, a shell included). It is the instrument behind the **Subagent** recipe, dispatched ONLY for a **bounded, file-disjoint slice** the orchestrator verifies afterwards by running its suites: a slice of execution (`plan-execution.execute`), a plan/contract authoring brief (`plan-authoring.author`), an authoring-round fold (`plan-authoring.fold`), a bounded chore (`routine.carrier`), an epic brief (`epic.author`), or one prompt the orchestrator wrote from one ledger row, run inside its Files (`task.execute`); `task.author` dispatches no slice, since the orchestrator writes each row's prompt itself. It **never commits** (no git write at all), is **never a review backend**, is **never a bridge substitute**, and is **never dispatched for read-only work** — a sweep, an inventory or a review rides a read-only vehicle instead.
|
|
16
16
|
|
|
17
17
|
**Its readiness is the vehicle FILE.** `surveyExecutorVehicle` answers exactly one of four states: **`placed`** (bytes equal to the body derived from `docs/ai/vehicles.json` at `.claude/agents/executor.md`), **`customized`** (a readable regular file whose frontmatter names `executor` and whose tools are not read-only), **`unusable`** (a symlink, a non-regular or unreadable file, one failing that check, or an unreadable `docs/ai/vehicles.json` — with the reason), **`missing`**. `placed` and `customized` are dispatchable; on `unusable` or `missing` a `subagent` slot **degrades to Solo** with a reason naming this mode's apply command (and `docs/ai/vehicles.json` when that file is unreadable). `/agent-workflow-kit status` shows the state in its `agents` block and the deployment advisor raises it when a configured slot names `subagent` and the vehicle is `unusable` or `missing` — that item is **`executor-vehicle`** (attention-class: a configured declaration that is broken), a DIFFERENT capability from this mode's placement offer (`agents`), which converges the moment nothing is left to place and therefore can never observe a present-but-unusable vehicle. It is a claim about the FILE, never about the host: a Claude Code lane, like this mode itself.
|
|
18
18
|
|
|
@@ -4,11 +4,14 @@
|
|
|
4
4
|
|
|
5
5
|
The reader + consent-gated **writer** for the **host-level** bridge settings file — the answer to *"turn on the codex Fast tier (or another bridge knob) once, predictably, so it survives kit upgrades."* The four bridge wrappers read `${XDG_CONFIG_HOME:-~/.config}/agent-workflow/bridge-settings.conf` (`KEY=VALUE` lines, **parsed never sourced**); this is the ONLY writer for it. The file lives **outside every kit-managed tree**, so a kit refresh never writes or clobbers it — upgrade-survival is structural (D2). It **previews by default**; `--apply` writes. Hand-editing the file stays fully supported — this is an offered convenience, never a lock.
|
|
6
6
|
|
|
7
|
-
**The knobs are the bundled bridges' own `settings` blocks** (manifest-as-source, D6) — the tool never invents a key or a value rule, and what it writes always passes the wrappers' own validation.
|
|
7
|
+
**The knobs are the bundled bridges' own `settings` blocks** (manifest-as-source, D6) — the tool never invents a key or a value rule, and what it writes always passes the wrappers' own validation. **The model keys set each bridge's host posture** — the model every run of that bridge uses (codex: and its effort); a set one is checked against the models the installed CLI offers **before anything is written**. Run **`/agent-workflow-kit bridge-settings`** (`node ${CLAUDE_SKILL_DIR}/tools/bridge-settings.mjs`) to see the live list and the models on offer; today:
|
|
8
8
|
|
|
9
9
|
| key | bridge | values | note |
|
|
10
10
|
|---|---|---|---|
|
|
11
|
-
| `
|
|
11
|
+
| `CODEX_MODEL` | codex | a model the installed codex offers | the host posture's model; default `gpt-6.1-sol`. |
|
|
12
|
+
| `CODEX_EFFORT` | codex | an effort that model offers | the host posture's reasoning effort; default `high`. |
|
|
13
|
+
| `AGY_MODEL` | agy | a display string the installed agy offers | the host posture's model; default `Gemini 3.8 Flash (High)`. |
|
|
14
|
+
| `CODEX_SERVICE_TIER` | codex | `priority` | **SPEND KNOB** — the "Fast" tier: "2x speed, **increased usage**" in the codex catalog's own words for gpt-6.1-sol (cache fetched 2026-10-03); it states no credit-rate figure; quality-neutral (same model). Default unset ⇒ standard tier. |
|
|
12
15
|
| `CODEX_HARD_TIMEOUT` | codex | integer `1..86400` | hard wall-clock cap (seconds) via `timeout(1)`. |
|
|
13
16
|
| `CODEX_REVIEW_MAX_TOTAL_BYTES` | codex | integer `1..100000000` | codex-review payload size above which the diff rides a temp file (never truncated). |
|
|
14
17
|
| `AGY_HARD_TIMEOUT` | agy | duration `5m`/`30m`/`90s` (unit required, nonzero) | hard wall-clock cap via `timeout(1)`. |
|
|
@@ -17,16 +20,16 @@ The reader + consent-gated **writer** for the **host-level** bridge settings fil
|
|
|
17
20
|
|
|
18
21
|
**Invocations:**
|
|
19
22
|
|
|
20
|
-
1. **Read** — `node ${CLAUDE_SKILL_DIR}/tools/bridge-settings.mjs [--json]` prints every knob's **effective value + source** (`env` / `file` / `default`) and flags any unknown/duplicate/malformed lines. Read-only.
|
|
23
|
+
1. **Read** — `node ${CLAUDE_SKILL_DIR}/tools/bridge-settings.mjs [--json]` prints every knob's **effective value + source** (`env` / `file` / `default`; a model key's `environment` / `setting` / `default`, as the wrappers' banner names it), each bridge's host posture with the models its installed CLI offers (read with `codex debug models` / `agy models`, never a model run; an unreadable or missing CLI is one stated line, exit 0), and flags any unknown/duplicate/malformed lines. Read-only.
|
|
21
24
|
2. **Preview a change** — `--set KEY=VALUE` (or `--unset KEY`) prints `before → after` and writes **nothing**. Re-run with **`--apply`** to write. Multiple `--set`/`--unset` ops apply in one atomic write.
|
|
22
25
|
3. **`--apply`** writes via the hardened out-of-tree atomic writer (creates the dir + file on first use; symlink/parent/TOCTOU-safe; last-writer-wins). It touches **only** the `KEY=` line it owns — every comment / blank / other line is preserved verbatim.
|
|
23
26
|
|
|
24
|
-
**Precedence at run time:** explicit env (even empty — `KEY=` disables the knob for one run) **>** this file **>** the wrapper's built-in default. So an operator can always override one run without editing the file; the reader shows which source wins.
|
|
27
|
+
**Precedence at run time:** explicit env (even empty — `KEY=` disables the knob for one run) **>** this file **>** the wrapper's built-in default. So an operator can always override one run without editing the file; the reader shows which source wins. A model key is the exception: an environment value off the host posture is a one-off, which `codex-exec`, `codex-review` and `agy-review` refuse unless it is a probe (the bridge-model contract).
|
|
25
28
|
|
|
26
|
-
**Refusals (the guarded contract):** an **unknown key** or an **invalid / out-of-range value** → exit `2` (nothing read of the file, nothing written). A file that already carries **duplicate keys** → exit `1`, named and left **byte-untouched** (fix the duplicates by hand first — the writer never edits blindly around them). A **symlinked / non-regular / unreadable** settings file → exit `1` (refuses to write through it). `--apply` with `--dry-run`, a duplicate op for one key, or a malformed `--set` → usage exit `2`.
|
|
29
|
+
**Refusals (the guarded contract):** an **unknown key** or an **invalid / out-of-range value** (a model key: empty, padded with whitespace, or carrying a control byte) → exit `2` (nothing read of the file, nothing written). A **model the catalog does not offer**, or a codex **effort that model does not offer**, → exit `2` with the offered list, nothing written; an unreadable catalog leaves the value unchecked and says so. A file that already carries **duplicate keys** → exit `1`, named and left **byte-untouched** (fix the duplicates by hand first — the writer never edits blindly around them). A **symlinked / non-regular / unreadable** settings file → exit `1` (refuses to write through it). `--apply` with `--dry-run`, a duplicate op for one key, or a malformed `--set` → usage exit `2`.
|
|
27
30
|
|
|
28
|
-
**Spend consent (D4):** enabling `CODEX_SERVICE_TIER=priority` costs **increased usage** (the catalog states no credit-rate figure) — a per-host, consented act, never a default. The preview shows the caveat (from the manifest `effect`); confirm with the user before `--apply`. The tool also warns when an env var currently shadows the key you are writing (the env value wins for that session until unset).
|
|
31
|
+
**Spend consent (D4):** enabling `CODEX_SERVICE_TIER=priority` costs **increased usage** (the catalog states no credit-rate figure) — a per-host, consented act, never a default. The preview shows the caveat (from the manifest `effect`); confirm with the user before `--apply`. The tool also warns when an env var currently shadows the key you are writing (the env value wins for that session until unset; for a model key, an environment value off the host posture is a one-off, which `codex-exec`, `codex-review` and `agy-review` refuse unless it is a probe).
|
|
29
32
|
|
|
30
33
|
Output is **English/structured** — **localize it to the user's conversational language** when you narrate.
|
|
31
34
|
|
|
32
|
-
**Invariants:** writer (writes only the host settings file — outside any project/kit tree) · never commits · never runs a
|
|
35
|
+
**Invariants:** writer (writes only the host settings file — outside any project/kit tree) · never commits · never runs a model (only the two read-only catalog commands) · previews by default · allowlist + value rules from the bundled manifests · a model key is judged against its bridge's catalog before any write · the host file survives every kit refresh.
|
|
@@ -2,16 +2,16 @@
|
|
|
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 or the executor vehicle and **owns any commit when the activity has a commit boundary** (every other carrier never commits). Not every activity commits: `plan-authoring` ends at approval and produces no commit (plans are ephemeral, never committed); `plan-execution` commits
|
|
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 or the executor vehicle and **owns any commit when the activity has a commit boundary** (every other carrier never commits). Not every activity commits: `plan-authoring` ends at approval and produces no commit (plans are ephemeral, never committed); `plan-execution` commits the story once, after its diff review.
|
|
6
6
|
|
|
7
7
|
The six activities (canon in the **installed engine**, `references/procedures.md`; the registry is `tools/carriers.mjs`):
|
|
8
8
|
|
|
9
|
-
- **`plan-authoring`** (slots: `author`, `fold`, `review`) — research → draft (the resolved `author` carrier drafts: Solo writes it, Subagent drafts from the orchestrator's brief) → self-review with the readers sweep first → **review {recipe}** →
|
|
10
|
-
- **`plan-execution`** (slots: `execute`, `review`) — per ledger row: resolve the recipe → if Delegated, dispatch execution first; if Subagent, dispatch file-disjoint slices to the executor vehicle and verify each returned slice → implement → self-review
|
|
9
|
+
- **`plan-authoring`** (slots: `author`, `fold`, `review`) — research → draft (the resolved `author` carrier drafts: Solo writes it, Subagent drafts from the orchestrator's brief) → self-review with the readers sweep first → **review {recipe}** of the spec, every contract the story revises and the plan's ledger in the same rounds, at most two → one fold ask per member per round, then fold through the resolved `fold` carrier, a fold of the last round re-read by its raiser → present the plan folded with the spec for approval; enforce the mandatory Cleanup.
|
|
10
|
+
- **`plan-execution`** (slots: `execute`, `review`) — per ledger row: resolve the recipe → if Delegated, dispatch execution first; if Subagent, dispatch file-disjoint slices to the executor vehicle and verify each returned slice → implement → self-review; then once, on the story's staged diff with every committable output (the project-declared stages' included) staged first: **review {recipe}** with the fold ask, the raiser's re-read and the re-check of a moved staged tree → gates → the one commit; Phase: Cleanup runs after it and changes nothing the review judged.
|
|
11
11
|
- **`routine`** (slots: `carrier`, `parallel`) — name the chore and its file-disjoint slices → resolve → carry it (Solo, or Subagent: a read-only slice rides a placed read-only vehicle, a write-capable one rides the executor; `parallel` on → concurrently) → verify every returned slice; the commit boundary is unchanged.
|
|
12
12
|
- **`feedback-triage`** (slot: `review`) — record → verify every claim by code on the stamped HEAD → `feedback-record-cli --check` → **review {recipe}** over the record, the excerpts as agy's `--facts` payload → `--rows` renders the queue rows and the ratchet line → fold only a false statement in shipped copy.
|
|
13
|
-
- **`epic`** (slots: `author`, `review`) — brief → draft by the resolved `author` carrier → `epic-shape-cli --check` → **review {recipe}
|
|
14
|
-
- **`task`** (slots: `author`, `execute`) —
|
|
13
|
+
- **`epic`** (slots: `author`, `review`) — brief → draft by the resolved `author` carrier → `epic-shape-cli --check` → **review {recipe}**: one review-lens read over the rendered review brief, whatever `epic.review` resolves to (no bridge wrapper, driving contract or grounding pre-step renders under it) → fold through the fold ask and `--fold`, at most two rounds → land.
|
|
14
|
+
- **`task`** (slots: `author`, `execute`) — the orchestrator writes one prompt from one ledger row, whatever `author` resolves to → with the story's changes staged, the resolved `execute` carrier runs it inside its Files (Delegated: `codex-exec --nonce <n> <prompt file>`) → the read after the hand-out restores writes outside the Files from the index and the copied excluded paths from their copy, then the row's tests → return into the story's row, a fold resuming the run's session from its exec receipt; no commit boundary or review of its own.
|
|
15
15
|
|
|
16
16
|
Value sets per slot type: `review` accepts `solo | reviewed | council`; `execute` (including `task.author` and `task.execute`) accepts `solo | delegated | subagent`; a carrier slot (`plan-authoring.author`, `plan-authoring.fold`, `routine.carrier`, `epic.author`) accepts `solo | subagent`; `parallel` is a **switch**, `on | off`, resolved outside the recipe lattice. Defaults when the config is silent: `review` → Reviewed if a review-capable backend is ready, else Solo; `author`, `fold`, `execute`, `carrier` → Solo (a placed executor never flips a default); `parallel` → on. The orchestrator owns every commit; every other carrier — a bridge or a subagent — never commits.
|
|
17
17
|
|
|
@@ -21,9 +21,9 @@ Run **`node ${CLAUDE_SKILL_DIR}/tools/procedures.mjs <activity> [--override <slo
|
|
|
21
21
|
2. **Default resolution (config silent):** `review` → Reviewed if any review-capable backend is `ready`, else Solo (never Council by default); `execute`, `author`, `fold`, `carrier` → Solo (Delegated and Subagent are opt-in; a placed executor never flips a default); `parallel` → on. **Degradation:** a config/computed default degrades **gracefully with a stated reason** (Council → Reviewed → Solo; Delegated → Solo; Subagent → Solo when the executor vehicle is missing or unusable, the reason naming the apply command; a switch never degrades); a per-run **`--override <slot>=<value>`** that can't be satisfied degrades **loudly** (a flagged warning, so you tell the user) — but is **still exit 0** (a valid request that gracefully degraded).
|
|
22
22
|
3. **Exit codes:** `0` success; `2` usage (unknown `<activity>` / bad `--override` — a bare `--override <recipe>`, an unknown slot, a value outside the slot's list, or a duplicate slot); `1` config error (malformed / schema-invalid / unreadable `orchestration.json`) **or** engine error (the installed engine is absent / invalid / **too old** to ship `references/procedures.md` — upgrade it with `npx @sabaiway/agent-workflow-engine@latest init`). A `1`/`2` failure is loud (`path: reason`), never a silent fallback. **Lagging-kit honesty:** a kit predating the `"flow"` key that reads a config carrying one fails this config load loudly (exit `1`, reddening its full gate matrix); the `set-flow` arming path now enforces the declared `kitMinVersion` floor with a null-guarded comparison (an unparseable version never passes), while tolerate-first ordering remains the only protection for readers older than the `"flow"` key itself — no in-config floor can reach a kit that dies on the unknown key.
|
|
23
23
|
|
|
24
|
-
**The dispatch form (a slot resolved to `subagent`).** A carrier that is only NAMED is a name, not an instruction, so after such a slot's resolved-recipe line the advisor prints — indented under it, in place of the one-line vehicle mention — the form the dispatch must take, in five parts: (1) what a SLICE is for THIS slot — for `plan-execution.execute`, a set of file-disjoint ledger rows, wording copied verbatim where wording is a red line; for `plan-authoring.author`, a brief naming the goal, the governing spec(s) and the ledger constraints, whose returned draft the orchestrator reviews as its own; for `plan-authoring.fold`, the round's findings with their dispositions, whose edits the orchestrator follows with the self-consistency read; for `routine.carrier`, a bounded mechanical task, where a read-only chore (a sweep, gate triage) rides its placed read-only vehicle — or is carried solo with a stated reason when that vehicle is absent — a write-capable one (a regeneration, a fixture build) rides the executor, and the changelog stays the orchestrator's; for `epic.author`, a brief naming the intent, the value, the non-goals and the stories in order, from which the subagent drafts the epic file and the orchestrator runs the shape check on the draft as its own; for `task.author`,
|
|
24
|
+
**The dispatch form (a slot resolved to `subagent`).** A carrier that is only NAMED is a name, not an instruction, so after such a slot's resolved-recipe line the advisor prints — indented under it, in place of the one-line vehicle mention — the form the dispatch must take, in five parts: (1) what a SLICE is for THIS slot — for `plan-execution.execute`, a set of file-disjoint ledger rows, wording copied verbatim where wording is a red line; for `plan-authoring.author`, a brief naming the goal, the governing spec(s) and the ledger constraints, whose returned draft the orchestrator reviews as its own; for `plan-authoring.fold`, the round's findings with their dispositions, whose edits the orchestrator follows with the self-consistency read; for `routine.carrier`, a bounded mechanical task, where a read-only chore (a sweep, gate triage) rides its placed read-only vehicle — or is carried solo with a stated reason when that vehicle is absent — a write-capable one (a regeneration, a fixture build) rides the executor, and the changelog stays the orchestrator's; for `epic.author`, a brief naming the intent, the value, the non-goals and the stories in order, from which the subagent drafts the epic file and the orchestrator runs the shape check on the draft as its own; for `task.author`, no slice the flow dispatches, since the orchestrator writes each row's prompt itself whatever the slot resolves to — that sentence renders alone, with none of the parts below; for `task.execute`, one prompt the orchestrator wrote from one ledger row, run inside the Files the prompt names with the changed paths reported and the row's tests run by the orchestrator; (2) the vehicle and its surveyed state — `.claude/agents/executor.md` (`placed` / `customized` / `unusable` / `missing`, from the same survey `status` and the advisor read) — dispatched **in the background**; (3) that the orchestrator **verifies every returned slice by running its suites itself**; (4) that the subagent is **never told to commit, never a review backend, never a bridge substitute**; (5) the **honest limit** — a Claude Code lane: on a host that cannot dispatch the vehicle, follow this form BY HAND and say so, never report it as a subagent dispatch. The wording is the kit's own (`tools/carriers.mjs`) and is printed, never re-worded. The dispatch-form branch is unchanged for a slot resolved to `solo` or `delegated`.
|
|
25
25
|
|
|
26
|
-
**Fold lane (an execute slot the activity reads resolved to `delegated`).** `procedures plan-execution` reads `plan-execution.execute` and `task.execute`, `procedures task` reads `task.execute` alone, and `task.author` never counts; a per-run `--override` moves only the rendered activity's own slot. The lane renders once, immediately after the rendered activity's `execute` slot block (after its driving contract when that slot itself resolves to `delegated`), as
|
|
26
|
+
**Fold lane (an execute slot the activity reads resolved to `delegated`).** `procedures plan-execution` reads `plan-execution.execute` and `task.execute`, `procedures task` reads `task.execute` alone, and `task.author` never counts; a per-run `--override` moves only the rendered activity's own slot. The lane renders once, immediately after the rendered activity's `execute` slot block (after its driving contract when that slot itself resolves to `delegated`), as one line: a fold of code a bridge wrote resumes that run's session, `codex-exec --resume <session id> --nonce <n> <prompt file>`, the session id read from the `sessionId` of the run's exec receipt, with a new prompt and a fresh nonce. No delegation ledger and no HEAD are read, so the line is the same whatever a ledger holds. The block is advisory and never changes the exit code; `foldLane` carries the identical line under `--json`, and is `[]` for every other activity and whenever no slot the activity reads resolves to `delegated`.
|
|
27
27
|
|
|
28
28
|
**`routine`'s `parallel` switch renders against the EFFECTIVE carrier.** The flag always renders with its source (`parallel: on` / `parallel: off`); the concurrency claim — *file-disjoint slices dispatch concurrently* — renders **only** while the resolved `carrier` is `subagent`. Under a `solo` carrier the line states its own inertness instead, `(no effect while the carrier is solo)`: a switch never degrades, so the flag keeps the value you set and the render simply stops promising a concurrency nothing can perform. That makes four cells (`on`/`off` x `subagent`/`solo`), and only the `subagent`+`on` cell claims concurrency.
|
|
29
29
|
|
|
@@ -10,9 +10,9 @@ The five recipes (defined over each bridge's `provides` roles — `codex`: execu
|
|
|
10
10
|
- **Reviewed** — you execute; **one** backend reviews the result (advisory). Prefers `codex` when both are ready (`agy` carries a standing health caveat).
|
|
11
11
|
- **Council** — **both** backends review independently; you synthesize the two opinions.
|
|
12
12
|
- **Delegated** — you hand a **bounded** execution sub-task to a backend (`codex exec`), then review the returned diff and commit.
|
|
13
|
-
- **Subagent** — a **full-tool frontier subagent**, dispatched from the placed executor vehicle (`.claude/agents/executor.md`), carries a **bounded, file-disjoint** slice — of execution, of plan/contract authoring, of an authoring fold, of routine work, of an epic brief (`epic.author`), of
|
|
13
|
+
- **Subagent** — a **full-tool frontier subagent**, dispatched from the placed executor vehicle (`.claude/agents/executor.md`), carries a **bounded, file-disjoint** slice — of execution, of plan/contract authoring, of an authoring fold, of routine work, of an epic brief (`epic.author`), or of one prompt the orchestrator wrote from one ledger row, run inside its Files (`task.execute`; `task.author` dispatches no slice: the orchestrator writes each row's prompt itself); you verify the returned slice by running its suites yourself and you make the commit. It is **never a review backend**, **never a bridge substitute**, and is **never told to commit**; it **degrades to Solo** when the vehicle is `missing` or `unusable`, with the reason. Readiness here is the **vehicle FILE, never the host** — a **Claude Code lane**, like the `agents` writer itself: on a host that cannot dispatch the vehicle, the rendered dispatch form is an instruction you follow by hand and report as such, never as a subagent dispatch.
|
|
14
14
|
|
|
15
|
-
1. Run **`node ${CLAUDE_SKILL_DIR}/tools/recipes.mjs`** (the read-only planner; `--json` for the structured form). It runs the backend detector, lists the five recipes, and prints — for the current environment — a **per-recipe dispatch plan that degrades with a stated reason** when a carrier isn't `ready` (Council → Reviewed → Solo; Delegated → Solo; Subagent → Solo when the executor vehicle is `missing`/`unusable`), plus advisory **quota/health notes** (
|
|
15
|
+
1. Run **`node ${CLAUDE_SKILL_DIR}/tools/recipes.mjs`** (the read-only planner; `--json` for the structured form). It runs the backend detector, lists the five recipes, and prints — for the current environment — a **per-recipe dispatch plan that degrades with a stated reason** when a carrier isn't `ready` (Council → Reviewed → Solo; Delegated → Solo; Subagent → Solo when the executor vehicle is `missing`/`unusable`), plus advisory **quota/health notes** (each bridge runs the host posture the user set — a weaker model is the user's bridge setting, never a per-call choice; Council spends two backends' quota; `agy` may stall on substantive prompts — Issue-001, prefer `codex`).
|
|
16
16
|
2. **Offer the choice** via **`AskUserQuestion` where your agent supports it** (`AskUserQuestion` in Claude Code) — one option per recipe, the `recommendRecipe` choice listed **first** — otherwise in prose. Then print `planRecipe(chosen, detection)` (the per-stage dispatch + degradation reasons + quota/health notes) so the user sees exactly what running it entails.
|
|
17
17
|
3. **Availability = `readiness === ready`, full stop.** Every other readiness supplies the human reason (needs-skill → "not installed — `/agent-workflow-kit setup`"; needs-cli → "install the CLI"; needs-credentials → "log in"; degraded → "wrapper not on PATH — `/agent-workflow-kit setup`"). This is set-up state only — **never** a claim that a backend's service is responsive (the detector cannot observe a runtime stall; `agy`'s Issue-001 is a *standing advisory*, not a readiness signal).
|
|
18
18
|
|
|
@@ -7,7 +7,7 @@ Read-only **review-receipt checker** (AD-038) — it makes *"reviewed ≠ shippe
|
|
|
7
7
|
Run `node ${CLAUDE_SKILL_DIR}/tools/review-state.mjs [--check] [--json]`:
|
|
8
8
|
|
|
9
9
|
1. Plain run → the human report: resolved recipe + source, plan-in-flight, tree fingerprint, the `held session: <id> — <n> fold(s) rode it` / `none` / substitution line when configured delegated execution arms it (with a task `code` thread of backend `codex` in the commit epoch and no unresolved substitution, `held sessions: <k> chain(s) — <label>: <id> (<n>) · …` is printed instead, one entry per chain, labelled by its brief or `untasked`, with `none` for a chain with no held session), and per-backend receipt state (current / stale / ungrounded / probe / rejected / missing) with verdict + grounding + timestamp.
|
|
10
|
-
2. **`--check`** → the gate exit code. Before the review-recipe early return, a configured `plan-execution.execute` or `task.execute` of `delegated` (each read on its own) with a plan in flight and a dirty, fingerprintable tree audits the delegation ledger and refuses a substituted held session; an absent ledger is inert, while an unreadable, malformed, foreign, audit-refused ledger or failed HEAD read fails closed with its own reason. For a head-base thread, the accepted-replacement escape is a `codex-exec` degrade at the substituted return's tree, standing after every later fold, never the review receipt id `codex`. A checkpoint-based thread's substitution closes only by its own ledger `degrade` (which also withdraws the expectation, so the next fold establishes HELD) — no core-evidence degrade lifts it, and the report's recovery hint says so. The remaining **normative exit contract lives in the tool header** (the single home — do not re-enumerate it elsewhere): exit 0 for a CONFIGURED solo recipe (after the held-session arm above) (a computed readiness-degrade NEVER silently becomes solo — it needs the explicit degrade record below), no plan in flight (the `docs/plans` naming convention: `queue.md` and `EXECUTE-`/`FEEDBACK-`/`TASK-`-prefixed or `PROMPT`/`prompt`/`handoff`-carrying names are scratch), a clean tree, a cwd where git ITSELF answers not-a-repository under both discoveries (the ONLY non-work-tree location that passes — `error`, `redirected`, `no-work-tree` and `env-only` refuse by their state name once a receipt could be required), or every recipe-named backend SATISFIED for the current tree. **A clean-tree PASS under a NON-SOLO review obligation is never silent about a latent arm:** when a `reviewed` or `council` recipe is configured, it NAMES every plan in flight and states that this gate arms as soon as the tree is dirty — the condition is discoverable BEFORE it blocks, instead of surfacing at the worst moment (a pending commit, or the landing of a feature worktree when main first turns dirty). Nothing is announced under a configured `solo` recipe or a not-a-repository cwd, where the gate can never arm. **Satisfaction is ship-class-only on the LATEST NORMAL receipt (D3(b)):** per backend, the latest probe-free current-fingerprint receipt is selected FIRST and THEN verdict-checked — only the recognized ship-class vocabulary (`ship` / `ship with nits`) satisfies; a recognized NEGATIVE (`revise` / `rethink` / `rework`) is an authoritative VETO (an earlier ship never survives a later revise); an UNRECOGNIZED verdict (e.g. `unknown` from a dead run) fails CLOSED unconditionally — a later `unknown` never lets an earlier SHIP stand, and a fresh normal re-run supersedes it. **The ONLY review-backend escape is an explicit degrade RECORD** (`core-evidence.mjs degrade --backend <name> --reason "…"`, fingerprint-bound to the current tree) — and never all backends: ≥1 non-degraded ship-class receipt is required whenever ≥1 backend is configured; a malformed evidence store denies the escape fail-closed but never fails an independently-satisfied tree. Exit 1 otherwise — missing, **stale** (every edit the payload can see moves the fingerprint, and no more), ungrounded, vetoed, or unrecognized. Plan/diff receipts and continuations (`agy-review --continue`) are **informational-only**: after a fold, only a **fresh grounded re-run** (`codex-review code`; `agy-review code --facts @f`) restores green. **Probe receipts never attest either:** a `CODEX_PROBE=1` / `AGY_PROBE=1` review
|
|
10
|
+
2. **`--check`** → the gate exit code. Before the review-recipe early return, a configured `plan-execution.execute` or `task.execute` of `delegated` (each read on its own) with a plan in flight and a dirty, fingerprintable tree audits the delegation ledger and refuses a substituted held session; an absent ledger is inert, while an unreadable, malformed, foreign, audit-refused ledger or failed HEAD read fails closed with its own reason. For a head-base thread, the accepted-replacement escape is a `codex-exec` degrade at the substituted return's tree, standing after every later fold, never the review receipt id `codex`. A checkpoint-based thread's substitution closes only by its own ledger `degrade` (which also withdraws the expectation, so the next fold establishes HELD) — no core-evidence degrade lifts it, and the report's recovery hint says so. The remaining **normative exit contract lives in the tool header** (the single home — do not re-enumerate it elsewhere): exit 0 for a CONFIGURED solo recipe (after the held-session arm above) (a computed readiness-degrade NEVER silently becomes solo — it needs the explicit degrade record below), no plan in flight (the `docs/plans` naming convention: `queue.md` and `EXECUTE-`/`FEEDBACK-`/`TASK-`-prefixed or `PROMPT`/`prompt`/`handoff`-carrying names are scratch), a clean tree, a cwd where git ITSELF answers not-a-repository under both discoveries (the ONLY non-work-tree location that passes — `error`, `redirected`, `no-work-tree` and `env-only` refuse by their state name once a receipt could be required), or every recipe-named backend SATISFIED for the current tree. **A clean-tree PASS under a NON-SOLO review obligation is never silent about a latent arm:** when a `reviewed` or `council` recipe is configured, it NAMES every plan in flight and states that this gate arms as soon as the tree is dirty — the condition is discoverable BEFORE it blocks, instead of surfacing at the worst moment (a pending commit, or the landing of a feature worktree when main first turns dirty). Nothing is announced under a configured `solo` recipe or a not-a-repository cwd, where the gate can never arm. **Satisfaction is ship-class-only on the LATEST NORMAL receipt (D3(b)):** per backend, the latest probe-free current-fingerprint receipt is selected FIRST and THEN verdict-checked — only the recognized ship-class vocabulary (`ship` / `ship with nits`) satisfies; a recognized NEGATIVE (`revise` / `rethink` / `rework`) is an authoritative VETO (an earlier ship never survives a later revise); an UNRECOGNIZED verdict (e.g. `unknown` from a dead run) fails CLOSED unconditionally — a later `unknown` never lets an earlier SHIP stand, and a fresh normal re-run supersedes it. **The ONLY review-backend escape is an explicit degrade RECORD** (`core-evidence.mjs degrade --backend <name> --reason "…"`, fingerprint-bound to the current tree) — and never all backends: ≥1 non-degraded ship-class receipt is required whenever ≥1 backend is configured; a malformed evidence store denies the escape fail-closed but never fails an independently-satisfied tree. Exit 1 otherwise — missing, **stale** (every edit the payload can see moves the fingerprint, and no more), ungrounded, vetoed, or unrecognized. Plan/diff receipts and continuations (`agy-review --continue`) are **informational-only**: after a fold, only a **fresh grounded re-run** (`codex-review code`; `agy-review code --facts @f`) restores green. **Probe receipts never attest either:** a `CODEX_PROBE=1` / `AGY_PROBE=1` review is the one route to a one-off model or effort, so the wrapper stamps `probe:true` and this checker excludes it — per receipt, so a real review at the same fingerprint still satisfies. **Silence is not a declaration:** a malformed *or* absent probe marker is rejected fail-closed and stated in the check line. Honest bound: receipts are **not authenticated** (a forger could write `probe:false` as easily as any other field) — like the rest of the receipt this is a self-discipline mechanism, not a security boundary.
|
|
11
11
|
3. **Wire it as a gate by hand OR via the explicit-consent init preview — never without consent (AD-021/D9).** The candidate line for your own `docs/ai/gates.json`: `{ "id": "review-state", "title": "Review receipts current for the uncommitted tree", "cmd": "node <path-to-this-skill>/tools/review-state.mjs --check" }` — with the path your project actually reaches the kit by, QUOTED so a path with spaces survives, executable from the project root. The consent-gated gates-init preview — `node ${CLAUDE_SKILL_DIR}/tools/gates-init.mjs --cwd <project>` (dry-run: it prints the derived entries and writes NOTHING; `--apply --only review-state` writes exactly this one on your explicit yes) — offers exactly this entry, path resolved and quoted, ONLY when your `docs/ai/orchestration.json` declares `reviewed`/`council` on `plan-execution.review` (the slot this checker enforces). The full consent-fill contract is in `${CLAUDE_SKILL_DIR}/references/modes/gates.md`. Once declared, the opt-in `${CLAUDE_SKILL_DIR}/references/modes/hook.md` auto-approves it like any other declared gate — and `run-gates --final` requires this check among its canonical core gates.
|
|
12
12
|
4. **`--await [--timeout <s>]`** (BUGFREE-3 / AD-049) → BLOCK until every recipe-named backend is SATISFIED for the current tree (i.e. until `--check` would PASS), or the bounded timeout elapses (a loud exit 1; default 900s). Run it after dispatching the review bridges to WAIT for their receipts to land instead of hand-polling a pid: the durable completion signal is the **receipt**, never a process event (a harness "completed" notification fires early; a bridge's output late-flushes). It inherits the `--check` decision whole — a backend with a current-tree degrade RECORD stops being waited on (the shared decideCheck), so you never hand-`--await` around a known degrade. A held-session refusal and an **AUTHORITATIVE veto terminate the wait loudly BEFORE the deadline**: neither can be moved by waiting; only the held-session retry/degrade lane or a fresh review can move its corresponding refusal. Still read-only (it re-reads the receipts + the evidence store); solo / no-plan / clean-tree resolve instantly. For waiting on **one dispatch's arrival** (never obligation satisfaction) use the receipt-arrival deadline runner, `${CLAUDE_SKILL_DIR}/references/modes/receipt-deadline.md`.
|
|
13
13
|
|
|
@@ -15,7 +15,7 @@ mapping their wording onto them is your job, not a shipped phrase list.
|
|
|
15
15
|
| "both review" | `--set <activity>.review=council` | **disambiguate**: which activity? If both, pass `--set plan-authoring.review=council --set plan-execution.review=council`. |
|
|
16
16
|
| "one reviewer" | `--set <activity>.review=reviewed` | per the named activity, else ask |
|
|
17
17
|
| "delegate execution" | `--set plan-execution.execute=delegated` | execution only (a **bridge** runs the change) |
|
|
18
|
-
| "let a subagent do it" | `--set <activity>.<slot>=subagent` | **disambiguate**: which work? `--set plan-execution.execute=subagent` (a slice of the change), `--set plan-authoring.author=subagent` (a plan/contract brief), `--set plan-authoring.fold=subagent` (the round's findings and dispositions), `--set routine.carrier=subagent` (a bounded chore), `--set epic.author=subagent` (an epic brief), `--set task.
|
|
18
|
+
| "let a subagent do it" | `--set <activity>.<slot>=subagent` | **disambiguate**: which work? `--set plan-execution.execute=subagent` (a slice of the change), `--set plan-authoring.author=subagent` (a plan/contract brief), `--set plan-authoring.fold=subagent` (the round's findings and dispositions), `--set routine.carrier=subagent` (a bounded chore), `--set epic.author=subagent` (an epic brief), `--set task.execute=subagent` (one row's prompt run inside its Files; `task.author` dispatches no slice) |
|
|
19
19
|
| "one slice at a time" | `--set routine.parallel=off` | `routine` only — `parallel` is a **flag**, not a recipe |
|
|
20
20
|
| "revert / do it myself" | `--unset <activity>.<slot>` | the named slot → its computed default |
|
|
21
21
|
|
package/references/modes/tier.md
CHANGED
|
@@ -8,7 +8,7 @@ Run `node ${CLAUDE_SKILL_DIR}/tools/tier-guide.mjs --dir <project> --json`.
|
|
|
8
8
|
|
|
9
9
|
Render the returned envelope compactly in the user's conversational language. Never paste the JSON. Keep every path and every command verbatim, each command on its own line so it runs as printed; translate only the prose around them.
|
|
10
10
|
|
|
11
|
-
Keep this order: the tier text (what each level is, the
|
|
11
|
+
Keep this order: the tier text (what each level is, the four story sessions, the two templates, the glossary of their keys, the Recommendations pointer); then every rendered state with its reader, file, cause and next command; then per epic its stage, any placeholder left and the accepted check; then each story in hand with its stage, any placeholder left and its ordered actions; then the epic's own ordered actions (for example the check, the close, or the Cleanup a landed story left over). The first action printed is the next step. Several epics or stories each render; never pick one silently.
|
|
12
12
|
|
|
13
13
|
Exit codes:
|
|
14
14
|
|
|
@@ -35,7 +35,7 @@ Run `node ${CLAUDE_SKILL_DIR}/tools/velocity-profile.mjs [--dry-run | --apply] [
|
|
|
35
35
|
- `node ${CLAUDE_SKILL_DIR}/tools/release-scan.mjs <path>` (wildcard)
|
|
36
36
|
- `node ${CLAUDE_SKILL_DIR}/tools/repo-search.mjs --pattern <literal> --path <p>` (wildcard — the LITERAL search lane; for a pattern carrying a shell-significant byte use `--pattern-file <p>` instead, and for a TARGET PATH carrying one use `--paths-file <p>` — either way the bytes never enter the command string. one of the TWO tier tools that carry hook residual coverage — see the honesty note below)
|
|
37
37
|
- `node ${CLAUDE_SKILL_DIR}/tools/path-inventory.mjs --path <p>` (wildcard — the read-only inventory lane: exists / type / size / `wc -l` lines / one-level listing / small-file contents for N paths in ONE call, so small path questions never need a composed shell. `--paths-file <p>` is its out-of-band target lane; hook residual coverage as with repo-search)
|
|
38
|
-
- `node ${CLAUDE_SKILL_DIR}/tools/review-rounds-cli.mjs --artifact <plan>` (wildcard — the read-only round table over the review receipts,
|
|
38
|
+
- `node ${CLAUDE_SKILL_DIR}/tools/review-rounds-cli.mjs --artifact <plan>` (wildcard — the read-only round table over the review receipts, which `procedures feedback-triage` renders over its record; the path argument is resolved and compared, never opened as a pattern, so it rides the settings-level posture like the rest)
|
|
39
39
|
- `node ${CLAUDE_SKILL_DIR}/tools/control-bytes.mjs --check` (wildcard — the read-only control-byte gate over the work tree: read-only git queries and descriptor-bound reads, no write API; the agent's own hand run before the declared gate runs it)
|
|
40
40
|
- `node ${CLAUDE_SKILL_DIR}/tools/robustness-brief.mjs --plan <plan>` (wildcard — the read-only executor-brief generator over a plan and the kit's shipped literal list; no write API and no process spawn)
|
|
41
41
|
- `node ${CLAUDE_SKILL_DIR}/tools/run-gates.mjs --cwd ${PROJECT_ROOT}` — **EXACT byte-string only**, and honestly **project-exec, not read-only**: it runs YOUR declared `docs/ai/gates.json` commands — the same trust boundary the opt-in hook grants byte-exact per-cmd. A wildcard would be BROADER than that boundary (`--cwd <dir>` executes another project's declared gates), so the bare cwd-defaulting form, any other `--cwd`, `--only`, and **`--final`** forms all still prompt (`--final` WRITES the final-run receipt into the core-evidence store — a recording run is never auto-approved).
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
"has": "The kit-owned checker gates are declared." },
|
|
27
27
|
{ "id": "session-close-rules",
|
|
28
28
|
"story": "S5",
|
|
29
|
-
"has": "The rules your project reads state the session-close value section and
|
|
29
|
+
"has": "The rules your project reads state the session-close value section and the four-session story flow." },
|
|
30
30
|
{ "id": "named-queue-row-seed",
|
|
31
31
|
"story": "S5",
|
|
32
32
|
"has": "A new work queue is seeded with the named row." },
|
|
@@ -21,7 +21,8 @@ revision: 1
|
|
|
21
21
|
## Contract
|
|
22
22
|
|
|
23
23
|
What the feature accepts and returns, stated as invariants a test can pin. A `draft` spec is authored
|
|
24
|
-
|
|
24
|
+
in the session that writes the plan landing the feature and exists at its spec review; approval of
|
|
25
|
+
that plan confirms the
|
|
25
26
|
contract (no separate stop). It becomes `live` on the plan's landing row; `revision` increments by one
|
|
26
27
|
per live contract change; `retired` on the removal row — never backwards.
|
|
27
28
|
|
|
@@ -38,8 +38,8 @@ Before claiming "done":
|
|
|
38
38
|
1. Run all quality gates (lint + type-check + tests) — all green.
|
|
39
39
|
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.
|
|
40
40
|
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`.
|
|
41
|
-
4.
|
|
42
|
-
5.
|
|
41
|
+
4. **Ask before committing** (§4): report lint / type-check / test counts + docs status, then wait for explicit approval. DO NOT auto-commit.
|
|
42
|
+
5. If the work executed a plan file — after the commit, run that plan's final **Phase: Cleanup** (see the planning skill / §5); it changes nothing the review judged. Without it the plan is not done.
|
|
43
43
|
|
|
44
44
|
---
|
|
45
45
|
|
|
@@ -78,15 +78,15 @@ Apply this as part of §2 before any user-facing summary:
|
|
|
78
78
|
### 2.6. Planning, review & process-fidelity invariants
|
|
79
79
|
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.)
|
|
80
80
|
- **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.
|
|
81
|
-
- **Finding scope (plan-execution) — name the invariant BEFORE the edit.** During EXECUTION only — a plan under authoring
|
|
81
|
+
- **Finding scope (plan-execution) — name the invariant BEFORE the edit.** During EXECUTION only — a spec and its plan under authoring have no shipped behaviour to call a live defect in, so the spec review carries none of this. Every finding names the invariant its fix would enforce, and where that invariant already lives decides the disposition: already an acceptance criterion of the phase → **fold here**; it would have to be ADDED → ship the **narrow fix** for the found site (red first, then green) and queue ONLY the generalization — a deferral row carries the invariant, the origin `file:line`, the narrow fix, its proof and a residual exposure declared NOT live; no correct narrow fix → **blocking**: the phase does not close, and it is **never queued**. Two bars declared before each round: a finding counts only if it changes a **WRITE/REMOVE decision** or is a false statement in shipped text; a repeat finding in one subarea **routes to SUBTRACTION**, not a fourth patch.
|
|
82
82
|
- **Right altitude.** Pin intent + invariants + acceptance criteria (named tests); leave fine code-mechanics to Execute, where prose cannot diverge from reality.
|
|
83
|
-
- **Spec-first.** A plan names its GOVERNING spec(s) — zero, one or many, one per touched spec-covered slice (the feature spec under `docs/ai/specs/`; page-only coverage governs as an ADOPTION SHIM, with Out of scope + Revision stated inline in the plan). A ZERO names the adoption state it relies on — `not adopted` (no store) or `adopting` (a store with no live contract), either with a recorded decline, or `nothing spec-covered touched` (a store with live contracts) — a bare zero is never a licence; the store's own state is what `status` and the upgrade advisor report. Each cited spec's Out of scope bounds that slice's work and the plan's non-goals restate it per slice — no global union; a cross-spec conflict is resolved by a spec revision BEFORE approval, never by silent precedence. A NEW feature's draft spec exists AT
|
|
83
|
+
- **Spec-first.** A plan names its GOVERNING spec(s) — zero, one or many, one per touched spec-covered slice (the feature spec under `docs/ai/specs/`; page-only coverage governs as an ADOPTION SHIM, with Out of scope + Revision stated inline in the plan). A ZERO names the adoption state it relies on — `not adopted` (no store) or `adopting` (a store with no live contract), either with a recorded decline, or `nothing spec-covered touched` (a store with live contracts) — a bare zero is never a licence; the store's own state is what `status` and the upgrade advisor report. Each cited spec's Out of scope bounds that slice's work and the plan's non-goals restate it per slice — no global union; a cross-spec conflict is resolved by a spec revision BEFORE approval, never by silent precedence. A NEW feature's draft spec exists AT the spec review (a `create` row); a change to a governed contract rides the plan as its proposed revision (a `modify` row); approval confirms plan and contract atomically, and the revision lands with the code. Scenario bindings are per scenario: a new scenario is `unbound` until its test lands in the same plan, and a status never regresses for an extension.
|
|
84
84
|
- **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.
|
|
85
85
|
- **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.
|
|
86
86
|
- **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.
|
|
87
87
|
- **State table BEFORE the guard — enumerate by PROOF, never by exclusion.** The subtraction rule above fires on a repeat finding, which is a LATE signal: by then the review has paid for each miss. The EARLY signal is structural — a decision whose input has **several independent state dimensions** (is it tracked? do the bytes still match the source? does the neighbouring file exist?). Write the table first, admit the write with **ONE conjunction of proven facts**, and funnel every other cell into a single refusal; the table is then the table-driven test. An exclusion list (`if (bad1) return; if (bad2) return;`) fails **OPEN** on the first state nobody enumerated — and "unreadable" is a state, distinct from "absent". A reviewer cannot save you here: it judges the patch in front of it and can only name the NEXT missing state, one round at a time.
|
|
88
|
-
- **Fold minimally — prose has no checker.**
|
|
89
|
-
- **Heavy review at the diff.**
|
|
88
|
+
- **Fold minimally — prose has no checker.** A spec under the spec review, like the ephemeral plan beside it, is prose with no executable checker; fold **minimally, in ONE place** and run a **self-consistency** read across the spec before every re-review — a fold that drifts several prose spots is what turns a 2-round review into churn.
|
|
89
|
+
- **Heavy review at the diff.** The spec review settles the contract and reads the plan's ledger in the same rounds (≤2 rounds, stop at the pre-existing→fold-induced crossover); the plan has no rounds of its own and is checked by its shape gate, that reading and the approval; the exhaustive review runs against the staged diff of 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**.
|
|
90
90
|
- **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.
|
|
91
91
|
- **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.
|
|
92
92
|
- **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.
|
|
@@ -94,7 +94,7 @@ Apply these when authoring a plan, reviewing, folding a finding, or editing code
|
|
|
94
94
|
- **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).
|
|
95
95
|
|
|
96
96
|
### 2.7. Story sessions
|
|
97
|
-
A story — one row of an epic's ledger, carried by one plan — runs as
|
|
97
|
+
A story — one row of an epic's ledger, carried by one plan — runs as four sessions, each step in them giving one checked result: **spec and plan** (every contract the story creates or revises and the plan's ledger beside them, checked by the spec gate, the plan-shape gate and one review of at most two rounds that reads both, then the plan's approval), **tests** (only tests, each new one failing for the reason its scenario or acceptance bullet states, or on the absence of a name the plan adds, imported inside the test; no code and no prototype), **code** (code until the tests and the pre-review gates pass; a wrong test is changed only back to what its scenario states), and **diff review, release and record** (every committable output, tracked records included, staged first, the review of the staged diff in at most two rounds, the final gates and the release where the story ships one, then the plan's Phase: Cleanup). Tests and code never share a session. A storyless plan runs the same four. **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. A bridge executor gets a task only when it writes new tests or code, from one prompt of the orchestrator; a file the orchestrator already wrote is laid down by the orchestrator, never relayed through a bridge.
|
|
98
98
|
|
|
99
99
|
---
|
|
100
100
|
|