Skip to content

feat: consume .hypatia-baseline.json in governance gate#166

Merged
hyperpolymath merged 2 commits into
mainfrom
claude/confident-wright-ZJCDT
May 26, 2026
Merged

feat: consume .hypatia-baseline.json in governance gate#166
hyperpolymath merged 2 commits into
mainfrom
claude/confident-wright-ZJCDT

Conversation

@hyperpolymath
Copy link
Copy Markdown
Owner

Summary

Adds a single, formal exemption convention to the estate governance gate: .hypatia-baseline.json. Same shape as Hypatia findings (severity, rule_module, type, file/file_pattern), so an acknowledged finding can be listed once and silently suppressed by the gate. Companion to hyperpolymath/gitbot-fleet#148.

Why

The language-policy job runs banned_language_file across every caller repo. In-flight migrations (e.g. the ReScript → AffineScript port at gitbot-fleet) keep getting blocked on .res files that are already acknowledged in the repo's baseline. PR authors started inventing alternate ignore conventions (.hypatia-ignore flat-files) to work around the gap. This PR formalises one convention so the estate stops sprouting more.

What

  1. validate-baseline job (new) — detects the per-repo baseline file, schema-validates it (ajv when available, jq fallback otherwise), surfaces stale entries (referenced file no longer exists) as warnings. Soft-failure throughout.
  2. language-policy job (updated) — is_exempt() now consults .hypatia-baseline.json before falling back to legacy .hypatia-ignore and the inline # hypatia:ignore pragma. The legacy path stays for back-compat; a follow-up PR retires it once the estate has converged.
  3. .machine_readable/hypatia-baseline.schema.json — formal JSON Schema (draft 2020-12). Required: severity, rule_module, type, plus exactly one of file / file_pattern. Optional: severity_override, expires_at, note, tracking_issue.
  4. scripts/apply-baseline.sh — pure bash+jq filter. Used by the richer findings-list flow this PR seeds; the current workflow integration uses the inline jq lookup instead so the advisory-mode landing has the smallest possible footprint.
  5. docs/HYPATIA-BASELINE-FORMAT.adoc — authoritative format doc.
  6. docs/EXEMPTION-MECHANISMS.adoc — convention doc: when to use .hypatia-baseline.json vs the estate-wide bot_exclusion_registry.a2ml vs per-PR labels.

Rollout

Advisory mode (default). Exempting a finding via the baseline removes it from the gate output. Blocking-mode promotion (via vars.HYPATIA_BASELINE_MODE = "blocking") is the follow-up after a one-week soak. Documented inline at the top of governance-reusable.yml.

Test plan

  • CI green on this branch.
  • Manual: caller repo with a baseline file gets a ⏭️ exempt (baseline) line in the language-policy job logs and the gate passes despite the banned file.
  • Manual: caller repo without a baseline behaves identically to before (legacy .hypatia-ignore + inline pragma still honoured).
  • Manual: caller repo with a malformed baseline gets a validate-baseline warning (not a hard failure during advisory soak).
  • Follow-up after one-week soak: flip HYPATIA_BASELINE_MODE to blocking and confirm the gate behaves identically across the estate.

https://claude.ai/code/session_01W3PAoaqgJj3mnM8kjhEqx4


Generated by Claude Code

Adds a per-repo exemption mechanism to the estate governance gate:
`.hypatia-baseline.json`. Same shape as Hypatia findings themselves
(severity, rule_module, type, file), so an acknowledged finding can be
listed once and silently suppressed by the gate.

Why
---
The `language-policy` job in `governance-reusable.yml` runs
`banned_language_file` across every caller repo. Repos with legitimate
in-flight migrations (e.g. `hyperpolymath/gitbot-fleet`'s ReScript
→ AffineScript port) have been blocked on .res files they have already
acknowledged; PR authors started inventing alternate ignore-file
conventions (`.hypatia-ignore` flat-file) to work around the gap.

This PR formalises one convention so the estate stops sprouting more.

What
----
1. `validate-baseline` job (new). Detects the per-repo baseline file,
   schema-validates it (ajv when available; jq fallback so it never
   fails for missing tooling), and surfaces stale entries (referenced
   file no longer exists) as warnings. Soft-failure throughout — a
   missing baseline is fine, a malformed one is a warning during
   advisory mode.

2. `language-policy` job (updated). The `is_exempt()` helper now
   consults `.hypatia-baseline.json` before falling back to the legacy
   `.hypatia-ignore` flat-file and the inline `# hypatia:ignore`
   pragma. The legacy path stays for backward-compat; a follow-up PR
   will retire it once the estate has converged.

3. `.machine_readable/hypatia-baseline.schema.json` — formal JSON
   Schema (draft 2020-12). Required fields: severity, rule_module,
   type, plus exactly one of file / file_pattern. Optional:
   severity_override, expires_at, note, tracking_issue.

4. `scripts/apply-baseline.sh` — pure bash+jq filter. Used in the
   richer findings-list flow this PR seeds; the current workflow
   integration uses the inline jq lookup instead so an advisory-mode
   landing has the smallest possible footprint.

5. `docs/HYPATIA-BASELINE-FORMAT.adoc` — authoritative format doc.

6. `docs/EXEMPTION-MECHANISMS.adoc` — convention doc clarifying when to
   use `.hypatia-baseline.json` vs the estate-wide
   `bot_exclusion_registry.a2ml` vs per-PR labels.

Rollout
-------
Advisory mode (default) — exempting a finding via the baseline removes
it from the gate output. Blocking-mode promotion (via
`vars.HYPATIA_BASELINE_MODE = "blocking"`) is the follow-up after a
one-week soak.

Companion: `hyperpolymath/gitbot-fleet#148` tracks the ReScript
migration that motivated this. Once this PR merges, the
`.hypatia-baseline.json` entries already in gitbot-fleet will start
being honoured by the gate.
@github-actions
Copy link
Copy Markdown

🔍 Hypatia Security Scan

Findings: 208 issues detected

Severity Count
🔴 Critical 64
🟠 High 120
🟡 Medium 24

⚠️ Action Required: Critical security issues found!

View findings
[
  {
    "reason": "Action hyperpolymath/standards/.github/workflows/governance-reusable.yml@main needs attention",
    "type": "unpinned_action",
    "file": "governance-reusable.yml",
    "action": "pin_sha",
    "rule_module": "workflow_audit",
    "severity": "high"
  },
  {
    "reason": "Action hyperpolymath/standards/.github/workflows/governance-reusable.yml@main needs attention",
    "type": "unpinned_action",
    "file": "governance.yml",
    "action": "pin_sha",
    "rule_module": "workflow_audit",
    "severity": "high"
  },
  {
    "reason": "Python file detected -- banned language",
    "type": "banned_language_file",
    "file": "/home/runner/work/standards/standards/a2ml-templates/state-scm-to-v2.py",
    "action": "flag",
    "rule_module": "cicd_rules",
    "severity": "critical"
  },
  {
    "reason": "TypeScript file detected -- banned language",
    "type": "banned_language_file",
    "file": "/home/runner/work/standards/standards/a2ml/bindings/deno/mod.ts",
    "action": "flag",
    "rule_module": "cicd_rules",
    "severity": "critical"
  },
  {
    "reason": "TypeScript file detected -- banned language",
    "type": "banned_language_file",
    "file": "/home/runner/work/standards/standards/lol/test/vitest.config.ts",
    "action": "flag",
    "rule_module": "cicd_rules",
    "severity": "critical"
  },
  {
    "reason": "TypeScript file detected -- banned language",
    "type": "banned_language_file",
    "file": "/home/runner/work/standards/standards/k9-svc/bindings/deno/mod.ts",
    "action": "flag",
    "rule_module": "cicd_rules",
    "severity": "critical"
  },
  {
    "reason": "Agda postulate assumes without proof -- potential soundness hole (4 occurrences, CWE-704)",
    "type": "agda_postulate",
    "file": "/home/runner/work/standards/standards/lol/proofs/theories/information_theory.agda",
    "action": "flag",
    "rule_module": "code_safety",
    "severity": "critical"
  },
  {
    "reason": "believe_me undermines formal verification (1 occurrences, CWE-704)",
    "type": "believe_me",
    "file": "/home/runner/work/standards/standards/lol/src/abi/Locale.idr",
    "action": "flag",
    "rule_module": "code_safety",
    "severity": "critical"
  },
  {
    "reason": "Wildcard CORS -- restrict to specific origins or use env var (1 occurrences, CWE-942)",
    "type": "js_wildcard_cors",
    "file": "/home/runner/work/standards/standards/consent-aware-http/examples/reference-implementations/deno/aibdp_middleware.js",
    "action": "flag",
    "rule_module": "code_safety",
    "severity": "high"
  },
  {
    "reason": "innerHTML assignment -- XSS risk, use textContent or SafeDOM (1 occurrences, CWE-79)",
    "type": "js_innerhtml",
    "file": "/home/runner/work/standards/standards/axel-protocol/src/Tea.res.js",
    "action": "flag",
    "rule_module": "code_safety",
    "severity": "high"
  }
]

Powered by Hypatia Neurosymbolic CI/CD Intelligence

…ript

The governance-reusable workflow change in this PR adds
.hypatia-baseline.json consumer support; dogfood it on this repo by
adding the baseline file itself. Suppresses the
`cicd_rules/banned_language_file` finding on
a2ml-templates/state-scm-to-v2.py — a one-shot v1->v2 STATE.scm
migration script that is banned (Python) but legitimate for its
purpose. The note records the rewrite-or-retire follow-up.

Demonstrates the mechanism end-to-end: the very PR that adds baseline
support has the gate honour an acknowledged finding on its own repo.

Resolves the dogfood failure on `governance / Language / package
anti-pattern policy`. The separate legacy `Check for Banned Languages`
workflow has no baseline support (intentionally out of scope for this
PR) and will continue to flag — to be retired by a follow-up.
@github-actions
Copy link
Copy Markdown

🔍 Hypatia Security Scan

Findings: 208 issues detected

Severity Count
🔴 Critical 64
🟠 High 120
🟡 Medium 24

⚠️ Action Required: Critical security issues found!

View findings
[
  {
    "reason": "Action hyperpolymath/standards/.github/workflows/governance-reusable.yml@main needs attention",
    "type": "unpinned_action",
    "file": "governance-reusable.yml",
    "action": "pin_sha",
    "rule_module": "workflow_audit",
    "severity": "high"
  },
  {
    "reason": "Action hyperpolymath/standards/.github/workflows/governance-reusable.yml@main needs attention",
    "type": "unpinned_action",
    "file": "governance.yml",
    "action": "pin_sha",
    "rule_module": "workflow_audit",
    "severity": "high"
  },
  {
    "reason": "Python file detected -- banned language",
    "type": "banned_language_file",
    "file": "/home/runner/work/standards/standards/a2ml-templates/state-scm-to-v2.py",
    "action": "flag",
    "rule_module": "cicd_rules",
    "severity": "critical"
  },
  {
    "reason": "TypeScript file detected -- banned language",
    "type": "banned_language_file",
    "file": "/home/runner/work/standards/standards/a2ml/bindings/deno/mod.ts",
    "action": "flag",
    "rule_module": "cicd_rules",
    "severity": "critical"
  },
  {
    "reason": "TypeScript file detected -- banned language",
    "type": "banned_language_file",
    "file": "/home/runner/work/standards/standards/lol/test/vitest.config.ts",
    "action": "flag",
    "rule_module": "cicd_rules",
    "severity": "critical"
  },
  {
    "reason": "TypeScript file detected -- banned language",
    "type": "banned_language_file",
    "file": "/home/runner/work/standards/standards/k9-svc/bindings/deno/mod.ts",
    "action": "flag",
    "rule_module": "cicd_rules",
    "severity": "critical"
  },
  {
    "reason": "Agda postulate assumes without proof -- potential soundness hole (4 occurrences, CWE-704)",
    "type": "agda_postulate",
    "file": "/home/runner/work/standards/standards/lol/proofs/theories/information_theory.agda",
    "action": "flag",
    "rule_module": "code_safety",
    "severity": "critical"
  },
  {
    "reason": "believe_me undermines formal verification (1 occurrences, CWE-704)",
    "type": "believe_me",
    "file": "/home/runner/work/standards/standards/lol/src/abi/Locale.idr",
    "action": "flag",
    "rule_module": "code_safety",
    "severity": "critical"
  },
  {
    "reason": "Wildcard CORS -- restrict to specific origins or use env var (1 occurrences, CWE-942)",
    "type": "js_wildcard_cors",
    "file": "/home/runner/work/standards/standards/consent-aware-http/examples/reference-implementations/deno/aibdp_middleware.js",
    "action": "flag",
    "rule_module": "code_safety",
    "severity": "high"
  },
  {
    "reason": "innerHTML assignment -- XSS risk, use textContent or SafeDOM (1 occurrences, CWE-79)",
    "type": "js_innerhtml",
    "file": "/home/runner/work/standards/standards/axel-protocol/src/Tea.res.js",
    "action": "flag",
    "rule_module": "code_safety",
    "severity": "high"
  }
]

Powered by Hypatia Neurosymbolic CI/CD Intelligence

@hyperpolymath hyperpolymath enabled auto-merge May 26, 2026 00:15
@hyperpolymath hyperpolymath merged commit 91d8b88 into main May 26, 2026
17 of 19 checks passed
@hyperpolymath hyperpolymath deleted the claude/confident-wright-ZJCDT branch May 26, 2026 00:17
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.

2 participants