pi-lens 4.4.2 → 4.4.4
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/CHANGELOG.md +306 -0
- package/README.md +13 -1
- package/dist/{chunk-VITUCP5A.js → chunk-24AKHFGP.js} +9 -7
- package/dist/{chunk-JSQFTSC6.js → chunk-2FN63LPV.js} +11 -11
- package/dist/{chunk-CF24OIYI.js → chunk-2KXTHF3M.js} +20 -20
- package/dist/{chunk-ESBQHFMJ.js → chunk-3DA2JDOL.js} +543 -349
- package/dist/{chunk-RWWYJ623.js → chunk-3KAZU3VR.js} +1 -1
- package/dist/chunk-3PTHXJXR.js +28 -0
- package/dist/chunk-3QED2P4V.js +31 -0
- package/dist/{chunk-N2H3ZPZY.js → chunk-3RKP3FMS.js} +1 -0
- package/dist/{chunk-XVF2VVXP.js → chunk-5HSRT26B.js} +2 -2
- package/dist/{chunk-XKIZ2HNN.js → chunk-5IUSNGOC.js} +18 -16
- package/dist/{chunk-EJIUXPBX.js → chunk-5OFV52AM.js} +1 -1
- package/dist/{chunk-AW7R2GWG.js → chunk-5VSF4UUQ.js} +12 -7
- package/dist/{chunk-NW7BOILN.js → chunk-5WRPDP2A.js} +18 -18
- package/dist/{chunk-7ULNCDCO.js → chunk-6DLWKFEX.js} +35 -34
- package/dist/{chunk-WOA4LN2R.js → chunk-7D6L4MTX.js} +2 -2
- package/dist/{chunk-GAEGEPOC.js → chunk-7HXE67BN.js} +2 -2
- package/dist/chunk-AGSS7277.js +84 -0
- package/dist/{chunk-R3PCY3YS.js → chunk-AMERCH6V.js} +13 -13
- package/dist/{chunk-WU567RSC.js → chunk-ATKJFDQN.js} +14 -10
- package/dist/{chunk-VSSBEUFT.js → chunk-AWSCPCN2.js} +16 -16
- package/dist/{chunk-VCHXCQFG.js → chunk-BWD5EPKO.js} +3 -3
- package/dist/{chunk-ODBNXWT4.js → chunk-CT4MN5IU.js} +1271 -262
- package/dist/{chunk-34WSVGEM.js → chunk-CUHSHSB6.js} +83 -5
- package/dist/{chunk-CHOW74WE.js → chunk-CYRKQRPM.js} +7 -10
- package/dist/{chunk-Q7DUK4LX.js → chunk-DEL2U6CM.js} +5 -5
- package/dist/{chunk-6C7JWPCP.js → chunk-DGUKIYSI.js} +26 -23
- package/dist/{chunk-PHDMFAKM.js → chunk-DUO2TU77.js} +2 -2
- package/dist/{chunk-MRXKYPCS.js → chunk-EBC36LNN.js} +2 -2
- package/dist/chunk-ED36RF6Y.js +17 -0
- package/dist/{chunk-76MWC2K6.js → chunk-EUXZEFTV.js} +90 -97
- package/dist/{chunk-QOZXJ4NA.js → chunk-FM4RDMKT.js} +11 -8
- package/dist/{chunk-66VMUL7Q.js → chunk-GAQ7OQG6.js} +31 -28
- package/dist/{chunk-Q6ZWTCLY.js → chunk-GL5LUMZE.js} +23 -24
- package/dist/{chunk-BKE7E7TC.js → chunk-GMX5OS7B.js} +9 -9
- package/dist/{chunk-ZHFZWTZV.js → chunk-GSLNCYGG.js} +11 -11
- package/dist/{chunk-ARJ6PLFH.js → chunk-GSM5UU7A.js} +26 -34
- package/dist/{chunk-724UL2TJ.js → chunk-GXFV6MYU.js} +3 -3
- package/dist/chunk-HAD7QRQI.js +30 -0
- package/dist/{chunk-QOBUHWHX.js → chunk-HRNHZA3N.js} +6 -6
- package/dist/{chunk-VWCXW2E7.js → chunk-HWCCCQNX.js} +1 -1
- package/dist/{chunk-7DYBLXYA.js → chunk-HYGZEMX6.js} +3 -3
- package/dist/chunk-IJYGIDF4.js +186 -0
- package/dist/{chunk-4W4VLAPJ.js → chunk-IQWN5JCP.js} +11 -11
- package/dist/{chunk-GZYBXISR.js → chunk-IUE7SSKV.js} +9 -9
- package/dist/{chunk-IBGIOBEE.js → chunk-IWDLU6K3.js} +68 -5
- package/dist/{chunk-XCJN5IJU.js → chunk-IYNJ6YPZ.js} +4 -4
- package/dist/{chunk-JAU72XNY.js → chunk-J64T55EI.js} +3 -3
- package/dist/{chunk-2BBLFX75.js → chunk-J6MPGQTS.js} +5 -5
- package/dist/chunk-JORED7EX.js +44 -0
- package/dist/{chunk-6SDEP3AJ.js → chunk-JUKMK5Y4.js} +8 -8
- package/dist/{chunk-IBRALRBR.js → chunk-JW3YWBVB.js} +15 -14
- package/dist/{chunk-L3BLXZG7.js → chunk-KAPJINKN.js} +30 -69
- package/dist/{chunk-2B73ZPOK.js → chunk-KN35K52N.js} +3 -3
- package/dist/{chunk-C34ZXZ7O.js → chunk-KUA4OJ5Y.js} +24 -11
- package/dist/chunk-KYUB6QDC.js +72 -0
- package/dist/{chunk-67WMNWEE.js → chunk-LLJNQKQW.js} +12 -10
- package/dist/chunk-LZSEQW6A.js +57 -0
- package/dist/{chunk-ZANLILYD.js → chunk-M2IFVFWU.js} +2 -2
- package/dist/chunk-M2UD3LPU.js +88 -0
- package/dist/{chunk-WOKKRCJ5.js → chunk-MBKQHGA7.js} +15 -14
- package/dist/{chunk-P7266HLM.js → chunk-MPNJLASA.js} +2 -2
- package/dist/{chunk-6GFRNVYR.js → chunk-MZGQNL3Y.js} +10 -10
- package/dist/{chunk-QZVW3AAK.js → chunk-N5FLEO7W.js} +33 -31
- package/dist/{chunk-3JNKMP3B.js → chunk-O4NWQT6I.js} +4 -4
- package/dist/{chunk-PFNSLWU5.js → chunk-OHKJ7PQF.js} +33 -31
- package/dist/{chunk-VRZP76YM.js → chunk-P63GXC37.js} +4 -1
- package/dist/{chunk-XTMJ7XDT.js → chunk-POMLXPMY.js} +1 -1
- package/dist/{chunk-QQNQ7SJW.js → chunk-QBFBRV2B.js} +10 -4
- package/dist/{chunk-3UUPUE3O.js → chunk-R3T7CLQ2.js} +84 -60
- package/dist/{chunk-23WOO7TX.js → chunk-R7YOCSNV.js} +10 -10
- package/dist/{chunk-2CD5RS6M.js → chunk-RKBXZN3A.js} +23 -2
- package/dist/{chunk-OG5UUPN7.js → chunk-RKKOYPRA.js} +14 -14
- package/dist/{chunk-52FUZI6K.js → chunk-RMLC67LF.js} +1 -1
- package/dist/{chunk-XMSXXAHW.js → chunk-ROYSX2S5.js} +2 -2
- package/dist/{chunk-PV6LR5P5.js → chunk-RVK72CZX.js} +9605 -14776
- package/dist/{chunk-FLKWCIZH.js → chunk-S2HEXIWI.js} +5 -5
- package/dist/{chunk-UZ3TUTRV.js → chunk-S67KYG37.js} +1 -1
- package/dist/{chunk-JWA5I3SR.js → chunk-SD4I7ZO4.js} +16 -18
- package/dist/{chunk-Z527N6YQ.js → chunk-SKAMFC7A.js} +12 -12
- package/dist/{chunk-MQLUAEOC.js → chunk-SRYEJNES.js} +2 -2
- package/dist/{chunk-BRGDSBJE.js → chunk-SYE6T2EB.js} +12 -12
- package/dist/{chunk-GXW6K4YJ.js → chunk-T57LYLZT.js} +1 -1
- package/dist/{chunk-ZXYDQ3TZ.js → chunk-T7FEBKXN.js} +48 -15
- package/dist/{chunk-IXXDFY73.js → chunk-TIQ2PKDW.js} +3 -3
- package/dist/{chunk-QILIYSJF.js → chunk-TLX72JTG.js} +1 -1
- package/dist/{chunk-TYM6OUIT.js → chunk-TOY6QKOH.js} +12 -12
- package/dist/{chunk-IZSHAIJ7.js → chunk-TRETHTQO.js} +12 -12
- package/dist/{chunk-3VPVG5SU.js → chunk-U44DJXQP.js} +10 -6
- package/dist/{chunk-PNQDPDRC.js → chunk-UA7ZXYDR.js} +1 -1
- package/dist/{chunk-OXXKQCSV.js → chunk-UBOQLVT2.js} +4 -4
- package/dist/{chunk-QGQ5CCCG.js → chunk-UMS2MFPZ.js} +2 -2
- package/dist/{chunk-QHJ6DQ2R.js → chunk-US7ECLD7.js} +55 -13
- package/dist/{chunk-EETY4LF7.js → chunk-UZ2XCLYS.js} +8 -8
- package/dist/chunk-V35JG4JB.js +2667 -0
- package/dist/{chunk-N3X6Q4YT.js → chunk-VOOAPROD.js} +3 -3
- package/dist/{chunk-SAEFPSB6.js → chunk-W66O5E25.js} +21 -11
- package/dist/{chunk-KBG47GHP.js → chunk-WMYE35PX.js} +15 -11
- package/dist/{chunk-5NGR67U5.js → chunk-XBJVAEEO.js} +32 -5
- package/dist/chunk-XHJBS436.js +4217 -0
- package/dist/{chunk-GBPP5P7X.js → chunk-XTBDCR27.js} +4 -4
- package/dist/{chunk-4UNXBNE2.js → chunk-XTFDJI3T.js} +11 -11
- package/dist/{chunk-UXGETRP4.js → chunk-XYURS6EN.js} +13 -12
- package/dist/{chunk-RPLINGVB.js → chunk-Y6GZHWSJ.js} +6 -6
- package/dist/{chunk-2ZGIZPDG.js → chunk-YCWYO6TQ.js} +41 -38
- package/dist/{chunk-66SXUJCA.js → chunk-YH5MVY2U.js} +10 -8
- package/dist/{chunk-AOHZU2BM.js → chunk-YNE3RP52.js} +1 -1
- package/dist/{chunk-GOYRYZ2R.js → chunk-ZHH37KZL.js} +72 -20
- package/dist/{chunk-ZGDGW2V3.js → chunk-ZIVJBOO3.js} +2 -2
- package/dist/{chunk-GHB6AYCP.js → chunk-ZVUL7QYY.js} +29 -28
- package/dist/index.js +11559 -6213
- package/dist/mcp/analyze-cli.js +10 -9
- package/dist/mcp/cli.js +41 -38
- package/dist/mcp/server.js +1142 -495
- package/dist/mcp/worker.js +61 -57
- package/dist/probes/installer.js +19 -19
- package/dist/workers/project-snapshot-persist-worker.js +28 -9
- package/dist/workers/review-graph-persist-worker.js +1 -1
- package/docs/configuration.md +11 -0
- package/docs/engineering-principles.md +32 -0
- package/docs/lsp-capability-matrix.md +1 -1
- package/docs/lsp-idle-eviction.md +15 -26
- package/docs/pi-lens-fixer.md +117 -13
- package/docs/pi-lens-merge-policy.md +109 -11
- package/docs/pi-lens-monitor.md +8 -2
- package/docs/pi-lens-retro.md +4 -1
- package/docs/pi-lens-reviewer.md +114 -3
- package/docs/pi-lens-subagent.md +27 -14
- package/docs/release-qa-baseline.md +3 -1
- package/docs/servercapabilities.md +9 -19
- package/package.json +7 -5
- package/scripts/download-grammars.js +40 -7
- package/scripts/lib/latency-log-phases.mjs +95 -0
- package/scripts/rpc-load-check.mjs +570 -81
- package/dist/chunk-3WA4HP4I.js +0 -55
- package/dist/chunk-466Z26MG.js +0 -30
- package/dist/chunk-5JM2524W.js +0 -84
- package/dist/chunk-CO2G5PHH.js +0 -84
- package/dist/chunk-LOP6GRPH.js +0 -31
- package/dist/chunk-UOPVJQ4N.js +0 -103
- package/dist/chunk-XPZPXCBV.js +0 -28
- /package/dist/{chunk-FC4RP4I2.js → chunk-6HWVI6MI.js} +0 -0
|
@@ -30,7 +30,9 @@ moved lines; include only structural views that changed.
|
|
|
30
30
|
1. **Review.** Spawn `pi-lens-reviewer` (worktree isolation) with the PR
|
|
31
31
|
number, a one-paragraph summary of the claim, and any PR-specific attack
|
|
32
32
|
angles. Self-authored and small PRs get reviewed too — the depth follows
|
|
33
|
-
the review tier below, never the priority label.
|
|
33
|
+
the review tier below, never the priority label. Bots review the PR as well:
|
|
34
|
+
every bot thread (Greptile and others) gets a disposition reply, `fixed in
|
|
35
|
+
<sha>`, `accepted and disclosed`, or `rejected because <reason>`.
|
|
34
36
|
2. **Fix rounds.** Send findings back to the PR's original author agent when
|
|
35
37
|
its worktree survives (SendMessage — cheapest context); otherwise spawn
|
|
36
38
|
`pi-lens-fixer` on the branch with the findings inlined.
|
|
@@ -75,7 +77,8 @@ moved lines; include only structural views that changed.
|
|
|
75
77
|
sweeps is not green — run the sweep on the merge before merging. Apply
|
|
76
78
|
AGENTS.md's one mutation layer (#4005): new-guard proof and demonstrated
|
|
77
79
|
correctness gaps gate the merge. `ci-verdict` prints no mutation line, and
|
|
78
|
-
the nightly Stryker report is not a merge input.
|
|
80
|
+
the nightly Stryker report is not a merge input. Every bot review thread
|
|
81
|
+
carries its disposition reply and is resolved before the merge.
|
|
79
82
|
5. **Merge.** `gh pr merge <N> --merge` (merge commit, repo convention).
|
|
80
83
|
If "not up to date", `gh api -X PUT .../pulls/<N>/update-branch`, wait for
|
|
81
84
|
CI, re-gate, merge. On GitHub 503s: retry with backoff, never switch to
|
|
@@ -160,6 +163,18 @@ blocks dispatch above the thresholds (no hand-written fallback;
|
|
|
160
163
|
every refill; state them in the lane ledger. Standing rule from
|
|
161
164
|
2026-09-03, lifted only when the maintainer says so.
|
|
162
165
|
|
|
166
|
+
## Host capacity (orchestrator)
|
|
167
|
+
|
|
168
|
+
The maintainer may cap how many subagents run at once, for example when RAM is
|
|
169
|
+
shared with a local model. This is a machine-load cap, separate from
|
|
170
|
+
`PI_LENS_TEST_MAX_WORKERS` and from Git authority. A lane counts by what it
|
|
171
|
+
runs, not by its role or brief wording: any agent that runs a build, Vitest, a
|
|
172
|
+
language server or a probe counts, including an investigator that reproduces
|
|
173
|
+
through a probe and a Git-read-only reviewer. Agents that only read files and
|
|
174
|
+
call `gh`, grep or Explore never count and run in parallel with the capped
|
|
175
|
+
lanes; their brief says "no builds, no tests, no language servers, no probes"
|
|
176
|
+
(maintainer, 2026-10-14).
|
|
177
|
+
|
|
163
178
|
## Brief contract (orchestrator)
|
|
164
179
|
|
|
165
180
|
Before dispatching any issue that adds a shared helper or seam: grep for
|
|
@@ -191,8 +206,27 @@ exactly one `priority:p1|p2|p3` (AGENTS.md #1676 rubric). The priority labels
|
|
|
191
206
|
were found deleted from the repo on 2026-09-03 and recreated (#2553); an
|
|
192
207
|
issue filed without one is a triage defect, not a shortcut.
|
|
193
208
|
|
|
194
|
-
|
|
195
|
-
|
|
209
|
+
**Merge bar (user, 2026-10-18).** A PR merges when no HIGH finding is open and
|
|
210
|
+
every gating check is green on the exact head. Each MEDIUM or LOW finding
|
|
211
|
+
either folds into the same PR or becomes an accepted residual: the PR body
|
|
212
|
+
lists it under `## Accepted residuals`, named `p3` with its severity and live
|
|
213
|
+
population (for example `p3 (MEDIUM, live 0): <the gap>`), so the gap keeps a
|
|
214
|
+
priority without an issue.
|
|
215
|
+
A residual never becomes a follow-up issue. File an issue only for p2 or
|
|
216
|
+
higher work that cannot ride the PR: a HIGH outside the PR's scope, or a
|
|
217
|
+
MEDIUM with a live population. Before a final round, the brief says "final
|
|
218
|
+
round" and names what it fixes; a residual of MEDIUM or below after it does not
|
|
219
|
+
reopen the round.
|
|
220
|
+
|
|
221
|
+
**Known gaps (user, 2026-10-19).** An open p3 issue is an accepted known gap,
|
|
222
|
+
not backlog. The orchestrator closes it as not planned with the `known-gap`
|
|
223
|
+
label and lists it under its seam on the pinned tracker #4626. When a PR
|
|
224
|
+
merges, its `## Accepted residuals` lines join the same tracker under their
|
|
225
|
+
seam. A known gap reopens as p2 when it turns material: a live wrong result,
|
|
226
|
+
data loss, a hang, or a leak with no bound.
|
|
227
|
+
|
|
228
|
+
Every reviewer **follow-up issue** generalization verdict that meets that bar is
|
|
229
|
+
filed and assigned to a seam group on the tracking queue in the same turn. At each regroup, scan
|
|
196
230
|
merged PRs for subset-shaped changes that lack a generalization verdict.
|
|
197
231
|
|
|
198
232
|
Before filing a review follow-up, apply the standing fold rule: fold same-seam
|
|
@@ -202,6 +236,13 @@ re-verification; small code folds carry a red-first test and return to the same
|
|
|
202
236
|
reviewer. File only different-seam, blocked, decision-dependent, untouched
|
|
203
237
|
pre-existing, or risk-class-changing items, as one consolidated issue per PR.
|
|
204
238
|
|
|
239
|
+
A brief carries the lane's facts and the task, and points at the role
|
|
240
|
+
contract for everything else. Lane facts are the worktree, branch, base,
|
|
241
|
+
TMPDIR, test-worker cap, Git grant, and deliverable path. It never restates
|
|
242
|
+
contract rules such as hooks, trailers, stash, PR-body lint or summary
|
|
243
|
+
shape, because the role wrapper loads them. `bin/claude-lane.sh` prints
|
|
244
|
+
exactly the lane facts.
|
|
245
|
+
|
|
205
246
|
## Round-count rail (orchestrator)
|
|
206
247
|
|
|
207
248
|
When a verify round reports that a fix round introduced a NEW defect on the
|
|
@@ -334,7 +375,16 @@ operator's private notes, so a different orchestrator can run the same train.
|
|
|
334
375
|
round 1.** Their correctness lives in parsing edge cases, exactly where the
|
|
335
376
|
smaller model loses: #2693 took two Sonnet rounds (~720k tokens) on a text
|
|
336
377
|
scanner before the rail sent round 3 to Opus, which rewrote it on the AST
|
|
337
|
-
and closed in two rounds.
|
|
378
|
+
and closed in two rounds. The rule covers checks that scan source text or
|
|
379
|
+
its AST. A plain assertion over config or workflow data (two pins match, a
|
|
380
|
+
key exists) goes to Sonnet, or to Haiku when mechanical (#4350).
|
|
381
|
+
- **Haiku 5.5 is the orchestrator's cheap lane.** The orchestrator uses it
|
|
382
|
+
without asking for read-only locate and premise-pointer passes, CI-red and
|
|
383
|
+
nightly investigations (`pi-lens-investigator`), and mechanical lanes
|
|
384
|
+
through `pi-lens-fixer-light`. Mechanical lanes include trailing folds,
|
|
385
|
+
dependabot pin and allowlist moves, and reviewer-prescribed test rows. It
|
|
386
|
+
never authors detectors or governance sweeps (the Opus rule above), and
|
|
387
|
+
never takes lifecycle or identity seams or reviews of runtime diffs.
|
|
338
388
|
- **Brief shape for a fixer.** Issue/PR number and head; the checked-out
|
|
339
389
|
branch; the exact findings with file:line, the reviewer's probe to reproduce
|
|
340
390
|
FIRST, and the remedy shape the maintainer chose; what to fold (net-count)
|
|
@@ -497,11 +547,22 @@ operator's private notes, so a different orchestrator can run the same train.
|
|
|
497
547
|
- **Detection retrospective on every merged bug fix (2026-09-06).** The
|
|
498
548
|
catalog records the CODE lesson of a bug (a shape, a screen, a guard). Before
|
|
499
549
|
a bug-labelled lane's ledger row closes, the orchestrator also records the
|
|
500
|
-
DETECTION lesson in one line: which verification layer caught it
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
550
|
+
DETECTION lesson in one line: which verification layer caught it and which
|
|
551
|
+
layer SHOULD have caught it earlier and at what cost. The accepted layer
|
|
552
|
+
words are the `DETECTION_LAYERS` list exported by `scripts/check-pr-body.mjs`,
|
|
553
|
+
which the `## Detection` body check reads; the prose does not restate them.
|
|
554
|
+
`nightly` may carry its workflow as `nightly:<workflow>`, and a bug-closing
|
|
555
|
+
PR is refused when `Caught by:`, `Should have been caught by:`, the reason
|
|
556
|
+
after `Gap: none:`, the `Shape: new:` name or the `Enforcer: none:` reason is
|
|
557
|
+
a placeholder (starts with `unknown`, or is exactly `n/a`, `tbd` or `?`)
|
|
558
|
+
(#4519: 139 of 363 closed bugs read unknown in the 2026-10-16 retro).
|
|
559
|
+
If that layer does not exist, file it as an issue with the bug as
|
|
560
|
+
its named recurrence — the same standard shapes are held to. The lesson
|
|
561
|
+
names the defect SHAPE and its tree-wide enforcer, not only a test for the
|
|
562
|
+
instance: the Gap names the `AGENTS.md` catalog shape (or a new shape) and
|
|
563
|
+
either a test that scans the whole population, an issue to build one, or
|
|
564
|
+
`judgment-only` with the reason. A one-bug test is the fix's regression
|
|
565
|
+
test, not the closed gap (lint half: #4439). The ledger
|
|
505
566
|
carries a `caught by / should have been caught by` column. Record: #2587's
|
|
506
567
|
manifest entry escaped the package for four releases; a second registration
|
|
507
568
|
path masked it, so the shipped defect was foreign-tree adoption, not absence
|
|
@@ -613,6 +674,13 @@ Each row cost a lane at least once; the prose above carries the record.
|
|
|
613
674
|
|---------|-----|
|
|
614
675
|
| Writing incident numbers and examples into an `AGENTS.md` rule | AGENTS.md stays lean; issues, PRs and examples go to `HISTORY.md` (maintainer, 2026-10-10). `tests/config/agents-governance.test.ts` ratchets the reference count down only |
|
|
615
676
|
| Routing a review finding as one PR's bug when it is a member of a class | Name the shape, grep for members, and record the verdict before the fix round; `plegma-delegate-guard` refuses a fix brief with a HIGH/MEDIUM finding and no `Shape:` line |
|
|
677
|
+
| Dispatching a fixer on an issue's text without checking it against the code | Grep the claimed gap on master before the brief. A stale premise turns the lane into a no-op or a witness-only PR |
|
|
678
|
+
| Writing off a worker's reds as "sandbox" without a same-env base run | Accept a sandbox attribution only with the same test names red on origin/master under the same env vars. Hundreds of guard reds can hide one real red |
|
|
679
|
+
| Folding a reviewer's remedy after running only the file the reviewer named | Run every test that references the changed symbol (`rg -l <symbol> tests`) before pushing a fold |
|
|
680
|
+
| Pushing with `-q` or a grep filter, then landing on whatever the PR head is | Read the push result unfiltered, check `git merge-base --is-ancestor <intended> origin/<branch>`, and land with `EXPECT_HEAD=<intended or its merge>` |
|
|
681
|
+
| Gating a background step on `until ! pgrep -f '<pattern>'` | That command line matches itself and never exits. Chain the steps in one command, or wait on a PID |
|
|
682
|
+
| Editing an orchestrator script while a chain or monitor runs it | Stop the chain first, or write a new file and `mv` it into place |
|
|
683
|
+
| Patching a CI-only red for a fifth round without CI evidence | When a red does not reproduce locally, put temporary instrumentation in a do-not-merge PR and read the CI log before the next fix round |
|
|
616
684
|
| Taking a causal premise ("a later merge dropped X") from a hand-back into a PR body or brief | Bisect before writing it: `git show <sha>:<file>` along the path from the fix commit to master. A lane round can revert its own earlier round, and that is not a merge drop |
|
|
617
685
|
| Trusting a wrapper script's exit status when it echoes a check's result | `pr-body.sh lint` printed `lint-exit=1` and exited 0, so a failing body went live; the wrapper now exits with the check's status. Read the check's own result line |
|
|
618
686
|
| Hand-rolling the governance suite in a fresh worktree | `npm run build` alone left `dist/` missing and three census suites red; use the orchestrator's `gov-check.sh <tree>`, which builds both outputs and keeps the `node_modules` link for the commit hook |
|
|
@@ -714,8 +782,10 @@ Each row cost a lane at least once; the prose above carries the record.
|
|
|
714
782
|
| Diagnosing a red from the first `##[error]` line | #4054's shard-5 red was called "npm registry unreachable"; that line came from a passing stubbed test, and the real failure was a 5 s timeout in check-pr-body.test.ts (#4088, 2026-10-07). Read the FAIL lines; treat annotation lines from stubbed tests as noise |
|
|
715
783
|
| Triggering CI on a bot PR before checking whether a run already exists | land.sh closed and reopened #4084 30 s after an update-branch, before the new run registered, which cancelled the run, and the cancelled aggregate read red (2026-10-07). Reopen only when no run exists for the head after a real wait |
|
|
716
784
|
| Writing a closing keyword where GitHub does not honour it, or by accident | #4121's title said `closes #3873`, which fails the close-keyword check (titles are never honoured); #4094's body said "then fixed #4080", an accidental closing keyword (2026-10-07). Put closing keywords in the body only, and reread the body for `fix(es\|ed) #N` prose |
|
|
785
|
+
| Quoting a closing keyword in a commit message | #4375's commit f40ac6c28 quoted `not fixed: #4346` and `Whether this closes #1513` as lint examples; GitHub acts on commit-message keywords that reach the default branch, so the merge closed both (2026-10-14). `closingIssuesReferences` omits them. Commit messages get the same keyword rules as the body; quote examples as `#N` without the keyword |
|
|
786
|
+
| Merging a contract-doc edit on an orchestrator read alone | #4379's seven-line host-cap section used "read-only" for the opposite of its meaning in `docs/pi-lens-subagent.md`, and left probe-running investigators unclassified; a scoped review caught both (2026-10-14). An edit to `docs/pi-lens-*.md` or AGENTS.md gets one scoped reviewer pass |
|
|
717
787
|
| Seeding a group list from the active queue instead of the tracker | The orchestrator's session group held 3 issues while `area:session` had 8 more open p2s, so "is the session group done?" was answered from an incomplete list (2026-10-08). Build a group from the label and the tracker, then subtract what is out of scope |
|
|
718
|
-
| Filing every LOW review finding as an issue | Each review spawned about one follow-up, so the CI group stayed at about 36 open after 16 closures (2026-10-07). Fold or drop LOW findings; file only
|
|
788
|
+
| Filing every LOW review finding as an issue | Each review spawned about one follow-up, so the CI group stayed at about 36 open after 16 closures (2026-10-07). Fold or drop LOW findings; file only what the merge bar admits (p2 or higher that cannot ride the PR), and give each group a "done when" |
|
|
719
789
|
| No cleanup when lanes end | 78 GB of finished lane trees and a 22 GB leaking test TMPDIR filled the root disk twice; two reviewers lost probe runs and one fixer's test file was truncated (2026-10-07). Remove a lane's trees and TMPDIR when its PR merges, and keep a disk alarm |
|
|
720
790
|
| Deriving the next round from a stale brief or a stale premise | #3871's brief asked for a selection fix #3903 had already shipped, and #3813's assumed every producer was unfixed; both fixers correctly refused to rebuild merged work (2026-10-07). Re-check the premise on current master when a lane starts, not when the issue was filed |
|
|
721
791
|
| Calling a PR-owned hygiene leak pre-existing because the same files fail on a later run | The PR's own CI run exposed the leak, but the reviewer classified it as a flake and fixed an unreachable injected path; the PR review and red-on-base comparison should have owned the finding. The hygiene check now treats a new leak on a green-master PR as CAUSED-BY-PR until red-on-base proves otherwise, and harness children receive a private `TMPDIR` (#4133, #4128). |
|
|
@@ -739,3 +809,31 @@ Each row cost a lane at least once; the prose above carries the record.
|
|
|
739
809
|
| Adapting repository fixtures to a Plegma guard failure | Verify caught the harness-specific workaround; the fixture lane should have reported the environment block without changing repository tests. Plegma-guard fixture failures are now reported as environmental. |
|
|
740
810
|
| Reading a piped command's exit status instead of its outcome record | A pending chain was reported as successful because `tail` returned zero; the landing check should have read the chain's own result. `land.sh` now prints `LAND-RESULT #N: <state> (rc=N)`, which callers must read. |
|
|
741
811
|
| Routing a same-seam new defect to a weaker fixer after a prior round | The next verify found the same-seam defect after a Luna-high assignment; round routing should have selected Opus from the seam and round count. Rule: a new same-seam defect after two rounds goes to Opus (cloud fixer when the subscription is short) with the state table and model step first. |
|
|
812
|
+
| Asking the maintainer whether to build or file a missing detection layer | The orchestrator owns the detection retrospective: it files the layer issue, or folds it into the same-seam PR, the same day, and tells the maintainer (maintainer, 2026-10-13). |
|
|
813
|
+
| Sending a detector or governance-test round to a cheap model | The #4341 npx-pin scanner went to a Haiku round before the Opus-from-round-1 rule was re-read; check the routing bullets before every detector brief. |
|
|
814
|
+
| Routing on the word "governance" instead of the risk | #4350 (a CodeQL pin-equality test) went to Opus as "governance authoring"; the Opus rule is for source-scanning detectors only. |
|
|
815
|
+
| Leaving the `dist/` precondition undeclared | At least 5 lanes (#4417, #4418, the #4422 verify, the #4410 r1 review, the #4423 review F5) each ruled out the same 3 census reds that need `npm run build:dist` (2026-10-14). Mechanical: fail fast when a selected test needs `dist/` and it is missing or stale (#4436); `CLAUDE.md` names `npm run build:dist` for those files meanwhile |
|
|
816
|
+
| A wait helper with a fixed wall-clock budget | `interleaving-kit` `waitFor` ran out at 3000 ms under CI load (run 38618401454, `tests/clients/fix-run-restore.test.ts:378`); the file passed alone and under 3 shuffle seeds, so the red read as a flake. Mechanical, filed as #4437 |
|
|
817
|
+
| Briefing a worker to "report the size first" before a large migration | A worker cannot wait for a reply, so the #4432 fixer did the migration anyway (2026-10-14). A brief authorizes the conditional branch with its bound, or tells the worker to stop and hand back; `AGENTS.md` "Orchestration and delegated work" |
|
|
818
|
+
| Naming a file by basename in a brief | "index.ts" meant `clients/lsp/index.ts`; a Haiku measurement pass searched the root `index.ts` and reported the #2052 comment missing (2026-10-14). Name every file by its repo path |
|
|
819
|
+
| Sending a lane that must find its own failure space to Haiku | #4342 rounds 1 and 2 left three review findings (a wall-clock bound, a wrong offline premise, a 13-vs-20 population); a fresh Opus round with a state table passed verify first time (#4410 round 3). Haiku folds with a prescribed remedy (#4340, #4341, #4345, #4356, #4368, #4372, #4374, #4417) landed first try. Haiku takes only a prescribed change; `AGENTS.md` "Orchestration and delegated work" |
|
|
820
|
+
| Listing a blast radius without the changed result's callers | #4411 round 3 changed `touchFile`'s result and the body omitted the cascade neighbour caller (`clients/dispatch/integration.ts:2139`), which then printed an uncaused "inconclusive" line every turn (review N2). `AGENTS.md` already requires `module_report` with `blastRadius: true` before and after; run it for the changed result and quote every caller, then read each one |
|
|
821
|
+
| Leaving a ledger row reading as a remainder after a PR flips from `refs` to `closes` | The orchestrator's closes-check refused two lands (#4422, #4409) because the row still named a remainder after verify confirmed every criterion (2026-10-14). Mechanical, orchestrator tooling outside this repo: to be fixed in the orchestrator's land tooling, not by a repo check |
|
|
822
|
+
| Linting the PR body only at the end of a round | #4423's advisory `PR body` check went red on 5 consecutive pushes in round 2 with the same passive-voice findings (2026-10-14); a push does not change the body, so the check re-read the unfixed one each time. Lint the body with `--lint-local` before the first push of a round (`docs/pi-lens-fixer.md` "Fix rounds") |
|
|
823
|
+
| Concluding "no existing seam does this" from a search of your own call names | #4528 searched `notifyExternalFileChange\(` and missed six freshness modules in `clients/`; five detectors ended up wiring their own consumers (#4535). Search by primitive (`docs/pi-lens-fixer.md` "Before code"); the reviewer widens the query (`docs/pi-lens-reviewer.md`, #4536) |
|
|
824
|
+
| Importing `dist/` from a script a workflow runs before any build | #4525's `scripts/assert-evaluated.mjs` reached `dist/` through `lib/clean-signal.mjs`, so `tool-smoke-prs` would fail on every refresh PR. #4531 pins the import graph with a test and plants |
|
|
825
|
+
| Pinning workflow step shell as text instead of running it | #4531 r1: four mutations of the Swift, APFS and handshake shell survived, including deleting `set +e`. Run the extracted step shell against stubs in a test |
|
|
826
|
+
| Filing gap after gap on one mechanism without an audit | Eleven freshness gaps went into #4532 before anyone asked why there were eleven; the cause was one missing fan-out (#4535). Three issues on one mechanism open a consolidation audit (`AGENTS.md` "Orchestration and delegated work") |
|
|
827
|
+
| Landing with an unresolved bot review thread | #4548 and #4558 merged with open Greptile threads (2026-10-17); each one's disposition arrived or never did, and nothing held the land. Every bot thread gets a disposition reply and is resolved before the merge (step 1 and step 4 of "The loop, per PR") |
|
|
828
|
+
| Pushing a worker tree on a stale "failed" settlement | The #4575 r5 settlement read as failed while its resumed turn was live and about to push (plegma #752). The orchestrator's push-verify now refuses a tree with a live agent process, and its wait loop takes a `turnId`. |
|
|
829
|
+
| Settling a fix round with unpushed commits | #4582 r1 settled with the commits still local and nobody noticed (plegma #753). The settlement hook now prints `UNPUSHED` or `DIRTY` for the tree it just settled. |
|
|
830
|
+
| Switching `closes` to `refs` through a raw `gh pr edit` body edit | The #4581 land was refused because commit `d068be947` still closed #4488. `pr-body.sh` now refuses a body that drops a commit's close keyword, and the orchestrator guard denies raw body edits. |
|
|
831
|
+
| Reading an empty DeepSeek turn as a worker stall and resuming it | Four resumes on one backend exhausted the balance (plegma #751). Two empty turns on one backend mean check the backend or the quota before any resume. |
|
|
832
|
+
| Proving a workflow floor with a test that matched the step's shell text | The step's exit code was never checked, and the body claimed a shared helper had not landed (#4584 review F1/F3). The reviewer caught both under the existing tautological-test and reuse-the-seam rules, and the round moves the case to `tests/scripts/floor-steps-executed.test.ts`. |
|
|
833
|
+
| Taking a local `vitest --shard=3/5` soak as CI's shard 3 | The shard never contained the target file, so four runs were wasted (#4488). The soak now asserts the target is in the set it recovered from CI's own job log before it runs. |
|
|
834
|
+
| Trusting fixers and reviewers to read the bot threads on their own | Greptile threads and code-scanning alerts reached a round only when the orchestrator relayed them (#4566, #4575). The role contracts now carry a conditional read-and-dispose rule; a missing bot review is never evidence, and the reviewer's own pass stands alone. |
|
|
835
|
+
| Leaving the PR watcher down after a context compaction | #4594 sat conflicting with nobody told (2026-10-18). An orchestrator hook now marks a compacted or resumed session and denies tool calls until the watcher runs again. |
|
|
836
|
+
| Resuming a review or fix round without `passthrough: ["gh"]` | A workspace override drops the inherited passthrough (plegma #762), so the #4593 verifier ran with `gh` unauthenticated and could not read CI or threads. The orchestrator's delegate guard refuses such a round. |
|
|
837
|
+
| Pushing to a PR branch while a fix round is queued against its old head | Merging master into #4594 staled the queued round's lease; the worker pushed a diverged copy to its handle branch (plegma #723). The orchestrator's push-verify refuses while a round still publishes to that branch. |
|
|
838
|
+
| Resuming a reviewer without naming the deliverable | The resumed verifies of #4575 and #4593 inherited report names that did not match the brief, so the hand-back missed the report. Every resumed round names its `deliverables` explicitly. |
|
|
839
|
+
| Calling an issue "blocked on a release" without reproducing it on master | #4554 waited on a release; 58 runs on master did not reproduce it, and it closed crediting #4563. Reproduce on master before naming a blocker. |
|
package/docs/pi-lens-monitor.md
CHANGED
|
@@ -76,7 +76,11 @@ snapshots; no additional telemetry sink is created.
|
|
|
76
76
|
re-activates and uses them. MCP remains connection-scoped and owns the
|
|
77
77
|
terminal latch.
|
|
78
78
|
6. **Backlogs**: `lsp_document_drift` rows by disposition, files affected,
|
|
79
|
-
`driftAgeMs` p50/p95/max; `
|
|
79
|
+
`driftAgeMs` p50/p95/max; `lsp_document_drift_cap` rows (at most one per
|
|
80
|
+
session) with `tracked` and `cap` when the tracked-document set stands above
|
|
81
|
+
`DRIFT_TRACK_CAP` because every record belongs to a document a live server
|
|
82
|
+
still holds (#4503) — `tracked - cap` is the excess at the first crossing,
|
|
83
|
+
not the held-document count or later growth; `agent_end_deferred_mutation_drain` durations and
|
|
80
84
|
coalesced path counts; `deferred_format_file` runs with `changed:true`
|
|
81
85
|
versus total. A formatter that never settles is visible only as an
|
|
82
86
|
anti-join (#3828): a `deferred_format_post_exit_resync` row with
|
|
@@ -109,7 +113,9 @@ snapshots; no additional telemetry sink is created.
|
|
|
109
113
|
displaced is another; a subagent beside a live primary writes none)
|
|
110
114
|
transitions,
|
|
111
115
|
`session_end_fence_rollup` (one per primary shutdown: `sources[]` with
|
|
112
|
-
`guarded` and `dropped`, plus totals)
|
|
116
|
+
`guarded` and `dropped`, plus totals), `lsp_created_import_scan_rollup`
|
|
117
|
+
(one per primary shutdown when the created-module producer ran: `calls`,
|
|
118
|
+
`importers`, `targets`, `capped`, `oversized`, `totalMs`, `maxMs`). Read `read_guard_branch_retained` with
|
|
113
119
|
`payloadReads`: `kept 0, dropped 0` is a missing payload when `payloadReads`
|
|
114
120
|
is `null`, an empty read set at `0`, and an ignored payload when it is above
|
|
115
121
|
0 beside a `payloadVersion` that is not the current one.
|
package/docs/pi-lens-retro.md
CHANGED
|
@@ -62,7 +62,10 @@ is involved. Every finding cites the source it came from.
|
|
|
62
62
|
is filed as an issue naming the incident as its recurrence, not merged.
|
|
63
63
|
4. **Judgement candidates become one line in the right place.** A defect shape
|
|
64
64
|
goes into the `AGENTS.md` catalog as a lean screen, and its issues, PRs and
|
|
65
|
-
examples go to `HISTORY.md
|
|
65
|
+
examples go to `HISTORY.md`, under a heading that names the shape, such as
|
|
66
|
+
`## 2026-10-14 - title (shape N)`: a lean entry cites no issue, and
|
|
67
|
+
`tests/config/shape-history-governance.test.ts` finds the record by that
|
|
68
|
+
heading or by one of the entry's own issue numbers. A reviewer duty goes
|
|
66
69
|
into `docs/pi-lens-reviewer.md`; a fixer duty goes into `docs/pi-lens-fixer.md`
|
|
67
70
|
only when the fixer is the sole actor who can honour it. Standards are
|
|
68
71
|
enforced by the reviewer, whose context pressure is lowest; fixers get
|
package/docs/pi-lens-reviewer.md
CHANGED
|
@@ -50,6 +50,53 @@ a brief supplies only `lane=<name>`, scope, and the grant.
|
|
|
50
50
|
7. Clean up: revert mutations, delete probes, and leave
|
|
51
51
|
`git status --porcelain` empty.
|
|
52
52
|
|
|
53
|
+
## Compliance pass
|
|
54
|
+
|
|
55
|
+
Run this over the merge-base diff at step 2, before the adversarial probes in
|
|
56
|
+
step 4. Each row is a rule a bot can decide from what the diff touches; the
|
|
57
|
+
probes still prove behaviour. Quote the named evidence in the review, and name
|
|
58
|
+
the anchor in the finding so the fixer can route it. A row with no recurrence
|
|
59
|
+
does not ship.
|
|
60
|
+
|
|
61
|
+
| Diff touches | Check | Evidence to quote | Recurrence |
|
|
62
|
+
| --- | --- | --- | --- |
|
|
63
|
+
| A new `it(` or `test(` title, or a case added to a table test | Red first: the case fails on the pre-fix source, with the failure the defect names (principles §2 "Red first") | The pre-fix transcript, with its `Tests N failed` line naming the new titles | #4577 (Greptile, 2026-10-17: round-4 cases shipped with no red) |
|
|
64
|
+
| A new guard, branch, filter, cap or fallback | Mutation red on that predicate, both directions, in a compile-valid change (principles §2 "Mutation output is quoted") | The `scripts/mutate.mjs` transcript and its `RED` status line, with the one test it reds | #4575 (Greptile r4304045025: no mutation red for the saveOnly rule) |
|
|
65
|
+
| A file under `clients/lsp/`, `formal/`, or any path `formal/switch-pins.json` names | The model moves with the code: a `.tla`/`.cfg` hunk and its TLC verdict, or a `TLA+ unaffected:` line; a flipped constant flips its config and its pin (AGENTS shape 68) | The line, or the model diff plus the verdict, and the pin's test name for a flipped constant | #4575 (Greptile r4304045020: the model did not move with the code), #4387, #4393 |
|
|
66
|
+
| A spawn, shell or path seam: `clients/package-manager.ts`, `clients/lsp/launch.ts`, `clients/path-utils.ts`, `clients/safe-spawn.ts`, or any `trySpawn` caller | Read the Windows lane, and keep a shim cell that asserts the platform command (AGENTS "Test requirements"; "Dispatch, runners, formatters, and installers") | The `Unit tests Windows` row on the head, or the shim cell's platform assertion | #4566 (Greptile r4304149666: the `.cmd` cells), #4356, #4263 |
|
|
67
|
+
| A rung that can execute project code | Judge the rung by the resolved target under every trust state, never by the name it was called with (AGENTS "LSP, trust, and process execution") | The target table: each spelling, its resolved path, and the verdict under trusted, unknown and denied | #4566 (an empty `PATH` and a global link each ran project code), #4530 |
|
|
68
|
+
| A new shared helper | Net-count rule: delete a same-shape sibling in this change (principles §1 "Net-count rule for shared helpers") | The deleted sibling in `Change outline`, or the unsafe-to-fold reason with its follow-up link | #2585 r1, #2617 r1 (an existing override and scan set bypassed or recopied), #3064, #3065, #3066, #3068 (a fold's newly sole predicate left untested) |
|
|
69
|
+
| A second writer, reader or mirror of one shared record | Design shared state once, with a reason or kind discriminator per writer (principles §1 "Design shared state once"; AGENTS shape 24) | The writers-by-axis table, and the discriminator each writer carries | #1631/#1641 (the `stale` collision that was green alone), #1633, #1703 |
|
|
70
|
+
| A durable record whose shape changes, or a new version of one | Keep the fixture corpus: every version that produced the record still parses (principles §2 "Keep fixture corpora") | The fixture path and the parser test that replays it | #3594 R2-F1 (AGENTS shape 57) |
|
|
71
|
+
| A cache or memo key | Key every input the value depends on, trust scope and install state included (AGENTS shape 6) | The key's input list beside the value's dependencies, and the mutation that changes one input | #4562 (a large update left a cached answer), #4566 (a trust change left tools missing) |
|
|
72
|
+
| A test-side source scan, census, ratchet or detector | Detectors match code, not prose, and fail closed on an unlisted spelling (principles §2 "Detectors match code"; AGENTS shape 69) | The blanked-source read, and three plants the author did not design for: an alias, an indirect call, a value through another binding | #2693 (a ratchet counted four sites where six existed), #4439 |
|
|
73
|
+
| A workflow, action or job | The edited lane runs on a pull request, or a branch run is quoted with its run id (AGENTS "Commands and gates") | `gh workflow run <file> --ref <branch>` with its run id, or the PR-eligible cell's name | #3043, #3085 |
|
|
74
|
+
| A `continue-on-error` producer or a nightly floor | The producer reports to `scripts/assert-evaluated.mjs`, and its floor reds below the measured count (AGENTS "LSP, trust, and process execution") | The floor value beside the run's evaluated count | #4518 |
|
|
75
|
+
| A path a host tool was given (a `~`, an `@` prefix, a `file://` URL), or a path re-resolved after it left disk | Resolve by provenance, one seam per provenance; a generated or recovered path is never re-resolved (AGENTS shape 74) | The resolver the caller uses, and the path form it accepts, before and after | #4576, #4577 (a bash operand resolved on the host-argument ladder, then an absolute spelling rewritten) |
|
|
76
|
+
| A path recovered from disk, a synthetic write event, or a path pi-lens generates | The path carries its provenance, host argument, shell token, recovered or generated, and nothing re-derives it (AGENTS shape 58) | The provenance the caller states at the injection point, and the resolver it therefore skips | #4577 (a recovered name was re-folded), #4558 |
|
|
77
|
+
| A path-keyed map, normalizer or path comparison | Normalize on write, read, delete and rehydrate, and test Windows separators and casing (AGENTS shape 1) | The writer and reader table, with the normalizer each one calls | #3178 (four rounds, two inverted arms, one unmeasured swap) |
|
|
78
|
+
| A session, lifecycle, generation or turn-end seam | Capture the generation before the await, and key the state by the session that owns it (AGENTS shapes 21 and 22; "Session, telemetry, and delivery") | The captured scope or generation the write checks, and the test that races it | #4258 (a stale activation rebinding a held bridge), #4154 |
|
|
79
|
+
| A lifecycle, ownership or queue-ordering change | Name a cell and a mutation per axis: owner and identity, last leave, and queue ordering (principles §1 "Identity and lifecycle rules"; AGENTS shapes 21 and 22) | The state table with one row per axis, and the mutation transcript for each cell | #4563 (seven lifecycle findings), #4575 (a slow send overwrote a newer edit), #4562 |
|
|
80
|
+
| A lifecycle change | The TLA+ model moves with the code, and `docs/pi-lens-monitor.md` gains the row for a new store or hand-off branch (AGENTS shape 68; "Session, telemetry, and delivery") | The model diff or `TLA+ unaffected:` line, and the monitor-doc row | #4563, #4569 (held documents undercounted), #4575 |
|
|
81
|
+
| A delivery surface, or a bound on findings that reach the model | A bound discloses its truncation on the rendered surface, and a skipped or unavailable result is not clean (AGENTS shape 10) | The rendered truncation line, or the skip reason from `RUNNER_SKIP_REASONS` | #3166 r2 (an 80-finding input bound zeroed a neighbour's errors) |
|
|
82
|
+
| A relaxed or rewritten existing assertion | Mutate the behaviour the test is named for; a rewrite that stays green is a deleted test (AGENTS "Issue and PR design contract"; principles §2) | The red on the new assertion, with that behaviour broken | #4390 (the eviction smoke's rewrite passed with root re-registration broken) |
|
|
83
|
+
| A new decision branch on a session, lifecycle or delivery seam | Name its record, sink plus kind, and read it back through the real seam (AGENTS "Session, telemetry, and delivery"; shape 31) | The record literal, and the test that reads it back | #3873 (a fix that could not be shown to fire live), #3875 |
|
|
84
|
+
| A new failure path, catch or silent return | One bounded record per distinct event, in a stream a monitor reads without asking (principles §1 "Every new failure path gets bounded observability"; shape 31) | The record literal and its sink, or `none:` with its reason | #4562 (a failed log write stayed silent), #4575 (a failed save left no trace) |
|
|
85
|
+
| Every diff, every changed file, tests included | Read the whole diff file by file. Check each PR-body claim against the diff, and look in the body for proof before calling it missing (principles §3 "Reviewing and delegating") | The body line or transcript quoted beside a claim the diff cannot show, or the finding names the body line that lacks it | #4574 F2, #4582 F1; 3 of Greptile's 4 false positives were a transcript already in the body (#4572, #4573, #4577) |
|
|
86
|
+
|
|
87
|
+
Rows 1, 2 and 4 are mechanical from #4585: `scripts/check-pr-body.mjs`
|
|
88
|
+
(`lintDiffCompliance`, wired into both entry points) reds a body that omits
|
|
89
|
+
their evidence, and it keys each item to the diff: a red belongs to the title
|
|
90
|
+
its table names and to the file whose path it spells, and a Windows read
|
|
91
|
+
belongs to the seam file it names or to a diff with exactly one seam file.
|
|
92
|
+
Row 1 is file-level: a changed test file owes one fenced red-first transcript
|
|
93
|
+
that names it and shows a failure from it, or a Controls row naming it with a
|
|
94
|
+
reason. The lint does not read a title, a table row or a suite chain, so a red
|
|
95
|
+
from the file proves the file whatever the new case is called (#4605). Row 3
|
|
96
|
+
stays a reviewer judgement row; the lint never decides what a model means. Confirm the lint passed on the head, then spend
|
|
97
|
+
this pass on the rest — a quoted mutation-table red is not a red-first
|
|
98
|
+
transcript, and a body that names the right file is still yours to judge.
|
|
99
|
+
|
|
53
100
|
## Verification
|
|
54
101
|
|
|
55
102
|
For each new or changed `vi.mock` or hand-built double of a `clients/` module,
|
|
@@ -61,10 +108,20 @@ real seam. Check that every gate the diff adds is exercised through that path.
|
|
|
61
108
|
a lifecycle, dispatch, or ownership seam, run EVERY suite that exercises the
|
|
62
109
|
behaviour the seam governs and name the list; a curated file set cannot
|
|
63
110
|
clear what it omits (#3622).
|
|
111
|
+
- **Challenge the population query.** Re-run the fixer's sibling search with
|
|
112
|
+
a wider query of your own, by primitive or mechanism instead of the fixer's
|
|
113
|
+
call names. Report what the fixer's query missed; a population that a wider
|
|
114
|
+
query extends is a finding (#4536).
|
|
115
|
+
- **Severity and live population.** Every finding carries HIGH, MEDIUM or LOW
|
|
116
|
+
and its live population (how many sites in the tree hit it today). The
|
|
117
|
+
verdict follows the merge bar in `docs/pi-lens-merge-policy.md` "Filing
|
|
118
|
+
issues": no HIGH plus green gating checks is merge-ready, and a MEDIUM or
|
|
119
|
+
LOW names whether it folds or stays an accepted residual.
|
|
64
120
|
- **Generalization verdict.** When a mechanism, policy, guard, or optimisation
|
|
65
121
|
targets N of M members (registry entries, servers, tools, languages,
|
|
66
122
|
stores), name M, why the others are excluded, and their default, and end
|
|
67
|
-
with *widen in this PR*, *
|
|
123
|
+
with *widen in this PR*, *accepted residual* (named `p3`, with its live population),
|
|
124
|
+
*follow-up issue* (p2 or higher only, with its seam group), or *stay
|
|
68
125
|
specific* (with the reason). A missing verdict is a finding (#3622; the
|
|
69
126
|
optional ast-grep assist is #3684).
|
|
70
127
|
- Review the pre-push self-scan with `npm run astgrep:self-scan`; `pr-preflight`
|
|
@@ -76,10 +133,20 @@ real seam. Check that every gate the diff adds is exercised through that path.
|
|
|
76
133
|
fixer's hand mutations. There is no per-PR Stryker comment or `MUTATION`
|
|
77
134
|
line to read; the nightly Stryker report on master is exploratory and is not
|
|
78
135
|
a review input.
|
|
136
|
+
- For every relaxed or rewritten existing assertion, mutate the behaviour the
|
|
137
|
+
test is named for; a rewrite that stays green is a finding (#4390). This is
|
|
138
|
+
the exception to the one-spot-check cap above.
|
|
79
139
|
- Repeat the pattern and population sweeps. Check blast radius, bounded
|
|
80
140
|
observability, changelog, commit, and PR-body requirements.
|
|
81
141
|
- Re-run the PR's `## Class sweep` search yourself and widen it when the
|
|
82
142
|
named shape is broader than the touched seam (#4273, #4268).
|
|
143
|
+
- On a bug-closing PR, check the `## Detection` lesson: the layer named under
|
|
144
|
+
`Should have been caught by:` must be one that would actually have caught
|
|
145
|
+
the bug, and `Gap:` must be a real issue, test, or reason (#4288). Judge
|
|
146
|
+
`Shape:` and `Enforcer:` too: the lint checks the catalog number and that the
|
|
147
|
+
path is on the base and named by the entry, not that the test scans the
|
|
148
|
+
shape's whole population, so open the enforcer and decide whether it does
|
|
149
|
+
(#4439).
|
|
83
150
|
- For LSP, dispatch, cache, runner, or tool changes, test one non-TypeScript
|
|
84
151
|
registry entry through the same seam.
|
|
85
152
|
- On a net-count fold, mutate every predicate the deleted sibling used to
|
|
@@ -92,6 +159,9 @@ real seam. Check that every gate the diff adds is exercised through that path.
|
|
|
92
159
|
## Standing probes
|
|
93
160
|
|
|
94
161
|
Run every probe the diff can trip and say which ran and what each returned.
|
|
162
|
+
For LSP diagnostics, the formatter, the review graph and `rename_file`, start
|
|
163
|
+
from the `verify-pi-lens` skill (`.claude/skills/verify-pi-lens/SKILL.md`)
|
|
164
|
+
instead of rebuilding the probe.
|
|
95
165
|
|
|
96
166
|
- **Ladder and deletion sweep.** Every ask names the ladder rung it serves. An
|
|
97
167
|
ask that adds a guard names its recurrence; an ask that deletes a defensive
|
|
@@ -111,6 +181,12 @@ Run every probe the diff can trip and say which ran and what each returned.
|
|
|
111
181
|
except `index.ts`, which gates on the lifecycle hook handler a hunk lands in.
|
|
112
182
|
A green `TLA+ models` run over an unchanged model proves nothing about the
|
|
113
183
|
new code.
|
|
184
|
+
For a `TLA+ unaffected` line, read the family's as-built config constants:
|
|
185
|
+
a diff that changes a behaviour one of them encodes refutes the line and is
|
|
186
|
+
a finding (#4387: #4235 changed read-guard authorship while the as-built
|
|
187
|
+
switches kept the old behaviour). `formal/switch-pins.json` names each
|
|
188
|
+
pinned constant's test (#4393); a changed behaviour with no flipped value
|
|
189
|
+
and pin is the same finding.
|
|
114
190
|
- **Red-proof audit.** A claimed red without its quoted transcript is a finding
|
|
115
191
|
of its own; reproduce it (step 3).
|
|
116
192
|
- **Quoted-evidence audit.** Diff every CI line the body quotes against the job
|
|
@@ -148,6 +224,26 @@ Run every probe the diff can trip and say which ran and what each returned.
|
|
|
148
224
|
`// flake-shape: <detector> — <reason>` header and `wallClockBudgetInclude`
|
|
149
225
|
membership (#2547). A pinned file whose count falls below its pin needs its
|
|
150
226
|
baseline tightened; a stale ceiling re-admits regrowth.
|
|
227
|
+
- **Hot-path timing.** When the diff touches dispatch, `session_start`, LSP
|
|
228
|
+
diagnostics, a cache lookup or turn-end, re-run the body's before/after
|
|
229
|
+
timing on the real path, at a small and a large input (file size, file
|
|
230
|
+
count). A regression the body does not name and justify is a finding (#4344
|
|
231
|
+
r1: replay went from 6 ms to 321 ms; #4368 r1: import extraction took 190 ms
|
|
232
|
+
at 1.6k lines and 9.2 s at 12k). Read the `Hot-path latency (advisory)` job
|
|
233
|
+
summary on the head (#4363) first; it covers `session_start`, dispatch and
|
|
234
|
+
replay, and a red there is a finding unless the body justifies it. Green
|
|
235
|
+
means no regression of 1.25x and 5 ms; a "slower, below threshold" row is
|
|
236
|
+
still a number to read.
|
|
237
|
+
- **Shutdown-path parity.** When the diff moves or rewraps code that stops a
|
|
238
|
+
child (a server, a client, a spawned tool), compare the stop path before and
|
|
239
|
+
after: does the child still get its graceful signal (stdin end, shutdown
|
|
240
|
+
request) before any kill, and do its exit-time records and files still
|
|
241
|
+
appear? Count them over a few runs on both heads. A green suite proves
|
|
242
|
+
nothing here (#4366 r2: a shared-client fold swapped stdin end for SIGTERM;
|
|
243
|
+
the shutdown record went from 3/3 to 0/12 and 11 sockets leaked).
|
|
244
|
+
- **Windows path shapes.** A new test or runtime comparison of paths goes
|
|
245
|
+
through `toPosix` or `path.win32` (`AGENTS.md`). A host-default separator is
|
|
246
|
+
a finding even when Linux CI is green (#4356: Windows advisory red).
|
|
151
247
|
- **Platform skips and session-start resets.** Apply the `AGENTS.md` test
|
|
152
248
|
screens and the `SessionStartClassification` invariant.
|
|
153
249
|
|
|
@@ -195,8 +291,10 @@ the rate they remove them.
|
|
|
195
291
|
|
|
196
292
|
## Findings and verdict
|
|
197
293
|
|
|
198
|
-
Classify every finding as **fold**
|
|
199
|
-
(`docs/pi-lens-subagent.md`
|
|
294
|
+
Classify every finding as **fold**, **accepted residual** (named `p3`) or
|
|
295
|
+
**file** with a one-word reason and its live population (`docs/pi-lens-subagent.md`
|
|
296
|
+
"Follow-ups"; the merge bar is in `docs/pi-lens-merge-policy.md` "Filing
|
|
297
|
+
issues"). Order findings `CRITICAL`, `HIGH`,
|
|
200
298
|
`MEDIUM`, `LOW`, `NITPICK`. Each carries a stable id, a file or symbol anchor,
|
|
201
299
|
the reproduction command or probe output, expected and observed behaviour, the
|
|
202
300
|
root cause, cost, and a concrete remedy, and whether it is an
|
|
@@ -215,6 +313,19 @@ merge-order interactions with other open PRs, plus:
|
|
|
215
313
|
- `Disposition table`: each prior finding as `fixed`, `not fixed`,
|
|
216
314
|
`new defect`, or `withdrawn (reason)`.
|
|
217
315
|
- Cleared categories (one compact list) and exact-head identity.
|
|
316
|
+
- **Bot threads and code-scanning alerts.** When bot threads or code-scanning
|
|
317
|
+
alerts exist, read and dispose of each one: list every unresolved review
|
|
318
|
+
thread on the PR (`reviewThreads`, `isResolved == false`) and every open
|
|
319
|
+
code-scanning alert on the branch, both read at the exact head with the
|
|
320
|
+
commands in `docs/pi-lens-fixer.md` "Fix rounds". Rate each one as a
|
|
321
|
+
finding with its probe, or `refuted` with the probe that refutes it, so an
|
|
322
|
+
item nobody probed cannot read as cleared. A missing bot review is never
|
|
323
|
+
evidence of anything: never wait for one, never read its absence as a clear
|
|
324
|
+
signal, and let your own pass stand alone. No `merge-ready` verdict while
|
|
325
|
+
any thread or alert stays undisposed; the merge condition is
|
|
326
|
+
`docs/pi-lens-merge-policy.md` "The loop, per PR" step 1 and step 4
|
|
327
|
+
(`:34`, `:81`). Recurrence: #4566 and #4575 (2026-10-17), where the threads
|
|
328
|
+
outlived the rounds that should have read them.
|
|
218
329
|
|
|
219
330
|
Use short, active, plain prose.
|
|
220
331
|
|
package/docs/pi-lens-subagent.md
CHANGED
|
@@ -58,9 +58,11 @@ explicit orchestrator authorization for
|
|
|
58
58
|
`--force-with-lease=<branch>:<sha>`.
|
|
59
59
|
|
|
60
60
|
Push forms are in "Orchestrator lane mechanics". Before `gh pr create` or `gh pr edit`, lint the body with
|
|
61
|
-
`node scripts/check-pr-body.mjs --lint-local <body-file> "<title>"`.
|
|
62
|
-
|
|
63
|
-
`
|
|
61
|
+
`node scripts/check-pr-body.mjs --lint-local <body-file> "<title>"`. Read the
|
|
62
|
+
lint's exit code directly, never through a pipe, before `gh pr create` or
|
|
63
|
+
`gh pr edit`: a piped status is the last command's, and a failing lint opened a
|
|
64
|
+
PR (#4348). Multiline text (bodies, commit messages, comments) goes through a
|
|
65
|
+
file (`--body-file`, `git commit -F`); re-read what GitHub stored and check the newlines survived.
|
|
64
66
|
|
|
65
67
|
## Orchestrator lane mechanics
|
|
66
68
|
|
|
@@ -130,8 +132,11 @@ the brief gives.
|
|
|
130
132
|
("Worktree and Git"). A reviewer is always `none` and read-only.
|
|
131
133
|
GitHub comments and issue edits are separate: only a brief that grants them
|
|
132
134
|
allows them.
|
|
133
|
-
- **Deliverable.** The report opens with an `ORCHESTRATOR SUMMARY
|
|
134
|
-
|
|
135
|
+
- **Deliverable.** The report opens with an `ORCHESTRATOR SUMMARY`. Its cap
|
|
136
|
+
follows the lane kind: at most 6 lines for a mechanical lane (trailing fold,
|
|
137
|
+
pin or allowlist move, merge-and-resolve), 20 for a locate or investigation
|
|
138
|
+
pass, and 30 for a fix or review round. The summary carries the PR (or
|
|
139
|
+
branch), the head SHA, the change or verdict in a few
|
|
135
140
|
lines, red and green evidence as counts with the quoted transcript below it,
|
|
136
141
|
every skipped check or environment block, and what the orchestrator must
|
|
137
142
|
decide. The RETURNED message (the agent's final reply, or the plegma answer)
|
|
@@ -169,8 +174,9 @@ sets the exit code and only `clean` exits 0:
|
|
|
169
174
|
file is tracked.
|
|
170
175
|
- `unproven` (3): a step failed or a red could not be attributed (the build, a
|
|
171
176
|
run with no named failing file, an `INCONCLUSIVE` red-on-base verdict, a
|
|
172
|
-
failed lint or format check, a selection over the 25-file cap where
|
|
173
|
-
|
|
177
|
+
failed lint or format check, a selection over the 25-file cap, where the
|
|
178
|
+
change's own tests, the governance suites and the best 25 import matches ran
|
|
179
|
+
and the rest did not). That is not evidence of unrelated: report it and
|
|
174
180
|
stop, or fix the cause. The summary prints `selection: selected S, matched
|
|
175
181
|
M, capped C`.
|
|
176
182
|
- `2`: usage error (`--body <path>` or `--body=<path>` missing, unknown, or the
|
|
@@ -193,9 +199,9 @@ change adds or removes a pinned use, run it on the head and on the merge of
|
|
|
193
199
|
|
|
194
200
|
Each pre-push head has a durable result record at
|
|
195
201
|
`$(git rev-parse --git-common-dir)/pi-lens-prepush/<sha>.json`. It contains the
|
|
196
|
-
head/base, timestamp, selected test files and their `
|
|
197
|
-
`governance` reason, plus passed/failed/skipped
|
|
198
|
-
and wall time. Re-pushes overwrite that head's record; writes prune records
|
|
202
|
+
head/base, timestamp, selected test files and their `changed`, `mirror`,
|
|
203
|
+
`import`, `history`, or `governance` reason, plus passed/failed/skipped
|
|
204
|
+
counts, the Vitest exit code, and wall time. Re-pushes overwrite that head's record; writes prune records
|
|
199
205
|
older than fourteen days. The provisional record is written before build and
|
|
200
206
|
self-scan work with outcome `tests-not-started`; preparation failures update it
|
|
201
207
|
to `build-failed` or `self-scan-failed`. The write uses a same-directory
|
|
@@ -224,15 +230,22 @@ runner's own notes say which mode lifts it). Run Vitest as
|
|
|
224
230
|
tree-sitter grammar prefetch hangs offline, verify through direct probes of the
|
|
225
231
|
built code and say so; the orchestrator re-runs the files outside the sandbox.
|
|
226
232
|
|
|
233
|
+
A worker may call a red "sandbox" only with the same test names red on
|
|
234
|
+
`origin/master` in the same worktree, under the same env vars (including
|
|
235
|
+
`GITHUB_ACTIONS` when the test reads it). The plegma git guard reds hundreds
|
|
236
|
+
of fixture tests, and a real red hidden among them reaches CI (#4308).
|
|
237
|
+
|
|
227
238
|
## Follow-ups
|
|
228
239
|
|
|
229
240
|
Fold a review follow-up into the same PR when it shares the seam or files, is
|
|
230
241
|
about one commit, and needs no maintainer decision. Contract-only folds (body,
|
|
231
242
|
comments, wording) are trailing commits; small code folds carry a red-first
|
|
232
|
-
test and are routed per principles §3 "Round routing".
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
243
|
+
test and are routed per principles §3 "Round routing". A MEDIUM or LOW that
|
|
244
|
+
does not fold is an accepted residual: list it under `## Accepted residuals`,
|
|
245
|
+
named `p3` with its severity and live population, and file nothing. File only p2 or
|
|
246
|
+
higher work that cannot ride the PR (a HIGH outside its scope, or a MEDIUM
|
|
247
|
+
with a live population), as one consolidated issue per PR. The merge bar is in
|
|
248
|
+
`docs/pi-lens-merge-policy.md` "Filing issues".
|
|
236
249
|
|
|
237
250
|
## Evidence and reporting
|
|
238
251
|
|
|
@@ -161,7 +161,7 @@ admitted lines explicitly.
|
|
|
161
161
|
|
|
162
162
|
### Verified hosts
|
|
163
163
|
|
|
164
|
-
The certified policy is `>=0.80.10 <1.
|
|
164
|
+
The certified policy is `>=0.80.10 <1.4.0`. Each listed minor line has a
|
|
165
165
|
release-QA witness; the workflow ceiling and `tests/packaging.test.ts` list are
|
|
166
166
|
updated together.
|
|
167
167
|
|
|
@@ -172,6 +172,8 @@ updated together.
|
|
|
172
172
|
| 0.99.2 | 2026-10-08 | 08abd60e193e5a17ea28dd4fbf3603cc9a0cdbe0 | 15 pass / 1 skipped (git-install-loads) |
|
|
173
173
|
| 1.0.4 | 2026-10-08 | 08abd60e193e5a17ea28dd4fbf3603cc9a0cdbe0 | 15 pass / 1 skipped (git-install-loads) |
|
|
174
174
|
| 1.1.0 | 2026-10-08 | 2fda17a53d62267cd9035fa04380bbf0e2de4318 | 15 pass / 1 skipped (git-install-loads) |
|
|
175
|
+
| 1.2.0 | 2026-10-16 | 9400454891d5a1beb0a4d2d9452dece276e22e71 | 15 pass / 1 skipped (git-install-loads) |
|
|
176
|
+
| 1.3.0 | 2026-10-16 | 9400454891d5a1beb0a4d2d9452dece276e22e71 | 15 pass / 1 skipped (git-install-loads) |
|
|
175
177
|
|
|
176
178
|
Re-run any row with `node scripts/release-qa.mjs --pi <host>` at the listed commit.
|
|
177
179
|
|