diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b17150d..2d1835f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -2345,21 +2345,38 @@ jobs: raise SystemExit(f'no tag found for {crate} in Cargo.toml') return m.group(1) persist = find_tag('ciris-persist') + verify_major = int(find_tag('ciris-keyring').split('.')[0]) pins = { # CIRISEdge is git-tag-only and persist stopped PyPI-publishing at # v30.4.0, so build persist from the git tag edge pins in Cargo.toml. # - # VERIFY is intentionally NOT pinned here — edge consumes verify THROUGH - # persist. persist's own pyproject says it: `pip install ciris-persist` - # pulls the whole verify+persist stack (its Requires-Dist includes the - # matching `ciris-verify` PyPI package), so a separate override is both - # unnecessary AND wrong: the CIRISVerify Python project lives at - # `bindings/python`, not the repo root, so a `git+…/CIRISVerify` override - # fails "does not appear to be a Python project" (v16.0.1 tag run). The - # Rust crate tag (v13.x) is also NOT the Python package version — persist - # pins the right `ciris-verify` transitively. ciris-server (a PyPI - # package) rounds out the cohabiting set via the harness's base pin. + # VERIFY IS PINNED HERE, as a RANGE, since v21.1.0 (CIRISEdge#579). + # + # It was deliberately omitted before, on reasoning that is true + # and was still wrong: edge consumes verify THROUGH persist, and + # persist's wheel Requires-Dist pins the matching `ciris-verify` + # transitively — so an override looked unnecessary. What that + # missed is that the conformance matrix carries its OWN explicit + # `ciris-verify==X.Y.Z` in `stack`, which this override never + # touched, and an explicit user pin beats a transitive range. The + # first time persist's firewall crossed a verify MAJOR (v42.0.0: + # `ciris-verify>=15,<16`) while the matrix still said 14.2.0, every + # cohab cell on the v21.0.0 tag died at pip-install with + # ResolutionImpossible — before a single test ran. + # + # The override is the MAJOR range derived from the ciris-keyring + # Cargo tag, not an exact version: it mirrors persist's own + # firewall shape, so a verify patch published ahead of edge's Cargo + # pin still resolves. It is a plain PyPI spec, not `git+…`, because + # the CIRISVerify Python project lives at `bindings/python`, not + # the repo root (the v16.0.1 lesson recorded here before). The + # Rust tag and the PyPI version now move together + # (`scripts/bump-version.sh` bumps the workspace and the Python + # package in one step), so the tag's major IS the wheel's major. + # ciris-server's wheel carries no `ciris-verify` dependency at all + # (only `ciris-client`), so this cannot create a third conflict. 'ciris-persist': f'git+https://github.com/CIRISAI/CIRISPersist.git@v{persist}', + 'ciris-verify': f'ciris-verify>={verify_major},<{verify_major + 1}', } print(f'json={json.dumps(pins)}') PYEOF diff --git a/Cargo.lock b/Cargo.lock index 4a29944..ec8d3bc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -996,7 +996,7 @@ dependencies = [ [[package]] name = "ciris-edge" -version = "21.0.0" +version = "21.1.0" dependencies = [ "async-trait", "axum", @@ -1095,8 +1095,8 @@ dependencies = [ [[package]] name = "ciris-persist" -version = "42.0.0" -source = "git+https://github.com/CIRISAI/CIRISPersist?tag=v42.0.0#13aa6347f15085cd8253a6265a3e873202650126" +version = "42.1.0" +source = "git+https://github.com/CIRISAI/CIRISPersist?tag=v42.1.0#00bc08e52a114c1099cb083af9d043ebfa73800f" dependencies = [ "async-trait", "base64 0.22.1", diff --git a/Cargo.toml b/Cargo.toml index d00c81d..ccf3c5d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "ciris-edge" -version = "21.0.0" +version = "21.1.0" edition = "2021" rust-version = "1.75" authors = ["Eric Moore "] @@ -441,7 +441,7 @@ publish = false # registers a SINGLE-role `identity_type` — no fixture encoded the # repealed loophole. # * 2566bc54 still pins CIRISVerify v13.6.1 — one `ciris-verify-core`. -ciris-persist = { git = "https://github.com/CIRISAI/CIRISPersist", tag = "v42.0.0", version = "42", features = ["sqlite", "encrypted-kv"] } +ciris-persist = { git = "https://github.com/CIRISAI/CIRISPersist", tag = "v42.1.0", version = "42", features = ["sqlite", "encrypted-kv"] } # Keyring — Ed25519 + ML-DSA-65 hardware/software signers used by # Edge::send and Edge::send_durable to sign outbound envelopes. # v0.13.0 — bumped to v4.0.0 in lockstep with persist v3.0.0. Both @@ -1540,7 +1540,7 @@ async-trait = "0.1" # two `ciris-verify-core` cdylibs — the empty-stdout SIGSEGV class). # v38.6.0 (CIRISPersist#774) — held in lockstep with the runtime pin above # through the RC-adopt and back onto `tag`. These two move together, always. -ciris-persist = { git = "https://github.com/CIRISAI/CIRISPersist", tag = "v42.0.0", version = "42", features = ["sqlite", "cirisnode", "classify", "scrub", "encrypted-kv"] } +ciris-persist = { git = "https://github.com/CIRISAI/CIRISPersist", tag = "v42.1.0", version = "42", features = ["sqlite", "cirisnode", "classify", "scrub", "encrypted-kv"] } # CIRISEdge#23 / #49 — `tests/transport_http_hardening.rs` + # `tests/https_per_messagetype_roundtrip.rs` + `tests/https_pyedge_init.rs` # (v0.19.3) mint self-signed Ed25519 certs on the fly. v0.19.3 diff --git a/docs/RELEASE_NOTES.md b/docs/RELEASE_NOTES.md index e6c6ce1..a0b6703 100644 --- a/docs/RELEASE_NOTES.md +++ b/docs/RELEASE_NOTES.md @@ -1,5 +1,46 @@ # CIRISEdge Release Notes +# v21.1.0 — adopt CIRISPersist v42.1.0 + +**2026-09-08** — Currency, and a read-path speedup edge actually uses. A +MINOR: same major, all four ABI constants unchanged, verify stays v15.0.0, the +`>=42,<43` floor holds. + +**CIRISPersist#818 — a dimension-prefix filter compares bytes.** SQLite's +`LIKE` is case-insensitive for ASCII, so `list_scores` / `list_attestations` +returned different row sets depending on the backend underneath, and sqlite +was the wrong one under CC 3.1.7 R3 (a dimension is a case-sensitive byte +string, enforced at the write door since v42.0.0). Edge emits only lowercase +dimensions, so no edge read returned a wrong row — but the predicate is now +correct on every backend, which is the property edge relies on. + +**CIRISPersist#817 — dimension reads were O(rows the node authored).** Both +dimension axes compiled to a per-row `json_extract`, so a read for one +dimension parsed every row its attester ever wrote. V137 indexes the generated +`dimension` column that V106 added and nothing used; no table rebuild. **This +one reaches edge directly:** `messages_in_room` and the chat readers filter by +`chat:*` dimension, and now they are index-served instead of a corpus scan. +Pinned upstream by an `EXPLAIN` plan assertion, not a timing. + +**CIRISEdge#579 — the cohabitation lane now carries the verify pin.** All six +cohab cells on the v21.0.0 tag run died at pip-install with +`ResolutionImpossible` — *"ciris-persist 42.0.0 depends on ciris-verify<16 +and >=15.0.0; the user requested ciris-verify==14.2.0"* — before a single test +ran. Edge's `extract-substrate-pins` job deliberately omitted a verify +override, on reasoning that was true and still wrong: persist pins the right +`ciris-verify` transitively, but the conformance matrix carries its own +explicit `ciris-verify==14.2.0`, which the override never touched, and an +explicit pin beats a transitive range. The first persist firewall to cross a +verify major exposed it. The job now emits `ciris-verify>=15,<16` derived from +the `ciris-keyring` Cargo tag — persist's own firewall shape, a plain PyPI spec +(the Python project is not at the repo root), and no conflict with +ciris-server, whose wheel carries no `ciris-verify` dependency. The v21.0.0 +release itself was unaffected: 15 assets, manifest and upload green. + +Verified: the tag derefs to `00bc08e`; one copy each; clippy `-D warnings` +clean on pyo3-full `--all-targets`; lib + integration suites, cargo exits +captured. + # v21.0.0 — adopt CIRISPersist v42.0.0 + CIRISVerify v15.0.0 **2026-09-07** — A MAJOR, because it amends a held contract: CIRISServer is on diff --git a/evidence/CIRISEdge.cc_impl.tsv b/evidence/CIRISEdge.cc_impl.tsv index 1ef90e9..5fde2e5 100644 --- a/evidence/CIRISEdge.cc_impl.tsv +++ b/evidence/CIRISEdge.cc_impl.tsv @@ -7,10 +7,10 @@ # failure. Vendored by CIRISConstitution/tools/check_evidence.py. # Columns: cc_section clm repo path#symbol crate@version decimal_id claim_id repo path#symbol crate@version -5.3.3 CLM-nsproc-delivery-mode CIRISEdge src/delivery_mode.rs#decide ciris-edge@v21.0.0 -3.3.6 CLM-nsproc-cohort-scope CIRISEdge src/replication/bridge.rs#attestation_is_advertised ciris-edge@v21.0.0 -3.1 CLM-nsproc-dimension CIRISEdge src/replication/bridge.rs#attestation_is_advertised ciris-edge@v21.0.0 -3.4 CLM-nsproc-key-boundary-scope CIRISEdge src/key_boundary.rs#KeyBoundaryScope ciris-edge@v21.0.0 -5.3.3.5 CLM-nsproc-recipient-serve-capability CIRISEdge src/replication/bridge.rs#peer_has_serve_capability ciris-edge@v21.0.0 -5.3.2.4 CLM-nsproc-recipient-capability CIRISEdge src/replication/bridge.rs#recipient_capability_withholds ciris-edge@v21.0.0 -5.3.2.4 CLM-nsproc-attestation-prefixes CIRISEdge src/replication/bridge.rs#recipient_capability_withholds ciris-edge@v21.0.0 +5.3.3 CLM-nsproc-delivery-mode CIRISEdge src/delivery_mode.rs#decide ciris-edge@v21.1.0 +3.3.6 CLM-nsproc-cohort-scope CIRISEdge src/replication/bridge.rs#attestation_is_advertised ciris-edge@v21.1.0 +3.1 CLM-nsproc-dimension CIRISEdge src/replication/bridge.rs#attestation_is_advertised ciris-edge@v21.1.0 +3.4 CLM-nsproc-key-boundary-scope CIRISEdge src/key_boundary.rs#KeyBoundaryScope ciris-edge@v21.1.0 +5.3.3.5 CLM-nsproc-recipient-serve-capability CIRISEdge src/replication/bridge.rs#peer_has_serve_capability ciris-edge@v21.1.0 +5.3.2.4 CLM-nsproc-recipient-capability CIRISEdge src/replication/bridge.rs#recipient_capability_withholds ciris-edge@v21.1.0 +5.3.2.4 CLM-nsproc-attestation-prefixes CIRISEdge src/replication/bridge.rs#recipient_capability_withholds ciris-edge@v21.1.0