@terreno/agent-plugin-loop 0.0.0-stage → 58.0.0-beta.2

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.
@@ -0,0 +1,185 @@
1
+ ---
2
+ name: campaign
3
+ description: Drive a long-term codebase goal to its target — charter it, sweep and sift the repository into findings, plot PR-sized slices, run each slice through the Terreno lifecycle, then re-measure and repeat until the metric hits target or a genuine human decision is required. Not a scan stage — an outer loop that invokes the scan stages and the lifecycle. Use when asked to run a scan campaign, work toward a long-term engineering goal, or keep scanning and fixing until an outcome is reached.
4
+ ---
5
+
6
+ # Scan campaign (outer driver)
7
+
8
+ Not a stage. The five scan stages stay Aim, Sweep, Sift, Plot, Track. This skill walks
9
+ them round after round and hands each plotted slice to the Terreno lifecycle, until the
10
+ goal metric reaches its target or a genuine human decision is required.
11
+
12
+ For a session that stays resident — heartbeating over open PRs, answering review, and
13
+ refilling work as PRs merge — use `run` instead. This skill runs the rounds
14
+ and stops at each gate; the loop wraps it and keeps going.
15
+
16
+ Read the shared [`scan contract`](../../references/scan-contract.md),
17
+ [`agentic map-reduce`](../../references/mapreduce.md),
18
+ [`goal tracking`](../../references/goal-tracking.md), and
19
+ [`PR routing`](../../references/pr-routing.md). The campaign state must conform to
20
+ [`scan-state.schema.json`](../../references/scan-state.schema.json).
21
+
22
+ ## Scope
23
+
24
+ - Included: the five scan stages, campaign-state persistence, lifecycle handoff for each
25
+ plotted slice, bounded retries, and one accumulated report.
26
+ - Excluded: implementing findings, editing product code, committing, pushing, opening or
27
+ merging PRs. The lifecycle owns all of that.
28
+ - Requires the Terreno lifecycle plugin (`1-grow` … `5-taste`). If it is
29
+ not installed, stop at Plot and report the missing dependency.
30
+
31
+ ## Preconditions
32
+
33
+ - A goal, outcome, or existing charter is available with a repository.
34
+ - The campaign-state location is resolvable and can be preserved between invocations.
35
+
36
+ If a charter exists but is unapproved, stop at a human gate. Do not invent a goal, a
37
+ target, or a metric.
38
+
39
+ ## Round shape
40
+
41
+ ```text
42
+ Aim (once per goal)
43
+ → Sweep → Sift
44
+ → dry round → Track
45
+ → findings → Plot → handoff
46
+ → 1-grow (slice brief → approved IP + tasks)
47
+ → pick-roast-loop, or 2-pick once
48
+ → 4-brew → 5-taste
49
+ → Track
50
+ → plot (backlog remains)
51
+ → sweep (backlog empty, rounds remain)
52
+ → null (target reached, budget spent, regression, or diminishing returns)
53
+ ```
54
+
55
+ ## Drive
56
+
57
+ 1. **Reconstruct once.** Read the charter and campaign state. Verify goal, round, branch,
58
+ findings, and slice PR status against reality. Identify the stage named by
59
+ `next.stage`; default to Aim when no charter exists, otherwise Sweep.
60
+ 2. **Invoke the named scan stage** in a fresh context with the charter, campaign state,
61
+ the previous result, and this round's artifacts. Never ask the stage to rediscover the
62
+ campaign from conversation.
63
+ 3. **Consume the result.** Update campaign state, then classify:
64
+ - `PASS` with `next` set → invoke that stage next.
65
+ - `PASS` with `handoff: grow` → run the lifecycle for the top slice (below), then
66
+ invoke Track.
67
+ - `PASS` with `next: null` → finish and report.
68
+ - `FAIL` with a concrete action → reinvoke the named stage with the exact evidence and
69
+ a new hypothesis.
70
+ - `BLOCKED` with `kind: human` or `next.human: true` → present the human gate.
71
+ - `BLOCKED` for environment/access/external → attempt safe remediation or one bounded
72
+ retry when a new hypothesis exists. Never relabel it `human` merely to stop.
73
+ - `PENDING` → wait per `wait`, preferring the harness's native completion hook or the
74
+ provider's watch hook; use a timer only when no hook applies. Then reinvoke.
75
+ 4. **Run the handed-off slice.** For the slice Plot names:
76
+ - Invoke `1-grow` with the slice brief. Grow owns the IP, the task list, and
77
+ human approval.
78
+ - On Grow `PASS`, invoke `pick-roast-loop` when it is installed, otherwise
79
+ `2-pick` once — Pick owns the pick → roast → next-task inner loop.
80
+ - On completion, invoke `4-brew`, then `5-taste`, honoring their
81
+ `PENDING` waits exactly as the lifecycle's own loops do.
82
+ - As soon as Brew reports the PR, apply the charter's routing per `pr-routing.md` and
83
+ record the reviewer and assignee. An unrouted PR is not a finished handoff.
84
+ - Record the slice's branch, PR, reviewer, and outcome in campaign state. A slice the lifecycle
85
+ blocks is recorded and skipped; the campaign continues with the next slice rather
86
+ than stalling the goal, unless the blocker applies to every slice.
87
+ 5. **Bound retries by evidence.** A retry must add a new hypothesis, changed setup, or
88
+ new evidence. Never repeat a failed approach. After two focused failures of the same
89
+ stage with no new hypothesis, classify the underlying decision honestly instead of
90
+ looping.
91
+ 6. **Continue quietly.** Repeat steps 2–5 without narrating each cycle. Keep details in
92
+ campaign state and report once at completion or at a human gate.
93
+
94
+ ## Budget and safety
95
+
96
+ - Honor the charter's budget: rounds, slices per round, and open PRs at once (`wipLimit`).
97
+ - Never exceed the open-PR limit; wait on Track instead of stacking review load.
98
+ - Stop and report when the horizon passes, even mid-backlog.
99
+ - Never run a campaign that edits code the charter marked out of scope.
100
+
101
+ ## Recurring campaigns
102
+
103
+ A campaign is resumable by design: every invocation reconstructs from the charter and
104
+ campaign state. To run it on a cadence, schedule this skill with the goal slug and let it
105
+ pick up the next move — a fresh sweep, the next slice, or a report. Repeated invocations
106
+ must not restart Aim or re-baseline a goal that already has one.
107
+
108
+ ## Genuine human gate
109
+
110
+ Ask for input only for:
111
+
112
+ - the goal statement, metric, or target itself
113
+ - destructive or irreversible remediation
114
+ - public API, data-format, or compatibility changes a finding requires
115
+ - scope growth beyond the approved charter
116
+ - a metric regression or two rounds below the charter's minimum step
117
+ - credentials or permissions no authorized alternative can supply
118
+ - a reviewer handle that cannot be verified or requested
119
+
120
+ Before the question, give this overview in plain language:
121
+
122
+ 1. **Goal and trajectory:** statement, metric, baseline → previous → current vs target.
123
+ 2. **What happened:** rounds run, findings found/fixed/reopened, slices merged, decisive
124
+ evidence.
125
+ 3. **Why input is needed:** the exact decision and why evidence cannot choose it.
126
+ 4. **Options:** two to four concrete choices with impact and risk.
127
+ 5. **Recommendation:** one default and its rationale.
128
+
129
+ End with **one exact question** the human can answer in one message. Then close with PR
130
+ deployment URLs when a slice's PR has them. Do not expose chain-of-thought, worker
131
+ transcripts, or unexplained stage YAML.
132
+
133
+ ## Completion report
134
+
135
+ When the target is reached, lead with:
136
+
137
+ `PASS — <metric> <baseline> → <current> <unit> (target <target>) across <n> rounds.`
138
+
139
+ Then report:
140
+
141
+ - `Trajectory`: metric per round with the command output for the final measurement
142
+ - `Fixed`: findings closed with evidence, grouped by slice and PR
143
+ - `Open`: findings still open or deferred, with the reason
144
+ - `Dismissed`: dropped findings and why
145
+ - `Regressions`: anything that moved the wrong way, or `None identified`
146
+ - `Residual risk`: explicit remaining risk, or `None identified`
147
+ - `Next`: the recommended follow-up, such as a cadence for re-sweeping
148
+
149
+ When stopped early, use the same report plus `Blocker`. Include everything from the round
150
+ records once; do not duplicate per-round narration.
151
+
152
+ ## Stop conditions
153
+
154
+ - `PASS`: the metric reached target and held after the last slice landed.
155
+ - `PASS` with a question: budget or horizon exhausted, or diminishing returns.
156
+ - `BLOCKED` (human): a genuine human gate above.
157
+ - `BLOCKED` (non-human): retries exhausted and no safe autonomous action exists.
158
+ - `FAIL`: campaign state is inconsistent or corrupt, or the named stage cannot be invoked.
159
+
160
+ Ordinary rule failures, empty shards, dry rounds, and lifecycle test failures are not
161
+ terminal while a concrete action remains.
162
+
163
+ ## Emit
164
+
165
+ After the human-facing report, include one collapsed scan-result payload. Since outer
166
+ loops are not stages, set `stage` to the last scan stage invoked.
167
+
168
+ ```yaml
169
+ v: 2
170
+ stage: track
171
+ status: PASS
172
+ goal: reduce-cold-build-time
173
+ round: 3
174
+ metric:
175
+ value: 28.4
176
+ unit: s
177
+ delta: -30.2
178
+ ev: "bun run compile (cold, best of 3): 28.4s"
179
+ next: null
180
+ action: Target reached; re-sweep quarterly to hold the gain
181
+ ```
182
+
183
+ For a human gate, use `status: BLOCKED`, `next: null`, and an `ask` entry with the exact
184
+ question, recommendation, and options. For a non-human terminal blocker, use a `block`
185
+ entry with `kind: environment`, `access`, or `external`, and omit `ask`.
@@ -0,0 +1,165 @@
1
+ ---
2
+ name: run
3
+ description: Run a scan campaign as a resident session — keep working toward the goal, open PR-sized slices routed to named reviewers, and heartbeat over every open PR to answer review comments, fix failing CI, and land merges, until the metric hits target or a human decision is required. Use when asked to keep a goal running continuously, leave a scan going in the background, watch and respond to campaign PRs, or run the scan loop; not for a single bounded round.
4
+ ---
5
+
6
+ # Scan loop (resident driver)
7
+
8
+ One session, running until the goal is met. It alternates between **making progress** —
9
+ sweep, sift, plot, hand a slice to the lifecycle, open a routed PR — and **servicing what
10
+ is already open** — answering human review, fixing red CI, tracking merges. Work happens
11
+ in fresh subagents; this session holds only the goal, the state, and the schedule.
12
+
13
+ Read [`scan contract`](../../references/scan-contract.md),
14
+ [`heartbeat`](../../references/heartbeat.md),
15
+ [`PR routing`](../../references/pr-routing.md),
16
+ [`goal tracking`](../../references/goal-tracking.md), and
17
+ [`agentic map-reduce`](../../references/mapreduce.md). Campaign state conforms to
18
+ [`scan-state.schema.json`](../../references/scan-state.schema.json).
19
+
20
+ ## Scope
21
+
22
+ - Included: the five scan stages, PR routing, the heartbeat over open campaign PRs,
23
+ lifecycle invocation per slice, state persistence, scheduling, and one report per
24
+ human gate or completion.
25
+ - Excluded: writing product code, committing, pushing, approving, and merging. Every one
26
+ of those belongs to a lifecycle stage invoked in a fresh subagent — Pick implements,
27
+ Brew submits, Taste reacts.
28
+ - Requires the lifecycle plugin (`1-grow` … `5-taste`) and a host CLI
29
+ with PR access (`gh`). Missing either is `BLOCKED`, not a workaround.
30
+
31
+ ## Arguments
32
+
33
+ Parse from the invocation, in this order: an explicit `goal=<slug>`, a quoted goal
34
+ statement, or the remaining text. Also accept:
35
+
36
+ | Argument | Meaning |
37
+ | --- | --- |
38
+ | `reviewer=<handle[,handle]>` | Override the charter's reviewers for this run |
39
+ | `assignee=<handle>` | Override the charter's assignee |
40
+ | `wip=<n>` | Override the charter's open-PR limit for this run |
41
+ | `rounds=<n>` | Stop after this many sweep rounds |
42
+ | `until=<ISO timestamp>` | Stop at this time regardless of progress |
43
+ | `tick=<seconds>` | Fixed heartbeat interval instead of the adaptive one |
44
+
45
+ An override applies to this run only and is recorded in state as an override, never
46
+ written back into the charter.
47
+
48
+ If no campaign exists for the goal, run Aim first and block for approval — a resident
49
+ loop does not invent a metric, a target, or a reviewer.
50
+
51
+ ## Start
52
+
53
+ 1. **Resolve the campaign.** Read the charter and campaign state for the goal. Verify the
54
+ branch, round, findings, and every recorded PR against the host. If nothing exists,
55
+ invoke `1-aim` and stop at its approval gate.
56
+ 2. **Resolve routing.** Confirm the charter's `review` block names a reachable reviewer or
57
+ an explicit `mode: none`. Verify unfamiliar handles per `pr-routing.md`. An unroutable
58
+ campaign stops here with one question, before any PR exists.
59
+ 3. **Announce once.** One short line: goal, metric baseline → current vs target, open PRs
60
+ and who has them, what this run will do first, and the heartbeat interval. This is the
61
+ only unprompted status message until something needs a human.
62
+
63
+ ## Run
64
+
65
+ Repeat until a stop condition:
66
+
67
+ 1. **Heartbeat tick.** Follow `heartbeat.md`: snapshot the campaign's PRs, classify each,
68
+ and act in priority order — route unrouted PRs, hand answered and broken PRs to Taste
69
+ in fresh subagents, Track merged ones, retire closed ones. Answer any given comment
70
+ exactly once.
71
+ 2. **Refill capacity.** When open campaign PRs are below the effective `wipLimit` and the
72
+ backlog has planned findings, advance the campaign one step:
73
+ - planned findings remain → `4-plot` for the next slice
74
+ - backlog empty, rounds remain → `2-sweep`, then `3-sift`
75
+ - a slice is ready to build → `1-grow` with its brief, then
76
+ `pick-roast-loop` (or `2-pick` once), then `4-brew`
77
+ - Brew reported a PR → apply routing immediately, then count the slice in flight
78
+ 3. **Persist.** Update campaign state after every stage and every tick: stage, round,
79
+ slices with PR/reviewer/assignee/bucket, answered comment ids, `lastTick`, and the
80
+ chosen next interval.
81
+ 4. **Schedule.** Pick the next interval from the heartbeat table — provider watch hook
82
+ while CI runs, minutes while bots report, tens of minutes while a human holds the PR,
83
+ no wait at all while backlog work remains. Prefer the harness's native scheduling or
84
+ completion hooks; use a timer only when no hook applies.
85
+ 5. **Stay quiet.** A tick with nothing to report prints nothing. Do not narrate ticks, do
86
+ not repeat the plan, and do not post PR comments to show activity.
87
+
88
+ ## Concurrency
89
+
90
+ - Never exceed the effective `wipLimit` of open campaign PRs.
91
+ - Never run two lifecycle stages against the same slice at once.
92
+ - Never start a new slice while a slice for the same files is open — the second PR will
93
+ conflict and waste the reviewer's time.
94
+ - One branch per slice, named from the slice slug. Never reuse a branch a human is
95
+ reviewing.
96
+
97
+ ## Speak only when it matters
98
+
99
+ Interrupt the human for:
100
+
101
+ - a genuine gate from `scan-contract.md`: goal or target changes, destructive remediation,
102
+ public API or data-format changes, scope growth, metric regression, exhausted budget
103
+ - an unroutable or unverifiable reviewer handle
104
+ - a PR a human has held with requested changes the campaign cannot satisfy without a
105
+ decision
106
+ - three consecutive host failures, lost credentials, or a lifecycle stage blocked on
107
+ something only a person can supply
108
+
109
+ Every interruption carries goal and trajectory, what happened, why input is needed,
110
+ two to four options with impact, a recommendation, then **one exact question**, then PR
111
+ deployment URLs when a campaign PR has them.
112
+
113
+ ## Stop conditions
114
+
115
+ - Metric reached target and held after the last slice merged → complete.
116
+ - `rounds=` or `until=` reached, or the charter's horizon passed → report and ask.
117
+ - Two rounds below the charter's minimum step, or a regression → report and ask.
118
+ - A genuine human gate → `BLOCKED`, with the question above.
119
+ - Three consecutive host failures → `BLOCKED` with `kind: access`.
120
+ - The human says stop → stop immediately, leave every PR routed and state consistent, and
121
+ report what is in flight and who holds it.
122
+
123
+ A resident loop never stops quietly. Every stop names what is open, who has it, and what
124
+ the next action would be.
125
+
126
+ ## Report
127
+
128
+ On completion or at a gate, lead with the trajectory:
129
+
130
+ `<metric> <baseline> → <current> <unit> (target <target>), <merged> slices merged, <open> open.`
131
+
132
+ Then: `In flight` (PR, reviewer, bucket, age), `Merged this run`, `Fixed` findings with
133
+ evidence, `Open` and `Dismissed` findings, `Regressions` or `None identified`,
134
+ `Residual risk`, and `Next`.
135
+
136
+ ## Emit
137
+
138
+ After the human-facing report, one collapsed scan-result payload. The loop is not a
139
+ stage, so set `stage` to the last scan stage invoked.
140
+
141
+ ```yaml
142
+ v: 2
143
+ stage: track
144
+ status: PENDING
145
+ goal: reduce-cold-build-time
146
+ round: 2
147
+ metric:
148
+ value: 41.7
149
+ unit: s
150
+ delta: -16.9
151
+ ev: "bun run compile (cold, best of 3): 41.7s"
152
+ prs:
153
+ - pr: "1421"
154
+ bucket: waiting
155
+ who: octocat
156
+ - pr: "1424"
157
+ bucket: answered
158
+ who: octocat
159
+ wait: 900
160
+ next: track
161
+ action: Taste is addressing review on #1424; recheck both PRs in 15 minutes
162
+ ```
163
+
164
+ Use `status: PENDING` with a `wait` while PRs are open and progress continues,
165
+ `status: PASS` when the goal is met, and `status: BLOCKED` with one `ask` at a human gate.