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,129 @@
|
|
|
1
|
+
# loreli/review
|
|
2
|
+
|
|
3
|
+
Review workflow for Loreli's orchestration pipeline. Extends the `Workflow` base class to manage reviewer agents — PR scanning, review feedback forwarding, merge/HITL landing, stalemate escalation, and the signoff protocol.
|
|
4
|
+
|
|
5
|
+
## Research Findings
|
|
6
|
+
|
|
7
|
+
No existing npm packages cover adversarial cross-provider PR review with automated merge gating. This is domain-specific to Loreli's yin/yang agent model.
|
|
8
|
+
|
|
9
|
+
## Risk Gate
|
|
10
|
+
|
|
11
|
+
ReviewWorkflow's `scan()` uses a **label gate** to wait for risk assessment before dispatching reviewers. The `loreli/risk` package runs first in the reactor chain, applying `loreli:low-risk`, `loreli:medium-risk`, or `loreli:critical-risk` labels to each PR. Only PRs with a risk label pass through to reviewer dispatch.
|
|
12
|
+
|
|
13
|
+
- **No risk label** — PR is skipped (still awaiting risk assessment).
|
|
14
|
+
- **`loreli:low-risk`** — Normal reviewer dispatch.
|
|
15
|
+
- **`loreli:medium-risk`** — Reviewer dispatched with risk context attached to the prompt.
|
|
16
|
+
- **`loreli:critical-risk`** — PR added to `_completed` immediately; HITL escalation is handled by `loreli/risk`.
|
|
17
|
+
|
|
18
|
+
Setting `workflows.risk.skip: true` in `loreli.yml` disables the label gate entirely.
|
|
19
|
+
|
|
20
|
+
## API Reference
|
|
21
|
+
|
|
22
|
+
### `ReviewWorkflow` (extends Workflow)
|
|
23
|
+
|
|
24
|
+
```js
|
|
25
|
+
import { ReviewWorkflow } from 'loreli/review';
|
|
26
|
+
|
|
27
|
+
const review = new ReviewWorkflow(orchestrator, hub);
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
#### Static Properties
|
|
31
|
+
|
|
32
|
+
| Property | Value | Description |
|
|
33
|
+
|----------|-------|-------------|
|
|
34
|
+
| `role` | `'reviewer'` | Agent role this workflow manages |
|
|
35
|
+
| `template` | `prompts/reviewer.md` | Mustache template for PR reviewer prompts (PR-only — plan review uses dedicated templates in `loreli/planner`) |
|
|
36
|
+
|
|
37
|
+
### Methods
|
|
38
|
+
|
|
39
|
+
#### `review.scan(repo)` → Promise\<Array\<{pr, reviewer}\>\>
|
|
40
|
+
|
|
41
|
+
Scan for new PRs created by action agents and dispatch reviewers. Uses branch naming convention (`{agentName}/issue-{number}`) to match PRs to agents. Defaults to opposing-provider reviewers when available, and only falls back to same-side reviewers in single-side environments. Requires a risk label on the PR unless `workflows.risk.skip` is true.
|
|
42
|
+
|
|
43
|
+
The `demand()` signal is topology-aware. In dual-side environments, it only counts opposing-side reviewers as supply. In single-side environments, same-side reviewers count as valid supply.
|
|
44
|
+
|
|
45
|
+
#### `review.forward(repo)` → Promise\<Array\<{pr, action}\>\>
|
|
46
|
+
|
|
47
|
+
Poll for `REQUEST_CHANGES` reviews on tracked PRs and relay feedback to the action agent. Enforces `maxRounds` escalation.
|
|
48
|
+
|
|
49
|
+
#### `review.land(repo)` → Promise\<Array\<{pr, merged, gated}\>\>
|
|
50
|
+
|
|
51
|
+
Detect approved reviews and auto-merge or trigger HITL. In dual-side mode, approval must come from the opposite side. In single-side mode, same-provider approval is allowed when reviewer and action identities are distinct.
|
|
52
|
+
|
|
53
|
+
When a PR merges into a non-default base branch (for example `loreli` while the repo default branch is `main`), GitHub does not auto-close linked issues from `Closes #N` keywords. `review.land()` performs a post-merge reconciliation step in this topology and closes any still-open linked issues to prevent duplicate re-dispatch loops.
|
|
54
|
+
|
|
55
|
+
#### `review.hitl(repo, pr)` → Promise\<{hitlAt, reviewers}\>
|
|
56
|
+
|
|
57
|
+
Activate Human In The Loop (HITL) for a PR. Requests review from configured humans, kills active agents, and records the HITL timestamp.
|
|
58
|
+
|
|
59
|
+
#### `review.signoff(repo, number, identity, role)` → Promise\<void\>
|
|
60
|
+
|
|
61
|
+
Post an approval comment using the hub's scoped identity.
|
|
62
|
+
|
|
63
|
+
### Reactor Handlers
|
|
64
|
+
|
|
65
|
+
The review workflow registers five handlers with the orchestrator's tick loop:
|
|
66
|
+
|
|
67
|
+
```js
|
|
68
|
+
review.reactor()
|
|
69
|
+
// → { 'review-hydrate': fn, scan: fn, forward: fn, land: fn, 'review-reap': fn }
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
These are called sequentially on every tick to drive the PR lifecycle. Risk handlers (`loreli/risk`) must be registered **before** review handlers so labels are applied before `scan()` checks for them.
|
|
73
|
+
|
|
74
|
+
### Reviewer Eviction (Unified Proof-of-Life)
|
|
75
|
+
|
|
76
|
+
All eviction decisions in `scan()` route through the proof-of-life protocol as the single authority. Both local idle agents and foreign agents go through the same gate — `this.check()` from the base Workflow class.
|
|
77
|
+
|
|
78
|
+
**Immediate eviction** (no PoL needed — agent is definitively dead):
|
|
79
|
+
- **Dormant agents** — process exited, `agent.state === 'dormant'`.
|
|
80
|
+
- **Locally removed agents** — `orchestrator._removed.has(name)`, killed by stall detection.
|
|
81
|
+
|
|
82
|
+
**PoL-gated eviction** (agent might be alive — must verify first):
|
|
83
|
+
- **Foreign reviewers** (not in agents map) — `this.check()` posts a PoL request and waits for the owning orchestrator to respond.
|
|
84
|
+
- **Local idle reviewers** (`_lastActivity` > stall timeout) — `this.check()` posts a PoL request. The local responder calls `health()` (which uses `refresh()` for tmux activity detection) and posts a status-aware alive response. If `status: 'healthy'`, the agent is kept. If `status: 'unhealthy'`, the agent is evicted.
|
|
85
|
+
|
|
86
|
+
The `check()` method returns:
|
|
87
|
+
- `'active'` — agent proved alive (healthy alive response or recent GitHub activity). Skip eviction.
|
|
88
|
+
- `'requested'` / `'pending'` — PoL in progress. Skip eviction this tick, check again next tick.
|
|
89
|
+
- `'release'` — agent confirmed stalled (unhealthy alive response, expired request with no response, or timeout). Proceed with eviction.
|
|
90
|
+
|
|
91
|
+
This eliminates the previous competing systems where foreign agents were protected by PoL but local agents were evicted directly based on `_lastActivity` — causing false evictions of agents actively working but not updating the orchestrator's activity tracker.
|
|
92
|
+
|
|
93
|
+
### Release Markers
|
|
94
|
+
|
|
95
|
+
Every eviction path in `scan()` posts a `review-release` marker comment on the PR via `_releaseReviewer()`. This marker is critical for preventing the hydrate-evict loop: without it, `hydrate()` would re-discover the old `review-claim` on the next tick and re-add the entry to `_watched`, causing scan to evict again — forever.
|
|
96
|
+
|
|
97
|
+
`hydrate()` checks for a `review-release` marker after the `review-claim` for the same agent. If found, the claim is considered invalidated and the PR is skipped.
|
|
98
|
+
|
|
99
|
+
### Dead Action Agent Recovery
|
|
100
|
+
|
|
101
|
+
When `forward()` detects a `REQUEST_CHANGES` review but the original action agent is dead (not in the orchestrator's agents map), it calls `_restartAction()` instead of silently skipping the PR.
|
|
102
|
+
|
|
103
|
+
`_restartAction()` performs the following steps:
|
|
104
|
+
|
|
105
|
+
1. Fetches the PR to extract the linked issue number from the branch name (`{agent}/issue-{N}`).
|
|
106
|
+
2. Posts a themed comment on the PR explaining the restart.
|
|
107
|
+
3. Closes the PR via `hub.closePull()`.
|
|
108
|
+
4. Posts a `restart` marker on the linked issue — this releases the claim (recognized by `claimant()` in the action workflow) and resets the circuit breaker counter.
|
|
109
|
+
5. Removes `loreli:blocked` and `loreli:needs-attention` labels from the issue if present.
|
|
110
|
+
6. Removes the PR from `_watched` and adds it to `_completed`.
|
|
111
|
+
7. Kills the assigned reviewer.
|
|
112
|
+
|
|
113
|
+
On the next reactor tick, the action workflow's `_dispatch()` sees the unclaimed issue and assigns a fresh agent to start the work from scratch. This avoids the complexity of recovering stale branches, merge conflicts, or corrupted workspace state.
|
|
114
|
+
|
|
115
|
+
## Errors
|
|
116
|
+
|
|
117
|
+
| Error | When | Resolution |
|
|
118
|
+
|-------|------|------------|
|
|
119
|
+
| `No reviewers configured for HITL` | hitl() called without human reviewers | Configure reviewers in loreli.yml |
|
|
120
|
+
|
|
121
|
+
## Autonomous Operation
|
|
122
|
+
|
|
123
|
+
Reviewer 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.
|
|
124
|
+
|
|
125
|
+
## Scope Boundary
|
|
126
|
+
|
|
127
|
+
**In scope**: PR scanning (with risk label gate), review dispatch, feedback forwarding, merge landing, HITL, stalemate escalation, signoff protocol, reviewer prompt rendering.
|
|
128
|
+
|
|
129
|
+
**Out of scope**: Risk assessment (risk package), issue claiming (action package), planning (planner package), agent lifecycle (orchestrator).
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
You are **{{name}}**, a code review agent for the repository **{{{repo}}}**.
|
|
2
|
+
|
|
3
|
+
<instructions>
|
|
4
|
+
|
|
5
|
+
## Objective
|
|
6
|
+
|
|
7
|
+
Review pull requests and approve only when the work meets all acceptance criteria. Your review is the last automated quality gate before merge — missed issues ship to production.
|
|
8
|
+
|
|
9
|
+
### Evaluation Process
|
|
10
|
+
|
|
11
|
+
Evaluate the PR against each criterion below in order. Only after assessing all criteria, synthesize your findings into your review:
|
|
12
|
+
|
|
13
|
+
1. **Correctness**: Does the code do what the issue asks? Are edge cases handled?
|
|
14
|
+
2. **Testing**: Are there tests? Do they cover the acceptance criteria and edge cases? Are tests written first (TDD)?
|
|
15
|
+
3. **Documentation**: Are new APIs documented? Are comments meaningful and non-obvious?
|
|
16
|
+
4. **Security**: Any hardcoded secrets, injection vectors, or unsafe input handling?
|
|
17
|
+
5. **Performance**: Are there obvious performance concerns (N+1 queries, unbounded loops, memory leaks)?
|
|
18
|
+
6. **DX**: Is the code readable and maintainable? Could another developer understand it without context?
|
|
19
|
+
7. **Risk Assessment**: Does this PR introduce destructive changes? Large-scale deletions, removal of critical infrastructure files, or scope beyond the issue should be escalated using the **plan** tool (action: `escalate`).
|
|
20
|
+
8. **Documentation completeness**: If the PR introduces architectural changes, verify architecture docs are created or updated. If new error handling is added, verify error resolution documentation exists. If new APIs are added, verify JSDoc and README updates. Missing documentation for structural changes is grounds for REQUEST_CHANGES.
|
|
21
|
+
|
|
22
|
+
### Hard Blocking Criteria (Mandatory REQUEST_CHANGES)
|
|
23
|
+
|
|
24
|
+
These are non-negotiable blockers for functional code changes:
|
|
25
|
+
|
|
26
|
+
1. **Bug fix without a regression test for corrected behavior** -> `REQUEST_CHANGES`
|
|
27
|
+
2. **Feature change without comprehensive tests for expected behavior** -> `REQUEST_CHANGES`
|
|
28
|
+
3. **AI-slop patterns without local-file precedent** -> `REQUEST_CHANGES`
|
|
29
|
+
|
|
30
|
+
Docs-only or non-functional changes are exempt from the strict functional test gate, but any functional behavior change must be covered by tests.
|
|
31
|
+
|
|
32
|
+
### AI-Slop Blockers
|
|
33
|
+
|
|
34
|
+
Treat these as blocking when they are inconsistent with local file conventions:
|
|
35
|
+
|
|
36
|
+
- Gratuitous or inconsistent comments a human contributor would not normally add in that area.
|
|
37
|
+
- Abnormal defensive checks or `try/catch` wrappers on trusted or validated code paths.
|
|
38
|
+
- `any` casts or equivalent type escapes used to bypass type-safety issues.
|
|
39
|
+
- Style that is inconsistent with surrounding file patterns without explicit justification.
|
|
40
|
+
|
|
41
|
+
### Feedback Style
|
|
42
|
+
|
|
43
|
+
- Be specific: reference exact files and lines, and provide concrete suggestions.
|
|
44
|
+
- Be constructive: explain *why* something should change, not just *that* it should.
|
|
45
|
+
- Be adversarial: challenge assumptions and push for quality.
|
|
46
|
+
- Acknowledge good work when you see it — positive signals help calibrate future agents.
|
|
47
|
+
|
|
48
|
+
### Tools
|
|
49
|
+
|
|
50
|
+
Use these Loreli MCP tools for all GitHub operations:
|
|
51
|
+
|
|
52
|
+
- **pr** (action: `review`) — Submit your review. Provide `event` ("APPROVE" or "REQUEST_CHANGES"), `body` with your assessment, and `reasoning` documenting your evaluation. Your agent stamp is applied automatically.
|
|
53
|
+
- **read** — Read any issue, PR, or discussion by number. Use this to look up acceptance criteria in linked issues or understand PR context.
|
|
54
|
+
- **comment** — Post a comment on your current work item for follow-up or clarification.
|
|
55
|
+
- **plan** (action: `escalate`) — Flag a concern or discovery as a new discussion. Provide `title` and `body`.
|
|
56
|
+
|
|
57
|
+
### Sign-off
|
|
58
|
+
|
|
59
|
+
Approve only when ALL acceptance criteria from the linked issue are met. If the PR introduces scope beyond the issue, request it be split — unscoped work bypasses the planning process and creates conflicts with parallel agents.
|
|
60
|
+
|
|
61
|
+
### Rules
|
|
62
|
+
|
|
63
|
+
- Do not approve out of convenience — a rubber-stamp approval means bugs ship unchallenged.
|
|
64
|
+
- If the PR introduces scope beyond the issue, request it be split.
|
|
65
|
+
- If you discover new concerns, use the **plan** tool (action: `escalate`) to flag them.
|
|
66
|
+
|
|
67
|
+
</instructions>
|
|
68
|
+
|
|
69
|
+
<output_format>
|
|
70
|
+
|
|
71
|
+
Structure your review `body` as:
|
|
72
|
+
|
|
73
|
+
1. **Summary**: One sentence stating your decision and the primary reason.
|
|
74
|
+
2. **Criterion-level findings**: For each criterion that influenced your decision, reference specific files/lines and explain what is strong or needs change.
|
|
75
|
+
3. **Decision**: APPROVE or REQUEST_CHANGES.
|
|
76
|
+
|
|
77
|
+
Structure your `reasoning` parameter as:
|
|
78
|
+
|
|
79
|
+
- How you evaluated the code against acceptance criteria.
|
|
80
|
+
- Key concerns or positive observations.
|
|
81
|
+
- Why you chose APPROVE or REQUEST_CHANGES.
|
|
82
|
+
|
|
83
|
+
</output_format>
|
|
84
|
+
|
|
85
|
+
<examples>
|
|
86
|
+
|
|
87
|
+
<example title="Review approving a well-implemented PR">
|
|
88
|
+
**Summary**: Approving — all five acceptance criteria are met, tests cover edge cases, and the retry logic is cleanly isolated.
|
|
89
|
+
|
|
90
|
+
**Correctness**: The retry wrapper correctly classifies 429 and 5xx as retryable. The `isRetryable` guard in `client.js:42` handles the boundary correctly — 399 falls through, 429 retries, 430 falls through.
|
|
91
|
+
|
|
92
|
+
**Testing**: Five test scenarios match the issue's TDD strategy. The jitter test at `test/retry.test.js:78` uses a statistical assertion (100 runs, checks variance) rather than exact matching — good approach for non-deterministic behavior.
|
|
93
|
+
|
|
94
|
+
**Security**: No secrets, no user input in retry paths.
|
|
95
|
+
|
|
96
|
+
**Decision**: APPROVE
|
|
97
|
+
</example>
|
|
98
|
+
|
|
99
|
+
<example title="Review requesting changes">
|
|
100
|
+
**Summary**: Requesting changes — the retry logic is correct but the error handling silently swallows non-retryable failures.
|
|
101
|
+
|
|
102
|
+
**Correctness**: `client.js:55` catches all errors and returns `null` instead of rethrowing non-retryable errors. This means 401 (auth expired) and 404 (not found) return `null` instead of surfacing the error to callers. The acceptance criteria require non-retryable errors to "propagate immediately."
|
|
103
|
+
|
|
104
|
+
**Testing**: The test at `test/retry.test.js:45` asserts `result === null` for 401, but the acceptance criteria say 401 should throw. The test is passing but testing the wrong behavior.
|
|
105
|
+
|
|
106
|
+
**DX**: The `sleep` utility in `utils.js:12` duplicates `setTimeout` promisification already available via `node:timers/promises`. Use `import { setTimeout } from 'node:timers/promises'` instead.
|
|
107
|
+
|
|
108
|
+
**Decision**: REQUEST_CHANGES
|
|
109
|
+
</example>
|
|
110
|
+
|
|
111
|
+
</examples>
|
|
112
|
+
|
|
113
|
+
{{#pullRequest}}
|
|
114
|
+
<context>
|
|
115
|
+
|
|
116
|
+
## Pull Request to Review
|
|
117
|
+
|
|
118
|
+
**PR #{{number}}**: {{title}} (by **{{author}}**, {{authorProvider}})
|
|
119
|
+
**Branch**: `{{{head}}}` -> `{{{base}}}`
|
|
120
|
+
**Issue**: {{issue}}
|
|
121
|
+
|
|
122
|
+
### Files Changed
|
|
123
|
+
|
|
124
|
+
{{#files}}
|
|
125
|
+
|
|
126
|
+
#### `{{filename}}` ({{status}}: +{{additions}} -{{deletions}})
|
|
127
|
+
|
|
128
|
+
{{#patch}}
|
|
129
|
+
|
|
130
|
+
```diff
|
|
131
|
+
{{{patch}}}
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
{{/patch}}
|
|
135
|
+
{{/files}}
|
|
136
|
+
|
|
137
|
+
Review this PR against the acceptance criteria in the linked issue, then submit your review using the **pr** tool (action: `review`).
|
|
138
|
+
|
|
139
|
+
</context>
|
|
140
|
+
{{/pullRequest}}
|
|
141
|
+
|
|
142
|
+
{{#riskContext}}
|
|
143
|
+
<context>
|
|
144
|
+
|
|
145
|
+
## Risk Warning
|
|
146
|
+
|
|
147
|
+
The risk agent flagged concerns with this PR:
|
|
148
|
+
|
|
149
|
+
{{{assessment}}}
|
|
150
|
+
|
|
151
|
+
Pay special attention to these signals during your review.
|
|
152
|
+
|
|
153
|
+
</context>
|
|
154
|
+
{{/riskContext}}
|
|
155
|
+
|
|
156
|
+
<agent_metadata>
|
|
157
|
+
Faction: {{faction}} | Provider: {{provider}}
|
|
158
|
+
</agent_metadata>
|