fix(cli): followups drift correctness — working-tree scan (#229) + appended follow-ups (#231)#235
Merged
Merged
Conversation
… 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]>
This was referenced Jun 11, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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 documenteddrift --applyflow runs — the new AILOG is uncommitted (usually untracked), so it was invisible:drift --applyreported "in sync" while real§Follow-upscontent 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-allsemantics unchanged.#231 — appended follow-ups silently dropped
fully_extracted_ailogswas 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-upsgrows 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'sSource-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 fromOrigin+description.fully_extracted_ailogsis retained as informational metadata (shown byfollowups status), no longer the skip gate.Tests
parse_porcelain_ailogsacross??/M/A/rename + quoted paths, filtered to the agent-logs dir ([adopter] cli-3.19.1: default 'followups drift' scan misses uncommitted/untracked AILOGs — breaks the documented pre-commit flow (v0 script handled this) #229).fu_content_hashstability/discrimination,split_origin,render_new_entryembeds matching hash,registry_extracted_hashes(stored-hash + legacy fallback + the appended-follow-up miss case) (followups drift: late-added follow-ups to an already-extracted AILOG are silently skipped (fully_extracted_ailogs is whole-AILOG granular) #231).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-managedSource-hashfield, and the revised role offully_extracted_ailogs. Version bumps across manifest, governance footers, and doc tables.Closes #229
Closes #231
🤖 Generated with Claude Code