Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
840c88d
bd init: initialize beads issue tracking
pacphi Jul 31, 2026
e12223e
Revert "bd init: initialize beads issue tracking"
pacphi Jul 31, 2026
dbc75c8
fix(frontend): stop swallowing test/audit failures in Makefile
pacphi Jul 31, 2026
4c595ba
ci: run PR checks on PRs into develop, not just main
pacphi Jul 31, 2026
789d5d5
chore(autopilot): scaffold ci-build-optimization pipeline
pacphi Jul 31, 2026
d1f7901
chore(autopilot:ci-build-optimization): re-plan — add phase 7 (Make -…
pacphi Jul 31, 2026
57206df
feat(autopilot:ci-build-optimization): phase 0 complete — gate PASSED
pacphi Jul 31, 2026
1295d39
feat(autopilot:ci-build-optimization): phase 1 complete — gate PASSED
pacphi Jul 31, 2026
d1cd7c5
feat(autopilot:ci-build-optimization): phase 2 complete — gate PASSED
pacphi Jul 31, 2026
8259e8c
chore(autopilot:ci-build-optimization): record cold-cache finding for…
pacphi Jul 31, 2026
efffd0a
feat(autopilot:ci-build-optimization): phase 3 complete — gate PASSED
pacphi Jul 31, 2026
17472c6
feat(autopilot:ci-build-optimization): phase 4 complete — gate PASSED
pacphi Jul 31, 2026
0a53d78
chore(autopilot:ci-build-optimization): record measured CI timings af…
pacphi Jul 31, 2026
c517743
feat(autopilot:ci-build-optimization): phase 5 complete — gate PASSED
pacphi Jul 31, 2026
5a27d5a
feat(autopilot:ci-build-optimization): phase 6 complete — gate PASSED
pacphi Jul 31, 2026
a07de31
feat(autopilot:ci-build-optimization): phase 7 complete — gate PASSED
pacphi Jul 31, 2026
4aa1c51
chore(autopilot:ci-build-optimization): cross-phase optimization — ga…
pacphi Jul 31, 2026
fa1eda8
fix(autopilot:ci-build-optimization): integration court REMAND — char…
pacphi Jul 31, 2026
b876bf0
chore(autopilot:ci-build-optimization): integration court SHIP — char…
pacphi Jul 31, 2026
f3c0b42
fix: close the four open items from the ci-build-optimization pipeline
pacphi Jul 31, 2026
78b9e96
fix(docker): postgres runs as uid 70, not 999 — the stack could never…
pacphi Aug 1, 2026
8d1a90b
fix(config): give the ONNX model cache a writable path
pacphi Aug 1, 2026
2e9048b
fix(docker): frontend tmpfs ownership + wait for backend before nginx…
pacphi Aug 1, 2026
16e5148
fix(docker): probe the frontend on 127.0.0.1, not localhost
pacphi Aug 1, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
103 changes: 103 additions & 0 deletions .autopilot/court/ci-build-optimization/integration.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
# qe-court record — ci-build-optimization, integration (develop -> main)

**Delivery:** the full 8-phase CI/build/Docker optimization, `main...develop`
(44 files, +2387/-1438) plus the cross-phase optimization pass.
**Date:** 2026-07-31 · **Seat:** the release go/no-go, per ADR-124.

## Panel — properly seated for the first time in this pipeline

The user fixed the jury routing before this convening (`.claude/skills/qe-court/config.json`).
Earlier phase courts could not seat a jury at all because 4 of 8 roles, including the
jury, routed to Cognitum, which is unconfigured in this environment.

| Role | Provider | Vendor |
| ---------------------------- | ------------------- | ------ |
| Writer (author under review) | claude-code | Claude |
| Jury | codex | GPT |
| Deeper reviewer | codex (high effort) | GPT |

`writerIsNeverJuror`: **SATISFIED** — the jury is a different vendor from the author.
`minDistinctVendors: 2`: **SATISFIED**.

**Caveat, stated plainly:** the jury's run was partly polluted by an injected plugin
preamble (the accepted risk recorded in `config.json._acceptedRisk`). It nonetheless
read the real diff — the transcript shows it running
`git diff --unified=40 main...develop` over the justfiles, ADR-032 and the setup
scripts — and returned a substantive, file-cited verdict. It is counted as a real
juror. The kill round and overturn round were NOT run, so this is still weaker than
the full ADR-124 protocol.

## Verdict: REMAND — charges upheld and fixed

Both charges were verified against the repo before being accepted, and both were
things the author's own Tier-3 reviews had missed.

### Charge 1 — false-green release assurance (UPHELD, FIXED)

Phase 6 added a paths-scoped `pull_request` trigger to `docker.yml` so image
packaging is verified pre-merge. The filter omitted inputs the image actually
consumes: `backend/entrypoint.sh`, `backend/migrations/**`,
`backend/rust-toolchain.toml`, and the `ruvector` submodule gitlink — all of them
`COPY`ed by `backend/Dockerfile`. A packaging regression in any of those could merge
with the Docker jobs never running, defeating the guarantee the trigger was added to
provide.

**Fix:** filter extended to every COPYed input, with a comment tying it back to the
Dockerfile's COPY lines. `backend/src/**` is deliberately excluded and the reason
recorded inline — it is COPYed, but the rust-build/rust-test jobs already compile it
and a cold release build per source change is not worth the cost.

### Charge 2 — incomplete task-runner migration (UPHELD, FIXED)

Phase 7 deleted the Makefiles, but live `make` commands survived in user-facing
places the author's sweep never covered — it grepped docs and `make <target>` in
shell scripts, but not source code, and not the `make -C <dir>` form in scripts:

- `frontend/apps/web/src/features/onboarding/OnboardingFlow.tsx:122` — the **product
onboarding UI** displayed `make dev` to end users.
- `backend/src/main.rs:207` — the CLI printed `Run 'make models'`.
- `scripts/setup-ai.sh:92`, `scripts/setup-validate.sh:108` — `make -C backend build`
/ `make -C frontend install`.

Every one pointed at a command that no longer exists.

**Fix:** all corrected; a repo-wide sweep across `.sh`, `.rs`, `.tsx`, `.ts`, `.yml`,
`.json` now returns no live `make` invocation. Verified after the edits:
`cargo check` clean, `tsc --noEmit` clean, `shellcheck` clean, `just lint` and
`just format-check` green.

### Charge 3 — ADR-032 status (NOT UPHELD)

The jury flagged ADR-032 as "Accepted" while the branch claims implementation. This
repo's ADR convention uses **Accepted** for decisions that are made and implemented
(ADR-031 uses **Proposed** for design-only). No change.

## For the human judge

**Strongest case FOR merging:** the core engineering holds up — 1177-test parity
proven by execution across the nextest migration, toolchain drift removed and then
de-duplicated, four swallowed exit codes fixed, and two genuinely broken release
images (wrong build stage; glibc mismatch that built clean but could not run) now
fixed and verified on the amd64 architecture that actually ships.

**Strongest case AGAINST:** CI proves images _build_, not that the system _runs_.
Three disclosed gaps remain open and are not addressed by this branch — the Compose
healthcheck passes a flag `main.rs` does not parse (so the container can never report
healthy), the frontend image cannot serve standalone, and the Lighthouse budgets are
all `warn` so that job still cannot fail. None is a regression introduced here; all
three are recorded as parking-lot items. A container-start/health smoke test is the
single highest-value thing still missing.

## Re-convening (protocol: REMAND -> fix -> re-convene once)

Re-convened on the fix commit only. The jury ran clean this time (no plugin
derailment) and checked the current files directly:

> CHARGE 1: RESOLVED — All four Docker inputs are now included in the PR paths filter.
> CHARGE 2: RESOLVED — All four live commands now use `just`; no reviewed files differ from the fix commit.
> **FINAL: SHIP**

Verdict stands as **SHIP**, from a jury of a different vendor than the author.
The kill round and overturn round were still not run, so this remains short of
the full ADR-124 protocol — but the seating invariant (`writerIsNeverJuror`) held
and both upheld charges were reproduced, fixed, and independently re-verified.
119 changes: 119 additions & 0 deletions .autopilot/court/ci-build-optimization/phase-4.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
# qe-court record — ci-build-optimization phase 4

**Delivery:** restructure Rust CI to build test binaries once into a `cargo-nextest`
archive consumed by `rust-test` (OPTIMIZATION_SPEC F-5).
**Date:** 2026-07-31 · **Phase:** 4 (in `risk_phases`) · **Court mode:** `auto`

---

## ⚠️ Panel could NOT be seated as configured — read this before trusting the verdict

`.claude/skills/qe-court/config.json` routes 4 of 8 roles to **Cognitum**
(`prosecutor.devils-advocate`, `prosecutor.sherlock`, `prosecutor.security-scanner`,
and — critically — **`jury`**). Cognitum is **not configured in this environment**:
no `COGNITUM*` env var, and `aqe llm-router config` returns nothing.

The skill also mandates calling `validateCourtConfig()` from
`src/skills/qe-court/referee.ts` before seating a panel. **That file is not present**
in this project's skill install (`.claude/skills/qe-court/` contains only
`config.json`, `evals`, `schemas`, `scripts`, `SKILL.md`), so the machine-checked
invariant validation could not be run at all.

Per the skill's own instruction — _"do not proceed with a degraded panel and do not
silently re-route around it"_ — this is recorded as a **partial court**, not a full
one. What actually ran is stated plainly below. **This verdict carries less weight
than a fully-seated court** and should be read as one strong cross-vendor lens plus
the Tier-3 floor, not as the ADR-124 protocol.

| Role | Configured | Actually run |
| ----------------------------- | ------------- | ------------------------------------------------------ |
| Defense | claude-code | — (not run) |
| Prosecutor · devils-advocate | cognitum-mid | ❌ vendor unavailable |
| Prosecutor · brutal-honesty | claude-code | ✅ ran as the Tier-3 reviewer subagent |
| Prosecutor · sherlock | cognitum-high | ❌ vendor unavailable |
| Prosecutor · security-scanner | cognitum-mid | ❌ vendor unavailable |
| Prosecutor · mutation | ollama | ❌ not run |
| Prosecutor · codex-review | codex | ✅ ran (`codex exec`, GPT — true cross-vendor) |
| Jury | cognitum-high | ❌ **vendor unavailable — no independent jury seated** |
| Deeper reviewer / overturn | codex | ❌ overturn round not run |

**Anti-collusion status:** 2 distinct vendors did file charges (Claude + GPT-via-codex),
satisfying `minDistinctVendors: 2`. But `writerIsNeverJuror` could not be _enforced_
because no jury was seated — the author (Claude) adjudicated the charges. That is the
weakness in this record. The human judge is the real backstop.

---

## Charges filed

### Prosecutor: brutal-honesty / Tier-3 reviewer (Claude) — 2 blockers, 1 false claim

| # | Charge | Status |
| --- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------- |
| 1 | **Arch split.** `rust-build` used `HEAVY_RUNNER` while `rust-test` hardcoded `ubuntu-latest`. A nextest archive is host-bound (pins host target triple, ships host libstd). Setting `HEAVY_RUNNER` to `ubuntu-24.04-arm` — its documented purpose — would emit aarch64 binaries `rust-test` cannot exec. Impossible before the split, when build+run shared a runner. | **REPRODUCED → FIXED** (both jobs now share `runs-on`) |
| 2 | **Bench gated the artifact.** `cargo bench --no-run` ran before `upload-artifact`, so a bench-only break aborted the job pre-upload and skipped `rust-test`. | **REPRODUCED → FIXED** |
| 3 | **False claim in my own comment.** I wrote that benches were "nearly free" in `rust-build` because they share its target dir. Verified false: `cargo bench --no-run` builds the _optimized_ `bench` profile into `target/release`, a separate full dep-graph build. | **CONFIRMED → comment removed, bench moved to its own job** |

### Prosecutor: codex-review (GPT — cross-vendor) — 3 charges

| # | Charge | Status |
| --- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 1 | **Test-signal suppression.** Moving `upload-artifact` earlier fixes artifact _availability_ but not job _conclusion_. A failing doctest step after the upload still fails `rust-build`; `rust-test` `needs:` it, so GitHub skips `rust-test` and all ~1177 tests go dark. **The upload-first comment was false.** | **REPRODUCED → FIXED.** `rust-build` now _ends_ at upload; doctests moved to independent `rust-extra-checks`. |
| 2 | **Version-skew / supply-chain race.** Both jobs installed `cargo-nextest` unpinned via mutable `@v2`. A release landing between the jobs could mismatch archive producer and consumer; nextest's archiving docs require matching versions. | **VALID → FIXED.** Both pinned to `cargo-nextest@0.9.140`. |
| 3 | **Merge-gate regression.** Benches moved out of the `Rust Tests` context; if branch protection required only that context, a bench failure would no longer block merge. | **NOT CURRENTLY EXPLOITABLE.** Verified via `gh api`: neither `main` nor `develop` has branch protection, so there are no required contexts to regress. Recorded for whenever protection is added — the new job names (`rust-build`, `rust-extra-checks`) must be included. |

**Notable:** charge 1 from the cross-vendor prosecutor is exactly the kind of finding
the court exists for — the Claude-side reviewer found the _adjacent_ bug (ordering)
and I applied a fix that looked sufficient but wasn't. A second vendor caught that the
fix was incomplete. Single-lens review would have shipped this.

---

## Kill round

Not run (no blind refuter seated). All charges above were instead **verified directly
by reproduction or by reading the authoritative source** before being accepted:

- Charge 3 (merge-gate) was _downgraded_ by direct evidence (`gh api` → 404 "Branch not protected").
- The bench-profile claim was confirmed by observing `cargo bench --no-run` build the optimized profile.

## Verdict

**REMAND → charges fixed → re-rendered as SHIP (partial court).**

Every reproduced charge was fixed in-phase; none was waived. The verdict is marked
_partial_ because no independent jury was seated and no overturn round ran, so the
asymmetric "SHIP must survive escalation" guarantee — the mechanic that makes a court
harder to fool than a review — **did not apply here**.

## Evidence backing the delivery

- Archive builds: 15 binaries, 106 files, **125 MB**.
- Run-from-archive in a _different directory_: **1177 tests run, 1177 passed, 7 skipped**.
- `cargo test --workspace`: **1177 passed, 7 ignored** — exact parity, no lost tests.
- Doctests: 2 present, both `ignored`, **0 executed** either way → nextest's lack of
doctest support costs nothing today, and `rust-extra-checks` now guards future ones.
- `--workspace-remap .` and `--profile ci` both verified working locally.

## Correction to an earlier record

The phase-0 PR and ledger reported **"39/39 tests passing."** That was **wrong** — it
summed only the tail of `cargo test` output and missed `lib.rs` (1004 unit tests) and
`main.rs` (65). The real figure was always **1177**. Corrected here for the record.

## For the human judge

**Strongest case FOR shipping:** exact 1177-test parity between the old and new paths,
verified by execution rather than inference; every charge from two vendors was
reproduced and fixed rather than argued away; the wall-clock win is structural
(`rust-build` runs concurrently with clippy instead of `rust-test` waiting for clippy
and only then compiling).

**Strongest case AGAINST:** no independent jury and no overturn round — the author
adjudicated charges against their own work. Two of the three most serious findings
were caught only _after_ an initial fix looked adequate, which is evidence the
remaining unreviewed surface may hold more. The 125 MB artifact round-trip is new
per-run cost that partially offsets the scheduling win, and has not been measured in
CI. And the real wall-clock benefit is still **unproven in CI** — the rust-cache has
been cold since phase 1 (`pl-rust-cache-cold-after-env-change`), so no trustworthy
warm baseline exists to compare against yet.
Loading
Loading