NK-WP-0056-T06: executor waits for every endpoint; errors named by phase, never mislabelled as no-effect
All checks were successful
Build and Publish bounded-executor / build-and-push (push) Successful in 8s
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
Identity provider journey acceptance / provider (push) Successful in 37s

Two live runs of BEA-2026-0002 ended setup:URLError while four read-only diagnostic pods (same
image, labels, mounts and config) reached every endpoint. Likely cause: a fresh Job pod reaches
OpenBao before the sso/approval-engine ingress rules admit it (NetworkPolicy is programmed per
destination). Now:
- build waits until OpenBao, KeyCape, approval-engine, audit-core and LLDAP all answer HTTP
  (one shared 30 s budget); an unreachable one is named: setup:<name> not reachable.
- a preflight error is a refusal named preflight_error:<Type> (preflight has no effect).
- an error in the consume read-back is outcome unknown, consume_unconfirmed:<Type>, alerted;
  before, any exception after setup was reported as 'refused, no effect' even after consume.
- any other escaping error after setup is outcome unknown (exit 5), never 'no effect'.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 523928@bnt-lap001
Assistant-Session: 6c737afb-9c14-4152-9f02-477214b9c350
This commit is contained in:
tegwick 2026-11-05 00:39:10 +01:00
parent a962bc8ecc
commit c2a0f2f4e0
5 changed files with 116 additions and 9 deletions

View file

@ -54,6 +54,7 @@ import pathlib
import signal
import sys
import threading
import urllib.parse
HERE = pathlib.Path(__file__).resolve().parent
@ -106,6 +107,19 @@ def distinct_roles(cfg: dict) -> None:
raise ValueError("every lane must use its own OpenBao role")
def run_endpoints(cfg: dict) -> dict:
"""Every service the run talks to, with a path that answers HTTP without credentials (any status counts)."""
ends = {"openbao": (cfg["openbao"]["addr"], "/v1/sys/health"),
"lldap": (cfg["lldap"]["url"], "/"),
"audit-core": (cfg["audit_core"]["url"], "/healthz"),
"approval-engine": (cfg["approval_engine"]["url"], "/healthz")}
client = cfg["approval_engine"].get("client")
if client: # the KeyCape token endpoint answers a GET with an HTTP error, which proves the path
token = urllib.parse.urlsplit(client["token_url"])
ends["keycape"] = (f"{token.scheme}://{token.netloc}", "/healthz")
return ends
def build(cfg: dict, logins: list):
"""`logins` collects every OpenBao client as soon as it exists, so the caller revokes them all, even when a
later step of setup fails."""
@ -114,7 +128,7 @@ def build(cfg: dict, logins: list):
raise ValueError("the journey read and the bind write must use separate roles")
distinct_roles(cfg)
OPS.wait_reachable(o["addr"], ca_file=o.get("ca_file")) # new pod: NetworkPolicy may not be applied yet
OPS.wait_all_reachable(run_endpoints(cfg)) # new pod: NetworkPolicy is programmed per destination
def login(role: str):
client = OPS.OpenBao(o["addr"], k8s_role=role, jwt_file=o["jwt_file"], ca_file=o.get("ca_file"))
@ -336,9 +350,16 @@ def main(argv=None) -> int:
logins: list = []
try:
config, deps = build(cfg, logins)
result = X.Run(admission, args.approval_id, config, deps).execute()
except Exception as error: # setup failed before preflight: nothing was consumed
result = {"outcome": "refused", "reason": "setup:" + type(error).__name__, "run_id": None, "effects": False}
where = str(error) if isinstance(error, OPS.Unreachable) else type(error).__name__
result = {"outcome": "refused", "reason": "setup:" + where, "run_id": None, "effects": False}
else:
run = X.Run(admission, args.approval_id, config, deps)
try:
result = run.execute() # labels its own preflight and consume errors
except Exception as error: # anything else after setup: the run's effect is not established
result = {"outcome": "unknown", "reason": "run:" + type(error).__name__, "run_id": run.run_id,
"effects": "unknown"}
finally:
for client in logins:
client.revoke_self()