# Cedros Extension Authoring

This folder is the complete guide to building **Cedros extensions**. A Cedros
extension is one installable, operator-reviewed package family — a sandboxed
WebAssembly server backend, a React admin/web package, and a React Native
package under one stable `extensionId` — that adds behavior to a Cedros site:
server APIs and jobs, admin pages and dashboard cards, public blocks and
pages, data models, AI tools, and integrations.

The guide assumes **zero prior knowledge of Cedros**. Someone who has never
seen the platform can start at `00`, walk forward in order, and end with a
valid, packaged, installable extension. Every contract described here is
grounded in the Cedros Data host implementation, vendored WIT contracts, and
host-provided browser runtime modules. Where behavior is enforced by code, the
docs say where.

The stable public orientation is
`/skills/cedros-extension-authoring.md`, linked directly from `/skill.md`.
The complete version-matched guide is publicly browsable below
`/authoring/<host-version>/extension/docs/extension-authoring/`, and the same
files, examples, validation scripts, WIT, and checksums are downloadable at
`/authoring/<host-version>/extension/kit.zip` for every retained release.
`/authoring/latest/extension/` is a mutable alias that serves the kit built
from the running host's own tree (the version in `server/Cargo.toml`), so it
always matches the deployed release. Current tool schemas and permissions
remain in the authenticated MCP registry.

`MUST`, `MUST NOT`, `SHOULD`, `SHOULD NOT`, and `MAY` are normative. Prose
outside an explicitly labeled rule, schema, runtime contract, integration
contract, validation step, or example is rationale and cannot create a Cedros
capability.

## Reading paths

- **Never seen Cedros before?** Read `00` → `01` → `02` in order — platform
  primer, system mental model, then a working installed extension in minutes —
  and keep going with `03`.
- **Building a specific surface?** Orient with `01`, plan with `03`, then jump
  to the surface doc (`07`–`21`) and keep the references (`04`–`06`) open
  while you write fields and code.
- **Server backend work?** `07` is canonical for everything the wasm runtime
  can do; `08`–`11` cover data, state, providers, and jobs on top of it.
- **Shipping?** `22` (package + upload) → `23` (release, versioning,
  rollback), with `24` as the assembled example and `25` when something
  misbehaves.
- **Integrating with Cedros products (Login, Pay, Balance, Shop, …)?** `18`–`20`, then
  the product-specific contracts in [`contracts/`](contracts/README.md).
  Standard customer-facing Login/Pay consumers use the published session,
  user-context, JWKS, and buyer-authenticated routes; they do not configure
  static Login or Pay service credentials.
- **Shipping admin UI?** The admin design standard,
  [`/design-admin.md`](../../design-admin.md) ("Workbench"), is the visual,
  motion, and voice source of truth — its §11 is the extension author
  contract. `12` covers the wiring and
  [`reference/admin-ui-patterns.md`](reference/admin-ui-patterns.md) the class
  + accessibility catalog. Use
  [`reference/admin-notifications.md`](reference/admin-notifications.md) for
  the host-owned toast API and the toast-vs-inline decision contract.

## Task-mode routing

Route by work type before selecting a surface. `/skill.json` contains the
normative ordered document IDs and conditional additions for all eight modes:
create, convert, audit/repair, add a released feature, complete product/UX,
prepare release, upgrade/rollback, and operate a live site. Operator mode starts
at `/skills/admin-site-operator.md` and skips this corpus unless an extension
artifact or platform contract changes.

For an existing repository, inventory first and preserve product intent,
stable IDs, migrations, data ownership, and compliant architecture. Add
`07-wasm-server-backends.md` and the WIT only when a Wasm component, route,
job, SEO export, or host import exists.

## Authority and precedence

1. Published machine-readable schemas and WIT contracts.
2. Published SDK exports and signatures.
3. Version-matched canonical references in this kit.
4. Surface-specific prompts.
5. Official examples.
6. Existing repository conventions.
7. Agent assumptions, which are never authoritative.

If same-level sources conflict, stop the affected work, preserve safe completed
work, and emit the structured blocked report from `/skill.md`. Never guess.
Stable normative IDs and verification methods are published in
[`reference/rules.json`](reference/rules.json).

## Declaration and runtime consequence

| Declaration | What it does | What it does not do |
|---|---|---|
| Route/job/module/block/skill/capability metadata | Registers reviewable identity and alignment metadata. | It does not compile, export, bind, or execute implementation. |
| A requested permission or provider/database access row | Requests an operator-reviewable grant. | It does not bypass runtime identity, authorization, scope, or dependency checks. |
| An extension dependency | Declares install/enable compatibility and a possible published seam. | It does not expose private modules, routes, tables, or credentials. |
| A setup seed | Declares idempotent initial intent for an owning product. | It does not imply an unpublished product write contract exists. |
| A schedule | Binds cadence to a declared job ID. | It does not register or implement the Wasm job. |

This redundancy is intentional: metadata never implies executable behavior
(`CED-AUTH-002`).

## Mechanical verification

Use `node scripts/cedros-authoring.mjs validate --repo . --json` for the
canonical aggregate check, or its focused `resolve-path`, `validate-context`,
`validate-manifest`, `validate-package`, `check-runtime-alignment`, and
`check-doc-consistency` commands. Exit `0` is pass, `1` is a contract failure,
and `2` is invalid invocation or unreadable input.

Audit rows use
`rule_id | applicability | status | evidence | issue | required_fix | verification`.
Prove stable IDs against prior manifests/migrations, permissions against used
capabilities, private-API avoidance against imports, Wasm compatibility with
the canonical build and WIT hash, and secret safety against source/package
scans plus canonical secret API usage.

Documentation evals live under `evals/`. Capture one independently assessed
JSONL row per case and repeat (`run`) with `id`, selected `mode`, loaded
`documents`, activation/entrypoint evidence for routing, or `ruleIds` plus
assessor-measured `metrics` for execution. Execution metrics include
`tokenUse` and `unnecessaryQuestions`; they are evaluator observations, never
the subject agent's self-report. Score and compare matched runs with:

```text
node scripts/cedros-authoring.mjs evaluate-routing routing-responses.jsonl --model <model> --variant with-skill --json
node scripts/cedros-authoring.mjs evaluate-execution execution-responses.jsonl --model <model> --variant without-skill --json
node scripts/cedros-authoring.mjs compare-evals without-skill-report.json with-skill-report.json --json
```

Run both variants with the same model, prompts, split, and repetition count.
The scorer fails on missing cases, unknown cases, rule/metric mismatches, or a
correctness regression (`EVAL-ROUTING-001`, `EVAL-EXECUTION-001`,
`EVAL-COMPARISON-001`).

The shared phase handoff is `extension-context.json`, validated by
[`schemas/extension-context.schema.json`](schemas/extension-context.schema.json).
Every phase updates the same file; unresolved questions, conflicts, evidence,
and provenance cannot be silently discarded. The canonical manifest schema is
[`schemas/extension-manifest.schema.json`](schemas/extension-manifest.schema.json);
this Markdown explains it and does not define a second field implementation.

Every HTTP-served corpus document exposes its document ID, documentation
version, compatible platform API, source commit, stability, `ETag`, and
`Last-Modified` in response headers. `AUTHORING-KIT.json` publishes the same
release identity plus every file hash and one content-set hash.

## The documents

Orientation:

| # | Document | What it covers |
| --- | --- | --- |
| 00 | [`00-cedros-platform-primer.md`](./00-cedros-platform-primer.md) | What Cedros is, how sites/pages/admin work, where extensions fit, trust model, glossary. |
| 01 | [`01-extension-system-overview.md`](./01-extension-system-overview.md) | The mental model: package family, runtimes, capability grants, lifecycle, self-serve vs metadata-first vs host-coordinated, id rules, the full surface matrix. |
| 02 | [`02-quickstart.md`](./02-quickstart.md) | Hands-on: build/validate/package the minimal example, install it, add a wasm route, curl it. |
| 03 | [`03-planning-an-extension.md`](./03-planning-an-extension.md) | Feature brief (greenfield) or code audit (existing project) → surface plan, dependency table, implementation mode. |

Contracts and references (keep open while implementing):

| # | Document | What it covers |
| --- | --- | --- |
| 04 | [`04-manifest-reference.md`](./04-manifest-reference.md) | Field-level source of truth for every manifest field, validation behavior, and invalid examples. |
| 05 | [`05-package-family-and-registration.md`](./05-package-family-and-registration.md) | The three package members: files, exports, bootstrap generation, alignment checks, smoke loop. |
| 06 | [`06-runtime-sdk-reference.md`](./06-runtime-sdk-reference.md) | Runtime contracts: vendored WIT, AdminModule, host services, ZIP loader rules, and virtual modules. |

Server backend:

| # | Document | What it covers |
| --- | --- | --- |
| 07 | [`07-wasm-server-backends.md`](./07-wasm-server-backends.md) | **Canonical.** The WIT worlds, every capability seam, routes, context envelope, limits, lifecycle, SEO export. |
| 08 | [`08-site-database.md`](./08-site-database.md) | `databaseAccess[]`, content models, the operation contract, filters/pagination, isolation, migrations. |
| 09 | [`09-settings-secrets-and-state.md`](./09-settings-secrets-and-state.md) | Settings, encrypted secrets, onboarding completion, runtime state ownership, storage decision table. |
| 10 | [`10-host-providers.md`](./10-host-providers.md) | Site-owned storage/AI/voice/email/blockchain providers: scopes, operation contracts, error codes. |
| 11 | [`11-jobs-and-scheduling.md`](./11-jobs-and-scheduling.md) | Job exports, `jobSchedules[]`, cron/concurrency rules, the no-automatic-retry model. |

Admin, public, and content surfaces:

| # | Document | What it covers |
| --- | --- | --- |
| 12 | [`12-admin-pages-and-dashboard-cards.md`](./12-admin-pages-and-dashboard-cards.md) | AdminModule sections, groups, gating, dashboard cards, admin styling and `--cd-*` tokens. |
| 13 | [`13-public-pages-and-seo.md`](./13-public-pages-and-seo.md) | Page seeds, chrome modes, the executable SEO contract, `seoRoutes[]`, the dynamic-SEO wasm seam. |
| 14 | [`14-blocks-templates-and-styling.md`](./14-blocks-templates-and-styling.md) | Visual-builder blocks/templates, the public block runtime contract, theme tokens, CSS delivery, parity. |
| 15 | [`15-content-starters-and-onboarding.md`](./15-content-starters-and-onboarding.md) | Form/policy starters, extension docs drafts, and onboarding steps. |
| 16 | [`16-analytics-and-site-brain.md`](./16-analytics-and-site-brain.md) | Analytics events, durable site-brain records, structured logs, channel choice, redaction. |
| 17 | [`17-ai-skills-and-capabilities.md`](./17-ai-skills-and-capabilities.md) | AI skill discovery and executable capabilities with endpoint mapping and schema rules. |

Integration:

| # | Document | What it covers |
| --- | --- | --- |
| 18 | [`18-official-extension-integrations.md`](./18-official-extension-integrations.md) | The official contract registry: Login, Pay, Balance, Scheduling, Shop, Notifications, Contracts, Email, Wallet, Compliance, including Compliance KYC self-service. |
| 19 | [`19-composability-and-relying-party-contracts.md`](./19-composability-and-relying-party-contracts.md) | Publishing/consuming extension contracts; credential-free customer-facing Login/Pay routes; Balance capability-gated provider routes; JWKS/introspection/user-directory patterns for explicitly declared contracts. |
| 20 | [`20-crm-tags-and-source-events.md`](./20-crm-tags-and-source-events.md) | CRM customer tags (assign/unassign/read, lifecycle, attribution) and CRM source events. |
| 21 | [`21-host-coordination-and-native.md`](./21-host-coordination-and-native.md) | What still needs host work: handoff rows/status vocabulary, sidecars, native surfaces. |

Shipping:

| # | Document | What it covers |
| --- | --- | --- |
| 22 | [`22-packaging-and-upload.md`](./22-packaging-and-upload.md) | The ZIP contract, intake endpoints and limits, packaging script, upload flow. |
| 23 | [`23-release-versioning-and-upgrades.md`](./23-release-versioning-and-upgrades.md) | Release packet, readiness/smoke checklists, stable-id semver, upgrade/rollback safety. |
| 24 | [`24-worked-example.md`](./24-worked-example.md) | A compact complete extension assembled end to end. |
| 25 | [`25-troubleshooting-and-faq.md`](./25-troubleshooting-and-faq.md) | Symptom → cause → fix for install, loading, rendering, routing, and runtime; FAQ. |

Reference and product contracts:

- [`reference/host-wire-contracts.md`](./reference/host-wire-contracts.md) —
  per-seam wire-level JSON quick reference (a digest; the owning docs above
  stay authoritative).
- [`reference/admin-ui-patterns.md`](./reference/admin-ui-patterns.md) — the
  reusable admin UI class + accessibility contract (cards, tables, tabs,
  dialogs, pills, …).
- [`reference/admin-notifications.md`](./reference/admin-notifications.md) —
  the public admin toast API, notification decision table, examples, release
  checks, and a copy/paste migration prompt for coding agents.
- [`reference/conditional-operations.json`](./reference/conditional-operations.json)
  — machine-readable published conditional-operation ids, capabilities,
  minimum host versions, access/scopes/models, schemas, and compatibility
  status. Published rows are immutable. It lists the published operations, not
  every operation the host registers. The legacy Pay
  `extension.configuration.compare-and-set` row names
  `cedros-data:extension-config-cas-v1`, but the host does not require that
  capability from Pay for this operation (the admin health report shows
  `requiredCapability: null`); Pay `status` and every non-Pay configuration
  grant do require it.
- [`contracts/`](./contracts/README.md) — product-specific integration
  contracts and launch handoffs (Balance, Pay-adjacent surfaces,
  Wallet/Compliance, Casino operational-wallet/notification seams, Shop/Core
  commerce, affiliates, Stream Assistant). Read only when that product is in
  scope.
- `examples/` — [`examples/minimal-extension`](./examples/minimal-extension/)
  (runnable package-family floor), [`examples/full-extension`](./examples/full-extension/)
  (broad manifest map; run `node scripts/validate-manifest.js` after editing),
  [`examples/extension-with-dependency`](./examples/extension-with-dependency/)
  (minimal dependency declaration),
  [`examples/extension-with-server-wasm`](./examples/extension-with-server-wasm/)
  (server-Wasm declaration and evidence boundary),
  [`examples/extension-with-admin-ui`](./examples/extension-with-admin-ui/)
  (admin-module declaration), [`examples/invalid`](./examples/invalid/)
  (invalid patterns paired with supported mechanisms),
  and [`examples/cedros-login-auth-blocks.reference.css`](./examples/cedros-login-auth-blocks.reference.css)
  (token-driven block skin).
- `archive/` — historical launch artifacts. Not authoring inputs.

## The extension contract in one paragraph

One extension is one manifest (`schemaVersion: 1`, `platformApiVersion: "1"`)
plus one ZIP. The manifest declares identity, the three-member package family,
every surface, and every capability; the archive carries the compiled admin/web
ESM and the `cedros-extension.server.wasm` component that make those
declarations executable. The operator reviews and grants exactly what is
declared; the host enforces it — capability-gated wasm linking, scope-checked
calls, a restricted browser module loader, hot-swap lifecycle with no
restarts. Manifest metadata never executes by itself, ids are forever, and
everything fails closed.

## Authoring toolchain

Download the versioned **extension authoring kit** from
`/authoring/latest/extension/kit.zip` (or from the Admin Extension
builder) and unzip it at the target repository root. Start from its checked-in,
runnable minimal example:

```bash
cp -R cedros-extension-authoring-kit/docs/extension-authoring/examples/minimal-extension \
  ./my-extension
cd my-extension
npm ci
npm run validate
npm run package
```

Inside this repository, use
`docs/extension-authoring/examples/minimal-extension` directly. The copied
workspace owns its npm/Cargo validation and packaging loop; no Cedros registry
package is installed.

Rename the copied identity in the canonical manifest, the React and React
Native `package.json` files, and Cargo `[package].name`. Keep Cargo
`[lib].name` omitted so the library crate follows the renamed package
automatically; an explicit library name must equal the package name with
hyphens converted to underscores and must be the crate prefix in
`registration.server.entrypoint`. Regenerate `package-lock.json` after npm
package renames, then run `npm run sync:manifest`; that command rewrites the
bootstrap and package-local generated manifests from the canonical manifest.

Use Node.js `24.17.0` LTS with npm `11.13.0` for authoring, packaging,
validation, and release evidence (the examples and scaffold pin both). For
server backends, Rust with the `wasm32-wasip2` target. Bun, pnpm, Yarn, or
other local tooling may be used for private iteration only when the final
extension still passes the documented Node/npm validation gate; release
packets should record the versions that produced the submitted archive.

## Conventions used throughout

- **Do not invent manifest fields, SDK helpers, host services, or runtime
  behavior.** If it is not documented in `04`–`07` (or marked published in a
  surface doc), it is a host-coordinated handoff, not live behavior.
- **Ship compiled runtime in the ZIP; never rely on undeployed host loader
  behavior.** Self-inject CSS; verify against the packaged artifact, not the
  source tree.
- **Public blocks must be live, not just good-looking.** The first-paint shell
  and the browser-running component must be visually equivalent, and every
  advertised action must work on the real seeded route (`14`).
- **Fail closed** for missing providers, permissions, dependencies, settings,
  secrets, host hooks, or credentials required by an explicitly declared
  contract — with visible owner states. Do not invent a credential requirement
  for standard Login/Pay customer seams; follow `18` and `19`.
- **No secrets or PII** in manifests, archives, logs, analytics, site-brain
  records, job metadata, or starter content.

## Using these docs with an AI agent

Agent-driven authoring works well against this folder. Suggested prompt:

```text
We are authoring a Cedros extension.

Pass 1 (orient): read docs/extension-authoring/README.md, then 01 and 03.
Classify the extension's surfaces as self-serve, metadata-first,
host-coordinated, or out of scope, using the surface matrix in 01. Ask only
questions that block manifest correctness, security, data ownership, or host
binding.

Pass 2 (implement): read just the surface docs for the classified surfaces,
plus 04/05/06 as references while writing fields and code, 07 for any server
behavior, and 22/23 before packaging. Do not invent Cedros APIs, manifest
fields, SDK helpers, host services, paths, or runtime behavior — if a field or
seam is not published in these docs, document a host handoff and fail closed
instead.

Report before implementing: docs read, surfaces classified, blocking
questions. Carry the shared context object from 03 forward between sessions.
```

The `Next:` footer on each numbered doc walks the full sequence in order.
