railiance-platform/docs/task-execution-native-fixture.md
codex d870596cc7
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 2s
Verify exact task metadata baseline and readback
Assistant: codex
Assistant-Model: gpt-6-astra
Assistant-Session: 01a140c4-354a-7823-8f0d-8f717397f786
2026-10-16 10:48:21 +02:00

8.4 KiB

Executable native metadata/grant/cleanup preparation

RPF-WP-0035-T12, 2026-10-16, second source package after the cleanup journal.

The fixed NativeFixtureAdapter actually dispatches to disposable loopback OpenBao. It requires a live owner-spawned OpenBao dev-process handle with the exact loopback port and dev/no-store-token arguments, and refuses every non-loopback origin. Production is deliberately not implemented. This is a guard against accidental misrouting inside the trusted fixture runtime, not a Python security sandbox. No estate credentials, grants, approvals or policy packages are read or changed. The tests start in-memory dev servers with synthetic root/session credentials, synthetic owner admission, grant/state/source digests and a synthetic postconsume journal transition. This proves native primitives, not authenticated admission.

The owner Compiler now deterministically includes the operation-specific temporary policy name and cleanup call commitments in each serialized Plan. Commitments include identity/task credential slots, exact native revoke/verify or delete/verify method/path pairs, and the narrow no-issue/no-create skip branches. The full execution descriptor can be bound into that Plan only by byte equality with an independently installed owner descriptor, with operation/actor/CCR/catalogue/six operations correspondence. Compiler revalidation preserves both descriptor and cleanup content. The descriptor's SHA is preparation provenance; no opaque digest or local file becomes approval or verified canonical request correspondence.

The adapter needs the exact compiler/Plan/binding and separately installed owner fixture inputs. All handles stay in owner memory with hidden representations. It requires the same live consumed journal admission and exact grant-issuing state. It refuses an existing per-operation grant policy, creates only the two compiler metadata endpoints plus revoke-self, verifies HCL, mints one parented service token with only this policy, no default/identity policies, nonrenewable TTL <=120 seconds and twelve uses, then verifies native token bounds through the owner. Six ordered metadata calls use independently recompiled source/method/path/body. A task use is reserved for revoke; native token limits also enforce the ceiling. Business calls check wall and monotonic deadlines before effect, with a five-second cleanup reserve. No retry/remint, caller HCL/JSON/path, mount/AppRole/KV/SecretID or shell API exists. Wave 5 below adds exact sequential snapshot acceptance; native baseline CAS remains absent.

Every business/grant request records durable intent and closed status evidence. Native cleanup has its own durable per-request intents beneath the original committed obligation; accessor verification cannot erase an uncertain revoke. The native adapter compares the exact committed cleanup sequence before request. Self-revoke success must be followed by owner lookup-accessor's specific invalid accessor response; generic HTTP400/403, timeout and policy deletion do not prove revocation. The two explicitly accepted error encodings cover OpenBao's plain and wrapped single-invalid-accessor forms. Native error text is never logged or hashed. Cleanup bypasses expired business deadlines under the retained explicit obligation, never source-driven business repair. Independent cleanup continues after failure; retirement never overwrites the original unknown/failed business outcome.

Current actual native tests cover policy/body and K8s-role application/readback, owner-parented TTL/use policy bounds, native sibling/KV/token/mount/SecretID capability denial, both token accessor-invalid proofs, policy absence, deadline-expired cleanup, source drift, no preconsume materialization, changed descriptor/cleanup commitments, nonloopback refusal, actual write followed by simulated lost response, and actual policy retirement with failed task revocation. The lost response is fault injection after a successful real native write; it does not pretend to be an actual network partition. The failed-revoke fixture independently confirms the still-existing native token, then performs explicit synthetic owner recovery. No blind retry occurs.

Minimal remaining decisions and integration

  1. Define/admit task-execution-grant in the owner CCR validator. Bind the exact cleanup commitments, temporary policy/token bodies and source revisions into its immutable projection, referenced by the existing descriptor grant SHA. The descriptor currently has no cleanup field; no engine schema extension is needed if this owner grant binding is made explicit. The immutable projection/excluded append-only fields are not implemented in the current owner validator. This is the concrete owner schema/admission decision, not a need for a new service.
  2. Have the existing authoritative engines supply authenticated initiating principal, exact canonical request + served claim/PDP/package and independent signed CAS consume verification to the owner mediator before its journal transition. The native fixture's local transition supplies none of that evidence.
  3. Install exact origin/cluster/source/grant/baseline/readback inputs under the attended owner runtime. The current binder compares independently installed descriptor bytes, but does not authenticate source-bundle paths, grant digest or compute immutable CCR projection. The six-operation plan still comes from pinned actual owner source. Production origin authentication and deadline bounds against served approval/PDP remain separate.
  4. Finish expected-state normalization and conflict handling for native K8s/OIDC defaults; add per-policy/role approved baseline comparison and exact readback verification. The fixture checks known fields, not total production equality. OpenBao metadata PUT has no native atomic CAS; the owner must choose exclusive admitted target custody or an honest conflict/recovery protocol.
  5. Wire the fixed adapter to that mediator with bounded runtime isolation, owner-private uncertain-issuance recovery, external audit outbox and exact founder-scoped attended trial. No production caller or protected recovery channel exists here. The existing production readiness gate remains refused.

No umbrella broker, general executor, new credential catalogue or standing service admin entitlement is introduced. Approval CAS prevents approval replay; it cannot make uncertain native effects exactly-once. RPF T12 and Secrets WP13 remain open.

Exact disposable metadata acceptance (2026-10-16, wave 5)

The owner-installed FixtureAdmission now carries canonical JSON before/after snapshot bytes. Their SHA-256 values must equal the existing descriptor's expected_before and expected_after, and both snapshots must name exactly the two compiled metadata paths. Explicit JSON null means absence. Only the actual OpenBao empty-errors 404 is accepted as absence; denied/malformed reads fail. These inputs contain metadata, never KV values or private token handles.

Policy comparison retains name, HCL, version and cas_required. Only the modification timestamp is excluded, after requiring an aware timestamp and the closed observed policy field set. Role comparison retains every returned field, including aliases, token defaults and unexpected additions, using canonical JSON bytes (therefore false cannot equal zero). The disposable Kubernetes fixture pins the complete OpenBao 2.5.5 response shape. Another plugin/version/default requires an independently reviewed owner snapshot; nothing infers new accepted defaults.

Each baseline gates its corresponding write. Policy readback occurs before role baseline/write/readback. A role conflict can therefore leave the policy applied; that operation remains unknown. This sequence has no native CAS, aggregate baseline gate, concurrent-writer exclusion, or simultaneous final-state proof. After all six calls match the committed snapshots, the same-live adapter records readback and verified with a value-free evidence digest. The mediator reports native_apply verified; cleanup-confirmed requires all separate cleanup receipts. Readback success with unconfirmed cleanup cannot reach cleanup-confirmed.

Reopening SQLite cannot dispatch, reconsume, restore token/accessor handles or retry cleanup. Native effects can survive process loss. Cleanup handles remain memory-only: no independently authorized recovery mechanism is implemented here. This closes disposable sequential apply acceptance only, not TSA03 or native production recovery/admission.