Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 27 additions & 10 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
6 changes: 3 additions & 3 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -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 <mooreericnyc@gmail.com>"]
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
41 changes: 41 additions & 0 deletions docs/RELEASE_NOTES.md
Original file line number Diff line number Diff line change
@@ -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
Expand Down
14 changes: 7 additions & 7 deletions evidence/CIRISEdge.cc_impl.tsv
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@
# failure. Vendored by CIRISConstitution/tools/check_evidence.py.
# Columns: cc_section <TAB> clm <TAB> repo <TAB> path#symbol <TAB> 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
Loading