ciris-server 0.4.7__tar.gz → 0.4.8__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.4.7 → ciris_server-0.4.8}/Cargo.lock +1 -1
- {ciris_server-0.4.7 → ciris_server-0.4.8}/Cargo.toml +1 -1
- {ciris_server-0.4.7 → ciris_server-0.4.8}/FSD/LENS_TO_SERVER_MIGRATION.md +23 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/PKG-INFO +1 -1
- {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/src/capture/batch.rs +92 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/src/capture/client.rs +68 -13
- {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/src/capture/correlation.rs +3 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/src/capture/partial.rs +17 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/src/capture/seal.rs +121 -39
- {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/src/config/egress.rs +6 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/src/ffi/pyo3.rs +8 -3
- {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/tests/sovereign_rlib.rs +13 -2
- {ciris_server-0.4.7 → ciris_server-0.4.8}/.cargo/config.toml +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/.github/workflows/bench.yml +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/.github/workflows/ci.yml +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/.github/workflows/conformance.yml +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/.github/workflows/publish-pypi.yml +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/.github/workflows/release.yml +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/.gitignore +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/CHANGELOG.md +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/FSD/MESH_ANIMATION_BRIEF.md +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/FSD/MODERATION_CHILD_SAFETY.md +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/FSD/ONE_WHEEL_REEXPORT.md +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/FSD/PQC_AV_STREAMING_BENCH.md +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/FSD/QA_AGAINST_RUST.md +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/FSD/REGISTRY_FOLD_DERISK.md +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/FSD/SAFETY_LANDSCAPE.md +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/FSD/SERVER_1.0_PLAN.md +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/FSD/WATCHLIST_DETECTION.md +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/LICENSE +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/MISSION.md +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/README.md +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/app/.gitignore +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/app/README.md +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/app/build.gradle.kts +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/app/fabric-client/build.gradle.kts +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/app/fabric-client/src/commonMain/kotlin/ai/ciris/fabric/auth/FederationSigner.kt +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/app/fabric-client/src/commonMain/kotlin/ai/ciris/fabric/model/federation/Erasure.kt +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/app/fabric-client/src/commonMain/kotlin/ai/ciris/fabric/model/federation/FederationContent.kt +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/app/fabric-client/src/commonMain/kotlin/ai/ciris/fabric/model/federation/FederationMetrics.kt +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/app/fabric-client/src/commonMain/kotlin/ai/ciris/fabric/model/federation/FederationPeer.kt +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/app/fabric-client/src/commonMain/kotlin/ai/ciris/fabric/model/federation/NodeCode.kt +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/app/fabric-client/src/commonMain/kotlin/ai/ciris/fabric/model/identity/LocalIdentityAggregate.kt +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/app/fabric-client/src/commonMain/kotlin/ai/ciris/fabric/net/FabricClient.kt +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/app/fabric-client/src/commonMain/kotlin/ai/ciris/fabric/net/FabricEndpoints.kt +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/app/fabric-client/src/commonMain/kotlin/ai/ciris/fabric/platform/PlatformLogger.kt +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/app/fabric-client/src/commonMain/kotlin/ai/ciris/fabric/ui/screens/ErasureScreen.kt +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/app/fabric-client/src/commonMain/kotlin/ai/ciris/fabric/ui/screens/IdentityScreen.kt +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/app/fabric-client/src/commonMain/kotlin/ai/ciris/fabric/viewmodel/ErasureViewModel.kt +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/app/fabric-client/src/commonMain/kotlin/ai/ciris/fabric/viewmodel/IdentityViewModel.kt +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/app/fabric-client/src/commonTest/kotlin/ai/ciris/fabric/IdentitySliceTest.kt +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/app/gradle/wrapper/gradle-wrapper.jar +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/app/gradle/wrapper/gradle-wrapper.properties +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/app/gradle.properties +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/app/gradlew +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/app/gradlew.bat +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/app/settings.gradle.kts +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/bench-site/data.json +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/bench-site/index.html +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/benches/alm_chain.rs +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/benches/pqc_av_streaming.rs +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/benches/replication_ingest.rs +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/benches/stream_fanout.rs +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/.github/workflows/bench.yml +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/.github/workflows/ci.yml +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/.gitignore +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/.pre-commit-config.yaml +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/Cargo.toml +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/FSD/CIRIS_LENS_CORE.md +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/FSD/LENS_CORE_V0_5.md +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/FSD/OPEN_QUESTIONS.md +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/LICENSE +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/MISSION.md +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/README.md +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/benches/aggregate.rs +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/benches/canonicalize.rs +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/benches/project.rs +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/deny.toml +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/docs/BENCHMARKS.md +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/docs/COHABITATION.md +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/docs/PRE_COMMIT.md +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/docs/PUBLIC_SCHEMA_CONTRACT.md +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/docs/PYPI_PUBLISH.md +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/docs/RELEASE_NOTES.md +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/docs/STANDARDS_COMPARISON.md +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/docs/THREAT_MODEL.md +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/patterns_from_cirislens_core/extraction/json_path.rs +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/patterns_from_cirislens_core/extraction/metadata.rs +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/patterns_from_cirislens_core/extraction/mod.rs +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/patterns_from_cirislens_core/scrubber/distilbert_loader.rs +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/patterns_from_cirislens_core/scrubber/fields.rs +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/patterns_from_cirislens_core/scrubber/mod.rs +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/patterns_from_cirislens_core/scrubber/ner.rs +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/patterns_from_cirislens_core/scrubber/ort_loader.rs +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/patterns_from_cirislens_core/scrubber/proptests.rs +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/patterns_from_cirislens_core/scrubber/regex.rs +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/patterns_from_cirislens_core/scrubber/walker.rs +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/patterns_from_cirislens_core/scrubber/xlm_r_loader.rs +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/pyproject.toml +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/python/ciris_lens_core/__init__.py +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/src/audit/api.rs +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/src/audit/delegate.rs +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/src/audit/mod.rs +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/src/audit/pyo3.rs +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/src/canonical/ceg_egress.rs +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/src/canonical/mod.rs +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/src/capacity/attestation.rs +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/src/capacity/mod.rs +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/src/capacity/score.rs +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/src/capture/consent.rs +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/src/capture/event.rs +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/src/capture/mod.rs +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/src/capture/py_engine.rs +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/src/cohort/declared.rs +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/src/cohort/mod.rs +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/src/cohort/resourcing.rs +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/src/config/mod.rs +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/src/config/node.rs +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/src/config/retention.rs +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/src/config/upstream.rs +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/src/detector/axis_metrics.rs +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/src/detector/coherence_ratchet.rs +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/src/detector/correlated_action.rs +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/src/detector/distributive_access.rs +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/src/detector/manifold.rs +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/src/detector/mod.rs +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/src/extract/mod.rs +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/src/extract/projection.rs +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/src/ffi/mod.rs +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/src/lib.rs +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/src/observability/mod.rs +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/src/pipeline/lifecycle.rs +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/src/pipeline/mod.rs +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/src/retention/eviction.rs +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/src/retention/mod.rs +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/src/retention/summary.rs +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/src/role/handler.rs +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/src/role/mod.rs +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/src/role/node.rs +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/src/role/relay.rs +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/src/role/ret_relay.rs +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/src/scores/aggregate.rs +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/src/scores/mod.rs +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/src/scores/oracle.rs +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/src/scoring/assembly.rs +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/src/scoring/axis_calibration.rs +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/src/scoring/calibration.rs +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/src/scoring/capacity.rs +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/src/scoring/mod.rs +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/src/scoring/n_eff.rs +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/src/scoring/result.rs +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/src/signing/event.rs +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/src/signing/mod.rs +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/src/wire/mod.rs +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/src/wire/signer.rs +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/tests/parity/README.md +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/tests/parity/canonical_fixtures.json +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/tests/parity/generate_canonical_fixtures.py +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/pyproject.toml +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/README.md +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/ciris_sdk/README.md +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/ciris_sdk/REFACTORING_SUMMARY.md +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/ciris_sdk/__init__.py +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/ciris_sdk/auth_store.py +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/ciris_sdk/client.py +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/ciris_sdk/examples/__init__.py +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/ciris_sdk/examples/agent_interaction.py +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/ciris_sdk/examples/unified_telemetry_examples.py +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/ciris_sdk/examples/wa_example.py +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/ciris_sdk/exceptions.py +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/ciris_sdk/model_types.py +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/ciris_sdk/models.py +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/ciris_sdk/pagination.py +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/ciris_sdk/rate_limiter.py +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/ciris_sdk/resources/CONFIG_CLIENT.md +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/ciris_sdk/resources/WA_CLIENT_GUIDE.md +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/ciris_sdk/resources/__init__.py +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/ciris_sdk/resources/agent.py +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/ciris_sdk/resources/audit.py +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/ciris_sdk/resources/auth.py +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/ciris_sdk/resources/billing.py +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/ciris_sdk/resources/config.py +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/ciris_sdk/resources/consent.py +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/ciris_sdk/resources/emergency.py +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/ciris_sdk/resources/jobs.py +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/ciris_sdk/resources/memory.py +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/ciris_sdk/resources/setup.py +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/ciris_sdk/resources/system.py +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/ciris_sdk/resources/telemetry.py +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/ciris_sdk/resources/wa.py +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/ciris_sdk/resources/websocket.py +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/ciris_sdk/setup.py +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/ciris_sdk/telemetry_models.py +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/ciris_sdk/telemetry_responses.py +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/ciris_sdk/transport.py +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/ciris_sdk/websocket.py +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/fabric_results.json +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/BILLING_QA_README.md +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/CLAUDE.md +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/README.md +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/SDK_MODULE_INTEGRATION.md +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/__init__.py +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/__main__.py +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/config.py +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/mcp_test_server.py +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/CLAUDE.md +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/MULTI_OCCURRENCE_README.md +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/__init__.py +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/_module_metadata.py +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/accord_metrics_tests.py +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/accord_tests.py +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/adapter_autoload_tests.py +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/adapter_availability_tests.py +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/adapter_config_tests.py +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/adapter_manifest_tests.py +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/agent_mode_tests.py +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/air_tests.py +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/api_tests.py +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/base_test_module.py +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/billing_integration_tests.py +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/billing_tests.py +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/cirisnode_tests.py +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/cognitive_state_api_tests.py +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/comprehensive_api_tests.py +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/comprehensive_single_step_tests.py +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/consent_tests.py +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/context_enrichment_tests.py +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/deferral_taxonomy_tests.py +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/deferral_tests.py +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/degraded_mode_tests.py +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/desktop_viz.py +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/dream_live_tests.py +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/dsar_multi_source_tests.py +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/dsar_tests.py +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/dsar_ticket_workflow_tests.py +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/filter_test_helper.py +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/filter_tests.py +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/handler_tests.py +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/he300_benchmark_tests.py +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/homeassistant_agentic_tests.py +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/hosted_tools_tests.py +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/identity_update_tests.py +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/l4_attestation_tests.py +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/licensed_agent_tests.py +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/mcp_tests.py +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/memory_benchmark_tests.py +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/message_id_debug_test.py +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/mobile/__init__.py +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/mobile/__main__.py +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/mobile/adb_helper.py +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/mobile/device_helper.py +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/mobile/first_time_licensed_agent.py +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/mobile/ios/__init__.py +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/mobile/ios/build_helper.py +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/mobile/ios/idevice_helper.py +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/mobile/ios/ios_ui_automator.py +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/mobile/ios/vision_helper.py +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/mobile/ios/xcrun_helper.py +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/mobile/ios_physical_test_cases.py +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/mobile/ios_test_cases.py +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/mobile/portal_registration.py +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/mobile/test_cases.py +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/mobile/test_runner.py +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/mobile/ui_automator.py +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/mobile/verify_trust_tests.py +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/model_eval_tests.py +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/multi_occurrence_tests.py +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/parallel_locales_tests.py +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/partnership_tests.py +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/play_live_tests.py +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/reddit_tests.py +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/safety_battery.py +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/safety_interpret.py +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/sdk_tests.py +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/secrets_encryption_tests.py +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/setup_e2e_tests.py +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/setup_tests.py +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/simple_single_step_tests.py +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/solitude_live_tests.py +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/sql_external_data_tests.py +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/state_transition_tests.py +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/streaming_verification.py +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/system_messages_tests.py +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/utility_adapters_tests.py +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/vision_tests.py +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/wallet_tests.py +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/web_ui/CLAUDE.md +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/web_ui/__init__.py +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/web_ui/__main__.py +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/web_ui/browser_helper.py +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/web_ui/desktop_app_helper.py +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/web_ui/desktop_test.py +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/web_ui/federation_screen_tags.py +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/web_ui/federation_walk_report.py +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/web_ui/federation_walk_test.py +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/web_ui/licensed_agent_flow.py +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/web_ui/server_manager.py +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/web_ui/test_cases.py +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/web_ui/test_federation_walk_unit.py +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/web_ui/test_runner.py +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/qa_api_test.py +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/qa_reports/qa_report_20250825_073205.json +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/qa_reports/qa_report_20250825_153259.json +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/qa_reports/qa_report_20250825_154628.json +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/qa_reports/qa_report_20250825_154817.json +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/qa_reports/qa_report_20250825_155917.json +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/qa_reports_comprehensive/qa_report_20250825_075504.json +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/qa_reports_final/qa_report_20250825_092420.json +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/qa_reports_test/qa_report_20250825_092452.json +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/qa_scripts/README.md +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/qa_scripts/qa_api_test.py +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/qa_scripts/qa_v1.0_sdk_comprehensive.py +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/qa_scripts/qa_v1.0_unhealthy_services_check.py +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/qa_test.py +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/qa_test_sdk.py +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/requirements.txt +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/runner.py +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/scripts/__init__.py +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/scripts/he300_stream_debug.py +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/server.py +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/staged_env.py +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/status_tracker.py +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/test_data/dsar_multi_source_privacy_schema.yaml +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/test_data/qa_test.db +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/test_data/qa_test_privacy_schema.yaml +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/test_data/sql_config.json +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/run_fabric.py +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/seed_wa_cert.py +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/rust-toolchain.toml +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/scripts/bench_report.py +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/src/auth/ABSORPTION.md +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/src/auth/api_keys.rs +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/src/auth/attestation.rs +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/src/auth/bootstrap.rs +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/src/auth/consent.rs +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/src/auth/device_auth.rs +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/src/auth/erasure.rs +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/src/auth/gate.rs +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/src/auth/mod.rs +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/src/auth/oauth.rs +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/src/auth/ownership.rs +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/src/auth/roles.rs +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/src/auth/self_login.rs +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/src/auth/session.rs +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/src/auth/store.rs +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/src/auth/verify.rs +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/src/benchmarks/mod.rs +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/src/benchmarks/scoreboard.rs +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/src/claim_remote.rs +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/src/compose.rs +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/src/config.rs +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/src/federation_admin.rs +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/src/federation_nodecode.rs +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/src/identity.rs +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/src/import.rs +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/src/ingest_http.rs +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/src/lib.rs +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/src/main.rs +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/src/nodecode.rs +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/src/peer.rs +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/src/quorum.rs +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/src/safety/age.rs +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/src/safety/mod.rs +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/src/safety/moderation.rs +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/src/safety/named.rs +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/src/safety/watchlist.rs +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/src/scorer/n_eff.rs +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/src/scorer.rs +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/tests/alm_chain.rs +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/tests/capacity_scorer.rs +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/tests/chaos_mesh.rs +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/tests/claim_remote.rs +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/tests/federation_admin.rs +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/tests/ingest_http.rs +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/tests/nodecode.rs +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/tests/noise_floor.rs +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/tests/ownership.rs +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/tests/peer_replication.rs +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/tests/replication.rs +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/tests/root_bootstrap.rs +0 -0
- {ciris_server-0.4.7 → ciris_server-0.4.8}/tests/safety.rs +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[package]
|
|
2
2
|
name = "ciris-server"
|
|
3
|
-
version = "0.4.
|
|
3
|
+
version = "0.4.8" # 0.1 = lens-only (agent ~2.9.7); 0.3 = +auth subsystem / one-wheel; 0.4 = +federation peering/identity (capacity scoring, consent:replication, register_federation_key gate, root-bootstrap, NodeCode); 0.4.1 = self-attested first-run root claim (#887); 0.4.2 = one-time claim PIN; 0.4.3 = CC-compliant ownership (infra:* responsible-party owner-binding, no agency, serve-only-until-owned); 0.4.4 = substrate-native user-signed owner-binding — 1-phase /v1/setup/root + the local node's /v1/setup/claim-remote (client is a node; crypto only in the substrate); 0.5 = +registry (~2.9.8); 1.0 = +node (~2.9.10). Patch forward on breakage.
|
|
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.
|
|
@@ -18,6 +18,29 @@
|
|
|
18
18
|
4. Verify (`/v1/identity` shows the same `key_id`; read endpoints 200; ingest lands).
|
|
19
19
|
5. Tear down Grafana / TimescaleDB / the Python ingest API / the OAuth admin.
|
|
20
20
|
|
|
21
|
+
> **v0.4.7 — bridge deploy + agent lens-drop-in (current).** Floor = persist v9.0.0 +
|
|
22
|
+
> verify v6.0.0 + edge v4.6.0 (CEG 1.0-RC29). Two consumers:
|
|
23
|
+
>
|
|
24
|
+
> **Bridge deploy.** `pip install ciris-server==0.4.7` (manylinux abi3 wheel) **or** the
|
|
25
|
+
> `ciris-server-x86_64-unknown-linux-gnu` release binary. **HTTP trace ingest is back**
|
|
26
|
+
> (the §3.4 listen+1 relay): the emitter's legacy POST lands directly —
|
|
27
|
+
> Caddy: `reverse_proxy /lens-api/api/v1/accord/events ciris-server:4243` (no path
|
|
28
|
+
> rewrite). The node is a public Reticulum node at `0.0.0.0:4242` (warm-link target +
|
|
29
|
+
> signed announce + `key_id→dest` discovery). **⚠ HYBRID HARD CUT:** persist v9.0.0
|
|
30
|
+
> rejects classical-only Ed25519 traces (`verify_hybrid_required`) — the deployed
|
|
31
|
+
> `CIRIS-AccordMetrics` emitter MUST run the **hybrid-signing agent build** (the in-tree
|
|
32
|
+
> adapter seals hybrid via `LensClient`), or ingest 401s. Mobile inbound-relay +
|
|
33
|
+
> LXMF propagation are edge work (CIRISEdge#168/#169), not in this release.
|
|
34
|
+
>
|
|
35
|
+
> **Agent lens replacement (drop-in).** `pip install ciris-server==0.4.7`, then swap
|
|
36
|
+
> `from ciris_lens_core import …` → `from ciris_server import …`. The wheel re-exports
|
|
37
|
+
> the **complete** lens surface — `LensClient`, `process_trace_batch`, `scrub_trace`,
|
|
38
|
+
> `scrub_traces_batch`, `ner_is_configured`, `install_relay`, `install_node`,
|
|
39
|
+
> `install_ret_relay`, `LensAudit`, `EgressFilter`, `PeerAcl`, `ScoringConfig`,
|
|
40
|
+
> `UxConfig`, `LensNode`, `RetRelay`, `PROJECTION_VERSION` — over ONE shared substrate
|
|
41
|
+
> (one `.so`, one PyO3 registry: `ciris_server.Engine is ciris_persist.Engine`). Drop the
|
|
42
|
+
> `ciris-lens-core` dependency. This is the 2.9.7 fold.
|
|
43
|
+
|
|
21
44
|
> **Procedure validated** (2026-06-15, on 0.1.x / persist-7 floor): two fresh
|
|
22
45
|
> homes given the *same* planted `ed25519.seed` + `.rid` both booted to the
|
|
23
46
|
> **identical** RNS destination hash — the federation seed is adopted + sealed
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: ciris-server
|
|
3
|
-
Version: 0.4.
|
|
3
|
+
Version: 0.4.8
|
|
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>
|
|
@@ -118,6 +118,23 @@ fn trace_to_wire_json(trace: &CompleteTrace) -> Value {
|
|
|
118
118
|
// but build_batch_bytes refuses unsigned traces, so they're Some here.
|
|
119
119
|
obj.insert("signature".into(), json!(trace.signature));
|
|
120
120
|
obj.insert("signature_key_id".into(), json!(trace.signature_key_id));
|
|
121
|
+
// Hybrid (ML-DSA-65) half + producer PQC pubkey. Required for the
|
|
122
|
+
// trace-tier hard cut (CIRISPersist#225): persist's `VerifyMode::Full`
|
|
123
|
+
// runs `verify_trace_hybrid` under `HybridPolicy::Strict` and the
|
|
124
|
+
// producer's ML-DSA-65 pubkey rides the envelope (the directory is
|
|
125
|
+
// Ed25519-only). Emitted ONLY when set, matching persist's
|
|
126
|
+
// `skip_serializing_if = "Option::is_none"` on these fields — so an
|
|
127
|
+
// Ed25519-only seal stays byte-identical on the wire (and is rejected
|
|
128
|
+
// by the hard cut, as intended).
|
|
129
|
+
if let Some(sig) = &trace.signature_ml_dsa_65 {
|
|
130
|
+
obj.insert("signature_ml_dsa_65".into(), json!(sig));
|
|
131
|
+
}
|
|
132
|
+
if let Some(pk) = &trace.pubkey_ml_dsa_65 {
|
|
133
|
+
obj.insert("pubkey_ml_dsa_65".into(), json!(pk));
|
|
134
|
+
}
|
|
135
|
+
if let Some(id) = &trace.pqc_key_id {
|
|
136
|
+
obj.insert("pqc_key_id".into(), json!(id));
|
|
137
|
+
}
|
|
121
138
|
Value::Object(obj)
|
|
122
139
|
}
|
|
123
140
|
|
|
@@ -233,6 +250,9 @@ mod tests {
|
|
|
233
250
|
],
|
|
234
251
|
signature: None,
|
|
235
252
|
signature_key_id: None,
|
|
253
|
+
signature_ml_dsa_65: None,
|
|
254
|
+
pubkey_ml_dsa_65: None,
|
|
255
|
+
pqc_key_id: None,
|
|
236
256
|
trace_level: Some("generic".into()),
|
|
237
257
|
trace_schema_version: TRACE_SCHEMA_VERSION.into(),
|
|
238
258
|
deployment_profile: Some(json!({
|
|
@@ -389,6 +409,9 @@ mod tests {
|
|
|
389
409
|
],
|
|
390
410
|
signature: None,
|
|
391
411
|
signature_key_id: None,
|
|
412
|
+
signature_ml_dsa_65: None,
|
|
413
|
+
pubkey_ml_dsa_65: None,
|
|
414
|
+
pqc_key_id: None,
|
|
392
415
|
trace_level: Some("generic".into()),
|
|
393
416
|
trace_schema_version: "3.0.0".into(),
|
|
394
417
|
deployment_profile: Some(serde_json::json!({
|
|
@@ -492,4 +515,73 @@ mod tests {
|
|
|
492
515
|
(the dispatch mismatch mints invalid signatures on non-ASCII — CIRISAgent#871 trap)"
|
|
493
516
|
);
|
|
494
517
|
}
|
|
518
|
+
|
|
519
|
+
// ── CIRISPersist#225: 3.0.0 / JCS HYBRID round-trip proof ───────────────
|
|
520
|
+
|
|
521
|
+
/// THE 3.0.0 hybrid wire proof (the trace-tier hard cut, CIRISPersist#225):
|
|
522
|
+
///
|
|
523
|
+
/// A `"3.0.0"` trace that lens-core seals with the bound HYBRID signature
|
|
524
|
+
/// (Ed25519 + ML-DSA-65, via `LocalSigner::sign_hybrid` +
|
|
525
|
+
/// `seal::apply_hybrid_signature`) and wraps must round-trip through
|
|
526
|
+
/// persist's `BatchEnvelope::from_json` AND pass persist's
|
|
527
|
+
/// `verify_trace_hybrid` under `HybridPolicy::Strict` with the JCS
|
|
528
|
+
/// canonicalizer — the exact admission gate `VerifyMode::Full` runs.
|
|
529
|
+
///
|
|
530
|
+
/// This is the regression guard for the `verify_hybrid_base64` break:
|
|
531
|
+
/// the seal frames every signature/pubkey field as STANDARD base64 (the
|
|
532
|
+
/// alphabet persist's hybrid gate decodes), and stamps the ML-DSA-65 half
|
|
533
|
+
/// + producer pubkey the Strict policy requires.
|
|
534
|
+
#[tokio::test]
|
|
535
|
+
async fn batch_300_hybrid_round_trips_through_persist_verify_trace_hybrid() {
|
|
536
|
+
use std::sync::Arc;
|
|
537
|
+
|
|
538
|
+
use base64::{engine::general_purpose::STANDARD as B64, Engine as _};
|
|
539
|
+
use ciris_persist::prelude::LocalSigner;
|
|
540
|
+
use ciris_persist::schema::{BatchEnvelope, BatchEvent};
|
|
541
|
+
use ciris_persist::verify::canonical::{canonicalizer_for, JcsCanonicalizer};
|
|
542
|
+
use ciris_persist::verify::ed25519::{canon_version_for_trace_schema, verify_trace_hybrid};
|
|
543
|
+
use ciris_persist::verify::{HybridPolicy, VerifyOutcome};
|
|
544
|
+
use ed25519_dalek::SigningKey;
|
|
545
|
+
|
|
546
|
+
// Hybrid LocalSigner: Ed25519 + ML-DSA-65 (deterministic seeds).
|
|
547
|
+
let sk = SigningKey::from_bytes(&[225u8; 32]);
|
|
548
|
+
let vk = sk.verifying_key();
|
|
549
|
+
let pqc = ciris_keyring::MlDsa65SoftwareSigner::from_seed_bytes(&[226u8; 32], "hyb-pqc")
|
|
550
|
+
.expect("ml-dsa seed");
|
|
551
|
+
let signer = LocalSigner::from_parts(
|
|
552
|
+
sk,
|
|
553
|
+
"hybrid-host-key".into(),
|
|
554
|
+
Some(Arc::new(pqc) as Arc<dyn ciris_keyring::PqcSigner>),
|
|
555
|
+
Some("hyb-pqc".into()),
|
|
556
|
+
);
|
|
557
|
+
|
|
558
|
+
// Seal: canonical bytes (JCS-dispatched for 3.0.0) → bound hybrid sign.
|
|
559
|
+
let mut trace = sealed_300_trace();
|
|
560
|
+
let canonical = seal::canonical_bytes(&trace).expect("canonicalize 3.0.0");
|
|
561
|
+
let hybrid = signer.sign_hybrid(&canonical).await.expect("hybrid sign");
|
|
562
|
+
seal::apply_hybrid_signature(
|
|
563
|
+
&mut trace,
|
|
564
|
+
&hybrid.classical.signature,
|
|
565
|
+
"hybrid-host-key",
|
|
566
|
+
&hybrid.pqc.signature,
|
|
567
|
+
&hybrid.pqc.public_key,
|
|
568
|
+
"hyb-pqc",
|
|
569
|
+
);
|
|
570
|
+
|
|
571
|
+
// Wrap → persist parse.
|
|
572
|
+
let bytes = build_batch_bytes(&[trace], &provenance_300()).expect("build hybrid batch");
|
|
573
|
+
let env = BatchEnvelope::from_json(&bytes)
|
|
574
|
+
.expect("persist must parse a lens-core-built 3.0.0 hybrid batch");
|
|
575
|
+
let BatchEvent::CompleteTrace { trace: ptrace, .. } = &env.events[0];
|
|
576
|
+
|
|
577
|
+
// The exact admission gate: V2Jcs canonicalizer + Strict hybrid policy.
|
|
578
|
+
let canon = canonicalizer_for(canon_version_for_trace_schema("3.0.0"));
|
|
579
|
+
let ed25519_pubkey_b64 = B64.encode(vk.to_bytes());
|
|
580
|
+
let outcome = verify_trace_hybrid(ptrace, canon, &ed25519_pubkey_b64, HybridPolicy::Strict)
|
|
581
|
+
.expect("persist verify_trace_hybrid must accept a 3.0.0 hybrid-sealed lens trace");
|
|
582
|
+
assert_eq!(outcome, VerifyOutcome::HybridVerified);
|
|
583
|
+
|
|
584
|
+
// Sanity: the canon we built equals JCS for 3.0.0 (dispatch live).
|
|
585
|
+
let _ = JcsCanonicalizer; // type-name lock; JCS is the 3.x canonicalizer.
|
|
586
|
+
}
|
|
495
587
|
}
|
|
@@ -74,7 +74,7 @@ use super::consent::{ConsentConfig, ConsentError, ConsentResolution};
|
|
|
74
74
|
use super::correlation::CorrelationMetadata;
|
|
75
75
|
use super::partial::CompleteTrace;
|
|
76
76
|
use super::partial::{CaptureOutcome, InboundEvent, PartialTraceStore};
|
|
77
|
-
use super::seal::{apply_signature, canonical_bytes, TraceSealError};
|
|
77
|
+
use super::seal::{self, apply_signature, canonical_bytes, TraceSealError};
|
|
78
78
|
|
|
79
79
|
use crate::config::UpstreamLens;
|
|
80
80
|
|
|
@@ -133,6 +133,14 @@ pub enum SealSignError {
|
|
|
133
133
|
#[error("hardware sign: {0}")]
|
|
134
134
|
HardwareSign(String),
|
|
135
135
|
|
|
136
|
+
/// `Engine::sign_hybrid` failed — no `LocalSigner` (the Engine was
|
|
137
|
+
/// built via `from_shared`), no PQC identity configured
|
|
138
|
+
/// (`PqcNotConfigured` — an Ed25519-only deployment cannot produce
|
|
139
|
+
/// the ML-DSA-65 half the trace-tier hard cut requires), or the
|
|
140
|
+
/// underlying signer errored.
|
|
141
|
+
#[error("hybrid sign: {0}")]
|
|
142
|
+
HybridSign(String),
|
|
143
|
+
|
|
136
144
|
/// Wraps [`TraceSealError`] for the (rare) path where a
|
|
137
145
|
/// `LocalSigner` is composed directly (e.g., in tests via
|
|
138
146
|
/// `sign_trace`).
|
|
@@ -253,17 +261,59 @@ pub async fn sign_trace_via_hardware_signer(
|
|
|
253
261
|
Ok(())
|
|
254
262
|
}
|
|
255
263
|
|
|
264
|
+
// ── hybrid_sign_trace_via_engine ─────────────────────────────────────
|
|
265
|
+
|
|
266
|
+
/// Hybrid-sign (Ed25519 + ML-DSA-65) a sealed trace via the Engine's
|
|
267
|
+
/// `LocalSigner`, the federation-admissible seal path.
|
|
268
|
+
///
|
|
269
|
+
/// Computes `seal::canonical_bytes` (the federation-wide canonical bytes
|
|
270
|
+
/// authority) and hands them to [`Engine::sign_hybrid`], which produces
|
|
271
|
+
/// the bound-hybrid signature — Ed25519 over `canonical`, ML-DSA-65 over
|
|
272
|
+
/// `canonical ‖ ed25519_sig` — plus both public keys. The five resulting
|
|
273
|
+
/// fields are stamped via [`seal::apply_hybrid_signature`] (all STANDARD
|
|
274
|
+
/// base64). The trace then passes persist's `VerifyMode::Full`
|
|
275
|
+
/// `verify_trace_hybrid` under `HybridPolicy::Strict` (CIRISPersist#225
|
|
276
|
+
/// trace-tier hard cut).
|
|
277
|
+
///
|
|
278
|
+
/// `signature_key_id` uses the Engine signer's current alias (the
|
|
279
|
+
/// Ed25519 key persist resolves from `accord_public_keys`); the
|
|
280
|
+
/// ML-DSA-65 `pqc_key_id` uses the LocalSigner's `pqc_key_id`, falling
|
|
281
|
+
/// back to the classical alias when the PQC key has no distinct id.
|
|
282
|
+
async fn hybrid_sign_trace_via_engine(
|
|
283
|
+
engine: &Engine,
|
|
284
|
+
trace: &mut CompleteTrace,
|
|
285
|
+
) -> Result<(), SealSignError> {
|
|
286
|
+
let bytes = canonical_bytes(trace).map_err(SealSignError::Canonicalize)?;
|
|
287
|
+
let hybrid = engine
|
|
288
|
+
.sign_hybrid(&bytes)
|
|
289
|
+
.await
|
|
290
|
+
.map_err(|e| SealSignError::HybridSign(e.to_string()))?;
|
|
291
|
+
// The Ed25519 key_id is the producer's federation alias persist
|
|
292
|
+
// resolves from `accord_public_keys`. `pqc_key_id` is verbatim
|
|
293
|
+
// metadata persist stores but the hybrid verify does not consult
|
|
294
|
+
// (the producer's ML-DSA-65 pubkey rides the envelope and is bound
|
|
295
|
+
// into the verify); the Engine exposes no separate PQC alias
|
|
296
|
+
// accessor, so we label it with the same federation alias.
|
|
297
|
+
let key_id = engine.signer().current_alias().to_owned();
|
|
298
|
+
seal::apply_hybrid_signature(
|
|
299
|
+
trace,
|
|
300
|
+
&hybrid.classical.signature,
|
|
301
|
+
&key_id,
|
|
302
|
+
&hybrid.pqc.signature,
|
|
303
|
+
&hybrid.pqc.public_key,
|
|
304
|
+
&key_id,
|
|
305
|
+
);
|
|
306
|
+
Ok(())
|
|
307
|
+
}
|
|
308
|
+
|
|
256
309
|
// ── seal_sign_wrap ───────────────────────────────────────────────────
|
|
257
310
|
|
|
258
|
-
/// Stamp missing fields, sign via `
|
|
259
|
-
/// signed trace into `BatchEnvelope` wire bytes ready for
|
|
311
|
+
/// Stamp missing fields, hybrid-sign via the Engine's `LocalSigner`, and
|
|
312
|
+
/// wrap the signed trace into `BatchEnvelope` wire bytes ready for
|
|
260
313
|
/// `Engine::receive_and_persist` (and federation fan-out).
|
|
261
314
|
///
|
|
262
315
|
/// Separated from the async `capture_event` path so it can be tested
|
|
263
|
-
/// independently (see `tests::seal_sign_wrap_*` below).
|
|
264
|
-
/// harness exercises this with a `LocalSigner`-backed
|
|
265
|
-
/// `sign_trace_via_hardware_signer` mock that skips the real
|
|
266
|
-
/// `HardwareSigner` I/O.
|
|
316
|
+
/// independently (see `tests::seal_sign_wrap_*` below).
|
|
267
317
|
///
|
|
268
318
|
/// Steps:
|
|
269
319
|
///
|
|
@@ -271,7 +321,7 @@ pub async fn sign_trace_via_hardware_signer(
|
|
|
271
321
|
/// one (2.7.9 required cohort block).
|
|
272
322
|
/// 2. Stamp `trace_level` if absent (fallback from
|
|
273
323
|
/// [`BatchProvenance::trace_level`]).
|
|
274
|
-
/// 3.
|
|
324
|
+
/// 3. Hybrid-sign via [`hybrid_sign_trace_via_engine`].
|
|
275
325
|
/// 4. Wrap into `BatchEnvelope` bytes via [`build_batch_bytes`].
|
|
276
326
|
///
|
|
277
327
|
/// # Design note — deployment_profile stamp
|
|
@@ -283,7 +333,7 @@ pub async fn sign_trace_via_hardware_signer(
|
|
|
283
333
|
/// whose `THOUGHT_START` event already carried a non-None
|
|
284
334
|
/// `deployment_profile` (future multi-hop scenario) keeps its own.
|
|
285
335
|
async fn seal_sign_wrap(
|
|
286
|
-
|
|
336
|
+
engine: &Engine,
|
|
287
337
|
trace: &mut CompleteTrace,
|
|
288
338
|
provenance: &BatchProvenance,
|
|
289
339
|
deployment_profile: Option<&serde_json::Value>,
|
|
@@ -296,8 +346,8 @@ async fn seal_sign_wrap(
|
|
|
296
346
|
if trace.trace_level.is_none() {
|
|
297
347
|
trace.trace_level = Some(provenance.trace_level.clone());
|
|
298
348
|
}
|
|
299
|
-
// 3.
|
|
300
|
-
|
|
349
|
+
// 3. Hybrid-sign (Ed25519 + ML-DSA-65 — the trace-tier hard cut).
|
|
350
|
+
hybrid_sign_trace_via_engine(engine, trace).await?;
|
|
301
351
|
// 4. Batch → bytes.
|
|
302
352
|
let bytes = build_batch_bytes(std::slice::from_ref(trace), provenance)?;
|
|
303
353
|
Ok(bytes)
|
|
@@ -632,9 +682,11 @@ impl CaptureClient {
|
|
|
632
682
|
} => {
|
|
633
683
|
let trace_id = trace.trace_id.clone();
|
|
634
684
|
|
|
635
|
-
// Sign + wrap (async, lock released).
|
|
685
|
+
// Sign + wrap (async, lock released). Hybrid-signs via the
|
|
686
|
+
// Engine's LocalSigner so the trace carries both halves the
|
|
687
|
+
// CIRISPersist#225 trace-tier hard cut requires.
|
|
636
688
|
let bytes = seal_sign_wrap(
|
|
637
|
-
self.engine.
|
|
689
|
+
self.engine.as_ref(),
|
|
638
690
|
&mut trace,
|
|
639
691
|
&provenance,
|
|
640
692
|
deployment_profile.as_ref(),
|
|
@@ -788,6 +840,9 @@ mod tests {
|
|
|
788
840
|
],
|
|
789
841
|
signature: None,
|
|
790
842
|
signature_key_id: None,
|
|
843
|
+
signature_ml_dsa_65: None,
|
|
844
|
+
pubkey_ml_dsa_65: None,
|
|
845
|
+
pqc_key_id: None,
|
|
791
846
|
trace_level: Some("generic".into()),
|
|
792
847
|
trace_schema_version: TRACE_SCHEMA_VERSION.into(),
|
|
793
848
|
deployment_profile: Some(deployment_profile()),
|
|
@@ -794,6 +794,9 @@ mod tests {
|
|
|
794
794
|
}],
|
|
795
795
|
signature: None,
|
|
796
796
|
signature_key_id: None,
|
|
797
|
+
signature_ml_dsa_65: None,
|
|
798
|
+
pubkey_ml_dsa_65: None,
|
|
799
|
+
pqc_key_id: None,
|
|
797
800
|
trace_level: Some("generic".into()),
|
|
798
801
|
trace_schema_version: TRACE_SCHEMA_VERSION.into(),
|
|
799
802
|
deployment_profile: Some(json!({
|
|
@@ -123,6 +123,20 @@ pub struct CompleteTrace {
|
|
|
123
123
|
pub components: Vec<TraceComponent>,
|
|
124
124
|
pub signature: Option<String>,
|
|
125
125
|
pub signature_key_id: Option<String>,
|
|
126
|
+
/// ML-DSA-65 (FIPS 204) signature half of the hybrid trace seal,
|
|
127
|
+
/// STANDARD base64. Signed over the bound input `canonical ‖
|
|
128
|
+
/// ed25519_sig` (the bound-hybrid construction persist's
|
|
129
|
+
/// `verify_trace_hybrid` reconstructs). `None` until the hybrid seal
|
|
130
|
+
/// stamps it; the trace-tier hard cut (CIRISPersist#225) rejects a
|
|
131
|
+
/// classical-only trace at `VerifyMode::Full` admission.
|
|
132
|
+
pub signature_ml_dsa_65: Option<String>,
|
|
133
|
+
/// Producer's ML-DSA-65 public key, STANDARD base64 (1952 raw bytes).
|
|
134
|
+
/// Rides the trace envelope because the `accord_public_keys`
|
|
135
|
+
/// directory is Ed25519-only; bound into the hybrid verify. `None`
|
|
136
|
+
/// together with [`signature_ml_dsa_65`](Self::signature_ml_dsa_65).
|
|
137
|
+
pub pubkey_ml_dsa_65: Option<String>,
|
|
138
|
+
/// Identifier of the ML-DSA-65 signing key (stored verbatim).
|
|
139
|
+
pub pqc_key_id: Option<String>,
|
|
126
140
|
pub trace_level: Option<String>,
|
|
127
141
|
pub trace_schema_version: String,
|
|
128
142
|
/// 6-field cohort-taxonomy block (2.7.9+). Required on the wire at
|
|
@@ -241,6 +255,9 @@ impl PartialTraceStore {
|
|
|
241
255
|
components: Vec::new(),
|
|
242
256
|
signature: None,
|
|
243
257
|
signature_key_id: None,
|
|
258
|
+
signature_ml_dsa_65: None,
|
|
259
|
+
pubkey_ml_dsa_65: None,
|
|
260
|
+
pqc_key_id: None,
|
|
244
261
|
trace_level: ev.trace_level.clone(),
|
|
245
262
|
trace_schema_version: TRACE_SCHEMA_VERSION.to_string(),
|
|
246
263
|
deployment_profile: None,
|
|
@@ -3,16 +3,22 @@
|
|
|
3
3
|
//!
|
|
4
4
|
//! # The signature-critical contract
|
|
5
5
|
//!
|
|
6
|
-
//! When `ACTION_RESULT` seals a trace, lens-core canonicalizes it
|
|
7
|
-
//! **
|
|
8
|
-
//!
|
|
9
|
-
//!
|
|
10
|
-
//!
|
|
11
|
-
//!
|
|
12
|
-
//!
|
|
13
|
-
//!
|
|
14
|
-
//!
|
|
15
|
-
//! +
|
|
6
|
+
//! When `ACTION_RESULT` seals a trace, lens-core canonicalizes it and
|
|
7
|
+
//! **hybrid**-signs the canonical bytes (Ed25519 + ML-DSA-65, via the
|
|
8
|
+
//! host `Engine::sign_hybrid`). persist's trace-tier hard cut
|
|
9
|
+
//! (CIRISPersist#225: `VerifyMode::Full` → `verify_trace_hybrid` under
|
|
10
|
+
//! `HybridPolicy::Strict`) REJECTS a classical-only trace at admission —
|
|
11
|
+
//! the durable, replicated, kept-for-posterity corpus outlives Ed25519,
|
|
12
|
+
//! so an HNDL forge-later adversary must not be able to mint backdated
|
|
13
|
+
//! traces. (The Ed25519-only [`apply_signature`] / [`sign_trace`] /
|
|
14
|
+
//! [`verify_trace_signature`] primitives remain for the classical verify
|
|
15
|
+
//! path + back-compat tests, but a federation-admissible seal is hybrid.)
|
|
16
|
+
//! The **canonical bytes must be byte-identical** to what every
|
|
17
|
+
//! federation verifier recomputes, or the signature fails to verify. This
|
|
18
|
+
//! module owns the canonical-envelope *structure*; the byte serialization
|
|
19
|
+
//! is delegated to persist's **version-aware dispatch** —
|
|
20
|
+
//! `canon_version_for_trace_schema` + `canonicalizer_for`
|
|
21
|
+
//! (CIRISPersist#171 / v4.6.0 / v4.15.0 #871).
|
|
16
22
|
//!
|
|
17
23
|
//! # JCS / 3.0.0 era (CIRISLensCore#43.2)
|
|
18
24
|
//!
|
|
@@ -58,12 +64,13 @@
|
|
|
58
64
|
//! # This module
|
|
59
65
|
//!
|
|
60
66
|
//! The pure, signature-critical core: [`build_canonical_envelope`] /
|
|
61
|
-
//! [`canonical_bytes`] (the signed bytes) +
|
|
62
|
-
//! [`
|
|
63
|
-
//!
|
|
64
|
-
//!
|
|
65
|
-
//! →
|
|
66
|
-
//!
|
|
67
|
+
//! [`canonical_bytes`] (the signed bytes) + the stamps
|
|
68
|
+
//! [`apply_signature`] (Ed25519-only) / [`apply_hybrid_signature`]
|
|
69
|
+
//! (Ed25519 + ML-DSA-65) + [`verify_trace_signature`] (the Ed25519
|
|
70
|
+
//! federation-verifier algorithm). No Engine, no I/O — fully unit-tested
|
|
71
|
+
//! incl. sign→verify round-trips. The async glue that hybrid-signs via
|
|
72
|
+
//! `Engine::sign_hybrid` and calls `receive_and_persist` lives in
|
|
73
|
+
//! `capture::client` (`hybrid_sign_trace_via_engine` / `seal_sign_wrap`).
|
|
67
74
|
|
|
68
75
|
use serde_json::{json, Map, Value};
|
|
69
76
|
|
|
@@ -200,31 +207,76 @@ pub fn canonical_bytes(trace: &CompleteTrace) -> Result<Vec<u8>, String> {
|
|
|
200
207
|
|
|
201
208
|
// ── Signature application + verification ────────────────────────────
|
|
202
209
|
//
|
|
203
|
-
// Trace signing is **Ed25519-
|
|
204
|
-
//
|
|
205
|
-
//
|
|
206
|
-
//
|
|
207
|
-
//
|
|
208
|
-
//
|
|
209
|
-
//
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
210
|
+
// Trace signing is a **bound hybrid** (Ed25519 + ML-DSA-65) over the
|
|
211
|
+
// canonical bytes. persist's trace-tier hard cut (CIRISPersist#225,
|
|
212
|
+
// `VerifyMode::Full` → `verify_trace_hybrid` under `HybridPolicy::Strict`)
|
|
213
|
+
// REJECTS a classical-only trace at admission — the durable, replicated,
|
|
214
|
+
// kept-for-posterity corpus outlives Ed25519, so an HNDL forge-later
|
|
215
|
+
// adversary must not be able to mint backdated traces. Both signature
|
|
216
|
+
// halves + the producer's ML-DSA-65 pubkey ride the trace envelope.
|
|
217
|
+
//
|
|
218
|
+
// **Base64 framing (the CIRISPersist#225 trap this module fixes):**
|
|
219
|
+
// every signature/pubkey field is **STANDARD** base64. persist's hybrid
|
|
220
|
+
// gate (`verify::hybrid::verify_hybrid` → `decode_b64_fixed`) decodes
|
|
221
|
+
// STANDARD ONLY; URL-safe-no-pad base64-rejects there with
|
|
222
|
+
// `verify_hybrid_base64` BEFORE any crypto runs. The Ed25519-only path
|
|
223
|
+
// (`verify_trace` → `decode_signature`) accepts any alphabet, so STANDARD
|
|
224
|
+
// satisfies BOTH — URL-safe-no-pad satisfies only the Ed25519-only path.
|
|
225
|
+
//
|
|
226
|
+
// The bound-hybrid construction: Ed25519 signs `canonical`; ML-DSA-65
|
|
227
|
+
// signs `canonical ‖ ed25519_sig` (prevents classical-half stripping).
|
|
228
|
+
// This mirrors persist's own `LocalSigner::sign_hybrid` /
|
|
229
|
+
// `verify_trace_hybrid` byte-for-byte (lens-core never rolls crypto).
|
|
230
|
+
|
|
231
|
+
/// Encode a signature/pubkey for a `CompleteTrace` field: **STANDARD**
|
|
232
|
+
/// base64 (with padding) — the alphabet persist's hybrid trace-tier gate
|
|
233
|
+
/// (`verify::hybrid::verify_hybrid`, STANDARD-only) decodes. persist's
|
|
234
|
+
/// Ed25519-only `verify_trace` accepts any alphabet, so STANDARD
|
|
235
|
+
/// satisfies BOTH verify paths; URL-safe-no-pad does NOT (it
|
|
236
|
+
/// base64-rejects at the hybrid gate → `verify_hybrid_base64`). Matches
|
|
237
|
+
/// persist's producer-side `hybrid_sign_trace` reference exactly.
|
|
214
238
|
pub fn encode_signature(sig_bytes: &[u8]) -> String {
|
|
215
239
|
use base64::Engine as _;
|
|
216
|
-
base64::engine::general_purpose::
|
|
240
|
+
base64::engine::general_purpose::STANDARD.encode(sig_bytes)
|
|
217
241
|
}
|
|
218
242
|
|
|
219
|
-
/// Stamp a computed signature onto a sealed trace
|
|
220
|
-
///
|
|
221
|
-
///
|
|
222
|
-
///
|
|
243
|
+
/// Stamp a computed **Ed25519** signature onto a sealed trace (classical
|
|
244
|
+
/// half only). Pure. For a federation-admissible trace use
|
|
245
|
+
/// [`apply_hybrid_signature`] — the classical-only stamp is rejected by
|
|
246
|
+
/// persist's `VerifyMode::Full` hybrid hard cut (CIRISPersist#225).
|
|
247
|
+
/// Retained for the Ed25519-only verify path + back-compat unit tests.
|
|
223
248
|
pub fn apply_signature(trace: &mut CompleteTrace, sig_bytes: &[u8], key_id: &str) {
|
|
224
249
|
trace.signature = Some(encode_signature(sig_bytes));
|
|
225
250
|
trace.signature_key_id = Some(key_id.to_string());
|
|
226
251
|
}
|
|
227
252
|
|
|
253
|
+
/// Stamp a computed **hybrid** (Ed25519 + ML-DSA-65) signature onto a
|
|
254
|
+
/// sealed trace — the federation-admissible seal. Stamps all five fields
|
|
255
|
+
/// persist's `verify_trace_hybrid` reads: the Ed25519 `signature` (+
|
|
256
|
+
/// `signature_key_id`), the `signature_ml_dsa_65` half, the producer's
|
|
257
|
+
/// `pubkey_ml_dsa_65` (rides the envelope; the directory is Ed25519-only),
|
|
258
|
+
/// and `pqc_key_id`. All raw byte inputs are STANDARD-base64 framed.
|
|
259
|
+
///
|
|
260
|
+
/// `ed25519_sig` is over `canonical`; `ml_dsa_65_sig` is over the bound
|
|
261
|
+
/// input `canonical ‖ ed25519_sig`. The caller (the Engine-coupled
|
|
262
|
+
/// hybrid signer glue) obtains both halves + the PQC pubkey from
|
|
263
|
+
/// `Engine::sign_hybrid`, which builds exactly this bound shape.
|
|
264
|
+
#[allow(clippy::too_many_arguments)]
|
|
265
|
+
pub fn apply_hybrid_signature(
|
|
266
|
+
trace: &mut CompleteTrace,
|
|
267
|
+
ed25519_sig: &[u8],
|
|
268
|
+
key_id: &str,
|
|
269
|
+
ml_dsa_65_sig: &[u8],
|
|
270
|
+
pubkey_ml_dsa_65: &[u8],
|
|
271
|
+
pqc_key_id: &str,
|
|
272
|
+
) {
|
|
273
|
+
trace.signature = Some(encode_signature(ed25519_sig));
|
|
274
|
+
trace.signature_key_id = Some(key_id.to_string());
|
|
275
|
+
trace.signature_ml_dsa_65 = Some(encode_signature(ml_dsa_65_sig));
|
|
276
|
+
trace.pubkey_ml_dsa_65 = Some(encode_signature(pubkey_ml_dsa_65));
|
|
277
|
+
trace.pqc_key_id = Some(pqc_key_id.to_string());
|
|
278
|
+
}
|
|
279
|
+
|
|
228
280
|
/// Verify a sealed trace's Ed25519 signature against `verifying_key`,
|
|
229
281
|
/// recomputing the canonical bytes (sign/verify can never drift — both
|
|
230
282
|
/// go through [`canonical_bytes`]). Returns `false` on any failure
|
|
@@ -242,7 +294,15 @@ pub fn verify_trace_signature(
|
|
|
242
294
|
let Some(sig_b64) = &trace.signature else {
|
|
243
295
|
return false;
|
|
244
296
|
};
|
|
245
|
-
|
|
297
|
+
// Decode any alphabet persist accepts (`verify::ed25519::decode_signature`):
|
|
298
|
+
// STANDARD (our seal stamp, hybrid-gate-compatible) then URL-safe
|
|
299
|
+
// (legacy / agent `urlsafe_b64encode`). Fail-closed if none decode.
|
|
300
|
+
use base64::engine::general_purpose::{STANDARD, URL_SAFE, URL_SAFE_NO_PAD};
|
|
301
|
+
let Ok(sig_raw) = STANDARD
|
|
302
|
+
.decode(sig_b64)
|
|
303
|
+
.or_else(|_| URL_SAFE_NO_PAD.decode(sig_b64))
|
|
304
|
+
.or_else(|_| URL_SAFE.decode(sig_b64))
|
|
305
|
+
else {
|
|
246
306
|
return false;
|
|
247
307
|
};
|
|
248
308
|
let Ok(sig_arr) = <[u8; 64]>::try_from(sig_raw.as_slice()) else {
|
|
@@ -337,6 +397,9 @@ mod tests {
|
|
|
337
397
|
],
|
|
338
398
|
signature: None,
|
|
339
399
|
signature_key_id: None,
|
|
400
|
+
signature_ml_dsa_65: None,
|
|
401
|
+
pubkey_ml_dsa_65: None,
|
|
402
|
+
pqc_key_id: None,
|
|
340
403
|
trace_level: Some("FULL_TRACES".into()),
|
|
341
404
|
trace_schema_version: TRACE_SCHEMA_VERSION.into(),
|
|
342
405
|
deployment_profile: None,
|
|
@@ -461,6 +524,9 @@ mod tests {
|
|
|
461
524
|
}],
|
|
462
525
|
signature: None,
|
|
463
526
|
signature_key_id: None,
|
|
527
|
+
signature_ml_dsa_65: None,
|
|
528
|
+
pubkey_ml_dsa_65: None,
|
|
529
|
+
pqc_key_id: None,
|
|
464
530
|
trace_level: Some("GENERIC".into()),
|
|
465
531
|
trace_schema_version: "2.7.9".into(), // V1Python path — explicit
|
|
466
532
|
deployment_profile: None,
|
|
@@ -482,14 +548,24 @@ mod tests {
|
|
|
482
548
|
}
|
|
483
549
|
|
|
484
550
|
#[test]
|
|
485
|
-
fn
|
|
486
|
-
// 64-byte Ed25519 sig →
|
|
487
|
-
//
|
|
551
|
+
fn encode_signature_is_standard_base64() {
|
|
552
|
+
// 64-byte Ed25519 sig → 88-char STANDARD base64 (padded). STANDARD
|
|
553
|
+
// is the alphabet persist's hybrid trace-tier gate decodes
|
|
554
|
+
// (STANDARD-only); URL-safe-no-pad base64-rejects there. Decodes
|
|
555
|
+
// back to the original 64 bytes round-trip.
|
|
556
|
+
use base64::Engine as _;
|
|
488
557
|
let sig = [0xFBu8; 64];
|
|
489
558
|
let enc = encode_signature(&sig);
|
|
490
|
-
assert_eq!(
|
|
491
|
-
|
|
492
|
-
|
|
559
|
+
assert_eq!(
|
|
560
|
+
enc.len(),
|
|
561
|
+
88,
|
|
562
|
+
"STANDARD base64 of 64 bytes is 88 chars (padded)"
|
|
563
|
+
);
|
|
564
|
+
assert!(enc.ends_with("=="), "64 bytes → two '=' pad chars");
|
|
565
|
+
let back = base64::engine::general_purpose::STANDARD
|
|
566
|
+
.decode(&enc)
|
|
567
|
+
.expect("STANDARD decodes our stamp");
|
|
568
|
+
assert_eq!(back, sig);
|
|
493
569
|
}
|
|
494
570
|
|
|
495
571
|
#[test]
|
|
@@ -674,6 +750,9 @@ mod tests {
|
|
|
674
750
|
components,
|
|
675
751
|
signature: None,
|
|
676
752
|
signature_key_id: None,
|
|
753
|
+
signature_ml_dsa_65: None,
|
|
754
|
+
pubkey_ml_dsa_65: None,
|
|
755
|
+
pqc_key_id: None,
|
|
677
756
|
trace_level: spec.trace_level,
|
|
678
757
|
trace_schema_version: spec.trace_schema_version,
|
|
679
758
|
deployment_profile: spec.deployment_profile,
|
|
@@ -739,6 +818,9 @@ mod tests {
|
|
|
739
818
|
}],
|
|
740
819
|
signature: None,
|
|
741
820
|
signature_key_id: None,
|
|
821
|
+
signature_ml_dsa_65: None,
|
|
822
|
+
pubkey_ml_dsa_65: None,
|
|
823
|
+
pqc_key_id: None,
|
|
742
824
|
trace_level: Some("GENERIC".into()),
|
|
743
825
|
trace_schema_version: "2.7.9".into(),
|
|
744
826
|
deployment_profile: None,
|
|
@@ -829,6 +829,9 @@ mod tests {
|
|
|
829
829
|
],
|
|
830
830
|
signature: None,
|
|
831
831
|
signature_key_id: None,
|
|
832
|
+
signature_ml_dsa_65: None,
|
|
833
|
+
pubkey_ml_dsa_65: None,
|
|
834
|
+
pqc_key_id: None,
|
|
832
835
|
trace_level: Some("full_traces".into()),
|
|
833
836
|
trace_schema_version: TRACE_SCHEMA_VERSION.into(),
|
|
834
837
|
deployment_profile: Some(serde_json::json!({
|
|
@@ -934,6 +937,9 @@ mod tests {
|
|
|
934
937
|
}],
|
|
935
938
|
signature: None,
|
|
936
939
|
signature_key_id: None,
|
|
940
|
+
signature_ml_dsa_65: None,
|
|
941
|
+
pubkey_ml_dsa_65: None,
|
|
942
|
+
pqc_key_id: None,
|
|
937
943
|
trace_level: Some("generic".into()),
|
|
938
944
|
trace_schema_version: TRACE_SCHEMA_VERSION.into(),
|
|
939
945
|
deployment_profile: Some(serde_json::json!({
|
|
@@ -603,9 +603,14 @@ impl PyLensClient {
|
|
|
603
603
|
/// (**cohabitation path**, CIRISLensCore#43.1 P0 fix). When provided,
|
|
604
604
|
/// sign+persist are driven via its Python methods — cross-wheel-safe.
|
|
605
605
|
/// Pass `None` (default) for the single-wheel / sovereign path.
|
|
606
|
-
/// - `trace_schema_version` — wire schema version string (default `"
|
|
606
|
+
/// - `trace_schema_version` — wire schema version string (default `"3.0.0"`).
|
|
607
|
+
/// `"3.0.0"`+ (major ≥ 3) signs over **RFC 8785 JCS** (`V2Jcs`) — the
|
|
608
|
+
/// post-#871 CEG-native canonical form the whole fabric is on; legacy
|
|
609
|
+
/// `"2.x"` is Python-compat (`V1Python`). persist's ingest dispatches the
|
|
610
|
+
/// verifier by this version (`canon_version_for_trace_schema`), so the
|
|
611
|
+
/// batch is a JCS CEG object end-to-end.
|
|
607
612
|
/// - `deployment_profile` — operator 6-field cohort dict; required on the
|
|
608
|
-
/// wire at schema
|
|
613
|
+
/// wire at schema 3.0.0. Pass `None` only for non-production / dev.
|
|
609
614
|
/// - `consent_attesting_key_id` — key ID for CEG-based consent resolution.
|
|
610
615
|
/// `None` → config-only path (2.9.6 interim). Has no effect when
|
|
611
616
|
/// `engine=` is provided (follow-up: CIRISEdge#85).
|
|
@@ -628,7 +633,7 @@ impl PyLensClient {
|
|
|
628
633
|
consent_timestamp,
|
|
629
634
|
trace_level,
|
|
630
635
|
engine = None,
|
|
631
|
-
trace_schema_version = "
|
|
636
|
+
trace_schema_version = "3.0.0".to_string(),
|
|
632
637
|
deployment_profile = None,
|
|
633
638
|
consent_attesting_key_id = None,
|
|
634
639
|
local_copy_dir = None,
|