lastlight 0.7.8 → 0.8.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lastlight",
3
- "version": "0.7.8",
3
+ "version": "0.8.0",
4
4
  "description": "GitHub repository maintenance agent — Agent SDK harness",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -2,7 +2,7 @@
2
2
  "$schema": "https://json.schemastore.org/claude-code-plugin.json",
3
3
  "name": "lastlight",
4
4
  "displayName": "Last Light",
5
- "version": "0.7.8",
5
+ "version": "0.8.0",
6
6
  "description": "Install, configure and operate Last Light (GitHub maintenance agent) — its server, CLI client, deployment overlay, and the Last Light Evals harness.",
7
7
  "author": {
8
8
  "name": "Clifton Cunningham"
@@ -13,6 +13,7 @@ Light's *internal* sandbox skills under the repo's top-level `skills/` dir
13
13
 
14
14
  | Skill | Use it when you want to… |
15
15
  |-------|--------------------------|
16
+ | `lastlight-guide` | **Not sure which of the below you need** — orientation & router across all the Last Light skills. Start here (or `/lastlight-guide`). |
16
17
  | `lastlight-server` | Install & configure a Last Light **server** (the agent + docker stack) on a host. |
17
18
  | `lastlight-client` | Point the `lastlight` **CLI client** at an existing server and log in. |
18
19
  | `lastlight-overlay` | Create a deployment **overlay** instance and fork/customize workflows, prompts, skills, or the agent persona. |
@@ -41,4 +42,6 @@ claude plugin install lastlight@lastlight-skills
41
42
  auto-discovers them on the next session.
42
43
 
43
44
  After installing, start a new Claude Code session and say e.g. *"set up a Last
44
- Light server"* or *"scaffold a Last Light evals workspace"*.
45
+ Light server"* or *"scaffold a Last Light evals workspace"* — or, if you're not
46
+ sure where to start, *"help me with Last Light"* (or `/lastlight-guide`) and the
47
+ guide skill will route you.
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: lastlight-evals
3
- description: Scaffold, configure and run a Last Light EVALS workspace — the harness that runs Last Light's real workflows against a mocked GitHub and grades them deterministically. Use when the user wants to "set up / scaffold Last Light Evals", "create an evals workspace or instance", "run evals", "compare models", or author new eval cases — including "create an eval dataset/case from this PR/issue <github url>" (triage / code-fix instances). GitHub is mocked when running, so no real GitHub token is needed — only a model provider API key (the one exception is `add-case`, which reads real PRs/issues via `gh`).
4
- version: 1.2.0
3
+ description: Scaffold, configure and run a Last Light EVALS workspace — the harness that runs Last Light's real workflows against a mocked GitHub and grades them deterministically. Use when the user wants to "set up / scaffold Last Light Evals", "create an evals workspace or instance", "run evals", "compare models", or author new eval cases — including "create an eval dataset/case from this PR/issue <github url>" and "create a PR-review eval dataset from these gold PRs" (triage / code-fix / pr-review instances, via `add-case --pr <url> --review|--code-fix` / `--issue`). GitHub is mocked when running, so no real GitHub token is needed — only a model provider API key (the one exception is `add-case`, which reads real PRs/issues via `gh`).
4
+ version: 1.3.0
5
5
  tags: [lastlight, evals, benchmark, models, swe-bench]
6
6
  ---
7
7
 
@@ -14,6 +14,24 @@ thin CLI on top of the `lastlight` core package (via the `lastlight/evals`
14
14
  barrel), so it exercises the same workflows/skills production does. SWE-bench
15
15
  compatible. **Node 24+.**
16
16
 
17
+ ## Start here — what do you want to do?
18
+
19
+ If the user's evals goal is clear, jump to the section. If it's vague ("help me
20
+ with the evals", "what can this do?"), **ask** (`AskUserQuestion`) which of these
21
+ they want, then go:
22
+
23
+ | Goal | Section |
24
+ |---|---|
25
+ | Set up an evals workspace (first time) | **§2 Scaffold** (+ §1 prereqs, §3 providers) |
26
+ | Run evals / compare models | **§4 Run** |
27
+ | Look at past runs (no models run) | **§4** — `lastlight-evals serve` |
28
+ | Author one case from a GitHub PR or issue | **§6** |
29
+ | **Build a PR-review dataset from my own gold PRs** | **§6 → "Build a PR-review dataset"** |
30
+ | Add cases by hand / understand the schema | **§5** + `references/instance-schema.md` |
31
+
32
+ New to the whole plugin (server / overlay / client, not just evals)? That's the
33
+ **`lastlight-guide`** skill — this one is evals-only.
34
+
17
35
  ## 1. Check prerequisites
18
36
 
19
37
  ```bash
@@ -102,7 +120,7 @@ lastlight-evals run triage --model openai/gpt-5.5,anthropic/claude-opus-4-8
102
120
  lastlight-evals run --compare # cross-vendor set (only models whose envKey is present)
103
121
  lastlight-evals run triage --runs 3 # repeat each case 3× (worst-case verdict, mean metrics)
104
122
  lastlight-evals run pr-review --limit 3 # only the first 3 cases of the tier (controlled/cheap run)
105
- lastlight-evals run triage --instance <id> # only this exact instance_id (or set EVAL_INSTANCE)
123
+ lastlight-evals run triage --instance <id[,id2]> # only these exact instance_id(s), comma-separated (or set EVAL_INSTANCE)
106
124
  lastlight-evals run pr-review --f-beta 0.5 # pr-review F-beta β (default 1=F1; 0.5=precision 2×). Or EVAL_F_BETA
107
125
  lastlight-evals run pr-review --judge-with-diff # feed the PR diff to the judge (higher fidelity; off by default)
108
126
  lastlight-evals run pr-review --sandbox gondolin # isolate the agent's tools in a QEMU micro-VM (anti-spoil). Or EVAL_SANDBOX
@@ -144,9 +162,11 @@ Quick shape (paths are relative to the workspace's `evals/` dir):
144
162
  `evals/datasets/code-fix/tests/<instance_id>/` (held-out tests applied at grade time).
145
163
  - **PR-review case:** a `SweBenchInstance` with a `pr` fixture (base/head refs +
146
164
  commits, checked out at the PR head) and a `review_gold` set (severity +
147
- description). The `pr-review` tier ships empty — populate the full Martian
165
+ description). Populate the full Martian
148
166
  [Code Review Bench](https://codereview.withmartian.com/) 50 with
149
- `npx tsx scripts/import-martian.ts`. Grading needs a judge model
167
+ `npx tsx scripts/import-martian.ts`, **or author your *own* gold-PR dataset**
168
+ with `add-case --pr <url> --review` (see §6 and
169
+ **`references/authoring-pr-review.md`**). Grading needs a judge model
150
170
  (`EVAL_JUDGE_MODEL`, else a strong default per provider key).
151
171
  - **Custom tier:** a new `evals/datasets/<tier>/` with `tier.json` +
152
172
  `instances.json` (+ `repos/` & `tests/` for code-fix-style tiers). Discovery is
@@ -154,16 +174,28 @@ Quick shape (paths are relative to the workspace's `evals/` dir):
154
174
 
155
175
  ## 6. Author a case from a real GitHub PR or issue
156
176
 
157
- When the user says **"create an eval dataset/case from this PR/issue <url>"**, use
158
- the `add-case` subcommand it does the mechanical extraction; you refine the
159
- fuzzy parts.
177
+ When the user says **"create an eval dataset/case from this PR/issue <url>"** or
178
+ **"create a PR-review eval dataset from these gold PRs"**, use the `add-case`
179
+ subcommand — it does the mechanical extraction; you refine the fuzzy parts.
180
+
181
+ A PR seeds two different evals, so `--pr` requires a kind — `--review` (the PR's
182
+ human review is the gold set) or `--code-fix` (hide the fix, the agent must
183
+ reproduce it):
160
184
 
161
185
  ```bash
162
- lastlight-evals add-case --pr <github-pr-url> --dry-run # propose a code-fix case; don't write
163
- lastlight-evals add-case --pr <github-pr-url> # write into ./datasets (or --datasets/--overlay)
164
- lastlight-evals add-case --issue <github-issue-url> --dry-run # propose a triage case
186
+ lastlight-evals add-case --pr <github-pr-url> --review --dry-run # propose a pr-review case; don't write
187
+ lastlight-evals add-case --pr <github-pr-url> --review # write into ./datasets/pr-review (or --overlay)
188
+ lastlight-evals add-case --pr <github-pr-url> --code-fix --dry-run # propose a code-fix case
189
+ lastlight-evals add-case --issue <github-issue-url> --dry-run # propose a triage case
165
190
  ```
166
191
 
192
+ - **From a PR (pr-review):** derives the `pr` fixture (base/head refs + commits,
193
+ from the PR's `baseRefOid`/`headRefOid`) and a **candidate `review_gold`** from
194
+ the PR's *human* review — inline comments + substantive review bodies, with
195
+ bot/nit/reply/outdated noise filtered out. Prints an evidence block; **you**
196
+ assign real severities and prune non-actionable comments. Byte-compatible with
197
+ `import-martian.ts`, so authored cases sit alongside imported ones. Leak-safe:
198
+ the review lands only in `review_gold`, never in the seeded PR the agent sees.
167
199
  - **From a PR (code-fix):** derives `repo`, `base_commit` (merge-base of base &
168
200
  head) + `head_commit`, the PR's **test** diff as the held-out `test_patch`, and
169
201
  auto-detects `FAIL_TO_PASS` / `PASS_TO_PASS` by running the tests at base (red)
@@ -176,9 +208,35 @@ lastlight-evals add-case --issue <github-issue-url> --dry-run # propose a triag
176
208
  **reviewer comments** — the raw triage signal. You then assign
177
209
  `triage_gold` (category/state) from those labels per the deployment's taxonomy.
178
210
 
211
+ ### Build a PR-review dataset from gold PRs (interactive)
212
+
213
+ When the user says **"I want to create a PR-review eval dataset"** (from *their*
214
+ PRs, to track review quality as they evolve models/prompts):
215
+
216
+ 1. **Get the PRs.** If they didn't paste URLs, **ask** for them — "give me the
217
+ gold PR URL(s) — one or many, whose human review is the standard you want a
218
+ model to reproduce." Also confirm *where* to write: the current workspace's
219
+ `./datasets` (or `--overlay <dir>` for a deployment's own dataset).
220
+ 2. **One PR at a time.** For each URL run
221
+ `add-case --pr <url> --review --dry-run`, read the evidence block, then
222
+ **curate** the candidate `review_gold` — set real severities and drop
223
+ comments that aren't concrete findings — and write it
224
+ (`add-case --pr <url> --review [--datasets/--overlay …]`). Re-running the same
225
+ PR **replaces by id**, so curation is idempotent.
226
+ - For **many** PRs, spawn a **curation sub-agent per PR** (each handed one URL
227
+ + the target dir, returning the curated instance) so the judgement stays
228
+ isolated and they run in parallel.
229
+ 3. **Smoke-run** the new tier with the cheapest model to confirm the seed + judge
230
+ plumbing (needs a judge-model key): `lastlight-evals run pr-review --limit 1 --model haiku`.
231
+
232
+ See **`references/authoring-pr-review.md`** for the full extract→curate→write
233
+ flow, the `--severity` / `--include-bots` knobs, and the anti-spoil guarantee.
234
+
179
235
  The full flow, what you refine for each, the `test_cmd` / `setup_cmd` options for
180
236
  non-`node --test` runners, and the trust/offline caveats are in
181
- **`references/authoring-from-pr.md`** read it before authoring.
237
+ **`references/authoring-from-pr.md`** (PR code-fix + issue triage) and
238
+ **`references/authoring-pr-review.md`** (PR review) — read the relevant one
239
+ before authoring.
182
240
 
183
241
  ## Done when
184
242
 
@@ -1,11 +1,17 @@
1
- # Author an eval case from a real GitHub PR or issue
1
+ # Author a code-fix or triage eval case from a real GitHub PR or issue
2
2
 
3
- `lastlight-evals add-case` turns a real GitHub **PR** into a code-fix (build) case
4
- or an **issue** into a triage case. It does the mechanical, reproducible
5
- extraction with `gh` + `git`; **you** refine the judgement parts. The result is a
6
- **git-source** case — no fixture repo is vendored; at run time the harness clones
7
- the repo into the gitignored `./.eval-cache/` and checks out `base_commit` (see
8
- the `instance-schema.md` "Git-source" flavor).
3
+ `lastlight-evals add-case --pr <url> --code-fix` turns a real GitHub **PR** into a
4
+ code-fix (build) case; `--issue <url>` turns an **issue** into a triage case. It
5
+ does the mechanical, reproducible extraction with `gh` + `git`; **you** refine the
6
+ judgement parts. The result is a **git-source** case — no fixture repo is
7
+ vendored; at run time the harness clones the repo into the gitignored
8
+ `./.eval-cache/` and checks out `base_commit` (see the `instance-schema.md`
9
+ "Git-source" flavor).
10
+
11
+ > A PR seeds two different evals. Use `--code-fix` (this doc) to hide the fix and
12
+ > have the agent reproduce it; use `--review` (see **`authoring-pr-review.md`**)
13
+ > to grade a review of the PR against its human review. `--pr` **requires** one of
14
+ > the two — it no longer defaults to code-fix.
9
15
 
10
16
  ## Two grading modes (default: suite)
11
17
 
@@ -34,7 +40,7 @@ the `instance-schema.md` "Git-source" flavor).
34
40
  ## Command
35
41
 
36
42
  ```bash
37
- lastlight-evals add-case --pr <github-pr-url> [options]
43
+ lastlight-evals add-case --pr <github-pr-url> --code-fix [options]
38
44
  lastlight-evals add-case --issue <github-issue-url> [options]
39
45
  ```
40
46
 
@@ -42,9 +48,10 @@ Options:
42
48
 
43
49
  | flag | meaning |
44
50
  |---|---|
45
- | `--pr <url>` | a GitHub PR url a **code-fix** (build) case |
51
+ | `--pr <url>` | a GitHub PR url (pair with `--code-fix` here, or `--review` for a pr-review case) |
52
+ | `--code-fix` | with `--pr` → a **code-fix** (build) case |
46
53
  | `--issue <url>` | a GitHub issue url → a **triage** case |
47
- | `--tier <name>` | target tier dir (default `code-fix` for `--pr`, `triage` for `--issue`) |
54
+ | `--tier <name>` | target tier dir (default `code-fix` for `--pr --code-fix`, `triage` for `--issue`) |
48
55
  | `--id <slug>` | `instance_id` (default derived from repo + number) |
49
56
  | `--datasets <dir>` | datasets root to write into (a `<tier>/` subdir). Default `./datasets`, else `./evals/datasets` |
50
57
  | `--overlay <dir>` | write into `<dir>/evals/datasets` instead |
@@ -57,8 +64,8 @@ Options:
57
64
 
58
65
  ## The recommended flow (CLI extracts → you refine)
59
66
 
60
- 1. **Dry-run first.** `add-case --pr <url> --dry-run` prints the proposed instance.
61
- The CLI derives:
67
+ 1. **Dry-run first.** `add-case --pr <url> --code-fix --dry-run` prints the proposed
68
+ instance. The CLI derives:
62
69
  - `repo`, `base_commit` (the **merge-base** of the base branch and the PR head —
63
70
  the true fork point, not the base-branch tip), and `head_commit`;
64
71
  - gold `patch` — the diff of the non-test files (reference only, never graded);
@@ -0,0 +1,110 @@
1
+ # Author a pr-review eval case from a real GitHub PR
2
+
3
+ `lastlight-evals add-case --pr <url> --review` turns a real GitHub **PR** into a
4
+ `pr-review` case: the PR's **human review is the gold set** the model's review is
5
+ scored against (precision / recall / F-beta, via an LLM judge). It does the
6
+ mechanical, reproducible extraction with `gh`; **you** curate the gold. The output
7
+ is **byte-compatible** with `scripts/import-martian.ts`, so cases you author sit
8
+ alongside the Martian Code Review Bench cases in the same `pr-review/instances.json`.
9
+
10
+ This is the path for *"I want to create a PR-review eval dataset from these gold
11
+ PRs"* — PRs whose human reviews are the standard you want a model (or an evolving
12
+ prompt/skill) to reproduce.
13
+
14
+ ## What it extracts
15
+
16
+ - **The `pr` fixture** — `base_ref`/`head_ref` + `base_commit`/`head_commit` (from
17
+ the PR's `baseRefOid`/`headRefOid`), `title`, `body` (truncated), `user`. At run
18
+ time the harness clones the repo and checks out the PR **head**; the review
19
+ workflow diffs `base..head`. No repo clone happens at author time.
20
+ - **A candidate `review_gold`** from the PR's *human* review: inline review
21
+ comments (`path` + `line` + body) and substantive top-level review bodies. The
22
+ CLI filters the obvious noise — reply threads, `LGTM`/approve-only comments, and
23
+ bot comments (unless `--include-bots`) — and defaults every entry's `severity`
24
+ to `medium` (GitHub comments carry none). Outdated comments (whose hunk moved)
25
+ are kept via `original_line` and flagged.
26
+
27
+ > **Anti-spoil.** The human review is written **only** into `review_gold` (the
28
+ > held-out judge gold). The CLI never puts it in `pr.reviews` / `pr.review_comments`
29
+ > — those seed the mocked GitHub the agent can read, which would hand it the
30
+ > answer. This mirrors `import-martian.ts`, and the run-time seeding
31
+ > (`seedWorkspacePrReview`) only checks out git, never the prior discussion.
32
+
33
+ ## Prerequisites
34
+
35
+ - `gh` on PATH and authenticated (`gh auth login`) — used to read PR metadata + review comments.
36
+ - Node 24+ (same as the rest of the harness). A **judge model** at run time
37
+ (`EVAL_JUDGE_MODEL`, else a strong default per provider key).
38
+
39
+ ## Command
40
+
41
+ ```bash
42
+ lastlight-evals add-case --pr <github-pr-url> --review [options]
43
+ ```
44
+
45
+ Options:
46
+
47
+ | flag | meaning |
48
+ |---|---|
49
+ | `--pr <url>` | a GitHub PR url (pair with `--review` here, or `--code-fix` for a build case) |
50
+ | `--review` | with `--pr` → a **pr-review** case (gold = the PR's human review) |
51
+ | `--severity <level>` | default severity for candidate gold comments (`low`\|`medium`\|`high`\|`critical`; default `medium`) |
52
+ | `--include-bots` | keep review comments from bots (default: skipped) |
53
+ | `--tier <name>` | target tier dir (default `pr-review`) |
54
+ | `--id <slug>` | `instance_id` (default `prreview__<repo>-<n>`) |
55
+ | `--datasets <dir>` | datasets root to write into (a `<tier>/` subdir). Default `./datasets`, else `./evals/datasets` |
56
+ | `--overlay <dir>` | write into `<dir>/evals/datasets` instead |
57
+ | `--dry-run` | print the proposed instance JSON + evidence block; don't write |
58
+
59
+ ## The recommended flow (CLI extracts → you refine)
60
+
61
+ 1. **Dry-run first.** `add-case --pr <url> --review --dry-run` prints the proposed
62
+ instance and an **evidence block** listing every candidate gold comment
63
+ (`author · file:line [severity] first-line`, tagged `(outdated)` / `(bot)`).
64
+ 2. **Read the evidence and curate `review_gold`** — this is the whole point of a
65
+ *gold* dataset:
66
+ - **Severity.** Every candidate defaults to `medium`. Set each to its real
67
+ impact (`critical`/`high`/`medium`/`low`) — the judge is severity-aware.
68
+ - **Prune noise.** Drop comments that aren't concrete findings — questions,
69
+ style nits, "why not X?", praise, anything `(outdated)` that no longer applies
70
+ to the head diff.
71
+ - **Add what the humans missed** (optional). If you know of a real issue the
72
+ human reviewer didn't post, add a `review_gold` entry by hand (`severity` +
73
+ `description`; `file`/`line` optional — the judge matches on substance).
74
+ - **Empty gold?** If the PR had no usable review comments, the CLI warns and
75
+ leaves `review_gold: []` — author it by hand from the PR diff, or the case
76
+ can't be judged.
77
+ 3. **Write it.** Re-run without `--dry-run` (add `--datasets <dir>` / `--overlay
78
+ <dir>` to target a workspace). The instance is appended to
79
+ `<root>/pr-review/instances.json` (creating `tier.json` if the tier is new);
80
+ re-running with the same PR **replaces by `instance_id`**, so curation is
81
+ idempotent.
82
+ 4. **Verify end-to-end** with the cheapest model — confirms the seed + judge
83
+ plumbing (needs a judge-model key):
84
+
85
+ ```bash
86
+ EVAL_INSTANCE=<instance_id> lastlight-evals run pr-review --model haiku
87
+ ```
88
+
89
+ Inspect the judge trace in the dashboard (the **judge** button) to see the
90
+ finding↔gold pairing behind the precision/recall/F score.
91
+
92
+ ## Authoring from a list of gold PRs
93
+
94
+ Run `add-case --pr <url> --review` **once per URL** — each appends into the same
95
+ `pr-review/instances.json`. Because `review_gold` curation is per-PR judgement,
96
+ do one curation pass per PR rather than a bulk import: dry-run → refine → write.
97
+ Spawning a **curation sub-agent per PR** (each handed one URL, returning the
98
+ curated instance) keeps the judgement isolated and parallelizes cleanly, while the
99
+ CLI's replace-by-id write makes accumulation safe.
100
+
101
+ ## Tuning knobs
102
+
103
+ - **`--severity <level>`** sets the default for *all* candidates in one PR — handy
104
+ when a PR's review is uniformly high- or low-stakes; you still refine per entry.
105
+ - **`--include-bots`** keeps bot review comments (CodeRabbit, Greptile, etc.).
106
+ Off by default because bot comments are noisy and rarely the human gold; include
107
+ them only if the bot's review *is* the standard you're grading against.
108
+
109
+ See `instance-schema.md` for the full `pr` / `review_gold` field reference and the
110
+ pr-review grading model.
@@ -44,12 +44,23 @@ Datasets are discovered from (overlay > user > built-in): `<overlay>/evals/datas
44
44
  "state": "open"
45
45
  },
46
46
  "triage_gold": { "category": "bug", "state": "ready-for-agent" }, // triage grading
47
+ "pr": { // pr-review: the PR fixture (base/head refs + SHAs)
48
+ "number": 37429, "title": "...", "body": "...",
49
+ "base_ref": "main", "head_ref": "feature-x",
50
+ "base_commit": "f3c8e8f...", "head_commit": "02f48f7...",
51
+ "user": "author" // do NOT put the human review here — see below
52
+ },
53
+ "review_gold": [ // pr-review: the held-out judge gold
54
+ { "file": "src/x.ts", "line": 42, "severity": "high", "description": "..." },
55
+ { "severity": "medium", "description": "..." } // file/line optional (judge matches on substance)
56
+ ],
47
57
  "expect_github": { // behavioral assertions on recorded GitHub calls
48
58
  "labels_added": ["bug"],
49
59
  "labels_absent": ["wontfix"],
50
60
  "issue_closed": false,
51
61
  "comment_matches": "(?i)thanks",
52
- "pr_opened": { "base": "main", "head_is_branch": true, "title_matches": "(?i)fix" }
62
+ "pr_opened": { "base": "main", "head_is_branch": true, "title_matches": "(?i)fix" },
63
+ "review_submitted": {} // pr-review: proxy check that a review was posted
53
64
  }
54
65
  }
55
66
  ```
@@ -83,6 +94,26 @@ hand-build these — use `lastlight-evals add-case --pr <url>` (see
83
94
  **`authoring-from-pr.md`**), which fills `base_commit`, `head_commit`,
84
95
  `test_patch`, and the verdicts for you.
85
96
 
97
+ ## Add a pr-review case
98
+
99
+ A pr-review instance has a **`pr`** fixture + a **`review_gold`** set and
100
+ `workflow: "pr-review"`. The `pr` fixture drives both the mocked PR endpoints and
101
+ the workspace checkout: at run time the harness checks out the PR **head**, and
102
+ the review workflow diffs `base..head`. `review_gold` is the held-out gold the
103
+ posted review is scored against by an LLM judge (each entry: `severity` ∈
104
+ `low`|`medium`|`high`|`critical` + `description`; `file`/`line` optional — the
105
+ judge matches on substance). Set `expect_github.review_submitted: {}` (a cheap
106
+ proxy that a review was posted).
107
+
108
+ > **Never** put the human/gold review in `pr.reviews` / `pr.review_comments` —
109
+ > those seed the mocked GitHub the agent can read, spoiling the case. The gold
110
+ > lives only in `review_gold`.
111
+
112
+ Don't hand-build these — use `lastlight-evals add-case --pr <url> --review` (see
113
+ **`authoring-pr-review.md`**), which pins the `pr` fixture and seeds a candidate
114
+ `review_gold` from the PR's human review for you to curate. Or bulk-import the
115
+ Martian Code Review Bench with `npx tsx scripts/import-martian.ts`.
116
+
86
117
  ## Add a custom tier
87
118
 
88
119
  Create `datasets/<tier-name>/` with `tier.json` (`name`, `defaultWorkflow`,
@@ -95,6 +126,11 @@ and `tests/<id>/`. Discovery auto-finds it — no code change. Run it with
95
126
  - **Behavioral:** did the workflow take the expected GitHub actions
96
127
  (`expect_github`)?
97
128
  - **Triage:** did the decision match `triage_gold`?
129
+ - **Review (pr-review):** an LLM judge matches the posted review's findings against
130
+ `review_gold` → **precision / recall / F-beta** (β via `EVAL_F_BETA` or
131
+ `--f-beta`; default F1). Needs a judge model (`EVAL_JUDGE_MODEL`, else a strong
132
+ default per provider key); independent of the model under test. The judge trace
133
+ is inspectable in the dashboard.
98
134
  - **Execution (code-fix)** — two modes:
99
135
  - **Suite (default).** Nothing held out: run the repo's own `test_cmd` against the
100
136
  agent's final tree, **resolved iff it exits 0**. Grades "did the agent leave the
@@ -0,0 +1,91 @@
1
+ ---
2
+ name: lastlight-guide
3
+ description: Orientation & router for the Last Light skills. Use ONLY when the user has NOT named a concrete Last Light task — i.e. they're unsure which skill/flow they need, ask "what can Last Light do / where do I start", say "help me with Last Light" with no specific goal, or want a guided tour across server / client / overlay / evals. Do NOT use when the ask already names a task — "set up/deploy a server" → lastlight-server, "connect/log in my CLI" → lastlight-client, "customize a workflow/prompt/persona/config" → lastlight-overlay, "run evals / compare models / author a case / build a PR-review dataset" → lastlight-evals: invoke that skill directly. This skill only routes and, when the goal is ambiguous, asks. Also invocable as /lastlight-guide.
4
+ version: 1.0.0
5
+ tags: [lastlight, guide, router, orientation, help]
6
+ ---
7
+
8
+ # Last Light — where do you want to go?
9
+
10
+ You don't need to know which skill you need — describe what you want and this
11
+ maps you onto it.
12
+
13
+ > **If the user already named a concrete task, don't linger here** — hand off to
14
+ > the matching skill immediately (see the menu below). This guide is for
15
+ > *"which one do I need?"*, not for doing the work.
16
+
17
+ There are two big things people do with Last Light:
18
+
19
+ - **Operate a deployment** — stand up the agent, connect to it, customize it.
20
+ - **Measure its quality** — run its real workflows as evals, compare models,
21
+ build datasets.
22
+
23
+ **If the user's goal is ambiguous, ask** (use `AskUserQuestion`) rather than
24
+ guessing which flow they mean — "are you setting up a server, connecting a CLI to
25
+ one, customizing workflows, or running evals?" Then hand off to the skill below;
26
+ each is a full runbook, so **invoke it and follow it** rather than re-deriving its
27
+ steps here.
28
+
29
+ ## Flow 1 — operate a Last Light deployment
30
+
31
+ The route from nothing to a running, customized agent. Do these in order the
32
+ first time; each is also usable on its own later.
33
+
34
+ 1. **`lastlight-server`** — install & configure the **server**: Docker stack, a
35
+ GitHub App, model provider key, and the repos it may manage. Start here to
36
+ stand one up for the first time. Config lives in a private **overlay** at
37
+ `instance/`.
38
+ 2. **`lastlight-client`** — point the `lastlight` **CLI** at an existing server
39
+ and log in (saves URL + token to `~/.lastlight/config.json`). For people who
40
+ *use* a server someone else runs — no Docker, no GitHub App.
41
+ 3. **`lastlight-overlay`** — create & customize the `instance/` **overlay**: fork
42
+ built-in **workflows**, **prompts**, **skills**, or the agent **persona**
43
+ (`agent-context`), and tune `config.yaml` — overriding only what you name,
44
+ layered over the packaged defaults. Reach for it whenever you want to change
45
+ *what the agent does or how it behaves* on an existing deployment.
46
+
47
+ ## Flow 2 — measure quality with Last Light Evals
48
+
49
+ Not required to run a deployment — this is how you **tell if a model or a
50
+ workflow/prompt change is any good** before shipping it.
51
+
52
+ - **`lastlight-evals`** — run Last Light's **real** workflows against a mocked
53
+ GitHub and grade them deterministically; compare models on pass rate / cost /
54
+ latency; author eval cases; **build a PR-review dataset from your own gold
55
+ PRs**. Its own front door lists the sub-flows (scaffold · run/compare · browse
56
+ past runs · author a case from a PR/issue · build a PR-review dataset). If the
57
+ user just hands you PR URLs and says "make a review eval set", that skill's
58
+ interactive flow prompts for the URLs and does the rest.
59
+
60
+ ## The bridge — overlay ↔ evals
61
+
62
+ The **overlay is shared** by both flows. `lastlight-evals --overlay <dir>` points
63
+ the harness at a *deployment's own* workflows **and** datasets, so you evaluate
64
+ exactly what you ship. The loop that ties it together:
65
+
66
+ > customize in **`lastlight-overlay`** → measure the change with
67
+ > **`lastlight-evals --overlay .`** → keep it or revert.
68
+
69
+ ## Quick menu — "I want to…"
70
+
71
+ | …do this | go to |
72
+ |---|---|
73
+ | Stand up / install / deploy a server for the first time | **`lastlight-server`** |
74
+ | Connect my CLI to a server / log in / run commands against it | **`lastlight-client`** |
75
+ | Customize a workflow, prompt, skill, or the agent's persona; tune config | **`lastlight-overlay`** |
76
+ | Run evals, compare models, browse past runs | **`lastlight-evals`** |
77
+ | Author an eval case from a GitHub PR or issue | **`lastlight-evals`** (§6) |
78
+ | Build a PR-review eval dataset from a list of gold PRs | **`lastlight-evals`** (§6) |
79
+
80
+ ## Preconditions (what every flow assumes)
81
+
82
+ - **Node 24+** and the CLI: `lastlight` (server/client/overlay) or
83
+ `lastlight-evals` (evals) — `npm i -g` either.
84
+ - **Docker + a GitHub App** — server only.
85
+ - **`gh` authenticated** — only for `lastlight-evals add-case` (reads real
86
+ PRs/issues); running evals mocks GitHub and needs no token.
87
+ - **A model provider API key** — server and evals (`OPENAI_API_KEY` /
88
+ `ANTHROPIC_API_KEY` / …).
89
+
90
+ Not sure which you have? Ask the user what they're trying to accomplish, confirm
91
+ the precondition for that flow, then hand off to the skill.