Skip to content

feat(blueprint-plugin): guard ADR-number collisions in blueprint-adr-validate#1963

Open
laurigates wants to merge 1 commit into
mainfrom
claude/goofy-easley-fa900b
Open

feat(blueprint-plugin): guard ADR-number collisions in blueprint-adr-validate#1963
laurigates wants to merge 1 commit into
mainfrom
claude/goofy-easley-fa900b

Conversation

@laurigates

Copy link
Copy Markdown
Owner

What

Adds a deterministic ADR-number collision guard to blueprint-adr-validate (the lightweight validation-only variant proposed in #1585).

blueprint-plugin/skills/blueprint-adr-validate/scripts/check-adr-numbers.sh reports three classes, emitting the STATUS=/ISSUE_COUNT= structured convention:

Type Severity Meaning
duplicate_adr_number ERROR Two working-tree files lead with the same NNNN-.
adr_number_collision ERROR A working-tree ADR's number is already held by a different filename on origin/main — the pre-merge parallel-PR case.
adr_missing_index_row WARN An ADR is not referenced from the ADR directory's README index.

It resolves docs/adrs/ (blueprint canonical) or docs/adr/, degrades to STATUS=OK when neither exists, and skips the base-ref comparison (still checking duplicates + index) when origin/main is unavailable — so it is parallel-safe (exit 0 on OK/WARN, 1 on ERROR).

Why

ADR numbers are chosen at branch time but only claimed at merge time, so two in-flight ADR PRs can pick the same number and both land. This is the FVH infrastructure #2015 collision: two ADRs both numbered 0038, a third assigned 0040 over the apparent gap, and the README index silently missed 0039/0040 for a week. blueprint-adr-validate validated ADR relationships but had no numbering guard, so the race was invisible until implementation time.

Per the issue, this is the lighter alternative (validation-only, no renaming automation). The full placeholder-number + merge-time-assignment automation remains open in #1585 if wanted later.

How

  • New check-adr-numbers.sh + wiring into blueprint-adr-validate/SKILL.md (Step 2b + Agentic Optimizations) and REFERENCE.md.
  • Regression test scripts/tests/test-check-adr-numbers.sh — git fixture, 8 assertions (clean→OK, base-ref collision→ERROR+exit1, within-tree dupe→ERROR, missing index→WARN, no ADR dir→OK, absent base ref→graceful degrade). Auto-discovered by run-skill-script-tests.sh.
  • plugin-compliance-check.sh check_skill_body() guard asserting the SKILL.md retains the check-adr-numbers.sh invocation (per .claude/rules/regression-testing.md).

Verification

  • shellcheck clean on both scripts; lint-shell-scripts.sh clean.
  • Regression test: PASS=8 FAIL=0.
  • Runs clean against this repo's own 19 ADRs (STATUS=OK).

Closes #1585

🤖 Generated with Claude Code

…validate

ADR numbers are chosen at branch time but only claimed at merge time, so two
in-flight ADR PRs can pick the same number and both land (issue #1585 — the
FVH infrastructure #2015 collision where two ADRs both claimed 0038 and the
README index silently missed 0039/0040 for a week).

Adds the lightweight validation-only guard from the issue's "lighter
alternative" — no renaming automation, just deterministic collision + index
detection:

- check-adr-numbers.sh reports duplicate_adr_number (two working-tree files
  share a number, ERROR), adr_number_collision (a working-tree ADR's number is
  held by a different filename on origin/main — the pre-merge parallel-PR case,
  ERROR), and adr_missing_index_row (ADR absent from the README index, WARN).
- Resolves docs/adrs/ or docs/adr/, emits the STATUS=/ISSUE_COUNT= convention,
  degrades to OK when no ADR dir / base ref exists (parallel-safe).
- Wired into blueprint-adr-validate SKILL.md Step 2b + Agentic Optimizations,
  documented in REFERENCE.md.
- Regression test (git fixture, 8 assertions) + plugin-compliance-check guard
  asserting the SKILL.md retains the invocation.

Closes #1585

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@laurigates laurigates added enhancement New feature or improvement blueprint-plugin Blueprint plugin related labels Jul 4, 2026
@laurigates laurigates self-assigned this Jul 4, 2026
@github-actions

github-actions Bot commented Jul 4, 2026

Copy link
Copy Markdown
Contributor

Plugin Compliance Review

Plugin plugin.json Frontmatter Body Marketplace Release Config Bash Patterns Descriptions When-to-Use Size Overall
blueprint-plugin ⚠️ ⚠️

Recommendations

  • ⚠️ blueprint-plugin/blueprint-feature-tracker-sync: SKILL.md is 17309 chars (~4327 tokens, >10000) — consider extracting to REFERENCE.md or scripts/ (ceiling: 26000 chars / ~6500 tokens)
  • ⚠️ blueprint-plugin/blueprint-work-order: SKILL.md is 11513 chars (~2878 tokens, >10000) — consider extracting to REFERENCE.md or scripts/ (ceiling: 26000 chars / ~6500 tokens)
  • ⚠️ blueprint-plugin/blueprint-claude-md: SKILL.md is 11076 chars (~2769 tokens, >10000) — consider extracting to REFERENCE.md or scripts/ (ceiling: 26000 chars / ~6500 tokens)
  • ⚠️ blueprint-plugin/document-detection: SKILL.md is 12442 chars (~3110 tokens, >10000) — consider extracting to REFERENCE.md or scripts/ (ceiling: 26000 chars / ~6500 tokens)
  • ⚠️ blueprint-plugin/blueprint-status: SKILL.md is 14947 chars (~3736 tokens, >10000) — consider extracting to REFERENCE.md or scripts/ (ceiling: 26000 chars / ~6500 tokens)
  • ⚠️ blueprint-plugin/blueprint-story-audit: SKILL.md is 11235 chars (~2808 tokens, >10000) — consider extracting to REFERENCE.md or scripts/ (ceiling: 26000 chars / ~6500 tokens)
  • ⚠️ blueprint-plugin/document-linking: SKILL.md is 11208 chars (~2802 tokens, >10000) — consider extracting to REFERENCE.md or scripts/ (ceiling: 26000 chars / ~6500 tokens)
  • ⚠️ blueprint-plugin/blueprint-derive-plans: SKILL.md is 10183 chars (~2545 tokens, >10000) — consider extracting to REFERENCE.md or scripts/ (ceiling: 26000 chars / ~6500 tokens)
  • ⚠️ blueprint-plugin/blueprint-upgrade: SKILL.md is 19649 chars (~4912 tokens, >10000) — consider extracting to REFERENCE.md or scripts/ (ceiling: 26000 chars / ~6500 tokens)
  • ⚠️ blueprint-plugin/blueprint-init: SKILL.md is 21578 chars (~5394 tokens, >10000) — consider extracting to REFERENCE.md or scripts/ (ceiling: 26000 chars / ~6500 tokens)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

blueprint-plugin Blueprint plugin related enhancement New feature or improvement

Projects

None yet

Development

Successfully merging this pull request may close these issues.

blueprint-plugin: placeholder ADR numbers with merge-time assignment (parallel-PR collision guard)

1 participant