Releases: bpmforge/attest
Release list
v3.10.0 — conductor hardening (GH #6 + twelve found auditing it)
Conductor hardening: the six defects reported in #6 by an external maintainer, plus twelve found while auditing them.
The two worst were not in the report, and affected every prior release:
- A chatty model self-approved. The review and runtime gates were unanchored
.test(body)regexes, and both prompts containVERDICT: APPROVED/RUNTIME: PASSas instructions — so a model that restated its instructions was read as approving. Reproduced: a document endingVERDICT: CHANGES REQUESTEDread as APPROVED. - Post-approval code landed unreviewed. Round 3 runs as the coder agent with the worktree writable; an edit inside
write_scopepassed the scope re-check and was folded into the closed commit by an unguarded amend.
Reported and fixed: reviewer fixes could escape write_scope (the scope gate ran after git commit --amend, and git status --porcelain is empty on a committed tree); the run lock died ENOTDIR in a linked worktree; blocking findings now cross the attempt boundary as findings, not reviewer names; --max-processed separates the activity ceiling from --max-tickets' success target; bounded runtime repair (--runtime-fix-iterations, default 1) that re-earns every gate; POSIX process-group timeout containment that fails closed.
Also found: the scope gate's containment bypass — **/*, */**, */* and [a-z]*/** each authorised the whole repo, because "refuse a bare *" was a blacklist of four literal strings; renames checked on one side only; close() ran verify with no timeout and a 1MB buffer that refused green tickets while reporting "did not exit 0"; provider-limit exhaustion crashed the run; STOP ignored during a 60m backoff; deletions invisible to reviewer selection.
Test harness: validate-scope.match.test.sh had been cited as proof the matcher was "fixture-backed" since v3.8.0 and no harness ever ran it — while testing its own copy of the matcher. Six more orphaned suites found (45 tests, including the entire JIRA board driver's coverage). Pass 53 now discovers every *.test.mjs under scripts/ rather than listing them.
Conductor coverage 19 → 93 tests. Full suite 724 passed, 0 failed. Every new negative control verified red against its prior commit.
Closes #6.
v3.9.0 — autopilot hardening, live-proof receipts
Every fix carries a receipt from the first live end-to-end /autopilot run (two tickets: coded by terra, reviewed by luna, runtime-verified, merged, board drained). Single-conductor lock; the machine owns the runtime verdict (agent FAILs the conductor's own verify can't reproduce are overridden); lean reviewer default (the orchestrator died docless in bounded unattended rounds — restorable via models.json agents.reviewer); evidence inside the project; /autopilot OPERATE section — the PRIMARY agent kicks off, tracks, and reconciles, with handoffs only where the HEAL ladder names one; dead-code tool detection now matches the harness probe (global binaries honored). 725 tests green under both tool PATHs.
v3.8.0 — JIRA board-driver conductor hardening
PR #3 merged after review: the scope gate finally GLOBS — validate-scope.sh's matcher was a quoted literal test, so glob-authored write_scopes silently matched nothing; the new matcher keeps literal behavior first, refuses bare /* and .. traversal, anchors full-string, and is fixture-backed. Plus: PR-bound tickets stay open until merge, resume state survives supervised restarts, baseline/process failures split from code exhaustion, --no-merge pushes the ticket branch, checkpoint-commit before review rounds, and the jira-tickets library with parity + integration tests. 725 tests green. install.sh unchanged by design: it copies scripts/ and skills/ wholesale and stamps the installed version from package.json.
v3.7.0 — /autopilot: opencode as orchestrator with auto-heal
The /goal contract made drivable: ASSESS what's left (board + gate receipts + requirement-closure denominator in STORIES, product map, unmerged branches, red suites) → DECIDE the path (ordered next-actions, each with an exit predicate) → DRIVE the existing loops (conductor/run-until-done/run-plan; NEVER-AUTO still pauses) → HEAL stuck work (narrowed retry → split → tier escalation → durable park with evidence; byte-identical gap set twice = no-progress halt) → EXIT on the proven-product predicate. 725 tests green; planted-red self-test proves the checks bite. attest-claude unchanged (0 generated files; /autopilot tracked in KNOWN_MISSING_IN_CLAUDE beside /wave and /goal).
v3.6.0 — Group P A-wave + P6 product-shape doctrine
Group P A-wave (A1–A15: three-level review model, conductor-first Phase 4, path+risk review triggers, citation gate, fixture-proving CI, rules primitive, /wave, /goal, consensus tiers, 5-state runtime verdicts, seams, requirement ledger) — previously merged unreleased — plus the P6 product-shape doctrine ported from Dokima: PRODUCT_SHAPE_PROTOCOL with the canonical role table (GOAL/ORCHESTRATOR/BOTS/REVIEW PANEL/HONESTY LOOPS) + two-stack rule, the feature map as a mandatory decomposition artifact (features from cited stories, connects_to edges from seams, gaps both directions, F-unmapped shouts), and feature-grouped landing (one merge per FEATURE, never per ticket; blocked holds the whole feature). 696 tests green, 98 agents in sync, Pass 55 pins the doctrine RED-capably.
v3.5.0 — gauntlet loop
Gauntlet loop as a first-class quality harness: /gauntlet + gauntlet-lead — builders never grade their own work, blind fresh-per-round critics grade against a named real exemplar, loop until all-pass / 2-round stall / budget. See CHANGELOG 3.5.0.
v3.4.0 — visual design loop
Claude-Design-style visual iteration: /design-iterate + design-iterator (render → screenshot → critique vs tokens.json → fix → re-verify), real-browser bridge tiers (no custom extension needed), design-chain wiring into sdlc phases, screenshot gates relocated to scripts/lib. See CHANGELOG 3.4.0.
v3.3.1 — a fresh WSL box could not bootstrap Node, and the README assumed git
v3.3.1 — a fresh WSL box could not bootstrap Node, and the README assumed git
Checked v3.3.0 against a genuinely empty machine and found three gaps:
- The v3.3.0 preflight called ensure_tool before defining it, so every check silently did nothing; once fixed, it still ran after the Node check — and nvm downloads over HTTP, so a box without curl failed to install Node before curl was ever offered.
- curl was assumed. Now ensured, with ca-certificates alongside it, and the nvm bootstrap falls back to wget.
- The README's first command is git clone, which is command-not-found on fresh WSL. Both READMEs now open with the one bootstrap line per platform and say that single step is the only manual one.
Contract test pins the ordering, having made the same mistake twice in one sitting.
626 tests green.
v3.3.0 — stop shipping 'installed' when nothing got registered
v3.3.0 — stop shipping 'installed' when nothing got registered
The MCPs are not containers: each is a stdio process opencode spawns itself. Nothing to start, no Docker/Podman, same on macOS/Linux/WSL. Registering the path IS the install — which is why a missing jq made it fail silently. The installer built and smoke-tested every server, printed paste-this-JSON mid-log, and exited 0.
- Package-manager layer (brew/apt/dnf/yum/pacman/zypper/apk) with ensure_tool: detect, explain why, offer the exact command, run, re-verify. Native build deps were apt-only and now use it too.
- git and jq are checked in preflight; git was never checked despite three clones.
- A skipped registration now names the servers and exits 1 under 'Installation INCOMPLETE'.
- doctor.sh audits MCP health: path exists, stdio servers answer a real initialize. Caught a bug in itself — jq's // treats false as empty, so a disabled server read as enabled.
625 tests green.
v3.2.1 — a P1 use case between two P0 rows was promoted to P0
v3.2.1 — a P1 use case between two P0 rows was promoted to P0
validate-requirements-matrix.sh read priority with grep -A5, and a 5-line window in a UC index table reaches the next four rows — so any P0 neighbour promoted a P1/P2 case. Reported 18 P0 on a real 19-case catalog where the truth is 14, while validate-sequence-coverage.sh read the same file and said 14.
Priority now comes from the case's own row, or its own section bounded by the next heading. Never a window. Both validators agree at 14.
625 tests green.