access-engine/workplans/FLEX-WP-0039-core-pdp-production-readiness.md
tegwick 7ef17639f8
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
Record hub ids
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 4515@bnt-lap001
Assistant-Session: 0bf96127-6e04-41be-bfda-d11717c3f354
2026-10-28 01:15:48 +01:00

4.5 KiB

id type title domain repo status flavor owner created updated related state_hub_workstream_id
FLEX-WP-0039 workplan Core PDP production readiness: per-pin readiness surface and policy import path infotech access-engine proposed implementation access-engine 2026-10-27 2026-10-27
NK-ADR-0018
NK-WP-0055
FLEX-WP-0031
FLEX-WP-0024
FLEX-WP-0011
f22b4291-f4d0-5b0c-927c-ffe9fdb156f2

FLEX-WP-0039 — Core PDP production readiness

NetKingdom ADR-0018 (accepted 2026-10-27) makes the access-engine Go core the production PDP and runs the PDP readiness checks against it: health, data freshness, policy load status, and per-consumer fail-closed behaviour (NK-WP-0055-T12). It moves the policy import gap to NK-WP-0055-T14.

Current state, from source: /healthz returns a static {"status":"ok"} and says nothing about what was loaded. Each pin loads its policy package and registry snapshot from a path baked into the image (/opt/flex-auth/examples/<consumer>/...), so every policy change is an image rebuild and rollout. /v1/emission already reports outbox state.

1. Readiness surface per pin

id: FLEX-WP-0039-T01
status: todo
priority: medium
state_hub_task_id: "69ff8d8c-20b7-5445-b19b-5b7b1dd2a4aa"

Add GET /v1/readiness (and make /readyz fail when it fails), no secrets, caller-auth exempt like /healthz:

  • policy: package id, version, policy_package_digest, source path, loaded_at, load result (ok or the refusal reason);
  • registry: registry_snapshot_digest, snapshot generated_at, age in seconds against a per-pin maxSnapshotAge (data freshness);
  • caller_auth: mode (enforce/warn/off) and audience;
  • emission: recorder attached, pending depth, lag-bound exceeded (from /v1/emission);
  • release_unit and image digest.

A pin is not ready when the policy failed to load, the snapshot is older than its bound, or caller auth is not enforce on a production unit. Gate: tests for each not-ready cause; chart wires readinessProbe to /readyz.

2. Per-consumer fail-closed receipt

id: FLEX-WP-0039-T02
status: todo
priority: medium
depends_on: [FLEX-WP-0039-T01]
state_hub_task_id: "6aff199c-2f96-5982-8bf6-ac07e31230fe"

A read-only script tools/readiness-receipt that, for each release unit in registry/release-units/, reads /v1/readiness through the operator access path and joins it with the consumer's pep-stance.yaml (ops-warden, tenant-engine, user-engine, secrets-engine, informed-decision). Output is a dated, non-secret receipt per consumer: readiness fields, declared stance on PDP unavailable / 503 / malformed envelope, and whether that stance is closed for the scope. An open-for-scope stance is reported as a finding, not corrected here (FLEX-WP-0031-T09: a 503 only denies if the consumer closes). Live runs are founder-run; the script is tested on fixtures. Gate: receipt for all nine units feeds NK-WP-0055-T12.

3. Decide the policy import path

id: FLEX-WP-0039-T03
status: todo
priority: medium
needs_human: true

NK-WP-0055-T14 accepts either option; the founder picks one:

  • A. Rebuild-and-deploy is the import path. Keep policies in the image; require digest-pinned images, a recorded policy_package_digest per release, and explain receipt after rollout. No new runtime surface. Cost: a release per policy change.
  • B. Mounted policy bundle. Chart mounts a ConfigMap (or OCI artifact pulled by an init container) holding the policy package and registry snapshot; the pin loads it at start (restart on change, no hot reload in v1). Requires a digest pin in values so the loaded package is the reviewed one, and the readiness surface (T01) to prove which digest is live.
  • C. Signed bundle pull. As B, but the bundle is signed and verified before load. Pairs with FLEX-WP-0024's signer custody; heavier, and blocked where 0024 is.

Recommendation: B now with digest pinning, C when FLEX-WP-0024 custody exists. Gate: founder decision recorded as a FLEX-DEC.

4. Split tenant:coulomb platform and tenant packages

id: FLEX-WP-0039-T04
status: todo
priority: medium
depends_on: [FLEX-WP-0039-T03]
state_hub_task_id: "cdb81cbd-abc4-5109-9e3e-7874f5e4984c"

Separate the platform-owned package (guardrails, protected-system actions) from a tenant:coulomb package so tenant policy changes do not touch platform rules, per NK-WP-0055-T14. Produce one production explain receipt (founder-run) against the split. Gate: both packages validate, tenant-scope tests pass, receipt recorded.