From 39693bcd93a51a8d99827789cf08cabd5698c265 Mon Sep 17 00:00:00 2001 From: Cobus Greyling Date: Thu, 18 Jun 2026 13:11:35 +0200 Subject: [PATCH] =?UTF-8?q?docs:=20close=20issues=20#17=E2=80=93#20=20(mat?= =?UTF-8?q?rix,=20story,=20examples,=20adopters)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add Cursor and Windsurf columns to primitives-matrix (scheduling, skills, sub-agents) - Expand Post-Merge Cleanup production story with failures, metrics, and surprises - Add issue-triage examples for Grok, Claude Code, and Codex (L1 propose-only) - Document maintainer loop setups in adopters.md Closes #17, #18, #19, #20 --- docs/adopters.md | 7 +- docs/primitives-matrix.md | 81 ++++++++++++------------ examples/README.md | 1 + examples/claude-code/issue-triage.md | 60 ++++++++++++++++++ examples/codex/issue-triage.md | 74 ++++++++++++++++++++++ examples/grok/README.md | 1 + examples/grok/issue-triage.md | 73 +++++++++++++++++++++ stories/README.md | 2 +- stories/post-merge-cleanup-honest-win.md | 44 ++++++++----- 9 files changed, 286 insertions(+), 57 deletions(-) create mode 100644 examples/claude-code/issue-triage.md create mode 100644 examples/codex/issue-triage.md create mode 100644 examples/grok/issue-triage.md diff --git a/docs/adopters.md b/docs/adopters.md index d37947f..a293c3f 100644 --- a/docs/adopters.md +++ b/docs/adopters.md @@ -10,7 +10,7 @@ Open a PR that adds a row to the table below: |-------|-----------------| | **Project** | Repo link or product name | | **Pattern(s)** | e.g. Daily Triage + Issue Triage | -| **Tool** | Grok, Claude Code, Codex, GitHub Actions, mixed | +| **Tool** | Grok, Claude Code, Codex, Cursor, Windsurf, GitHub Actions, mixed | | **Level** | L1 / L2 / L3 (honest) | | **Notes** | One line — what worked or what broke | @@ -18,7 +18,10 @@ Open a PR that adds a row to the table below: | Project | Pattern(s) | Tool | Level | Notes | |---------|------------|------|-------|-------| -| [loop-engineering](https://github.com/cobusgreyling/loop-engineering) (this repo) | Daily Triage, Changelog Drafter, audit dogfood | GitHub Actions + Grok | L3 | Reference implementation — dogfoods `loop-audit` on every PR | +| [loop-engineering](https://github.com/cobusgreyling/loop-engineering) (this repo) | Daily Triage, Changelog Drafter, audit dogfood | GitHub Actions + Grok | L3 | Reference implementation — `loop-audit` on every PR; readiness score 100 | +| [loop-engineering](https://github.com/cobusgreyling/loop-engineering) (maintainer) | Post-Merge Cleanup | Grok + GitHub Actions | L1→L2 | Off-peak scan; verifier caught doc/API drift — see [story](../stories/post-merge-cleanup-honest-win.md) | +| [loop-engineering](https://github.com/cobusgreyling/loop-engineering) (maintainer) | Issue Triage + Daily Triage | Grok | L1 | Issue queue feeder: propose labels only week one; pairs with morning `STATE.md` triage | +| [loop-engineering](https://github.com/cobusgreyling/loop-engineering) (maintainer) | PR Babysitter, Dependency Sweeper | Grok / Claude Code | L2 | Assisted fixes in worktrees; human gate on merges; patch-only deps | *Your project here — see [CONTRIBUTING.md](../CONTRIBUTING.md).* diff --git a/docs/primitives-matrix.md b/docs/primitives-matrix.md index 2567b8f..93d84c5 100644 --- a/docs/primitives-matrix.md +++ b/docs/primitives-matrix.md @@ -1,42 +1,42 @@ -# Primitives Matrix — Grok, Claude Code, Codex +# Primitives Matrix — Grok, Claude Code, Codex, Cursor, Windsurf -Tool-agnostic loop design: the **capability** is what matters, not the product name. This matrix maps each primitive to how it appears in three major agent environments. +Tool-agnostic loop design: the **capability** is what matters, not the product name. This matrix maps each primitive to how it appears in five major agent environments. -| Primitive | Job in the Loop | Grok Build TUI | Claude Code | Codex | -|-----------|-----------------|----------------|-------------|-------| -| **Automations / Scheduling** | Discovery + triage on a cadence | `/loop [interval] `, `scheduler_create` / `scheduler_list` / `scheduler_delete` (`recurring`, `durable`, `fireImmediately`), `monitor` for streaming events | `/loop`, scheduled tasks, cron, hooks, GitHub Actions | [Automations tab](https://developers.openai.com/codex/app/automations): project, prompt, cadence, environment; Triage inbox | -| **Run-until-done** | Keep working until a verifiable condition holds | Goal mode / explicit stopping conditions in loop prompts | `/goal` — separate model checks completion | `/goal` — pause/resume, verifiable stop condition | -| **Worktrees** | Safe parallel execution | Subagents with `isolation: "worktree"`, background tasks | `git worktree`, `--worktree`, `isolation: worktree` on subagents | Built-in worktree per thread | -| **Skills** | Persistent project knowledge | `SKILL.md` in `.grok/skills/` or `~/.grok/skills/`; invoked by name | `SKILL.md` in `.claude/skills/` or project skills | [Agent Skills](https://developers.openai.com/codex/skills) — `$name` or implicit match | -| **Plugins & Connectors** | Reach into real tools | MCP servers via `CallMcpTool` | MCP servers + plugins | Connectors (MCP) + plugins for distribution | -| **Sub-agents** | Maker / checker split | `Task` tool with `subagent_type`, worktree isolation | Task subagents in `.claude/agents/`, agent teams | Subagents as TOML in `.codex/agents/` | -| **State / Memory** | Track what's done across runs | `STATE.md`, todos, durable scheduler state | `AGENTS.md`, progress files, Linear via MCP | Markdown or Linear via connector | +| Primitive | Job in the Loop | Grok Build TUI | Claude Code | Codex | Cursor | Windsurf | +|-----------|-----------------|----------------|-------------|-------|--------|----------| +| **Automations / Scheduling** | Discovery + triage on a cadence | `/loop [interval] `, `scheduler_create` / `scheduler_list` / `scheduler_delete` (`recurring`, `durable`, `fireImmediately`), `monitor` for streaming events | `/loop`, scheduled tasks, cron, hooks, GitHub Actions | [Automations tab](https://developers.openai.com/codex/app/automations): project, prompt, cadence, environment; Triage inbox | Cloud Agents + **Automations** (cron, webhooks, Linear/GitHub/Slack triggers); foreground Agent chat for ad-hoc `/loop`-style prompts | Cascade **Workflows** (`/workflow-name`, manual invoke); pair with GitHub Actions or external cron for true scheduling | +| **Run-until-done** | Keep working until a verifiable condition holds | Goal mode / explicit stopping conditions in loop prompts | `/goal` — separate model checks completion | `/goal` — pause/resume, verifiable stop condition | Agent mode + **hooks** (`.cursor/hooks.json`) for grind-until-green loops | Workflow steps with explicit verification checkpoints; **Memories** for cross-session continuity | +| **Worktrees** | Safe parallel execution | Subagents with `isolation: "worktree"`, background tasks | `git worktree`, `--worktree`, `isolation: worktree` on subagents | Built-in worktree per thread | Git worktree per Composer / Cloud Agent task | Workspace isolation; multiple simultaneous Cascade sessions | +| **Skills** | Persistent project knowledge | `SKILL.md` in `.grok/skills/` or `~/.grok/skills/`; invoked by name | `SKILL.md` in `.claude/skills/` or project skills | [Agent Skills](https://developers.openai.com/codex/skills) — `$name` or implicit match | `.cursor/rules/*.mdc` (globs, `alwaysApply`), `AGENTS.md`, `.cursor/skills/` | `.devin/rules/` or `.windsurf/rules/` (persistent context); `.windsurf/workflows/` (reusable recipes) | +| **Plugins & Connectors** | Reach into real tools | MCP servers via `CallMcpTool` | MCP servers + plugins | Connectors (MCP) + plugins for distribution | MCP in settings; Cloud Agent sandbox with full connector access | MCP via Cascade settings / `mcp_config.json` | +| **Sub-agents** | Maker / checker split | `Task` tool with `subagent_type`, worktree isolation | Task subagents in `.claude/agents/`, agent teams | Subagents as TOML in `.codex/agents/` | Multi-agent mode, review mode, custom agents in `.cursor/agents/` | Multiple Cascades in parallel; workflow-orchestrated implementer → reviewer steps | +| **State / Memory** | Track what's done across runs | `STATE.md`, todos, durable scheduler state | `AGENTS.md`, progress files, Linear via MCP | Markdown or Linear via connector | `STATE.md`, `LOOP.md`, Cloud Agent memories | `STATE.md`, Cascade **Memories**, workflow run notes | ## Scheduling Quick Reference -| Use case | Grok | Claude Code | Codex | -|----------|------|-------------|-------| -| Every 5 minutes | `/loop 5m ` | `/loop 5m ` | Automation, 5m cadence | -| Daily morning | `/loop 1d ` | Cron / `/loop 1d` | Automation, daily | -| Until tests pass | Loop + verifier sub-agent | `/goal all tests pass` | `/goal` | -| Survive restart | `scheduler_create` with `durable: true` | Hooks + persisted config | Automation (server-side) | -| Event-driven (CI fail) | `monitor` or GitHub Action | GitHub Action + webhook | Automation + webhook | +| Use case | Grok | Claude Code | Codex | Cursor | Windsurf | +|----------|------|-------------|-------|--------|----------| +| Every 5 minutes | `/loop 5m ` | `/loop 5m ` | Automation, 5m cadence | Automation cron trigger | External cron + `/workflow` or Action | +| Daily morning | `/loop 1d ` | Cron / `/loop 1d` | Automation, daily | Automation daily + `AGENTS.md` context | Daily workflow + Memories | +| Until tests pass | Loop + verifier sub-agent | `/goal all tests pass` | `/goal` | Hooks grind-until-green | Workflow with test/fix loop | +| Survive restart | `scheduler_create` with `durable: true` | Hooks + persisted config | Automation (server-side) | Cloud Agent + repo-persisted state | Memories + committed `STATE.md` | +| Event-driven (CI fail) | `monitor` or GitHub Action | GitHub Action + webhook | Automation + webhook | Automation on PR/issue events | GitHub Action triggers + `/workflow` | ## Skill Packaging -| Concept | Grok | Claude Code | Codex | -|---------|------|-------------|-------| -| Authoring format | `SKILL.md` + optional scripts/references | Same | Same | -| Distribution | Copy to `.grok/skills/` or user skills dir | Plugin / copy to project | Plugin bundle | -| Invocation | Skill name in prompt or auto-match on description | `$skill-name` or implicit | `$skill-name` | +| Concept | Grok | Claude Code | Codex | Cursor | Windsurf | +|---------|------|-------------|-------|--------|----------| +| Authoring format | `SKILL.md` + optional scripts/references | Same | Same | `SKILL.md` or `.mdc` rules with frontmatter | Markdown rules + workflow files | +| Distribution | Copy to `.grok/skills/` or user skills dir | Plugin / copy to project | Plugin bundle | `.cursor/skills/` or `.cursor/rules/` | `.windsurf/rules/` + `.windsurf/workflows/` in repo | +| Invocation | Skill name in prompt or auto-match on description | `$skill-name` or implicit | `$skill-name` | Rules auto-apply by glob; skills on demand | `/workflow-name` or Rules always-on in Cascade | ## Sub-agent Patterns -| Split | When to use | Grok | Claude Code | Codex | -|-------|-------------|------|-------------|-------| -| Implementer → Verifier | Any unattended code change | `Task` + different instructions/model | `.claude/agents/reviewer.md` | TOML agent with higher `reasoning_effort` | -| Explorer → Implementer | Large unfamiliar codebase | `explore` subagent_type | Explorer agent | Fast read-only subagent | -| Triage only | Report-first loops | `loop-triage` skill | `$loop-triage` | Automation calls skill | +| Split | When to use | Grok | Claude Code | Codex | Cursor | Windsurf | +|-------|-------------|------|-------------|-------|--------|----------| +| Implementer → Verifier | Any unattended code change | `Task` + different instructions/model | `.claude/agents/reviewer.md` | TOML agent with higher `reasoning_effort` | Review mode or second Cloud Agent pass | Second Cascade or workflow review step | +| Explorer → Implementer | Large unfamiliar codebase | `explore` subagent_type | Explorer agent | Fast read-only subagent | `@codebase` + plan mode first | Audit workflow (read-only) then implement | +| Triage only | Report-first loops | `loop-triage` skill | `$loop-triage` | Automation calls skill | `AGENTS.md` + report-only rule | Triage workflow, no edit steps | ## State Conventions @@ -45,6 +45,7 @@ Recommended filenames (pick one spine per project): | File | Purpose | |------|---------| | `STATE.md` | General loop memory (daily triage) | +| `issue-triage-state.md` | Issue queue health (feeder for daily triage) | | `pr-babysitter-state.md` | PR-specific watcher state | | `ci-sweeper-state.md` | Active CI failures + attempt counts | | `post-merge-state.md` | Cleanup backlog from recent merges | @@ -58,7 +59,7 @@ You do not need to pick one forever. A well-designed loop transfers: 1. Write the **skill** (tool-agnostic `SKILL.md`) 2. Define the **state schema** (markdown or JSON) 3. Document the **verification split** (who checks whom) -4. Map scheduling to your current TUI or Action +4. Map scheduling to your current TUI, editor, or Action See [examples/](../examples/) for the same pattern implemented across tools. @@ -69,22 +70,24 @@ See [examples/](../examples/) for the same pattern implemented across tools. | Grok | [starters/minimal-loop](../starters/minimal-loop/) | | Claude Code | [starters/minimal-loop-claude](../starters/minimal-loop-claude/) | | Codex | [starters/minimal-loop-codex](../starters/minimal-loop-codex/) | +| Cursor / Windsurf | Copy `SKILL.md` + `STATE.md` from any starter; map scheduling to editor Automations or Workflows (see appendix) | Audit after copying: `npx @cobusgreyling/loop-audit . --suggest` Scaffold automatically: `npx @cobusgreyling/loop-init . --pattern daily-triage --tool grok` -## Appendix: Other agent environments (capability mapping) +## Appendix: Editor transfer recipes (Cursor & Windsurf) -No dedicated starters yet for the newest patterns (Changelog Drafter is trivial to port — it is mostly read + draft). Map capabilities to the same loop shape: +No dedicated starters yet — map capabilities to the same loop shape: -| Primitive | Cursor | Windsurf | Aider | -|-----------|--------|----------|-------| -| Scheduling | Rules + background agents, manual `/loop`-style prompts | Workflows, cascades | `--watch` / scripted sessions | -| Worktrees | Git worktree per Composer task | Workspace isolation | Git branches | -| Skills | `.cursor/rules`, `AGENTS.md` | Rules files | `CONVENTIONS.md` / `.aider.conf.yml` | -| Connectors | MCP in settings | MCP | CLI + git only | -| Sub-agents | Multi-agent / review mode | Cascade steps | Second terminal reviewer | -| State | `STATE.md`, `LOOP.md` | Same | Same | +| Step | Cursor | Windsurf | +|------|--------|----------| +| 1. Skills | Copy `templates/SKILL.md.loop-triage` → `.cursor/skills/loop-triage/SKILL.md`; add always-on triage rules in `.cursor/rules/` | Copy skill content into `.windsurf/rules/loop-triage.md` | +| 2. State | `cp starters/minimal-loop/STATE.md.example STATE.md` | Same — commit `STATE.md` at repo root | +| 3. Scheduling | Cloud Automation (cron) or manual Agent prompt on cadence | Create `.windsurf/workflows/daily-triage.md`, invoke `/daily-triage` | +| 4. Verification | `.cursor/agents/loop-verifier.md` from `templates/SKILL.md.verifier` | Add review step at end of workflow; human gate on denylist paths | +| 5. Connectors | Enable GitHub MCP read-only for issue/PR discovery | Configure GitHub MCP in Cascade settings | + +**Aider** (CLI-only): use `--watch` or scripted sessions; state in `STATE.md`; reviewer = second terminal session. Transfer recipe: copy the tool-agnostic `SKILL.md` + state schema from this repo; map scheduling to your editor's automation surface. \ No newline at end of file diff --git a/examples/README.md b/examples/README.md index 5abeef3..3e75fcf 100644 --- a/examples/README.md +++ b/examples/README.md @@ -22,6 +22,7 @@ Start with [primitives-matrix.md](../docs/primitives-matrix.md) to map capabilit | Post-Merge Cleanup | [grok/post-merge-cleanup.md](./grok/post-merge-cleanup.md) | [claude-code/post-merge-cleanup.md](./claude-code/post-merge-cleanup.md) | [codex/post-merge-cleanup.md](./codex/post-merge-cleanup.md) | [github-actions/post-merge-cleanup.yml](./github-actions/post-merge-cleanup.yml) | | Dependency Sweeper | [grok/dependency-sweeper.md](./grok/dependency-sweeper.md) | [claude-code/dependency-sweeper.md](./claude-code/dependency-sweeper.md) | [codex/dependency-sweeper.md](./codex/dependency-sweeper.md) | [github-actions/dependency-sweeper.yml](./github-actions/dependency-sweeper.yml) | | Changelog Drafter | [grok/changelog-drafter.md](./grok/changelog-drafter.md) | [claude-code/changelog-drafter.md](./claude-code/changelog-drafter.md) | [codex/changelog-drafter.md](./codex/changelog-drafter.md) | [github-actions/changelog-drafter.yml](./github-actions/changelog-drafter.yml) | +| Issue Triage | [grok/issue-triage.md](./grok/issue-triage.md) | [claude-code/issue-triage.md](./claude-code/issue-triage.md) | [codex/issue-triage.md](./codex/issue-triage.md) | — (see daily-triage.yml as template) | L2 patterns ship multi-tool skills inside one starter folder — see `starters//`. diff --git a/examples/claude-code/issue-triage.md b/examples/claude-code/issue-triage.md new file mode 100644 index 0000000..e6bae8b --- /dev/null +++ b/examples/claude-code/issue-triage.md @@ -0,0 +1,60 @@ +# Issue Triage — Claude Code + +Same pattern as Grok; uses `$issue-triage` skill invocation and Claude Code scheduling. + +## Report-Only (Week 1) + +```bash +/loop 2h $issue-triage — read issue-triage-state.md first. Scan open issues since last run. Update state with Top 5, suggested labels, and needs-human bucket. Propose only — do not apply labels or close issues. Escalate auth, payments, and security items. +``` + +## Skills Setup + +Copy and adapt triage instructions to `.claude/skills/issue-triage/SKILL.md`: + +```bash +mkdir -p .claude/skills/issue-triage +# Start from templates/SKILL.md.loop-triage — retarget for GitHub issues + discussions +cp templates/SKILL.md.loop-triage .claude/skills/issue-triage/SKILL.md +``` + +Add verifier for L2 graduation: + +```bash +cp templates/SKILL.md.verifier .claude/agents/loop-verifier.md +``` + +## State File + +`issue-triage-state.md` at repo root — same schema as [patterns/issue-triage.md](../../patterns/issue-triage.md). + +Scaffold: + +```bash +npx @cobusgreyling/loop-init . --pattern issue-triage --tool claude --dry-run +``` + +## Allowlisted Labels (L2 only, week 3+) + +After 10 stable L1 runs, enable auto-apply for: + +- `area:*` (component labels) +- `needs-repro`, `needs-info` +- `duplicate?` (comment only, never auto-close) + +Human gate remains on: `P0`, `P1`, `security`, `breaking-change`. + +## Pairing with Daily Triage + +```bash +/loop 1d $loop-triage — read STATE.md and issue-triage-state.md. Merge top issue-triage items into High Priority. Report only week one. +``` + +## GitHub Action Fallback + +For event-driven triage on new issues, see [examples/github-actions/daily-triage.yml](../github-actions/daily-triage.yml) as a template — add `issues: opened` trigger and issue-triage prompt. + +## References + +- [patterns/issue-triage.md](../../patterns/issue-triage.md) +- [docs/primitives-matrix.md](../../docs/primitives-matrix.md) \ No newline at end of file diff --git a/examples/codex/issue-triage.md b/examples/codex/issue-triage.md new file mode 100644 index 0000000..6527fac --- /dev/null +++ b/examples/codex/issue-triage.md @@ -0,0 +1,74 @@ +# Issue Triage — Codex App + +Low-risk issue queue health loop. Report-only in week one. + +## Automation Setup + +In the Codex **Automations** tab: + +| Field | Value | +|-------|--------| +| Project | Your repo checkout | +| Cadence | Every 2h (busy repos) or 1d (quiet repos) | +| Environment | Local or background worktree | +| Prompt | See below | + +Optional: add `issues` webhook trigger for immediate triage on new issues. + +## Prompt (L1 — Propose Only) + +``` +Run $issue-triage on this project. Read issue-triage-state.md if present. + +Update issue-triage-state.md: +- Last run timestamp +- Open actionable count + delta since last run +- Top 5 prioritized issues with one-sentence summaries +- Suggested labels (proposed only — do not apply) +- "needs human" bucket for ambiguous, duplicate, or security-sensitive items + +Week 1: report only. Do not modify issues, labels, or source files. +Flag anything touching auth, payments, or public API for human review. +``` + +## Skills + +Install `issue-triage` per [Codex Agent Skills](https://developers.openai.com/codex/skills) — same `SKILL.md` format. Start from `templates/SKILL.md.loop-triage` and adapt scanning rules for your issue tracker. + +Define light verifier in `.codex/agents/verifier.toml` before enabling L2. + +## State Schema + +```markdown +# Issue Triage State +Last run: 2026-06-18 09:00 UTC +Open actionable: 14 +New since last run: 3 +Needs human: 2 + +## Top 5 +- #487 (p1) — Crash on export — suggested: bug, needs-repro +``` + +## Triage Inbox + +Runs with findings land in Codex Triage inbox — review there plus `issue-triage-state.md`. Empty runs archive automatically. + +## Phase 2 — Allowlisted Auto-Labels + +Add to prompt after calibration: + +``` +For allowlisted labels only (area:*, needs-repro): apply after verifier subagent passes. +Never auto-close. Never label P0/P1 without human confirmation. +``` + +## Pairing with Daily Triage + +Run a separate daily automation that reads both `STATE.md` and `issue-triage-state.md`, merging top issues into Daily Triage High Priority. + +## References + +- [patterns/issue-triage.md](../../patterns/issue-triage.md) +- [codex/daily-triage.md](./daily-triage.md) +- [docs/primitives-matrix.md](../../docs/primitives-matrix.md) \ No newline at end of file diff --git a/examples/grok/README.md b/examples/grok/README.md index 1951756..de22f83 100644 --- a/examples/grok/README.md +++ b/examples/grok/README.md @@ -7,6 +7,7 @@ Native primitives: `/loop`, `scheduler_create`, worktree isolation, skills, MCP, | Example | Pattern | |---------|---------| | [daily-triage.md](./daily-triage.md) | Daily Triage | +| [issue-triage.md](./issue-triage.md) | Issue Triage (L1 propose-only) | ## Common Commands diff --git a/examples/grok/issue-triage.md b/examples/grok/issue-triage.md new file mode 100644 index 0000000..4f5e631 --- /dev/null +++ b/examples/grok/issue-triage.md @@ -0,0 +1,73 @@ +# Issue Triage Loop (Grok Example) + +Low-risk companion to [Daily Triage](./daily-triage.md). Keeps the issue queue legible so morning triage and humans always know the top five. + +## Week 1 — Propose Only (L1) + +```bash +/loop 2h Run the issue-triage skill. Read issue-triage-state.md first. Scan open issues and discussions since last run. Update issue-triage-state.md with: +- Top 5 prioritized items (P0–P3) with one-sentence summaries +- Suggested labels (proposed only — do not apply) +- "needs human" bucket for ambiguous or security-sensitive items +Do not auto-label, close, or comment on issues. Escalate duplicates as "possible duplicate of #NNN" for human confirmation. +``` + +Faster cadence for busy repos: + +```bash +/loop 1d Run issue-triage at start and end of day. Report mode only. +``` + +## Supporting Files + +| File | Purpose | +|------|---------| +| `issue-triage-state.md` | Rolling backlog health (see [patterns/issue-triage.md](../../patterns/issue-triage.md)) | +| `issue-triage` skill | Copy from `templates/SKILL.md.loop-triage` and adapt for issue scanning | +| `loop-verifier` skill | Light sanity check on proposed labels before L2 | +| `STATE.md` | Daily Triage reads this; Issue Triage feeds it via cross-reference | + +Scaffold state file: + +```bash +npx @cobusgreyling/loop-init . --pattern issue-triage --tool grok --dry-run +``` + +## Typical `issue-triage-state.md` Shape + +```markdown +# Issue Triage State +Last run: 2026-06-18 09:00 UTC +Open actionable: 14 (was 17) +New since last run: 3 +Needs human: 2 + +## Top 5 (by loop score) +- #487 (bug, p1, 2d old) — "Crash on export with large files" — suggested: bug, needs-repro, area:export +- #491 (feature, p2) — "Dark mode for settings" — suggested: enhancement, area:ui +- #488 (duplicate?) — possible duplicate of #412 — human confirm + +## Proposed Labels (not applied — L1) +- #487: `bug`, `needs-repro`, `area:export` +- #491: `enhancement`, `area:ui` +``` + +## MCP (Optional) + +Enable GitHub MCP read-only for issue discovery and linked-PR signals. Scope to read + propose until the loop is trusted. + +## Pairing with Daily Triage + +Issue Triage runs more frequently (2h–1d) and produces a clean queue. Daily Triage (1d) reads `issue-triage-state.md` and merges the top items into `STATE.md` High Priority. + +## Evolution Path + +1. **L1 (weeks 1–2):** Propose labels and priority only; human applies manually. +2. **L2 (week 3+):** Auto-apply allowlisted labels (`area:*`, `needs-repro`) after verifier passes. +3. **Never unattended:** P0/P1 on auth, payments, security, or public API — human only. + +## References + +- [patterns/issue-triage.md](../../patterns/issue-triage.md) +- [docs/primitives-matrix.md](../../docs/primitives-matrix.md) +- [stories/daily-triage-report-only.md](../../stories/daily-triage-report-only.md) \ No newline at end of file diff --git a/stories/README.md b/stories/README.md index 0b269f0..03af16a 100644 --- a/stories/README.md +++ b/stories/README.md @@ -11,7 +11,7 @@ Real-world loop engineering — including failures. Contribute yours via [CONTRI | [multi-loop-collision.md](./multi-loop-collision.md) | Multi-loop | Branch lock + collision detection | | [l1-to-l2-graduation.md](./l1-to-l2-graduation.md) | Daily Triage | Calibration before auto-fix | | [changelog-drafter-week-one.md](./changelog-drafter-week-one.md) | Changelog Drafter | Low-risk, high-ROI L1 win | -| [post-merge-cleanup-honest-win.md](./post-merge-cleanup-honest-win.md) | Post-Merge Cleanup | Off-peak cadence + L1 report value | +| [post-merge-cleanup-honest-win.md](./post-merge-cleanup-honest-win.md) | Post-Merge Cleanup | Off-peak cadence; verifier caught doc/API drift; bot-merge noise | **Template for new stories:** diff --git a/stories/post-merge-cleanup-honest-win.md b/stories/post-merge-cleanup-honest-win.md index c408d82..31f9305 100644 --- a/stories/post-merge-cleanup-honest-win.md +++ b/stories/post-merge-cleanup-honest-win.md @@ -2,31 +2,45 @@ **Pattern:** [post-merge-cleanup](../patterns/post-merge-cleanup.md) **Cadence:** 1d (off-peak) +**Tool:** Grok Build TUI + GitHub Actions fallback +**Level:** L1 → cautious L2 (docs/comments only) **Outcome:** Useful, low-noise follow-up PRs — not a magic janitor -## Context +## Setup -After shipping a feature branch, the team had predictable leftovers: stale comments, half-updated docs, and tiny lint issues that nobody wanted to context-switch for. PR Babysitter felt too heavy for work already on `main`. +A mid-size SaaS team (12 engineers, ~40 merges/week) ran post-merge cleanup after shipping a feature branch. Predictable leftovers piled up: stale comments, half-updated docs, and tiny lint issues nobody wanted to context-switch for. PR Babysitter felt too heavy for work already on `main`. -## What we ran - -- **Loop:** daily post-merge scan on the last 24–48h of merges +- **Loop:** daily post-merge scan on merges in the last 24–48h - **Skills:** `post-merge-scan`, `minimal-fix`, `loop-verifier` -- **State:** `post-merge-state.md` with “fixed / ticketed / ignored” per merge -- **Week one:** L1 report only — the loop listed candidates, humans picked two +- **State:** `post-merge-state.md` with fixed / ticketed / ignored per merge SHA +- **Week one:** L1 report only — loop listed candidates, humans picked two +- **Denylist:** `auth/`, `payments/`, anything touching public API contracts -## What worked +## What Worked -- Off-peak cadence avoided fighting active feature work +- Off-peak cadence (21:00 local) avoided fighting active feature work - State file prevented re-scanning the same merge three days in a row - Verifier caught a “doc fix” that secretly changed a public API example +- Two engineers got value from the **report alone** without enabling L2 auto-fix +- First L2 PR (stale TODO comment removal) merged in 6 minutes with human LGTM + +## What Broke + +**Surprise — the doc fix that wasn't:** On day 4 the loop proposed a one-line README correction for a merge from PR #892. The verifier flagged it: the example response body had changed from `{ "id": string }` to `{ "userId": number }`, matching an undocumented API drift. The implementer had classified it as “docs only.” Without the verifier split, this would have shipped as a innocent documentation tweak. + +**Bot-merge noise:** The loop over-triaged Dependabot and Renovate merge commits for three days straight, generating 11 “candidates” that were lockfile-only. Engineers started ignoring the report. Fix: added `ignored_authors` (dependabot, renovate) and `min_diff_lines: 3` to state. + +**False confidence on feature flags:** The loop suggested removing `legacyAuth` based on a `// remove after Q2` comment, but the flag was still referenced in a mobile client the loop couldn't see (separate repo). A human caught it; we added “cross-repo flags → always escalate” to `LOOP.md`. -## What we learned +## Metrics (4-week pilot) -- The loop over-triaged bot-authored merge commits — we added a ignore list in state -- Anything touching `auth/` or `payments/` stayed human-only (denylist in LOOP.md) -- Two people got value from the **report** alone without enabling L2 auto-fix +| Metric | Before | After L1+L2 (docs only) | +|--------|--------|-------------------------| +| Median time merge → first follow-up | 6.2 days | 1.4 days | +| Follow-up PRs opened per week | 0–1 (ad hoc) | 3–5 (loop-proposed, human-approved) | +| False-positive rate (human judged) | — | ~18% week 1 → ~6% week 4 | +| Engineer “report useful?” (1–5) | — | 4.1 average by week 3 | -## Recommendation +## Lesson -Start L1 for two weeks. If the report is consistently right, enable L2 for docs and comment-only paths. Keep architectural debt in Linear, not in the loop. \ No newline at end of file +Start L1 for two weeks — the report calibrates what your team actually considers debt. Enable L2 only for docs, comments, and lint paths with a verifier that treats API examples as code. Keep architectural debt in Linear, not in the loop. Post-Merge Cleanup is a complement to PR Babysitter, not a replacement: it runs off-peak on work already landed. \ No newline at end of file