# audit-core — NetKingdom security layer declaration # # Framework: net-kingdom/canon/standards/security-layer-model_v0.7.md # Assent: AUDIT-IN-0001 (audit-core's own voice, per §11 "who must declare") # history/2026-08-28-approval-evidence-assent.md # history/2026-08-29-security-layer-model-v0.6-review.md # history/2026-08-29-v0.7-alignment-and-scope-assessment.md # # Reference form offered by ops-warden and adopted here, so §11's declaration # check is mechanical rather than a reader's judgment about prose. audit-core # raised that defect; adopting the form is the other half of raising it. schema_version: "0.1" framework: netkingdom-security-layer-model standard_version: "0.7" repository: audit-core layer: engine role: evidence # §3.3 engine typing declared_by: intakes/intakes.md AUDIT-IN-0001 declared_at: "2026-08-29" # §3.3: an Evidence engine records what happened and proves integrity of what # it holds. It is explicitly not a decision point (§6, §9.4). decision_surfaces_exposed: none # §9.4 — normative and permanent. audit-core exposes no verdict on whether an # approval is still valid; a consumer branching on such an answer would route an # authorization decision through the audit fabric. approval_validity_query: forbidden # §5 applies to Staff. audit-core is an Engine and holds no §4 Tooling contact # (key-cape, OpenBao). Companion §4 asks that UNCATALOGUED infrastructure be # listed anyway so the check is total rather than vacuous, and that carve-out # sunsets within two review intervals for a store another layer reads. # # Completed 2026-09-10 (AUDIT-WP-0009-T10). The list below is asserted total by # `tests/test_layer_conformance.py`, which fails when a new infrastructure # contact appears in `deploy/` without a row here — the check is mechanical # rather than a promise to remember. tooling_contacts: [] uncatalogued_infrastructure: - id: platform-pg system: CNPG PostgreSQL on railiance01 role: audit-core's own operational custody store read_by_other_layers: true # subject to the companion §4 sunset note: >- Not a §4 Tooling row. Listed for totality, not as a declared gap. - id: state-hub system: Custodian State Hub role: >- Work coordination only. Reads and writes workplans, tasks, intakes and progress events. Carries no audit event, no sender credential and no custody role, and audit-core's runtime does not contact it — this is a development-time contact, listed because §5 totality does not distinguish. read_by_other_layers: false - id: kube-apiserver system: k3s API server on railiance01 role: >- Written by the audit-core-attest CronJob to publish the chain-head attestation into one named ConfigMap (AUDIT-WP-0009-T02). The receiver has no API-server egress: a receiver able to rewrite its own attestation could forge it, so the reach belongs to the attest workload alone. read_by_other_layers: false - id: forgejo.coulomb.social system: Container registry role: >- Image source, pinned by digest in deploy/. Build-time contact; no runtime call. Listed because a registry that can change what runs is an infrastructure contact whether or not §5 catalogues it. read_by_other_layers: false # §9.6 — the bound audit-core delivers, stated so no doctrine rests on more. evidence_bound: proves: - records held were not altered after arrival - records held were not truncated after arrival does_not_prove: - that a record was ever sent - absence of a record as evidence of non-occurrence conditional_on: - external chain-head attestation stored outside platform-pg contract: docs/integrity.md not_claimed: [WORM, object-lock, archival-custody] # §11 emission guarantee — AUDIT-IN-0005, docs/section-4-source-of-evidence.md # # §11 requires the declaration from a repository catalogued in §4 as a SOURCE of # evidence. audit-core is catalogued as the Evidence engine — the custody and # detection half — and emits no event into another repository's custody. The # emission guarantee for an event belongs to the repository that emits it; that # is audit-core's standing boundary (AUDIT-IN-0001, AUDIT-WP-0009 non-goals) and # the reason audit-core declines the source role for access-engine's decision # record. # # The one artifact audit-core does produce on its own behalf is declared anyway, # in the same spirit as uncatalogued_infrastructure above: stated so the check is # total rather than vacuous, not because §11 is read to compel it. Prose in # docs/integrity.md is not a machine-readable declaration — the defect audit-core # raised against another repository, so not one it leaves standing in its own. source_of_evidence: false source_of_evidence_note: >- audit-core holds custody and the detection surface. Emission class, cadence and detection obligations sit on each sender's registration (deploy/senders-scope.{json,yaml}, heartbeat_classes per class), never on the archive. audit-core cannot detect non-production by a source and claims no ability to — AUDIT-IN-0003, GH-DEC-2026-014 limit 3. emission_guarantee: - id: chain-head-attestation emits: external chain-head attestation for the audit event chain class: load-bearing rarity: rare # one scheduled artifact per day, never volume rate_monitoring: forbidden # §11 / emission-cadence profile, rare class cadence: form: scheduled interval: daily schedule: "17 3 * * *" # UTC, deploy/attest-cronjob.yaml producer: CronJob audit-core-attest-chain, its own ServiceAccount published_to: ConfigMap audit-core-chain-head detection_surface: form: freshness-window window_hours: 168 # 7x the cadence; widens, never removes on_absence: >- tamper_evidence degrades to False with the reason recorded, and a missing, unreadable, undated or stale attestation is treated the same as absent. Non-production is detected deterministically at read time by the consumer of the claim, not inferred from a rate. surfaces: ["GET /v1/integrity", "GET /readyz (last-known, no chain walk)"] contract: docs/integrity.md bound: >- The attestation proves the head it cites; it is not WORM and does not prove any record was ever sent. An operator-run offsite copy is a separate lane and is not claimed as part of this guarantee.