Merge pull request #63 from Heretek-AI/docs/spike-12-build-capability

Spike: #12 build-capability findings + DRAFT spec (canary-validated)
This commit is contained in:
BillyOutlast authored and GitHub committed 2026-10-23 15:22:22 -04:00
commit a33f3bbad4
6 files changed
+829

No files matched your search

@@ -0,0 +1,54 @@
# QA checks — spike-12-builds (investigation spike, report-claim verification)
Date: 2026-10-23 (UTC) | Verifier: Agency QA (subagent, read-only + canary denial re-probes)
Worktree: .lane/trees/spike-12-builds | Branch: docs/spike-12-build-capability @ e6914ae (confirmed)
Scope: verify REPORT claims. No implementation exists to red-proof. No commits made by QA.
## 0. Branch / cleanliness — PASS
- `git rev-parse --abbrev-ref HEAD` -> docs/spike-12-build-capability; `git rev-parse --short HEAD` -> e6914ae (matches tasking).
- `git status --short` at start AND end: empty (clean). Report + draft package are committed as e6914ae.
- NOTE: report §0 cites branch @ 5a244ac (pre-report-commit HEAD). Expected staleness, not a defect.
## 1. Fleet integrity — PASS
- `rig ps` (run 2x, start + end): `1 rig · 51 seats · 0 need attention` / heretek-omni-fleet 51/51 running, 0 ATTN. Unchanged across QA.
- `git diff main --stat` / `--name-only`: EXACTLY 5 files, all report + draft package:
docs/reports/spike-12-build-capability.md (281 lines added)
openspec/changes/issue-12-build-capability/design.md
openspec/changes/issue-12-build-capability/proposal.md
openspec/changes/issue-12-build-capability/specs/build-capability/spec.md
openspec/changes/issue-12-build-capability/tasks.md
No fleet/fleet.yaml, no scripts/, no Makefile, no verify-rigs.sh changes. PASS.
## 2. Claim spot-checks — PASS (3/3)
### 2a. BC-L1 canary denials re-run (2 of 5) — PASS, verbatim match
- Verb: `rig send 'engine-engine-systems-eng@heretek-omni-fleet' "<QA-labeled 2-probe tasking>"` (denied commands only — incapable of mutation by design); read via `rig transcript 'engine-engine-systems-eng@heretek-omni-fleet' --tail 40`.
- Seat reply (verbatim from transcript):
1. `cmake --preset linux-release` — DENIED — `[pi-permission-system] Denied by policy: 'bash' (rule '*').`
== report §3 row 1 verbatim. PASS.
2. `git add src/engine tests/engine .` — DENIED — `[pi-permission-system] Denied by policy: 'path' for tool 'bash' for path 'src/engine' (rule '*').`
== report §3 row 5 denial text verbatim (bash-rule vs path-rule shape preserved). PASS.
- NUANCE: QA added a trailing `.` to probe 2 vs the report's exact `git add src/engine tests/engine`. Denial still fires on the `src/engine` path rule with identical text; no material deviation.
- Receipt matched report convention: 2/2 bare, 0 ALLOWED / 2 DENIED, no artifacts, no qitem (PENDING_DISPATCH).
### 2b. Gate suite git-drift-coord — PASS, count confirmed
- `bash scripts/gate-role.sh git-drift-coord` -> exit=0, `grep -c "^ok"` = 40, `grep -cE "FAIL|not ok"` = 0.
- Matches report §8: "git-drift-coord PASS (40 ok, 0 FAIL)". (Other three suites not re-run — tasking required one.)
### 2c. verify-rigs.sh --check-only — PASS, SUMMARY confirmed
- `./scripts/verify-rigs.sh --check-only` -> `SUMMARY: 27 checks passed, 0 failed.`
- Matches report §0/§7 claim of 27/0 (floor was 26/0 at AGENTS.md writing; report notes the +1). PASS.
## 3. Draft hygiene — PASS with 1 MINOR note
- DRAFT marking: proposal.md, design.md, tasks.md, spec.md each carry `# DRAFT` title + `Status: DRAFT` banner (grep -c "DRAFT" = 2 per file). PASS.
- BC-L1..L5 acceptance criteria: ALL present in tasks.md —
L1: verbatim-denial table (MEASURED, cited); L2: build log exit 0 + CTest N/N + tree SHA + ELAPSED on #12; L3: live relay transcript ACK quoted verbatim; L4: snapshot ID + --plan output + audit excerpts, --stop gated on TPM sign-off; L5: D5 scoped stage+commit + D6/D7 merge + re-proof. PASS.
- MINOR (not FAIL): proposal.md banner (ll.3-7) + design.md banner (ll.3-6) still read "every live measurement is marked STAGED / fleet DOWN, no live-seat contact" — stale after the 2026-10-23 live update. The correction lives in report §0/§8 + tasks.md L1/L3/L4, so no promise is broken, but the two banners are internally inconsistent with the package they head. Recommend a one-line banner amendment on each.
## 4. Bounds audit — PASS
- Report experiment log contacts exactly 4 seats, all with non-mutating verbs:
canary engine-engine-systems-eng (5 denied probes + --plan + --dry-run previews); systems-cpp-lowlevel-eng (cmake --version, ./build.sh --help exit-127 file-absent); delivery-git-drift-coord (git status --short); platform-dependency-patcher (git status + charter self-check). No other seat received any verb; capture/transcript reads only elsewhere.
- No --stop execution, no re-seed/restore, no queue writes, no file writes outside worktree + /tmp scratch. Single fleet-side artifact: one rollback snapshot (by-design hygiene, ID recorded).
- Secrets: diff scan for secret-shaped content clean (only hits: the words "decisions"/"disk-side" and `printf dummy` lines writing literal "dummy" to /tmp paths). No real credential material in report or draft package.
- QA's own contact: 1 rig send to canary only (2 denied probes) + 1 transcript read. Fleet 51/51 + status clean after. PASS.
## Verdict: PASS (4/4 items; 0 FAIL; 1 MINOR hygiene note in §3)
No vacuous checks found (every re-run check returns real measured output). Nothing committed by QA.
+297
View File
@@ -0,0 +1,297 @@
# Spike-12 build capability — findings report (NO implementation, NO commits)
- **Stage:** spike-12-builds (issues #12 + #9 + #11 design decisions, canary validation)
- **Worktree:** `.lane/trees/spike-12-builds` (branch `docs/spike-12-build-capability` @ `5a244ac`)
- **Binding:** findings + DRAFT openspec only. One `rig ps` gate check at
spike start showed the live fleet DOWN → initial posture was all-live-STAGED.
CORRECTION 2026-10-23: after restore (51/51 verified by this spike),
BC-L1/companions/dry-run/#11-previews MEASURED same-day (§3); D1–D7/BC-L3
live round-trip/BC-L4 mutation stay STAGED with reasons. No fleet edits,
no pushes, dummy secrets only (`/tmp/spike12-dummy-secrets`, 0700/0600),
nothing written outside the worktree except `/tmp` scratch.
- **Companion draft:** `openspec/changes/issue-12-build-capability/` (`proposal.md`, `design.md`, `specs/build-capability/spec.md`, `tasks.md` — all marked DRAFT).
## 0. Gate + verdict up front
- `rig ps` (spike start): **0 rigs · 0 seats running** (2 stopped, 8 archived). Coordinator relaunch had not landed. Per binding: **SKIP live contact entirely, no waiting/polling — check once.** Done: checked once.
- **Verdict: LIVE PHASE EXECUTED 2026-10-23 ~18:43–18:55Z.** Fleet verified
by this spike (`rig ps`: heretek-omni-fleet 51/51 running, rigId
`01M5GWFPKVNQEXQVSAGQ2ANJBE`). Pre-contact snapshot:
`01M5N162P3C5J21KFPCKGHD8XX`
(`rig restore 01M5N162P3C5J21KFPCKGHD8XX --rig 01M5GWFPKVNQEXQVSAGQ2ANJBE`).
MEASURED: BC-L1 (5/5 canary denials, verbatim), companion probes (cpp /
drift-coord / patcher), scratch widened-fragment dry-run + mock-gate
delta, #11 mechanics previews (`seat launch --fresh --plan`,
`seat handover --dry-run`). STILL STAGED: D1–D4/D5–D7 (no grants changed —
correctly not run), live relay round-trip (deferred, see §5), live
`--stop` execution (blocked without TPM sign-off — recorded, not forced).
- `verify-rigs.sh --check-only`: **27 passed, 0 failed** (floor was 26/0 at AGENTS.md writing; current tree reports 27 — untouched by this spike, just run).
- `git status` scope: ONLY the report (this file) + the draft openspec package. Verified at hand-off (§8).
## 1. Corrected capability matrix (#12 headline is over-narrow)
#12's fleet-wide claim ("the ONLY build-capable seat is cpp-lowlevel-eng") was re-audited against `fleet/fleet.yaml` in this worktree (51 roles, full `bash_allow` scan; runnable command in §7). **15 roles** hold at least one build/test verb:
| Role | Build/test verbs | Standing |
|---|---|---|
| `cpp-lowlevel-eng` | `cmake*`, `ninja*`, `ctest*`, `./build.sh*`, `clang-tidy*` | only `./build.sh` runner; cannot stage/commit |
| `engine-systems-eng` | `cargo bench*`, `cargo test engine*`, `cmake --build*`, `ctest*`, `cmake --version*`, `clang --version*` | existing-tree build/test only; configure (`cmake --preset*`), direct compiler invocation, and `./build.sh*` denied |
| `dependency-patcher` | `npm test*`, `cargo test*`, `pytest*`, `go test*` (+ `git checkout*`, `git commit*`) | lang tests; commit w/o add = dead grant |
| `go-backend-eng` | `go build*`, `go test*`, `golangci-lint*`, `go mod*` | go-only |
| `rust-systems-spec` | `cargo build*`, `cargo test*` | rust-only |
| `game-systems-dev` / `game-ai-dev` / `graphics-shader-eng` / `physics-sim-eng` | scoped `cargo test <area>*` etc.; physics adds `ctest -R physics*` | tests-only |
| `python-backend-spec` / `vector-rag-spec` | `pytest*` shapes | tests-only |
| `ts-node-fullstack` / `sabotage-qa-tester` | `npm test*` (+ pytest/cargo test for sabotage-qa) | tests-only |
| `java-kotlin-eng` / `android-mobile-spec` | `./gradlew test*` / `check*` / `assembleDebug*` | jvm-only |
| `git-drift-coord` | `git branch*`, `git merge-base*` + read-only git verbs; `builtin:locked`, in `READONLY_16_ROLES` | read-only by charter |
| remaining 48 roles | read-only git verbs + `rig` observability | — |
Recon-claim verification (all three check out exactly):
- **git add absent fleet-wide?** YES — `grep -c "git add" fleet/fleet.yaml` → **0**.
- **git commit only on dependency-patcher?** YES — single occurrence (line 1598, unscoped `git commit*`); `git checkout*` likewise only there (line 1597).
- **./build.sh only on cpp-lowlevel-eng?** YES — single occurrence (line 1392, `./build.sh*`, landed via PR #13).
**What stays true from #12:** exactly ONE seat can drive the canonical entry point; ZERO seats can stage; ZERO seats can commit seat-authored trees; the engine seat's configure/compile half is dead. The correction is scope, not exoneration: "only cpp builds" → "15 seats can run scoped tests/builds, one seat can run `./build.sh`, none can finish (stage/commit)".
## 2. Still-true gaps (ranked, with recommendations — see draft `design.md` §5)
- **12a (build-runner): RECOMMEND A1** — extend the designated `cpp-lowlevel-eng` runner (bounded holes closed only as far as output-anchored verification needs, e.g. a clock read for ELAPSED proof), keep authoring seats unwidened. A2 (widen engine seat) rejected as first choice (merges authorship + execution); A3 (new role) held in reserve.
- **12b (operator-runner protocol): RECOMMEND B1** — promote `send-authenticated.sh` + PRE-AUTH envelopes to protocol (decision record in draft `design.md` §3; dry-run proof in §5 below).
- **12c (committer): RECOMMEND C1** — envelope-shaped committer design, NOT a `git add*` delta (prefix-matcher makes scoped commit inexpressible: `git commit*` matches `-a`/`--amend`/arbitrary paths; identity needs `git -c` surface; `.git/` deny-guarded). BUILD-CLOSEOUT Part-2 refusal stands; C2 (grant `git-drift-coord`) rejected on the four documented fail-closed grounds.
## 3. Mock-harness verb evidence (pi + mock model, this worktree's catalog)
Method: `render-seat.py --model-provider mock --model-id mock-model`, one probe per command via `scripts/gate-run.sh` (`/tmp/spike12-probe2.sh`, scratch — not committed). Classification is STRICT: **POLICY-DENY** only on `[pi-permission-system] Denied by policy` text (quoted); **EXEC-ALLOW** when the tool executed (failure exit codes recorded — execution failure ≠ denial).
> ⚠️ Spike-in-spike lesson (kept in the report deliberately): the first probe
> pass classified on `"isError":true` and falsely reported
> `cpp-lowlevel-eng ./build.sh --help` as DENIED. Full-output recheck showed
> the command EXECUTED (exit 127, no `build.sh` in the scratch workdir) —
> i.e. the policy ALLOWED it. All rows below are re-verified with denial
> text or execution output; `isError`-only rows were re-run, never trusted.
| Seat | Command | Verdict | Evidence |
|---|---|---|---|
| engine-systems-eng | `cmake --build --preset linux-release` | EXEC-ALLOW | tool executed |
| engine-systems-eng | `ctest` | EXEC-ALLOW | tool executed (`No test configuration file found!` in scratch dir) |
| engine-systems-eng | `cargo test engine foo` | EXEC-ALLOW | tool executed |
| engine-systems-eng | `cmake --preset linux-release` | POLICY-DENY | `Denied by policy: 'bash' (rule '*')` |
| engine-systems-eng | `./build.sh --help` | POLICY-DENY | `Denied by policy: 'bash' (rule '*')` |
| engine-systems-eng | `clang++ -fsyntax-only foo.cpp` | POLICY-DENY | `Denied by policy: 'bash' (rule '*')` |
| engine-systems-eng | `git add src/engine` | POLICY-DENY | `Denied by policy: 'path' for tool 'bash' for path 'src/engine' (rule '*')` |
| cpp-lowlevel-eng | `cmake --preset linux-release` | EXEC-ALLOW | tool executed (cmake ran, missing presets file in scratch dir) |
| cpp-lowlevel-eng | `ctest` | EXEC-ALLOW | tool executed |
| cpp-lowlevel-eng | `ninja --version` | EXEC-ALLOW | tool executed |
| cpp-lowlevel-eng | `./build.sh --help` | EXEC-ALLOW | tool executed (exit 127, no `build.sh` in scratch dir — policy ALLOWED; PR #13 grant live, no path-block) |
| cpp-lowlevel-eng | `git add src/engine` | POLICY-DENY | `Denied by policy: 'bash' (rule '*')` |
| dependency-patcher | `git commit -m probe` | EXEC-ALLOW | tool executed (git ran; dead-grant demo: nothing stageable — `git add` denied below) |
| dependency-patcher | `cargo test` / `npm test` | EXEC-ALLOW | tools executed (missing manifest errors in scratch dir) |
| dependency-patcher | `git add package.json` | POLICY-DENY | `Denied by policy: 'bash' (rule '*')` |
| git-drift-coord | `git status --short` | EXEC-ALLOW | tool executed |
| git-drift-coord | `git add docs/ops/x` | POLICY-DENY | `Denied by policy: 'bash' (rule '*')` |
| git-drift-coord | `git commit -m probe` | POLICY-DENY | `Denied by policy: 'bash' (rule '*')` |
Read: the #12 denial set reproduces in the mock harness verbatim for the
engine seat; the designated runner's `./build.sh` grant is policy-live;
`git add` is denied on every seat probed (consistent with 0 fleet-wide
occurrences); `dependency-patcher`'s `git commit*` executes but stages
nothing — the dead grant, demonstrated.
### Canary baseline (dry-run, dummy secrets — rollback anchor)
Canary: `engine.engine-systems-eng`
(`engine-engine-systems-eng@game-dev-and-sim-rig`). Rendered with dummy
secrets (`/tmp/spike12-dummy-secrets`); references only, no real credentials
touched (`~/.config/heretek-rigs/secrets` never read — directory listing for
filenames only; `stat` not needed since dummy path used throughout).
- Full-render sha256: `64fcad80e6ac7ac260a52712be5eb3e6b3a303f655d5983198d30ba2c8d984f6`
- `extensions/pi-permission-system/config.json`: `92aea891e71be339dc1ef5471020fa2be5ddc35b2454fe907528d96a67e27346`
- `mcp.json`: `478530510b31c3eb4abeaac8a33b81f8f3c207df7f56e076ec3f7ae5b6bf9838`
- `settings.json`: `781034d972e657357498c5a4f32c590b0efa9b4953d4fe7661d0cd3087cf046d`
Rendered permission facts (canary): `bash.*=deny` default; allows exactly
`cargo bench*`, `cargo test engine*`, `cmake --build*`, `ctest*`,
`cmake --version*`, `clang --version*`, `rig whoami/ps/queue/send/capture/transcript *`,
read-only git verbs; `path_write` = `src/engine/*`, `tests/engine/*`,
`build.sh`, `CMakePresets.json`, `CMakeLists.txt` (PR #10 scope, present).
Rollback recipe (canary): snapshot first (`rig snapshot heretek-omni-fleet`,
record ID) → member-fragment re-seed from post-merge charters
(`seed-rig.py … --rig <rig-id> --pod engine`) → `rig seat launch
<canary-session> --stop --reason <ref>` (`--plan` first) → misbehavior:
`rig restore <snapshotId> --rig <rig-id>` + re-seed from pre-change charters.
Full text in draft `design.md` §6.
### Remaining STAGED measurements (D1–D7, BC-L3 live round-trip, BC-L4 mutation)
Still STAGED, with exact commands in tasks BC-L2…L5: D1–D7 closeout checks
(no catalog change was made, so no build was runnable — correctly not
attempted); the live authenticated-relay round-trip (BC-L3); the first
per-node refresh mutation (BC-L4). If `seat launch --stop` reports "already
running" or equivalent, STOP and record
the block as a headline finding — that failure IS the spike data for #11
(never bounce the fleet from this spike).
**LIVE UPDATE 2026-10-23: BC-L1 MEASURED.** All five #12 denials re-ran live
from the canary (`engine-engine-systems-eng@heretek-omni-fleet`, via
`rig send`; seat receipt 18:43Z, execution window ~18:44Z). Verbatim seat
result table (5/5 run bare in order, 0 ALLOWED / 5 DENIED, no artifacts,
no qitem, `PENDING_DISPATCH`):
| # | Command | Result | Verbatim denial |
|---|---|---|---|
| 1 | `cmake --preset linux-release` | DENIED | `[pi-permission-system] Denied by policy: 'bash' (rule '*').` |
| 2 | `./build.sh --help` | DENIED | `[pi-permission-system] Denied by policy: 'bash' (rule '*').` |
| 3 | `clang++ -fsyntax-only /dev/null` | DENIED | `[pi-permission-system] Denied by policy: 'path' for tool 'bash' for path '/dev/null' (rule '*').` |
| 4 | `date +%s` | DENIED | `[pi-permission-system] Denied by policy: 'bash' (rule '*').` |
| 5 | `git add src/engine tests/engine` | DENIED | `[pi-permission-system] Denied by policy: 'path' for tool 'bash' for path 'src/engine' (rule '*').` |
Matches the 2026-10-20 issue record exactly (including the path-rule shape
for `clang++`/`git add` and the clock denial — the seat noted no epoch was
returnable, times are the post-receipt execution window). Baseline
reaffirmed; D1–D7 REMAINS STAGED (no catalog change was made, so no build
was runnable — correctly not attempted).
**Companion probes (same window, read-only flags only — MEASURED):**
| Seat | Command | Result |
|---|---|---|
| `systems-cpp-lowlevel-eng` | `cmake --version` | ALLOWED — `cmake version 4.3.0` |
| `systems-cpp-lowlevel-eng` | `./build.sh --help` | harness permitted execution; file absent in seat workspace (exit 127). No build/configure/modify performed. Matches the mock EXEC-ALLOW exactly. |
| `delivery-git-drift-coord` | `git status --short` | ALLOWED (status output returned) |
| `platform-dependency-patcher` | `git status --short` + charter self-check | ALLOWED; seat confirms `git add` NOT in its allowed verbs. No staging/commit/modify. |
**Scratch widened-fragment experiment (dry-run + mock-gate — MEASURED,
real catalog untouched):** `/tmp/spike12-fleet-widened.yaml` (scratch copy,
engine seat +`cmake --preset*` +`date*`) renders config hash `75f6d34d…`
vs baseline `92aea891…` (delta demonstrated); mock-gate of the widened
render flips exactly the two predicted cells (`cmake --preset`,
`date +%s` → EXEC-ALLOW) while `./build.sh --help` and `git add` stay
POLICY-DENY. The A1-vs-A2 decision now has a previewable method, not just
static claims.
**#11 mechanics previews (non-mutating, MEASURED):**
`rig seat launch --fresh --plan <canary>` → `Complete: true; launchable:
false; stop required: true; would stop: false. Blocked: A live managed
occupant requires --stop.` + full sibling-unchanged list (single-target
containment previewed clean). `rig seat handover <canary> --dry-run` →
two-phase plan (prepare successor → atomic rebind), `No changes were made.`
**Execution of `--stop` NOT attempted**: canary owns no queue items
(verified empty pre-contact) but TPM sign-off + in-flight-slice clearance
per the runbook pre-flight checklist are outside this spike's authority —
recorded as blocked-with-reason, not forced. The #11 "already running"
refusal now has a documented successor path (`seat launch --stop` /
handover) whose *preview* is proven and whose *mutation* awaits the gated
wave (task BC-L4).
## 4. Policy-flow map (edit → generate → seed → launch)
`fleet.yaml` surgical edit (never `yaml.safe_dump`) → `generate-rigs.py` →
`verify-rigs.sh` (27/0) → strict `seed-rig.py` (secrets fail closed) →
`launch`/`up`. Running sessions enforce launch-time policy — staleness is
both the #11 pain and the §2.2 safety property; every refresh design in this
package is relaunch-shaped, never mutation-shaped.
## 5. #9 / #11 decision records (disk-side)
**#9 — PROMOTE `send-authenticated.sh` to protocol (12b/B1).** Dry-run verified
in this spike: prints the exact 0.6.13 invocation
(`--source operator … --summary "Operator relay (grounded: …) at …"`,
exit 0); `--help` documents the 0.6.13 requirement, claim-not-proof
semantics, and never-forge-identity rules (exit 0); missing `--human-ref`
aborts with usage error (fail-closed; never falls back to `rig send`, never
claims seat origin; `--source` documented as `claimed:v1` claim-not-proof).
Prior live proof cited (CLI-0.6.13-BUMP.md §8,
`qitem-20261020194128-151843c3600dfc35`). **Live-phase note:** the four spike
probings went via raw `rig send` (per tasking bounds) and all four seats
flagged the expected `Delivered without sender identity` advisory —
`cpp-lowlevel-eng` explicitly noted `No rig send reply possible — sender
address unknown` yet still executed the read-only tasking from the labeled
body. That is both a re-confirmation of #9 and evidence that clearly-labeled
spike tasking is actionable; the live authenticated-relay round-trip itself
is STAGED (BC-L3 — deferred to avoid extra mission-seat traffic; nothing in
this spike contradicts the prior live proof).
**#11 — per-node refresh composition for the live wave to prove.**
New since filing (0.6.13 help text verified daemon-down):
`rig seat launch <seat> --stop --plan` (fresh occupant, exactly one seat,
siblings untouched) + `rig policy permissions apply --seat` (stored policy
for later restores/resumes/launches; explicitly no relaunch itself) +
`rig seat handover --dry-run` (continuity alternative, policy fitness
unproven). `rig seat set-permissions` is explicitly NOT a refresh path
("no relaunch or work-posture change" — recorded to prevent misselection).
SEAT-REFRESH-RUNBOOK stays the fallback until the composition proves live;
its Step-5 crux gets amended on first live use. Upstream CLI fix stays
Workstream C.
## 6. Risks
- Trailing-`*` prefix grants widen silently — every new verb needs a
sabotage red-proof pre-merge (as this spike's own classifier lesson shows,
even measurement needs adversarial care).
- `claimed:v1` source is forgeable — seats must treat it as routing context
+ queue-checkable receipt, never authentication.
- Help text is not behavior proof — every 0.6.13 verb above is STAGED until
live.
- Mock ALLOW ≠ seat truth — live D1–D7 still required before #12 closes.
## 7. Repro commands (all read-only / mock / dummy-secret)
```bash
# matrix + git-write audit (read-only; reproduces the §1 table: 51 roles, 15 with build verbs)
python3 - <<'EOF'
import yaml
d = yaml.safe_load(open('fleet/fleet.yaml'))
roles = d['roles']
toks = ['cmake','ninja','ctest','build.sh','clang','cargo test','cargo bench',
'go test','go build','npm test','pytest','gradlew','cargo build']
print("roles:", len(roles))
n = 0
for name in sorted(roles):
ba = (roles[name].get('permissions') or {}).get('bash_allow') or []
hits = [b for b in ba if any(t in b for t in toks)]
if hits:
n += 1
print(f"{name}: {hits}")
print("roles-with-build-verbs:", n)
EOF
grep -c "git add" fleet/fleet.yaml # 0
grep -n "git commit\|git checkout" fleet/fleet.yaml
# canary baseline (dummy secrets)
mkdir -p /tmp/spike12-dummy-secrets && chmod 700 /tmp/spike12-dummy-secrets
printf dummy > /tmp/spike12-dummy-secrets/github.pat
printf dummy > /tmp/spike12-dummy-secrets/opencode-go.key
chmod 600 /tmp/spike12-dummy-secrets/*
HERETEK_SECRETS=/tmp/spike12-dummy-secrets python3 scripts/render-seat.py \
--role engine-systems-eng --rig game-dev-and-sim-rig --pod engine --dry-run
# gate mocks (mock model, no fleet)
bash scripts/gate-role.sh <role> # engine-systems-eng, cpp-lowlevel-eng: PASS (see §8 notes)
# wrapper check
scripts/send-authenticated.sh --destination <seat> --message <t> --human-ref <r> --dry-run
# untouched floor
./scripts/verify-rigs.sh --check-only # 27/0
```
## 8. Self-audit + hand-off status
- No `fleet/fleet.yaml` edit (all catalog reads); no regen; no `verify-rigs.sh`/`Makefile` edits; no generated-leaf touches; no commits; no pushes; no secret contents touched.
- Full gate suites (foreground re-runs 2026-10-23, mock model, exit 0 throughout): engine-systems-eng PASS (40 ok, 0 FAIL), cpp-lowlevel-eng PASS (40 ok, 0 FAIL), dependency-patcher PASS (38 ok, 0 FAIL), git-drift-coord PASS (40 ok, 0 FAIL).
- `git status` at hand-off (2026-10-23, exact output):
```
?? docs/reports/spike-12-build-capability.md
?? openspec/changes/issue-12-build-capability/
```
Report + draft package only. Uncommitted by design.
- Live-vs-STAGED: live was NONE at first gate check (fleet DOWN) —
CORRECTION 2026-10-23: after the coordinator's `rig up` restore (verified
51/51 by this spike), BC-L1 (5/5 canary denials), companion probes (cpp /
drift-coord / patcher), scratch widened-fragment dry-run + mock-gate, and
#11 mechanics previews all MEASURED same-day (see §3). STILL STAGED:
D1–D7 (no catalog change made, so no build was runnable — correctly not
attempted), BC-L3 live relay round-trip (deferred to avoid extra
mission-seat traffic; dry-run + --help measured, prior live proof cited),
BC-L4 `--stop` mutation (blocked without TPM sign-off, recorded not
forced).
- Open question for principal: A1's bounded hole-closure list (clock read? artifact paths?) is sketched, not finalized — needs the live D1–D4 attempt to ground it.
@@ -0,0 +1,227 @@
# DRAFT — Design: issue-12-build-capability (spike, for principal approval — NOT implementation)
> **Status: DRAFT.** Companion to `proposal.md`. All static claims verified
> read-only from disk in worktree `.lane/trees/spike-12-builds`
> (branch `docs/spike-12-build-capability` @ `5a244ac`). All live claims
> STAGED (fleet DOWN: `rig ps` → 0 rigs running at spike time). CORRECTION
> 2026-10-23: after restore (51/51 verified), BC-L1/companions/dry-run/
> #11-previews MEASURED same-day; D1–D7/BC-L3/BC-L4 stay STAGED with reasons.
## 1. Corrected capability matrix (static, verified)
Source: `fleet/fleet.yaml`, 51 roles. Method: every `bash_allow` entry
matched against build/test tokens
(`cmake`, `ninja`, `ctest`, `build.sh`, `clang`, `cargo test/bench`,
`go test/build`, `npm test`, `pytest`, `gradlew`, `cargo build`).
| Role | Build/test verbs (`bash_allow`) | Can run canonical entry? | Can stage/commit? |
|---|---|---|---|
| `cpp-lowlevel-eng` | `cmake*`, `ninja*`, `ctest*`, `./build.sh*`, `clang-tidy*` | YES (`./build.sh`) | NO (no `git add` anywhere) |
| `engine-systems-eng` | `cargo bench*`, `cargo test engine*`, `cmake --build*`, `ctest*`, `cmake --version*`, `clang --version*` | NO (no configure, no compiler, no `./build.sh`) | NO |
| `dependency-patcher` | `npm test*`, `cargo test*`, `pytest*`, `go test*` (+ `git checkout*`, `git commit*`) | partial (lang tests only) | HALF (`git commit*` w/o `git add` = dead grant) |
| `go-backend-eng` | `go build*`, `go test*`, `golangci-lint*`, `go mod*` | partial (go only) | NO |
| `rust-systems-spec` | `cargo build*`, `cargo test*` | partial (rust only) | NO |
| `game-systems-dev` | `cargo test game*`, `npm test game*`, `pytest tests/game*` | NO (tests only) | NO |
| `game-ai-dev` | `cargo test ai*`, `npm test ai*`, `pytest tests/game/ai*` | NO | NO |
| `physics-sim-eng` | `cargo test physics*`, `ctest -R physics*`, `ctest --version*` | NO | NO |
| `graphics-shader-eng` | `cargo test rendering*` | NO | NO |
| `python-backend-spec` | `pytest*`, `uv run pytest*` | NO | NO |
| `vector-rag-spec` | `pytest tests/rag*` | NO | NO |
| `ts-node-fullstack` | `npm test*` | NO | NO |
| `sabotage-qa-tester` | `npm test*`, `pytest*`, `cargo test*` | NO | NO |
| `java-kotlin-eng` | `./gradlew test*`, `./gradlew check*` | partial (jvm only) | NO |
| `android-mobile-spec` | `./gradlew testDebugUnitTest*`, `./gradlew assembleDebug*`, `./gradlew ktlintCheck*` | partial (android only) | NO |
| `git-drift-coord` | `git branch*`, `git merge-base*` + read-only git verbs; `builtin:locked`, `READONLY_16_ROLES` | NO | NO |
| all other 48 roles | read-only git verbs + `rig` observability only | NO | NO |
Fleet-wide git-write audit: `git add` → **0 occurrences**; `git commit*` →
**1 occurrence** (`dependency-patcher`, unscoped); `git checkout*` → 1
(`dependency-patcher`). The #12 recon claims check out exactly
("git add absent fleet-wide? git commit only on dependency-patcher?
`./build.sh` only on cpp-lowlevel-eng?" — YES to all three).
**Correction to #12's headline:** 15 roles (not one) hold some build/test
verb. What remains true: exactly ONE seat can drive the canonical
`./build.sh` entry point; ZERO seats can stage; ZERO seats can commit
seat-authored trees. The "cannot build" claim holds for the engine seat's
configure/compile half and for end-to-end (build→stage→commit) everywhere.
Mock-harness confirmation (pi + mock model via `scripts/gate-run.sh`,
rendered from this worktree's catalog — 18 probes, strict classification):
engine seat reproduces the #12 denial set verbatim (`cmake --preset`,
`./build.sh`, `clang++`, `git add` all POLICY-DENY with denial text);
positive controls (`cmake --build`, `ctest`, `cargo test engine`) EXEC-ALLOW;
`cpp-lowlevel-eng` EXEC-ALLOWs `./build.sh` (exit 127 in scratch dir =
policy allowed — the first-pass "DENY" was a classifier false positive,
kept as a lesson in the report); `git add` POLICY-DENY on all four roles
probed; `dependency-patcher git commit` executes but stages nothing (dead
grant demonstrated). Full table in the findings report
`docs/reports/spike-12-build-capability.md` §3.]
## 2. Policy-flow map (edit → generate → seed → launch)
```
fleet/fleet.yaml (surgical text edit; NEVER yaml.safe_dump — strips comments)
→ python3 scripts/generate-rigs.py (bakes specs/, rigs/, rosters/, registry/)
→ ./scripts/verify-rigs.sh --check-only (27/0 floor at spike time)
→ python3 scripts/seed-rig.py <member-fragment> --rig --pod (strict; secrets fail closed)
→ rig launch / rig up (running sessions keep enforcing LAUNCH-TIME policy)
```
**Staleness as safety property.** A running session never silently widens its
own permissions (Constitution §2.2). The #11 pain (one stale seat forces a
fleet-wide bounce) is the same mechanism as the safety guarantee — any
refresh design must preserve it: propagation is always relaunch-shaped, never
mutation-shaped.
## 3. #9 decision record — promote `send-authenticated.sh` to protocol
**Finding.** The #9 workaround (`scripts/send-authenticated.sh` →
`rig queue create --json --verify --source operator --destination <seat>
--summary <text> --body-file <staged>`) is the only operator→seat channel
with verifiable provenance: the queue receipt (`qitemId` + state, parsed
fail-closed) is checkable against the queue itself, unlike `rig send` (no
sender identity) or body self-claims (forgeable). CLI 0.6.13 hardened it
further: `--source` required outside a managed seat (fail-closed), `--summary`
warned-when-omitted; the wrapper already passes both on every invocation.
Live proof exists (CLI-0.6.13-BUMP.md §8: `qitem-20261020194128-151843c3600dfc35`,
seat ACK with `From: operator`).
**Decision (recommended): PROMOTE to protocol as 12b.** Keep the
never-invoke-`rig-send` and never-claim-seat-origin rules; `--source`
recorded as `claimed:v1` (a claim, not proof — documented in the wrapper
header). Remaining gap for the implementation wave: seat-side verification
wording (what a seat checks: receipt `qitemId` visible in `rig queue show` /
transcript metadata) should be pinned in one place rather than living in
wrapper comments. STAGED live item: re-run one relay against the relaunched
fleet and record the transcript ACK verbatim.
**Alternative rejected:** stamping identity via `rig send` headers — no such
verb exists upstream; body self-signing is forgeable. Queue-recorded relay
is the only checkable path with today's CLI.
## 4. #11 design — per-node refresh given CLI 0.6.13
**New verbs since #11 was filed** (help text verified daemon-down on 0.6.13;
behavior STAGED):
- `rig seat launch <seat> [--stop] [--plan] [--reason]` — "Launch a
deliberate fresh occupant for exactly one existing seat … Sibling seats
stay attached and untouched." With `--plan` preview. This is the closest
thing to the missing relaunch verb #11 asks for.
- `rig policy permissions apply <name> [--seat]` — "Record a policy choice
… with `--seat` store it on an existing seat. Restore, resume and launches
that read the seat's stored state use the stored policy." Policy recorded
without relaunch ("this does not relaunch seats").
- `rig seat handover <seat> --dry-run` (`fresh`/`rebuild`/`fork` sources) —
continuity-preserving alternative, policy-change fitness unproven.
- `rig seat set-permissions` — native-permissions selection for future
managed launches only; explicitly "no relaunch or work-posture change"
(NOT a refresh path — recorded here to prevent misselection).
**Recommended refresh composition (for the implementation wave to prove):**
```
snapshot (rig snapshot <rig>, record ID)
→ drain/park seat queue items (queue list --destination; block/fallback)
→ re-seed member fragment from post-merge charters (seed-rig.py)
→ rig policy permissions apply --seat (if stored-policy path needed)
→ rig seat launch <seat> --stop --plan first, then execute
→ confirm: rig ps --nodes + make audit-sessions + make gate ROLE=
→ unpark HELD items
```
Rollback = `rig restore <snapshotId> --rig <rigId>` + re-seed from
pre-change charters + re-launch (existing SEAT-REFRESH-RUNBOOK §5 stands;
amend its Step 5 crux — "`launch` refuses running nodes" — with the
`seat launch --stop` alternative on first live use).
**What stays:** the SEAT-REFRESH-RUNBOOK fallback (remove+launch path) until
the composition above is proven live; the upstream CLI fix stays tracked
under Workstream C. If `seat launch --stop` also refuses or disturbs
neighbors, STOP and record — that failure is spike data, and the runbook's
when-to-bounce rules (§6) govern.
## 5. Ranked options
### 12a — build-runner scope
- **Option A1 (RECOMMENDED): extend the designated runner.** `cpp-lowlevel-eng`
already holds `cmake*`/`ninja*`/`ctest*`/`./build.sh*`. Close its remaining
holes ONLY as far as output-anchored verification needs (e.g. a bounded
clock read for ELAPSED proof — `date*`-shaped grant — and any missing
artifact-path writes), each grant paired with a checkable artifact (exit
code + committed log + no-fetch scan). Authoring seats stay unwidened.
- **Option A2:** widen `engine-systems-eng` with `cmake --preset*` +
compiler + `./build.sh*`. REJECTED as first choice: it merges authorship
and execution in the seat that owns the tree it would then vouch for;
weakens the separation that makes output-anchored verification meaningful.
- **Option A3:** new dedicated `build-runner` role. Viable but heavier
(charter + regen + seed + seat); prefer only if A1's grant list cannot be
bounded within cpp-lowlevel-eng's existing charter.
### 12b — operator-runner protocol
- **Option B1 (RECOMMENDED): promote `send-authenticated.sh` + PRE-AUTH
envelopes** (§3). Process-only, no permission change, provable on the
relaunched fleet in one relay round-trip.
- **Option B2:** new queue-native operator-runner verbs. Upstream work,
out of scope for this repo change.
### 12c — committer scope
- **Option C1 (RECOMMENDED): envelope-shaped committer design.** Standing
`git add`/`git commit` grants are inexpressible safely under trailing-`*`
prefix matching (`git commit*` matches `-a`/`--amend`/arbitrary paths;
`git -c` identity needs separate config surface; `.git/` is deny-guarded).
Design instead: exact-argv allowlisting and/or operator-executed commits
under A2 envelopes, on a non-locked non-readonly role, with TPM-gated
provenance. This is a design task, not a delta — the BUILD-CLOSEOUT
Part-2 refusal stands.
- **Option C2:** scoped `git add/commit` for `git-drift-coord`. REJECTED
(four independent fail-closed reasons in BUILD-CLOSEOUT-CRITERIA.md §5:
unscoped-commit-by-construction, identity surface, wrong role, A2
pre-emption).
## 6. Canary experiment (LIVE LOG 2026-10-23 — was STAGED, now MEASURED where noted)
Canary seat: `engine.engine-systems-eng`
(`engine-engine-systems-eng@heretek-omni-fleet`). Baseline rendered
policy hashes (dry-run, dummy secrets, this worktree's catalog):
- `extensions/pi-permission-system/config.json`: `92aea891…7ae5b6` (full in report)
- `mcp.json`: `47853051…f9838` · `settings.json`: `781034d9…d3087cf`
Planned re-seed/relaunch recipe that would restore the canary (rollback —
only the named preview steps ran 2026-10-23; launch/reseed/restore NOT executed):
```bash
rig snapshot 01M5GWFPKVNQEXQVSAGQ2ANJBE # MEASURED: snapshot 01M5N162P3C5J21KFPCKGHD8XX created
python3 scripts/seed-rig.py <member-fragment-for-engine-systems-eng> \
--rig <rig-id> --pod engine # NOT executed (planned: from post-merge charters)
rig seat launch engine-engine-systems-eng@heretek-omni-fleet --fresh \
--reason "<change-ref>" # MEASURED: --plan preview only ("launchable: false;
# stop required: true", siblings unchanged);
# live --stop execution NOT attempted
rig seat handover engine-engine-systems-eng@heretek-omni-fleet \
--reason "<ref>" --dry-run # MEASURED: two-phase plan preview, no changes made
rig restore 01M5N162P3C5J21KFPCKGHD8XX --rig 01M5GWFPKVNQEXQVSAGQ2ANJBE
# NOT executed (planned rollback handle)
```
Live denial baseline (BC-L1, 2026-10-23 ~18:44Z): 5/5 DENIED verbatim —
`cmake --preset`, `./build.sh --help`, `clang++ -fsyntax-only /dev/null`,
`date +%s`, `git add` — matching the 2026-10-20 issue record exactly; full
table in the findings report §3. D1–D7 REMAINS STAGED (no catalog change,
no build runnable — correctly not attempted).
## 7. Risks
- Prefix-matcher grants widen silently (`trailing-*`); every new verb needs
a red-proof (sabotage replay) before merge.
- `claimed:v1` source is forgeable by construction — seats must treat it as
routing context + queue-checkable receipt, never as authentication.
- Stored-policy (`apply --seat`) vs launch-time enforcementComparisons must
be verified live; help text is not proof.
- Mock-harness allows are catalog truth, not seat truth — live D1–D7 still
required before #12 closes.
@@ -0,0 +1,69 @@
# DRAFT — Proposal: issue-12-build-capability (spike, for principal approval — NOT implementation)
> **Status: DRAFT.** Produced by spike-12-builds (issues #12 + #9 + #11 design
> decisions, canary validation). Disk-side evidence only: the live fleet was
> DOWN at spike time (`rig ps`: 0 rigs running), so every live measurement is
> marked STAGED. CORRECTION 2026-10-23: after restore (51/51 verified),
> BC-L1/companions/dry-run/#11-previews MEASURED same-day; D1–D7/BC-L3/BC-L4
> stay STAGED with reasons (§3 of the findings report). Nothing in this package authorizes implementation; the
> implementation wave is separately gated on principal approval.
## Problem
Issue #12 reports that no seat can execute an end-to-end build. Its headline
claim — "the ONLY build-capable seat is cpp-lowlevel-eng" — is **over-narrow
and needs correction**: a fleet-wide static audit of `fleet/fleet.yaml`
(`bash_allow`, this worktree, 51 roles) shows **15 roles** hold at least one
build/test verb. The still-true core gaps are narrower and more actionable:
1. **No `git add` anywhere fleet-wide** (`grep -c "git add" fleet/fleet.yaml`
→ 0). Staging is impossible for every seat.
2. **No committer for seat-authored trees.** `git-drift-coord` (nominal
committer) holds read-only git verbs only and is `builtin:locked` +
`READONLY_16_ROLES`. `dependency-patcher` holds `git commit*` but without
`git add` that grant commits only already-staged content — a dead grant
for seat-authored work.
3. **Configure/compile dead for the engine seat.** `engine-systems-eng` holds
existing-tree build/test verbs only (`cmake --build*`, `ctest*`,
`cargo test engine*`, `cargo bench*`, plus `cmake --version*` /
`clang --version*`) but NOT `cmake --preset*` (configure), NOT a direct
compiler invocation, NOT `./build.sh*`.
4. **`./build.sh` runnable in exactly one seat** (`cpp-lowlevel-eng`,
via PR #13) — and that seat cannot stage/commit its output (gaps 1–2).
Related backlog (self-governance triple): #9 (operator→seat provenance) and
#11 (no single-node policy refresh). This change designs all three together
because each option below touches the same policy-propagation path.
## Already merged (do not re-litigate)
- PR #10: `engine-systems-eng.path_write` += `build.sh`, `CMakePresets.json`,
`CMakeLists.txt`.
- PR #13: `cpp-lowlevel-eng.bash_allow` += `./build.sh*`.
- CLI 0.6.13 (`rig seat set-permissions`, `rig seat launch --stop`,
`rig policy permissions apply --seat`) — new verbs directly relevant to #11,
discovered during this spike (help-text verified daemon-down, behavior
STAGED).
## Scope of the proposed change (at implementation time)
- **12a — build-runner scope.** Bounded configure/compile/test grants for a
designated runner (options ranked in `design.md`; recommendation: extend
the `cpp-lowlevel-eng` runner rather than widening authoring seats).
- **12b — operator-runner protocol.** Promote `scripts/send-authenticated.sh`
+ the PRE-AUTH-ENVELOPES template to the sanctioned fallback protocol with
provenance (queue-authorized task → operator executes → log hashed into
evidence chain), so today's ad-hoc fallbacks become a designed interface.
- **12c — committer scope.** A grant design that survives prefix-matcher
reality (see `design.md` §4): exact-argv allowlisting, seat git identity
without git-config widening, a non-locked non-readonly role, aligned with
the A2 envelope model — NOT a one-line `git add*` delta.
## Non-goals
- No implementation in this change (spec + design + tasks only).
- No `fleet/fleet.yaml` edit, no regen, no re-seed, no relaunch.
- No `verify-rigs.sh` / `Makefile` edits.
- No live-seat contact beyond the canary: no catalog or policy edits, no
staged-mutation tasks executed (`--stop`, re-seed, restore all NOT run);
live canary probes + MEASURED items stand as stated in the findings report.
@@ -0,0 +1,119 @@
# DRAFT — Spec: build-capability (spike, for principal approval — NOT implementation)
> **Status: DRAFT.** Requirements below are proposal-grade. Every live
> acceptance is TBD-marked STAGED until the gated implementation wave runs
> them against the relaunched fleet. Static acceptances (catalog greps,
> mock-harness probes) are runnable now and cited with exact commands.
## Capability: designated build-runner execution (12a)
### REQ-BC1 — One designated seat drives the canonical build entry
The designated runner seat SHALL execute `./build.sh` (and/or the
equivalent `cmake --preset` configure + `cmake --build` + `ctest` chain)
to exit 0 with a captured build log, on a tree whose SHA is recorded
alongside the log (D1–D4 of BUILD-CLOSEOUT-CRITERIA.md).
- Static acceptance (now): `cpp-lowlevel-eng.bash_allow` contains
`./build.sh*` + `cmake*` + `ninja*` + `ctest*` (already merged, PR #13 —
verify with `grep -n "build.sh" fleet/fleet.yaml`).
- Static acceptance (now): sabotage replays against the rendered runner
policy MUST RED-reject (mock harness, `gate-run.sh` form — e.g.
`./build.sh --help; id` denied by the chaining rule,
`cmake --build x > /tmp/pwned` denied by the write-escape rule,
`ctest | tee /tmp/pwned` denied by the chaining rule). All three verified
POLICY-DENY on the current catalog 2026-10-23. Any future grant widening
MUST re-run this replay set with zero EXEC-ALLOW before merge.
- **TBD (STAGED):** live D1–D4 logs attached to #12 (exit 0, CTest N/N,
tree SHA, ELAPSED). Mock-harness ALLOW is NOT accepted as build proof.
### REQ-BC2 — Runner grants are output-anchored, not trust-based
Every build-adjacent grant SHALL pair with a checkable artifact: exit code
+ committed log + no-fetch scan (no network fetch during build). A grant
without its artifact check is incomplete.
- Acceptance: design doc lists each grant → artifact pair; implementation
wave attaches the artifacts to #12.
### REQ-BC3 — No authoring seat gains execution scope under this change
Authoring seats (notably `engine-systems-eng`) SHALL NOT receive
configure/compile/`./build.sh` grants as part of 12a. Authorship and
execution stay separated so output-anchored verification stays meaningful.
- Static acceptance (now): `engine-systems-eng.bash_allow` contains no
`cmake --preset*`, no compiler invocation, no `./build.sh*`
(`sed -n '/^ engine-systems-eng:/,/^ exec-director:/p' fleet/fleet.yaml`).
## Capability: operator-runner protocol with provenance (12b)
### REQ-BC4 — Sanctioned fallback path replaces ad-hoc fallbacks
Operator-executed build/commit fallbacks SHALL run only under a
pre-authorization envelope (PRE-AUTH-ENVELOPES.md template: path scope,
owning seats, enumerated COMMIT/FILE-QUEUE-ITEM actions, TPM gate, expiry,
revocation, 3-link audit trail), delivered via `send-authenticated.sh`
(queue receipt `qitemId` + state parsed fail-closed).
- Static acceptance (now): wrapper passes `--source` + `--summary` on every
invocation; `--dry-run` prints the exact `rig queue create` form
(`scripts/send-authenticated.sh --destination <seat> --message <t>
--human-ref <r> --dry-run` exits 0).
- Static acceptance (now): NO envelope-validating code or schema exists in
this worktree (verified 2026-10-23: zero matches for envelope/pre-auth
consumers in `scripts/`, `Makefile`, `tests/`) — so the implementation
wave SHALL ship these as binary fail-closed tests, one per required
field: an envelope missing/invalid in path scope, owning seats,
enumerated actions, TPM gating, expiry, revocation, or any of the 3 audit
links MUST be refused (operator holds, no execution); exactly one
fully-populated envelope MUST be accepted. Existing receipt-parsing +
never-raw-`rig-send` coverage stays unchanged.
- **TBD (STAGED):** one relay round-trip on the relaunched fleet with the
seat transcript ACK quoted verbatim.
### REQ-BC5 — `rig send` never carries authority
Raw `rig send` from outside a managed seat SHALL continue to arrive (and be
treated) as UNVERIFIED. No requirement in this package changes seat
fail-closed handling of anonymous relays.
## Capability: committer scope (12c)
### REQ-BC6 — Commit path without standing broad grants
Seat-authored output SHALL reach a commit through ONE of: (a) an
envelope-authorized operator COMMIT under REQ-BC4, or (b) a future grant
design that survives prefix-matcher reality — exact-argv allowlisting (not
path-suffixed `git commit*`), seat git identity without git-config surface
widening, on a non-locked non-readonly role, aligned with the A2 envelope
model.
- Static acceptance (now): no role holds `git add*`
(`grep -c "git add" fleet/fleet.yaml` → 0 stays 0 until the C1 design
lands); `git-drift-coord` stays `builtin:locked` + `READONLY_16_ROLES`.
- **TBD (STAGED):** D5 exercised (scoped stage + commit on a branch,
push-to-main never granted) + D6/D7 (human merge, post-merge re-proof).
## Capability: single-node policy refresh (#11)
### REQ-BC7 — Refresh exactly the affected seats
Charter/permission changes SHALL propagate via a documented per-node path
(recommended composition: snapshot → drain/park → member-fragment re-seed →
`rig policy permissions apply --seat` if needed → `rig seat launch --stop`
with `--plan` preview → audit + gate confirm → unpark), with the
SEAT-REFRESH-RUNBOOK remove+launch fallback retained until the composition
is proven live.
- **TBD (STAGED):** first live use records snapshot ID, `--plan` output,
audit excerpts; if `seat launch --stop` refuses a running node, that block
is recorded as a headline finding (never worked around by bouncing).
BC-L4 acceptance additionally requires, all recorded: sibling seats
preserved (the `--plan` non-target list shows no other seat touched),
queue drain-to-zero before mutation with HELD items unparked (or
explicitly left rerouted) after confirm, and snapshot-restore rollback
proven available (snapshot ID on file pre-mutation).
- Static acceptance (now): help-text verbs exist
(`rig seat launch --help`, `rig policy permissions --help` show the flags
cited in `design.md` §4).
@@ -0,0 +1,63 @@
# DRAFT — Tasks: issue-12-build-capability (spike, for principal approval — NOT implementation)
> **Status: DRAFT.** Disk-side tasks are executable now; every live task is
> marked **TBD (STAGED)** and belongs to the gated implementation wave after
> principal approval + fleet relaunch. Task IDs: `BC-T*` (static/design),
> `BC-L*` (live, STAGED).
## Static / design tasks (runnable now, no fleet)
- [ ] BC-T1 — REQ-BC1/BC3 static pin: record the corrected 15-role
build/test matrix from `fleet/fleet.yaml` with the exact grep + parse
commands (`grep -n "git add"`, `grep -n "git commit"`, per-role
`bash_allow` dump). Acceptance: matrix reproduces byte-identical from
the cited commands on the merge commit.
- [ ] BC-T2 — Mock-harness verb probes: render the 4 recon roles with
`--model-provider mock` and probe the #12 denial set via
`scripts/gate-run.sh` (`cmake --preset`, `./build.sh --help`,
`clang++ -fsyntax-only`, `git add`, plus positive controls `ctest`,
`cmake --build`, `git status`). Acceptance: every probe classified
ALLOW/DENY with the denial text quoted; surprises (e.g. path-rule
denials on `./build.sh` for the designated runner) written up as
findings, not smoothed over.
- [ ] BC-T3 — REQ-BC4 wrapper check: `send-authenticated.sh --dry-run`
prints the exact 0.6.13 invocation (`--source` + `--summary` always
passed); fail-closed validation rejections (`--help` cases) exit 2.
Acceptance: dry-run output + rejection cases recorded.
- [ ] BC-T4 — REQ-BC7 static check: `rig seat launch --help`,
`rig policy permissions --help`, `rig seat handover --help` show the
flags cited in `design.md` §4 on CLI 0.6.13. Acceptance: help excerpts
on file (already captured in this spike).
- [ ] BC-T5 — 12c design alignment: confirm the C1 committer design against
the A2 envelope owner (no pre-emption) and prefix-matcher reality
(exact-argv allowlisting sketch). Acceptance: decision record signed
by principal; BUILD-CLOSEOUT Part-2 refusal stays standing until then.
## Live tasks — TBD (STAGED, gated wave only)
- [x] BC-L1 — **MEASURED 2026-10-23:** 5/5 canary denials live, verbatim
(0 ALLOWED / 5 DENIED, table in findings report §3; matches the
2026-10-20 issue record exactly).
- [ ] BC-L2 — **TBD (STAGED):** D1–D4 live build proof from the designated
runner (build log exit 0, CTest N/N, tree SHA, ELAPSED) attached to #12.
- [ ] BC-L3 — **PARTIAL (dry-run + --help MEASURED 2026-10-23; live
round-trip STAGED):** wrapper `--dry-run`/`--help` verified; raw
`rig send` advisories re-observed live on all four probe seats. Live
authenticated-relay round-trip with seat transcript ACK deferred to
the gated wave (avoid extra mission-seat traffic).
- [ ] BC-L4 — **PARTIAL (previews MEASURED 2026-10-23; mutation STAGED):**
`seat launch --fresh --plan` (blocked: requires `--stop`,
siblings-unchanged preview clean) + `seat handover --dry-run`
(two-phase plan, no changes) recorded; snapshot `01M5N162P3C5J21KFPCKGHD8XX`
taken. `--stop` execution awaits TPM sign-off in the gated wave;
if it refuses, record the block as a headline finding and STOP
(REQ-BC7).
- [ ] BC-L5 — **TBD (STAGED):** D5–D7 committer path + human merge +
post-merge re-proof (REQ-BC6, needs the C1 design approved first).
## Canary rollback (applies to every BC-L task)
Before any BC-L step: `rig snapshot heretek-omni-fleet` (record ID);
re-seed from post-merge charters via member-fragment `seed-rig.py`;
restore with `rig restore <snapshotId> --rig <rig-id>` on misbehavior.
Full recipe in `design.md` §6 and the findings report.