3aac1b456c
Universal: PR Check / Branch Policy (pull_request) Successful in 3s
PR RC Release / Build RC Release (pull_request) Successful in 5s
Universal: PR Check / Validate PR (pull_request) Successful in 15s
Generic: Project CI / Lint & Validate (pull_request) Successful in 23s
Universal: PR Check / Secret Scan (pull_request) Successful in 1m13s
RC Revert / Rename rc/ back to dev/ (pull_request) Has been skipped
Branch Cleanup / Delete merged branch (pull_request) Successful in 1s
Generic: Project CI / Tests (pull_request) Has been cancelled
Universal: PR Check / Build RC Package (pull_request) Has been cancelled
Universal: PR Check / Report Issues (pull_request) Has been cancelled
Adds a single per-org push policy that cascades to every repo of the org and is
enforced in the pre-receive hook:
- Branch/tag name conventions (glob) — a pushed ref name must match. Fail-closed.
- Mandatory secret-scanning block-on-push — org can force secret blocking that a
repo cannot disable (overrides the per-repo scanner config in the orchestrator).
- Max pushed-file size — rejects a tip tree containing a blob over the limit.
- Blocked file-path patterns — rejects pushes changing matching paths (reuses
pull_service.CheckFileProtection).
The two content checks (blocked paths, max size) FAIL OPEN on any error so a
policy/parsing bug can never wedge all pushes; naming is fail-closed.
- models/git/org_push_policy.go: OrgPushPolicy model + CRUD + matchers +
GetOrgPushPolicyForRepo. Migration 364.
- API: GET/PATCH/DELETE /orgs/{org}/push_policy (routers/api/v1/org/push_policy.go,
DTOs in modules/structs/org_push_policy.go, wired in api.go).
- Enforcement: routers/private/hook_pre_receive.go (branch: naming + blocked paths
+ max size; tag: naming) and services/security/orchestrator.go (secret mandate).
Deferred: a repo-facing read-only view of the org push policy (it is an org-wide
config, not per-repo overlay rules; readable via the API for now).
Stacked on #729/#728 for migration ordering (this = 364). Swagger annotations
omitted (can't regenerate without the toolchain).
Note: no Go toolchain available locally, so not compiled/gofmt'd/tested here.
Hand-verified: gofmt (tabs, no blank-in-block), escape sequences in the ls-tree
parser, imports used, migration contiguous (364), fail-open on content checks.
Claude-Session: https://claude.ai/code/session_01Wsno14cxE49MstXFs9G5KT