test(versioning): pin supported compatibility matrix
req: abi/001 req: abi/003 req: v1_release/007
This commit is contained in:
@@ -71,8 +71,10 @@ encryption, retention, backup, and deployment policy remain host concerns.
|
|||||||
## Slice 7 — v1 compatibility and closure
|
## Slice 7 — v1 compatibility and closure
|
||||||
|
|
||||||
- [ ] **User value:** maintainers and adopters receive a reproducible, migration-aware v1 with no known material contradiction and no hidden publication side effect.
|
- [ ] **User value:** maintainers and adopters receive a reproducible, migration-aware v1 with no known material contradiction and no hidden publication side effect.
|
||||||
- **State:** Active; Slices 1-6 are complete, and publishing remains separately authorized.
|
- **State:** In progress — the compatibility audit now names the actually supported matrix, replaces the vague migration-fixture gate with checked-in ABI-v1 bytes plus the real legacy durable-record browser migration, and proves all four canonical example packages together.
|
||||||
- **Build:** freeze the supported Rust/browser/WASM/integration matrix; reconcile public/generated/Surface/symbol/wire/runtime/persisted-schema compatibility; add migration fixtures; make canonical examples compatibility tests; update the progressive tutorial path; run all local release gates and disposition every P0/P1, advisory, unsafe-code, license, performance, accessibility, and documentation finding.
|
- **Build:** freeze the supported Rust/browser/WASM/integration matrix; reconcile public/generated/Surface/symbol/wire/runtime/persisted-schema compatibility; add migration fixtures; make canonical examples compatibility tests; update the progressive tutorial path; run all local release gates and disposition every P0/P1, advisory, unsafe-code, license, performance, accessibility, and documentation finding.
|
||||||
- **Refusals:** no publish, deploy, upload, store submission, speculative feature, or weakening a gate to make it pass.
|
- **Refusals:** no publish, deploy, upload, store submission, speculative feature, or weakening a gate to make it pass.
|
||||||
- **Requirements:** `v1_release/001-010`, `versioning/*`, `test/*`, `diag/*`, `performance/*`, `security/008`, and all requirements changed by the preceding slices.
|
- **Requirements:** `v1_release/001-010`, `versioning/*`, `test/*`, `diag/*`, `performance/*`, `security/008`, and all requirements changed by the preceding slices.
|
||||||
- **Proof:** clean-tree formatting, workspace tests, strict all-target Clippy, compile-fail, browser/WASM/offline/multiplayer scenarios, benchmark budgets, approved pinned lockfile audit, requirements proof audit, docs/examples checks, and independent contradiction review all pass with no unresolved P0/P1.
|
- **Proof:** clean-tree formatting, workspace tests, strict all-target Clippy, compile-fail, browser/WASM/offline/multiplayer scenarios, benchmark budgets, approved pinned lockfile audit, requirements proof audit, docs/examples checks, and independent contradiction review all pass with no unresolved P0/P1.
|
||||||
|
|
||||||
|
`cargo test -p hemx-core --test effect_batch compatibility_fixture_accepts_only_the_declared_v1_wire_version -- --exact`, `cargo test -p hemx-wasm --test browser flat_patch_persists_offline_then_uploads_with_same_operation_identity -- --exact`, and `cargo test -p hemx-v0-examples -p hemx-client-local-example -p hemx-kanban-example -p hemx-saas-example --lib --bins` prove the first compatibility gate. Execution cursor: run the remaining Slice 7 release audit gates from the canonical `hemx-xtask test` entry point, resolve only genuine local failures, and record exact blocked external audit tools instead of inventing substitutes.
|
||||||
|
|||||||
+25
-2
@@ -39,6 +39,22 @@ An incompatible wire/runtime change must bump the relevant ABI version and cause
|
|||||||
old pages or old runtimes to refuse partial updates rather than silently applying
|
old pages or old runtimes to refuse partial updates rather than silently applying
|
||||||
wrong effects. req: abi/002 req: abi/003 req: abi/004 req: failure/005
|
wrong effects. req: abi/002 req: abi/003 req: abi/004 req: failure/005
|
||||||
|
|
||||||
|
### Supported compatibility matrix
|
||||||
|
|
||||||
|
The v1 support claim is deliberately narrow:
|
||||||
|
|
||||||
|
| Boundary | Supported | Fails closed when |
|
||||||
|
|---|---|---|
|
||||||
|
| Rust toolchain | stable Rust, workspace edition 2021 | an unsupported compiler cannot build the workspace |
|
||||||
|
| Browser/WASM | Firefox browser suite plus the generated real-WASM path | WASM/bootstrap cannot load or bind |
|
||||||
|
| Effect wire | ABI `1` only | decoding preserves the version, `is_compatible()` is false, and runtimes refuse application |
|
||||||
|
| Generated resources | one matching build fingerprint | a stale fingerprint receives reload recovery instead of mutation |
|
||||||
|
| Durable sync | schema `1`; legacy flat schema-1 records upgrade in place | unknown schema or malformed projection is rejected |
|
||||||
|
| Runtime set | same-tree `hemx-js`, `hemx-wasm`, generated bindings, and framework sync runtime | mismatched assets have no compatibility guarantee |
|
||||||
|
| Canonical examples | `v0`, Kanban, client-local, and SaaS workspace packages | an example no longer builds or its focused proof fails |
|
||||||
|
|
||||||
|
No support claim is made for untested browser engines, future wire/schema versions, or arbitrary cross-release runtime mixing. req: abi/001 req: abi/003 req: public_api/003 req: v1_release/007
|
||||||
|
|
||||||
### Advanced escape hatches
|
### Advanced escape hatches
|
||||||
|
|
||||||
These are public but advanced. They may evolve faster, but every change still
|
These are public but advanced. They may evolve faster, but every change still
|
||||||
@@ -126,15 +142,22 @@ redgate health --strict
|
|||||||
|
|
||||||
Before tagging a v1-compatible release:
|
Before tagging a v1-compatible release:
|
||||||
|
|
||||||
- `examples/v0` and `examples/saas` compile and test without raw ids, raw effects,
|
- `examples/v0`, `examples/client_local`, `examples/kanban`, and `examples/saas`
|
||||||
|
compile and their package tests pass; v0 and SaaS remain the canonical public
|
||||||
|
surface examples without raw ids, raw effects,
|
||||||
selector targeting, manual registries, raw render/lower calls, or user-authored
|
selector targeting, manual registries, raw render/lower calls, or user-authored
|
||||||
UI JavaScript in the normal path. req: examples/004 req: examples/005
|
UI JavaScript in the normal path. req: examples/004 req: examples/005
|
||||||
- `docs/diagnostics.md` describes any new common error class in user language.
|
- `docs/diagnostics.md` describes any new common error class in user language.
|
||||||
req: diagnostics/001 req: diagnostics/002
|
req: diag/001 req: diag/002
|
||||||
|
- The canonical local release gate is `cargo run -p hemx-xtask -- test`; there
|
||||||
|
are no separate `public-api` or `ownership-check` xtask subcommands.
|
||||||
- `docs/recipes/deploy-versioning.md` remains accurate for runtime asset and
|
- `docs/recipes/deploy-versioning.md` remains accurate for runtime asset and
|
||||||
fingerprint behavior.
|
fingerprint behavior.
|
||||||
- Any incompatible generated ABI/runtime change bumps the relevant ABI/fingerprint
|
- Any incompatible generated ABI/runtime change bumps the relevant ABI/fingerprint
|
||||||
inputs and has tests for fail-closed behavior. req: abi/005
|
inputs and has tests for fail-closed behavior. req: abi/005
|
||||||
|
- The checked-in ABI-v1 byte fixture in `hemx-core/tests/effect_batch.rs`, the
|
||||||
|
legacy flat durable-record browser migration, and canonical example package
|
||||||
|
tests all pass. req: abi/001 req: abi/003 req: v1_release/007
|
||||||
- Advanced APIs touched by the release are still named as escape hatches in docs.
|
- Advanced APIs touched by the release are still named as escape hatches in docs.
|
||||||
- Upgrade notes state whether users must regenerate code, redeploy the
|
- Upgrade notes state whether users must regenerate code, redeploy the
|
||||||
helper-provided runtime asset, or change app code.
|
helper-provided runtime asset, or change app code.
|
||||||
|
|||||||
@@ -30,6 +30,28 @@ fn effect_batch_wire_round_trips() {
|
|||||||
assert!(decoded.is_compatible());
|
assert!(decoded.is_compatible());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn compatibility_fixture_accepts_only_the_declared_v1_wire_version() {
|
||||||
|
// test req: abi/001 req: abi/003 req: v1_release/007
|
||||||
|
const V1_EMPTY_BATCH: &[u8] = &[
|
||||||
|
72, 69, 77, 88, // HEMX
|
||||||
|
1, 0, // ABI v1
|
||||||
|
0, 0, // reserved
|
||||||
|
7, 0, 0, 0, 0, 0, 0, 0, // fingerprint
|
||||||
|
0, 0, 0, 0, // zero operations
|
||||||
|
];
|
||||||
|
assert_eq!(
|
||||||
|
EffectBatch::from_wire(V1_EMPTY_BATCH).unwrap().to_wire(),
|
||||||
|
V1_EMPTY_BATCH
|
||||||
|
);
|
||||||
|
|
||||||
|
let mut future = V1_EMPTY_BATCH.to_vec();
|
||||||
|
future[4] = 2;
|
||||||
|
let future = EffectBatch::from_wire(&future).unwrap();
|
||||||
|
assert_eq!(future.abi_version, 2);
|
||||||
|
assert!(!future.is_compatible());
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn encoded_len_covers_every_effect_shape() {
|
fn encoded_len_covers_every_effect_shape() {
|
||||||
let unscoped = ResourceRef::unscoped(ResourceId::new(ResourceKind::Slot, 1));
|
let unscoped = ResourceRef::unscoped(ResourceId::new(ResourceKind::Slot, 1));
|
||||||
|
|||||||
Reference in New Issue
Block a user