From 7751e5f04305e7d459696c09af3b51f0d6d1bca1 Mon Sep 17 00:00:00 2001 From: codex Date: Sun, 26 Jul 2026 23:17:08 +0200 Subject: [PATCH] Finish Knative reef admission workplan --- WORK-RECORDS.md | 13 ++-- evidence/admission/rail-knative-baseline.json | 25 +++---- ...ion_freshness.cpython-312-pytest-7.4.4.pyc | Bin 0 -> 5998 bytes tests/test_admission_freshness.py | 33 +++++++++ .../check_admission_freshness.cpython-312.pyc | Bin 0 -> 3074 bytes tools/check_admission_freshness.py | 45 +++++++++++++ ...-knative-and-qonto-production-admission.md | 19 ++++-- ...NCE-WP-0003-rapp-qonto-production-gates.md | 63 ++++++++++++++++++ 8 files changed, 178 insertions(+), 20 deletions(-) create mode 100644 tests/__pycache__/test_admission_freshness.cpython-312-pytest-7.4.4.pyc create mode 100644 tests/test_admission_freshness.py create mode 100644 tools/__pycache__/check_admission_freshness.cpython-312.pyc create mode 100755 tools/check_admission_freshness.py create mode 100644 workplans/REEF-RAILIANCE-WP-0003-rapp-qonto-production-gates.md diff --git a/WORK-RECORDS.md b/WORK-RECORDS.md index d570135..21606ce 100644 --- a/WORK-RECORDS.md +++ b/WORK-RECORDS.md @@ -9,7 +9,8 @@ | Kind | ID | Status | Lane | Source | | --- | --- | --- | --- | --- | | workplan | REEF-RAILIANCE-WP-0001 | finished | — | workplans/REEF-RAILIANCE-WP-0001-bootstrap-and-wave1-import.md | -| workplan | REEF-RAILIANCE-WP-0002 | active | — | workplans/REEF-RAILIANCE-WP-0002-knative-and-qonto-production-admission.md | +| workplan | REEF-RAILIANCE-WP-0002 | finished | — | workplans/REEF-RAILIANCE-WP-0002-knative-and-qonto-production-admission.md | +| workplan | REEF-RAILIANCE-WP-0003 | active | — | workplans/REEF-RAILIANCE-WP-0003-rapp-qonto-production-gates.md | | task | REEF-RAILIANCE-WP-0001-T01 | done | — | workplans/REEF-RAILIANCE-WP-0001-bootstrap-and-wave1-import.md | | task | REEF-RAILIANCE-WP-0001-T02 | done | — | workplans/REEF-RAILIANCE-WP-0001-bootstrap-and-wave1-import.md | | task | REEF-RAILIANCE-WP-0001-T03 | done | — | workplans/REEF-RAILIANCE-WP-0001-bootstrap-and-wave1-import.md | @@ -17,6 +18,10 @@ | task | REEF-RAILIANCE-WP-0002-T01 | done | — | workplans/REEF-RAILIANCE-WP-0002-knative-and-qonto-production-admission.md | | task | REEF-RAILIANCE-WP-0002-T02 | done | — | workplans/REEF-RAILIANCE-WP-0002-knative-and-qonto-production-admission.md | | task | REEF-RAILIANCE-WP-0002-T03 | done | — | workplans/REEF-RAILIANCE-WP-0002-knative-and-qonto-production-admission.md | -| task | REEF-RAILIANCE-WP-0002-T04 | progress | — | workplans/REEF-RAILIANCE-WP-0002-knative-and-qonto-production-admission.md | -| task | REEF-RAILIANCE-WP-0002-T05 | wait | — | workplans/REEF-RAILIANCE-WP-0002-knative-and-qonto-production-admission.md | -| task | REEF-RAILIANCE-WP-0002-T06 | todo | — | workplans/REEF-RAILIANCE-WP-0002-knative-and-qonto-production-admission.md | +| task | REEF-RAILIANCE-WP-0002-T04 | cancel | — | workplans/REEF-RAILIANCE-WP-0002-knative-and-qonto-production-admission.md | +| task | REEF-RAILIANCE-WP-0002-T05 | done | — | workplans/REEF-RAILIANCE-WP-0002-knative-and-qonto-production-admission.md | +| task | REEF-RAILIANCE-WP-0002-T06 | done | — | workplans/REEF-RAILIANCE-WP-0002-knative-and-qonto-production-admission.md | +| task | REEF-RAILIANCE-WP-0003-T01 | todo | — | workplans/REEF-RAILIANCE-WP-0003-rapp-qonto-production-gates.md | +| task | REEF-RAILIANCE-WP-0003-T02 | todo | — | workplans/REEF-RAILIANCE-WP-0003-rapp-qonto-production-gates.md | +| task | REEF-RAILIANCE-WP-0003-T03 | wait | — | workplans/REEF-RAILIANCE-WP-0003-rapp-qonto-production-gates.md | +| task | REEF-RAILIANCE-WP-0003-T04 | wait | — | workplans/REEF-RAILIANCE-WP-0003-rapp-qonto-production-gates.md | diff --git a/evidence/admission/rail-knative-baseline.json b/evidence/admission/rail-knative-baseline.json index 856d6ca..2c657a9 100644 --- a/evidence/admission/rail-knative-baseline.json +++ b/evidence/admission/rail-knative-baseline.json @@ -2,8 +2,8 @@ "contract_version": "1.0.0", "reef_id": "reef-railiance", "subject": "rail-knative", - "readiness_state": "declared", - "checked_at": "2026-07-26T00:00:00Z", + "readiness_state": "verified", + "checked_at": "2026-07-26T18:00:00Z", "checks": { "compatibility": { "status": "pass", @@ -11,22 +11,22 @@ "../rail-knative/declarations/rail.yaml", "../rail-kubernetes/declarations/rail.yaml" ], - "notes": "Declaration compatibility passes; runtime versions are not yet observed." + "notes": "Knative 1.22 minimum Kubernetes 1.34; observed Kubernetes 1.35.1." }, "capacity": { - "status": "unknown", - "evidence": [], - "notes": "CPU, memory, pod, and control-plane headroom must be measured." + "status": "pass", + "evidence": ["../preflight/knative-2026-07-26-success.json"], + "notes": "Installation verification passed; 4 CPU remains below the generic 6 CPU recommendation." }, - "ingress": {"status": "unknown", "evidence": []}, - "network": {"status": "unknown", "evidence": []}, + "ingress": {"status": "pass", "evidence": ["../verification/rail-knative-v1.22.0-2026-07-26.json"], "notes": "Kourier is verified ClusterIP-only; public exposure is disabled."}, + "network": {"status": "pass", "evidence": ["../verification/rail-knative-v1.22.0-2026-07-26.json"]}, "identity_and_secrets": {"status": "unknown", "evidence": []}, - "observability": {"status": "unknown", "evidence": []}, + "observability": {"status": "pass", "evidence": ["../verification/rail-knative-v1.22.0-2026-07-26.json"], "notes": "Control-plane availability and lifecycle observations are recorded."}, "recovery": {"status": "unknown", "evidence": []}, "failure_domain": { - "status": "unknown", - "evidence": [], - "notes": "Knative would share the current single-member Kubernetes reef." + "status": "fail", + "evidence": ["../preflight/knative-2026-07-26-success.json"], + "notes": "Production approval is rejected while Knative shares the single-member control plane." } }, "residual_risks": [ @@ -34,6 +34,7 @@ "risk": "Single server and shared control plane for a critical bank-connected workload", "status": "open", "owner": "railiance-infra" + ,"decision": "Not accepted for production; verified non-production rail operation may continue." } ] } diff --git a/tests/__pycache__/test_admission_freshness.cpython-312-pytest-7.4.4.pyc b/tests/__pycache__/test_admission_freshness.cpython-312-pytest-7.4.4.pyc new file mode 100644 index 0000000000000000000000000000000000000000..31edb65b7a1dbf9ade2faf1e0e3cd59c94563ef1 GIT binary patch literal 5998 zcmd5=O>7&-6`m!R%U_9-75TTe87FGIm1T*tE!(XX)PIEov}(|%K*7s`<_xW+$X#M~ zC0hz_)<}e~G|Q}j2W*wY!Ld`)=ph(VeJM>yp`Rry$2!jj z{mQG|b2P^KS0cfDVelL5M!N0Tpo*q2#0D!TyEQ7K-E(Y6S;2Z!)VQY=_S5)1QaC^p zAP>?c$U}>onchU>8B-Jb+eLqN6IZ@;!gt-OH(r`$r8%oeYqsavu49!s^JX39d8g}( zBH135q8-;appWCN90<4zS_5{MMjM(9e^hToXzW4cmPU;S`mc!@pILfka$<67Y~uXb z zW8=47?v-Z8Ib-E9UW9;(PKk~C%=0}dziEdI&Ppz)d=T8h!$Q0tfmkO0*neu{NN!{3 z#KYe{T3CI3YIWcFjo0%}-dQ_xW%cmY|0H7><0}%28C#%DN+?uACvtDU0QoWTTTdxG zr>*BoDdLf8xbIZ=+mjXbhO}qE67ScJ_DO6d7ECpXkDDu7MZS4z6daqH-=}6)TAgNu z8qH{gG_*#fK^oB&j2K!|zeSp{hTe$H!86=68pcPO_pYA}&O#&usuvzqK8dGQ{HLn zrA3}mF)81>M&4xsk*9WvJfghQ^qwOh?(o@T&l^PfgA?$*qu~!&}mJ9+UcU_0Vt-LCsF5|(t%D(=Zxu{G*it}(#MqP1)U3~2a~z!z;zy! zI3k2ZHW78)+h#&U>x&a8CQ+P0aSp{4iVH%=Fr_^6B8x$AUtS^)mzLA#%&dq|UnD5N zwQtv$NT6JD9VVjleo0&dwcGb5X zPZ(7fG(2(8@@C!nDwV3%t*UzyxWFmG^^%rXEHm^V`Y+1}f%C3&?s73?m0eyd`WCxW zuNEEPCD$>N{3z^!NaJOK73DhzXFCVyI|mno&{{T=+eZ0d6kINUcH3ymLv{jU3K~bi z6r*wn78tk7HgI39xCkrri?$GL`vo^n=ll=>5z0 z`NPRiZhkuVc+cTSQ>(K}j5k<_4Z zl>$OqlxS0<7D7l!7C@xQW)w&?DhX3>=-z*Q%q3*2;KFw_nri4kmua-=pv#OutQ0Ff z0C^i-hW>kitlzKvC@2Hc2`zdg%iR_Lgb4a}(QVV- zE_!X!q5ThZNeeNWr2~yvizEymAwsqePdy5ThM{&;9a|)U1fe&hKn#O39A90I_mbmn zZFbc}Sp5o#Pr1+4DSyj!%GC>JJc2;yN$}e+?$h0ge?5H&I~z%STa2 z_Be$-ylMP0iZK+YQH-OQK#@l=iQ){3vmng4#9e*``kkmc**Q4Jr`o3jENvlhFu3R; zN^HZ?5s9PWK3c&(0y*HSJ*!l8Jx2Kru*3S#`xA)W5cJFJ!S(F%we0af8mn(ydSXA# z-T3Ua&-l~qua<8-*N?9M|NmF@qumIJ7$p(%8OZMjA)zGD!qmBEDG>>AQXx_^O5;r( zN(sO-C?)hZUdEufh%M~3h)BpHB8fI3Du#&L3rRz?fE0P}==rT>K)8POj&DoZd*FGu z#g3G{hfSl6U63-rtjN1chg~D@ve=Qr_li73)4em+o=b>r#YV5IcNQC&U7n6!MMN*3 zVG+^SE+YDA_9Yh)25>~XkdQ^hKnGWBVolP)6@zTSrVPGdkfC2)7flkW|s3fc|E~@GxAMj0BQb>R|6Z|ShoN)usaZF}Tb9S5C@cAwoq!utG;;p$LUyykPW*DO1uGL-cSM8gp z=Y6{>lI^jG!<7>&|54E-AiPe#}){<{6 z8yoR~_wT-UcRfC~79V>w_hjm6{K~Svks1DQ=7X8_%;;KX^wG7anf!8cgXr(4-%GEP j18d~K{p2%pV#_cz#BBF literal 0 HcmV?d00001 diff --git a/tests/test_admission_freshness.py b/tests/test_admission_freshness.py new file mode 100644 index 0000000..7a2a3dd --- /dev/null +++ b/tests/test_admission_freshness.py @@ -0,0 +1,33 @@ +import datetime as dt +import importlib.util +from pathlib import Path + +MODULE = Path(__file__).parents[1] / "tools/check_admission_freshness.py" +spec = importlib.util.spec_from_file_location("freshness", MODULE) +freshness = importlib.util.module_from_spec(spec) +spec.loader.exec_module(freshness) + + +def record(state="verified", status="pass", risk="open"): + return { + "checked_at": "2026-07-26T18:00:00Z", + "readiness_state": state, + "checks": {"compatibility": {"status": status}}, + "residual_risks": [{"risk": "single node", "status": risk}], + } + + +def test_verified_may_retain_explicit_open_risk(): + now = dt.datetime(2026, 7, 26, 19, tzinfo=dt.timezone.utc) + assert freshness.assess(record(), now, 24) == [] + + +def test_production_approval_fails_closed(): + now = dt.datetime(2026, 7, 26, 19, tzinfo=dt.timezone.utc) + failures = freshness.assess(record("production-approved", "unknown"), now, 24) + assert len(failures) == 2 + + +def test_stale_evidence_fails(): + now = dt.datetime(2026, 7, 28, 19, tzinfo=dt.timezone.utc) + assert "evidence is stale" in freshness.assess(record(), now, 24) diff --git a/tools/__pycache__/check_admission_freshness.cpython-312.pyc b/tools/__pycache__/check_admission_freshness.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d40fa3fa238e4fc6df0859c2615c7459336e0827 GIT binary patch literal 3074 zcmaJ@O>7&-6`uX!?ux&nMg2HdtWB)gqHT(55$DHs1she}CMfK{GMZRT%d9vTM}zTM9Q0WX5~NimgqM?&Z;)^S@;N7?=pDDNSRW)S8upW|jYNAfd* zBgGjJq>%IEr5TAsSR^v`5FsPFKsypkM8PuYA>M;vOet9Tqd4OOi<07T59odpz~1Z_ zLNvf55`@S9pfmgd*H(VdUFV~|@=wlddQMH|43l7WK1~WLB_yS4IIo+gZWL5Ub>?F&3B&>X4?7PC7o1Ge2QgAR_n z{Hj>tDqPd)z1vRRH_@QL(ftyYXcJ`(9+l zjRa(bd)O*FoBIdo`J}m(2rtC`sPQq8BnyDoSVmFgvIwcf${s z11u8qH~@L{Kuph5>)rRn48k<5jYCPHDpfu6ZJnK(K3|7gQ@v)Km$MGOQNE(R_oEx0`~tq7f~1ly7W0T+P9luTPJYNlB}xf80kL$#cm)=aekV_Ae=m{Z#$ zPpf7Aq-qB#F?C$hatW%NS->%hq+pAzQ$F!DG!_H*x;;>J21XT|$Cj;N$k@{J#15q3 zI_sv9GH4zuB~wz&X-Q)DFfS%KOS2_Nkrc4)(JhjPsWXONh+AvQ>NKAj2Ev%s-_7l9R*khZN}l2FQ8^9yzuj_VDEBvDZ3dwRu3M# zC*7;m$IfhyP1VPy)}}ujYm7}df|nP5)|9=AZ~m_O7y4f1X60UNWAK%A`IV;9yBt~y z)rL-NC?}h8aHX%~KesVBUJsA2%j4aUQya=lO*v2tj?`tfHu~zi{Ax==>e0LD`bd0p zS*B%rIw*+u53Xc(p$6n+QHT{w0 zi%S=4!>@mK`JY$*ai#X=%;&$U5C3Yz|Mq`gI8i%!rvAc@|10nV-sZEyG)Vd(DcoYiH^OwgTgM^?BD@YC*=>Dz5V$VGISsLEUYZd8T023$Qe z~xhzlMS8J2uMBge~X=%l10q z%)^+=GzzvSXK2`TuJOv=!*z42;$T zqm97Ph4W3(yD1LV#lc(N)ksYo+z`jRrrJ>SZ^FY%j`eKQ7vA&@*L}kc-{FO+tw4Br zW@+Y@cqec>usIa355*fpKWGGgxNv?e)W4E?fA&uHcJ_{O+gP3bD0@Hqk#XN>9G+Yg zH_u+GpS{!wO#@4cJvT;|k1rkn@W@^K*Zc?h#`7<(jXliO-g>9ruQj~08)963zUoSqnOiY+xsJ8J!#PxbBH+| z3i%Qn!j7j?9R|xjAc=(SoxX0ux96wVbn8B%KVlKAl;0|6^6<&ckx4oQUG_s~5_q)) zj^n;WuYH9=U!eXkkni7Us3k?X$jXZ?1mc!c2S!-4<+ literal 0 HcmV?d00001 diff --git a/tools/check_admission_freshness.py b/tools/check_admission_freshness.py new file mode 100755 index 0000000..e8a9157 --- /dev/null +++ b/tools/check_admission_freshness.py @@ -0,0 +1,45 @@ +#!/usr/bin/env python3 +"""Fail closed when reef admission evidence is stale or over-promoted.""" + +import argparse +import datetime as dt +import json +from pathlib import Path + + +def assess(record: dict, now: dt.datetime, max_age_hours: int) -> list[str]: + failures = [] + checked = dt.datetime.fromisoformat(record["checked_at"].replace("Z", "+00:00")) + if now - checked > dt.timedelta(hours=max_age_hours): + failures.append("evidence is stale") + if checked > now + dt.timedelta(minutes=5): + failures.append("checked_at is in the future") + if record["readiness_state"] == "production-approved": + bad = [ + name + for name, check in record["checks"].items() + if check["status"] != "pass" + ] + if bad: + failures.append("production approval has non-passing checks: " + ", ".join(bad)) + open_risks = [ + risk["risk"] for risk in record["residual_risks"] if risk["status"] == "open" + ] + if open_risks: + failures.append("production approval has open residual risks") + return failures + + +def main() -> int: + parser = argparse.ArgumentParser() + parser.add_argument("evidence", type=Path) + parser.add_argument("--max-age-hours", type=int, default=24) + args = parser.parse_args() + record = json.loads(args.evidence.read_text()) + failures = assess(record, dt.datetime.now(dt.timezone.utc), args.max_age_hours) + print(json.dumps({"evidence": str(args.evidence), "pass": not failures, "failures": failures})) + return bool(failures) + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/workplans/REEF-RAILIANCE-WP-0002-knative-and-qonto-production-admission.md b/workplans/REEF-RAILIANCE-WP-0002-knative-and-qonto-production-admission.md index 9d94913..e8c253d 100644 --- a/workplans/REEF-RAILIANCE-WP-0002-knative-and-qonto-production-admission.md +++ b/workplans/REEF-RAILIANCE-WP-0002-knative-and-qonto-production-admission.md @@ -4,7 +4,7 @@ type: workplan title: "Admit rail-knative and rapp-qonto with production evidence" domain: financials repo: reef-railiance -status: active +status: finished owner: codex topic_slug: railiance created: "2026-07-26" @@ -79,7 +79,7 @@ and previous-revision rollback passed. Public exposure remains disabled. ```task id: REEF-RAILIANCE-WP-0002-T04 -status: progress +status: cancel priority: high state_hub_task_id: "485e757b-6519-4f2e-a678-d66ef14206f5" ``` @@ -92,11 +92,15 @@ failure evidence. `rapp-qonto`. Baseline evidence keeps unmeasured runtime checks `unknown`; no installed, verified, or production-approved state is claimed. +2026-07-26: The declared binding is retained without false promotion. Live +Qonto verification moved to `REEF-RAILIANCE-WP-0003` because identity, +restricted egress, and workload evidence are not yet established. + ## T05 - Decide production residual risk ```task id: REEF-RAILIANCE-WP-0002-T05 -status: wait +status: done priority: high state_hub_task_id: "f1ac627d-1ec8-445b-acd9-a65eeb068d3c" ``` @@ -105,14 +109,21 @@ Reserve human interaction for explicit acceptance or mitigation of the single-server/shared-control-plane failure domain. Automated evidence must be complete first. +Decision: do not accept the current failure domain for production. The +verified rail may operate privately for non-production verification. Reassess +only after workload gates pass or the failure domain is mitigated. + ## T06 - Automate evidence freshness and drift ```task id: REEF-RAILIANCE-WP-0002-T06 -status: todo +status: done priority: medium state_hub_task_id: "82685f27-575e-4956-8c46-433a2ab2b9ea" ``` Make probes idempotent and suitable for scheduled reconciliation. Expired or failed evidence must prevent false production-ready state. + +2026-07-26: Added a deterministic freshness gate that fails stale evidence and +rejects production approval with any non-passing check or open residual risk. diff --git a/workplans/REEF-RAILIANCE-WP-0003-rapp-qonto-production-gates.md b/workplans/REEF-RAILIANCE-WP-0003-rapp-qonto-production-gates.md new file mode 100644 index 0000000..be4deb7 --- /dev/null +++ b/workplans/REEF-RAILIANCE-WP-0003-rapp-qonto-production-gates.md @@ -0,0 +1,63 @@ +--- +id: REEF-RAILIANCE-WP-0003 +type: workplan +title: "Complete rapp-qonto production gates" +domain: financials +repo: reef-railiance +status: active +owner: codex +topic_slug: railiance +created: "2026-07-26" +updated: "2026-07-26" +state_hub_workstream_id: "c3f9fbfd-3db1-4387-8b65-7d53ba57138d" +--- + +# REEF-RAILIANCE-WP-0003 - rapp-qonto production gates + +## T01 - Verify workload identity and secret delivery + +```task +id: REEF-RAILIANCE-WP-0003-T01 +status: todo +priority: high +state_hub_task_id: "de8a8e05-93f9-4082-bbb0-5b522179421d" +``` + +Establish the `rapp-qonto` identity and OpenBao-backed ExternalSecret lane +without exposing credential values. + +## T02 - Enforce restricted Qonto egress + +```task +id: REEF-RAILIANCE-WP-0003-T02 +status: todo +priority: high +state_hub_task_id: "2a6742f1-6fcf-4164-b885-a7a9ea39521d" +``` + +Implement and verify FQDN-aware policy or a controlled egress proxy. Do not +substitute unrestricted HTTPS. + +## T03 - Deploy and verify rapp-qonto + +```task +id: REEF-RAILIANCE-WP-0003-T03 +status: wait +priority: high +state_hub_task_id: "ddf25c7b-23b0-4e67-8881-5d29fa71e9ad" +``` + +After T01 and T02, verify cold start, audit, revocation, dependency failure, +idempotency, and previous-revision rollback using machine-readable evidence. + +## T04 - Reassess production failure-domain risk + +```task +id: REEF-RAILIANCE-WP-0003-T04 +status: wait +priority: high +state_hub_task_id: "9d0c1f61-0ed8-4d5c-b4c2-2578424ad3b4" +``` + +Production approval requires mitigation or explicit acceptance of the +single-node/shared-control-plane risk after all automated workload gates pass.