Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
166 changes: 166 additions & 0 deletions .corbits-triage.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
# Corbits Triage policy.
rules:
- check: linked-issue
text: Link a GitHub or Linear issue. Open an issue for the change first, then a pull request that links it.
tracker: either
reason: Every change starts from an issue that says what and why.
evidence:
- maintainer-stated
- check: focused
text: Check the change is focused on one thing.
onFail: ask
reason: One logical change per pull request.
evidence:
- maintainer-stated
- check: no-merge-conflicts
text: Flag merge conflicts with the base branch.
reason: A conflicted pull request cannot merge as reviewed.
evidence:
- maintainer-stated
- check: ci-green
text: CI must pass before merge.
reason: bun run check and the vendor check gate every change.
evidence:
- maintainer-stated
- check: conventional-commits
text: Titles and commits follow Conventional Commits.
reason: Commits and pull request titles use feat/fix/chore(scope).
evidence:
- maintainer-stated
- check: no-forbidden-paths
text: Never accept dependencies, local env files or scratch output.
paths:
- node_modules/**
- .env.hub
- .env.web
- tmp/**
reason: Secrets and generated files stay out of the repository.
evidence:
- maintainer-stated
- check: sensitive-paths
text: Route vendor, migration, auth and secret changes to a person.
groups:
vendor: { level: high, paths: ["vendor/**", "patches/**"] }
schema: { level: high, paths: ["**/migrations/**", "**/*.sql"] }
auth: { level: high, paths: ["**/auth/**", "**/secrets/**"] }
ci: { level: medium, paths: [".github/**", "**/Dockerfile", "deploy/**"] }
locks: { level: medium, paths: ["**/bun.lock"] }
reason: Vendored Interchange changes are deliberate and recorded; schema and auth changes are hard to undo.
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; the earlier one stays.
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-Session:"
- "claude.ai/code/session"
- "noreply@anthropic.com"
- "Generated with Claude"
- "Generated with [Claude"
reason: No AI co-author lines, session trailers or links, or generated-with footers.
evidence:
- maintainer-stated
- id: conventions
check: code-patterns
text: Added code has no IIFEs, promise chains, empty catches, nested ternaries, invented ?? 0 or ?? [] fallbacks, or suppression comments.
presets:
- convention
onFail: fail
reason: Errors are never swallowed; async/await with named functions throughout.
evidence:
- maintainer-stated
- id: errors-kept
check: code-patterns
text: Added code keeps every caught error and imports Interchange by package name.
patterns:
- id: bare-catch
language: typescript
message: A catch without a binding drops the error; check for the expected failure, or catch it and rethrow the rest.
rule:
{ kind: catch_clause, not: { has: { field: parameter, regex: "." } } }
- id: interchange-by-path
language: typescript
message: Imports vendored Interchange source by path; import the @intx/* package.
rule:
kind: string_fragment
regex: "vendor/interchange/(packages|apps)/"
inside: { kind: import_statement, stopBy: end }
onFail: fail
reason: A swallowed error hid failures in the live app host and the build tools; reaching into vendor/ bypasses the package boundary.
evidence:
- maintainer-stated
- id: interchange-owns-it
check: code-patterns
text: Added code does not hand-roll waits or open its own event streams.
patterns:
- id: hand-rolled-wait
language: typescript
message: A hand-rolled sleep; wait through Interchange's waits, retries and timeouts, or an event.
rule:
any:
- pattern: new Promise(($R) => setTimeout($R, $$$))
- pattern: new Promise($R => setTimeout($R, $$$))
- id: own-event-stream
language: typescript
files: [apps/web/**]
message: The interface opens its own stream; talk to the hub through @corbits-builder/client.
rule:
any:
- pattern: new EventSource($$$)
- pattern: new WebSocket($$$)
onFail: ask
reason: Interchange owns retries, waits, timeouts and the event stream; a person decides when one is really needed.
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.ts", "tests/**"]
rule:
any:
- pattern: $X || []
- pattern: $X ?? ""
- pattern: $X || ""
- pattern: $X || 0
onFail: ask
reason: A missing input is a failing check, never a silent default; a person confirms a real default.
evidence:
- maintainer-stated
code-review:
on: false
actions:
pass:
- do: approve
when:
author:
- users:
- thegreataxios
- brianjfox
fail:
- do: close
when:
linkedIssue: false
- do: request-changes
unsure:
- do: assign
target:
to: users
users:
- thegreataxios