Summary
body-links-drift fires on artifacts whose links do exist, and names targets that are already linked. The rule also names non-artifact tokens (invariant numbers) that can never satisfy it, so the warning is unclosable by design.
Found on forgeplan 0.34.0 while shaping an ADR in a real project.
Reproduction
ADR-008 has five links, all created via forgeplan link:
$ forgeplan graph | grep "ADR-008 -->"
ADR-008 -->|based_on| ADR-004
ADR-008 -->|based_on| PRD-001
ADR-008 -->|based_on| RFC-001
ADR-008 -->|informs| SPEC-002
ADR-008 -->|informs| SPEC-004
Its ## Related Artifacts section mentions exactly those five, plus a few invariant numbers from the parent RFC. Validation:
$ forgeplan validate ADR-008
! [SHOULD] body-links-drift: Body's `## Related Artifacts` table mentions
ADR-004, I-1, I-3, I-6, I-8, I-9, PRD-001, RFC-001, SPEC-002, SPEC-004
but frontmatter `links:` array doesn't reference them.
Every artifact ID in that list is linked. The graph proves it in the same workspace, same moment.
Two separate problems in one warning
1. False positive on linked targets. ADR-004, PRD-001, RFC-001, SPEC-002, SPEC-004 are all present as edges. The rule appears to read the markdown projection's links: frontmatter rather than the graph, and the projection does not carry them — so the check disagrees with forgeplan graph about the same artifact.
Re-running after the links landed produced the warning verbatim, still naming ADR-004. That is the part that matters: the operator's natural response ("add the link") does not clear it, so the signal teaches them to ignore it.
2. Unsatisfiable tokens. I-1, I-3, I-6, I-8, I-9 are invariant numbers from RFC-001's body, not artifact IDs. There is nothing to link them to. The rule asks for an action that cannot be performed, and its own remedy text ("Run: forgeplan link …") does not apply.
Why this is worth fixing rather than muting
A SHOULD-level warning that cannot be cleared by doing what it asks is worse than no warning: it trains people to skip the validate output, and the next finding — a real one — goes with it. In this project the same warning sat on the artifact through activation, and the only way to tell "false positive" from "genuinely missing link" was to read forgeplan graph by hand and diff it against the message.
Suggested direction
- Resolve mentions against the graph, not the projection frontmatter — or make the projection carry the edges, so the two agree.
- Restrict ID extraction to known artifact-kind prefixes, so
I-3 and similar in-body references are not treated as link candidates.
- If a mention is deliberately incidental, the existing "remove the table row" escape hatch is fine — but it should not be the only way out for targets that are, in fact, linked.
Environment
forgeplan 0.34.0 (Homebrew, macOS arm64)
- Workspace with 28 artifacts, 30 edges
Summary
body-links-driftfires on artifacts whose links do exist, and names targets that are already linked. The rule also names non-artifact tokens (invariant numbers) that can never satisfy it, so the warning is unclosable by design.Found on
forgeplan 0.34.0while shaping an ADR in a real project.Reproduction
ADR-008has five links, all created viaforgeplan link:Its
## Related Artifactssection mentions exactly those five, plus a few invariant numbers from the parent RFC. Validation:Every artifact ID in that list is linked. The graph proves it in the same workspace, same moment.
Two separate problems in one warning
1. False positive on linked targets.
ADR-004,PRD-001,RFC-001,SPEC-002,SPEC-004are all present as edges. The rule appears to read the markdown projection'slinks:frontmatter rather than the graph, and the projection does not carry them — so the check disagrees withforgeplan graphabout the same artifact.Re-running after the links landed produced the warning verbatim, still naming
ADR-004. That is the part that matters: the operator's natural response ("add the link") does not clear it, so the signal teaches them to ignore it.2. Unsatisfiable tokens.
I-1,I-3,I-6,I-8,I-9are invariant numbers fromRFC-001's body, not artifact IDs. There is nothing to link them to. The rule asks for an action that cannot be performed, and its own remedy text ("Run: forgeplan link …") does not apply.Why this is worth fixing rather than muting
A SHOULD-level warning that cannot be cleared by doing what it asks is worse than no warning: it trains people to skip the validate output, and the next finding — a real one — goes with it. In this project the same warning sat on the artifact through activation, and the only way to tell "false positive" from "genuinely missing link" was to read
forgeplan graphby hand and diff it against the message.Suggested direction
I-3and similar in-body references are not treated as link candidates.Environment
forgeplan 0.34.0(Homebrew, macOS arm64)