Wait within decision validity bounds and preserve failed preflight evidence
All checks were successful
CI Smoke / host-smoke (push) Successful in 1s
CI Smoke / container-smoke (push) Successful in 3s

Assistant: codex
Assistant-Model: gpt-6-astra
Assistant-Session: 01a09cbb-87c6-7900-a145-4ce53ba9f1a6
This commit is contained in:
tegwick 2026-09-14 03:46:28 +02:00
parent 1c9fd5279c
commit 5aaa49a2ec
7 changed files with 647 additions and 1 deletions

View file

@ -18,7 +18,7 @@
| workplan | SECRETS-WP-0007 | active | — | workplans/SECRETS-WP-0007-production-lifecycle-hardening.md | | workplan | SECRETS-WP-0007 | active | — | workplans/SECRETS-WP-0007-production-lifecycle-hardening.md |
| workplan | SECRETS-WP-0008 | active | — | workplans/SECRETS-WP-0008-layer-model-lifecycle-conformance.md | | workplan | SECRETS-WP-0008 | active | — | workplans/SECRETS-WP-0008-layer-model-lifecycle-conformance.md |
| workplan | SECRETS-WP-0009 | blocked | — | workplans/SECRETS-WP-0009-glas-claude-native-delivery.md | | workplan | SECRETS-WP-0009 | blocked | — | workplans/SECRETS-WP-0009-glas-claude-native-delivery.md |
| workplan | SECRETS-WP-0010 | blocked | — | workplans/SECRETS-WP-0010-openrouter-native-access.md | | workplan | SECRETS-WP-0010 | active | — | workplans/SECRETS-WP-0010-openrouter-native-access.md |
| task | SECRETS-WP-ADHOC-2026-08-21-T01 | done | — | workplans/ADHOC-2026-08-21.md | | task | SECRETS-WP-ADHOC-2026-08-21-T01 | done | — | workplans/ADHOC-2026-08-21.md |
| task | SECRETS-WP-ADHOC-2026-08-23-T01 | done | — | workplans/ADHOC-2026-08-23.md | | task | SECRETS-WP-ADHOC-2026-08-23-T01 | done | — | workplans/ADHOC-2026-08-23.md |
| task | SECRETS-WP-0001-T01 | done | — | workplans/SECRETS-WP-0001-statehub-bootstrap.md | | task | SECRETS-WP-0001-T01 | done | — | workplans/SECRETS-WP-0001-statehub-bootstrap.md |

View file

@ -199,3 +199,11 @@ The catalog CCR reference remains provenance; the native path does not demand a
second hub decision or local fixture with that CCR identifier. Unserved legacy second hub decision or local fixture with that CCR identifier. Unserved legacy
build/test paths retain their existing review gate. Claim, PDP, human-control, build/test paths retain their existing review gate. Claim, PDP, human-control,
stance, freshness and consume refusals still prevent backend access. stance, freshness and consume refusals still prevent backend access.
A future `not_before` is now awaited for at most two seconds before full decision
validation. Larger skew refuses. Expiry and claim freshness are checked afterward;
the consumer never shifts its validation clock or treats a future decision as
already valid. Native preflight exposed workstation clock drift; the existing
NTP service was restarted. All three owner-store/native-PDP diagnostic joins
passed afterward, without consuming approvals. Full regression suite: 420 passed.

View file

@ -0,0 +1,557 @@
[
{
"action": "apply",
"scope": "read-only owner-store claim and native PDP diagnosis; not authenticated claim/consume execution",
"claim_valid_now": true,
"claim_reason": "ok",
"effect": "allow",
"reason": "catalog_lane_policy_matched",
"binding": {
"tenant": "tenant:platform",
"subject": {
"id": "secrets-engine",
"type": "service",
"tenant": "tenant:platform",
"attributes": {
"description": "secrets-engine's own service identity, the single calling identity for the twelve gated catalog-lane actions it sends to POST /v1/check. Because it is the only subject, the package has no action_not_granted branch (FLEX-WP-0021-T02); registering a second identity is the revisit trigger.",
"display_name": "secrets-engine service principal",
"groups": [
"group:secrets-engine-lane-operators"
],
"organization_relation": "ServiceProvider",
"roles": [
"Operator"
]
}
},
"action": "apply",
"resource": {
"id": "catalog:openrouter-llm-connect",
"type": "secret-catalog-lane",
"system": "secrets-engine",
"tenant": "tenant:platform",
"attributes": {
"auth_targets": [
"se-prod-openrouter-llm-connect"
],
"fields": [],
"policy_targets": [
"se-prod-openrouter-llm-connect"
],
"stage": "prod"
}
},
"context": {
"approval": {
"approval_id": "09592588-ab15-53e7-89b8-c4e9f29aaacf",
"binding": {
"action": "apply",
"actor": "secrets-engine",
"digest": "sha256:03cc5b37437f14e86b686ce4054f976556334eff3fa260b03e8014ed3d9217e5",
"human_control": true,
"pdp_digest": "sha256:933427642c58c54f65dd4781b8e4c8e2f358eb96497ae35870fff4bd593d2b84",
"pdp_path": true,
"principal": "secrets-engine",
"purpose": "IR-WP-0004 read-only OpenRouter key authentication check; no inference",
"target": {
"attributes": {
"auth_targets": [
"se-prod-openrouter-llm-connect"
],
"fields": [],
"policy_targets": [
"se-prod-openrouter-llm-connect"
],
"stage": "prod"
},
"id": "catalog:openrouter-llm-connect",
"system": "secrets-engine",
"type": "secret-catalog-lane"
}
},
"consumed": false,
"freshness": {
"not_after": "2026-09-14T01:43:41+00:00",
"observed_at": "2026-09-14T01:43:11+00:00",
"ttl_seconds": 30
},
"issuer": "approval-engine",
"kind": "approval-claim",
"reason_code": "ok",
"schema_version": "0.1",
"state": "valid",
"valid_now": true,
"validity": {
"expires_at": "2026-09-15T00:33:06.559689+00:00",
"not_before": "2026-09-14T00:33:06.559689+00:00"
},
"yields_to": "net-kingdom taxonomy request-claim schema (statute \u00a717; unassigned)"
},
"catalog_target": {
"auth_capability": {},
"consumers": [
{
"auth": "kubernetes",
"claim": "serviceaccount:external-secrets/external-secrets",
"name": "llm-connect-activity-core",
"purpose": "sync llm-connect-provider-secrets for the activity-core deployment"
},
{
"auth": "approle",
"claim": "catalog:openrouter-llm-connect",
"name": "intelligence-radar-key-check",
"purpose": "IR-WP-0004 read-only OpenRouter key authentication check; no inference"
}
],
"delivery_auth": {
"management": "engine",
"method": "approle",
"policy_name": "se-prod-openrouter-llm-connect",
"role_name": "se-prod-openrouter-llm-connect",
"secret_id_num_uses": 1,
"secret_id_ttl": "15m",
"token_max_ttl": "30m",
"token_num_uses": 8,
"token_ttl": "15m"
},
"delivery_config": {
"exec_owner": {
"command": [
"/usr/bin/python3.12",
"-I",
"-B",
"/home/worsch/.local/share/secrets-engine/recipients/openrouter-key-check-dc1569f63ef7/openrouter_key_check.py"
],
"cwd": "/run/user/1000/secrets-engine-openrouter-check",
"environment": {
"LANG": "C.UTF-8"
},
"files": {
"/home/worsch/.local/share/secrets-engine/recipients/openrouter-key-check-dc1569f63ef7/openrouter_key_check.py": {
"private": true,
"sha256": "dc1569f63ef74d73f0a735548c0573db2a1493f7ffc86945f52d0be9b27a3253"
},
"/usr/bin/python3.12": {
"private": false,
"sha256": "e50d468e8b0adfb05733f5b87b3cff34829c4a8c1aea50c865aa8bdfe4bb150f"
}
},
"owner": "intelligence-radar-key-check",
"status": "configured"
}
},
"delivery_modes": [
"exec-env",
"read-check"
],
"fields": [
"OPENROUTER_API_KEY"
],
"kind": "kv",
"mount": "platform",
"mount_management": "existing",
"org": "coulomb",
"path": "workloads/activity-core/llm-connect/llm-connect-provider-secrets",
"repo": "llm-connect",
"workload_delivery": [
{
"mode": "external-secrets",
"owner": "railiance-platform + llm-connect"
}
]
},
"human_control": true,
"purpose": "IR-WP-0004 read-only OpenRouter key authentication check; no inference"
},
"request_digest": "sha256:1e2a0b721dca7a8e719a5837fd4e298be11be4c66535a0f40e11f2fa0639f9df",
"approval_binding_digest": "sha256:933427642c58c54f65dd4781b8e4c8e2f358eb96497ae35870fff4bd593d2b84",
"submitted_request_digest": "sha256:9241fdc373759d67b8db7c356730714e784804465f1a18d7c12a91bd200f3517"
},
"provenance": {
"evaluator": "flex-auth/local",
"mode": "standalone",
"policy_package": "secrets-engine.catalog-lane.lifecycle",
"policy_version": "v2",
"policy_package_digest": "sha256:bd11c5fe77ce6439c65fea225ad6b71d2110efc5e7b5bc9b499c59cd0a53b8b4",
"registry_snapshot_digest": "sha256:f5a309bc0b36721fd6d9ad7f53eb21222162bc2eac62a0ab0802a9a1d51340bb",
"input_claim_digests": {
"context": "sha256:eb41f86373ada6e123049610c1722116b1638d597069b460b2d0b3538b868a60"
},
"decision_time": "2026-09-14T01:43:11Z"
},
"validated": true
},
{
"action": "verify",
"scope": "read-only owner-store claim and native PDP diagnosis; not authenticated claim/consume execution",
"claim_valid_now": true,
"claim_reason": "ok",
"effect": "allow",
"reason": "catalog_lane_policy_matched",
"binding": {
"tenant": "tenant:platform",
"subject": {
"id": "secrets-engine",
"type": "service",
"tenant": "tenant:platform",
"attributes": {
"description": "secrets-engine's own service identity, the single calling identity for the twelve gated catalog-lane actions it sends to POST /v1/check. Because it is the only subject, the package has no action_not_granted branch (FLEX-WP-0021-T02); registering a second identity is the revisit trigger.",
"display_name": "secrets-engine service principal",
"groups": [
"group:secrets-engine-lane-operators"
],
"organization_relation": "ServiceProvider",
"roles": [
"Operator"
]
}
},
"action": "verify",
"resource": {
"id": "catalog:openrouter-llm-connect",
"type": "secret-catalog-lane",
"system": "secrets-engine",
"tenant": "tenant:platform",
"attributes": {
"auth_targets": [
"se-prod-openrouter-llm-connect"
],
"fields": [
"OPENROUTER_API_KEY"
],
"policy_targets": [
"se-prod-openrouter-llm-connect"
],
"stage": "prod"
}
},
"context": {
"approval": {
"approval_id": "9416fa31-fa9e-5603-8289-f35bc9625409",
"binding": {
"action": "verify",
"actor": "secrets-engine",
"digest": "sha256:72d9267d038c17107c880ffc9009793ce9c70defbddfe2219628854b811a04b2",
"human_control": true,
"pdp_digest": "sha256:9e36cdbf3890cc5a7e550fd57191f9c0f2a6b2180909aac302aa3b999e7e6b25",
"pdp_path": true,
"principal": "secrets-engine",
"purpose": "IR-WP-0004 read-only OpenRouter key authentication check; no inference",
"target": {
"attributes": {
"auth_targets": [
"se-prod-openrouter-llm-connect"
],
"fields": [
"OPENROUTER_API_KEY"
],
"policy_targets": [
"se-prod-openrouter-llm-connect"
],
"stage": "prod"
},
"id": "catalog:openrouter-llm-connect",
"system": "secrets-engine",
"type": "secret-catalog-lane"
}
},
"consumed": false,
"freshness": {
"not_after": "2026-09-14T01:43:43+00:00",
"observed_at": "2026-09-14T01:43:13+00:00",
"ttl_seconds": 30
},
"issuer": "approval-engine",
"kind": "approval-claim",
"reason_code": "ok",
"schema_version": "0.1",
"state": "valid",
"valid_now": true,
"validity": {
"expires_at": "2026-09-15T00:33:06.722887+00:00",
"not_before": "2026-09-14T00:33:06.722887+00:00"
},
"yields_to": "net-kingdom taxonomy request-claim schema (statute \u00a717; unassigned)"
},
"catalog_target": {
"auth_capability": {},
"consumers": [
{
"auth": "kubernetes",
"claim": "serviceaccount:external-secrets/external-secrets",
"name": "llm-connect-activity-core",
"purpose": "sync llm-connect-provider-secrets for the activity-core deployment"
},
{
"auth": "approle",
"claim": "catalog:openrouter-llm-connect",
"name": "intelligence-radar-key-check",
"purpose": "IR-WP-0004 read-only OpenRouter key authentication check; no inference"
}
],
"delivery_auth": {
"management": "engine",
"method": "approle",
"policy_name": "se-prod-openrouter-llm-connect",
"role_name": "se-prod-openrouter-llm-connect",
"secret_id_num_uses": 1,
"secret_id_ttl": "15m",
"token_max_ttl": "30m",
"token_num_uses": 8,
"token_ttl": "15m"
},
"delivery_config": {
"exec_owner": {
"command": [
"/usr/bin/python3.12",
"-I",
"-B",
"/home/worsch/.local/share/secrets-engine/recipients/openrouter-key-check-dc1569f63ef7/openrouter_key_check.py"
],
"cwd": "/run/user/1000/secrets-engine-openrouter-check",
"environment": {
"LANG": "C.UTF-8"
},
"files": {
"/home/worsch/.local/share/secrets-engine/recipients/openrouter-key-check-dc1569f63ef7/openrouter_key_check.py": {
"private": true,
"sha256": "dc1569f63ef74d73f0a735548c0573db2a1493f7ffc86945f52d0be9b27a3253"
},
"/usr/bin/python3.12": {
"private": false,
"sha256": "e50d468e8b0adfb05733f5b87b3cff34829c4a8c1aea50c865aa8bdfe4bb150f"
}
},
"owner": "intelligence-radar-key-check",
"status": "configured"
}
},
"delivery_modes": [
"exec-env",
"read-check"
],
"fields": [
"OPENROUTER_API_KEY"
],
"kind": "kv",
"mount": "platform",
"mount_management": "existing",
"org": "coulomb",
"path": "workloads/activity-core/llm-connect/llm-connect-provider-secrets",
"repo": "llm-connect",
"workload_delivery": [
{
"mode": "external-secrets",
"owner": "railiance-platform + llm-connect"
}
]
},
"human_control": true,
"purpose": "IR-WP-0004 read-only OpenRouter key authentication check; no inference"
},
"request_digest": "sha256:9e9f8b506b94fb3d0351b2129f6804f09bc8f207230b636da2112ff722005ab9",
"approval_binding_digest": "sha256:9e36cdbf3890cc5a7e550fd57191f9c0f2a6b2180909aac302aa3b999e7e6b25",
"submitted_request_digest": "sha256:ae7fdd0a04e2d1f131cbe8e384357aa0f994ab325032b8ff2322aba4532111c7"
},
"provenance": {
"evaluator": "flex-auth/local",
"mode": "standalone",
"policy_package": "secrets-engine.catalog-lane.lifecycle",
"policy_version": "v2",
"policy_package_digest": "sha256:bd11c5fe77ce6439c65fea225ad6b71d2110efc5e7b5bc9b499c59cd0a53b8b4",
"registry_snapshot_digest": "sha256:f5a309bc0b36721fd6d9ad7f53eb21222162bc2eac62a0ab0802a9a1d51340bb",
"input_claim_digests": {
"context": "sha256:418548cb749db472a28010fdd9dbb2a20a1c6fdd35b3d756fac6c7a7abc306fe"
},
"decision_time": "2026-09-14T01:43:13Z"
},
"validated": true
},
{
"action": "exec",
"scope": "read-only owner-store claim and native PDP diagnosis; not authenticated claim/consume execution",
"claim_valid_now": true,
"claim_reason": "ok",
"effect": "allow",
"reason": "catalog_lane_policy_matched",
"binding": {
"tenant": "tenant:platform",
"subject": {
"id": "secrets-engine",
"type": "service",
"tenant": "tenant:platform",
"attributes": {
"description": "secrets-engine's own service identity, the single calling identity for the twelve gated catalog-lane actions it sends to POST /v1/check. Because it is the only subject, the package has no action_not_granted branch (FLEX-WP-0021-T02); registering a second identity is the revisit trigger.",
"display_name": "secrets-engine service principal",
"groups": [
"group:secrets-engine-lane-operators"
],
"organization_relation": "ServiceProvider",
"roles": [
"Operator"
]
}
},
"action": "exec",
"resource": {
"id": "catalog:openrouter-llm-connect",
"type": "secret-catalog-lane",
"system": "secrets-engine",
"tenant": "tenant:platform",
"attributes": {
"auth_targets": [
"se-prod-openrouter-llm-connect"
],
"fields": [
"OPENROUTER_API_KEY"
],
"policy_targets": [
"se-prod-openrouter-llm-connect"
],
"stage": "prod"
}
},
"context": {
"approval": {
"approval_id": "da678b61-35be-598e-8d95-a7aefa2fdc73",
"binding": {
"action": "exec",
"actor": "secrets-engine",
"digest": "sha256:f2cf0fb53b740900756ccde5587c3578fcff44beef2f1edab17b9a198a4033d8",
"human_control": true,
"pdp_digest": "sha256:9f17812750fc8962b0fc58fc09df136850c9935a864fafa998a1c030dfb75bd9",
"pdp_path": true,
"principal": "secrets-engine",
"purpose": "IR-WP-0004 read-only OpenRouter key authentication check; no inference",
"target": {
"attributes": {
"auth_targets": [
"se-prod-openrouter-llm-connect"
],
"fields": [
"OPENROUTER_API_KEY"
],
"policy_targets": [
"se-prod-openrouter-llm-connect"
],
"stage": "prod"
},
"id": "catalog:openrouter-llm-connect",
"system": "secrets-engine",
"type": "secret-catalog-lane"
}
},
"consumed": false,
"freshness": {
"not_after": "2026-09-14T01:43:46+00:00",
"observed_at": "2026-09-14T01:43:16+00:00",
"ttl_seconds": 30
},
"issuer": "approval-engine",
"kind": "approval-claim",
"reason_code": "ok",
"schema_version": "0.1",
"state": "valid",
"valid_now": true,
"validity": {
"expires_at": "2026-09-15T00:33:06.955168+00:00",
"not_before": "2026-09-14T00:33:06.955168+00:00"
},
"yields_to": "net-kingdom taxonomy request-claim schema (statute \u00a717; unassigned)"
},
"catalog_target": {
"auth_capability": {},
"consumers": [
{
"auth": "kubernetes",
"claim": "serviceaccount:external-secrets/external-secrets",
"name": "llm-connect-activity-core",
"purpose": "sync llm-connect-provider-secrets for the activity-core deployment"
},
{
"auth": "approle",
"claim": "catalog:openrouter-llm-connect",
"name": "intelligence-radar-key-check",
"purpose": "IR-WP-0004 read-only OpenRouter key authentication check; no inference"
}
],
"delivery_auth": {
"management": "engine",
"method": "approle",
"policy_name": "se-prod-openrouter-llm-connect",
"role_name": "se-prod-openrouter-llm-connect",
"secret_id_num_uses": 1,
"secret_id_ttl": "15m",
"token_max_ttl": "30m",
"token_num_uses": 8,
"token_ttl": "15m"
},
"delivery_config": {
"exec_owner": {
"command": [
"/usr/bin/python3.12",
"-I",
"-B",
"/home/worsch/.local/share/secrets-engine/recipients/openrouter-key-check-dc1569f63ef7/openrouter_key_check.py"
],
"cwd": "/run/user/1000/secrets-engine-openrouter-check",
"environment": {
"LANG": "C.UTF-8"
},
"files": {
"/home/worsch/.local/share/secrets-engine/recipients/openrouter-key-check-dc1569f63ef7/openrouter_key_check.py": {
"private": true,
"sha256": "dc1569f63ef74d73f0a735548c0573db2a1493f7ffc86945f52d0be9b27a3253"
},
"/usr/bin/python3.12": {
"private": false,
"sha256": "e50d468e8b0adfb05733f5b87b3cff34829c4a8c1aea50c865aa8bdfe4bb150f"
}
},
"owner": "intelligence-radar-key-check",
"status": "configured"
}
},
"delivery_modes": [
"exec-env",
"read-check"
],
"fields": [
"OPENROUTER_API_KEY"
],
"kind": "kv",
"mount": "platform",
"mount_management": "existing",
"org": "coulomb",
"path": "workloads/activity-core/llm-connect/llm-connect-provider-secrets",
"repo": "llm-connect",
"workload_delivery": [
{
"mode": "external-secrets",
"owner": "railiance-platform + llm-connect"
}
]
},
"exec_owner_sha256": "22393c7e751e458fa64bb24305ee66a26bbe3993c5aba03ae1fc1a488e777b42",
"human_control": true,
"purpose": "IR-WP-0004 read-only OpenRouter key authentication check; no inference"
},
"request_digest": "sha256:0d18ec993f609e9fcaa0d0b18314d1cbfd10e5e16176748f0c21abbd3bf27c51",
"approval_binding_digest": "sha256:9f17812750fc8962b0fc58fc09df136850c9935a864fafa998a1c030dfb75bd9",
"submitted_request_digest": "sha256:1da3ba876912a80bf0df729ab58325d4ec8da2ff3b77f25bd4157a874f6faa06"
},
"provenance": {
"evaluator": "flex-auth/local",
"mode": "standalone",
"policy_package": "secrets-engine.catalog-lane.lifecycle",
"policy_version": "v2",
"policy_package_digest": "sha256:bd11c5fe77ce6439c65fea225ad6b71d2110efc5e7b5bc9b499c59cd0a53b8b4",
"registry_snapshot_digest": "sha256:f5a309bc0b36721fd6d9ad7f53eb21222162bc2eac62a0ab0802a9a1d51340bb",
"input_claim_digests": {
"context": "sha256:da1e2a9704eb5aae6a6cc2d24154246221668d2bd293c0e204f5d0c9d4fb8047"
},
"decision_time": "2026-09-14T01:43:16Z"
},
"validated": true
}
]

View file

@ -0,0 +1,24 @@
{
"status": "failed",
"phase": "preflight",
"observed_at": "2026-09-14T01:32:29.742409+00:00",
"actions": [],
"health_before": {
"deployment": [
{
"namespace": "activity-core",
"name": "llm-connect",
"ready": 1
}
],
"externalsecret": [
{
"namespace": "activity-core",
"name": "llm-connect-provider-secrets",
"ready": true
}
]
},
"failure_type": "DecisionError",
"owner_forwards_closed": true
}

View file

@ -25,6 +25,7 @@ from secrets_engine.decision_check import check_decision
from secrets_engine.authorization import ( from secrets_engine.authorization import (
build_action_request, build_action_request,
validate_decision_envelope, validate_decision_envelope,
wait_for_decision_start,
) )
from secrets_engine.errors import DecisionError from secrets_engine.errors import DecisionError
from secrets_engine.openbao import read_strict_token_file from secrets_engine.openbao import read_strict_token_file
@ -312,6 +313,7 @@ def authorize_action(
request=expected_request, request=expected_request,
opener=pdp_opener or urlopen, opener=pdp_opener or urlopen,
) )
wait_for_decision_start(envelope)
validated = validate_decision_envelope( validated = validate_decision_envelope(
envelope, envelope,
expected_request, expected_request,

View file

@ -10,6 +10,7 @@ import copy
import hashlib import hashlib
import json import json
import re import re
import time
import uuid import uuid
from dataclasses import dataclass from dataclasses import dataclass
from datetime import datetime, timezone from datetime import datetime, timezone
@ -399,3 +400,24 @@ def validate_decision_envelope(
request_digest=evaluated, request_digest=evaluated,
submitted_request_digest=submitted, submitted_request_digest=submitted,
) )
def wait_for_decision_start(envelope: object, *, clock=None, sleeper=None) -> None:
"""Wait at most two seconds for an owner's future start, never waive it.
Full decision/claim validation still runs afterward against the real clock.
Longer skew refuses rather than holding an approval claim until it is stale.
"""
current_time = clock or (lambda: datetime.now(timezone.utc))
sleep = sleeper or time.sleep
if not isinstance(envelope, dict):
return
lifetime = _required_dict(envelope, "lifetime")
if lifetime.get("not_before") is None:
return
start = _parse_time(lifetime["not_before"], "not_before")
delay = (start - current_time()).total_seconds()
if delay > 2:
raise DecisionError("flex-auth decision start exceeds bounded wait")
if delay > 0:
sleep(delay)

View file

@ -0,0 +1,33 @@
from datetime import datetime, timedelta, timezone
import pytest
from secrets_engine.authorization import wait_for_decision_start
from secrets_engine.errors import DecisionError
@pytest.mark.parametrize("offset,expected", [(-1, []), (0, []), (0.25, [0.25]), (2, [2])])
def test_waits_until_start_without_changing_the_envelope(offset, expected):
now = datetime(2026, 9, 14, tzinfo=timezone.utc)
envelope = {"lifetime": {"not_before": (now + timedelta(seconds=offset)).isoformat()}}
calls = []
wait_for_decision_start(envelope, clock=lambda: now, sleeper=calls.append)
assert calls == expected
assert envelope["lifetime"]["not_before"] == (now + timedelta(seconds=offset)).isoformat()
def test_large_skew_refuses_without_sleep():
now = datetime(2026, 9, 14, tzinfo=timezone.utc)
with pytest.raises(DecisionError, match="bounded wait"):
wait_for_decision_start({"lifetime": {"not_before": (now + timedelta(seconds=3)).isoformat()}},
clock=lambda: now, sleeper=lambda _: pytest.fail("must not sleep"))
def test_wait_does_not_waive_expiration_or_start_validation():
from secrets_engine.authorization import validate_decision_envelope
from tests.test_action_authorization import _envelope, _request
request = _request()
envelope = _envelope(request)
now = datetime(2026, 9, 14, tzinfo=timezone.utc)
envelope["lifetime"] = {"not_before": (now + timedelta(seconds=1)).isoformat(),
"expires_at": (now + timedelta(seconds=2)).isoformat()}
wait_for_decision_start(envelope, clock=lambda: now, sleeper=lambda _: None)
with pytest.raises(DecisionError, match="has not started"):
validate_decision_envelope(envelope, request, accepted_policy_packages={"secrets-engine.catalog-lane.lifecycle"}, accepted_policy_versions={"v2"}, now=now)
with pytest.raises(DecisionError, match="expired"):
validate_decision_envelope(envelope, request, accepted_policy_packages={"secrets-engine.catalog-lane.lifecycle"}, accepted_policy_versions={"v2"}, now=now + timedelta(seconds=3))