Skip to content

Releases: fusebase-dev/fusebase-flow

v3.26.0 — context-compression discipline

16 Jun 01:36

Choose a tag to compare

FuseBase Flow v3.26.0 — FR-26 context-compression discipline (large-output / repeat-output audit, MCP coverage)

Release date: 2026-06-15
Previous version: 3.25.1
Type: MINOR (feature — additive)

Summary

Extends FR-26 (token-efficient execution) from read-side hygiene to large context and large output — the case where loading a big input or tool result whole is itself the waste. Adds a new ## Context compression discipline section to the token-economy skill plus two new candidate classes in /token-waste-audit: large-output (oversized results from any output-producing tool) and repeat-output (the same large body re-sent across turns). Clean-room original, MIT, stdlib-only, no new dependency. No new FR rule and no new skill — this extends the existing FR-26 / token-economy carrier, so the FR range (FR-01..FR-26) and the skill count (31) are unchanged.

The discipline is routing, not a budget: it slices and points to large artifacts and keeps compressed context honest. The Guardrail still governs — quality outranks tokens, and nothing here authorizes skipping a needed read or thinning verification.

What ships

Piece What it does
## Context compression discipline in flow-skills/token-economy/SKILL.md Behavioral rules with per-row quality guards: content-route-before-consuming, extract-before-reasoning, preserve-the-retrieval-path (every summary carries a handle back to ground truth), original-before-edit, summary-is-not-authority, stable-context-floor, cross-agent dedupe, reference-an-in-context-body-once, large-output hygiene (anticipate then narrow), generated/vendored restraint, and compression-is-not-verification.
large-output audit class Flags tool results ≥20k chars from any output-producing tool — built-in and MCP (write tools excluded via a generic predicate). Corrects a real coverage gap: the prior allowlist silently missed MCP tools, so oversized MCP results were never surfaced.
repeat-output audit class Flags the same large body re-sent across turns, fingerprinted by a one-way stdlib hash — the body is never emitted into the report. A fresh first inclusion or a deliberately re-run command's new output is not a re-send.

All findings are reported as candidates that MAY indicate an FR-26 rule (the report header lists the known false-positive classes) — never verdicts.

Clean-room

Clean-room original FuseBase Flow content: FuseBase-native behavioral rules + deterministic, stdlib-only audit heuristics. No third-party code, prompts, skill/command/hook text, docs, benchmark language, or dependency is copied or vendored. No third-party tool is named in any shipped artifact. Attestation recorded in docs/source-map.md (§ FR-26 context-compression discipline, dated 2026-06-15).

Validation

Triple-validated before ship: a gap-analysis workflow pass, two independent Codex SHIP reviews, and a name/license firewall audit (the conceptual reference is Apache-2.0; nothing was copied; the firewall-term grep over the repo returns 0).

Verified

preflight 0/0 (committed tree) · python -m py_compile hooks/local/token-waste-audit.py OK · check-module-size --all exit 0 (parser ~479 lines) · mirror-skills 31 skills / 0 drift (manifest byte-identical) · firewall-term grep over the repo = 0 · LICENSE untouched (MIT) · plugin == VERSION == 3.26.0 · GEMINI.md = v3.26.0 · README badge = 3.26.0 · sync --dry-run framework-scoped (no consumer doc touched; under-reach guard passes) · FR-07 clean (version-string attestation sweep only; no FR rule rows, no deploy-policy rule semantics, no ratchet-governance.yml). FR-range FR-01..FR-26, 31 skills unchanged. Feature commit 6d97829.

Feature smoke (post-deploy)

A synthetic transcript built outside the repo with an oversized mcp__-tool result and an identical large body sent twice: the audit fires large-output ≥1 (including the MCP tool) and repeat-output ≥1, and a unique content marker planted in the bodies appears 0 times in the report (the one-way hash never emits the body).

Rollback

git revert <release commit> — additive (skill section + two audit classes + docs); behavior-preserving for the existing audit classes; no new dependency. Re-push; re-mirror. Tag v3.26.0.

v3.25.1 — adoption-hop baseline merge-preserve

15 Jun 16:44

Choose a tag to compare

FuseBase Flow v3.25.1 — adoption-hop baseline merge-preserve (the v3.25.0 U3/W2 merge now runs on the FIRST upgrade adopting v3.25.x)

Release date: 2026-06-15
Previous version: 3.25.0
Type: PATCH (hotfix)

Summary

Hotfix — baseline merge-preserve now runs on the first upgrade adopting v3.25.x. v3.25.0 shipped the U3/W2 module-size-baseline.txt + policy-state merge-preserve rule, but a post-ship Codex adversarial review found it was skipped on the adoption hop — the very first upgrade that brings a project onto v3.25.x. Root cause: upgrade.sh sourced the merge lib from the local (pre-upgrade) tree before hooks/ was refreshed, and bootstrap-upgrade.sh did not stage hooks/local/lib/, so the new merge code was never on disk when the merge had to run. Result: a project's own module-size-baseline.txt rows were clobbered on adoption — exactly the WorkHub Managed failure U3 was meant to fix, just one hop earlier than the gate caught.

This release is bounded to how/when the merge lib is sourced plus bootstrap staging, routing docs, and a new RED-then-GREEN adoption-hop test. The LOCKED merge rule itself is unchanged (ownership = upstream-baseline membership; project rows absent upstream preserved verbatim) — only the source-ordering that lets that rule actually execute on the adoption hop.

Why this is a hotfix, not speculative

The blocker was found by a post-ship Codex adversarial review of v3.25.0 and reproduced with a RED-then-GREEN integration test: the pre-fix engine loses the project baseline row on the adoption hop (RED), the fixed engine preserves it (GREEN). Codex re-review verdict: SHIP.

What ships

ID Piece What it does
P1 bootstrap-upgrade.sh stages hooks/local/lib/ The bootstrap path now stages the merge lib so the new upgrade.sh finds its merge code before handoff. Commit 49f335c.
P2 upgrade.sh sources the merge lib from the authoritative target tree Sources from $SOURCE_CLONE/hooks/local/lib/ (the version being adopted) with a local fallback, re-sources before Step 1a, and prints a loud no-skip warning if the merge lib can't be loaded — so a silent skip can never recur. Commit b562166.
P3 README routing Pre-v3.25 installs are routed through bootstrap-upgrade.sh for the v3.25.x hop (the merge ships in the target version; a clobbered baseline is recoverable from the .pre-upgrade backup). Commit 5324358.
P4 RED-then-GREEN adoption-hop integration test New hooks/tests/test-bootstrap-baseline-hop.sh (13 cases) wired into run-tests: proves the pre-fix engine loses the row and the fixed engine preserves it, plus the P1 bootstrap-staging preconditions. Commit 28fe2ea.

ACCEPTED-RISK

An old, already-installed upgrade.sh run directly (not via bootstrap) still cannot run the target-version merge code — it predates the fix and sources its own old lib. This residual is mitigated by routing pre-v3.25 installs through bootstrap-upgrade.sh (P3 docs) and is the only residual Codex flagged. Use bootstrap-upgrade.sh for the v3.25.x hop.

Verified

preflight 0/0 · run-tests 92/92 PASS (79 + 13 new adoption-hop cases) · check-module-size --all exit 0 · mirror-skills 31 skills / 0 drift (manifest byte-identical) · sync --dry-run framework-scoped (consumer docs excluded; under-reach guard passes) · plugin == VERSION == 3.25.1 · GEMINI.md synced to v3.25.1 · recovery-sim 31/31 exit 0 (state/audit/recovery-sim-v3.25.1-2026-06-15.log) · health no PARTIAL_UPGRADE false-positive · bash hooks/tests/test-bootstrap-baseline-hop.sh PASS on the released tree · FR-07 clean (version-string sweep only; no FR rule rows, no deploy-policy rule semantics, no ratchet-governance.yml, and the LOCKED merge rule untouched — only how/when the lib is sourced). FR-range FR-01..FR-26, 31 skills unchanged.

Credit

Found by post-ship Codex adversarial review of v3.25.0. The discipline of running an independent adversarial review of the shipped code caught a real adoption-hop blocker the self gate-report missed.

Rollback

git revert <SHA range 49f335c..28fe2ea + release commit> — additive (script source-ordering + bootstrap staging + docs + test); steady-state behavior is unchanged (the merge rule and content model are untouched). Re-push; re-mirror. Tag v3.25.1.

v3.25.0 — upgrade-tooling hardening

15 Jun 11:29

Choose a tag to compare

FuseBase Flow v3.25.0 — upgrade-tooling hardening (Windows perf, baseline/policy merge-preserve, sync allowlist, GEMINI sync, PARTIAL_UPGRADE)

Release date: 2026-06-15
Previous version: 3.24.0

Summary

The v3.23.x content model is correct and well-guarded — but the refresh/upgrade scripts forced manual intervention on Windows. Two independent consumer projects filed the same friction during a v3.21.1 → v3.23.1 upgrade on Windows/Git-Bash:

  • paperclip+hermes-v1upgrade.sh stalled mid-mirror (operator killed it and finished by hand), churned 11 consumer docs on an EOF-newline strip, and rewrote FR references inside historical consumer docs. (I1–I9, plus a proven hash-spawn-batch patch.)
  • WorkHub Managed — the upgrade clobbered a project-state file (policies/module-size-baseline.txt), breaking check-module-size --all post-upgrade; tag fetch failed on Windows schannel. (W1–W5, commit 2504584.)

This release is a reactive, bounded hardening of the three refresh scripts (mirror-skills.sh, sync-version-strings.sh, upgrade.sh) plus the GEMINI adapter, .gitattributes, and the health check. The content model, the byte-exact copy contract, and the marker-anchored overlay refresh are unchanged. Codex adversarial design review (verdict RESCOPE) flagged the biggest risk — a sync allowlist that under-reaches would recreate the GEMINI drift in reverse — so the allowlist ships with an executable under-reach guard test.

The version bump for this very release was run through the new tooling as a live self-test: the new in-script sync allowlist swept every framework adapter to v3.25.0, and the U5 regex fix finally un-stuck GEMINI.md (it had been stranded at an older header for several releases).

What ships

ID Piece What it does
U1 Batched mirror/sync spawns (Windows perf) mirror-skills.sh and sync-version-strings.sh spawned a process per file; on Windows Git-Bash each spawn is ≈0.8–1.4s, so a 6,974-.md sync scan stalled into minutes. Now a single sha256sum/shasum call (ARG_MAX-chunked via xargs) primes an associative-array cache; the loop is fork-free (fixed-offset hash slicing, direct cache reads). Copy scope is unchanged — still only SKILL.md + references/* per the mirror contract (a bounded copy, NOT a blind cp -R), so the manifest stays byte-identical. Windows ~5 min → seconds.
U2 Portable EOF-newline-preserving sync sync-version-strings.sh used printf '%s' "$after" > "$f", which strips the trailing newline → 11 consumer docs churned. Replaced with the consumer's committed approach: capture each file's trailing-newline state and restore it exactly (NOT a bare sed -i, which differs GNU vs BSD). A grep -lE superset pre-filter (chunked) skips files with no token. Fixtures prove both trailing-newline and no-trailing-newline files round-trip on Git-Bash (macOS noted).
U3 module-size-baseline.txt + policy-state merge-preserve on upgrade upgrade.sh copied policies/ wholesale, overwriting project state and breaking check-module-size --all. New merge rule (LOCKED): ownership = upstream-baseline membership (not path prefixes). Upstream Flow rows get the upstream line-count; project rows absent from the upstream baseline are preserved verbatim; a Flow row dropped upstream is removed locally; malformed local rows warn (never silently drop). Also guards approval-policy.yml:workflow_mode and protected-paths.yml worker_undisturbed — project values must live in *.local.yml (deep-merged by policy_loader.py), backed by a policy-state-preserve test.
U4 Executable framework-owned sync allowlist + under-reach guard Replaced the broad find+prune with an in-script SYNC_ROOTS/SYNC_FILES allowlist (adapters, FLOW_RULES.md, agents/**/AGENT.md, flow-skills/**, workflows/, templates/, overlays, framework docs; plugin metadata via a parity check, not sed). The under-reach guard is a test that scans those roots for syncable tokens and FAILS if any token-bearing framework file is not in the allowlist (the anti-GEMINI). Consumer roots (docs/product-backlog, problem-catalog, product-execution, client-workflows/**) are NEVER synced.
U5 GEMINI version regex The sync regex required a literal Fusebase Flow v + 3-part semver; GEMINI ships Fusebase Flow **Local** v2.1, so it stayed stuck for releases. Regex now matches Fusebase Flow (Local )?v[0-9]+(\.[0-9]+){1,2}. GEMINI.md now syncs with every release (confirmed live: v3.25.0).
U7 Upgrade trap recovery + health-check PARTIAL_UPGRADE upgrade.sh now traps interruption/failure and prints the exact recovery command(s) to finish by hand. The health check compares derived facts (VERSION, plugin manifest, root + cursor/copilot adapters, canonical agents/workflows/templates/overlays version/FR/skill-count) against the live strings and reports PARTIAL_UPGRADE + the repair command on mismatch. Builds on the v3.24.0 health-check engine.
U9 Progress output mirroring N/31…, scanning N files…, upgrade-phase progress — the silent multi-minute window that made operators think it hung is gone.
U11 .gitattributes LF pins VERSION text eol=lf, *.sh text eol=lf (plus the no-extension hook scripts and config/doc formats). A Windows clone could rewrite VERSION CRLF on checkout, churning it in every diff.
U8 Windows docs (docs only) README / install docs: Git-Bash invocation, detect-unusable-WSL-bash message, and the git -c http.sslBackend=openssl fallback for tag/clone failures on schannel-impaired Windows hosts.

Deferred follow-up

  • U6 — full GEMINI/copilot/cursor overlay-refresh parity (marker-anchored blocks + a refresh path). It needs a marker-strategy design of its own, so per the RESCOPE verdict it ships as a separate ticket: docs/backlog/adapter-overlay-refresh-parity/. U5 (version sync) ships now; U6 (full overlay refresh) is the follow-up.

Why this is reactive, not speculative

Two unrelated teams hit the same refresh-script failures on the same upgrade. The fix is bounded to how the upgrade/refresh scripts handle files — not what content ships. Credit and thanks to paperclip+hermes-v1 and WorkHub Managed for the grounded, reproducible reports.

Verified

preflight 0/0 · run-tests 79/79 PASS (incl. new AC2 newline / AC3 baseline-merge / AC4 under-reach-guard + consumer-not-synced / AC7 policy-state fixtures) · check-module-size --all exit 0 · mirror-skills 31 skills / 0 drift · agent mirrors byte-identical / 0 drift · recovery-sim 31/31 exit 0 (the strongest guard — exercises both refresh scripts; captured state/audit/recovery-sim-2026-06-15.log) · plugin == VERSION == 3.25.0 · GEMINI.md synced to v3.25.0 (U5) · .gitattributes present (U11) · health PARTIAL_UPGRADE no false-positive on the synced repo · FR-07/FR-25 clean (version-string sweep only; no FR rule rows, deploy-policy semantics, or ratchet-governance.yml touched). FR-range FR-01..FR-26, 31 skills unchanged.

Rollback

git revert <SHA range> — the changes are to tooling scripts + tests + docs; additive/behavior-preserving where it counts (manifest byte-identical, content model untouched). Re-push; re-mirror. Tag v3.25.0.

v3.24.0 — health-check fast/timeout hardening

15 Jun 07:00

Choose a tag to compare

Fusebase Flow v3.24.0 — health check fast/bounded execution + PARTIAL_UNVERIFIED (exit 4)

Release date: 2026-06-15
Previous version: 3.23.1

Summary

hooks/local/fusebase-flow-health-check.sh — the read-only diagnostic operators trust for recovery — could exceed two minutes and appear to hang during installs on a network-impaired (Windows/schannel-impaired) or large-repo host. The unbounded, verdict-affecting operations were the upstream git fetch and the preflight / run-tests / check-cli-flow-conflicts sub-invocations.

The naive fix (bound/skip and move on) creates a false HEALTHY — the design review's blocker — because an empty LOCAL_BROKEN already meant HEALTHY/0, and a run-tests crash read OK via || true. So this release intentionally changes verdict semantics: a critical check that didn't run is now distinct from "ran clean."

What ships

Piece What it does
PARTIAL_UNVERIFIED verdict + exit code 4 New LOCAL_UNVERIFIED tracking array. Exit 0 only when every CRITICAL check (preflight, hook tests, conflict reporter) actually ran and passed. A timed-out/skipped critical ⇒ PARTIAL_UNVERIFIED/exit 4 — never HEALTHY/0. Precedence: BROKEN > real drift > EXCEPTION > PARTIAL_UNVERIFIED > HEALTHY.
Optional upstream comparison The git fetch timing out is a "upstream not verified (fetch timed out)" note only — never UNVERIFIED, never exit 4. GIT_TERMINAL_PROMPT=0 + low-speed config make it fail fast, not block on a prompt.
run_with_timeout helper (hooks/local/lib/run-with-timeout.sh) Extracted per FR-25 (keeps the engine under the 800-line ceiling). Detects timeoutgtimeout; -k grace; rc 124 = timeout; preserves the wrapped command's own rc otherwise. No timeout binary ⇒ bounded ops skipped ⇒ PARTIAL_UNVERIFIED (opt into unbounded with FFHC_ALLOW_UNBOUNDED=1). A missing lib is a loud BROKEN, never a silent degrade.
H6 run-tests rc fix A harness crash (rc≠0, no parsable FAIL:) previously read OK via `
Flags --no-upstream = full local verdict (exit 0 OK). --fast = skips the slow hook tests (keeps preflight + inventory + conflict reporter) for a quick verdict, but is explicitly partial: exit 4, never 0, and prints "fast mode — not a full health verdict."
SLO-budgeted timeouts (env-overridable) FFHC_FETCH_TIMEOUT (15s), FFHC_PREFLIGHT_TIMEOUT (30s), FFHC_CONFLICT_TIMEOUT (30s), FFHC_TESTS_TIMEOUT (60s); worst-case bounded full run ≈ 155s. The conflict reporter's wildcard matcher now scopes its scan to the static path prefix instead of walking the whole tree — behavior-preserving (--json output byte-identical), measured ~1.8s.

The false-HEALTHY blocker (why this matters)

This diagnostic is what operators run to decide whether to repair after a fusebase update. If a critical check silently doesn't run and the engine still says HEALTHY, an operator skips a needed recovery. Exit 4 makes "I couldn't verify" a first-class, distinct outcome from both "all good" (0) and "drift/breakage" (1/2).

Exit-code contract (callers, AC8)

Exit Verdict Caller treats as
0 HEALTHY full health (every critical ran clean)
1 *_DRIFT drift
2 BROKEN breakage
3 EXCEPTION_IN_EFFECT drift covered by an operator artifact
4 PARTIAL_UNVERIFIED partial/unverified — re-run; NOT healthy, NOT a hard failure

Swept for callers: no script/hook branches on the engine's exit code (the recovery test harness keys off the Verdict: line, with || true). The skill, README, and docs/health-check-deferrals.md exit-code tables now carry exit 4.

Verified

preflight 0/0 · recovery suite incl. 7 new health-check timeout fixtures (AC1 fetch-timeout-not-hang→exit0; AC2 critical-timeout→exit4; AC4a preflight-fail→BROKEN; AC4b harness-crash→BROKEN; AC4c --fast→exit4; AC6 no-timeout-binary→partial; AC6 unbounded-opt-in→HEALTHY) · existing U/F engine drift tests unchanged · AC3 full reachable run → HEALTHY/0 · mirrors 0 drift · module-size: engine + new lib both under the 800-line ceiling.

Rollback

git revert <SHA> — additive (a new verdict/exit code + flags + a sourced helper lib + tests + docs); no schema/data, no deploy-authority change, fully reversible. Tag v3.24.0.

v3.23.1 — find-wasted-effort containment hardening

14 Jun 21:09

Choose a tag to compare

FuseBase Flow v3.23.1 — /find-wasted-effort containment hardening

Release date: 2026-06-14
Previous version: 3.23.0
Deploy hash: 08940a4

Summary

Patch hardening of the /find-wasted-effort audit's on-disk write path (additive; the analyzer stays read-only to the project). The audit's report/proposals write is now an atomic temp-file + os.replace() into the contained state/audit/ directory, and it rejects hardlinked/symlinked targets up front (fail-closed) — defeating a pre-planted-alias write-through that could otherwise have modified a file outside state/audit/. The at-rest threat model is now documented in the write path: containment defends pre-planted symlink/hardlink/traversal targets at rest; active concurrent filesystem races mid-run are explicitly out of scope for a local, single-operator, read-only audit tool. No behavior change to verdicts or proposals; the read-only-to-the-project invariant is unchanged.

What ships

Piece What it does
Atomic contained write write_audit_file() writes to a fresh temp file inside the resolved state/audit/ dir, then os.replace()s it onto the target. The replace rebinds the directory entry to a NEW inode, so any pre-planted hardlink/alias at the target is severed and the outside file it aliased is never modified. Same-filesystem temp keeps the rename atomic and contained.
Hardlink/symlink fail-closed Before writing, the target is rejected outright if it is a symlink (is_symlink()) or a hardlink alias (lstat().st_nlink > 1) — the audit refuses to write through a planted alias, raising RootError. Loud, not silent.
Honest fail-closed fixture The g2 selftest now asserts the TRUE contract: a pre-planted-at-rest hardlink at the target ⇒ RootError (fail-closed) AND the outside aliased file is byte-unchanged. It drops the prior dishonest "report still lands despite planted hardlink" claim (which masked the fail-closed reality by removing the alias first). The severed-alias / new-inode happy path stays proven by the g3 normal-write fixture (st_nlink == 1, no temp turd left behind).
Documented at-rest threat model A concise FR-22 threat-model note at write_audit_file() (with a pointer from contained_audit_path()): containment defends pre-planted symlink/hardlink/traversal targets AT REST; active concurrent FS races mid-run (e.g. renaming state/audit/ between temp-create and replace) are OUT OF SCOPE for a local single-operator read-only audit tool.

Still read-only to the project (unchanged invariant)

The analyzer writes nothing outside the gitignored state/audit/ directory and applies nothing. This patch only hardens how that single contained write happens; verdicts, proposals, and the Phase-2A descope (write-apply Phase 2B and the Middle Lane Phase 3 remain deferred to the paperclip+hermes-v1 consumer repo) are unchanged.

Live proof

python hooks/local/find-wasted-effort.py on this repo: 34 artifacts scanned, 6 rounds, window 20. The run wrote ONLY the contained state/audit/find-wasted-effort-<date>.md report + the gitignored proposals JSON; git status showed no edits outside state/audit/. --selftest: 155 passed, 2 skipped (skips = host lacks symlink/hardlink privilege; the now-honest g2 fail-closed assertions run on a capable host).

Verified

preflight 0/0 · --selftest 155 passed, 2 skipped · run-tests 24/24 · mirrors 0 drift · health HEALTHY · plugin valid · counts unchanged (FR-01..FR-26, 31 skills — patch hardens find-wasted-effort, no new skill/rule).

Rollback

git revert 08940a4 (and 2ee0a2c / 1e36b8b if the containment fix itself must come out too) — additive and read-only-safe; a clean revert (no schema/data, no deploy-authority change, no protected-path edit). Tag v3.23.1.

v3.23.0 — find-wasted-effort proposal output

14 Jun 18:57

Choose a tag to compare

Fusebase Flow v3.23.0 — /find-wasted-effort proposal output (ceremony-efficiency Phase 2A)

Release date: 2026-06-14
Previous version: 3.22.0
Deploy hash: __DEPLOY_HASH__

Summary

Phase 2A of the ceremony-efficiency-middle-lane ticket — additive, read-only-safe. /find-wasted-effort now emits schema'd proposals (a Proposed memory entries report section + an optional gitignored state/audit/ JSON), so a human can see the exact change each finding would justify. The analyzer stays read-only to the project — it writes nothing outside the gitignored state/audit/ directory; it applies nothing.

Per the Codex Phase-2 design review (2026-06-14), the read-only→write flip was descoped from the framework: the actual memory write-apply (Phase 2B) and the Middle Lane (Phase 3) are routed to the paperclip+hermes-v1 consumer repo as hard-gated prototypes, upstreamed only once proven (the Lightweight-lane pattern). The framework side stays proposal-output-only until then.

What ships

Piece What it does
Proposal output (read-only-safe) A Proposed memory entries section in the contained state/audit/<date>.md report + an optional sibling gitignored state/audit/find-wasted-effort-proposals-<date>.json (--no-proposals-json skips the JSON; the report section is always written). A confirmed finding → a recommendation proposal; a rule-6 review-candidate → a prune_review_candidate; inconclusive/dismissed findings emit none.
Defined proposal schema Each proposal carries proposal_id, rule, verdict, raw_evidence_refs, target_kind, target_path, exact_patch, operator_confirmation_required: true, source: "audit". The audit proposes the change a human could apply — it never applies it.
Self-output quarantine (Codex finding 5) Proposals cite raw on-disk artifacts as evidence, never a prior audit report/proposal; the evidence collectors do not read state/audit/, so the audit cannot cite itself (no self-reinforcement loop).
prune_review_candidate only A rule-6 element is a review candidate for a PO-owned subtraction under the policies/ratchet-governance.yml prune protocol — never an auto-prune or a recorded prune decision.
Containment hardening (Codex Phase-2A LOW) contained_audit_path now resolves the target before the relative check and rejects an absolute / .. / path-separator basename at the boundary (raises RootError). Both real callers pass fixed flat basenames — a no-op for them; it closes internal-misuse traversal in the containment helper.

Still read-only to the project (the load-bearing invariant)

Phase 2A enriches the output only. The analyzer writes nothing outside the gitignored state/audit/ directory — a hard test asserts a full run modifies no memory / overlay / spec / provider / policy file. Findings remain review candidates; the PO owns subtraction. This is NOT the read-only→write flip (that is Phase 2B, deferred to the consumer repo behind AC2b's hard gates).

Live proof (this repo as the first consumer)

python hooks/local/find-wasted-effort.py on this repo: 33 artifacts scanned, 6 rounds, window 20. Report carries the new "Proposed memory entries" section; the gitignored proposals JSON is written under state/audit/. The run made no edits outside state/audit/ (git status clean). --selftest 151 passed, 2 skipped (skips = host-symlink fixtures; +6 over v3.22.0 = the new basename-hardening containment fixtures).

Verified

preflight 0/0 · --selftest 151 passed, 2 skipped · run-tests 24/24 · mirrors 0 drift · health HEALTHY · plugin valid · counts unchanged (31 skills — Phase 2A extends find-wasted-effort, no new skill).

Deferred (consumer-repo prototypes → upstream when proven)

  • Phase 2B — memory write-apply — behind AC2b: operator-authored approval artifact · per-target containment · self-output quarantine · ≥1 real confirmed + 1 dismissed counterexample · security-permissions-review. Prototyped in paperclip+hermes-v1.
  • Phase 3 — Middle Lane / middle_deploy — prototyped as a FLOW:PRESERVE overlay in paperclip+hermes-v1, proven on real rounds, then upstreamed (Full lane, AC7).
  • Overlay-edit apply — dropped to a later ticket (Phase 2A emits a diff only).

Rollback

git revert <SHA> — Phase 2A is additive and read-only-safe (a clean revert; no schema/data, no deploy-authority change, no protected-path edit). Tag v3.23.0.

v3.22.0 — find-wasted-effort + ratchet governance

14 Jun 00:42

Choose a tag to compare

Fusebase Flow v3.22.0 — ratchet governance (A3) + /find-wasted-effort read-only audit (A2)

Release date: 2026-06-13
Previous version: 3.21.1

Summary

Phase 1 of the ceremony-efficiency-middle-lane ticket — the low-risk, reversible, no-deploy-risk wins that earn the evidence for the risky lane later. It solves two of the three reported problems:

  • PR-2 (ceremony ratchets) — incidents ADD steps; success never removes them; no role owns pruning → A3 ratchet governance: every safety-bearing ceremony element carries prevents: <incident-class>; the PO owns subtraction.
  • PR-3 (can't diagnose outcome-neutral ceremony) — no instrument separated safety-bearing from waste → A2 /find-wasted-effort: the process-per-outcome sibling of /token-waste-audit.

PR-1 (the Middle Lane) is Phase 3 and is not in this release (it changes deploy authority and ships via the Full lane on its own gate). Phase 2 (audit write phase) is also separate.

What ships

Piece What it does
A3 — policies/ratchet-governance.yml The prevents: <incident-class> annotation convention + the catastrophic-low-frequency severity tag (rare-but-severe controls are HARDER to prune — a clean window is expected, not evidence of waste). A 9-class incident taxonomy (false-green-deploy, unattended-prod-cutover, unauthorized-deploy, irreversible-loss, silent-protected-path-drift, …) is the WHY-home; a D5-scoped coverage map (deploy/gate controls + the elements rule 6 reads) states its own scope so the audit reports coverage rather than implying full-framework annotation. PO-owned, never-automatic prune protocol.
A3 scoped annotations prevents: markers (tripwire + pointer, FR-22) on the deploy/gate control set: templates/{handoff-deploy,handoff-implement,gate-report,verification-gate}.md + workflows/{greenlight-deploy,eight-phase-flow}.md.
A2 — find-wasted-effort skill (31st) Process-per-outcome ceremony audit. Distinct AXIS from /token-waste-audit (tokens-per-rule, transcripts); distinct INPUTS (Flow artifacts on disk); shared DISCIPLINE (FP header, read-only-first, state/audit/ output — reused from token-economy, not reinvented). 6 active rules — rule 4 CUT (token-waste-audit's v3.21.0 cross-session aggregate covers context-rebuild), rule 7 scoped to the cross-session ceremony layer only (no overlap with FR-26's execution-layer polling). Each rule emits confirmed / dismissed / inconclusive with the contrary evidence it searched for.
hooks/local/find-wasted-effort.py + find_wasted_effort/ package Deterministic, stdlib-only, READ-ONLY analyzer (thin CLI orchestrator + a 6-module package split along the per-rule + test-layer seam; every module under the FR-25 800-line ceiling). Writes only its own gitignored state/audit/find-wasted-effort-<date>.md; NO memory/overlay/spec edits, NO prune/reclassify (D4 — those are Phase 2/3, gated on per-rule FP fixtures). Mirrors token-waste-audit.py's substrate. --selftest = synthetic + evidence-sourcing/scoping + end-to-end + path-containment + prevents:-parser fixtures (116 passed, 2 skipped — skips = host-symlink fixtures).
/find-wasted-effort (6th command) Command file + recovery snapshot (preflight §8 + 5d enforced); skill mirrored to .claude/skills/ + .agents/skills/.

Read-only is load-bearing (D4)

Phase 1 ships the audit read-only: it describes review candidates; it never removes ceremony, edits memory/overlays, or reclassifies a lane. A confirmed finding is a candidate for a PO review under the ratchet-governance.yml prune protocol — never an auto-prune. A catastrophic-low-frequency control on a clean window is reported inconclusive, never confirmed.

Live proof (this repo as the first consumer)

python hooks/local/find-wasted-effort.py on this repo: 30 artifacts scanned, well-formed report with the FP header, per-rule confirmed/dismissed/inconclusive, and a coverage section listing all 17 governed controls. Rule 6 detected prevents: markers in all 6 annotated files. --selftest 116 passed, 2 skipped (skips = host-symlink fixtures). No tracked changes beyond the analyzer (report is gitignored).

Verified

preflight 0/0 · --selftest 116 passed, 2 skipped · mirrors 0 drift · counts swept 30 → 31 skills / 8 → 9 policies / 5 → 6 commands.

Rollback

git revert <SHA> — Phase 1 is additive (a new skill + analyzer + policy + annotations + a command); no schema/data, no deploy-authority change, fully reversible. Tag v3.22.0.

v3.21.1 — delegation residuals (recovery surfacing, deploy push, report pointers, ground-truth returns)

12 Jun 18:37

Choose a tag to compare

Fusebase Flow v3.21.1 — delegation residuals

Release date: 2026-06-12
Previous version: 3.21.0

Summary

Downstream (paperclip+hermes-v1) verified v3.20.1 + v3.21.0 — all 10 prior asks confirmed delivered — and reported 4 second-order residuals from continued live use. All four verified real against this repo and fixed: one silent-failure surfacing, three rules that existed but didn't reach the surface that needed them.

Fixes

# Fix
1 Recovery call surfaced (upgrade.sh step 4). The overlay/command recovery ran fully silenced — a mid-run crash half-applied (downstream: 2 of 5 command files stale) with the root cause masked. Now: success prints the recovery's actions-taken summary ([upgrade] recovery: …); non-zero exit prints a loud HALF-APPLIED warning + last output lines + the literal re-run command. Note: the recovery exits 1 on warnings as well as crashes — the WARN says "review", it does not fail the upgrade.
2 Deploy sessions inherit the delegation contract. The v3.21.0 push-not-pull fix reached implement handoffs but not templates/handoff-deploy.md — the prompt a delegated Deploy session actually reads. It now carries the turn-completion + progress-ledger + BLOCKED-AT-<gate> invariant bullet, and workflows/greenlight-deploy.md joins its mandatory-reads list.
3 Self-recording clause for reports (gate-report + deploy-report headers + validation-and-qa): if the system under test has durable evidence surfaces (journals, run records, logs, snapshots), report fields carry POINTERS to them — transcribe only what no system records. Extends the v3.21.0 pointers rule from returns to reports (FR-23).
4 Ground-truth rule in the return shape (task-delegation + push block + implement-handoff quote): any claim that system state changed names the verification performed — the system surface read and what it showed. An attempted action or an observed look-alike artifact is not evidence (downstream: a false "launched" claim survived ~19 hours).

Verified

Sim (real v3.19.1 consumer, git-inited, v3.21.1 engine): success path shows the surfaced recovery summary + post-upgrade preflight 0/0; stubbed-crash source shows the HALF-APPLIED warning block with re-run command. Upstream gates: preflight 0/0 · run-tests 24/24 · mirrors 78/0 drift · overlays byte-match · history guard intact. Independent post-implementation review before tag.

Rollback

git revert <SHA> — one script block + template/skill text; no rule, gate, or hook-handler change. Tag v3.21.1.

v3.21.0 — delegation resilience + return contracts

12 Jun 04:56

Choose a tag to compare

Fusebase Flow v3.21.0 — delegation resilience + return contracts

Release date: 2026-06-12
Previous version: 3.20.1

Summary

Closes the six evidence-backed residuals from live delegated-run experience (downstream proposal, paperclip+hermes-v1): sessions that die mid-work lose end-loaded reports; unbounded waits had no honest exit; returns re-pasted artifact bodies; reused templates propagated superseded procedures; one file served two confusing masters (restart artifact vs run ledger); cross-session recurring costs were invisible to the per-session audit. Built under the double-review protocol — the plan review caught two genuine design blockers before implementation.

What ships

Piece What it does
Progress-ledger contract task-delegation §3 + greenlight-deploy step 7: durable facts written AS THEY OCCUR (deploy hash at deploy moment, probe rows as earned, skeleton first) — never end-loaded. Successor contract: resume from records, never redo verified steps.
Blocked-return semantics At an UNBOUNDED wait (human gate, no-ETA event): return BLOCKED-AT-<gate> + what-cleared-looks-like + state pointer. Never fake-complete; never burn an open watch.
Delegated return shape Verdict (DONE|BLOCKED-AT-<gate>|FAILED-<reason>) · per-task SHAs · count deltas · artifact POINTERS · residual risk. Never re-paste what an artifact already holds. Delegated returns only — gate reports keep PASS/FAIL.
Delegation contract push block The plan-review blocker fix: workers never load skills, so the whole contract rides the delegating prompt — a named, quotable ≤4-line block; templates/handoff-implement.md's push line upgraded to it.
Restart vs run-ledger split docs/tmp/handoff.md header gains Mode: restart | run-ledger. Restart stays operator-triggered; run-ledger is the sole sanctioned autonomous write (announced in chat). Run-ledger updates supersede IN PLACE — archive fires on restart supersede / mode transition only (plan review killed the archive-flood + same-minute filename collision). Legacy files without Mode: = restart.
Procedure freshness One line in handoff Procedure + handoff-implement + handoff-deploy headers: check whether a shipped capability supersedes a reused procedural block before executing it.
Cross-session aggregate (/token-waste-audit) New report section when ≥2 sessions parsed: files/commands recurring across sessions, top-N capped. Framing header maps recurring rules/handoff reads + session-initiation Bash floor to FR-23 session-floor discipline (by-design), NOT FR-26 violations, and states the Read-tool-only visibility limit.

Review provenance

Plan review: REVISE-FIRST, 13 findings, all folded into the locked spec — including two blockers: (1) the contract text would bind nobody (workers don't load orchestrator skills) → push block; (2) archive-on-every-ledger-update floods docs/tmp/handoff/archive/ and <YYYY-MM-DD-HHMM> filenames clobber within a minute → in-place supersede. Implementation review ran before ship; findings fixed pre-tag.

Verified

preflight 0/0 · run-tests 24/24 · module-size --all green · mirrors 78 files / 0 drift (count unchanged — no new skill) · AGENTS/CLAUDE inline overlays byte-match · live self-run: aggregate section produced from 3 real transcripts; degraded paths (empty dir, nonexistent dir) exit 0; parser 397 lines (stdlib-only).

Rollback

git revert <SHA> — skill/template/workflow text + one parser section; no rule, gate, or hook change. Tag v3.21.0.

v3.20.1 — upgrade installer parity + self-overwrite-safe engine

12 Jun 04:07

Choose a tag to compare

Fusebase Flow v3.20.1 — upgrade installer parity + self-overwrite-safe engine

Release date: 2026-06-12
Previous version: 3.20.0

Summary

Defect-fix release driven by two downstream reports (paperclip+hermes-v1): in-place upgrades crossing a command-adding release landed BROKEN by their own preflight (/handoff at 3.14.x, recurred with /token-waste-audit at 3.20.0). The E2E verification then exposed a second, worse latent defect: pre-3.20.1 engines can abort mid-upgrade by overwriting their own running script. Both are fixed, with a write-time gate so the first class cannot recur.

What was wrong

Defect Root cause
New slash commands never install on upgrade The installer chain existed all along (upgrade.sh step 4 → post-fusebase-update.sh Step 8, a data-driven loop) — but its source, the recovery snapshot hooks/local/fusebase-flow-overlays/commands/, held 3 of 5 commands and nothing enforced completeness (preflight checked snapshot→live only; live commands absent from the snapshot were invisible).
Upgrade aborts mid-run with syntax error (found by this release's E2E sim) upgrade.sh refreshes hooks/ — overwriting its own running file; bash streams scripts incrementally, so execution resumes at a stale byte offset inside the replaced content. Offset-dependent (nondeterministic luck on past hops; deterministic on 3.19.1→3.20.1), stranding the consumer half-upgraded: content new, VERSION old, mirrors stale, commands missing.

Fixes

  • Snapshot backfilled to 5/5 commands, byte-identical to .claude/commands/ (preflight 5d cmp enforces).
  • Write-time gate: preflight §8 refactored data-driven over one FLOW_COMMANDS array — per command, three ERROR checks: live file · recovery-snapshot copy · CLAUDE.md reference. A command surface may only ship with its installer step (the downstream report's sharpened ask, made deterministic). PUBLISHING.md carries the matching release rule.
  • main()-wrapped engine: the whole upgrade.sh body is parsed before step 1 executes — v3.20.1+ engines are immune to self-overwrite.
  • Upgrading FROM ≤3.20.0 (old engines are unfixable retroactively — README documents both recoveries): bash hooks/local/bootstrap-upgrade.sh -- --auto-yes (stages the new engine first; the self-overwrite becomes byte-identical → harmless; works on any 3.8.0+ install) — or simply re-run upgrade.sh after an abort (the refreshed engine completes idempotently).
  • Actionable, not silent: upgrade.sh step 4b WARNs when CLAUDE.md still lacks a /command reference after the overlay refresh; the plan output names the command-restore step; stale enumerating comments de-hardcoded.

Verified (against the real v3.19.1 engine, not a synthetic consumer)

Consumer = git archive v3.19.1 extract, git-inited; source = this release's final tree. All rows observed, not inferred.

Path Result
Old upgrade.sh direct Run 1 aborts mid-run (the latent defect, reproduced: syntax error, exit 2) → run 2 completes: preflight 0 errors / 0 warnings, /token-waste-audit installed, CLAUDE.md ref present, plugin.json 3.20.1 == VERSION
Old bootstrap-upgrade.sh -- --auto-yes One-shot: preflight 0/0, command installed, plugin parity, zero manual wiring
New wrapped engine, source bytes differ mid-run Single run completes — zero syntax errors (immunity observed)
Negative (gate) Deleting a snapshot command file ⇒ preflight ERROR naming the installer-step rule

Plus: preflight 0/0 · run-tests 24/24 · upstream gates green.

Review provenance

Shipped after an independent FIX-FIRST review: every mechanical claim verified (gate refactor strictly supersets the old checks; wrapper semantics; byte-identical snapshot; dated-history guard). The review also forced the evidence re-run above (first sim predated the plugin.json fix), caught a pre-existing backup-corruption bug — the attestation sweep rewrote version strings inside *.pre-upgrade-*/*.pre-bootstrap-* rollback backups (fixed here; backups stay pristine) — and tightened command-ref matching to word boundaries.

Rollback

git revert <SHA> — script + docs + snapshot additions; no rule, skill, or hook-handler change. Tag v3.20.1.