Commit cb021c4
feat(scripts): extend §1.5 verb-canary coverage (Phase E) (#215)
## Summary
Tightens `scripts/hcg-policy-smoke.sh` against three verb-governance
regression classes the original three canaries (DELETE/PUT/PATCH on
`/cartridges` and `/health`) don't catch. Single-lane HCG tier-2 channel
(`standards#91`); Phase E (`standards#100`) is the active phase.
## What this PR adds
Three new deny-mode verb-canary probes:
1. **`OPTIONS /cartridges`** — `global_verbs: [GET, POST]` bans OPTIONS,
but a CORS preflight auto-responder added later would silently bypass
policy. The canary fails closed against that regression class.
2. **`DELETE /cartridge/probe/invoke`** — exercises the regex route
`^/cartridge/[A-Za-z0-9_.-]+/invoke$` under a banned verb. The existing
exact-path canaries don't catch a regex-matcher regression where the
path is accepted under any verb instead of only the verb the rule lists.
3. **`GET /cartridges/ssg-mcp/webhook`** — the path is in the policy as
a documented public exception, but only for POST. The canary verifies
the `{path, verb}` pairing is enforced: GET on the same path must
default-deny because no rule covers it.
Runbook §1.5 description updated to enumerate the expanded canary set;
runbook version bump 0.4 → 0.5.
## What this PR deliberately does NOT do
- **Probe HEAD.** Curl with `-X HEAD` (vs `--head`) waits for a body the
server will not send, which interacts badly with the script's
`--max-time 10`. HEAD enforcement remains covered by the gateway's own
unit tests; the §1.5 operator pre-check focuses on probes that survive
curl's method quirks. The reasoning is captured inline in the script
comment so a future maintainer doesn't add it back as an oversight.
- **Extend the `--with-backend` allow-path matrix.** The authenticated
routes the script probes in allow mode are the ones actually wired in
`BojRest.Router`; the additional policy entries (`graphql`, `sse`,
`order`, `umoja/*`, etc.) are declared-not-yet-wired per contract §8 and
would 404 from BoJ, which the `allow_or_upstream` pattern misdiagnoses
as gateway-deny. They stay in the deny matrix until they are wired in
BoJ. The `ssg-mcp-webhook-post` route is not added to the
`--with-backend` allow probes for the same reason.
- **Auto-derive the probe matrix from the policy YAML.** The matrix
stays hand-maintained and the parity-with-policy property remains a
manual maintenance discipline. PR #210's commitment ("the script doubles
as a policy-completeness checklist") is preserved.
- **Close `standards#100`.** Per runbook §6.5 the joint-close happens
after the §6.4 Trustfile flip, which itself follows the §3.3 100%
production-soak window. Using `Refs` per the Phase E PR convention (#38,
#208, #210).
## Verification
- [x] `bash -n scripts/hcg-policy-smoke.sh` — syntax check passes.
- [x] Synthetic always-403 mock on `:18443` — `PASS=31 FAIL=0` (was 28);
the three new canaries report PASS; exit 0.
- [x] `--help` and bad-args exit codes unchanged (64).
- [x] SPDX header `MPL-2.0` unchanged.
- [x] Runbook cross-references resolve.
## Channel position
```
standards#91 (parent, open)
├── #96 Phase A — closed
├── #97 Phase B — closed
├── #98 Phase C — closed
├── #99 Phase D — closed (joint-closed via boj-server#168)
└── #100 Phase E — IN PROGRESS
├── E5 runbook draft — boj-server#128 (landed)
├── E1 loopback prereqs — boj-server#130/#131/#132/#165/#173 (landed)
├── E1 deploy spec — http-capability-gateway#38 (landed)
├── E1 live policy promotion — boj-server#208 (landed)
├── §1.5 operator pre-check smoke — boj-server#210 (landed)
├── §1.5 verb-canary expansion — THIS PR (in review)
├── E1 .ctp signing — owner follow-up
├── E2 staging cut-over — owner follow-up
├── E3 telemetry verification — owner follow-up
├── E4 production rollout — owner follow-up
└── §6.4 Trustfile flip + §6.5 joint-close — owner-only
```
Refs hyperpolymath/standards#91
Refs hyperpolymath/standards#100
🤖 Generated with [Claude Code](https://claude.com/claude-code)
---
_Generated by [Claude
Code](https://claude.ai/code/session_01NgeisSDPZ7NJSjkhU95qYS)_
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>1 parent 4bf4641 commit cb021c4
2 files changed
Lines changed: 34 additions & 10 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
3 | 3 | | |
4 | 4 | | |
5 | 5 | | |
6 | | - | |
7 | | - | |
8 | | - | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
9 | 9 | | |
10 | 10 | | |
11 | 11 | | |
| |||
88 | 88 | | |
89 | 89 | | |
90 | 90 | | |
91 | | - | |
| 91 | + | |
92 | 92 | | |
93 | 93 | | |
94 | 94 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
193 | 193 | | |
194 | 194 | | |
195 | 195 | | |
196 | | - | |
197 | | - | |
198 | | - | |
199 | | - | |
200 | | - | |
201 | | - | |
| 196 | + | |
| 197 | + | |
| 198 | + | |
| 199 | + | |
| 200 | + | |
| 201 | + | |
| 202 | + | |
| 203 | + | |
| 204 | + | |
| 205 | + | |
| 206 | + | |
| 207 | + | |
| 208 | + | |
| 209 | + | |
| 210 | + | |
| 211 | + | |
| 212 | + | |
| 213 | + | |
| 214 | + | |
| 215 | + | |
| 216 | + | |
| 217 | + | |
| 218 | + | |
| 219 | + | |
| 220 | + | |
| 221 | + | |
| 222 | + | |
| 223 | + | |
| 224 | + | |
| 225 | + | |
202 | 226 | | |
203 | 227 | | |
204 | 228 | | |
| |||
0 commit comments