From c36cb6bcf6b0545f8d0b646b8ac16ff86217ca74 Mon Sep 17 00:00:00 2001 From: forkwright Date: Fri, 21 Aug 2026 11:25:28 -0500 Subject: [PATCH 1/2] refactor(lint): point each dead-code suppression at the issue that ends it MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Every suppression carried a tracking ref, which satisfied the letter of `WORKFLOW/unwired-dead-code-untracked`, but each named a direction rather than a consumer: "await daemon integration", "staged for the akroasis hardware backend". Nothing can ever contradict a reason like that, so the suppression can sit accurate and permanent at the same time — which is the condition the rule exists to surface, not a state it should be able to reach. Each reason now names the issue whose landing makes the suppression provably wrong: - mesh status/node tables need a live `NodeDb` and `GatewayBridge`; the CLI has neither and says so in three explicit constants. #83 supplies them. - the baofeng protocol constants and variant API are consumed only by the `hardware-serial` protocol module, which #79 qualifies. - the hardware warning helpers have no constructor anywhere outside their own file, while the detect path already runs without surfacing them. #410 owns the caller-initiated detect surface where they belong. - the `Config` struct is not staged work at all. It is loaded and discarded, so the surface aborts unrelated commands while its one key does nothing; that is #461. The mapping was derived by reading each consumer rather than by matching issue titles, and every named helper was confirmed to still have zero references outside its defining file. --- crates/akroasis/src/main.rs | 4 ++-- crates/syntonia/src/baofeng/constants.rs | 2 +- crates/syntonia/src/baofeng/variant.rs | 2 +- crates/syntonia/src/hardware/warnings.rs | 6 +++--- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/crates/akroasis/src/main.rs b/crates/akroasis/src/main.rs index f0c9ca2..76945de 100644 --- a/crates/akroasis/src/main.rs +++ b/crates/akroasis/src/main.rs @@ -8,7 +8,7 @@ mod cli; not(test), expect( dead_code, - reason = "mesh table/status helpers await daemon integration, tracked in #264" + reason = "mesh status/node tables need a live NodeDb and GatewayBridge, which #83 supplies" ) )] mod mesh; @@ -60,7 +60,7 @@ enum Error { #[serde(deny_unknown_fields)] #[expect( dead_code, - reason = "config fields reserved for future CLI options, tracked in #264" + reason = "config is loaded and discarded; the surface is resolved by #461" )] struct Config { /// Path to the configuration file (default: `~/.config/akroasis/config.toml`). diff --git a/crates/syntonia/src/baofeng/constants.rs b/crates/syntonia/src/baofeng/constants.rs index c086042..d88547e 100644 --- a/crates/syntonia/src/baofeng/constants.rs +++ b/crates/syntonia/src/baofeng/constants.rs @@ -9,7 +9,7 @@ not(feature = "hardware-serial"), expect( dead_code, - reason = "protocol constants used only with hardware-serial feature, tracked in #264" + reason = "protocol constants are consumed only by the hardware-serial protocol module, qualified by #79" ) )] diff --git a/crates/syntonia/src/baofeng/variant.rs b/crates/syntonia/src/baofeng/variant.rs index c76e46a..1c99490 100644 --- a/crates/syntonia/src/baofeng/variant.rs +++ b/crates/syntonia/src/baofeng/variant.rs @@ -6,7 +6,7 @@ not(feature = "hardware-serial"), expect( dead_code, - reason = "variant API used only with hardware-serial feature, tracked in #264" + reason = "variant API is consumed only by the hardware-serial protocol module, qualified by #79" ) )] diff --git a/crates/syntonia/src/hardware/warnings.rs b/crates/syntonia/src/hardware/warnings.rs index 800bf8c..a1aaf7a 100644 --- a/crates/syntonia/src/hardware/warnings.rs +++ b/crates/syntonia/src/hardware/warnings.rs @@ -67,7 +67,7 @@ impl fmt::Display for HardwareWarning { not(test), expect( dead_code, - reason = "crate-local warning helpers are staged for the akroasis hardware backend, tracked in #264" + reason = "warnings have no constructor until the caller-initiated detect path in #410 surfaces them" ) )] pub(crate) fn collect_scan_warnings(cables: &[UsbCable]) -> Vec { @@ -95,7 +95,7 @@ pub(crate) fn collect_scan_warnings(cables: &[UsbCable]) -> Vec not(test), expect( dead_code, - reason = "crate-local warning helpers are staged for the akroasis hardware backend, tracked in #264" + reason = "warnings have no constructor until the caller-initiated detect path in #410 surfaces them" ) )] pub(crate) fn collect_detection_warnings(detected: &[DetectedRadio]) -> Vec { @@ -114,7 +114,7 @@ pub(crate) fn collect_detection_warnings(detected: &[DetectedRadio]) -> Vec HardwareWarning { From f4284c2d441c2c3491b9a31990f0c22773c6a873 Mon Sep 17 00:00:00 2001 From: forkwright Date: Fri, 21 Aug 2026 11:37:07 -0500 Subject: [PATCH 2/2] docs(koinon): finish the split the rename left half-done MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Renaming the crate moved the code but left every description of it behind, so the repo documented a `koinon` crate that no longer exists: the README domain map and architecture diagram, CLAUDE.md and AGENTS.md, `docs/ARCHITECTURE.md`, the lexicon, both `_llm` corpora, and fourteen comments still explaining which crate owned what. A reader following any of them landed on nothing. The README and lexicon now carry both halves with their own etymologies rather than one entry rewritten in place, because the split was a division of concepts and a single renamed row would have hidden that. Three things were stale in a way a search for the old name would not have surfaced on its own: - `fuzz/Cargo.lock` still resolved `koinon` at 0.5.0. The fuzz workspace is detached, so nothing in the main workspace's resolution reaches it and it had been two releases behind before this rename touched it. - `crates/stoicheion/.kanon-lint-ignore` suppressed `RUST/pub-visibility` for a gap that no longer exists. Measured both ways: 38 bare `pub` items across the crate's non-lib files, and the rule reports nothing repo-wide with the ignore removed. A suppression that suppresses nothing states something untrue about the code and would silently absorb a real violation later. - `.kanon-lint-baseline.toml` still carried the two `koinon` collision entries its own reason described as "deferred to a fleet naming decision" — the decision this rename made. `storage.rs` also stopped indexing to build a slice. `&public_key_bytes()[..]` tripped `RUST/indexing-slicing`, which clippy cannot catch here because `indexing_slicing` is allow-by-default restriction; `.as_slice()` says the same thing without an index expression. --- .cargo/audit.toml | 2 +- .kanon-lint-baseline.toml | 14 +- AGENTS.md | 4 +- CLAUDE.md | 4 +- README.md | 7 +- _llm/architecture.toml | 11 +- _llm/decisions.toml | 4 +- _llm/glossary.toml | 9 +- crates/akroasis/src/caller.rs | 2 +- crates/kryphos/src/storage.rs | 11 +- crates/kryphos/tests/tamper_log_signing.rs | 4 +- crates/kryphos/tests/vault_tamper_audit.rs | 2 +- crates/semaino/src/aggregator.rs | 4 +- crates/stoicheion/.kanon-lint-ignore | 13 -- .../src/tamper_log_recovery_tests.rs | 2 +- crates/tekmerion/src/tamper_log_seal.rs | 2 +- deny.toml | 2 +- docs/ARCHITECTURE.md | 5 +- docs/lexicon.md | 3 +- fuzz/Cargo.lock | 178 ++---------------- 20 files changed, 60 insertions(+), 223 deletions(-) delete mode 100644 crates/stoicheion/.kanon-lint-ignore diff --git a/.cargo/audit.toml b/.cargo/audit.toml index 5bea178..4d64dfd 100644 --- a/.cargo/audit.toml +++ b/.cargo/audit.toml @@ -13,7 +13,7 @@ ignore = [ # rand 0.9.2 unsound only when a custom logger re-enters rand::rng(); # akroasis uses tracing-subscriber with no custom logger that calls # into rand, so the condition is unreachable. Pulled in transitively - # via ulid 1.2.1 (semaino/koinon/syntonia/kryphos/kerykeion) and + # via ulid 1.2.1 (semaino/stoicheion/syntonia/kryphos/kerykeion) and # proptest 1.11.0 (dev-only). "RUSTSEC-2026-0097", ] diff --git a/.kanon-lint-baseline.toml b/.kanon-lint-baseline.toml index d83af68..bf7401e 100644 --- a/.kanon-lint-baseline.toml +++ b/.kanon-lint-baseline.toml @@ -1,7 +1,7 @@ [baseline] created = "2026-08-03" remove_after = "2026-11-01" -reason = "akroasis#261 lint-debt burn-down — errors first (vault plain-string-secret, kerykeion crypto indexing), both resolved. Remaining entries are deliberate exceptions, not deferred mechanical work: RUST/no-arc-mutex-anti-pattern (kerykeion/collector.rs) already uses tokio::sync::Mutex — the rule's own recommended async-safe primitive; converting further to RwLock needs a per-callsite read/write classification across 5 files, an architecture change outside a lint-driven edit. VOCAB/crate-name-collision + NAMING/no-fleet-collision (koinon) are a cross-repo naming call deferred to a fleet naming decision (akroasis#264). NAMING/no-owner-prefix (akroasis-server) needs a GNOMON-reviewed rename, an identity decision outside a mechanical fix. ARCH/substrate-dead-dep (sphragis) is a deliberately staged dependency awaiting the pinax reference-store integration and a cryptographic review (akroasis#172). TOML/missing-trailing-comma (.gitleaks.toml), RUST/doc-promised-observability (delivery.rs), CI/release-yml-missing-attestation (release-please.yml builds no artifacts to attest — release.yml already attests), and RUST/plain-string-secret (ListEntryReport.credential_type, a JSON category label not a secret) are confirmed lint-rule false positives. YAML/missing-concurrency (gate-attestation.yml, added #262) is the same class: the file deliberately carries NO caller-level concurrency block because forkwright/.github/.github/workflows/hybrid-gate.yml already declares one and its own comment states a caller-level duplicate self-cancels the shared group — sphragis's gate-attestation.yml (the reusable workflow's other adopter) carries the identical no-block shape for the identical reason. Entries clear only when the rule is fixed upstream or the cited decision resolves." +reason = "akroasis#261 lint-debt burn-down — errors first (vault plain-string-secret, kerykeion crypto indexing), both resolved. Remaining entries are deliberate exceptions, not deferred mechanical work: RUST/no-arc-mutex-anti-pattern (kerykeion/collector.rs) already uses tokio::sync::Mutex — the rule's own recommended async-safe primitive; converting further to RwLock needs a per-callsite read/write classification across 5 files, an architecture change outside a lint-driven edit. NAMING/no-owner-prefix (akroasis-server) needs a GNOMON-reviewed rename, an identity decision outside a mechanical fix. ARCH/substrate-dead-dep (sphragis) is a deliberately staged dependency awaiting the pinax reference-store integration and a cryptographic review (akroasis#172). TOML/missing-trailing-comma (.gitleaks.toml), RUST/doc-promised-observability (delivery.rs), CI/release-yml-missing-attestation (release-please.yml builds no artifacts to attest — release.yml already attests), and RUST/plain-string-secret (ListEntryReport.credential_type, a JSON category label not a secret) are confirmed lint-rule false positives. YAML/missing-concurrency (gate-attestation.yml, added #262) is the same class: the file deliberately carries NO caller-level concurrency block because forkwright/.github/.github/workflows/hybrid-gate.yml already declares one and its own comment states a caller-level duplicate self-cancels the shared group — sphragis's gate-attestation.yml (the reusable workflow's other adopter) carries the identical no-block shape for the identical reason. Entries clear only when the rule is fixed upstream or the cited decision resolves." [[baseline.entry]] rule = "ARCH/substrate-dead-dep" @@ -15,12 +15,6 @@ file = ".github/workflows/release-please.yml" line = 1 hash = "b525087c2878d94b7bcb773fc6795d4e90b36c64bb32ad2ec421a37935890fb1" -[[baseline.entry]] -rule = "NAMING/no-fleet-collision" -file = "crates/koinon/Cargo.toml" -line = 1 -hash = "70acf00586aa7b90c3866278505be7b81fb7ee1f7e21c17c1a22ac239be3c72a" - [[baseline.entry]] rule = "NAMING/no-owner-prefix" file = "crates/akroasis-server/Cargo.toml" @@ -147,12 +141,6 @@ file = ".gitleaks.toml" line = 40 hash = "725011530d3abd84a570798b9d272d44d36de3c2a2fac6d6b2e0eda8aeba371b" -[[baseline.entry]] -rule = "VOCAB/crate-name-collision" -file = "crates/koinon/Cargo.toml" -line = 1 -hash = "70acf00586aa7b90c3866278505be7b81fb7ee1f7e21c17c1a22ac239be3c72a" - [[baseline.entry]] rule = "YAML/missing-concurrency" file = ".github/workflows/gate-attestation.yml" diff --git a/AGENTS.md b/AGENTS.md index dc958ce..8d54509 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -29,7 +29,7 @@ Communications sovereignty and RF intelligence platform. Rust workspace, single ## Architecture -- Foundation: `koinon` (shared types, signal model), `kryphos` (crypto, identity) +- Foundation: `stoicheion` (vocabulary: shared types, signal model), `tekmerion` (evidence: callers, receipts, tamper log), `kryphos` (crypto, identity) - Collection crates produce typed `GeoSignal` into the shared pipeline - add a domain, add a crate, signals flow automatically - Async: tokio, native async traits - Mesh: clean-room Meshtastic stack via `prost` protobuf - not the official `meshtastic` crate (GPL-3, ~15% coverage) @@ -37,7 +37,7 @@ Communications sovereignty and RF intelligence platform. Rust workspace, single ## Where to add things - New crate: `crates//`, register in root `Cargo.toml` members, follow `~/dev/kanon/crates/basanos/standards/GNOMON.md` for naming, add entry to `docs/lexicon.md` -- New signal type: extend `GeoSignal` enum in `koinon`; downstream crates match exhaustively +- New signal type: extend `GeoSignal` enum in `stoicheion`; downstream crates match exhaustively - New standard or convention: propose it in `~/dev/kanon/crates/basanos/standards/`; cross-link from this repo's `standards/README.md` ## Boundaries diff --git a/CLAUDE.md b/CLAUDE.md index dba77d9..a430469 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -1,5 +1,5 @@ @@ -17,7 +17,7 @@ Writing: `~/dev/kanon/crates/basanos/standards/WRITING.md` ## Structure -Foundation layer: `koinon` (shared types, signal model), `kryphos` (encryption, identity). See README.md for the full domain map with status markers and `docs/ARCHITECTURE.md` for layer structure. +Foundation layer: `stoicheion` (the vocabulary: shared types, signal model), `tekmerion` (evidence: callers, effect receipts, tamper log), `kryphos` (encryption, identity). See README.md for the full domain map with status markers and `docs/ARCHITECTURE.md` for layer structure. ## Commands diff --git a/README.md b/README.md index 2062773..922f797 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,8 @@ Capability domains span radio, mesh, SDR, proximity, network defense, OSINT, off | Domain | Crate | Crate Shipped | Hardware Backend | What | |--------|-------|:-------------:|:----------------:|------| | **Application shell** | akroasis, akroasis-server | ✓ | △ | CLI binary + typed axum library routes. No server binary or desktop ships yet. Radio uses `StubHardware` by default; opt-in `hardware-serial` enables Baofeng detect/read/program/export sessions. Mesh CLI is static/no-live-connection until daemon mode is implemented. | -| **Foundation** | koinon | ✓ | - | Shared IDs, coordinates, frequency and power types, 7-domain `GeoSignal` model, hardware asset registry, temporal baselines, and tamper-evident logging. | +| **Foundation** | stoicheion | ✓ | - | The workspace vocabulary: shared IDs, coordinates, frequency and power types, 7-domain `GeoSignal` model, hardware asset registry, and temporal baselines. | +| **Foundation** | tekmerion | ✓ | - | Evidence about what was done: validated callers and authority, effect receipts, and the tamper-evident log that attests to them. | | **Foundation** | kryphos | ✓ | - | Credential vault and installation identity: fjall-backed encrypted storage, Argon2id derivation, ChaCha20-Poly1305 encryption, Ed25519 signing keys, rotation/revocation metadata, and mutation audit logging at `tamper.log` beside the vault store. | | **Radio Management** | syntonia | ✓ | △ | Frequency plans, CHIRP CSV/IMG import, CHIRP CSV export, validation, USB detection metadata, and Baofeng UV-5R-family codec. With `akroasis/hardware-serial`, live Baofeng serial detect/read/program/export sessions ship; real-device verification and Yaesu protocol sessions remain incomplete. | | **Mesh Networking** | kerykeion | ✓ | △ | Meshtastic protocol stack implemented in this repository: protobuf framing, serial/TCP transports, handshake, encryption, node database, topology, discovery, routing, delivery tracking, store-and-forward, gateway bridge, and signal conversion. Real-device wire fixtures and live application wiring remain open. | @@ -55,7 +56,7 @@ Capability domains span radio, mesh, SDR, proximity, network defense, OSINT, off └────────┬─────────┘ │ (correlation, │ └──────┬──────┘ │ │ focal points, │ │ ┌────────▼─────────┐ │ threat scoring) │ ┌──────▼──────┐ - │ koinon │ └──────────────────┘ │ opsis │ + │ stoicheion │ └──────────────────┘ │ opsis │ │ (signal model, │ │ (operator │ │ entity types, │ ┌──────────────────┐ │ surfaces) │ │ temporal engine)│ │ chorografia │ └─────────────┘ @@ -70,7 +71,7 @@ Capability domains span radio, mesh, SDR, proximity, network defense, OSINT, off └──────────────────┘ ``` -Every collection crate is expected to produce typed `GeoSignal` objects defined by koinon. Kerykeion implements mesh-to-signal conversion, while semaino provides domain-agnostic aggregation and synthetic coverage for the seven-domain signal model; neither is wired into a live application pipeline yet. Ichneutes, Praxis, and Opsis remain architectural targets. Add a domain, add a crate, then explicitly wire and verify the collector-to-processing path. +Every collection crate is expected to produce typed `GeoSignal` objects defined by stoicheion. Kerykeion implements mesh-to-signal conversion, while semaino provides domain-agnostic aggregation and synthetic coverage for the seven-domain signal model; neither is wired into a live application pipeline yet. Ichneutes, Praxis, and Opsis remain architectural targets. Add a domain, add a crate, then explicitly wire and verify the collector-to-processing path. --- diff --git a/_llm/architecture.toml b/_llm/architecture.toml index ccd2423..2e2ccb8 100644 --- a/_llm/architecture.toml +++ b/_llm/architecture.toml @@ -29,9 +29,14 @@ path = "crates/akroasis" role = "Single binary shell with CLI dispatch for shipped and future domain stubs." [[architecture.crates]] -name = "koinon" -path = "crates/koinon" -role = "Shared IDs, coordinates, frequency/power types, GeoSignal model, hardware registry, baselines, and tamper log." +name = "stoicheion" +path = "crates/stoicheion" +role = "The workspace vocabulary: shared IDs, coordinates, frequency/power types, GeoSignal model, hardware registry, and baselines." + +[[architecture.crates]] +name = "tekmerion" +path = "crates/tekmerion" +role = "Evidence: validated callers and authority, effect receipts, and the tamper-evident log." [[architecture.crates]] name = "kryphos" diff --git a/_llm/decisions.toml b/_llm/decisions.toml index c5b82e8..024705a 100644 --- a/_llm/decisions.toml +++ b/_llm/decisions.toml @@ -16,7 +16,7 @@ id = "D-one-signal-model" title = "Unify domains through typed signals" status = "accepted" context = "Radio, mesh, network, proximity, OSINT, and field operations otherwise fragment into separate tools." -decision = "Every domain emits typed GeoSignal objects into shared koinon/semaino models." +decision = "Every domain emits typed GeoSignal objects into shared stoicheion/semaino models." consequences = "Correlation and convergence are domain-agnostic." [[decision]] @@ -40,7 +40,7 @@ id = "D-collector-trait" title = "Hardware-facing crates implement Collector" status = "accepted" context = "Hardware domains vary but need a common integration shape." -decision = "Define hardware abstraction through the Collector trait in koinon." +decision = "Define hardware abstraction through the Collector trait in stoicheion." consequences = "Hardware tests can use mocks and recorded replay." [[decision]] diff --git a/_llm/glossary.toml b/_llm/glossary.toml index 8094828..84a6ce0 100644 --- a/_llm/glossary.toml +++ b/_llm/glossary.toml @@ -22,8 +22,13 @@ definition = "Typed signal object carrying domain, location, temporal, and sever canonical = true [[terms]] -term = "koinon" -definition = "Shared foundation crate for IDs, signal types, baselines, hardware registry, and tamper log." +term = "stoicheion" +definition = "στοιχεῖον — element. The workspace vocabulary: shared IDs, signal types, baselines, and the hardware registry." +canonical = true + +[[terms]] +term = "tekmerion" +definition = "τεκμήριον — proof. Evidence about what was done: callers, effect receipts, and the tamper-evident log." canonical = true [[terms]] diff --git a/crates/akroasis/src/caller.rs b/crates/akroasis/src/caller.rs index ebed9a0..9aaac0f 100644 --- a/crates/akroasis/src/caller.rs +++ b/crates/akroasis/src/caller.rs @@ -1,7 +1,7 @@ //! Application caller resolution and audit-before-effect execution. //! //! This module adapts authenticated transport evidence into the shared -//! `koinon` contract. It owns no credential store and does not implement any +//! `tekmerion` contract. It owns no credential store and does not implement any //! domain-specific effect or policy. use std::fmt; diff --git a/crates/kryphos/src/storage.rs b/crates/kryphos/src/storage.rs index 1123749..125cf45 100644 --- a/crates/kryphos/src/storage.rs +++ b/crates/kryphos/src/storage.rs @@ -598,7 +598,8 @@ impl Vault { // `installation_public_key` while every signature verified against a // different key entirely, which is the substitution this identity // exists to make detectable. - if header.installation_public_key.as_deref() != Some(&identity.public_key_bytes()[..]) { + if header.installation_public_key.as_deref() != Some(identity.public_key_bytes().as_slice()) + { return Err(VaultError::InvalidHeader { reason: String::from( "installation_public_key does not match the sealed signing key", @@ -1010,7 +1011,7 @@ impl Vault { /// /// WHY the vault answers this rather than the caller reaching for /// `tekmerion::verify_tip_provenance` directly: the vault is what knows - /// whether an identity is *expected*. koinon can report that a log is + /// whether an identity is *expected*. tekmerion can report that a log is /// unsigned; only the header says whether that is a vault which never had /// an identity or one whose signing has been stripped. /// @@ -1029,7 +1030,7 @@ impl Vault { /// header errors of [`Self::installation_identity`]. pub fn verify_tamper_log_provenance(&self) -> Result { let Some(identity) = self.installation_identity()? else { - // No identity to check against; koinon reports the log's own state. + // No identity to check against; tekmerion reports the log's own state. return tekmerion::verify_tip_provenance( self.tamper_log_path(), &self.chain_key(), @@ -1182,10 +1183,10 @@ impl Vault { // INVARIANT: `log` must drop before `_guard` — Rust drops function // locals in reverse declaration order, so declaring `_guard` first - // guarantees `log`'s koinon-level OS advisory lock (`TamperLog`'s + // guarantees `log`'s tekmerion-level OS advisory lock (`TamperLog`'s // `_lock` field) is released before this mutex is, so a thread that // was waiting on `_guard` never sees a spurious `TamperLogError:: - // Locked` from koinon's own (fail-fast, non-blocking) lock. + // Locked` from tekmerion's own (fail-fast, non-blocking) lock. // WHY the identity is resolved per append rather than cached on the // handle: the sealed signing key lives in the header, and reading it // here keeps the plaintext key alive only for the append that uses it diff --git a/crates/kryphos/tests/tamper_log_signing.rs b/crates/kryphos/tests/tamper_log_signing.rs index 24eeaaf..ab423c9 100644 --- a/crates/kryphos/tests/tamper_log_signing.rs +++ b/crates/kryphos/tests/tamper_log_signing.rs @@ -85,7 +85,7 @@ fn a_substituted_signature_does_not_verify() { // The seal's MAC covers the signature field, so the edit is caught there // and the signature check never runs. That is the correct outer defence and // the honest thing for this test to assert — it does NOT cover - // `check_tip`'s signature arm, which koinon's own unit tests exercise + // `check_tip`'s signature arm, which tekmerion's own unit tests exercise // directly with a valid MAC over a bad signature. assert_eq!( status.unwrap(), @@ -121,7 +121,7 @@ fn a_substituted_key_id_does_not_verify() { .verify_tamper_log_provenance(); // As above: the MAC covers the key id too, so this is refused before the - // signature is examined. koinon's unit tests cover the case where the MAC + // signature is examined. tekmerion's unit tests cover the case where the MAC // is valid and the key id names a different installation. assert_eq!( status.unwrap(), diff --git a/crates/kryphos/tests/vault_tamper_audit.rs b/crates/kryphos/tests/vault_tamper_audit.rs index 7e0d322..e55918a 100644 --- a/crates/kryphos/tests/vault_tamper_audit.rs +++ b/crates/kryphos/tests/vault_tamper_audit.rs @@ -241,7 +241,7 @@ fn concurrent_vault_mutations_produce_a_single_non_forked_chain() { // sharing this `Arc` could both recover the same tail and each // append an entry chained from it, forking the chain (`verify_chain` // reports `Broken`) or losing one writer's entry outright. The - // in-process mutex in `append_vault_audit` plus koinon's own + // in-process mutex in `append_vault_audit` plus tekmerion's own // single-writer lock must make every mutation land, in some order, as // one strictly-serial, verifiable chain. const WRITERS: usize = 8; diff --git a/crates/semaino/src/aggregator.rs b/crates/semaino/src/aggregator.rs index a5955ca..e878a85 100644 --- a/crates/semaino/src/aggregator.rs +++ b/crates/semaino/src/aggregator.rs @@ -73,7 +73,7 @@ impl KindKey { SignalKind::Proximity(_) => Self::Proximity, SignalKind::Gps(_) => Self::Gps, SignalKind::Environmental(_) => Self::Environmental, - // WHY: SignalKind is #[non_exhaustive] in koinon; the wildcard arm + // WHY: SignalKind is #[non_exhaustive] in stoicheion; the wildcard arm // handles Osint and any future variants without triggering // unreachable_patterns. Grouping unknowns with Osint keeps the // baseline discriminant stable. @@ -241,7 +241,7 @@ pub(crate) fn day_hour_from_timestamp(ts: &stoicheion::Timestamp) -> (u8, u8) { return (0, 0); }; let dt = zoned.datetime(); - // WHY: jiff Weekday is 1-indexed (Mon=1..Sun=7); subtract 1 to match koinon's 0-indexed layout. + // WHY: jiff Weekday is 1-indexed (Mon=1..Sun=7); subtract 1 to match stoicheion's 0-indexed layout. let day = match dt.weekday() { Weekday::Monday => 0u8, Weekday::Tuesday => 1, diff --git a/crates/stoicheion/.kanon-lint-ignore b/crates/stoicheion/.kanon-lint-ignore deleted file mode 100644 index 4904720..0000000 --- a/crates/stoicheion/.kanon-lint-ignore +++ /dev/null @@ -1,13 +0,0 @@ -# Rules to skip for specific paths in this crate. -# Format: RULE/name:path/glob — gitignore-style glob relative to crate root. -# Every entry requires a WHY: comment. No blanket category ignores. - -# WHY: koinon provides the shared domain types (Frequency, SignalKind, -# Timestamp, Baseline, TamperLog, etc.) re-exported via lib.rs `pub use` -# and consumed across the workspace. Item-definition files (baseline.rs, -# frequency.rs, …) must expose `pub` for those re-exports to compile -# (Rust E0365). Methods on those re-exported types form part of the -# public API surface. The RUST/pub-visibility rule exempts lib.rs/mod.rs -# but does not follow `pub use` chains into the defining files; this -# scoped ignore bridges that gap. -RUST/pub-visibility:src/** diff --git a/crates/tekmerion/src/tamper_log_recovery_tests.rs b/crates/tekmerion/src/tamper_log_recovery_tests.rs index f34daa5..7bbb4ad 100644 --- a/crates/tekmerion/src/tamper_log_recovery_tests.rs +++ b/crates/tekmerion/src/tamper_log_recovery_tests.rs @@ -292,7 +292,7 @@ fn a_seal_destroyed_by_a_failed_rename_stays_fail_closed() { let reopened = TamperLog::open(&path, test_key()); // WHY not `{reopened:?}`: `TamperLog` intentionally has no `Debug` - // impl (it holds the `ChainKey`; koinon follows + // impl (it holds the `ChainKey`; tekmerion follows // RUST/no-debug-derive-on-public-types), so format the outcome without // naming the Ok payload. let got = match &reopened { diff --git a/crates/tekmerion/src/tamper_log_seal.rs b/crates/tekmerion/src/tamper_log_seal.rs index 9446f7f..e5bd24e 100644 --- a/crates/tekmerion/src/tamper_log_seal.rs +++ b/crates/tekmerion/src/tamper_log_seal.rs @@ -152,7 +152,7 @@ pub(super) fn genesis_hash(chain_key: &ChainKey) -> [u8; 32] { /// Signs a tamper log's terminal hash on behalf of an installation. /// -/// WHY a trait here rather than a concrete key type: koinon owns the chain and +/// WHY a trait here rather than a concrete key type: tekmerion owns the chain and /// its keyed hashing, not the fleet's choice of signature scheme. The identity /// layer lives in `kryphos`, which depends on this crate — so a concrete /// Ed25519 type in this signature would invert that dependency. Implementors diff --git a/deny.toml b/deny.toml index 01c652a..13ade07 100644 --- a/deny.toml +++ b/deny.toml @@ -13,7 +13,7 @@ reason = "number_prefix unmaintained, transitive via indicatif; no safe upgrade [[advisories.ignore]] id = "RUSTSEC-2026-0097" -reason = "rand 0.9.2 unsound only when a custom logger re-enters rand::rng(); akroasis uses tracing-subscriber with no custom logger that calls into rand, so the condition is unreachable. Pulled in transitively via ulid 1.2.1 (semaino/koinon/syntonia/kryphos/kerykeion) and proptest 1.11.0 (dev-only)." +reason = "rand 0.9.2 unsound only when a custom logger re-enters rand::rng(); akroasis uses tracing-subscriber with no custom logger that calls into rand, so the condition is unreachable. Pulled in transitively via ulid 1.2.1 (semaino/stoicheion/syntonia/kryphos/kerykeion) and proptest 1.11.0 (dev-only)." [licenses] # WHY: AGPL-3.0-only is the workspace license itself (declared in diff --git a/docs/ARCHITECTURE.md b/docs/ARCHITECTURE.md index 8487624..a49f5de 100644 --- a/docs/ARCHITECTURE.md +++ b/docs/ARCHITECTURE.md @@ -11,14 +11,15 @@ Interface: opsis (desktop-first via theatron); akroasis-server (axum HTTP/S Orchestration: praxis (automation, playbooks, PACE) Analysis: semaino (aggregation), ichneutes (correlation) Collection: syntonia, kerykeion, dektis, engys, aspis, skopos, peira -Foundation: koinon (shared types), kryphos (encryption), lethe (privacy) +Foundation: stoicheion (vocabulary), tekmerion (evidence), kryphos (encryption), lethe (privacy) ``` ## Crate registry | Crate | Layer | Purpose | |-------|-------|---------| -| **koinon** | Foundation | Shared types, signal model, entity index, temporal baseline engine, tamper-evident logging | +| **stoicheion** | Foundation | Shared types, signal model, entity index, temporal baseline engine | +| **tekmerion** | Foundation | Validated callers and authority, effect receipts, tamper-evident logging | | **kryphos** | Foundation | Encryption, key management, forward secrecy, credential vault, identity management | | **lethe** | Foundation | Privacy infrastructure, VPN, anonymization, OPSEC scoring | | **syntonia** | Collection | Radio management, frequency plans, serial protocols, hardware programming | diff --git a/docs/lexicon.md b/docs/lexicon.md index ab76200..dab1cf9 100644 --- a/docs/lexicon.md +++ b/docs/lexicon.md @@ -26,7 +26,8 @@ | Crate | Greek | Over | L3 Essential Nature | |-------|-------|------|---------------------| -| **koinon** | κοινόν | "common/shared" | The commons - shared types, signal model, entity index, temporal engine, geographic primitives, hardware asset registry, simulation framework, tamper-evident logging. What belongs to everyone. The koinon was the federation - the shared structure that made cooperation between independent cities possible. | +| **stoicheion** | στοιχεῖον | "element" | The elements - shared types, signal model, entity index, temporal engine, geographic primitives, hardware asset registry. The letters of the alphabet and the primary constituents of matter bore the same name: what everything else is composed of and stated in, carrying no argument of its own. | +| **tekmerion** | τεκμήριον | "proof" | The evidence - validated callers and authority, effect receipts, tamper-evident logging. In Attic legal usage a τεκμήριον was conclusive proof, distinguished from σημεῖον, a mere sign: not what suggests a conclusion but what establishes it. What the system can still assert about its own past. | | **kryphos** | κρύφος | "crypto/identity" | The hidden - encryption, key management, forward secrecy, credential vault, identity/persona management, callsign compliance. That which is kryphos resists discovery by nature. | | **lethe** | λήθη | "privacy" | Forgetting - VPN/proxy management, anonymization, metadata scrubbing, counter-surveillance, OPSEC scoring, IMSI catcher detection. The river that makes what passes through it unseen. Etymological complement to Aletheia: ἀ-λήθεια negates λήθη. Same root, opposite directions. Strongest topological pairing in the ecosystem. | diff --git a/fuzz/Cargo.lock b/fuzz/Cargo.lock index 732a512..9a835ad 100644 --- a/fuzz/Cargo.lock +++ b/fuzz/Cargo.lock @@ -34,12 +34,6 @@ version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c3d036a3c4ab069c7b410a2ce876bd74808d2d0888a82667669f8e783a898bf1" -[[package]] -name = "arrayvec" -version = "0.7.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3fb67a6e08acf24fdeccbac2cb6ac4305825bd1f117462e0e6f2f193345ad56" - [[package]] name = "bitflags" version = "1.3.2" @@ -52,19 +46,6 @@ version = "2.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b588b76d00fde79687d7646a9b5bdf3cc0f655e0bbd080335a95d7e96f3587da" -[[package]] -name = "blake3" -version = "1.8.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d9e454fc11f76977dc803893aff6304ed33d6a26efae8696573bea74baa27ae" -dependencies = [ - "arrayvec", - "cc", - "cfg-if", - "constant_time_eq", - "cpufeatures", -] - [[package]] name = "block-buffer" version = "0.12.1" @@ -130,33 +111,6 @@ dependencies = [ "rand_core 0.10.1", ] -[[package]] -name = "ciborium" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42e69ffd6f0917f5c029256a24d0161db17cea3997d185db0d35926308770f0e" -dependencies = [ - "ciborium-io", - "ciborium-ll", - "serde", -] - -[[package]] -name = "ciborium-io" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05afea1e0a06c9be33d539b876f1ce3692f4afea2cb41f740e7743225ed1c757" - -[[package]] -name = "ciborium-ll" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57663b653d948a338bfb3eeba9bb2fd5fcfaecb9e199e87e1eda4d9e8b240fd9" -dependencies = [ - "ciborium-io", - "half", -] - [[package]] name = "cipher" version = "0.5.2" @@ -182,12 +136,6 @@ dependencies = [ "zmij", ] -[[package]] -name = "constant_time_eq" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d52eff69cd5e647efe296129160853a42795992097e8af39800e1060caeea9b" - [[package]] name = "core-foundation" version = "0.10.1" @@ -219,12 +167,6 @@ dependencies = [ "libc", ] -[[package]] -name = "crunchy" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5" - [[package]] name = "crypto-common" version = "0.2.2" @@ -320,16 +262,6 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" -[[package]] -name = "fs2" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9564fc758e15025b46aa6643b1b77d047d1a56a1aea6e01002ac0c7026876213" -dependencies = [ - "libc", - "winapi", -] - [[package]] name = "futures" version = "0.3.34" @@ -441,17 +373,6 @@ dependencies = [ "rand_core 0.10.1", ] -[[package]] -name = "half" -version = "2.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ea2d84b969582b4b1864a92dc5d27cd2b77b622a8d79306834f1be5ba20d84b" -dependencies = [ - "cfg-if", - "crunchy", - "zerocopy", -] - [[package]] name = "hashbrown" version = "0.15.5" @@ -602,14 +523,13 @@ dependencies = [ [[package]] name = "kerykeion" -version = "0.5.0" +version = "0.6.1" dependencies = [ "aes", "bytes", "ctr", "futures", "jiff", - "koinon", "petgraph", "prost", "prost-build", @@ -617,6 +537,7 @@ dependencies = [ "serde", "serde_json", "snafu", + "stoicheion", "tokio", "tokio-serial", "tokio-util", @@ -635,24 +556,6 @@ dependencies = [ "tokio-util", ] -[[package]] -name = "koinon" -version = "0.5.0" -dependencies = [ - "blake3", - "ciborium", - "compact_str", - "fs2", - "jiff", - "serde", - "serde_json", - "snafu", - "subtle", - "tracing", - "ulid", - "zeroize", -] - [[package]] name = "libc" version = "0.2.189" @@ -1132,10 +1035,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" [[package]] -name = "subtle" -version = "2.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" +name = "stoicheion" +version = "0.6.1" +dependencies = [ + "compact_str", + "jiff", + "serde", + "serde_json", + "snafu", + "tracing", + "ulid", +] [[package]] name = "syn" @@ -1411,28 +1321,6 @@ dependencies = [ "wasm-bindgen", ] -[[package]] -name = "winapi" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" -dependencies = [ - "winapi-i686-pc-windows-gnu", - "winapi-x86_64-pc-windows-gnu", -] - -[[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" - -[[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" - [[package]] name = "windows-link" version = "0.2.1" @@ -1527,46 +1415,6 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "23b97319f7b8343df12cc98938e5c3eb436064524c8d2b4e30a1d3a36eecdf81" -[[package]] -name = "zerocopy" -version = "0.8.56" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "556764e583adb45a9f8d413c2a147fa7e8d821e48e12b14fd560b607998b75eb" -dependencies = [ - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.8.56" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2ab42fc20575779bd240faa45f94a74256f755c0fa9e89f0ede20d91d0cdfc1" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.119", -] - -[[package]] -name = "zeroize" -version = "1.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e13c156562582aa81c60cb29407084cdb54c4164760106ab78e6c5b0858cf64e" -dependencies = [ - "zeroize_derive", -] - -[[package]] -name = "zeroize_derive" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c50655cbb0fe3fc43170059e702f1ce5e19b84cec58dc87b037a09935c2f328" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.119", -] - [[package]] name = "zmij" version = "1.0.23"