Skip to content

docs(contract): define the v1 artifact — kb-docs.tar.gz and kb-docs.json - #80

Merged
oto-macenauer-absa merged 1 commit into
chore/kb-identifier-renamefrom
chore/kb-docs-contract
Sep 4, 2026
Merged

docs(contract): define the v1 artifact — kb-docs.tar.gz and kb-docs.json#80
oto-macenauer-absa merged 1 commit into
chore/kb-identifier-renamefrom
chore/kb-docs-contract

Conversation

@oto-macenauer-absa

Copy link
Copy Markdown
Collaborator

Closes #74. Part of #73.

Stacked on #79 (chore/kb-identifier-rename). Review that one first; this PR's base is that branch, so the diff shown here is only the contract change.

The shape

Two artifact shapes become one. Packaged sites shipped dist.tar.gz containing dist/ plus a root marketplace.json describing one app. Single-page bundles shipped dist.tar.gz containing bundle.json plus one directory per doc, describing many. dist.tar.gz is also indistinguishable from a repo's own distribution package, which a release usually carries alongside.

kb-docs.tar.gz
├─ kb-docs.json
├─ <slug-a>/
│  ├─ index.html          ← entryPoint
│  └─ assets/…
└─ <slug-b>/              ← only a bundle publishing several apps has more than one

A documentation site is a manifest listing one app. A set of markdown docs is a manifest listing several. Nothing downstream has to tell them apart, which is what lets #75 collapse two install paths into one.

What's here

File
contract/ARTIFACT.md New. Normative: layout, manifest, archive rules, versioning, size budget, registration
contract/kb-docs.schema.json New. Draft-07, $id at its raw GitHub URL so the actions and this build validate the same document
tests/contract.spec.js New. 30 assertions pinning what the schema accepts and rejects
contract/schema.json Deleted. Described the old single-app manifest
HEADLESS_RULES.md, SINGLE_PAGE.md Rewritten around the unified manifest
README.md, CLAUDE.md Contract-facing sections updated

Two deliberate choices in the schema

Forgiving about the future. kbVersion is a string, so the contract can reach "1.1" or "2" without changing type, and unknown fields are ignored rather than rejected — an additive change never breaks an older knowledge base.

Strict about paths. entryPoint and pages[].path are pattern-constrained against .. and leading /. The archive is unpacked into a directory this deployment then serves, so a manifest must not be able to point outside the app's own tree. artifact-safety.spec.js already guards the tarball members; this closes the same hole one level up, in the manifest that names them.

A budget that was never written down

20 MB target, warned above that, refused above 100 MB, which is also GitHub's per-asset release limit. Every registered artifact is downloaded on every deployment build, so artifact size is a shared cost rather than a private one. Enforcement lands with the fetch path in #75; this PR is where the number is agreed.

validate-doc-app.yml is now a loud deprecation

It validated marketplace.json against the schema this PR deletes, and it assumed npm run build -- --headless, which the Python example repo cannot run — so it was already not what any real doc repo used. Rather than half-migrating a workflow that #76 removes, it now fails with the replacement in both the error and the step summary. A green check against a contract that no longer exists is worse than no check.

Verification

Suite Result
npm test (embedded, now including the contract spec) 115 passed
playwright.config.ci.js (standalone) 22 passed

Contract-only: no build code changes, so the build still reads the old layout and CI stays green. The docs describing that layout move with it in #75.

Two forward references are deliberate. HEADLESS_RULES.md and README.md show actions/publish-docs@v1, which #76 creates; SINGLE_PAGE.md still pins the existing action at @master until the same PR cuts the tag.

🤖 Generated with Claude Code

https://claude.ai/code/session_01PYtmxSeSXFg4wEXRcKCmAi

The artifact contract had grown two shapes and a misleading name. Packaged
sites shipped dist.tar.gz containing dist/ plus a root marketplace.json
describing one app; single-page bundles shipped dist.tar.gz containing
bundle.json plus one directory per doc, describing many. dist.tar.gz is also
indistinguishable from a repo's own distribution package, which a release
usually carries alongside.

This defines one shape for both. kb-docs.tar.gz holds kb-docs.json at its root
plus one directory per app. A documentation site is a manifest listing one app;
a set of markdown docs is a manifest listing several. Nothing downstream has to
tell them apart.

New:

  contract/ARTIFACT.md          normative: layout, manifest, archive rules,
                                versioning, size budget, registration
  contract/kb-docs.schema.json  draft-07 schema, $id at its raw GitHub URL so
                                the actions and this build validate the same
                                document
  tests/contract.spec.js        30 assertions pinning what the schema accepts
                                and rejects

Removed contract/schema.json, which described the old single-app manifest.

Two things the schema is deliberate about. kbVersion is a string, so the
contract can reach "1.1" or "2" without changing type, and unknown fields are
ignored rather than rejected so an additive change never breaks an older
knowledge base. Conversely entryPoint and pages[].path are pattern-constrained
against traversal and absolute paths: the archive is unpacked into a directory
this deployment then serves, so a manifest must not be able to point outside
the app's own tree.

The size budget is new and was previously unstated: 20 MB target, warned above
that, refused above 100 MB, which is also GitHub's per-asset limit. Every
registered artifact is downloaded on every deployment build, so it is a shared
cost rather than a private one.

validate-doc-app.yml is now a loud deprecation. It validated marketplace.json
against a schema this commit deletes, and it assumed `npm run build --headless`,
which the Python example repo cannot run. Rather than half-migrating a workflow
that #76 removes, it fails with the replacement in the message and the step
summary — a green check against a contract that no longer exists is worse than
no check.

Contract-only. No build code changes, so the build still reads the old layout
until #75 lands. The docs describing that layout move with it.

Part of #73. Closes #74.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PYtmxSeSXFg4wEXRcKCmAi
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.

Contract v1: rename dist.tar.gz to kb-docs.tar.gz and unify marketplace.json + bundle.json into kb-docs.json

1 participant