Skip to content

backlog: 3 follow-up rows from PR #1253 (B-0171 OpenSpec + B-0172 plugin + B-0173 hooks)#1261

Merged
AceHack merged 2 commits intomainfrom
backlog/follow-up-rows-from-pr-1253-openspec-plugin-hooks-aaron-2026-05-03
May 3, 2026
Merged

backlog: 3 follow-up rows from PR #1253 (B-0171 OpenSpec + B-0172 plugin + B-0173 hooks)#1261
AceHack merged 2 commits intomainfrom
backlog/follow-up-rows-from-pr-1253-openspec-plugin-hooks-aaron-2026-05-03

Conversation

@AceHack
Copy link
Copy Markdown
Member

@AceHack AceHack commented May 3, 2026

Summary

Files the 3 follow-up backlog rows that PR #1253's skill-design memo named but didn't actually file. Per the at-creation-time discipline (memory/feedback_depends_on_backlog_search_*).

Rows

  • B-0171 P1 OpenSpec catch-up — load-bearing prerequisite per Aaron 2026-05-03 "if we deleted everything other than it [OpenSpec]". 4-phase incremental scope. depends_on: [].
  • B-0172 P2 skill-domain plugin packaging — Aaron's rule 3a. P2 because promotion-trigger hasn't fired for any domain yet. depends_on: [B-0171, B-0173].
  • B-0173 P1 hook authoring for skill-creation contracts — Aaron's rule 3b. Pre-commit + commit-msg + CI integration. Turns substrate-claim-checker from advisory to enforcement. depends_on: [B-0170, B-0171].

depends_on graph

B-0170 (substrate-claim-checker, in-flight #1260) ──┐
                                                     ├──> B-0173 (hooks)
B-0171 (OpenSpec catch-up, this PR) ────────────────┤        │
                                                     │        ▼
                                                     └──> B-0172 (plugin packaging)

B-0171 is independent (can ship in parallel with B-0170). B-0173 depends on both. B-0172 depends on B-0171 + B-0173.

Why now

The skill-design memo (PR #1253, merged) named these 3 rows in its body but didn't file them. The at-creation-time discipline says: when filing a new row, search backlog for prerequisites. The reverse-search (memo names rows that don't exist yet) is the same discipline at the row-creation point — file the named-but-not-existing rows.

Test plan

  • All 3 rows have proper frontmatter (id, priority, status, title, tier, effort, ask, created, last_updated, depends_on, composes_with, tags)
  • depends_on populated per the graph above
  • composes_with populated with cross-references
  • B-0172 in P2/ directory matching its priority; B-0171 + B-0173 in P1/
  • BACKLOG.md regenerated; 3 new rows visible in index
  • CI green

🤖 Generated with Claude Code

…gin packaging + hook authoring)

Per the at-creation-time discipline (memory/feedback_depends_on_backlog_search_*), filing the 3 follow-up rows that PR #1253 named in its skill-design memo but didn't actually file.

- **B-0171 P1 OpenSpec catch-up** — restore OpenSpec as
  canonical source-of-truth per Aaron 2026-05-03 *"if we
  deleted everything other than it"*. 4-phase scope: inventory
  + sequencing → top-10 spec authoring → cross-reference
  tooling → validation. Long-arc; incremental. depends_on:[].

- **B-0172 P2 skill-domain plugin packaging** — package
  mature skill domains as Claude Code plugins per Aaron's
  rule 3a. P2 because promotion-trigger has not yet fired
  for any domain (named-but-future: git-native-backlog +
  multi-harness-alignment). depends_on:[B-0171, B-0173].

- **B-0173 P1 hook authoring for skill-creation contracts** —
  pre-commit + commit-msg + PR-description CI hooks turning
  substrate-claim-checker from advisory to enforcement. Per
  Aaron's rule 3b. Strict-vs-warn mode design + opt-out
  semantics specified. depends_on:[B-0170, B-0171].

The depends_on graph this composes:
- B-0170 (substrate-claim-checker tool) → blocks B-0173 (hooks need tool)
- B-0171 (OpenSpec) → blocks B-0172 + B-0173 (specs are contract carriers)
- B-0173 (hooks) → blocks B-0172 (plugins ship hooks)

Result: B-0173 + B-0172 are sequenced AFTER B-0170 + B-0171.
B-0171 is independent; can ship in parallel with B-0170.

BACKLOG.md regenerated.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings May 3, 2026 01:24
@chatgpt-codex-connector
Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@AceHack AceHack enabled auto-merge (squash) May 3, 2026 01:24
…rst no-finding tick this session

PR #1260 wait-ci with no actionable threads (first tick this
session). Pivoted to filing 3 follow-up rows from PR #1253's
skill-design memo: B-0171 OpenSpec + B-0172 plugin + B-0173
hooks. depends_on graph: B-0170 + B-0171 → B-0173 → B-0172.
At-creation-time discipline applied in reverse (search-then-file).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@AceHack AceHack merged commit e714837 into main May 3, 2026
22 checks passed
@AceHack AceHack deleted the backlog/follow-up-rows-from-pr-1253-openspec-plugin-hooks-aaron-2026-05-03 branch May 3, 2026 01:26
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds three new per-row backlog entries (B-0171/0172/0173) that were referenced in PR #1253 but not yet filed, and updates the generated backlog index so the new rows are visible.

Changes:

  • Added P1 backlog rows for OpenSpec catch-up (B-0171) and hook authoring for contract enforcement (B-0173).
  • Added P2 backlog row for skill-domain plugin packaging (B-0172).
  • Regenerated docs/BACKLOG.md to include the new rows.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 4 comments.

File Description
docs/backlog/P1/B-0171-openspec-catch-up-canonical-source-of-truth-aaron-2026-05-03.md New P1 backlog row defining phased OpenSpec catch-up scope and acceptance criteria.
docs/backlog/P2/B-0172-skill-domain-plugin-packaging-aaron-2026-05-03.md New P2 backlog row describing packaging mature skill domains as plugins and outlining a target structure.
docs/backlog/P1/B-0173-hook-authoring-for-skill-creation-contracts-aaron-2026-05-03.md New P1 backlog row describing hook integrations (pre-commit/commit-msg/CI) to enforce contract checks.
docs/BACKLOG.md Updated generated index to list B-0171, B-0172, B-0173.

@AceHack
Copy link
Copy Markdown
Member Author

AceHack commented May 3, 2026

All 4 post-merge findings addressed:

Pattern: existence-drift sub-class — claimed locations without verifying canonical surfaces. Each would have been caught by the v1+ existence-check sub-class of substrate-claim-checker (B-0170).

AceHack added a commit that referenced this pull request May 3, 2026
… (B-0173) per repo conventions (#1262)

3 substantive Copilot post-merge findings on PR #1261 (the 3
follow-up rows). Empirically verified each against repo state
+ existing docs:

1. **B-0172 plugin location wrong**:
   was: `.claude/plugins/<name>/`
   actual: `~/.claude/plugins/cache/<plugin-name>/` (per
   `docs/research/codex-builtins-skills-vs-plugins-factory-
   integration-2026-04-24.md`)

2. **B-0172 manifest path wrong**:
   was: top-level `plugin.json`
   actual: `.claude-plugin/plugin.json` (Claude Code) /
   `.codex-plugin/plugin.json` (Codex), per the same
   research doc

3. **B-0173 hook path wrong**:
   was: `tools/git-hooks/`
   actual: `tools/git/hooks/` (verified via `ls tools/git/`
   showing existing batch-resolve + push-with-retry scripts)

These are verify-then-claim drift instances of the
existence-drift sub-class: I claimed locations/conventions
without checking the canonical surfaces (existing research
docs + tools/ directory layout). Each fix would have been
caught by the v1+ existence-check sub-class of
substrate-claim-checker.

The 4th Copilot finding (depends_on:[B-0170] but B-0170 not
on main yet) resolves automatically when PR #1260 lands —
B-0170 ships in that PR. False-positive on timing.

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
AceHack added a commit that referenced this pull request May 3, 2026
…triaged; #1260 rebased; existence-drift caught 3×

Existence-drift sub-class caught 3 times on #1261's follow-up
rows (plugin location + manifest path + hook directory). Each
fix verified empirically against repo state + existing research
docs. The substrate-claim-checker v1+ existence-check would
have caught all 3 pre-publish — empirical urgency for v1
mechanization continues.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
AceHack added a commit that referenced this pull request May 3, 2026
…1260)

* tools(substrate-claim-checker): v0 ship — count-drift detection + B-0170 backlog row

Builds the v0 of `tools/substrate-claim-checker/` per the
verify-then-claim discipline mechanization path. After 19+ drift
instances across 9+ PRs in a single session despite naming the
discipline, manual discipline provably insufficient — mechanization
is the only path.

V0 scope: ONE sub-class — count drift.

- `tools/substrate-claim-checker/check-counts.ts` (~150 lines, single-purpose)
  - Scans narrative for "N <noun>" patterns where <noun> is one of
    drift instances / rows / items / procedure skills / experts /
    tools / sub-classes
  - Counts data rows in the nearest markdown table within 50 lines
  - Reports drift if claimed N differs from actual
  - Exit 0 on no drift; exit 1 on drift detected

- `tools/substrate-claim-checker/README.md`
  - Usage + v0 scope + known limitations + composes-with

Self-test: runs cleanly on the verify-then-claim memo (which
catalogues 15 drift instances + has 15 table rows = consistent).
Synthetic test caught "5 drift instances" claim vs 3-row table.
Cross-scan of memory/feedback_*.md surfaced 7 findings: ~3 real
(multi-harness experts/skills counts) + ~4 false positives
(rhetorical "100 rows" in narrative, nearest-table heuristic
limitations).

V0 limitations documented in README:
- Nearest-table heuristic (no noun-to-table matching yet)
- Rhetorical number false positives
- Markdown-table data rows only (lists not counted)

V1 path covers remaining 6 sub-classes (existence / semantic-
equivalence / empirical-output / convention / path-form /
self-recursive); plus pre-commit + commit-msg + CI hook integration.

Per Aaron's no-dynamic-commands rule (skill-design memo): TS file
under tools/, single-purpose, type-checked, re-runnable. Per
hub-satellite separation: tool is hub-shaped; per-invocation
outputs are satellite-shaped.

B-0170 backlog row filed with done-criteria, depends_on:[],
composes_with [B-0169 decision-archaeology], canonical mapping
of v0 (1 sub-class shipped) to v1+ (6 remaining).

This PR breaks the drift-fix-meta-cycle from the past several ticks
by shipping the actual mechanization the cycle was pointing toward.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* hygiene(tick-history): 2026-05-03T00:55Z — drift-fix meta-cycle broken; substrate-claim-checker v0 shipped

After 19+ drift instances + 6+ ticks of drift-fix-on-fix producing
new drift faster than fixes land, the path forward is shipping the
mechanization the cycle was pointing at. V0 of substrate-claim-checker
ships with count-drift sub-class coverage; eval-set + sub-class
taxonomy made authoring mechanical.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* review(pr-1260): substrate-claim-checker v0.1 — address 6 Copilot findings + 2 lint fails

Iterating v0 → v0.1 on the same branch per the verify-then-claim
discipline applied to itself: tool needs to be substrate-quality
substrate before it gates substrate quality.

Lint fixes:
- **tsc strict-null** (4 errors at lines 57, 59, 64, 102) —
  added `?? ""` fallbacks for `lines[i]` and `m[N]` access under
  `noUncheckedIndexedAccess`; explicit `if (numStr === undefined
  || noun === undefined) continue` guard
- **markdownlint MD032** in B-0170 — added blank line before
  v0-limitations list (lists need blanks-around per MD032)

Copilot findings (6):

1. **P1 fail-fast on missing file** — `checkFile()` previously
   returned [] silently, allowing exit 0 even when inputs were
   missing. Refactored: returns `{findings, ok}`; `main()` tracks
   inputErrors separately and exits 1 if any input was missing.

2. **P2 preserve `+` semantics** — `"20+ drift instances"` was
   treated identically to `"20"`. Added `claimIsMinimum` field
   to Claim; drift fires only when `actual < claimed` for
   minimum-claims (vs strict-equal for non-plus claims). Output
   format shows `>=` vs `==` operator.

3. **(duplicate of #1)** Same issue, same fix.

4. **Hyphenated forms not caught** — `"13-row table"` didn't
   match `\d+\s+noun`. Updated regex to `\d+\+?[\s-]+noun` so
   both `"13 rows"` and `"13-row"` match.

5. **Skip fenced code + tables** — `findClaims()` previously
   scanned every line including code blocks + table data rows.
   Added inFence toggle on ` ``` ` / `~~~` lines; skip lines
   starting with `|` (table rows).

6. **Drop unused Table.endLine** — interface simplified to
   `{startLine, rowCount}` only.

Self-verified v0.1:
- Missing file → exit 1 with error ✓
- Verify-then-claim memo (15 rows + "15 instances" claim) → no drift ✓
- tsc --noEmit passes against full repo tsconfig ✓

The 4 Copilot tsc fixes + 6 review findings are themselves
worked examples of the verify-then-claim discipline: each fix
is a count/semantic claim that needed empirical verification
before publishing.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* hygiene(tick-history): 2026-05-03T01:02Z — substrate-claim-checker v0→v0.1 iteration; 6 findings + 2 lint addressed

V0 of the discipline-mechanizer hit 6 Copilot findings + 2
lint failures; v0.1 addresses all in same PR. Recursive
composition of verify-then-claim discipline through tool
review IS the worked example.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* review(pr-1260): v0.2 — findTables skips fenced code blocks

P2 finding on PR #1260: `findTables()` previously matched any
`|...|` + separator sequence as a real table without checking
fenced-code-block context. If a memo's narrative contained a
fenced markdown example like:

    ```markdown
    | # | example |
    |---|---|
    | 1 | a |
    ```

...the tool would treat it as a real table. When followed by an
actual table, the nearest-table heuristic would pick the FENCED
example over the real one — false drift report.

Fix: added `inFence` toggle to `findTables()` matching the same
fence-tracking discipline `findClaims()` already uses. Tables
inside fenced code blocks are now ignored.

Verified via synthetic test: a memo with a 3-row fenced example
table + a 5-row real table + claim "5 drift instances" now
correctly reports no drift (v0.1 would have flagged because it
picked the 3-row fenced table first).

This finding is itself a worked example of the verify-then-claim
discipline: I claimed `findClaims` and `findTables` had the same
fence-tracking discipline (in v0.1's docstring), but only
`findClaims` actually had it. Empirical verification before
publishing claim would have caught this.

tsc --noEmit passes against full repo tsconfig.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* hygiene(tick-history): 2026-05-03T01:08Z — v0.2 fence-asymmetry fix; substrate-claim-checker becomes its own primary user

Asymmetric fence-tracking between findClaims (skip fences) and
findTables (didn't) IS the bug class. Verify-then-claim applied
recursively: claim about parallel-discipline-between-functions
needed empirical verification, not docstring assertion. v0 → v0.2
caught 10 substrate-quality findings on the discipline-mechanizer
itself — the tool's recursive self-application IS the empirical
evidence that mechanization is correct.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* review(pr-1260): v0.3 — separator regex + import.meta.main + B-0170 sub-class accuracy + indented-table v1 doc

4 Copilot findings on PR #1260 addressed:

1. **Separator regex too lax** — `^\|[\s\-:|]+\|\s*$` accepted
   `|   |` and `||||` as valid table separators. GFM requires
   at least one `-` per separator cell. Tightened regex to
   require at least one `-`: `^\|[\s\-:|]*-[\s\-:|]*\|\s*$`.

2. **process.exit(main()) unconditional** — script couldn't be
   imported for testing. Refactored: exported `main` + `findTables`
   + `findClaims` + `checkFile` + types; wrapped invocation in
   `if (import.meta.main) { process.exit(main()); }` per Bun
   convention. Other tools/ scripts use this pattern.

3. **B-0170 sub-class table mis-claim** — row "Frontmatter ↔
   body ↔ index count drift" said "v0 covers" but v0 only checks
   narrative-vs-nearby-table within a single document, not
   cross-surface narrative-to-narrative comparison. Reclassified
   as v1 work; explicitly named the 5 surfaces (frontmatter
   description / body table / section heading / carved sentence /
   MEMORY.md index entry) per the 0106Z shard's 5-surface finding.

4. **Indented tables not matched** — `findTables` regex `^\|`
   requires column-1 anchor. Tables inside nested lists or
   blockquotes aren't recognized. Documented as v1 limitation
   in README; v1 fix is `^\s*\|`. Not fixed in v0 to avoid
   broadening false-positive surface before adding scope-aware
   matching.

tsc clean + self-test (verify-then-claim memo) reports no drift.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* hygiene(tick-history): 2026-05-03T01:11Z — v0.3 iteration; #1259 merged with 5 post-merge threads triaged

V0 → V0.3 substrate-claim-checker iteration through 4 Copilot
review passes; 14 substrate-quality findings catalogued; recursive
discipline-mechanization application is itself the primary teacher.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* review(pr-1260): v0.4 — CommonMark fence delimiter tracking + directory rejection

2 Copilot findings on v0.3:

1. **P2 fence delimiter length** — `inFence` toggle on any
   ` ``` ` or `~~~` line is wrong per CommonMark: a fence
   closes only when the closing delimiter is the SAME char
   AND at-least-equal length. So a 3-backtick fence containing
   a longer block of backticks shouldn't close on the inner
   line. Refactored both `findTables` and `findClaims` to
   track `fenceChar` + `fenceLen`; close only on matching
   char + length>=open.

2. **P2 directory input** — `existsSync` returns true for
   directories, then `readFileSync` throws with cryptic error.
   Added `statSync(filePath).isFile()` check; reject directories
   with explicit "not a regular file" error.

Self-tested:
- `bun tools/substrate-claim-checker/check-counts.ts tools/`
  → "error: not a regular file (directory or other): tools/"
  → exit 1 with explicit message
- Verify-then-claim memo → no count drift detected (regression
  test for fence-tracking + table-counting)
- tsc --noEmit clean

Both fixes are CommonMark-spec compliance + filesystem-input
robustness — the kind of edge case the eventual deployed-tool
will hit on real corpus.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* hygiene(tick-history): 2026-05-03T01:14Z — v0.4 CommonMark + directory; 5 review passes; v0.x mature for count-drift

V0 → V0.4 substrate-claim-checker iteration: 5 Copilot review
passes catching 16 substrate-quality findings. Edge-case
absorption (CommonMark fence delimiter, directory rejection)
is the substrate-quality-maturity path — recursive review IS
the eval-set.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* review(pr-1260): v0.4.1 — file header version label refresh + readFileSync error wrap

5 Copilot findings on v0.4 — 3 already-resolved or false-positive,
2 substantive:

1. **(stale)** Tick shard 0108Z says "v0.1 → v0.2" while file
   header (then) said v0.1. Tick shards are append-only history;
   they accurately recorded the version-label-at-write-time. The
   header had been v0.1 BEFORE that tick; the shard correctly
   notes the v0.1 → v0.2 transition. No retroactive edit.

2. **(false positive)** docs/BACKLOG.md flagged as
   "auto-generated, don't edit". Verified: BACKLOG.md WAS
   regenerated via `bash tools/backlog/generate-index.sh` when
   B-0170 was added; the diff is the auto-generated entry. No
   action needed.

3. **(already-resolved in v0.3)** `process.exit(...)` without
   `if (import.meta.main)` guard. Verified: line 278-280 has
   the guard already. False positive on stale review state.

4. **(real, fixed)** `readFileSync` could throw on permission
   errors / transient IO. Wrapped in try/catch; emit explicit
   error message; return ok:false. Together with the prior
   directory check, all read-failure modes now produce clean
   error output rather than crash trace.

5. **(real, fixed)** File header docstring still said v0.1
   while the iteration is now v0.4. Updated header to v0.4 +
   added an iteration-history block listing each version's
   changes (v0 / v0.1 / v0.2 / v0.3 / v0.4).

The version-label-drift in the file header was itself drift
instance-class — version-string-vs-iteration-state inconsistency.
Future tooling for substrate-claim-checker should add a check:
"file's docstring version label matches latest iteration commit
in git log."

tsc clean + self-test on verify-then-claim memo passes.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* hygiene(tick-history): 2026-05-03T01:17Z — v0.4.1 + 5 findings triaged (3 stale/FP, 2 real)

Triage-as-substrate: empirically verify each finding's currency
BEFORE deciding to fix. 3 of 5 #1260 findings were stale or
false-positive after verification (tick-shard append-only history;
BACKLOG.md auto-gen verified; import.meta.main guard already in
v0.3). 2 real fixes: file header v0.1 → v0.4 with iteration
history; readFileSync error wrap.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* review(pr-1260): v0.4.2 — collapse existsSync+statSync+readFileSync into single try/catch (eliminates TOCTOU race per CodeQL)

CodeQL flagged TOCTOU (time-of-check-to-time-of-use) race
condition: the existsSync() → statSync() → readFileSync()
sequence had two windows where the file could change between
check and use.

Fix: collapse into single readFileSync try/catch + categorize
the resulting NodeJS.ErrnoException by err.code:
- ENOENT → "error: file not found: <path>"
- EISDIR → "error: not a regular file (directory): <path>"
- other → "error: read failed for <path>: <msg>"

This produces equivalent user-facing error messages from a
single syscall — eliminates TOCTOU race while preserving the
explicit error categorization the prior v0.4 added.

Verified empirically (verify-then-claim discipline applied):
- missing file → "file not found" + exit 1 ✓
- directory → "not a regular file (directory)" + exit 1 ✓
- valid file → no count drift detected ✓
- tsc --noEmit clean ✓

This is the FIRST CodeQL-class finding caught on the tool —
distinct from the Copilot review pattern (CodeQL is static
analysis for security; Copilot is general code review). Both
should integrate as inputs to the eventual deployed
substrate-claim-checker for PR description / commit-msg /
file-content checking.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* hygiene(tick-history): 2026-05-03T01:19Z — v0.4.2 TOCTOU fix; CodeQL is a new review-input class

First CodeQL finding on substrate-claim-checker — TOCTOU race
between existsSync+statSync+readFileSync. Collapsed to single
readFileSync try/catch with err.code categorization. CodeQL is
distinct from Copilot review pattern; eventual deployed
substrate-claim-checker should integrate both as parallel
review-inputs with shared triage discipline.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* review(pr-1260): v0.4.3 — bun:test unit tests + README/B-0170 count drift fixes

6 Copilot findings on v0.4.2:

1. **(real, fixed)** README "differs" missed `+` minimum-count
   semantics. Updated: "Reports drift if claimed N differs from
   actual. **Special case for `N+` minimum-count claims:** drift
   fires only when `actual < N`."

2. **(real, fixed)** README cited "19+" drift instances + "#19"
   as count-drift, but main memo enumerated 15. Switched to
   no-specific-count: "drift instances catalogued in the
   verify-then-claim memo's body table — see that file for
   current count." Avoids two-surface count drift between README
   + memo.

3. **(real, fixed)** B-0170 cited "19+" — same drift class.
   Replaced with "(the verify-then-claim memo's body table is
   canonical)". Two occurrences updated.

4. **(false-positive on stale review state)** v0.1 file header.
   Verified: file header is at v0.4.2 (since commit 464c086 +
   484cc48). Resolved as stale.

5. **(real, fixed)** No bun:test unit tests. Added 16 unit
   tests covering findTables (5 tests) + findClaims (5 tests)
   + checkFile (6 tests) including: separator-`-`-required,
   fenced-code-block skipping, CommonMark fence-delimiter
   length matching, hyphenated forms, minimum-count semantics
   (allows actual >= claimed; fires on actual < claimed),
   missing-file + directory rejection, drift detection +
   no-drift cases.

6. **(false-positive on stale review state)** Closing fence
   rules. Verified: v0.4 + v0.4.2 implement CommonMark same-char
   + at-least-equal-length closing. Resolved as stale.

Test results: 16/16 pass; tsc --noEmit clean.

The unit-test suite is the missing eval-set per Aarav's BP-14
review on B-0169 (worked-examples-are-the-dry-run-eval-set).
Each test fixture is a known-good or known-drift case the tool
should classify correctly. Future v1+ work extends the suite
as new sub-classes ship.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* hygiene(tick-history): 2026-05-03T01:28Z — v0.4.3 unit-test suite + count-drift fixes; "point at canonical" pattern

V0 → V0.4.3 substrate-claim-checker iteration: 8 review passes
catching 18+ findings. v0.4.3 adds 16-test bun:test suite
(findTables/findClaims/checkFile coverage) per Aarav's BP-14
worked-examples-are-the-eval-set finding. README + B-0170 count
claims switched from specific count to "memo's body table is
canonical" — hub-satellite separation applied to count-claim
sourcing.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* hygiene(tick-history): 2026-05-03T01:33Z — #1261 merged + 4 findings triaged; #1260 rebased; existence-drift caught 3×

Existence-drift sub-class caught 3 times on #1261's follow-up
rows (plugin location + manifest path + hook directory). Each
fix verified empirically against repo state + existing research
docs. The substrate-claim-checker v1+ existence-check would
have caught all 3 pre-publish — empirical urgency for v1
mechanization continues.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* review(pr-1260): v0.4.4 — fence-close requires whitespace-only after delimiter; remove remaining 19+/20+ count claims; bump header

5 Copilot findings on v0.4.3:

1. **(real, fixed)** findTables fence-close: per CommonMark,
   closing fences must have ONLY whitespace after the delimiter.
   "```bash" was being treated as a closer; it's actually an
   info-string-bearing line that occurs INSIDE a fence.
   Refactored to use two regexes: fenceOpen (allows info string)
   and fenceClose (strict whitespace-only); only fenceClose
   triggers fence-close transitions.

2. **(real, fixed)** Same in findClaims; same fix.

3. **(real, fixed)** File header v0.4.2; bumped to v0.4.4 with
   iteration history block extended (v0.4.3 unit tests +
   count-cleanup; v0.4.4 fence-close strictness).

4. **(real, fixed)** BACKLOG.md auto-generated; regenerated to
   pick up B-0170 title from the per-row file (drift was caused
   by an earlier in-flight title rename — `19+` → `(memo's body
   table is canonical)` — that the prior regeneration didn't
   pick up post-rebase).

5. **(real, fixed)** Remaining 19+/20+ claims:
   - README line 73: "running 20+ as of late 2026-05-03 wake" →
     dropped specific count
   - B-0170 line 18: "catalogues 19+ distinct" → "catalogues N
     distinct"
   - B-0170 line 22: "19+ instances of substrate-authoring" →
     "N instances"
   - B-0170 line 23: "19 × 20min ≈ 6 hours" → "compound to many
     hours"
   - B-0170 line 71: "19+ historical drift instances" → "N
     historical drift instances"

The replace_all pass on v0.4.3 caught some but missed others —
this is itself a verify-then-claim drift instance: I claimed
"removed all 19+/20+ counts" but actually only removed some.
v0.4.4 catches the rest. tsc clean; 16/16 tests pass.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* hygiene(tick-history): 2026-05-03T01:36Z — v0.4.4 fence-close strictness; #1262 merged; replace-all-isn't-comprehensive

V0 → V0.4.4 substrate-claim-checker: 9 review iterations + 23+
substrate-quality findings. v0.4.4 fixes CommonMark fence-close
strictness + remaining count-claim drift that v0.4.3's
replace_all missed. Recursive verify-then-claim catches its own
remediation drift. v1+ existence-check would catch the
"removed all X" → grep should return 0 class.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants