Skip to content

Commit 269dfdd

Browse files
committed
feat: hard-cut registry to Edition 2026
1 parent 503db63 commit 269dfdd

20 files changed

Lines changed: 361 additions & 58 deletions

‎CHANGELOG.md‎

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,11 @@
1111
editions and older persisted schemas are rejected; no migration or
1212
compatibility reader is provided. Generated CKB entries also remove the
1313
raw-`CSARGv1` witness fallback, so Edition 2026 accepts the payload only
14-
inside canonical `WitnessArgs.input_type`. See the
14+
inside canonical `WitnessArgs.input_type`. The public registry contract is
15+
hard-cut to publish protocol v2 and registry schema 2: signed entries,
16+
persisted rows, CDN JSON, and the website all require Edition 2026 and the
17+
compatibility-profile hash. The generic admin API can no longer manufacture
18+
`verified_build` or `deployed` claims without an evidence-specific path. See the
1519
[0.23 development release notes](docs/releases/CELLSCRIPT_0_23_RELEASE_NOTES.md).
1620
- Complete the native-tooling cleanup: neutralize migration-era identifiers,
1721
remove tracked legacy traceback logs and cache exclusions, rename the native

‎docs/CELLSCRIPT_GATE_POLICY.md‎

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ deciding whether a change is ready.
1515
| Mode | When to run | Evidence boundary |
1616
|---|---|---|
1717
| `dev` | Local development before pushing | Rust formatting, canonical CellScript example formatting, all workspace-package Rust checks (including `cellscript-tools`), strict backend quick audit, syntax-combination quick audit, parity-gated skill-pack freshness, README-linked CellScript doc Status freshness, local markdown link check, whitespace diff check |
18-
| `ci` | Pull requests, pushes, and routine merge readiness | Canonical CellScript example formatting; tests and clippy for the compiler, Fiber adapter, CKB adapter, WASM crate, CKB SDK builder example, and `cellscript-tools`; strict backend CI audit; package verification; parity-gated skill-pack/doc freshness; local-link and script syntax checks |
18+
| `ci` | Pull requests, pushes, and routine merge readiness | Canonical CellScript example formatting; tests and clippy for the compiler, Fiber adapter, CKB adapter, WASM crate, CKB SDK builder example, and `cellscript-tools`; registry API typecheck/tests/dry-run Worker build; strict backend CI audit; package verification; parity-gated skill-pack/doc freshness; local-link and script syntax checks |
1919
| `backend` | Changes touching IR, codegen, assembler, ABI, ELF, or RISC-V behavior | Full Rust tests, clippy, and strict backend full audit, including stateful CKB scenarios |
2020
| `release` | Nightly/stable release candidates and any production CKB claim | Clean tagged source plus `ci`, a fresh size-gated website WASM rebuild, tooling/docs and VS Code checks, pinned-CKB acceptance harnesses, public builder-contract generation, and mandatory stateful scenario/action coverage |
2121
| `release-quick` | Wrapper compatibility and local compile-only preflight | `ci` plus compile-only production acceptance; not external live/devnet evidence |
@@ -53,6 +53,11 @@ migrated. See
5353
ABI changes require the `backend` gate in addition to ordinary `dev` and `ci`
5454
coverage.
5555

56+
The `ci` gate also typechecks, tests, and performs a Wrangler dry-run build of
57+
`services/registry-api`. This pins the publish-protocol/schema contract to the
58+
compiler-generated registry entry. It is local service coverage, not evidence
59+
that Cloudflare, R2, Hyperdrive, Neon, DNS, or a production deployment works.
60+
5661
The full gate reads `scripts/ckb_acceptance_pin.json` and rejects a CKB checkout
5762
whose revision or worktree differs from the pin. Its report binds the CKB
5863
version string, executable SHA-256, source-template hashes, effective devnet

‎docs/CELLSCRIPT_PACKAGE_PROVENANCE_AND_DEPLOYMENT_IDENTITY.md‎

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -793,7 +793,7 @@ for audit, offline fixtures, and direct-Git fallback:
793793
"version": "1.2.0",
794794
"tag": "v1.2.0",
795795
"source_hash": "blake2b:0xabcd...",
796-
"cellscript_version": "0.19.0",
796+
"cellscript_version": "0.22.0",
797797
"dependencies": {
798798
"token": { "namespace": "cellscript", "version": "0.3.0" }
799799
},
@@ -1093,7 +1093,7 @@ alongside `Cell.toml`, for audit and offline use:
10931093

10941094
```json
10951095
{
1096-
"schema_version": 1,
1096+
"schema_version": 2,
10971097
"name": "amm",
10981098
"namespace": "cellscript",
10991099
"versions": [
@@ -1102,13 +1102,16 @@ alongside `Cell.toml`, for audit and offline use:
11021102
"tag": "v1.2.0",
11031103
"source_hash": "blake2b:0xabcd...",
11041104
"cellscript_version": "0.19.0",
1105+
"edition": "2026",
1106+
"compatibility_profile_hash": "42d297cd7879917ade58c89cdc5dcbbb38a5d39b720788387db80e918a3f7fd9",
11051107
"dependencies": {
11061108
"token": { "namespace": "cellscript", "version": "0.3.0" }
11071109
},
11081110
"abi_index": "blake2b:0xdef0...",
11091111
"schema_hash": "blake2b:0x9abc...",
11101112
"license": "MIT",
11111113
"released_at": "2026-04-24T00:00:00Z",
1114+
"status": "source_published",
11121115
"yanked": false,
11131116
"audit": {
11141117
"report_hash": "blake2b:0x5555...",
@@ -1119,6 +1122,10 @@ alongside `Cell.toml`, for audit and offline use:
11191122
}
11201123
```
11211124

1125+
The current Edition 2026 reader accepts only schema 2. The older schema-1
1126+
shape described in the historical Phase 1 audit below is not a compatibility
1127+
surface.
1128+
11221129
The `tag` field maps each version to a git tag in the source repository.
11231130
This allows `cellc install` to clone the exact commit without needing
11241131
a separate archive storage layer.

‎docs/releases/CELLSCRIPT_0_23_RELEASE_NOTES.md‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ work until their implementation and evidence boundaries are complete.
2222
| Entry witness | `CSARGv1` is decoded only from canonical Molecule `WitnessArgs.input_type`. |
2323
| Failure mode | Raw payloads, malformed tables, absent `input_type`, wrong placement, and mismatched identities fail closed. |
2424
| Build identity | The resolved compatibility profile is bound into metadata, registry, lock, deployment, receipt, and builder records. |
25+
| Registry contract | Publish protocol v2 and registry schema 2 require Edition 2026 plus its compatibility-profile hash from CLI signature through API, database, CDN JSON, and website. |
2526
| Tooling | CLI, LSP, WASM, website bindings, examples, and package tooling use the same edition contract. |
2627
| Native gate | Active test, fixture, evidence, and release tooling is Rust, shell, or Node; repository policy rejects Python source reintroduction. |
2728

@@ -104,10 +105,18 @@ The 0.23 identity set is:
104105
| Compile receipt | edition and resolved compatibility profile |
105106
| Generated action builder | `cellscript-generated-action-builder-v0.23-edition-2026` |
106107
| Registry build record | edition and compatibility-profile hash |
108+
| `registry.json` / public publish | schema 2 / `cellscript-registry-publish-v2` |
107109

108110
Consumers reject other identities. Rebuild the artifact and regenerate its
109111
metadata, lock/deployment records, receipt, and builder together.
110112

113+
The registry boundary has no v1 reader or migration path. The write API checks
114+
the complete signed nested entry instead of accepting an untyped JSON object,
115+
persists edition/profile as typed columns, and repeats them in the CDN object.
116+
Generic admin status changes may quarantine, yank, deprecate, or move an entry
117+
through indexing, but cannot label it `verified_build` or `deployed` without a
118+
future evidence-specific promotion endpoint.
119+
111120
## CLI, LSP, WASM, And Website
112121

113122
- Package commands read Edition 2026 from `Cell.toml`.
@@ -116,6 +125,8 @@ metadata, lock/deployment records, receipt, and builder together.
116125
accept only `"2026"`.
117126
- The playground worker and TypeScript declarations pass that edition into the
118127
WASM boundary and include it in compiler-output provenance.
128+
- Registry pages reject stale schema-1 fixture data and display each package
129+
version's edition and compatibility-profile hash.
119130
- Entry-witness reports, ABI reports, action plans, and generated builders
120131
expose canonical `WitnessArgs.input_type` placement.
121132
- NovaSeal core, agreement, and planned-profile devnet transaction constructors

‎docs/wiki/Tutorial-12-Phase1-Registry-End-to-End.md‎

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,34 @@ cellc publish --json
6464
The public write API admits package metadata, but consumers still verify the
6565
source and build identity locally.
6666

67+
## Edition 2026 Registry Contract
68+
69+
Public publishing uses `cellscript-registry-publish-v2` and registry schema 2.
70+
The signed payload contains one complete version entry, and the API checks that
71+
its namespace, package name, version, and source hash equal the outer signed
72+
identity. The entry must also contain:
73+
74+
```json
75+
{
76+
"schema_version": 2,
77+
"versions": [{
78+
"edition": "2026",
79+
"compatibility_profile_hash": "<32-byte hex hash>"
80+
}]
81+
}
82+
```
83+
84+
These are not website labels. `edition` identifies the selected language and
85+
CKB ABI rule bundle; `compatibility_profile_hash` binds the resolved details of
86+
that bundle. The API stores both as typed fields and exposes them in its static
87+
package-version JSON. Schema 1, a missing field, or a mismatched nested identity
88+
is rejected. There is no v1 migration or compatibility reader.
89+
90+
`source_published` means the signed source snapshot was admitted; it does not
91+
mean the build or deployment was verified. The generic admin endpoint cannot
92+
promote an entry to `verified_build` or `deployed`. Those labels require a
93+
future evidence-specific verification flow.
94+
6795
## Consumer Flow
6896

6997
Add a dependency, resolve it, and check the resulting package graph:

‎roadmap/CELLSCRIPT_0_23_ROADMAP.md‎

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,13 @@ path, idempotent publish, and admin-gated status transitions. The 0.23 work
130130
is to actually deploy it on `cellscript.dev` and to wire the frontend and CLI
131131
into the same trust model.
132132

133+
The Edition 2026 contract slice is complete: publish protocol v2 and registry
134+
schema 2 are a hard cut across the Rust publisher/reader, API validation,
135+
Postgres schema, R2 package-version object, checked-in registry fixture, and
136+
website data model. There is no schema-1 compatibility path. Generic admin
137+
status changes cannot create `verified_build` or `deployed` claims; an
138+
evidence-specific promotion path remains production work.
139+
133140
### Production Domains And Hosting
134141

135142
```text
@@ -198,9 +205,10 @@ Production-readiness for the registry means all of:
198205
- the first real CellScript source package is published through the
199206
production flow and resolves on a clean machine via `cellc install`.
200207

201-
The existing `services/registry-api` test suite is the baseline. New
202-
end-to-end coverage belongs in a deployable scenario harness, not in the
203-
compiler test gate.
208+
The existing `services/registry-api` typecheck, unit suite, and dry-run Worker
209+
build run in the unified `ci` gate as the local contract baseline. Deployed
210+
end-to-end coverage still belongs in a staging scenario harness; local compiler
211+
CI is not Cloudflare/R2/Hyperdrive/Neon evidence.
204212

205213
### Non-Goals
206214

‎scripts/cellscript_gate.sh‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -357,6 +357,15 @@ run_website_build_check() {
357357
run_in_dir website npm exec -- astro build
358358
}
359359

360+
run_registry_api_check() {
361+
if [[ ! -d services/registry-api/node_modules ]]; then
362+
run npm --prefix services/registry-api ci
363+
fi
364+
run npm --prefix services/registry-api run check
365+
run npm --prefix services/registry-api test
366+
run npm --prefix services/registry-api run build
367+
}
368+
360369
check_wasm_release_bundle() {
361370
require_cmd docker
362371
run website/scripts/build-wasm.sh
@@ -438,6 +447,7 @@ run_ci_gate() {
438447
check_markdown_local_links
439448
check_package_contents
440449
run cargo package --locked --offline --allow-dirty
450+
run_registry_api_check
441451
run_website_build_check
442452
check_script_syntax
443453
run git diff --check

‎services/registry-api/README.md‎

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@ snapshots and static registry read objects are stored in R2.
2929
- Namespace claim cooldown for newly claimed namespaces by the same JoyID
3030
principal; invalid JoyID signatures do not consume principal quota.
3131
- Publish admission path for source packages.
32+
- Hard-cut `cellscript-registry-publish-v2` admission: the signed
33+
`registry_entry` must use registry schema 2, contain exactly the published
34+
version, and bind Edition 2026 plus its compatibility-profile hash.
3235
- Namespace owner ACL check before publish admission.
3336
- P-256 capability-signature verification for daily publish payloads.
3437
- One-time signed nonce consumption for capability creation, capability
@@ -50,7 +53,10 @@ snapshots and static registry read objects are stored in R2.
5053
- Future `policy_hooks` and `bond_policy_hooks` tables for later bond or
5154
refundable-deposit policies; no on-chain fee or bond is enforced now.
5255
- Token-gated admin operations for reserved namespaces, namespace review
53-
status, and package-version status transitions.
56+
status, and conservative package-version status transitions. Generic admin
57+
status changes cannot claim `verified_build` or `deployed`; those promotions
58+
remain unavailable until an evidence-specific endpoint verifies and stores
59+
the corresponding proof.
5460
- Suppressive package-version admin transitions (`deprecated`, `yanked`,
5561
`quarantined`) update the static read object before changing the write-store
5662
status, so public reads fail conservative during incident response.
@@ -128,20 +134,22 @@ for controlled staging tests.
128134
Admin operations require `Authorization: Bearer <REGISTRY_ADMIN_TOKEN>` or
129135
`x-registry-admin-token`. The optional `x-registry-admin-actor` header is stored
130136
in audit logs so manual review, reserved namespace changes, quarantine, yanks,
131-
deprecations, and verification promotions are attributable.
137+
and deprecations are attributable.
132138

133139
Supported package-version status transitions through the admin API are:
134140

135141
```text
136142
source_published
137143
indexed_pending
138-
verified_build
139-
deployed
140144
deprecated
141145
yanked
142146
quarantined
143147
```
144148

149+
`verified_build`, `deployed`, and `on_chain_attested` remain registry states,
150+
but this generic endpoint cannot create those claims. A future promotion path
151+
must validate evidence rather than accepting an operator-supplied label.
152+
145153
Audit events can be queried with:
146154

147155
```text
@@ -193,7 +201,7 @@ cellscript-registry-auth-v1 / authorize_capability
193201
Daily publish signs the canonical JSON form of:
194202

195203
```text
196-
cellscript-registry-publish-v1 / publish
204+
cellscript-registry-publish-v2 / publish
197205
```
198206

199207
The API rejects a publish unless:
@@ -203,6 +211,10 @@ The API rejects a publish unless:
203211
- the capability scope covers `publish:namespace/package`;
204212
- the namespace exists and is active;
205213
- the capability principal owns the namespace;
214+
- the signed nested registry entry is schema 2, names the same package/version
215+
and source hash, and records `edition = "2026"` plus a 32-byte
216+
`compatibility_profile_hash`;
217+
- the signed manifest hash is present;
206218
- the capability signature verifies;
207219
- the signed publish nonce has not already been consumed;
208220
- the package version does not already exist;
@@ -232,7 +244,9 @@ https://registry.cellscript.dev/packages/:namespace/:name/versions/:version.json
232244

233245
The route is served from R2 and sets short CDN cache headers. It does not
234246
require Hyperdrive or the write store, so ordinary package reads stay isolated
235-
from authenticated write-path dependencies.
247+
from authenticated write-path dependencies. Its JSON object is also schema 2
248+
and repeats `edition` and `compatibility_profile_hash` at the top level so
249+
consumers do not need to trust an untyped nested blob.
236250

237251
CLI publish has two supported signing shapes:
238252

‎services/registry-api/migrations/0001_initial.sql‎

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,9 @@ create table if not exists package_versions (
9292
version text not null,
9393
status text not null,
9494
source_hash text not null,
95-
manifest_hash text,
95+
manifest_hash text not null,
96+
edition text not null,
97+
compatibility_profile_hash text not null,
9698
capability_key_id text not null references capabilities(key_id),
9799
principal_type text not null,
98100
principal_id text not null,
@@ -117,7 +119,11 @@ create table if not exists package_versions (
117119
'deprecated',
118120
'yanked',
119121
'quarantined'
120-
))
122+
)),
123+
check (source_hash ~ '^(0x)?[0-9A-Fa-f]{64}$'),
124+
check (manifest_hash ~ '^(0x)?[0-9A-Fa-f]{64}$'),
125+
check (edition = '2026'),
126+
check (compatibility_profile_hash ~ '^(0x)?[0-9A-Fa-f]{64}$')
121127
);
122128

123129
create table if not exists idempotency_keys (

0 commit comments

Comments
 (0)