diff --git a/.github/workflows/gate-attestation.yml b/.github/workflows/gate-attestation.yml index 1eadff9..18d4945 100644 --- a/.github/workflows/gate-attestation.yml +++ b/.github/workflows/gate-attestation.yml @@ -51,9 +51,6 @@ # carries its own rust-toolchain.toml (channel "stable"), auto-detected by # actions-rust-lang/setup-rust-toolchain inside the reusable workflow. # -# needs_fleet_repo_token false: the sole git dependency (sphragis) is a -# public forkwright repo with no observed anonymous-fetch rate-limit -# flakiness -- matches the reusable workflow's own conservative default. name: Gate Attestation on: diff --git a/.kanon-lint-baseline.toml b/.kanon-lint-baseline.toml index bf7401e..97d6174 100644 --- a/.kanon-lint-baseline.toml +++ b/.kanon-lint-baseline.toml @@ -1,13 +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. 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" -file = "Cargo.toml" -line = 1 -hash = "59bc0a0f46c351ca788a518854b298adb512865e8c940bc63665cae98879b4f8" +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. 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 = "CI/release-yml-missing-attestation" diff --git a/Cargo.toml b/Cargo.toml index 68e95c7..6f2c9c4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -130,13 +130,3 @@ tower-http = { version = "0.7", features = ["cors", "trace", "limit"] } # Testing proptest = "1" nix = { version = "0.31.2", features = ["pty"] } - -# Post-quantum hybrid KEM — standalone fleet crate. -# WHY: extracted from akroasis crates/sphragis to forkwright/sphragis for -# cross-repo access. preview-pq gated; unaudited until cryptographic review. -# WHY the expanded form: the inline table exceeded the 80-column limit -# (TOML.md#formatting), and a multi-line inline table needs TOML 1.1. -[workspace.dependencies.sphragis] -git = "https://github.com/forkwright/sphragis" -tag = "v0.1.1" -features = ["preview-pq"] diff --git a/README.md b/README.md index 0d20837..9f4cea1 100644 --- a/README.md +++ b/README.md @@ -33,7 +33,7 @@ Capability domains span radio, mesh, SDR, proximity, network defense, OSINT, off | **Signal Intelligence** | ichneutes | ◻ | - | Future entity correlation, focal point synthesis, threat scoring, and forensic timeline reconstruction across all domains. | | **Automation** | praxis | ◻ | - | Future event-driven triggers, named playbooks, PACE communications, and operational state machines. | | **Navigation** | chorografia | ◻ | ◻ | Future RF propagation modeling, infrastructure graphs, offline OSM navigation, and space weather HF prediction. | -| **Knowledge** | pinax | ◻ | - | Future offline repository for frequency databases, protocol specs, equipment manuals, topo maps, and indexed references. Target instance layout is documented in [docs/reference-store.md](docs/reference-store.md). | +| **Knowledge** | reference library (application name pending) | ◻ | - | Future offline library for frequency databases, protocol specs, equipment manuals, topo maps, and indexed references. Akroasis owns the application/domain layer; standalone [Pinax](https://github.com/forkwright/pinax) owns relational persistence. Target instance layout is documented in [docs/reference-store.md](docs/reference-store.md). | | **Privacy** | lethe | ◻ | ◻ | Future VPN/proxy management, anonymization, IMSI catcher detection, and OPSEC scoring. The etymological complement to [Aletheia](https://github.com/forkwright/aletheia). | | **Interface** | opsis | ◻ | - | Operator surfaces are planned desktop-first via theatron. The shipped `akroasis-server` library provides routes intended for future desktop and agent clients; no server binary or desktop ships yet. #118 resolved. | @@ -63,7 +63,7 @@ Capability domains span radio, mesh, SDR, proximity, network defense, OSINT, off │ │ │ (geo, nav, RF │ │ kryphos │ │ propagation) │ │ (crypto, keys, │ │ │ - │ credentials) │ │ pinax │ + │ credentials) │ │ reference library│ │ │ │ (offline maps, │ │ lethe │ │ specs, manuals) │ │ (privacy, VPN, │ └──────────────────┘ @@ -99,7 +99,7 @@ Every collection crate is expected to produce typed `GeoSignal` objects defined | SDR | Planned: an operator-owned RTL-SDR V4 driver over `rusb` and an owned async DSP engine will land with `dektis` | | IDS/IPS | Planned: Suricata and Zeek orchestration will land with `aspis` | | Maps | Planned: OSM vector tiles and SRTM elevation will land with `chorografia` | -| Search | Planned: full-text indexing will land with `pinax` | +| Search | Planned: full-text indexing belongs to the reference-library application over standalone Pinax persistence | | Interfaces | Schema-versioned JSON is the canonical programmatic contract. CLI: `akroasis radio import --json`, `radio detect --json`, `radio export --json`, `mesh {status,nodes,topology} --json`, `vault list --json`, `vault identity --json`. HTTP: the `akroasis-server` library defines `/api/v1/radio/detect` and `/api/v1/mesh/{status,nodes,topology}` routes with the same JSON schemas, but no server binary or in-repo client ships. Interactive secret vault commands and planned placeholder domains remain TTY-only until their service surfaces ship. Desktop remains planned via theatron. | | License | AGPL-3.0-only | @@ -119,7 +119,7 @@ Akroasis reads these environment variables at runtime; unset variables fall back - [standards/README.md](standards/README.md): Pointer to the canonical Kanon standards - [docs/lexicon.md](docs/lexicon.md): Project name registry -- [docs/reference-store.md](docs/reference-store.md): Target `/instance/reference/` layout for the planned pinax knowledge store +- [docs/reference-store.md](docs/reference-store.md): Target `/instance/reference/` layout and standalone-Pinax authority boundary ## Status diff --git a/crates/akroasis/src/main.rs b/crates/akroasis/src/main.rs index 76945de..6e03b07 100644 --- a/crates/akroasis/src/main.rs +++ b/crates/akroasis/src/main.rs @@ -117,7 +117,11 @@ fn dispatch(command: &Command, out: &mut dyn std::io::Write) -> Result<(), Error writeln!(out, "chorografia — navigation (not yet implemented)").context(IoSnafu)?; } Command::Know => { - writeln!(out, "pinax — knowledge repository (not yet implemented)").context(IoSnafu)?; + writeln!( + out, + "reference-library application (name pending; not yet implemented)" + ) + .context(IoSnafu)?; } Command::Vault(args) => { vault::dispatch(&args.command, out).context(VaultSnafu)?; diff --git a/docs/ARCHITECTURE.md b/docs/ARCHITECTURE.md index a49f5de..06ce074 100644 --- a/docs/ARCHITECTURE.md +++ b/docs/ARCHITECTURE.md @@ -33,11 +33,18 @@ Foundation: stoicheion (vocabulary), tekmerion (evidence), kryphos (encrypti | **ichneutes** | Analysis | Entity correlation, focal points, threat scoring, intelligence synthesis | | **praxis** | Orchestration | Automation engine, playbooks, event triggers, state machines | | **chorografia** | Model | Geographic model, RF propagation, navigation, terrain | -| **pinax** | Knowledge | Offline knowledge repository, frequency databases, maps; see `reference-store.md` for target instance layout | | **opsis** | Interface | Operator surfaces: desktop-first via theatron (akroasis-desktop), consumed through the `akroasis-server` HTTP API. #118 resolved. | | **akroasis** | Binary | CLI entrypoint, subcommand routing, and library interface for akroasis-server | | **akroasis-server** | Interface | Canonical durable programmatic surface: typed axum HTTP backend (`/api/v1/*`) called by akroasis-desktop and agent clients. Mirrors schema-versioned CLI `--json` report contracts for shipped non-interactive surfaces. | +The planned reference-library application has not earned an application or +crate name. Akroasis owns its domain model and envelope policy; standalone +[`forkwright/pinax`](https://github.com/forkwright/pinax) exclusively owns the +relational engine, including transactions, typed schemas, and page-at-rest +encryption. A local `pinax` crate would be a second authority, not an +application layer. Sphragis recipient wrapping is separate from Pinax page +encryption. + ## Key decisions | Decision | Choice | Rationale | @@ -62,5 +69,5 @@ Foundation: stoicheion (vocabulary), tekmerion (evidence), kryphos (encrypti - Planning docs (scope, roadmap, vision, research): live in the kanon repo - Naming: `../standards/GNOMON.md`, `lexicon.md` - Reference store layout: `reference-store.md` -- Fjall column encryption boundary: `fjall-column-encryption.md` +- Reference-library encryption authority boundary: `fjall-column-encryption.md` - PQ content-key wrapping boundary: `pq-content-key-wrapping.md` diff --git a/docs/MANIFEST.toml b/docs/MANIFEST.toml index 697feec..b64ddcb 100644 --- a/docs/MANIFEST.toml +++ b/docs/MANIFEST.toml @@ -28,8 +28,9 @@ type = "authored" evergreen = false description = "Registry of akroasis crate names and the concept each one owns." -# WHY not evergreen: describes a store owned through a crate that is still planned, so it states an -# intended arrangement rather than one a reader can currently observe. +# WHY not evergreen: describes an application and Pinax integration that are +# still planned, so it states an intended arrangement rather than one a reader +# can currently observe. [[doc]] path = "docs/reference-store.md" type = "authored" @@ -40,7 +41,7 @@ description = "Layout of the long-term offline reference store and its ownership path = "docs/fjall-column-encryption.md" type = "decision-record" evergreen = true -description = "Where the encryption boundary sits for fjall-backed columns, and what is left declarative." +description = "Corrected Pinax/Akroasis authority boundary for reference-library encryption." decided = "2026-08-17" [[doc]] diff --git a/docs/PROJECT.md b/docs/PROJECT.md index 4411070..1333183 100644 --- a/docs/PROJECT.md +++ b/docs/PROJECT.md @@ -20,15 +20,16 @@ Phase index lives in the kanon repo roadmap. Wave status is reflected in merged |---------|-------------| | [Aletheia](https://github.com/forkwright/aletheia) | Akroasis plugs into Aletheia as a thesauros domain pack (Phase 14). Standalone otherwise. | | [Harmonia](https://github.com/forkwright/harmonia) | Sibling project: same toolchain and patterns, different domain. | +| [Pinax](https://github.com/forkwright/pinax) | Standalone relational engine for the planned reference-library application; Akroasis does not own a local Pinax crate. | ## References | Document | Purpose | |----------|---------| | `ARCHITECTURE.md` | Crate map, layer structure, key decisions | -| `fjall-column-encryption.md` | Future declarative encrypted-field boundary for fjall-backed stores | +| `fjall-column-encryption.md` | Historical #132 premise and current reference-library encryption authority boundary | | `pq-content-key-wrapping.md` | Future PQ content-key wrapping boundary and implementation gates | -| `reference-store.md` | Target `/instance/reference/` layout for the planned pinax knowledge store | +| `reference-store.md` | Target `/instance/reference/` layout and standalone-Pinax authority boundary | | `../standards/GNOMON.md` | Greek naming methodology | | `lexicon.md` | Domain terms and name registry | | `../standards/STANDARDS.md` | Universal coding standards | diff --git a/docs/fjall-column-encryption.md b/docs/fjall-column-encryption.md index ea5603a..c0e3d8d 100644 --- a/docs/fjall-column-encryption.md +++ b/docs/fjall-column-encryption.md @@ -1,14 +1,15 @@ -# Fjall Column Encryption Boundary +# Reference-Library Encryption Authority Boundary -Issue #132 tracks a future declarative encryption layer for fjall-backed -stores. Current main does not have a generic table/column store abstraction: -the only fjall-backed runtime store is `kryphos::Vault`, and it already -encrypts every field of a credential record — secret, name, type, metadata, -status, and history — through two typed fields before serializing the row. +Issue #132 was filed on the premise that Akroasis would own a generic +declarative encryption codec over a future fjall-backed reference store. That +premise is superseded. Standalone +[`forkwright/pinax`](https://github.com/forkwright/pinax) exclusively owns the +relational engine and its page-at-rest encryption. Akroasis owns only the +reference-library domain-envelope policy above that engine. -This note defines the boundary to use when akroasis adds its first mixed -plaintext/ciphertext fjall schema for signals, references, or other indexed -runtime data. It is not an implementation of #132. +The historical filename remains so existing issue and review links still +resolve. This note records the corrected authority boundary; it is not an +implementation of #132. ## Current State @@ -25,52 +26,58 @@ runtime data. It is not an implementation of #132. - `Vault::add`, `Vault::get`, `Vault::rotate`, `Vault::revoke`, and `Vault::history` call the existing ChaCha20-Poly1305 helpers directly for both fields via `Vault::encrypt_metadata`/`Vault::decrypt_metadata`. -- There is no fjall-backed signal store in current main. Mesh signals are - produced in memory and forwarded through the collector/processor path. +- There is no fjall-backed signal or reference store in current main. Mesh + signals are produced in memory and forwarded through the + collector/processor path. Because of that shape, wrapping the vault in a generic column codec now would add indirection around an already-specific and working encryption path. -## Target Shape +## Authority split -The first store that needs mixed encrypted and plaintext fields should own a -small codec boundary with these parts: +Pinax owns encryption of its database pages and all storage-engine artifacts. +Akroasis consumes that contract; it does not reproduce it with a local fjall +wrapper, `ColumnCodec`, or table/column registry. -1. A stable field identity type for the store, such as `(StoreId, FieldId)` or a - store-local enum. Do not use ad hoc string literals at call sites. -2. A single canonical encrypted-field registry in the owning crate, for example - `ENCRYPTED_FIELDS`. -3. A `ColumnCodec` trait or equivalent helper that receives plaintext bytes, - field identity, and domain context, then returns authenticated ciphertext. -4. A read path that decrypts mapped fields before returning typed domain values. -5. A migration rule for legacy plaintext rows. The preferred first rule is - re-encrypt-on-write; a one-shot migration tool is only needed after a durable - store with existing plaintext rows ships. +Akroasis owns a canonical, typed domain policy that decides which reference +payloads require an authenticated content envelope before they cross the +Pinax API. Every write must consult that policy, and reads must authenticate +and decrypt an envelope before returning a typed domain value. The policy uses +domain identities, not Pinax page, table, or column identifiers. -The registry should be declarative, but the owning store still decides which -fields may remain plaintext for indexing, filtering, or redacted display. +Sphragis supplies recipient distribution for domain content keys. Its profile +API wraps keys for recipients and epochs; it does not encrypt Pinax pages. +Pinax page encryption protects engine-managed data at rest, but it does not +replace an Akroasis envelope whose recipient and revocation semantics must +survive export or replication. + +Any legacy plaintext reference data must have an explicit migration rule +before default promotion. A preview fixture may be discarded and recreated +only while the preview contract explicitly permits that behavior. ## Non-Goals -- Do not retrofit `kryphos::Vault` onto the generic `ColumnCodec`/ - `ENCRYPTED_FIELDS` shape only for consistency with future stores. Its - existing typed-field model (now two fields: `encrypted_secret` and - `encrypted_metadata`) is clearer than a generic map until another store - proves the abstraction. -- Do not encrypt fields that are required for safe listing or lifecycle checks - unless the caller has an explicit decrypted view. -- Do not add new cryptographic primitives for this issue. Reuse the existing - vault AEAD unless a later key-management design selects a different content - key envelope. +- Do not add a local `crates/pinax`, an Akroasis-owned relational engine, or a + direct fjall reference store. +- Do not retrofit `kryphos::Vault`; its typed encrypted fields already fit its + separate credential-vault domain. +- Do not copy Pinax page-encryption policy into Akroasis or treat page + encryption as recipient distribution. +- Do not call Sphragis `hazmat` or raw KEM operations. The reviewed profile API + is the only permitted recipient-wrapping boundary. -## Open Decisions +## Review gates -- Whether the first codec lives in `kryphos` as a shared storage utility or in - the first crate that owns a mixed fjall schema. -- Whether encrypted fields should use the vault passphrase key, a per-store - content key, or a future wrapped content-key design. -- Which fields in future signal/reference stores are safe to leave plaintext for - search and indexing. +Issue #132 remains open until a real reference-library consumer demonstrates +all of the following: -Implementation of #132 should wait for the first durable multi-field store that -needs this boundary. +1. Pinax page encryption is enabled and its producer-owned contract covers the + engine artifacts used by the integration. +2. One typed Akroasis policy is the sole authority for domain envelopes; no + call site can silently bypass it. +3. An on-disk adversarial test cannot find protected reference plaintext, while + the authenticated read path returns the original typed value. +4. Migration behavior for any prior plaintext fixture or durable data is + executable and tested. +5. The recipient and epoch lifecycle tracked by #395 remains distinct from, + and composes with, Pinax page encryption. diff --git a/docs/lexicon.md b/docs/lexicon.md index dab1cf9..f0eebb7 100644 --- a/docs/lexicon.md +++ b/docs/lexicon.md @@ -61,7 +61,13 @@ | Crate | Greek | Over | L3 Essential Nature | |-------|-------|------|---------------------| | **chorografia** | χωρογραφία | "geographic model" | Writing the land - geographic modeling, RF propagation, infrastructure dependency graph, cascade analysis, vehicle/foot navigation, military planning, space weather, terrain, offline map rendering. Ptolemy's term for detailed regional description - intimate knowledge of a specific place. | -| **pinax** | πίναξ | "knowledge repository" | The register, the catalog. Offline knowledge repository - maps, frequency databases, protocol specs, equipment manuals, emergency procedures, vulnerability databases. Callimachus created the Pinakes to make Alexandria's knowledge *findable*. Not a pile of scrolls - a system. The pinax made knowledge usable. | + +The reference-library application is intentionally unnamed. **Pinax** remains +reserved for the standalone fleet relational engine at `forkwright/pinax`; +using the same identity for an Akroasis application crate would collapse engine +and domain authority. The original register/catalog resonance remains strong, +but the mesh collision is decisive. A distinct application name must pass the +Gnomon gate when the consumer is ready to exist. ### Interface layer @@ -80,7 +86,7 @@ - **Skopos → Semaino** - The scout reports to the sign reader. Collection feeds analysis. - **Dektis → Semaino** - The receiver feeds the sign reader. Hardware reception → intelligence. - **Ichneutes → Praxis** - Analysis produces understanding. Praxis converts understanding to action. -- **Pinax ↔ Chorografia** - The register holds the data (maps, terrain, specs). The model computes against it (propagation, routing, cascade). +- **Reference library ↔ Chorografia** - The library holds the data (maps, terrain, specs). The model computes against it (propagation, routing, cascade). --- @@ -90,4 +96,4 @@ |------|---------|-------------| | **Pheme** (Φήμη) | Rumor, report, reputation | System is about listening, not hearsay. Pheme unconceals gossip, not attentive reception. | | **Phrourion** (φρούριον) | Watchtower, garrison | Too defensive/military. Merged into Akroasis - the system actively listens, manages, communicates. | -| **Mouseion** (Μουσεῖον) | Seat of the Muses | Already used by another project (Aletheia). Replaced by Pinax. | +| **Mouseion** (Μουσεῖον) | Seat of the Muses | Already used by another project (Aletheia); the application identity remains open. | diff --git a/docs/reference-store.md b/docs/reference-store.md index e29c4c2..d5b10d4 100644 --- a/docs/reference-store.md +++ b/docs/reference-store.md @@ -1,10 +1,27 @@ -# Reference Store Layout - -Akroasis owns the long-term offline reference store through `pinax`, the planned -knowledge layer. The repository does not ship an `instance/` tree today; this -document defines the target layout and migration policy so the existing -`theke/_reference` staging area can move only after the source inventory is -visible and checksummed. +# Reference Library Layout + +Akroasis owns the long-term offline reference-library application and its +domain policy. The standalone +[`forkwright/pinax`](https://github.com/forkwright/pinax) project exclusively +owns relational persistence; this repository must not grow a `crates/pinax` or +a second local Pinax identity. The application layer remains deliberately +unnamed until it passes the fleet naming gate. + +The repository does not ship an `instance/` tree today. This document defines +the target layout and migration policy so the existing `theke/_reference` +staging area can move only after the source inventory is visible and +checksummed. A transactional Pinax integration waits for the standalone +engine's multi-record transaction and typed-schema contracts; the final +async-native shape also waits for its async API rather than shipping a +temporary blocking adapter. + +The encryption authorities are distinct. Pinax owns encryption of its database +pages at rest. Akroasis owns the domain-envelope policy for reference content, +including which payloads require envelopes and how content-key epochs map to +the application model. Sphragis supplies recipient distribution for those +content keys through its reviewed profile API; it does not replace Pinax page +encryption, and Pinax page encryption does not replace recipient-scoped +envelopes. Issue #395 tracks the integration and promotion gates. ## Canonical path @@ -121,6 +138,8 @@ Before moving content out of the current staging area: ## Current repo state -As of this design note, akroasis only documents the planned `pinax` knowledge -layer. There is no checked-in `instance/` directory, no `crates/pinax`, and no -verified local copy of the source `theke/_reference` tree in this worktree. +As of this design note, akroasis only documents the planned reference-library +application. There is no checked-in `instance/` directory, no local +persistence crate, and no verified copy of the source `theke/_reference` tree +in this worktree. Akroasis issue #395 owns the producer-readiness and Sphragis +handoff gates for the first durable implementation.