fix: reject broken runtime launchers and preserve failed proof evidence
Some checks failed
Governed runtime contract / contract (push) Failing after 16s

Assistant: codex
Assistant-Model: gpt-6-astra
Assistant-Session: 01a0e387-534d-70e3-ad53-4ea05676db8c
This commit is contained in:
tegwick 2026-09-27 23:19:50 +02:00
parent 4e666d6fa3
commit 43e621439a
26 changed files with 1367 additions and 3 deletions

View file

@ -0,0 +1,40 @@
{
"observed_at": "2026-09-27T20:01:04.485643+00:00",
"activity_revision": "428f2d71b0f5ade11457e16d7b6341f571f6735f",
"platform_revision": "c3607fffeade70acd361a4757e72a062725cb83a",
"deployment_diff": "worker image only; reuse already deployed API image; API/router/config/schedules unchanged",
"tests": {
"focused_grant_tests_passed": 21,
"queue_repair_guard_tests_passed": 9,
"native_binding_tests_passed": 5,
"actual_image_rule_emission_queue_support": true
},
"argocd": {
"sync": "Synced",
"health": "Healthy",
"phase": "Succeeded"
},
"deployments": [
{
"name": "actcore-api",
"generation": 50,
"observed_generation": 50,
"ready": 1,
"image": "forgejo.coulomb.social/coulomb/activity-core@sha256:713bddad10a41950f446100a8b370fca8ccdd0b8969cccae751e3870c9c63ccd"
},
{
"name": "actcore-worker",
"generation": 63,
"observed_generation": 63,
"ready": 1,
"image": "forgejo.coulomb.social/coulomb/activity-core@sha256:713bddad10a41950f446100a8b370fca8ccdd0b8969cccae751e3870c9c63ccd"
},
{
"name": "actcore-event-router",
"generation": 33,
"observed_generation": 33,
"ready": 1,
"image": "forgejo.coulomb.social/coulomb/activity-core@sha256:cd4e924c2809f0d1d319e53a9ddd20db2e88a1b543d62e6442702c184b7842f4"
}
]
}

View file

@ -0,0 +1,44 @@
[
{
"memo_id": "metered-20260927-provider-apply",
"disposition": "accept",
"approval_id": "0c05bd0a-f81f-451d-840c-5565628e2edc",
"native_submission_state": "confirmed",
"approved_at": "2026-09-27T19:23:59+00:00"
},
{
"memo_id": "metered-20260927-provider-exec",
"disposition": "accept",
"approval_id": "7b32443a-a817-400c-a130-01b9ef04c8ee",
"native_submission_state": "confirmed",
"approved_at": "2026-09-27T19:24:15+00:00"
},
{
"memo_id": "metered-20260927-provider-verify",
"disposition": "accept",
"approval_id": "47f118a3-a86c-43ad-969d-42e09a0f45bb",
"native_submission_state": "confirmed",
"approved_at": "2026-09-27T19:24:32+00:00"
},
{
"memo_id": "metered-20260927-worker-apply",
"disposition": "accept",
"approval_id": "2ce76d7f-01c3-4b63-8476-8d1230679769",
"native_submission_state": "confirmed",
"approved_at": "2026-09-27T19:24:43+00:00"
},
{
"memo_id": "metered-20260927-worker-exec",
"disposition": "accept",
"approval_id": "dc22666a-d5d7-46bc-9490-ebe9fe09dc38",
"native_submission_state": "confirmed",
"approved_at": "2026-09-27T19:24:55+00:00"
},
{
"memo_id": "metered-20260927-worker-verify",
"disposition": "accept",
"approval_id": "c2af4bcf-15b4-4305-aac1-acc7e4dcb099",
"native_submission_state": "confirmed",
"approved_at": "2026-09-27T19:25:10+00:00"
}
]

View file

@ -0,0 +1,12 @@
{
"phase": "failed",
"status": "failed",
"credential_values_emitted": false,
"reader_scope_verified": true,
"kv_version": 1,
"named_owner_images_verified": true,
"remote_exit_code": 1,
"owner_forwards_closed": true,
"failure_type": "ValueError",
"failure_code": "attended_execution_failed"
}

View file

@ -0,0 +1,12 @@
{
"phase": "failed",
"status": "failed",
"credential_values_emitted": false,
"reader_scope_verified": true,
"kv_version": 1,
"named_owner_images_verified": true,
"remote_exit_code": 1,
"owner_forwards_closed": true,
"failure_type": "ValueError",
"failure_code": "attended_execution_failed"
}

View file

@ -0,0 +1,32 @@
{
"0c05bd0a-f81f-451d-840c-5565628e2edc": {
"approval_id": "0c05bd0a-f81f-451d-840c-5565628e2edc",
"valid_now": false,
"consumed": true
},
"47f118a3-a86c-43ad-969d-42e09a0f45bb": {
"approval_id": "47f118a3-a86c-43ad-969d-42e09a0f45bb",
"valid_now": false,
"consumed": true
},
"7b32443a-a817-400c-a130-01b9ef04c8ee": {
"approval_id": "7b32443a-a817-400c-a130-01b9ef04c8ee",
"valid_now": false,
"consumed": true
},
"2ce76d7f-01c3-4b63-8476-8d1230679769": {
"approval_id": "2ce76d7f-01c3-4b63-8476-8d1230679769",
"valid_now": false,
"consumed": true
},
"c2af4bcf-15b4-4305-aac1-acc7e4dcb099": {
"approval_id": "c2af4bcf-15b4-4305-aac1-acc7e4dcb099",
"valid_now": false,
"consumed": true
},
"dc22666a-d5d7-46bc-9490-ebe9fe09dc38": {
"approval_id": "dc22666a-d5d7-46bc-9490-ebe9fe09dc38",
"valid_now": false,
"consumed": true
}
}

View file

@ -0,0 +1,60 @@
{
"status": "failed",
"phase": "one_trigger_started",
"observed_at": "2026-09-27T19:48:11.627308+00:00",
"actions": [
{
"catalog": "glas-claude-agent-dev-anthropic",
"action": "apply",
"approval_id": "0c05bd0a-f81f-451d-840c-5565628e2edc",
"exit_code": 0,
"limits": {
"token_ttl": 300,
"token_max_ttl": 900,
"secret_id_ttl": 300,
"secret_id_num_uses": 1,
"token_num_uses": 8
}
},
{
"catalog": "activity-core-metered-worker-token",
"action": "apply",
"approval_id": "2ce76d7f-01c3-4b63-8476-8d1230679769",
"exit_code": 0,
"limits": {
"token_ttl": 300,
"token_max_ttl": 900,
"secret_id_ttl": 300,
"secret_id_num_uses": 1,
"token_num_uses": 8
}
},
{
"catalog": "glas-claude-agent-dev-anthropic",
"action": "verify",
"approval_id": "47f118a3-a86c-43ad-969d-42e09a0f45bb",
"exit_code": 0,
"sibling_denied": true,
"metadata_denied": true,
"session_revoked": true,
"revoked_lookup_status": 403
},
{
"catalog": "activity-core-metered-worker-token",
"action": "verify",
"approval_id": "c2af4bcf-15b4-4305-aac1-acc7e4dcb099",
"exit_code": 0,
"sibling_denied": true,
"metadata_denied": true,
"session_revoked": true,
"revoked_lookup_status": 403
}
],
"automatic_retry": false,
"trigger": {
"workflow_id": "activity-5bae5505-77f1-5ba3-8dfa-2e10ed15531e:manual-dab6c4c7-db03-4887-a17b-9d99b752482e",
"trigger_key": "manual-dab6c4c7-db03-4887-a17b-9d99b752482e"
},
"failure_type": "ValueError",
"failure_code": "natural_queue_binding_refused"
}

View file

@ -0,0 +1,63 @@
{
"status": "attempt_failed",
"phase": "one_exec_returned",
"observed_at": "2026-09-27T20:01:30.849242+00:00",
"actions": [
{
"catalog": "glas-claude-agent-dev-anthropic",
"action": "exec",
"approval_id": "7b32443a-a817-400c-a130-01b9ef04c8ee",
"exit_code": 1
},
{
"catalog": "activity-core-metered-worker-token",
"action": "exec",
"approval_id": "dc22666a-d5d7-46bc-9490-ebe9fe09dc38",
"exit_code": 1
}
],
"automatic_retry": false,
"prior_receipt": "execution.json",
"completed_actions_not_replayed": [
"provider/apply",
"worker/apply",
"provider/verify",
"worker/verify",
"queue/trigger"
],
"trigger": {
"workflow_id": "activity-5bae5505-77f1-5ba3-8dfa-2e10ed15531e:manual-dab6c4c7-db03-4887-a17b-9d99b752482e",
"trigger_key": "manual-dab6c4c7-db03-4887-a17b-9d99b752482e"
},
"queued_run": {
"id": "6efa9436-6a91-47c0-94e5-b31b5a0e7e3a",
"state": "open",
"attempt": 0,
"claim_owner": null,
"target_repo": "hfact-glas-proof",
"harness_profile_ref": "harness.agent-dev-local@1.1.1",
"repository_grant": {
"publish": false,
"version": "1",
"commit_count": {
"max": 1,
"min": 1
},
"allowed_paths": [
"PROOF.md"
]
},
"triggering_event_id": "manual-dab6c4c7-db03-4887-a17b-9d99b752482e"
},
"exec_exit_code": 1,
"owner_results": [
{
"ok": false,
"claimed": true,
"empty": false,
"run_id": "6efa9436-6a91-47c0-94e5-b31b5a0e7e3a",
"ops_state": "failed"
}
],
"private_runtime_removed": true
}

View file

@ -0,0 +1,39 @@
{
"runtime_sha256": "b6e4e8a429393d68831c996a65c0489664205df969ac9882e581983ec2da4969",
"repository_head": "679d23e0517707ba63e25399b5262f0d2f37315d",
"repository_clean": true,
"repository_lock_available": true,
"sandbox": {
"sandbox_id": "b67907f1",
"state": "destroyed",
"created_at": "2026-09-27T20:01:43.835992Z",
"destroyed_at": "2026-09-27T20:01:45.650937Z"
},
"removed_paths": {
"workspace_dir": true
},
"private_credential_directories_remaining": 0,
"close_outbox_pending": 0,
"close_outbox_quarantined": 0,
"spend_reservations": [
{
"run_id": "6efa9436-6a91-47c0-94e5-b31b5a0e7e3a",
"definition_id": "5bae5505-77f1-5ba3-8dfa-2e10ed15531e",
"idempotency_key": "5bae5505-77f1-5ba3-8dfa-2e10ed15531e:execute-hfact-glas-metered-proof:manual-dab6c4c7-db03-4887-a17b-9d99b752482e",
"attempt": 1,
"state": "held",
"liability": 10000000,
"start_day": "2026-09-27",
"end_day": null,
"observed_usd": null,
"receipt": null
}
],
"provider_request_reservations": [],
"request_routes": [
{
"run_id": "6efa9436-6a91-47c0-94e5-b31b5a0e7e3a",
"revoked": 1
}
]
}

View file

@ -0,0 +1,27 @@
{
"status": "applied",
"observed_at": "2026-09-27T19:59:50.642053+00:00",
"worker_pod": "actcore-worker-659497dcf9-rvf4h",
"worker_image": "sha256:713bddad10a41950f446100a8b370fca8ccdd0b8969cccae751e3870c9c63ccd",
"run_id": "6efa9436-6a91-47c0-94e5-b31b5a0e7e3a",
"definition_id": "5bae5505-77f1-5ba3-8dfa-2e10ed15531e",
"definition_version": 1,
"triggering_event_id": "manual-dab6c4c7-db03-4887-a17b-9d99b752482e",
"source": "typed_existing_definition_rule",
"grant_id": "656911f7dff83e871434b415f0cee685",
"grant": {
"version": "1",
"allowed_paths": [
"PROOF.md"
],
"commit_count": {
"min": 1,
"max": 1
},
"publish": false
},
"attempt": 0,
"claim_owner": null,
"new_trigger": false,
"new_task": false
}

View file

@ -0,0 +1,20 @@
{
"status": "installed",
"observed_at": "2026-09-27T19:39:35.079399+00:00",
"old_counts": {
"reservations": 0,
"request_routes": 0,
"request_reservations": 0
},
"old_ledger_preserved": true,
"new_ledger": "/home/tegwick/hfact/owner-metered/spend-tool-proof-renewal-20260927.sqlite3",
"old_dispatch_pins_retired": true,
"owner_check": {
"ok": true,
"check_only": true,
"dispatch_enabled": false,
"policy_sha256": "de3d01c9f4753994e8f73c111cde328a649e05dbb2563c37b5c12d86a488b2fa",
"runtime_sha256": "b6e4e8a429393d68831c996a65c0489664205df969ac9882e581983ec2da4969"
},
"dispatches": 0
}

View file

@ -0,0 +1,109 @@
{
"source": "railiance01/native-metered-20260927/native-evidence; allowlisted fields only",
"native_records": [
{
"action": "apply",
"catalog_id": "glas-claude-agent-dev-anthropic",
"result": "applied",
"record_id": "53136c39-5fb6-4f61-8d73-231c5d0fe57d",
"detail": {
"approval_consumed": true,
"approval_id": "0c05bd0a-f81f-451d-840c-5565628e2edc",
"approval_consume_idempotent": false
}
},
{
"action": "apply",
"catalog_id": "activity-core-metered-worker-token",
"result": "applied",
"record_id": "f218efea-a990-4393-a99c-e405050a349e",
"detail": {
"approval_consumed": true,
"approval_id": "2ce76d7f-01c3-4b63-8476-8d1230679769",
"approval_consume_idempotent": false
}
},
{
"action": "verify",
"catalog_id": "glas-claude-agent-dev-anthropic",
"result": "pass",
"record_id": "9a3347b1-9b1c-42a1-a504-ce791fdf1215",
"detail": {
"approval_consumed": true,
"approval_id": "47f118a3-a86c-43ad-969d-42e09a0f45bb",
"approval_consume_idempotent": false
}
},
{
"action": "verify",
"catalog_id": "activity-core-metered-worker-token",
"result": "pass",
"record_id": "43517ef4-ab0e-47c4-ae96-4284a6f67b2e",
"detail": {
"approval_consumed": true,
"approval_id": "c2af4bcf-15b4-4305-aac1-acc7e4dcb099",
"approval_consume_idempotent": false
}
},
{
"action": "exec",
"catalog_id": "activity-core-metered-worker-token",
"result": "exit-1",
"record_id": "7b3f492c-cf80-4e4d-8158-7e4504b136ca",
"detail": {
"approval_consumed": true,
"approval_id": "dc22666a-d5d7-46bc-9490-ebe9fe09dc38",
"approval_consume_idempotent": false,
"session": {
"established": true,
"revocation_attempted": true,
"revocation_succeeded": true,
"session_handle": "a0f9a121b064"
},
"companion_of": "glas-claude-agent-dev-anthropic",
"exec_owner_sha256": "310600eab467ed79fc3851178a065de12d57d3ada5bcf68d9c364ed11b3ee50f"
}
},
{
"action": "exec",
"catalog_id": "glas-claude-agent-dev-anthropic",
"result": "exit-1",
"record_id": "1b6fabda-dbe5-4fe3-a74e-b9abf62050c1",
"detail": {
"approval_consumed": true,
"approval_id": "7b32443a-a817-400c-a130-01b9ef04c8ee",
"approval_consume_idempotent": false,
"session": {
"established": true,
"revocation_attempted": true,
"revocation_succeeded": true,
"session_handle": "d7e5f59e383d"
},
"companions": [
"activity-core-metered-worker-token"
],
"exec_owner_sha256": "310600eab467ed79fc3851178a065de12d57d3ada5bcf68d9c364ed11b3ee50f"
}
}
],
"terminal_queue": {
"id": "6efa9436-6a91-47c0-94e5-b31b5a0e7e3a",
"state": "failed",
"attempt": 1,
"claim_owner": "rein-aharness-metered@railiance01",
"lease_until": null
},
"verification": {
"full_suite": "406 passed, 9 skipped",
"focused_owner_claim_spend_glas": "99 passed (includes new close-evidence test)",
"native_procedure_and_queue_guards": "14 passed",
"sandbox_builder": "12 passed",
"activity_core_grant": "21 passed"
},
"remaining": {
"workplan": "blocked",
"parent_eur_reservation": "10.00 held; observed USD unknown",
"retry_authorized": false,
"corrected_artifact_admitted": false
}
}

View file

@ -0,0 +1,97 @@
# Attended disposable proof — 2026-09-27
Existing work: REINAH-WP-0003-T05/T06 and SECRETS-WP-0009-T03.
No new workplan, publication, automatic retry, or factory operating admission.
The operator accepted replacement spend memo `infd-20260927-b02`, confirmed
USD 10 including tax/conversion fees fits EUR 10, and accepted all six
`metered-20260927-{provider,worker}-{apply,verify,exec}` decisions. Native
submission confirmations and replacement host installation are separate receipts
in `docs/evidence/2026-09-27-metered-*.json`. The earlier expired spend grant is
preserved and never used.
`scripts/metered-native-owner.py` checks the frozen six-request packet and exact
recipient files before native claim/PDP checks. The provider's human-control
flag and the worker companion's ordinary flag remain unchanged. Apply and
verify each consume their own native approval before OpenBao effects. Exec
uses the existing Secrets Engine primary/companion consume and delivery code;
the procedure does not manufacture decisions, claims, or delivery state.
The attended workstation wrapper `scripts/attended-metered-proof.py` follows
the existing scoped approval-client reader and nested platform-admin OIDC
procedure. The operator-controlled SSH session runs the controller on Railiance
because the approved command and owner-file bindings name that host. Client
secret, short-lived operator/negative-test tokens and PDP caller token cross
encrypted SSH stdin only. The host uses a fresh owner-only temporary directory
on `/run/user/1000` tmpfs. Approval bearer tokens are minted in memory. No
cluster reader, persistent service, credential rotation or new custody path is
created. Warden self-revokes both attended sessions; private files and the
named-pod forwarding processes are removed on normal exit, including failure.
The delivered model child receives only its catalog-bound environment plus
its separately approved provider and worker credentials.
Before activation, the installer locks and checks all three old ledger tables,
refusing any prior reservation or liability. It preserves the old ledger and
backs up both old configuration files. A new private ledger is initialized
without resetting old evidence. Replacement file hashes retire dispatch using
the old catalog pins. The immutable runtime's backend-free owner check passes.
The single trigger occurs after both lanes verify. The controller waits for
exactly one open, unclaimed, attempt-zero task with the admitted profile and
one-file/one-commit/no-publication grant. It records trigger and exec intent
before either action. An existing execution receipt refuses all replays,
including uncertain/failed attempts. The scheduled definition stays disabled.
The approved maximum request hold remains USD 4.64; at most two such holds fit
the USD 10 liability cap. The [provider tariff](https://platform.claude.com/docs/en/about-claude/pricing)
was rechecked immediately before activation: Sonnet 5 global standard output is
USD 10/million tokens; the conservative input bound of USD 4/million covers
one-hour cache writes. The proof has no authority to enlarge these limits.
After interruption, inspect the durable local/remote receipts and native
consume state before any further action. Explicitly reconcile remaining
`metered-native-*` / `metered-attended-*` private runtime directories and any
open queue item; never rerun the command as a cleanup strategy. Hard-kill
cleanup is not claimed by this wrapper. Provider-request reservations remain
conservative until reconciled. T04's tenant migrations and broader T06
acceptance requirements remain in the existing workplan.
## Actual execution and corrections
All six decisions were accepted and consumed once. Both lane apply/verify
operations passed; exec delivered through two AppRole sessions whose revocation
succeeded. The single definition trigger initially produced a row with no grant:
the deployed Activity Core worker predated the API's grant-carriage support.
Activity Core `428f2d7` and Platform `c3607ff` changed only the worker image to
the already-deployed grant-aware API image through the existing GitOps parent
and child applications. Argo reports Synced/Healthy/Succeeded.
The explicit repair script validates and locks the original disabled definition
and original open, unclaimed, attempt-zero job. It copies only the exact typed
grant from that definition; it creates no row or trigger. Nine negative/positive
guard tests pass. This repair is recorded separately and is not represented as
successful natural grant carriage by the old producer.
The `resume` mode is limited to that recorded pre-execution queue-binding failure.
It verifies the four completed native actions, installed policies/role limits,
zero prior request/reservation counts, and the same repaired job. It repeats
neither apply/verify nor queue creation. Both remaining exec approvals were then
consumed. There is no further resume path for the attempted job.
Job `6efa9436-6a91-47c0-94e5-b31b5a0e7e3a` closed `failed`, attempt 1, with its
lease cleared. Its installed Python launchers still referenced a deleted build
directory: uv's long-path shell trampoline had escaped the builder's direct
shebang rewrite. A no-credential synthetic probe reproduced exit 127 for both
launchers inside the actual pinned bwrap artifact, with zero provider forwards.
The runtime builder correction is Sand-boxer `81b5fcf`; relocation tests execute
after the old build directory disappears. Rein now also rejects these launchers
before claim and retains bounded gateway stage/cleanup facts on accounting refusal.
The approved artifact itself remains unchanged. Sandbox `b67907f1` and its
workspace are destroyed; the repository is clean at its original commit, the
lock is available, and no close-outbox item or private credential directory is
left over. The request route is revoked and there are no provider-request
reservations. The parent EUR 10 reservation remains held; observed billing was
not invented and the ledger was not reset. A corrected artifact and its changed
pins need admission, held-liability reconciliation remains an owner action, and
another attempt requires separate authority. REINAH-WP-0003 stays blocked.

View file

@ -47,6 +47,9 @@ profile/descriptor digests, operational readiness, model, empty-egress bwrap pro
and runtime digest are checked before claim. Runtime, owner state and target checkout and runtime digest are checked before claim. Runtime, owner state and target checkout
must not overlap. Provision parent and request ledgers as separate reviewed actions. must not overlap. Provision parent and request ledgers as separate reviewed actions.
The normal ACTIVITY_CORE/AGENT_HARNESS worker and state configuration still applies. The normal ACTIVITY_CORE/AGENT_HARNESS worker and state configuration still applies.
The governed Python console launchers must be executable regular files naming
`/opt/sandboxer/runtime/bin/python3`, rather than a build-host interpreter.
The installed bwrap proof also runs their `--help` commands before any model request.
This config is not an authorization decision or a custody provenance proof. The This config is not an authorization decision or a custody provenance proof. The
invoking credential engine must already have passed its exact action approval, invoking credential engine must already have passed its exact action approval,

View file

@ -627,6 +627,8 @@ def _process_profiled_run_active(
except GlasExecutionError as exc: except GlasExecutionError as exc:
execution_error = type(exc).__name__ execution_error = type(exc).__name__
execution_reason = str(exc) if isinstance(exc, GlasSpendError) else "profiled execution failed (GlasExecutionError)" execution_reason = str(exc) if isinstance(exc, GlasSpendError) else "profiled execution failed (GlasExecutionError)"
if isinstance(exc, GlasSpendError):
safe_evidence = exc.execution_evidence
if tx is not None and tx.baseline is not None: if tx is not None and tx.baseline is not None:
tx_evidence = tx.evidence() tx_evidence = tx.evidence()

View file

@ -66,6 +66,16 @@ class GlasExecutionError(RuntimeError):
class GlasSpendError(GlasExecutionError): class GlasSpendError(GlasExecutionError):
"""Spend refusal with bounded, operator-safe reason text.""" """Spend refusal with bounded, operator-safe reason text."""
def __init__(self, message: str, *, execution_evidence: Any = None) -> None:
super().__init__(message)
evidence = normalise_execution_evidence_for_close(execution_evidence)
# Accounting must remain fail-closed without erasing the gateway stage
# and cleanup facts. Do not transport raw provider error/output here.
self.execution_evidence = {
key: value for key, value in evidence.items()
if key not in {"error", "artifacts"}
}
def normalise_execution_evidence_for_close(raw: Any) -> dict[str, Any]: def normalise_execution_evidence_for_close(raw: Any) -> dict[str, Any]:
"""Retain only bounded Glas evidence fields safe for durable close state.""" """Retain only bounded Glas evidence fields safe for durable close state."""
@ -85,6 +95,10 @@ def normalise_execution_evidence_for_close(raw: Any) -> dict[str, Any]:
and value >= 0 and value >= 0
): ):
result[key] = value result[key] = value
for key in ("session_cleanup", "sandbox_destroy"):
value = raw.get(key)
if isinstance(value, str) and value in {"succeeded", "failed", "not_attempted"}:
result[key] = value
artifacts = raw.get("artifacts") artifacts = raw.get("artifacts")
if isinstance(artifacts, list): if isinstance(artifacts, list):
result["artifacts"] = [ result["artifacts"] = [
@ -220,7 +234,10 @@ def execute_profiled_run(
if not spend.observe(run.id, raw): if not spend.observe(run.id, raw):
raise SpendAdmissionError("execution accounting requires reconciliation") raise SpendAdmissionError("execution accounting requires reconciliation")
except SpendAdmissionError as exc: except SpendAdmissionError as exc:
raise GlasSpendError(f"spend accounting refused: {exc}") from None raise GlasSpendError(
f"spend accounting refused: {exc}",
execution_evidence=raw["evidence"],
) from None
if transfer is not None and raw["ok"]: if transfer is not None and raw["ok"]:
evidence = raw["evidence"] evidence = raw["evidence"]
if evidence.get("session_cleanup") != "succeeded" or evidence.get("sandbox_destroy") != "succeeded": if evidence.get("session_cleanup") != "succeeded" or evidence.get("sandbox_destroy") != "succeeded":

View file

@ -25,7 +25,7 @@ class BootstrapRefused(RuntimeError):
def prepare(path: Path, config: OpsRunConfig) -> tuple[MessagesPolicy, Path, str]: def prepare(path: Path, config: OpsRunConfig) -> tuple[MessagesPolicy, Path, str]:
"""Validate value-free, owner-controlled pins without a key or queue claim.""" """Validate value-free, owner-controlled pins without a key or queue claim."""
from glas_harness.profiles import ProfileCatalog from glas_harness.profiles import ProfileCatalog
from sandboxer.extensions.runtime import verified_runtime from sandboxer.extensions.runtime import RUNTIME_MOUNT, verified_runtime
try: try:
_private_file(path) _private_file(path)
if not path.is_absolute() or path.resolve() != path or path.stat().st_size > 65536: if not path.is_absolute() or path.resolve() != path or path.stat().st_size > 65536:
@ -64,6 +64,15 @@ def prepare(path: Path, config: OpsRunConfig) -> tuple[MessagesPolicy, Path, str
runtime = verified_runtime({"runtime": data["runtime"]}) runtime = verified_runtime({"runtime": data["runtime"]})
if runtime is None or not runtime.is_absolute() or runtime.resolve() != runtime: if runtime is None or not runtime.is_absolute() or runtime.resolve() != runtime:
raise ValueError raise ValueError
# A matching artifact digest does not prove its generated launchers
# survived relocation. Refuse build-host interpreters before claiming.
for name in ("rein-aharness", "glas-harness"):
executable = runtime / "bin" / name
if executable.is_symlink() or not executable.is_file() or not os.access(executable, os.X_OK):
raise ValueError
with executable.open("rb") as stream:
if stream.readline(4096) != f"#!{RUNTIME_MOUNT}/bin/python3\n".encode():
raise ValueError
for private in (path.parent, spend.path.parent, Path(spend.policy.target_repo)): for private in (path.parent, spend.path.parent, Path(spend.policy.target_repo)):
a, b = runtime.resolve(), private.resolve() a, b = runtime.resolve(), private.resolve()
if a.is_relative_to(b) or b.is_relative_to(a): if a.is_relative_to(b) or b.is_relative_to(a):

View file

@ -0,0 +1,140 @@
"""Contained workstation login envelope for the exact Railiance native proof.
Run the reader through Warden. Both attended sessions self-revoke. Values stay
in private tmpfs / process memory and encrypted SSH stdin; output is suppressed.
"""
import importlib.util
import json
import os
from pathlib import Path
import socket
import subprocess
import sys
import tempfile
import time
from urllib.request import Request, build_opener, ProxyHandler, HTTPRedirectHandler
ROOT = Path("/home/worsch/rein-aharness")
PLATFORM = Path("/home/worsch/railiance-platform")
PYTHON = "/home/worsch/secrets-engine/.venv/bin/python"
REMOTE = "/home/tegwick/hfact/native-metered-20260927"
KUBE = ["kubectl", "--kubeconfig", "/home/worsch/.kube/config-railiance01"]
RECEIPT = ROOT / "docs/evidence/2026-09-27-metered-attended-execution.json"
RESUME = len(sys.argv) > 1 and sys.argv[1] in ("reader-resume", "admin-resume")
if RESUME:
RECEIPT = ROOT / "docs/evidence/2026-09-27-metered-attended-resume.json"
spec = importlib.util.spec_from_file_location("native", ROOT / "scripts/metered-native-owner.py")
native = importlib.util.module_from_spec(spec)
spec.loader.exec_module(native)
require, private, run, write_new = native.require, native.private, native.run, native.write_new
class NoRedirect(HTTPRedirectHandler):
def redirect_request(self, *args, **kwargs):
return None
def receipt(phase, **fields):
data = json.loads(RECEIPT.read_text()) if RECEIPT.exists() else {}
data.update(phase=phase, **fields)
RECEIPT.write_text(json.dumps(data, indent=2) + "\n")
def helper():
require(Path.home().parent.name == ".warden-attended-login" and not os.getenv("BAO_TOKEN") and not os.getenv("VAULT_TOKEN"), "attended_containment_required")
path = Path.home() / ".vault-token"
private(path)
return path
def reader():
require(not RECEIPT.exists(), "prior_session_requires_reconciliation")
receipt("reader_preflight", status="in_progress", credential_values_emitted=False)
token_file = helper()
spec = importlib.util.spec_from_file_location("reader", PLATFORM / "scripts/approval-client-reader-preflight.py")
pre = importlib.util.module_from_spec(spec)
spec.loader.exec_module(pre)
pre.validate_identity(pre.bao("token", "lookup", "-format=json")["data"])
for path, expected in pre.EXPECTED.items():
require(sorted(pre.bao("token", "capabilities", "-format=json", path)) == expected, "reader_scope_failed")
runtime = Path("/run/user") / str(os.getuid())
private(runtime, True)
require(run(["findmnt", "-n", "-o", "FSTYPE", "-T", str(runtime)]) == "tmpfs", "private_tmpfs_required")
with tempfile.TemporaryDirectory(prefix="metered-attended-", dir=runtime) as name:
directory = Path(name)
req = Request("http://127.0.0.1:18200/v1/platform/data/workloads/secrets-engine/approval-client?version=1", headers={"X-Vault-Token": token_file.read_text().strip()})
with build_opener(ProxyHandler({}), NoRedirect()).open(req, timeout=20) as response:
raw = response.read(65537)
require(len(raw) <= 65536, "credential_response_bound")
data = json.loads(raw)
require(data["data"]["metadata"]["version"] == 1, "custody_version_drift")
value = data["data"]["data"]["CLIENT_SECRET"]
require(isinstance(value, str) and 0 < len(value) <= 16384, "credential_invalid")
write_new(directory / "client-secret", value)
del value, raw, data, req
receipt("attended_admin_login", reader_scope_verified=True, kv_version=1)
result = subprocess.run(["python3", str(PLATFORM / "scripts/openbao-attended-exec.py"), "--", PYTHON, "-B", str(Path(__file__).resolve()), "admin-resume" if RESUME else "admin", str(directory), str(token_file)], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, timeout=780)
require(result.returncode == 0, "attended_execution_failed")
receipt("attended_sessions_completed", status="completed", local_private_runtime_removed=True)
def admin(directory, negative):
admin_file = helper()
private(directory, True)
private(directory / "client-secret")
private(negative)
forwards = []
payload = {}
try:
for namespace, label, image, port in (("approval-engine", "approval-engine", "251941a5cb2724b57cc32cff6b693b1ab0be695bee4f56f02d51961189c0fa49", 19281), ("flex-auth", "flex-auth-secrets-engine", "05a03a8790c2210c48ea92391441c77ddf640d0cd32f5ec09838f5393171fcbd", 19282)):
pods = json.loads(run(KUBE + ["-n", namespace, "get", "pods", "-l", "app.kubernetes.io/name=" + label, "-o", "json"]))["items"]
require(len(pods) == 1, "single_owner_pod_required")
pod = pods[0]
require(any(c.get("ready") and c.get("imageID", "").endswith("@sha256:" + image) for c in pod.get("status", {}).get("containerStatuses", [])), "native_image_pin_drift")
forwards.append(subprocess.Popen(KUBE + ["-n", namespace, "port-forward", "pod/" + pod["metadata"]["name"], str(port) + ":8080", "--address=127.0.0.1"], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL))
for port in (19281, 19282):
for _ in range(50):
require(all(p.poll() is None for p in forwards), "native_forward_failed")
try:
with socket.create_connection(("127.0.0.1", port), timeout=.2):
break
except OSError:
time.sleep(.1)
else:
raise ValueError("native_forward_not_ready")
bridge = subprocess.Popen(["ssh", "-N", "-o", "ExitOnForwardFailure=yes", "-R", "127.0.0.1:28200:127.0.0.1:18200", "-R", "127.0.0.1:28281:127.0.0.1:19281", "-R", "127.0.0.1:28282:127.0.0.1:19282", "railiance01"], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
forwards.append(bridge)
time.sleep(1)
require(bridge.poll() is None, "ssh_bridge_failed")
payload = dict(client_secret=(directory / "client-secret").read_text(), negative_token=negative.read_text().strip(), backend_token=admin_file.read_text().strip(), pdp_token=run(KUBE + ["-n", "secrets-engine", "create", "token", "secrets-engine", "--audience=flex-auth", "--duration=10m"]))
receipt("remote_native_execution_started", named_owner_images_verified=True)
result = subprocess.run(["ssh", "railiance01", "env", "PATH=/home/tegwick/.local/bin:/usr/local/bin:/usr/bin:/bin", "PYTHONPATH=/home/tegwick/secrets-engine/src", "/home/tegwick/secrets-engine/.venv/bin/python", "-B", REMOTE + "/metered-native-owner.py", "resume" if RESUME else "execute", REMOTE], input=json.dumps(payload), text=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, timeout=650)
payload.clear()
receipt("remote_native_execution_returned", remote_exit_code=result.returncode)
require(result.returncode == 0, "remote_native_execution_failed")
finally:
payload.clear()
for process in reversed(forwards):
process.terminate()
try:
process.wait(timeout=5)
except subprocess.TimeoutExpired:
process.kill()
process.wait()
receipt("native_transport_closed", owner_forwards_closed=True)
if __name__ == "__main__":
try:
if sys.argv[1:] in (["reader"], ["reader-resume"]):
reader()
elif len(sys.argv) == 4 and sys.argv[1] in ("admin", "admin-resume"):
admin(Path(sys.argv[2]), Path(sys.argv[3]))
else:
raise ValueError("unsupported_mode")
except Exception as error:
fields = {"status": "failed", "failure_type": type(error).__name__}
if type(error) is ValueError and str(error).replace("_", "").isalnum():
fields["failure_code"] = str(error)
receipt("failed", **fields)
raise SystemExit(1) from None

View file

@ -0,0 +1,347 @@
"""Single attended, non-retrying Railiance proof under the six frozen approvals.
Non-secret bundle is staged separately. Credentials arrive only on SSH stdin,
live in owner-only tmpfs for this process, and never enter the bound child except
through Secrets Engine's approved provider/worker delivery.
"""
from __future__ import annotations
import argparse
import contextlib
import copy
import hashlib
import io
import json
import os
from pathlib import Path
import sqlite3
import stat
import subprocess
import sys
import tempfile
import time
from datetime import datetime, timezone
from dataclasses import replace
PACKET_SHA = "22e640428e3a7ae8fc2363cf193db98381cd94e4be7ab009bc6703658d6fc544"
PROVIDER = "glas-claude-agent-dev-anthropic"
WORKER = "activity-core-metered-worker-token"
IDS = {
PROVIDER: dict(apply="0c05bd0a-f81f-451d-840c-5565628e2edc", verify="47f118a3-a86c-43ad-969d-42e09a0f45bb", exec="7b32443a-a817-400c-a130-01b9ef04c8ee"),
WORKER: dict(apply="2ce76d7f-01c3-4b63-8476-8d1230679769", verify="c2af4bcf-15b4-4305-aac1-acc7e4dcb099", exec="dc22666a-d5d7-46bc-9490-ebe9fe09dc38"),
}
LIMITS = dict(token_ttl=300, token_max_ttl=900, secret_id_ttl=300, secret_id_num_uses=1, token_num_uses=8)
OWNER = Path("/home/tegwick/hfact/owner-metered")
TARGET = Path("/home/tegwick/hfact/targets/hfact-glas-proof")
BASE_HEAD = "679d23e0517707ba63e25399b5262f0d2f37315d"
OLD_FILES = {"owner.json": "e0d3fb84649fdca302eccd9415f3cc2beaee84bf07bd83205cdffbe93e5573bc", "spend-policy.json": "f31c585916de1ea8bd8e48c72421803dfde1015e6201704b9320f77d2c545d9c"}
DEFINITION = "5bae5505-77f1-5ba3-8dfa-2e10ed15531e"
RECEIPT_NAME = "execution.json"
def require(value, code):
if not value:
raise ValueError(code)
def private(path, directory=False):
s = path.lstat()
require(s.st_uid == os.getuid() and stat.S_IMODE(s.st_mode) == (0o700 if directory else 0o600) and (stat.S_ISDIR(s.st_mode) if directory else stat.S_ISREG(s.st_mode)), "private_path_required")
def write_new(path, value):
fd = os.open(path, os.O_CREAT | os.O_EXCL | os.O_WRONLY | os.O_NOFOLLOW, 0o600)
with os.fdopen(fd, "w") as stream:
stream.write(value)
stream.flush()
os.fsync(stream.fileno())
def run(args):
p = subprocess.run(args, capture_output=True, text=True, timeout=30)
require(p.returncode == 0, "metadata_command_failed")
return p.stdout.strip()
def save(bundle, receipt):
path = bundle / RECEIPT_NAME
temp = path.with_suffix(".tmp")
temp.write_text(json.dumps(receipt, indent=2) + "\n")
temp.chmod(0o600)
temp.replace(path)
def queue_rows():
# Read-only owner metadata via the existing authenticated cluster transport.
code = '''import asyncio,json
from activity_core.db import make_engine
from sqlalchemy import text
async def main():
e=make_engine()
async with e.connect() as c:
rows=await c.execute(text("SELECT id,state,attempt,claim_owner,target_repo,harness_profile_ref,repository_grant,triggering_event_id FROM ops_runs WHERE activity_definition_id='5bae5505-77f1-5ba3-8dfa-2e10ed15531e' OR labels @> '[\\\"hfact-metered\\\"]'::jsonb"))
print(json.dumps([dict(x) for x in rows.mappings()],default=str))
await e.dispose()
asyncio.run(main())'''
return json.loads(run(["/usr/local/bin/kubectl", "-n", "activity-core", "exec", "deploy/actcore-api", "--", "python", "-c", code]))
def install_host(bundle):
"""Run with the immutable admitted runtime; preserve every old ledger byte."""
from rein_aharness.spend_admission import SpendLedger, SpendPolicy
from rein_aharness.request_admission import RequestLedger
import yaml
private(OWNER, True)
require(not (bundle / "installation.json").exists(), "prior_installation_requires_reconciliation")
require(not queue_rows(), "metered_queue_not_empty")
require(run(["git", "-C", str(TARGET), "rev-parse", "HEAD"]) == BASE_HEAD and not run(["git", "-C", str(TARGET), "status", "--porcelain"]), "target_not_pristine")
for filename, expected in OLD_FILES.items():
private(OWNER / filename)
require(hashlib.sha256((OWNER / filename).read_bytes()).hexdigest() == expected, "old_host_pin_drift")
candidate = yaml.safe_load((bundle / "catalog" / (PROVIDER + ".yaml")).read_text())["delivery_config"]["exec_owner"]
for filename in OLD_FILES:
require(hashlib.sha256((bundle / filename).read_bytes()).hexdigest() == candidate["files"][str(OWNER / filename)]["sha256"], "candidate_pin_drift")
old = OWNER / "spend.sqlite3"
private(old)
db = sqlite3.connect(old)
try:
db.execute("BEGIN EXCLUSIVE")
counts = {table: db.execute("SELECT count(*) FROM " + table).fetchone()[0] for table in ("reservations", "request_routes", "request_reservations")}
require(not any(counts.values()), "prior_liabilities_require_reconciliation")
policy = SpendPolicy.load(bundle / "spend-policy.json")
ledger = SpendLedger(Path(candidate["environment"]["AGENT_HARNESS_SPEND_LEDGER"]), policy)
require(not ledger.path.exists(), "new_ledger_already_exists")
for filename in OLD_FILES:
write_new(OWNER / (filename + ".pre-renewal-20260927"), (OWNER / filename).read_text())
ledger.initialize()
RequestLedger(ledger).initialize()
for filename in OLD_FILES:
staged = OWNER / (filename + ".renewal-staged")
write_new(staged, (bundle / filename).read_text())
staged.replace(OWNER / filename)
# Changing both pins retires the old catalog's dispatch. There is no
# active metered worker; old ledger and files remain preserved.
check = subprocess.run([*candidate["command"], "--check"], env=candidate["environment"], cwd=candidate["cwd"], capture_output=True, text=True, timeout=30)
require(check.returncode == 0, "installed_owner_check_failed")
receipt = dict(status="installed", observed_at=datetime.now(timezone.utc).isoformat(), old_counts=counts, old_ledger_preserved=True, new_ledger=str(ledger.path), old_dispatch_pins_retired=True, owner_check=json.loads(check.stdout), dispatches=0)
write_new(bundle / "installation.json", json.dumps(receipt, indent=2) + "\n")
finally:
db.rollback()
db.close()
def prepare_configs(bundle, private_dir, trust=None):
import yaml
from secrets_engine.config import Config
from secrets_engine.catalog import get_entry
from secrets_engine.approval_consume import _expected_request
packet = (bundle / "native-pdp-inputs.json").read_bytes()
require(hashlib.sha256(packet).hexdigest() == PACKET_SHA, "frozen_packet_drift")
data = json.loads(packet)
rows = data if isinstance(data, list) else data["requests"]
expected = {(r["catalog"], r["action"]): r["request"] for r in rows}
require(set(expected) == {(lane, action) for lane in IDS for action in IDS[lane]}, "six_exact_requests_required")
configs, entries = {}, {}
for action in ("apply", "verify", "exec"):
folder = private_dir / action
folder.mkdir(mode=0o700)
for lane in IDS:
doc = yaml.safe_load((bundle / "catalog" / (lane + ".yaml")).read_text())
doc = copy.deepcopy(doc)
doc["approval"]["authorization_id"] = IDS[lane][action]
write_new(folder / (lane + ".yaml"), yaml.safe_dump(doc, sort_keys=False))
cfg = replace(Config.load(), catalog_dir=folder, evidence_dir=bundle / "native-evidence", hub_url="", bao_addr="http://127.0.0.1:28200", approval_url="http://127.0.0.1:28281", approval_token_file=None, approval_client_secret_file=private_dir / "client-secret", keycape_token_url="https://kc.coulomb.social/token", keycape_issuer="https://kc.coulomb.social", keycape_client_secret_file=None, openbao_jwt_login_file=None, authorization_subject_id="secrets-engine", authorization_subject_type="service", authorization_policy_package="secrets-engine.catalog-lane.lifecycle", authorization_policy_version="v2", authorization_min_approvals=1, pdp_url="http://127.0.0.1:28282", pdp_token_file=private_dir / "pdp-caller", clock_trust_file=trust)
configs[action] = cfg
for lane in IDS:
entry = get_entry(folder, lane)
actual = _expected_request(cfg, entry, action, fields=() if action == "apply" else tuple(entry.fields), policy_targets=(entry.policy_name,), auth_targets=(entry.role_name,))
require(actual == expected[lane, action], "frozen_action_request_drift")
entries[lane, action] = entry
return configs, entries
def clock_admission(bundle, directory):
from railiance_clock.admission import admit
from urllib.request import urlopen
custody = json.loads((bundle / "clock-public.json").read_text())
require(hashlib.sha256(custody["public_key_pem"].encode()).hexdigest() == "bd583446b5ed61d086806b2a0c5aaf33a875b751e45599e75335d1f415be609a", "clock_key_drift")
with urlopen("http://127.0.0.1:8787/healthz", timeout=5) as response:
epoch = json.load(response)["epoch"]
require(epoch == "b1164ccb-a4c2-4cc8-adf8-1d5597de697b", "clock_epoch_requires_readmission")
return admit(directory=directory, authority_id="railiance01", environment="prod", kid=custody["kid"], epoch=epoch, policy_id="railiance01-online-v1", public_key_pem=custody["public_key_pem"], endpoint="http://127.0.0.1:8787/v1/time-samples", limits=dict(max_age_ns=5000000000, max_rtt_ns=2000000000, max_width_ns=3000000000, max_server_error_ns=500000000, timer_ppm=1000, timer_resolution_ns=1000, suspend_tolerance_ns=5000000, trust_session_ns=900000000000), admission_ref="CCR-2026-0028; REINAH-WP-0003; attended proof 2026-09-27", transport="admitted-loopback")
def verify_cleanup(client, entry, other):
from urllib.request import Request, urlopen
from urllib.error import HTTPError
with client.approle_session(entry.role_name) as session:
token = session.client.token
for path in (f"platform/data/{other.path}", "platform/metadata/workloads", "platform/data/workloads/secrets-engine/approval-client"):
require(session.client.token_capabilities(path, token=token) == ["deny"], "sibling_or_metadata_authority")
require(session.revocation_succeeded, "session_revocation_failed")
try:
with urlopen(Request(client.addr + "/v1/auth/token/lookup-self", headers={"X-Vault-Token": token}), timeout=15):
raise ValueError("revoked_token_still_usable")
except HTTPError as error:
require(error.code == 403, "revocation_not_definitive")
finally:
del token
return dict(sibling_denied=True, metadata_denied=True, session_revoked=True, revoked_lookup_status=403)
def validate_queued(rows, trigger):
require(len(rows) == 1 and rows[0]["state"] == "open" and rows[0]["attempt"] == 0 and rows[0]["claim_owner"] is None and rows[0]["target_repo"] == "hfact-glas-proof" and rows[0]["harness_profile_ref"] == "harness.agent-dev-local@1.1.1" and rows[0]["repository_grant"] == {"version": "1", "allowed_paths": ["PROOF.md"], "commit_count": {"min": 1, "max": 1}, "publish": False} and rows[0]["triggering_event_id"] == trigger, "natural_queue_binding_refused")
def execute(bundle, resume=False):
from secrets_engine.openbao import OpenBaoClient
from secrets_engine.approval_consume import authorize_action
from secrets_engine.application_time import read_window
from secrets_engine.cli import build_parser
from secrets_engine.exec_owner import validate_delivery_target
from secrets_engine.plan import build_plan
global RECEIPT_NAME
prior = None
if resume:
prior = json.loads((bundle / "execution.json").read_text())
require(prior.get("phase") == "one_trigger_started" and prior.get("failure_code") == "natural_queue_binding_refused" and prior.get("trigger", {}).get("trigger_key") == "manual-dab6c4c7-db03-4887-a17b-9d99b752482e", "unexpected_prior_failure")
require([(r["catalog"], r["action"], r["approval_id"], r["exit_code"]) for r in prior["actions"]] == [(lane, action, IDS[lane][action], 0) for action in ("apply", "verify") for lane in IDS], "prior_native_actions_not_verified")
RECEIPT_NAME = "execution-resume.json"
require(not (bundle / RECEIPT_NAME).exists(), "prior_attempt_requires_reconciliation")
receipt = dict(status="failed", phase="preflight", observed_at=datetime.now(timezone.utc).isoformat(), actions=[], automatic_retry=False)
save(bundle, receipt)
payload = {}
directory = None
try:
require(run(["git", "-C", str(TARGET), "rev-parse", "HEAD"]) == BASE_HEAD and not run(["git", "-C", str(TARGET), "status", "--porcelain"]), "target_not_pristine")
require(json.loads((bundle / "installation.json").read_text())["status"] == "installed", "installation_receipt_required")
if resume:
validate_queued(queue_rows(), prior["trigger"]["trigger_key"])
with sqlite3.connect(f"file:{OWNER}/spend-tool-proof-renewal-20260927.sqlite3?mode=ro", uri=True) as db:
require(all(db.execute("SELECT count(*) FROM " + table).fetchone()[0] == 0 for table in ("reservations", "request_routes", "request_reservations")), "prior_paid_dispatch_requires_reconciliation")
receipt.update(prior_receipt="execution.json", completed_actions_not_replayed=["provider/apply", "worker/apply", "provider/verify", "worker/verify", "queue/trigger"], trigger=prior["trigger"])
else:
require(not queue_rows(), "metered_queue_not_empty")
runtime = Path("/run/user") / str(os.getuid())
private(runtime, True)
require(run(["findmnt", "-n", "-o", "FSTYPE", "-T", str(runtime)]) == "tmpfs", "tmpfs_required")
with tempfile.TemporaryDirectory(prefix="metered-native-", dir=runtime) as name:
directory = Path(name)
private(directory, True)
payload = json.loads(sys.stdin.buffer.read(131073))
require(set(payload) == {"client_secret", "negative_token", "backend_token", "pdp_token"}, "credential_envelope_invalid")
for key, filename in (("client_secret", "client-secret"), ("negative_token", "negative-token"), ("pdp_token", "pdp-caller")):
require(isinstance(payload[key], str) and 0 < len(payload[key]) < 32768, "credential_envelope_invalid")
write_new(directory / filename, payload.pop(key))
os.environ["BAO_TOKEN"] = payload.pop("backend_token")
os.environ.pop("VAULT_TOKEN", None)
os.environ["BAO_ADDR"] = "http://127.0.0.1:28200"
trust = clock_admission(bundle, directory)
configs, entries = prepare_configs(bundle, directory, trust)
read_window(configs["exec"])
command = entries[PROVIDER, "exec"].delivery_config["exec_owner"]["command"]
validate_delivery_target(entries[PROVIDER, "exec"], "ANTHROPIC_API_KEY", command, "exec-env")
client = OpenBaoClient.resolve(configs["exec"].bao_addr)
identity = json.loads(run([client.bao_bin, "token", "lookup", "-format=json"]))["data"]
policies = set(identity["policies"]) | set(identity.get("identity_policies", []))
require("platform-admin" in policies and "root" not in policies and identity.get("entity_id") and 0 < identity["ttl"] <= 3600, "attended_operator_required")
# Refuse drift/existing state before any native consume. An already
# applied lane needs reconciliation, never a replay of this procedure.
for lane in IDS:
entry = entries[lane, "apply"]
if resume:
require(client.read_policy(entry.policy_name).strip() == build_plan(entry, "prod").policy_hcl.strip(), "applied_policy_drift")
role = json.loads(run([client.bao_bin, "read", "-format=json", "auth/approle/role/" + entry.role_name]))["data"]
require(all(role.get(k) == v for k, v in LIMITS.items()) and role.get("token_policies") == [entry.policy_name], "role_limits_drift")
else:
require(client.read_policy(entry.policy_name) is None and not client.approle_exists(entry.role_name), "existing_lane_requires_reconciliation")
for lane in IDS:
for action in (("exec",) if resume else IDS[lane]):
entry = entries[lane, action]
require(authorize_action(configs[action], entry, action, fields=() if action == "apply" else tuple(entry.fields), policy_targets=(entry.policy_name,), auth_targets=(entry.role_name,)) is not None, "native_authorization_missing")
receipt["phase"] = "remaining_exec_checks_passed" if resume else "all_six_native_checks_passed"
save(bundle, receipt)
for action in (() if resume else ("apply", "verify")):
for lane in IDS:
receipt["phase"] = lane + "_" + action + "_started"
save(bundle, receipt)
argv = ["apply", lane, "--stage", "prod", "--auth", "env"] if action == "apply" else ["verify", lane, "--auth", "env", "--negative-token-file", str(directory / "negative-token")]
args = build_parser().parse_args(argv)
with contextlib.redirect_stdout(io.StringIO()), contextlib.redirect_stderr(io.StringIO()):
code = args.func(configs[action], args)
require(code == 0, "native_action_failed")
row = dict(catalog=lane, action=action, approval_id=IDS[lane][action], exit_code=code)
entry = entries[lane, action]
if action == "apply":
role = json.loads(run([client.bao_bin, "read", "-format=json", "auth/approle/role/" + entry.role_name]))["data"]
require(all(role.get(k) == v for k, v in LIMITS.items()) and role.get("token_policies") == [entry.policy_name], "role_limits_drift")
require(client.read_policy(entry.policy_name).strip() == build_plan(entry, "prod").policy_hcl.strip(), "applied_policy_drift")
row["limits"] = LIMITS
else:
row.update(verify_cleanup(client, entry, entries[WORKER if lane == PROVIDER else PROVIDER, action]))
receipt["actions"].append(row)
save(bundle, receipt)
# The owner triggers exactly once only after both lanes verify.
# Persist intent first; any uncertainty blocks re-trigger/re-exec.
if not resume:
receipt["phase"] = "one_trigger_started"
save(bundle, receipt)
from urllib.request import Request, urlopen
with urlopen(Request("http://127.0.0.1:8010/activity-definitions/" + DEFINITION + "/trigger", method="POST"), timeout=30) as response:
require(response.status == 202, "trigger_refused")
receipt["trigger"] = json.load(response)
for _ in range(20):
rows = queue_rows()
if rows:
break
time.sleep(1)
validate_queued(rows, receipt["trigger"]["trigger_key"])
receipt["queued_run"] = rows[0]
receipt["phase"] = "one_exec_started"
save(bundle, receipt)
args = build_parser().parse_args(["exec", "--catalog", PROVIDER, "--auth", "env", "--mode", "exec-env", "--", *command])
args.command = args.command[1:]
captured = io.StringIO()
with contextlib.redirect_stdout(captured), contextlib.redirect_stderr(io.StringIO()):
code = args.func(configs["exec"], args)
# Only the closed owner result schema may leave this envelope.
results = []
for line in captured.getvalue().splitlines():
try:
row = json.loads(line)
except ValueError:
continue
if isinstance(row, dict) and set(row) <= {"ok", "claimed", "empty", "run_id", "ops_state", "code"} and "ok" in row:
results.append(row)
receipt.update(exec_exit_code=code, owner_results=results, phase="one_exec_returned")
receipt["actions"].extend(dict(catalog=lane, action="exec", approval_id=IDS[lane]["exec"], exit_code=code) for lane in IDS)
receipt["status"] = "passed" if code == 0 and len(results) == 1 and results[0].get("claimed") and results[0].get("ok") else "attempt_failed"
receipt["private_runtime_removed"] = True
except Exception as error:
receipt["failure_type"] = type(error).__name__
if type(error) is ValueError and str(error).replace("_", "").isalnum():
receipt["failure_code"] = str(error)
finally:
payload.clear()
os.environ.pop("BAO_TOKEN", None)
if directory is not None:
receipt["private_runtime_removed"] = not directory.exists()
save(bundle, receipt)
return 0 if receipt["status"] == "passed" else 1
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument("mode", choices=("validate", "install", "execute", "resume"))
parser.add_argument("bundle", type=Path)
args = parser.parse_args()
if args.mode == "validate":
with tempfile.TemporaryDirectory() as directory:
prepare_configs(args.bundle, Path(directory))
print("Six frozen request bindings verified")
elif args.mode == "install":
install_host(args.bundle)
else:
raise SystemExit(execute(args.bundle, resume=args.mode == "resume"))

View file

@ -230,6 +230,8 @@ except OSError: readonly=True
else: readonly=False else: readonly=False
print(json.dumps({'runtime_readonly':readonly,'python_prefix':sys.prefix, print(json.dumps({'runtime_readonly':readonly,'python_prefix':sys.prefix,
'cli_version':subprocess.check_output(['claude','--version'],text=True).strip(), 'cli_version':subprocess.check_output(['claude','--version'],text=True).strip(),
'entrypoints':{name:subprocess.run([name,'--help'],capture_output=True,timeout=15).returncode
for name in ('rein-aharness','glas-harness')},
'private_absent':not Path(sys.argv[1]).exists(),'source_absent':not Path(sys.argv[2]).exists(), 'private_absent':not Path(sys.argv[1]).exists(),'source_absent':not Path(sys.argv[2]).exists(),
'proxy_absent':not any('proxy' in k.lower() for k in os.environ), 'proxy_absent':not any('proxy' in k.lower() for k in os.environ),
'interfaces':[x.split(':')[0].strip() for x in Path('/proc/net/dev').read_text().splitlines()[2:]]})) 'interfaces':[x.split(':')[0].strip() for x in Path('/proc/net/dev').read_text().splitlines()[2:]]}))
@ -239,6 +241,7 @@ print(json.dumps({'runtime_readonly':readonly,'python_prefix':sys.prefix,
assert facts["runtime_readonly"] and facts["private_absent"] and facts["source_absent"] assert facts["runtime_readonly"] and facts["private_absent"] and facts["source_absent"]
assert facts["proxy_absent"] and facts["interfaces"] == ["lo"] assert facts["proxy_absent"] and facts["interfaces"] == ["lo"]
assert facts["cli_version"] == "2.1.266 (Claude Code)" assert facts["cli_version"] == "2.1.266 (Claude Code)"
assert all(code == 0 for code in facts["entrypoints"].values()), json.dumps({"entrypoint_check_failed": facts["entrypoints"], "provider_requests": server.provider_calls-before})
adapter = AgenticClaudeCodeAdapter(workdir=Path(status.inputs["workspace_dir"]), adapter = AgenticClaudeCodeAdapter(workdir=Path(status.inputs["workspace_dir"]),
cli_path="/opt/sandboxer/runtime/bin/claude", cli_path="/opt/sandboxer/runtime/bin/claude",
model=profile.model.model) model=profile.model.model)

View file

@ -0,0 +1,70 @@
"""Repair the one unclaimed proof row from its existing typed owner definition.
Run inside the Activity Core owner process context, first without --apply.
No trigger, claim, inferred authority, retry, or new task is created.
"""
import asyncio
import json
import sys
import uuid
RUN = "6efa9436-6a91-47c0-94e5-b31b5a0e7e3a"
DEFINITION = "5bae5505-77f1-5ba3-8dfa-2e10ed15531e"
TRIGGER = "manual-dab6c4c7-db03-4887-a17b-9d99b752482e"
GRANT = {"version": "1", "allowed_paths": ["PROOF.md"], "commit_count": {"min": 1, "max": 1}, "publish": False}
def validate(definition, row, live_worker_image):
if live_worker_image != "sha256:713bddad10a41950f446100a8b370fca8ccdd0b8969cccae751e3870c9c63ccd":
raise ValueError("grant_aware_worker_required")
if str(definition.id) != DEFINITION or definition.enabled or definition.version != 1:
raise ValueError("definition_drift")
rules = definition.rules_json
if len(rules) != 1 or rules[0]["id"] != "execute-hfact-glas-metered-proof" or rules[0]["condition"] != "True":
raise ValueError("rule_drift")
action = rules[0]["action"]
if action.get("repository_grant") != GRANT or action.get("target_repo") != "hfact-glas-proof" or action.get("harness_profile_ref") != "harness.agent-dev-local@1.1.1" or action.get("labels") != ["hfact-metered"]:
raise ValueError("typed_authority_drift")
expected = dict(id=RUN, activity_definition_id=DEFINITION, state="open", attempt=0, claim_owner=None, lease_until=None, target_repo="hfact-glas-proof", harness_profile_ref="harness.agent-dev-local@1.1.1", triggering_event_id=TRIGGER, source_type="rule", source_id=rules[0]["id"], repository_grant=None)
for field, value in expected.items():
actual = getattr(row, field)
if field in ("id", "activity_definition_id"):
actual = str(actual)
if actual != value:
raise ValueError("queue_row_drift")
if row.description != action["description"] or row.title != action["task_template"] or row.labels != action["labels"]:
raise ValueError("task_content_drift")
return action["repository_grant"]
async def main(apply, image):
from sqlalchemy import select
from sqlalchemy.ext.asyncio import async_sessionmaker
from activity_core.db import make_engine
from activity_core.orm import ActivityDefinition, OpsRun
from activity_core.repository_grant import RepositoryGrant
engine = make_engine()
try:
async with async_sessionmaker(engine, expire_on_commit=False)() as session:
async with session.begin():
definition = (await session.execute(select(ActivityDefinition).where(ActivityDefinition.id == uuid.UUID(DEFINITION)).with_for_update())).scalar_one()
row = (await session.execute(select(OpsRun).where(OpsRun.id == uuid.UUID(RUN)).with_for_update())).scalar_one()
grant = RepositoryGrant.model_validate(validate(definition, row, image))
if grant.grant_id != "656911f7dff83e871434b415f0cee685":
raise ValueError("spend_grant_binding_mismatch")
if apply:
row.repository_grant = grant.payload()
receipt = dict(status="applied" if apply else "dry_run_passed", run_id=RUN, definition_id=DEFINITION, definition_version=1, triggering_event_id=TRIGGER, source="typed_existing_definition_rule", grant_id=grant.grant_id, grant=grant.payload(), attempt=0, claim_owner=None, new_trigger=False, new_task=False)
print(json.dumps(receipt, indent=2))
finally:
await engine.dispose()
if __name__ == "__main__":
args = sys.argv[1:]
apply = args[:1] == ["--apply"]
if apply:
args = args[1:]
if len(args) != 1:
raise SystemExit("Supply the independently observed live worker image digest")
asyncio.run(main(apply, args[0]))

View file

@ -535,6 +535,34 @@ def test_profile_refusal_fails_terminally_without_legacy_fallback(
execute.assert_not_called() execute.assert_not_called()
def test_spend_refusal_closes_with_gateway_cleanup_evidence(tmp_path: Path) -> None:
from rein_aharness.glas_execution import GlasSpendError
_repo, run, client = _profiled_case(tmp_path)
client.fail.return_value = OpsRun(
id=run.id, activity_definition_id="def", idempotency_key="k",
target_repo=run.target_repo, title=run.title, description="", state="failed",
)
refusal = GlasSpendError(
"spend accounting refused: execution accounting requires reconciliation",
execution_evidence={
"outcome": "failed", "failure_stage": "execution",
"session_cleanup": "succeeded", "sandbox_destroy": "succeeded",
"error": "private response", "provider_response": "private payload",
},
)
with patch("rein_aharness.claim_loop.execute_profiled_run", side_effect=refusal):
result = process_one(client)
assert result.ok is False
assert client.fail.call_args.kwargs["reopen"] is False
evidence = client.fail.call_args.kwargs["result"]["execution_evidence"]
assert evidence == {
"outcome": "failed", "failure_stage": "execution",
"session_cleanup": "succeeded", "sandbox_destroy": "succeeded",
}
client.complete.assert_not_called()
def test_profiled_signal_cancellation_releases_lock_and_durably_fails( def test_profiled_signal_cancellation_releases_lock_and_durably_fails(
tmp_path: Path, tmp_path: Path,
) -> None: ) -> None:

View file

@ -0,0 +1,53 @@
"""Frozen action packet safety; requires the governed secrets-engine sibling."""
import importlib.util
from pathlib import Path
import shutil
import pytest
pytest.importorskip("secrets_engine")
ROOT = Path(__file__).resolve().parents[1]
SOURCE = ROOT.parent / "secrets-engine/docs/proposals/glas-metered-tool-renewal-20260927"
spec = importlib.util.spec_from_file_location("metered_native", ROOT / "scripts/metered-native-owner.py")
native = importlib.util.module_from_spec(spec)
spec.loader.exec_module(native)
@pytest.fixture
def bundle(tmp_path):
path = tmp_path / "bundle"
shutil.copytree(SOURCE, path)
return path
def test_all_six_action_bindings_match(bundle, tmp_path):
private = tmp_path / "private"
private.mkdir()
configs, entries = native.prepare_configs(bundle, private)
assert len(entries) == 6
for (lane, action), entry in entries.items():
assert entry.approval["authorization_id"] == native.IDS[lane][action]
assert configs["exec"].clock_trust_file is None # validation is backend-free
@pytest.mark.parametrize("lane", [native.PROVIDER, native.WORKER])
def test_recipient_drift_refused_before_auth(bundle, tmp_path, lane):
path = bundle / "catalog" / (lane + ".yaml")
path.write_text(path.read_text().replace("token_max_ttl: 15m", "token_max_ttl: 16m"))
private = tmp_path / "private"
private.mkdir()
with pytest.raises(ValueError, match="frozen_action_request_drift"):
native.prepare_configs(bundle, private)
def test_changed_packet_refused(bundle, tmp_path):
path = bundle / "native-pdp-inputs.json"
path.write_bytes(path.read_bytes() + b"\n")
with pytest.raises(ValueError, match="frozen_packet_drift"):
native.prepare_configs(bundle, tmp_path)
def test_execution_never_replays_prior_attempt(bundle):
(bundle / "execution.json").write_text('{"phase":"one_exec_started"}')
with pytest.raises(ValueError, match="prior_attempt_requires_reconciliation"):
native.execute(bundle)

View file

@ -0,0 +1,46 @@
"""The one-row repair cannot widen or synthesize mutation authority."""
import importlib.util
from pathlib import Path
from types import SimpleNamespace
from copy import deepcopy
import pytest
spec = importlib.util.spec_from_file_location("repair", Path(__file__).resolve().parents[1] / "scripts/reconcile-metered-queue-grant.py")
repair = importlib.util.module_from_spec(spec)
spec.loader.exec_module(repair)
IMAGE = "sha256:713bddad10a41950f446100a8b370fca8ccdd0b8969cccae751e3870c9c63ccd"
@pytest.fixture
def records():
action = dict(repository_grant=deepcopy(repair.GRANT), target_repo="hfact-glas-proof", harness_profile_ref="harness.agent-dev-local@1.1.1", labels=["hfact-metered"], description="bounded task", task_template="proof")
definition = SimpleNamespace(id=repair.DEFINITION, enabled=False, version=1, rules_json=[dict(id="execute-hfact-glas-metered-proof", condition="True", action=action)])
row = SimpleNamespace(id=repair.RUN, activity_definition_id=repair.DEFINITION, state="open", attempt=0, claim_owner=None, lease_until=None, target_repo="hfact-glas-proof", harness_profile_ref="harness.agent-dev-local@1.1.1", triggering_event_id=repair.TRIGGER, source_type="rule", source_id="execute-hfact-glas-metered-proof", repository_grant=None, description="bounded task", title="proof", labels=["hfact-metered"])
return definition, row
def test_copies_only_typed_existing_authority(records):
definition, row = records
assert repair.validate(definition, row, IMAGE) is definition.rules_json[0]["action"]["repository_grant"]
assert row.repository_grant is None
@pytest.mark.parametrize("field,value", [("state", "claimed"), ("attempt", 1), ("claim_owner", "worker"), ("repository_grant", repair.GRANT), ("triggering_event_id", "another-trigger"), ("description", "changed task")])
def test_changed_or_used_row_refused(records, field, value):
definition, row = records
setattr(row, field, value)
with pytest.raises(ValueError):
repair.validate(definition, row, IMAGE)
def test_changed_definition_cannot_grant_more(records):
definition, row = records
definition.rules_json[0]["action"]["repository_grant"]["allowed_paths"] = ["**"]
with pytest.raises(ValueError, match="typed_authority_drift"):
repair.validate(definition, row, IMAGE)
def test_stale_worker_blocks_repair(records):
with pytest.raises(ValueError, match="grant_aware_worker_required"):
repair.validate(*records, "sha256:old")

View file

@ -42,6 +42,10 @@ def prepared(ledger, tmp_path, monkeypatch):
runtime = tmp_path / "runtime" runtime = tmp_path / "runtime"
(runtime / "bin").mkdir(parents=True) (runtime / "bin").mkdir(parents=True)
(runtime / "bin/python3").write_bytes(b"not executed; fixture runtime structure") (runtime / "bin/python3").write_bytes(b"not executed; fixture runtime structure")
for name in ("rein-aharness", "glas-harness"):
executable = runtime / "bin" / name
executable.write_text("#!/opt/sandboxer/runtime/bin/python3\n# fixture only\n")
executable.chmod(0o755)
(runtime / "pyvenv.cfg").write_text("fixture only") (runtime / "pyvenv.cfg").write_text("fixture only")
messages = MessagesPolicy("fixture:upper-rate", profile.model.model, 1000, 1000, 1000, 1000) messages = MessagesPolicy("fixture:upper-rate", profile.model.model, 1000, 1000, 1000, 1000)
data = {"version": "1", "authority_ref": policy.authority_ref, data = {"version": "1", "authority_ref": policy.authority_ref,
@ -62,7 +66,8 @@ def test_prepare_pins_without_key_or_claim(prepared, monkeypatch):
@pytest.mark.parametrize("case", ["authority", "policy_digest", "model", "version", "unknown_field", @pytest.mark.parametrize("case", ["authority", "policy_digest", "model", "version", "unknown_field",
"duplicate", "public", "runtime_changed", "schema_missing"]) "duplicate", "public", "runtime_changed", "schema_missing",
"build_host_launcher", "missing_launcher", "nonexecutable_launcher"])
def test_bad_bootstrap_refuses_before_claim(prepared, monkeypatch, capsys, case): def test_bad_bootstrap_refuses_before_claim(prepared, monkeypatch, capsys, case):
path, config, data, runtime = prepared path, config, data, runtime = prepared
if case == "authority": data["authority_ref"] = "unrelated" if case == "authority": data["authority_ref"] = "unrelated"
@ -71,6 +76,16 @@ def test_bad_bootstrap_refuses_before_claim(prepared, monkeypatch, capsys, case)
elif case == "version": data["version"] = "2" elif case == "version": data["version"] = "2"
elif case == "unknown_field": data["upstream_url"] = "https://not-admitted.invalid" elif case == "unknown_field": data["upstream_url"] = "https://not-admitted.invalid"
elif case == "runtime_changed": (runtime / "added-file").write_text("changed") elif case == "runtime_changed": (runtime / "added-file").write_text("changed")
elif case in {"build_host_launcher", "missing_launcher", "nonexecutable_launcher"}:
executable = runtime / "bin/rein-aharness"
if case == "build_host_launcher":
executable.write_text("#!/bin/sh\nexec /old-build/bin/python3\n")
elif case == "missing_launcher":
executable.unlink()
else:
executable.chmod(0o644)
# Even a correctly pinned malformed runtime must fail before claim.
data["runtime"]["sha256"] = runtime_digest(runtime)
elif case == "schema_missing": elif case == "schema_missing":
import sqlite3 import sqlite3
with sqlite3.connect(config.spend_ledger_path) as db: db.execute("DROP TABLE request_routes") with sqlite3.connect(config.spend_ledger_path) as db: db.execute("DROP TABLE request_routes")

View file

@ -419,6 +419,29 @@ def test_uncertain_gateway_never_imports_and_blocks_next_claim(dispatch_case, fa
store.preflight() store.preflight()
def test_accounting_refusal_preserves_stage_and_cleanup_without_raw_error(dispatch_case):
from rein_aharness.glas_execution import GlasSpendError, execute_profiled_run
store, config, _catalog, transfer = dispatch_case
result = success(store, run(), None)
result["ok"] = False
result["evidence"].update(
outcome="failed", failure_stage="execution", sandbox_id="fixture-sandbox",
error="private provider response", provider_response="private payload",
)
with pytest.raises(GlasSpendError) as caught:
execute_profiled_run(run(), config, gateway=lambda *a, **k: result, report_to_hub=False)
evidence = caught.value.execution_evidence
assert evidence["failure_stage"] == "execution"
assert evidence["sandbox_destroy"] == evidence["session_cleanup"] == "succeeded"
assert "private" not in json.dumps(evidence)
assert "error" not in evidence and "cost_usd" not in evidence
transfer.import_after_teardown.assert_not_called()
assert store.status()["reservations"][0]["state"] == "held"
with pytest.raises(SpendAdmissionError):
store.preflight()
def test_cli_reconciliation_requires_termination_attestation(ledger, capsys): def test_cli_reconciliation_requires_termination_attestation(ledger, capsys):
from rein_aharness.cli import main from rein_aharness.cli import main

View file

@ -985,3 +985,56 @@ backend delivery/consume, natural execution and recovery acceptance. T04's
existing tenant-owner gates remain. The plan stays blocked; no new task or existing tenant-owner gates remain. The plan stays blocked; no new task or
workplan was opened. The previous unsigned-spend/requester-mandate blockers above workplan was opened. The previous unsigned-spend/requester-mandate blockers above
are superseded by the confirmed evidence in this return. are superseded by the confirmed evidence in this return.
### Native activation, one failed attempt, and implemented fixes — 2026-09-27
All six human dispositions were accepted and confirmed. Both scoped credential
lanes passed native apply and positive/negative verification, including sibling
and metadata denial and revoked-token rejection. Each of the six exact native
approvals was consumed once. Exec delivery sessions both revoked successfully;
the attended Warden sessions exited and no private credential files remain.
Installed the approved renewed owner/spend pins after exclusively checking the
old ledger's three tables were empty. The old ledger and configuration backups
are preserved. No prior liability was discarded and old dispatch pins were retired.
The single trigger exposed a deployed Activity Core mismatch: its older worker
dropped the definition's typed repository grant. Corrected only its image to
the already-deployed grant-aware API artifact, using the existing GitOps parent
and child. Source commits: Activity Core `428f2d7`, Platform `c3607ff`. Both
applications are healthy/synced. A guarded, row-locked repair copied only the
existing definition's exact grant to the same unclaimed attempt-zero job. It
created no task/trigger and did not infer authority from text. Nine guard tests
and 21 Activity Core carriage tests pass; actual image carriage checks pass.
Resumed only the two unused exec approvals. Job
`6efa9436-6a91-47c0-94e5-b31b5a0e7e3a` reached attempt 1 and closed `failed`
with its lease cleared. No provider request reservation was created. The
installed `b6e4e8a4` artifact's uv shell launchers retained a vanished temporary
build interpreter. The real bwrap no-credential probe reproduces exit 127 for
rein and Glas with zero provider forwards. The prior direct-Claude fixture did
not exercise these Python entrypoints and cannot stand in for this evidence.
Fixed Sand-boxer's builder to relocate direct and long-path/space-containing
shell launchers (commit `81b5fcf`, 12 builder tests and focused lint pass).
Added pre-claim launcher validation and actual in-sandbox entrypoint checks in
rein. Accounting refusal now preserves bounded gateway stage/cleanup evidence
without copying raw provider errors; it still holds the liability and prevents
artifact import or another claim. The approved immutable artifact was not edited.
Postflight: original repository clean at `679d23e0`, lock available, sandbox
`b67907f1`/workspace removed, request route revoked, no pending/quarantined close
outbox records, and no private credential directories. The parent EUR 10
reservation remains held for owner reconciliation; no billing figure or refund
is inferred. There was no retry, publication, extra queue job, or new workplan.
Evidence: `docs/native-metered-proof.md` and
`docs/evidence/2026-09-27-metered-{acceptance-confirmations,native-consumes,native-execution,native-resume,postflight,queue-grant-reconciliation,renewal-installation}.json`;
worker rollout is `docs/evidence/2026-09-27-grant-aware-worker-rollout.json`.
T05/T06 remain `wait`, and the workplan remains `blocked`: a corrected immutable
artifact/pin admission, reconciliation of the held reservation, and separately
authorized successful model/tool/commit acceptance remain. The accepted decisions
must not be requested again as though still pending; they are consumed historical
authority. T04's FI/Binky owner gates remain unchanged. These residuals stay in
the existing REINAH-WP-0003, SAND-WP-0015-T04 and SECRETS-WP-0009-T03 records.