fix: repair chained imports and track blocked evidence dependencies
Assistant: codex Assistant-Model: gpt-6.1-sol Assistant-Session: 01a1046e-465c-7d43-8c4c-d10f0a1feadd
This commit is contained in:
parent
28b567e588
commit
146f4e1dd3
21 changed files with 869 additions and 95 deletions
166
docs/cross-repo-evidence-admission.md
Normal file
166
docs/cross-repo-evidence-admission.md
Normal file
|
|
@ -0,0 +1,166 @@
|
|||
# Cross-repo evidence admission requirements
|
||||
|
||||
Reviewed 2026-10-04 against audit-core source, intakes, inbox and owner files.
|
||||
Work: AUDIT-WP-0013 (senders), AUDIT-WP-0014 (execution receipts), and
|
||||
AUDIT-WP-0015 (independent evidence). These are source and metadata commitments;
|
||||
activation requires the relevant owner delivery and approved live change.
|
||||
|
||||
## Flex-auth decision records — AUDIT-WP-0013-T02/T03
|
||||
|
||||
Owner file: access-engine/workplans/FLEX-WP-0031-decision-record-emission.md,
|
||||
reviewed at `257a83e997d7d30d3ace2b4524fab47cdfb7a6de`. T03's durable outbox
|
||||
is done. Do not keep registration waiting on an outbox that already exists.
|
||||
Audit-core accepts custody admission per AUDIT-IN-0006; it does not decide how
|
||||
authorization effects are released.
|
||||
|
||||
Flex-auth must supply six final non-secret registration payloads and exact
|
||||
namespace/pod ingress selectors: ops-warden, tenant-engine, user-engine,
|
||||
secrets-engine, informed-decision-t03 and informed-decision-sitting. Each
|
||||
identity permits its exact `flex-auth.<pin>` source, write true/read false,
|
||||
`tenants: ["*"]` with the existing deny-before-tenant-creation justification,
|
||||
load-bearing and explicitly selected `secret_policy: redact` in the protected
|
||||
registry. No wildcard source match and no credential in the payload.
|
||||
|
||||
The emitter actually uses `flex-auth.decision.<effect>` (ClassPrefix in
|
||||
internal/emission/outbox.go). Final heartbeat keys must therefore be
|
||||
`flex-auth.decision.deny`, `.redact`, `.not_applicable`, `.audit_only`, each at
|
||||
86400 seconds; shorthand effect names would monitor the wrong stored class.
|
||||
Heartbeat wire type is `audit-core.heartbeat`, with `data.class` set to the
|
||||
exact vouched-for class, independent non-empty correlation/id and offset-aware
|
||||
occurred_at. Each per-pin canonical `emission_cadence` must name the exact
|
||||
source and classes; flex-auth supplies allow's expected rate, window and
|
||||
threshold. Audit-core will not choose them for the source. Counts compare
|
||||
committed outbox entries, not all released decisions, by identical class/window.
|
||||
|
||||
The remaining custody owner is railiance-platform; ops-warden must supply a usable sender-mint routing entry.
|
||||
The current audit-core-senders entry exists but is draft, unresolvable and
|
||||
non-executable, names ops-mason, and describes an old in-cluster generation
|
||||
path; it is not the reviewed attended per-pin mint lane. Correct/promote the
|
||||
existing routing record or return a concrete owner lane, without creating a
|
||||
second competing registry. Use `warden route` before any credential
|
||||
request. An attended seed/delivery needs the founder's terminal and per-change
|
||||
go. Then audit-core reviews the payloads, prepares exact scope/ingress,
|
||||
and verifies accepted/duplicate writes, wrong source/tenant/read refusals,
|
||||
reconciliation, per-class missing heartbeats and formerly-valid bearer
|
||||
revocation. Source and owner revisions plus sanitized receipts are required.
|
||||
|
||||
Gate House GH-WP-0004-T12 owes the final decision for FLEX-DEC-2026-018.
|
||||
Message `715cf1f2-55dd-4d2d-9b7b-c5dffa0181e5` is explicitly a reading, not
|
||||
that decision: current text admits no load-bearing failure-path exception.
|
||||
Audit-core retains the non-atomic/non-conformant description for the restrictive
|
||||
classes released uncommitted. It will not repurpose attributive
|
||||
`completeness_trade`, add a permissive schema field ahead of the ruling, or
|
||||
claim atomicity. The final ruling blocks an exception/conformance declaration;
|
||||
it does not block preparing transport custody for honestly described evidence.
|
||||
|
||||
## Qonto collector mapping — AUDIT-WP-0013-T04/T05
|
||||
|
||||
Accepted bounded receiver admission/mapping commitment for QONTO-WP-0006-T02.
|
||||
Qonto source reviewed at `bf8a9ede6704523d4744d63bf481ca8b195d86f4`.
|
||||
rapp-qonto owns the collector runtime; its finished RAPP-QONTO-WP-0003 is
|
||||
historical rollout evidence, not current collector acceptance. qonto-assistant
|
||||
owns the source declaration, class inventory, scope and process counters.
|
||||
|
||||
| Source class | Proposed receiver type | Required preserved metadata |
|
||||
| --- | --- | --- |
|
||||
| audit.allow | audit.allow | stream_id, stream_instance_id, stream_sequence, event_class and sanitized identity/egress context |
|
||||
| audit.deny | audit.deny | same metadata; rare load-bearing, no expected-rate monitor |
|
||||
| audit.heartbeat | audit-core.heartbeat | original event_class audit.heartbeat, timestamp/reason, instance and sequence, both source/window transition counts and window bounds |
|
||||
|
||||
The adapter must supply every field of docs/event-envelope.md. Stable event id
|
||||
and Idempotency-Key must derive deterministically from the original instance
|
||||
and sequence so retries cannot mint new accepted records. Tenant and subject
|
||||
must come from an owner-approved binding, never inferred from a pod name or a
|
||||
convenience tenant. Preserve the original heartbeat event_class in data; do
|
||||
not rename Qonto's emitted class in its documentation.
|
||||
|
||||
A heartbeat can vouch for the quiet deny class through `data.class=audit.deny`.
|
||||
Its assertion is no deny transitions in the window, not proof that there were
|
||||
no allow transitions. qonto-assistant must approve that mapping and the exact
|
||||
per-class heartbeat registration with its canonical declaration and actual
|
||||
configured interval (default 86400). If another vouched-for class is needed,
|
||||
review fan-out and sequence/count accounting explicitly. Sender-level
|
||||
`evidence_kind` has one value: use the source owner's explicit load-bearing
|
||||
admission for this mixed stream, retaining attributive allow and load-bearing
|
||||
deny/heartbeat in the per-class canonical inventory. No blanket atomicity or
|
||||
completeness claim follows from admission.
|
||||
|
||||
Audit-core now implements `GET /v1/reconciliation`'s optional
|
||||
`stream_instance_id`, selecting exact stored `data.stream_instance_id` within
|
||||
an authorized source/tenant and acceptance-time window. Duplicates count once;
|
||||
restarts never share counts accidentally. This is source-tested and requires a
|
||||
reviewed receiver release before live use. It does not turn source-time windows
|
||||
into acceptance-time windows. The collector/observer must define bounded lag,
|
||||
watermark/sequence boundaries and the comparable accepted-count derivation;
|
||||
it must distinguish late arrival from lost evidence. Sender own counts are
|
||||
available with read false. Independent kings-guard archive/sequence inspection
|
||||
needs its separately scoped read identity/feed, not a writer upgraded to read
|
||||
all tenants. No observer access scope is invented here.
|
||||
|
||||
Unblock inputs from rapp-qonto: collector source/image/config/Deployment pins,
|
||||
metadata-only sample envelopes, exact namespace/pod selectors, authoritative
|
||||
tenant binding, stable instance/restart/scale-to-zero semantics, retry/drop and
|
||||
lag behavior, redacted success/failure receipts and actual accepted receiver
|
||||
records. From qonto-assistant: reviewed mapping and per-class cadence,
|
||||
classification, retention/access/export/secret policy. Audit-core then prepares
|
||||
registration and checks acceptance, retries, retained instance/sequence,
|
||||
wrong-scope refusals and accepted-count derivation. King's Guard KG-WP-0005-T03
|
||||
subsequently owns independent missing-heartbeat, sequence-gap and count-divergence
|
||||
acceptance. T02's sender proof never waits on Qonto T03 observer acceptance.
|
||||
No bank keys or bank API traffic are needed for these receipts.
|
||||
|
||||
## Execution-attribution receipts — AUDIT-WP-0014
|
||||
|
||||
Proposal reviewed in net-kingdom/canon/standards/playbook-capability-contract_v0.2.md
|
||||
at `45a189a39167eef62709df0e857309f7ddc59029` (NK-WP-0040-T02).
|
||||
Audit-core accepts the evidence-holder role; Railiance is the proposed emitter
|
||||
and must confirm its exact emitting component and sender source. NetKingdom
|
||||
owns the canonical receipt schema and validator. Audit-core checks shape and
|
||||
credential scope, stores the event and chains it. Custody does not authenticate
|
||||
the historical actor chain or decide whether decision_refs authorize execution.
|
||||
|
||||
Before implementation, NetKingdom must return a versioned schema, artifact
|
||||
path/digest, unknown/absent semantics and positive/negative fixtures. All listed
|
||||
fields must be represented: initiator issuer/subject, optional delegation,
|
||||
executing workload, runtime principal, tenant, environment, run id, source
|
||||
commit, artifact digest, target, action, decision refs and time interval with
|
||||
clock source and optional established precision bound. Unknown attribution stays
|
||||
explicit `unknown`; delegation is absent when none; a time bound is absent when
|
||||
not established. No bearer or role response may be embedded.
|
||||
|
||||
Railiance must supply the exact wire event class and sender, authoritative
|
||||
scope, stable retry/id binding to run_id, classification, emission guarantee,
|
||||
retention/access/export and secret policy, plus emitter revision and metadata
|
||||
fixtures. Audit-core will wrap the receipt in its existing eight-field envelope,
|
||||
validate the canonical data schema before accept, enforce declared tenant/source,
|
||||
refuse malformed/secret content, retain original unknowns, and prove duplicate
|
||||
and conflict behavior. Cross-check receipt tenant with envelope tenant; require
|
||||
ordered offset-aware start/end if that is the canonical rule. No independent
|
||||
local receipt schema is shipped ahead of the owner schema, and generic JSON
|
||||
acceptance is not advertised as receipt-schema validation.
|
||||
|
||||
## Independent chain-head custody — AUDIT-WP-0015-T01
|
||||
|
||||
RESOURCE-WP-0002-T06 is done for encrypted logical database copies. That
|
||||
terminal task is not an unfinished chain-head copy commitment. The 2026-09-15
|
||||
AUDIT-WP-0009-T12 receipt proves the in-cluster attestor only.
|
||||
resource-control and rapp-postgres must name the current offsite operator/owner
|
||||
record, return a destination outside cluster and Barman failure domains on the
|
||||
existing Nextcloud + age lane, and supply metadata-only upload and independent
|
||||
readback receipts for the same chain-head digest, event id/count and observed_at.
|
||||
State cadence, freshness/failure handling, access separation and retrieval test.
|
||||
No Nextcloud credential belongs in audit-core. Without this return, the control
|
||||
remains a database-owner boundary and carries no cluster-owner survival claim.
|
||||
|
||||
## Refreshed E2 and asm-t08 — AUDIT-WP-0015-T02
|
||||
|
||||
Whitehat commit `7b5bc1e444cf57ae5d9ba1dac0c0189c0833e278` and message
|
||||
`81bebdd8-5ca7-47b3-aafe-1d00ff8be122` leave WHITEHAT-WP-0006-T03 wait.
|
||||
The 2026-08-22 E2 run is historical and its -01/-02/-03 engagement ids are
|
||||
terminal. Whitehat is not requesting a run. A future run needs a distinct
|
||||
engagement, plane admission and rules-of-engagement approvals; audit-core
|
||||
creates none of those during this review. The alternative is access-engine's
|
||||
confirmation of a flex-auth tenant-A identity with no tenant-B authority.
|
||||
asm-t08's surface owner owes component revision, identities, window and technique.
|
||||
These remain owner inputs; no field or authorization is fabricated. Original
|
||||
AUDIT-WP-0008-T05 remains done for its historical accepted scope.
|
||||
|
|
@ -22,8 +22,13 @@ duplicate accept must not mint a second link. A conflict must not
|
|||
advance the head. Concurrent first-accepts of different events take an
|
||||
advisory lock (`CHAIN_LOCK_KEY`) so they cannot fork.
|
||||
|
||||
Verify walks `ORDER BY accepted_at, event_id`, recomputes every link,
|
||||
and reports the first event id whose stored hashes do not match. A
|
||||
PostgreSQL verification follows `chain_prev` from genesis, recomputes every
|
||||
link, and retains orphaned or forked rows as breaks. The next append selects
|
||||
the unique unreferenced head under the same advisory lock. This separates
|
||||
chain insertion order from historical `accepted_at`: importing older SQLite
|
||||
events extends the existing chain without rewriting timestamps or links.
|
||||
SQLite's development chain still walks `ORDER BY accepted_at, event_id`.
|
||||
Verification reports the first event id whose stored hashes do not match. A
|
||||
break is a **custody defect**, not a sender error. Retrying the event
|
||||
will not repair it.
|
||||
|
||||
|
|
|
|||
|
|
@ -290,3 +290,27 @@ The historical SQLite importer has five PostgreSQL test failures tracked by
|
|||
AUDIT-IN-0004. It is outside the live receiver path; do not use it as a recovery
|
||||
procedure until that record closes. The release test result must state this
|
||||
exclusion explicitly, never describe the entire suite as green.
|
||||
|
||||
|
||||
### Historical SQLite import
|
||||
|
||||
`python -m audit_core migrate-store --from-sqlite <file> --source-id <stable-id>`
|
||||
uses PostgreSQL custody with schema migration `0007-import-receipts`. Run this
|
||||
with the migration owner's database authority, not a runtime writer identity.
|
||||
Keep `source-id` unchanged across file relocation and retries; its default is
|
||||
the absolute file path. Replacing a source at that path requires a new identity.
|
||||
No source content is copied into the receipt table: it holds hashed source and
|
||||
row identities, content fingerprints and previously imported finding counts.
|
||||
|
||||
Import reads one SQLite snapshot and writes under the native append advisory
|
||||
lock. Historical events extend the stored link chain with original IDs, hashes,
|
||||
records and exact acceptance timestamps. Existing differing evidence is reported
|
||||
as a conflict and retained; no trigger is disabled and no existing chain link
|
||||
is rewritten. Retries skip imported dead letters and add only the incremental
|
||||
source finding count. Decreasing counts or changed historical dead letters are
|
||||
conflicts. Verification checks events and the resulting chain independently.
|
||||
|
||||
The new PostgreSQL receiver and attestor follow links rather than sorting by
|
||||
historical timestamps. Deploy that code to all PostgreSQL append/verify workers
|
||||
before importing historical rows into a populated destination; older workers
|
||||
still use timestamp order. Source tests do not authorize a production import.
|
||||
|
|
|
|||
|
|
@ -114,6 +114,19 @@ The response carries a `means` field stating that agreement proves neither
|
|||
completeness nor that any event occurred — because this is the number most
|
||||
likely to be quoted out of context in someone else's conformance argument.
|
||||
|
||||
|
||||
The optional `stream_instance_id` query parameter restricts counts to the exact
|
||||
string stored at `details.data.stream_instance_id`. The response echoes that
|
||||
filter; no filter preserves the existing aggregate response. Empty or repeated
|
||||
instance parameters are refused. Source and tenant authorization still apply,
|
||||
and duplicate deliveries count once. Both SQLite and PostgreSQL implement it.
|
||||
These are **acceptance-time** windows (`since` inclusive, `until` exclusive),
|
||||
not the producer's occurrence-time or sequence windows. A collector/observer
|
||||
must account for drain lag before comparing source-window counters, retain
|
||||
`stream_sequence`, and never compare a restarted process's reset counters with
|
||||
another instance or a lifetime total. Instance isolation alone does not detect
|
||||
sequence gaps or determine whether an instance is active.
|
||||
|
||||
## Declared emission cadence
|
||||
|
||||
`AUDIT-WP-0009-T05`. The contract is info-tech-canon's EmissionCadence
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue