# Complete and ship the remaining mod-cms program

## Outcome

Finish the checkpointed content-model program, land and release it, then finish and release Posts-list parity, then reconcile and graduate the standalone multi-host distribution. Completion means the expected packages are publicly resolvable, the canonical `apps/mod-cms` deployment is armed and live-verified, `platform-modules/mod-cms` is generated from a pinned canonical commit, and fresh Cloudflare, Vercel, and Node/Docker installs pass real acceptance.

## Sources of truth and fixed facts

Read these before each affected phase, in this order:

1. `docs/specs/2026-08-08-content-types-complete-design.md`
2. `docs/specs/2026-08-08-fields-complete-design.md`
3. `docs/specs/2026-08-08-mod-cms-content-model-completion-design.md`
4. `docs/plans/2026-08-08-mod-cms-content-model-completion.md`
5. `docs/specs/2026-08-08-mod-cms-posts-list-parity-design.md`
6. `docs/plans/2026-08-08-mod-cms-posts-list-parity.md`
7. `docs/specs/2026-06-18-mod-cms-onboarding-install-design.md` and `docs/plans/2026-06-18-mod-cms-distro-graduation.md` from the distro worktree, reconciled onto the final branch
8. `docs/standards/coding-standard.md`, `docs/standards/authz.md`, `docs/standards/ui-api-conventions.md`, and `docs/standards/ui-liveness-and-a11y.md`

Repository facts:

- Canonical product source is this repository's `apps/mod-cms`. Never read from, write to, or sync from `../mod-cms`.
- Current branch is based on `origin/main` at `d132d81d` and intentionally preserves completed Task 1 commit `33e7a1ba` plus unfinished Task 17 checkpoint `4dc55149`. Do not squash away or replace `33e7a1ba`.
- The separate distro worktree `/home/user/Projects/platform/.worktrees/mod-cms-distro-graduation` contains valuable committed work in `16059e4a` and `c8332bda` plus a large dirty/untracked continuation. It is two commits ahead and two behind its `origin/main`; preserve and reconcile it, never overwrite it.
- Use Node 22 and the repository's pnpm version. Call tools by bare name. Browser/dev-server work must run through `~/.claude/bin/e2e-remote`. Never run a local raw `wrangler deploy`; Cloudflare publication belongs in GitHub Delivery.
- All implementation tasks use `gpt-5.6-terra/high` coders. After every stable task diff, run an independent `gpt-5.6-sol/low` review against the relevant boundary/program specs and standards. Fix every P1/P2 and repeat review before unlocking dependents.
- Work in isolated worktrees, keep task commits reviewable, and land Platform changes by PR only. Reuse a valid same-tree broad-gate receipt; do not rerun broad checks merely to prove they ran. Targeted RED/GREEN tests and one assembled-candidate gate remain mandatory.
- If a fixed spec is wrong, ambiguous, or incomplete, amend the spec and its plan before implementing the divergent behavior. This applies immediately to the distro credential contract described below.

## Cross-cutting invariants

Apply these to every phase and make each one discriminatingly testable:

- Authorization occurs before every existence-sensitive lookup or response. SQL authorization is part of the query before count, distinct filter projection, search, aggregate join, order, or page.
- Bulk writes validate and authorize the complete set, use one callback-minted transaction, and either commit entirely or return one non-enumerating failure. Duplicate IDs, oversized sets, unavailable lanes, and stale expected versions reject before effects.
- Password plaintext/hash never enters package public contracts, content/field definitions or values, revisions/autosaves, export/import manifests, logs, errors, events, audit, outbox, idempotency bytes/receipts, or public/persistent schemas. Protected content stores only private credential records and exposes opaque proof operations. Distro owner setup should use passkey or verified-email claim so the shared initializer does not accept a password.
- Imported data is bounded before allocation-heavy parsing and cannot contain executable imports, callbacks, expressions, provider code, unsafe regexes, or password material.
- Registries are explicit immutable inputs. No module-global registry, cursor, cache, or mutable singleton.
- Content/fields composite effects receive the exact same callback-minted opaque transaction. Independently minted transactions, casts, wrappers, or caller-supplied identities reject before effects.
- Audit, outbox, idempotency, revisions, current state, and import lifecycle transitions are atomic where the specs require them.
- UI uses semantic HTML, token-driven styles, container queries for reusable components, full keyboard/focus/live-region behavior, 44px targets, phone through large-screen layouts, and zero console warnings.
- Vitest fixtures use `.test.ts`; reserve `.spec.ts` for Playwright. Do not import `node:` builtins into host-agnostic package runtime source. Do not read `process.env` in client or `-react` runtime source.

## Phase 1 — Repair and finish Task 17 before any migration work

Start from `4dc55149`; do not proceed to Tasks 2 or 7 until all three verified P2s are closed.

### 1.1 Genuine D1 execution

Files:

- `packages/content/src/conformance.test.ts`
- `packages/fields/src/conformance.test.ts`
- package dev dependencies only if needed (`packages/content/package.json`, `packages/fields/package.json`, `pnpm-lock.yaml`)

Replace each hand-written D1 statement/binding mock with a genuine D1-compatible SQLite fixture, preferably a Miniflare D1 database using the already-established repository dependency. The fixture must:

- create the actual legacy `content_entries` / `field_values` table with D1-compatible SQL;
- insert the corpus through SQL, not return preloaded JS rows;
- execute the package store query through `createD1Client` and its transaction callback;
- prove a SQL mutation changes the returned result, so a static-row mock cannot pass;
- identify itself as D1 and run alongside the embedded real-Postgres fixture under the package's real-PG Vitest configuration;
- fail if either backend is missing, skipped, or did not execute;
- compare normalized dates, numerics, JSON/reference metadata, ordering, immutability, typed malformed-row errors, and distinct transaction identities.

### 1.2 Complete public barrels without regressions

Files:

- `packages/content/src/index.ts`
- `packages/fields/src/index.ts`
- co-located export/type tests and `apps/consumer` public-import tests as needed

Export every new schema/store/error/transaction contract added by Task 17 while retaining every existing export. At minimum expose the final schema records, flat read contracts, transaction aliases/assertions, contract errors and structural guards, and definition-version contracts. Add compile-time/public-barrel tests that import only package roots and compare the pre-checkpoint export inventory so no legacy symbol silently disappears. Do not expose internal parser helpers unless the spec makes them a seam.

### 1.3 Correct immutable field definition contract

Files:

- `packages/fields/src/schema.ts`
- `packages/fields/src/store.ts`
- `packages/fields/src/index.ts`
- `packages/fields/src/conformance.test.ts`
- Task 7 definition tests/types where necessary

Replace `ImmutableFieldDefinitionVersion.definition: FieldStorageValue` with the spec-named `FieldDefinitionVersion.definition: FieldGroup`. Implement strict trust-boundary parsing/validation for persisted/imported definition snapshots: exact object keys, normalized group/key/origin/revision, all recursive field discriminants, bounded depth/count/string sizes, duplicate field/path rejection, registered field-family checks, and rejection of executable/secret-like content. Canonical hashing must operate on the validated normalized `FieldGroup`; same key/revision with different canonical bytes is an integrity error. Keep Task 7 migration compatibility by making the immutable row/version schema consume this one contract rather than adding an alias with the old weak shape.

Verification:

```bash
pnpm --filter @platform-modules/content exec vitest run --config vitest.config.ts src/conformance.test.ts
pnpm --filter @platform-modules/fields exec vitest run --config vitest.config.ts src/conformance.test.ts
pnpm --filter @platform-modules/content typecheck
pnpm --filter @platform-modules/fields typecheck
pnpm --filter @platform-modules/content build
pnpm --filter @platform-modules/fields build
```

Run the independent `gpt-5.6-sol/low` review specifically against the three P2 findings and Task 7 compatibility. Fix all P1/P2, then mark Task 17 complete in its plan ledger if the ledger tracks completion.

## Phase 2 — Complete the content-model plan in dependency order

Use the exact task contracts and file lists in `docs/plans/2026-08-08-mod-cms-content-model-completion.md`; the detail below highlights implementation and gate intent. Do not collapse waves in a way that bypasses review.

### Wave 3: Tasks 2 and 7

- **Task 2, content migration floor:** add immutable type/status/revision/journal/private-credential/hierarchy/tombstone storage and adapter-neutral checkpoints. Materialize every existing free-form type/status before enforcement. Prove reversible D1 and real-Postgres migration with exact IDs, counts, values, hashes, dates, references, and no password surface.
- **Task 7, fields migration floor:** add recursive EAV nodes, stable row IDs/paths, immutable `FieldDefinitionVersion`, options/block revisions, staging/journals, constraints and indexes. Migrate every flat value and historical definition losslessly on D1 and Postgres; mixed/missing definition revisions fail closed.

Run each task's named acceptance command, review independently, and fix P1/P2 before Wave 4.

### Wave 4: Tasks 3 and 8

- **Task 3:** normalized code/DB type and status registries, code-wins reconciliation, immutable revisions, impact tokens, current authorization, corpus-bound destructive strategies, verified backup/core-owned restore, idempotency, atomic audit/outbox. Cover collisions, narrowing, purge/restore/replay/revocation on both databases.
- **Task 8:** all field families and recursive codecs, canonical paths, repeater/flexible/group/clone/tab/layout rules, location/conditional engines, relationship authorization, formatted projection, custom descriptors, and authoritative SQL/search with explicit bounds.

### Wave 5: Tasks 4, 5, 9, and 10

- **Task 4:** type-feature-aware entries, explicit author transfer, registered transitions, hierarchy integrity, protected-content proof/credential operations, revisions/autosaves, atomic permanent delete/reparent, hooks, receipts, audit/outbox. Unauthorized and missing branches remain indistinguishable.
- **Task 5:** one canonical SQL authorization predicate reused by counted page/status-free counts/distinct filters; authoritative search composition; route compiler/resolver/templates; actor-independent headless schemas and typed invocation. Never cap an incomplete candidate set or render protected body before proof.
- **Task 9:** Options Pages, Blocks, nested validation/references, immutable revisions/autosaves, exact parent transaction identity, code reconciliation, and verified destructive restore lifecycle.
- **Task 10:** bounded fields import/export/headless schemas, exact registry binding, collision shadowing, hidden staging, pre-lookup scope authorization, coordinate-CAS resumability, before-image rollback, atomic publication, and corpus-bound published reverse. Imported executable or password material rejects.

### Wave 6: Tasks 6 and 11

- **Task 6:** content native staged import/export with immutable plans, hidden staging, exact claims and reverse ledgers, atomic publish/rollback events, corpus-version-bound published reverse, malicious-bundle rejection, and exact authorized replay.
- **Task 11:** complete `fields-react` editors/builders for every family, recursive row/layout editing, conditional logic, Options/Blocks/revision diff/restore, accessible validation, container responsiveness, SSR-safe IDs, and adopter-supplied React only.

### Waves 7–9: Tasks 12, 13, and 14

- **Task 12:** in `apps/mod-cms`, compose one combined-schema transaction plus explicit registries, authorization, effects, entity map, import/reverse coordinator, and media/taxonomy/comments/translation/search adapters. Migrate all existing content, fields, terms, comments, translations, revisions, and routes losslessly before enabling enforcement.
- **Task 13:** build responsive, accessible type/status, field-group, Options Page, and Block administration with impact preview, collision diagnostics, destructive confirmation, backup and restore.
- **Task 14:** make editing type-aware; compose block documents with deterministic sanitized body fallback; link content/fields revisions and restores in one transaction; add route/template/render adapters, status transitions, protected reads, import/export screens, and headless discovery.

### Wave 10: Tasks 15 and 16

- **Task 15:** add root-public-import consumer tests (one behavioral test per export), D1/real-PG parity and concurrency probes, migration round trips, export/import, tarball/DTS/tree-shaking/bundle/self-description checks, registry updates, package metadata, and non-1.0 changesets for all changed public packages.
- **Task 16:** through `e2e-remote`, prove desktop and phone admin/code definitions, complete recursive create/render/revise/export/import, hidden staging, collisions, migrated production-shaped corpus, keyboard/screen-reader paths, and no warning/error output.

Run the full Task 15 command once on the assembled tree and the Task 16 remote command. Fix all warnings, not only failing exit codes.

### Wave 11: Task 18 and content-model delivery

Implement and test:

- `.github/workflows/delivery.yml`: identify `changesets/action`, run package verification only when `published == 'true'`, reject empty/malformed publication output, and pass the exact package/version set;
- `scripts/verify-published-packages.mjs`: require every expected changed package, resolve exact GitHub Packages versions, install them together in a clean consumer, import every declared export, and reject workspace/catalog leaks or version mismatch without logging credentials;
- `scripts/wait-for-delivery-run.mjs`: exact workflow/branch/SHA matching, newest deterministic result, bounded 10-minute wait, command/clock injection, and fail-closed API/auth/malformed/timeout behavior;
- `apps/mod-cms/e2e/content-model-live.spec.ts`: desktop and phone live content-model acceptance after arming, with base URL only from the production environment secret.

Verify the Task 18 commands from the canonical plan. Open the implementation PR, require Main Gate for its exact SHA plus all independent reviews, and merge only with `scripts/safe-merge.mjs`. If Delivery creates/updates a Changesets release PR instead of publishing, inspect that PR for every expected bump and consumed changeset, require its exact-SHA gate/review marker, and safely merge it. Fetch `origin/main`; use only the resulting release-merge SHA as final `EXPECTED_SHA`. Wait for that exact Delivery run and require successful package release, exact package verification, mod-cms deployment, scheduled-publishing arm, and live content-model test. A skip is not success.

## Phase 3 — Execute Posts-list parity from clean landed `origin/main`

Only start after Phase 2 is published/deployed/live-verified. Create a fresh PR worktree from fetched `origin/main`; do not stack Posts work on the old content-model branch.

### Posts Task 10 prerequisite

Add `apps/mod-cms/src/lib/content-model-prerequisite.test.ts`. Import registry/status/query/transaction/hierarchy/composite/template/revision seams exclusively from public package barrels and execute them through mod-cms adapters on D1 and real Postgres. Enforce the plan's clean-tree allowlist before running it. This must prove the prerequisite came from landed `origin/main`, not local package source.

### Posts Tasks 1 and 2

- In `packages/ui-primitives/src/data-table/**` and pagination, complete controlled/manual sort, submitted search, first/previous/next/last boundaries, page-scoped controlled selection, disabled rows, scope-key clearing, authoritative result announcements, focus/keyboard semantics, and container responsiveness. Keep it a generic state-owner primitive with no CMS policy.
- In `packages/comments`, add bounded aggregate and aggregate-subquery seams with actor scope before grouping, zero defaults, constant query count, non-leaking target IDs, and D1/Postgres parity. Export and package-test them.

### Posts Tasks 3 and 4

- Build `apps/mod-cms/src/lib/admin-content-list.ts` and API route: strict URL parsing, single/all-type surfaces, built-in/custom views, one consistent snapshot, canonical SQL authorization before items/counts/custom counts/filter options/aggregate ordering/page, batched projections, total ordering, timezone month bounds, hierarchy labels, and safe intersection capabilities.
- Build quick edit, atomic bulk mutations, and revisioned principal/surface/type-scoped Screen Options. Require operation IDs, duplicate-free bounded IDs, exact versions, current in-transaction authority, one transaction/audit/outbox, hierarchy plans, and non-enumerating failure. Date/status lanes follow resolved status metadata and strict site-timezone ambiguity/gap handling.

### Posts Tasks 5 and 6

Replace `apps/mod-cms/src/pages/admin/posts.astro` and `PostsTable.tsx` with the manual server-driven `DataTable`. Render canonical columns/views/counts/search/filters/total sorting/pagination/row actions/state markers, URL Back/Forward restoration, and server-projected capabilities. Add inline Quick Edit, bulk controls, Screen Options persistence, page-only selection reconciliation, mobile details, focus return, live announcements, visible labels, touch targets, and container-query layouts. Never duplicate status or authorization logic in React.

### Posts Tasks 7 and 8

Add the finite parity/property matrix for query normalization, authorization monotonicity, total order, count independence, concurrent snapshots, all capability states, and D1/Postgres equivalence. Then run `posts-list.spec.ts` via `e2e-remote` at phone, tablet, desktop, and large-screen sizes, exercising every sort/filter/page/view, Back/Forward, quick/bulk success/error/concurrency, trash/restore/delete, role rejection, keyboard/a11y, overflow/touch/focus, and zero console warnings.

### Posts Task 9 and delivery

Add changesets for changed public packages, package/build/export/bundle/packaging checks, and `posts-list-live.spec.ts`. Reuse (do not fork) the content-model exact-SHA waiter and package verifier. Delivery must verify the exact changed public package/version set and run the live Posts test after arming using the production environment secret. Land by exact-SHA PR gate and safe merge. If a Changesets release PR is produced, verify and safely merge it as in Phase 2. Wait for the release-merge SHA's Delivery run and require publication verification, deployment, arming, and phone/tablet/desktop/large live success.

## Phase 4 — Reconcile and complete standalone distribution graduation

Start only from the Posts release/deployment-complete `origin/main`, because the generated product must contain the final canonical app and use its published package versions.

### 4.1 Preserve and reconcile the existing distro worktree

Before touching it:

1. Record `git status --porcelain=v2`, branch/base/head, committed diff stats, untracked inventory, and a binary-safe patch/bundle or backup ref for all unique work.
2. Preserve commits `16059e4a` (seed/shared initializer/CLI foundation) and `c8332bda` (public CLI/create packages and deterministic generator).
3. Preserve the dirty continuation, including zero-data conversion, seeds, initializer adapters/routes, containment tests, theme/home changes, and `tools/mod-cms-dogfood`.
4. Rebase or port onto a new distro integration branch from current `origin/main`. Apply committed units first, then reconcile dirty files path-by-path against current `apps/mod-cms`; do not blindly restore stale package manifests, lockfiles, delivery YAML, or deleted app files. Resolve behavior against the current specs and keep a reconciliation ledger identifying reused, superseded, and rewritten pieces.
5. Do not edit `/home/user/Projects/platform/.worktrees/mod-cms-distro-graduation` destructively until every unique commit/file is reachable from the integration branch or backup artifact.

### 4.2 Correct the credential contract before implementation

The distro spec currently exposes `InitializeSiteInput.owner.credential`; that contradicts this request's password/public-contract invariant. Amend `docs/specs/2026-06-18-mod-cms-onboarding-install-design.md` and `docs/plans/2026-06-18-mod-cms-distro-graduation.md` first:

- shared `initializeSite` accepts a validated seed plus an opaque already-verified owner claim/principal, not password plaintext/hash;
- browser ownership uses passkey or verified-email claim; CLI/MCP transport obtains a bounded setup claim without putting passwords in seed, argv, exported types, logs, durable receipts, or schemas;
- the auth adapter owns any audit-hardened secret processing privately; initializer errors expose only structural codes and safe field/status context;
- update wizard/CLI/MCP parity and acceptance tests to the corrected contract.

Independently review this spec amendment before continuing.

### 4.3 Finish foundation: seed, initializer, zero-data source

Reconcile and finish:

- Zod 4 `SiteSeed` as the single source; generated checked-in JSON Schema; strict unknown/ID/tuple/bounds checks and recursive secret-like-key rejection;
- one shared initializer used by wizard, remote `mod-cms init`, and MCP `apply_site_seed`, with atomic lease, one winner, TTL recovery, exact digest replay, conflict behavior, provision/settings/content/finalize transaction, and D1/real-PG zero-row blank acceptance;
- generic `apps/mod-cms` source with catalogue/blueprint/UI-kit instance material removed, an accessible blank-state CTA, and explicit validated opt-in demo seeds only;
- dogfood content under `tools/mod-cms-dogfood`, never in generated source;
- source and rendered-output containment tests that reject instance content, legacy admin-token/private MCP prototype, secrets, escaping imports, symlinks/non-blobs, and unallowlisted files.

### 4.4 Reusable runtime seams and all targets

Implement host-neutral `CmsRuntime` and request-scoped injection. Only target adapters may import provider SDKs. Add/finish public storage and rate-limit seams with structural errors, tests, exports, registry entries, and changesets.

Target descriptors and acceptance:

- **Cloudflare:** `@astrojs/cloudflare`, D1, R2, native limiter, trusted `CF-Connecting-IP`, ScheduledPublishDO, binding-only `wrangler.jsonc` with no resource IDs/names, private-media proxy with validated type and `nosniff`.
- **Vercel:** `@astrojs/vercel`, Node 22.x, Neon/Postgres, Vercel Blob, transactional Postgres limiter, trusted Vercel headers, constant-time secret-gated schedule endpoint, and generated five-minute GitHub schedule workflow.
- **Node/Docker:** `@astrojs/node` standalone on Node >=22.12, postgres-js, filesystem bind-mount storage plus tested S3-compatible alternative, explicit trusted proxies, non-root multi-stage image, read-only root, health check, Compose database/volumes, and separate scheduler service.

Select exactly one target through an allowlisted build-time alias. Unknown target or provider import outside target code fails the build. All scheduling calls the existing idempotent `runScheduledPublish(db)`.

### 4.5 Finish public CLI, MCP, and revocable transport credentials

Reconcile `packages/mod-cms-cli` and `packages/create-mod-cms` into the current workspace (renaming/package metadata as dictated by the active spec) and make them real publishable packages:

- `mod-cms init` validates seed locally, uses environment/stdin for setup transport, never prompts on non-TTY, redacts safe errors, and implements the pinned exit-code matrix;
- deployed `/api/mcp` is authenticated Streamable HTTP; stdio is only a bridge;
- service-token management issues a random token once, stores only a private hash plus immutable token ID/scopes/expiry, supports list/revoke/rotate, rechecks current authorization before token lookup/use, and never logs or returns it again;
- token scopes separate initialization from normal content/settings tools; setup scope expires or is revoked on finalization;
- the admin connect card/easy-install flow creates a bounded token, writes URL/token through a mode-0600 file or adopter secret store/environment (never argv), pins the exact `mod-cms` package version, shows token once, and provides immediate revocation/rotation;
- tests prove revoked/expired/wrong-scope tokens fail non-enumeratingly, transport headers are redacted, redirects are rejected, and CLI/MCP/browser initialization creates byte-equivalent normalized state.

`create-mod-cms` must reject non-empty destinations, verify immutable GitHub release metadata, manifest/source commit, SHA-256, Sigstore workflow identity/provenance, and archive path/link safety before extraction. Enable `--target` only after all three descriptors and real acceptance are green; selection must materially alter generated runtime/descriptors.

### 4.6 Public npm closure and deterministic standalone repository

Compute the actual transitive package closure of the final generated app (do not rely on the old hard-coded count). For every required `@platform-modules/*`, `mod-cms`, and `create-mod-cms` package:

- add correct non-1.0 changesets/metadata;
- publish to public npmjs with least-privilege credentials;
- prove exact versions resolve and clean token-free install/import/build succeeds;
- invoke packed CLI bins through package-manager-created symlinks, not import-only tests.

Finish `tools/mod-cms-distro/generate.mjs` so it reads only allowlisted regular blobs from one full pinned canonical commit, rewrites `workspace:` and `catalog:` to the exact published compatible versions, removes private tooling, copies license/templates/target descriptors, emits a lockfile plus manifest/SHA receipt/source commit, and is byte-identical across two runs. Reject leaked protocols, absolute/file/remote/outside-root imports, private prototype/admin tokens, secret paths, symlinks, extras/missing files, and anonymous build failure.

Generate a `sync/<source-sha>` branch and open a PR to `platform-modules/mod-cms`; bootstrap the empty target without force pushing, then use normal PRs. The generated repository is an artifact and is never hand-edited. Its README must contain exactly the correct Cloudflare and URL-encoded Vercel deploy links plus a real Node/Docker quickstart, not a fake Docker button.

### 4.7 Delivery and real three-target acceptance

Split verification from publication:

- Main Gate generates and builds exact source/target artifacts and uploads SHA-256 receipts/attestations.
- Publisher receives only attested artifacts and cannot checkout/install/execute repository code.
- Enable immutable releases; publish manifest, archive, source commit, and Sigstore provenance.
- Delivery consumes exact artifacts without rebuilding. Cloudflare deployment occurs only in GitHub Actions; never run raw local Wrangler deploy.

After target repo CI is green, make the repository public and run fresh acceptance from public artifacts:

1. Cloudflare deploy button provisions fresh D1/R2/bindings, blank first-run succeeds, media/publish/schedule/CLI/MCP work, and deployed source hash matches receipt.
2. Vercel deploy button provisions a fresh project with Neon/Blob inputs, blank first-run and scheduled endpoint/workflow succeed, and runtime hash matches.
3. Node/Docker fresh pull/build/Compose on an isolated host succeeds with read-only app root, persistent DB/media, scheduler, health, blank first-run, restart persistence, and runtime hash.
4. Token-free `npx create-mod-cms@<exact-version>` creates each target from the immutable release; each then initializes from the same seed and reaches equivalent state.
5. Run keyboard/screen-reader/phone/desktop install and connect-card acceptance through `e2e-remote` where a browser/dev server is involved; require zero console or build warnings.

Record package/version URLs, target PR/release/deploy/job URLs, exact source and artifact hashes, live URLs, arming evidence, MCP token revoke proof, and acceptance receipts.

## Final assembled verification

Use targeted task commands throughout, then one final assembled candidate gate covering all changed packages/apps/tools. At minimum it must include:

```bash
pnpm --filter @platform-modules/db test
pnpm --filter @platform-modules/content test
pnpm --filter @platform-modules/fields test
pnpm --filter @platform-modules/fields-react test
pnpm --filter @platform-modules/ui-primitives test
pnpm --filter @platform-modules/comments test
pnpm --filter @app/mod-cms test
pnpm --filter @app/mod-cms typecheck
pnpm --filter @app/mod-cms build
node tools/smoke-exports.mjs
node tools/bundle-check.mjs
pnpm check:packaging-conformance
pnpm exec prettier --check .github/workflows/delivery.yml
node --test scripts/wait-for-delivery-run.test.mjs scripts/verify-published-packages.test.mjs
```

Also run the distro generator tests, CLI/create package tests, source-containment checks, target-specific builds, anonymous clean-install tests, and the three real target acceptances added in Phase 4. Run all browser suites through `e2e-remote`.

## Definition of done

Do not stop at code complete, PR merged, or a green feature-SHA job. Done requires all of the following:

- Task 17's three P2s are demonstrably fixed and independently reviewed.
- Every remaining content-model and Posts-list task is implemented in dependency order with no open P1/P2.
- Expected public packages are published at exact verified versions with no workspace/catalog leak.
- Canonical mod-cms is deployed, scheduled publishing armed, and both live content-model and Posts-list matrices pass.
- Existing distro work is reconciled without loss.
- The standalone repo is generated from the final pinned canonical commit, public, immutable-release-backed, and has correct deploy instructions.
- `mod-cms` CLI/MCP and `create-mod-cms` are publicly installable; MCP credentials are scoped and revocable.
- Fresh Cloudflare, Vercel, and Node/Docker installs pass real blank-first-run, seed parity, media, publish/schedule, CLI/MCP, restart/runtime-hash, responsive, accessibility, and warning-free acceptance.
- No local raw Wrangler deploy occurred, no `../mod-cms` file changed, and no P1/P2 was deferred.
