Review security layer model v0.6 — assent, three findings
All three v0.4 findings landed in v0.5 (local outbox, machine-readable declaration, §14 arithmetic). §9.6's load-bearing/attributive split and §16's ruling on approval custody both improve on what audit-core raised. Findings, all correcting audit-core's own contribution: (1) the local outbox closes accidental omission, not the compromised-source case §9.6 opens with — a compromised emitter can decline the insert or drop the row before drain; §16 rests a ruling on that conflation. (2) cadence is the only control touching the residual and is a SHOULD, and rate-based detection is weakest for the rare negative events §9.6 says matter most — recommend positive reconciliation for load-bearing low-volume classes. (3) §3.3's Evidence row states an availability/independence trade as a property of evidence engines. Adds layer.yaml in ops-warden's reference form, per §11. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WpeL68AWHqtqPQZEXY5kFe Assistant: claude-code Assistant-Model: opus Assistant-Process: 4040362@bnt-lap001 Assistant-Session: 4fd0fd24-2ee8-4413-bd67-43bd79ca73f1
This commit is contained in:
parent
c7a0ce9557
commit
cecc3659b9
2 changed files with 195 additions and 0 deletions
149
history/2026-08-29-security-layer-model-v0.6-review.md
Normal file
149
history/2026-08-29-security-layer-model-v0.6-review.md
Normal file
|
|
@ -0,0 +1,149 @@
|
|||
# Security layer model v0.6 — audit-core's review
|
||||
|
||||
**Date:** 2026-08-29
|
||||
**Standard:** `net-kingdom/canon/standards/security-layer-model_v0.6.md` (proposed)
|
||||
**Reviewed against:** v0.4, audit-core's v0.4 review, and `AUDIT-IN-0001`
|
||||
**Outcome:** assent. Three findings, all in §9.4/§9.6 — the sections audit-core
|
||||
owns the argument for. Finding 1 corrects a remedy audit-core itself proposed.
|
||||
|
||||
---
|
||||
|
||||
## Disposition of audit-core's v0.4 findings
|
||||
|
||||
All three landed in v0.5, and two were improved on:
|
||||
|
||||
| v0.4 finding | v0.6 |
|
||||
| --- | --- |
|
||||
| §9.4's MUST is safe only if the outbox is local | §9.4 now requires the queue in `approval-engine`'s own store, with no synchronous `audit-core` dependency inside the state-change transaction |
|
||||
| §11's who-must-declare rule is not mechanically checkable | §11 now requires a machine-readable form; `ops-warden` built a reference (`layer.yaml` + conformance script) and offered it estate-wide |
|
||||
| §14's arithmetic | corrected to *seven of sixteen*, *the remaining nine* |
|
||||
|
||||
§9.6 also gained the **load-bearing / attributive** distinction, which resolves
|
||||
the over-generalization risk audit-core did not spot: `ops-warden`'s
|
||||
`# audit must not block signing` is legitimate for attributive evidence and is
|
||||
now named as the estate's live example rather than being caught by a rule
|
||||
written for approvals. The mirror rule — *absence of a record is not evidence of
|
||||
non-occurrence* — is the correct dual of the original and audit-core did not
|
||||
state it.
|
||||
|
||||
§16's ruling on stronger approval custody is **right, and better argued than the
|
||||
gap audit-core opened**: archival custody does not address omission at all, so
|
||||
leaving it open while calling the evidence half load-bearing created a promise
|
||||
the archive cannot cash. audit-core accepts the decision and withdraws the gap.
|
||||
|
||||
---
|
||||
|
||||
## Finding 1 — atomicity closes accidental omission, not the adversarial case §9.6 names
|
||||
|
||||
This one corrects audit-core's own contribution, so it is stated plainly.
|
||||
|
||||
§9.6 opens on the adversarial threat: *"against a compromised or buggy source, a
|
||||
suppressed event leaves the chain perfectly intact and verification reports
|
||||
intact."* The remedy the standard mandates for load-bearing evidence is emission
|
||||
atomicity via a transactional outbox in the source's own store (§9.4).
|
||||
|
||||
**A local outbox does not defend against that threat.** It makes emission atomic
|
||||
with respect to *crash and partial failure* — the process dies between mutation
|
||||
and emit, and the outbox row is already committed, so the event survives. It
|
||||
does nothing against a compromised `approval-engine`, which can decline to
|
||||
insert the row, delete it before the drainer runs, or drain it to nowhere. The
|
||||
outbox lives inside the blast radius of the very component whose compromise
|
||||
§9.6 posits.
|
||||
|
||||
This matters because §16 now rests a decision on it. The ruling reads:
|
||||
*"archival custody does not address omission at all; emission atomicity with a
|
||||
local outbox (§9.4) and a detection surface (`GH-WP-0002-T04`) do."* Atomicity
|
||||
addresses the accidental half. Only the detection surface touches the
|
||||
adversarial half, and only after the fact.
|
||||
|
||||
The conclusion is still right — archival custody is the wrong tool, and
|
||||
audit-core is not reopening it. But the standard should say which threat each
|
||||
control covers, because as written §9.4 reads as though it closes §9.6's
|
||||
opening sentence, and it does not:
|
||||
|
||||
- **atomicity (§9.4)** — closes accidental omission: crash, partial failure, a
|
||||
buggy emitter;
|
||||
- **cadence and reconciliation (§9.6, `GH-WP-0002-T04`)** — *detects* adversarial
|
||||
omission, after the fact, probabilistically;
|
||||
- **nothing in the model prevents adversarial omission at a compromised source.**
|
||||
That is a true residual and it should be visible as one.
|
||||
|
||||
audit-core proposed atomicity as the condition of its assent. It is the right
|
||||
requirement and audit-core still asks for it. It is narrower than the problem
|
||||
audit-core raised, and the standard should not carry it as broader.
|
||||
|
||||
## Finding 2 — cadence is SHOULD, and it is the only control covering the residual
|
||||
|
||||
Following directly from finding 1: §9.6 consequence 2 makes an expected emission
|
||||
cadence a **SHOULD**. For load-bearing evidence it is the sole control that
|
||||
touches adversarial omission. A SHOULD is too weak for the only defence in the
|
||||
class.
|
||||
|
||||
**Recommended:** for sources whose evidence is load-bearing under §9.6, the
|
||||
cadence declaration is a MUST. §17 already requires the emission-cadence
|
||||
declaration as a Taxonomy artifact, so the machinery is planned; the obligation
|
||||
should match it.
|
||||
|
||||
**With one qualification that matters more than the strength of the verb.**
|
||||
Rate-based cadence detection is weakest exactly where §9.6 says the stakes are
|
||||
highest. Its own words: *the most valuable event to suppress is the negative
|
||||
one* — a revocation, a denial, a containment action. Those are **rare**. A
|
||||
source emitting a handful of revocations a month has no rate to drop below;
|
||||
suppression is indistinguishable from a quiet month. Cadence monitoring works
|
||||
for high-volume attributive streams and fails for low-volume load-bearing ones,
|
||||
which inverts the priority.
|
||||
|
||||
For load-bearing low-volume classes the control is not rate monitoring but
|
||||
**positive reconciliation**: compare `approval-engine`'s object-state
|
||||
transitions against `audit-core`'s event count per class, and treat divergence
|
||||
as a finding. That is `GH-WP-0002-T04`, and audit-core suggests §9.6 name it as
|
||||
the required form for that case rather than leaving cadence as the general
|
||||
answer. A heartbeat — *nothing to report, and here is the signed assertion of
|
||||
that* — turns silence into a positive claim that can itself be missing, which
|
||||
rate monitoring never does.
|
||||
|
||||
## Finding 3 — §3.3's Evidence row states a trade as a property
|
||||
|
||||
§3.3 types `audit-core` as an Evidence engine and gives its outage semantics as:
|
||||
**MUST NOT block the operation being recorded.**
|
||||
|
||||
audit-core assents to this as the default, and it is the correct default —
|
||||
availability of the recorded operation should not depend on its recorder, and
|
||||
the local-outbox rule in §9.4 makes it achievable without losing atomicity.
|
||||
|
||||
But stated absolutely it forecloses the one control that would address finding
|
||||
1's residual for the highest-assurance class: *do not proceed unless an
|
||||
independent custodian already holds the record*. That is the classic break-glass
|
||||
control, and it is the only shape that puts the record outside the actor's blast
|
||||
radius **before** the act. §9.6's own independence argument — audit-core's
|
||||
custody is what Canon core rule 13 wants — is an argument for that shape
|
||||
existing somewhere in the model.
|
||||
|
||||
The trade is real and audit-core does not claim the default is wrong: choosing
|
||||
availability here means accepting that a compromised source can suppress, and
|
||||
that detection is the answer. **That is a deliberate estate trade, not a
|
||||
property of evidence engines**, and §3.3 should read as the former. audit-core
|
||||
suggests the row keep its MUST NOT as the default and note that an operation
|
||||
whose control requirement is independent recording before effect is a declared
|
||||
exception the estate has not needed yet — so that if it is ever needed, it is
|
||||
raised rather than ruled out by a table cell.
|
||||
|
||||
---
|
||||
|
||||
## Conformance action taken
|
||||
|
||||
§11 now requires a machine-readable declaration. audit-core raised that defect;
|
||||
adopting the remedy is the other half of raising it. `layer.yaml` added in
|
||||
`ops-warden`'s reference form, declaring layer `engine`, role `evidence`, no
|
||||
Tooling contacts, no decision surfaces, the approval-validity prohibition, and
|
||||
the §9.6 evidence bound in machine-readable form so no doctrine can rest on more
|
||||
than `docs/integrity.md` delivers.
|
||||
|
||||
## Position
|
||||
|
||||
audit-core assents to v0.6. The engine typing is a real improvement and the
|
||||
Evidence role is correctly drawn. Findings 1 and 2 are one argument: the model
|
||||
mandates a control for accidental omission and treats it as covering the
|
||||
adversarial case it opens with, while the control that does address that case is
|
||||
a SHOULD and is the wrong shape for the events that matter most. Finding 3 is a
|
||||
framing correction, not a rule change.
|
||||
46
layer.yaml
Normal file
46
layer.yaml
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
# audit-core — NetKingdom security layer declaration
|
||||
#
|
||||
# Framework: net-kingdom/canon/standards/security-layer-model_v0.6.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
|
||||
#
|
||||
# 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.6"
|
||||
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 Tooling contact
|
||||
# requiring a §5.1/§5.2/§5.3 declaration. Its PostgreSQL custody is its own
|
||||
# operational store, not a §4 Tooling row.
|
||||
tooling_contacts: []
|
||||
|
||||
# §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]
|
||||
Loading…
Add table
Add a link
Reference in a new issue