From d9fa885fdcc78f33221a82ccd5a31e90d69bc680 Mon Sep 17 00:00:00 2001 From: Sawyer Cutler Date: Tue, 27 Oct 2026 14:27:52 -0700 Subject: [PATCH 1/4] ci(policy): run the corbits-triage rules and actions --- .corbits-triage.yml | 118 ++++++++++++++++++++++++++++++++------- .github/workflows/ci.yml | 14 +++++ CONTRIBUTING.md | 1 + 3 files changed, 113 insertions(+), 20 deletions(-) diff --git a/.corbits-triage.yml b/.corbits-triage.yml index 6f7733f62..b61dec8d9 100644 --- a/.corbits-triage.yml +++ b/.corbits-triage.yml @@ -1,56 +1,129 @@ # Corbits Triage policy. rules: - check: max-files-changed - text: Flag pull requests over 30 files changed. - max: 30 + text: Flag pull requests over 25 files changed. + max: 25 onFail: ask - reason: Set in the portal before the policy file. + reason: Large pull requests are hard to review. evidence: - maintainer-stated - check: max-lines-changed - text: Flag pull requests over 5,000 lines changed. - max: 5000 + text: Flag pull requests over 1,500 lines changed. + max: 1500 onFail: ask - reason: Set in the portal before the policy file. + reason: Large pull requests are hard to review. evidence: - maintainer-stated - check: focused text: Check the change is focused on one thing. - reason: Set in the portal before the policy file. + reason: A change that does several things is harder to review and to revert. evidence: - maintainer-stated - check: docs text: Check docs are updated when behavior changes. - reason: Set in the portal before the policy file. + reason: A behavior change without a docs update leaves the docs wrong. evidence: - maintainer-stated enabled: false - check: linked-issue - text: Require a linked issue from GitHub or Linear. - tracker: either - reason: Set in the portal before the policy file. + text: Require a linked Linear issue, such as CL-123. + tracker: linear + reason: Every change is tracked in a Linear issue. evidence: - maintainer-stated - check: no-merge-conflicts text: Flag merge conflicts with the base branch. - reason: Set in the portal before the policy file. - evidence: - - maintainer-stated - - check: conventional-commits - text: Pull request titles and commits follow conventional commits. - reason: This repository uses conventional commits. + reason: A pull request with conflicts can't be merged as it is. evidence: - maintainer-stated - check: ci-green text: CI must pass before merge. - reason: Set in the portal before the policy file. + reason: A change is not ready until CI passes. evidence: - maintainer-stated - check: no-forbidden-paths text: Never accept changes to node_modules/**. paths: - node_modules/** - reason: Set in the portal before the policy file. + reason: Dependencies are installed, never committed. + evidence: + - maintainer-stated + - check: conventional-commits + text: Titles and commits follow Conventional Commits. + reason: CONTRIBUTING.md requires Conventional Commits, and 29 of the last 50 merged titles already use them. + evidence: + - maintainer-stated + - check: hidden-content + text: Flag text hidden in the pull request. + reason: Hidden text can steer the rules a model judges. + evidence: + - maintainer-stated + - check: no-duplicate + text: Flag a pull request whose diff or commits match another open one. + reason: Two pull requests for the same change waste a review. + evidence: + - maintainer-stated + - check: duplicates-open-pull-request + text: Ask when a pull request overlaps another open one. + reason: A near duplicate needs a person to pick which one goes on. + evidence: + - maintainer-stated + - check: sensitive-paths + text: Note changes to schema, auth, CI, lockfiles and vendored code. + groups: + schema: { level: high, paths: ["**/migrations/**", "**/*.sql"] } + auth: { level: high, paths: ["**/auth/**", "**/secrets/**"] } + ci: { level: medium, paths: [".github/**"] } + locks: { level: medium, paths: ["**/bun.lock"] } + vendor: { level: medium, paths: ["vendor/**"] } + reason: Schema, auth, CI, lockfile and vendored changes reach beyond what the diff shows. + evidence: + - maintainer-stated + - check: risk + text: Flag high-risk pull requests and label medium-risk ones. + reason: A risky change needs a maintainer's eye. + evidence: + - maintainer-stated + - id: no-ai-attribution + check: text + text: Titles, descriptions and commits carry no AI attribution. + fields: [title, description, commits] + failWhen: contains + phrases: + - "Co-Authored-By: Claude" + - "noreply@anthropic.com" + - "Claude-Session:" + - "claude.ai/code/session" + - "Generated with Claude" + - "Generated with [Claude" + reason: Tool-generated co-author lines, session trailers and footers don't belong in the history. + evidence: + - maintainer-stated + - id: conventions + check: code-patterns + text: Added code follows the repository's conventions. + presets: + - convention + onFail: label + reason: Keeps added code free of invented fallbacks, nested ternaries, IIFEs and promise chains. + evidence: + - maintainer-stated + - id: no-any + check: code-patterns + text: Added code uses no any type. + patterns: + - id: no-any + language: typescript + message: "`any` turns type checking off; name the type, or take unknown and narrow it." + ignores: + [ + "**/*.{test,spec}.*", + "**/{test,tests,Tests,__tests__}/**", + "**/*.*{Test,Tests}/**", + ] + rule: { kind: predefined_type, regex: "^any$" } + onFail: ask + reason: An any type turns type checking off for every value it touches. evidence: - maintainer-stated actions: @@ -62,11 +135,16 @@ actions: - thegreataxios - do: request-review target: - to: codeowners + to: users + users: + - thegreataxios when: author: - external fail: + - do: close + when: + linkedIssue: false - do: request-changes unsure: - do: assign diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f50fc9ea7..0a9e15edc 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -132,3 +132,17 @@ jobs: # hub-booting suite migrating first. - run: bun scripts/db-setup.ts - run: bun test e2e/hub e2e/install e2e/workflows + + policy-check: + if: github.event_name == 'pull_request' + runs-on: ubuntu-latest + timeout-minutes: 5 + permissions: + checks: read + contents: read + pull-requests: read + steps: + - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0 + with: + persist-credentials: false + - uses: corbitsdev/corbits-triage/packages/policy-check-action@28a902e9a6e2f7ec53c581425b72d97c6800fc89 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 1fe886f91..bdc0759c6 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -34,3 +34,4 @@ Thanks for your interest in Corbits Workbench. 6. Each package that owns product tables ships one idempotent SQL migration, applied by the hub at boot. 7. Security issues go through [SECURITY.md](SECURITY.md), never a public issue. +8. A pull request without a linked issue is closed. From 5bcbcad62fb61e19c8a0f04550cae493fe55fc87 Mon Sep 17 00:00:00 2001 From: Sawyer Cutler Date: Tue, 27 Oct 2026 14:36:22 -0700 Subject: [PATCH 2/4] ci(policy): run the corbits-triage rules and actions --- .corbits-triage.yml | 149 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 146 insertions(+), 3 deletions(-) diff --git a/.corbits-triage.yml b/.corbits-triage.yml index b61dec8d9..b7ecdfb51 100644 --- a/.corbits-triage.yml +++ b/.corbits-triage.yml @@ -24,10 +24,9 @@ rules: reason: A behavior change without a docs update leaves the docs wrong. evidence: - maintainer-stated - enabled: false - check: linked-issue - text: Require a linked Linear issue, such as CL-123. - tracker: linear + text: Require a linked issue from GitHub or Linear. + tracker: either reason: Every change is tracked in a Linear issue. evidence: - maintainer-stated @@ -96,6 +95,7 @@ rules: - "claude.ai/code/session" - "Generated with Claude" - "Generated with [Claude" + onFail: ask reason: Tool-generated co-author lines, session trailers and footers don't belong in the history. evidence: - maintainer-stated @@ -108,6 +108,148 @@ rules: reason: Keeps added code free of invented fallbacks, nested ternaries, IIFEs and promise chains. evidence: - maintainer-stated + - id: invented-fallbacks + check: code-patterns + text: Added code handles a missing value instead of inventing an empty one. + patterns: + - id: more-invented-fallbacks + language: typescript + message: Invented fallback (an empty string, || [] or || 0); handle the missing value instead. + ignores: + [ + "**/*.{test,spec}.*", + "**/{test,tests,Tests,__tests__}/**", + "**/*.*{Test,Tests}/**", + ] + rule: + any: + - pattern: $X || [] + - all: + - any: + - pattern: $X ?? "" + - pattern: $X ?? '' + - pattern: $X ?? `` + - pattern: $X || "" + - pattern: $X || '' + - pattern: $X || `` + - not: + any: + - inside: { kind: template_substitution } + - inside: + { + kind: binary_expression, + has: { field: operator, regex: '^\+$' }, + } + - inside: + { + kind: parenthesized_expression, + inside: + { + kind: binary_expression, + has: { field: operator, regex: '^\+$' }, + }, + } + - has: { field: left, kind: subscript_expression } + - has: + { + field: left, + kind: call_expression, + has: + { + field: function, + regex: '\.(at|get|getAttribute)$', + }, + } + - all: + - pattern: $X || 0 + - not: + any: + - inside: + { + kind: binary_expression, + has: { field: operator, regex: "^[-+*/%]$" }, + } + - inside: + { + kind: parenthesized_expression, + inside: + { + kind: binary_expression, + has: { field: operator, regex: "^[-+*/%]$" }, + }, + } + - inside: { kind: augmented_assignment_expression } + - id: more-invented-fallbacks + language: javascript + message: Invented fallback (an empty string, || [] or || 0); handle the missing value instead. + ignores: + [ + "**/*.{test,spec}.*", + "**/{test,tests,Tests,__tests__}/**", + "**/*.*{Test,Tests}/**", + ] + rule: + any: + - pattern: $X || [] + - all: + - any: + - pattern: $X ?? "" + - pattern: $X ?? '' + - pattern: $X ?? `` + - pattern: $X || "" + - pattern: $X || '' + - pattern: $X || `` + - not: + any: + - inside: { kind: template_substitution } + - inside: + { + kind: binary_expression, + has: { field: operator, regex: '^\+$' }, + } + - inside: + { + kind: parenthesized_expression, + inside: + { + kind: binary_expression, + has: { field: operator, regex: '^\+$' }, + }, + } + - has: { field: left, kind: subscript_expression } + - has: + { + field: left, + kind: call_expression, + has: + { + field: function, + regex: '\.(at|get|getAttribute)$', + }, + } + - all: + - pattern: $X || 0 + - not: + any: + - inside: + { + kind: binary_expression, + has: { field: operator, regex: "^[-+*/%]$" }, + } + - inside: + { + kind: parenthesized_expression, + inside: + { + kind: binary_expression, + has: { field: operator, regex: "^[-+*/%]$" }, + }, + } + - inside: { kind: augmented_assignment_expression } + onFail: label + reason: A fallback belongs only where a real default exists. + evidence: + - maintainer-stated - id: no-any check: code-patterns text: Added code uses no any type. @@ -133,6 +275,7 @@ actions: author: - users: - thegreataxios + - brianjfox - do: request-review target: to: users From 88f681bf70de706bed8ebd2b050e414479c94df7 Mon Sep 17 00:00:00 2001 From: Sawyer Cutler Date: Tue, 27 Oct 2026 16:34:53 -0700 Subject: [PATCH 3/4] ci(policy): make size limits a risk signal --- .corbits-triage.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.corbits-triage.yml b/.corbits-triage.yml index b7ecdfb51..5ea9d9bf5 100644 --- a/.corbits-triage.yml +++ b/.corbits-triage.yml @@ -3,14 +3,14 @@ rules: - check: max-files-changed text: Flag pull requests over 25 files changed. max: 25 - onFail: ask + onFail: label reason: Large pull requests are hard to review. evidence: - maintainer-stated - check: max-lines-changed text: Flag pull requests over 1,500 lines changed. max: 1500 - onFail: ask + onFail: label reason: Large pull requests are hard to review. evidence: - maintainer-stated From 7d7458eb1e8a378df91a29a1231733fe4816b734 Mon Sep 17 00:00:00 2001 From: "user.email" Date: Fri, 30 Oct 2026 12:17:55 -0700 Subject: [PATCH 4/4] ci(policy): add convention checks without code review --- .corbits-triage.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.corbits-triage.yml b/.corbits-triage.yml index 5ea9d9bf5..8f3a61d64 100644 --- a/.corbits-triage.yml +++ b/.corbits-triage.yml @@ -285,9 +285,6 @@ actions: author: - external fail: - - do: close - when: - linkedIssue: false - do: request-changes unsure: - do: assign