Skip to content

commands/reflect: exclude H1 from the numbered-sequence match - #175

Merged
bborbe merged 1 commit into
masterfrom
fix/reflect-numbering-exclude-h1
Sep 17, 2026
Merged

bborbe merged 1 commit into
masterfrom
fix/reflect-numbering-exclude-h1

Conversation

@bborbe

@bborbe bborbe commented Sep 17, 2026

Copy link
Copy Markdown
Owner

What

Narrows the numbered-sequence match in /vault-cli:reflect's ENHANCE path from ^#+ to ^#{2,6}.

The bug

v0.133.1 (merged ~40 min ago) added a step telling ENHANCE to derive the next section number from the whole file:

grep -oE '^#+ [0-9]+\.' <page> | grep -oE '[0-9]+' | sort -n | tail -1

^#+ matches any heading depth — including a #-prefixed line inside a fenced code block. On a page whose bash examples contain:

# 1. What is suppressed, and is the suppression still in force?
# 2. The unfiltered source — if this is 0 too, the quiet is real

…those comments are counted as sections 1 and 2, and uniq -d reports duplicates that do not exist.

Caught on the first real run of the step it had just added. The check returned 1 2 17 against a page whose only genuine duplicate is 17.

The tail -1 max carries the same exposure: a numbered comment higher than any real heading would silently inflate the next number, which is the exact failure the step was written to prevent.

Why it reached a release

The step was verified before shipping, with a positive control (fabricated ### 5. duplicate → caught) and a negative control (clean file → silent). Both fixtures were synthetic and neither contained a code fence, so the defect existed only in real input. That is the gap, and it is worth naming rather than quietly patching.

The fix

^#{2,6} — excludes depth-1 only. Safe because vault notes never carry # H1; the filename is the title, and the no-H1 rule is a documented vault convention.

Verified on the same real page:

pattern max duplicates
^#+ (shipped) 38 1 2 17 ← two phantom
^#{2,6} (this PR) 38 17 ← correct

Negative control re-run: a fabricated ### 5. / ### 5. pair is still caught.

Severity

Fails safe — it over-reports collisions, so a reader investigates a phantom rather than missing a real one. Hence a follow-up rather than a revert.

v0.133.1 shipped `^#+ [0-9]+\.`, which matches any heading depth. A fenced
code block containing `# 1. what is suppressed` / `# 2. the unfiltered source`
is therefore counted as sections 1 and 2, and `uniq -d` reports collisions
that do not exist.

Caught on the first real run of the step it had just added: the check returned
`1 2 17` against a page whose only true duplicate is 17. The `tail -1` max is
exposed to the same defect - a numbered comment above every real heading would
silently inflate the next number.

Narrow to `^#{2,6}`. Safe because vault notes never carry `# H1` (the filename
is the title), and the collision detector still fires on a fabricated `### 5.`
duplicate.

The step was verified before shipping with a positive and a negative control,
both synthetic; neither had a code fence, so the failure mode existed only in
real input.
@bborbe
bborbe marked this pull request as ready for review September 17, 2026 16:42

@ben-s-pull-request-reviewer ben-s-pull-request-reviewer Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Now I have everything I need. Let me perform the in-session classification and adjudication.

Classification (Step 4c-sel):

Changed files: CHANGELOG.md, commands/reflect.md — neither is a .go file, no go.mod, no Makefile, no agent/command/skills files.

Judgment candidates filtered by trigger:

  • changelog/conventional-prefix-required — trigger CHANGELOG.md → applicable: the entry starts with fix: ✓ (passes)
  • agent-cmd/command-frontmatter — trigger commands/**/*.md → skipped: file existed before, rule applies when "any commands/*.md file is created"
  • agent-cmd/command-thin — trigger includes commands/**/*.md → skipped: file existed before, rule applies when "any new commands/*.md file is added or substantially changed"

All other rules have triggers that don't match (**/*.go, go.mod, Makefile, etc.).

Mechanical findings: zero (already confirmed).

Adjudication (Step 4d-sel):

  • changelog/conventional-prefix-required: entry fix:
  • The fix itself is correct: ^#{2,6} on lines 169/171 properly excludes depth-1 headings
  • Version alignment: all four version strings are still 0.133.1 — appropriate for an ## Unreleased entry (the releaser will bump on merge)
  • No Go code, no tests, no security surface

{
  "verdict": "approve",
  "summary": "Clean bugfix: the ENHANCE path's collision-detection regex was too broad (`^#+`), matching bash comments inside fenced code blocks as section headings. The fix narrows it to `^#{2,6}` (depth 2–6 only), which is safe because vault note filenames are the H1 and never carry `# H1`. The CHANGELOG entry uses the correct `fix:` prefix. Version strings remain at v0.133.1, appropriate for an `## Unreleased` section.",
  "comments": [],
  "concerns_addressed": [
    {
      "concern": "correctness: regex `^#+` matched depth-1 headings AND `#`-prefixed lines inside fenced code blocks, causing false positive duplicate collisions",
      "disposition": "addressed",
      "detail": "commands/reflect.md:169,171 — `^#+` replaced with `^#{2,6}`; depth-1 headings excluded because vault filenames serve as titles"
    },
    {
      "concern": "tests: original v0.133.1 step was verified with synthetic fixtures lacking code fences — defect only reproduced in real input",
      "disposition": "not-an-issue",
      "detail": "This is a documentation-only fix in a Claude Code commands file; no Go code or test suite is affected. The concern is noted as background context for why the defect was not caught pre-release."
    }
  ]
}

@bborbe
bborbe merged commit 7852ce6 into master Sep 17, 2026
5 checks passed
@bborbe
bborbe deleted the fix/reflect-numbering-exclude-h1 branch September 17, 2026 16:45
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.

1 participant