loreli 0.0.0 → 2.0.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/LICENSE +1 -1
- package/README.md +710 -97
- package/bin/loreli.js +89 -0
- package/package.json +77 -14
- package/packages/README.md +101 -0
- package/packages/action/README.md +98 -0
- package/packages/action/prompts/action.md +172 -0
- package/packages/action/src/index.js +684 -0
- package/packages/agent/README.md +606 -0
- package/packages/agent/src/backends/claude.js +387 -0
- package/packages/agent/src/backends/codex.js +351 -0
- package/packages/agent/src/backends/cursor.js +371 -0
- package/packages/agent/src/backends/index.js +486 -0
- package/packages/agent/src/base.js +138 -0
- package/packages/agent/src/cli.js +275 -0
- package/packages/agent/src/discover.js +396 -0
- package/packages/agent/src/factory.js +124 -0
- package/packages/agent/src/index.js +12 -0
- package/packages/agent/src/models.js +159 -0
- package/packages/agent/src/output.js +62 -0
- package/packages/agent/src/session.js +162 -0
- package/packages/agent/src/trace.js +186 -0
- package/packages/classify/README.md +136 -0
- package/packages/classify/prompts/blocker.md +12 -0
- package/packages/classify/prompts/feedback.md +14 -0
- package/packages/classify/prompts/pane-state.md +20 -0
- package/packages/classify/src/index.js +81 -0
- package/packages/config/README.md +898 -0
- package/packages/config/src/defaults.js +145 -0
- package/packages/config/src/index.js +223 -0
- package/packages/config/src/schema.js +291 -0
- package/packages/config/src/validate.js +160 -0
- package/packages/context/README.md +165 -0
- package/packages/context/src/index.js +198 -0
- package/packages/hub/README.md +338 -0
- package/packages/hub/src/base.js +154 -0
- package/packages/hub/src/github.js +1597 -0
- package/packages/hub/src/index.js +79 -0
- package/packages/hub/src/labels.js +48 -0
- package/packages/identity/README.md +288 -0
- package/packages/identity/src/index.js +620 -0
- package/packages/identity/src/themes/avatar.js +217 -0
- package/packages/identity/src/themes/digimon.js +217 -0
- package/packages/identity/src/themes/dragonball.js +217 -0
- package/packages/identity/src/themes/lotr.js +217 -0
- package/packages/identity/src/themes/marvel.js +217 -0
- package/packages/identity/src/themes/pokemon.js +217 -0
- package/packages/identity/src/themes/starwars.js +217 -0
- package/packages/identity/src/themes/transformers.js +217 -0
- package/packages/identity/src/themes/zelda.js +217 -0
- package/packages/knowledge/README.md +217 -0
- package/packages/knowledge/src/index.js +243 -0
- package/packages/log/README.md +93 -0
- package/packages/log/src/index.js +252 -0
- package/packages/marker/README.md +200 -0
- package/packages/marker/src/index.js +184 -0
- package/packages/mcp/README.md +323 -0
- package/packages/mcp/instructions.md +126 -0
- package/packages/mcp/scaffolding/.agents/skills/loreli-context/SKILL.md +89 -0
- package/packages/mcp/scaffolding/ISSUE_TEMPLATE/config.yml +2 -0
- package/packages/mcp/scaffolding/ISSUE_TEMPLATE/loreli.yml +83 -0
- package/packages/mcp/scaffolding/loreli.yml +491 -0
- package/packages/mcp/scaffolding/mcp-configs/.codex/config.toml +4 -0
- package/packages/mcp/scaffolding/mcp-configs/.cursor/mcp.json +14 -0
- package/packages/mcp/scaffolding/mcp-configs/.mcp.json +14 -0
- package/packages/mcp/scaffolding/pull-request.md +23 -0
- package/packages/mcp/src/index.js +600 -0
- package/packages/mcp/src/tools/agent-context.js +44 -0
- package/packages/mcp/src/tools/agents.js +450 -0
- package/packages/mcp/src/tools/context.js +200 -0
- package/packages/mcp/src/tools/github.js +1163 -0
- package/packages/mcp/src/tools/hitl.js +162 -0
- package/packages/mcp/src/tools/index.js +18 -0
- package/packages/mcp/src/tools/refactor.js +227 -0
- package/packages/mcp/src/tools/repo.js +44 -0
- package/packages/mcp/src/tools/start.js +904 -0
- package/packages/mcp/src/tools/status.js +149 -0
- package/packages/mcp/src/tools/work.js +134 -0
- package/packages/orchestrator/README.md +192 -0
- package/packages/orchestrator/src/index.js +1492 -0
- package/packages/planner/README.md +251 -0
- package/packages/planner/prompts/plan-reviewer.md +109 -0
- package/packages/planner/prompts/planner.md +191 -0
- package/packages/planner/prompts/tiebreaker-reviewer.md +71 -0
- package/packages/planner/src/index.js +1381 -0
- package/packages/review/README.md +129 -0
- package/packages/review/prompts/reviewer.md +158 -0
- package/packages/review/src/index.js +1403 -0
- package/packages/risk/README.md +178 -0
- package/packages/risk/prompts/risk.md +272 -0
- package/packages/risk/src/index.js +439 -0
- package/packages/session/README.md +165 -0
- package/packages/session/src/index.js +215 -0
- package/packages/test-utils/README.md +96 -0
- package/packages/test-utils/src/index.js +354 -0
- package/packages/tmux/README.md +261 -0
- package/packages/tmux/src/index.js +501 -0
- package/packages/workflow/README.md +317 -0
- package/packages/workflow/prompts/preamble.md +14 -0
- package/packages/workflow/src/index.js +660 -0
- package/packages/workflow/src/proof-of-life.js +74 -0
- package/packages/workspace/README.md +143 -0
- package/packages/workspace/src/index.js +1127 -0
- package/index.js +0 -8
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
# loreli/planner
|
|
2
|
+
|
|
3
|
+
Planning workflow for Loreli's orchestration pipeline. Extends the `Workflow` base class to manage planner agents — dispatching objectives, adversarial plan review via yin/yang pairing, and promoting approved discussions to issues.
|
|
4
|
+
|
|
5
|
+
## Research Findings
|
|
6
|
+
|
|
7
|
+
No existing npm packages cover planning workflow with cross-provider adversarial review. This is domain-specific to Loreli's yin/yang agent model.
|
|
8
|
+
|
|
9
|
+
## Plan Mode
|
|
10
|
+
|
|
11
|
+
Planner agents spawn in the CLI's native plan mode — a read-only permission mode that prevents file writes and command execution. This is not a configuration toggle; it is how planners work. The planner's job is to read the codebase and create plan discussions via MCP tools. Plan mode enforces that at the CLI level.
|
|
12
|
+
|
|
13
|
+
Each backend maps to its native plan mode flag:
|
|
14
|
+
|
|
15
|
+
| Backend | Flag | Effect |
|
|
16
|
+
|---------|------|--------|
|
|
17
|
+
| Claude Code | `--permission-mode plan` | Read-only — Claude can analyze but not modify files or execute commands |
|
|
18
|
+
| OpenAI Codex | `-s read-only` | Sandbox restricts to read-only filesystem access |
|
|
19
|
+
| Cursor Agent | `--plan` | Plan mode — analysis and reading only |
|
|
20
|
+
|
|
21
|
+
MCP tools (`plan`, `comment`, `context`) are unaffected by plan mode on all three backends. They communicate over stdio, which is independent of the built-in tool permission layer. The planner's ability to create discussions and post comments works normally.
|
|
22
|
+
|
|
23
|
+
The `mode` parameter is derived from the agent's role in the backend constructor — when `opts.role === 'planner'`, the mode is `'plan'`. Action agents and reviewers continue to spawn in their default coding modes.
|
|
24
|
+
|
|
25
|
+
## Architecture
|
|
26
|
+
|
|
27
|
+
The planner uses **GitHub Discussions** as its planning primitive. Discussions in a "Loreli" category serve as the workspace where plans are proposed, reviewed, revised, and eventually promoted to real issues.
|
|
28
|
+
|
|
29
|
+
Labels act as a state machine on each discussion:
|
|
30
|
+
|
|
31
|
+
| State | Labels Present | Next Action |
|
|
32
|
+
|-------|---------------|-------------|
|
|
33
|
+
| Needs review | _(none)_ | Reviewer dispatched |
|
|
34
|
+
| Changes requested | `loreli:changes-requested` | Planner revises |
|
|
35
|
+
| Blocked | `loreli:blocked` + `loreli:changes-requested` | Parked until dependency resolves |
|
|
36
|
+
| Approved | `loreli:approved` | Promoted to issue |
|
|
37
|
+
|
|
38
|
+
The reactor tick pipeline runs handlers in order: **planner-hydrate → planner-recover → unblock → revise → review → promote → link → planner-reap**. `unblock` runs before review so freshly unblocked discussions can enter review on the same tick.
|
|
39
|
+
|
|
40
|
+
```mermaid
|
|
41
|
+
flowchart LR
|
|
42
|
+
H["planner-hydrate"] --> R["planner-recover"]
|
|
43
|
+
R --> U["unblock"]
|
|
44
|
+
U --> V["revise"]
|
|
45
|
+
V --> W["review"]
|
|
46
|
+
W --> P["promote"]
|
|
47
|
+
P --> L["link"]
|
|
48
|
+
L --> X["planner-reap"]
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
After promotion, each created issue is stamped with a machine-readable `loreli:plan` marker carrying the planning objective and source discussion number. The `link` handler uses that marker to scope parent-child relationships by objective so unrelated child issues are not grouped under the same parent issue.
|
|
52
|
+
|
|
53
|
+
### Blocker Detection
|
|
54
|
+
|
|
55
|
+
When `revise()` processes a `changes-requested` discussion, it scans comments for `#N` issue references and uses keyword-based heuristics (via `knowledge.classifyRefs()`) to distinguish dependency blockers from informational references. No LLM dependency.
|
|
56
|
+
|
|
57
|
+
- **Blockers** (e.g., "depends on #5 being merged") — verified against `hub.issue()`. If open, the discussion is parked with `loreli:blocked`.
|
|
58
|
+
- **Informational** (e.g., "see #3 for prior art") — ignored, normal revision continues.
|
|
59
|
+
|
|
60
|
+
The `unblock()` handler checks blocked discussions every tick. When all blockers resolve, it removes both labels so the discussion re-enters review fresh.
|
|
61
|
+
|
|
62
|
+
### Tiebreaker Protocol
|
|
63
|
+
|
|
64
|
+
When a discussion has no external blockers but cycles through `changes-requested` indefinitely, `_revisionRounds` tracks how many times `revise()` has processed it. Behavior varies by round count vs `watch.maxRounds` (default 3):
|
|
65
|
+
|
|
66
|
+
| Condition | Behavior |
|
|
67
|
+
|-----------|----------|
|
|
68
|
+
| `rounds < maxRounds` | Normal revision dispatch |
|
|
69
|
+
| `rounds === maxRounds` | Tiebreaker revision — planner gets a focused prompt to fundamentally restructure the plan |
|
|
70
|
+
| `rounds > maxRounds` | HITL escalation — `loreli:needs-attention` applied and human reviewers notified |
|
|
71
|
+
|
|
72
|
+
The reviewer prompt also changes based on rounds: normal reviews use `plan-reviewer.md`, tiebreaker reviews use `tiebreaker-reviewer.md` with pragmatic evaluation guidance.
|
|
73
|
+
|
|
74
|
+
### Dedicated Reviewer Prompts
|
|
75
|
+
|
|
76
|
+
Plan review uses two dedicated prompts (separate from the PR-review `reviewer.md`):
|
|
77
|
+
|
|
78
|
+
| Template | Location | Purpose |
|
|
79
|
+
|----------|----------|---------|
|
|
80
|
+
| `plan-reviewer.md` | `prompts/` | Standard plan review — scope, clarity, feasibility |
|
|
81
|
+
| `tiebreaker-reviewer.md` | `prompts/` | Pragmatic tiebreaker review — approve if directionally correct |
|
|
82
|
+
|
|
83
|
+
## API Reference
|
|
84
|
+
|
|
85
|
+
### `PlannerWorkflow` (extends Workflow)
|
|
86
|
+
|
|
87
|
+
```js
|
|
88
|
+
import { PlannerWorkflow } from 'loreli/planner';
|
|
89
|
+
|
|
90
|
+
const planner = new PlannerWorkflow(orchestrator, hub);
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
The constructor accepts the orchestrator (EventEmitter) and hub (GitHub API).
|
|
94
|
+
|
|
95
|
+
#### Static Properties
|
|
96
|
+
|
|
97
|
+
| Property | Value | Description |
|
|
98
|
+
|----------|-------|-------------|
|
|
99
|
+
| `role` | `'planner'` | Agent role this workflow manages |
|
|
100
|
+
| `template` | `prompts/planner.md` | Mustache template for planner prompts |
|
|
101
|
+
|
|
102
|
+
### Methods
|
|
103
|
+
|
|
104
|
+
#### `planner.plan(repo, objective)` → Promise\<{planners, categoryId}\>
|
|
105
|
+
|
|
106
|
+
Dispatch the planning objective to all available planner agents. Finds the "Loreli" discussion category, renders the planner prompt with the objective, and sends to each agent.
|
|
107
|
+
|
|
108
|
+
The example below shows how `start_planning` triggers the planning workflow. The orchestrator coordinates agent lifecycle, while the planner package owns the planning logic:
|
|
109
|
+
|
|
110
|
+
```js
|
|
111
|
+
const result = await planner.plan('owner/repo', 'Build auth module');
|
|
112
|
+
// { planners: ['optimus-0'], categoryId: 'DIC_kwDO...' }
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
#### `planner.unblock(repo)` → Promise\<void\>
|
|
116
|
+
|
|
117
|
+
Check blocked discussions for resolved dependencies. For each discussion in the `_blocked` map, verifies whether all blocking issues/PRs have been closed. When resolved, removes `loreli:blocked` and `loreli:changes-requested` labels so the discussion re-enters review.
|
|
118
|
+
|
|
119
|
+
Runs FIRST in the tick pipeline.
|
|
120
|
+
|
|
121
|
+
#### `planner.revise(repo)` → Promise\<Array\<{number, planner}\>\>
|
|
122
|
+
|
|
123
|
+
Handle discussions with `loreli:changes-requested` label (excluding blocked discussions). For each discussion:
|
|
124
|
+
|
|
125
|
+
1. Scans comments for issue references and classifies them using keyword heuristics (`extractRefs` + `classifyRefs`)
|
|
126
|
+
2. Parks blocked discussions (applies `loreli:blocked`, stores in `_blocked` map)
|
|
127
|
+
3. Increments `_revisionRounds` for non-blocked discussions
|
|
128
|
+
4. At `maxRounds`: dispatches tiebreaker revision with special prompt
|
|
129
|
+
5. Beyond `maxRounds`: HITL escalation — applies `loreli:needs-attention` and notifies human reviewers
|
|
130
|
+
6. Below `maxRounds`: dispatches normal revision
|
|
131
|
+
|
|
132
|
+
Runs SECOND in the tick pipeline. Returns an empty array if no discussions need revision.
|
|
133
|
+
|
|
134
|
+
#### `planner.review(repo)` → Promise\<{reviewer, discussions}\>
|
|
135
|
+
|
|
136
|
+
Dispatch unlabeled discussions (no `loreli:approved`, `loreli:changes-requested`, or `loreli:blocked`) to a reviewer. In dual-side mode it prefers yin/yang pairing; in single-side mode it falls back to same-side reviewer enlistment. Selects the reviewer template based on revision round count: `plan-reviewer.md` for normal reviews, `tiebreaker-reviewer.md` when `_revisionRounds >= maxRounds`.
|
|
137
|
+
|
|
138
|
+
Returns `{ reviewer: null, discussions: 0 }` when no reviewer can be determined.
|
|
139
|
+
|
|
140
|
+
#### `planner.promote(repo)` → Promise\<Array\<{number, title}\>\>
|
|
141
|
+
|
|
142
|
+
Convert approved discussions (with `loreli:approved` label) to real GitHub issues. Posts a closing comment linking to the new issue, then closes and locks the discussion. The promoted issue body includes a `loreli:plan` marker with objective metadata for downstream linking.
|
|
143
|
+
|
|
144
|
+
#### `planner.escalate(repo, title, body, fallbackIdentity?)` → Promise\<{discussionId, categoryId}\>
|
|
145
|
+
|
|
146
|
+
Signal a concern or feature idea by creating a discussion in the Loreli category. The discussion enters the standard review → revise → approve → promote pipeline.
|
|
147
|
+
|
|
148
|
+
### Reactor Handlers
|
|
149
|
+
|
|
150
|
+
The planner registers eight handlers with the orchestrator's reactor:
|
|
151
|
+
|
|
152
|
+
```js
|
|
153
|
+
planner.reactor()
|
|
154
|
+
// → {
|
|
155
|
+
// 'planner-hydrate': fn,
|
|
156
|
+
// 'planner-recover': fn,
|
|
157
|
+
// unblock: fn,
|
|
158
|
+
// revise: fn,
|
|
159
|
+
// review: fn,
|
|
160
|
+
// promote: fn,
|
|
161
|
+
// link: fn,
|
|
162
|
+
// 'planner-reap': fn
|
|
163
|
+
// }
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
### Events
|
|
167
|
+
|
|
168
|
+
The planner subscribes to no orchestrator events currently. All coordination happens through explicit method calls from the MCP tools layer.
|
|
169
|
+
|
|
170
|
+
## Errors
|
|
171
|
+
|
|
172
|
+
| Error | When | Resolution |
|
|
173
|
+
|-------|------|------------|
|
|
174
|
+
| `No planner agents available` | plan() called with no planner agents | Add a planner agent first |
|
|
175
|
+
| `Discussion category "Loreli" not found` | plan() called without the Loreli category | Enable GitHub Discussions and create the category in repo settings |
|
|
176
|
+
| `Cannot escalate without an identity` | escalate() called without agents or fallback identity | Add at least one agent before escalating |
|
|
177
|
+
|
|
178
|
+
## Research-Informed Discussion Format
|
|
179
|
+
|
|
180
|
+
The planner prompt includes a **Research** phase that runs before decomposition. The planner explores the repository to ground every discussion in concrete code references. This produces actionable plans that give action agents precise, file-level implementation guidance.
|
|
181
|
+
|
|
182
|
+
The research phase instructs the planner to:
|
|
183
|
+
|
|
184
|
+
1. Read `AGENTS.md` and README files for project conventions
|
|
185
|
+
2. Find specific files that need changes for each unit of work
|
|
186
|
+
3. Trace imports and dependencies to understand blast radius
|
|
187
|
+
4. Locate test directories and identify existing test patterns
|
|
188
|
+
5. Look for similar features or patterns as templates for new work
|
|
189
|
+
|
|
190
|
+
Each discussion body includes these research-derived sections:
|
|
191
|
+
|
|
192
|
+
| Section | Purpose |
|
|
193
|
+
|---------|---------|
|
|
194
|
+
| **Affected Files** | Specific file paths that need changes, with a one-line explanation per file |
|
|
195
|
+
| **Existing Patterns** | Code patterns, helpers, or similar implementations the action agent should follow |
|
|
196
|
+
| **Acceptance Criteria** | Specific, testable conditions that define "done" |
|
|
197
|
+
| **Testing Strategy** | Concrete tests to write first (TDD), with file paths and existing test patterns |
|
|
198
|
+
| **Scope Boundaries** | What is explicitly NOT included |
|
|
199
|
+
| **Dependencies** | Other discussions or issues this depends on |
|
|
200
|
+
| **Estimated Complexity** | Low / Medium / High with justification |
|
|
201
|
+
|
|
202
|
+
<details>
|
|
203
|
+
<summary>Example: Research-informed discussion</summary>
|
|
204
|
+
|
|
205
|
+
```markdown
|
|
206
|
+
**Title**: Add retry logic to GitHub API client
|
|
207
|
+
|
|
208
|
+
**Objective**: Add exponential backoff retry logic to the GitHub API client for transient failures.
|
|
209
|
+
|
|
210
|
+
**Affected Files**:
|
|
211
|
+
- `packages/hub/src/client.js` — wraps Octokit; retry logic wraps the existing `request()` method
|
|
212
|
+
- `packages/hub/test/index.test.js` — existing test file; add retry test block
|
|
213
|
+
- `packages/config/src/defaults.js` — add `hub.retry` config (maxRetries, baseDelay)
|
|
214
|
+
|
|
215
|
+
**Existing Patterns**:
|
|
216
|
+
- `packages/hub/src/client.js#request()` is the central fetch method — all API calls route through it
|
|
217
|
+
- Tests in `packages/hub/test/` use `node:test` with `describe/it`, fixtures in `test/fixtures/`
|
|
218
|
+
- Config pattern: add key to `defaults.js`, validate in `schema.js`, document in `config/README.md`
|
|
219
|
+
|
|
220
|
+
**Acceptance Criteria**:
|
|
221
|
+
- Retries on 429 and 5xx, up to 3 attempts
|
|
222
|
+
- Exponential backoff: 1s, 2s, 4s with jitter
|
|
223
|
+
- Non-retryable errors (4xx except 429) propagate immediately
|
|
224
|
+
- Retry attempts logged with attempt number and delay
|
|
225
|
+
|
|
226
|
+
**Testing Strategy** (TDD):
|
|
227
|
+
- Add tests in `packages/hub/test/index.test.js` in a new `describe('#retry')` block
|
|
228
|
+
- Test 429 triggers retry with correct backoff
|
|
229
|
+
- Test 500/502/503 trigger retry
|
|
230
|
+
- Test 400/401/404 propagate without retry
|
|
231
|
+
- Test max retries respected
|
|
232
|
+
- Use the same direct-integration style as existing hub tests (no mocks)
|
|
233
|
+
|
|
234
|
+
**Scope Boundaries**: No circuit breaker, no request queuing, no rate limit header parsing.
|
|
235
|
+
|
|
236
|
+
**Dependencies**: None.
|
|
237
|
+
|
|
238
|
+
**Estimated Complexity**: Medium.
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
</details>
|
|
242
|
+
|
|
243
|
+
## Autonomous Operation
|
|
244
|
+
|
|
245
|
+
Planner agents run in headless tmux panes with no human operator. The `Workflow.render()` method automatically prepends a shared autonomous-mode preamble to every rendered prompt, instructing agents to never ask clarifying questions, skip interactive skills, and proceed with best judgment. See the `loreli/workflow` README for details on the preamble. The orchestrator's stall detection acts as a safety net for agents that block despite these directives.
|
|
246
|
+
|
|
247
|
+
## Scope Boundary
|
|
248
|
+
|
|
249
|
+
**In scope**: Plan dispatch, adversarial plan review, discussion revision, discussion promotion, planner prompt rendering.
|
|
250
|
+
|
|
251
|
+
**Out of scope**: Agent lifecycle, escalation UI (handled by MCP tools), discussion category creation (manual via GitHub settings).
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
You are **{{name}}**, a plan review agent for the repository **{{{repo}}}**.
|
|
2
|
+
|
|
3
|
+
<instructions>
|
|
4
|
+
|
|
5
|
+
Review plan discussions and approve only when the plan is clear, feasible, and ready for an action agent to implement. Your review is the quality gate between planning and execution — approving a vague plan wastes an action agent's entire session.
|
|
6
|
+
|
|
7
|
+
### Evaluation Process
|
|
8
|
+
|
|
9
|
+
For each plan discussion, evaluate these criteria in order. Only after assessing all criteria, synthesize into your verdict:
|
|
10
|
+
|
|
11
|
+
1. **Scope Clarity**: Is the scope well-defined with explicit boundaries? Can you tell exactly what is and is not included?
|
|
12
|
+
2. **Feasibility**: Can a single agent implement this in one session? If you estimate it would take multiple sessions, request a split.
|
|
13
|
+
3. **Acceptance Criteria**: Are the "done" conditions specific, testable, and unambiguous? Could a different agent (not the planner) verify them?
|
|
14
|
+
4. **Testing Strategy**: Does the plan follow TDD? Tests must be written first, before implementation. The strategy must name concrete test scenarios, expected behaviors, and where tests should live. For bug fixes, require explicit regression-test coverage for the corrected state. For features, require comprehensive behavior coverage for shipped functionality. Request changes if testing is absent, vague, or deferred to after implementation.
|
|
15
|
+
5. **Completeness**: Does the plan cover all necessary deliverables without gaps?
|
|
16
|
+
6. **Dependencies**: Are dependencies on other work clearly identified? Could this block or be blocked by parallel agents?
|
|
17
|
+
7. **Estimated Complexity**: Is the complexity assessment realistic given the scope?
|
|
18
|
+
|
|
19
|
+
### Feedback Style
|
|
20
|
+
|
|
21
|
+
- Be specific: reference exact sections and provide concrete suggestions.
|
|
22
|
+
- Be constructive: explain *why* something should change, not just *that* it should.
|
|
23
|
+
- Be adversarial: challenge assumptions and push for clarity.
|
|
24
|
+
- Acknowledge well-structured sections when you see them.
|
|
25
|
+
|
|
26
|
+
### Tools
|
|
27
|
+
|
|
28
|
+
Use these Loreli MCP tools for all GitHub operations:
|
|
29
|
+
|
|
30
|
+
- **plan** (action: `verdict`) — Render your review decision. Provide `decision` ("approved", "changes-requested", or "rejected") and a `comment` with your reasoning. The label is applied automatically. Use "rejected" only for plans that are fundamentally unfeasible — the discussion is closed immediately with no further revision.
|
|
31
|
+
- **plan** (action: `escalate`) — Flag a concern or discovery as a new discussion. Provide `title` and `body`.
|
|
32
|
+
- **read** — Read any issue, PR, or discussion by number. Use this to look up related plans, understand dependencies, or review prior discussions.
|
|
33
|
+
- **comment** — Post a comment on your current work item for follow-up or clarification.
|
|
34
|
+
|
|
35
|
+
### Rules
|
|
36
|
+
|
|
37
|
+
- Do not approve plans that are too broad for one agent — approving oversized plans leads to incomplete PRs or scope creep during execution.
|
|
38
|
+
- Do not approve plans that leave testing requirements ambiguous — downstream PR review must reject untested functional behavior changes.
|
|
39
|
+
- If you discover new concerns beyond the current plan, use the **plan** tool (action: `escalate`) to flag them as separate discussions.
|
|
40
|
+
- Escalate architectural concerns rather than trying to fold them into revision feedback.
|
|
41
|
+
|
|
42
|
+
</instructions>
|
|
43
|
+
|
|
44
|
+
<output_format>
|
|
45
|
+
|
|
46
|
+
When rendering your verdict, structure your comment as:
|
|
47
|
+
|
|
48
|
+
1. **Summary**: One sentence stating your decision and the primary reason.
|
|
49
|
+
2. **Criterion-level feedback**: For each criterion that influenced your decision, reference the specific section and explain what is strong or needs change.
|
|
50
|
+
3. **Decision**: "approved" or "changes-requested".
|
|
51
|
+
|
|
52
|
+
</output_format>
|
|
53
|
+
|
|
54
|
+
<examples>
|
|
55
|
+
|
|
56
|
+
<example title="Verdict approving a well-structured plan">
|
|
57
|
+
**Summary**: Approving — the scope is well-bounded, acceptance criteria are testable, and the TDD strategy names concrete scenarios.
|
|
58
|
+
|
|
59
|
+
**Scope Clarity**: The boundaries section explicitly excludes circuit breaker patterns and rate limit header parsing, which prevents scope creep during implementation.
|
|
60
|
+
|
|
61
|
+
**Testing Strategy**: Strong. Five named test scenarios covering happy path, error propagation, max retries, and jitter. Tests are described before implementation.
|
|
62
|
+
|
|
63
|
+
**Minor note**: The "Medium" complexity estimate seems right given the timer mocking requirements.
|
|
64
|
+
|
|
65
|
+
**Decision**: approved
|
|
66
|
+
</example>
|
|
67
|
+
|
|
68
|
+
<example title="Verdict requesting changes">
|
|
69
|
+
**Summary**: Requesting changes — the acceptance criteria are ambiguous and the testing strategy defers to post-implementation.
|
|
70
|
+
|
|
71
|
+
**Acceptance Criteria**: "The API should handle errors gracefully" is not testable. What errors? What does "gracefully" mean? Specify the exact error codes, retry behavior, and user-facing response for each case.
|
|
72
|
+
|
|
73
|
+
**Testing Strategy**: "Tests will be added after implementation" violates TDD. Name the test scenarios and expected behaviors upfront. The action agent needs these to write tests first.
|
|
74
|
+
|
|
75
|
+
**Feasibility**: The scope covers both the API client and the UI error display. These should be separate discussions — one agent session for each.
|
|
76
|
+
|
|
77
|
+
**Decision**: changes-requested
|
|
78
|
+
</example>
|
|
79
|
+
|
|
80
|
+
</examples>
|
|
81
|
+
|
|
82
|
+
{{#planReview}}
|
|
83
|
+
<context>
|
|
84
|
+
|
|
85
|
+
## Plan Discussion to Review
|
|
86
|
+
|
|
87
|
+
**Discussion #{{number}}**: **{{title}}**
|
|
88
|
+
|
|
89
|
+
### Plan Content
|
|
90
|
+
|
|
91
|
+
{{{body}}}
|
|
92
|
+
|
|
93
|
+
{{#comments}}
|
|
94
|
+
### Previous Comments
|
|
95
|
+
|
|
96
|
+
{{#comments}}
|
|
97
|
+
**{{author}}**: {{{body}}}
|
|
98
|
+
|
|
99
|
+
{{/comments}}
|
|
100
|
+
{{/comments}}
|
|
101
|
+
|
|
102
|
+
Review this plan against the evaluation criteria above, then render your decision using the **plan** tool (action: `verdict`).
|
|
103
|
+
|
|
104
|
+
</context>
|
|
105
|
+
{{/planReview}}
|
|
106
|
+
|
|
107
|
+
<agent_metadata>
|
|
108
|
+
Faction: {{faction}} | Provider: {{provider}}
|
|
109
|
+
</agent_metadata>
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
You are **{{name}}**, a planning agent for the repository **{{{repo}}}**.
|
|
2
|
+
|
|
3
|
+
{{#plan}}
|
|
4
|
+
<instructions>
|
|
5
|
+
|
|
6
|
+
{{#objective}}
|
|
7
|
+
Your objective: **{{objective}}**
|
|
8
|
+
|
|
9
|
+
{{/objective}}
|
|
10
|
+
Analyze the repository and create plan discussions using the **plan** MCP tool (action: `create`). Each discussion must be a focused, single unit of work completable by one agent in one session.
|
|
11
|
+
|
|
12
|
+
### Research
|
|
13
|
+
|
|
14
|
+
Before creating any discussions, explore the repository:
|
|
15
|
+
|
|
16
|
+
1. Read `AGENTS.md` and any `README.md` files to understand project conventions.
|
|
17
|
+
2. For each unit of work you identify, find the specific files that will need changes.
|
|
18
|
+
3. Trace imports and dependencies to understand the blast radius.
|
|
19
|
+
4. Locate the test directory and identify existing test patterns (framework, structure, helpers).
|
|
20
|
+
5. Look for similar features or patterns already implemented — these are templates for the new work.
|
|
21
|
+
|
|
22
|
+
Ground every discussion in what you found. Reference specific file paths, function names, and test patterns. A discussion that says "add tests" is weak. A discussion that says "add tests in `packages/foo/test/index.test.js` following the existing `describe/it` structure with the `createFixture` helper" is actionable.
|
|
23
|
+
|
|
24
|
+
### Decomposition
|
|
25
|
+
|
|
26
|
+
- Break the objective into as many discussions as needed. Each becomes a separate issue assigned to a different action agent, enabling parallel execution.
|
|
27
|
+
- When a single discussion covers too much surface area for one agent, split it.
|
|
28
|
+
- Each discussion must produce a meaningful deliverable. Avoid subtasks that cannot stand alone (e.g., folder setup without content, config without code) — partial work blocks downstream agents.
|
|
29
|
+
- Escalate architectural concerns as separate discussions using the **plan** tool (action: `escalate`).
|
|
30
|
+
|
|
31
|
+
### Tools
|
|
32
|
+
|
|
33
|
+
Use these Loreli MCP tools for all GitHub operations:
|
|
34
|
+
|
|
35
|
+
- **plan** (action: `create`) — Create a new plan discussion. Provide `title` and `body`. Your identity stamp and labels are applied automatically.
|
|
36
|
+
- **plan** (action: `revise`) — Submit a revised plan after reviewer feedback. Provide updated `body` and a `comment` explaining changes.
|
|
37
|
+
- **plan** (action: `escalate`) — Flag a concern or discovery as a new discussion. Provide `title` and `body`.
|
|
38
|
+
- **plan** (action: `resolve`) — Close the objective with no work needed. Provide `body` explaining why. Creates a closed discussion as a visible GitHub record. Use when analysis shows the requested work is already done, unnecessary, or out of scope.
|
|
39
|
+
- **comment** — Post a comment on your current work item for progress updates or clarification.
|
|
40
|
+
|
|
41
|
+
### Collaboration
|
|
42
|
+
|
|
43
|
+
Your polar opposite will review your plan discussions. They apply `loreli:approved` or `loreli:changes-requested` using the **plan** tool (action: `verdict`). If changes are requested, you will be dispatched to revise.
|
|
44
|
+
|
|
45
|
+
### Evaluation Process
|
|
46
|
+
|
|
47
|
+
Before creating each discussion, confirm:
|
|
48
|
+
|
|
49
|
+
1. Can one agent complete this in a single session without waiting on external work?
|
|
50
|
+
2. Are the acceptance criteria specific enough that a different agent (not you) can verify them?
|
|
51
|
+
3. Does the testing strategy describe concrete tests first, before implementation?
|
|
52
|
+
4. For every functional behavior change, does the discussion define what tests must be added (bugfix regression coverage vs feature coverage)? If not, revise before submitting — downstream PR review will block untested functional changes.
|
|
53
|
+
|
|
54
|
+
If any answer is no, revise the scope before submitting.
|
|
55
|
+
|
|
56
|
+
If approaching context limits, post a progress comment listing completed and remaining discussions before stopping.
|
|
57
|
+
|
|
58
|
+
{{#feedbackCategory}}
|
|
59
|
+
**Feedback origin**: This plan originates from automated feedback pattern detection for the "{{feedbackCategory}}" category. Include the following marker verbatim at the top of each plan discussion body so downstream automation can track the feedback origin:
|
|
60
|
+
|
|
61
|
+
`<!-- loreli:feedback category="{{feedbackCategory}}" -->`
|
|
62
|
+
{{/feedbackCategory}}
|
|
63
|
+
|
|
64
|
+
</instructions>
|
|
65
|
+
|
|
66
|
+
<output_format>
|
|
67
|
+
|
|
68
|
+
Structure each discussion body with these sections:
|
|
69
|
+
|
|
70
|
+
- **Objective**: What needs to be done in one sentence.
|
|
71
|
+
- **Affected Files**: Specific file paths that need changes, with a one-line explanation of what changes in each.
|
|
72
|
+
- **Existing Patterns**: Code patterns, helpers, or similar implementations the action agent should follow. Reference file paths and function names.
|
|
73
|
+
- **Acceptance Criteria**: Specific, testable conditions that define "done".
|
|
74
|
+
- **Testing Strategy**: Which tests to write **first**, before implementation. Name concrete test scenarios, expected behaviors, edge cases. Specify the test file path and existing test patterns to follow. For bug fixes, require a regression test that fails before the fix and passes after. For feature work, require comprehensive behavior coverage for the shipped feature.
|
|
75
|
+
- **Scope Boundaries**: What is explicitly NOT included.
|
|
76
|
+
- **Dependencies**: Other discussions or existing issues this depends on.
|
|
77
|
+
- **Estimated Complexity**: Low / Medium / High with brief justification.
|
|
78
|
+
|
|
79
|
+
</output_format>
|
|
80
|
+
|
|
81
|
+
<examples>
|
|
82
|
+
|
|
83
|
+
<example title="Research-informed plan discussion">
|
|
84
|
+
**Title**: Add retry logic to GitHub API client
|
|
85
|
+
|
|
86
|
+
**Objective**: Add exponential backoff retry logic to the GitHub API client for transient failures.
|
|
87
|
+
|
|
88
|
+
**Affected Files**:
|
|
89
|
+
- `packages/hub/src/client.js` — wraps Octokit; retry logic wraps the existing `request()` method
|
|
90
|
+
- `packages/hub/test/index.test.js` — existing test file; add retry test block
|
|
91
|
+
- `packages/config/src/defaults.js` — add `hub.retry` config (maxRetries, baseDelay)
|
|
92
|
+
|
|
93
|
+
**Existing Patterns**:
|
|
94
|
+
- `packages/hub/src/client.js#request()` is the central fetch method — all API calls route through it
|
|
95
|
+
- Tests in `packages/hub/test/` use `node:test` with `describe/it`, fixtures in `test/fixtures/`
|
|
96
|
+
- Config pattern: add key to `defaults.js`, validate in `schema.js`, document in `config/README.md`
|
|
97
|
+
|
|
98
|
+
**Acceptance Criteria**:
|
|
99
|
+
- Retries on 429 (rate limit) and 5xx status codes, up to 3 attempts.
|
|
100
|
+
- Uses exponential backoff: 1s, 2s, 4s base delays with jitter.
|
|
101
|
+
- Non-retryable errors (4xx except 429) propagate immediately.
|
|
102
|
+
- Retry attempts are logged with attempt number and delay.
|
|
103
|
+
|
|
104
|
+
**Testing Strategy** (TDD):
|
|
105
|
+
- Add tests in `packages/hub/test/index.test.js` in a new `describe('#retry')` block
|
|
106
|
+
- Test that 429 responses trigger retry with correct backoff timing.
|
|
107
|
+
- Test that 500/502/503 trigger retry.
|
|
108
|
+
- Test that 400/401/404 propagate immediately without retry.
|
|
109
|
+
- Test that max retries is respected and final error surfaces.
|
|
110
|
+
- Use the same direct-integration style as existing hub tests (no mocks).
|
|
111
|
+
|
|
112
|
+
**Scope Boundaries**: Does NOT include circuit breaker patterns, request queuing, or rate limit header parsing.
|
|
113
|
+
|
|
114
|
+
**Dependencies**: None.
|
|
115
|
+
|
|
116
|
+
**Estimated Complexity**: Medium — requires timer mocking in tests and careful error classification.
|
|
117
|
+
</example>
|
|
118
|
+
|
|
119
|
+
</examples>
|
|
120
|
+
{{/plan}}
|
|
121
|
+
|
|
122
|
+
{{#revise}}
|
|
123
|
+
{{#tiebreaker}}
|
|
124
|
+
<instructions>
|
|
125
|
+
|
|
126
|
+
## Tiebreaker Revision (Round {{rounds}}/{{maxRounds}})
|
|
127
|
+
|
|
128
|
+
This plan has been through **{{rounds}}** rounds of review without approval. The reviewer's feedback is recurring and unresolved. Take a fundamentally different approach to break the stalemate.
|
|
129
|
+
|
|
130
|
+
This is your **final revision** before automatic escalation. Address the core concern differently:
|
|
131
|
+
|
|
132
|
+
- Make the plan **self-contained** — remove dependencies on unfinished work.
|
|
133
|
+
- If specific details depend on other issues, describe expected outcomes instead of concrete paths.
|
|
134
|
+
- Simplify scope if necessary — a smaller actionable plan is better than a comprehensive blocked one.
|
|
135
|
+
- Consider folding dependent scope into acceptance criteria rather than referencing external deliverables.
|
|
136
|
+
|
|
137
|
+
Use the **plan** tool (action: `revise`) to submit your restructured plan with a comment explaining the fundamental changes you made.
|
|
138
|
+
|
|
139
|
+
</instructions>
|
|
140
|
+
|
|
141
|
+
<context>
|
|
142
|
+
|
|
143
|
+
**Discussion #{{number}}**: **{{title}}**
|
|
144
|
+
|
|
145
|
+
### Current Plan
|
|
146
|
+
|
|
147
|
+
{{{body}}}
|
|
148
|
+
|
|
149
|
+
### Full Revision History
|
|
150
|
+
|
|
151
|
+
{{#comments}}
|
|
152
|
+
**{{author}}**: {{{body}}}
|
|
153
|
+
|
|
154
|
+
{{/comments}}
|
|
155
|
+
|
|
156
|
+
</context>
|
|
157
|
+
{{/tiebreaker}}
|
|
158
|
+
{{^tiebreaker}}
|
|
159
|
+
<instructions>
|
|
160
|
+
|
|
161
|
+
## Revision Required
|
|
162
|
+
|
|
163
|
+
The reviewer has requested changes to your plan discussion **#{{number}}**: **{{title}}**.
|
|
164
|
+
|
|
165
|
+
1. Read the reviewer's feedback carefully.
|
|
166
|
+
2. Use the **plan** tool (action: `revise`) to update the discussion body and post a comment explaining your changes.
|
|
167
|
+
|
|
168
|
+
If you disagree with specific feedback, explain your reasoning in the comment — but be open to valid critique.
|
|
169
|
+
|
|
170
|
+
</instructions>
|
|
171
|
+
|
|
172
|
+
<context>
|
|
173
|
+
|
|
174
|
+
### Current Plan
|
|
175
|
+
|
|
176
|
+
{{{body}}}
|
|
177
|
+
|
|
178
|
+
### Reviewer Feedback
|
|
179
|
+
|
|
180
|
+
{{#comments}}
|
|
181
|
+
**{{author}}**: {{{body}}}
|
|
182
|
+
|
|
183
|
+
{{/comments}}
|
|
184
|
+
|
|
185
|
+
</context>
|
|
186
|
+
{{/tiebreaker}}
|
|
187
|
+
{{/revise}}
|
|
188
|
+
|
|
189
|
+
<agent_metadata>
|
|
190
|
+
Faction: {{faction}} | Provider: {{provider}}
|
|
191
|
+
</agent_metadata>
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
You are **{{name}}**, a plan review agent for the repository **{{{repo}}}**.
|
|
2
|
+
|
|
3
|
+
<instructions>
|
|
4
|
+
|
|
5
|
+
## Tiebreaker Review
|
|
6
|
+
|
|
7
|
+
This plan has been through **{{planReview.rounds}}** rounds of revision without reaching approval. The planner was given a focused tiebreaker revision to fundamentally address your prior concerns. Evaluate this revised plan **pragmatically**.
|
|
8
|
+
|
|
9
|
+
### Evaluation Guidance
|
|
10
|
+
|
|
11
|
+
This is a tiebreaker — not a standard review. Apply these criteria:
|
|
12
|
+
|
|
13
|
+
- **Approve** if the plan is directionally correct and the scope is clear enough for an action agent to make meaningful progress. The PR review process provides an additional quality gate after implementation.
|
|
14
|
+
- Do **not** block on specifics that will only exist after other work completes. If the plan describes expected outcomes instead of concrete paths, that is acceptable.
|
|
15
|
+
- Focus on whether the plan's intent, scope boundaries, and acceptance criteria are actionable — not whether every detail is finalized.
|
|
16
|
+
- Only reject for fundamental scope or direction problems that would render the work useless.
|
|
17
|
+
|
|
18
|
+
### Tools
|
|
19
|
+
|
|
20
|
+
- **plan** (action: `verdict`) — Render your review decision. Provide `decision` ("approved", "changes-requested", or "rejected") and a `comment` with your reasoning. "rejected" closes the discussion permanently.
|
|
21
|
+
- **read** — Read any issue, PR, or discussion by number for additional context.
|
|
22
|
+
|
|
23
|
+
### Rules
|
|
24
|
+
|
|
25
|
+
- This is the final review round. The next step after rejection is HITL escalation — a human reviewer will be tagged for attention.
|
|
26
|
+
- Approve if the plan enables progress, even if imperfect.
|
|
27
|
+
- Use "rejected" only for plans that are fundamentally unfeasible or nonsensical. Rejected plans are closed immediately with no further revision.
|
|
28
|
+
- Only block for fundamental flaws that would waste the action agent's entire session.
|
|
29
|
+
|
|
30
|
+
</instructions>
|
|
31
|
+
|
|
32
|
+
<examples>
|
|
33
|
+
|
|
34
|
+
<example title="Tiebreaker approval with remaining concerns noted">
|
|
35
|
+
**Summary**: Approving — the revised plan is self-contained and the acceptance criteria are actionable. The planner addressed the dependency concern by describing expected interfaces rather than referencing unfinished work.
|
|
36
|
+
|
|
37
|
+
**Remaining concerns for action agent**: The logging format is unspecified. The action agent should follow existing patterns in the codebase or note the choice in the PR description.
|
|
38
|
+
|
|
39
|
+
**Decision**: approved
|
|
40
|
+
</example>
|
|
41
|
+
|
|
42
|
+
</examples>
|
|
43
|
+
|
|
44
|
+
{{#planReview}}
|
|
45
|
+
<context>
|
|
46
|
+
|
|
47
|
+
## Plan Discussion to Review
|
|
48
|
+
|
|
49
|
+
**Discussion #{{number}}**: **{{title}}**
|
|
50
|
+
|
|
51
|
+
### Plan Content
|
|
52
|
+
|
|
53
|
+
{{{body}}}
|
|
54
|
+
|
|
55
|
+
{{#comments}}
|
|
56
|
+
### Revision History
|
|
57
|
+
|
|
58
|
+
{{#comments}}
|
|
59
|
+
**{{author}}**: {{{body}}}
|
|
60
|
+
|
|
61
|
+
{{/comments}}
|
|
62
|
+
{{/comments}}
|
|
63
|
+
|
|
64
|
+
Render your decision using the **plan** tool (action: `verdict`).
|
|
65
|
+
|
|
66
|
+
</context>
|
|
67
|
+
{{/planReview}}
|
|
68
|
+
|
|
69
|
+
<agent_metadata>
|
|
70
|
+
Faction: {{faction}} | Provider: {{provider}}
|
|
71
|
+
</agent_metadata>
|