This repository was archived by the owner on May 9, 2026. It is now read-only.
release: v1.0.0 — site mode, surface registry, migration runner, hosted SSO#148
Draft
slavasolutions wants to merge 64 commits into
Draft
release: v1.0.0 — site mode, surface registry, migration runner, hosted SSO#148slavasolutions wants to merge 64 commits into
slavasolutions wants to merge 64 commits into
Conversation
Lock seven new ADRs (and one supersession) from the 2026-05-06 grilling session that reshapes v1 around an opt-in site mode. - 0021 Headless / Site mode split — per-project flag, UUID + manifest block ordering (reframes ADR-0007 from definition to storage strategy) - 0022 Record schema-version persistence — every record stamps version, declarative + imperative migrations chain at read - 0023 Editor surface registry — closed core (form/article/sections/canvas) with internal contract; future-opens to third parties non-breaking - 0024 Site mode renderer = library + scaffold template (supersedes ADR-0008) - 0025 Per-bucket theme tokens — design-system foundation, schemas reference via optionsFromTokens, store token name (not resolved value) - 0026 Preview tier contract — T0/T1/T2 named tiers (T1 mostly built; site mode auto-emits markers; T2 reserved) - 0027 Markdown as first-class widget alongside richtext — two prose widgets, two storages - 0028 Block library publishing rhythm — strict semver, package-shipped migrations CONTEXT.md updated with the new vocabulary (Mode, Site, Block, Block-schema, Theme tokens, Preview tier, Schema version, Richtext extensions; Frontend / Editor mode / Widget extended). STATE.md records the architectural pivot and links the new ADRs. ADR-0007 reframed (storage strategy, not block definition). ADR-0008 superseded by ADR-0024. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
0.3.0 in package.json never reached npm (broken publish workflow, fixed by #21). Rather than catch-up publish, accumulate the queued changesets + open feature PRs and ship as v0.4.0 in one wave. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
All 9 queued packages now on npm. Documents the path that got us there (six commits + per-package TP config) so future debug saves that walk. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Two compounding causes: 1. Cached libSQL singleton in lib/db.ts opened lazily when a route is imported was never closed by tests. Added closeDb() export. 2. Windows occasionally needs a retry window on rm even after close(). Added safeRm() helper in test/teardown.ts (5 retries, 50ms backoff). Wired into pages-reindex, schemas/[key], preview/[token], backup, restore test suites. All 389 admin tests pass on Linux. Windows clone should clear the EBUSY blocking Eng B's full test runs. Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…+ SQLite teardown + update notifier)
…/0028) (#57) Squash of 9 commits — contract trail preserved here per the PR body's "do not squash" intent (forced by repo policy: only squash-merge is allowed). The per-commit narrative below maps to the changeset entries under .changeset/ that ship with this PR. 1. f4c6f4d feat(spec): add clear.config.json mode field (ADR-0021) 2. 4e0147c feat(spec): add schemaVersion + version per ADR-0022 3. dabb8e5 feat(spec): add sections + canvas editor modes (ADR-0021/ADR-0023) 4. eb50062 feat(spec): add markdown as a first-class widget (ADR-0027) 5. 2a4c137 feat(spec): per-field extensions allowlist for richtext + markdown 6. f2bdd41 feat(spec): per-field optionsFromTokens for select widgets (ADR-0025) 7. ed0bea0 feat(spec): block-schema dialect + block-instance + blockStorage hint 8. 96a0a3b feat(spec): per-bucket tokens shape + Migration types (ADRs 0025/0022) 9. b6c6294 chore(spec): self-review polish — drop dup config re-export, symmetric tokens re-exports Phase 3 of the v1.0 release plan. Extends @clearcms/spec with the contract surface site mode and schema-version persistence depend on. Eng B track per clearcms/planning/decisions/2026-05-06-v1-architecture.md. Track tests: 219/219 (spec) — typecheck clean, build green. Self-review: APPROVE — no blockers, three LOW-severity nits addressed in commit 9. Closes the Phase 3 spec foundation milestone. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Squash of 6 commits — Eng B Phase 5/6 storage track. Trail preserved here per the no-squash intent (forced by repo policy: only squash-merge allowed). Per-commit narrative maps to .changeset/ entries. 1. 4956c11 feat(storage): write-time schemaVersion stamp (ADR-0022) 2. 40612df feat(storage): named-global writers — identity / nav / tokens 3. e8db616 feat(storage): writeItem + writePage with status routing 4. 971102c feat(storage): writeBlock + resolveBlockStorage + writePageData stamp 5. f31fe83 feat(storage): bucket-path helpers 6. b696176 feat(admin): clear-admin backfill-schema-versions CLI surface (stub) Adds the load-bearing schema-version write primitives + every named writer the v1 plan asks for, all routing through `writeStampedJson`: - `stampSchemaVersion(record, schemaVersion?)` — pure precedence chain (explicit arg → record's existing valid semver → `DEFAULT_SCHEMA_VERSION`). - `writeStampedJson(adapter, key, record, schemaVersion?)` — atomic temp+rename with stamp. - Named globals: `writeIdentity` / `writeNav` / `writeTokens` / `writeGlobal` (generic dispatch on closed-set name). - Records: `writeItem` (status-routed via `itemPath()`), `writePage` (`content/pages/<slug>/index.json`). - `writeBlock` for `blockStorage: "files"` per-instance file path. - `writePageData` augmented to stamp on object payloads. - `resolveBlockStorage(collectionSchema, collectionSlug)` strategy resolver (default `"files"` for `pages`, `"inline"` elsewhere). - Path helpers `themeBlocksDir` / `pageBlocksDir` / `pageBlockPath`. - `clear-admin backfill-schema-versions` CLI surface (stub; full bucket walk lands in Phase 6 closeout). Track tests: spec 219/219 + storage 89/89 = 308 ✅. Full implementation of bucket walk pending Phase 6. Stacked on PR #57; auto-retarget didn't fire — manually retargeted to release/v1.0 + rebased --onto to drop the now-merged spec commits. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Squash of 2 commits — Stream-Migrate. Trail preserved here per no-squash intent (forced by repo policy). 1. 89441bc feat(spec): migration runner + library discovery (ADR-0022, ADR-0028) 2. ebf44a1 feat(admin): clear-admin migrate-records stub (ADR-0022) `@clearcms/spec/migrate` runtime: `migrate(record, from, to, migrations)`, `buildMigrationChain` (greedy shortest-path), `applyOp` for each declarative op kind (rename / default / remove / tiptap-to-markdown / markdown-to-tiptap), `discoverMigrations` walking both `<bucket>/migrations/` and `node_modules/@clearcms/blocks-*/migrations/` per ADR-0028. Markdown ↔ TipTap conversions are best-effort with `_migration_warnings` annotation per ADR-0027. In-package serializers (no `marked` / `remark` deps). `apps/admin/src/cli/migrate-records.ts` — argv shape (`--collection <slug>` | `--all`, `--dry-run`) locked, full bucket walk + persist deferred to Phase 6 closeout. Track tests: spec 247/247 (+25 for migration runner). Stacked on PR #57; manually retargeted + rebased --onto release/v1.0 to drop the spec commits already squashed via #57. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Squash of 2 commits — Stream-Renderer scaffold. 1. f06d7f8 feat(renderer): library scaffold (ADR-0024) 2. 43c2d70 chore(renderer): clarify FOLLOWUP(#57) marker for spec-types swap `@clearcms/renderer` library shape (NOT an Astro integration). Types + dispatch only — no real blocks yet. Exports: `renderBlocks(blocks, registry)` (pure dispatch), `UnknownBlock` (no-op fallback per ADR-0021), `usePreview()` (SSR-safe `?clear-preview=` detection + `markField` helper for ADR-0026 T1 markers). Framework-neutral — no React/Astro/Vue dep. `RendererBlockInstance` is a local mirror with a `FOLLOWUP(#57)` marker for the swap to `@clearcms/spec/blocks` once #57 lands. Now that #57 is merged, the swap is queued — see `grep -r 'FOLLOWUP(#57)' packages/`. 9 tests cover renderBlocks happy path with known + unknown blocks, `UnknownBlock` fallback, `usePreview` URL detection, `markField` output shape. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…1/0022/0025) (#75) Stream-Doctor — 4 new `clear-admin doctor` checks for the v1 site-mode + ADR-0022 schema-version contract. Each is a pure async function returning `DoctorIssue[]`; all four return zero issues on a healthy v0/v1 bucket. - `checkModeConsistency` (ADR-0021) — `clear.config.json`'s `mode` vs the bucket's site-mode artifacts. Headless + `theme/blocks/` files present → warning. Site + no `theme/blocks/` → info. - `checkDanglingBlockTypes` (ADR-0021) — page `data.json` block manifests reference unknown block types → warning each. - `checkStaleSchemaVersions` (ADR-0022) — record `schemaVersion` vs the schema's current `version`, per-collection counts. Suggests `clear-admin migrate-records` for stale collections. - `checkDanglingTokenRefs` (ADR-0025) — block-instance fields with `widget: "select" + optionsFromTokens: <category>` reference token names absent from `theme/tokens.json[<category>]`. Wired into `doctor.ts`'s main run sequence so `clear-admin doctor` surfaces the new checks alongside the 10 existing ones. Tests: 18/18 across 4 new test files. Pure fs fixtures (`mkdtemp` + JSON file writes); no SQLite DB harness — Windows EBUSY pre-existing issue (#56) doesn't apply. Local `assumeSchemaVersion` shim in `doctor-stale-schema-versions.ts` that should be swapped to `@clearcms/spec`'s now that #57 has merged. Tracked as a follow-up cleanup PR per the lead's review. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Squash of 2 commits — Stream-Docs CONTENT-PROTOCOL v1 rewrite. 1. (initial commit) docs(protocol): CONTENT-PROTOCOL.md v1 rewrite (site mode) 2. (review-nits commit) docs(protocol): address review nits — ADR-0024 scope note + SDK schemaVersion default Rewrites `docs/CONTENT-PROTOCOL.md` to cover v1 site mode. Archives the v0 file to `docs/CONTENT-PROTOCOL-v0.md` via `git mv` (history preserved). 14 sections covering: Overview (mode split) | Bucket layout | Schema versioning + migrations | Block storage strategy | Theme tokens | Markdown / richtext widgets | Item document schema | Page document schema | Block library publishing | REST API | Site mode example | Headless mode unchanged | Doctor + backfill commands | Summary TOC. Cross-references ADRs 0021 / 0022 / 0024 / 0025 / 0027 / 0028 inline. Review nits addressed in commit 2: - §1 scope note clarifying ADR-0024 (renderer architecture) lives outside this protocol doc by design — bucket-level contract only. - §3 SDK-author note on the absent-`schemaVersion` = `"1.0.0"` rule; recommends `assumeSchemaVersion` over `.default()` Zod parse so the doctor's "untracked" check stays meaningful. 1015 lines. Status line: v1, descriptive. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Establishes the rigid task list + turn-based coordination for the rest of v1. Both engineers (S1 = lead/Eng A, S2 = Eng B) read these files at session start and follow them strictly. PLAN.md is the ordered task queue from now to v1.0.0. Each task is tagged [S1] or [S2] with prereqs noted. Phase 3 already complete (all 6 PRs merged today). Phase 4-8 still queued. BATON.md is a single-line file (S1 or S2) marking whose turn it is to merge to release/v1.0. Initial value: S2 — Eng B has #102/#103 to process before lead picks up Phase 4. Hard rules in PLAN.md: - One in-flight merge at a time per session. - Strict alternation enforced by BATON. - No direct push to release/v1.0 except the two-line BATON+PLAN flip commit immediately after each merge. - Surface ownership zones to prevent file-level conflicts. Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
#102) Reflects the v1 wave merged on release/v1.0 (PRs #57/#72/#73/#74/#75/#76). Updates header date + tagline; new "v0.5 conceptual milestone" section listing each merged PR with SHA + scope; bucket protocol section flips to v1 layout; "in flight" section points at next gates (#52, blocks-marketing); ADR status block updated per ADR. closes T-3.7 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
T-3.9 (lead's #101 migrate-bucket-to-r2 merge) is blocked: the @clearcms/spec barrel re-exports migrate/run.ts (node:fs/promises + node:url + node:path), so Vite drags it into both client and server chunks of admin's astro build. Build fails with __vite-browser-external, or smoke tests fail with ERR_MODULE_NOT_FOUND at runtime. Confirmed with a clean lockfile + green typecheck + 426/426 tests + an astro.config external mark — the issue is fundamentally in the spec package's exports shape. Spec is S2 surface (per PLAN ownership zones). Inserting T-3.8.5 [S2] as a hot unblocker: split @clearcms/spec/migrate so the bucket-walking runner is a server-only sub-export. Detail in PLAN.md. Flipping BATON to S2 to enable the fix. T-3.9 stays open and unticked — S1 will retry it after S2's spec fix lands and lead's #101 rebases clean. T-3.10 / T-3.11 / T-3.12 reordered for cleaner Phase 3 wrap-up (pulled #103 blocks-marketing forward as T-3.11 since it's already in flight). This commit modifies only BATON.md + PLAN.md per protocol.
…rowing (#106) Bundled fix unblocking the entire v1 PR queue. Per-commit trail: - e9e9b4b fix(spec): split migrate runner — Node-only fs in /migrate/runtime sub-export - 07b3aa8 fix(deps): regenerate pnpm-lock.yaml after spec exports map change - 6370200 fix(spec,core,storage,design): publish hygiene — dist-only tarballs + spec/migrate split - eae5978 fix(admin): narrow editor mode + add markdown widget label (cherry-picked from #109 per S1's Path A) What this fixes: 1. @clearcms/spec migrate split — run.ts now pure (no node:* imports). Node-only discovery lives in new runtime.ts at @clearcms/spec/migrate/runtime (node condition only). Drops src from files whitelist. 2. Publish hygiene — @clearcms/core, @clearcms/storage, @clearcms/design flipped from raw-TS to dist-only with tsconfig.build.json + conditional exports map. 3. Admin enum narrowing — PageItemEditor + SchemaPreview narrow editorModeFor() via requiresSiteMode guard; PageContentTypeFields uses 'as const'; AddFieldModal adds 'markdown' to WIDGETS + WIDGET_DESCRIPTIONS. Per-callsite narrow until Phase 4 editor surface registry (#52). Changesets: - @clearcms/spec: minor (export shape change) - @clearcms/core: minor - @clearcms/storage: minor - @clearcms/design: minor - @clearcms/admin: patch Verification: - pnpm --filter @clearcms/admin typecheck → 0 errors - pnpm --filter @clearcms/admin build → green (no node:* in browser bundle) - pnpm pack across the four packages confirms dist-only tarballs Closes #105 Closes #107 Closes #108 Closes T-3.8.5 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* feat(admin): clear-admin migrate-bucket-to-r2 (closes #14) One-shot fs → R2 data migration. Reads ~/clear/registry.json, creates the target bucket via the platform R2 token from R2_* env vars, PUTs every file under bucket/ at the same key, atomically rewrites registry.json with bucketProvider:'r2', and renames the local bucket dir to bucket.archived-<ISO>/ so the operator can verify parity before deleting. Implements ADR-0017 v1 happy path (steps 1, 2, 3, 5, 6, 7, 8). Status flipped from proposed to accepted. Deferred (called out in the changeset): - Step 4: per-project scoped R2 token mint per ADR-0016. - Resume-on-failure via .migration-progress.json (ADR-0017 Risks). - Streaming PUTs for large media (v1 reads each file fully into memory; fine for text-shaped sites, fails on multi-GB media libraries). Env contract: reads R2_* (the platform-token shape from ~/.r2-platform.env), distinct from the per-project CLEAR_R2_* the admin reads at boot. CreateBucket requires admin scope across all buckets, so the platform token is the right input here; ADR-0016 will replace this with a per-project token mint. Tests: vitest fixture suite injects a recording StorageOps double; covers happy path, content-type map, --bucket-name override, already-on-R2 short-circuit, missing-slug + missing-source-bucket fail-fast, env validation, and that other registry entries are preserved during rewrite. 8/8 pass. Dogfooded against ~/clear/clear-marketing/ (37 files, 172K, fs → R2 bucket "clear-marketing"). Post-migration verified: archive dir present, original bucket renamed, registry shape correct, and astro build with CLEAR_BACKEND=r2 produces the same 12 pages as the fs baseline (only diff is the homepage's local _demo/ walker, which is site-code-specific and unrelated to the migration). Discovered during testing: doctor.test.ts > "PASS for a present bucket dir" has a tight 5s timeout on a sqlite3 execSync loop that occasionally trips when running alongside other parallel test files. Pre-existing fragility (passes 397/397 with --no-file-parallelism); the new test file just adds enough load to expose it. Out of scope for this PR. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix(admin): remove obsolete vite externals for spec/migrate Pre-T-3.8.5 astro.config.ts marked @clearcms/spec/migrate as a ssr.external + rollup external, which baked the BUILD-TIME absolute path of /home/runner/packages/spec/dist/migrate/run.js into the items chunk. That path is correct on the dev machine but doesn't exist on the CI runner (which builds from /home/runner/work/clear/ clear/...), so the smoke test failed with ERR_MODULE_NOT_FOUND. T-3.8.5 (PR #106) fixed the underlying problem structurally by splitting @clearcms/spec/migrate into a browser-safe barrel and a Node-only @clearcms/spec/migrate/runtime subpath. The vite externals in admin became obsolete and harmful — same posture as release/v1.0 HEAD, which has none. This commit removes the externals so admin's build matches HEAD's configuration. Local build passes; CI smoke test should now resolve the chunk imports through Node's normal package-exports resolution instead of an absolute file path. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
First v1 block library shipping with create-clear scaffolds and renderer support. Per-commit trail: - 10542dc feat(blocks-marketing): scaffold + Hero (ADRs 0024/0025/0028) - 3ffca3c feat(blocks-marketing): Features + CTA + FAQ + Footer + Contact (5 blocks) - 43154d4 feat(blocks-marketing): Testimonials + Pricing + Logos + RichText (final 4 blocks) 10 blocks: Hero, Features, CTA, FAQ, Footer, Contact, Testimonials, Pricing, Logos, RichText. Each block ships an Astro component + Zod schema with the v1 widget dialect (ADR-0027). Theme tokens (ADR-0025) referenced via optionsFromTokens binding. Schema versioning per ADR-0022; lockstep publishing per ADR-0028. Changeset: @clearcms/blocks-marketing minor. Closes T-3.11. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Implements ADR-0023's closed-core surface registry. The schema's
`editor:` keyword resolves through `surfaceFor(schema)` to one of
four surfaces — form, article, sections, canvas — each implementing
the EditorSurface interface (validate + Component). PageItemEditor
and PagePageEditor dispatch through the registry instead of
branching on a narrowed 'form' | 'article' value.
- apps/admin/src/surfaces/types.ts — EditorSurface, SurfaceProps,
SurfaceContext, SurfaceValidationResult, SiteContext + ok()/failed()
helpers.
- apps/admin/src/surfaces/{form,article}/index.tsx — delegate to
SchemaForm for behavior parity. Article validator wraps
validateArticleSchema (exactly one richtext required).
- apps/admin/src/surfaces/{sections,canvas}/index.tsx — not-implemented
placeholders. Sections validator refuses outside site mode + when
no block schemas exist. Canvas validator always refuses (post-v1).
- apps/admin/src/surfaces/index.ts — surfaceFor() dispatcher + the
closed registry object. Type re-exports for consumers.
- PageItemEditor + PagePageEditor: surface dispatch + inline
SurfaceValidationFailed render when validate() returns ok: false.
Tests: 10 cases covering dispatch defaults, named-value resolution,
per-surface validators (article richtext-count, sections site-mode
+ block-schema gates, canvas reserved-for-post-v1, form always-ok),
and registry shape integrity.
Per ADR-0023 the registry is internal-only — no public registration
API in v1. Opening it to third-party surfaces is a future ADR keyed
off concrete adopter demand.
Closes T-4.1, T-4.2, T-4.3, T-4.4, T-4.5, T-4.6, T-4.7. Closes #52.
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* feat(admin): plumb project mode at boot (T-5A.1, ADR-0021) Adds the runtime resolution path for ADR-0021's mode flag. Site-mode surfaces (tokens UI, sections editor, designer extension, blocks library) consume getProjectMode() / isSiteMode() in T-5B/C/D PRs to gate sidebar entries and route guards. - project-config.ts: mode: ProjectMode now resolved from env CLEAR_MODE > file.mode > headless. Provenance tracked in sources.mode. Unknown values fall back to default rather than throwing — boot must succeed even with a slightly off config so the operator can fix the file from the running admin. - project-mode.ts: cached getProjectMode() + isSiteMode() helpers for runtime hot paths. Cache resets only via _resetProjectModeCache() (tests only). Existing v0.x installs default to headless and see no behavior change. The site-mode-only sidebar entries + route guards land in T-5B.1 (/settings/site/tokens) and T-5D.1 (sections route exposure). Tests: 6 helper cases + 4 resolver cases covering default / file / env / env-override / unknown-value fallback. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix(admin): address #120 review findings — provenance + test cwd hygiene Self-review pass on T-5A.1 found two in-scope fixes: 1. project-config.ts mode resolution: provenance was reported based on which input was *populated*, not which input *resolved*. A bogus env like CLEAR_MODE=composer would record sources.mode='env' while actually using the default — misleading in doctor output. Fixed to use a validity-aware predicate so sources.mode reports the source of the *resolved* value. 2. project-mode.test.ts: process.chdir leaked across tests in the same worker, and chdir'ing to /tmp picked up stray clear.config.json files on dev machines. Fixed by capturing originalCwd in beforeEach + restoring in afterEach, and using mkdtemp for the default-case tests instead of /tmp. Follow-up filed separately for the third finding (wire doctor-mode-consistency.ts to consume the new resolver + warn on typo'd mode values). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
T-5A.1 follow-up. The mode-consistency check now uses loadProjectConfig().mode as the resolver — single source of truth across env / file / default. Critical addition: when the resolver fell back to default because the raw value didn't validate, the check WARNs with the operator-supplied bad value. Without this, mode='sote' silently boots as headless and the operator can't tell their typo wasn't honored. Tests: 9 cases (was 5). Added 4: file.mode typo, env.CLEAR_MODE typo, typo prevails over headless+blocks WARN, valid env value doesn't trip the typo branch. Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* feat(admin): block-schema designer extension (T-5C.1, ADR-0024)
Site-mode-only — extends the visual SchemaDesigner to read+write
theme/blocks/<Name>.schema.json files alongside the existing
collection + layout schemas.
- lib/schemas.ts: 'block' added to SchemaKind; b:<PascalName> key
encoding with isValidBlockName guard (PascalCase only, ADR-0024);
listSchemas now scans theme/blocks/*.schema.json; readSchemaByKey
+ writeSchemaByKey convert between BlockSchema (on-disk shape:
{ name, version, fields }) and ClearSchema (designer shape:
{ type: 'object', properties }) so the existing SchemaDesigner
works without modification. Block meta (name/version/title/
description/deprecated) round-trips via a clear:block field the
designer ignores; final-form BlockSchemaSchema validation on
write.
- SchemaList.tsx: third "Block schemas" section in the left rail,
shown only when at least one block exists.
- settingsSections.ts: Settings sub-nav adds "Schemas" + "Block
schemas" entries (gated by schemaEditor).
- pages/settings/blocks/index.astro: site-mode list (302 to /settings
in headless, /schemas in site).
- pages/settings/blocks/[name].astro: site-mode designer wrapper
(302 to /schemas/b:<name>; rejects non-PascalCase names with 400).
Tests: 18 cases (was 10). New: block-key encoding (PascalCase
required, path-traversal rejected, empty rejected), dialect
conversion round-trip (fields ↔ properties + meta + deprecated +
default-version fallback).
Closes T-5C.1.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix(admin): address #122-style review on T-5C.1 — site-mode gate + cache + spec parity
Self-review pass on the block-designer extension found 3 in-PR fixes:
1. invalidateCachesForKey: block kind was falling through to the layout-
cache invalidation branch, calling invalidateLayoutSchema() with a
block name. Harmless today (no block-schema cache exists yet) but
wrong shape. Added explicit block branch (no-op + comment).
2. Site-mode leak on /schemas + /api/admin/schemas: the existing schema
designer routes had no isSiteMode() gate, so a headless operator who
bookmarked /schemas/b:Hero would land on a working block-designer
surface. Now: /schemas/[key] returns 404 when key is `b:` and not
site-mode; /schemas + /schemas/[key] filter blocks out of the rail;
POST /api/admin/schemas/[key] returns 403 on block writes in headless.
3. PascalCase regex was stricter than @clearcms/spec's BlockNameSchema
(which allows `[A-Za-z][A-Za-z0-9-]{0,59}` — hyphens + lowercase
leading). Mismatch meant on-disk hyphenated block schemas would be
reachable on disk but invisible in the designer. Reconciled by
matching spec's regex (max 60, leading alpha, alnum+dash). Tests
updated.
Tests: 19 (was 10 → 18 after T-5C.1 → 19 with the spec-parity case).
Filing follow-ups for: writeSchemaByKey block-path coverage, listSchemas
blocks-present coverage, redirect-route tests, title==name drop edge
case.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* feat(admin): sections surface MVP (T-5D.1-4, ADR-0021/0024)
Replaces the Phase 4 SectionsPlaceholder with a real composition UX.
Site-mode admins with at least one block schema can now author a
sections page end-to-end: add block instances, edit each block's
fields via per-type SchemaForm, reorder via up/down buttons, delete.
Files:
- surfaces/sections/types.ts — SectionInstance, SectionsManifest,
toManifest defensive coercion, newSectionId crypto-random helper.
- surfaces/sections/SectionCard.tsx — header (type label + reorder +
delete) + body (per-block fields via SchemaForm with block-schema
converted to ClearSchema). UnknownBlockType renders inline error.
- surfaces/sections/AddSectionPicker.tsx — minimal select + add UI;
empty state when no block types exist.
- surfaces/sections/SectionsSurface.tsx — manifest stack + dispatcher.
- surfaces/sections/index.tsx — validator now returns ok() when
siteContext + at least one block schema. Component = SectionsSurface.
Storage strategy: v1 ships inline-in-pageData. Per-instance block
files (writeBlock + blockInstancePath) land as v1.x follow-up. dnd-
kit reorder, visual block picker, click-to-focus from preview also
deferred to v1.x — operator can author end-to-end with the MVP.
Tests: 11 surface-registry cases (added "sections passes when site-
mode + blocks" branch) + 7 manifest helper cases.
Closes T-5D.1 / T-5D.2 / T-5D.3 (basic) / T-5D.4. Defers T-5D.5/6/7/8.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix(admin): wire siteContext to surface dispatchers (closes block-merge from review)
Self-review on T-5D found a hard blocker: PageItemEditor and
PagePageEditor passed `{}` as the surface validation context, so
sections surface's validator (which requires `ctx.siteContext`)
returned failed() unconditionally — surface never actually mounted.
Fix:
- New `lib/site-context.ts` with `loadSiteContext()` + cache. Reads
every theme/blocks/*.schema.json and theme/tokens.json into a
SiteContext shape. Returns null in headless mode.
- PageItemEditor + PagePageEditor accept `siteContext?: SiteContext |
null` prop, thread it through to surface.validate() + Component.
- .astro callers (item editor + page editor) pass `await
loadSiteContext()` as the prop.
Plus the memo fix from the same review:
- SectionsSurface uses useMemo for types + schemaForType conversion
(was rebuilt every render). Removed useCallback that was no-op
due to props-deps capturing every-render onChange.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix(admin): keep storage server-only by converting block schemas in site-context
CI failure on PR #142: SectionsSurface imported blockSchemaToClearSchema
from lib/schemas.ts, which transitively imports @clearcms/storage's
readJson/writeJson — pulled the FS adapter (node:fs/promises, node:path)
into the client bundle and exploded with "join is not exported by
__vite-browser-external".
Fix: move the BlockSchema → ClearSchema dialect conversion into
loadSiteContext() (server-side .astro path). The SiteContext that
arrives at the editor island already carries ClearSchema-shaped block
schemas, so SectionsSurface no longer needs to import any conversion
helper or anything else from lib/schemas.ts. Bundle stays clean.
Local `astro build` now succeeds; CI should match.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
T-7.1 — ADR status sweep + block-library author guide + CONTENT-PROTOCOL v1 polish. ADR sweep: - 0007 reframed by 0021 (page block storage shifted to v1 dialect) - 0008 superseded by 0024 (Workers renderer dropped for self-hosted Astro) - 0021–0028 carry Implementation status (2026-05-07) sections with PR references where shipped ADR README index: - 0007 row updated to reframed - 0019 noted as skipped/reserved - 0021–0028 annotated with v1 impl status - New v1 ADR set one-line summaries New file: docs/guides/block-library-authoring.md (~325 lines) - Required exports + widget vocabulary (ADR-0027) - optionsFromTokens binding (ADR-0025) - Versioning + migrations (ADR-0022) - Publishing cadence (ADR-0028) - Worked Pricing block example - Reference: @clearcms/blocks-marketing CONTENT-PROTOCOL polish: - "What's new in v1" section - Cross-link to author guide - Renderer name fix: clear-site → @clearcms/renderer Changeset: empty frontmatter — root docs, no package version bumps. Closes T-7.1. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…(T-7.3+T-7.4 partial) (#146) Pre-stages T-7.3 (README v1 rewrite) + T-7.4 (STATE.md refresh) docs in parallel with Eng B's T-7.1 docs sweep (separate paths — they touch docs/adr/ + docs/CONTENT-PROTOCOL.md + docs/guides/, this PR touches README.md + docs/migration-v0.2-to-v1.0.md + STATE.md). - README.md — adds prominent "Two modes (v1, ADR-0021)" section near the top: explains headless vs site mode + points at the migration guide. Existing scaffolder/quick-start sections unchanged. - docs/migration-v0.2-to-v1.0.md (new) — TL;DR upgrade for headless installs (just bump deps + run doctor); spec/storage table of changes with backwards-compat notes; site-mode opt-in walkthrough (config flag → scaffold → sections layout → renderer); breaking- change list (rare; only matters for internal-import consumers); rollback notes. - STATE.md — refreshed package versions to match npm reality (#110) + reflect v1 phases shipped: admin 0.4.2 with v1.0.0 queued, create 0.4.0 with --theme=marketing, blocks-marketing 0.1.0 new, renderer 0.1.0 scaffold. Header line updated to v1.0 release prep status. T-7.3 (full): full clear-admin command reference + integration guides (Astro/React/SDK) + REST docs deferred to v1.0.x — covered by issue referencing #94. Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…tamp per PLAN override)
Adds 103 tests across 7 new files, no production-code changes. Targets
the highest-value gaps in @clearcms/sdk after a public-surface review:
- errors.test.ts (10 tests) — ClearSdkError code/cause contract +
factory tagging. Adapters branch on err.code; pin the values.
- index.test.ts (13 tests) — isResolvedRef / getResolved edge cases
(null _resolved, arrays, primitives, missing keys).
- client.test.ts (15 tests) — bucket-direct listPage offset cursors
(clamp, NaN/negative limits, malformed cursor tolerance, hasMore),
listAll exhaustion, lazy adapter-load config errors, unknown backend.
- adapters/shared.test.ts (24 tests) — LRU eviction + promotion + delete,
pMapBounded order/concurrency cap/empty input, all parsers (valid,
invalid JSON, schema-fail, unicode).
- adapters/rest.test.ts (21 tests) — query-param forwarding (locale,
status, expand, limit, cursor), Bearer auth, draft-without-token
guard, 401/403/404/5xx code mapping, fetch network error wrapping,
malformed JSON parse error, nested page slug encoding,
metaEffective stripping, favicon URL→bucket-key reverse translation,
nav 410 subsystem-off fallback, theme-tokens default fallback,
trailing-slash adminUrl stripping, Z2 cursor pagination shape.
- adapters/config.test.ts (10 tests) — config validation for r2
(accountId, bucket, credentials.{accessKeyId,secretAccessKey}),
s3 (endpoint, bucket, region), fs (root). Errors fire on first call
(lazy load), not factory time — pin that contract.
- adapters/fs.test.ts (13 tests) — empty-bucket defaults
(DEFAULT_IDENTITY/NAV/THEME_TOKENS), bucket-direct draft invisibility
on listItems/getItem/pages.list/pages.get, sort-order contract
(publishedAt desc, slug asc tiebreak), locale filter, missing
collection prefix, corrupt-JSON tolerance (parse error on get,
skip-and-continue on list), nested page slug round-trip.
Verification:
- pnpm --filter @clearcms/sdk test → 118 passed (was 15)
- pnpm --filter @clearcms/sdk typecheck → clean
- pnpm pack → no *.test.* files in tarball (verified via tar -tzf)
No new dependencies. No production code touched. No changeset (this is
internal quality work, not a publishable change).
Co-authored-by: Engineer B <engineer-b@clearcms.dev>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds 23 tests in a single new file (src/edge-cases.test.ts), no production-code changes. Targets the corners of the @clearcms/renderer public surface that the shipped src/index.test.ts doesn't pin: renderBlocks edge cases (6 tests): - empty manifest in / empty manifest out - order preservation across a 50-block manifest - registry value type-agnosticism (string, number, function, object) — locked because the package is framework-neutral - props reference passthrough (memo-friendly for downstream adapters) - schemaVersion preserved on descriptor.meta when present - two unknown blocks of the same type stay independent (no aliasing) UnknownBlock (3 tests): - fresh object each call (no shared state) - props reference passthrough - kind=\"unknown\" discriminator is stable usePreview URL parsing (7 tests): - clear-preview detected when surrounded by other params - empty value / valueless key still count - hash-fragment-only \"clear-preview\" does NOT trigger - relative URL strings work via synthesized base - query-only string (no path) works - similar-named params (clear-preview-debug, xclear-preview) excluded - empty string returns previewing=false usePreview.markField (7 tests): - empty fieldPath returns the whole record - numeric segments resolve through array index lookup - primitive ancestors (string/number/boolean) return undefined - null ancestor returns undefined - non-object input record returns undefined - __proto__ named keys read literally (own properties only) - dataClearField only emitted when previewing (production markup byte-identical to no-preview path) Bug found and filed (NOT fixed here): - #135 — packages/renderer/package.json files array does not exclude *.test.ts → tests currently ship in the npm tarball. Mirrors the SDK convention. Pure manifest fix; out of scope for this audit branch. Verification: - pnpm --filter @clearcms/renderer test → 32 passed (was 9) - pnpm --filter @clearcms/renderer typecheck → clean No new dependencies. No production code touched. No changeset. Co-authored-by: Engineer B <engineer-b@clearcms.dev> Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…0005) Adds canonical action vocabulary (~40 stable string IDs) and matrix shape contract for role enforcement. Same string IDs feed admin guards, REST-token-to-action mapping, the permissions panel UI, and the audit log subsystem when it lands. @clearcms/spec 0.3.1 -> 0.4.0 (additive).
…SLICE-0021 BUG-3)
`PagePageEditor.handlePublish` ran `await handleSave()` then guarded on
`dataErrors.length > 0 || errMsg !== null`. Those `setState` calls inside
`handleSave` had not flushed to the closure yet, so the guard always saw
the pre-call values and proceeded to call `pages.publish` on a page
whose `pageData.save` had just been rejected — the operator saw a
"Published" pill on data that was never persisted.
`handleSave` now returns `{ ok: boolean }`; `handlePublish` checks the
return value directly. Regression test added in
`PagePageEditor.test.tsx` — fails before the fix, passes after.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…021 BUG-4) `actions.settings.setLocales` wrote `default_locale`, `enabled_locales`, and `fallback_strategy` as three separate `settings` upserts in a non-transactional `for` loop. If the second upsert failed, the first had already been committed and the third never ran — leaving the project in a half-saved state with no recovery UX. Extracted the write to `lib/settings-locales.ts` and wrapped the loop in `db.transaction(...)`. Two regression tests in `settings-locales.test.ts`: - a transaction is opened (asserts the helper does not regress to a bare loop) - a forced failure on row 2 leaves the seeded row 1 untouched Both fail against the pre-fix bare-loop implementation. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…0021 BUG-5) Eight call sites in `lib/items.ts` and one in `lib/scheduler.ts` used `void indexItem(...)` / `void unindexItem(...)` to push the FTS write off the request path. Rejected promises were silently dropped — items saved successfully but search missed them with no log line and no doctor signal that anything was wrong, until an operator ran `clear-admin reindex`. `indexItemAsync` / `unindexItemAsync` keep the non-blocking shape but route rejections through a swappable logger that defaults to `console.error`. Tests can override the logger via `setFtsLoggerForTests`. Regression test in `search.test.ts` forces a rejected `execute` and asserts the logger is invoked. Pre-fix the `void` swallow caused the rejection to fall through to vitest's unhandledRejection handler and fail the run. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…ns (SLICE-0021) `actions.collections.setEditorMode` invalidates the collection-schema cache after writing; the four `fields.*` handlers (`create`, `update`, `delete`, `reorder`) did the bucket dual-write but skipped the invalidation. `loadCollectionSchema(slug)` could serve a compiled validator without the new field until the next bucket-watch tick. Drive-by fix from the save-flow audit's "across-the-board" cache recommendations. No new test — this is parity with `setEditorMode`, which already covers the pattern. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Astro's `defineAction` wrappers carry a complex type that doesn't
overlap with `vi.fn`'s `Mock<...>` shape under TS 6 strict-cast
checking, even though the runtime mock from `vi.mock('astro:actions')`
returns plain `vi.fn()`s. Cast through `unknown` to satisfy the
checker. No behavior change.
Follow-on to SLICE-0021 BUG-3 commit; surfaced by `pnpm -w typecheck`.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
New `widget: "markdown"` option in collection + layout schemas. Renders a raw-markdown textarea with a live preview pane and a small toolbar (bold / italic / link / heading / list); Cmd+B / Cmd+I / Cmd+K shortcuts wrap the selection or insert a link skeleton at the caret. Stores raw markdown text on save; the renderer parses at read time. Defaults to full width on the SchemaForm grid, mirroring textarea and richtext. Spec changes: - `'markdown'` added to `CLEAR_WIDGETS` (after `'textarea'`) - `widthFor` defaults markdown fields to `full` - minor: 0.3.1 -> 0.4.0 Admin changes: - new `apps/admin/src/components/widgets/Markdown.tsx` - `FieldRouter` routes `widget: "markdown"` to it - `AddFieldModal` exposes Markdown in the picker grid - preview HTML is sanitised against <script>, <iframe>, `javascript:` URIs, and inline event handlers (defence-in-depth; not a full DOMPurify pass) - minor: 0.4.2 -> 0.5.0 Tests: - `Markdown.test.tsx` — 21 cases: render, commit/save, toolbar, keyboard shortcuts, and edge cases (empty / very long / special characters / XSS strip) - `SchemaForm.test.tsx` — router + grid integration cases for the new widget; textarea regression guard - spec `widgetFor` / `widthFor` / `CLEAR_WIDGETS` updated for the enum extension Gates: 431 admin + 128 spec tests green; typecheck clean; CHANGELOGs updated for both packages; STATE.md bumped in clear/ + plan/. Acceptance criteria from SLICE.md all checked.
…cherry-pick collision)
After 005793e retired the PLAN.md+BATON.md coordination protocol, leaving the file absent created a discoverability hole for any returning collaborator. This stub replaces it with a 5-line redirect to the new clearcms/plan orchestration repo so anyone walking into clear/ on release/v1.0 lands on a clear pointer instead of a missing file.
clearcms/plan is private, so adopters can't reach individual ADR drafts. The public index is now the single source of truth for the *why* behind every decision: each ADR gets a 3–6 line plain-language paragraph in docs/adr/README.md alongside the status table. The 28 individual ADR files in docs/adr/ are removed; full long-form drafts continue to live in the private clearcms/plan repo under decisions/. ADR-0029 (spec v1 type vocabulary), 0031 (storage path resolvers + write-stamp), and 0032 (content lint engine shape) added to the index. STATE.md: bumped to 2026-05-08; "In flight — open PRs" replaced with Phase 7 done summary, Phase 7 cherry-picks (SLICE-0005 / 0021 / 0011) and SHAs, Phase 8 Stamp queue, and a note on the 3 open dependabot CVEs to clear before tag. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…pick collision) The SLICE-0011 markdown widget cherry-pick left two duplicate-key collisions in apps/admin/src/components/schema-designer/AddFieldModal.tsx that the companion 7b06585 fix only handled in @clearcms/spec: - WIDGET_DESCRIPTIONS had two entries for "markdown" (last-write-wins in JS, silently overwriting the first description). - The WIDGETS array listed "markdown" twice, which would render the markdown widget card twice in the picker grid. Both collapsed to a single entry each. Confirmed by clean rebuild — the "Duplicate key markdown in object literal" vite warning that landed on release/v1.0 after the cherry-picks is gone. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…-r build
The "tracked dist" footgun called out in STATE.md ("apps/admin/dist/ is
force-tracked despite .gitignore listing dist/ ... cleanup is its own task")
was wider than the two directories STATE.md mentioned. Five workspace dirs
were force-tracked:
- apps/admin/dist/
- packages/astro/dist/
- packages/index/dist/
- packages/sdk/dist/
- packages/spec/dist/
All five untracked via `git rm --cached -r`. The per-package
`packages/spec/.gitignore` that negated the root `dist/` rule
(`!dist/` + `!dist/**`, justified at the time as "consumers without a TS
toolchain can read the artifact") is removed; spec/dist now falls under the
root rule with the rest. Files stay on disk — npm publish builds fresh, so
adopters consuming via `@clearcms/*` packages are unaffected.
Fresh-clone workflow remains as STATE.md already directs:
pnpm install
pnpm -r build
Pre-v1.0.0 cleanup. Removes the largest source of "edits to source can land
out of sync with the tracked compiled output" footgun before the tag.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds pnpm.overrides to root package.json forcing patched versions of three transitive deps flagged by dependabot on clearcms/clear: - ip-address >=10.1.1 (was <= 10.1.0) — GHSA-v2v4-37r5-5v8g XSS in Address6 HTML methods - yaml >=2.8.3 (was < 2.8.3) — GHSA-48c2-rrv3-qjmp stack overflow on deeply-nested YAML collections - esbuild >=0.25.0 (was <= 0.24.2) — GHSA-67mh-4wv8-2f99 dev server lets any site read responses Verified resolved versions: ip-address@10.2.0, yaml@2.8.3, esbuild@0.25.12 + 0.27.7 (multiple esbuild copies in the tree, all on the patched line). Workspace clean after the bump: - pnpm typecheck: 278 files, 0 errors, 0 warnings - pnpm test: 527 tests passed across 49 test files Pre-tag cleanup. T-8.1 acceptance check item. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…ONTEXT
Surveyed 8 peer + agent-aware OSS repos (Payload / Strapi / Sanity / Directus
/ TinaCMS / KeystoneJS / Astro / Next.js). Universal at the root: README,
CONTRIBUTING, LICENSE. Near-universal: AGENTS.md (7/8), SECURITY.md (7/8).
Common: CODE_OF_CONDUCT.md (5/8), CLAUDE.md (4/8). Niche or absent:
ARCHITECTURE.md (1/8 — Sanity). Zero of eight have STATE / ROADMAP / CONTEXT
/ PLAN at the root — those are working-notes filenames, not OSS conventions.
This commit converges clear/ to that standard.
README.md ← rewritten. Absorbs ROADMAP "What's next" themes;
carries a "Current status" section pointing at
GitHub Releases as the canonical timeline. New
reading-order section reflects the trimmed surface.
ARCHITECTURE.md ← unchanged. Sanity precedent; useful deep-dive.
AGENTS.md ← rewritten. New read order (4 files instead of 7).
Documents the Issue-driven workflow, agent-ready
label convention, repo conventions for commits /
PRs / tests / changesets.
CLAUDE.md ← new, thin. Mirrors Payload / TinaCMS / Sanity / Next
pattern. Points at AGENTS.md as canonical; lists
project-specific Claude rules (caveman mode, no new
top-level docs, working-notes go to private plan/).
CONTEXT.md → moved to docs/glossary.md. Same content, standard
path/name. AGENTS.md and README link to the new
location.
STATE.md → deleted. Adopter-facing "what shipped when" lives
on the GitHub Releases page (the OSS standard).
Internal daily-touch state moves to plan/STATE.md
(private; trimmed in a companion commit there).
ROADMAP.md → deleted. Themes folded into README's "What's next"
section. Public-roadmap-as-Markdown isn't a
standard pattern; GitHub Projects + Issues is.
PLAN.md (stub) → deleted. A stub redirect to a private repo serves
no adopter purpose.
Net diff: 263 lines removed, 100 lines added. Public surface dropped from
~10 root Markdown files to 6 (README, ARCHITECTURE, AGENTS, CLAUDE,
CONTRIBUTING, LICENSE, SECURITY, CODE_OF_CONDUCT — the standard set).
Companion changes coming:
- Custom GitHub labels (agent-ready, human-only, priority:p0-p2, area:*).
- v1.x Project board with the 3-6 candidate work items pulled from the
private MASTER_PLAN.md before it's archived.
- plan/ repo shrink to its lean shape (decisions/ + thin STATE + archive).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…8 shape
Future sessions sometimes drift back to invented filenames (STATE.md /
ROADMAP.md / CONTEXT.md / PLAN.md / MASTER_PLAN.md / slices/) when the
working memory of why those were retired isn't surfaced. Adds a "Canonical
structure (locked 2026-05-08) — don't regress" section to CLAUDE.md that:
- States the fixed root surface (the 8 standard OSS files).
- Lists the retired patterns explicitly so a session reading CLAUDE.md
sees them by name and knows not to recreate them.
- Names where each piece of content actually lives now (Releases, Issues,
docs/glossary.md, docs/adr/README.md, packages/*/CHANGELOG.md).
- Tells future sessions to pause + confirm before regressing.
A companion section lands in plan/CLAUDE.md (private repo) for symmetry —
both Claude entry points carry the directive.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The cleanup that landed in 6a743ee (drop STATE/ROADMAP/PLAN/CONTEXT) and 90bce43 (consolidate 28 individual ADRs into a single index) left downstream cross-references unfixed. This commit walks every reference per the docs-audit checklist and applies the mechanical fixes: Class A — ./CONTEXT.md → ./docs/glossary.md ARCHITECTURE.md, CONTRIBUTING.md, apps/admin/README.md Class B — ./STATE.md → GitHub Releases + CHANGELOGs docs/adr/README.md (opening blurb) Class C — ./ROADMAP.md → per-package CHANGELOGs docs/known-issues.md Class D — ./docs/adr/<NNNN>-<topic>.md → ./docs/adr/README.md#<anchor> ARCHITECTURE.md (5 refs) CONTRIBUTING.md (1 ref) docs/glossary.md (10 refs) docs/deployment.md (1 ref) docs/migration-v0.2-to-v1.0.md (1 ref) docs/integrations/r2.md (2 refs) .changeset/README.md (1 ref) packages/create-clear/template/README.md (1 ref) packages/create-clear/template/theme-examples/README.md (1 ref) packages/design/README.md (1 ref) Class E — clearcms/clear-headless → clearcms/clear (old repo name) apps/admin/README.md (4 refs, npm-published) packages/core/README.md, packages/db/README.md, packages/mcp/README.md, packages/storage/README.md (1 each) Orphan — docs/prd/0002-site-tree-phase-2.md Single PRD in an otherwise-empty folder; not referenced from any active doc. Moved to clearcms/plan repo at archive/2026-05-08/imported-prd/. Empty docs/prd/ folder removed. Audit doc at docs/AUDIT-2026-05-08.md captures the full triage table and "applied this audit" log for diff against future audits. Two CHANGELOG historical mentions of STATE.md / ROADMAP.md were intentionally left alone (immutable changelog history). Deferred: currency-check pass on docs/CONTENT-PROTOCOL.md + docs/integrations/*.md + packages/*/README.md prose. Broken references are now fixed; verifying the prose itself is current is a follow-up before the v1.0.0 tag. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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 subscribe to this conversation on GitHub.
Already have an account?
Sign in.
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.
Summary
This is the v1.0.0 release PR — `release/v1.0` → `main`. Once merged, the changesets bot opens a "Version Packages" PR; merging that triggers the publish train across every `@clearcms/*` package.
Phases shipped
Off-PLAN ships (also live on main)
Acceptance (T-8.1)
Drafted
Marked draft because merging this PR triggers the publish train. Operator authorization required before:
Deferred to v1.0.x (filed as issues, not blocking)
🤖 Generated with Claude Code