ciris-server 0.1.2__tar.gz → 0.2.0__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.2.0/.cargo/config.toml +14 -0
- ciris_server-0.2.0/.github/workflows/bench.yml +67 -0
- {ciris_server-0.1.2 → ciris_server-0.2.0}/.github/workflows/ci.yml +22 -2
- {ciris_server-0.1.2 → ciris_server-0.2.0}/.github/workflows/publish-pypi.yml +59 -1
- {ciris_server-0.1.2 → ciris_server-0.2.0}/CHANGELOG.md +31 -0
- {ciris_server-0.1.2 → ciris_server-0.2.0}/Cargo.lock +4 -1
- {ciris_server-0.1.2 → ciris_server-0.2.0}/Cargo.toml +33 -10
- {ciris_server-0.1.2 → ciris_server-0.2.0}/FSD/LENS_TO_SERVER_MIGRATION.md +8 -1
- {ciris_server-0.1.2 → ciris_server-0.2.0}/PKG-INFO +1 -1
- ciris_server-0.2.0/benches/replication_ingest.rs +181 -0
- {ciris_server-0.1.2 → ciris_server-0.2.0}/pyproject.toml +1 -1
- ciris_server-0.2.0/scripts/bench_report.py +234 -0
- {ciris_server-0.1.2 → ciris_server-0.2.0}/src/compose.rs +73 -19
- {ciris_server-0.1.2 → ciris_server-0.2.0}/.github/workflows/conformance.yml +0 -0
- {ciris_server-0.1.2 → ciris_server-0.2.0}/.github/workflows/release.yml +0 -0
- {ciris_server-0.1.2 → ciris_server-0.2.0}/.gitignore +0 -0
- {ciris_server-0.1.2 → ciris_server-0.2.0}/FSD/PQC_AV_STREAMING_BENCH.md +0 -0
- {ciris_server-0.1.2 → ciris_server-0.2.0}/FSD/REGISTRY_FOLD_DERISK.md +0 -0
- {ciris_server-0.1.2 → ciris_server-0.2.0}/FSD/SERVER_1.0_PLAN.md +0 -0
- {ciris_server-0.1.2 → ciris_server-0.2.0}/LICENSE +0 -0
- {ciris_server-0.1.2 → ciris_server-0.2.0}/MISSION.md +0 -0
- {ciris_server-0.1.2 → ciris_server-0.2.0}/README.md +0 -0
- {ciris_server-0.1.2 → ciris_server-0.2.0}/benches/pqc_av_streaming.rs +0 -0
- {ciris_server-0.1.2 → ciris_server-0.2.0}/crates/ciris-lens-core/.github/workflows/bench.yml +0 -0
- {ciris_server-0.1.2 → ciris_server-0.2.0}/crates/ciris-lens-core/.github/workflows/ci.yml +0 -0
- {ciris_server-0.1.2 → ciris_server-0.2.0}/crates/ciris-lens-core/.gitignore +0 -0
- {ciris_server-0.1.2 → ciris_server-0.2.0}/crates/ciris-lens-core/.pre-commit-config.yaml +0 -0
- {ciris_server-0.1.2 → ciris_server-0.2.0}/crates/ciris-lens-core/Cargo.toml +0 -0
- {ciris_server-0.1.2 → ciris_server-0.2.0}/crates/ciris-lens-core/FSD/CIRIS_LENS_CORE.md +0 -0
- {ciris_server-0.1.2 → ciris_server-0.2.0}/crates/ciris-lens-core/FSD/LENS_CORE_V0_5.md +0 -0
- {ciris_server-0.1.2 → ciris_server-0.2.0}/crates/ciris-lens-core/FSD/OPEN_QUESTIONS.md +0 -0
- {ciris_server-0.1.2 → ciris_server-0.2.0}/crates/ciris-lens-core/LICENSE +0 -0
- {ciris_server-0.1.2 → ciris_server-0.2.0}/crates/ciris-lens-core/MISSION.md +0 -0
- {ciris_server-0.1.2 → ciris_server-0.2.0}/crates/ciris-lens-core/README.md +0 -0
- {ciris_server-0.1.2 → ciris_server-0.2.0}/crates/ciris-lens-core/benches/aggregate.rs +0 -0
- {ciris_server-0.1.2 → ciris_server-0.2.0}/crates/ciris-lens-core/benches/canonicalize.rs +0 -0
- {ciris_server-0.1.2 → ciris_server-0.2.0}/crates/ciris-lens-core/benches/project.rs +0 -0
- {ciris_server-0.1.2 → ciris_server-0.2.0}/crates/ciris-lens-core/deny.toml +0 -0
- {ciris_server-0.1.2 → ciris_server-0.2.0}/crates/ciris-lens-core/docs/BENCHMARKS.md +0 -0
- {ciris_server-0.1.2 → ciris_server-0.2.0}/crates/ciris-lens-core/docs/COHABITATION.md +0 -0
- {ciris_server-0.1.2 → ciris_server-0.2.0}/crates/ciris-lens-core/docs/PRE_COMMIT.md +0 -0
- {ciris_server-0.1.2 → ciris_server-0.2.0}/crates/ciris-lens-core/docs/PUBLIC_SCHEMA_CONTRACT.md +0 -0
- {ciris_server-0.1.2 → ciris_server-0.2.0}/crates/ciris-lens-core/docs/PYPI_PUBLISH.md +0 -0
- {ciris_server-0.1.2 → ciris_server-0.2.0}/crates/ciris-lens-core/docs/RELEASE_NOTES.md +0 -0
- {ciris_server-0.1.2 → ciris_server-0.2.0}/crates/ciris-lens-core/docs/STANDARDS_COMPARISON.md +0 -0
- {ciris_server-0.1.2 → ciris_server-0.2.0}/crates/ciris-lens-core/docs/THREAT_MODEL.md +0 -0
- {ciris_server-0.1.2 → ciris_server-0.2.0}/crates/ciris-lens-core/patterns_from_cirislens_core/extraction/json_path.rs +0 -0
- {ciris_server-0.1.2 → ciris_server-0.2.0}/crates/ciris-lens-core/patterns_from_cirislens_core/extraction/metadata.rs +0 -0
- {ciris_server-0.1.2 → ciris_server-0.2.0}/crates/ciris-lens-core/patterns_from_cirislens_core/extraction/mod.rs +0 -0
- {ciris_server-0.1.2 → ciris_server-0.2.0}/crates/ciris-lens-core/patterns_from_cirislens_core/scrubber/distilbert_loader.rs +0 -0
- {ciris_server-0.1.2 → ciris_server-0.2.0}/crates/ciris-lens-core/patterns_from_cirislens_core/scrubber/fields.rs +0 -0
- {ciris_server-0.1.2 → ciris_server-0.2.0}/crates/ciris-lens-core/patterns_from_cirislens_core/scrubber/mod.rs +0 -0
- {ciris_server-0.1.2 → ciris_server-0.2.0}/crates/ciris-lens-core/patterns_from_cirislens_core/scrubber/ner.rs +0 -0
- {ciris_server-0.1.2 → ciris_server-0.2.0}/crates/ciris-lens-core/patterns_from_cirislens_core/scrubber/ort_loader.rs +0 -0
- {ciris_server-0.1.2 → ciris_server-0.2.0}/crates/ciris-lens-core/patterns_from_cirislens_core/scrubber/proptests.rs +0 -0
- {ciris_server-0.1.2 → ciris_server-0.2.0}/crates/ciris-lens-core/patterns_from_cirislens_core/scrubber/regex.rs +0 -0
- {ciris_server-0.1.2 → ciris_server-0.2.0}/crates/ciris-lens-core/patterns_from_cirislens_core/scrubber/walker.rs +0 -0
- {ciris_server-0.1.2 → ciris_server-0.2.0}/crates/ciris-lens-core/patterns_from_cirislens_core/scrubber/xlm_r_loader.rs +0 -0
- {ciris_server-0.1.2 → ciris_server-0.2.0}/crates/ciris-lens-core/pyproject.toml +0 -0
- {ciris_server-0.1.2 → ciris_server-0.2.0}/crates/ciris-lens-core/python/ciris_lens_core/__init__.py +0 -0
- {ciris_server-0.1.2 → ciris_server-0.2.0}/crates/ciris-lens-core/src/audit/api.rs +0 -0
- {ciris_server-0.1.2 → ciris_server-0.2.0}/crates/ciris-lens-core/src/audit/delegate.rs +0 -0
- {ciris_server-0.1.2 → ciris_server-0.2.0}/crates/ciris-lens-core/src/audit/mod.rs +0 -0
- {ciris_server-0.1.2 → ciris_server-0.2.0}/crates/ciris-lens-core/src/audit/pyo3.rs +0 -0
- {ciris_server-0.1.2 → ciris_server-0.2.0}/crates/ciris-lens-core/src/canonical/ceg_egress.rs +0 -0
- {ciris_server-0.1.2 → ciris_server-0.2.0}/crates/ciris-lens-core/src/canonical/mod.rs +0 -0
- {ciris_server-0.1.2 → ciris_server-0.2.0}/crates/ciris-lens-core/src/capacity/attestation.rs +0 -0
- {ciris_server-0.1.2 → ciris_server-0.2.0}/crates/ciris-lens-core/src/capacity/mod.rs +0 -0
- {ciris_server-0.1.2 → ciris_server-0.2.0}/crates/ciris-lens-core/src/capacity/score.rs +0 -0
- {ciris_server-0.1.2 → ciris_server-0.2.0}/crates/ciris-lens-core/src/capture/batch.rs +0 -0
- {ciris_server-0.1.2 → ciris_server-0.2.0}/crates/ciris-lens-core/src/capture/client.rs +0 -0
- {ciris_server-0.1.2 → ciris_server-0.2.0}/crates/ciris-lens-core/src/capture/consent.rs +0 -0
- {ciris_server-0.1.2 → ciris_server-0.2.0}/crates/ciris-lens-core/src/capture/correlation.rs +0 -0
- {ciris_server-0.1.2 → ciris_server-0.2.0}/crates/ciris-lens-core/src/capture/event.rs +0 -0
- {ciris_server-0.1.2 → ciris_server-0.2.0}/crates/ciris-lens-core/src/capture/mod.rs +0 -0
- {ciris_server-0.1.2 → ciris_server-0.2.0}/crates/ciris-lens-core/src/capture/partial.rs +0 -0
- {ciris_server-0.1.2 → ciris_server-0.2.0}/crates/ciris-lens-core/src/capture/py_engine.rs +0 -0
- {ciris_server-0.1.2 → ciris_server-0.2.0}/crates/ciris-lens-core/src/capture/seal.rs +0 -0
- {ciris_server-0.1.2 → ciris_server-0.2.0}/crates/ciris-lens-core/src/cohort/declared.rs +0 -0
- {ciris_server-0.1.2 → ciris_server-0.2.0}/crates/ciris-lens-core/src/cohort/mod.rs +0 -0
- {ciris_server-0.1.2 → ciris_server-0.2.0}/crates/ciris-lens-core/src/cohort/resourcing.rs +0 -0
- {ciris_server-0.1.2 → ciris_server-0.2.0}/crates/ciris-lens-core/src/config/egress.rs +0 -0
- {ciris_server-0.1.2 → ciris_server-0.2.0}/crates/ciris-lens-core/src/config/mod.rs +0 -0
- {ciris_server-0.1.2 → ciris_server-0.2.0}/crates/ciris-lens-core/src/config/node.rs +0 -0
- {ciris_server-0.1.2 → ciris_server-0.2.0}/crates/ciris-lens-core/src/config/retention.rs +0 -0
- {ciris_server-0.1.2 → ciris_server-0.2.0}/crates/ciris-lens-core/src/config/upstream.rs +0 -0
- {ciris_server-0.1.2 → ciris_server-0.2.0}/crates/ciris-lens-core/src/detector/axis_metrics.rs +0 -0
- {ciris_server-0.1.2 → ciris_server-0.2.0}/crates/ciris-lens-core/src/detector/coherence_ratchet.rs +0 -0
- {ciris_server-0.1.2 → ciris_server-0.2.0}/crates/ciris-lens-core/src/detector/correlated_action.rs +0 -0
- {ciris_server-0.1.2 → ciris_server-0.2.0}/crates/ciris-lens-core/src/detector/distributive_access.rs +0 -0
- {ciris_server-0.1.2 → ciris_server-0.2.0}/crates/ciris-lens-core/src/detector/manifold.rs +0 -0
- {ciris_server-0.1.2 → ciris_server-0.2.0}/crates/ciris-lens-core/src/detector/mod.rs +0 -0
- {ciris_server-0.1.2 → ciris_server-0.2.0}/crates/ciris-lens-core/src/extract/mod.rs +0 -0
- {ciris_server-0.1.2 → ciris_server-0.2.0}/crates/ciris-lens-core/src/extract/projection.rs +0 -0
- {ciris_server-0.1.2 → ciris_server-0.2.0}/crates/ciris-lens-core/src/ffi/mod.rs +0 -0
- {ciris_server-0.1.2 → ciris_server-0.2.0}/crates/ciris-lens-core/src/ffi/pyo3.rs +0 -0
- {ciris_server-0.1.2 → ciris_server-0.2.0}/crates/ciris-lens-core/src/lib.rs +0 -0
- {ciris_server-0.1.2 → ciris_server-0.2.0}/crates/ciris-lens-core/src/observability/mod.rs +0 -0
- {ciris_server-0.1.2 → ciris_server-0.2.0}/crates/ciris-lens-core/src/pipeline/lifecycle.rs +0 -0
- {ciris_server-0.1.2 → ciris_server-0.2.0}/crates/ciris-lens-core/src/pipeline/mod.rs +0 -0
- {ciris_server-0.1.2 → ciris_server-0.2.0}/crates/ciris-lens-core/src/retention/eviction.rs +0 -0
- {ciris_server-0.1.2 → ciris_server-0.2.0}/crates/ciris-lens-core/src/retention/mod.rs +0 -0
- {ciris_server-0.1.2 → ciris_server-0.2.0}/crates/ciris-lens-core/src/retention/summary.rs +0 -0
- {ciris_server-0.1.2 → ciris_server-0.2.0}/crates/ciris-lens-core/src/role/handler.rs +0 -0
- {ciris_server-0.1.2 → ciris_server-0.2.0}/crates/ciris-lens-core/src/role/mod.rs +0 -0
- {ciris_server-0.1.2 → ciris_server-0.2.0}/crates/ciris-lens-core/src/role/node.rs +0 -0
- {ciris_server-0.1.2 → ciris_server-0.2.0}/crates/ciris-lens-core/src/role/relay.rs +0 -0
- {ciris_server-0.1.2 → ciris_server-0.2.0}/crates/ciris-lens-core/src/role/ret_relay.rs +0 -0
- {ciris_server-0.1.2 → ciris_server-0.2.0}/crates/ciris-lens-core/src/scores/aggregate.rs +0 -0
- {ciris_server-0.1.2 → ciris_server-0.2.0}/crates/ciris-lens-core/src/scores/mod.rs +0 -0
- {ciris_server-0.1.2 → ciris_server-0.2.0}/crates/ciris-lens-core/src/scores/oracle.rs +0 -0
- {ciris_server-0.1.2 → ciris_server-0.2.0}/crates/ciris-lens-core/src/scoring/assembly.rs +0 -0
- {ciris_server-0.1.2 → ciris_server-0.2.0}/crates/ciris-lens-core/src/scoring/axis_calibration.rs +0 -0
- {ciris_server-0.1.2 → ciris_server-0.2.0}/crates/ciris-lens-core/src/scoring/calibration.rs +0 -0
- {ciris_server-0.1.2 → ciris_server-0.2.0}/crates/ciris-lens-core/src/scoring/capacity.rs +0 -0
- {ciris_server-0.1.2 → ciris_server-0.2.0}/crates/ciris-lens-core/src/scoring/mod.rs +0 -0
- {ciris_server-0.1.2 → ciris_server-0.2.0}/crates/ciris-lens-core/src/scoring/n_eff.rs +0 -0
- {ciris_server-0.1.2 → ciris_server-0.2.0}/crates/ciris-lens-core/src/scoring/result.rs +0 -0
- {ciris_server-0.1.2 → ciris_server-0.2.0}/crates/ciris-lens-core/src/signing/event.rs +0 -0
- {ciris_server-0.1.2 → ciris_server-0.2.0}/crates/ciris-lens-core/src/signing/mod.rs +0 -0
- {ciris_server-0.1.2 → ciris_server-0.2.0}/crates/ciris-lens-core/src/wire/mod.rs +0 -0
- {ciris_server-0.1.2 → ciris_server-0.2.0}/crates/ciris-lens-core/src/wire/signer.rs +0 -0
- {ciris_server-0.1.2 → ciris_server-0.2.0}/crates/ciris-lens-core/tests/parity/README.md +0 -0
- {ciris_server-0.1.2 → ciris_server-0.2.0}/crates/ciris-lens-core/tests/parity/canonical_fixtures.json +0 -0
- {ciris_server-0.1.2 → ciris_server-0.2.0}/crates/ciris-lens-core/tests/parity/generate_canonical_fixtures.py +0 -0
- {ciris_server-0.1.2 → ciris_server-0.2.0}/crates/ciris-lens-core/tests/sovereign_rlib.rs +0 -0
- {ciris_server-0.1.2 → ciris_server-0.2.0}/rust-toolchain.toml +0 -0
- {ciris_server-0.1.2 → ciris_server-0.2.0}/src/config.rs +0 -0
- {ciris_server-0.1.2 → ciris_server-0.2.0}/src/lib.rs +0 -0
- {ciris_server-0.1.2 → ciris_server-0.2.0}/src/main.rs +0 -0
- {ciris_server-0.1.2 → ciris_server-0.2.0}/src/quorum.rs +0 -0
- {ciris_server-0.1.2 → ciris_server-0.2.0}/tests/replication.rs +0 -0
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# Android cross-link targets (NDK API 24). The 16 KiB max-page-size arg is the
|
|
2
|
+
# Android-15+ compatibility flag the substrate crates use. Mirrors
|
|
3
|
+
# CIRISVerify/.cargo/config.toml so the android wheel lane links cleanly.
|
|
4
|
+
[target.armv7-linux-androideabi]
|
|
5
|
+
linker = "armv7a-linux-androideabi24-clang"
|
|
6
|
+
rustflags = ["-C", "link-arg=-Wl,-z,max-page-size=16384"]
|
|
7
|
+
|
|
8
|
+
[target.aarch64-linux-android]
|
|
9
|
+
linker = "aarch64-linux-android24-clang"
|
|
10
|
+
rustflags = ["-C", "link-arg=-Wl,-z,max-page-size=16384"]
|
|
11
|
+
|
|
12
|
+
[target.x86_64-linux-android]
|
|
13
|
+
linker = "x86_64-linux-android24-clang"
|
|
14
|
+
rustflags = ["-C", "link-arg=-Wl,-z,max-page-size=16384"]
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
name: bench
|
|
2
|
+
|
|
3
|
+
# Run the criterion benches, turn them into an INTERPRETED page (video
|
|
4
|
+
# throughput / replication speed / post-quantum overhead — what the numbers
|
|
5
|
+
# mean, not just ns), and publish to GitHub Pages. Mirrors the substrate
|
|
6
|
+
# sisters' publish-only bench discipline (not a pass/fail gate — shared runners
|
|
7
|
+
# are too noisy), but with an interpretation layer on top (scripts/bench_report.py).
|
|
8
|
+
#
|
|
9
|
+
# Published at: https://cirisai.github.io/CIRISServer/
|
|
10
|
+
# One-time: Settings → Pages → Source = "GitHub Actions" (the configure-pages
|
|
11
|
+
# step below sets enablement: true to do this automatically on first run).
|
|
12
|
+
|
|
13
|
+
on:
|
|
14
|
+
push:
|
|
15
|
+
branches: [main]
|
|
16
|
+
paths:
|
|
17
|
+
- "benches/**"
|
|
18
|
+
- "scripts/bench_report.py"
|
|
19
|
+
- ".github/workflows/bench.yml"
|
|
20
|
+
- "Cargo.toml"
|
|
21
|
+
workflow_dispatch:
|
|
22
|
+
schedule:
|
|
23
|
+
- cron: "0 7 * * 1" # Mondays 07:00 UTC
|
|
24
|
+
|
|
25
|
+
permissions:
|
|
26
|
+
contents: read
|
|
27
|
+
pages: write
|
|
28
|
+
id-token: write
|
|
29
|
+
|
|
30
|
+
# Never cancel an in-flight Pages deploy; let bench runs serialize.
|
|
31
|
+
concurrency:
|
|
32
|
+
group: bench-pages
|
|
33
|
+
cancel-in-progress: false
|
|
34
|
+
|
|
35
|
+
jobs:
|
|
36
|
+
bench-and-publish:
|
|
37
|
+
runs-on: ubuntu-latest
|
|
38
|
+
environment:
|
|
39
|
+
name: github-pages
|
|
40
|
+
url: ${{ steps.deploy.outputs.page_url }}
|
|
41
|
+
steps:
|
|
42
|
+
- uses: actions/checkout@v4
|
|
43
|
+
- uses: dtolnay/rust-toolchain@stable
|
|
44
|
+
- name: Install build deps
|
|
45
|
+
run: sudo apt-get update && sudo apt-get install -y libtss2-dev libsqlite3-dev
|
|
46
|
+
- uses: Swatinem/rust-cache@v2
|
|
47
|
+
continue-on-error: true
|
|
48
|
+
with:
|
|
49
|
+
cache-bin: false
|
|
50
|
+
key: bench
|
|
51
|
+
- uses: actions/setup-python@v5
|
|
52
|
+
with:
|
|
53
|
+
python-version: "3.12"
|
|
54
|
+
- name: Run benches (criterion)
|
|
55
|
+
run: cargo bench --bench pqc_av_streaming --bench replication_ingest
|
|
56
|
+
- name: Generate interpreted page
|
|
57
|
+
run: |
|
|
58
|
+
BENCH_DATE="$(date -u +%Y-%m-%d)" \
|
|
59
|
+
python3 scripts/bench_report.py --out bench-site --commit "$GITHUB_SHA"
|
|
60
|
+
- uses: actions/configure-pages@v5
|
|
61
|
+
with:
|
|
62
|
+
enablement: true
|
|
63
|
+
- uses: actions/upload-pages-artifact@v3
|
|
64
|
+
with:
|
|
65
|
+
path: bench-site
|
|
66
|
+
- id: deploy
|
|
67
|
+
uses: actions/deploy-pages@v4
|
|
@@ -33,13 +33,23 @@ jobs:
|
|
|
33
33
|
components: clippy
|
|
34
34
|
- name: Install build deps (Linux)
|
|
35
35
|
if: runner.os == 'Linux'
|
|
36
|
+
# libtss2-dev: the Linux-only keyring/tpm backend (cfg(target_os=linux)).
|
|
37
|
+
# libsqlite3-dev: persist's sqlite. macOS/Windows pull NEITHER tss-esapi
|
|
38
|
+
# nor openssl (postgres+tpm are Linux-only per Cargo.toml [target.linux]).
|
|
36
39
|
run: sudo apt-get update && sudo apt-get install -y libtss2-dev libsqlite3-dev
|
|
37
40
|
- uses: Swatinem/rust-cache@v2
|
|
38
41
|
continue-on-error: true
|
|
39
42
|
with:
|
|
40
43
|
cache-bin: false
|
|
41
|
-
|
|
42
|
-
-
|
|
44
|
+
# Default features build everywhere (sqlite + the binary path); postgres +
|
|
45
|
+
# tpm are Linux-only (per-target). NOT --all-features: that drags
|
|
46
|
+
# `extension-module` (libpython-no-link) into the test binary.
|
|
47
|
+
- run: cargo clippy --all-targets -- -D warnings
|
|
48
|
+
- run: cargo test
|
|
49
|
+
# The PyO3 wheel surface (Linux only; libpython linked, no extension-module).
|
|
50
|
+
- name: clippy (python surface, Linux)
|
|
51
|
+
if: runner.os == 'Linux'
|
|
52
|
+
run: cargo clippy --all-targets --features python -- -D warnings
|
|
43
53
|
|
|
44
54
|
# Win7-SP1 → Win11 build check (CIRISVerify#67 pattern, mirrored by every
|
|
45
55
|
# upstream substrate crate). Rust 1.78 raised the windows-msvc std floor to
|
|
@@ -65,6 +75,16 @@ jobs:
|
|
|
65
75
|
- name: Build (x86_64-win7-windows-msvc, build-std)
|
|
66
76
|
shell: bash
|
|
67
77
|
run: |
|
|
78
|
+
# LNK1181 workaround (persist's recipe): build-std relinks std, which
|
|
79
|
+
# needs the windows_x86_64_msvc import-lib dirs on LIB. openssl/tss2 are
|
|
80
|
+
# NOT pulled on this windows target (postgres+tpm are Linux-only), so no
|
|
81
|
+
# vcpkg/openssl-src build is needed here anymore.
|
|
82
|
+
cargo fetch
|
|
83
|
+
extra=""
|
|
84
|
+
while IFS= read -r d; do
|
|
85
|
+
extra="${extra};$(cygpath -w "$d")"
|
|
86
|
+
done < <(find "$HOME/.cargo/registry/src" -type d -path '*windows_x86_64_msvc-*/lib' 2>/dev/null | sort -u)
|
|
87
|
+
[ -n "$extra" ] && export LIB="${LIB:-}${extra}"
|
|
68
88
|
cargo +nightly build --release \
|
|
69
89
|
--target x86_64-win7-windows-msvc \
|
|
70
90
|
-Z build-std=std,panic_abort \
|
|
@@ -108,6 +108,64 @@ jobs:
|
|
|
108
108
|
path: dist/*.whl
|
|
109
109
|
if-no-files-found: warn
|
|
110
110
|
|
|
111
|
+
# Android abi3 wheels (incl. arm32 armeabi-v7a) — the CIRISAgent KMP client's
|
|
112
|
+
# mobile targets. NDK cross-compile + libpython stub, the substrate recipe
|
|
113
|
+
# (CIRISVerify/Persist/Edge). continue-on-error while the cross lane iterates
|
|
114
|
+
# to green — it must not block the desktop/server publish.
|
|
115
|
+
android:
|
|
116
|
+
name: wheel android-${{ matrix.abi }}
|
|
117
|
+
runs-on: ubuntu-latest
|
|
118
|
+
continue-on-error: true
|
|
119
|
+
strategy:
|
|
120
|
+
fail-fast: false
|
|
121
|
+
matrix:
|
|
122
|
+
include:
|
|
123
|
+
- { abi: armeabi-v7a, target: armv7-linux-androideabi, clang: armv7a-linux-androideabi24, pw: 32 }
|
|
124
|
+
- { abi: arm64-v8a, target: aarch64-linux-android, clang: aarch64-linux-android24, pw: 64 }
|
|
125
|
+
steps:
|
|
126
|
+
- uses: actions/checkout@v4
|
|
127
|
+
- uses: dtolnay/rust-toolchain@stable
|
|
128
|
+
with:
|
|
129
|
+
targets: ${{ matrix.target }}
|
|
130
|
+
- uses: actions/setup-python@v5
|
|
131
|
+
with:
|
|
132
|
+
python-version: "3.12"
|
|
133
|
+
- uses: nttld/setup-ndk@v1
|
|
134
|
+
id: ndk
|
|
135
|
+
with:
|
|
136
|
+
ndk-version: r26b
|
|
137
|
+
add-to-path: true
|
|
138
|
+
- name: PyO3 cross config + libpython stub
|
|
139
|
+
env:
|
|
140
|
+
ANDROID_NDK_HOME: ${{ steps.ndk.outputs.ndk-path }}
|
|
141
|
+
run: |
|
|
142
|
+
CFG="${RUNNER_TEMP}/pyo3-android.config"
|
|
143
|
+
{
|
|
144
|
+
echo "implementation=CPython"; echo "version=3.10"; echo "shared=false"
|
|
145
|
+
echo "abi3=true"; echo "lib_name=python3.10"; echo "lib_dir="
|
|
146
|
+
echo "executable="; echo "pointer_width=${{ matrix.pw }}"; echo "build_flags="
|
|
147
|
+
echo "suppress_build_script_link_lines=true"
|
|
148
|
+
} > "$CFG"
|
|
149
|
+
echo "PYO3_CONFIG_FILE=${CFG}" >> "$GITHUB_ENV"
|
|
150
|
+
STUB="${RUNNER_TEMP}/python-stub"; mkdir -p "$STUB"
|
|
151
|
+
TC="${ANDROID_NDK_HOME}/toolchains/llvm/prebuilt/linux-x86_64"
|
|
152
|
+
echo 'void __pystub(void){}' | \
|
|
153
|
+
"${TC}/bin/${{ matrix.clang }}-clang" -shared -nostdlib \
|
|
154
|
+
-Wl,-soname,libpython3.10.so -o "${STUB}/libpython3.10.so" -x c -
|
|
155
|
+
- name: Build wheel (maturin, Android NDK)
|
|
156
|
+
env:
|
|
157
|
+
ANDROID_NDK_HOME: ${{ steps.ndk.outputs.ndk-path }}
|
|
158
|
+
RUSTFLAGS: "-L ${{ runner.temp }}/python-stub -C link-arg=-Wl,--no-as-needed -C link-arg=-lpython3.10"
|
|
159
|
+
run: |
|
|
160
|
+
python -m pip install --upgrade pip
|
|
161
|
+
pip install "maturin>=1.7,<2"
|
|
162
|
+
maturin build --release --out dist --target ${{ matrix.target }}
|
|
163
|
+
- uses: actions/upload-artifact@v4
|
|
164
|
+
with:
|
|
165
|
+
name: wheels-android-${{ matrix.abi }}
|
|
166
|
+
path: dist/*.whl
|
|
167
|
+
if-no-files-found: warn
|
|
168
|
+
|
|
111
169
|
sdist:
|
|
112
170
|
name: sdist
|
|
113
171
|
runs-on: ubuntu-latest
|
|
@@ -145,7 +203,7 @@ jobs:
|
|
|
145
203
|
# ── Publish to PyPI via Trusted Publishing (OIDC) ──────────────────────────
|
|
146
204
|
publish:
|
|
147
205
|
name: publish to PyPI
|
|
148
|
-
needs: [linux, macos, windows, sdist, conformance-gate]
|
|
206
|
+
needs: [linux, macos, windows, android, sdist, conformance-gate]
|
|
149
207
|
runs-on: ubuntu-latest
|
|
150
208
|
if: startsWith(github.ref, 'refs/tags/') || inputs.publish
|
|
151
209
|
environment: pypi
|
|
@@ -4,6 +4,37 @@ All notable changes to CIRISServer. Format follows [Keep a Changelog](https://ke
|
|
|
4
4
|
this project uses [Semantic Versioning](https://semver.org/). The minor line tracks
|
|
5
5
|
the fabric-node scope (0.1 lens · 0.5 +registry · 1.0 +node), paced by the CIRISAgent train.
|
|
6
6
|
|
|
7
|
+
## [0.2.0] — 2026-06-15
|
|
8
|
+
|
|
9
|
+
All-platforms-green CI, **full hybrid post-quantum federation signatures**, and a
|
|
10
|
+
published interpreted benchmark page.
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
- **Full hybrid PQC federation signature (Ed25519 + ML-DSA-65).** The node mints
|
|
14
|
+
(or **adopts**, on takeover) an `ml_dsa_65.seed` and signs every federation
|
|
15
|
+
envelope with both halves (edge `LocalSigner` classical + pqc). `/v1/identity`
|
|
16
|
+
now carries `ml_dsa_65_pubkey_b64` + `pqc_key_id`. Classical stays
|
|
17
|
+
hardware-sealed; the ML-DSA half is a software seed (no sealed-ML-DSA backend
|
|
18
|
+
exists — a TPM can't do ML-DSA).
|
|
19
|
+
- **One remaining classical path**, filed upstream: persist's storage-tier
|
|
20
|
+
scrub signature is Ed25519-only — `with_hardware_signer` is classical-only and
|
|
21
|
+
`with_signer_arcs` (hybrid) needs a plaintext key. **CIRISPersist#224** adds a
|
|
22
|
+
hybrid-hardware ctor to close it without un-sealing.
|
|
23
|
+
- **Interpreted benchmark page** → `https://cirisai.github.io/CIRISServer/`
|
|
24
|
+
(`.github/workflows/bench.yml` + `scripts/bench_report.py`): video throughput
|
|
25
|
+
(fps ceiling, sustainable mesh participants @30 fps), post-quantum handshake
|
|
26
|
+
overhead, mesh fan-out, and **replication speed** (new `replication_ingest`
|
|
27
|
+
bench, ~13K traces/s/core).
|
|
28
|
+
- Android arm32 (armeabi-v7a) + arm64 wheel lane (NDK cross-compile;
|
|
29
|
+
`continue-on-error` while it iterates to green).
|
|
30
|
+
|
|
31
|
+
### Changed / Fixed
|
|
32
|
+
- **All CI platforms green** (was red on macOS/Windows/Win7). Root cause was our
|
|
33
|
+
own feature wiring: a top-level `tpm` feature + unconditional `postgres`
|
|
34
|
+
dragged `tss-esapi`/`openssl` onto platforms that can't build them. Fixed with
|
|
35
|
+
per-target deps (`postgres` + `tpm` Linux-only; `android` keyring backend) and
|
|
36
|
+
dropping `--all-features`.
|
|
37
|
+
|
|
7
38
|
## [0.1.2] — 2026-06-15
|
|
8
39
|
|
|
9
40
|
Substrate floor bump + the `/v1/identity` endpoint the migration runbook requires.
|
|
@@ -982,7 +982,7 @@ dependencies = [
|
|
|
982
982
|
|
|
983
983
|
[[package]]
|
|
984
984
|
name = "ciris-server"
|
|
985
|
-
version = "0.
|
|
985
|
+
version = "0.2.0"
|
|
986
986
|
dependencies = [
|
|
987
987
|
"anyhow",
|
|
988
988
|
"axum",
|
|
@@ -997,6 +997,7 @@ dependencies = [
|
|
|
997
997
|
"criterion",
|
|
998
998
|
"ed25519-dalek",
|
|
999
999
|
"fs2",
|
|
1000
|
+
"getrandom 0.3.4",
|
|
1000
1001
|
"pyo3",
|
|
1001
1002
|
"pyo3-async-runtimes",
|
|
1002
1003
|
"serde_json",
|
|
@@ -1206,6 +1207,7 @@ dependencies = [
|
|
|
1206
1207
|
"ciborium",
|
|
1207
1208
|
"clap",
|
|
1208
1209
|
"criterion-plot",
|
|
1210
|
+
"futures",
|
|
1209
1211
|
"is-terminal",
|
|
1210
1212
|
"itertools 0.10.5",
|
|
1211
1213
|
"num-traits",
|
|
@@ -1218,6 +1220,7 @@ dependencies = [
|
|
|
1218
1220
|
"serde_derive",
|
|
1219
1221
|
"serde_json",
|
|
1220
1222
|
"tinytemplate",
|
|
1223
|
+
"tokio",
|
|
1221
1224
|
"walkdir",
|
|
1222
1225
|
]
|
|
1223
1226
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[package]
|
|
2
2
|
name = "ciris-server"
|
|
3
|
-
version = "0.
|
|
3
|
+
version = "0.2.0" # 0.1 = lens-only (agent ~2.9.7); 0.5 = +registry (~2.9.8); 1.0 = +node (~2.9.10). Patch forward (0.1.1) 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.
|
|
@@ -41,13 +41,13 @@ python = ["dep:pyo3", "dep:pyo3-async-runtimes", "ciris-lens-core/python"]
|
|
|
41
41
|
# `extension-module` is what maturin builds the wheel with (tells PyO3 not to
|
|
42
42
|
# link libpython). The bin must NOT enable it. See pyproject.toml [tool.maturin].
|
|
43
43
|
extension-module = ["python", "pyo3/extension-module"]
|
|
44
|
-
#
|
|
45
|
-
#
|
|
46
|
-
#
|
|
47
|
-
#
|
|
48
|
-
#
|
|
49
|
-
# software when absent (`is_hardware_backed()` reports the posture).
|
|
50
|
-
|
|
44
|
+
# NOTE: hardware key custody (TPM/SE/StrongBox) is wired per-TARGET below, not as
|
|
45
|
+
# a cargo feature — TPM (tss-esapi) is Linux-only, so a top-level `tpm` feature
|
|
46
|
+
# made `--all-features` drag tss-esapi onto Windows/macOS (where it can't build).
|
|
47
|
+
# The `[target.'cfg(target_os = "linux")']` table enables keyring/tpm + persist
|
|
48
|
+
# postgres on Linux only; runtime auto-detects hardware and degrades to encrypted
|
|
49
|
+
# software when absent (`is_hardware_backed()` reports the posture). This mirrors
|
|
50
|
+
# the substrate crates' per-target keyring/postgres gating.
|
|
51
51
|
|
|
52
52
|
# ----------------------------------------------------------------------------
|
|
53
53
|
# Dependencies — CIRISServer AUTHORS NO PRIMITIVES. It composes the core
|
|
@@ -82,7 +82,10 @@ ciris-lens-core = { path = "crates/ciris-lens-core" } # ABSORBED in-tree (wo
|
|
|
82
82
|
|
|
83
83
|
# The substrate trio (also pulled transitively by the cores; pinned here so the
|
|
84
84
|
# composition root owns the singleton construction).
|
|
85
|
-
|
|
85
|
+
# sqlite on all platforms; postgres is Linux-only (libpq/openssl don't link
|
|
86
|
+
# cleanly on the macOS/Windows runners — same posture as persist's own CI). The
|
|
87
|
+
# `[target.linux]` table below adds postgres.
|
|
88
|
+
ciris-persist = { git = "https://github.com/CIRISAI/CIRISPersist", tag = "v7.0.0", features = ["sqlite"] }
|
|
86
89
|
ciris-edge = { git = "https://github.com/CIRISAI/CIRISEdge", tag = "v3.6.0", features = ["transport-reticulum", "transport-http"] }
|
|
87
90
|
# Founder-quorum verification + key-id fingerprint at the composition root
|
|
88
91
|
# (threshold:: module path — NOT re-exported at the crate root).
|
|
@@ -106,9 +109,24 @@ fs2 = "0.4" # available-disk check for realistic-minimum feature gating
|
|
|
106
109
|
axum = "0.8"
|
|
107
110
|
base64 = "0.22"
|
|
108
111
|
serde_json = "1"
|
|
112
|
+
getrandom = "0.3" # mint the ML-DSA-65 federation seed on first boot (hybrid PQC)
|
|
109
113
|
tracing = "0.1"
|
|
110
114
|
tracing-subscriber = { version = "0.3", features = ["env-filter", "json"] }
|
|
111
115
|
|
|
116
|
+
# Linux-only hardware + Postgres: cargo UNIONS these onto the base deps above.
|
|
117
|
+
# - persist `postgres` (libpq/openssl) — Linux deployment + the postgres
|
|
118
|
+
# conformance lane; macOS/Windows stay sqlite-only.
|
|
119
|
+
# - keyring `tpm` (tss-esapi / TPM 2.0) — the real hardware backend; needs
|
|
120
|
+
# libtss2 (Linux build dep). Other targets keep the software keystore.
|
|
121
|
+
[target.'cfg(target_os = "linux")'.dependencies]
|
|
122
|
+
ciris-persist = { git = "https://github.com/CIRISAI/CIRISPersist", tag = "v7.0.0", features = ["postgres"] }
|
|
123
|
+
ciris-keyring = { git = "https://github.com/CIRISAI/CIRISVerify", tag = "v5.6.0", version = "5", features = ["tpm"] }
|
|
124
|
+
|
|
125
|
+
# Android (arm64/arm32/x86_64): the keyring `android` backend (JNI → Android
|
|
126
|
+
# Keystore/StrongBox); sqlite bundles, no postgres/tpm. Mirrors persist/edge.
|
|
127
|
+
[target.'cfg(target_os = "android")'.dependencies]
|
|
128
|
+
ciris-keyring = { git = "https://github.com/CIRISAI/CIRISVerify", tag = "v5.6.0", version = "5", features = ["android"] }
|
|
129
|
+
|
|
112
130
|
# Test-only — the two-node replication integration test (tests/replication.rs)
|
|
113
131
|
# builds + signs CEG batches with the same primitives persist verifies against.
|
|
114
132
|
# ed25519-dalek MUST match persist's locked 2.x (the SigningKey type crosses the
|
|
@@ -118,7 +136,7 @@ ed25519-dalek = "2"
|
|
|
118
136
|
base64 = "0.22"
|
|
119
137
|
chrono = { version = "0.4", features = ["serde"] }
|
|
120
138
|
serde_json = "1"
|
|
121
|
-
criterion = "0.5"
|
|
139
|
+
criterion = { version = "0.5", features = ["async_tokio"] }
|
|
122
140
|
# The PQC primitives the realtime-A/V E2E bench drives directly: hybrid KEX
|
|
123
141
|
# (X25519 + ML-KEM-768) for the per-Link transit key, AES-256-GCM for the
|
|
124
142
|
# two-layer chunk seal. Same pin/features edge composes (tag parity).
|
|
@@ -129,6 +147,11 @@ ciris-crypto = { git = "https://github.com/CIRISAI/CIRISVerify", tag = "v5.6.0"
|
|
|
129
147
|
name = "pqc_av_streaming"
|
|
130
148
|
harness = false
|
|
131
149
|
|
|
150
|
+
# Replication / corpus-ingest throughput (the CEG-RC5 receive spine).
|
|
151
|
+
[[bench]]
|
|
152
|
+
name = "replication_ingest"
|
|
153
|
+
harness = false
|
|
154
|
+
|
|
132
155
|
[profile.release]
|
|
133
156
|
# panic strategy stays "unwind" (the Win7 build-std lane relies on this being
|
|
134
157
|
# pinned here, not on the build-std crate list — see release.yml win7 lane).
|
|
@@ -72,8 +72,13 @@ pip install ciris-server # the abi3 wheel (live on PyPI; self-contained,
|
|
|
72
72
|
```
|
|
73
73
|
export CIRIS_HOME=/var/lib/ciris-server # data + identity root
|
|
74
74
|
mkdir -p "$CIRIS_HOME/identity"
|
|
75
|
-
# Federation signing seed → adopted + TPM-sealed on first boot, byte-identical
|
|
75
|
+
# Federation signing seed (Ed25519) → adopted + TPM-sealed on first boot, byte-identical
|
|
76
76
|
cp /var/lib/cirislens/keyring/ed25519.seed "$CIRIS_HOME/identity/ed25519.seed"
|
|
77
|
+
# PQC signing seed (ML-DSA-65) → adopted as the hybrid half, IF the deployment had one.
|
|
78
|
+
# The federation signature is a FULL HYBRID (Ed25519 + ML-DSA-65); if no ml_dsa_65.seed
|
|
79
|
+
# is carried over, the node MINTS a fresh PQC half on first boot — a NEW PQC pubkey, so
|
|
80
|
+
# coordinate enrollment (the Ed25519 key_id is still continuous).
|
|
81
|
+
cp /var/lib/cirislens/keyring/ml_dsa_65.seed "$CIRIS_HOME/identity/ml_dsa_65.seed" # if present
|
|
77
82
|
# RNS transport identity → adopted into the keystore byte-identically (dest hash preserved)
|
|
78
83
|
export CIRIS_SERVER_RET_IDENTITY_PATH=/var/lib/cirislens/keyring/lens-edge.identity
|
|
79
84
|
```
|
|
@@ -81,6 +86,8 @@ On first boot the node:
|
|
|
81
86
|
- **adopts** `ed25519.seed` (`SealedEd25519Signer::adopt`) → the **same** 32-byte
|
|
82
87
|
Ed25519 pubkey ⇒ the **same `key_id`**, now TPM-sealed; the plaintext is archived
|
|
83
88
|
to `ed25519.seed.migrated` (the sealed copy is load-bearing);
|
|
89
|
+
- **adopts** `ml_dsa_65.seed` (if present) → the **same** ML-DSA-65 pubkey (the PQC
|
|
90
|
+
half of the hybrid signature); software-at-rest (no sealed-ML-DSA backend);
|
|
84
91
|
- **adopts** the `.rid` into `BlobTransportKeystore` → the **same Reticulum
|
|
85
92
|
destination hash**, now TPM-sealed; the original is archived to
|
|
86
93
|
`*.migrated-<ts>`.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: ciris-server
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.2.0
|
|
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>
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
//! Replication / corpus-ingest throughput — the receive side of CEG-RC5
|
|
2
|
+
//! replication (the spine `tests/replication.rs` proves correct). Measures
|
|
3
|
+
//! `Engine::receive_and_persist`: verify (Ed25519) + persist + content-addressed
|
|
4
|
+
//! dedup — the cost a node pays per replicated trace. Run:
|
|
5
|
+
//! `cargo bench --bench replication_ingest`.
|
|
6
|
+
//!
|
|
7
|
+
//! Two numbers:
|
|
8
|
+
//! - `ingest_new` — a fresh signed trace each iteration (insert path = a new
|
|
9
|
+
//! envelope arriving from a peer). This is "replication speed" — traces/sec a
|
|
10
|
+
//! node absorbs.
|
|
11
|
+
//! - `ingest_dedup` — re-delivering an already-seen trace (the anti gossip-loop
|
|
12
|
+
//! path: verify + dedup-reject, no insert). The steady-state of anti-entropy.
|
|
13
|
+
|
|
14
|
+
use std::sync::Arc;
|
|
15
|
+
use std::time::SystemTime;
|
|
16
|
+
|
|
17
|
+
use base64::engine::general_purpose::STANDARD as BASE64;
|
|
18
|
+
use base64::Engine as _;
|
|
19
|
+
use criterion::{criterion_group, criterion_main, BatchSize, Criterion, Throughput};
|
|
20
|
+
use ed25519_dalek::{Signer as _, SigningKey};
|
|
21
|
+
|
|
22
|
+
use ciris_persist::federation::types::{algorithm, identity_type};
|
|
23
|
+
use ciris_persist::federation::{FederationDirectory as _, KeyRecord, SignedKeyRecord};
|
|
24
|
+
use ciris_persist::prelude::{Engine, LocalSigner};
|
|
25
|
+
use ciris_persist::schema::{
|
|
26
|
+
CompleteTrace, ComponentType, ReasoningEventType, SchemaVersion, TraceComponent, TraceLevel,
|
|
27
|
+
};
|
|
28
|
+
use ciris_persist::scrub::NullScrubber;
|
|
29
|
+
|
|
30
|
+
const KEY_ID: &str = "bench-agent";
|
|
31
|
+
|
|
32
|
+
fn rt() -> tokio::runtime::Runtime {
|
|
33
|
+
tokio::runtime::Builder::new_current_thread()
|
|
34
|
+
.enable_all()
|
|
35
|
+
.build()
|
|
36
|
+
.unwrap()
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
async fn engine_with_key(agent_sk: &SigningKey) -> Arc<Engine> {
|
|
40
|
+
let node = Arc::new(LocalSigner::from_parts(
|
|
41
|
+
SigningKey::from_bytes(&[0xA0; 32]),
|
|
42
|
+
"bench-node".to_string(),
|
|
43
|
+
None,
|
|
44
|
+
None,
|
|
45
|
+
));
|
|
46
|
+
let engine = Arc::new(
|
|
47
|
+
Engine::with_signer(node, "sqlite::memory:")
|
|
48
|
+
.await
|
|
49
|
+
.expect("engine"),
|
|
50
|
+
);
|
|
51
|
+
// Register the agent key so VerifyMode::Full resolves the trace signature.
|
|
52
|
+
let pubkey_b64 = BASE64.encode(agent_sk.verifying_key().to_bytes());
|
|
53
|
+
let now = chrono::Utc::now();
|
|
54
|
+
let record = KeyRecord {
|
|
55
|
+
key_id: KEY_ID.into(),
|
|
56
|
+
pubkey_ed25519_base64: pubkey_b64.clone(),
|
|
57
|
+
pubkey_ml_dsa_65_base64: None,
|
|
58
|
+
algorithm: algorithm::HYBRID.into(),
|
|
59
|
+
identity_type: identity_type::AGENT.into(),
|
|
60
|
+
identity_ref: KEY_ID.into(),
|
|
61
|
+
valid_from: now,
|
|
62
|
+
valid_until: None,
|
|
63
|
+
registration_envelope: serde_json::json!({ "key_id": KEY_ID }),
|
|
64
|
+
original_content_hash: "deadbeef".into(),
|
|
65
|
+
scrub_signature_classical: pubkey_b64,
|
|
66
|
+
scrub_signature_pqc: None,
|
|
67
|
+
scrub_key_id: KEY_ID.into(),
|
|
68
|
+
scrub_timestamp: now,
|
|
69
|
+
pqc_completed_at: None,
|
|
70
|
+
persist_row_hash: String::new(),
|
|
71
|
+
roles: Vec::new(),
|
|
72
|
+
attestation_evidence: None,
|
|
73
|
+
};
|
|
74
|
+
engine
|
|
75
|
+
.sqlite_backend()
|
|
76
|
+
.expect("sqlite")
|
|
77
|
+
.put_public_key(SignedKeyRecord { record })
|
|
78
|
+
.await
|
|
79
|
+
.expect("register key");
|
|
80
|
+
engine
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
fn batch_bytes(agent_sk: &SigningKey, trace_id: &str) -> Vec<u8> {
|
|
84
|
+
use ciris_persist::verify::canonical::Canonicalizer;
|
|
85
|
+
use ciris_persist::verify::{ed25519::canonical_payload_value, PythonJsonDumpsCanonicalizer};
|
|
86
|
+
let mut data = serde_json::Map::new();
|
|
87
|
+
data.insert("seq".into(), serde_json::json!(0));
|
|
88
|
+
let mut trace = CompleteTrace {
|
|
89
|
+
trace_id: trace_id.into(),
|
|
90
|
+
thought_id: trace_id.into(),
|
|
91
|
+
task_id: Some("bench".into()),
|
|
92
|
+
agent_id_hash: "cafebabe".into(),
|
|
93
|
+
started_at: "2026-06-15T00:00:00Z".parse().unwrap(),
|
|
94
|
+
completed_at: "2026-06-15T00:01:00Z".parse().unwrap(),
|
|
95
|
+
trace_level: TraceLevel::Generic,
|
|
96
|
+
trace_schema_version: SchemaVersion::parse("2.7.0").unwrap(),
|
|
97
|
+
components: vec![TraceComponent {
|
|
98
|
+
component_type: ComponentType::Conscience,
|
|
99
|
+
event_type: ReasoningEventType::ConscienceResult,
|
|
100
|
+
timestamp: "2026-06-15T00:00:00Z".parse().unwrap(),
|
|
101
|
+
data,
|
|
102
|
+
agent_id_hash: None,
|
|
103
|
+
}],
|
|
104
|
+
deployment_profile: None,
|
|
105
|
+
cohort_scope: "federation".into(),
|
|
106
|
+
cohort_target_id: None,
|
|
107
|
+
signature: String::new(),
|
|
108
|
+
signature_key_id: KEY_ID.into(),
|
|
109
|
+
};
|
|
110
|
+
let canon = PythonJsonDumpsCanonicalizer
|
|
111
|
+
.canonicalize_value(&canonical_payload_value(&trace))
|
|
112
|
+
.unwrap();
|
|
113
|
+
trace.signature = BASE64.encode(agent_sk.sign(&canon).to_bytes());
|
|
114
|
+
serde_json::json!({
|
|
115
|
+
"events": [{ "event_type": "complete_trace", "trace_level": "generic",
|
|
116
|
+
"trace": serde_json::to_value(&trace).unwrap() }],
|
|
117
|
+
"batch_timestamp": "2026-06-15T00:00:00Z",
|
|
118
|
+
"consent_timestamp": "2025-01-01T00:00:00Z",
|
|
119
|
+
"trace_level": "generic",
|
|
120
|
+
"trace_schema_version": "2.7.0",
|
|
121
|
+
})
|
|
122
|
+
.to_string()
|
|
123
|
+
.into_bytes()
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
fn bench_ingest(c: &mut Criterion) {
|
|
127
|
+
let _ = SystemTime::now(); // (no-op; keeps import honest if trimmed)
|
|
128
|
+
let agent_sk = SigningKey::from_bytes(&[0x11; 32]);
|
|
129
|
+
let runtime = rt();
|
|
130
|
+
let engine = runtime.block_on(engine_with_key(&agent_sk));
|
|
131
|
+
|
|
132
|
+
let mut g = c.benchmark_group("replication_ingest");
|
|
133
|
+
g.throughput(Throughput::Elements(1)); // one trace per iteration
|
|
134
|
+
|
|
135
|
+
// New-trace insert path (a fresh envelope from a peer) = replication speed.
|
|
136
|
+
g.bench_function("ingest_new", |b| {
|
|
137
|
+
let mut n = 0u64;
|
|
138
|
+
b.to_async(&runtime).iter_batched(
|
|
139
|
+
|| {
|
|
140
|
+
n += 1;
|
|
141
|
+
batch_bytes(&agent_sk, &format!("repl-{n:08}"))
|
|
142
|
+
},
|
|
143
|
+
|bytes| {
|
|
144
|
+
let engine = Arc::clone(&engine);
|
|
145
|
+
async move {
|
|
146
|
+
engine
|
|
147
|
+
.receive_and_persist(&bytes, &NullScrubber)
|
|
148
|
+
.await
|
|
149
|
+
.expect("ingest")
|
|
150
|
+
}
|
|
151
|
+
},
|
|
152
|
+
BatchSize::SmallInput,
|
|
153
|
+
);
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
// Re-delivery of an already-seen trace (anti gossip-loop dedup path).
|
|
157
|
+
let dup = batch_bytes(&agent_sk, "repl-dup-fixed");
|
|
158
|
+
runtime.block_on(async {
|
|
159
|
+
engine
|
|
160
|
+
.receive_and_persist(&dup, &NullScrubber)
|
|
161
|
+
.await
|
|
162
|
+
.expect("seed dup");
|
|
163
|
+
});
|
|
164
|
+
g.bench_function("ingest_dedup", |b| {
|
|
165
|
+
b.to_async(&runtime).iter(|| {
|
|
166
|
+
let engine = Arc::clone(&engine);
|
|
167
|
+
let bytes = dup.clone();
|
|
168
|
+
async move {
|
|
169
|
+
engine
|
|
170
|
+
.receive_and_persist(&bytes, &NullScrubber)
|
|
171
|
+
.await
|
|
172
|
+
.expect("dedup")
|
|
173
|
+
}
|
|
174
|
+
});
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
g.finish();
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
criterion_group!(benches, bench_ingest);
|
|
181
|
+
criterion_main!(benches);
|
|
@@ -12,7 +12,7 @@ build-backend = "maturin"
|
|
|
12
12
|
[project]
|
|
13
13
|
name = "ciris-server"
|
|
14
14
|
# Mirrors Cargo.toml; bump in lockstep.
|
|
15
|
-
version = "0.
|
|
15
|
+
version = "0.2.0" # matches the Cargo crate. 0.1 = lens-only; patch forward (0.1.1) on breakage
|
|
16
16
|
description = "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."
|
|
17
17
|
authors = [{ name = "Eric Moore", email = "eric@ciris.ai" }]
|
|
18
18
|
license = { text = "AGPL-3.0-or-later" }
|