- 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.
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
1. Extract `title` (lowercase), `body` (lowercase) from issue JSON
2. If the issue is new/untriaged: ensure `kind/bug` + `needs-triage`; do not add active severity yet
3. Detect domains: is_partition, is_streaming, is_cold_feature, is_feature_request, duplicate/consolidation candidate
4. Detect evidence flags: panic/hung/OOM/data-integrity/resource-leak/common-path/release-blocker
5. 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
6. 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
7. 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.
8. 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:
```markdown
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
```bash
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)
GitHubで見る