From 225e7f6139b1a6aa54a93b779091321e30ac0530 Mon Sep 17 00:00:00 2001 From: "Jonathan D.A. Jewell" <6759885+hyperpolymath@users.noreply.github.com> Date: Thu, 28 May 2026 06:16:57 +0000 Subject: [PATCH] =?UTF-8?q?fix(hcg-policy):=20cover=20wired=20POST=20/cart?= =?UTF-8?q?ridge/:name/sse=20(Phase=20E=20=C2=A71.5)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Re-verified config/gateway-policy-boj-example.yaml against the live BojRest.Router for HCG tier-2 rollout. The wired POST /cartridge/:name/sse route (router.ex line 130; ADR-0013 §6; STATE 2026-05-18) was absent from the example policy — silent surface drift since contract v1.0. Adds `cartridge-sse-post` alongside `cartridge-invoke-post` (same trust gate, same per-cartridge auth.method requirement, streaming response envelope around a single dispatch). Ticks the §1.5 surface-coverage box on the rollout runbook with the re-verification date; flags the live-policy promotion (config/gateway-policy-boj.yaml) and the smoke-test box as the remaining §1.5 work. No runtime behaviour change. Policy YAML re-parses cleanly (27 → 28 rules; global_verbs unchanged: GET, POST). `sse-get` (top-level, declared-not-yet-wired) and `cartridge-sse-post` (per-cartridge, wired) coexist as distinct rules — different path, different verb. Refs hyperpolymath/standards#100 Refs hyperpolymath/standards#91 Co-Authored-By: Claude Opus 4.7 --- config/gateway-policy-boj-example.yaml | 24 +++++++++++++++++++ docs/integration/hcg-tier2-rollout-runbook.md | 2 +- 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/config/gateway-policy-boj-example.yaml b/config/gateway-policy-boj-example.yaml index e1c97299..f8405024 100644 --- a/config/gateway-policy-boj-example.yaml +++ b/config/gateway-policy-boj-example.yaml @@ -23,6 +23,14 @@ # declared in openapi.yaml but not yet wired in router.ex are governed anyway # (contract §8) so they are not silently exposed when implemented. # +# Re-verified 2026-05-28 against `BojRest.Router` for HCG tier-2 rollout +# (Phase E §1.5 prereq, standards#100). Recorded drift since contract v1.0: +# the wired `POST /cartridge/:name/sse` route (router.ex line 130, ADR-0013 +# §6, STATE entry 2026-05-18) was absent from the example policy. Added below +# as `cartridge-sse-post` alongside `cartridge-invoke-post`. The unrelated +# top-level `/sse` GET rule (declared-not-yet-wired, openapi.yaml only) is +# left in place — different path, different verb, different surface. +# # --------------------------------------------------------------------------- # DEFAULT-DENY NOTE (must be confirmed in the Phase A manual verification) # --------------------------------------------------------------------------- @@ -120,6 +128,22 @@ governance: check_trust/3 requires internal/authenticated for cartridges whose auth.method is not `none`." + - path: "^/cartridge/[A-Za-z0-9_.-]+/sse$" + verbs: [POST] + exposure: "authenticated" + name: "cartridge-sse-post" + narrative: "Tool dispatch into a cartridge over Server-Sent Events + (text/event-stream: open → result|error → done; ADR-0013 §6, router.ex + line 130). Same `BojRest.Router.check_trust/3` gate as + cartridge-invoke-post, same per-cartridge auth.method requirement — + just a streaming response envelope around one dispatch. The handler + is bounded (single tool invocation framed by open/done), not + long-lived, so the proxy-timeout / circuit-breaker risk flagged on + sse-get is narrower here: bracketed by tool latency, not by stream + duration. Phase D benchmarks should still cover this path before the + live policy promotes it (Phase E §1.5 surface-drift verification, + standards#100)." + - path: "/graphql" verbs: [POST] exposure: "authenticated" diff --git a/docs/integration/hcg-tier2-rollout-runbook.md b/docs/integration/hcg-tier2-rollout-runbook.md index 4440f492..de41f614 100644 --- a/docs/integration/hcg-tier2-rollout-runbook.md +++ b/docs/integration/hcg-tier2-rollout-runbook.md @@ -81,7 +81,7 @@ These cannot be inferred from the code/contract; the owner must fill them before - [ ] Gateway Containerfile built and signed as a `.ctp` bundle via cerro-torre (plan §E1). - [ ] `container/gateway-deploy.k9.ncl` exists in the gateway repo (plan §E1). -- [ ] Gateway policy file in place: `config/gateway-policy-boj-example.yaml`, covering all BoJ surface routes (`/.well-known/boj-node-pubkey`, `/health`, `/menu`, `/cartridges`, `/cartridge/:name`, `/cartridge/:name/invoke`, plus any added since contract v1.0 — re-verify against `BojRest.Router` at rollout time). +- [x] Gateway policy file in place: `config/gateway-policy-boj-example.yaml`, covering all BoJ surface routes (`/.well-known/boj-node-pubkey`, `/health`, `/menu`, `/cartridges`, `/cartridge/:name`, `/cartridge/:name/invoke`, `/cartridge/:name/sse`, plus any added since contract v1.0). Re-verified 2026-05-28 against `BojRest.Router`; the `POST /cartridge/:name/sse` route (router.ex line 130, wired since the SSE landing — ADR-0013 §6, STATE entry 2026-05-18) was the only drift since contract v1.0 and is now governed by the `cartridge-sse-post` rule alongside `cartridge-invoke-post`. The live policy file (`config/gateway-policy-boj.yaml`, per the example header) is still to be promoted from this example before §3.1. - [ ] Gateway has been smoke-tested in isolation with the policy, returning expected allow/deny on each route. ---