lastlight 0.9.0 → 0.10.1
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/dist/cli/cli-config.d.ts +7 -0
- package/dist/cli/cli-config.js +15 -0
- package/dist/cli/cli-config.js.map +1 -1
- package/dist/cli/cli-server.d.ts +7 -0
- package/dist/cli/cli-server.js +60 -15
- package/dist/cli/cli-server.js.map +1 -1
- package/dist/cli/cli.js +4 -2
- package/dist/cli/cli.js.map +1 -1
- package/dist/cli/setup.d.ts +14 -4
- package/dist/cli/setup.js +91 -30
- package/dist/cli/setup.js.map +1 -1
- package/dist/config/config.d.ts +24 -0
- package/dist/config/config.js +12 -0
- package/dist/config/config.js.map +1 -1
- package/dist/connectors/github-webhook.d.ts +11 -1
- package/dist/connectors/github-webhook.js +10 -17
- package/dist/connectors/github-webhook.js.map +1 -1
- package/dist/engine/agent-executor.js +16 -0
- package/dist/engine/agent-executor.js.map +1 -1
- package/dist/engine/chat/chat.d.ts +14 -0
- package/dist/engine/chat/chat.js +38 -0
- package/dist/engine/chat/chat.js.map +1 -1
- package/dist/engine/github/github-tools.d.ts +8 -2
- package/dist/engine/github/github-tools.js +4 -2
- package/dist/engine/github/github-tools.js.map +1 -1
- package/dist/index.js +71 -26
- package/dist/index.js.map +1 -1
- package/docker-compose.yml +5 -0
- package/package.json +1 -1
- package/plugins/lastlight/.claude-plugin/plugin.json +1 -1
- package/plugins/lastlight/skills/lastlight-evals-loop/SKILL.md +93 -42
- package/plugins/lastlight/skills/lastlight-evals-loop/references/approach.md +47 -0
- package/plugins/lastlight/skills/lastlight-evals-loop/references/guardrails.md +16 -2
- package/plugins/lastlight/skills/lastlight-evals-loop/references/journal-format.md +21 -10
|
@@ -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.
|
|
5
|
+
"version": "0.10.1",
|
|
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"
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: lastlight-evals-loop
|
|
3
|
-
description: Drive a Last Light EVAL toward a target score with a disciplined, anti-gaming improvement loop — run →
|
|
4
|
-
version: 1.
|
|
3
|
+
description: Drive a Last Light EVAL toward a target score with a disciplined, anti-gaming improvement loop — run → mine failures → propose candidate fix(es) → re-measure → keep the best or revert → repeat. Use when the user wants to "improve / raise the pr-review F1", "make the reviewer better against the eval", "close the loop on evals", "iterate on prompts/skills to pass more cases", or "tune the workflow to hit a score target". The loop diagnoses on a TRAIN split and validates on a BLIND held-out split so fixes must generalize, not overfit; it prefers generic overlay prompt/skill edits, and stops for human sign-off before editing any gold answer. For a one-off run/compare use lastlight-evals; to hand-fork a workflow/prompt use lastlight-overlay. Needs an already-scaffolded evals workspace (lastlight-evals) with a pr-review dataset.
|
|
4
|
+
version: 1.1.0
|
|
5
5
|
tags: [lastlight, evals, loop, improvement, overfitting, pr-review]
|
|
6
6
|
---
|
|
7
7
|
|
|
@@ -16,6 +16,11 @@ That lifts the number and ruins the reviewer. Every guardrail here exists to for
|
|
|
16
16
|
Scope: the **pr-review** tier (its judge trace gives you the agent-vs-gold detail
|
|
17
17
|
diagnosis needs). The pattern extends to triage/code-fix, but start here.
|
|
18
18
|
|
|
19
|
+
The method — **weakness-mine → propose a few minimal candidates → keep the one
|
|
20
|
+
that survives a blind held-out gate** — follows *Self-Harness: Harnesses That
|
|
21
|
+
Improve Themselves* ([arXiv:2606.09498](https://arxiv.org/abs/2606.09498)), adapted
|
|
22
|
+
to keep our anti-gaming discipline. See **references/approach.md** for the mapping.
|
|
23
|
+
|
|
19
24
|
## Prerequisites
|
|
20
25
|
|
|
21
26
|
- A scaffolded evals workspace with a **pr-review** dataset and a working provider
|
|
@@ -23,22 +28,25 @@ diagnosis needs). The pattern extends to triage/code-fix, but start here.
|
|
|
23
28
|
bare `lastlight-evals run pr-review --limit 1 --no-open` grades a case.
|
|
24
29
|
- An **`instance/` overlay** (the deployment overlay) to receive generic edits —
|
|
25
30
|
see **`lastlight-overlay`**. The loop edits copies here, never core.
|
|
26
|
-
-
|
|
27
|
-
|
|
31
|
+
- Two helpers ship with the evals package: **`scripts/mine-failures.ts`** (ranks
|
|
32
|
+
the TRAIN failure signatures into an evidence bundle — the diagnosis input) and
|
|
33
|
+
**`scripts/diff-runs.ts`** (compares two runs and calls keep/revert).
|
|
28
34
|
|
|
29
35
|
## The one rule
|
|
30
36
|
|
|
31
|
-
**One change per
|
|
32
|
-
|
|
33
|
-
moved the number and
|
|
37
|
+
**One change *kept* per round.** A round may *explore* a few minimal candidates,
|
|
38
|
+
but at most one is ever kept and committed to `instance/` — the rest are reverted.
|
|
39
|
+
So which edit moved the number is always attributable, and no overfit edit rides
|
|
40
|
+
along with a good one. Never keep two edits from one round without re-measuring
|
|
41
|
+
each in isolation.
|
|
34
42
|
|
|
35
43
|
## Start here
|
|
36
44
|
|
|
37
45
|
| You have… | Go to |
|
|
38
46
|
|---|---|
|
|
39
47
|
| Never run this loop on this dataset | **§1 Set up the split** then §2 |
|
|
40
|
-
| A split + baseline already recorded | **§3 Diagnose** |
|
|
41
|
-
|
|
|
48
|
+
| A split + baseline already recorded | **§3 Diagnose (mine failures)** |
|
|
49
|
+
| Candidate change(s) ready to test | **§5 Audit → §6 Apply → §7 Measure → §8 Decide** |
|
|
42
50
|
|
|
43
51
|
## 1. Set up the split (once per dataset)
|
|
44
52
|
|
|
@@ -54,7 +62,7 @@ lastlight-evals run pr-review --instance <all-ids> --no-open # or omit --insta
|
|
|
54
62
|
```
|
|
55
63
|
|
|
56
64
|
Set a **target**: an F1 goal (e.g. 0.55) or "improve until plateau" (N=3
|
|
57
|
-
consecutive no-keep
|
|
65
|
+
consecutive no-keep rounds).
|
|
58
66
|
|
|
59
67
|
## 2. Baseline
|
|
60
68
|
|
|
@@ -69,23 +77,41 @@ lastlight-evals run pr-review --overlay instance --instance <heldout-ids> --no-o
|
|
|
69
77
|
|
|
70
78
|
Each writes `eval-results/pr-review/<runId>/scorecard.json`. Note the two runIds.
|
|
71
79
|
|
|
72
|
-
## 3. Diagnose (TRAIN only)
|
|
73
|
-
|
|
74
|
-
Read the TRAIN scorecard's `results[].review` and `review.trace`. **Do not open
|
|
75
|
-
held-out traces.** For each failing case:
|
|
76
|
-
- `falseNegatives` (with `severity`) = **recall** loss — real issues the agent missed.
|
|
77
|
-
- `falsePositives` = **precision** loss — noise the agent posted that matched no gold.
|
|
80
|
+
## 3. Diagnose (TRAIN only) — mine the failure signatures
|
|
78
81
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
rubric says to suppress"*, *"confidence bar too low → noise"*, *"no awareness of the
|
|
82
|
-
repo's conventions → wrong-fit findings"*. See **references/levers.md** for how
|
|
83
|
-
each pattern maps to an edit.
|
|
82
|
+
Mine the TRAIN scorecard into a ranked **evidence bundle** — recall-loss and
|
|
83
|
+
precision-loss signatures ordered by impact — instead of reading traces by hand:
|
|
84
84
|
|
|
85
|
-
|
|
85
|
+
```bash
|
|
86
|
+
npx tsx scripts/mine-failures.ts <train-scorecard.json> --train <train-ids> --keywords
|
|
87
|
+
```
|
|
86
88
|
|
|
87
|
-
|
|
88
|
-
**
|
|
89
|
+
It reads only the TRAIN split (never held-out) and prints two ranked blocks:
|
|
90
|
+
- **RECALL LOSS** — missed gold (`falseNegatives`, weighted by `severity`): the
|
|
91
|
+
real issues the agent missed. Biggest F1 headroom is at the top.
|
|
92
|
+
- **PRECISION LOSS** — noise (`falsePositives`): findings that matched no gold.
|
|
93
|
+
|
|
94
|
+
Each signature is `axis·severity·area` with a frequency, case count, example ids,
|
|
95
|
+
and (with `--keywords`) a heuristic category guess. Take the **top systematic
|
|
96
|
+
pattern** — not a one-off — and name it: *"misses security-relevant findings"*,
|
|
97
|
+
*"posts style nits the rubric says to suppress"*, *"confidence bar too low →
|
|
98
|
+
noise"*, *"no awareness of the repo's conventions → wrong-fit findings"*. See
|
|
99
|
+
**references/levers.md** for how each pattern maps to an edit. (You can still open
|
|
100
|
+
individual TRAIN `review.trace`s to read a signature's underlying findings — just
|
|
101
|
+
never a held-out trace.)
|
|
102
|
+
|
|
103
|
+
## 4. Propose candidates — a few minimal, diverse edits
|
|
104
|
+
|
|
105
|
+
For the top signature, draft **K = 2–4 candidate edits**, each **minimal** (touches
|
|
106
|
+
only what the pattern needs) and each targeting a *different* mechanism or a
|
|
107
|
+
different formulation of the same one — e.g. one tightens the severity bar in the
|
|
108
|
+
`code-review` skill, another adds a confidence gate in the reviewer prompt. K stays
|
|
109
|
+
small on purpose: selecting the best of many candidates optimistically inflates the
|
|
110
|
+
train number, so keep the field narrow and let the held-out gate (§7b) be the check.
|
|
111
|
+
Drafting one candidate is fine — best-of-K is an option, not an obligation.
|
|
112
|
+
|
|
113
|
+
Every candidate uses the **lowest** lever that could move the cluster (full detail
|
|
114
|
+
in **references/levers.md**):
|
|
89
115
|
|
|
90
116
|
- **(a) generic — auto.** Edit an overlay prompt/skill/persona, or add a generic
|
|
91
117
|
`instance/repo-context/AGENTS.md` injected into every repo. Must be general.
|
|
@@ -95,55 +121,80 @@ Pick the **lowest** lever that could move the whole cluster (full detail in
|
|
|
95
121
|
- **(c) the eval itself — rare, signed-off.** Edit `review_gold[]` ONLY when the
|
|
96
122
|
gold is demonstrably wrong/incomplete; name the evidence. Human approves.
|
|
97
123
|
|
|
98
|
-
Escalate only when a lower lever genuinely can't address the pattern,
|
|
99
|
-
down why.
|
|
124
|
+
Escalate a candidate only when a lower lever genuinely can't address the pattern,
|
|
125
|
+
and write down why.
|
|
100
126
|
|
|
101
|
-
## 5. Audit
|
|
127
|
+
## 5. Audit each candidate (adversarial sub-agent)
|
|
102
128
|
|
|
103
|
-
Before
|
|
104
|
-
in **references/guardrails.md**). It **REJECTS** if the change:
|
|
129
|
+
Before measuring, run the **generality + leak auditor** sub-agent (prompt template
|
|
130
|
+
in **references/guardrails.md**) on **every** candidate. It **REJECTS** if the change:
|
|
105
131
|
- names a specific repo / `instance_id` / file path (lever a must be generic), or
|
|
106
132
|
- **encodes the gold answer** — injected repo context that describes the specific
|
|
107
133
|
findings is cheating. It must read as plausible maintainer guidance written
|
|
108
134
|
*without* knowledge of this PR's bug (conventions, architecture, review
|
|
109
135
|
priorities), never "look for bug X".
|
|
110
136
|
|
|
111
|
-
Rejected
|
|
137
|
+
Rejected candidates are dropped (not counted); survivors go to §6. If none survive,
|
|
138
|
+
back to §4.
|
|
112
139
|
|
|
113
140
|
## 6. Apply (hybrid autonomy)
|
|
114
141
|
|
|
142
|
+
Apply each surviving candidate on its **own throwaway branch** (or stash between
|
|
143
|
+
candidates) so their §7a measurements don't cross-contaminate — only the winner is
|
|
144
|
+
committed in §8.
|
|
145
|
+
|
|
115
146
|
- **Lever (a)** (incl. generic `repo-context/AGENTS.md`): apply automatically to
|
|
116
147
|
`instance/…` once the auditor passes.
|
|
117
148
|
- **Lever (b)/(c)**: **STOP.** Present the diff + the written justification and ask
|
|
118
149
|
the human to approve before writing to the dataset.
|
|
119
150
|
|
|
120
|
-
## 7. Re-measure
|
|
151
|
+
## 7. Re-measure — train selects, held-out confirms **once**
|
|
152
|
+
|
|
153
|
+
The blind held-out set must be consumed **once per round**, not once per candidate —
|
|
154
|
+
gating every candidate on held-out and keeping the best would inflate it (max-of-K
|
|
155
|
+
selection bias). So split measurement in two:
|
|
156
|
+
|
|
157
|
+
**7a. Rank candidates on TRAIN only.** Run each survivor on the TRAIN split and diff
|
|
158
|
+
*without* `--heldout` (the verdict prints `REVIEW — no held-out`, expected here):
|
|
159
|
+
|
|
160
|
+
```bash
|
|
161
|
+
npx tsx scripts/diff-runs.ts <baseline-train.json> <candidate-train.json> --train <train-ids>
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
Pick **one winner**: highest train Δ → tie-break lowest lever → smallest diff →
|
|
165
|
+
fewest per-case train regressions. **Do not touch held-out in 7a.**
|
|
121
166
|
|
|
122
|
-
|
|
167
|
+
**7b. Confirm the winner on HELD-OUT, once.** Run the winner on both splits and diff
|
|
168
|
+
with the full gate:
|
|
123
169
|
|
|
124
170
|
```bash
|
|
125
|
-
npx tsx scripts/diff-runs.ts <baseline
|
|
171
|
+
npx tsx scripts/diff-runs.ts <baseline.json> <winner.json> \
|
|
126
172
|
--train <train-ids> --heldout <heldout-ids>
|
|
127
173
|
```
|
|
128
174
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
175
|
+
(Run the two splits in one `--instance <all-ids>` run so a single scorecard holds
|
|
176
|
+
both.) If a candidate may legitimately be held-out-driven with flat train, add
|
|
177
|
+
`--symmetric` for the paper's non-regressive gate (KEEP iff neither split regresses
|
|
178
|
+
and one improves); record which gate you used. With a single candidate, 7a and 7b
|
|
179
|
+
collapse into one gated run.
|
|
132
180
|
|
|
133
181
|
## 8. Decide
|
|
134
182
|
|
|
135
|
-
- **KEEP** iff train F1 improved **and** held-out did **not** regress
|
|
136
|
-
verdict). Train ↑ with held-out ↓ = **overfit → revert**.
|
|
183
|
+
- **KEEP** the winner iff its train F1 improved **and** held-out did **not** regress
|
|
184
|
+
(the helper's verdict). Train ↑ with held-out ↓ = **overfit → revert**.
|
|
137
185
|
- **Lever (b)** per-repo edits are case-scoped: keep iff that case improved, the
|
|
138
186
|
auditor passed, and the human approved — recorded as a per-repo recommendation,
|
|
139
187
|
not a workflow change (no held-out claim is made for it).
|
|
140
|
-
-
|
|
188
|
+
- **Revert the K−1 losers** and, on a REVERT verdict, the winner too: `git checkout`
|
|
189
|
+
the overlay file, or remove the sidecar. Exactly one edit (or none) survives the
|
|
190
|
+
round — that is the "one change kept per round" rule.
|
|
141
191
|
|
|
142
192
|
## 9. Journal, then repeat
|
|
143
193
|
|
|
144
|
-
Append one entry per
|
|
145
|
-
pattern,
|
|
146
|
-
running best. Then return to §3. Stop at
|
|
194
|
+
Append one entry per **round** (schema in **references/journal-format.md**): the
|
|
195
|
+
mined pattern, the K candidates with each one's train Δ, which won, the winner's
|
|
196
|
+
single held-out Δ, the decision, and the running best. Then return to §3. Stop at
|
|
197
|
+
the target or the plateau (N=3 consecutive no-keep rounds).
|
|
147
198
|
|
|
148
199
|
Run the loop on a cadence with the built-in `/loop` if you want it to keep going
|
|
149
200
|
unattended between your check-ins — but the lever-(b)/(c) sign-off stops still
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# Approach & prior art — why the loop looks like this
|
|
2
|
+
|
|
3
|
+
This loop is a **self-improving harness**: it edits the reviewing agent's harness
|
|
4
|
+
(prompts, skills, persona, injected repo-context) — never its weights and never the
|
|
5
|
+
core workflow — and keeps only edits that a blind held-out split confirms.
|
|
6
|
+
|
|
7
|
+
## Prior art: *Self-Harness*
|
|
8
|
+
|
|
9
|
+
The structure follows ***Self-Harness: Harnesses That Improve Themselves***
|
|
10
|
+
([arXiv:2606.09498](https://arxiv.org/abs/2606.09498)), which runs a three-stage
|
|
11
|
+
cycle on a fixed model: **mine weaknesses → propose K minimal candidate edits →
|
|
12
|
+
validate on held-in *and* held-out under a non-regressive gate**, keeping only edits
|
|
13
|
+
that don't degrade either split. Its notable result: the retained edits are
|
|
14
|
+
concrete and evidence-grounded, "not generic instruction padding."
|
|
15
|
+
|
|
16
|
+
We adopt the parts that make our loop better-grounded and better-explored, and
|
|
17
|
+
deliberately *diverge* where our anti-gaming constraints are stricter than the
|
|
18
|
+
paper's.
|
|
19
|
+
|
|
20
|
+
| Self-Harness stage | Here | Where |
|
|
21
|
+
|---|---|---|
|
|
22
|
+
| Weakness mining (cluster failing traces by signature, ranked by impact) | `scripts/mine-failures.ts` → ranked recall/precision signature bundle from TRAIN traces | SKILL §3 |
|
|
23
|
+
| K diverse minimal candidate edits | Draft K=2–4 minimal candidates, each a different mechanism/formulation | SKILL §4 |
|
|
24
|
+
| Validate on both splits, non-regressive gate | **TRAIN selects, HELD-OUT confirms once**; default asymmetric gate, opt-in `--symmetric` for the paper's rule | SKILL §7, `diff-runs.ts` |
|
|
25
|
+
| Document each transition | The per-round journal (all candidates + winner + held-out Δ) | `journal-format.md` |
|
|
26
|
+
|
|
27
|
+
## Where we diverge from the paper (on purpose)
|
|
28
|
+
|
|
29
|
+
- **Held-out is consumed once per round, not once per candidate.** The paper gates
|
|
30
|
+
each candidate on held-out. Because our loop can *see* the gold set, screening K
|
|
31
|
+
candidates on the blind split and keeping the best would inflate it (max-of-K
|
|
32
|
+
selection bias). So we rank on TRAIN only and give the single winner one held-out
|
|
33
|
+
confirmation. See guardrails §2.
|
|
34
|
+
- **Generic-first, not model-specific.** The paper found value in *model-specific*
|
|
35
|
+
harness edits. Our default lever must generalize across **repos** (the held-out
|
|
36
|
+
split is a repo split), so we prefer generic overlay edits and gate them on
|
|
37
|
+
held-out. A model-specific-but-repo-generic lever is a possible future escalation,
|
|
38
|
+
but it is **not** part of this loop today — don't reach for it.
|
|
39
|
+
- **A leak/generality auditor gates every candidate.** The paper relies on the
|
|
40
|
+
held-out gate alone; we add an adversarial auditor (guardrails §3) because a loop
|
|
41
|
+
that can read the gold answer can encode it — a failure mode the paper's setup
|
|
42
|
+
doesn't face.
|
|
43
|
+
- **Human sign-off on the game-able levers.** Per-repo context (b) and gold edits
|
|
44
|
+
(c) are case-scoped with no held-out claim, so a human ratifies them.
|
|
45
|
+
|
|
46
|
+
The net: same mine → propose → validate skeleton, hardened for a loop that can see
|
|
47
|
+
the answers it is being graded against.
|
|
@@ -15,10 +15,18 @@ not override it by eyeballing train alone.
|
|
|
15
15
|
The split ids are fixed for the whole loop. If you re-split (e.g. to add cases),
|
|
16
16
|
say so in the journal and treat prior held-out results as no longer comparable.
|
|
17
17
|
|
|
18
|
-
## 2. One change per
|
|
18
|
+
## 2. One change *kept* per round
|
|
19
19
|
|
|
20
20
|
Isolates causal effect. If two edits ship together and the number moves, you can't
|
|
21
|
-
attribute it — and you can't tell an overfit edit riding along with a good one.
|
|
21
|
+
attribute it — and you can't tell an overfit edit riding along with a good one. A
|
|
22
|
+
round may *explore* K=2–4 minimal candidates, but each is measured on its own
|
|
23
|
+
branch and at most one is kept.
|
|
24
|
+
|
|
25
|
+
**Best-of-K must not consume the blind split K times.** Selecting the best of many
|
|
26
|
+
candidates on held-out inflates it (max-of-K selection bias). So candidates are
|
|
27
|
+
ranked on **TRAIN only**; the single winner gets **one** held-out confirmation.
|
|
28
|
+
Keep K small — the more candidates you screen on train, the more optimistic the
|
|
29
|
+
winner's train number, and only the one held-out run keeps it honest.
|
|
22
30
|
|
|
23
31
|
## 3. The generality + leak auditor (adversarial sub-agent)
|
|
24
32
|
|
|
@@ -72,8 +80,14 @@ and why the number moved — no silent wins.
|
|
|
72
80
|
## The keep/revert decision, precisely
|
|
73
81
|
|
|
74
82
|
```
|
|
83
|
+
best-of-K selection (per round, before the gate below):
|
|
84
|
+
rank surviving candidates on TRAIN ONLY -> winner = highest trainΔ
|
|
85
|
+
(tie-break: lowest lever, smallest diff, fewest train per-case regressions)
|
|
86
|
+
then apply the gate below to the WINNER, consuming held-out ONCE.
|
|
75
87
|
lever (a) generic:
|
|
76
88
|
KEEP iff trainΔ > epsilon AND heldoutΔ >= -epsilon (else REVERT)
|
|
89
|
+
(--symmetric variant, for a held-out-driven candidate:
|
|
90
|
+
KEEP iff trainΔ >= -epsilon AND heldoutΔ >= -epsilon AND max(both) > epsilon)
|
|
77
91
|
lever (b) per-repo:
|
|
78
92
|
KEEP iff that case improved AND auditor ACCEPTED AND human approved
|
|
79
93
|
(recorded as a per-repo recommendation; no held-out claim)
|
|
@@ -19,31 +19,42 @@ moved — keep it complete even for reverted iterations (a revert is a result).
|
|
|
19
19
|
- Baseline: train F1 = 0.33, heldout F1 = 0.31 (runIds: <train>, <heldout>)
|
|
20
20
|
```
|
|
21
21
|
|
|
22
|
-
## Per-
|
|
22
|
+
## Per-round entry
|
|
23
|
+
|
|
24
|
+
A round mines one pattern, explores K candidates (ranked on TRAIN), and keeps at
|
|
25
|
+
most one (confirmed on HELD-OUT once). A single-candidate round is just K=1.
|
|
23
26
|
|
|
24
27
|
```markdown
|
|
25
|
-
##
|
|
28
|
+
## Round <N> — <one-line hypothesis for the top pattern>
|
|
26
29
|
|
|
27
|
-
- Pattern: <the systematic failure named in §3, e.g. "
|
|
28
|
-
-
|
|
29
|
-
|
|
30
|
+
- Pattern: <the systematic failure named in §3, e.g. "misses security-relevant findings (recall·high, 4 train cases)"; from mine-failures.ts>
|
|
31
|
+
- Candidates (ranked on TRAIN only):
|
|
32
|
+
| # | lever | change (file) | trainΔ | auditor |
|
|
33
|
+
|---|-------|---------------|--------|---------|
|
|
34
|
+
| 1 | (a) | instance/skills/code-review/SKILL.md | +0.08 | ACCEPT |
|
|
35
|
+
| 2 | (a) | instance/workflows/prompts/reviewer.md | +0.03 | ACCEPT |
|
|
36
|
+
| 3 | (a) | instance/repo-context/AGENTS.md | -0.01 | REJECT (leak) |
|
|
37
|
+
- Winner: #1 — <why (highest trainΔ; tie-break rule if used)>
|
|
38
|
+
- Winner change:
|
|
30
39
|
file: instance/skills/code-review/SKILL.md
|
|
31
40
|
diff: |
|
|
32
41
|
<the actual diff, or the injected-context text>
|
|
33
|
-
- Auditor: ACCEPT | REJECT — <one-line reason>
|
|
34
42
|
- Applied: auto | human-approved (<who/when>) | not applied (auditor rejected)
|
|
35
|
-
-
|
|
43
|
+
- Held-out confirmation (diff-runs.ts, winner only — held-out consumed ONCE):
|
|
44
|
+
gate: default | --symmetric
|
|
36
45
|
train: 0.33 -> 0.41 (Δ +0.08)
|
|
37
46
|
heldout: 0.31 -> 0.31 (Δ +0.00)
|
|
38
|
-
per-case regressions: 0
|
|
47
|
+
per-case regressions: 0 (REGRESSED(train): none)
|
|
39
48
|
- Decision: KEEP | REVERT | (b) recorded as per-repo recommendation
|
|
49
|
+
- Reverted losers: #2, #3
|
|
40
50
|
- Running best: train F1 = 0.41, heldout F1 = 0.31
|
|
41
51
|
```
|
|
42
52
|
|
|
43
53
|
## Rules
|
|
44
54
|
|
|
45
|
-
- **One entry per
|
|
46
|
-
of no-keep
|
|
55
|
+
- **One entry per round**, including all-revert rounds and auditor rejections — the
|
|
56
|
+
tail of no-keep rounds is the plateau signal. Record every candidate's train Δ,
|
|
57
|
+
not just the winner's, so the best-of-K selection is auditable.
|
|
47
58
|
- Paste the **actual diff / context text**, not a paraphrase — the point is
|
|
48
59
|
reproducibility.
|
|
49
60
|
- Always record **both** train and held-out deltas. A missing held-out number
|