Skip to content

fix(cli): followups drift correctness — working-tree scan (#229) + appended follow-ups (#231)#235

Merged
montfort merged 1 commit into
mainfrom
fix/followups-drift-correctness-229-231
Jun 11, 2026
Merged

fix(cli): followups drift correctness — working-tree scan (#229) + appended follow-ups (#231)#235
montfort merged 1 commit into
mainfrom
fix/followups-drift-correctness-229-231

Conversation

@montfort

Copy link
Copy Markdown
Contributor

Summary

Fixes two silent-data-loss bugs in straymark followups drift, both reported by the reference adopter (Sentinel). Both are prerequisites for wiring drift into the Charter-close flow — RFC #135 Tier 3 (the agreed "stabilize drift first" step).

Combined fw-4.25.0 / cli-3.21.0.

Bugs fixed

#229 — default scan was blind to the working tree

The default scan considered only the committed git range (git diff origin/main..HEAD). At pre-commit time — exactly when the documented drift --apply flow runs — the new AILOG is uncommitted (usually untracked), so it was invisible: drift --apply reported "in sync" while real §Follow-ups content went unextracted, recreating the silent-miss class the tool exists to prevent.

Fix: the default scan now unions the git range with the working tree (git status --porcelain, handling ??/M/A/rename), mirroring the v0 reference script. --scan-all semantics unchanged.

#231 — appended follow-ups silently dropped

fully_extracted_ailogs was a whole-AILOG idempotency gate: once an AILOG id landed in it, the file was never re-scanned. Follow-ups appended to that AILOG later — the multi-batch Charter pattern, where one AILOG's §Follow-ups grows across batches — were silently lost, with no drift signal and no non-zero exit.

Fix (approach chosen with the maintainer — stable content hash + legacy fallback): drift now dedups per follow-up by a stable content hash (fu_content_hash = SHA-256 of AILOG id + origin section + description, 12 hex), stored as each entry's Source-hash. Already-extracted AILOGs are re-scanned and individual follow-ups deduped, so appended content is caught.

The stored hash is captured at extraction time and never recomputed from the (later paraphrased) registry heading — so it preserves the zero-false-positive property that motivated the original per-AILOG choice (curated entries paraphrase the source bullet). Legacy entries (pre-cli-3.21.0, no Source-hash) fall back to recomputing the hash from Origin + description. fully_extracted_ailogs is retained as informational metadata (shown by followups status), no longer the skip gate.

Tests

Docs

FOLLOW-UPS-BACKLOG-PATTERN.md (EN/ES/zh-CN): documents the working-tree union, the per-follow-up content-hash dedup (replacing the "Per-AILOG vs per-bullet granularity" section that documented the #231 bug as an intentional trade-off), the auto-managed Source-hash field, and the revised role of fully_extracted_ailogs. Version bumps across manifest, governance footers, and doc tables.

Closes #229
Closes #231

🤖 Generated with Claude Code

… catch appended follow-ups (#231)

Two silent-data-loss bugs in `straymark followups drift`, both surfaced by
the reference adopter (Sentinel) and both prerequisites for wiring drift into
the Charter-close flow (RFC #135 Tier 3).

- #229: the default scan considered only the committed git range, so an
  uncommitted/untracked AILOG (the normal pre-commit state) was invisible and
  `drift --apply` reported "in sync" while real follow-up content went
  unextracted. The scan now unions the git range with the working tree
  (`git status --porcelain`), mirroring the v0 reference script.
- #231: `fully_extracted_ailogs` was a whole-AILOG idempotency gate — once an
  AILOG id was in it the file was never re-scanned, so follow-ups appended
  later (the multi-batch Charter pattern) were silently dropped. Drift now
  dedups per follow-up by a stable content hash (`Source-hash`, stored on each
  entry): already-extracted AILOGs are re-scanned and individual follow-ups
  deduped. The stored hash is captured at extraction time, immune to later
  triage rewording — preserving the zero-false-positive property; legacy
  entries fall back to recomputing the hash from Origin + description.

Updates FOLLOW-UPS-BACKLOG-PATTERN.md (EN/ES/zh-CN) to match; the old
"Per-AILOG vs per-bullet granularity" section documented the #231 bug as an
intentional trade-off. Bump fw-4.24.0 → 4.25.0 / cli-3.20.0 → 3.21.0.

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant