WARDEN-WP-0029: implement plan front door, org posture, desk, freshness
All checks were successful
CI Smoke / host-smoke (push) Successful in 1s
CI Smoke / container-smoke (push) Successful in 2s

Ship posture-aware access planning: organization_posture=build (axis C),
catalog freshness warnings, warden plan verdicts, localhost founder desk,
and playbook/agent guidance that retire /tmp file-drop patterns.

Compose route catalog + handoff rather than a second routing layer.
This commit is contained in:
tegwick 2026-07-18 16:59:37 +02:00
parent 5c6b71b83b
commit 5149946a4c
18 changed files with 1690 additions and 102 deletions

View file

@ -42,6 +42,16 @@ class MaturityLevel:
promotion_gate: List[str]
@dataclass
class OrganizationPosture:
"""Fleet lifecycle posture (WARDEN-WP-0029) — third axis, not env/maturity."""
id: str
summary: str
relaxations: List[str]
graduation_triggers: List[str]
@dataclass
class PostureCatalog:
path: Path
@ -49,6 +59,7 @@ class PostureCatalog:
maturity_levels: List[MaturityLevel]
dataclass_floor: Dict[str, str] # dataclass -> maturity id
requires_env_posture: str # lattice: posture a secret fetch requires
organization_posture: OrganizationPosture
# --- lookups ----------------------------------------------------------
def env(self, env_id: str) -> Optional[EnvPosture]:
@ -184,10 +195,24 @@ def load_posture(path: Optional[Path] = None) -> PostureCatalog:
if not any(e.id == requires_env for e in env_postures):
raise PostureError(f"lattice requires_env_posture {requires_env!r} is not an env posture")
org_raw = raw.get("organization_posture") or {}
if not isinstance(org_raw, dict) or not org_raw.get("id"):
raise PostureError(
"posture descriptors need organization_posture with at least an id "
"(WARDEN-WP-0029 third axis)"
)
organization_posture = OrganizationPosture(
id=str(org_raw["id"]),
summary=str(org_raw.get("summary") or "").strip(),
relaxations=[str(x) for x in (org_raw.get("relaxations") or [])],
graduation_triggers=[str(x) for x in (org_raw.get("graduation_triggers") or [])],
)
return PostureCatalog(
path=posture_path,
env_postures=env_postures,
maturity_levels=maturity_levels,
dataclass_floor=dataclass_floor,
requires_env_posture=requires_env,
organization_posture=organization_posture,
)