@ikon85/agent-workflow-kit 0.27.1 → 0.29.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/.agents/skills/ask-matt/SKILL.md +2 -2
- package/.agents/skills/board-to-waves/SKILL.md +13 -3
- package/.agents/skills/grill-me/SKILL.md +1 -1
- package/.agents/skills/grill-with-docs/SKILL.md +1 -1
- package/.agents/skills/kit-update/SKILL.md +12 -0
- package/.agents/skills/orchestrate-wave/SKILL.md +68 -21
- package/.agents/skills/orchestrate-wave/references/builder-contract.md +6 -4
- package/.agents/skills/retro/SKILL.md +24 -1
- package/.agents/skills/scale-check/SKILL.md +2 -2
- package/.agents/skills/setup-workflow/SKILL.md +44 -1
- package/.agents/skills/setup-workflow/workflow-overview.md +5 -5
- package/.agents/skills/tdd/SKILL.md +68 -14
- package/.agents/skills/to-issues/SKILL.md +104 -29
- package/.agents/skills/to-prd/SKILL.md +13 -3
- package/.agents/skills/to-waves/SKILL.md +16 -4
- package/.agents/skills/verify-spike/SKILL.md +1 -1
- package/.agents/skills/wrapup/SKILL.md +14 -3
- package/.claude/hooks/drift-guard.py +5 -2
- package/.claude/hooks/kit-origin-edit-hint.py +64 -0
- package/.claude/skills/ask-matt/SKILL.md +2 -2
- package/.claude/skills/board-to-waves/SKILL.md +13 -3
- package/.claude/skills/codex-build/SKILL.md +69 -23
- package/.claude/skills/codex-review/SKILL.md +47 -37
- package/.claude/skills/grill-me/SKILL.md +1 -1
- package/.claude/skills/grill-me-codex/SKILL.md +45 -34
- package/.claude/skills/grill-with-docs/SKILL.md +1 -1
- package/.claude/skills/grill-with-docs-codex/SKILL.md +46 -34
- package/.claude/skills/kit-update/SKILL.md +12 -0
- package/.claude/skills/orchestrate-wave/SKILL.md +68 -21
- package/.claude/skills/orchestrate-wave/references/builder-contract.md +6 -4
- package/.claude/skills/retro/SKILL.md +23 -0
- package/.claude/skills/scale-check/SKILL.md +2 -2
- package/.claude/skills/setup-workflow/SKILL.md +44 -1
- package/.claude/skills/setup-workflow/workflow-overview.md +5 -5
- package/.claude/skills/skill-manifest.json +1 -1
- package/.claude/skills/tdd/SKILL.md +68 -14
- package/.claude/skills/to-issues/SKILL.md +104 -29
- package/.claude/skills/to-prd/SKILL.md +13 -3
- package/.claude/skills/to-waves/SKILL.md +16 -4
- package/.claude/skills/verify-spike/SKILL.md +1 -1
- package/.claude/skills/wrapup/SKILL.md +14 -3
- package/README.md +70 -7
- package/agent-workflow-kit.package.json +99 -43
- package/docs/adr/0001-consumer-divergence-policy.md +49 -0
- package/docs/agents/wave-anchor-template.md +1 -1
- package/docs/research/wave-152-consumer-acceptance.md +98 -0
- package/package.json +1 -1
- package/scripts/board-sync.py +187 -12
- package/scripts/build-kit.test.mjs +42 -1
- package/scripts/codex-exec-scenarios/fake-codex.mjs +152 -0
- package/scripts/codex-exec.sh +566 -0
- package/scripts/codex-exec.test.mjs +815 -0
- package/scripts/codex_proc.py +602 -0
- package/scripts/find-by-marker.py +68 -0
- package/scripts/marker_lib.py +88 -0
- package/scripts/pr-body-check.py +34 -6
- package/scripts/pr_body_e2e.py +83 -0
- package/scripts/render-anchor.py +111 -0
- package/scripts/test_board_sync.py +208 -0
- package/scripts/test_census_backstop.py +56 -3
- package/scripts/test_marker_lib.py +154 -0
- package/scripts/test_orchestrate_wave_contract.py +116 -0
- package/scripts/test_pr_body_check.py +245 -0
- package/scripts/test_render_anchor.py +267 -0
- package/scripts/test_retro_wrapup_contract.py +117 -0
- package/scripts/test_skill_codex_exec_lifecycle.py +123 -0
- package/scripts/test_tdd_contract.py +78 -0
- package/src/cli.mjs +44 -8
- package/src/commands/diff.mjs +5 -2
- package/src/commands/init.mjs +12 -0
- package/src/commands/own.mjs +16 -0
- package/src/commands/uninstall.mjs +8 -1
- package/src/commands/update.mjs +37 -9
- package/src/lib/bundle.mjs +14 -0
- package/src/lib/consumerPath.mjs +30 -0
- package/src/lib/manifest.mjs +18 -0
- package/src/lib/ownedDiff.mjs +88 -0
- package/src/lib/updateCandidate.mjs +14 -0
- package/src/lib/updateReconcile.mjs +45 -6
|
@@ -11,11 +11,13 @@ This is a **deliberate, high-stakes tool** — reach for it on auth, data models
|
|
|
11
11
|
|
|
12
12
|
## Prerequisites (verify once, fast)
|
|
13
13
|
|
|
14
|
-
-
|
|
15
|
-
-
|
|
14
|
+
- Let `scripts/codex-exec.sh` preflight Codex before launch. It enforces the
|
|
15
|
+
exact tested-version allowlist, authentication, platform, and capabilities;
|
|
16
|
+
surface any failure to the user rather than retrying silently.
|
|
16
17
|
- Do NOT pin `-m` unless the user asks. The user's `~/.codex/config.toml` default model is used. Pinning `gpt-5.x-codex` variants fails on ChatGPT-account auth.
|
|
17
18
|
- **Echo the active model before Round 1** so the user can confirm: read the `model` line from `~/.codex/config.toml` (absent = "CLI default"); state it alongside the resolved tunables. If the user objects, stop before burning a round.
|
|
18
|
-
-
|
|
19
|
+
- Use `scripts/codex-exec.sh` for every round. Its `review` profile persists the
|
|
20
|
+
initial `read-only` mode across resumes and rejects mode drift.
|
|
19
21
|
|
|
20
22
|
## Tunable variables (read from skill args, else default)
|
|
21
23
|
|
|
@@ -37,7 +39,7 @@ The invocation itself is the kickoff. Confirm scope in one line: what is being p
|
|
|
37
39
|
|
|
38
40
|
Do real planning: read the relevant code, think through the approach, surface decisions and tradeoffs. Then write the plan to `PLAN_FILE` in this structure:
|
|
39
41
|
|
|
40
|
-
> **Where to write it:** `PLAN.md` + `PLAN-REVIEW-LOG.md` are per-session scratch — write them in the working directory the implementing session will actually use, and
|
|
42
|
+
> **Where to write it:** `PLAN.md` + `PLAN-REVIEW-LOG.md` are per-session scratch — write them in the working directory the implementing session will actually use, and invoke the wrapper from that directory. A project may gitignore these files, so don't rely on git to carry them across checkouts/worktrees. In worktree-based repos, create the issue worktree BEFORE this write and plan inside it.
|
|
41
43
|
|
|
42
44
|
```markdown
|
|
43
45
|
# Plan: <task>
|
|
@@ -69,60 +71,66 @@ Show the user the plan inline and say you're sending it to Codex for adversarial
|
|
|
69
71
|
|
|
70
72
|
### Step 2 — The loop
|
|
71
73
|
|
|
72
|
-
Maintain `ROUND` (start 1) and
|
|
74
|
+
Maintain `ROUND` (start 1) and the wrapper's opaque `RUN_ID`.
|
|
73
75
|
|
|
74
76
|
**The review prompt** sent to Codex each round (adjust the task line):
|
|
75
77
|
|
|
76
78
|
> You are an adversarial reviewer for an implementation plan. Be skeptical and specific — your job is to find what breaks, not to be agreeable. Read the plan at `PLAN.md` (and any repo files you need; you are read-only). Identify concrete flaws: security holes, race conditions, missing edge cases, schema conflicts, wrong assumptions, observability gaps, simpler alternatives. For each, give a one-line fix. Do NOT modify any files. End your reply with EXACTLY one line: `VERDICT: APPROVED` if the plan is sound enough to implement, or `VERDICT: REVISE` if it still has material problems.
|
|
77
79
|
|
|
78
|
-
**Round 1**
|
|
79
|
-
|
|
80
|
-
Stream `--json` to a FILE, never pipe to `grep` — `codex exec --json | grep` deadlocks on codex-cli ≥0.137. **Always launch with `< /dev/null`** — a backgrounded `codex exec … &` without it blocks on stdin and sits at **0 CPU / 0 bytes** forever (the #1 cause of the "silent hang"; verified 2026-06-09). Background it so a **90s liveness probe** still catches a genuine sandbox deadlock.
|
|
80
|
+
**Round 1** creates the session and returns the opaque run ID plus the report:
|
|
81
81
|
|
|
82
82
|
```bash
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
BYTES=$(wc -c < $CODEX_TMP/r1.jsonl 2>/dev/null || echo 0)
|
|
91
|
-
if [ "${CPU:-00:00:00}" = "00:00:00" ] && [ "${BYTES:-0}" -eq 0 ]; then
|
|
92
|
-
kill -9 "$CODEX_PID" 2>/dev/null; echo "CODEX-HUNG" # alive + 0 CPU + 0 bytes = blocked, NOT working
|
|
93
|
-
fi
|
|
83
|
+
if ROUND_RESULT=$(scripts/codex-exec.sh new --profile review --mode read-only --prompt "$REVIEW_PROMPT"); then
|
|
84
|
+
RUN_ID=$(printf '%s\n' "$ROUND_RESULT" | python3 -c 'import json,sys; print(json.load(sys.stdin)["runId"])')
|
|
85
|
+
CODEX_REPORT=$(printf '%s\n' "$ROUND_RESULT" | python3 -c 'import json,sys; print(json.load(sys.stdin)["verdict"])')
|
|
86
|
+
else
|
|
87
|
+
FAILURE_RESULT=$(scripts/codex-exec.sh handle-failure --result "$ROUND_RESULT") || :
|
|
88
|
+
printf '%s\n' "$FAILURE_RESULT" >&2
|
|
89
|
+
exit 1
|
|
94
90
|
fi
|
|
95
|
-
wait "$CODEX_PID" 2>/dev/null
|
|
96
|
-
THREAD_ID=$(grep -o '"thread_id":"[^"]*"' $CODEX_TMP/r1.jsonl | head -1 | cut -d'"' -f4)
|
|
97
91
|
```
|
|
98
|
-
- **`CODEX-HUNG` printed** (alive + 0 CPU + 0 bytes at 90s) → **first suspect the stdin block**: confirm the launch has `< /dev/null` and retry. That fixes it in nearly every case. **NEVER `pgrep`/`kill` codex procs to "clear contention"** — that murders the user's live, unrelated codex sessions and does **not** fix a stdin hang. Only if `< /dev/null` is present and it still hangs (genuine sandbox deadlock) → **STOP**: tell the user, offer to proceed without the cross-model review or retry once. Don't touch other codex processes.
|
|
99
|
-
- **Healthy:** CPU climbs past `00:00:00` and/or `$CODEX_TMP/r1.jsonl` grows; `THREAD_ID` parses; critique lands in `$CODEX_TMP/verdict.txt`. `2>/dev/null` hides cosmetic MCP/auth noise.
|
|
100
|
-
- **Clean finish but no verdict file + no `THREAD_ID`** = auth/model failure → stop, tell the user.
|
|
101
92
|
|
|
102
|
-
**Rounds 2..MAX**
|
|
93
|
+
**Rounds 2..MAX** resume the same wrapper-owned session; do not pass a mode
|
|
94
|
+
again because the wrapper enforces the persisted read-only mode:
|
|
103
95
|
|
|
104
96
|
```bash
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
codex
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
97
|
+
if ROUND_RESULT=$(scripts/codex-exec.sh resume "$RUN_ID" --prompt "I revised the plan. Re-review PLAN.md. Same rules. End with VERDICT: APPROVED or VERDICT: REVISE."); then
|
|
98
|
+
CODEX_REPORT=$(printf '%s\n' "$ROUND_RESULT" | python3 -c 'import json,sys; print(json.load(sys.stdin)["verdict"])')
|
|
99
|
+
else
|
|
100
|
+
FAILURE_RESULT=$(scripts/codex-exec.sh handle-failure --result "$ROUND_RESULT" --run-id "$RUN_ID") || :
|
|
101
|
+
printf '%s\n' "$FAILURE_RESULT" >&2
|
|
102
|
+
exit 1
|
|
103
|
+
fi
|
|
112
104
|
```
|
|
113
|
-
Wrap resume in the **same 90s liveness probe** (background + `wait`). Resume discards the `--json` stream, so probe on the verdict file: `BYTES=$(wc -c < $CODEX_TMP/verdict.txt)` plus the `CPU` check — `00:00:00` CPU + empty verdict at 90s → kill, treat as `CODEX-HUNG`, same STOP path as round 1.
|
|
114
105
|
|
|
115
|
-
|
|
106
|
+
The wrapper owns stdin closure, hang detection, the overall timeout, stderr
|
|
107
|
+
redaction, and its process group. `handle-failure` surfaces the structured
|
|
108
|
+
status and cleanup metadata, then the caller stops before report handling. A
|
|
109
|
+
surfaced `HUNG` returns to the user for the choice to retry once with a fresh
|
|
110
|
+
run or continue without cross-model review. Never inspect, signal, or kill
|
|
111
|
+
foreign Codex processes.
|
|
112
|
+
|
|
113
|
+
Separately, cancellation or a decision to stop orchestration after an OK round
|
|
114
|
+
but before normal finalize must abort the known run:
|
|
116
115
|
|
|
117
|
-
|
|
116
|
+
```bash
|
|
117
|
+
scripts/codex-exec.sh abort "$RUN_ID"
|
|
118
|
+
```
|
|
118
119
|
|
|
119
120
|
**Each round, after Codex returns:**
|
|
120
|
-
1. Read
|
|
121
|
+
1. Read `CODEX_REPORT`. Append to `LOG_FILE`: `## Round <n> — Codex` + the full critique.
|
|
121
122
|
2. Grep the last line for the verdict token.
|
|
122
123
|
- `VERDICT: APPROVED` → break the loop, go to Step 3 (converged).
|
|
123
124
|
- `VERDICT: REVISE` → Claude reads the critique, decides **what's actually worth acting on** (Claude has final say — Codex advises, it does not command). Revise `PLAN_FILE`. Append to `LOG_FILE`: `### Claude's response` + what you changed and what you rejected and why. Increment `ROUND`.
|
|
124
125
|
3. If `ROUND > MAX_ROUNDS` → break to Step 3 (deadlock).
|
|
125
126
|
|
|
127
|
+
After harvesting the final report and updating the log, delete the successful
|
|
128
|
+
run state:
|
|
129
|
+
|
|
130
|
+
```bash
|
|
131
|
+
scripts/codex-exec.sh finalize "$RUN_ID"
|
|
132
|
+
```
|
|
133
|
+
|
|
126
134
|
### Step 3 — Resolution (human gate #2)
|
|
127
135
|
|
|
128
136
|
**If APPROVED:** Present to the user — the final `PLAN_FILE`, a 3-bullet summary of what the argument improved, and the round count. Ask: *"Plan survived N rounds of Codex. Implement it now — Codex builds it (`/codex-build`), Claude builds it, or stop here?"* Only on a yes is code written. **No code is written during the loop.** If the user picks Codex, invoke the `codex-build` skill with `SPEC_FILE=PLAN.md` and the same `LOG_FILE` — roles flip (Codex writes in a bounded workspace-write sandbox, Claude reviews the diff) and the build rounds append to the same log.
|
|
@@ -131,7 +139,9 @@ Both `codex exec` and `codex exec resume` support `--json` (stream → parse `th
|
|
|
131
139
|
|
|
132
140
|
## Hard rules
|
|
133
141
|
|
|
134
|
-
- Codex is read-only EVERY round
|
|
142
|
+
- Codex is read-only EVERY round. Establish that once with the wrapper's
|
|
143
|
+
`review` + `read-only` new call; every resume inherits it. If you're tempted
|
|
144
|
+
to give it write access, stop — that's a different skill.
|
|
135
145
|
- The loop ALWAYS terminates at `MAX_ROUNDS`. No unbounded recursion.
|
|
136
146
|
- Claude is the final arbiter on every REVISE — incorporate good critiques, reject bad ones *with a reason logged*. Don't cave to Codex on everything (that defeats the cross-model check) and don't ignore it (that defeats the point).
|
|
137
147
|
- Code only after human gate #2.
|
|
@@ -48,7 +48,7 @@ Once all decisions are made (plan locked, before sign-off/handoff) and the sessi
|
|
|
48
48
|
|
|
49
49
|
## Re-grill reconcile — execute-ready (Wave 26)
|
|
50
50
|
|
|
51
|
-
Applies when you **re-grill an issue that already exists** (a leaf of a grilled epic, or a child of an anchor) — the most common re-grill path, since campaign HITL slices route via `/grill-me → /
|
|
51
|
+
Applies when you **re-grill an issue that already exists** (a leaf of a grilled epic, or a child of an anchor) — the most common re-grill path, since campaign HITL slices route via `/grill-me → /implement`. Goal: the rooted sub-graph comes out **execute-ready**, never silent drift. (grill-me has no docs layer — CONTEXT.md/ADR don't apply; core rules identical to grill-with-docs §"Re-Grill Reconcile".)
|
|
52
52
|
|
|
53
53
|
1. **Read parent-anchor decisions FIRST** — fetch the anchor body + its PRD/key decisions, take the seam decision **from there**. Do not re-derive the architecture from the leaf (lesson: a leaf whose central decision was never read got re-litigated through question rounds). For an atomic leaf, its own body/PRD is the reference.
|
|
54
54
|
2. **Check the leaf for internal contradiction**: a body that contradicts itself ("no new UI" + "build a name field") or the anchor decision → **no execute**. Likewise a leaf that says *"final cut depends on #X"* via `<!-- final-cut-depends-on: #X -->` where **#X is closed** without resolving the cut.
|
|
@@ -41,7 +41,7 @@ For a cross-cutting plan, run `python3 .claude/hooks/drift-guard.py --census-sta
|
|
|
41
41
|
|
|
42
42
|
When the decision tree is resolved and we're aligned, **write the agreed plan to `PLAN.md`** in this structure, then move to Act 2:
|
|
43
43
|
|
|
44
|
-
> **Where to write it:** `PLAN.md` + `PLAN-REVIEW-LOG.md` are per-session scratch — write them in the working directory the implementing session will actually use, and
|
|
44
|
+
> **Where to write it:** `PLAN.md` + `PLAN-REVIEW-LOG.md` are per-session scratch — write them in the working directory the implementing session will actually use, and invoke the wrapper from that directory. A project may gitignore these files, so don't rely on git to carry them across checkouts/worktrees. In worktree-based repos, create the issue worktree BEFORE this write and plan inside it.
|
|
45
45
|
|
|
46
46
|
```markdown
|
|
47
47
|
# Plan: <task>
|
|
@@ -76,8 +76,9 @@ Act 1 (grill) complete — plan locked with the user. MAX_ROUNDS=<n>.
|
|
|
76
76
|
Now hand the locked plan to Codex for adversarial review. Same engine, mechanics verified end-to-end (2026-06-04).
|
|
77
77
|
|
|
78
78
|
### Prerequisites (verify once, fast)
|
|
79
|
-
- `codex
|
|
80
|
-
-
|
|
79
|
+
- Let `scripts/codex-exec.sh` preflight Codex before launch. It enforces the
|
|
80
|
+
exact tested-version allowlist, authentication, platform, and capabilities;
|
|
81
|
+
surface any failure rather than retrying silently.
|
|
81
82
|
- Do NOT pin `-m`. Use the config default. Pinning `gpt-5.x-codex` variants 400s on ChatGPT-account auth.
|
|
82
83
|
- **Echo the active model before Round 1** so the user can confirm: read the `model` line from `~/.codex/config.toml` (absent = "CLI default"); state it alongside the resolved tunables. If the user objects, stop before burning a round.
|
|
83
84
|
|
|
@@ -93,50 +94,59 @@ If invoked with e.g. `rounds=3`, use that for `MAX_ROUNDS`. Echo resolved values
|
|
|
93
94
|
### The review prompt (sent each round)
|
|
94
95
|
> You are an adversarial reviewer for an implementation plan. Be skeptical and specific — your job is to find what breaks, not to be agreeable. Read the plan at `PLAN.md` and any repo files you need (you are read-only). Identify concrete flaws: security holes, race conditions, missing edge cases, schema conflicts, wrong assumptions, observability gaps, simpler alternatives. For each, give a one-line fix. Do NOT modify any files. End your reply with EXACTLY one line: `VERDICT: APPROVED` if the plan is sound enough to implement, or `VERDICT: REVISE` if it still has material problems.
|
|
95
96
|
|
|
96
|
-
### Round 1 — fresh session
|
|
97
|
-
|
|
97
|
+
### Round 1 — fresh wrapper-owned session
|
|
98
|
+
|
|
98
99
|
```bash
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
BYTES=$(wc -c < $CODEX_TMP/r1.jsonl 2>/dev/null || echo 0)
|
|
107
|
-
if [ "${CPU:-00:00:00}" = "00:00:00" ] && [ "${BYTES:-0}" -eq 0 ]; then
|
|
108
|
-
kill -9 "$CODEX_PID" 2>/dev/null; echo "CODEX-HUNG" # alive + 0 CPU + 0 bytes = blocked, NOT working
|
|
109
|
-
fi
|
|
100
|
+
if ROUND_RESULT=$(scripts/codex-exec.sh new --profile review --mode read-only --prompt "$REVIEW_PROMPT"); then
|
|
101
|
+
RUN_ID=$(printf '%s\n' "$ROUND_RESULT" | python3 -c 'import json,sys; print(json.load(sys.stdin)["runId"])')
|
|
102
|
+
CODEX_REPORT=$(printf '%s\n' "$ROUND_RESULT" | python3 -c 'import json,sys; print(json.load(sys.stdin)["verdict"])')
|
|
103
|
+
else
|
|
104
|
+
FAILURE_RESULT=$(scripts/codex-exec.sh handle-failure --result "$ROUND_RESULT") || :
|
|
105
|
+
printf '%s\n' "$FAILURE_RESULT" >&2
|
|
106
|
+
exit 1
|
|
110
107
|
fi
|
|
111
|
-
wait "$CODEX_PID" 2>/dev/null
|
|
112
|
-
THREAD_ID=$(grep -o '"thread_id":"[^"]*"' $CODEX_TMP/r1.jsonl | head -1 | cut -d'"' -f4)
|
|
113
108
|
```
|
|
114
|
-
- **`CODEX-HUNG` printed** (alive + 0 CPU + 0 bytes at 90s) → **first suspect the stdin block**: confirm the launch has `< /dev/null` and retry. That fixes it in nearly every case. **NEVER `pgrep`/`kill` codex procs to "clear contention"** — that murders the user's live, unrelated codex sessions and does **not** fix a stdin hang. Only if `< /dev/null` is present and it still hangs (genuine sandbox deadlock) → **STOP Act 2**: tell the user, offer to sign off without the cross-model review or retry once. Don't touch other codex processes.
|
|
115
|
-
- **Healthy:** CPU climbs past `00:00:00` and/or `$CODEX_TMP/r1.jsonl` grows; `THREAD_ID` parses; critique lands in `$CODEX_TMP/verdict.txt`. `2>/dev/null` hides cosmetic MCP/auth noise.
|
|
116
|
-
- **Clean finish but no verdict file + no `THREAD_ID`** = auth/model failure → stop, tell the user.
|
|
117
109
|
|
|
118
|
-
### Rounds 2..MAX — resume the SAME session
|
|
110
|
+
### Rounds 2..MAX — resume the SAME session
|
|
111
|
+
|
|
119
112
|
```bash
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
< /dev/null 2>/dev/null >/dev/null &
|
|
113
|
+
if ROUND_RESULT=$(scripts/codex-exec.sh resume "$RUN_ID" --prompt "I revised the plan. Re-review PLAN.md — check whether your prior findings are addressed and flag anything new. End with VERDICT: APPROVED or VERDICT: REVISE."); then
|
|
114
|
+
CODEX_REPORT=$(printf '%s\n' "$ROUND_RESULT" | python3 -c 'import json,sys; print(json.load(sys.stdin)["verdict"])')
|
|
115
|
+
else
|
|
116
|
+
FAILURE_RESULT=$(scripts/codex-exec.sh handle-failure --result "$ROUND_RESULT" --run-id "$RUN_ID") || :
|
|
117
|
+
printf '%s\n' "$FAILURE_RESULT" >&2
|
|
118
|
+
exit 1
|
|
119
|
+
fi
|
|
128
120
|
```
|
|
129
|
-
Wrap resume in the **same 90s liveness probe** (background + `wait`). Resume discards the `--json` stream, so probe on the verdict file: `BYTES=$(wc -c < $CODEX_TMP/verdict.txt)` plus the `CPU` check — `00:00:00` CPU + empty verdict at 90s → kill, treat as `CODEX-HUNG`, same STOP path as round 1. Both `codex exec` and `codex exec resume` support `--json` and `-o/--output-last-message`.
|
|
130
121
|
|
|
131
|
-
|
|
122
|
+
The wrapper persists read-only mode and owns stdin closure, hang detection, the
|
|
123
|
+
overall timeout, stderr redaction, and its process group. `handle-failure`
|
|
124
|
+
surfaces the structured status and cleanup metadata, then the caller stops
|
|
125
|
+
before report handling. A surfaced `HUNG` returns to the user for the choice to
|
|
126
|
+
retry once with a fresh run or sign off without cross-model review. Never
|
|
127
|
+
inspect, signal, or kill foreign Codex processes.
|
|
128
|
+
|
|
129
|
+
Separately, cancellation or a decision to stop orchestration after an OK round
|
|
130
|
+
but before normal finalize must abort the known run:
|
|
131
|
+
|
|
132
|
+
```bash
|
|
133
|
+
scripts/codex-exec.sh abort "$RUN_ID"
|
|
134
|
+
```
|
|
132
135
|
|
|
133
136
|
### Each round, after Codex returns
|
|
134
|
-
1. Read
|
|
137
|
+
1. Read `CODEX_REPORT`; append to `LOG_FILE`: `## Round <n> — Codex` + the full critique.
|
|
135
138
|
2. Grep the last line for the verdict:
|
|
136
139
|
- `VERDICT: APPROVED` → break to Resolution (converged).
|
|
137
140
|
- `VERDICT: REVISE` → Claude decides **what's actually worth acting on** (Claude is final arbiter — Codex advises, doesn't command). Revise `PLAN_FILE`. Append `### Claude's response` to `LOG_FILE`: what changed, what was rejected, why. Increment round.
|
|
138
141
|
3. If round > `MAX_ROUNDS` → break to Resolution (deadlock).
|
|
139
142
|
|
|
143
|
+
After harvesting the final report and updating the log, delete the successful
|
|
144
|
+
run state:
|
|
145
|
+
|
|
146
|
+
```bash
|
|
147
|
+
scripts/codex-exec.sh finalize "$RUN_ID"
|
|
148
|
+
```
|
|
149
|
+
|
|
140
150
|
### Resolution (you sign off — final gate)
|
|
141
151
|
- **APPROVED:** present the final `PLAN_FILE`, a 3-bullet summary of what the two acts improved, and the round count. Ask: *"Grilled + survived N rounds of Codex. Implement it now — Codex builds it (`/codex-build`), Claude builds it, or stop here?"* Code only on a yes. **No code is written during either act.**
|
|
142
152
|
- **MAX_ROUNDS hit without APPROVED (deadlock):** do NOT fake convergence. List each unresolved point + Claude's counter-position; hand it to the user to break the tie. A flagged disagreement beats a false "approved."
|
|
@@ -149,7 +159,8 @@ If the user picks Codex: invoke the `codex-build` skill with `SPEC_FILE=PLAN.md`
|
|
|
149
159
|
|
|
150
160
|
## Hard rules
|
|
151
161
|
- Act 1 always precedes Act 2 — don't write `PLAN.md` until the grill has actually resolved the decision tree with the user.
|
|
152
|
-
- Codex is read-only EVERY round —
|
|
162
|
+
- Codex is read-only EVERY round — establish it once through the wrapper's
|
|
163
|
+
`review` + `read-only` new call; every resume inherits it.
|
|
153
164
|
- The loop ALWAYS terminates at `MAX_ROUNDS`.
|
|
154
165
|
- Claude is final arbiter on every REVISE — incorporate good critiques, reject bad ones *with a logged reason*. Don't cave to everything (defeats the cross-model check) and don't ignore it (defeats the point).
|
|
155
166
|
- Code only after the user's final sign-off.
|
|
@@ -136,6 +136,6 @@ Triggers when you **re-grill an issue that already exists in the graph** (a leaf
|
|
|
136
136
|
2. **Check the leaf for internal contradiction** (Fix B): a body that contradicts itself ("no new UI" + "build a name field") or the anchor decision → **no execute**. Likewise a leaf that says *"final cut depends on #X"* via `<!-- final-cut-depends-on: #X -->` where **#X is closed** without resolving the cut.
|
|
137
137
|
3. **On drift/contradiction:** update the affected issue(s), re-stamp `plan_revision`, set the correct bucket. An internal contradiction → set the leaf to **HITL** (remove `ready-for-agent`, add the `headings.vorBau` heading — board profile `docs/agents/board-sync.md`; <project> currently `## Vor Bau zu klären`); the drift-guard then blocks a build-handoff via `target_buildable`. So the contradiction flows through existing machinery — no semantic heuristic in the hook.
|
|
138
138
|
4. **Audit, non-blocking:** `python3 scripts/execute-ready-check.py --issue <n> --mode audit` → visible two-liner. The **blocking** net is the drift-guard at handoff (`.claude/hooks/drift-guard.py`).
|
|
139
|
-
5. **Global `-codex` variant** can't change the repo → leave a pointer note ("reconcile the issues + re-stamp plan_revision, repo-side"); real enforcement = the repo hook. **Honest bound:** the hook fires at the handoff/session boundary, not at a "grill-exit" event; a same-session global-codex grill → direct `/
|
|
139
|
+
5. **Global `-codex` variant** can't change the repo → leave a pointer note ("reconcile the issues + re-stamp plan_revision, repo-side"); real enforcement = the repo hook. **Honest bound:** the hook fires at the handoff/session boundary, not at a "grill-exit" event; a same-session global-codex grill → direct `/implement` (no handoff) is a documented residual (global follow-up).
|
|
140
140
|
|
|
141
141
|
**Markers used here** (HTML comments, grep-able): `<!-- guard-ack: #<n> r<N> reason:<text> by-user -->` (deliberate handoff override), `<!-- final-cut-depends-on: #<n> -->`, `<!-- handoff-intent: build|grill -->`, `<!-- guard-legacy -->` (grandfathered legacy-anchor → warn not block). **Canonical table of all markers:** module docstring of `scripts/execute-ready-check.py`.
|
|
@@ -125,7 +125,7 @@ For a cross-cutting plan, run `python3 .claude/hooks/drift-guard.py --census-sta
|
|
|
125
125
|
|
|
126
126
|
When the decision tree is resolved, the glossary/ADRs are updated, and we're aligned, **write the agreed plan to `PLAN.md`** (use the canonical terms from `CONTEXT.md`), then run Act 2:
|
|
127
127
|
|
|
128
|
-
> **Where to write it:** `PLAN.md` + `PLAN-REVIEW-LOG.md` are per-session scratch — write them in the working directory the implementing session will actually use, and
|
|
128
|
+
> **Where to write it:** `PLAN.md` + `PLAN-REVIEW-LOG.md` are per-session scratch — write them in the working directory the implementing session will actually use, and invoke the wrapper from that directory. A project may gitignore these files, so don't rely on git to carry them across checkouts/worktrees. In worktree-based repos, create the issue worktree BEFORE this write and plan inside it.
|
|
129
129
|
|
|
130
130
|
```markdown
|
|
131
131
|
# Plan: <task>
|
|
@@ -160,8 +160,9 @@ Act 1 (grill-with-docs) complete — plan locked, CONTEXT.md/ADRs updated. MAX_R
|
|
|
160
160
|
Hand the locked plan to Codex for adversarial review. Mechanics verified end-to-end (2026-06-04).
|
|
161
161
|
|
|
162
162
|
### Prerequisites
|
|
163
|
-
- `codex
|
|
164
|
-
-
|
|
163
|
+
- Let `scripts/codex-exec.sh` preflight Codex before launch. It enforces the
|
|
164
|
+
exact tested-version allowlist, authentication, platform, and capabilities;
|
|
165
|
+
surface any failure rather than retrying silently.
|
|
165
166
|
- Do NOT pin `-m` (config default is used; `gpt-5.x-codex` variants 400 on ChatGPT-account auth).
|
|
166
167
|
- **Echo the active model before Round 1** so the user can confirm: read the `model` line from `~/.codex/config.toml` (absent = "CLI default"); state it alongside the resolved tunables. If the user objects, stop before burning a round.
|
|
167
168
|
|
|
@@ -177,48 +178,57 @@ Invoked with e.g. `rounds=3` → use it. Echo resolved values first.
|
|
|
177
178
|
### Review prompt (each round)
|
|
178
179
|
> You are an adversarial reviewer for an implementation plan. Be skeptical and specific — your job is to find what breaks, not to be agreeable. Read the plan at `PLAN.md` (and `CONTEXT.md`/ADRs for the domain language) and any repo files you need (you are read-only). Identify concrete flaws: security holes, race conditions, missing edge cases, schema conflicts, domain-language mismatches, wrong assumptions, observability gaps, simpler alternatives. For each, give a one-line fix. Do NOT modify any files. End with EXACTLY one line: `VERDICT: APPROVED` or `VERDICT: REVISE`.
|
|
179
180
|
|
|
180
|
-
### Round 1 — fresh session
|
|
181
|
-
|
|
181
|
+
### Round 1 — fresh wrapper-owned session
|
|
182
|
+
|
|
182
183
|
```bash
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
BYTES=$(wc -c < $CODEX_TMP/r1.jsonl 2>/dev/null || echo 0)
|
|
191
|
-
if [ "${CPU:-00:00:00}" = "00:00:00" ] && [ "${BYTES:-0}" -eq 0 ]; then
|
|
192
|
-
kill -9 "$CODEX_PID" 2>/dev/null; echo "CODEX-HUNG" # alive + 0 CPU + 0 bytes = blocked, NOT working
|
|
193
|
-
fi
|
|
184
|
+
if ROUND_RESULT=$(scripts/codex-exec.sh new --profile review --mode read-only --prompt "$REVIEW_PROMPT"); then
|
|
185
|
+
RUN_ID=$(printf '%s\n' "$ROUND_RESULT" | python3 -c 'import json,sys; print(json.load(sys.stdin)["runId"])')
|
|
186
|
+
CODEX_REPORT=$(printf '%s\n' "$ROUND_RESULT" | python3 -c 'import json,sys; print(json.load(sys.stdin)["verdict"])')
|
|
187
|
+
else
|
|
188
|
+
FAILURE_RESULT=$(scripts/codex-exec.sh handle-failure --result "$ROUND_RESULT") || :
|
|
189
|
+
printf '%s\n' "$FAILURE_RESULT" >&2
|
|
190
|
+
exit 1
|
|
194
191
|
fi
|
|
195
|
-
wait "$CODEX_PID" 2>/dev/null
|
|
196
|
-
THREAD_ID=$(grep -o '"thread_id":"[^"]*"' $CODEX_TMP/r1.jsonl | head -1 | cut -d'"' -f4)
|
|
197
192
|
```
|
|
198
|
-
- **`CODEX-HUNG` printed** (alive + 0 CPU + 0 bytes at 90s) → **first suspect the stdin block**: confirm the launch has `< /dev/null` and retry. That fixes it in nearly every case (verified 2026-06-09). **NEVER `pgrep`/`kill` codex procs to "clear contention"** — that murders the user's live, unrelated codex sessions and does **not** fix a stdin hang. If `< /dev/null` is already present and it still hangs (genuine sandbox deadlock) → **STOP Act 2**: append the hang to `LOG_FILE`, tell the user, and offer to (a) proceed to sign-off **without** the cross-model review, or (b) retry once more. Do **not** keep waiting minutes, and do **not** touch other codex processes.
|
|
199
|
-
- **Healthy:** CPU climbs past `00:00:00` and/or `$CODEX_TMP/r1.jsonl` grows; `THREAD_ID` parses; critique lands in `$CODEX_TMP/verdict.txt`.
|
|
200
|
-
- **Clean finish but no verdict file + no `THREAD_ID`** = auth/model failure → stop, tell the user. `2>/dev/null` hides cosmetic MCP/auth noise.
|
|
201
193
|
|
|
202
194
|
### Rounds 2..MAX — resume SAME session
|
|
195
|
+
|
|
203
196
|
```bash
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
< /dev/null 2>/dev/null >/dev/null &
|
|
197
|
+
if ROUND_RESULT=$(scripts/codex-exec.sh resume "$RUN_ID" --prompt "I revised the plan. Re-review PLAN.md — check prior findings + flag anything new. End with VERDICT: APPROVED or VERDICT: REVISE."); then
|
|
198
|
+
CODEX_REPORT=$(printf '%s\n' "$ROUND_RESULT" | python3 -c 'import json,sys; print(json.load(sys.stdin)["verdict"])')
|
|
199
|
+
else
|
|
200
|
+
FAILURE_RESULT=$(scripts/codex-exec.sh handle-failure --result "$ROUND_RESULT" --run-id "$RUN_ID") || :
|
|
201
|
+
printf '%s\n' "$FAILURE_RESULT" >&2
|
|
202
|
+
exit 1
|
|
203
|
+
fi
|
|
212
204
|
```
|
|
213
|
-
Wrap resume in the **same 90s liveness probe** (background + `wait`). Resume discards the `--json` stream, so probe on the verdict file instead: `BYTES=$(wc -c < $CODEX_TMP/verdict.txt)` plus the `CPU` check — `00:00:00` CPU + empty verdict at 90s → kill, treat as `CODEX-HUNG`, same STOP path as round 1.
|
|
214
205
|
|
|
215
|
-
|
|
206
|
+
The wrapper persists read-only mode and owns stdin closure, hang detection, the
|
|
207
|
+
overall timeout, stderr redaction, and its process group. `handle-failure`
|
|
208
|
+
surfaces the structured status and cleanup metadata for `LOG_FILE`, then the
|
|
209
|
+
caller stops before report handling. A surfaced `HUNG` returns to the user for
|
|
210
|
+
the choice to retry once with a fresh run or proceed without cross-model
|
|
211
|
+
review. Never inspect, signal, or kill foreign Codex processes.
|
|
212
|
+
|
|
213
|
+
Separately, cancellation or a decision to stop orchestration after an OK round
|
|
214
|
+
but before normal finalize must abort the known run:
|
|
215
|
+
|
|
216
|
+
```bash
|
|
217
|
+
scripts/codex-exec.sh abort "$RUN_ID"
|
|
218
|
+
```
|
|
216
219
|
|
|
217
220
|
### Each round
|
|
218
|
-
1. Read
|
|
221
|
+
1. Read `CODEX_REPORT`; append `## Round <n> — Codex` + critique to `LOG_FILE`.
|
|
219
222
|
2. Last line verdict: `APPROVED` → Resolution (converged); `REVISE` → Claude decides what's worth acting on (final arbiter), revise `PLAN_FILE`, append `### Claude's response` (what changed/rejected + why), increment.
|
|
220
223
|
3. round > `MAX_ROUNDS` → Resolution (deadlock).
|
|
221
224
|
|
|
225
|
+
After harvesting the final report and updating the log, delete the successful
|
|
226
|
+
run state:
|
|
227
|
+
|
|
228
|
+
```bash
|
|
229
|
+
scripts/codex-exec.sh finalize "$RUN_ID"
|
|
230
|
+
```
|
|
231
|
+
|
|
222
232
|
### Resolution (you sign off)
|
|
223
233
|
- **APPROVED:** present final plan + 3-bullet summary of what the two acts improved + round count. Ask: implement now — Codex builds it (`/codex-build`), Claude builds it, or stop? No code during either act.
|
|
224
234
|
- **Deadlock (cap hit, no APPROVED):** list unresolved points + Claude's counter-position; hand to user. Don't fake convergence.
|
|
@@ -228,9 +238,11 @@ Wrap resume in the **same 90s liveness probe** (background + `wait`). Resume dis
|
|
|
228
238
|
|
|
229
239
|
## Hard rules
|
|
230
240
|
- Act 1 precedes Act 2. `CONTEXT.md` stays a glossary only — no implementation details.
|
|
231
|
-
- Codex read-only EVERY round
|
|
241
|
+
- Codex is read-only EVERY round — establish it once through the wrapper's
|
|
242
|
+
`review` + `read-only` new call; every resume inherits it.
|
|
232
243
|
- Loop ALWAYS terminates at `MAX_ROUNDS`. Claude is final arbiter on REVISE (reject with logged reason). Code only after sign-off. `LOG_FILE` is the deliverable.
|
|
233
|
-
-
|
|
244
|
+
- A `HUNG` wrapper result always returns to the user for the proceed-without or
|
|
245
|
+
retry-once choice.
|
|
234
246
|
|
|
235
247
|
## What NOT to do
|
|
236
248
|
- Don't review already-written code (`/codex:review`). Don't pin `-codex` variants on ChatGPT auth. Don't let Codex edit files. Don't skip Act 1.
|
|
@@ -40,6 +40,18 @@ release contain the same artifact.
|
|
|
40
40
|
conflict manually; never auto-merge, delete a local edit, or silently choose
|
|
41
41
|
the incoming copy.
|
|
42
42
|
|
|
43
|
+
For each conflicted kit-shipped file, always ask the user whether the local
|
|
44
|
+
edit is a generic improvement or project-specific; never decide or act
|
|
45
|
+
automatically. For a generic improvement, offer to file an issue in the
|
|
46
|
+
public kit repository and keep the local edit in place as a bridge until a
|
|
47
|
+
kit release containing the improvement lands. Before running
|
|
48
|
+
`gh issue create --repo <owner>/agent-workflow-kit`, show a sanitized preview
|
|
49
|
+
of the exact title and body with consumer identifiers and secrets stripped,
|
|
50
|
+
then require the user's explicit approval. The consumer user does not need
|
|
51
|
+
to be a kit maintainer. For a project-specific edit, recommend
|
|
52
|
+
`npx @ikon85/agent-workflow-kit@latest own <path>` so future updates treat
|
|
53
|
+
that path as consumer-owned.
|
|
54
|
+
|
|
43
55
|
4. If a candidate is interrupted, discard its reported stage directory or
|
|
44
56
|
resume the transaction through the update API's `resumeFrom` option. Do not
|
|
45
57
|
copy staged files into the consumer by hand.
|
|
@@ -7,7 +7,7 @@ description: >-
|
|
|
7
7
|
delegates wave-landing responsibility to you), "ultracode diese Welle / diesen
|
|
8
8
|
Cluster", or a wave-anchor issue (a cluster/umbrella issue with file-disjoint
|
|
9
9
|
sub-issues whose specs are already locked) handed over to land. NOT for a single
|
|
10
|
-
slice (just `
|
|
10
|
+
slice (just `implement` it), NOT for finding/clustering a wave (that's `board-to-waves`),
|
|
11
11
|
NOT for planning specs (that's `grill-with-docs`/`to-issues`).
|
|
12
12
|
---
|
|
13
13
|
|
|
@@ -48,6 +48,10 @@ you must NOT paraphrase.
|
|
|
48
48
|
- **Plan-level error** (integration/verify reveals a wrong LOCKED decision, not a
|
|
49
49
|
slice bug): STOP the wave. No improvised redesign AFK — keep worktrees intact,
|
|
50
50
|
report findings + options.
|
|
51
|
+
- **On ANY wave STOP/abort:** if this run planted the active-wave claim, remove
|
|
52
|
+
exactly that claim as part of shutdown. Never delete a claim marker observed
|
|
53
|
+
during a preflight collision, nor any sibling/foreign wave marker — those are
|
|
54
|
+
owned by another run. A stale marker owned by this run would block a safe retry.
|
|
51
55
|
- **Routing = one axis: how expensive is a wrong result to catch?** Mechanically
|
|
52
56
|
caught (test/screenshot/lint) → default tier at medium/low effort; plausible-but-
|
|
53
57
|
wrong / subtle logic / architecture → top tier at high effort + main-thread
|
|
@@ -72,19 +76,30 @@ you must NOT paraphrase.
|
|
|
72
76
|
**once** that `/setup-workflow` plus project maintenance fill the layer (the
|
|
73
77
|
commands/tunnel/login can't be guessed). Never treat an empty heading as a
|
|
74
78
|
verify recipe.
|
|
75
|
-
3. **
|
|
79
|
+
3. **Preflight — refuse a wave already in flight, otherwise claim it.** Before
|
|
80
|
+
dispatch, inspect all three same-machine collision signals: **(a)** an existing
|
|
81
|
+
`wave-active/<anchor>` tag; **(b)** any slice branch ahead of the wave's current
|
|
82
|
+
base (`git rev-list --count <base>..<slice-branch>` > 0); **(c)** uncommitted
|
|
83
|
+
changes in any slice worktree (`git -C <worktree> status --porcelain` non-empty).
|
|
84
|
+
A hit not created by this run means another session may be building the wave:
|
|
85
|
+
**STOP**, report the exact tag/branch/worktree, and do not touch it. If clean,
|
|
86
|
+
record that this run owns the claim and plant a LOCAL annotated tag:
|
|
87
|
+
`git tag -a wave-active/<anchor> -m "orchestrating since <UTC timestamp>;
|
|
88
|
+
slices: <slice-branches>"`. It is local coordination state — never push it.
|
|
89
|
+
4. **Wave worktree**: reuse the planning worktree (never re-create; the handoff
|
|
76
90
|
points there). Bring its branch to current `main`:
|
|
77
91
|
`git -C <wave> merge --ff-only origin/main` (if your repo guards destructive
|
|
78
92
|
git, ff-merge is the safe path — not `reset --hard`). Install dependencies with
|
|
79
93
|
your package manager after (the lockfile may have moved). A gitignored plan doc
|
|
80
94
|
survives the merge.
|
|
81
|
-
|
|
95
|
+
5. **Run project setup steps (`§Setup`)** the later verify needs — e.g. a DB
|
|
82
96
|
tunnel or service the live-verify depends on. Absent layer → start whatever your
|
|
83
97
|
live-verify environment requires before Phase 4.
|
|
84
98
|
|
|
85
99
|
**Done when:** anchor + every sub-issue + plan read · project layer probed
|
|
86
|
-
(filled → project recipe; stub/absent → generic + one-time warning) ·
|
|
87
|
-
ff'd to `origin/main` + deps
|
|
100
|
+
(filled → project recipe; stub/absent → generic + one-time warning) · preflight
|
|
101
|
+
clean + this run's local claim planted · wave branch ff'd to `origin/main` + deps
|
|
102
|
+
installed · project setup steps running.
|
|
88
103
|
|
|
89
104
|
## Phase 1 — Disjointness recon (the load-bearing step)
|
|
90
105
|
|
|
@@ -116,6 +131,13 @@ Zero merge conflicts later depends entirely on getting this right.
|
|
|
116
131
|
"X already exists in `<file>` — do NOT add it, consume only." (Real case: all 14
|
|
117
132
|
sub-issues claimed the same registry adds + 4 contradictions — hub expanded to
|
|
118
133
|
own all 20 keys, batch merged conflict-free.)
|
|
134
|
+
- **Retirement slices require a valid topological deletion order.** Before
|
|
135
|
+
dispatching slices that delete a legacy cluster, map every to-delete module's
|
|
136
|
+
production importers and build the cluster's internal import graph. Order the
|
|
137
|
+
deletions so no pending slice imports a module already removed; zero remaining
|
|
138
|
+
production importers is the behavior-neutral proof. If mutually dependent
|
|
139
|
+
deletions form a cycle, separate each-slice-green steps are impossible: combine
|
|
140
|
+
the whole cycle into ONE atomic slice instead of landing dangling imports.
|
|
119
141
|
|
|
120
142
|
**Done when:** FILE→SLICES table exists · every ≥2-slice file has exactly ONE
|
|
121
143
|
owning slice · disjoint waves cut in dependency order · every dependent contract
|
|
@@ -233,15 +255,19 @@ checks pass · console 0/0 · DB outcome value compared.
|
|
|
233
255
|
- **`Closes #N` needs the keyword before EACH issue, one per line** — `Closes #a,
|
|
234
256
|
#b` only closes the first. Anchor → `Part of #<anchor>`, never `closes`
|
|
235
257
|
(premature close).
|
|
236
|
-
- **Anchor tracker
|
|
237
|
-
|
|
238
|
-
|
|
258
|
+
- **Anchor tracker sync is mandatory at EVERY slice event (PR-create AND merge).**
|
|
259
|
+
Use the project-layer command from `§Landing`: dry-run first, review the diff,
|
|
260
|
+
then write; preserve gate symbols and stable cells of freshly appended rows.
|
|
261
|
+
Absent a filled layer, use the tracker's native parent/table reconciliation.
|
|
239
262
|
- **Stacked follow-up PRs** that build on the unmerged wave: base on the **wave
|
|
240
|
-
branch** (not main)
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
263
|
+
branch** (not main) and note the merge order in every PR body. **Do NOT rely on
|
|
264
|
+
auto-retarget:** deleting the merged base branch can close its stacked child.
|
|
265
|
+
Either merge the child before deleting the base, or expect the close and open a
|
|
266
|
+
FRESH PR from the child's still-existing head branch against the final base.
|
|
267
|
+
Keep any deploy/release/manual gate in the documented merge order.
|
|
268
|
+
- New issues go through the project-layer board command (`§Landing`; never a bare
|
|
269
|
+
tracker-create call that skips the board). Write multi-paragraph bodies through
|
|
270
|
+
a body file so shell metacharacters cannot alter them.
|
|
245
271
|
|
|
246
272
|
**Done when:** PR(s) open with correct `Closes`/`Part of` lines · anchor-sync
|
|
247
273
|
written · merge order documented.
|
|
@@ -251,19 +277,40 @@ written · merge order documented.
|
|
|
251
277
|
- Stop the dev server(s) you started, by port (`lsof -ti:<port> | xargs kill` —
|
|
252
278
|
your own processes, targeted by the worktree's assigned ports, never blind).
|
|
253
279
|
Remove temp verify scripts (a login helper, DB-check scripts).
|
|
280
|
+
- **Remove only this run's claim marker.** If this run planted
|
|
281
|
+
`wave-active/<anchor>`, delete that exact local tag after success or abort. Never
|
|
282
|
+
delete a claim marker observed during a preflight collision or any other
|
|
283
|
+
`wave-active/*` marker; ownership, not a broad pattern, authorizes cleanup.
|
|
254
284
|
- **Before removing any slice worktree, read its `ANNAHMEN.md`** (an assumptions
|
|
255
285
|
log, gitignored at worktree-root) and propagate each build-time assumption marker
|
|
256
286
|
to the sibling issue it carries. A hand-driven multi-PR / migration landing does
|
|
257
287
|
NOT run `wrapup`'s assumption-propagation step — this is the only place it
|
|
258
288
|
happens; `worktree remove` deletes the log.
|
|
259
|
-
- **Post-merge:**
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
-
|
|
263
|
-
|
|
264
|
-
|
|
289
|
+
- **Post-merge completion sync:** use `§Landing` to reconcile the anchor again and
|
|
290
|
+
verify every leaf actually closed. Then read the anchor's `Closing Conditions`,
|
|
291
|
+
`Done when`, and acceptance criteria and make an explicit closure decision:
|
|
292
|
+
- **No open manual gate:** close the anchor, set its project completion status to
|
|
293
|
+
the configured done role, and re-read the board item to verify both states.
|
|
294
|
+
Closing the tracker issue alone is not proof that its workflow field changed.
|
|
295
|
+
- **Open manual gate:** ask the user in the main thread, naming the exact gate and
|
|
296
|
+
condition. Confirmation follows the close/status/verify path above; otherwise
|
|
297
|
+
leave the anchor open and add exactly one completion marker explaining the
|
|
298
|
+
remaining gate and close condition.
|
|
299
|
+
- **Program propagation:** resolve the anchor's native parent with the
|
|
300
|
+
project-layer command from `§Landing`. If the parent is a Program-PRD, run the
|
|
301
|
+
project-layer program sync after the anchor decision. On closure, set the
|
|
302
|
+
anchor's completion status first so the program can observe the completed wave;
|
|
303
|
+
run program sync again after close even if landing ran it earlier. If a manual
|
|
304
|
+
gate remains open, propagation may refresh the program but must not claim wave
|
|
305
|
+
completion. Absent a filled layer, use equivalent tracker-native parent lookup,
|
|
306
|
+
completion-field update, re-read, and program propagation commands.
|
|
307
|
+
- A skill edited during the wave → sync its dual-surface mirror in the SAME PR
|
|
308
|
+
using the tool named by `§Landing` when present; mirror parity remains a pre-PR
|
|
309
|
+
gate.
|
|
265
310
|
- Leave slice worktrees for the user to inspect, or note they're
|
|
266
311
|
post-merge-removable.
|
|
267
312
|
|
|
268
|
-
**Done when:** no orphan process ·
|
|
269
|
-
closes verified ·
|
|
313
|
+
**Done when:** no orphan process · this run's claim removed · ANNAHMEN propagated ·
|
|
314
|
+
anchor reconciled + leaf closes verified · anchor closure decided and documented ·
|
|
315
|
+
Program-PRD propagation completed or explicitly skipped · final report lists
|
|
316
|
+
landed/pulled slices as **X of Y**.
|