Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions .github/workflows/gate-attestation.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
8 changes: 1 addition & 7 deletions .kanon-lint-baseline.toml
Original file line number Diff line number Diff line change
@@ -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"
Expand Down
10 changes: 0 additions & 10 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"]
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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. |

Expand Down Expand Up @@ -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, │ └──────────────────┘
Expand Down Expand Up @@ -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 |

Expand All @@ -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

Expand Down
6 changes: 5 additions & 1 deletion crates/akroasis/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)?;
Expand Down
11 changes: 9 additions & 2 deletions docs/ARCHITECTURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 |
Expand All @@ -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`
7 changes: 4 additions & 3 deletions docs/MANIFEST.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -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]]
Expand Down
5 changes: 3 additions & 2 deletions docs/PROJECT.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 |
Expand Down
97 changes: 52 additions & 45 deletions docs/fjall-column-encryption.md
Original file line number Diff line number Diff line change
@@ -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

Expand All @@ -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.
Loading