Skip to content

spec: render frontmatter edges as a Related Artifacts body section - #219

Merged
joestump merged 2 commits into
mainfrom
feat/spec-related-artifacts-section
Aug 19, 2026
Merged

spec: render frontmatter edges as a Related Artifacts body section#219
joestump merged 2 commits into
mainfrom
feat/spec-related-artifacts-section

Conversation

@joestump-agent

Copy link
Copy Markdown
Collaborator

Third of five authoring-skill hardening PRs from the downstream audit.

Problem

Frontmatter edges (implements / requires / extends / supersedes) are machine-readable only. A human reading the raw markdown or the rendered docs page never sees the graph, so downstream projects hand-write their own "Related ADRs" header lines — and in every repo audited (msgbrowse's 20 specs, plus older plugin-generated projects) those lines drifted into at least three inconsistent shapes: some linked, some plain text, some with titles in the link text, some absent entirely.

Change

The spec.md template gains a canonical ## Related Artifacts section immediately after the H1 that mirrors the frontmatter edges — one bullet per edge target, naming the edge verb and linking the target. A MUST rule requires it whenever edges exist and requires regenerating it in the same pass whenever edges change on update ("a stale section is a lie about the graph"); it's omitted entirely when the spec declares no edges.

New specs get the section for free from the template; existing specs pick it up on their next /sdd:spec --update.

Verification

  • scripts/check-structure.sh passes; template-only change.

🤖 This was posted autonomously by glm-5.3 using Crush.

@github-actions

Copy link
Copy Markdown

Skill Eval Results

Mode: quick | No eval results found.

ℹ️ High-cost scenarios exist (full-chain-with-review) but did not run in this build. They run only on release PRs or manual pipeline dispatch.

1 similar comment
@github-actions

Copy link
Copy Markdown

Skill Eval Results

Mode: quick | No eval results found.

ℹ️ High-cost scenarios exist (full-chain-with-review) but did not run in this build. They run only on release PRs or manual pipeline dispatch.

@joestump
joestump force-pushed the feat/spec-related-artifacts-section branch from d3b5ae9 to 9224c75 Compare August 19, 2026 10:03
@github-actions

Copy link
Copy Markdown

Skill Eval Results

Mode: quick | No eval results found.

ℹ️ High-cost scenarios exist (full-chain-with-review) but did not run in this build. They run only on release PRs or manual pipeline dispatch.

@joestump

Copy link
Copy Markdown
Owner

Code review — /code-review --fix

Reviewed the diff and pushed two fixes to this branch.

Finding: the heading collides with the one /sdd:docs generates

skills/spec/SKILL.md:380

buildMiniDagSection emits its neighbour graph under exactly ## Related Artifacts, and it is appended to every generated spec and design page:

// docs-site/scripts/graph-data.js
'## Related Artifacts',
'',
`Direct relationships declared in YAML frontmatter (per …). Run \`/sdd:graph chain ${artifactId}\` …`,
// docs-site/scripts/transform-openspecs.js:216
const miniDag = buildMiniDagSection(artifactId, ARTIFACT_GRAPH);
fs.writeFileSync(destPath, frontmatter + escapeMdxUnsafe(content) + miniDag);

Same in the vendored plugin. So a spec.md carrying an authored section under that name renders with two identical H2s — Docusaurus assigns #related-artifacts and #related-artifacts-1, the sidebar TOC shows the heading twice, and any existing deep link to #related-artifacts silently changes which of the two it lands on. Since the rule is a MUST for every spec with edges, it would hit essentially every spec page in the repo at once.

Renamed the authored section to ## Graph Edges, which matches the vocabulary already used in this file (## Graph Edge Frontmatter, per ADR-0023). The Rules bullet now states the constraint and the reason, so the next person does not rename it back.

Finding: the Implements example points at a directory that does not exist

skills/spec/SKILL.md:388

- **Implements:** [ADR-XXXX](../../../adr/ADR-XXXX-title.md)

Singular adr/. Specs live at docs/openspec/specs/{capability}/spec.md, so ../../../ resolves to docs/ and the target is docs/adr/… — but the ADR directory is docs/adrs/ (references/shared-patterns.md:34). Every spec seeded from this template would ship a dead link on its very first bullet.

That also puts it on a collision course with #217, which adds "every relative markdown link in both files MUST point at a file that exists on disk" — the template would fail the validation the sibling PR introduces. Fixed to adrs/, and added a note that the paths assume the default layout and must be resolved against the actual {adr-dir}/{spec-dir} from Step 0 when a project overrides them (per the Artifact Path Resolution pattern, which forbids hardcoding these).

Verified, no change needed

  • The Requires example, [SPEC-XXXX](../capability/spec.md), resolves correctly from a sibling capability directory.
  • "Omit the entire section when there are no edges" is stated in both the template comment and the rule — consistent.
  • The regenerate-on-edge-change obligation is the right call; a stale mirror of the frontmatter is worse than no mirror.

🤖 Posted on behalf of @joestump by claude-opus-5 using Claude Code.

@github-actions

Copy link
Copy Markdown

Skill Eval Results

Mode: quick | No eval results found.

ℹ️ High-cost scenarios exist (full-chain-with-review) but did not run in this build. They run only on release PRs or manual pipeline dispatch.

joestump-agent and others added 2 commits August 19, 2026 11:35
Frontmatter edges are machine-readable only -- a reader of the raw
markdown or the rendered docs page never sees which ADRs a spec
implements or which capabilities it requires, so downstream projects
hand-write ad-hoc "Related ADRs" header lines in inconsistent shapes
(found in every audited downstream repo). Give the template a
canonical home for that information: a Related Artifacts section that
mirrors the frontmatter edges, one bullet per target, regenerated
whenever edges change.

💘 Generated with Crush

Assisted-by: Crush:glm-5.3
…path

Two defects in the Related Artifacts section:

The heading collided with the one /sdd:docs already appends. Both
transform-openspecs.js and the vendored Docusaurus plugin emit a
generated '## Related Artifacts' mini-DAG at the foot of every spec and
design page, so an authored section under the same name gave every
rendered page two identical H2s -- duplicate anchors and a doubled TOC
entry. Renamed to '## Graph Edges', matching the repo's own edge
vocabulary.

The Implements example pointed at ../../../adr/, singular. The ADR
directory is docs/adrs/, so every spec seeded from this template shipped
a dead link -- and PR #217 adds a validation rule requiring exactly the
links this template breaks.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@joestump
joestump force-pushed the feat/spec-related-artifacts-section branch from e4cf20b to 36807f4 Compare August 19, 2026 10:35
@github-actions

Copy link
Copy Markdown

Skill Eval Results

Mode: quick | No eval results found.

ℹ️ High-cost scenarios exist (full-chain-with-review) but did not run in this build. They run only on release PRs or manual pipeline dispatch.

@joestump
joestump merged commit b7793e5 into main Aug 19, 2026
10 checks passed
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