mirror of
https://github.com/Heretek-AI/heretek-rigs.git
synced 2026-11-07 10:55:57 -10:00
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:
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.
|
||||
@@ -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.
|
||||
Reference in new issue
Block a user