Repository navigation
ci: scan hypatia with its own main instead of a hand-bumped pin - #973
Conversation
governance.yml and hypatia-scan.yml pinned hypatia-ref to 23dc74d, so a rule fix merged to main (for example #966's risk-scoped RE001) reached hypatia's own gate only after someone bumped the SHA by hand. Pass `github.event.pull_request.base.sha || github.sha` instead. On a PR that is the base-branch commit, and otherwise the commit being run. It is never the PR head, so a PR still cannot weaken the rules that gate it, and the value is always a 40-hex SHA as the reusable requires. Only hypatia's own callers change; every other repo keeps the reusable's vetted default. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01J4QvDfStHgMdZGTeqaBgM1
|
Warning Review limit reachedYou've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. Next included review available in 55 minutes. View limit details
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
) ## Summary Step 3 of the governance-gate stack, after #966, #967, #968 and #973. Under RE001 as #964 (standards ADR-009) now ships it, every job that reads a real secret is in scope. On main that is **9 `:warn` findings**. Once #973 makes hypatia's gate run main's rules, they hold it red at the `info` threshold. This PR clears them by the safety-triangle order: **eliminate** the credential where we can, then **control** what remains. | job | secret | action | |---|---|---| | `security-policy` / `secret-gitleaks` | `GITLEAKS_LICENSE` | **Eliminated.** gitleaks-action needs a licence only for an organization owner. Run 40442141312 logs `[hyperpolymath] is an individual user. No license key is required.` and shows the secret empty, so it was never set. | | `inbox-steward-intake` / `analyze-patterns` | `FARM_PAT` | Its read-only checkout no longer takes the PAT and keeps no credential (`persist-credentials: false`). The `gh api` read still uses the PAT, so the job is **hardened** with GitHub + API. | | `inbox-steward-intake` / `dispatch-to-farm` | `FARM_PAT` | Dropped a checkout nothing read. **Hardened**, API only. | | `inbox-steward-intake` / `record-report`, `update-ruleset` | `FARM_PAT` | **Hardened**, GitHub + API (push, `gh pr create`). | | `ci-health-sweep` / `sweep` | `HYPATIA_DISPATCH_PAT` | **Hardened**, GitHub + API. Every call in `scripts/ci-health/*.sh` is `gh`. | | `hypatia-remediation-sweep` / `sweep` | `HYPATIA_DISPATCH_PAT` | **Hardened**, API plus the artifact service and its blob storage. | | `roadmap-sync` / `sync` | App private key | **Hardened**, API only. It already used an App token (substitution done before this PR). | | `push-email-notify` / `notify` | `SMTP_*` | **Hardened**: the action's release download, plus `${{ secrets.SMTP_HOST }}:${{ secrets.SMTP_PORT \|\| '465' }}`. The mail host is itself a secret, so it stays masked. | All hardening is `step-security/harden-runner@v2.22.2` with `egress-policy: block`, the same pin #968 introduced. `actions.lock` holds the tool's bytes from run 40443523409 (sha256 `74ebf8be…`, `GATE_RC=0`); it was not hand-written. ## How has this been verified? - **RE001, #964's version** (`653d09c`) on this tree: 9 → **0**. Main's version: 0 → 0. - **Differential self-scan**, all 15 rule modules over `origin/main` and this branch, keeping findings on the six touched workflows: - with #964's rules, only those 9 RE001 findings go and nothing is added; - with main's rules, there is no change; - WH004 is 0 once the lock is in. - **actionlint 1.7.7:** the same 85 issues as main, none new. - **Not verified, and the real risk:** a `block` allow-list that misses a host breaks its job at run time. These jobs run on schedule, dispatch or push, so PR CI can't exercise them. I worked out each list from the job's code (every `gh`/`git`/action call), not by observation. I propose one `workflow_dispatch` per job with its own `dry_run`, before or just after merge, and reading harden-runner's egress report. ## Not done here (needs the owner or another repo) - **Substitution:** the four `FARM_PAT` jobs and the two `HYPATIA_DISPATCH_PAT` sweeps could each move to a GitHub App installation token scoped to the repos they touch, as roadmap-sync already does. That means creating Apps, which this session can't do. - **Attestation:** a `hypatia_chora.deed` with `(egress …)` entries (`:enforcement harden-runner-block`), once #964 lands, agreed with the #964 session. - **Org move:** if the repo moves to an organization (as standards did), gitleaks will need `GITLEAKS_LICENSE` again. --- _Generated by [Claude Code](https://claude.ai/code/session_01J4QvDfStHgMdZGTeqaBgM1)_
) ## Summary The last step of the RE001 / governance-gate work (#966, #967, #968, #973, #974). The order was eliminate the credential, then harden the job, then **declare** what remains. This PR is the declaring step: hypatia's first repo deed, following one-deed-per-repo (standards#837) and modelled on `standards_chora.deed`. **Translated from `.machine_readable/CLADE.a2ml`** under `clade-to-repo-deed.adoc`: - `(identity)`, `(clade)`, `(forges)`, `(lineage)` and `(status)`. - `:repo-uuid` is the ADR-008 v8 form re-derived from the name (spec §5 P-1), not the retired v5 that CLADE holds. - CLADE's `[identity] name` and `project` aren't in the mapping table, and both repeat `canonical-name`, so they aren't emitted. **Not translated, and named in the header.** These records stay live, as standards' are: - AGENTIC (`max-automation`, `sprint-patterns`, `workflow-pin-detection`), NEUROSYM (`proof-integration`) and PLAYBOOK (`crg-promotion-criteria`) carry sections their mapping table doesn't list, so `a2ml_to_deed.py` refuses them rather than guess. - META and ECOSYSTEM aren't translated either. - STATE waits on `state-v1-decision.adoc`. **`(egress …)`:** all 10 jobs on main that read a secret other than `GITHUB_TOKEN`. - Each uses `:enforcement harden-runner-block`. - Each `:endpoints` list is that job's harden-runner `allowed-endpoints`, byte for byte, so a later check can test the two for equality. - The one exception is push-email-notify's mail host. It is itself a secret, so it's written `secret:SMTP_HOST`. | workflow | jobs | secret | |---|---|---| | `ci-health-sweep` | `sweep` | `HYPATIA_DISPATCH_PAT` | | `estate-rescan` | `preflight`, `publish` | `HYPATIA_DISPATCH_PAT` | | `hypatia-remediation-sweep` | `sweep` | `HYPATIA_DISPATCH_PAT` | | `inbox-steward-intake` | `record-report`, `analyze-patterns`, `update-ruleset`, `dispatch-to-farm` | `FARM_PAT` | | `push-email-notify` | `notify` | `SMTP_*` | | `roadmap-sync` | `sync` | App private key | ## How has this been verified? - **Linters, from standards main `e0645391`:** `bun deed_lint.js` OK, and `bun deed_lint.js --egress` OK with 10 jobs. These are the checks standards' `deed-conformance.yml` runs. `deed_lint.py` rejects the `#u8` form, but it rejects `standards_chora.deed` with the same error, and CI doesn't run it. - **Hypatia's own reader and rule, compiled from main:** `Hypatia.Deed.egress_declarations/1` reads all 10 entries. RE001 reports **0**, with no drift, stale, enforcement or computed-key findings. - **Negative control:** a wrong secret in one entry gives exactly one drift finding, so the comparison is running. - **Differential self-scan** of all 15 rule modules over main and this branch: no content rule flags the new file. ## Notes for reviewers - The deed changes no workflow behaviour. Harden-runner already clears RE001, and the declarations add attestation on top. - `hypatia-remediation-sweep`, `ci-health-sweep` and `estate-rescan` are still red on main. `HYPATIA_DISPATCH_PAT` returns 401 (reported 10-27), and there were startup failures on 11-04 while the lock was being repaired. Neither is caused by this PR. --- _Generated by [Claude Code](https://claude.ai/code/session_01J4QvDfStHgMdZGTeqaBgM1)_
Summary
Step 2 of the stack that turns
governance / Validate Hypatia Baselinegreen, after #966, #967 and #968.Both of hypatia's scanner callers pinned
hypatia-refto23dc74d. A rule fix merged to main therefore reached hypatia's own gate only after a hand bump. #966's risk-scoped RE001 is on main now, but the gate would still build the old rule.This PR replaces the literal with:
pull_requestpush,schedule,workflow_dispatchHEADcanary mode is not used, and nothing callsgit ls-remote.Only the
with:input and its comment change.uses:, the allow-list andactions.lockare untouched.How has this been verified?
actionlint1.7.7 is clean on both files.lib/rulesmodules withscan/1,2were run overorigin/mainand this branch, keeping findings on the two files. Both give the same 10 findings (the ones already on main), with none added or removed.startup_failureon every PR until the Actions allow-list acceptsmetadatastician/standards, which is handled separately.Hypatia Security Scancan confirm thepull_requestbranch of the expression as soon as it runs here.Beyond this repo
Moving the reusables' own
hypatia-refdefault past51ab649, so other repos get #966 too, is a standards decision. This PR does not make it.Generated by Claude Code