@aotter/mantle 0.1.0-alpha.9 → 0.1.2-alpha.2
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 +38 -38
- package/dist/cli/generate.d.ts +10 -1
- package/dist/cli/generate.d.ts.map +1 -1
- package/dist/cli/generate.js +49 -4
- package/dist/cli/generate.js.map +1 -1
- package/dist/cli/main.js +0 -8
- package/dist/cli/main.js.map +1 -1
- package/dist/codegen/emitMantleModule.js +8 -0
- package/dist/codegen/emitMantleModule.js.map +1 -1
- package/docs/adapter-guide.md +23 -26
- package/docs/adr/0008-structured-diagnostic-shape.md +7 -2
- package/docs/adr/0010-locale-and-translates.md +14 -16
- package/docs/adr/0011-adapter-port-spec.md +2 -1
- package/docs/adr/0014-auth-better-auth-and-multi-tenant-mcp.md +100 -0
- package/docs/adr/0018-core-starters-repository-boundary.md +3 -0
- package/docs/adr/0019-sealed-manifest-runtime-pipeline.md +38 -2
- package/docs/adr/0020-builtin-handler-contracts-and-matched-upsert.md +199 -0
- package/docs/adr/0021-retire-starter-scaffolding.md +30 -0
- package/docs/adr/0022-caller-observed-version-occ.md +212 -0
- package/docs/adr/0023-port-failure-contract.md +69 -0
- package/docs/adr/0024-manifest-native-schema-tables.md +260 -0
- package/docs/adr/README.md +19 -3
- package/docs/adr/adr-lite-803-request-diagnostics.md +38 -0
- package/docs/adr/adr-lite-808-route-readiness.md +47 -0
- package/docs/adr/adr-lite-809-bounded-public-content.md +71 -0
- package/docs/adr/adr-lite-812-native-parity.md +150 -0
- package/docs/adr/adr-lite-823-home-statistics.md +64 -0
- package/docs/adr/adr-lite-842-mcp-authoring.md +30 -0
- package/docs/adr/adr-lite-861-admin-webmcp.md +42 -0
- package/docs/adr/adr-lite-909-admin-ui-kit.md +37 -0
- package/docs/api-mcp-authorization.md +3 -664
- package/docs/auth-hosting-model.md +4 -4
- package/docs/cloudflare-low-level-composition.md +3 -104
- package/docs/deferred-lifecycle-queues.md +2 -243
- package/docs/design-atoms.md +16 -796
- package/docs/direct-authoring.md +5 -0
- package/docs/examples/minimal-worker/README.md +37 -0
- package/docs/examples/minimal-worker/manifests/site.yaml +25 -0
- package/docs/examples/minimal-worker/package.json +26 -0
- package/docs/examples/minimal-worker/smoke.mjs +23 -0
- package/docs/examples/minimal-worker/src/index.ts +4 -0
- package/docs/examples/minimal-worker/tsconfig.json +17 -0
- package/docs/examples/minimal-worker/wrangler.jsonc +22 -0
- package/docs/handbook/cloudflare/authentication.md +167 -0
- package/docs/handbook/cloudflare/bindings.md +236 -0
- package/docs/handbook/cloudflare/conventional-worker.md +162 -0
- package/docs/handbook/cloudflare/deferred-hooks-queues.md +171 -0
- package/docs/handbook/cloudflare/deploy-and-operate.md +105 -0
- package/docs/handbook/cloudflare/low-level-composition.md +169 -0
- package/docs/handbook/cloudflare/media-r2.md +216 -0
- package/docs/handbook/cloudflare/public-web.md +144 -0
- package/docs/handbook/concepts/authorization.md +116 -0
- package/docs/handbook/concepts/four-atoms.md +173 -0
- package/docs/handbook/concepts/lifecycle-and-locales.md +142 -0
- package/docs/handbook/concepts/mcp-and-agents.md +109 -0
- package/docs/handbook/concepts/procedures-and-triggers.md +221 -0
- package/docs/handbook/concepts/runtime-and-adapters.md +177 -0
- package/docs/handbook/concepts/views.md +191 -0
- package/docs/handbook/examples/commerce-transaction.md +813 -0
- package/docs/handbook/examples/guarded-api.md +427 -0
- package/docs/handbook/examples/intake-form.md +319 -0
- package/docs/handbook/examples/legal-documents.md +218 -0
- package/docs/handbook/examples/procurement-approvals.md +240 -0
- package/docs/handbook/examples/publication.md +240 -0
- package/docs/handbook/examples/reservation.md +220 -0
- package/docs/handbook/navigation.json +63 -0
- package/docs/handbook/reference/authorization.md +295 -0
- package/docs/handbook/reference/diagnostics.md +183 -0
- package/docs/handbook/reference/manifest.md +132 -0
- package/docs/handbook/reference/procedure.md +263 -0
- package/docs/handbook/reference/schema.md +250 -0
- package/docs/handbook/reference/site-config.md +233 -0
- package/docs/handbook/reference/surface.md +207 -0
- package/docs/handbook/reference/trigger.md +193 -0
- package/docs/handbook/reference/view.md +256 -0
- package/docs/handbook/start/project-and-cli.md +122 -0
- package/docs/handbook/start/quickstart-worker.md +193 -0
- package/docs/labels.md +3 -1
- package/docs/media-uploads.md +3 -184
- package/docs/migration-0.1.2.md +60 -3
- package/docs/performance-harness.md +127 -10
- package/docs/release-process.md +85 -231
- package/docs/schema-indexes.md +3 -180
- package/docs/sealed-pipeline-ownership.md +6 -5
- package/docs/spec-only-host-adoption.md +158 -0
- package/docs/transaction-patterns.md +5 -0
- package/package.json +21 -25
- package/skills/README.md +4 -4
- package/skills/develop/SKILL.md +23 -28
- package/skills/install/SKILL.md +55 -147
- package/skills/provision/SKILL.md +4 -3
- package/skills/theme/SKILL.md +6 -6
- package/skills/update/SKILL.md +32 -68
- package/dist/cli/create.d.ts +0 -2
- package/dist/cli/create.d.ts.map +0 -1
- package/dist/cli/create.js +0 -243
- package/dist/cli/create.js.map +0 -1
- package/dist/cli/update.d.ts +0 -2
- package/dist/cli/update.d.ts.map +0 -1
- package/dist/cli/update.js +0 -413
- package/dist/cli/update.js.map +0 -1
- package/dist/provision/renderProvisionBundle.d.ts +0 -70
- package/dist/provision/renderProvisionBundle.d.ts.map +0 -1
- package/dist/provision/renderProvisionBundle.js +0 -367
- package/dist/provision/renderProvisionBundle.js.map +0 -1
- package/dist/provision.d.ts +0 -2
- package/dist/provision.d.ts.map +0 -1
- package/dist/provision.js +0 -2
- package/dist/provision.js.map +0 -1
package/docs/release-process.md
CHANGED
|
@@ -1,39 +1,29 @@
|
|
|
1
1
|
# Release process
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
## Authority
|
|
9
|
-
|
|
10
|
-
`.github/workflows/release.yml` is the
|
|
11
|
-
a reviewed release PR
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
```
|
|
28
|
-
|
|
29
|
-
The Starter worker owns only its repository transition: it prepares a release
|
|
30
|
-
PR from the exact gated `develop` commit, waits for the named checks, merges
|
|
31
|
-
that checked head atomically into `develop`, and tags the recorded merge
|
|
32
|
-
commit. It does not promote `main`, backport, infer releases from commit text,
|
|
33
|
-
or dispatch Landing.
|
|
34
|
-
|
|
35
|
-
Landing is an explicit controller input and defaults off. A release that keeps
|
|
36
|
-
`deploy_landing=false` does not mutate or deploy Landing.
|
|
3
|
+
First stable targets 0.1.2 (#826). The last legacy Landing/Starter release is
|
|
4
|
+
0.1.0-alpha.17. Its immutable artifacts and repositories remain available;
|
|
5
|
+
recover that version with its tagged controller/docs. New releases have no
|
|
6
|
+
Starter/Landing checkout, tag, dispatch, credential or deployment dependency.
|
|
7
|
+
|
|
8
|
+
## Authority and state transitions
|
|
9
|
+
|
|
10
|
+
`.github/workflows/release.yml` is the only release controller. Humans merge
|
|
11
|
+
a reviewed same-repository release PR, then explicitly dispatch that merge.
|
|
12
|
+
No task implicitly authorizes publication; no manual package/tag writer exists.
|
|
13
|
+
|
|
14
|
+
| State | Sole next writer | Retry / invariant |
|
|
15
|
+
|---|---|---|
|
|
16
|
+
| Reviewed source; unused version | Core source/packed-consumer gates, then immutable Core tag | Exact canonical merged PR SHA and version required |
|
|
17
|
+
| Tag exists; registry candidates partial | Existing npm/GPR publication steps | Verify existing artifact identity; publish missing versions only |
|
|
18
|
+
| Registry candidates verified | Public-registry reference consumer gate | No mutation; failure leaves public channels unchanged |
|
|
19
|
+
| Consumer passes | Monotonic npm/GPR channel promotion | Same version is a no-op; older runs cannot move a channel backward |
|
|
20
|
+
| Channels promoted/preserved newer | GitHub release step | Existing release identity or fail |
|
|
21
|
+
|
|
22
|
+
The public-registry gate uses a disposable copy of the directly authored
|
|
23
|
+
`docs/examples/minimal-worker` reference, installs the exact candidate, then
|
|
24
|
+
checks generation, skill projection, TypeScript and real Worker HTTP behavior.
|
|
25
|
+
The same reference is gated against exact tarballs before Core tagging. It is
|
|
26
|
+
a test/example, not a scaffold product or another repository release.
|
|
37
27
|
|
|
38
28
|
## Changing release automation
|
|
39
29
|
|
|
@@ -48,203 +38,67 @@ verdict expires when that SHA changes. After two patch rounds, a new
|
|
|
48
38
|
foundational blocker returns to the state table and the user for a scope
|
|
49
39
|
decision instead of starting another local redesign loop.
|
|
50
40
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
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`.
|
|
41
|
+
Invariants: immutable versions/tags retain their identity; registry integrity
|
|
42
|
+
and the published-consumer gate precede public channel promotion; retries
|
|
43
|
+
cannot move channels backward. No downstream mutation, unpublish or rollback
|
|
44
|
+
is introduced. The runnable release-order check guards these transitions.
|
|
78
45
|
|
|
79
46
|
## Branches and channels
|
|
80
47
|
|
|
81
|
-
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
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).
|
|
143
|
-
|
|
144
|
-
## Run the controller
|
|
145
|
-
|
|
146
|
-
Dispatch `.github/workflows/release.yml` from the merged release commit with:
|
|
147
|
-
|
|
148
|
-
- `version`: the version without the leading `v`.
|
|
149
|
-
- `deploy_landing`: `false` unless Landing was separately reviewed and is
|
|
150
|
-
intentionally part of this release.
|
|
151
|
-
|
|
152
|
-
Before creating the Core tag, the controller proves:
|
|
153
|
-
|
|
154
|
-
- the requested version matches every package, plugin, and marketplace ref;
|
|
155
|
-
- `pnpm check` passes;
|
|
156
|
-
- packed Core passes in the exact pinned Starter source;
|
|
157
|
-
- all nine release tarballs exist;
|
|
158
|
-
- npm and cross-repository credentials are present and readable;
|
|
159
|
-
- a fresh version is unused across npmjs, GitHub Packages, and Starter tags;
|
|
160
|
-
- the pinned Starter commit is still the remote `develop` tip.
|
|
161
|
-
|
|
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.
|
|
171
|
-
|
|
172
|
-
## Idempotency and recovery
|
|
173
|
-
|
|
174
|
-
The global controller lock serializes releases. Re-running the same release is
|
|
175
|
-
supported:
|
|
176
|
-
|
|
177
|
-
- an existing Core tag must resolve to the same controller commit;
|
|
178
|
-
- existing npm and GitHub Packages versions are verified and skipped;
|
|
179
|
-
- channel dist-tags are never moved backward by an older rerun;
|
|
180
|
-
- a duplicate Starter dispatch resumes its open/merged state or reports a
|
|
181
|
-
tagged no-op;
|
|
182
|
-
- an existing GitHub Release is a no-op.
|
|
183
|
-
|
|
184
|
-
If source or immutable state disagrees, the workflow fails instead of guessing.
|
|
185
|
-
Fix source and publish the next version when public state is wrong. Re-run the
|
|
186
|
-
same controller only for a transient failure or a verified partial transition.
|
|
187
|
-
Never force-retag or republish an existing version.
|
|
188
|
-
|
|
189
|
-
## Credentials
|
|
190
|
-
|
|
191
|
-
Core repository secrets:
|
|
192
|
-
|
|
193
|
-
| Secret | Minimum purpose |
|
|
194
|
-
|---|---|
|
|
195
|
-
| `NPM_TOKEN` | Publish the nine `@aotter/*` packages on npmjs. |
|
|
196
|
-
| `RELEASE_FANOUT_TOKEN` | Read and dispatch `aotter/mantle-starters`; also read and dispatch `aotter/mantle-landing` only when Landing is enabled. |
|
|
197
|
-
|
|
198
|
-
Core's job-scoped `GITHUB_TOKEN` creates the Core tag and release and mirrors
|
|
199
|
-
packages to GitHub Packages. Starter's job-scoped token pushes its generated
|
|
200
|
-
branch, checked merge, and tag; its `RELEASE_FANOUT_TOKEN` is used only to
|
|
201
|
-
create the canonical same-repository PR. Prefer separate fine-grained tokens
|
|
202
|
-
or a GitHub App when practical; do not grant organization-wide repository
|
|
203
|
-
access for this flow.
|
|
204
|
-
|
|
205
|
-
## Post-release verification
|
|
206
|
-
|
|
207
|
-
Completion requires evidence for both repositories, not only a green publish
|
|
208
|
-
step:
|
|
209
|
-
|
|
210
|
-
```bash
|
|
211
|
-
gh -R aotter/mantle release view vX.Y.Z
|
|
212
|
-
gh api repos/aotter/mantle-starters/git/ref/tags/vX.Y.Z
|
|
213
|
-
|
|
214
|
-
for p in \
|
|
215
|
-
@aotter/mantle-spec \
|
|
216
|
-
@aotter/mantle-admin-ui \
|
|
217
|
-
@aotter/mantle-runtime \
|
|
218
|
-
@aotter/mantle-web \
|
|
219
|
-
@aotter/mantle-admin \
|
|
220
|
-
@aotter/mantle-bun \
|
|
221
|
-
@aotter/mantle-vercel \
|
|
222
|
-
@aotter/mantle-cloudflare \
|
|
223
|
-
@aotter/mantle; do
|
|
224
|
-
npm view "$p@X.Y.Z" version dist.integrity dependencies --json
|
|
225
|
-
done
|
|
226
|
-
```
|
|
227
|
-
|
|
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.
|
|
236
|
-
|
|
237
|
-
If `deploy_landing=false`, also verify that no Landing release dispatch or
|
|
238
|
-
deployment was started.
|
|
239
|
-
|
|
240
|
-
## Fix-forward policy
|
|
241
|
-
|
|
242
|
-
- Broken public package or Starter bundle: publish the next alpha and explain
|
|
243
|
-
the re-spin in the fix PR and generated GitHub Release notes.
|
|
244
|
-
- Use `npm deprecate` to steer consumers away from a broken version.
|
|
245
|
-
- Unpublish only for secrets, private files, or similarly severe exposure;
|
|
246
|
-
npm versions cannot be reused and registry metadata may remain unavailable
|
|
247
|
-
during the unpublish cooldown.
|
|
248
|
-
- A cross-cutting rename must include an explicit infrastructure-config diff
|
|
249
|
-
and live smoke test. CI success does not prove renamed Worker, D1, KV, route,
|
|
250
|
-
or secret bindings are correct.
|
|
48
|
+
- Alpha releases use the reviewed develop merge. Beta/RC/stable use main after
|
|
49
|
+
explicit promotion; first stable acceptance is tracked by #826.
|
|
50
|
+
- Alpha/beta/RC GitHub releases are prereleases; their npm tags match suffixes.
|
|
51
|
+
- Stable publishes latest. Final 0.1.0 alphas only advance alpha, preserving
|
|
52
|
+
existing legacy latest. Historic 0.0 alpha behavior remains recoverable.
|
|
53
|
+
|
|
54
|
+
## Prepare and run
|
|
55
|
+
|
|
56
|
+
1. Fetch Core refs, prove the version and tag unused. Preview GitHub generated
|
|
57
|
+
notes since the previous tag; correct PR metadata and label release-only
|
|
58
|
+
PRs skip-release-notes. Do not duplicate release entries in CHANGELOG.md.
|
|
59
|
+
2. Align every workspace package, plugin and marketplace ref to the version.
|
|
60
|
+
3. Review API compatibility and migration instructions for actual consumers.
|
|
61
|
+
Frozen legacy consumers stay on alpha.17; do not make them follow new Core.
|
|
62
|
+
4. Run `pnpm check`, including exact packed Worker, optional products, Bun,
|
|
63
|
+
Vercel, skills, release invariants, types and tests. Inspect the umbrella
|
|
64
|
+
docs/skills payload: no workspace dependencies, secrets or local state.
|
|
65
|
+
5. Freeze the PR head for self review; CI must pass before merge. Dispatch
|
|
66
|
+
release.yml from that merge with `version` (without v). It refuses an
|
|
67
|
+
untagged source that is no longer the expected branch tip.
|
|
68
|
+
|
|
69
|
+
The ten public packages remain in dependency order:
|
|
70
|
+
|
|
71
|
+
1. @aotter/mantle-spec
|
|
72
|
+
2. @aotter/mantle-admin-ui
|
|
73
|
+
3. @aotter/mantle-runtime
|
|
74
|
+
4. @aotter/mantle-indexeddb
|
|
75
|
+
5. @aotter/mantle-web
|
|
76
|
+
6. @aotter/mantle-admin
|
|
77
|
+
7. @aotter/mantle-bun
|
|
78
|
+
8. @aotter/mantle-vercel
|
|
79
|
+
9. @aotter/mantle-cloudflare
|
|
80
|
+
10. @aotter/mantle
|
|
81
|
+
|
|
82
|
+
## Credentials and verification
|
|
83
|
+
|
|
84
|
+
Core needs NPM_TOKEN for npmjs. Its job-scoped GITHUB_TOKEN creates the Core
|
|
85
|
+
tag/release and mirrors GitHub Packages. No cross-repository fanout token is
|
|
86
|
+
needed. Before tagging, verify credentials and new-version absence on both
|
|
87
|
+
registries. Existing artifacts on retry must have matching integrity.
|
|
88
|
+
|
|
89
|
+
Completion requires the Core tag SHA, all ten npmjs/GPR packages, exact
|
|
90
|
+
integrity, no workspace dependencies, a passing public-registry Worker gate,
|
|
91
|
+
correct channel tags and the GitHub release. Retain run links and gate evidence.
|
|
92
|
+
This does not prove stable production soak or upgrade safety; #826 owns those
|
|
93
|
+
acceptance requirements. A first-stable agent acceptance uses only the
|
|
94
|
+
version-matched authoring instructions, not an SDK checkout or generated site.
|
|
95
|
+
|
|
96
|
+
## Recovery
|
|
97
|
+
|
|
98
|
+
Rerun the same controller commit/version for a transient or verified partial
|
|
99
|
+
transition. Existing tags/artifacts must match; newer channels stay put. Fail
|
|
100
|
+
on identity disagreement instead of guessing. A wrong public artifact needs
|
|
101
|
+
a new version; never force-retag, overwrite or reuse a published version.
|
|
102
|
+
Unpublish is reserved for actual secret/private-file exposure, never routine
|
|
103
|
+
fixes. Infrastructure renames require their explicit config diff and live
|
|
104
|
+
smoke; CI alone cannot prove provider identity.
|
package/docs/schema-indexes.md
CHANGED
|
@@ -1,182 +1,5 @@
|
|
|
1
|
-
# Schema indexes
|
|
1
|
+
# Schema indexes
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
JSON `TEXT` column. Declare `indexes` for measured, hot access paths that need
|
|
5
|
-
an ordered non-unique B-tree index. Use `uniqueIndexes` when the same ordered
|
|
6
|
-
fields are a data-integrity constraint.
|
|
3
|
+
This guide moved into the handbook: [`docs/handbook/reference/schema.md`](handbook/reference/schema.md).
|
|
7
4
|
|
|
8
|
-
|
|
9
|
-
apiVersion: cms.mantle.aotter.net/v1
|
|
10
|
-
kind: Schema
|
|
11
|
-
metadata: { name: account-members }
|
|
12
|
-
spec:
|
|
13
|
-
title: Account members
|
|
14
|
-
lifecycle: operational
|
|
15
|
-
schema:
|
|
16
|
-
type: object
|
|
17
|
-
properties:
|
|
18
|
-
userId: { type: string }
|
|
19
|
-
state: { type: string }
|
|
20
|
-
accountId: { type: string }
|
|
21
|
-
email: { type: [string, "null"] }
|
|
22
|
-
indexes:
|
|
23
|
-
- [userId, state, accountId]
|
|
24
|
-
- [accountId, state, userId]
|
|
25
|
-
uniqueIndexes:
|
|
26
|
-
- [accountId, userId]
|
|
27
|
-
- [accountId, email]
|
|
28
|
-
```
|
|
29
|
-
|
|
30
|
-
Each inner array is one index. Field order is significant. A one-field array
|
|
31
|
-
is valid; a bare string or the retired `indexedFields` spelling is not.
|
|
32
|
-
Invalid matrix shapes report `INVALID_MANIFEST_ENVELOPE`; invalid index
|
|
33
|
-
semantics report `SCHEMA_INDEX_INVALID`, and unknown fields report
|
|
34
|
-
`SCHEMA_INDEX_FIELD_UNKNOWN` (`uniqueIndexes` keeps its existing
|
|
35
|
-
`UNIQUE_INDEX_FIELD_UNKNOWN` code).
|
|
36
|
-
|
|
37
|
-
## Leftmost-prefix behavior
|
|
38
|
-
|
|
39
|
-
For `[userId, state, accountId]`, SQLite can use the index for:
|
|
40
|
-
|
|
41
|
-
```sql
|
|
42
|
-
WHERE userId = ?
|
|
43
|
-
WHERE userId = ? AND state = ?
|
|
44
|
-
WHERE userId = ? AND state = ? AND accountId = ?
|
|
45
|
-
```
|
|
46
|
-
|
|
47
|
-
It does not provide the same guarantee when the leftmost field is skipped:
|
|
48
|
-
|
|
49
|
-
```sql
|
|
50
|
-
WHERE state = ? AND accountId = ?
|
|
51
|
-
```
|
|
52
|
-
|
|
53
|
-
The second declaration, `[accountId, state, userId]`, supports the other hot
|
|
54
|
-
path and supplies the requested order without a temporary sort:
|
|
55
|
-
|
|
56
|
-
```sql
|
|
57
|
-
WHERE accountId = ? AND state = ?
|
|
58
|
-
ORDER BY userId
|
|
59
|
-
```
|
|
60
|
-
|
|
61
|
-
Do not declare every possible permutation. Each index consumes storage and
|
|
62
|
-
adds work to inserts and updates. Start from an observed query plan or hot
|
|
63
|
-
endpoint and declare only the access paths it needs.
|
|
64
|
-
|
|
65
|
-
## Supported fields
|
|
66
|
-
|
|
67
|
-
Indexed fields are exact, own, top-level keys of
|
|
68
|
-
`spec.schema.properties`. `a.b` means a literal top-level key named `a.b`; it
|
|
69
|
-
does not traverse `{ a: { b: ... } }`.
|
|
70
|
-
|
|
71
|
-
An index-bearing Schema name and every indexed field must match
|
|
72
|
-
`^[A-Za-z][A-Za-z0-9_.-]*$`.
|
|
73
|
-
|
|
74
|
-
The property must declare exactly one non-null scalar type. It may also allow
|
|
75
|
-
`null` with a type array or `nullable: true`.
|
|
76
|
-
|
|
77
|
-
| JSON Schema type | generated-column affinity |
|
|
78
|
-
|---|---|
|
|
79
|
-
| `string` | `TEXT` |
|
|
80
|
-
| `integer`, `boolean` | `INTEGER` |
|
|
81
|
-
| `number` | `REAL` |
|
|
82
|
-
|
|
83
|
-
Objects, arrays, enum-only properties, and mixed non-null unions are not
|
|
84
|
-
indexable. Reserved native View fields (`id`, `status`, `version`,
|
|
85
|
-
`createdAt`, `updatedAt`, `authorId`) also cannot be index declarations.
|
|
86
|
-
|
|
87
|
-
Missing and `null` leftmost values are omitted from the partial index. SQLite
|
|
88
|
-
UNIQUE semantics still allow more than one composite containing `NULL`.
|
|
89
|
-
|
|
90
|
-
## Core-compiled queries
|
|
91
|
-
|
|
92
|
-
Mantle creates collection-gated VIRTUAL generated columns during `bootInit`.
|
|
93
|
-
Core-compiled View projections, filters, and ordering automatically reference
|
|
94
|
-
a generated column when their field is declared by `indexes` or
|
|
95
|
-
`uniqueIndexes`; undeclared fields keep using `json_extract`.
|
|
96
|
-
|
|
97
|
-
D1 stores the original JSON as `TEXT`, not PostgreSQL JSONB. The generated
|
|
98
|
-
scalar columns and their B-tree indexes are the supported indexed-path
|
|
99
|
-
mechanism. Their physical identifiers are private, versioned, and encoded;
|
|
100
|
-
never copy one from `sqlite_schema` into site code.
|
|
101
|
-
|
|
102
|
-
## Site-owned Procedure SQL
|
|
103
|
-
|
|
104
|
-
Use the pure helper when a business query remains site-owned. It returns a
|
|
105
|
-
fully quoted reference for a declared field or `null` when that field has no
|
|
106
|
-
declared index. Pass a table alias for joins so the generated column is not
|
|
107
|
-
ambiguous.
|
|
108
|
-
|
|
109
|
-
```ts
|
|
110
|
-
import {
|
|
111
|
-
schemaIndexedFieldSql,
|
|
112
|
-
type SchemaManifest,
|
|
113
|
-
} from "@aotter/mantle/spec";
|
|
114
|
-
import { loadManifests } from "../mantle/manifests.js";
|
|
115
|
-
|
|
116
|
-
const accountMembers = loadManifests().find(
|
|
117
|
-
(manifest): manifest is SchemaManifest =>
|
|
118
|
-
manifest.kind === "Schema" && manifest.metadata.name === "account-members",
|
|
119
|
-
);
|
|
120
|
-
if (!accountMembers) throw new Error("account-members Schema is missing");
|
|
121
|
-
|
|
122
|
-
const userId = schemaIndexedFieldSql(accountMembers, "userId", "member");
|
|
123
|
-
const state = schemaIndexedFieldSql(accountMembers, "state", "member");
|
|
124
|
-
if (!userId || !state) {
|
|
125
|
-
throw new Error("account-members actor lookup requires its declared index");
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
const rows = await env.DB.prepare(
|
|
129
|
-
`SELECT member.id, member.data
|
|
130
|
-
FROM entries AS member
|
|
131
|
-
WHERE member.collection = ?
|
|
132
|
-
AND ${userId} = ?
|
|
133
|
-
AND ${state} = ?`,
|
|
134
|
-
)
|
|
135
|
-
.bind("account-members", actorId, "active")
|
|
136
|
-
.all();
|
|
137
|
-
```
|
|
138
|
-
|
|
139
|
-
The helper does not authorize the query or define its business response. The
|
|
140
|
-
site still owns actor resolution, account rules, aggregation, and output.
|
|
141
|
-
|
|
142
|
-
## Verify a plan
|
|
143
|
-
|
|
144
|
-
Prefer the shipped crowded-data harness for a manifest View:
|
|
145
|
-
|
|
146
|
-
```bash
|
|
147
|
-
pnpm exec mantle-harness indexes --require-public --format text
|
|
148
|
-
```
|
|
149
|
-
|
|
150
|
-
It applies Mantle's real canonical migrations and generated DDL, seeds skewed
|
|
151
|
-
rows, compiles and executes the real View SQL, then records
|
|
152
|
-
`EXPLAIN QUERY PLAN`. By default findings are advisory; use `--require-public`
|
|
153
|
-
or repeat `--require <view-name>` only for paths whose performance is part of
|
|
154
|
-
the contract. See [the performance harness](./performance-harness.md).
|
|
155
|
-
|
|
156
|
-
For site-owned SQL that cannot be represented by a View, inspect the real
|
|
157
|
-
database directly when adding or changing a hot path:
|
|
158
|
-
|
|
159
|
-
```sql
|
|
160
|
-
PRAGMA index_list("entries");
|
|
161
|
-
PRAGMA index_xinfo("<index returned above>");
|
|
162
|
-
|
|
163
|
-
EXPLAIN QUERY PLAN
|
|
164
|
-
SELECT id FROM entries
|
|
165
|
-
WHERE collection = 'account-members'
|
|
166
|
-
AND "<reference emitted by Core>" = 'user-1';
|
|
167
|
-
```
|
|
168
|
-
|
|
169
|
-
The plan should contain `SEARCH entries USING INDEX ...`, and an indexed
|
|
170
|
-
filter/order path should not contain `USE TEMP B-TREE FOR ORDER BY`.
|
|
171
|
-
|
|
172
|
-
Existing databases upgrade by adding new affinity-correct VIRTUAL columns and
|
|
173
|
-
versioned indexes; populated `entries` rows do not need a rewrite. Unused
|
|
174
|
-
generated columns may remain because dropping them is not safe across every D1
|
|
175
|
-
version Mantle supports. Compatible alpha.59 unique indexes remain during a
|
|
176
|
-
rolling upgrade; ambiguous legacy flattened names and indexes removed from
|
|
177
|
-
manifests are reconciled away at boot.
|
|
178
|
-
|
|
179
|
-
References: [D1 JSON](https://developers.cloudflare.com/d1/sql-api/query-json/),
|
|
180
|
-
[D1 generated columns](https://developers.cloudflare.com/d1/reference/generated-columns/),
|
|
181
|
-
[D1 indexes](https://developers.cloudflare.com/d1/best-practices/use-indexes/),
|
|
182
|
-
[SQLite partial indexes](https://www.sqlite.org/partialindex.html).
|
|
5
|
+
The handbook ships inside the `@aotter/mantle` package under `node_modules/@aotter/mantle/docs/handbook/` and describes the installed release.
|
|
@@ -26,7 +26,7 @@ issue that must delete or delegate the old path.
|
|
|
26
26
|
| Semantic fingerprint | Runtime boot from raw manifests | Compile plan | #665 |
|
|
27
27
|
| Declarative View resolution | `ViewSqlCompiler` during each `ExecuteViewUseCase` call | Compile logical plan once | #665 |
|
|
28
28
|
| SQLite/JSON1 View lowering and native `spec.sql` | `ViewSqlCompiler` plus `DatabaseDriver` invocation | Selected storage preparation | #666 |
|
|
29
|
-
| Canonical SQL migrations,
|
|
29
|
+
| Canonical SQL migrations, native Schema tables/indexes, readiness | `createCmsRuntime.bootInit` and runtime infrastructure | Prepare | #666 |
|
|
30
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
31
|
| Content, View, Procedure, Trigger, lifecycle invocation | Runtime use cases over raw maps/driver | `MantleRuntime` over plan + semantic ports | #667 |
|
|
32
32
|
| Target authorization/admin bypass | Runtime plus adapter entry points | One Core invocation policy; adapter resolves caller only | #667 |
|
|
@@ -59,10 +59,11 @@ auth/guard references, all Trigger surfaces, multi-document YAML, empty
|
|
|
59
59
|
documents, aliases, unknown keys, malformed YAML, and deterministic
|
|
60
60
|
diagnostics.
|
|
61
61
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
62
|
+
The following pins record the historical sealed-pipeline migration gates.
|
|
63
|
+
ADR-0021 supersedes the Starter/Landing release coupling: current Core CI and
|
|
64
|
+
release use `docs/examples/minimal-worker` from the same reviewed commit.
|
|
65
|
+
Private consumers can still run the exact-tarball checker in their own repos;
|
|
66
|
+
public Core PRs receive no cross-repository credentials:
|
|
66
67
|
|
|
67
68
|
| Consumer | Revision | Gate authority | Manifest paths |
|
|
68
69
|
|---|---|---|---|
|