Skip to content

docs(generator): document data provenance and source-of-truth rules - #1111

Draft
teallarson wants to merge 6 commits into
chore/hardeningfrom
docs/generator-architecture
Draft

docs(generator): document data provenance and source-of-truth rules#1111
teallarson wants to merge 6 commits into
chore/hardeningfrom
docs/generator-architecture

Conversation

@teallarson

@teallarson teallarson commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

⚠️ On hold — do not merge. Superseded by #1112.

This PR's central claim — that the committed JSON is the system of record
for hand-authored prose, and that --force-regenerate discarding it is an
unfixed hazard — was fixed by #1112, which gives that prose a real home
in curation/ read via --custom-sections. The provenance table and
source-of-truth rules below describe the pre-fix architecture and are now
partly outdated (the prose warning in particular). This PR should be
rewritten against the shipped design (the planned S7), not landed as-is.
Original description preserved below for reference.


The provenance-docs slice (S7) of the docs-pipeline series. Base is chore/hardening (#1106); #1105 has since merged to main, so #1106 is the only PR still beneath this one. Documentation only; no code changes.


Why

ARCHITECTURE.md described the pipeline's shape but never said where any individual field comes from. Answering "why is this toolkit in the wrong sidebar section" or "where did this callout go" meant reading the generator end to end and then guessing. Three sources feed the same output file with very different durability guarantees, and nothing wrote that down.

What's here

A per-field provenance table — the main deliverable. For every field in the committed JSON: which of the four sources it came from, and what has to happen for it to change. Arcade Engine, the pinned design-system package, Anthropic, and hand-authoring are not interchangeable, and the table makes that legible at a glance.

A pipeline diagram in the repo's existing plain graph TD dialect. The dotted Artifact -.-> Merger edge is the point: the output directory is also an input.

Source-of-truth rules — five constraints that are true but invisible from any single file:

  • The committed JSON is the system of record for hand-authored prose. documentationChunks, customImports, and subPages have no upstream source. The nightly workflow does not pass --custom-sections, so they survive only through previous-output carry-forward. --force-regenerate and --overwrite-output both set the previous-output directory to undefined, which discards them — a side effect, not the documented intent of either flag. src/diff/previous-output.ts carries these three fields past a failed schema parse for the same reason, which is why that leniency should not be tidied away without giving prose another home first.
  • One schema, imported by both halvessrc/shared/toolkit-schemas.ts, validated on write by the generator and on read by the app (refactor: singular + enforced toolkit data contract #1105).
  • A design-system bump can move page URLs, because category + docsLink determine the path. An unrecognized category now throws rather than falling back (refactor: singular + enforced toolkit data contract #1105).
  • Toolkits are derived by grouping tools, not fetched as a list. /v1/tool_metadata_summary would give an authoritative list with per-toolkit counts; fetchToolkitsSummary implements it and nothing calls it.
  • Absence and corruption are different failures, now enforced on both halves.

Also records the skip-toolkits.txt / remove-toolkits.txt distinction (#1103), the cached loader (#1105), the placeholder-metadata behaviour and --require-complete (#1106), and the new src/shared/ modules.

Verification

Every claim was checked against this branch's tip rather than main, since the stack changes several of them. Specifically confirmed still true after all four PRs:

  • Both previousOutputDir assignments in src/cli/index.ts are unchanged, mergeCustomSectionsArrays is unchanged, src/diff/previous-output.ts is untouched by the stack (chore: turn on the checks that were inert #1106 edits only its test), and the workflow still omits --custom-sections — so the prose warning describes the post-stack system, not a problem already fixed.
  • fetchToolkitsSummary remains uncalled outside its own test.

Confirmed changed by the stack and written to match: normalizeCategory throws with the expected-values list, loadAllToolkitData is cache()-wrapped, app types are z.infer of the shared schemas, getDefaultMetadata forces isHidden: true and is tracked via usedDefaultMetadata.

Drops the note about the root layout reading request headers, which #1104 already superseded.

Not in scope

The prose hazard is documented here, not fixed. The fix — decoupling "regenerate LLM content" from "carry prose forward" so --force-regenerate stops discarding hand-authored content — belongs in data-merger.ts and cli/index.ts, both of which #1106 owns. Worth doing before the next --force-regenerate run.

🤖 Generated with Claude Code

@vercel

vercel Bot commented Aug 3, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
docs Ready Ready Preview Aug 4, 2026 3:39pm

Request Review

teallarson and others added 3 commits August 3, 2026 15:46
ARCHITECTURE.md described the pipeline but not where any individual field
comes from, so tracing a wrong category or a missing callout back to its
origin meant reading the generator end to end.

Adds a pipeline diagram, a per-field provenance table, and the constraints
that are not visible from any single file:

- The output directory is also an input. Hand-authored documentationChunks,
  customImports, and subPages have no upstream source and survive only
  through previous-output carry-forward, so --force-regenerate and
  --overwrite-output discard them as a side effect.
- src/shared/toolkit-schemas.ts is the one contract, validated on write by
  the generator and on read by the app.
- metadata.category and docsLink come from a pinned design-system
  dependency and determine the page URL, making a version bump a routing
  change. An unrecognized category throws rather than falling back.
- Toolkits are derived by grouping tools, not fetched as a list.
- Absence and corruption are different failures, enforced on both halves.

Also records the skip-toolkits/remove-toolkits distinction, the cached
loader, and the shared modules under src/shared/.

Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
…lve-pr-1111

# Conflicts:
#	tests/toolkit-data-cache.test.ts
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