Repository navigation
feat: link library APIs to their documentation at the pinned version - #94
Merged
Merged
Conversation
After the review, the library APIs the change's added lines use link to their documentation at the version the project pins. A Python name counts when the file imports it from a library a lock file pins, the module named like the library; a C# name when it sits under one of the file's usings, .NET's own APIs at the target framework the nearest project file names, and a package's at the version a lock or project file pins. Other languages get a note saying their files are not read for links. The links come first from published inventories, which the engine downloads: the Sphinx inventory under the documentation site PyPI names for the pinned release, tried in Read the Docs' folder for that version first and read only when the version its header names documents the pinned one, and the .NET API reference's cross-reference map, scanned as it streams in, each entry linked with the view of the pinned version only when the map lists it there. Inventories are untrusted data, parsed and never run: every download is https on a named host with no credentials or port, connects only to public addresses, follows no redirect, and is capped downloaded and inflated. A library whose inventory cannot be read is a note, never a failure. Then the agent suggests links for the APIs no inventory linked, from what it knows; the engine checks each names an API it asked about, once, at an https address on a named public host, and never fetches it. The result, now version 18, carries docLinks: every inventory link, then every suggestion labelled as the agent's, the APIs left without a link and a note per library. The overview lists them in that order, suggestions flagged as not checked, and a hover on the name on the head side of the diff shows the same. The doc-links prompt lands with its cases and score: one labelled API each on canary-python and canary-csharp, scored by doc-links-on-site and doc-links-checked. The baseline records Pi 0.86.1 with zai-coding-cn/glm-5.3: both scores 1. The plain rows are rewritten from a full model-free run; every other agent row stays. Closes #49
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Intent
Closes #49. Library APIs used in a change link to their documentation at the version the project pins. Links come first from published inventories, which the engine downloads: Sphinx inventories for Python libraries and the .NET API reference's cross-reference map. Links the agent suggests come after them and are labelled as suggestions. The overview panel and hovers on the head side of the diff show the links.
The acceptance criteria are tests for parsing both inventory formats and for version matching; agent-suggested links that are labelled and shown only after the inventory links; and a suggestion prompt that lands with its evaluation cases and score. Validation never launches, downloads or installs VS Code or any other tool: extension tests that need VS Code run only in CI, and live validation goes through the engine protocol, the unit tests and rendered output.
What Changed
objects.invinventories and the streamed .NET API reference.xrefmap.json, only when the inventory documents that exact version, downloaded by a hardened https fetcher (named public hosts only, no redirects, no credentials or ports, download/inflate caps); APIs no inventory links go to the agent, whose suggestions are checked but never fetched. The review result (schema v18) carriesdocLinkswith every inventory link before every labelled suggestion.prompts.json, run and scored over the canary cases (doc-links-on-site,doc-links-checked) with an excerpt of the .NET cross-reference map recorded forcanary-csharp, and the baseline was rewritten; README and CONTEXT.md document the feature.Risk Assessment
✅ Low: Both round-1 findings are fixed exactly as the recorded user decisions prescribed, the fix-round code adds no components beyond those prescriptions, the fixes are deterministic and covered by regression tests that fail without them, and the rest of the change re-traced clean against its acceptance criteria and security boundary.
Testing
Live-drove the product through the engine protocol as the intent's standing boundary prescribes: the real review pipeline ran to completion over JSON-RPC four times, and its docLinks output matched the ticket's behavior exactly — attrs.field linked from the 23.1.0 Sphinx inventory, a stable inventory documenting 26.1 refused with an explanatory note, .NET Stream/CopyTo linked at the net-8.0 moniker, the package type no inventory holds left unlinked even though a multi-target packages.lock.json and the project file pin it three times, the 'At most 60 library APIs are listed, so 2 with a link and 3 without one are left out' note, and the agent's suggestion checked, never fetched, labelled and placed after the inventory link. The panel's Documentation section and both hovers were rendered through the extension's own code from that engine answer. No screenshot was captured because no browser exists on PATH and validation installs no tools; the self-contained panel HTML in the evidence directory is the rendered artifact (the repo's own UX record validates this surface as a browser-opened HTML page). The two fixes from review round 1 were each verified live and by their requested tests. Two scenarios remain untested rather than passed: the in-editor hover (requires the VS Code application, which the standing boundary forbids launching, downloading or installing, so only the rendered hover Markdown and unit/integration tests could be produced) and the doc-links evaluation scoring (requires a live model credential, so only the scripted-agent evaluation harness tests could be run).
Evidence: Engine protocol drive A: Python change, pinned attrs 23.1.0 and httpx 0.27.2
docLinks.links = [attrs.field from inventory at https://www.attrs.org/en/23.1.0/api.html#attrs.field, httpx.Client from agent at https://www.python-httpx.org/api/]; notes name the inventory read and why httpx has none; stages include 'suggesting documentation links with fake'; the suggested URL is never fetched.Evidence: Rendered overview panel (Documentation section) from the engine's protocol answer
Evidence: Hover Markdown the editor shows on the two library names (inventory vs agent-suggested)
[attrs\.field](https://www.attrs.org/en/23.1.0/api.html#attrs.field): documentation of attrs 23\.1\.0, from its published inventory — **Suggested by the agent, not checked:** [httpx\.Client](https://www.python-httpx.org/api/), for httpx 0\.27\.2Evidence: Engine protocol drive B: C# change under net8.0/net9.0 with the package pinned by a multi-target lock file and the project file
links: System.IO.Stream and System.IO.Stream.CopyTo at ?view=net-8.0 from the cross-reference map; unlinked: Microsoft.IO.RecyclableMemoryStreamManager pinned by src/packages.lock.json despite the three duplicate pins; note: the map documents Microsoft.Extensions.Logging.ILogger, but not at the version pinned.Evidence: Engine protocol drive C: 65 library APIs used against the 60-API cap
Source: Engine protocol drive C: 65 library APIs used against the 60-API cap (local file:
~/.no-mistakes/evidence/01M4BESXE1D0DCDHJQXKTT6P8E/run-c-cap-note.json)Evidence: Engine protocol drive D (adversarial): pinned 22.2.0, only the stable inventory (26.1) exists
links: 0; unlinked: attrs.field; note: 'attrs 22.2.0: no Sphinx inventory under https://www.attrs.org/ documents 22.2.0; https://www.attrs.org/en/stable/objects.inv documents 26.1'Evidence: Full review result as the engine answered it over the protocol (version 18, docLinks present)
Pipeline
Updates from git push no-mistakes
✅ **intent** - passed
✅ No issues found.
✅ **Rebase** - passed
✅ No issues found.
🔧 **Review** - 2 issues found → auto-fixed ✅
packages/engine/src/doc-links.ts:348- The fallback that attributes an unmapped C# type to 'the one pinned package a using names' requires exactly one (using, pin) holder, butnugetPinsreturns the same package more than once in common setups:lockPins(packages/engine/src/nuget-fetch.ts:62-77) emits one pin per target framework in a multi-target packages.lock.json, and a lock file plus the project file that generated it (standard NuGet lock-file mode) each add a pin for the same package at the same version. Concrete sequence: head copy haspackages.lock.jsonlistingMicrosoft.IO.RecyclableMemoryStream 3.0.1andsrc/BlobTool.csprojwith<PackageReference Include="Microsoft.IO.RecyclableMemoryStream" Version="3.0.1" />; an added line underusing Microsoft.IO;writesnew RecyclableMemoryStreamManager(); the type is not in the .NET cross-reference map, so the holders branch runs,pins.filtermatches both pins for the same using,holders.length === 2, and the type is skipped — no link, nounlinkedentry, no note, and the agent is never asked, so the API vanishes from the Documentation section and the hover even though the canary case (project-only pin) shows it works there. Remedy: dedupe the matched holders by package id + version before the uniqueness check (keep skipping when two genuinely different packages or versions match); the sibling consumer of the same pins,pins.findinsidelink()at packages/engine/src/doc-links.ts:322, already tolerates duplicates by taking the first, so only this site needs the fix.packages/engine/src/doc-links.ts:414- Beyond MAX_APIS (60), inventory links and unlinked APIs are silently dropped (links.slice(0, MAX_APIS),unlinked.slice(0, ...)at lines 414-415) with no note, while the per-library notes still say the Sphinx inventory was read; a reviewer hovering a dropped API on the head side gets nothing and no explanation. The cap itself is a reasonable bound; this only records the tradeoff that truncation is invisible in the result.🔧 Fix applied.
✅ Re-checked - no issues remain.
✅ **Test** - passed
✅ No issues found.
npx vitest run packages/engine/test/doc-inventory.test.ts packages/engine/test/doc-fetch.test.ts packages/engine/test/doc-links.test.ts — 88 tests: Sphinx objects.inv and .NET xrefmap parsing, version matching, fetch guards, findDocLinks for both languages, the multi-target lock-plus-project pin-holder test and the MAX_APIS left-out note testnpx vitest run packages/engine/test/review.test.ts packages/engine/test/server.test.ts packages/engine/test/cli.test.ts — 74 tests: the doc-links stage through reviewPullRequest and the RPC server, protocol version 18npx vitest run packages/extension/test/doc-hover.test.ts packages/evaluation/test/run.test.ts packages/evaluation/test/score.test.ts — 83 tests: hover links and labels, panel section, protocol acceptance and ordering rejection, and the doc-links evaluation wiring with its cases and scoresnpm run build && node tmp-validation/drive-rpc.mjs — four live JSON-RPC drives of the built engine's runRpcServer (the serve command's loop) against disposable fixture pull requests with recorded inventories served through the engine's own fetch seam and a scripted agent at its adapter seam: run A Python inventory+agent, run B C# xrefmap+deduped pins, run C cap note, run D wrong-version inventory refusednode --import ./tmp-validation/register.mjs tmp-validation/render-panel.mjs — the extension's isReviewResult accepted the engine's protocol answer (JSON round trip), overviewHtml rendered the Documentation section from it, doc-hover rendered both hoversgrep for doc-links-on-site/doc-links-checked in packages/evaluation/baseline.json — the prompt's score rows and prompt version 1 are recorded in the baseline✅ **Document** - passed
✅ No issues found.
✅ **Lint** - passed
✅ No issues found.
✅ **Push** - passed
✅ No issues found.