TDD 0049: Touched-files extractor — single source of truth + annotation-robust#140
Merged
cahenesy merged 1 commit intoJun 11, 2026
Merged
Conversation
…+ annotation-robust Gap-closure follow-up to TDD 0048 (PR #139), covering the two parser gaps that surfaced while landing it. Does NOT supersede 0048 — extends it (repo pattern). Gap 1: the 0048 em-dash-split mis-parses an annotation between the path and the em-dash (`- `src/a.txt` (post) — …` → `src/a.txt (post)`) → false structural-finding(a). Refined algorithm: prefer the first backtick token WITHIN the left-of-em-dash segment, else the first whitespace token — handles bare, backticked, AND annotated forms while preserving 0048's 0044 fix. Gap 2: the third reader `_touched_files_of_tdd` (learnings.sh) still used the old first-backtick logic with a false-parity comment. Unify all three readers onto a single shared `scripts/lib/touched-files.sh` extractor (the chosen prevent-divergence-by-construction option); the three named functions become thin delegating wrappers; the agreement cross-check extends to all three. Covers FR-53/FR-54/FR-67 (no new PRD requirement; PRD unchanged at 0aa1e28). ADR constraints 0005, 0006. 5 files, ~210 lines. Design gate (carried for the human reviewer): Mechanical pre-pass: tl_lint rc=0; --bounds rc=0; body 302/500 lines. Independent design critique (design-reviewer, sonnet): DESIGN_REVIEW: PASS. 1 MAJOR (misleading prose on the sourcing idiom — folded in: clarified that `return 1 2>/dev/null || exit 1` is one idiom correct in both sourced and executed contexts), + minor/nit clarity items (guard must not be unset; paths-only intent of the learnings wrapper; alternatives grammar) — all addressed inline. Verdict was PASS; the major was documentation-clarity, not a mechanism flaw. Open assumptions & waivers: - fallback semantics for bare+annotation — resolved: prefer first backtick token within the left-of-em-dash segment, else first whitespace token; the 0044 bare-path/backticked-description case still extracts the path (backtick is right of the em-dash). - 3-way agreement test signature mismatch — resolved: the agreement test stages a docs/tdd/<slug>.md under a temp repo so the `<repo> <slug>`-signature learnings wrapper runs on the same fixture as the file-path siblings. - shared-lib sourcing robustness — resolved: sibling path via ${BASH_SOURCE[0]%/*}/touched-files.sh + include guard + FATAL-on-missing matching implement.sh; pinned in Verification §5 across all four sourcing contexts. - supersede-vs-extend correctness — waived: New TDD referencing 0048 per established repo pattern; 0048 body untouched. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
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.
Design PR (gate = your merge). One new TDD,
Status: draft. The merge is what makes it buildable via/implement. No code yet — this is the design-of-record.What & why
Gap-closure follow-up to TDD 0048 (PR #139), addressing the two parser gaps that surfaced while landing it. Does not supersede 0048 — extends it (the repo's gap-closure pattern: 0041 extended 0019, 0033 extended 0031). PRD is unchanged (
0aa1e28); this hardens the existing FR-53 / FR-54 / FR-67 mechanism, no new requirement.- `src/a.txt` (post) — …→src/a.txt (post)) → a falsestructural-finding(a). Refined rule: prefer the first backtick token within the left-of-em-dash segment; else the first whitespace token. Handles bare, backticked, and annotated forms — and still extracts the path for the original 0044 case (bare path, backticked description right of the em-dash)._touched_files_of_tdd(learnings.sh) still used the pre-0048 first-backtick logic with a false-parity comment. All three readers move onto a single sharedscripts/lib/touched-files.shextractor (chosen: prevent divergence by construction); the three named functions become thin delegating wrappers; the agreement cross-check extends to all three.Scope
5 files (~210 lines): new
scripts/lib/touched-files.sh;gates.sh,tdd-lint.sh,learnings.shwired to it;tests/bounded-tdd-scope.test.sh(3-way agreement + form cases + the annotated-path membership regression). All inside bounds.Design gate (informed review)
tl_lintrc=0,--boundsrc=0, body 302/500 lines.DESIGN_REVIEW: PASS. One MAJOR (the prose explaining the sourcing idiom was misleading enough to risk a subtly wrong build) — folded in: clarified thatreturn 1 2>/dev/null || exit 1is one idiom correct in both sourced and executed contexts. Minor/nit items (the include-guard var must not be unset; the learnings wrapper is paths-only by intent; alternatives-analysis grammar) — all addressed inline. The reviewer independently re-verified the extraction algorithm against every row of the Approach table, including the critical 0044 safety case.Open assumptions & waivers
docs/tdd/<slug>.mdunder a temp repo so the<repo> <slug>-signature learnings wrapper runs on the same fixture as the file-path siblings.${BASH_SOURCE[0]%/*}/touched-files.sh+ include guard + FATAL-on-missing matching implement.sh; pinned in Verification §5 across all four sourcing contexts.🤖 Generated with Claude Code