@cobusgreyling/loop-init 1.3.1 → 1.3.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/README.md +7 -0
  2. package/dist/cli.js +56 -2
  3. package/dist/contributor-cta.d.ts +2 -0
  4. package/dist/contributor-cta.js +6 -0
  5. package/package.json +1 -1
  6. package/starters/README.md +6 -0
  7. package/starters/changelog-drafter-opencode/AGENTS.md +15 -0
  8. package/starters/changelog-drafter-opencode/LOOP.md +26 -0
  9. package/starters/changelog-drafter-opencode/README.md +44 -0
  10. package/starters/changelog-drafter-opencode/changelog-drafter-state.md.example +10 -0
  11. package/starters/changelog-drafter-opencode/opencode.json.example +35 -0
  12. package/starters/changelog-drafter-opencode/skills/changelog-scan/SKILL.md +38 -0
  13. package/starters/ci-sweeper-opencode/AGENTS.md +17 -0
  14. package/starters/ci-sweeper-opencode/LOOP.md +26 -0
  15. package/starters/ci-sweeper-opencode/README.md +43 -0
  16. package/starters/ci-sweeper-opencode/ci-sweeper-state.md.example +10 -0
  17. package/starters/ci-sweeper-opencode/opencode.json.example +35 -0
  18. package/starters/ci-sweeper-opencode/skills/ci-triage/SKILL.md +32 -0
  19. package/starters/dependency-sweeper-opencode/AGENTS.md +15 -0
  20. package/starters/dependency-sweeper-opencode/LOOP.md +27 -0
  21. package/starters/dependency-sweeper-opencode/README.md +44 -0
  22. package/starters/dependency-sweeper-opencode/dependency-sweeper-state.md.example +11 -0
  23. package/starters/dependency-sweeper-opencode/opencode.json.example +35 -0
  24. package/starters/dependency-sweeper-opencode/skills/dependency-triage/SKILL.md +35 -0
  25. package/starters/issue-triage-opencode/AGENTS.md +16 -0
  26. package/starters/issue-triage-opencode/LOOP.md +21 -0
  27. package/starters/issue-triage-opencode/README.md +43 -0
  28. package/starters/issue-triage-opencode/issue-triage-state.md.example +11 -0
  29. package/starters/issue-triage-opencode/opencode.json.example +35 -0
  30. package/starters/issue-triage-opencode/skills/issue-triage/SKILL.md +33 -0
  31. package/starters/post-merge-cleanup-opencode/AGENTS.md +15 -0
  32. package/starters/post-merge-cleanup-opencode/LOOP.md +26 -0
  33. package/starters/post-merge-cleanup-opencode/README.md +44 -0
  34. package/starters/post-merge-cleanup-opencode/opencode.json.example +35 -0
  35. package/starters/post-merge-cleanup-opencode/post-merge-state.md.example +10 -0
  36. package/starters/post-merge-cleanup-opencode/skills/post-merge-scan/SKILL.md +34 -0
  37. package/starters/pr-babysitter-opencode/AGENTS.md +18 -0
  38. package/starters/pr-babysitter-opencode/LOOP.md +27 -0
  39. package/starters/pr-babysitter-opencode/README.md +44 -0
  40. package/starters/pr-babysitter-opencode/opencode.json.example +35 -0
  41. package/starters/pr-babysitter-opencode/pr-babysitter-state.md.example +10 -0
  42. package/starters/pr-babysitter-opencode/skills/pr-review-triage/SKILL.md +33 -0
  43. package/templates/SKILL.md.loop-guard +94 -0
  44. package/templates/loop-constraints.md +1 -0
package/README.md CHANGED
@@ -31,6 +31,13 @@ After scaffolding, always run `npx @cobusgreyling/loop-audit . --suggest` and ac
31
31
 
32
32
  L2 patterns (`ci-sweeper`, `dependency-sweeper`) also copy `minimal-fix` and `loop-verifier` templates when missing from the starter.
33
33
 
34
+ Fix-capable patterns (`pr-babysitter`, `ci-sweeper`, `dependency-sweeper`, `post-merge-cleanup`) also get a **circuit breaker**:
35
+
36
+ - `loop-guard` skill — logs each attempt to `loop-ledger.json` and runs [`loop-context`](../loop-context) `--check` before retrying
37
+ - `loop-ledger.json` — seeded with the pattern's goal, its `pattern`/`level`, and an empty `attempts` array
38
+
39
+ The ledger's `pattern`/`level` let `loop-guard` size the breaker's `--token-budget` from [`loop-cost`](../loop-cost)'s realistic per-run estimate instead of a hand-typed number. The breaker escalates (same error N× in a row, too many consecutive failures, token budget, or iteration cap) instead of looping in vain. Report-only patterns skip it.
40
+
34
41
  Every scaffold also creates:
35
42
 
36
43
  - `loop-budget.md` — pattern-specific daily caps and kill switch
package/dist/cli.js CHANGED
@@ -3,6 +3,7 @@ import { spawn } from 'node:child_process';
3
3
  import { cp, mkdir, readFile, writeFile, access } from 'node:fs/promises';
4
4
  import path from 'node:path';
5
5
  import { fileURLToPath } from 'node:url';
6
+ import { printContributorCta } from './contributor-cta.js';
6
7
  const __dirname = path.dirname(fileURLToPath(import.meta.url));
7
8
  const PACKAGE_ROOT = path.resolve(__dirname, '..');
8
9
  const MONOREPO_STARTERS = path.resolve(PACKAGE_ROOT, '../../starters');
@@ -142,6 +143,53 @@ async function copyL2Templates(pattern, tool, targetDir, templatesRoot, dryRun)
142
143
  await copyTemplateVerifier(templatesRoot, targetDir, tool, dryRun);
143
144
  }
144
145
  }
146
+ /** Per-pattern goal seeded into loop-ledger.json for the circuit breaker. */
147
+ const LEDGER_GOAL = {
148
+ 'daily-triage': 'Keep the repo healthy and STATE.md current',
149
+ 'pr-babysitter': 'Get the watched PR review-ready and green',
150
+ 'ci-sweeper': 'Get failing CI back to green',
151
+ 'dependency-sweeper': 'Land safe dependency updates',
152
+ 'post-merge-cleanup': 'Clean up regressions from recent merges',
153
+ 'changelog-drafter': 'Draft accurate release notes',
154
+ 'issue-triage': 'Triage the open issue queue',
155
+ };
156
+ /**
157
+ * Readiness level seeded into loop-ledger.json so the loop-guard skill can
158
+ * resolve a realistic per-run token budget from `loop-cost --json` instead of a
159
+ * hand-typed number. Fix-capable loops draft changes with a verifier (a human
160
+ * still merges), so L2 is the right default; tune it in the ledger if a loop
161
+ * runs unattended (L3) or report-only (L1).
162
+ */
163
+ const LEDGER_LEVEL = {
164
+ 'daily-triage': 'L1',
165
+ 'pr-babysitter': 'L2',
166
+ 'ci-sweeper': 'L2',
167
+ 'dependency-sweeper': 'L2',
168
+ 'post-merge-cleanup': 'L2',
169
+ 'changelog-drafter': 'L1',
170
+ 'issue-triage': 'L1',
171
+ };
172
+ /**
173
+ * Fix-capable loops retry actions, so they need a circuit breaker: scaffold the
174
+ * loop-guard skill plus a seeded loop-ledger.json wired to `loop-context`.
175
+ * Report-only patterns (daily-triage, issue-triage, changelog-drafter) don't
176
+ * retry fixes, so they skip this to keep the scaffold minimal.
177
+ */
178
+ async function scaffoldCircuitBreaker(pattern, tool, targetDir, templatesRoot, dryRun) {
179
+ if (!PATTERNS_NEEDING_FIX.has(pattern))
180
+ return;
181
+ await copyTemplateSkill(templatesRoot, 'SKILL.md.loop-guard', targetDir, tool, 'loop-guard', dryRun);
182
+ const ledgerPath = path.join(targetDir, 'loop-ledger.json');
183
+ if (await exists(ledgerPath))
184
+ return;
185
+ const seed = `${JSON.stringify({ goal: LEDGER_GOAL[pattern], pattern, level: LEDGER_LEVEL[pattern], attempts: [] }, null, 2)}\n`;
186
+ if (dryRun) {
187
+ console.log(` would write: ${ledgerPath}`);
188
+ return;
189
+ }
190
+ await writeFile(ledgerPath, seed);
191
+ console.log(' created: loop-ledger.json (circuit breaker)');
192
+ }
145
193
  function formatTokenCap(n) {
146
194
  if (n >= 1_000_000)
147
195
  return `${n / 1_000_000}M`;
@@ -361,7 +409,7 @@ Examples:
361
409
  const targetDir = path.resolve(target);
362
410
  const baseStarter = PATTERN_STARTERS[pattern];
363
411
  const suffix = TOOL_SUFFIX[tool];
364
- const starterName = pattern === 'daily-triage' ? `minimal-loop${suffix}` : baseStarter;
412
+ const starterName = `${baseStarter}${suffix}`;
365
413
  const startersRoot = await resolveBundledOrMonorepo('starters');
366
414
  const templatesRoot = await resolveBundledOrMonorepo('templates');
367
415
  const starterRoot = path.join(startersRoot, starterName);
@@ -442,6 +490,7 @@ Examples:
442
490
  await copyFile(loopMd, path.join(targetDir, 'LOOP.md'), dryRun);
443
491
  }
444
492
  await copyL2Templates(pattern, tool, targetDir, templatesRoot, dryRun);
493
+ await scaffoldCircuitBreaker(pattern, tool, targetDir, templatesRoot, dryRun);
445
494
  await scaffoldObservability(pattern, tool, targetDir, templatesRoot, dryRun);
446
495
  await scaffoldConstraints(targetDir, templatesRoot, tool, dryRun);
447
496
  if (tool !== 'opencode' && !dryRun && !(await exists(path.join(targetDir, 'AGENTS.md')))) {
@@ -475,12 +524,17 @@ npm run lint
475
524
  console.log(` npx @cobusgreyling/loop-audit ${auditArg} --suggest`);
476
525
  }
477
526
  }
527
+ if (PATTERNS_NEEDING_FIX.has(pattern)) {
528
+ console.log('');
529
+ console.log('Circuit breaker wired (loop-guard skill + loop-ledger.json):');
530
+ console.log(' npx @cobusgreyling/loop-context --check --ledger loop-ledger.json');
531
+ }
478
532
  console.log('');
479
533
  console.log(`First loop (${tool}):`);
480
534
  console.log(` ${firstLoopCommand(pattern, tool)}`);
481
535
  console.log('');
482
536
  console.log(`Estimate cost: npx @cobusgreyling/loop-cost --pattern ${pattern} --level L1`);
483
- console.log('');
537
+ printContributorCta();
484
538
  }
485
539
  async function readDirNames(dir) {
486
540
  const { readdir } = await import('node:fs/promises');
@@ -0,0 +1,2 @@
1
+ export declare const CONTRIBUTOR_QUICKSTART_URL = "https://github.com/cobusgreyling/loop-engineering/discussions/123";
2
+ export declare function printContributorCta(): void;
@@ -0,0 +1,6 @@
1
+ export const CONTRIBUTOR_QUICKSTART_URL = 'https://github.com/cobusgreyling/loop-engineering/discussions/123';
2
+ export function printContributorCta() {
3
+ console.log('');
4
+ console.log('Contribute (~15 min tasks):');
5
+ console.log(` ${CONTRIBUTOR_QUICKSTART_URL}`);
6
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cobusgreyling/loop-init",
3
- "version": "1.3.1",
3
+ "version": "1.3.3",
4
4
  "description": "Scaffold loop engineering patterns and starters into any project. Supports Grok, Claude Code, Codex, Opencode and more. npx @cobusgreyling/loop-init . --pattern daily-triage --tool opencode",
5
5
  "type": "module",
6
6
  "bin": {
@@ -21,11 +21,17 @@ npx @cobusgreyling/loop-init . -p pr-babysitter -t claude
21
21
  | Starter | Pattern | Tools | Readiness |
22
22
  |---------|---------|-------|-----------|
23
23
  | [pr-babysitter](./pr-babysitter/) | PR Babysitter | Grok, Claude, Codex | L2 assisted |
24
+ | [pr-babysitter-opencode](./pr-babysitter-opencode/) | PR Babysitter | Opencode | L1 → L2 |
24
25
  | [ci-sweeper](./ci-sweeper/) | CI Sweeper | Grok, Claude, Codex | L2 assisted |
26
+ | [ci-sweeper-opencode](./ci-sweeper-opencode/) | CI Sweeper | Opencode | L2 cautious |
25
27
  | [dependency-sweeper](./dependency-sweeper/) | Dependency Sweeper | Grok, Claude, Codex | L2 patch-only |
28
+ | [dependency-sweeper-opencode](./dependency-sweeper-opencode/) | Dependency Sweeper | Opencode | L2 patch-only |
26
29
  | [post-merge-cleanup](./post-merge-cleanup/) | Post-Merge Cleanup | Grok, Claude, Codex | L1 → L2 |
30
+ | [post-merge-cleanup-opencode](./post-merge-cleanup-opencode/) | Post-Merge Cleanup | Opencode | L1 → L2 |
27
31
  | [changelog-drafter](./changelog-drafter/) | Changelog Drafter | Grok, Claude, Codex | L1 draft → L2 |
32
+ | [changelog-drafter-opencode](./changelog-drafter-opencode/) | Changelog Drafter | Opencode | L1 draft → L2 |
28
33
  | [issue-triage](./issue-triage/) | Issue Triage | Grok, Claude, Codex | L1 propose-only |
34
+ | [issue-triage-opencode](./issue-triage-opencode/) | Issue Triage | Opencode | L1 propose-only |
29
35
 
30
36
  After copying:
31
37
 
@@ -0,0 +1,15 @@
1
+ # AGENTS.md — Changelog Drafter (Opencode)
2
+
3
+ ## Loop Mode
4
+ - L1 report + draft for the first 1-2 weeks.
5
+ - Read `changelog-drafter-state.md` before every run.
6
+ - Human approves every draft before any publish or PR.
7
+
8
+ ## Safety
9
+ - Never create tags, GitHub releases, or update CHANGELOG.md without explicit human approval.
10
+ - Breaking changes and security items must be surfaced explicitly.
11
+ - Draft PRs only when L2 is enabled — never auto-merge.
12
+
13
+ ## Verification
14
+ - Verifier checks draft completeness: categories, date range, links.
15
+ - Record draft status and human feedback in state.
@@ -0,0 +1,26 @@
1
+ # Loop Configuration — Changelog Drafter (Opencode)
2
+
3
+ ## Active Loops
4
+
5
+ | Pattern | Cadence | Status | Command |
6
+ |---------|---------|--------|---------|
7
+ | Changelog Drafter | 1d or on release prep | L1 draft-only | `opencode run "Run changelog-scan"` via cron (after merges settle) |
8
+
9
+ ## Human Gates
10
+ - Breaking changes always human review.
11
+ - Security notes / CVEs human must approve wording.
12
+ - No tags, no PRs, no publishes without explicit approval.
13
+ - First 3 releases: human approves full draft.
14
+
15
+ ## Budget
16
+ - Max sub-agent spawns per run: 2 (scanner + drafter).
17
+ - Prefer running after merges settle (evening).
18
+
19
+ ## Output Convention
20
+ - Draft: `RELEASE_NOTES_DRAFT.md` at repo root.
21
+ - State: `changelog-drafter-state.md`.
22
+
23
+ ## Links
24
+ - Pattern: [changelog-drafter](../../patterns/changelog-drafter.md)
25
+ - Example: [examples/opencode/changelog-drafter.md](../../examples/opencode/changelog-drafter.md)
26
+ - Safety: [docs/safety.md](../../docs/safety.md)
@@ -0,0 +1,44 @@
1
+ # Changelog Drafter — Opencode Starter
2
+
3
+ Clone-and-run scaffold for the **Changelog Drafter** pattern with opencode. Scan merged PRs and commits, produce categorized release notes.
4
+
5
+ ## Quick Start
6
+
7
+ ```bash
8
+ npx @cobusgreyling/loop-init . --pattern changelog-drafter --tool opencode
9
+ ```
10
+
11
+ Or copy manually:
12
+
13
+ ```bash
14
+ cp -r starters/changelog-drafter-opencode/skills .
15
+ cp starters/changelog-drafter-opencode/AGENTS.md .
16
+ cp starters/changelog-drafter-opencode/LOOP.md .
17
+ cp starters/changelog-drafter-opencode/changelog-drafter-state.md.example changelog-drafter-state.md
18
+ cp starters/changelog-drafter-opencode/opencode.json.example opencode.json
19
+ ```
20
+
21
+ Start (L1 report + draft, week 1):
22
+
23
+ ```bash
24
+ opencode run \
25
+ "Run skills/changelog-scan/SKILL.md. Scan merges since last tag (or last 7 days). Produce categorized draft in RELEASE_NOTES_DRAFT.md. Update state. Do not publish or create PRs." \
26
+ --title "Changelog drafter"
27
+ ```
28
+
29
+ ## What's Included
30
+
31
+ | File | Purpose |
32
+ |------|---------|
33
+ | `changelog-drafter-state.md.example` | State spine (last release, draft status) |
34
+ | `skills/changelog-scan/SKILL.md` | Merge scan and categorization skill |
35
+ | `AGENTS.md` | Always-on safety rules |
36
+ | `LOOP.md` | Cadence, gates, budget |
37
+ | `opencode.json.example` | Named agent definitions |
38
+
39
+ ## Next Steps
40
+
41
+ - [patterns/changelog-drafter.md](../../patterns/changelog-drafter.md)
42
+ - [examples/opencode/changelog-drafter.md](../../examples/opencode/changelog-drafter.md)
43
+ - [docs/loop-design-checklist.md](../../docs/loop-design-checklist.md)
44
+ - [stories/changelog-drafter-week-one.md](../../stories/changelog-drafter-week-one.md)
@@ -0,0 +1,10 @@
1
+ # Changelog Drafter State
2
+ Last run: 2026-06-20 09:00 UTC
3
+ Last tag scanned: v0.0.0
4
+ Draft status: none
5
+ Human feedback: pending
6
+
7
+ ## Scan Window
8
+ - From: <!-- last tag or date -->
9
+ - To: <!-- current -->
10
+ - Merges found: 0
@@ -0,0 +1,35 @@
1
+ {
2
+ "$schema": "https://opencode.ai/config.json",
3
+ "agent": {
4
+ "changelog-scan": {
5
+ "name": "changelog-scan",
6
+ "description": "Changelog drafting loop. Reads changelog-drafter-state.md, scans merges, and produces categorized release notes.",
7
+ "mode": "primary",
8
+ "prompt": "Read AGENTS.md, LOOP.md, changelog-drafter-state.md, and skills/changelog-scan/SKILL.md. Scan merges since last tag. Produce categorized draft in RELEASE_NOTES_DRAFT.md. Never publish or tag without human approval.",
9
+ "permission": {
10
+ "bash": "ask",
11
+ "edit": "ask"
12
+ }
13
+ },
14
+ "implementer": {
15
+ "name": "implementer",
16
+ "description": "L2 implementer for creating changelog PRs.",
17
+ "mode": "subagent",
18
+ "prompt": "Commit the approved release notes to a new branch and open a draft PR. Flag breaking changes and security items explicitly in the PR body. Do not merge.",
19
+ "permission": {
20
+ "bash": "ask",
21
+ "edit": "ask"
22
+ }
23
+ },
24
+ "verifier": {
25
+ "name": "verifier",
26
+ "description": "Checker agent for draft release notes. APPROVE or REJECT only.",
27
+ "mode": "subagent",
28
+ "prompt": "Review the draft notes for completeness, categorization, and correct date range. Flag missing sections. Do not edit. APPROVE or REJECT.",
29
+ "permission": {
30
+ "bash": "ask",
31
+ "edit": "deny"
32
+ }
33
+ }
34
+ }
35
+ }
@@ -0,0 +1,38 @@
1
+ ---
2
+ name: changelog-scan
3
+ description: >
4
+ Scan merged PRs and commits since a given reference, extract
5
+ titles, labels, types, and signals. Produces structured input
6
+ for release notes drafting.
7
+ user_invocable: true
8
+ ---
9
+
10
+ # Changelog Scan Skill
11
+
12
+ You are a changelog drafting agent. Scan merges and produce release notes.
13
+
14
+ ## Scan Sources
15
+
16
+ - `git log --merges --oneline <last-tag>..HEAD`
17
+ - PR labels and milestones
18
+ - Commit messages since last tag
19
+
20
+ ## Categories
21
+
22
+ - Features
23
+ - Bug fixes
24
+ - Documentation
25
+ - Dependencies
26
+ - Breaking changes
27
+ - Security
28
+
29
+ ## Output
30
+
31
+ - Categorized draft in `RELEASE_NOTES_DRAFT.md`
32
+ - Update `changelog-drafter-state.md` with scan window
33
+
34
+ ## Rules
35
+
36
+ - Never publish or tag without explicit human approval.
37
+ - Surface breaking changes and security items explicitly.
38
+ - L1: draft only — no PRs, no tags.
@@ -0,0 +1,17 @@
1
+ # AGENTS.md — CI Sweeper (Opencode)
2
+
3
+ ## Loop Mode
4
+ - CI sweeper is L2 from week one (action-oriented — CIs are urgent).
5
+ - Read `ci-sweeper-state.md` before every run.
6
+ - Classify failures before attempting any fix.
7
+
8
+ ## Safety
9
+ - Always dispatch into a git worktree per attempt.
10
+ - Infra / security / payments test failures: do not auto-fix; flag and stop.
11
+ - Max 3 fix attempts per item; escalate after.
12
+ - Enforce budget cap from `LOOP.md`.
13
+
14
+ ## Verification
15
+ - Verifier must run tests after implementer.
16
+ - Record attempt count in `ci-sweeper-state.md`.
17
+ - No auto-merge without verifier approval.
@@ -0,0 +1,26 @@
1
+ # Loop Configuration — CI Sweeper (Opencode)
2
+
3
+ ## Active Loops
4
+
5
+ | Pattern | Cadence | Status | Command |
6
+ |---------|---------|--------|---------|
7
+ | CI Sweeper | 5-15m | L2 cautious | `opencode run "Run ci-triage" --agent loop-triage` via cron/systemd |
8
+
9
+ ## Human Gates
10
+ - Infra / security / payments test failures: do not auto-fix.
11
+ - Max 3 fix attempts per item; escalate after.
12
+ - No auto-merge without verifier pass.
13
+
14
+ ## Worktrees
15
+ - Always dispatch into a git worktree per attempt.
16
+ - One worktree per fix; discard after REJECT.
17
+
18
+ ## Budget
19
+ - Max sub-agent spawns per run: 3.
20
+ - Max auto-PRs per day: 5.
21
+ - Early exit if no failures found.
22
+
23
+ ## Links
24
+ - Pattern: [ci-sweeper](../../patterns/ci-sweeper.md)
25
+ - Example: [examples/opencode/ci-sweeper.md](../../examples/opencode/ci-sweeper.md)
26
+ - Safety: [docs/safety.md](../../docs/safety.md)
@@ -0,0 +1,43 @@
1
+ # CI Sweeper — Opencode Starter
2
+
3
+ Clone-and-run scaffold for the **CI Sweeper** pattern with opencode. React to failing CI with minimal fixes at short cadences.
4
+
5
+ ## Quick Start
6
+
7
+ ```bash
8
+ npx @cobusgreyling/loop-init . --pattern ci-sweeper --tool opencode
9
+ ```
10
+
11
+ Or copy manually:
12
+
13
+ ```bash
14
+ cp -r starters/ci-sweeper-opencode/skills .
15
+ cp starters/ci-sweeper-opencode/AGENTS.md .
16
+ cp starters/ci-sweeper-opencode/LOOP.md .
17
+ cp starters/ci-sweeper-opencode/ci-sweeper-state.md.example ci-sweeper-state.md
18
+ cp starters/ci-sweeper-opencode/opencode.json.example opencode.json
19
+ ```
20
+
21
+ Start (L2 cautious — CI sweeper is action-oriented from week one):
22
+
23
+ ```bash
24
+ opencode run \
25
+ "Run skills/ci-triage/SKILL.md. Classify each failing check. For clear single-file regressions, create a worktree and apply a minimal fix with verifier. Update ci-sweeper-state.md. Infra and security failures: escalate." \
26
+ --title "CI sweeper"
27
+ ```
28
+
29
+ ## What's Included
30
+
31
+ | File | Purpose |
32
+ |------|---------|
33
+ | `ci-sweeper-state.md.example` | State spine (in-flight CI failures) |
34
+ | `skills/ci-triage/SKILL.md` | CI-focused triage skill |
35
+ | `AGENTS.md` | Always-on safety rules |
36
+ | `LOOP.md` | Cadence, gates, budget |
37
+ | `opencode.json.example` | Named agent definitions |
38
+
39
+ ## Next Steps
40
+
41
+ - [patterns/ci-sweeper.md](../../patterns/ci-sweeper.md)
42
+ - [examples/opencode/ci-sweeper.md](../../examples/opencode/ci-sweeper.md)
43
+ - [docs/loop-design-checklist.md](../../docs/loop-design-checklist.md)
@@ -0,0 +1,10 @@
1
+ # CI Sweeper State
2
+ Last run: 2026-06-20 09:00 UTC
3
+ Active failures: 0
4
+ Attempt counts: {}
5
+
6
+ ## Failures
7
+ - <!-- Add failing checks here -->
8
+
9
+ ## Escalated
10
+ - <!-- Infra/security failures escalated to human -->
@@ -0,0 +1,35 @@
1
+ {
2
+ "$schema": "https://opencode.ai/config.json",
3
+ "agent": {
4
+ "ci-triage": {
5
+ "name": "ci-triage",
6
+ "description": "CI-focused triage and fix loop. Reads ci-sweeper-state.md, classifies CI failures, and applies minimal fixes in worktrees with verifier.",
7
+ "mode": "primary",
8
+ "prompt": "Read AGENTS.md, LOOP.md, ci-sweeper-state.md, and skills/ci-triage/SKILL.md. Classify each failing check. For clear regressions: worktree + implementer + verifier. Escalate infra and security failures.",
9
+ "permission": {
10
+ "bash": "ask",
11
+ "edit": "ask"
12
+ }
13
+ },
14
+ "implementer": {
15
+ "name": "implementer",
16
+ "description": "L2 implementer for CI-fix patches inside an isolated worktree.",
17
+ "mode": "subagent",
18
+ "prompt": "Implement the minimal fix for the identified CI failure inside the supplied worktree. Run tests. Output the diff path. Max 3 attempts per item.",
19
+ "permission": {
20
+ "bash": "ask",
21
+ "edit": "ask"
22
+ }
23
+ },
24
+ "verifier": {
25
+ "name": "verifier",
26
+ "description": "Checker agent for CI fix diffs. APPROVE or REJECT only.",
27
+ "mode": "subagent",
28
+ "prompt": "Review the supplied CI-fix diff. Verify tests pass. Do not edit files. APPROVE or REJECT with evidence.",
29
+ "permission": {
30
+ "bash": "ask",
31
+ "edit": "deny"
32
+ }
33
+ }
34
+ }
35
+ }
@@ -0,0 +1,32 @@
1
+ ---
2
+ name: ci-triage
3
+ description: >
4
+ Classify CI failures — distinguish clear regressions from infra flakes
5
+ and security-test failures. Produces structured failure reports.
6
+ user_invocable: true
7
+ ---
8
+
9
+ # CI Triage Skill
10
+
11
+ You are a CI triage agent. Classify each failing check and decide the next action.
12
+
13
+ ## Classification
14
+
15
+ - **Clear regression**: single-file, obvious root cause (candidate for auto-fix)
16
+ - **Infra flake**: network timeout, runner issue, dependency unavailable
17
+ - **Security test failure**: never auto-fix; escalate to human
18
+ - **Non-deterministic**: retry once before classifying
19
+
20
+ ## Output
21
+
22
+ Update `ci-sweeper-state.md` with:
23
+
24
+ - List of failures by category
25
+ - Suggested next action per item
26
+ - Attempt count per item
27
+
28
+ ## Rules
29
+
30
+ - Infra and security failures always escalate.
31
+ - Max 3 fix attempts per item.
32
+ - Worktree isolation required for any code change.
@@ -0,0 +1,15 @@
1
+ # AGENTS.md — Dependency Sweeper (Opencode)
2
+
3
+ ## Loop Mode
4
+ - L2 assisted from week one (patch-only with strong verifier gates).
5
+ - Read `dependency-sweeper-state.md` before every run.
6
+
7
+ ## Safety
8
+ - Patch-only by default. Majors and breaking changes escalate to human.
9
+ - Maintain denylist in state file — never touch those packages.
10
+ - One worktree per update attempt.
11
+ - Max 3 fix attempts per run; max 5 auto-PRs per day.
12
+
13
+ ## Verification
14
+ - Verifier must run `npm ci && npm test` (or equivalent).
15
+ - Record attempt count and test evidence in state.
@@ -0,0 +1,27 @@
1
+ # Loop Configuration — Dependency Sweeper (Opencode)
2
+
3
+ ## Active Loops
4
+
5
+ | Pattern | Cadence | Status | Command |
6
+ |---------|---------|--------|---------|
7
+ | Dependency Sweeper | 6h | L2 patch-only | `opencode run "Run dependency-triage" --agent loop-triage` via cron |
8
+
9
+ ## Human Gates
10
+ - Major version bumps always human.
11
+ - High-severity CVE requiring breaking change: human.
12
+ - Denylist packages (edit in state) never auto-touched.
13
+ - No auto-merge without verifier pass.
14
+
15
+ ## Worktrees
16
+ - One worktree per package update attempt.
17
+ - Discard on REJECT or human escalation.
18
+
19
+ ## Budget
20
+ - Max sub-agent spawns per run: 3.
21
+ - Max auto-PRs per day: 5.
22
+ - Pause if token budget exceeded.
23
+
24
+ ## Links
25
+ - Pattern: [dependency-sweeper](../../patterns/dependency-sweeper.md)
26
+ - Example: [examples/opencode/dependency-sweeper.md](../../examples/opencode/dependency-sweeper.md)
27
+ - Safety: [docs/safety.md](../../docs/safety.md)
@@ -0,0 +1,44 @@
1
+ # Dependency Sweeper — Opencode Starter
2
+
3
+ Clone-and-run scaffold for the **Dependency Sweeper** pattern with opencode. Discover, safely apply, and verify dependency updates.
4
+
5
+ ## Quick Start
6
+
7
+ ```bash
8
+ npx @cobusgreyling/loop-init . --pattern dependency-sweeper --tool opencode
9
+ ```
10
+
11
+ Or copy manually:
12
+
13
+ ```bash
14
+ cp -r starters/dependency-sweeper-opencode/skills .
15
+ cp starters/dependency-sweeper-opencode/AGENTS.md .
16
+ cp starters/dependency-sweeper-opencode/LOOP.md .
17
+ cp starters/dependency-sweeper-opencode/dependency-sweeper-state.md.example dependency-sweeper-state.md
18
+ cp starters/dependency-sweeper-opencode/opencode.json.example opencode.json
19
+ ```
20
+
21
+ Start (L2 assisted, patch-only):
22
+
23
+ ```bash
24
+ opencode run \
25
+ "Run skills/dependency-triage/SKILL.md. Scan package manifests for outdated and vulnerable deps. Patch-only auto-fix in worktree with verifier. Escalate majors, high-sev CVEs, and denylist packages. Update state." \
26
+ --title "Dependency sweeper"
27
+ ```
28
+
29
+ ## What's Included
30
+
31
+ | File | Purpose |
32
+ |------|---------|
33
+ | `dependency-sweeper-state.md.example` | State spine (in-flight updates, denylist) |
34
+ | `skills/dependency-triage/SKILL.md` | Dependency-focused triage skill |
35
+ | `AGENTS.md` | Always-on safety rules |
36
+ | `LOOP.md` | Cadence, gates, budget |
37
+ | `opencode.json.example` | Named agent definitions |
38
+
39
+ ## Next Steps
40
+
41
+ - [patterns/dependency-sweeper.md](../../patterns/dependency-sweeper.md)
42
+ - [examples/opencode/dependency-sweeper.md](../../examples/opencode/dependency-sweeper.md)
43
+ - [docs/loop-design-checklist.md](../../docs/loop-design-checklist.md)
44
+ - [stories/dependency-sweeper-week-one.md](../../stories/dependency-sweeper-week-one.md)
@@ -0,0 +1,11 @@
1
+ # Dependency Sweeper State
2
+ Last run: 2026-06-20 09:00 UTC
3
+ Outdated packages: 0
4
+ Attempt counts: {}
5
+ Auto-PRs today: 0
6
+
7
+ ## Denylist (never touch)
8
+ - <!-- Add packages the loop must never update -->
9
+
10
+ ## Escalated to Human
11
+ - <!-- Major bumps and high-sev CVEs -->
@@ -0,0 +1,35 @@
1
+ {
2
+ "$schema": "https://opencode.ai/config.json",
3
+ "agent": {
4
+ "dependency-triage": {
5
+ "name": "dependency-triage",
6
+ "description": "Dependency-focused triage loop. Reads dependency-sweeper-state.md, scans manifests, and applies patch-only upgrades with verifier.",
7
+ "mode": "primary",
8
+ "prompt": "Read AGENTS.md, LOOP.md, dependency-sweeper-state.md, and skills/dependency-triage/SKILL.md. Scan manifests for outdated and vulnerable deps. Patch-only auto-fix in worktree. Escalate majors and denylisted packages.",
9
+ "permission": {
10
+ "bash": "ask",
11
+ "edit": "ask"
12
+ }
13
+ },
14
+ "implementer": {
15
+ "name": "implementer",
16
+ "description": "L2 implementer for patch-only dependency upgrades in a worktree.",
17
+ "mode": "subagent",
18
+ "prompt": "Apply the identified patch-only upgrade inside the supplied worktree. Run npm ci && npm test. Never touch denylisted packages. Output the diff.",
19
+ "permission": {
20
+ "bash": "ask",
21
+ "edit": "ask"
22
+ }
23
+ },
24
+ "verifier": {
25
+ "name": "verifier",
26
+ "description": "Checker agent for dependency upgrade diffs. APPROVE or REJECT only.",
27
+ "mode": "subagent",
28
+ "prompt": "Verify the dependency patch passes tests and touches no denylisted packages. Do not edit files. APPROVE or REJECT with evidence.",
29
+ "permission": {
30
+ "bash": "ask",
31
+ "edit": "deny"
32
+ }
33
+ }
34
+ }
35
+ }