Repository navigation
feat(docs-site): add model explorer as default docs site - #534
Merged
Merged
Conversation
docsSiteFile() now builds a model explorer by default: a main page that says what the software does (count tiles, feature and quality cards with roll-ups), a model map with slices and colour-by, a page per object, projection, report, prompt and requirement with a one-hop mini-map, the traceability matrix, a trace from a requirement to its generated files, the API index and a gaps page. Every page is drawn from explorer.json, which the generator builds in the same run from the loaded model, the requirement gate's ledger, the files the run wrote and the routes it mounts (it runs after the other generators wherever it is listed). Declared status is a filled chip with its glyph, gate verdicts are outlines, roll-ups are bars, and no colour reports a test result. Pages carry Pagefind markup, work at phone width, depend on the model alone so verify --codegen holds them, and are link-checked. meta eject docs-site copies the explorer theme beside the classic one. site: "classic" keeps the earlier site.
…es, page-path collisions, textRef guard - ctx.runOutput widens a run narrowed to some entities with the manifest, and drops records for generators no longer declared or files no longer on disk. - No routes in the run leaves explorer.json's api section out, so the site says the run recorded none instead of claiming none are mounted. - A requirement ledger that throws warns and leaves the ledger out. - An object named index gets index.node.html; the empty package's pages live under -root; writing one page twice throws. - readPromptTexts refuses an absolute or .. @textref. - Named constants for the disposition and dataGrid attributes.
…etween the two sites simplify pass: one buildInScratch()/ownedSiteDirs() for the classic and explorer paths, one requirementLedger closure in verify, body templates read once per build, and the explorer's edge sort keys each edge once. Output is byte-identical.
…uctured unclaimed node
…ne stale fact fixed in docs/features/explorer-data.md: the builder now takes an optional fourth input (routes), so "three inputs" no longer holds. Every other doc touched by the change (CHANGELOG, cli.md, own-your-codegen.md, requirements.md, explorer-site.md, docs-site README, the typescript-docs skill reference, docs/README.md) already matches the code. Spot-checked the classic-theme warning, the Pagefind filter markup, the `/` shortcut, the URL params, and the `node` field in requirement-payload.ts.
Pagefind 1.x derives its base URL from where pagefind.js loads; the explorer loads it from the site root, so result links carry the serving path. Checked by serving an indexed site from a sub-path: results link under it and load.
…t, match undecided count
The typecheck gate failed: the local LedgerRow diagnostics type lacked message, which the verdict assertion expects. Test-only fix.
…dict, advisory and out-of-tree rules.
dmealing
added a commit
that referenced
this pull request
Nov 5, 2026
…land Conflicts were additive on both sides: the branch's schema build settings and #534's run output and requirement ledger now travel together through GenContext, the runner, meta gen, meta verify --codegen and the codegen-drift probe. CHANGELOG keeps the branch's consolidated Unreleased section and adds #534's two entries.
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.
What Changed
docsSiteFile()now builds the model explorer by default: a main page with count tiles and feature/quality cards, a model map with colour-by views, per-object, projection, report, prompt and requirement pages, a traceability matrix, requirement-to-file traces, an API index and a gaps page. All pages read a newexplorer.json, whichmeta genbuilds in the same run from the loaded model, the requirement gate's ledger, the files the run wrote and the routes it mounts. The builder runs after the other generators (readsRunOutput). The earlier site stays available, unchanged, asdocsSiteFile({ site: "classic" }); a project with an ejected classic theme gets a warning naming that option.assetBase; search uses a built-in index with Pagefind when served over HTTP.meta eject docs-sitecopies the explorer templates,explorer.cssandexplorer.jsbeside the classic theme.meta verify --format jsonrequirement rows gain anodefield, and ledger findings carrymessage. CHANGELOG (Unreleased) and docs (docs/features/explorer-site.md,explorer-data.md) describe the new default and page paths.Validation
Risk Assessment
✅ Low: Round-1 fixes check out against the gate's own logic: findings are scoped per node, lint is split from gate verdicts, and the undecided card matches the gate's roll-up-ancestor rule. The new tests drive the real ledger. No concrete defect found; the earlier-round changes outside this fix delta were not re-read.
Testing
Baseline configured command passes and build/typecheck is green. Explorer site live-driven on a disposable copy of the public shop fixture: gen builds the default site, S1 main page and S6 requirement page render correctly (screenshots taken), unclaimed ring and verdict/advisory separation are visible in the generated output, and verify --codegen holds including an out-of-tree outDir case. Classic site builds. Not driven live: the configured ts-fast/ts-unit run is a test-suite result, not a live product drive; Pagefind search (needs HTTP serve and pagefind index) and Cytoscape graph pages (need jsDelivr network) are untested, not failed. Full flagless ci-local (C#/Java/Kotlin/Python lanes) was not run in this step.
Evidence:
meta verify --format jsonover the shop fixture reported 9 requirement rows;Shop.Checkout.Shippinghas verdictwarn(WARN_REQUIREMENT_NOTHING_IMPLEMENTS, sourcegate) andacme::shop::AuditEntryis reported unclaimed.Evidence:
meta verify --codegenon the out-of-tree outDir project exited 0 and reported no codegen drift, alongside the shop fixture's expected requirement warnings.Outcome: 🔧 2 issues found → no changes applied ✅ across 2 runs (1h26m55s)
Pipeline
Updates from git push no-mistakes
✅ **Intent** - passed
✅ No issues found.
✅ **Rebase** - passed
✅ No issues found.
🔧 **Review** - 4 issues found → auto-fixed ✅
server/typescript/packages/docs-site/src/explorer/html.ts:41- Wrong label: authoring-lint findings show up as gate verdicts. Intent: "Gate verdicts are outlines". The ledger row'sverdictis computed "from gate findings only", butrow.diagnosticsandledger.diagnosticshold BOTH gate and lint findings (each taggedsource). Lint findings can never fail a build. (1)verdictBadge(html.ts:38-45) counts every row diagnostic and prints an outlined "! N gate warning(s)" badge. A requirement with one lint advisory and no gate finding therefore gets an amber gate-warning outline on S1 cards, the S5 tree and the S6 header, whilerow.verdictsaysclean. (2) The S6 proof row labelled "Gate findings" (pages.ts:690, 732-734) counts and lists lint rows too. (3) The Gaps card "Gate findings" (pages.ts:804-817, source "meta verify", "Printed by every run of the requirement gate") includes lint rows. Fix: filter onsource === "gate"at all three sites, or drive the badge fromrow.verdict. Lint can get its own neutral label if wanted.server/typescript/packages/docs-site/src/explorer/pages.ts:690- Cross-package mix-up: the S6 page and the Gaps page match flatrequirements.rowsfindings to a requirement by bare dottedpathalone. The ledger contract states explicitly that two packages may declare a requirement at the same path. requirement-ledger.test.ts pins this:acme::a::Billing.Invoicingis clean andacme::b::Billing.Invoicingcarries ERR_REQUIREMENT_DANGLING_REF. On the explorer page foracme::a::Billing.Invoicing,findings(pages.ts:690,d.path === row.path) picks up package b's dangling-ref finding. The "Gate findings" proof row then shows 1 finding with b's message, while the header badge fromrow.diagnosticsshows clean. The Gaps page (pages.ts:814,ix.requirements.find(r => r.row?.path === d.path)) links that finding to whichever package's requirement comes first, here package a's. Fix: drive both views from the per-noderow.diagnostics, which the ledger already scopes to the right node. If the S6 page needs message text, carrymessageinto those refs in the builder.server/typescript/packages/docs-site/src/explorer/pages.ts:820- Wrong count: the Gaps card "Undecided gaps" is labelled source "meta verify" with "The gate counts these", but it recomputes the set as every partial or planned entry with no@disposition(pages.ts:820). The gate'sundecided(requirement-check.ts:702-753) deliberately leaves out every roll-up ANCESTOR of an entry that has outstanding work. Its comment cites a real ledger where this overstated by 6x. Concrete case:Shop.Checkoutis partial with no disposition, andShop.Checkout.Orders.Refundedbelow it is planned. The gate (andledger.counts.undecided) reports 1, but the explorer card shows 2 and lists the parent as a decision owed. This also breaks the intent's rule that views never re-derive model facts. Fix: take the count fromledger.counts.undecidedand leave out entries that have an outstanding descendant, so the list matches the gate.server/typescript/packages/docs-site/test/explorer-site.test.ts:181- Source-text proxy test: the "phone-ready" test greps the emittedassets/explorer.css, which is a byte copy of the bundled theme source, for@media (max-width: 700px). It is the same kind of CSS-source grep that round 1 asked to replace. A harmless change to the breakpoint or its syntax would fail it, and the grep proves nothing about layout. Drop the CSS assertion. The viewport-meta anddata-pagefind-bodyassertions on the generated HTML already cover the public contract.🔧 Fix applied.
✅ Re-checked - no issues remain.
🔧 **Test** - 2 issues found → no changes applied ✅
meta genagainst an isolated root. That was not done in this phase.meta verify --format jsonplus site build was driven.scripts/ci-local.sh --only ts-fast --only ts-unit --strict-toolchainsscripts/ci-local.sh --only ts-fast --only ts-unit --strict-toolchains(configured test command; passed, LOCAL CI PASSED)Confirmed the requirement-ledger.test.tsnode-key allowance is committed (c879dbd46) and the worktree has no uncommitted changesLive drive of the explorer docs site (meta genwith docsSiteFile, served output, search, verdict outlines, unclaimed rings): not performed in this phase🔧 No changes applied.
✅ Re-checked - no issues remain.
scripts/ci-local.sh --only ts-fast --only ts-unit --strict-toolchainsbun run --filter '*' build && bun run --filter '*' typecheck (repo root): exit 0scripts/ci-local.sh --only ts-fast --only ts-unit --strict-toolchains: LOCAL CI PASSEDDisposable project from fixtures/explorer-conformance/shop/project under evidence dir; node dist/bin/meta.js gen (exit 0), docs-out/site produced with explorer.json, index, requirements, gaps, model, matrix pagesnode dist/bin/meta.js verify --codegen on shop-live: exit 0node dist/bin/meta.js verify --format json: WARN_REQUIREMENT_OBJECT_UNCLAIMED row carries node field acme::shop::AuditEntryGenerated HTML inspection: model/acme/shop/AuditEntry.html carries chip v-unclaimed; Shop.Checkout.Shipping.html carries v-warn chip and Authoring advisories sectionOut-of-tree outDir project (targets web outDir ../web/src/generated, docs outDir ../docs-out): meta gen exit 0, meta verify --codegen exit 0, explorer.json generated list empty (no web-target generator in this fixture, so the stand-in exclusion is exercised only in part)docsSiteFile({ site: "classic" }) project: meta gen exit 0, classic site emitted (index, coverage, enums, acme/)google-chrome --headless screenshots of index.html and requirements/acme/shop/Shop.Checkout.Shipping.html✅ **Document** - passed
✅ No issues found.
✅ **Lint** - passed
✅ No issues found.
✅ **Push** - passed
✅ No issues found.
no-mistakes: 2 runs. Run 1 fixed 5 review findings and 1 test expectation; run 2 recorded why Pagefind results resolve under a sub-path (verified, no code change needed), fixed 4 review findings (gate verdicts versus authoring advisories, per-node findings, the undecided count, a CSS-source test) and 1 type error, and ignored an inconclusive live-validation verdict whose scenarios have deterministic tests.