Ambiguous anchors fail the run, the editor understands reference blocks, and ADR 0016 has no open questions - #113
Conversation
180eee3 to
7e15c04
Compare
There was a problem hiding this comment.
🟡 Changes recommended
One or more issues must be addressed before approval.
Get a fresh assessment by requesting another Copilot review.
Pull request overview
Adds cross-port ambiguous-anchor diagnostics, LSP support for reference blocks, and documentation/conformance updates for ADR 0016 decisions.
Changes:
- Records document headings and rejects duplicate reference anchors across all ports.
- Adds reference hover and go-to-definition behavior in the LSP.
- Resolves ADR questions and adds bundle 22 plus regenerated artifacts.
File summaries
| File | Description |
|---|---|
| typescript/packages/website/src/content/docs/reference/lint.md | Updated as part of this pull request. |
| typescript/packages/website/src/content/docs/reference/examples.mdx | Updated as part of this pull request. |
| typescript/packages/website/src/content/docs/reference/editor-support.mdx | Updated as part of this pull request. |
| typescript/packages/website/src/content/docs/how-to/share-setup-between-examples.md | Updated as part of this pull request. |
| typescript/packages/lsp/tests/handlers.test.ts | Updated as part of this pull request. |
| typescript/packages/lsp/src/handlers.ts | Updated as part of this pull request. |
| typescript/packages/language/tests/index-workspace.test.ts | Updated as part of this pull request. |
| typescript/packages/core/tests/structurer.test.ts | Updated as part of this pull request. |
| typescript/packages/core/tests/reference.test.ts | Updated as part of this pull request. |
| typescript/packages/core/tests/conformance.test.ts | Updated as part of this pull request. |
| typescript/packages/core/src/structurer.ts | Updated as part of this pull request. |
| typescript/packages/core/src/plan.ts | Updated as part of this pull request. |
| typescript/packages/core/src/index.ts | Updated as part of this pull request. |
| typescript/packages/core/src/diagnostics.ts | Updated as part of this pull request. |
| typescript/packages/core/src/conformance.ts | Updated as part of this pull request. |
| typescript/packages/core/src/ast.ts | Updated as part of this pull request. |
| typescript/packages/cli/tests/lint.test.ts | Updated as part of this pull request. |
| typescript/packages/cli/src/lint.ts | Updated as part of this pull request. |
| rust/varar/tests/conformance.rs | Updated as part of this pull request. |
| rust/core/tests/ast_test.rs | Updated as part of this pull request. |
| rust/core/src/structurer.rs | Updated as part of this pull request. |
| rust/core/src/plan.rs | Updated as part of this pull request. |
| rust/core/src/diagnostics.rs | Updated as part of this pull request. |
| rust/core/src/conformance.rs | Updated as part of this pull request. |
| rust/core/src/ast.rs | Updated as part of this pull request. |
| ruby/packages/core/spec/varar/core/plan_spec.rb | Updated as part of this pull request. |
| ruby/packages/core/lib/varar/core/structurer.rb | Updated as part of this pull request. |
| ruby/packages/core/lib/varar/core/plan.rb | Updated as part of this pull request. |
| ruby/packages/core/lib/varar/core/diagnostics.rb | Updated as part of this pull request. |
| ruby/packages/core/lib/varar/core/conformance.rb | Updated as part of this pull request. |
| ruby/packages/core/lib/varar/core/ast.rb | Updated as part of this pull request. |
| python/packages/core/tests/test_structurer.py | Updated as part of this pull request. |
| python/packages/core/tests/test_plan.py | Updated as part of this pull request. |
| python/packages/core/tests/test_conformance.py | Updated as part of this pull request. |
| python/packages/core/src/varar_core/structurer.py | Updated as part of this pull request. |
| python/packages/core/src/varar_core/plan.py | Updated as part of this pull request. |
| python/packages/core/src/varar_core/diagnostics.py | Updated as part of this pull request. |
| python/packages/core/src/varar_core/conformance.py | Updated as part of this pull request. |
| python/packages/core/src/varar_core/ast.py | Updated as part of this pull request. |
| java/varar/src/test/java/dev/varar/ConformanceTest.java | Updated as part of this pull request. |
| java/kotlin/src/test/kotlin/dev/varar/kotlin/ConformanceTest.kt | Updated as part of this pull request. |
| java/core/src/test/java/dev/varar/core/StructurerTest.java | Updated as part of this pull request. |
| java/core/src/test/java/dev/varar/core/AstTest.java | Updated as part of this pull request. |
| java/core/src/main/java/dev/varar/core/Structurer.java | Updated as part of this pull request. |
| java/core/src/main/java/dev/varar/core/Plan.java | Updated as part of this pull request. |
| java/core/src/main/java/dev/varar/core/Diagnostics.java | Updated as part of this pull request. |
| java/core/src/main/java/dev/varar/core/Conformance.java | Updated as part of this pull request. |
| java/core/src/main/java/dev/varar/core/Ast.java | Updated as part of this pull request. |
| go/core/structurer.go | Updated as part of this pull request. |
| go/core/plan.go | Updated as part of this pull request. |
| go/core/diagnostics.go | Updated as part of this pull request. |
| go/core/conformance.go | Updated as part of this pull request. |
| go/core/ast.go | Updated as part of this pull request. |
| go/conformance/conformance_test.go | Updated as part of this pull request. |
| go/conformance/b22/library.steps.go | Updated as part of this pull request. |
| dotnet/Varar.Tests/ConformanceFixtures.cs | Updated as part of this pull request. |
| dotnet/Varar.Core/Structurer.cs | Updated as part of this pull request. |
| dotnet/Varar.Core/Plan.cs | Updated as part of this pull request. |
| dotnet/Varar.Core/Diagnostics.cs | Updated as part of this pull request. |
| dotnet/Varar.Core/Conformance.cs | Updated as part of this pull request. |
| dotnet/Varar.Core/Ast.cs | Updated as part of this pull request. |
| doc/adr/0016-reuse-is-a-link.md | Updated as part of this pull request. |
| conformance/bundles/22-reference-ambiguous-anchor/shared.md | Updated as part of this pull request. |
| conformance/bundles/22-reference-ambiguous-anchor/LibrarySteps.java | Updated as part of this pull request. |
| conformance/bundles/22-reference-ambiguous-anchor/library.steps.ts | Updated as part of this pull request. |
| conformance/bundles/22-reference-ambiguous-anchor/library.steps.rs | Updated as part of this pull request. |
| conformance/bundles/22-reference-ambiguous-anchor/library.steps.rb | Updated as part of this pull request. |
| conformance/bundles/22-reference-ambiguous-anchor/library.steps.py | Updated as part of this pull request. |
| conformance/bundles/22-reference-ambiguous-anchor/library.steps.kt | Updated as part of this pull request. |
| conformance/bundles/22-reference-ambiguous-anchor/library.steps.go | Updated as part of this pull request. |
| conformance/bundles/22-reference-ambiguous-anchor/library.steps.cs | Updated as part of this pull request. |
| conformance/bundles/22-reference-ambiguous-anchor/golden/trace.json | Updated as part of this pull request. |
| conformance/bundles/22-reference-ambiguous-anchor/golden/registry.json | Updated as part of this pull request. |
| conformance/bundles/22-reference-ambiguous-anchor/golden/plan.json | Updated as part of this pull request. |
| conformance/bundles/22-reference-ambiguous-anchor/golden/doc.json | Updated as part of this pull request. |
| conformance/bundles/22-reference-ambiguous-anchor/example.md | Updated as part of this pull request. |
| conformance/bundles/21-reference-consumed/golden/doc.json | Updated as part of this pull request. |
| conformance/bundles/20-reference-splice/golden/doc.json | Updated as part of this pull request. |
| conformance/bundles/19-emphasis-parameter/golden/doc.json | Updated as part of this pull request. |
| conformance/bundles/18-multi-table-example/golden/doc.json | Updated as part of this pull request. |
| conformance/bundles/17-unexpected-pass/golden/doc.json | Updated as part of this pull request. |
| conformance/bundles/16-stimulus-state-replacement/golden/doc.json | Updated as part of this pull request. |
| conformance/bundles/15-custom-parameter-format/golden/doc.json | Updated as part of this pull request. |
| conformance/bundles/14-stateless-steps/golden/doc.json | Updated as part of this pull request. |
| conformance/bundles/13-custom-parameter-type/golden/doc.json | Updated as part of this pull request. |
| conformance/bundles/12-combining-marks/golden/doc.json | Updated as part of this pull request. |
| conformance/bundles/11-emoji-offsets/golden/doc.json | Updated as part of this pull request. |
| conformance/bundles/10-error-fence-without-step/golden/doc.json | Updated as part of this pull request. |
| conformance/bundles/09-expected-message-mismatch/golden/doc.json | Updated as part of this pull request. |
| conformance/bundles/08-string-capture/golden/doc.json | Updated as part of this pull request. |
| conformance/bundles/07-row-check-mismatch/golden/doc.json | Updated as part of this pull request. |
| conformance/bundles/06-doc-string-mismatch/golden/doc.json | Updated as part of this pull request. |
| conformance/bundles/05-ambiguous-match/golden/doc.json | Updated as part of this pull request. |
| conformance/bundles/04-tables-and-docstrings/golden/doc.json | Updated as part of this pull request. |
| conformance/bundles/03-expected-failure/golden/doc.json | Updated as part of this pull request. |
| conformance/bundles/02-context-isolation/golden/doc.json | Updated as part of this pull request. |
| conformance/bundles/01-roman-numerals/golden/doc.json | Updated as part of this pull request. |
Review details
Suppressed comments (3)
typescript/packages/core/src/plan.ts:221
- When this check runs recursively,
unit.spanbelongs to the nestedtargetdocument, not necessarily the top-levelfromdocument. The resulting diagnostic carries only a span; the language index then labels every diagnostic fromplan(doc, ...)with the host oath path, while the consumed target's own plan omits the section. An ambiguous anchor inside a nested shared section is therefore underlined at target offsets in the referring file instead of on the target reference block. Propagate the originating document path with diagnostics or retain nested diagnostics per oath.
typescript/packages/lsp/src/handlers.ts:437 - This test covers the new one-link-per-heading behavior only indirectly through the implementation; it does not exercise an ambiguous reference through
buildHandlers().definition. Since returning both target links is the editor's promised behavior for the new diagnostic, add a duplicate-heading case that asserts both target ranges so a future change cannot silently choose one.
typescript/packages/lsp/src/handlers.ts:486 - Filtering the standalone plan by
ex.scopeStackloses a valid nested-only section. If the referenced section contains only another reference,plan(target, ... referenced: new Set())starts the merged example with the nested target's scope stack and never replaces it with the outer heading, so this predicate rejects it and hover reports_Contributes no steps._even though the run resolver splices the nested steps. Select the target section before flattening, or retain the source section when planning, so nested-only references are included.
- Files reviewed: 97/97 changed files
- Comments generated: 2
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| const heading = slug === '' ? undefined : sectionHeadings(target, slug)[0] | ||
| const title = slug === '' ? basenamePosix(target.path) : (heading?.text ?? `#${slug}`) | ||
| const lines = [`**${title}** · \`${linkTarget(at.written)}\``, ''] | ||
| const steps = sectionSteps(index, target, slug) |
There was a problem hiding this comment.
Fixed in 9789407: when the anchor names more than one heading the hover says so — _Ambiguous: 2 headings share this anchor (lines 3, 7), so nothing is spliced in._ — and previews nothing, since the reference contributes nothing until it is fixed. Go to Definition still offers every heading so the clash is visible, and the ambiguous-anchor diagnostic sits on the block. Pinned by a handler test.
| 2. ~~Where is drift reported for a referenced section?~~ **Resolved** — it is | ||
| not drift at all. A consumed section plans no example in its own file, so | ||
| its paragraphs are not in the baseline; a step that stops matching one is | ||
| caught as `reference-empty` at the reference that depends on it — once, | ||
| loudly, where the fix goes. The consumed file's baseline entry means only | ||
| "this file was discovered". Consequence, accepted: delete every referrer and | ||
| the section reads as a new example, not a restored one. Documented under |
There was a problem hiding this comment.
Fixed in eec87a8: the section is now ## Open questions, and how each was decided, with an intro saying every question is closed and kept in place with its decision beneath it; the two in-document links to it are updated to the new anchor.
0119df7 to
b3f79ea
Compare
… as ambiguous-anchor ADR 0016 listed the "ambiguous anchor" error and nothing detected it (#106). Two headings that slug identically (`## Setup` twice — GitHub's `#setup` and `#setup-1`) are indistinguishable to the scope-stack rule, so a reference to `#setup` silently spliced BOTH sections in and the run stayed green. Now `Doc` carries `headings` — every heading block, in order — and plan() refuses a reference whose anchor names more than one of them: an `ambiguous-anchor` error on the reference block, like the other three reference errors, and nothing is spliced in until it is fixed. The rule is "the anchor a reference names belongs to one heading", not "unique headings in any referenced file": a duplicate nobody links to is harmless. The doc artifact pins the outline, so every bundle's doc.json golden gains `headings`, and `22-reference-ambiguous-anchor` gates the diagnostic in all seven ports. Ports whose diagnostics carry messages (TypeScript, Python, Ruby, .NET) name the target and the headings' lines; Java, Rust and Go stay message-less as their other reference diagnostics are. varar lint no longer goes through the runner's planOath, which re-parsed every oath it had already parsed to build the workspace. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RQVAKGfMEKPbT919FqAChP
A reference block (ADR 0016) was inert in the editor beyond ordinary Markdown link rendering (#107). Now: - Go to Definition on the link lands on the heading the anchor names, in the oath that holds it — the top of the file for a whole-file reference, and one link per heading for an ambiguous anchor, so the editor peeks them all rather than picking one. - Hover shows the steps the reference splices in, in order, with nested references resolved and a step from a third file saying which. The section is consumed, so the index holds no plan for it; the hover plans the target as if nothing referenced it and keeps the section's examples. - The reference diagnostics already reached the editor through the ordinary rail; a test now pins that they sit on the block. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RQVAKGfMEKPbT919FqAChP
Ambiguous anchors fail the run in every port (the TypeScript-only lint check was reversed; deviation 2 records why and what moved). The editor's behaviour at a reference block is decided (question 8). And the decisions on #108, #109 and #110: a consumed section's paragraphs are not in the drift baseline and reference-empty is the intended signal; reports stay flat, attributed by the run result's docPath; the same section twice runs twice; whole-file references stay, hazard documented; a referenced section's own heading chain is discarded; no opt-in depth lint. Nothing on the ADR is open. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RQVAKGfMEKPbT919FqAChP
7e15c04 to
eec87a8
Compare
Closes #106, #107, #108, #109, #110. Stacked on #112 (which is stacked on #104) — the diff here is the three commits on top.
#106 — ambiguous anchors fail the run, in every port
ADR 0016 listed the error and nothing detected it. Two headings that slug identically (
## Setuptwice — GitHub's#setupand#setup-1) are indistinguishable to the scope-stack rule, so a reference to#setupspliced both sections in and stayed green.Docnow carriesheadings(every heading block, in order), andplan()refuses a reference whose anchor names more than one of them: anambiguous-anchorerror on the reference block, like the other three reference errors, and nothing is spliced in until it is fixed. The rule is "the anchor a reference names belongs to one heading", not "unique headings in any referenced file" — a duplicate nobody links to is harmless.doc.jsongainsheadings(all 21 regenerated by the TypeScript reference; every port matches by content).22-reference-ambiguous-anchorgates the diagnostic across all seven ports.(The first push of this PR had this as a TypeScript-only lint check. That was reversed after review; deviation 2 in the ADR records why and what moved.)
#107 — the editor at a reference block
Go to Definition lands on the heading the anchor names (top of file for a whole-file reference; one link per heading for an ambiguous anchor, so VS Code peeks both).
Hover shows the steps the reference splices in, nested references resolved, with a step from a third file saying which:
The section is consumed, so the index holds no plan for it; the hover plans the target as if nothing referenced it and keeps the section's examples, reusing the planner's own splice semantics.
Diagnostics already reached the editor; a test pins that they sit on the block.
Nothing changes in the VS Code extension —
hoverProvideranddefinitionProviderwere already on.#108, #109, #110 — decided and documented
Recorded in the ADR (every open question is now resolved) and in
reference/examples.mdx:reference-emptyat the reference site is the intended signal. Consequence accepted and documented: delete every referrer and the section reads as new, not restored.docPath(v2, Run results carry per-step document identity (closes #105) #112). No nesting.Gate
make checkat the repo root exits 0: all seven ports built and tested (bundle 22 exercised in each), parity, commit lint, and every adapter smoke contract. Also green on their own:pnpm check(94 files, 682 tests),pnpm -r build, and the website build.🤖 Generated with Claude Code
https://claude.ai/code/session_01RQVAKGfMEKPbT919FqAChP