@cobusgreyling/loop-init 1.3.3 → 1.4.0

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.
package/README.md CHANGED
@@ -4,6 +4,8 @@ Scaffold loop engineering starters into your project by pattern and tool.
4
4
 
5
5
  **npx @cobusgreyling/loop-init . --pattern daily-triage --tool grok** works immediately.
6
6
 
7
+ See [docs/loop-init-validation.md](../../docs/loop-init-validation.md) for a validated pattern × --tool matrix.
8
+
7
9
  ## Install & Run
8
10
 
9
11
  ```bash
@@ -38,6 +40,10 @@ Fix-capable patterns (`pr-babysitter`, `ci-sweeper`, `dependency-sweeper`, `post
38
40
 
39
41
  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
42
 
43
+ Patterns that act on human-authored, often underspecified input (`issue-triage`) also get an **intake** skill:
44
+
45
+ - `loop-intake` skill — when a work item is too vague to verify "done", it asks one question at a time, pushes for exact values, and writes an open question + `needs-human` escalation instead of guessing. Clarifying up front keeps the loop from burning fix attempts on a goal that was never well defined.
46
+
41
47
  Every scaffold also creates:
42
48
 
43
49
  - `loop-budget.md` — pattern-specific daily caps and kill switch
package/dist/cli.js CHANGED
@@ -30,6 +30,12 @@ const PATTERNS_NEEDING_FIX = new Set([
30
30
  'dependency-sweeper',
31
31
  'post-merge-cleanup',
32
32
  ]);
33
+ /**
34
+ * Patterns that act on human-authored, often underspecified input (issues).
35
+ * They get the loop-intake skill so the loop clarifies a vague item or escalates
36
+ * it instead of guessing and burning fix attempts.
37
+ */
38
+ const PATTERNS_NEEDING_INTAKE = new Set(['issue-triage']);
33
39
  const STATE_FILES = {
34
40
  'daily-triage': 'STATE.md',
35
41
  'pr-babysitter': 'pr-babysitter-state.md',
@@ -190,6 +196,15 @@ async function scaffoldCircuitBreaker(pattern, tool, targetDir, templatesRoot, d
190
196
  await writeFile(ledgerPath, seed);
191
197
  console.log(' created: loop-ledger.json (circuit breaker)');
192
198
  }
199
+ /**
200
+ * Scaffold the loop-intake skill for patterns that receive ambiguous human
201
+ * input, so the loop sharpens the goal (or escalates) before acting on it.
202
+ */
203
+ async function scaffoldIntake(pattern, tool, targetDir, templatesRoot, dryRun) {
204
+ if (!PATTERNS_NEEDING_INTAKE.has(pattern))
205
+ return;
206
+ await copyTemplateSkill(templatesRoot, 'SKILL.md.loop-intake', targetDir, tool, 'loop-intake', dryRun);
207
+ }
193
208
  function formatTokenCap(n) {
194
209
  if (n >= 1_000_000)
195
210
  return `${n / 1_000_000}M`;
@@ -492,6 +507,7 @@ Examples:
492
507
  await copyL2Templates(pattern, tool, targetDir, templatesRoot, dryRun);
493
508
  await scaffoldCircuitBreaker(pattern, tool, targetDir, templatesRoot, dryRun);
494
509
  await scaffoldObservability(pattern, tool, targetDir, templatesRoot, dryRun);
510
+ await scaffoldIntake(pattern, tool, targetDir, templatesRoot, dryRun);
495
511
  await scaffoldConstraints(targetDir, templatesRoot, tool, dryRun);
496
512
  if (tool !== 'opencode' && !dryRun && !(await exists(path.join(targetDir, 'AGENTS.md')))) {
497
513
  const agentsTemplate = `# AGENTS.md
@@ -529,6 +545,10 @@ npm run lint
529
545
  console.log('Circuit breaker wired (loop-guard skill + loop-ledger.json):');
530
546
  console.log(' npx @cobusgreyling/loop-context --check --ledger loop-ledger.json');
531
547
  }
548
+ if (PATTERNS_NEEDING_INTAKE.has(pattern)) {
549
+ console.log('');
550
+ console.log('Intake wired (loop-intake skill): clarify a vague item or escalate before acting.');
551
+ }
532
552
  console.log('');
533
553
  console.log(`First loop (${tool}):`);
534
554
  console.log(` ${firstLoopCommand(pattern, tool)}`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cobusgreyling/loop-init",
3
- "version": "1.3.3",
3
+ "version": "1.4.0",
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": {
@@ -38,30 +38,27 @@ After every iteration, append what you just tried:
38
38
  `outcome` is `success | failure | noop`. Always include `error` on failures —
39
39
  that is how the breaker detects a repeated (stagnant) failure.
40
40
 
41
- ## Size the token budget from the pattern (once per run)
41
+ ## Size the token budget from the pattern
42
42
 
43
- Don't hand-type a token cap — derive it from the pattern's realistic per-run
44
- cost so the breaker trips on genuine cost blowup, not a made-up number.
45
- [`loop-cost`](https://github.com/cobusgreyling/loop-engineering/tree/main/tools/loop-cost)
46
- already computes this from `patterns/registry.yaml`; read the loop's `pattern`
47
- and `level` straight from the ledger:
43
+ Don't hand-type a token cap — `loop-context` can derive it directly from the
44
+ pattern's realistic per-run cost
45
+ ([`loop-cost`](https://github.com/cobusgreyling/loop-engineering/tree/main/tools/loop-cost)
46
+ computes this from `patterns/registry.yaml`) so the breaker trips on genuine
47
+ cost blowup, not a made-up number. Substitute the ledger's own `pattern`/`level`
48
+ (here: `ci-sweeper` / `L2`):
48
49
 
49
50
  ```bash
50
- # Substitute the ledger's own pattern/level (here: ci-sweeper / L2).
51
- BUDGET=$(npx @cobusgreyling/loop-cost --pattern ci-sweeper --level L2 --json \
52
- | node -e 'let d="";process.stdin.on("data",c=>d+=c).on("end",()=>process.stdout.write(String(JSON.parse(d).scenarios.realistic.tokensPerRun)))')
51
+ npx @cobusgreyling/loop-context --check --ledger loop-ledger.json \
52
+ --budget-from-pattern ci-sweeper --budget-level L2
53
53
  ```
54
54
 
55
- `scenarios.realistic.tokensPerRun` is a rounded integer, so it feeds
56
- `--token-budget` directly. The two tools stay independent — this is shell
57
- wiring, not a code dependency.
58
-
59
55
  ## Before each iteration
60
56
 
61
57
  1. Append the previous attempt to `loop-ledger.json`.
62
58
  2. Run the breaker with the resolved budget:
63
59
  ```bash
64
- npx @cobusgreyling/loop-context --check --ledger loop-ledger.json --token-budget "$BUDGET"
60
+ npx @cobusgreyling/loop-context --check --ledger loop-ledger.json \
61
+ --budget-from-pattern ci-sweeper --budget-level L2
65
62
  ```
66
63
  3. Act on the exit code:
67
64
  - **0** → continue. Optionally trim the next prompt first:
@@ -83,12 +80,13 @@ wiring, not a code dependency.
83
80
  - Never widen thresholds just to keep looping — escalation is a feature, not a failure.
84
81
  - Never edit the ledger to hide a repeated error; the breaker exists to catch it.
85
82
  - Defaults: 3× same error, 5 consecutive failures, 10 iterations. Tune with
86
- `--stagnation`, `--no-progress`, `--max-iterations`, `--token-budget`.
83
+ `--stagnation`, `--no-progress`, `--max-iterations`, or an explicit
84
+ `--token-budget` (wins over `--budget-from-pattern` if both are given).
87
85
 
88
86
  ## Interaction with other skills
89
87
 
90
88
  - `minimal-fix` / `ci-triage` — record each attempt's outcome + error in the ledger.
91
89
  - `loop-verifier` — a verifier rejection is a `failure`; log it so repeats trip the breaker.
92
90
  - `loop-constraints` — honors "escalate after N attempts"; this skill makes it mechanical.
93
- - `loop-budget` — the per-run `--token-budget` here comes from loop-cost's
94
- realistic estimate; loop-budget.md still governs the *daily* cap across runs.
91
+ - `loop-budget` — the per-run budget here comes from `--budget-from-pattern`;
92
+ loop-budget.md still governs the *daily* cap across runs.
@@ -0,0 +1,71 @@
1
+ ---
2
+ name: loop-intake
3
+ description: >
4
+ Clarify an ambiguous goal or work item BEFORE the loop acts on it. Runs at the
5
+ front of a run when the assigned task is underspecified. Ask one question at a
6
+ time, push for exact values, and escalate instead of guessing.
7
+ user_invocable: true
8
+ ---
9
+
10
+ # Loop Intake - Clarify Before You Act
11
+
12
+ Autonomous loops waste attempts (and budget) when they guess at a vague goal.
13
+ This skill runs FIRST, before triage or any action skill, whenever the item the
14
+ loop is about to work on is not specific enough to verify "done".
15
+
16
+ ## When to run
17
+
18
+ Run intake when the goal or work item is missing any of:
19
+
20
+ - a single, testable definition of done
21
+ - the exact scope (which repo / branch / paths / tickets)
22
+ - concrete values a fix would depend on (error text, thresholds, versions)
23
+
24
+ If the goal is already specific and verifiable, skip intake and proceed.
25
+
26
+ ## How to clarify (one question at a time)
27
+
28
+ 1. Read the current state file and the item (issue, PR, request) in full. Do NOT
29
+ re-ask anything already answered there.
30
+ 2. Ask the SINGLE most decision-blocking question. Wait for the answer.
31
+ 3. Push for an exact value. "It should be fast" becomes "What p95 latency, in
32
+ ms?". "Add a limit" becomes "How many per minute?". Re-ask once if the answer
33
+ is still vague.
34
+ 4. Stop as soon as the goal is verifiable. Do not interrogate for its own sake.
35
+
36
+ Ask in behavior terms, not implementation: what the system must do, what the user
37
+ sees, which values matter. Not: which function, table, or endpoint.
38
+
39
+ ## When an answer stays vague
40
+
41
+ Do not guess. Record it and move on:
42
+
43
+ - Write the gap as an open question in the state file: `- [ ] OQ: <question>`.
44
+ - Mark the item `needs-human` (escalate per the loop's handoff rule).
45
+ - If NO blocking question can be resolved, escalate the whole item and stop.
46
+ Acting on a guess burns attempts the circuit breaker should not have to catch.
47
+
48
+ ## Output
49
+
50
+ Append a short, sharpened goal to the state file (or the item):
51
+
52
+ ```
53
+ Goal (clarified): <one testable sentence>
54
+ Done when: <verifiable condition>
55
+ Open questions: <N> (needs-human) - <list>
56
+ ```
57
+
58
+ Hand back to triage or the action skill only if "Done when" is now verifiable.
59
+
60
+ ## Interaction with other skills
61
+
62
+ - Runs BEFORE `loop-triage` / `issue-triage` and any action skill.
63
+ - Feeds `loop-verifier`: the "Done when" line becomes the verifier's check.
64
+ - Pairs with `loop-guard` (circuit breaker): intake prevents wasted attempts on a
65
+ goal that was never well defined; the breaker catches the ones that slip through.
66
+ - Respects `loop-constraints`: never ask for, or act on, denylisted scope.
67
+
68
+ ## Default behavior
69
+
70
+ Report-only in week one: propose the clarified goal and open questions, but let a
71
+ human confirm before the loop acts on the sharpened goal.