Skip to content

fix(lint_roadmap): check Blocked-by fragments into YAML and JSON decision files - #3569

Merged
clabonte merged 1 commit into
mainfrom
fix/issue-3567-blocked-by-entry-anchor
Nov 3, 2026
Merged

clabonte merged 1 commit into
mainfrom
fix/issue-3567-blocked-by-entry-anchor

Conversation

@clabonte

@clabonte clabonte commented Nov 3, 2026

Copy link
Copy Markdown
Contributor

Closes #3567.

Root cause

_check_blocked_by checks a link's fragment only when the target ends in .md. For a project keeping decisions in YAML or JSON, a typo in the id, or a link to a renamed or withdrawn decision, passed the lint.

Fix

  • New opt-in decisions.entryKey in .specfuse/layout.yml, naming the key that holds an entry's id. Without it, behavior is unchanged.
  • With it, a fragment into a .yaml, .yml or .json target must match one of those values, or the lint reports an ERROR worded like the Markdown finding.
  • An unreadable file, malformed JSON, or a file with no entries under the key is a finding, never a silent pass.
  • The key is refused under style: adr, and must be a valid mapping key.

Decision taken: ERROR under status: blocked, same as Markdown, not a warning. A decision still under review links to the file with no fragment, or to its PR; both still pass.

Known limits:

  • YAML is scanned by line, because _miniyaml refuses block scalars and flow mappings. A line inside a block scalar, or a nested key, that looks like entryKey: x counts as an id. That can let a typo pass, as it does today, but never fails a good link.
  • An entry written in flow style (- {name: x}) is not seen, so linking to it reports a missing anchor.

Scope note: a new layout key is a small addition to the project's config surface. It stays within bug size (2 production files, 1 test file) and is opt-in, so no consumer has to act.

Tests

tests/test_blocked_by_entry_anchor.py, 15 tests. 8 failed on unchanged code; the rest cover behavior that must not change.

Verification

scripts/smoke-test.sh passes: 4995 tests OK, 4 skipped.

🤖 Generated with Claude Code

…sion files

Closes #3567. `_check_blocked_by` resolved a link's fragment only for Markdown
targets, so a typo in `decisions/billing.yaml#<id>` passed the lint, and so did a
link to a renamed or withdrawn decision.

Add an opt-in `decisions.entryKey` naming the key that holds an entry's id. When
set, a fragment into a .yaml, .yml or .json target must match one of those values,
or the lint reports an ERROR worded like the Markdown finding. YAML is scanned by
line because `_miniyaml` refuses block scalars and flow mappings; JSON uses stdlib
`json`. An unreadable file, or one with no entries under the key, is a finding.
Without the key, behavior is unchanged.

Tests:
- tests/test_blocked_by_entry_anchor.py: YAML, JSON and Markdown targets, the
  no-key case, a link with no fragment, and validation of the new key

Verification:
- scripts/smoke-test.sh passes: 4995 tests OK, 4 skipped

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@clabonte
clabonte merged commit 001f147 into main Nov 3, 2026
7 checks passed
@clabonte
clabonte deleted the fix/issue-3567-blocked-by-entry-anchor branch November 3, 2026 14:13
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.

Roadmap lint cannot check a Blocked-by decision anchor in a non-Markdown file

1 participant