fix(skills): copy phase-data-contracts.md to fix transitive broken-link gate

isolation-contract.md (just copied to crank/discovery/validation in 053111a8)
references phase-data-contracts.md as a sibling. The doc-release link
validator flagged it as broken in the new locations because the file lived
only in skills/rpi/references/. Per CLAUDE.md "no symlinks; copy", copies
phase-data-contracts.md into each affected skill's references/ and adds the
link to each SKILL.md's Reference Documents section so heal.sh's UNLINKED_REF
check stays green. Refreshes codex .agentops-generated.json hashes for the
4 touched skills.

Verified: link validator 1990/1990 ok, heal.sh --strict clean, codex artifact
metadata + parity audits both pass.
This commit is contained in:
Boden Fuller
2026-05-07 16:36:51 -04:00
parent 95e8909efd
commit 3ae3ce8531
11 changed files with 185 additions and 8 deletions
+4 -4
View File
@@ -709,7 +709,7 @@
{
"name": "crank",
"source_skill": "skills/crank",
"source_hash": "5693784e93885fbf3ebe58c8ac4010ab14377d7f3d6ee53b3f2698a03938060c",
"source_hash": "870103393336bc56fe53cc722501f238861b8eab5767835f5230de333e69a169",
"generated_hash": "ba0a5b1f6a4f1c2350341611d2977b387451c63f550254263fe61f582afcfbca"
},
{
@@ -727,7 +727,7 @@
{
"name": "discovery",
"source_skill": "skills/discovery",
"source_hash": "3f1bbc935567a72e645c037e34940d7259c2badc190f8f91db49fa4a2e589010",
"source_hash": "707331322addee81ff52032fa6eefc4c39a4eccc8538888ec8a7c75a8ffda45c",
"generated_hash": "027be281254ef5b62ffacc604f55d2ce34b49c2bbbd99a9f31d3ad4702f94009"
},
{
@@ -787,7 +787,7 @@
{
"name": "heal-skill",
"source_skill": "skills/heal-skill",
"source_hash": "3327b65b82a4167f3a52e0936cb7e59a58b27ec54ec9a9017f0beb4e5b2ab47a",
"source_hash": "3c108dcae47ce755778685f6432f8ebea752f1f21d94adbc1dc547283cb547b3",
"generated_hash": "3e5f02ccb7201f1ab86a1ed72233ecb3b3af9690a290d770f65366b2472d2f1b"
},
{
@@ -1069,7 +1069,7 @@
{
"name": "validation",
"source_skill": "skills/validation",
"source_hash": "3c55c8e9789682c1c1de3aee4f5b7856ccf2e8511dde12c995fb8b27a20412e4",
"source_hash": "18d13f593d2f7bcfe562a89bdf740269631004f8a990911d71615d7500d82926",
"generated_hash": "becd183323fa80b92579e49d340fadaaa2bda832866d1d3c93b6b29a5880c50a"
},
{
+1 -1
View File
@@ -2,6 +2,6 @@
"generator": "manual-maintained",
"source_skill": "skills/crank",
"layout": "modular",
"source_hash": "5693784e93885fbf3ebe58c8ac4010ab14377d7f3d6ee53b3f2698a03938060c",
"source_hash": "870103393336bc56fe53cc722501f238861b8eab5767835f5230de333e69a169",
"generated_hash": "ba0a5b1f6a4f1c2350341611d2977b387451c63f550254263fe61f582afcfbca"
}
@@ -2,6 +2,6 @@
"generator": "manual-maintained",
"source_skill": "skills/discovery",
"layout": "modular",
"source_hash": "3f1bbc935567a72e645c037e34940d7259c2badc190f8f91db49fa4a2e589010",
"source_hash": "707331322addee81ff52032fa6eefc4c39a4eccc8538888ec8a7c75a8ffda45c",
"generated_hash": "027be281254ef5b62ffacc604f55d2ce34b49c2bbbd99a9f31d3ad4702f94009"
}
@@ -2,6 +2,6 @@
"generator": "manual-maintained",
"source_skill": "skills/heal-skill",
"layout": "modular",
"source_hash": "3327b65b82a4167f3a52e0936cb7e59a58b27ec54ec9a9017f0beb4e5b2ab47a",
"source_hash": "3c108dcae47ce755778685f6432f8ebea752f1f21d94adbc1dc547283cb547b3",
"generated_hash": "3e5f02ccb7201f1ab86a1ed72233ecb3b3af9690a290d770f65366b2472d2f1b"
}
@@ -2,6 +2,6 @@
"generator": "manual-maintained",
"source_skill": "skills/validation",
"layout": "modular",
"source_hash": "3c55c8e9789682c1c1de3aee4f5b7856ccf2e8511dde12c995fb8b27a20412e4",
"source_hash": "18d13f593d2f7bcfe562a89bdf740269631004f8a990911d71615d7500d82926",
"generated_hash": "becd183323fa80b92579e49d340fadaaa2bda832866d1d3c93b6b29a5880c50a"
}
+1
View File
@@ -678,6 +678,7 @@ Crank runs as an isolated phase-2 execution context — discovery and validation
- [references/team-coordination.md](references/team-coordination.md)
- [references/test-first-mode.md](references/test-first-mode.md)
- [references/troubleshooting.md](references/troubleshooting.md)
- [references/phase-data-contracts.md](references/phase-data-contracts.md) — phase artifact data contracts (cited from references/isolation-contract.md)
- [references/uat-integration-wave.md](references/uat-integration-wave.md)
- [references/wave1-spec-consistency-checklist.md](references/wave1-spec-consistency-checklist.md)
- [references/wave-patterns.md](references/wave-patterns.md)
@@ -0,0 +1,58 @@
# Phase Data Contracts
How each consolidated phase passes data to the next. Artifacts are filesystem-based; no in-memory coupling between phases.
| Transition | Output | Extraction | Input to Next |
|------------|--------|------------|---------------|
| → Discovery | Goal string + repo execution profile contract | Goal from the `/rpi` invocation; repo policy from `docs/contracts/repo-execution-profile.md`, `repo-execution-profile.schema.json`, and `repo-execution-profile.json` when present | `repo_profile` state is loaded before research/planning begins, including validation lane mutation metadata |
| Discovery → Implementation | Epic execution context or file-backed objective + discovery summary + `execution_packet` | `phased-state.json` + `.agents/rpi/phase-1-summary.md` + `.agents/rpi/execution-packet.json` (latest alias) or `.agents/rpi/runs/<run-id>/execution-packet.json` (run archive) | `/crank <epic-id>` when `epic_id` exists; otherwise `/crank .agents/rpi/execution-packet.json` with repo policy, contract surfaces, validation bundle, and `validation_lanes` already normalized |
| Implementation → Validation | Completed/partial crank status + implementation summary + `execution_packet` | `bd children <epic-id>` or file-backed implementation state + `.agents/rpi/phase-2-summary.md` + `.agents/rpi/execution-packet.json` (latest alias) or `.agents/rpi/runs/<run-id>/execution-packet.json` (run archive) | `/validation <epic-id>` when `epic_id` exists; otherwise standalone `/validation` with the same repo execution profile fields, validation lanes, and done criteria |
| Validation → Next Cycle (optional) | Vibe/post-mortem verdicts + harvested follow-up work + queue lifecycle fields (`claim_status`, `claimed_by`, `claimed_at`, `consumed`, `failed_at`) | Latest council reports + `.agents/rpi/next-work.jsonl` | Stop, loop (`--loop`), suggest next `/rpi` (`--spawn-next`), or hand work back to `/evolve` |
Execution packet v1 should remain additive. Recommended fields:
- `schema_version`
- `run_id`
- `objective`
- `epic_id` (optional when the tracker cannot mint an epic)
- `plan_path`
- `contract_surfaces`
- `validation_commands`
- `validation_lanes` (repo profile lane metadata: `read_only`, `writes_artifacts`, `isolated_agents_home`, `release_only`, `mutation_escape_hatch`)
- `tracker_mode`
- `tracker_health`
- `done_criteria`
- `pre_mortem_verdict`
- `test_levels`
- `ranked_packet_path`
Execution packet retention rule:
- `.agents/rpi/execution-packet.json` is the mutable latest alias for the current objective
- `.agents/rpi/runs/<run-id>/execution-packet.json` is the durable per-run packet archive when `run_id` exists
Validation lane selection rule:
- implementation and fast closeout phases prefer lanes where `read_only=true`, `writes_artifacts=false`, `release_only=false`, `cost_class` is `cheap` or `standard`, and `auto_select` is `default` or matches the changed surface
- lanes with `cost_class=expensive`, `auto_select=explicit`, or `auto_select=release-only` require an explicit operator request, a named plan acceptance criterion, or a release-readiness objective
- every selected lane should honor `timeout_seconds`; when a lane times out, record `[TIME-BOXED]` and continue with narrower evidence unless it was the only code-surface proof
- lanes with `isolated_agents_home=true` require isolated agent state before execution
- lanes with `writes_artifacts=true` or `release_only=true` are release/audit lanes; run them only when the packet objective or operator explicitly asks for release readiness
- lanes with a non-null `mutation_escape_hatch` require the escape hatch name in the validation report or handoff
- unclassified commands containing `go test -race`, `-shuffle`, `-count=N` where `N > 1`, eval runners, retrieval bench, headless runtime smoke, or release gates are explicit-only
Queue lifecycle rule:
- post-mortem writes new entries as available: entry aggregate `consumed=false`, `claim_status="available"`
- consumers treat item lifecycle as authoritative inside `items[]`; omitted item `claim_status` means available
- `/evolve` and `/rpi loop` claim an item before starting a cycle: item `claim_status="in_progress"`
- successful `/rpi` + regression gate finalizes that item claim: item `consumed=true`, `claim_status="consumed"`, `consumed_by`, `consumed_at`
- failed or regressed cycles release the claim back to available state and may stamp item `failed_at` for retry ordering
- consumers may rewrite existing queue lines to claim, release, fail, or consume items after initial write
- the entry aggregate flips to `consumed=true` only after every child item is consumed
Canonical schema contract: [`docs/contracts/next-work.schema.md`](../../../docs/contracts/next-work.schema.md) (v1.4)
## Rollback discipline
When changing phase-boundary logic, ship phase-3 (closeout) updates FIRST and remove phase-2 (handoff) logic SECOND. This keeps a working closeout path in place during the transition window — if phase-3 ships broken, you can revert before phase-2's removal lands.
Pre-mortem F3 of `soc-bcrn` (`.agents/council/2026-05-07-pre-mortem-rpi-lifecycle-sharpening.md`) called this out as the primary rollback risk for the consolidated daemon epic (E3).
Worked example: `cli/cmd/ao/rpi_cleanup.go:preserveWorktreeCommits` (phase-3 commit-preservation logic) was added BEFORE the phase-2 cleanup-removal as part of E3.S3. The order matters: orphaned worktree commits that previously fell into git fsck dangling now land on `codex/preserve-<runID>` branches before the worktree is force-removed. If preservation had been wired in the opposite order, a regression window would have lost commits during the transition.
+1
View File
@@ -235,5 +235,6 @@ Read `references/troubleshooting.md` for common problems and solutions.
- [references/phase-budgets.md](references/phase-budgets.md) — time budgets per complexity level
- [references/troubleshooting.md](references/troubleshooting.md) — common problems and solutions
- [references/output-templates.md](references/output-templates.md) — execution packet and phase summary formats
- [references/phase-data-contracts.md](references/phase-data-contracts.md) — phase artifact data contracts (cited from references/isolation-contract.md)
**See also:** [brainstorm](../brainstorm/SKILL.md), [design](../design/SKILL.md), [research](../research/SKILL.md), [plan](../plan/SKILL.md), [pre-mortem](../pre-mortem/SKILL.md), [crank](../crank/SKILL.md), [rpi](../rpi/SKILL.md), [scaffold](../scaffold/SKILL.md)
@@ -0,0 +1,58 @@
# Phase Data Contracts
How each consolidated phase passes data to the next. Artifacts are filesystem-based; no in-memory coupling between phases.
| Transition | Output | Extraction | Input to Next |
|------------|--------|------------|---------------|
| → Discovery | Goal string + repo execution profile contract | Goal from the `/rpi` invocation; repo policy from `docs/contracts/repo-execution-profile.md`, `repo-execution-profile.schema.json`, and `repo-execution-profile.json` when present | `repo_profile` state is loaded before research/planning begins, including validation lane mutation metadata |
| Discovery → Implementation | Epic execution context or file-backed objective + discovery summary + `execution_packet` | `phased-state.json` + `.agents/rpi/phase-1-summary.md` + `.agents/rpi/execution-packet.json` (latest alias) or `.agents/rpi/runs/<run-id>/execution-packet.json` (run archive) | `/crank <epic-id>` when `epic_id` exists; otherwise `/crank .agents/rpi/execution-packet.json` with repo policy, contract surfaces, validation bundle, and `validation_lanes` already normalized |
| Implementation → Validation | Completed/partial crank status + implementation summary + `execution_packet` | `bd children <epic-id>` or file-backed implementation state + `.agents/rpi/phase-2-summary.md` + `.agents/rpi/execution-packet.json` (latest alias) or `.agents/rpi/runs/<run-id>/execution-packet.json` (run archive) | `/validation <epic-id>` when `epic_id` exists; otherwise standalone `/validation` with the same repo execution profile fields, validation lanes, and done criteria |
| Validation → Next Cycle (optional) | Vibe/post-mortem verdicts + harvested follow-up work + queue lifecycle fields (`claim_status`, `claimed_by`, `claimed_at`, `consumed`, `failed_at`) | Latest council reports + `.agents/rpi/next-work.jsonl` | Stop, loop (`--loop`), suggest next `/rpi` (`--spawn-next`), or hand work back to `/evolve` |
Execution packet v1 should remain additive. Recommended fields:
- `schema_version`
- `run_id`
- `objective`
- `epic_id` (optional when the tracker cannot mint an epic)
- `plan_path`
- `contract_surfaces`
- `validation_commands`
- `validation_lanes` (repo profile lane metadata: `read_only`, `writes_artifacts`, `isolated_agents_home`, `release_only`, `mutation_escape_hatch`)
- `tracker_mode`
- `tracker_health`
- `done_criteria`
- `pre_mortem_verdict`
- `test_levels`
- `ranked_packet_path`
Execution packet retention rule:
- `.agents/rpi/execution-packet.json` is the mutable latest alias for the current objective
- `.agents/rpi/runs/<run-id>/execution-packet.json` is the durable per-run packet archive when `run_id` exists
Validation lane selection rule:
- implementation and fast closeout phases prefer lanes where `read_only=true`, `writes_artifacts=false`, `release_only=false`, `cost_class` is `cheap` or `standard`, and `auto_select` is `default` or matches the changed surface
- lanes with `cost_class=expensive`, `auto_select=explicit`, or `auto_select=release-only` require an explicit operator request, a named plan acceptance criterion, or a release-readiness objective
- every selected lane should honor `timeout_seconds`; when a lane times out, record `[TIME-BOXED]` and continue with narrower evidence unless it was the only code-surface proof
- lanes with `isolated_agents_home=true` require isolated agent state before execution
- lanes with `writes_artifacts=true` or `release_only=true` are release/audit lanes; run them only when the packet objective or operator explicitly asks for release readiness
- lanes with a non-null `mutation_escape_hatch` require the escape hatch name in the validation report or handoff
- unclassified commands containing `go test -race`, `-shuffle`, `-count=N` where `N > 1`, eval runners, retrieval bench, headless runtime smoke, or release gates are explicit-only
Queue lifecycle rule:
- post-mortem writes new entries as available: entry aggregate `consumed=false`, `claim_status="available"`
- consumers treat item lifecycle as authoritative inside `items[]`; omitted item `claim_status` means available
- `/evolve` and `/rpi loop` claim an item before starting a cycle: item `claim_status="in_progress"`
- successful `/rpi` + regression gate finalizes that item claim: item `consumed=true`, `claim_status="consumed"`, `consumed_by`, `consumed_at`
- failed or regressed cycles release the claim back to available state and may stamp item `failed_at` for retry ordering
- consumers may rewrite existing queue lines to claim, release, fail, or consume items after initial write
- the entry aggregate flips to `consumed=true` only after every child item is consumed
Canonical schema contract: [`docs/contracts/next-work.schema.md`](../../../docs/contracts/next-work.schema.md) (v1.4)
## Rollback discipline
When changing phase-boundary logic, ship phase-3 (closeout) updates FIRST and remove phase-2 (handoff) logic SECOND. This keeps a working closeout path in place during the transition window — if phase-3 ships broken, you can revert before phase-2's removal lands.
Pre-mortem F3 of `soc-bcrn` (`.agents/council/2026-05-07-pre-mortem-rpi-lifecycle-sharpening.md`) called this out as the primary rollback risk for the consolidated daemon epic (E3).
Worked example: `cli/cmd/ao/rpi_cleanup.go:preserveWorktreeCommits` (phase-3 commit-preservation logic) was added BEFORE the phase-2 cleanup-removal as part of E3.S3. The order matters: orphaned worktree commits that previously fell into git fsck dangling now land on `codex/preserve-<runID>` branches before the worktree is force-removed. If preservation had been wired in the opposite order, a regression window would have lost commits during the transition.
+1
View File
@@ -245,3 +245,4 @@ See [references/troubleshooting.md](references/troubleshooting.md).
- [references/four-surface-closure.md](references/four-surface-closure.md) — four-surface closure validation (code + docs + examples + proof)
- [references/forge-scope.md](references/forge-scope.md) and [references/idempotency-and-resume.md](references/idempotency-and-resume.md) — forge scoping, rerun behavior, standalone mode
- [references/remote-and-multi-repo-validation.md](references/remote-and-multi-repo-validation.md)
- [references/phase-data-contracts.md](references/phase-data-contracts.md) — phase artifact data contracts (cited from references/isolation-contract.md)
@@ -0,0 +1,58 @@
# Phase Data Contracts
How each consolidated phase passes data to the next. Artifacts are filesystem-based; no in-memory coupling between phases.
| Transition | Output | Extraction | Input to Next |
|------------|--------|------------|---------------|
| → Discovery | Goal string + repo execution profile contract | Goal from the `/rpi` invocation; repo policy from `docs/contracts/repo-execution-profile.md`, `repo-execution-profile.schema.json`, and `repo-execution-profile.json` when present | `repo_profile` state is loaded before research/planning begins, including validation lane mutation metadata |
| Discovery → Implementation | Epic execution context or file-backed objective + discovery summary + `execution_packet` | `phased-state.json` + `.agents/rpi/phase-1-summary.md` + `.agents/rpi/execution-packet.json` (latest alias) or `.agents/rpi/runs/<run-id>/execution-packet.json` (run archive) | `/crank <epic-id>` when `epic_id` exists; otherwise `/crank .agents/rpi/execution-packet.json` with repo policy, contract surfaces, validation bundle, and `validation_lanes` already normalized |
| Implementation → Validation | Completed/partial crank status + implementation summary + `execution_packet` | `bd children <epic-id>` or file-backed implementation state + `.agents/rpi/phase-2-summary.md` + `.agents/rpi/execution-packet.json` (latest alias) or `.agents/rpi/runs/<run-id>/execution-packet.json` (run archive) | `/validation <epic-id>` when `epic_id` exists; otherwise standalone `/validation` with the same repo execution profile fields, validation lanes, and done criteria |
| Validation → Next Cycle (optional) | Vibe/post-mortem verdicts + harvested follow-up work + queue lifecycle fields (`claim_status`, `claimed_by`, `claimed_at`, `consumed`, `failed_at`) | Latest council reports + `.agents/rpi/next-work.jsonl` | Stop, loop (`--loop`), suggest next `/rpi` (`--spawn-next`), or hand work back to `/evolve` |
Execution packet v1 should remain additive. Recommended fields:
- `schema_version`
- `run_id`
- `objective`
- `epic_id` (optional when the tracker cannot mint an epic)
- `plan_path`
- `contract_surfaces`
- `validation_commands`
- `validation_lanes` (repo profile lane metadata: `read_only`, `writes_artifacts`, `isolated_agents_home`, `release_only`, `mutation_escape_hatch`)
- `tracker_mode`
- `tracker_health`
- `done_criteria`
- `pre_mortem_verdict`
- `test_levels`
- `ranked_packet_path`
Execution packet retention rule:
- `.agents/rpi/execution-packet.json` is the mutable latest alias for the current objective
- `.agents/rpi/runs/<run-id>/execution-packet.json` is the durable per-run packet archive when `run_id` exists
Validation lane selection rule:
- implementation and fast closeout phases prefer lanes where `read_only=true`, `writes_artifacts=false`, `release_only=false`, `cost_class` is `cheap` or `standard`, and `auto_select` is `default` or matches the changed surface
- lanes with `cost_class=expensive`, `auto_select=explicit`, or `auto_select=release-only` require an explicit operator request, a named plan acceptance criterion, or a release-readiness objective
- every selected lane should honor `timeout_seconds`; when a lane times out, record `[TIME-BOXED]` and continue with narrower evidence unless it was the only code-surface proof
- lanes with `isolated_agents_home=true` require isolated agent state before execution
- lanes with `writes_artifacts=true` or `release_only=true` are release/audit lanes; run them only when the packet objective or operator explicitly asks for release readiness
- lanes with a non-null `mutation_escape_hatch` require the escape hatch name in the validation report or handoff
- unclassified commands containing `go test -race`, `-shuffle`, `-count=N` where `N > 1`, eval runners, retrieval bench, headless runtime smoke, or release gates are explicit-only
Queue lifecycle rule:
- post-mortem writes new entries as available: entry aggregate `consumed=false`, `claim_status="available"`
- consumers treat item lifecycle as authoritative inside `items[]`; omitted item `claim_status` means available
- `/evolve` and `/rpi loop` claim an item before starting a cycle: item `claim_status="in_progress"`
- successful `/rpi` + regression gate finalizes that item claim: item `consumed=true`, `claim_status="consumed"`, `consumed_by`, `consumed_at`
- failed or regressed cycles release the claim back to available state and may stamp item `failed_at` for retry ordering
- consumers may rewrite existing queue lines to claim, release, fail, or consume items after initial write
- the entry aggregate flips to `consumed=true` only after every child item is consumed
Canonical schema contract: [`docs/contracts/next-work.schema.md`](../../../docs/contracts/next-work.schema.md) (v1.4)
## Rollback discipline
When changing phase-boundary logic, ship phase-3 (closeout) updates FIRST and remove phase-2 (handoff) logic SECOND. This keeps a working closeout path in place during the transition window — if phase-3 ships broken, you can revert before phase-2's removal lands.
Pre-mortem F3 of `soc-bcrn` (`.agents/council/2026-05-07-pre-mortem-rpi-lifecycle-sharpening.md`) called this out as the primary rollback risk for the consolidated daemon epic (E3).
Worked example: `cli/cmd/ao/rpi_cleanup.go:preserveWorktreeCommits` (phase-3 commit-preservation logic) was added BEFORE the phase-2 cleanup-removal as part of E3.S3. The order matters: orphaned worktree commits that previously fell into git fsck dangling now land on `codex/preserve-<runID>` branches before the worktree is force-removed. If preservation had been wired in the opposite order, a regression window would have lost commits during the transition.