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.
Files changed (381) hide show
  1. {ciris_server-0.4.7 → ciris_server-0.4.8}/Cargo.lock +1 -1
  2. {ciris_server-0.4.7 → ciris_server-0.4.8}/Cargo.toml +1 -1
  3. {ciris_server-0.4.7 → ciris_server-0.4.8}/FSD/LENS_TO_SERVER_MIGRATION.md +23 -0
  4. {ciris_server-0.4.7 → ciris_server-0.4.8}/PKG-INFO +1 -1
  5. {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/src/capture/batch.rs +92 -0
  6. {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/src/capture/client.rs +68 -13
  7. {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/src/capture/correlation.rs +3 -0
  8. {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/src/capture/partial.rs +17 -0
  9. {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/src/capture/seal.rs +121 -39
  10. {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/src/config/egress.rs +6 -0
  11. {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/src/ffi/pyo3.rs +8 -3
  12. {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/tests/sovereign_rlib.rs +13 -2
  13. {ciris_server-0.4.7 → ciris_server-0.4.8}/.cargo/config.toml +0 -0
  14. {ciris_server-0.4.7 → ciris_server-0.4.8}/.github/workflows/bench.yml +0 -0
  15. {ciris_server-0.4.7 → ciris_server-0.4.8}/.github/workflows/ci.yml +0 -0
  16. {ciris_server-0.4.7 → ciris_server-0.4.8}/.github/workflows/conformance.yml +0 -0
  17. {ciris_server-0.4.7 → ciris_server-0.4.8}/.github/workflows/publish-pypi.yml +0 -0
  18. {ciris_server-0.4.7 → ciris_server-0.4.8}/.github/workflows/release.yml +0 -0
  19. {ciris_server-0.4.7 → ciris_server-0.4.8}/.gitignore +0 -0
  20. {ciris_server-0.4.7 → ciris_server-0.4.8}/CHANGELOG.md +0 -0
  21. {ciris_server-0.4.7 → ciris_server-0.4.8}/FSD/MESH_ANIMATION_BRIEF.md +0 -0
  22. {ciris_server-0.4.7 → ciris_server-0.4.8}/FSD/MODERATION_CHILD_SAFETY.md +0 -0
  23. {ciris_server-0.4.7 → ciris_server-0.4.8}/FSD/ONE_WHEEL_REEXPORT.md +0 -0
  24. {ciris_server-0.4.7 → ciris_server-0.4.8}/FSD/PQC_AV_STREAMING_BENCH.md +0 -0
  25. {ciris_server-0.4.7 → ciris_server-0.4.8}/FSD/QA_AGAINST_RUST.md +0 -0
  26. {ciris_server-0.4.7 → ciris_server-0.4.8}/FSD/REGISTRY_FOLD_DERISK.md +0 -0
  27. {ciris_server-0.4.7 → ciris_server-0.4.8}/FSD/SAFETY_LANDSCAPE.md +0 -0
  28. {ciris_server-0.4.7 → ciris_server-0.4.8}/FSD/SERVER_1.0_PLAN.md +0 -0
  29. {ciris_server-0.4.7 → ciris_server-0.4.8}/FSD/WATCHLIST_DETECTION.md +0 -0
  30. {ciris_server-0.4.7 → ciris_server-0.4.8}/LICENSE +0 -0
  31. {ciris_server-0.4.7 → ciris_server-0.4.8}/MISSION.md +0 -0
  32. {ciris_server-0.4.7 → ciris_server-0.4.8}/README.md +0 -0
  33. {ciris_server-0.4.7 → ciris_server-0.4.8}/app/.gitignore +0 -0
  34. {ciris_server-0.4.7 → ciris_server-0.4.8}/app/README.md +0 -0
  35. {ciris_server-0.4.7 → ciris_server-0.4.8}/app/build.gradle.kts +0 -0
  36. {ciris_server-0.4.7 → ciris_server-0.4.8}/app/fabric-client/build.gradle.kts +0 -0
  37. {ciris_server-0.4.7 → ciris_server-0.4.8}/app/fabric-client/src/commonMain/kotlin/ai/ciris/fabric/auth/FederationSigner.kt +0 -0
  38. {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
  39. {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
  40. {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
  41. {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
  42. {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
  43. {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
  44. {ciris_server-0.4.7 → ciris_server-0.4.8}/app/fabric-client/src/commonMain/kotlin/ai/ciris/fabric/net/FabricClient.kt +0 -0
  45. {ciris_server-0.4.7 → ciris_server-0.4.8}/app/fabric-client/src/commonMain/kotlin/ai/ciris/fabric/net/FabricEndpoints.kt +0 -0
  46. {ciris_server-0.4.7 → ciris_server-0.4.8}/app/fabric-client/src/commonMain/kotlin/ai/ciris/fabric/platform/PlatformLogger.kt +0 -0
  47. {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
  48. {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
  49. {ciris_server-0.4.7 → ciris_server-0.4.8}/app/fabric-client/src/commonMain/kotlin/ai/ciris/fabric/viewmodel/ErasureViewModel.kt +0 -0
  50. {ciris_server-0.4.7 → ciris_server-0.4.8}/app/fabric-client/src/commonMain/kotlin/ai/ciris/fabric/viewmodel/IdentityViewModel.kt +0 -0
  51. {ciris_server-0.4.7 → ciris_server-0.4.8}/app/fabric-client/src/commonTest/kotlin/ai/ciris/fabric/IdentitySliceTest.kt +0 -0
  52. {ciris_server-0.4.7 → ciris_server-0.4.8}/app/gradle/wrapper/gradle-wrapper.jar +0 -0
  53. {ciris_server-0.4.7 → ciris_server-0.4.8}/app/gradle/wrapper/gradle-wrapper.properties +0 -0
  54. {ciris_server-0.4.7 → ciris_server-0.4.8}/app/gradle.properties +0 -0
  55. {ciris_server-0.4.7 → ciris_server-0.4.8}/app/gradlew +0 -0
  56. {ciris_server-0.4.7 → ciris_server-0.4.8}/app/gradlew.bat +0 -0
  57. {ciris_server-0.4.7 → ciris_server-0.4.8}/app/settings.gradle.kts +0 -0
  58. {ciris_server-0.4.7 → ciris_server-0.4.8}/bench-site/data.json +0 -0
  59. {ciris_server-0.4.7 → ciris_server-0.4.8}/bench-site/index.html +0 -0
  60. {ciris_server-0.4.7 → ciris_server-0.4.8}/benches/alm_chain.rs +0 -0
  61. {ciris_server-0.4.7 → ciris_server-0.4.8}/benches/pqc_av_streaming.rs +0 -0
  62. {ciris_server-0.4.7 → ciris_server-0.4.8}/benches/replication_ingest.rs +0 -0
  63. {ciris_server-0.4.7 → ciris_server-0.4.8}/benches/stream_fanout.rs +0 -0
  64. {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/.github/workflows/bench.yml +0 -0
  65. {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/.github/workflows/ci.yml +0 -0
  66. {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/.gitignore +0 -0
  67. {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/.pre-commit-config.yaml +0 -0
  68. {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/Cargo.toml +0 -0
  69. {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/FSD/CIRIS_LENS_CORE.md +0 -0
  70. {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/FSD/LENS_CORE_V0_5.md +0 -0
  71. {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/FSD/OPEN_QUESTIONS.md +0 -0
  72. {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/LICENSE +0 -0
  73. {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/MISSION.md +0 -0
  74. {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/README.md +0 -0
  75. {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/benches/aggregate.rs +0 -0
  76. {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/benches/canonicalize.rs +0 -0
  77. {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/benches/project.rs +0 -0
  78. {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/deny.toml +0 -0
  79. {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/docs/BENCHMARKS.md +0 -0
  80. {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/docs/COHABITATION.md +0 -0
  81. {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/docs/PRE_COMMIT.md +0 -0
  82. {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/docs/PUBLIC_SCHEMA_CONTRACT.md +0 -0
  83. {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/docs/PYPI_PUBLISH.md +0 -0
  84. {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/docs/RELEASE_NOTES.md +0 -0
  85. {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/docs/STANDARDS_COMPARISON.md +0 -0
  86. {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/docs/THREAT_MODEL.md +0 -0
  87. {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/patterns_from_cirislens_core/extraction/json_path.rs +0 -0
  88. {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/patterns_from_cirislens_core/extraction/metadata.rs +0 -0
  89. {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/patterns_from_cirislens_core/extraction/mod.rs +0 -0
  90. {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/patterns_from_cirislens_core/scrubber/distilbert_loader.rs +0 -0
  91. {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/patterns_from_cirislens_core/scrubber/fields.rs +0 -0
  92. {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/patterns_from_cirislens_core/scrubber/mod.rs +0 -0
  93. {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/patterns_from_cirislens_core/scrubber/ner.rs +0 -0
  94. {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/patterns_from_cirislens_core/scrubber/ort_loader.rs +0 -0
  95. {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/patterns_from_cirislens_core/scrubber/proptests.rs +0 -0
  96. {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/patterns_from_cirislens_core/scrubber/regex.rs +0 -0
  97. {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/patterns_from_cirislens_core/scrubber/walker.rs +0 -0
  98. {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
  99. {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/pyproject.toml +0 -0
  100. {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/python/ciris_lens_core/__init__.py +0 -0
  101. {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/src/audit/api.rs +0 -0
  102. {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/src/audit/delegate.rs +0 -0
  103. {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/src/audit/mod.rs +0 -0
  104. {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/src/audit/pyo3.rs +0 -0
  105. {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/src/canonical/ceg_egress.rs +0 -0
  106. {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/src/canonical/mod.rs +0 -0
  107. {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/src/capacity/attestation.rs +0 -0
  108. {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/src/capacity/mod.rs +0 -0
  109. {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/src/capacity/score.rs +0 -0
  110. {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/src/capture/consent.rs +0 -0
  111. {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/src/capture/event.rs +0 -0
  112. {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/src/capture/mod.rs +0 -0
  113. {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/src/capture/py_engine.rs +0 -0
  114. {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/src/cohort/declared.rs +0 -0
  115. {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/src/cohort/mod.rs +0 -0
  116. {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/src/cohort/resourcing.rs +0 -0
  117. {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/src/config/mod.rs +0 -0
  118. {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/src/config/node.rs +0 -0
  119. {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/src/config/retention.rs +0 -0
  120. {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/src/config/upstream.rs +0 -0
  121. {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/src/detector/axis_metrics.rs +0 -0
  122. {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/src/detector/coherence_ratchet.rs +0 -0
  123. {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/src/detector/correlated_action.rs +0 -0
  124. {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/src/detector/distributive_access.rs +0 -0
  125. {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/src/detector/manifold.rs +0 -0
  126. {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/src/detector/mod.rs +0 -0
  127. {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/src/extract/mod.rs +0 -0
  128. {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/src/extract/projection.rs +0 -0
  129. {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/src/ffi/mod.rs +0 -0
  130. {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/src/lib.rs +0 -0
  131. {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/src/observability/mod.rs +0 -0
  132. {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/src/pipeline/lifecycle.rs +0 -0
  133. {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/src/pipeline/mod.rs +0 -0
  134. {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/src/retention/eviction.rs +0 -0
  135. {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/src/retention/mod.rs +0 -0
  136. {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/src/retention/summary.rs +0 -0
  137. {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/src/role/handler.rs +0 -0
  138. {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/src/role/mod.rs +0 -0
  139. {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/src/role/node.rs +0 -0
  140. {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/src/role/relay.rs +0 -0
  141. {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/src/role/ret_relay.rs +0 -0
  142. {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/src/scores/aggregate.rs +0 -0
  143. {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/src/scores/mod.rs +0 -0
  144. {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/src/scores/oracle.rs +0 -0
  145. {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/src/scoring/assembly.rs +0 -0
  146. {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/src/scoring/axis_calibration.rs +0 -0
  147. {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/src/scoring/calibration.rs +0 -0
  148. {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/src/scoring/capacity.rs +0 -0
  149. {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/src/scoring/mod.rs +0 -0
  150. {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/src/scoring/n_eff.rs +0 -0
  151. {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/src/scoring/result.rs +0 -0
  152. {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/src/signing/event.rs +0 -0
  153. {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/src/signing/mod.rs +0 -0
  154. {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/src/wire/mod.rs +0 -0
  155. {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/src/wire/signer.rs +0 -0
  156. {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/tests/parity/README.md +0 -0
  157. {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/tests/parity/canonical_fixtures.json +0 -0
  158. {ciris_server-0.4.7 → ciris_server-0.4.8}/crates/ciris-lens-core/tests/parity/generate_canonical_fixtures.py +0 -0
  159. {ciris_server-0.4.7 → ciris_server-0.4.8}/pyproject.toml +0 -0
  160. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/README.md +0 -0
  161. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/ciris_sdk/README.md +0 -0
  162. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/ciris_sdk/REFACTORING_SUMMARY.md +0 -0
  163. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/ciris_sdk/__init__.py +0 -0
  164. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/ciris_sdk/auth_store.py +0 -0
  165. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/ciris_sdk/client.py +0 -0
  166. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/ciris_sdk/examples/__init__.py +0 -0
  167. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/ciris_sdk/examples/agent_interaction.py +0 -0
  168. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/ciris_sdk/examples/unified_telemetry_examples.py +0 -0
  169. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/ciris_sdk/examples/wa_example.py +0 -0
  170. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/ciris_sdk/exceptions.py +0 -0
  171. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/ciris_sdk/model_types.py +0 -0
  172. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/ciris_sdk/models.py +0 -0
  173. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/ciris_sdk/pagination.py +0 -0
  174. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/ciris_sdk/rate_limiter.py +0 -0
  175. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/ciris_sdk/resources/CONFIG_CLIENT.md +0 -0
  176. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/ciris_sdk/resources/WA_CLIENT_GUIDE.md +0 -0
  177. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/ciris_sdk/resources/__init__.py +0 -0
  178. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/ciris_sdk/resources/agent.py +0 -0
  179. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/ciris_sdk/resources/audit.py +0 -0
  180. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/ciris_sdk/resources/auth.py +0 -0
  181. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/ciris_sdk/resources/billing.py +0 -0
  182. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/ciris_sdk/resources/config.py +0 -0
  183. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/ciris_sdk/resources/consent.py +0 -0
  184. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/ciris_sdk/resources/emergency.py +0 -0
  185. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/ciris_sdk/resources/jobs.py +0 -0
  186. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/ciris_sdk/resources/memory.py +0 -0
  187. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/ciris_sdk/resources/setup.py +0 -0
  188. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/ciris_sdk/resources/system.py +0 -0
  189. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/ciris_sdk/resources/telemetry.py +0 -0
  190. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/ciris_sdk/resources/wa.py +0 -0
  191. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/ciris_sdk/resources/websocket.py +0 -0
  192. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/ciris_sdk/setup.py +0 -0
  193. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/ciris_sdk/telemetry_models.py +0 -0
  194. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/ciris_sdk/telemetry_responses.py +0 -0
  195. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/ciris_sdk/transport.py +0 -0
  196. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/ciris_sdk/websocket.py +0 -0
  197. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/fabric_results.json +0 -0
  198. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/BILLING_QA_README.md +0 -0
  199. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/CLAUDE.md +0 -0
  200. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/README.md +0 -0
  201. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/SDK_MODULE_INTEGRATION.md +0 -0
  202. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/__init__.py +0 -0
  203. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/__main__.py +0 -0
  204. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/config.py +0 -0
  205. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/mcp_test_server.py +0 -0
  206. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/CLAUDE.md +0 -0
  207. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/MULTI_OCCURRENCE_README.md +0 -0
  208. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/__init__.py +0 -0
  209. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/_module_metadata.py +0 -0
  210. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/accord_metrics_tests.py +0 -0
  211. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/accord_tests.py +0 -0
  212. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/adapter_autoload_tests.py +0 -0
  213. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/adapter_availability_tests.py +0 -0
  214. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/adapter_config_tests.py +0 -0
  215. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/adapter_manifest_tests.py +0 -0
  216. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/agent_mode_tests.py +0 -0
  217. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/air_tests.py +0 -0
  218. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/api_tests.py +0 -0
  219. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/base_test_module.py +0 -0
  220. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/billing_integration_tests.py +0 -0
  221. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/billing_tests.py +0 -0
  222. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/cirisnode_tests.py +0 -0
  223. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/cognitive_state_api_tests.py +0 -0
  224. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/comprehensive_api_tests.py +0 -0
  225. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/comprehensive_single_step_tests.py +0 -0
  226. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/consent_tests.py +0 -0
  227. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/context_enrichment_tests.py +0 -0
  228. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/deferral_taxonomy_tests.py +0 -0
  229. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/deferral_tests.py +0 -0
  230. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/degraded_mode_tests.py +0 -0
  231. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/desktop_viz.py +0 -0
  232. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/dream_live_tests.py +0 -0
  233. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/dsar_multi_source_tests.py +0 -0
  234. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/dsar_tests.py +0 -0
  235. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/dsar_ticket_workflow_tests.py +0 -0
  236. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/filter_test_helper.py +0 -0
  237. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/filter_tests.py +0 -0
  238. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/handler_tests.py +0 -0
  239. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/he300_benchmark_tests.py +0 -0
  240. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/homeassistant_agentic_tests.py +0 -0
  241. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/hosted_tools_tests.py +0 -0
  242. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/identity_update_tests.py +0 -0
  243. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/l4_attestation_tests.py +0 -0
  244. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/licensed_agent_tests.py +0 -0
  245. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/mcp_tests.py +0 -0
  246. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/memory_benchmark_tests.py +0 -0
  247. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/message_id_debug_test.py +0 -0
  248. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/mobile/__init__.py +0 -0
  249. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/mobile/__main__.py +0 -0
  250. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/mobile/adb_helper.py +0 -0
  251. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/mobile/device_helper.py +0 -0
  252. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/mobile/first_time_licensed_agent.py +0 -0
  253. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/mobile/ios/__init__.py +0 -0
  254. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/mobile/ios/build_helper.py +0 -0
  255. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/mobile/ios/idevice_helper.py +0 -0
  256. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/mobile/ios/ios_ui_automator.py +0 -0
  257. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/mobile/ios/vision_helper.py +0 -0
  258. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/mobile/ios/xcrun_helper.py +0 -0
  259. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/mobile/ios_physical_test_cases.py +0 -0
  260. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/mobile/ios_test_cases.py +0 -0
  261. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/mobile/portal_registration.py +0 -0
  262. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/mobile/test_cases.py +0 -0
  263. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/mobile/test_runner.py +0 -0
  264. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/mobile/ui_automator.py +0 -0
  265. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/mobile/verify_trust_tests.py +0 -0
  266. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/model_eval_tests.py +0 -0
  267. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/multi_occurrence_tests.py +0 -0
  268. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/parallel_locales_tests.py +0 -0
  269. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/partnership_tests.py +0 -0
  270. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/play_live_tests.py +0 -0
  271. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/reddit_tests.py +0 -0
  272. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/safety_battery.py +0 -0
  273. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/safety_interpret.py +0 -0
  274. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/sdk_tests.py +0 -0
  275. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/secrets_encryption_tests.py +0 -0
  276. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/setup_e2e_tests.py +0 -0
  277. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/setup_tests.py +0 -0
  278. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/simple_single_step_tests.py +0 -0
  279. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/solitude_live_tests.py +0 -0
  280. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/sql_external_data_tests.py +0 -0
  281. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/state_transition_tests.py +0 -0
  282. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/streaming_verification.py +0 -0
  283. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/system_messages_tests.py +0 -0
  284. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/utility_adapters_tests.py +0 -0
  285. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/vision_tests.py +0 -0
  286. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/wallet_tests.py +0 -0
  287. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/web_ui/CLAUDE.md +0 -0
  288. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/web_ui/__init__.py +0 -0
  289. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/web_ui/__main__.py +0 -0
  290. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/web_ui/browser_helper.py +0 -0
  291. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/web_ui/desktop_app_helper.py +0 -0
  292. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/web_ui/desktop_test.py +0 -0
  293. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/web_ui/federation_screen_tags.py +0 -0
  294. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/web_ui/federation_walk_report.py +0 -0
  295. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/web_ui/federation_walk_test.py +0 -0
  296. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/web_ui/licensed_agent_flow.py +0 -0
  297. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/web_ui/server_manager.py +0 -0
  298. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/web_ui/test_cases.py +0 -0
  299. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/web_ui/test_federation_walk_unit.py +0 -0
  300. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/modules/web_ui/test_runner.py +0 -0
  301. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/qa_api_test.py +0 -0
  302. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/qa_reports/qa_report_20250825_073205.json +0 -0
  303. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/qa_reports/qa_report_20250825_153259.json +0 -0
  304. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/qa_reports/qa_report_20250825_154628.json +0 -0
  305. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/qa_reports/qa_report_20250825_154817.json +0 -0
  306. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/qa_reports/qa_report_20250825_155917.json +0 -0
  307. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/qa_reports_comprehensive/qa_report_20250825_075504.json +0 -0
  308. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/qa_reports_final/qa_report_20250825_092420.json +0 -0
  309. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/qa_reports_test/qa_report_20250825_092452.json +0 -0
  310. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/qa_scripts/README.md +0 -0
  311. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/qa_scripts/qa_api_test.py +0 -0
  312. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/qa_scripts/qa_v1.0_sdk_comprehensive.py +0 -0
  313. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/qa_scripts/qa_v1.0_unhealthy_services_check.py +0 -0
  314. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/qa_test.py +0 -0
  315. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/qa_test_sdk.py +0 -0
  316. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/requirements.txt +0 -0
  317. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/runner.py +0 -0
  318. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/scripts/__init__.py +0 -0
  319. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/scripts/he300_stream_debug.py +0 -0
  320. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/server.py +0 -0
  321. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/staged_env.py +0 -0
  322. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/status_tracker.py +0 -0
  323. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/test_data/dsar_multi_source_privacy_schema.yaml +0 -0
  324. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/test_data/qa_test.db +0 -0
  325. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/test_data/qa_test_privacy_schema.yaml +0 -0
  326. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/qa_runner/test_data/sql_config.json +0 -0
  327. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/run_fabric.py +0 -0
  328. {ciris_server-0.4.7 → ciris_server-0.4.8}/qa/seed_wa_cert.py +0 -0
  329. {ciris_server-0.4.7 → ciris_server-0.4.8}/rust-toolchain.toml +0 -0
  330. {ciris_server-0.4.7 → ciris_server-0.4.8}/scripts/bench_report.py +0 -0
  331. {ciris_server-0.4.7 → ciris_server-0.4.8}/src/auth/ABSORPTION.md +0 -0
  332. {ciris_server-0.4.7 → ciris_server-0.4.8}/src/auth/api_keys.rs +0 -0
  333. {ciris_server-0.4.7 → ciris_server-0.4.8}/src/auth/attestation.rs +0 -0
  334. {ciris_server-0.4.7 → ciris_server-0.4.8}/src/auth/bootstrap.rs +0 -0
  335. {ciris_server-0.4.7 → ciris_server-0.4.8}/src/auth/consent.rs +0 -0
  336. {ciris_server-0.4.7 → ciris_server-0.4.8}/src/auth/device_auth.rs +0 -0
  337. {ciris_server-0.4.7 → ciris_server-0.4.8}/src/auth/erasure.rs +0 -0
  338. {ciris_server-0.4.7 → ciris_server-0.4.8}/src/auth/gate.rs +0 -0
  339. {ciris_server-0.4.7 → ciris_server-0.4.8}/src/auth/mod.rs +0 -0
  340. {ciris_server-0.4.7 → ciris_server-0.4.8}/src/auth/oauth.rs +0 -0
  341. {ciris_server-0.4.7 → ciris_server-0.4.8}/src/auth/ownership.rs +0 -0
  342. {ciris_server-0.4.7 → ciris_server-0.4.8}/src/auth/roles.rs +0 -0
  343. {ciris_server-0.4.7 → ciris_server-0.4.8}/src/auth/self_login.rs +0 -0
  344. {ciris_server-0.4.7 → ciris_server-0.4.8}/src/auth/session.rs +0 -0
  345. {ciris_server-0.4.7 → ciris_server-0.4.8}/src/auth/store.rs +0 -0
  346. {ciris_server-0.4.7 → ciris_server-0.4.8}/src/auth/verify.rs +0 -0
  347. {ciris_server-0.4.7 → ciris_server-0.4.8}/src/benchmarks/mod.rs +0 -0
  348. {ciris_server-0.4.7 → ciris_server-0.4.8}/src/benchmarks/scoreboard.rs +0 -0
  349. {ciris_server-0.4.7 → ciris_server-0.4.8}/src/claim_remote.rs +0 -0
  350. {ciris_server-0.4.7 → ciris_server-0.4.8}/src/compose.rs +0 -0
  351. {ciris_server-0.4.7 → ciris_server-0.4.8}/src/config.rs +0 -0
  352. {ciris_server-0.4.7 → ciris_server-0.4.8}/src/federation_admin.rs +0 -0
  353. {ciris_server-0.4.7 → ciris_server-0.4.8}/src/federation_nodecode.rs +0 -0
  354. {ciris_server-0.4.7 → ciris_server-0.4.8}/src/identity.rs +0 -0
  355. {ciris_server-0.4.7 → ciris_server-0.4.8}/src/import.rs +0 -0
  356. {ciris_server-0.4.7 → ciris_server-0.4.8}/src/ingest_http.rs +0 -0
  357. {ciris_server-0.4.7 → ciris_server-0.4.8}/src/lib.rs +0 -0
  358. {ciris_server-0.4.7 → ciris_server-0.4.8}/src/main.rs +0 -0
  359. {ciris_server-0.4.7 → ciris_server-0.4.8}/src/nodecode.rs +0 -0
  360. {ciris_server-0.4.7 → ciris_server-0.4.8}/src/peer.rs +0 -0
  361. {ciris_server-0.4.7 → ciris_server-0.4.8}/src/quorum.rs +0 -0
  362. {ciris_server-0.4.7 → ciris_server-0.4.8}/src/safety/age.rs +0 -0
  363. {ciris_server-0.4.7 → ciris_server-0.4.8}/src/safety/mod.rs +0 -0
  364. {ciris_server-0.4.7 → ciris_server-0.4.8}/src/safety/moderation.rs +0 -0
  365. {ciris_server-0.4.7 → ciris_server-0.4.8}/src/safety/named.rs +0 -0
  366. {ciris_server-0.4.7 → ciris_server-0.4.8}/src/safety/watchlist.rs +0 -0
  367. {ciris_server-0.4.7 → ciris_server-0.4.8}/src/scorer/n_eff.rs +0 -0
  368. {ciris_server-0.4.7 → ciris_server-0.4.8}/src/scorer.rs +0 -0
  369. {ciris_server-0.4.7 → ciris_server-0.4.8}/tests/alm_chain.rs +0 -0
  370. {ciris_server-0.4.7 → ciris_server-0.4.8}/tests/capacity_scorer.rs +0 -0
  371. {ciris_server-0.4.7 → ciris_server-0.4.8}/tests/chaos_mesh.rs +0 -0
  372. {ciris_server-0.4.7 → ciris_server-0.4.8}/tests/claim_remote.rs +0 -0
  373. {ciris_server-0.4.7 → ciris_server-0.4.8}/tests/federation_admin.rs +0 -0
  374. {ciris_server-0.4.7 → ciris_server-0.4.8}/tests/ingest_http.rs +0 -0
  375. {ciris_server-0.4.7 → ciris_server-0.4.8}/tests/nodecode.rs +0 -0
  376. {ciris_server-0.4.7 → ciris_server-0.4.8}/tests/noise_floor.rs +0 -0
  377. {ciris_server-0.4.7 → ciris_server-0.4.8}/tests/ownership.rs +0 -0
  378. {ciris_server-0.4.7 → ciris_server-0.4.8}/tests/peer_replication.rs +0 -0
  379. {ciris_server-0.4.7 → ciris_server-0.4.8}/tests/replication.rs +0 -0
  380. {ciris_server-0.4.7 → ciris_server-0.4.8}/tests/root_bootstrap.rs +0 -0
  381. {ciris_server-0.4.7 → ciris_server-0.4.8}/tests/safety.rs +0 -0
@@ -995,7 +995,7 @@ dependencies = [
995
995
 
996
996
  [[package]]
997
997
  name = "ciris-server"
998
- version = "0.4.7"
998
+ version = "0.4.8"
999
999
  dependencies = [
1000
1000
  "anyhow",
1001
1001
  "async-trait",
@@ -1,6 +1,6 @@
1
1
  [package]
2
2
  name = "ciris-server"
3
- version = "0.4.7" # 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.
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.7
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 `HardwareSigner`, and wrap the
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). The test
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. Sign via [`sign_trace_via_hardware_signer`].
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
- signer: &dyn HardwareSigner,
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. Sign.
300
- sign_trace_via_hardware_signer(signer, trace).await?;
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.signer().as_ref(),
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
- //! **Ed25519**-signs the canonical bytes (via the host `Engine`'s
8
- //! signing identity), and persists it. (Trace signing is Ed25519-only —
9
- //! the hybrid Ed25519+ML-DSA-65 pair is the detection-event /
10
- //! attestation surface, not traces.) The **canonical bytes must be
11
- //! byte-identical** to what every federation verifier recomputes, or
12
- //! the signature fails to verify. This module owns the canonical-
13
- //! envelope *structure*; the byte serialization is delegated to
14
- //! persist's **version-aware dispatch** — `canon_version_for_trace_schema`
15
- //! + `canonicalizer_for` (CIRISPersist#171 / v4.6.0 / v4.15.0 #871).
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) + [`apply_signature`] /
62
- //! [`verify_trace_signature`] (Ed25519 stamp + the federation-verifier
63
- //! algorithm). No Engine, no I/O — fully unit-tested incl. a sign→verify
64
- //! round-trip. The thin async glue (`engine.local_sign(canonical_bytes)`
65
- //! → `apply_signature` → `receive_and_persist`) lands with the Engine
66
- //! integration (Cut 4).
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-only** over the canonical bytes (NOT a
204
- // hybrid Ed25519+ML-DSA pair — that is the detection-event / attestation
205
- // surface). The signature is stored URL-safe-base64-no-pad, the
206
- // `signature_key_id` names the signing key. This mirrors CIRISAgent's
207
- // `Ed25519TraceSigner.sign_trace` (`unified_key.sign_base64(message)`) +
208
- // `verify_trace` (`Ed25519.verify(sig, message)`) exactly, so a trace
209
- // lens-core seals verifies under the agent's verify path and vice-versa.
210
-
211
- /// Encode an Ed25519 signature for the `CompleteTrace.signature` field:
212
- /// URL-safe base64, no padding — the form CIRISAgent's `verify_trace`
213
- /// decodes (it re-appends `==` before `urlsafe_b64decode`).
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::URL_SAFE_NO_PAD.encode(sig_bytes)
240
+ base64::engine::general_purpose::STANDARD.encode(sig_bytes)
217
241
  }
218
242
 
219
- /// Stamp a computed signature onto a sealed trace. Pure — the caller
220
- /// (the Engine-coupled `sign_trace`, Cut 3b glue) obtains `sig_bytes`
221
- /// from `engine.local_sign(canonical_bytes(trace))` and the host's
222
- /// signing `key_id`.
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
- let Ok(sig_raw) = base64::engine::general_purpose::URL_SAFE_NO_PAD.decode(sig_b64) else {
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 encode_signature_is_urlsafe_no_pad() {
486
- // 64-byte Ed25519 sig → 86-char URL-safe base64, no '=' padding,
487
- // no '+'/'/' (the form the agent's verify_trace decodes).
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!(enc.len(), 86);
491
- assert!(!enc.contains('='));
492
- assert!(!enc.contains('+') && !enc.contains('/'));
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 `"2.7.9"`).
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 2.7.9. Pass `None` only for non-production / dev.
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 = "2.7.9".to_string(),
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,