@aotter/mantle 0.0.11-alpha.73 → 0.1.0-alpha.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +107 -28
- package/dist/admin.d.ts +2 -0
- package/dist/admin.d.ts.map +1 -0
- package/dist/admin.js +2 -0
- package/dist/admin.js.map +1 -0
- package/dist/bun.d.ts +2 -0
- package/dist/bun.d.ts.map +1 -0
- package/dist/bun.js +2 -0
- package/dist/bun.js.map +1 -0
- package/dist/cli/create.d.ts +2 -0
- package/dist/cli/create.d.ts.map +1 -0
- package/dist/cli/create.js +243 -0
- package/dist/cli/create.js.map +1 -0
- package/dist/cli/generate.d.ts.map +1 -0
- package/dist/cli/generate.js +101 -0
- package/dist/cli/generate.js.map +1 -0
- package/dist/cli/harness.d.ts +3 -0
- package/dist/cli/harness.d.ts.map +1 -0
- package/dist/{harness-cli.js → cli/harness.js} +13 -8
- package/dist/cli/harness.js.map +1 -0
- package/dist/cli/main.d.ts +3 -0
- package/dist/cli/main.d.ts.map +1 -0
- package/dist/{cli.js → cli/main.js} +6 -8
- package/dist/cli/main.js.map +1 -0
- package/dist/cli/skills.d.ts +3 -0
- package/dist/cli/skills.d.ts.map +1 -0
- package/dist/{skills.js → cli/skills.js} +51 -6
- package/dist/cli/skills.js.map +1 -0
- package/dist/cli/update.d.ts.map +1 -0
- package/dist/{update.js → cli/update.js} +72 -46
- package/dist/cli/update.js.map +1 -0
- package/dist/codegen/emitMantleModule.d.ts +16 -0
- package/dist/codegen/emitMantleModule.d.ts.map +1 -0
- package/dist/codegen/emitMantleModule.js +217 -0
- package/dist/codegen/emitMantleModule.js.map +1 -0
- package/dist/codegen.d.ts +2 -0
- package/dist/codegen.d.ts.map +1 -0
- package/dist/codegen.js +2 -0
- package/dist/codegen.js.map +1 -0
- package/dist/provision/renderProvisionBundle.d.ts +70 -0
- package/dist/provision/renderProvisionBundle.d.ts.map +1 -0
- package/dist/provision/renderProvisionBundle.js +367 -0
- package/dist/provision/renderProvisionBundle.js.map +1 -0
- package/dist/provision.d.ts +2 -0
- package/dist/provision.d.ts.map +1 -0
- package/dist/provision.js +2 -0
- package/dist/provision.js.map +1 -0
- package/dist/vercel-libsql.d.ts +2 -0
- package/dist/vercel-libsql.d.ts.map +1 -0
- package/dist/vercel-libsql.js +2 -0
- package/dist/vercel-libsql.js.map +1 -0
- package/dist/vercel.d.ts +2 -0
- package/dist/vercel.d.ts.map +1 -0
- package/dist/vercel.js +2 -0
- package/dist/vercel.js.map +1 -0
- package/dist/web.d.ts +2 -0
- package/dist/web.d.ts.map +1 -0
- package/dist/web.js +2 -0
- package/dist/web.js.map +1 -0
- package/docs/adapter-guide.md +95 -51
- package/docs/adr/0001-four-atom-manifest-model.md +48 -307
- package/docs/adr/0002-closed-enums-for-bindings.md +6 -15
- package/docs/adr/0007-ai-as-primary-author.md +6 -4
- package/docs/adr/0008-structured-diagnostic-shape.md +2 -2
- package/docs/adr/0009-consumer-supplied-manifests.md +15 -9
- package/docs/adr/0010-locale-and-translates.md +13 -8
- package/docs/adr/0011-adapter-port-spec.md +39 -43
- package/docs/adr/0012-views-as-public-rest.md +6 -10
- package/docs/adr/0014-auth-better-auth-and-multi-tenant-mcp.md +124 -43
- package/docs/adr/0018-core-starters-repository-boundary.md +22 -1
- package/docs/adr/0019-sealed-manifest-runtime-pipeline.md +204 -0
- package/docs/adr/README.md +16 -14
- package/docs/api-mcp-authorization.md +78 -44
- package/docs/assets/mantle-admin-operations.png +0 -0
- package/docs/assets/mantle-hero.jpg +0 -0
- package/docs/auth-hosting-model.md +15 -11
- package/docs/cloudflare-low-level-composition.md +30 -18
- package/docs/deferred-lifecycle-queues.md +20 -41
- package/docs/design-atoms.md +159 -400
- package/docs/labels.md +5 -3
- package/docs/media-uploads.md +9 -2
- package/docs/migration-0.1.2.md +45 -0
- package/docs/performance-harness.md +23 -23
- package/docs/release-process.md +91 -28
- package/docs/schema-indexes.md +1 -1
- package/docs/sealed-pipeline-ownership.md +100 -0
- package/package.json +85 -15
- package/skills/README.md +39 -7
- package/skills/develop/SKILL.md +33 -19
- package/skills/install/SKILL.md +26 -25
- package/skills/media-gc/SKILL.md +85 -0
- package/skills/plugin/SKILL.md +2 -1
- package/skills/provision/SKILL.md +24 -2
- package/skills/theme/SKILL.md +11 -1
- package/skills/update/SKILL.md +1 -0
- package/dist/cli.d.ts +0 -3
- package/dist/cli.d.ts.map +0 -1
- package/dist/cli.js.map +0 -1
- package/dist/generate.d.ts.map +0 -1
- package/dist/generate.js +0 -181
- package/dist/generate.js.map +0 -1
- package/dist/harness-cli.d.ts +0 -3
- package/dist/harness-cli.d.ts.map +0 -1
- package/dist/harness-cli.js.map +0 -1
- package/dist/skills.d.ts +0 -2
- package/dist/skills.d.ts.map +0 -1
- package/dist/skills.js.map +0 -1
- package/dist/update.d.ts.map +0 -1
- package/dist/update.js.map +0 -1
- /package/dist/{generate.d.ts → cli/generate.d.ts} +0 -0
- /package/dist/{update.d.ts → cli/update.d.ts} +0 -0
package/docs/labels.md
CHANGED
|
@@ -26,14 +26,14 @@ For package README or package-local docs changes, prefer the package area label
|
|
|
26
26
|
|
|
27
27
|
| Label | Meaning |
|
|
28
28
|
|---|---|
|
|
29
|
-
| `area:runtime` | `packages/mantle-runtime` behavior, ports, use cases, dispatcher,
|
|
29
|
+
| `area:runtime` | `packages/mantle-runtime` behavior, ports, use cases, dispatcher, and MCP runtime. |
|
|
30
30
|
| `area:spec` | `packages/mantle-spec`, manifest parsing, validation, diagnostics, CLI, spec types. |
|
|
31
31
|
| `area:cf` | `packages/adapters/cloudflare`, Workers adapter, D1/KV/ASSETS wiring, Cloudflare deploy behavior. |
|
|
32
32
|
| `area:starters` | External `aotter/mantle-starters` integration, release fanout, and the local moved-starter stub. |
|
|
33
33
|
| `area:skills` | `skills/*` agent briefs and install/extend/provision workflows. |
|
|
34
34
|
| `area:admin-ui` | `packages/mantle-admin-ui` React admin SPA. |
|
|
35
35
|
| `area:docs` | Repo-wide human docs, governance docs, ADR text, release docs, root README content, and cross-cutting documentation work. |
|
|
36
|
-
| `area:adapter` | Adapter boundary work spanning Cloudflare
|
|
36
|
+
| `area:adapter` | Adapter boundary work spanning Cloudflare or future adapters. |
|
|
37
37
|
|
|
38
38
|
## Release and review gates
|
|
39
39
|
|
|
@@ -41,7 +41,8 @@ For package README or package-local docs changes, prefer the package area label
|
|
|
41
41
|
|---|---|---|---|
|
|
42
42
|
| `release-gate` | Blocks a public release or release-quality claim. | Must be resolved or explicitly deferred before release. | The gate is closed or deferred by maintainer decision. |
|
|
43
43
|
| `v0.1.0` | Required for the v0.1.0 release gate. | Track in the v0.1.0 release pass. | The item lands or is moved out of v0.1.0. |
|
|
44
|
-
| `breaking-change` | Semver-relevant breaking change. |
|
|
44
|
+
| `breaking-change` | Semver-relevant breaking change. | Generated release notes must call it out. | The change is redesigned to be non-breaking. |
|
|
45
|
+
| `skip-release-notes` | Release bookkeeping with no user-facing change. | Excluded from generated GitHub Release notes. | The PR contains a user-facing change. |
|
|
45
46
|
| `needs-adr` | Architecture, trust boundary, package boundary, or long-lived decision needs an ADR or ADR-lite proposal. | Do not merge implementation until the decision is captured. | ADR/proposal lands or maintainer confirms an existing ADR covers it. |
|
|
46
47
|
| `needs-grammar-revise` | Manifest grammar or closed-enum change. | Requires grammar-revise round before code/types/starters change. | Grammar decision lands or the change no longer affects grammar. |
|
|
47
48
|
| `needs-discussion` | Not converged enough for implementation. | Do not start coding from this issue. | Closing criteria are met and scope is concrete. |
|
|
@@ -60,6 +61,7 @@ gh label create "area:admin-ui" --description "React admin UI" --color "1d76db"
|
|
|
60
61
|
gh label create "area:docs" --description "Documentation and governance" --color "1d76db"
|
|
61
62
|
gh label create "area:adapter" --description "Adapter boundary and future adapter work" --color "1d76db"
|
|
62
63
|
gh label create "breaking-change" --description "Semver-relevant breaking change" --color "b60205"
|
|
64
|
+
gh label create "skip-release-notes" --description "Release bookkeeping only; omit from generated GitHub notes" --color "ededed"
|
|
63
65
|
gh label create "needs-adr" --description "Requires an ADR or ADR-lite decision before merge" --color "d93f0b"
|
|
64
66
|
gh label create "needs-grammar-revise" --description "Requires manifest grammar review before implementation" --color "d93f0b"
|
|
65
67
|
gh label create "needs-discussion" --description "Not converged enough for implementation" --color "fbca04"
|
package/docs/media-uploads.md
CHANGED
|
@@ -78,7 +78,7 @@ wrangler secret put R2_SECRET_ACCESS_KEY
|
|
|
78
78
|
## `src/mantle/config.ts`
|
|
79
79
|
|
|
80
80
|
```ts
|
|
81
|
-
import { R2MediaStorage, type
|
|
81
|
+
import { R2MediaStorage, type MantleCloudflareConfig } from "@aotter/mantle/cloudflare";
|
|
82
82
|
import { AwsClient } from "aws4fetch";
|
|
83
83
|
|
|
84
84
|
export interface Env {
|
|
@@ -89,7 +89,7 @@ export interface Env {
|
|
|
89
89
|
readonly MEDIA_PUBLIC_URL_BASE?: string;
|
|
90
90
|
}
|
|
91
91
|
|
|
92
|
-
function buildMediaStorage(env: Env):
|
|
92
|
+
function buildMediaStorage(env: Env): MantleCloudflareConfig["bindings"]["mediaStorage"] {
|
|
93
93
|
if (
|
|
94
94
|
!env.MEDIA_BUCKET ||
|
|
95
95
|
!env.R2_ACCOUNT_ID ||
|
|
@@ -177,3 +177,10 @@ Preserve source semantics:
|
|
|
177
177
|
- animated GIFs must stay animated;
|
|
178
178
|
- do not silently flatten, resize, or recompress user assets without
|
|
179
179
|
asking.
|
|
180
|
+
|
|
181
|
+
## Cleanup
|
|
182
|
+
|
|
183
|
+
Run the version-matched `media-gc` skill when an upload reached R2 but was
|
|
184
|
+
never committed. It audits first and removes only stale objects without
|
|
185
|
+
`committedAt` metadata after explicit operator confirmation. Do not use an R2
|
|
186
|
+
lifecycle rule: committed and uncommitted media share the same purpose prefix.
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# Migrating from 0.1.0-alpha.7 to 0.1.2
|
|
2
|
+
|
|
3
|
+
0.1.2 removes the temporary full-site compatibility stack. Mantle Core is now
|
|
4
|
+
an embeddable parse → link → compile → prepare → bind pipeline; Web, Admin,
|
|
5
|
+
Admin UI, Bun, Vercel, and Cloudflare are selected separately.
|
|
6
|
+
|
|
7
|
+
| alpha.7 | 0.1.2 |
|
|
8
|
+
|---|---|
|
|
9
|
+
| `parseManifests*` | `parseManifestSources({ sources })` |
|
|
10
|
+
| raw `Manifest[]` validation/runtime input | `ParsedManifestSet` → `LinkedManifestSet` → `RuntimePlan` |
|
|
11
|
+
| `createCmsRuntime({ manifests, db })` | `bootMantleRuntime({ plan, storage })`, or explicit prepare then `createMantleRuntime({ prepared })` |
|
|
12
|
+
| `CmsRuntime.db` / `entryReader` | keep the application DB handle; use `runtime.entries` for Mantle reads |
|
|
13
|
+
| generated `manifest`, `site.ts`, `types.d.ts` | generated `plan`, `createMantle`, `bindMantle`, and types in `mantle.ts` |
|
|
14
|
+
| `mantle introspect` | install `@aotter/mantle-spec` directly and run `mantle-spec introspect` |
|
|
15
|
+
| `mantle emit-types` | use `mantle generate`; for raw declarations, run `mantle-spec emit-types` |
|
|
16
|
+
| generated `.agent/skills/` | generated `.agents/skills/`; legacy user files are left untouched |
|
|
17
|
+
| `bindMantleSite` / string-keyed Views | `bindMantle(runtime)` and generated lower-camel properties |
|
|
18
|
+
| `createCmsRef` / `CmsConfig` | `createMantleRuntimeRef` / `MantleCloudflareConfig` |
|
|
19
|
+
| `mountServerEndpoints` | explicitly compose `mountRuntimeEndpoints` and optional `mountAdmin` |
|
|
20
|
+
|
|
21
|
+
Delete stale generated `site.ts` and `types.d.ts` files once, then run
|
|
22
|
+
`mantle generate`. Install only the optional package used by the host;
|
|
23
|
+
installing the umbrella alone now pulls only Spec and Runtime.
|
|
24
|
+
|
|
25
|
+
Intentional behavior changes:
|
|
26
|
+
|
|
27
|
+
- Generated-plan fingerprint or version mismatches fail immediately and ask
|
|
28
|
+
the developer to regenerate.
|
|
29
|
+
- Runtime HTTP trigger JSON bodies must be objects. Arrays and primitives are
|
|
30
|
+
rejected at the request boundary.
|
|
31
|
+
- Malformed percent-encoded paths are routing misses (`404`), not claimed
|
|
32
|
+
Mantle routes.
|
|
33
|
+
- Better Auth and every `@better-auth/*` package move together to 1.7.
|
|
34
|
+
`oauthProvider.validAudiences` becomes protected `resources`; MCP uses one
|
|
35
|
+
canonical `${PUBLIC_ORIGIN}/mcp` resource and CIMD client discovery.
|
|
36
|
+
- The Cloudflare adapter no longer requires `OAUTH_KV` or
|
|
37
|
+
`@cloudflare/workers-oauth-provider`. Old opaque tokens and KV registrations
|
|
38
|
+
cannot be migrated safely and must reconnect.
|
|
39
|
+
- Canonical plan ordering may change stable field/export order (including
|
|
40
|
+
Admin CSV columns) without changing field values.
|
|
41
|
+
|
|
42
|
+
This alpha changes the Better Auth D1 schema, including required account
|
|
43
|
+
issuer identity and OAuth resource/client tables. Reset and re-bootstrap a
|
|
44
|
+
pre-1.7 alpha auth database; do not guess an issuer backfill. Content tables
|
|
45
|
+
remain portable through the normal application migration/export path.
|
|
@@ -10,30 +10,29 @@ make a normal content/API/page change.
|
|
|
10
10
|
| Read or state | Owner | Notes |
|
|
11
11
|
|---|---|---|
|
|
12
12
|
| Entry get/list and public slug/data-field/published reads | `DatabaseEntryRepository` through `EntryRepository` / `EntryReader` | Schema-aware field resolution is shared here. |
|
|
13
|
-
| Manifest View execution | `ExecuteViewUseCase` + `
|
|
13
|
+
| Manifest View execution | `ExecuteViewUseCase` + prepared `ViewQueryExecutor` | Core owns authorization and request validation; selected storage lowers queries once and resolves declared Schema indexes. |
|
|
14
14
|
| Editable settings and code-owned locale/media policy | `DatabaseSiteConfigRepository` | Editable values and dynamic media tool policy are read fresh; boot-seeded locale policy may be memoized within the runtime instance. |
|
|
15
15
|
| Pending media uploads | `DatabasePendingUploadRepository` | Canonical, read-after-write D1 state; never publish-cache state. |
|
|
16
|
-
| Rendered HTML, Markdown, and `llms.txt` |
|
|
17
|
-
| D1
|
|
16
|
+
| Rendered HTML, Markdown, and `llms.txt` | Request-time render use cases plus the Cloudflare public-route cache policy | D1 is canonical; version-local Workers Cache stores anonymous HTTP responses. |
|
|
17
|
+
| D1 transport and optional query metrics | Cloudflare bindings | Bindings stay thin. Query/cache policy does not belong in a generic provider `BaseRepository`. |
|
|
18
18
|
|
|
19
|
-
|
|
20
|
-
|
|
19
|
+
The runtime exposes no raw database handle. Application and adapter code uses
|
|
20
|
+
the sealed plan, runtime use cases, `entries`, and `siteConfig`. An application may own
|
|
21
21
|
additional tables behind its own repository at the composition root, but it
|
|
22
|
-
must not query Mantle-owned tables
|
|
22
|
+
must not query Mantle-owned tables outside the selected storage adapter.
|
|
23
23
|
|
|
24
24
|
## Cache contract
|
|
25
25
|
|
|
26
26
|
- D1 is canonical for entries, site settings, media metadata, and pending
|
|
27
|
-
uploads.
|
|
28
|
-
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
-
|
|
35
|
-
|
|
36
|
-
scan/delete KV prefixes themselves.
|
|
27
|
+
uploads. Core stores no rendered artifact copies.
|
|
28
|
+
- Public routes render canonical state and return
|
|
29
|
+
`Cache-Control: public, max-age=0, s-maxage=300`.
|
|
30
|
+
- Cloudflare Workers Cache checks eligible anonymous responses before invoking
|
|
31
|
+
the Worker. Cache keys are version-local, so a deploy starts with no stale
|
|
32
|
+
response from the previous Worker version.
|
|
33
|
+
- Successful publishing-content and site-setting writes purge the shared
|
|
34
|
+
`mantle-public` Cache-Tag through Cloudflare's native cache API. Operational
|
|
35
|
+
records and immutable assets stay outside that invalidation boundary.
|
|
37
36
|
- Do not cache every repository read. Cross-isolate correctness for editable
|
|
38
37
|
data wins unless a read has a measured hot-path contract and explicit
|
|
39
38
|
invalidation.
|
|
@@ -76,11 +75,12 @@ Timing always reports p50/p95/max. A test-only Worker wrapper may also return
|
|
|
76
75
|
`x-mantle-query-count` and `x-mantle-rows-read`; those become distributions in
|
|
77
76
|
the same report. Do not expose these diagnostic headers in production.
|
|
78
77
|
|
|
79
|
-
Core CI runs `pnpm bench:wrangler` against real Wrangler-local D1,
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
78
|
+
Core CI runs `pnpm bench:wrangler` against real Wrangler-local D1, Worker HTTP
|
|
79
|
+
routing, View execution, and origin page rendering. It compares 100 and 10,000
|
|
80
|
+
row fixtures and gates row-read scaling plus endpoint query budgets, not
|
|
81
|
+
absolute milliseconds. Wrangler-local does not emulate the new entrypoint
|
|
82
|
+
Workers Cache, so cache hits are a deployment-level smoke check rather than a
|
|
83
|
+
fabricated local metric.
|
|
84
84
|
|
|
85
85
|
## Seven findings: measured disposition
|
|
86
86
|
|
|
@@ -89,12 +89,12 @@ diagnostic, while query/row counts are the stable assertions.
|
|
|
89
89
|
|
|
90
90
|
| Finding | Disposition |
|
|
91
91
|
|---|---|
|
|
92
|
-
| Public
|
|
92
|
+
| Public cache hits read D1 first | Removed from Worker code. Cloudflare's entrypoint Workers Cache runs before the Worker; Core has no inner render cache. |
|
|
93
93
|
| Slug/locale reads bypass generated indexes | Fixed by the shared schema-aware entry-read boundary. A 10,000-row page MISS measured 2 queries / 5 rows read. |
|
|
94
94
|
| OFFSET pagination | Accepted for the v0.1 bounded-result surfaces: every response is capped at 500 rows and public hot paths must stay shallow. Deep/export workloads require a purpose-shaped cursor API before they are declared hot. |
|
|
95
95
|
| Admin substring search scans | Accepted only for the authenticated Admin collection browser, with a 500-row response cap. Large/search-heavy sites should add a purpose-shaped indexed View or dedicated search service; do not expose this scan publicly. |
|
|
96
96
|
| Published list/sitemap/llms paths lack system indexes | Fixed with measured partial indexes for published global, locale, collection, and collection+locale ordering. The 100-row and 10,000-row API runs both measured 1 query / 20 rows read. |
|
|
97
|
-
| Page MISS waits for
|
|
97
|
+
| Page MISS waits for cache write-back | Removed. Origin rendering returns directly; Workers Cache owns response storage outside the Worker. |
|
|
98
98
|
| Benchmark stops at fake in-process dispatch | Fixed by the Node planner and Wrangler-local Worker/API/page layers. The old dispatch microbenchmark remains a narrow CPU signal only. |
|
|
99
99
|
|
|
100
100
|
The retained OFFSET and substring-search trade-offs are visible exceptions,
|
package/docs/release-process.md
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
# Release process
|
|
2
2
|
|
|
3
|
-
Mantle
|
|
4
|
-
versions, Git tags, GitHub releases, and Starter tags are
|
|
5
|
-
bad release with the next version, never by replacing
|
|
3
|
+
Mantle remains prerelease software until the stable v0.1.0 gate closes.
|
|
4
|
+
Published package versions, Git tags, GitHub releases, and Starter tags are
|
|
5
|
+
immutable: repair a bad release with the next version, never by replacing
|
|
6
|
+
public state.
|
|
6
7
|
|
|
7
8
|
## Authority
|
|
8
9
|
|
|
@@ -15,10 +16,12 @@ The controller owns this order:
|
|
|
15
16
|
```text
|
|
16
17
|
Core source + exact-packed Starter gates
|
|
17
18
|
-> Core tag
|
|
18
|
-
-> npmjs + GitHub Packages
|
|
19
|
+
-> npmjs + GitHub Packages candidate packages (`mantle-release`)
|
|
19
20
|
-> Starter release worker
|
|
20
21
|
-> immutable Starter tag
|
|
21
22
|
-> public-registry Starter gate
|
|
23
|
+
-> clean-create + reviewed Landing compatibility gates
|
|
24
|
+
-> npmjs + GitHub Packages public channel promotion
|
|
22
25
|
-> Core GitHub Release
|
|
23
26
|
-> optional Landing worker
|
|
24
27
|
```
|
|
@@ -45,23 +48,54 @@ verdict expires when that SHA changes. After two patch rounds, a new
|
|
|
45
48
|
foundational blocker returns to the state table and the user for a scope
|
|
46
49
|
decision instead of starting another local redesign loop.
|
|
47
50
|
|
|
51
|
+
For the candidate-to-channel transition, the controller follows this finite
|
|
52
|
+
state table:
|
|
53
|
+
|
|
54
|
+
| Durable state | Permitted next mutation | Re-run behavior | Public channel |
|
|
55
|
+
|---|---|---|---|
|
|
56
|
+
| Source gated; version unused | Create the immutable Core tag | Existing tag must match or the run fails | Unchanged |
|
|
57
|
+
| Core tag exists; candidate packages incomplete | Publish and verify missing exact versions under `mantle-release` through each registry's sole publish step | Existing versions are verified and skipped | Unchanged |
|
|
58
|
+
| Candidate packages verified; Starter tag absent | Dispatch the pinned Starter release and wait | The Starter worker resumes or reports its matching no-op | Unchanged |
|
|
59
|
+
| Matching Starter tag exists | Validate its Core/base provenance; run the frozen Starter, clean-create, and Landing compatibility gates | Validation and gates repeat without mutation | Unchanged |
|
|
60
|
+
| All downstream consumer gates pass | Promote npmjs and GitHub Packages channel tags monotonically | Same version is a no-op; an older run preserves a newer tag | Candidate or newer version |
|
|
61
|
+
| Channels promoted or preserved newer | Create the Core GitHub Release | Existing matching release is a no-op | Candidate or newer version |
|
|
62
|
+
| Core GitHub Release exists | Dispatch Landing only when explicitly enabled | Landing remains untouched by default | Candidate or newer version |
|
|
63
|
+
|
|
64
|
+
Invariants:
|
|
65
|
+
|
|
66
|
+
- immutable package versions and Core/Starter tags must keep the requested
|
|
67
|
+
version, Core SHA, and pinned Starter SHA identity;
|
|
68
|
+
- public channel tags cannot move until the released Starter, clean-create, and
|
|
69
|
+
reviewed Landing compatibility gates pass;
|
|
70
|
+
- channel updates use the controller's monotonic promotion boundary, so an
|
|
71
|
+
older re-run cannot move a channel backward;
|
|
72
|
+
- the candidate version may be fetched explicitly or through the temporary
|
|
73
|
+
`mantle-release` tag before promotion, but is not the public channel default.
|
|
74
|
+
|
|
75
|
+
Non-goals: this transition does not change Starter worker ownership, add
|
|
76
|
+
rollback or unpublish behavior, or deploy Landing unless
|
|
77
|
+
`deploy_landing=true`.
|
|
78
|
+
|
|
48
79
|
## Branches and channels
|
|
49
80
|
|
|
50
81
|
- Feature and release PRs target `develop`.
|
|
51
|
-
-
|
|
82
|
+
- Alpha prereleases before stable v0.1.0 release directly from the merged
|
|
83
|
+
`develop` release commit.
|
|
52
84
|
- Beta, RC, and stable promotion to `main` remains a deliberate human decision;
|
|
53
85
|
it is not part of the alpha controller.
|
|
54
86
|
- Alpha, beta, and RC GitHub releases are prereleases.
|
|
55
87
|
- npm dist-tags follow the suffix: `alpha`, `beta`, `rc`, or `latest` for
|
|
56
88
|
stable versions.
|
|
57
|
-
- During the
|
|
58
|
-
|
|
89
|
+
- During the legacy `0.0.x-alpha` cadence, `latest` follows the current alpha.
|
|
90
|
+
The final `0.1.0-alpha.N` candidates advance only `alpha`; `latest` moves to
|
|
91
|
+
`0.1.0` after the stable gate passes.
|
|
59
92
|
|
|
60
93
|
## Release PR
|
|
61
94
|
|
|
62
95
|
1. Fetch Core and Starter remotes and choose the next unused version.
|
|
63
|
-
2.
|
|
64
|
-
|
|
96
|
+
2. Preview GitHub's generated notes for the merged commits since the previous
|
|
97
|
+
tag. Correct PR titles and labels before release; do not duplicate the notes
|
|
98
|
+
in `CHANGELOG.md`. Label the release-only PR `skip-release-notes`.
|
|
65
99
|
3. Set that exact version in every workspace package and in all four agent
|
|
66
100
|
plugin manifests. Set `.agents/plugins/marketplace.json` to the immutable
|
|
67
101
|
`v<version>` ref.
|
|
@@ -75,18 +109,37 @@ decision instead of starting another local redesign loop.
|
|
|
75
109
|
packed-consumer gate. Review and merge a same-repository PR into `develop`;
|
|
76
110
|
the controller rejects a direct-push release commit.
|
|
77
111
|
|
|
78
|
-
|
|
112
|
+
Preview the native notes before merging the release PR:
|
|
113
|
+
|
|
114
|
+
```bash
|
|
115
|
+
gh api --method POST repos/aotter/mantle/releases/generate-notes \
|
|
116
|
+
-f tag_name=vX.Y.Z \
|
|
117
|
+
-f target_commitish="$(git rev-parse origin/develop)" \
|
|
118
|
+
-f previous_tag_name=vPREVIOUS \
|
|
119
|
+
--jq .body
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
The nine public packages publish in dependency order:
|
|
79
123
|
|
|
80
124
|
1. `@aotter/mantle-spec`
|
|
81
125
|
2. `@aotter/mantle-admin-ui`
|
|
82
126
|
3. `@aotter/mantle-runtime`
|
|
83
|
-
4. `@aotter/mantle-
|
|
84
|
-
5. `@aotter/mantle`
|
|
127
|
+
4. `@aotter/mantle-web`
|
|
128
|
+
5. `@aotter/mantle-admin`
|
|
129
|
+
6. `@aotter/mantle-bun`
|
|
130
|
+
7. `@aotter/mantle-vercel`
|
|
131
|
+
8. `@aotter/mantle-cloudflare`
|
|
132
|
+
9. `@aotter/mantle`
|
|
85
133
|
|
|
86
134
|
The umbrella package must contain its version-matched `docs/` and `skills/`
|
|
87
135
|
payload. No tarball may contain `workspace:*` dependencies, secrets, local
|
|
88
|
-
state, or workspace-only files. Starter
|
|
89
|
-
versioned `mantle-starters` repository
|
|
136
|
+
state, or workspace-only files. Starter content is still authored and released
|
|
137
|
+
from the versioned `mantle-starters` repository — Core owns no starter source.
|
|
138
|
+
Core's umbrella CLI is the canonical consumer of that release: `mantle create`
|
|
139
|
+
resolves the official immutable `v${packageVersion}` starter tag and renders it
|
|
140
|
+
through Core's shared provision module. A published Core version
|
|
141
|
+
therefore requires the matching starter tag to exist; see
|
|
142
|
+
[ADR-0018](adr/0018-core-starters-repository-boundary.md).
|
|
90
143
|
|
|
91
144
|
## Run the controller
|
|
92
145
|
|
|
@@ -101,16 +154,20 @@ Before creating the Core tag, the controller proves:
|
|
|
101
154
|
- the requested version matches every package, plugin, and marketplace ref;
|
|
102
155
|
- `pnpm check` passes;
|
|
103
156
|
- packed Core passes in the exact pinned Starter source;
|
|
104
|
-
- all
|
|
157
|
+
- all nine release tarballs exist;
|
|
105
158
|
- npm and cross-repository credentials are present and readable;
|
|
106
159
|
- a fresh version is unused across npmjs, GitHub Packages, and Starter tags;
|
|
107
160
|
- the pinned Starter commit is still the remote `develop` tip.
|
|
108
161
|
|
|
109
|
-
After
|
|
110
|
-
the locally packed tarball, rejects leaked
|
|
111
|
-
for the Starter tag, checks that tag's exact
|
|
112
|
-
frozen locks from the public registry, and
|
|
113
|
-
|
|
162
|
+
After candidate publication under `mantle-release`, it compares each public
|
|
163
|
+
registry integrity value with the locally packed tarball, rejects leaked
|
|
164
|
+
`workspace:*` dependencies, waits for the Starter tag, checks that tag's exact
|
|
165
|
+
Core/base provenance, installs its frozen locks from the public registry, and
|
|
166
|
+
reruns the Starter bundle gates. It then creates clean Blank and multilingual
|
|
167
|
+
Transaction projects through the registry candidate, frozen-installs and checks
|
|
168
|
+
both, and runs the reviewed Landing consumer against the exact packed candidate.
|
|
169
|
+
Only then does it promote the public npmjs and GitHub Packages channel tags and
|
|
170
|
+
create the Core GitHub Release.
|
|
114
171
|
|
|
115
172
|
## Idempotency and recovery
|
|
116
173
|
|
|
@@ -135,7 +192,7 @@ Core repository secrets:
|
|
|
135
192
|
|
|
136
193
|
| Secret | Minimum purpose |
|
|
137
194
|
|---|---|
|
|
138
|
-
| `NPM_TOKEN` | Publish the
|
|
195
|
+
| `NPM_TOKEN` | Publish the nine `@aotter/*` packages on npmjs. |
|
|
139
196
|
| `RELEASE_FANOUT_TOKEN` | Read and dispatch `aotter/mantle-starters`; also read and dispatch `aotter/mantle-landing` only when Landing is enabled. |
|
|
140
197
|
|
|
141
198
|
Core's job-scoped `GITHUB_TOKEN` creates the Core tag and release and mirrors
|
|
@@ -158,18 +215,24 @@ for p in \
|
|
|
158
215
|
@aotter/mantle-spec \
|
|
159
216
|
@aotter/mantle-admin-ui \
|
|
160
217
|
@aotter/mantle-runtime \
|
|
218
|
+
@aotter/mantle-web \
|
|
219
|
+
@aotter/mantle-admin \
|
|
220
|
+
@aotter/mantle-bun \
|
|
221
|
+
@aotter/mantle-vercel \
|
|
161
222
|
@aotter/mantle-cloudflare \
|
|
162
223
|
@aotter/mantle; do
|
|
163
224
|
npm view "$p@X.Y.Z" version dist.integrity dependencies --json
|
|
164
225
|
done
|
|
165
226
|
```
|
|
166
227
|
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
a
|
|
172
|
-
|
|
228
|
+
The controller already creates and checks clean Blank and multilingual
|
|
229
|
+
Transaction projects. For 0.1.2 release acceptance, give a coding agent with no
|
|
230
|
+
Mantle checkout or repository knowledge only the generated instructions and
|
|
231
|
+
confirm it reaches a running Worker. This is one manual clean-room acceptance,
|
|
232
|
+
not a nondeterministic CI framework. Confirm the generated project contains
|
|
233
|
+
version-matched repo-local Mantle skills and the expected typed runtime surface.
|
|
234
|
+
`blank` remains headless and contains no Kiwa; a typed Starter revision may
|
|
235
|
+
retain its replaceable offline UI palette, but runtime code must not import it.
|
|
173
236
|
|
|
174
237
|
If `deploy_landing=false`, also verify that no Landing release dispatch or
|
|
175
238
|
deployment was started.
|
|
@@ -177,7 +240,7 @@ deployment was started.
|
|
|
177
240
|
## Fix-forward policy
|
|
178
241
|
|
|
179
242
|
- Broken public package or Starter bundle: publish the next alpha and explain
|
|
180
|
-
the re-spin in
|
|
243
|
+
the re-spin in the fix PR and generated GitHub Release notes.
|
|
181
244
|
- Use `npm deprecate` to steer consumers away from a broken version.
|
|
182
245
|
- Unpublish only for secrets, private files, or similarly severe exposure;
|
|
183
246
|
npm versions cannot be reused and registry metadata may remain unavailable
|
package/docs/schema-indexes.md
CHANGED
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
# Sealed pipeline ownership ledger
|
|
2
|
+
|
|
3
|
+
This is the migration evidence for ADR-0019 and epic #656. It records the
|
|
4
|
+
`v0.1.0-alpha.7` owners before code moves, the single target owner, and the
|
|
5
|
+
issue that must delete or delegate the old path.
|
|
6
|
+
|
|
7
|
+
## Rule ownership
|
|
8
|
+
|
|
9
|
+
| Behavior | Current owner(s) | Target owner | Migration |
|
|
10
|
+
|---|---|---|---|
|
|
11
|
+
| YAML document decode, empty documents, syntax errors, alias cap | `ManifestParser.parseOneStream` | Parse/decode in `mantle-spec` | #663 |
|
|
12
|
+
| Four-atom discrimination, envelope keys, primitive/enum shape | `ManifestParser` | Parse/normalize | #663 |
|
|
13
|
+
| Source identity and document location | Synthetic parser doc index plus `loadManifests`/`ManifestPathDiagnoser` reconstruction | `ManifestSourceSet` authored metadata | #663 |
|
|
14
|
+
| Schema atom-local shape, index/search/UI shape | Parser plus `ValidateManifestsUseCase` checkers | Parse/normalize | #663; old checks deleted in #673 |
|
|
15
|
+
| Defaults for localized/lifecycle/indexes/search/order | `IntrospectManifestsUseCase`, runtime lifecycle checks, and callers using `??` | Parse/normalize exactly once | #663, #667 |
|
|
16
|
+
| Duplicate names | `ValidateManifestsUseCase` | Link | #664 |
|
|
17
|
+
| Schema/View/Procedure/Trigger cross-references | `ValidateManifestsUseCase` and repeated boot checks | Link | #664 |
|
|
18
|
+
| Guard existence, self-reference, builtin/chain rules | Validate plus `ValidateBootUseCase` | Link | #664 |
|
|
19
|
+
| Locale/translates graph | `checkLocaleAndTranslates` in validate and boot | Link for manifest graph; Prepare for selected deployment locales | #664, #666 |
|
|
20
|
+
| Manifest-owned HTTP/MCP collisions | Validate plus boot | Link | #664 |
|
|
21
|
+
| Handler source/registry availability | Optional CLI source scan plus boot registry scan | Prepare | #666 |
|
|
22
|
+
| Optional Web/Admin/Auth path reservations | Fixed boot/Cloudflare prefix lists | Prepare selected capabilities only | #666, #669, #670 |
|
|
23
|
+
| Kind/name lookup maps | `ValidateManifestsUseCase`, `ValidateBootUseCase`, `createCmsRuntime`, adapters | Compile once into `RuntimePlan` | #665 |
|
|
24
|
+
| Authorization/guard descriptors | Raw manifests interpreted by validators, runtime use cases, and mounts | Compile plan; evaluate in Core invocation | #665, #667 |
|
|
25
|
+
| Trigger indices and Procedure descriptors | Runtime construction/use cases | Compile plan | #665 |
|
|
26
|
+
| Semantic fingerprint | Runtime boot from raw manifests | Compile plan | #665 |
|
|
27
|
+
| Declarative View resolution | `ViewSqlCompiler` during each `ExecuteViewUseCase` call | Compile logical plan once | #665 |
|
|
28
|
+
| SQLite/JSON1 View lowering and native `spec.sql` | `ViewSqlCompiler` plus `DatabaseDriver` invocation | Selected storage preparation | #666 |
|
|
29
|
+
| Canonical SQL migrations, indexes, schema SQL Views, readiness | `createCmsRuntime.bootInit` and runtime infrastructure | Prepare | #666 |
|
|
30
|
+
| Entry/media/site repositories | Runtime constructs `Database*Repository` from `DatabaseDriver` | Prepared semantic storage ports; media/config move with final owner | #666, #669, #670 |
|
|
31
|
+
| Content, View, Procedure, Trigger, lifecycle invocation | Runtime use cases over raw maps/driver | `MantleRuntime` over plan + semantic ports | #667 |
|
|
32
|
+
| Target authorization/admin bypass | Runtime plus adapter entry points | One Core invocation policy; adapter resolves caller only | #667 |
|
|
33
|
+
| Generated manifest module and TypeScript names | `packages/mantle/src/cli/generate.ts` + `EmitTypesUseCase` | Pure linked/plan projection and `bindMantle` | #668 |
|
|
34
|
+
| Admin asset copy during generation | `packages/mantle/src/cli/generate.ts` | Removed; Admin install/composition owns assets | #668, #670 |
|
|
35
|
+
| HTML/templates/public paths/Markdown/SEO/preview/`llms.txt`/sitemap | Runtime render services plus Cloudflare public routes | Optional `mantle-web` | #669 |
|
|
36
|
+
| Public request mapping and cache policy | `mountPublicRoutes` | Platform adapter using selected Web projection | #669 |
|
|
37
|
+
| Admin API/application/static assets | Optional `mantle-admin`; Cloudflare only binds auth/request context/assets | Optional `mantle-admin` + existing UI artifact | #670 |
|
|
38
|
+
| View/HTTP Trigger route transport | Combined Cloudflare mounts | Platform adapters over the same Core descriptors | #669–#672 |
|
|
39
|
+
| Bun SQLite/process lifecycle | `mantle-bun`; host owns server/database | `mantle-bun`; host owns server/database | #671 |
|
|
40
|
+
| Vercel function/durable-storage lifecycle | `mantle-vercel`; host owns handler/client | `mantle-vercel`; host owns handler/client | #672 |
|
|
41
|
+
| Legacy overloads, aliases, combined mounts, duplicate tests | Current public API plus temporary migration delegates | Deleted | #673 |
|
|
42
|
+
| Contributor/agent/release guidance | `AGENTS.md`, `CLAUDE.md`, `CONTRIBUTING.md`, two release skill copies | One tool-neutral authority and one release skill | #674 |
|
|
43
|
+
|
|
44
|
+
## Deletion evidence
|
|
45
|
+
|
|
46
|
+
All baseline production callers now consume `ParsedManifestSet`,
|
|
47
|
+
`LinkedManifestSet`, or `RuntimePlan` according to their pipeline stage.
|
|
48
|
+
`scripts/check-boundaries.mjs` fails if the removed runtime facade, generated
|
|
49
|
+
site API, raw parser facade, or combined Cloudflare route owner returns.
|
|
50
|
+
Parser-focused tests may inspect parser output, but runtime and platform tests
|
|
51
|
+
must compile and prepare the same sealed plan used by production.
|
|
52
|
+
|
|
53
|
+
## Consumer manifest corpus
|
|
54
|
+
|
|
55
|
+
The Core repository does not vendor every downstream manifest. That would
|
|
56
|
+
create a second source of truth. The reusable golden fixture under
|
|
57
|
+
`packages/mantle-spec/test/fixtures/pipeline-v0.1/` covers every shipped atom,
|
|
58
|
+
auth/guard references, all Trigger surfaces, multi-document YAML, empty
|
|
59
|
+
documents, aliases, unknown keys, malformed YAML, and deterministic
|
|
60
|
+
diagnostics.
|
|
61
|
+
|
|
62
|
+
Exact downstream sources and their gate authorities are pinned here. The public
|
|
63
|
+
Starter runs in Core CI and release preflight. Private consumers run the same
|
|
64
|
+
exact-tarball checker in their own repositories, so public Core PRs never
|
|
65
|
+
receive cross-repository credentials:
|
|
66
|
+
|
|
67
|
+
| Consumer | Revision | Gate authority | Manifest paths |
|
|
68
|
+
|---|---|---|---|
|
|
69
|
+
| `aotter/mantle-starters` | `157e8f49e1e25ae1c52c0115f0dd9e8b6017ef0e` | Core CI + release | `blank/manifests/site.yaml`; `overlays/{community,intake,presence,publication,reservation,transaction}/manifests/site.yaml`; `recipes/typed-web/manifests/site.yaml` |
|
|
70
|
+
| `aotter/mantle-landing` | `4381354dd25d5d94f4096cf3e55a4cb9eecbf3ad` | Landing CI + Core release | `manifests/site.yaml` |
|
|
71
|
+
| `aotter/mantle-platform` (Remote Mantle/control plane) | `3cc0d9ad6ee47b15f06c915c12f56fc4b9143f32` | Platform `exact-packed-core` | `manifests/platform.yaml` |
|
|
72
|
+
| Core i18n fixture | this repository | Core CI | `packages/mantle-spec/test/fixtures/i18n-parent-child/manifests/site.yaml` |
|
|
73
|
+
|
|
74
|
+
## Baseline gates
|
|
75
|
+
|
|
76
|
+
The alpha.7 baseline was captured from tag `v0.1.0-alpha.7` on 2026-08-16
|
|
77
|
+
with Node 22, pnpm 9, Wrangler local mode, and datasets of 100/10,000 rows:
|
|
78
|
+
|
|
79
|
+
| Route | p95 queries | p95 rows read | local p95 timing |
|
|
80
|
+
|---|---:|---:|---:|
|
|
81
|
+
| public View, 10k rows | 1 | 20 | 3.01 ms |
|
|
82
|
+
| public page miss, 10k rows | 2 | 5 | 3.92 ms |
|
|
83
|
+
| Admin list, 10k rows | 1 | 21–22 | 2.49–3.24 ms |
|
|
84
|
+
| Admin related detail, dense | 4 | 151 | 5.23 ms |
|
|
85
|
+
| public builtin create | 1 | 0 | 2.55 ms |
|
|
86
|
+
|
|
87
|
+
Wall-clock values are evidence, not a cross-machine budget. The normative
|
|
88
|
+
baseline is the existing `pnpm bench:wrangler` query/row gate: every gate must
|
|
89
|
+
remain true, unchanged revisions must perform no repeated preparation, and any
|
|
90
|
+
intentional budget change needs its own reviewed evidence.
|
|
91
|
+
|
|
92
|
+
Existing full-facade behavior is covered by Cloudflare authorization, Admin,
|
|
93
|
+
public-route/cache, View REST, HTTP Trigger, media, form, and facade tests.
|
|
94
|
+
Issues #669–#673 move those assertions to selected modules and exact packed
|
|
95
|
+
consumers; they do not duplicate the suite under new names.
|
|
96
|
+
|
|
97
|
+
Issue #674 leaves `CONTRIBUTING.md` plus accepted ADRs as the contributor
|
|
98
|
+
authority. `AGENTS.md`, `CLAUDE.md`, and the Claude release-skill entry are
|
|
99
|
+
small routers; `.agent/skills/mantle-release/SKILL.md` is the only maintainer
|
|
100
|
+
release procedure. Shipped `skills/*` remain separate consumer artifacts.
|