fitme·story
v7.8.1 · 7 min read
Summary card · 60-second read

Framework v7.8.1 — Branch Isolation + Feature-Closure Completeness from One Full PM Cycle

Version
v7.8.1
Date
2026-05-07
Tier
light

Two cooperating pre-commit gates shipped as one feature in advisory mode on 2026-05-07. BRANCH_ISOLATION_VIOLATION prevents agents from mutating feature state from the wrong branch/worktree (Mode B fires on every commit when staged files match infra-path globs; Mode C fires on current_phase mutations from a non-feature branch). FEATURE_CLOSURE_COMPLETENESS fires on current_phase=complete transitions and validates 7 required case-study frontmatter fields + Q7 (kill_criteria_resolution) + Q6 (bidirectional PR-list parity). 14 commits across 9 phase transitions in one session — the first feature shipped via the v7.8 protocol (Mechanism C session attribution + isolated worktree from Phase 1 onward + Tier 2.2 logging on every phase transition + Mechanism A coverage telemetry verification on its own gates). 28/28 implementation tasks done; 130/130 unit tests pass; 19/19 pipeline assertions pass. v7.9 promotion candidate decision: 2026-05-21 (T+14d).

How to read this case studyT1/T2/T3 · ledger · kill criterion
T1Instrumented
Numbers come from a machine-generated ledger or commit. Reproducible. Highest reader trust.
T2Declared
Numbers stated by a structured declaration (PRD, plan, frontmatter) but not directly measured.
T3Narrative
Estimates and observations from session memory. Useful for context; not citable as evidence.
Ledger
Where to verify the claim — a file path, GitHub issue, or backlog entry. Anything labelled ledger: is the audit trail.
Kill criterion
The pre-registered threshold under which this work would have been killed mid-flight. Not fired = work shipped without hitting the threshold.
Deferred
Items intentionally not closed in this version. Each cites the ledger that tracks remaining work.

Visual aid · key numbers at a glance

Default · no specialised visual declared
PRs mergedT1
FT2 #244 + #245 + #246; fitme-story #53
Phase transitions in one sessionT1
9
Implementation tasks doneT1
28 / 28
Unit tests passT1
130 / 130
Pipeline assertionsT1
19 / 19
Files changedT1
25
High-risk iOS files touchedT1
0
New gates shippedT1
3 write-time + 3 cycle-time advisory
v7.9 promotion decision dateT1
2026-05-21

Two trigger incidents witnessed within seven days defined the feature's scope.

Incident 1 — HADF Phase 2 (2026-04-30) — a long-running launchd-driven fingerprint-collection job was anchored to the canonical repo path instead of an isolated feature/ worktree. The wrapper's relative writes resolved against launchd's WorkingDirectory; canonical .jsonl data landed in the wrong tree; the campaign required mid-flight isolation + restart + remerge. Beyond the launchd specifics, the incident revealed four distinct isolation failure modes the existing worktree pattern doesn't address: read-shared/write-isolated, awareness-without-blocking, conflict-detection-at-write-time, recoverable-state.

Incident 2 — 2026-05-07 reconcile session (the day this feature shipped) — a make documentation-debt readout pass surfaced 5 silently-missing case-study frontmatter fields across 4 already-shipped features (UCC + import-training-plan + framework-story-site + push-notifications-v2). Manual reconcile took ~30 minutes — cost would be 0 if a write-time gate had blocked the closure commits. The 5 fields: date_written, dispatch_pattern, success_metrics, kill_criteria, plus a case_study_showcase typo on framework-story-site.

Bundled because both gates: (a) extend the same pre-commit infrastructure (scripts/check-state-schema.py + scripts/check-case-study-preflight.py); (b) share v7.8 Mechanism A coverage telemetry; (c) emerged from the same root cause class — silent gaps in cross-references the existing gate stack doesn't see.

What v7.8.1 actually adds

Three new write-time gates in scripts/check-state-schema.py:

  • BRANCH_ISOLATION_VIOLATION (advisory in v7.8.1 → enforced in v7.9). Two-mode predicate. Mode B fires on every commit when ANY staged file matches the 8-glob list (.githooks/*, .github/workflows/*, scripts/*, .claude/skills/*, .claude/shared/*, CLAUDE.md, docs/architecture/*, Makefile) OR the modified state.json's work_subtype: framework_feature or work_type: chore. Per-feature isolation_opt_out: true is ignored for Mode B (Q3 infra override — the framework cannot opt itself out of its own enforcement). Mode C fires only when staged state.json mutates current_phase AND current branch != state.json::branch. Honors per-feature isolation_opt_out: true.
  • FEATURE_CLOSURE_COMPLETENESS (advisory in v7.8.1 → enforced in v7.9). Fires on current_phase=complete transitions. Validates four sub-checks: (1) 7 required case-study frontmatter fields with synonym resolution; (2) Q7 kill_criteria_resolution required when kill_criteria is non-empty; (3) Q6 bidirectional PR-list parity between state.json (tasks[].pr_number, phases.merge.pr_number, tasks[].related_prs) and case study (regex matches in body + related_prs frontmatter); (4) cycle-time mirror in integrity-check.py catches --no-verify bypasses.
  • ISOLATION_OPT_OUT_REASON_MISSING (enforced from ship). When isolation_opt_out: true, isolation_opt_out_reason must be a non-empty string.

Three new cycle-time advisories in scripts/integrity-check.py: BRANCH_ISOLATION_HISTORICAL (forward-only audit of features whose entire git history happened on main); BRANCH_ISOLATION_LAUNCHD_DRIFT (macOS-only plist scan); FEATURE_CLOSURE_COMPLETENESS cycle-time mirror.

Companion deliverables: scripts/create-isolated-worktree.py (idempotent local CLI auto-isolation; ADOPTS existing-but-unlinked worktrees), make verify-isolation + make feature-completeness-audit (system-wide readouts), /ux + /design pre-merge-review extended with sub-step 6f (kill_criteria_resolution check), .claude/shared/branch-isolation-exempt.json (exempt-pattern allowlist), .claude/shared/path-reducers.json extended (+gate-coverage.jsonl + _session-*.events.jsonl entries).

v7.8 advisory protocol — the discipline of unfired gates

Both main gates ship in advisory mode: they emit Mechanism A coverage telemetry to .claude/logs/gate-coverage.jsonl on every script run but do NOT block any commits. The pre-commit hook prints [ADVISORY] warnings to stderr; the exit code stays 0 unless OTHER (existing) gates fail.

This is the explicit lesson from v7.7's CACHE_HITS_EMPTY_POST_V6 silent-pass: the gate shipped at 0/46 effective coverage because 43/46 features used the legacy created key while the gate read created_at. The gate "ran" 53 times per script invocation but checked=0 every time — a textbook silent pass.

v7.8's design principle, applied for the first time on its own ship: measure the gate's effective coverage before promoting to enforced. The promotion path:

PhaseTriggerBehavior
v7.8.1 advisory (this ship)2026-05-07Gates emit telemetry; print warnings; do NOT block
v7.8.1 grace (T+7d, 2026-05-14)Telemetry reviewVerify checked > 0 continuously for 7 days + FP rate < 5% from any manual_bypass events
v7.9 enforced (T+14d earliest, 2026-05-21)Decision pointSingle config-flag flip in .claude/shared/framework-manifest.json::capabilities.v7_8_1_branch_isolation.gates.{name}.mode from advisoryenforced. Gates start blocking.

If kill criteria fire at T+7d, revert: git revert {merge_commit} -m 1 + open hot-fix PR + restore previous .githooks/pre-commit content + open root-cause case study within 48h. v7.5 pipeline test verified the rollback works.

First feature to ship via the v7.8 protocol

Three meta-observations from running the v7.8 protocol on a v7.8-protocol feature:

  1. Mechanism C session attribution worked end-to-end. The .claude/active-feature lockfile written at /pm-workflow invocation captured every Read tool call into .claude/logs/_session-<id>.events.jsonl with the correct active_feature tag throughout the session. No drift across worktree creation, branch switches, or phase transitions.

  2. The PHASE_TRANSITION_NO_LOG gate fired correctly on every phase mutation. Tier 2.2 events were appended to <feature>.log.json BEFORE state.json mutations on all 9 phase transitions. Order matters: log-first, state-second, commit-third. A near-miss when the feature's log was being written to the wrong worktree (main's filesystem instead of the feature worktree's filesystem) was caught immediately because the worktree's log had the older state and pre-commit's freshness check would have flagged it. Recovered by appending events directly to the worktree's log file via Python (bypassing the script's static REPO_ROOT).

  3. The make documentation-debt readout informed Block C's predicate design. The 5 doc-debt items found in the 2026-05-07 reconcile session became the EXACT list of fields enforced by FEATURE_CLOSURE_COMPLETENESS Q12. The readout-time detection logic in documentation-debt-report.py was promoted to the write-time gate predicate — single source of truth, zero duplicate field-list maintenance.

Out-of-scope deliverables (queued for v8 prioritization at Phase 9)

7 items were explicitly de-scoped during Phase 0 research: Sapling-smartlog UI, jj op-log replay, Vercel Sandbox, Landlock/App Sandbox, path-watcher daemon, cross-feature dependency graph, auto-rollback on kill criteria. Each got a backlog entry + companion spec at docs/superpowers/specs/2026-05-07-branch-isolation-out-of-scope.md with re-evaluation triggers. Phase 9 prioritization pass on 2026-05-21 (T+14d) will produce the ranked v8 roadmap based on 7-day telemetry signals.

What's next: T+7d telemetry review (2026-05-14)

Pull gate-coverage.jsonl entries for the 3 new gates. Verify:

  • BRANCH_ISOLATION_VIOLATION Mode B fires on infra-path commits (≥ 1 fire expected per ~5 commits)
  • FEATURE_CLOSURE_COMPLETENESS fires when any feature transitions to complete (count = number of complete-transitions in the 7-day window)
  • ISOLATION_OPT_OUT_REASON_MISSING evaluates on every state.json file (53 candidates per --all run)
  • False-positive rate < 5% across all three (count manual_bypass events vs total fires)

If clean → schedule v7.9 promotion (single config-flag flip). If kill criteria fire → revert + redesign.

v1 vs v2 isn't the right framing here

This is a framework feature, not a product feature. There's no v1. The relevant comparison is v7.8 (bridge mechanisms A–F shipped on 2026-05-04) versus v7.8.1 (gates extending those mechanisms shipped on 2026-05-07):

Dimensionv7.8 (bridge)v7.8.1 (this ship)
Calendar days end-to-end~3 days1 (~6-8h elapsed)
Phase transitions9 across 9 PRs9 in one session
Cooperating mechanisms6 (A–F)5 new gates extending existing mechanisms
Schema additionsagent_manifest, _meta.deprecation_warnings, path-reducers.json, agent-leases.jsonisolation_opt_out, isolation_opt_out_reason, worktree_path, 2 case-study frontmatter fields
Tests(across 9 PRs)14 new + pipeline +4 = 18 new
First feature using its own protocol(n/a — bridge laid the foundations)Yes — v7.8.1 ate its own dogfood

Honest disclosures

  • No production data on the new gates yet. All telemetry zero by definition pre-T+7d. T1-instrumented and ready. First measurement window 2026-05-14.
  • Auto-isolation flow is advisory-only in v7.8.1. The gate prints a remediation message pointing at scripts/create-isolated-worktree.py but does not subprocess-dispatch in advisory mode. v7.9 enforcement will add the actual subprocess call once the predicate is calibrated.
  • macOS-only BRANCH_ISOLATION_LAUNCHD_DRIFT advisory. The plist scan only runs on Darwin. Linux/CI hosts skip cleanly. No equivalent for systemd / cron scheduled jobs in v7.8.1; deferred.
  • The v7.7 silent-pass class is closed in advisory but not enforced. Until v7.9 promotes both new gates, a --no-verify bypass on a closure commit can still ship a feature with missing case-study fields. The cycle-time mirror (T19) will catch it within 72h, but the write-time block is the canonical fix.
  • 5 of 6 v7.8 mechanisms ship in advisory mode through this case study window. v7.9 promotion (2026-05-11 onward for v7.8 Mechanism C; 2026-05-21 onward for v7.8.1 gates) is the next milestone for the full v7.8 → v7.9 transition.

Source case study + spec chain