| name | mo-bug-triage |
| description | Systematic MatrixOne kind/bug lifecycle triage — intake normalization with `needs-triage`, conservative promotion to active severity (`severity/s-1`, `severity/s0`, `severity/s1`), immediate downgrade to `deferred` with explanatory comments, optional five-level AI effort labeling (`ai-easy`, `ai-light`, `ai-medium`, `ai-heavy`, `ai-manual`) only when explicitly requested for issues/PRs, and frozen-candidate, drift-safe, resumable GitHub metadata updates. Use when asked to triage, classify, review, downgrade, defer, label, AI-effort-assess, or bulk-update MO bugs and related PRs. |
| metadata | {"project":"matrixone","repository":"matrixorigin/matrixone","workflow":"bug-triage"} |
Compatibility: designed for Codex CLI and compatible agents on macOS and Linux. Requires authenticated GitHub CLI (gh) and jq; inspect the token's actual scopes and current rate-limit response instead of assuming a fixed quota. Read-only triage needs no write scope.
Enforcement Gates
| Gate | When | Action |
|---|
| G-INTAKE | When handling new bugs | New kind/bug issues enter needs-triage. Do not assign active severity during intake unless a maintainer explicitly confirms emergency impact. |
| G-PROMOTION | Before applying severity/s-1, severity/s0, or active severity/s1 | Evidence must show confirmed urgency/impact or a committed owner. Record the rationale in the report or issue comment. |
| G-DEFER-COMMENT | Before applying deferred | Add an explicit comment explaining why the issue should not continue as s0/s1 active work. |
| G-AI-REQUEST | Before assessing or applying any AI effort label | User must explicitly request AI effort assessment, or the run mode must be ai-assess/ai-final. Plain needs-triage intake must not infer or apply ai-*. |
| G-AI-SOURCE | Before applying any AI effort label | Record assessment stage (issue-initial, pr-review, or user-assisted), confidence, and one-sentence rationale. |
| G-AI-FINAL | During explicit ai-final or PR AI-label review | Recheck five-level AI effort against actual implementation effort and update issue + PR labels if stale. |
| G-STANDARDS | Before any GitHub write | Policy approval must bind repository, run ID, standards hash, and frozen-candidate hash; apply authorization must additionally bind the exact classified write-plan hash and scope. A bare mutable Approved: true is insufficient. |
| G-SNAPSHOT | Before batch update | Save current updated_at, labels, milestone number/null, and every explicitly in-scope project field plus the exact proposed delta. Writes stop on drift. |
| G-DRYRUN | Before any apply | Dry-run performs zero writes and emits exact requests/deltas. A real five-item canary is a separate, explicitly authorized apply. |
| G-DRIFT | Before each write and before declaring "done" | Re-fetch updated_at and relevant fields; drift means skip/reclassify, never overwrite concurrent maintainer work. |
TL;DR
Default lifecycle
→ New bug: kind/bug + needs-triage; no priority promise at entry
→ Analysis: verify repro, impact, owner, dependency, duplicates
→ Execute: promote only confirmed urgent/high-impact work to s-1/s0
→ Active non-emergency work: use s1 only when owned and committed
→ Downgrade: if not s0/s1 active work, move to deferred + comment
→ AI effort: do not run by default; assess only on explicit request or ai-* mode
Phase 1: LOCK STANDARDS (~15min, 0 writes)
→ Sample 8-12 bugs by domain → lock lifecycle/severity/defer rules
Phase 2: BATCHED PROCESS (~5min per batch of 50)
→ Freeze issue IDs once → hydrate evidence → classify → zero-write dry-run
→ optional authorized canary → drift-check → serial/idempotent apply → progress
→ Batch N failure never touches Batch 1..N-1 (already committed)
Phase 3: FINAL VERIFY (~10min)
→ Lifecycle audit + label count cross-check + defer-comment check; AI-label checks only for explicit AI modes
Estimate runtime from the frozen candidate count and the authenticated token's
live primary/secondary rate-limit state. Do not encode a universal request quota.
Core Rules
Current GitHub Bug Workflow
| Stage | Required Behavior |
|---|
| Intake | Label new bugs as kind/bug + needs-triage. Treat this as the candidate pool, not a priority commitment. Do not pre-assign severity/s0, severity/s1, or severity/s-1 from title keywords alone. |
| Execution | Promote only confirmed urgent or broad-impact issues to severity/s0 or severity/s-1. Use severity/s1 only for owned, committed near-term bug work that should stay active but is not s0/s-1. |
| Downgrade | After analysis, if an issue should not continue as s0/s1 active work, immediately remove active severity/needs-triage, add deferred, and comment with the concrete reason. |
| AI Labels | Do not apply AI effort labels during default needs-triage. Apply exactly one AI effort label (ai-easy, ai-light, ai-medium, ai-heavy, ai-manual) only when the user asks for AI effort assessment or when running explicit ai-assess/ai-final. |
| Ownership | Each owner is responsible for their own issues and PRs: keep labels, comments, linked PRs, and closure status current without waiting to be driven. |
Lifecycle Labels
| Label | Meaning | Write Rule |
|---|
needs-triage | Candidate pool for newly reported or not-yet-analyzed bugs. | Add at entry; remove only when promoted, deferred, closed, or explicitly excluded. Do not add ai-* during intake. |
severity/s-1 | Confirmed project emergency. | Use only for multi-tenant isolation/data exposure or explicit maintainer-confirmed emergency. If confirmed serious but not s-1 → severity/s0; if evidence is incomplete → needs-triage. |
severity/s0 | Confirmed urgent/high-impact active work. | Requires evidence: stable repro or production signal plus broad impact, data integrity risk, crash/hang/OOM/leak, common-path breakage, or release blocker. |
severity/s1 | Confirmed active work that is important but not emergency. | Requires an owner or near-term commitment. Do not use as a parking lot for unconfirmed bugs. |
deferred | Analyzed but not active s0/s1 work. | Requires a comment explaining why and what signal would justify reopening/promoting. Prefer this over creating new severity/s2 triage unless explicitly requested. |
ai-easy | AI can directly implement; human review is mostly a quick scan. Suitable for batch/parallel AI execution. | Use for clear, localized, low-risk fixes with deterministic validation. |
ai-light | AI can produce a good draft or plan; human must tune details or make a small decision. | Use when scope is bounded but there is minor ambiguity in expected behavior, tests, or local integration. |
ai-medium | Human and AI likely need several rounds, with roughly shared effort. | Use when root cause or fix shape is partially unclear, or the change crosses a few modules. |
ai-heavy | AI can assist with research, snippets, tests, or log analysis; core logic stays human-owned. | Use for broad, risky, or subsystem-level work where human design/debug judgment dominates. |
ai-manual | AI is unlikely to help beyond clerical support. | Use when work depends on unavailable environments/data, security-sensitive access, product decisions, or human-only operational context. |
Severity Hierarchy
| Severity | Criteria | Examples |
|---|
| s-1 | MUST be conservative. Multi-tenant isolation/data exposure, cross-tenant corruption, or explicitly confirmed project emergency. Refer to existing project s-1 count (≤5). If confirmed serious but not s-1 → s0; if evidence is incomplete → needs-triage. | tenant isolation break, cross-account data exposure |
| s0 | Confirmed urgent/high-impact active bug: panic/crash, hung/deadlock, OOM/memory exhaustion, data integrity violation, resource leak, commonly-used feature broken, performance regression on core paths, release blocker. | INSERT panic, subquery hung, LOAD DATA OOM, lockservice leak, ORDER BY wrong, Prisma compat |
| s1 | Confirmed active non-emergency bug with owner/commitment. Lower-impact partition/streaming/cold-feature bugs can be s1 only when they should be worked soon. | planned partition pruning fix, assigned streaming CTE bug, owned backup/restore issue |
| deferred | Not active s0/s1 work after analysis. Use for unstable repro, missing dependencies, non-critical paths, duplicate/consolidated work, feature requests mislabeled as bugs, tech debt, typos, or cleanup. | repro not stable, blocked by dependency, merge into existing issue, cold feature not planned |
Domain Downgrade Table
These domains default to deferred after analysis unless a higher-severity trigger is confirmed or an owner commits to near-term work:
| Domain | Default | Exception |
|---|
| Partition | deferred | Confirmed panic/crash/data integrity → s0; owned near-term work → s1 |
| Streaming | deferred | Confirmed panic/crash/data integrity → s0; owned near-term work → s1 |
| Cold features | deferred | Confirmed panic/crash/data integrity → s0; owned near-term work → s1 |
| Feature Request | exclude | N/A — skip bug triage entirely |
Cold features list: stored procedures, CTE, window functions, collation, fulltext, backup/restore, role/DCL (GRANT/REVOKE), REPLACE INTO, trigger, event scheduler.
Note: LOAD DATA and import are NOT cold features — they are commonly-used ETL paths. Confirmed breakage can justify s0, but intake still starts at needs-triage.
s0 Investigation Triggers
These keywords are investigation triggers. They justify a closer look, not automatic promotion from needs-triage.
| Trigger | Keywords |
|---|
| Panic/crash | panic, nil pointer, index out of range, fatal, makeslice, segmentation, nil dereference |
| Hung/deadlock | hung, deadlock, stuck, blocked, infinite, never, cannot kill, can't cancel, waiting, timeout |
| OOM/memory | oom, out of memory, memory leak, memory exhaust, oomkilled, consuming memory, memory growth, memory blow |
| Data integrity | data integrity, wrong result, incorrect result, inconsistent, duplicate key, unique constraint, check constraint, foreign key, corrupt, data loss, wrong data |
| Resource leak | leak, orphaned, stale, never cleaned, growing, accumulate, not released, not freed |
Classification Algorithm
- Extract
title (lowercase), body (lowercase) from issue JSON
- If the issue is new/untriaged: ensure
kind/bug + needs-triage; do not add active severity yet
- Detect domains: is_partition, is_streaming, is_cold_feature, is_feature_request, duplicate/consolidation candidate
- Detect evidence flags: panic/hung/OOM/data-integrity/resource-leak/common-path/release-blocker
- Decide action:
promote-s-1: confirmed multi-tenant isolation/data exposure or explicit maintainer emergency
promote-s0: confirmed urgent/high-impact active bug with evidence and owner path
promote-s1: confirmed active non-emergency bug with owner/near-term commitment
defer: analyzed but not active s0/s1 work; requires comment
keep-needs-triage: insufficient information and no owner analysis yet
exclude: feature request or non-bug; remove from bug triage path per repo convention
- Skip AI effort assessment by default. If and only if explicitly requested or running
ai-assess/ai-final, estimate one AI effort label and record stage (issue-initial, pr-review, or user-assisted), confidence, and evidence in the report
- Treat project routing as a separate, explicitly approved policy. Do not assign
ProjectV2 from title keywords alone; if project writes are in scope, snapshot
and restore item/field/option IDs exactly.
- If the user requested
ai-final or PR AI-label review, re-evaluate AI label using actual code changes/tests/review complexity and update issue + PR labels
Key invariant: no issue leaves needs-triage for active severity without evidence and an owner/impact rationale. Keywords alone are never sufficient.
Deferred Comment Template
When moving to deferred, write a short, concrete comment:
Triage decision: defer.
Reason: <unstable repro | missing dependency | non-critical path | consolidated into #NNNNN | feature request / not a bug | insufficient impact signal>
Current evidence: <one sentence>
To promote later: <specific signal needed, owner action, or linked issue/PR>
Run-Specific Exclusions
Do not hard-code exclusions as timeless workflow facts. If maintainers request
an exclusion, record its subject, owner, rationale, approval date, and
expiry/review date in the run's locked standards.
Severity Inflation Guard
- Before s-1: verify exactly matches multi-tenant isolation breach or explicit maintainer emergency. If serious but not s-1 and confirmed → s0; if unconfirmed → keep
needs-triage.
- Before s0: verify actual panic/hung/OOM/integrity/common-function-break plus urgency/impact. If evidence is only title keywords → keep
needs-triage.
- Before s1: verify there is an owner or near-term commitment. If not →
deferred after analysis or keep needs-triage before analysis.
- Default for any post-analysis ambiguity →
deferred with a clear reopen/promote condition.
AI Effort Assessment
Use AI labels to estimate how much human involvement is required, not severity or business priority. This is an opt-in assessment, not part of default needs-triage. Normalize spelling to lowercase: use ai-medium, not ai-Medium.
| Label | Meaning | Strong Signals |
|---|
ai-easy | AI directly handles it; human only scans the result. Can be batched and run in parallel. | Clear repro, obvious expected behavior, localized fix, deterministic test, no data/security/consensus risk. |
ai-light | AI writes a useful first draft or plan; human adjusts details or makes one bounded decision. | Localized bug with minor ambiguity, test needs adaptation, existing pattern is clear but exact choice needs review. |
ai-medium | Human and AI iterate for several rounds; roughly half the work is human judgment/debugging. | Root cause not fully isolated, fix touches several files/modules, requires repro refinement, test strategy is non-trivial. |
ai-heavy | AI is support only; core logic and decisions remain human-owned. | Cross-subsystem impact, concurrency/transaction/storage semantics, data correctness risk, production-only symptom, significant design/debug judgment. |
ai-manual | AI mostly cannot help beyond clerical tasks. | Requires private/unavailable environment or data, sensitive access, human-only operational/product decision, unclear report with no actionable evidence. |
Assessment stages:
issue-initial: rough label from issue title/body/logs/repro. Prefer ai-medium or ai-heavy when evidence is thin.
pr-review: revise using linked PR diff, tests, review comments, files changed, and actual debugging burden.
user-assisted: combine issue/PR evidence with user-provided context such as owner knowledge, hidden dependency, production signal, or known fix plan.
Assessment rules:
- Do not infer AI effort during plain intake or default
kind/bug,needs-triage triage. Leave all ai-* labels untouched unless the user requested AI assessment.
- Apply at most one AI effort label at a time; remove the other four when updating.
- Record
ai_label_stage, ai_confidence (low, medium, high), and one-sentence ai_rationale in reports.
- Escalate the label when correctness/security/consensus/storage/transaction risk is present, even if the diff looks small.
- De-escalate only with evidence: linked PR proved localized, deterministic tests pass, or user confirms a simple known fix.
- Near PR close, revise labels based on actual work rather than the initial estimate when an AI label exists or the user asks for
ai-final.
Ownership Rule
- For issues/PRs assigned to you or linked to your work, update labels/comments proactively.
- Link PRs to issues, keep existing/requested issue and PR AI labels consistent near close, and close or defer issues explicitly.
- Do not wait for another person to drive routine status, downgrade, AI label correction, or closure hygiene.
Phase 1: LOCK STANDARDS (Read-Only, ~15 min)
Step 1.1: Freeze The Candidate Set
state_parent=${MO_TRIAGE_STATE_PARENT:-${TMPDIR:-/tmp}}
run_dir=$(mktemp -d "$state_parent/mo-triage.XXXXXX")
capture_cutoff=$(date -u '+%Y-%m-%dT%H:%M:%SZ')
gh api --paginate -H 'Accept: application/vnd.github+json' \
'/repos/matrixorigin/matrixone/issues?state=open&labels=kind%2Fbug&per_page=100&sort=created&direction=asc' \
| jq -s --arg cutoff "$capture_cutoff" \
'[.[][] | select(has("pull_request") | not)