Skip to content

MERGE_POLICY.md gate 2 names six security checks and requires none of them #1412

Description

@groupthinking

Problem

MERGE_POLICY.md landed on main in #1408 (f93fecd). Its gate 2 lists the security check-run names the repository actually produces:

| Security | Security Scan - python, Security Scan - javascript, bandit, python-safety, npm-audit, trivy |

But the unconditional required list that follows contains none of them:

Required for every pull request: validate, guards, lint-python, lint-frontend, build, test, CodeQL, gitleaks (working tree), dependency-review, PR Governance, Canonical issue and evidence.

And the conditional list names only one:

  • Security Scan - javascript — only when the diff touches JS/TS.

So Security Scan - python, bandit, python-safety, npm-audit, and trivy appear in the table and then in neither list. The literal reading of v2 is that no security scan gates a merge.

Why this matters

Merge Gate v1 listed Security among its required six. The rewrite that set out to make gate 2 precise therefore dropped every security scan out of the required set — a weakening introduced by the fix rather than present before it.

This is the same defect class the policy is named for and that #1408's own second commit repaired one layer up: a list that does not say what it means. Anyone following adoption step 3 would configure branch protection from the required list and ship a policy with no security gate, while the document's own table implies there is one.

Evidence

All six were measured against the 29 check runs on #1408's documentation-only head 27b2ecf, not inferred:

Context Conclusion on a docs-only PR
Security Scan - python success
Security Scan - javascript success
bandit success
python-safety success
npm-audit success
trivy success

None can strand a pull request permanently pending, which is the only reason gate 2 gives for holding a check back. So all six can be required unconditionally.

Two further findings from the same measurement:

  1. The stated rationale for holding Security Scan - javascript back is empirically false. It reads "only when the diff touches JS/TS", yet it ran to success on a docs-only head.
  2. trivy and Trivy are two different check-runs on the same headsuccess and neutral respectively. Selecting the capitalised one in branch protection would pin a check that never passes. This is exactly the trap gate 2's own confirmation rule exists to catch, and it is currently uncaught.

The conditional entries were re-confirmed and are correct: Generate and Upload Coverage is absent from all 29 checks, and E2E Pipeline Tests is skipped. Both stay conditional.

Acceptance criteria

  • The six security contexts are in gate 2's unconditional required list.
  • Security Scan - javascript is removed from the conditional list, since its stated rationale does not hold.
  • The trivy / Trivy case collision is recorded where someone configuring branch protection will see it.
  • Generate and Upload Coverage and E2E Pipeline Tests remain conditional.

Scope

MERGE_POLICY.md only. Branch protection configuration remains adoption step 3 and is out of scope here.

Activity

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

Metadata

Metadata

Assignees

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions