Skip to content

feat(scripts): hcg-policy-smoke.sh — unknown-path default-deny canary (Phase E)#222

Merged
hyperpolymath merged 2 commits into
mainfrom
feat/hcg-smoke-unknown-path-canary
Jun 14, 2026
Merged

feat(scripts): hcg-policy-smoke.sh — unknown-path default-deny canary (Phase E)#222
hyperpolymath merged 2 commits into
mainfrom
feat/hcg-smoke-unknown-path-canary

Conversation

@hyperpolymath

Copy link
Copy Markdown
Owner

Summary

Extends the §1.5 operator pre-check (scripts/hcg-policy-smoke.sh) with one new probe — GET /__phase-e-canary-unknown-path__ — that isolates the no-match → default-deny branch of the gateway's three-tier lookup at the {:error, :no_match} clause in http-capability-gateway/lib/http_capability_gateway/gateway.ex. The existing six verb canaries cover the unknown-method path (known path, verb outside global_verbs); this canary covers the symmetric unknown-path path (verb in global_verbs, no matching rule). Both must default-deny on independent code branches, so the operator pre-check now fails closed on both classes.

Why

A regression in global-fallback handling alone would leak through the unknown-path branch without tripping any existing canary. The verb-canary block is comprehensive within its class; this PR adds the symmetric class so neither half can silently regress.

The synthetic prefix __phase-e-canary- is reserved for this probe by the script comment and cannot collide with any real or future route in config/gateway-policy-boj.yaml.

Changes

  • scripts/hcg-policy-smoke.sh: one new probe GET … invocation + leading comment explaining the unknown-method vs unknown-path code-path split.
  • docs/integration/hcg-tier2-rollout-runbook.md: §1.5 prose updated to describe the new canary alongside the existing verb canaries; version 0.5 → 0.6; date 2026-06-13 → 2026-06-14.

Test plan

  • bash -n scripts/hcg-policy-smoke.sh — script parses cleanly.
  • Operator-side: when the gateway is up in staging, scripts/hcg-policy-smoke.sh --gateway-url <staging> should report PASS path-canary:GET on synthetic unknown path (no-match default-deny) alongside the existing 25 deny probes and six verb canaries. (Same operator action as before; one extra PASS line.)

Phase E channel notes

  • Channel: hyperpolymath/standards#91 (parent) → Phase E (#100) is the active sub-issue.
  • This PR is a Phase E §1.5 sub-task; per rollout runbook §6.5 (single-lane channel discipline), Phase E close is owner-driven and gated on §3.3 (100% soak), §6.4 (Trustfile flip), and cerro-torre .ctp signing. Each Phase E sub-task therefore lands as a Refs-only advance — this PR deliberately does not Closes #100.

Refs hyperpolymath/standards#91
Refs hyperpolymath/standards#100

🤖 Generated with Claude Code


Generated by Claude Code

@github-actions

Copy link
Copy Markdown

🔍 Hypatia Security Scan

Findings: 215 issues detected

Severity Count
🔴 Critical 15
🟠 High 129
🟡 Medium 71

⚠️ Action Required: Critical security issues found!

View findings
[
  {
    "reason": "Stale AI session file -- delete",
    "type": "stale",
    "file": "GEMINI.md",
    "action": "delete",
    "rule_module": "root_hygiene",
    "severity": "medium"
  },
  {
    "reason": "Issue in scorecard-enforcer.yml",
    "type": "missing_timeout_minutes",
    "file": "scorecard-enforcer.yml",
    "action": "flag",
    "rule_module": "workflow_audit",
    "severity": "medium"
  },
  {
    "reason": "Issue in scorecard-enforcer.yml",
    "type": "scorecard_publish_with_run_step",
    "file": "scorecard-enforcer.yml",
    "action": "split_scorecard_publish_job",
    "rule_module": "workflow_audit",
    "severity": "high"
  },
  {
    "reason": "Issue in instant-sync.yml",
    "type": "secret_action_without_presence_gate",
    "file": "instant-sync.yml",
    "action": "peter-evans/repository-dispatch",
    "rule_module": "workflow_audit",
    "severity": "high"
  },
  {
    "reason": "Issue in codeql.yml",
    "type": "codeql_missing_actions_language",
    "file": "codeql.yml",
    "action": "flag",
    "rule_module": "workflow_audit",
    "severity": "medium"
  },
  {
    "reason": "TypeScript file detected -- banned language",
    "type": "banned_language_file",
    "file": "/home/runner/work/boj-server/boj-server/cartridges/academic-workflow-mcp/adapter/mod.ts",
    "action": "flag",
    "rule_module": "cicd_rules",
    "severity": "critical"
  },
  {
    "reason": "TypeScript file detected -- banned language",
    "type": "banned_language_file",
    "file": "/home/runner/work/boj-server/boj-server/cartridges/ephapax-mcp/adapter/mod.ts",
    "action": "flag",
    "rule_module": "cicd_rules",
    "severity": "critical"
  },
  {
    "reason": "TypeScript file detected -- banned language",
    "type": "banned_language_file",
    "file": "/home/runner/work/boj-server/boj-server/cartridges/bofig-mcp/adapter/mod.ts",
    "action": "flag",
    "rule_module": "cicd_rules",
    "severity": "critical"
  },
  {
    "reason": "TypeScript file detected -- banned language",
    "type": "banned_language_file",
    "file": "/home/runner/work/boj-server/boj-server/cartridges/fireflag-mcp/adapter/mod.ts",
    "action": "flag",
    "rule_module": "cicd_rules",
    "severity": "critical"
  },
  {
    "reason": "TypeScript file detected -- banned language",
    "type": "banned_language_file",
    "file": "/home/runner/work/boj-server/boj-server/cartridges/sanctify-mcp/adapter/mod.ts",
    "action": "flag",
    "rule_module": "cicd_rules",
    "severity": "critical"
  }
]

Powered by Hypatia Neurosymbolic CI/CD Intelligence

@hyperpolymath hyperpolymath marked this pull request as ready for review June 14, 2026 10:52
@hyperpolymath hyperpolymath enabled auto-merge (rebase) June 14, 2026 10:58
@hyperpolymath hyperpolymath disabled auto-merge June 14, 2026 12:05
@hyperpolymath hyperpolymath enabled auto-merge (squash) June 14, 2026 12:05
@hyperpolymath hyperpolymath disabled auto-merge June 14, 2026 12:36
@hyperpolymath hyperpolymath enabled auto-merge (rebase) June 14, 2026 12:44
@hyperpolymath hyperpolymath disabled auto-merge June 14, 2026 12:45
@hyperpolymath hyperpolymath enabled auto-merge (squash) June 14, 2026 14:07
@github-actions

github-actions Bot commented Jun 14, 2026

Copy link
Copy Markdown

🏁 path-claims bench

Commit 863d10e

Numbers
path-claims bench  (node v22.22.3)

  scenario                                              iters       ms        ns/op          ops/s
  --------------------------------------------------------------------------------------------------------------
  register: 10 active claims, 3 new paths               50000 iters    185 ms      3.70 µs/op    270.1k ops/s
  register: 100 active claims, 3 new paths              20000 iters    330 ms     16.54 µs/op     60.5k ops/s
  register: 1000 active claims, 3 new paths              5000 iters    986 ms    197.34 µs/op      5.1k ops/s
  register: 100 active claims, 20 new paths              5000 iters    374 ms     74.96 µs/op     13.3k ops/s

  pathsOverlap: deep diverge at segment 4             1000000 iters    160 ms     160.1 ns/op     6.25M ops/s
  pathsOverlap: short prefix match                    1000000 iters    138 ms     139.0 ns/op     7.20M ops/s

  refresh (existing claim)                             100000 iters     10 ms     109.1 ns/op     9.17M ops/s
  list (100 active claims)                              50000 iters    353 ms      7.07 µs/op    141.5k ops/s

  (Bench numbers depend on host; use deltas across commits, not absolute values.)

Host-dependent — compare deltas across commits, not absolute values.

@github-actions

Copy link
Copy Markdown

🔍 Hypatia Security Scan

Findings: 215 issues detected

Severity Count
🔴 Critical 15
🟠 High 129
🟡 Medium 71

⚠️ Action Required: Critical security issues found!

View findings
[
  {
    "reason": "Stale AI session file -- delete",
    "type": "stale",
    "file": "GEMINI.md",
    "action": "delete",
    "rule_module": "root_hygiene",
    "severity": "medium"
  },
  {
    "reason": "Issue in scorecard-enforcer.yml",
    "type": "missing_timeout_minutes",
    "file": "scorecard-enforcer.yml",
    "action": "flag",
    "rule_module": "workflow_audit",
    "severity": "medium"
  },
  {
    "reason": "Issue in scorecard-enforcer.yml",
    "type": "scorecard_publish_with_run_step",
    "file": "scorecard-enforcer.yml",
    "action": "split_scorecard_publish_job",
    "rule_module": "workflow_audit",
    "severity": "high"
  },
  {
    "reason": "Issue in instant-sync.yml",
    "type": "secret_action_without_presence_gate",
    "file": "instant-sync.yml",
    "action": "peter-evans/repository-dispatch",
    "rule_module": "workflow_audit",
    "severity": "high"
  },
  {
    "reason": "Issue in codeql.yml",
    "type": "codeql_missing_actions_language",
    "file": "codeql.yml",
    "action": "flag",
    "rule_module": "workflow_audit",
    "severity": "medium"
  },
  {
    "reason": "TypeScript file detected -- banned language",
    "type": "banned_language_file",
    "file": "/home/runner/work/boj-server/boj-server/cartridges/academic-workflow-mcp/adapter/mod.ts",
    "action": "flag",
    "rule_module": "cicd_rules",
    "severity": "critical"
  },
  {
    "reason": "TypeScript file detected -- banned language",
    "type": "banned_language_file",
    "file": "/home/runner/work/boj-server/boj-server/cartridges/ephapax-mcp/adapter/mod.ts",
    "action": "flag",
    "rule_module": "cicd_rules",
    "severity": "critical"
  },
  {
    "reason": "TypeScript file detected -- banned language",
    "type": "banned_language_file",
    "file": "/home/runner/work/boj-server/boj-server/cartridges/bofig-mcp/adapter/mod.ts",
    "action": "flag",
    "rule_module": "cicd_rules",
    "severity": "critical"
  },
  {
    "reason": "TypeScript file detected -- banned language",
    "type": "banned_language_file",
    "file": "/home/runner/work/boj-server/boj-server/cartridges/fireflag-mcp/adapter/mod.ts",
    "action": "flag",
    "rule_module": "cicd_rules",
    "severity": "critical"
  },
  {
    "reason": "TypeScript file detected -- banned language",
    "type": "banned_language_file",
    "file": "/home/runner/work/boj-server/boj-server/cartridges/sanctify-mcp/adapter/mod.ts",
    "action": "flag",
    "rule_module": "cicd_rules",
    "severity": "critical"
  }
]

Powered by Hypatia Neurosymbolic CI/CD Intelligence

@hyperpolymath hyperpolymath disabled auto-merge June 14, 2026 14:31
@hyperpolymath hyperpolymath enabled auto-merge (rebase) June 14, 2026 14:31
@hyperpolymath hyperpolymath disabled auto-merge June 14, 2026 14:34
@hyperpolymath hyperpolymath enabled auto-merge (rebase) June 14, 2026 14:36
@hyperpolymath hyperpolymath disabled auto-merge June 14, 2026 14:40
hyperpolymath and others added 2 commits June 14, 2026 15:47
… (Phase E)

Adds one new probe to `scripts/hcg-policy-smoke.sh` so the §1.5 operator
pre-check isolates the no-match → default-deny branch of the gateway's
three-tier lookup (exact → regex → global) at the `{:error, :no_match}`
clause in `http-capability-gateway/lib/http_capability_gateway/gateway.ex`.

Before this PR the smoke script's verb-canary block covered six
unknown-method regressions (DELETE/PUT/PATCH on listed exact paths,
OPTIONS on a listed path, DELETE on a regex-matched route, GET on a
POST-only public route). All six exercise a known path with a verb
outside `global_verbs`. None of them exercises the symmetric pathway: a
verb that *is* in `global_verbs` against a path that has no matching
rule at all. That branch is independently possible to break (a regression
in the global-fallback handling alone would leak there without
triggering any of the existing canaries) so the operator pre-check now
fails closed on both classes.

The new probe targets `GET /__phase-e-canary-unknown-path__` — a
synthetic path that cannot collide with any real route in
`config/gateway-policy-boj.yaml` or any future addition (the prefix is
reserved for this probe by the comment in the script). GET is in
`global_verbs`, so the only way this can default-deny is the no-match
branch.

Runbook §1.5 prose updated to describe the new canary alongside the
existing verb canaries; version bumped 0.5 → 0.6. The §1.5 checkbox
itself stays open — it requires the operator to actually run the script
against staging, which is unchanged.

`bash -n scripts/hcg-policy-smoke.sh` passes. No Elixir / Idris / CI
workflow files touched.

Refs hyperpolymath/standards#91
Refs hyperpolymath/standards#100

(Per rollout runbook §6.5 — single-lane channel discipline — this PR
deliberately does NOT `Closes #100`. Phase E close is owner-driven and
gated on §3.3 (100% soak), §6.4 (Trustfile flip), and cerro-torre
`.ctp` signing. Each Phase E sub-task PR is a `Refs`-only advance.)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@hyperpolymath hyperpolymath force-pushed the feat/hcg-smoke-unknown-path-canary branch from 1d253ac to b53bba6 Compare June 14, 2026 14:48
@hyperpolymath hyperpolymath merged commit c710e25 into main Jun 14, 2026
33 checks passed
@hyperpolymath hyperpolymath deleted the feat/hcg-smoke-unknown-path-canary branch June 14, 2026 14:48
@github-actions

Copy link
Copy Markdown

🔍 Hypatia Security Scan

Findings: 215 issues detected

Severity Count
🔴 Critical 15
🟠 High 129
🟡 Medium 71

⚠️ Action Required: Critical security issues found!

View findings
[
  {
    "reason": "Stale AI session file -- delete",
    "type": "stale",
    "file": "GEMINI.md",
    "action": "delete",
    "rule_module": "root_hygiene",
    "severity": "medium"
  },
  {
    "reason": "Issue in scorecard-enforcer.yml",
    "type": "missing_timeout_minutes",
    "file": "scorecard-enforcer.yml",
    "action": "flag",
    "rule_module": "workflow_audit",
    "severity": "medium"
  },
  {
    "reason": "Issue in scorecard-enforcer.yml",
    "type": "scorecard_publish_with_run_step",
    "file": "scorecard-enforcer.yml",
    "action": "split_scorecard_publish_job",
    "rule_module": "workflow_audit",
    "severity": "high"
  },
  {
    "reason": "Issue in instant-sync.yml",
    "type": "secret_action_without_presence_gate",
    "file": "instant-sync.yml",
    "action": "peter-evans/repository-dispatch",
    "rule_module": "workflow_audit",
    "severity": "high"
  },
  {
    "reason": "Issue in codeql.yml",
    "type": "codeql_missing_actions_language",
    "file": "codeql.yml",
    "action": "flag",
    "rule_module": "workflow_audit",
    "severity": "medium"
  },
  {
    "reason": "TypeScript file detected -- banned language",
    "type": "banned_language_file",
    "file": "/home/runner/work/boj-server/boj-server/cartridges/academic-workflow-mcp/adapter/mod.ts",
    "action": "flag",
    "rule_module": "cicd_rules",
    "severity": "critical"
  },
  {
    "reason": "TypeScript file detected -- banned language",
    "type": "banned_language_file",
    "file": "/home/runner/work/boj-server/boj-server/cartridges/ephapax-mcp/adapter/mod.ts",
    "action": "flag",
    "rule_module": "cicd_rules",
    "severity": "critical"
  },
  {
    "reason": "TypeScript file detected -- banned language",
    "type": "banned_language_file",
    "file": "/home/runner/work/boj-server/boj-server/cartridges/bofig-mcp/adapter/mod.ts",
    "action": "flag",
    "rule_module": "cicd_rules",
    "severity": "critical"
  },
  {
    "reason": "TypeScript file detected -- banned language",
    "type": "banned_language_file",
    "file": "/home/runner/work/boj-server/boj-server/cartridges/fireflag-mcp/adapter/mod.ts",
    "action": "flag",
    "rule_module": "cicd_rules",
    "severity": "critical"
  },
  {
    "reason": "TypeScript file detected -- banned language",
    "type": "banned_language_file",
    "file": "/home/runner/work/boj-server/boj-server/cartridges/sanctify-mcp/adapter/mod.ts",
    "action": "flag",
    "rule_module": "cicd_rules",
    "severity": "critical"
  }
]

Powered by Hypatia Neurosymbolic CI/CD Intelligence

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant