Files
gstack/investigate/sections/polluter.md
Garry Tanandcapy-ai[bot] ab79e55119 v1.91.78.0 feat(review): plan reality rows, sideways review and cso sweep, investigate recipes (multi-agent wave PR D) (#3119)
* v1.91.70.0 feat(unattended): artifact contract, unattended session kind, findings-derived review log, gate list

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

* v1.91.72.0 feat(autoplan): unattended runner next|submit, pluggable outside voice, review checklists, spec-loop cap

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

* fix(b-runner): atomic lock creation in spend-ledger, judge bundle skips runner-only sections, fixture env spelling

- lib/spend-ledger.ts: create the lock by linking a complete temp file so a
  contender never reads an empty lock and breaks a live owner (CI admitted 20
  of a cap of 8 under contention); unreadable locks break only by mtime age.
- test/helpers/workflow-judge-input.ts: exclude manifest runner_only sections
  (the B4 checklists) from the judge bundle; the judge rates the interactive
  workflow. test/workflow-judge-input.test.ts expects the same set.
- test/helpers/autoplan-run-fixture.ts: spell the runner's session kind
  without the literal the free-suite environment scan rejects.

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

* v1.91.74.0 feat(review): plan reality rows, sideways review and cso sweep, investigate recipes

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

* test: register the investigate carve case and map Reality rows to real headings in the review checklists

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

* test: pin the corrected Reality rows obligation rows

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

* fix(investigate): use allowlisted placeholders in the flake and polluter fences; select the investigate carve case on PTY changes

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>

---------

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
2026-10-11 02:14:23 +00:00

2.0 KiB

Polluter recipe

A polluter is an earlier test that leaks state the victim depends on: the victim passes alone and fails in the suite or in one shard.

  1. File order from the CI log. The shard runner prints its file list in execution order. Take the files that ran before the victim in the failing shard (gh run view <run-id> --log, or the local shard listing bun run scripts/ship-measure.ts free --shard <I> which reproduces the exact packing bun run test used).
  2. Confirm the dependency. The victim alone passes; the victim after the earlier files fails (<affected-files> is the earlier files then the victim, comma-joined, in shard order):
    bun run scripts/ship-measure.ts free --files <failing-test-file> --reruns 3
    bun run scripts/ship-measure.ts free --files <affected-files> --reruns 3
    
  3. Bisect the earlier files. Halve the earlier list, keep the half that still fails the victim, repeat until one file remains. Each step is one --files run; log the list at every step.
  4. Name what leaked. Read the polluter for state that outlives it: an env var, process.cwd(), process.exitCode, a module-level cache or singleton, a mock or spy left installed, a server or watcher left listening, a temp file under a shared path, a learnings or state file under the home directory (the free lane's home guard reports these), a global timer.
  5. Fix the polluter, not the victim. Restore or isolate the state where it is created (afterEach, mkdtemp, a private env); an order-dependent beforeEach added to the victim hides the leak for the next victim.
  6. Report: POLLUTER: <file> leaked <what> into <victim>; fixed by <change>, with the bisect log. If the polluter is on main, the victim's failure is outside the PR (route it with the flake recipe's evidence section).