ciris-server 0.5.76__tar.gz → 0.5.78__tar.gz
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.
- {ciris_server-0.5.76 → ciris_server-0.5.78}/Cargo.lock +5 -5
- {ciris_server-0.5.76 → ciris_server-0.5.78}/Cargo.toml +5 -5
- {ciris_server-0.5.76 → ciris_server-0.5.78}/PKG-INFO +1 -1
- {ciris_server-0.5.76 → ciris_server-0.5.78}/crates/ciris-lens-core/Cargo.toml +2 -2
- {ciris_server-0.5.76 → ciris_server-0.5.78}/src/accord_provision.rs +42 -4
- {ciris_server-0.5.76 → ciris_server-0.5.78}/src/compose.rs +27 -3
- {ciris_server-0.5.76 → ciris_server-0.5.78}/src/federation_peers.rs +6 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/src/holonomic.rs +4 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/src/replication_reconcile.rs +20 -6
- {ciris_server-0.5.76 → ciris_server-0.5.78}/tests/accord.rs +27 -9
- {ciris_server-0.5.76 → ciris_server-0.5.78}/tests/accord_admit_node.rs +106 -0
- ciris_server-0.5.78/tests/mesh_seed_keyplane_e2e.rs +225 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/tests/release_gates/support.rs +2 -2
- {ciris_server-0.5.76 → ciris_server-0.5.78}/tests/replication_reconcile.rs +23 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/.cargo/config.toml +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/.claude/workflows/localize-ui.js +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/.github/workflows/bench.yml +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/.github/workflows/build-wheels.yml +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/.github/workflows/ci.yml +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/.github/workflows/client-artifacts.yml +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/.github/workflows/conformance.yml +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/.github/workflows/localization.yml +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/.github/workflows/publish-pypi.yml +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/.github/workflows/release.yml +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/.gitignore +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/CHANGELOG.md +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/LICENSE +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/MISSION.md +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/README.md +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/WIRE_VOCABULARY_KINDS.md +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/bench-site/bench_results.json +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/bench-site/index.html +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/bench_results.json +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/benches/alm_chain.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/benches/erasure_survival.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/benches/n_eff_scoring.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/benches/pqc_av_streaming.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/benches/replication_ingest.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/benches/sig_overhead.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/benches/stream_fanout.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/crates/ciris-lens-core/.github/workflows/bench.yml +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/crates/ciris-lens-core/.github/workflows/ci.yml +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/crates/ciris-lens-core/.gitignore +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/crates/ciris-lens-core/.pre-commit-config.yaml +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/crates/ciris-lens-core/FSD/CIRIS_LENS_CORE.md +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/crates/ciris-lens-core/FSD/LENS_CORE_V0_5.md +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/crates/ciris-lens-core/FSD/OPEN_QUESTIONS.md +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/crates/ciris-lens-core/LICENSE +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/crates/ciris-lens-core/MISSION.md +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/crates/ciris-lens-core/README.md +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/crates/ciris-lens-core/benches/aggregate.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/crates/ciris-lens-core/benches/canonicalize.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/crates/ciris-lens-core/benches/project.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/crates/ciris-lens-core/deny.toml +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/crates/ciris-lens-core/docs/BENCHMARKS.md +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/crates/ciris-lens-core/docs/COHABITATION.md +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/crates/ciris-lens-core/docs/PRE_COMMIT.md +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/crates/ciris-lens-core/docs/PUBLIC_SCHEMA_CONTRACT.md +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/crates/ciris-lens-core/docs/PYPI_PUBLISH.md +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/crates/ciris-lens-core/docs/RELEASE_NOTES.md +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/crates/ciris-lens-core/docs/STANDARDS_COMPARISON.md +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/crates/ciris-lens-core/docs/THREAT_MODEL.md +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/crates/ciris-lens-core/patterns_from_cirislens_core/extraction/json_path.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/crates/ciris-lens-core/patterns_from_cirislens_core/extraction/metadata.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/crates/ciris-lens-core/patterns_from_cirislens_core/extraction/mod.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/crates/ciris-lens-core/patterns_from_cirislens_core/scrubber/distilbert_loader.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/crates/ciris-lens-core/patterns_from_cirislens_core/scrubber/fields.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/crates/ciris-lens-core/patterns_from_cirislens_core/scrubber/mod.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/crates/ciris-lens-core/patterns_from_cirislens_core/scrubber/ner.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/crates/ciris-lens-core/patterns_from_cirislens_core/scrubber/ort_loader.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/crates/ciris-lens-core/patterns_from_cirislens_core/scrubber/proptests.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/crates/ciris-lens-core/patterns_from_cirislens_core/scrubber/regex.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/crates/ciris-lens-core/patterns_from_cirislens_core/scrubber/walker.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/crates/ciris-lens-core/patterns_from_cirislens_core/scrubber/xlm_r_loader.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/crates/ciris-lens-core/pyproject.toml +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/crates/ciris-lens-core/python/ciris_lens_core/__init__.py +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/crates/ciris-lens-core/src/audit/api.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/crates/ciris-lens-core/src/audit/delegate.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/crates/ciris-lens-core/src/audit/mod.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/crates/ciris-lens-core/src/audit/pyo3.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/crates/ciris-lens-core/src/canonical/ceg_egress.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/crates/ciris-lens-core/src/canonical/mod.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/crates/ciris-lens-core/src/capacity/attestation.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/crates/ciris-lens-core/src/capacity/mod.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/crates/ciris-lens-core/src/capacity/score.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/crates/ciris-lens-core/src/capture/batch.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/crates/ciris-lens-core/src/capture/client.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/crates/ciris-lens-core/src/capture/consent.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/crates/ciris-lens-core/src/capture/correlation.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/crates/ciris-lens-core/src/capture/event.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/crates/ciris-lens-core/src/capture/mod.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/crates/ciris-lens-core/src/capture/partial.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/crates/ciris-lens-core/src/capture/py_engine.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/crates/ciris-lens-core/src/capture/seal.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/crates/ciris-lens-core/src/cohort/declared.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/crates/ciris-lens-core/src/cohort/mod.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/crates/ciris-lens-core/src/cohort/resourcing.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/crates/ciris-lens-core/src/config/egress.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/crates/ciris-lens-core/src/config/mod.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/crates/ciris-lens-core/src/config/node.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/crates/ciris-lens-core/src/config/retention.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/crates/ciris-lens-core/src/config/upstream.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/crates/ciris-lens-core/src/detector/axis_metrics.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/crates/ciris-lens-core/src/detector/coherence_ratchet.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/crates/ciris-lens-core/src/detector/correlated_action.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/crates/ciris-lens-core/src/detector/distributive_access.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/crates/ciris-lens-core/src/detector/manifold.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/crates/ciris-lens-core/src/detector/mod.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/crates/ciris-lens-core/src/extract/mod.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/crates/ciris-lens-core/src/extract/projection.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/crates/ciris-lens-core/src/ffi/mod.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/crates/ciris-lens-core/src/ffi/pyo3.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/crates/ciris-lens-core/src/lib.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/crates/ciris-lens-core/src/observability/mod.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/crates/ciris-lens-core/src/pipeline/lifecycle.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/crates/ciris-lens-core/src/pipeline/mod.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/crates/ciris-lens-core/src/retention/eviction.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/crates/ciris-lens-core/src/retention/mod.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/crates/ciris-lens-core/src/retention/summary.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/crates/ciris-lens-core/src/role/handler.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/crates/ciris-lens-core/src/role/mod.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/crates/ciris-lens-core/src/role/node.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/crates/ciris-lens-core/src/role/relay.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/crates/ciris-lens-core/src/role/ret_relay.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/crates/ciris-lens-core/src/scores/aggregate.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/crates/ciris-lens-core/src/scores/mod.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/crates/ciris-lens-core/src/scores/oracle.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/crates/ciris-lens-core/src/scoring/assembly.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/crates/ciris-lens-core/src/scoring/axis_calibration.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/crates/ciris-lens-core/src/scoring/calibration.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/crates/ciris-lens-core/src/scoring/capacity.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/crates/ciris-lens-core/src/scoring/mod.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/crates/ciris-lens-core/src/scoring/n_eff.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/crates/ciris-lens-core/src/scoring/result.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/crates/ciris-lens-core/src/signing/event.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/crates/ciris-lens-core/src/signing/mod.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/crates/ciris-lens-core/src/wire/mod.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/crates/ciris-lens-core/src/wire/signer.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/crates/ciris-lens-core/tests/parity/README.md +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/crates/ciris-lens-core/tests/parity/canonical_fixtures.json +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/crates/ciris-lens-core/tests/parity/generate_canonical_fixtures.py +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/crates/ciris-lens-core/tests/sovereign_rlib.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/data/live_mesh_2026-06-22.json +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/docs/SCOPE_PRIVACY.md +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/examples/mesh_propagation/main.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/examples/qa_runner/accord.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/examples/qa_runner/common.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/examples/qa_runner/family.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/examples/qa_runner/main.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/examples/qa_runner/verify.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/installers/windows/README.md +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/installers/windows/bundle-jre.ps1 +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/installers/windows/ciris-server-entry.py +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/installers/windows/ciris-server-installer.iss +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/installers/windows/ciris-server.spec +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/pyproject.toml +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/python/ciris_server/__init__.py +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/python/ciris_server/__main__.py +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/python/ciris_server/cli.py +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/python/ciris_server/desktop_launcher.py +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/rust-toolchain.toml +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/scripts/bench_report.py +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/src/accord.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/src/accord_custody.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/src/accord_halt.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/src/accord_pki/yubico_attestation_root_1.der +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/src/accord_pki/yubico_attestation_root_1.pem +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/src/accord_reactivate.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/src/adapter.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/src/auth/ABSORPTION.md +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/src/auth/api_keys.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/src/auth/attestation.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/src/auth/bootstrap.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/src/auth/consent.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/src/auth/device_auth.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/src/auth/device_grant.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/src/auth/erasure.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/src/auth/gate.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/src/auth/loopback.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/src/auth/mod.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/src/auth/oauth.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/src/auth/occurrence.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/src/auth/ownership.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/src/auth/portable_occurrence.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/src/auth/roles.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/src/auth/self_login.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/src/auth/session.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/src/auth/store.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/src/auth/verify.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/src/benchmarks/bench_results.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/src/benchmarks/mesh.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/src/benchmarks/mod.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/src/benchmarks/scoreboard.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/src/claim_remote.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/src/config.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/src/config_api.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/src/config_reconcile.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/src/delegation_transparency.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/src/family.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/src/federation_admin.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/src/federation_nodecode.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/src/graph_config.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/src/health.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/src/http_log.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/src/identity.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/src/ids.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/src/import.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/src/ingest_http.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/src/lib.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/src/main.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/src/memory_api.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/src/mesh_relay.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/src/nodecode.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/src/peer.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/src/proxy.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/src/py_adapter.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/src/quorum.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/src/radio.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/src/safety/age.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/src/safety/mod.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/src/safety/moderation.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/src/safety/named.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/src/safety/watchlist.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/src/scorer/n_eff.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/src/scorer.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/src/system_data.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/src/telemetry_logs.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/src/yubico_attestation_ca.pem +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/tests/alm_chain.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/tests/audit_chain.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/tests/capacity_scorer.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/tests/chaos_mesh.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/tests/claim_remote.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/tests/config_reconcile.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/tests/device_grant.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/tests/federation_admin.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/tests/federation_session_kex.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/tests/graph_config.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/tests/ingest_http.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/tests/mesh_seed_e2e.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/tests/nat_traversal.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/tests/nodecode.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/tests/noise_floor.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/tests/occurrence.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/tests/ownership.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/tests/peer_replication.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/tests/portable_occurrence.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/tests/release_gates/stage1.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/tests/release_gates/stage2.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/tests/release_gates/stage3.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/tests/release_gates/stage4.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/tests/release_gates/stage5.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/tests/release_gates/stage6.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/tests/release_gates/stage7.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/tests/release_gates/stage8.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/tests/release_gates.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/tests/replication.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/tests/root_bootstrap.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/tests/safety.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/tests/stream_sth_consistency.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/tests/wire_vocabulary_gate.rs +0 -0
- {ciris_server-0.5.76 → ciris_server-0.5.78}/tools/audit_cohort_scope_callers.py +0 -0
|
@@ -821,8 +821,8 @@ dependencies = [
|
|
|
821
821
|
|
|
822
822
|
[[package]]
|
|
823
823
|
name = "ciris-edge"
|
|
824
|
-
version = "8.
|
|
825
|
-
source = "git+https://github.com/CIRISAI/CIRISEdge?tag=v8.
|
|
824
|
+
version = "8.6.1"
|
|
825
|
+
source = "git+https://github.com/CIRISAI/CIRISEdge?tag=v8.6.1#acf26ce7cfe01aee5400c7e01dbd9d5b2e797d9b"
|
|
826
826
|
dependencies = [
|
|
827
827
|
"async-trait",
|
|
828
828
|
"axum",
|
|
@@ -943,8 +943,8 @@ dependencies = [
|
|
|
943
943
|
|
|
944
944
|
[[package]]
|
|
945
945
|
name = "ciris-persist"
|
|
946
|
-
version = "12.0
|
|
947
|
-
source = "git+https://github.com/CIRISAI/CIRISPersist?tag=v12.0
|
|
946
|
+
version = "12.2.0"
|
|
947
|
+
source = "git+https://github.com/CIRISAI/CIRISPersist?tag=v12.2.0#766212c92b52f27f7bf35779bf99f692d6b6a8d0"
|
|
948
948
|
dependencies = [
|
|
949
949
|
"async-trait",
|
|
950
950
|
"base64 0.22.1",
|
|
@@ -983,7 +983,7 @@ dependencies = [
|
|
|
983
983
|
|
|
984
984
|
[[package]]
|
|
985
985
|
name = "ciris-server"
|
|
986
|
-
version = "0.5.
|
|
986
|
+
version = "0.5.78"
|
|
987
987
|
dependencies = [
|
|
988
988
|
"anyhow",
|
|
989
989
|
"async-trait",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[package]
|
|
2
2
|
name = "ciris-server"
|
|
3
|
-
version = "0.5.
|
|
3
|
+
version = "0.5.78" # 0.5.78 = edge v8.6.1 / persist v12.2.0 adoption — the COMPLETE admit-node → mesh-seed loop. (1) #144 KEY-PLANE replication (KERI publish-own): the ReplicationRuntime converges an EnvelopeKind::Key coordinator per consent peer + a key_selector publishing the node's OWN key_id. (2) #150 PRODUCER: admit-node now calls persist v12.2.0 Engine::adopt_scrub_upgrade (CIRISPersist#351) to upgrade the node's own self-signed row to the accord-holder-scrubbed record — so the Key plane publishes an ANCHORED, rootable record → peers root it. Producer (server upgrades the row) + publish-own (edge advertises it) = the seed closes in place, no wipe. (3) #147 §Q B5: persist FountainHeldMeta.{content_bytes,cohort_scope} adopted (server has no fountain-content admit path; import.rs already sets cohort_scope). Verify unchanged v8.5.0. 0.5.77 = persist v12.0.2 anchor seed + accord-card UX.
|
|
4
4
|
edition = "2021"
|
|
5
5
|
# MSRV floor is set by the substrate: ciris-verify v5.2.0 requires 1.86
|
|
6
6
|
# (persist v6.0.1 is 1.83). Build with the higher of the two.
|
|
@@ -123,8 +123,8 @@ ciris-lens-core = { path = "crates/ciris-lens-core" } # ABSORBED in-tree (wo
|
|
|
123
123
|
# `cirislens_wa_cert` + `cirislens_service_token_revocation` expose the auth
|
|
124
124
|
# substrate the fabric absorbs (CIRISServer#9, src/auth): the agent's `wa_cert`
|
|
125
125
|
# table (users/WA/OAuth/api-keys) + the `revoked_service_tokens` table.
|
|
126
|
-
ciris-persist = { git = "https://github.com/CIRISAI/CIRISPersist", tag = "v12.0
|
|
127
|
-
ciris-edge = { git = "https://github.com/CIRISAI/CIRISEdge", tag = "v8.
|
|
126
|
+
ciris-persist = { git = "https://github.com/CIRISAI/CIRISPersist", tag = "v12.2.0", features = ["sqlite", "cirisgraph", "cirislens_wa_cert", "cirislens_service_token_revocation", "cirisaudit", "cirislens_tasks", "cirislens_thoughts", "cirislens_tickets", "cirislens_correlations", "cirislens_deferral_reports", "cirislens_maintenance_locks", "cirislens_creation_ceremonies", "cirislens_legacy_migration", "cirisincident", "telemetry", "secrets"] }
|
|
127
|
+
ciris-edge = { git = "https://github.com/CIRISAI/CIRISEdge", tag = "v8.6.1", features = ["transport-reticulum", "transport-http", "transport-packet-radio"] }
|
|
128
128
|
# Founder-quorum verification + key-id fingerprint at the composition root
|
|
129
129
|
# (threshold:: module path — NOT re-exported at the crate root).
|
|
130
130
|
# LOCKSTEP: persist v9.4.0 transitively pins verify-core v6.6.x — the whole
|
|
@@ -206,7 +206,7 @@ tracing-appender = "0.2"
|
|
|
206
206
|
# - keyring `tpm` (tss-esapi / TPM 2.0) — the real hardware backend; needs
|
|
207
207
|
# libtss2 (Linux build dep). Other targets keep the software keystore.
|
|
208
208
|
[target.'cfg(target_os = "linux")'.dependencies]
|
|
209
|
-
ciris-persist = { git = "https://github.com/CIRISAI/CIRISPersist", tag = "v12.0
|
|
209
|
+
ciris-persist = { git = "https://github.com/CIRISAI/CIRISPersist", tag = "v12.2.0", features = ["postgres", "cirisgraph", "cirislens_wa_cert", "cirislens_service_token_revocation", "cirisaudit", "cirislens_tasks", "cirislens_thoughts", "cirislens_tickets", "cirislens_correlations", "cirislens_deferral_reports", "cirislens_maintenance_locks", "cirislens_creation_ceremonies", "cirislens_legacy_migration", "cirisincident", "telemetry", "secrets"] }
|
|
210
210
|
# keyring `tpm` (TPM-at-rest, Linux-only via tss-esapi). `pkcs11` is no longer
|
|
211
211
|
# per-target — it rides the global `pkcs11` feature now that cryptoki builds on all
|
|
212
212
|
# targets (CIRISVerify v6.12.0).
|
|
@@ -259,7 +259,7 @@ ciris-crypto = { git = "https://github.com/CIRISAI/CIRISVerify", tag = "v8.5.0"
|
|
|
259
259
|
# and never encodes/decodes). This lets tests/chaos_mesh.rs exercise the SUBSTRATE
|
|
260
260
|
# codec (`fountain_encode`/`fountain_decode`) directly — a real MEASURED proof,
|
|
261
261
|
# not a reference stand-in.
|
|
262
|
-
ciris-edge = { git = "https://github.com/CIRISAI/CIRISEdge", tag = "v8.
|
|
262
|
+
ciris-edge = { git = "https://github.com/CIRISAI/CIRISEdge", tag = "v8.6.1", features = ["codec-fountain"] }
|
|
263
263
|
|
|
264
264
|
# PQC realtime-A/V streaming E2E benchmark (CIRISEdge#62 realtime_av profile).
|
|
265
265
|
[[bench]]
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: ciris-server
|
|
3
|
-
Version: 0.5.
|
|
3
|
+
Version: 0.5.78
|
|
4
4
|
License-File: LICENSE
|
|
5
5
|
Summary: The fabric node — the federation's headless cohabitation runtime (registry + lens [+ node] over one shared substrate), as the abi3 wheel CIRISAgent consumes. agent = fabric node + brain.
|
|
6
6
|
Author-email: Eric Moore <eric@ciris.ai>
|
|
@@ -26,8 +26,8 @@ crate-type = ["cdylib", "rlib"]
|
|
|
26
26
|
#
|
|
27
27
|
# OQ-01 closure 2026-05-03: rlib primary, PyO3 cdylib via `python`
|
|
28
28
|
# feature for the deployed-lens cutover.
|
|
29
|
-
ciris-persist = { git = "https://github.com/CIRISAI/CIRISPersist", tag = "v12.0
|
|
30
|
-
ciris-edge = { git = "https://github.com/CIRISAI/CIRISEdge", tag = "v8.
|
|
29
|
+
ciris-persist = { git = "https://github.com/CIRISAI/CIRISPersist", tag = "v12.2.0", version = "12", features = ["extract", "sqlite"] }
|
|
30
|
+
ciris-edge = { git = "https://github.com/CIRISAI/CIRISEdge", tag = "v8.6.1", version = "8", features = ["transport-http", "transport-reticulum"] }
|
|
31
31
|
|
|
32
32
|
# Keyring — relay mode (CIRISLensCore#10) loads its Edge transport-
|
|
33
33
|
# signing identity via `ciris_keyring::load_local_seed`. Edge's
|
|
@@ -1048,7 +1048,7 @@ fn default_admit_identity_type() -> String {
|
|
|
1048
1048
|
/// (the predictable, persist-ingestable path the operator hands to CIRISPersist
|
|
1049
1049
|
/// v12.0.2 to bake) and returned. **1-of-N bootstrap:** a single holder suffices —
|
|
1050
1050
|
/// this is a trust EXTENSION, not the 2/3 kill-switch. Loopback + `pkcs11`-gated.
|
|
1051
|
-
async fn admit_node(State(
|
|
1051
|
+
async fn admit_node(State(st): State<ProvisionState>, body: axum::body::Bytes) -> Response {
|
|
1052
1052
|
let req: AdmitNodeRequest = match serde_json::from_slice(&body) {
|
|
1053
1053
|
Ok(r) => r,
|
|
1054
1054
|
Err(e) => return err(StatusCode::BAD_REQUEST, &format!("bad request: {e}")),
|
|
@@ -1082,11 +1082,11 @@ async fn admit_node(State(_st): State<ProvisionState>, body: axum::body::Bytes)
|
|
|
1082
1082
|
"target key_id contains path separators — refusing to write it",
|
|
1083
1083
|
);
|
|
1084
1084
|
}
|
|
1085
|
-
admit_node_impl(req).await
|
|
1085
|
+
admit_node_impl(st.engine, req).await
|
|
1086
1086
|
}
|
|
1087
1087
|
|
|
1088
1088
|
#[cfg(not(feature = "pkcs11"))]
|
|
1089
|
-
async fn admit_node_impl(_req: AdmitNodeRequest) -> Response {
|
|
1089
|
+
async fn admit_node_impl(_engine: Arc<Engine>, _req: AdmitNodeRequest) -> Response {
|
|
1090
1090
|
err(
|
|
1091
1091
|
StatusCode::NOT_IMPLEMENTED,
|
|
1092
1092
|
"admit-node needs the `pkcs11` feature (the holder's YubiKey + USB-wrapped ML-DSA signer)",
|
|
@@ -1094,7 +1094,7 @@ async fn admit_node_impl(_req: AdmitNodeRequest) -> Response {
|
|
|
1094
1094
|
}
|
|
1095
1095
|
|
|
1096
1096
|
#[cfg(feature = "pkcs11")]
|
|
1097
|
-
async fn admit_node_impl(req: AdmitNodeRequest) -> Response {
|
|
1097
|
+
async fn admit_node_impl(engine: Arc<Engine>, req: AdmitNodeRequest) -> Response {
|
|
1098
1098
|
use std::path::PathBuf;
|
|
1099
1099
|
use std::sync::Arc;
|
|
1100
1100
|
|
|
@@ -1253,10 +1253,48 @@ async fn admit_node_impl(req: AdmitNodeRequest) -> Response {
|
|
|
1253
1253
|
);
|
|
1254
1254
|
}
|
|
1255
1255
|
|
|
1256
|
+
// #150 — PRODUCER: adopt the scrubbed record onto this node's OWN directory row
|
|
1257
|
+
// (persist v12.2.0 `Engine::adopt_scrub_upgrade`, CIRISPersist#351). When the
|
|
1258
|
+
// target IS this node, its boot-time self-signed own-key row is upgraded to the
|
|
1259
|
+
// accord-holder-scrubbed record, so the Key plane (edge publish-own) advertises
|
|
1260
|
+
// an ANCHORED, rootable record and consent peers root it. The primitive is
|
|
1261
|
+
// self-gating (verifies the scrub sig + only upgrades a self-signed → scrubbed
|
|
1262
|
+
// row for the SAME key_id/pubkey), so we call it unconditionally: a target whose
|
|
1263
|
+
// row isn't a valid local upgrade returns Err and we report it without failing
|
|
1264
|
+
// the outbox write (the JSON is still the transport for a remote target / bake).
|
|
1265
|
+
let applied: serde_json::Value = match serde_json::to_value(&scrubbed)
|
|
1266
|
+
.and_then(serde_json::from_value::<ciris_persist::federation::SignedKeyRecord>)
|
|
1267
|
+
{
|
|
1268
|
+
Ok(persist_rec) => match engine.adopt_scrub_upgrade(persist_rec).await {
|
|
1269
|
+
Ok(outcome) => {
|
|
1270
|
+
tracing::info!(
|
|
1271
|
+
target_key_id = %req.target.key_id.trim(),
|
|
1272
|
+
?outcome,
|
|
1273
|
+
"admit-node: adopted the scrubbed record onto the local directory row"
|
|
1274
|
+
);
|
|
1275
|
+
serde_json::json!({ "adopted": true, "outcome": format!("{outcome:?}") })
|
|
1276
|
+
}
|
|
1277
|
+
Err(e) => {
|
|
1278
|
+
tracing::warn!(
|
|
1279
|
+
target_key_id = %req.target.key_id.trim(),
|
|
1280
|
+
error = %e,
|
|
1281
|
+
"admit-node: scrubbed record NOT adopted locally (not this node's own \
|
|
1282
|
+
self-signed row?) — seed JSON saved for transport/bake"
|
|
1283
|
+
);
|
|
1284
|
+
serde_json::json!({ "adopted": false, "reason": e.to_string() })
|
|
1285
|
+
}
|
|
1286
|
+
},
|
|
1287
|
+
Err(e) => {
|
|
1288
|
+
tracing::warn!(error = %e, "admit-node: scrubbed record convert for local adoption");
|
|
1289
|
+
serde_json::json!({ "adopted": false, "reason": format!("record convert: {e}") })
|
|
1290
|
+
}
|
|
1291
|
+
};
|
|
1292
|
+
|
|
1256
1293
|
(
|
|
1257
1294
|
StatusCode::OK,
|
|
1258
1295
|
Json(serde_json::json!({
|
|
1259
1296
|
"saved_to": out_path.display().to_string(),
|
|
1297
|
+
"applied": applied,
|
|
1260
1298
|
"seed": seed,
|
|
1261
1299
|
})),
|
|
1262
1300
|
)
|
|
@@ -1352,18 +1352,42 @@ async fn setup_peer_replication(
|
|
|
1352
1352
|
// health:liveness in. v5.1.0 `start` installs the scheduler control channel
|
|
1353
1353
|
// unconditionally, so the runtime accepts `set_peers` mutation with no
|
|
1354
1354
|
// extra opt-in (CIRISEdge#173 resolved).
|
|
1355
|
+
// Two coordinators per consent peer: Attestation (capacity:* / health:liveness)
|
|
1356
|
+
// AND Key (#144, CIRISEdge#257 — the KERI publish-own key plane). The reconciler
|
|
1357
|
+
// (replication_reconcile.rs) converges the same pair set at runtime.
|
|
1355
1358
|
let peers: Vec<ReplicationPeer> = desired
|
|
1356
1359
|
.iter()
|
|
1357
|
-
.
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
+
.flat_map(|p| {
|
|
1361
|
+
[
|
|
1362
|
+
ReplicationPeer {
|
|
1363
|
+
peer_key_id: p.clone(),
|
|
1364
|
+
kind: EnvelopeKind::Attestation,
|
|
1365
|
+
},
|
|
1366
|
+
ReplicationPeer {
|
|
1367
|
+
peer_key_id: p.clone(),
|
|
1368
|
+
kind: EnvelopeKind::Key,
|
|
1369
|
+
},
|
|
1370
|
+
]
|
|
1360
1371
|
})
|
|
1361
1372
|
.collect();
|
|
1373
|
+
|
|
1374
|
+
// Key-plane publish selector (CIRISEdge#257 / edge v8.6.0): the Key plane's
|
|
1375
|
+
// `list_keys` advertises the key_ids THIS selector yields — the node's OWN
|
|
1376
|
+
// record — instead of the cohort's-own-keys projection. `list_keys` re-reads
|
|
1377
|
+
// the record live each tick, so once admit-node scrub-signs this node's own
|
|
1378
|
+
// record (scrub_key_id = an accord holder), the NEXT anti-entropy round
|
|
1379
|
+
// publishes the scrubbed, ANCHORED record to consent peers → they root it.
|
|
1380
|
+
// (KERI publish-own: the controller publishes its own establishment record.)
|
|
1381
|
+
let own_key_id = cfg.key_id.clone();
|
|
1382
|
+
let key_selector: ciris_edge::replication::CohortProvider =
|
|
1383
|
+
Arc::new(move || vec![own_key_id.clone()]);
|
|
1384
|
+
|
|
1362
1385
|
let runtime = ReplicationRuntime::start(
|
|
1363
1386
|
directory,
|
|
1364
1387
|
transport as Arc<dyn ciris_edge::transport::Transport>,
|
|
1365
1388
|
peers,
|
|
1366
1389
|
ReplicationRuntimeConfig::default(),
|
|
1390
|
+
Some(key_selector),
|
|
1367
1391
|
)
|
|
1368
1392
|
.await;
|
|
1369
1393
|
|
|
@@ -80,6 +80,11 @@ fn err(code: StatusCode, error: &str) -> Response {
|
|
|
80
80
|
struct LocalPeerState {
|
|
81
81
|
key_id: String,
|
|
82
82
|
pubkey_ed25519_base64: String,
|
|
83
|
+
/// The ML-DSA-65 half (present on a hybrid-complete row; `None` on a legacy
|
|
84
|
+
/// bookmark). Projected so the accord admit-node card can auto-fill BOTH of a
|
|
85
|
+
/// selected owned node's pubkeys from the local directory — no manual paste.
|
|
86
|
+
#[serde(skip_serializing_if = "Option::is_none")]
|
|
87
|
+
pubkey_ml_dsa_65_base64: Option<String>,
|
|
83
88
|
canonical: bool,
|
|
84
89
|
/// One of "trusted"|"untrusted"|"blocked"|"unknown". A directory row is an
|
|
85
90
|
/// admitted key ⇒ "trusted".
|
|
@@ -104,6 +109,7 @@ fn to_peer(rec: KeyRecord) -> LocalPeerState {
|
|
|
104
109
|
LocalPeerState {
|
|
105
110
|
key_id: rec.key_id,
|
|
106
111
|
pubkey_ed25519_base64: rec.pubkey_ed25519_base64,
|
|
112
|
+
pubkey_ml_dsa_65_base64: rec.pubkey_ml_dsa_65_base64,
|
|
107
113
|
canonical,
|
|
108
114
|
trust: "trusted",
|
|
109
115
|
first_seen: rec.valid_from.to_rfc3339(),
|
|
@@ -185,6 +185,8 @@ mod tests {
|
|
|
185
185
|
min_viable_symbols: 6,
|
|
186
186
|
symbol_size: 256,
|
|
187
187
|
held_symbols: 5,
|
|
188
|
+
content_bytes: 1280,
|
|
189
|
+
cohort_scope: Some("federation".to_string()),
|
|
188
190
|
recoverable: false,
|
|
189
191
|
admitted_at: "2026-06-21T00:00:00Z".to_string(),
|
|
190
192
|
};
|
|
@@ -207,6 +209,8 @@ mod tests {
|
|
|
207
209
|
min_viable_symbols: 1,
|
|
208
210
|
symbol_size: 1,
|
|
209
211
|
held_symbols: 0,
|
|
212
|
+
content_bytes: 0,
|
|
213
|
+
cohort_scope: None,
|
|
210
214
|
recoverable: false,
|
|
211
215
|
admitted_at: "2026-06-21T00:00:00Z".to_string(),
|
|
212
216
|
};
|
|
@@ -68,13 +68,25 @@ pub async fn reconcile_once(
|
|
|
68
68
|
// EnvelopeKind::Attestation carries BOTH directions (capacity:* out,
|
|
69
69
|
// health:liveness in).
|
|
70
70
|
let directory = engine.federation_directory();
|
|
71
|
-
let mut desired: Vec<ReplicationPeer> = Vec::with_capacity(consented.len());
|
|
71
|
+
let mut desired: Vec<ReplicationPeer> = Vec::with_capacity(consented.len() * 2);
|
|
72
72
|
for peer in consented {
|
|
73
73
|
match directory.lookup_public_key(&peer).await {
|
|
74
|
-
Ok(Some(_)) =>
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
74
|
+
Ok(Some(_)) => {
|
|
75
|
+
// BOTH planes per admitted peer:
|
|
76
|
+
// - Attestation: capacity:* out, health:liveness in (as before).
|
|
77
|
+
// - Key (#144, CIRISEdge#257): the KEY-PLANE anti-entropy. Paired
|
|
78
|
+
// with the runtime's `key_selector` (publishes the node's OWN
|
|
79
|
+
// record — KERI publish-own), this converges a node's scrub-signed
|
|
80
|
+
// accord-anchored record to its consent peers so they can ROOT it.
|
|
81
|
+
desired.push(ReplicationPeer {
|
|
82
|
+
peer_key_id: peer.clone(),
|
|
83
|
+
kind: EnvelopeKind::Attestation,
|
|
84
|
+
});
|
|
85
|
+
desired.push(ReplicationPeer {
|
|
86
|
+
peer_key_id: peer,
|
|
87
|
+
kind: EnvelopeKind::Key,
|
|
88
|
+
});
|
|
89
|
+
}
|
|
78
90
|
Ok(None) => tracing::warn!(
|
|
79
91
|
peer_key_id = %peer,
|
|
80
92
|
"consent:replication observed for an UNADMITTED peer key — skipping reconcile for \
|
|
@@ -91,7 +103,9 @@ pub async fn reconcile_once(
|
|
|
91
103
|
// Diff-converge the live Initiator set to the desired consent peers. Adds
|
|
92
104
|
// become active Initiators (scheduler-driven pull) at runtime; removals stop
|
|
93
105
|
// their rounds + drop inbound routing — all without a restart.
|
|
94
|
-
|
|
106
|
+
// `desired` holds TWO coordinators per peer (Attestation + Key); the reported
|
|
107
|
+
// count is distinct consent peers.
|
|
108
|
+
let count = desired.len() / 2;
|
|
95
109
|
if let Err(e) = runtime.set_peers(desired).await {
|
|
96
110
|
// The runtime's scheduler has stopped (shutdown) — surface so the caller
|
|
97
111
|
// logs + skips; the controller never panics.
|
|
@@ -859,7 +859,11 @@ async fn genesis_refuses_a_member_that_is_not_a_custody_verified_accord_holder()
|
|
|
859
859
|
"rejection must name the non-holder member; got {body}"
|
|
860
860
|
);
|
|
861
861
|
|
|
862
|
-
//
|
|
862
|
+
// The rejected genesis must not entrench THIS test's family. (Every node now
|
|
863
|
+
// seeds + bakes the canonical HUMANITY_ACCORD genesis A1/B1/C1 — persist
|
|
864
|
+
// v12.0.2 / verify v8.5.0 — so `family_established` is baseline-true and the
|
|
865
|
+
// seats are the baked A1/B1/C1; that is orthogonal to this test. What must
|
|
866
|
+
// hold is that NONE of the proposed test members became a seat.)
|
|
863
867
|
let roster: serde_json::Value = client
|
|
864
868
|
.get(format!("{base}/v1/accord-holders"))
|
|
865
869
|
.send()
|
|
@@ -868,10 +872,13 @@ async fn genesis_refuses_a_member_that_is_not_a_custody_verified_accord_holder()
|
|
|
868
872
|
.json()
|
|
869
873
|
.await
|
|
870
874
|
.unwrap();
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
+
let seats = roster["holders"].as_array().expect("holders array");
|
|
876
|
+
for member in ["seat-a", "seat-b", "outsider-not-a-holder"] {
|
|
877
|
+
assert!(
|
|
878
|
+
!seats.iter().any(|h| h["key_id"] == member),
|
|
879
|
+
"a rejected genesis must not entrench member {member}; got {roster}"
|
|
880
|
+
);
|
|
881
|
+
}
|
|
875
882
|
}
|
|
876
883
|
|
|
877
884
|
// ─── Operational halt (CC 4.2.1 / 4.2.3 / §9.2.1) — the enforceable kill-switch ─
|
|
@@ -1116,10 +1123,21 @@ async fn registered_spare_is_not_a_seat_and_cannot_help_reach_quorum() {
|
|
|
1116
1123
|
.await
|
|
1117
1124
|
.unwrap();
|
|
1118
1125
|
assert_eq!(roster["seat_count"], 3, "exactly 3 seats; got {roster}");
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
);
|
|
1126
|
+
// This test's 3 seats + 1 spare are ALL registered accord_holders. (Every node
|
|
1127
|
+
// also seeds the baked A1/B1/C1 canonical genesis — persist v12.0.2 — so assert
|
|
1128
|
+
// membership rather than an exact `registered_total`, which now baselines +3.)
|
|
1129
|
+
let registered = roster["registered"].as_array().expect("registered array");
|
|
1130
|
+
for kid in [
|
|
1131
|
+
"accord-holder-a",
|
|
1132
|
+
"accord-holder-b",
|
|
1133
|
+
"accord-holder-c",
|
|
1134
|
+
"accord-holder-a-spare",
|
|
1135
|
+
] {
|
|
1136
|
+
assert!(
|
|
1137
|
+
registered.iter().any(|h| h["key_id"] == kid),
|
|
1138
|
+
"the 3 seats + spare must all be registered; missing {kid}; got {roster}"
|
|
1139
|
+
);
|
|
1140
|
+
}
|
|
1123
1141
|
assert!(
|
|
1124
1142
|
!roster["holders"]
|
|
1125
1143
|
.as_array()
|
|
@@ -159,3 +159,109 @@ async fn admit_node_scrubbed_record_roots_at_accord_anchor() {
|
|
|
159
159
|
"must NOT root when A1 is not a pinned anchor, got {verdict_wrong:?}"
|
|
160
160
|
);
|
|
161
161
|
}
|
|
162
|
+
|
|
163
|
+
/// The PRODUCER path (CIRISServer#150 / CIRISPersist#351): a node that already
|
|
164
|
+
/// holds its boot-time **self-signed** own-key row upgrades that row IN PLACE to
|
|
165
|
+
/// the accord-holder-scrubbed record via `Engine::adopt_scrub_upgrade` (the old
|
|
166
|
+
/// `register_federation_key` is `ON CONFLICT DO NOTHING` and would have left the
|
|
167
|
+
/// self-signed row). After the upgrade the row ROOTS at the anchor, and a second
|
|
168
|
+
/// apply is idempotent — exactly what admit-node relies on to publish an anchored
|
|
169
|
+
/// record over the Key plane.
|
|
170
|
+
#[tokio::test]
|
|
171
|
+
async fn adopt_scrub_upgrade_promotes_self_signed_own_row_and_roots() {
|
|
172
|
+
use ciris_persist::federation::register::AdoptScrubOutcome;
|
|
173
|
+
|
|
174
|
+
let engine = node().await;
|
|
175
|
+
let now = chrono::Utc::now().to_rfc3339();
|
|
176
|
+
|
|
177
|
+
let a1 = HybridSigningIdentity::generate("humanity-accord-a1-test").expect("gen A1");
|
|
178
|
+
let anchor = produce_self_key_record(&a1, "steward,accord_holder", &now)
|
|
179
|
+
.await
|
|
180
|
+
.expect("A1 anchor");
|
|
181
|
+
let a1_ed_b64 = anchor.record.pubkey_ed25519_base64.clone();
|
|
182
|
+
engine
|
|
183
|
+
.register_federation_key(to_persist(&anchor))
|
|
184
|
+
.await
|
|
185
|
+
.expect("register A1 anchor");
|
|
186
|
+
|
|
187
|
+
// The node's boot-time state: its OWN row, SELF-signed.
|
|
188
|
+
let target = HybridSigningIdentity::generate("canonical-server-1-test").expect("gen target");
|
|
189
|
+
let target_self = produce_self_key_record(&target, "node", &now)
|
|
190
|
+
.await
|
|
191
|
+
.expect("target self record");
|
|
192
|
+
let target_ed_b64 = target_self.record.pubkey_ed25519_base64.clone();
|
|
193
|
+
let target_mldsa_b64 = target_self
|
|
194
|
+
.record
|
|
195
|
+
.pubkey_ml_dsa_65_base64
|
|
196
|
+
.clone()
|
|
197
|
+
.expect("target ml_dsa");
|
|
198
|
+
engine
|
|
199
|
+
.register_federation_key(to_persist(&target_self))
|
|
200
|
+
.await
|
|
201
|
+
.expect("register target SELF-signed own row");
|
|
202
|
+
|
|
203
|
+
// Precondition: a self-signed row does NOT root.
|
|
204
|
+
let backend = engine.sqlite_backend().expect("sqlite backend");
|
|
205
|
+
let anchor_set = [ed32(&a1_ed_b64)];
|
|
206
|
+
assert!(
|
|
207
|
+
!matches!(
|
|
208
|
+
root_binding_anchored(
|
|
209
|
+
backend.as_ref(),
|
|
210
|
+
"canonical-server-1-test",
|
|
211
|
+
&target_ed_b64,
|
|
212
|
+
&anchor_set
|
|
213
|
+
)
|
|
214
|
+
.await,
|
|
215
|
+
RootingVerdict::Confirmed { .. }
|
|
216
|
+
),
|
|
217
|
+
"precondition: the self-signed own row must NOT root yet"
|
|
218
|
+
);
|
|
219
|
+
|
|
220
|
+
// A1 scrub-signs the target, and the node ADOPTS the upgrade onto its own row.
|
|
221
|
+
let scrubbed = produce_scrubbed_key_record(
|
|
222
|
+
&a1,
|
|
223
|
+
ScrubTarget {
|
|
224
|
+
key_id: "canonical-server-1-test".to_string(),
|
|
225
|
+
pubkey_ed25519_base64: target_ed_b64.clone(),
|
|
226
|
+
pubkey_ml_dsa_65_base64: target_mldsa_b64,
|
|
227
|
+
identity_type: "node".to_string(),
|
|
228
|
+
},
|
|
229
|
+
&now,
|
|
230
|
+
)
|
|
231
|
+
.await
|
|
232
|
+
.expect("A1 scrub-signs target");
|
|
233
|
+
|
|
234
|
+
let outcome = engine
|
|
235
|
+
.adopt_scrub_upgrade(to_persist(&scrubbed))
|
|
236
|
+
.await
|
|
237
|
+
.expect("adopt_scrub_upgrade must succeed on a self-signed own row");
|
|
238
|
+
assert!(
|
|
239
|
+
matches!(outcome, AdoptScrubOutcome::Upgraded),
|
|
240
|
+
"first adopt upgrades the self-signed row, got {outcome:?}"
|
|
241
|
+
);
|
|
242
|
+
|
|
243
|
+
// Now the SAME key_id ROOTS — the Key plane would publish an anchored record.
|
|
244
|
+
assert!(
|
|
245
|
+
matches!(
|
|
246
|
+
root_binding_anchored(
|
|
247
|
+
backend.as_ref(),
|
|
248
|
+
"canonical-server-1-test",
|
|
249
|
+
&target_ed_b64,
|
|
250
|
+
&anchor_set
|
|
251
|
+
)
|
|
252
|
+
.await,
|
|
253
|
+
RootingVerdict::Confirmed { .. }
|
|
254
|
+
),
|
|
255
|
+
"after adopt the own row must ROOT at the accord anchor"
|
|
256
|
+
);
|
|
257
|
+
|
|
258
|
+
// Idempotent: re-applying the same outbox record is a no-op (second boot).
|
|
259
|
+
let again = engine
|
|
260
|
+
.adopt_scrub_upgrade(to_persist(&scrubbed))
|
|
261
|
+
.await
|
|
262
|
+
.expect("re-adopt must not error");
|
|
263
|
+
assert!(
|
|
264
|
+
matches!(again, AdoptScrubOutcome::AlreadyAdopted),
|
|
265
|
+
"second adopt is idempotent, got {again:?}"
|
|
266
|
+
);
|
|
267
|
+
}
|