Skip to content

docs: the Extending-the-canvas contract — how it loads, what's required, what you may reach (goal 0211) - #433

Merged
alicoding merged 1 commit into
mainfrom
goal-0211-extension-contract-page
Aug 25, 2026
Merged

docs: the Extending-the-canvas contract — how it loads, what's required, what you may reach (goal 0211)#433
alicoding merged 1 commit into
mainfrom
goal-0211-extension-contract-page

Conversation

@alicoding

Copy link
Copy Markdown
Owner

What

One reference page — userdocs/reference/extending-the-canvas.md — the goal 0211 slice 1 deliverable: "here is how you load it, what is required, and what platform API and services exist." Three sections plus a stability paragraph, exactly per the goal's Sharpened scope.

Generation mechanism

Go's internal/docsgen has no TypeScript parser, so extracting the "What is required" field table straight from AtlasToolShape's own .ts type was disproportionate. Chosen instead: a small committed JSON (frontend/src/atlas/atlasNounDeclarationFields.json) is the generation source docsgen.GenerateNounFieldTable reads to render the table into one marked region of the page (go generate ./internal/docsgen, freshness-checked by TestExtendingCanvasPage_NounFieldTableMatchesCommitted, mirroring the existing TestUserDocs_MatchCommitted shape). A satisfies Record<keyof AtlasToolShape, true>-checked literal inside atlasNounDeclarationFields.test.ts closes the other half of the freshness chain on the TypeScript side — the JSON's field set can never silently drift from the real registry type, because TypeScript's excess/missing-property checks only apply to a fresh object literal (not an imported JSON binding), so the check lives in that literal, and a vitest assertion compares the JSON's keys against it. The rest of the page (sections 1 and 3, the stability paragraph) is hand-authored prose, not claimed as generated.

Named-tax audit (the goal's teeth)

Found while writing section 3 against the actual code, all clustered around the shared atlas-object rendering path:

  1. diagram has no registered descriptor at all (no tools/diagramTool.ts, no identity entry) — the entry the goal named first.
  2. AtlasBoardObjectNode.tsx's content dispatch is an unregistered object.Kind if/else chain — the registry has no renderContent hook.
  3. Per-Kind aria-labels live in locales/en/atlas/shared.json, not each noun's own locale file — breaks the "each noun owns its own locale file" model section 1 documents.
  4. atlasBuildBoardObjectNodes.ts's OBJECT_Z_INDEX is a hand-maintained string-keyed table with a silent ?? 0 default for an omitted noun.
  5. Diagram's own dragBand/resizable gap, already partly documented in atlasNounRegistry.ts's own comments — same root cause as build(deps): Bump golang.org/x/oauth2 from 0.35.0 to 0.36.0 in the go-dependencies group #1.

Full detail appended to docs/goals/0211-extension-tiers.md's new "Named tax" section (committed separately to the nested docs repo, ahead of this PR). Deferred to a future 0211 slice, triggered by the first diagram-shaped noun or v1 planning — not built here.

What stays hand-authored

Sections 1 ("How it loads") and 3 ("What platform APIs exist / may not reach") plus the stability paragraph — reviewed prose, not generated, and the page says so nowhere implies otherwise. Only the field table in section 2 carries the generated-region markers and the doc-freshness promise.

Test plan

  • go test ./internal/docsgen/... — green, including the new freshness test
  • go generate ./internal/docsgen produces a byte-identical committed file
  • npx vitest run (targeted + full suite via lefthook) — green
  • npx tsc --noEmit, npm run boundaries (dependency-cruiser) — green
  • Full local lefthook pre-commit suite green (go-vet, golangci-lint, go-test, boundaries, file-loc-limit, comment-hygiene, vitest, tsc, eslint, docsgen-freshness)

🤖 Generated with Claude Code

https://claude.ai/code/session_012im1JxQQV2ahnXzZDdVmZq

…ed, what you may reach (goal 0211)

One reference page, userdocs/reference/extending-the-canvas.md: how a
canvas noun's tools/<id>Tool.ts loads (glob discovery + the
declaration-vs-code split, VS Code's contributes/API precedent named
directly), the AtlasToolShape field table (generated), the conformance
suite that IS the contract test, and which platform APIs a noun's
runtime code may use vs. what it may not reach — with the actual
enforcement (dependency-cruiser boundary, review-only, or "no RPC
exists to call") named per line rather than implying a sandbox
compiled-in TypeScript doesn't have.

Generation mechanism: Go docsgen has no TypeScript parser, so
extracting the field table straight from AtlasToolShape's own .ts type
was disproportionate. Instead: a small committed JSON
(atlasNounDeclarationFields.json) is the generation source docsgen
reads to render the table into one marked region of the page (go
generate ./internal/docsgen, freshness-checked by
TestExtendingCanvasPage_NounFieldTableMatchesCommitted); a `satisfies
Record<keyof AtlasToolShape, true>`-checked literal inside
atlasNounDeclarationFields.test.ts enforces on the TypeScript side that
the JSON's field set can never drift from the real registry type
(TypeScript's own excess/missing-property checks only apply to a fresh
literal, so the check lives in the test file, not on the JSON import
itself). The rest of the page is hand-authored prose, honestly not
claimed as generated.

Named-tax audit (goal 0211's own teeth): five places today's
board-object rendering path already reaches past the documented
surface, all clustered around AtlasBoardObjectNode.tsx/
atlasBuildBoardObjectNodes.ts/locales/en/atlas/shared.json --
diagram's missing registry entry, the unregistered object.Kind
if/else content dispatch, per-Kind aria-labels leaking into the shared
locale namespace, a hand-maintained z-order table with a silent
default, and diagram's own dragBand/resizable gap. Full detail and the
deferral (0211 slice 2, triggered by the first diagram-shaped noun or
v1 planning) recorded in docs/goals/0211-extension-tiers.md's new
"Named tax" section; SPEC.md §9.5 now points at the page.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012im1JxQQV2ahnXzZDdVmZq
@alicoding
alicoding enabled auto-merge (squash) August 25, 2026 06:53
@alicoding
alicoding merged commit ccf7d4e into main Aug 25, 2026
27 checks passed
@alicoding
alicoding deleted the goal-0211-extension-contract-page branch August 25, 2026 07:02
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.

1 participant