@redue/cli 0.1.0-alpha.3 → 0.1.0-alpha.30

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.
Files changed (67) hide show
  1. package/CHANGELOG.md +806 -0
  2. package/README.md +157 -99
  3. package/bin/redue.mjs +267 -61
  4. package/docs/README.md +3 -1
  5. package/docs/user/agents.md +333 -15
  6. package/docs/user/configuration.md +28 -2
  7. package/docs/user/direct-typescript.md +219 -0
  8. package/docs/user/getting-started.md +49 -7
  9. package/docs/user/json.md +4 -2
  10. package/docs/user/node-script.md +177 -0
  11. package/docs/user/npm-launcher-notice.md +42 -0
  12. package/docs/user/pilot.md +146 -0
  13. package/docs/user/sandbox.md +312 -0
  14. package/docs/user/shell.md +3 -3
  15. package/docs/user/supported-projects.md +69 -23
  16. package/docs/user/tests-direct.md +143 -0
  17. package/package.json +4 -3
  18. package/src/agent-integration.mjs +467 -0
  19. package/src/agent-policy.md +28 -0
  20. package/src/cached-state.mjs +24 -1
  21. package/src/claude-hook.mjs +616 -0
  22. package/src/cli.mjs +449 -54
  23. package/src/daemon.mjs +442 -93
  24. package/src/decision-profile.mjs +15 -1
  25. package/src/decision-validation.mjs +12 -1
  26. package/src/declared-plan.mjs +38 -6
  27. package/src/direct-run-certificate.mjs +254 -0
  28. package/src/direct-typescript-probe.mjs +27 -0
  29. package/src/direct-typescript.mjs +205 -0
  30. package/src/glob.mjs +8 -0
  31. package/src/history-worker.mjs +21 -13
  32. package/src/index.mjs +108 -21
  33. package/src/installed-inputs.mjs +7 -1
  34. package/src/installed-observation.mjs +23 -0
  35. package/src/landlock.py +527 -0
  36. package/src/linux-inotify.py +39 -10
  37. package/src/node-onboarding.mjs +203 -54
  38. package/src/node-script.mjs +406 -0
  39. package/src/npm-integrity.mjs +124 -0
  40. package/src/npm-typecheck-environment.mjs +36 -0
  41. package/src/npmrc.mjs +16 -0
  42. package/src/observation.mjs +34 -12
  43. package/src/path-identity.mjs +8 -0
  44. package/src/plan-worker.mjs +17 -17
  45. package/src/pnpm-inputs.mjs +122 -57
  46. package/src/pnpm-shim-templates.json +180 -0
  47. package/src/pnpm-shims.mjs +54 -0
  48. package/src/pnpm-typecheck-probe.mjs +11 -6
  49. package/src/presentation.mjs +13 -4
  50. package/src/probe-deadline.mjs +37 -0
  51. package/src/probe-result.mjs +7 -3
  52. package/src/project-location.mjs +34 -0
  53. package/src/python-onboarding.mjs +89 -0
  54. package/src/run-recorder.cjs +91 -0
  55. package/src/sandbox.mjs +653 -0
  56. package/src/setup.mjs +205 -0
  57. package/src/stats.mjs +72 -0
  58. package/src/test-direct.mjs +608 -0
  59. package/src/test-recorder.cjs +435 -0
  60. package/src/typescript-contract-probe.mjs +4 -187
  61. package/src/typescript-input-facts.mjs +92 -0
  62. package/src/typescript-invocation.mjs +92 -0
  63. package/src/typescript-list.mjs +118 -13
  64. package/src/typescript-qualification.mjs +29 -49
  65. package/src/workspace-manifests.mjs +24 -0
  66. package/src/yarn-workspace-inputs.mjs +3 -0
  67. package/src/yarn-workspace-typecheck-probe.mjs +2 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,811 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.1.0-alpha.30 — 2026-11-03
4
+
5
+ `init` runs a check fewer times, and tests try the sandbox first.
6
+
7
+ - **Fewer trial runs at init.** A check proposed for the sandboxed recipe
8
+ now runs once plainly and once in the sandbox with ignored files and
9
+ documentation hidden (`sandbox-v3`). If they differ, it runs once more
10
+ with the whole checkout (`sandbox-v1`), compared with the same plain run.
11
+ When the plain run passed and the sandboxed one failed only on reading a
12
+ hidden file, the check gets `sandbox-v1` without that run. `init` no
13
+ longer tries `sandbox-v2`; existing `sandbox-v2` checks keep working.
14
+ On the 13 census repos with the slowest checks, `init --dry-run` took
15
+ 4740 s in all before and 3870 s after on Linux, 6929 s and 5784 s on
16
+ macOS. OneUptime went from 1204 s to 903 s (Linux) and 1206 s to 605 s
17
+ (macOS). Nomi did not get faster (485 s to 383 s on Linux, 836 s to
18
+ 893 s on macOS): its typecheck agrees on the first trial, and each of its
19
+ two runs stops at init's 5-minute limit.
20
+ - **Tests try the sandbox first.** For a Node test script, `init` tries the
21
+ sandboxed recipe before the direct test recipe, which becomes its
22
+ fallback, when both would run the same script. In the census, on the repos where both qualified (2 on each OS),
23
+ the direct recipe's results went STALE when the project's build rewrote
24
+ its output, and the sandboxed results stayed CURRENT. A test script now
25
+ costs `init` one plain run and one or two sandboxed runs.
26
+ - Known limit: artsy/eigen's typecheck, which fails in the census, no
27
+ longer agrees with the whole checkout at init and falls back to the
28
+ general recipe (Linux) or recording (macOS).
29
+
30
+ ## 0.1.0-alpha.29 — 2026-11-03
31
+
32
+ Editing documentation no longer makes sandboxed checks STALE, a fast check
33
+ is skipped or recorded as it should be, and macOS test runs can no longer
34
+ reach a service started outside them.
35
+
36
+ - **Documentation is hidden too (`sandbox-v3`).** A sandboxed run now also
37
+ hides the project's documentation: files named `*.md`, `*.mdx`, `*.rst`,
38
+ `LICENSE*` or `CHANGELOG*` anywhere, and text, image and PDF files in the
39
+ root `docs/` folder (code there stays visible). The receipt names the
40
+ files the run hid, and a later edit to one of them leaves the result
41
+ CURRENT: editing the README no longer makes the tests STALE. A new
42
+ documentation file still counts. `init` tries this first, then the
43
+ git-ignored files only (`sandbox-v2`), then the whole checkout. A check
44
+ that reads documentation (a doctest over the README) keeps `sandbox-v2`.
45
+ Run `redue init` again to move an existing check to `sandbox-v3`.
46
+ - **A fast check is no longer missed by the hook.** The hook waited half of
47
+ the check's last run for `redue status`, so a 0.2 s mypy got 0.1 s, the
48
+ status answer came too late, and the agent's run went unrecorded. The
49
+ wait is now at least 2 s. `REDUE_HOOK_LOG` (an absolute file path) makes
50
+ the hook write one line per Bash command with its decision and why.
51
+ - **macOS test runs get no network.** Seatbelt cannot refuse only the ports
52
+ that were already listening (a per-port rule under a loopback allow is not
53
+ applied; an allow list of every other port does not compile), so a macOS
54
+ test run now gets Unix sockets in its own temporary directory only, as a
55
+ typecheck or lint does. A suite that needs loopback fails `init`'s trial
56
+ and runs without REDUE. Test checks set up by alpha.28 on macOS are not
57
+ CURRENT after the upgrade.
58
+ - **`redue status` reconciles by default.** `redue status --cached` gives the
59
+ observer's last published answer; `--sync` is still accepted. Like
60
+ `--sync`, plain `status` exits 2 when it cannot reach the observer (after
61
+ `redue stop`, for example); `--cached` exits 0.
62
+ - **`redue setup` says more and prints less.** It lists the checks it left
63
+ out and why (a kind it found nothing for, a proposed `tsc --noEmit` no
64
+ recipe takes), says what recording only means, and prints one line per
65
+ recorded run instead of the check's whole output.
66
+ - `redue remove-state` waits for the observer to exit before removing its
67
+ state (a Windows ENOTEMPTY).
68
+ - **Measured.** In the product census, repositories whose qualifying
69
+ sandboxed check keeps the documentation hidden, out of those with one:
70
+ TypeScript on Linux, typecheck 17 of 19, lint 20 of 20, tests 7 of 8; on
71
+ macOS 12 of 13, 14 of 16, 6 of 9. Python on Linux 15 of 15, 22 of 22, 12
72
+ of 17; on macOS 11 of 13, 17 of 17, 8 of 11. No network for macOS test
73
+ runs cost 1 TypeScript suite (it starts a server on 127.0.0.1) and 2
74
+ Python suites: test suites qualifying on macOS went from 12 to 11
75
+ (TypeScript) and 14 to 11 (Python; one checkout no longer installs). The
76
+ strace cross-check found no read outside the recorded inputs. In a Claude
77
+ Code follow-up on starlette and nestjs-api-gateway, a README edit made no
78
+ check STALE; the hook skipped mypy, pytest and the lint, and each skipped
79
+ command passed when run plainly.
80
+
81
+ ## 0.1.0-alpha.28 — 2026-11-02
82
+
83
+ Test suites can run in the sandbox, so REDUE can reuse a passing test run
84
+ for more projects, Python included.
85
+
86
+ - **Sandboxed tests.** A root test script that the direct test recipe does
87
+ not take, and pytest in a Python project's `.venv`, can now use the
88
+ sandboxed recipe. `init` keeps it only when the run in the sandbox gives the
89
+ same exit status and test counts as a plain run. On top of what a
90
+ typecheck or lint gets, a test run gets:
91
+ - **Loopback only.** It may listen on any address and connect to the local
92
+ host and Unix sockets, never to a remote host. On macOS, Seatbelt
93
+ enforces that. On Linux, a seccomp filter refuses UDP and other non-TCP
94
+ sockets, TCP Fast Open and `io_uring`, and hands each `connect` to
95
+ REDUE's launcher. The launcher allows a local port nothing listens on or
96
+ one the run's own processes listen on, and refuses everything else,
97
+ including a service you started outside the run (a local database). If
98
+ the launcher cannot start or stops early, the result is UNVERIFIED.
99
+ - **A private `/tmp`.** Its `TMPDIR` is new for each run, and it may not
100
+ write elsewhere in `/tmp` or `/var/tmp`.
101
+ - **A fresh home** for each run, as on CI.
102
+ - **Ignored files hidden** when the trial agrees, else the whole checkout.
103
+ - **Measured.** In the product census, test suites with a qualifying check
104
+ (alpha.27 in brackets): TypeScript on Linux 11 (2), on macOS 12 (2);
105
+ Python on Linux 17 (0), on macOS 14 (0). The strace cross-check found no
106
+ read outside the recorded inputs. The Linux connect supervisor added at
107
+ most 1.5% over the sandbox without it on suites with worker processes
108
+ (pytest-xdist, Jest, Vitest): apprise 233 s to 237 s, run-to-run spread
109
+ 218-243 s. In a pilot with Claude Code on two pytest projects, the hook
110
+ skipped both "do the tests still pass?" reruns (19 s to 6 s and 28 s to
111
+ 7 s), and plain reruns agreed with both skips.
112
+ - **macOS hides contents only.** On macOS, a hidden file's contents and
113
+ execution are refused, but its metadata is not, as on Linux. A test that
114
+ writes into an ignored folder works.
115
+ - Known limits: a suite that reads back ignored files it writes in the same
116
+ run (a coverage database, a build it starts) gets the whole checkout, and
117
+ one that writes tracked files or coverage data during the run ends
118
+ UNVERIFIED. On Linux, a test that needs a service started outside the run
119
+ fails in the sandbox, so `init` leaves it to a plain run.
120
+
121
+ ## 0.1.0-alpha.27 — 2026-11-01
122
+
123
+ A build or test run no longer makes a sandboxed typecheck or lint STALE,
124
+ and `redue stats` shows what REDUE saved you.
125
+
126
+ - **Files git ignores are hidden from sandboxed runs.** A sandboxed
127
+ typecheck or lint now runs without the files git ignores (`dist/`,
128
+ `.next/`, coverage files, `.env`), except `node_modules`, `.venv` and
129
+ runner caches. Those files are not its inputs, so a build or test run that
130
+ writes them leaves the result CURRENT. The claim: the result holds for a
131
+ run that sees only the project's files that git doesn't ignore, its
132
+ installed packages and the toolchain. Only the project's `.gitignore`
133
+ files and `.git/info/exclude` count, not your global excludes file.
134
+ - **Checks that need ignored files keep working.** `init` tries the
135
+ sandbox with ignored files hidden first (`sandbox-v2`), then with the
136
+ whole checkout (`sandbox-v1`), then the general recipe. A hidden run that
137
+ fails on a hidden file runs again in the sandbox without hiding, and that
138
+ result is kept. Checks set up by alpha.26 stay `sandbox-v1` until you run
139
+ `redue init` again.
140
+ - **Measured.** In the product census, after each project's own build and
141
+ tests ran, checks that stayed CURRENT (alpha.26 in brackets, from the
142
+ measurement census): TypeScript on Linux 31 of 37 (5 of 43), on macOS 24
143
+ of 34 (5 of 38); Python on Linux 31 of 38 (24 of 37), on macOS 28 of 34
144
+ (20 of 33). Where a check qualifies with both, the sandbox stayed CURRENT
145
+ 16 times and the general recipe 9 of 23 (Linux). The strace cross-check
146
+ found no read outside the recorded inputs.
147
+ - **`redue stats`.** Per check: reruns the hook skipped, the time that
148
+ saved, recorded runs, and the top reasons a check was UNVERIFIED, from a
149
+ log in REDUE's local state.
150
+ - `redue remove-state` no longer fails on Windows while the observer is
151
+ still closing its files.
152
+ - Known limits: a sandboxed run can still see that a hidden file exists
153
+ (its name on macOS; listings, sizes and times on Linux), so a tool that
154
+ acts on existence alone is not covered; tests do not use hidden files for
155
+ that reason. On Linux, a file a run creates in a folder that holds hidden
156
+ files cannot be read back in the same run.
157
+ - Contributors: eval entry points that run third-party code refuse to start
158
+ unless `GITHUB_ACTIONS=true`, and importing any eval entry point throws
159
+ before it does anything.
160
+
161
+ ## 0.1.0-alpha.26 — 2026-10-31
162
+
163
+ Typecheck and lint checks run inside an OS sandbox, so REDUE can reuse them
164
+ for native tools and for Python. Python projects are supported for the first
165
+ time.
166
+
167
+ - **Sandboxed recipe.** On macOS (Seatbelt) and Linux 6.7+ (Landlock), a
168
+ root typecheck or lint script runs in a sandbox that sees only the
169
+ project, its installed packages and the toolchain, the way CI does. Its
170
+ inputs are the whole checkout, git-ignored files included, plus the
171
+ installed packages and a fingerprint of the environment it was given. A
172
+ result holds for a run that sees only those. `init` tries the precise
173
+ TypeScript recipes first, then the sandbox, then the general recipe. See
174
+ [sandboxed recipe](docs/user/sandbox.md).
175
+ - **Python.** `redue setup claude` and `init` find mypy, pyright, ty and
176
+ ruff in the project's `.venv`, from its CI workflows, Makefile, justfile,
177
+ tox, nox and scripts. The Claude Code hook recognizes `uv run`,
178
+ `poetry run`, `python -m` and `.venv/bin` forms.
179
+ - **What the sandbox changes.** Network is off. HOME and the temp folder
180
+ are private to the check; HOME is kept between runs so caches persist.
181
+ Tools can read `.git`, but git commands find no repository. A background
182
+ process the check leaves running is stopped when the run ends.
183
+ - **Checked at init.** `init` runs each check plainly and sandboxed, and
184
+ proposes the sandbox only when exit status and output (timings and paths
185
+ aside) match. Otherwise the general recipe applies. A failing run whose
186
+ output looks like a sandbox refusal is rerun plainly; if the plain run
187
+ exits differently, the result is UNVERIFIED. Other failures run once.
188
+ - **Coverage.** In a census of 120 public TypeScript repositories (86
189
+ installed on macOS), 35 have a qualifying check (alpha.24 census: 30):
190
+ typecheck 22, lint 25, tests 2. Of 120 Python repositories, 23 of the 75
191
+ that installed on Linux have one (typecheck 15, lint 22); 20 of 64 on
192
+ macOS. On Linux, every sandboxed run was traced with strace: each file
193
+ it read in the checkout was a recorded input, a cache or its own output.
194
+ - **Measured with Claude Code.** On starlette, graphon and
195
+ claude-agent-sdk-python, sessions took 58 s with REDUE and 125 s without.
196
+ REDUE skipped 10 typechecks and every one matched a plain rerun.
197
+ - Known limits: inside Claude Code's own macOS sandbox and on Windows, the
198
+ sandbox can't start and the general recipe applies. On Linux before 6.7,
199
+ sandboxed runs are UNVERIFIED.
200
+ A build or test run that writes into the checkout (`dist/`, `.next/`,
201
+ coverage files) makes a sandboxed check STALE, as it does a
202
+ general-recipe check: about 1 in 4 TypeScript and 2 in 3 Python checks
203
+ stayed CURRENT through the project's build and tests.
204
+
205
+ ## 0.1.0-alpha.25 — 2026-10-29
206
+
207
+ Running your tests no longer makes a typecheck STALE, and `status --sync`
208
+ answers about twice as fast.
209
+
210
+ - **Vitest and the direct TypeScript recipe.** A Vitest run writes its
211
+ results under `node_modules/.vite/vitest`, which the recipe counted as an
212
+ installed input, so the typecheck turned STALE after every test run. Those
213
+ files are no longer inputs. Everything else under `node_modules/.vite`
214
+ still is. A program that asks the compiler about anything under
215
+ `node_modules/.vite`, or lists `node_modules`, is UNVERIFIED instead. A
216
+ check set up by an earlier alpha reports STALE ("input plan changed") once
217
+ after the upgrade.
218
+ - **Faster status.** `status --sync`, `detail` and `explain` no longer start
219
+ a second Node process on macOS and Linux, the YAML parser loads only for
220
+ pnpm projects, and each call to the observer no longer waits on a fresh
221
+ read of its status file. On the 800-file bench, warm `status --sync` adds
222
+ 27 ms over cached status on a GitHub Linux runner (alpha.24: 120 ms) and
223
+ 36 ms on a macOS runner (alpha.24: 137 ms).
224
+ - **Releases are benched.** The release smoke now benches the candidate
225
+ against the last release on macOS and Linux runners; a slower candidate,
226
+ or one over the warm-sync or run-overhead budget, blocks the release.
227
+ - Known limit: on the maintainer's Mac, which runs Microsoft Defender,
228
+ `redue run` still adds about 15-20% to a 2.7 s typecheck (3% on a GitHub
229
+ Linux runner).
230
+
231
+ ## 0.1.0-alpha.24 — 2026-10-28
232
+
233
+ Checks keep working after a normal `npm install`, and agents that chain an
234
+ edit and a check get the same skip-or-record as a check run on its own.
235
+
236
+ - **Hard-linked installed files.** Without a pnpm store, any installed file
237
+ with a second hard link made a recorded run UNVERIFIED. esbuild's install
238
+ makes one (npm, not Yarn or Windows), so after an ordinary `npm install`
239
+ general-recipe and test checks in projects with esbuild stayed
240
+ UNVERIFIED. Such a file is now accepted when every one of its links is an
241
+ installed file the check observes; its link count is checked again before
242
+ every answer, so a link added later is noticed.
243
+ - **Checks inside a chain.** In a simple chain (`printf ... >> README.md &&
244
+ npm run lint`), the Claude Code hook rewrites each check to the new
245
+ `redue run CHECK --if-due`, which skips the check when its last pass still
246
+ applies at that moment and otherwise runs it through REDUE with the same
247
+ exit code. The hook changes the command without approving it, so your
248
+ permission rules still apply. Chains with subshells, substitutions,
249
+ here-documents, background jobs, shell keywords or builtins before a check
250
+ run untouched.
251
+ - The CLAUDE.md section asks agents to run each check as a command of its
252
+ own. Setups from earlier alphas are recognized and updated.
253
+ - The README's coverage numbers now come from a census that installs with
254
+ dependencies' install scripts on, as users do: of 120 public TypeScript
255
+ repositories, 86 installed and 30 have a qualifying check (typecheck 21,
256
+ lint 18, tests 2).
257
+ - Known limit, unchanged: a Vitest run writes under `node_modules/.vite`,
258
+ which makes a direct TypeScript typecheck STALE until it runs again.
259
+
260
+ - Contributors: census `--install-scripts`; the stranger test can install
261
+ from npm (`--npm`) and run a follow-up session that uses the hooks.
262
+
263
+ ## 0.1.0-alpha.23 — 2026-10-26
264
+
265
+ One command to set up REDUE with Claude Code, and one to undo it.
266
+
267
+ - **`redue setup claude`** runs `init` (when there is no
268
+ `redue.config.json`), connects Claude Code, starts the observer, waits for
269
+ it to index the project, and records each check that can qualify once. It
270
+ asks once (`--yes` for no prompts), prints every file it writes, and a
271
+ second run changes nothing. It stops before writing when dependencies are
272
+ not installed or nothing can be set up.
273
+ - **`redue remove`** undoes exactly what setup created: the integration (or
274
+ only this machine's hooks), the observer state, the local ignore line, and
275
+ the config if it is unchanged since setup wrote it. Anything that existed
276
+ before setup stays. Setup notes what it created in the clone's Git
277
+ directory, never in a committed file.
278
+ - **Hooks find REDUE.** The Claude Code hooks name plain `redue` only when
279
+ the `redue` that your shell and a login shell find is this install;
280
+ otherwise they name this install's Node and entry by absolute path, so a
281
+ Claude Code started from an IDE or with a shorter PATH still runs it.
282
+ Checks the hook runs for the agent follow the same rule.
283
+ - `init` keeps a typecheck that runs TypeScript 7's `tsc` (or `tsgo` from
284
+ `@typescript/native-preview`) recording-only and says why. The pnpm and
285
+ Yarn TypeScript recipes refuse TypeScript 7 with a clear reason instead
286
+ of an error from inside the compiler API.
287
+ - The README is rewritten around a 5-minute quickstart, what REDUE covers
288
+ today (census qualifiers) and what it won't do.
289
+ - Known limits, found by the stranger test: a Vitest run writes under
290
+ `node_modules/.vite`, which makes a direct TypeScript typecheck STALE until
291
+ it runs again; an installed file with a second hard link (esbuild's install
292
+ makes one) keeps the test check UNVERIFIED.
293
+
294
+ - Contributors: the census can run every recipe (`--all-recipes`) and
295
+ counts direct TypeScript checks; its unrecorded-program check no longer
296
+ flags Yarn's temporary `node` wrapper; `eval/stranger.mjs` runs fresh
297
+ Claude Code sessions that set REDUE up from the README alone.
298
+
299
+ ## 0.1.0-alpha.22 — 2026-10-25
300
+
301
+ A correctness fix for recorded runs. Earlier alphas could report CURRENT for
302
+ a script that replaced itself with another program.
303
+
304
+ - **Fixed: a script that replaced itself with another program could be
305
+ CURRENT.** Node's `process.execve` (Node 22.15 and later) swaps a process
306
+ for another program under the same PID. The recorder did not see it, so
307
+ that program ran unseen. TypeScript 7's `tsc` does this to start its
308
+ native compiler, so alphas 19 to 21 could report a TypeScript 7 typecheck
309
+ as CURRENT while REDUE saw none of what the compiler did. The general
310
+ recipe and the direct test recipe now judge the new program like any
311
+ program a run starts: TypeScript 7's `tsc` makes the run UNVERIFIED and
312
+ names it. Support for TypeScript 7 is planned.
313
+ - Runs that use Node's bindings with file, network or program access
314
+ (`process.binding('fs')`, `'spawn_sync'` and others), or run Node with
315
+ `--expose-internals`, are UNVERIFIED: the recorder cannot follow them.
316
+ - Direct test recipe: a shell a test starts is read by its command, as in the
317
+ general recipe. One that runs another program before it becomes Node makes
318
+ the run UNVERIFIED.
319
+ - General recipe, on Linux: pnpm 12 writes a file with no name in
320
+ `node_modules` when it rewrites its workspace state, which left the first
321
+ run after an install UNVERIFIED. That file now counts as the run's output
322
+ when the pnpm executable ran and no file has its name. Known limit: another
323
+ program's file with no name there, during such a run, is taken as pnpm's.
324
+ - UNVERIFIED reasons for an input that changed during a run name up to five
325
+ files and a count of the rest.
326
+
327
+ - Contributors: the census traces each run on Linux and flags programs the
328
+ recorder missed.
329
+
330
+ ## 0.1.0-alpha.21 — 2026-10-25
331
+
332
+ `init` finds more typecheck scripts and no longer stops in large monorepos.
333
+ In the census of 108 public TypeScript repos, the general recipe qualifies 26
334
+ typecheck scripts (was 23) and 20 lint scripts.
335
+
336
+ - `init` prefers typecheck scripts named `tsc`, `types` or `lint:types`, then
337
+ takes one script named under a typecheck name (`typecheck:test`,
338
+ `tsc:build`, ...), watch scripts aside. Two such scripts are reported as
339
+ ambiguous unless a command alone decides. Scripts named `build` or `dev`
340
+ that run tsc are not taken: they write output.
341
+ - A workspace of more than 50 packages no longer stops `init`. It reads up to
342
+ 1000 packages, proposes the root's checks, and past 50 packages skips
343
+ per-package checks and says so (`skipped` in `--json`, a "Skipped:" line
344
+ otherwise). Five census repos got no check at all before.
345
+ - General recipe: pnpm 12 writes its workspace state through a temporary
346
+ `node_modules/.tmpXXXXXX` file. Like the state file, it counts as the run's
347
+ output when the pnpm executable ran. Known limit: the agent eval's seed lint
348
+ run on one pnpm 12 project is still UNVERIFIED for an input event REDUE does
349
+ not yet name.
350
+
351
+ - Contributors: the agent eval records each run's seed and final receipt,
352
+ and the files a session changed when its seed run is not stable.
353
+
354
+ ## 0.1.0-alpha.20 — 2026-10-24
355
+
356
+ A fix for agents on macOS.
357
+
358
+ - Fixed: on macOS, `redue status --sync --json`, `status --json` and
359
+ `explain --json` read by an agent's shell tool stopped at 8 KB, leaving
360
+ invalid JSON. The agent instructions REDUE installs run `status --sync
361
+ --json`; its output passes 8 KB at about 25 checks, or sooner when STALE
362
+ checks list many changed files. Through a shell pipe, `init --json`
363
+ stopped at 64 KB. The CLI exited with output still queued; it now writes
364
+ all of it first. Linux and Windows were not affected.
365
+
366
+ ## 0.1.0-alpha.19 — 2026-10-24
367
+
368
+ A general recipe for typecheck and lint scripts that the strict recipes do not
369
+ take. Test scripts stay on the direct test recipe (Vitest, Jest).
370
+
371
+ - `redue init` tries the strict recipes first, then writes a general check
372
+ (`"qualification": "node-script-v1"`) for a root typecheck or lint script.
373
+ `redue run` runs the script through the project's package manager (npm,
374
+ pnpm 9-12 or Yarn with the `node-modules` linker) with REDUE's recorder in
375
+ every Node process, on macOS and Linux. The input is the whole checkout but
376
+ `.git`, `node_modules` and runner caches, plus every workspace
377
+ `node_modules` observed as installed files, the package manager and its
378
+ version, and the environment. See docs/user/node-script.md.
379
+ - pnpm's launchers are trusted only when their text matches a template a pnpm
380
+ release writes (pnpm 8.0 to 12.14). The pnpm executable, Corepack's
381
+ pnpm-native included, is toolchain; its configuration files are kept by
382
+ content.
383
+ - A run that starts a program REDUE does not record is UNVERIFIED and the
384
+ reason names it: native programs from installed packages (esbuild, turbo,
385
+ tsgolint, biome), git, find, and shells that read startup files.
386
+ - `status` and the hook's skip message name the recipe that made the receipt
387
+ ("general recipe"). The Claude Code hook recognizes lint commands as it does
388
+ typecheck and test commands: `npm run lint`, `pnpm lint`, and for a script
389
+ that is one plain command, that command and its `npx` form.
390
+ - In the census of 108 public TypeScript repos, the general recipe qualifies
391
+ 23 typecheck and 21 lint scripts (both recorded runs clean, CURRENT after
392
+ the second). Of the scripts whose runs start only Node and the package
393
+ manager's own launchers (35 typecheck, 37 lint, measured with strace), init
394
+ proposes and observes about 21 and 22, and 18 of each qualify. The rest:
395
+ init does not pick script names such as `tsc:build`, fails in monorepos
396
+ over 50 packages, or refuses source directory links and custom install
397
+ setups; plans with submodules or dangling links are unavailable.
398
+ - Known limits: on macOS, pnpm 12's temporary files in the project root can
399
+ arrive as an event on the root and make a run UNVERIFIED. Writes into
400
+ `node_modules` during a run make it UNVERIFIED, except pnpm's workspace
401
+ state and vue-tsc's global types, which stay inputs and are kept as the run
402
+ left them. A workspace's recording checks now leave out nested
403
+ `node_modules`, so `redue init` rewrites them once.
404
+
405
+ - Contributors: `census.mjs --product` applies the product's own rule and
406
+ lists the files an unstable run touched; the eval kills a timed-out
407
+ command's whole process group; the agent eval has lint tasks.
408
+
409
+ ## 0.1.0-alpha.18 — 2026-10-23
410
+
411
+ Typecheck in more project shapes, and pnpm test reuse on Linux. In the census
412
+ of 108 public TypeScript repos, the ones `init` makes ready went from 8 to 11
413
+ for typecheck (the census clones each repo's current head, so one or two
414
+ repos move between runs) and stayed at 22 for tests.
415
+
416
+ - pnpm test checks are reused on Linux. A recorded run accepts an installed
417
+ file hard-linked into the pnpm store the install recorded, when the store
418
+ holds it at its content address (pnpm names store files by their sha512).
419
+ Links anywhere else stay UNVERIFIED. Each file is hashed once; REDUE keeps
420
+ its identity and store path in its state and hashes it again only when the
421
+ identity changes. A 46 MB install takes about 160 ms to check the first
422
+ time. Limit: an in-place edit of an installed file in another project that
423
+ shares the store file is not seen until the next recorded run.
424
+
425
+ - Typecheck scripts in more shapes. A script of `tsc --noEmit` runs with
426
+ `-p`/`--project`, `--skipLibCheck` or `--pretty`, in any argument order,
427
+ qualifies for the direct npm recipe and the pnpm contract. A chain of such
428
+ runs joined by `&&` becomes one check per run (`typecheck.1`,
429
+ `typecheck.2`); the hook skips the script only when every run is CURRENT
430
+ and otherwise runs the stale ones through `redue run`. `check-types` joins
431
+ the recognized script names.
432
+ - The hook acts on a typecheck script's form only while the script in
433
+ package.json still has exactly the configured `tsc` runs. Before, a script
434
+ changed to `tsc --noEmit && eslint .` was rewritten to `redue run
435
+ typecheck`, which ran tsc alone.
436
+ - Without a typecheck script, `init` proposes a `tsc --noEmit` check for a
437
+ root `tsconfig.json` (direct npm recipe, pnpm) and for each pnpm workspace
438
+ package with one, unless a script runs a TypeScript checker in another form
439
+ (`tsc -b`, `vue-tsc`, ...). package.json is not changed; the check is
440
+ written only when the contract holds.
441
+ - The pnpm contract no longer needs `include: ["src"]`. Its source inputs are
442
+ the directories the config's `include` covers, as TypeScript computes them
443
+ for new files, minus `node_modules`. `exclude` entries stay inputs, since an
444
+ import can still reach an excluded file. A config extended from an installed
445
+ package is an installed input.
446
+ - Fixed: a config with three or more pnpm or test checks never got a
447
+ synchronized answer. The observer dropped control requests over 4 KB, and a
448
+ sync request carries about 1.5 KB of context digests per check; status
449
+ showed "Unexpected end of JSON input" for every check. The limit is 1 MiB.
450
+
451
+ - The direct npm TypeScript recipe takes any TypeScript 5.x or 6.0, not only
452
+ the five reviewed releases. Another release qualifies when package-lock.json
453
+ records the registry's `typescript` at that version with an integrity
454
+ (sha512, or sha1 from registries that record only sha1), npm's cache holds
455
+ the tarball under it, and the installed package is exactly the tarball's
456
+ files. Nothing is downloaded; a missing tarball
457
+ keeps the check recording-only with `npm-tarball-uncached`. The check takes
458
+ about 100 ms per full probe (TypeScript 5.x and 6.0 tarballs, 120-140 files).
459
+ CI runs the direct contract suite against 5.0.4, 5.1.6, 5.2.2, 5.3.3, 5.4.5,
460
+ 5.5.4, 5.7.3 and 5.8.3.
461
+
462
+ - Contributors: `npm test` runs up to four test files at a time, keeping two
463
+ cores free (a 3-core CI macOS runner runs one at a time), and takes about
464
+ 6 minutes on the owner's Mac (was 19.6). The two TypeScript 6 fixture
465
+ suites are separate files so they run side by side.
466
+
467
+ ## 0.1.0-alpha.17 — 2026-10-22
468
+
469
+ Workspaces and package managers beyond npm. In the census of 108 public
470
+ TypeScript repos, the ones `init` makes ready went from 5 to 8 for typecheck
471
+ and from 6 to 22 for tests.
472
+
473
+ - pnpm 9-12 for the pnpm TypeScript contract (it took only an exact pnpm 12
474
+ pin). The installed `.modules.yaml` names the version; a pin is optional,
475
+ with or without Corepack's `+sha512` hash (pins with a hash never matched
476
+ before). `.npmrc` settings that only change what gets installed are
477
+ accepted; settings that move or copy installed files, or run code during
478
+ install, are refused in either file: custom modules, virtual-store or
479
+ lockfile directories, the global virtual store, injected workspace
480
+ packages, separate lockfiles, pnpmfile hooks, `configDependencies`.
481
+ - The tests recipe takes single-package pnpm 9-12 and Yarn `node-modules`
482
+ installs, and gives each workspace package (npm or Yarn `workspaces`, pnpm
483
+ `packages`) whose test script runs Vitest directly its own `PACKAGE:test`
484
+ check, run in the package directory. Inputs stay the whole checkout; every
485
+ package's node_modules is an installed input. Jest and root test scripts in
486
+ workspaces stay recording-only. A package added later makes the
487
+ workspace's checks UNVERIFIED until `init` runs again.
488
+ - A recorded test run is UNVERIFIED when an installed file has another hard
489
+ link: a package store outside the checkout (pnpm's default on Linux, Yarn's
490
+ hardlinks modes) could change it unseen. pnpm on macOS clones files and is
491
+ not affected; on Linux, pnpm test checks qualify but are not reused unless
492
+ pnpm copies files.
493
+ - Observer: an installed link to a directory (pnpm links every package) is
494
+ observed by its link chain when the target is itself observed installed;
495
+ any other directory link still makes observation unavailable.
496
+ - Workspace patterns honour `!pattern` exclusions; before, a negated pattern
497
+ matched every directory.
498
+ - Fixed: a new workspace package manifest did not re-plan a test check, for
499
+ npm workspaces too.
500
+
501
+ Eval on alpha.17 code (CI 39828002753, 84 sessions, test tasks on twilio,
502
+ cheerio and SwitchHosts plus the pnpm project devops-daily): 0 critical
503
+ findings; 23 skipped test runs, each passing three plain reruns; nothing was
504
+ skipped on devops-daily, whose recorded runs were UNVERIFIED on the Linux
505
+ runner.
506
+ ## 0.1.0-alpha.16 — 2026-10-22
507
+
508
+ Changes to the Claude Code integration, and one fix for commands that meet
509
+ on fresh state. Run `redue agent setup claude --apply` again to get the new
510
+ hook entries.
511
+
512
+ - A SessionStart hook starts the project's observer when a session starts,
513
+ resumes, clears or compacts, if none is running. It returns at once and
514
+ prints nothing. Without a running observer every check was UNVERIFIED, so
515
+ the hook could neither skip nor record. `agent doctor` reports it.
516
+ - The hook matches more command forms, each mapping to one configured check:
517
+ `pnpm SCRIPT`, `pnpm run SCRIPT`, `yarn SCRIPT`, `yarn run SCRIPT`,
518
+ `pnpm exec tsc ...`; for a workspace package's check, `pnpm --filter NAME
519
+ SCRIPT`, `yarn workspace NAME SCRIPT`, `npm run SCRIPT -w NAME`, and its
520
+ script after a `cd` into the package. In the census of 108 public
521
+ TypeScript repos, 61 use pnpm or Yarn.
522
+ - `turbo run TASK` and, in pnpm projects, `pnpm -r TASK` (or a root script
523
+ that is one of them) are skipped only when every workspace package with the
524
+ task's script has a check and all are CURRENT; otherwise they run as typed,
525
+ never rewritten. No skip when turbo may run more (other `dependsOn` tasks,
526
+ `with`, package-scoped keys, a package turbo.json), when pnpm includes the
527
+ workspace root, or for a root script with pre/post scripts. Filters and nx
528
+ are not matched.
529
+ - Fixed: when two commands met on fresh state (SessionStart's `start` and the
530
+ first `status`), the second failed and no observer started.
531
+
532
+ Pilot eval on alpha.16 code (CI 39799994225, 96 sessions over twilio,
533
+ semiotic, Ultra-Card and SwitchHosts): 0 critical findings; 29 skipped
534
+ typechecks, each confirmed by a plain rerun.
535
+ ## 0.1.0-alpha.15 — 2026-10-22
536
+
537
+ No change to observation, status or `redue run` since alpha.14; the changes
538
+ are to the Claude Code integration.
539
+
540
+ - The CLAUDE.md block now tells agents to run the typecheck or test command
541
+ before saying it passes, even after an edit that seems irrelevant, and to
542
+ leave skipping to REDUE's hook. In the alpha.14 eval, two of six mixed-task
543
+ sessions skipped their final test run on their own after a README edit;
544
+ with the new block, none of six did (twilio and SwitchHosts, CI
545
+ 39702429765), at the same token cost. Run `redue agent setup claude --apply`
546
+ again to update the block; the earlier wording is recognized and replaced.
547
+ - The hook also matches a typecheck or test command after a leading
548
+ `cd <project root>;` or `cd <project root> &&`. A skip denies the whole
549
+ command; a rewrite keeps the `cd`. A `cd` to any other directory matches
550
+ nothing.
551
+
552
+ ## 0.1.0-alpha.14 — 2026-10-21
553
+
554
+ Bench numbers below are from one 800-file project on macOS arm64, Node 22.13.0.
555
+ Released alpha.13 and this build ran interleaved on the same machine; the
556
+ typecheck decision path is unchanged within noise (warm `status --sync` 162/157
557
+ ms on alpha.13, 169/166/289 ms on alpha.14; `redue run` overhead 12/14% and
558
+ 12/7/18%; states correct, no idle probe launches).
559
+
560
+ - New opt-in recipe for unit tests: `redue init --recipe tests-direct --check
561
+ test` records a single-package npm project's Vitest 4/5 or Jest 29 run on
562
+ macOS and Linux. The check's inputs are the whole checkout (minus `*.md`,
563
+ `*.mdx` and, with `--coverage`, `coverage/`), the installed files, the Node
564
+ binary, the exact command, and every environment variable the run's
565
+ JavaScript reads directly, compared by value. A recorder loaded into every
566
+ Node process and worker thread of the run guards the rest: reading an
567
+ excluded or git-ignored file, a directory listing or large file outside the
568
+ checkout, network use other than loopback, or a process that escaped the
569
+ recorder makes the result UNVERIFIED with the reason. Lookups outside the
570
+ checkout become run facts that status checks again. Two runs on the same
571
+ inputs with different results make the check UNVERIFIED until the inputs
572
+ change. See [direct tests](docs/user/tests-direct.md) for the claim and its
573
+ limits.
574
+ - Claude Code: the hook skips or records a direct test check's runs (`npm run
575
+ <script>`, `npm test`, the script's own command) like the typecheck's.
576
+ - Linux: a directory created or deleted in the checkout is now an event, not
577
+ an observation gap. Before, every new directory forced a full reconciliation,
578
+ and a second one during it left the observer UNVERIFIED (`plan_gap`).
579
+ - An excluded installed path appearing (a runner cache, a TypeScript build-info
580
+ file) no longer changes the input plan. Checks with such an exclusion are
581
+ STALE with "input plan changed" once after the upgrade, until their next run.
582
+ - Measured with Claude Code on three public projects (Sonnet 5.5, CI Linux,
583
+ 72 sessions): agents skipped 21 test runs, every skip confirmed by three
584
+ plain reruns on its tree, and session time fell from 515 to 295 s summed over
585
+ the task medians. In two sessions the agent itself left out its final test
586
+ run after a README-only edit, without asking REDUE; both said so, and the
587
+ final trees passed.
588
+
589
+ ## 0.1.0-alpha.13 — 2026-10-19
590
+
591
+ Bench numbers below are from one 800-file project on macOS arm64, Node 22.13.0.
592
+ Released alpha.12 and this build ran interleaved on the same machine; the
593
+ decision path is unchanged within noise (warm `status --sync` 192/197 ms on
594
+ alpha.12, 174/198 ms on alpha.13; states correct, no idle probe launches).
595
+ On the CI screen of 38 public TypeScript projects, 22 qualify for the direct
596
+ recipe, up from 19 at alpha.12: worldmonitor, Recordly and open-cowork, which
597
+ the fixed 5 s probe deadline blocked.
598
+
599
+ - A full state probe may run longer on large projects. Its deadline was a
600
+ fixed 5 s (10 s on Windows and for pnpm); now it is the larger of twice the
601
+ last successful probe and the last completed run, at least that floor and at
602
+ most 60 s, doubling after a timeout. A probe that never finishes is still
603
+ killed at its deadline and the check stays UNVERIFIED. `redue status --sync`
604
+ and `redue run` wait for the observer up to the sum of its checks' probe
605
+ deadlines plus 10 s (`probe_deadline_ms` in status JSON), never less than
606
+ before. While a full probe runs the observer does not answer, so with a hung
607
+ probe a decision can wait up to 60 s per check before it is UNVERIFIED.
608
+
609
+ ## 0.1.0-alpha.12 — 2026-10-19
610
+
611
+ Bench numbers below are from one 800-file project on macOS arm64, Node 22.13.0.
612
+ Released alpha.11 and this build ran interleaved on the same machine; the
613
+ decision path is unchanged within noise (warm `status --sync` 183/410 ms on
614
+ alpha.11, 298/174 ms on alpha.12; states correct, no idle probe launches).
615
+ On a screen of 38 public TypeScript projects in CI, 10 qualified for the
616
+ direct recipe before the run-facts change, 17 after it and 19 after incremental
617
+ and references support. worldmonitor and Recordly now stop at the 5 s probe
618
+ timeout, and open-cowork at its end-checkpoint probe.
619
+
620
+ - Large installations reach ready quickly. Installed files are observed by
621
+ identity (inode, size, mode, link count, times), not by hashing their contents;
622
+ the compiler's own reads stay content-checked by the probe. On macOS:
623
+ Recordly (75k files in `node_modules`) ready in 7 s instead of failing after
624
+ 120 s; worldmonitor (143k) in 30 s instead of not ready after 15 min.
625
+ Behavior change: reinstalling identical packages, restoring an installed
626
+ file's bytes or copying the installation now makes the check STALE once.
627
+ - The direct TypeScript recipe supports TypeScript 6.0.2 and 6.0.3.
628
+ - Claude Code: the typecheck hook also matches a typecheck that starts a `;` or
629
+ `&&` chain. When it skips one, the message names the rest of the chain. The
630
+ skill lists the exact commands the hook matches for the selected config.
631
+ - Shorter agent instructions: the CLAUDE.md block is 235 bytes instead of 739,
632
+ the skill 1.8 KB instead of 5 KB. The reuse rules are unchanged. When the
633
+ Claude Code hook matches a typecheck, the block no longer points to the
634
+ skill; the skill stays for agents that look for it.
635
+ - Claude Code hook: it waits for status up to half the last completed run's
636
+ duration, at most 10 s, instead of a fixed 2 s. Run `redue agent setup claude
637
+ --apply` again to raise the hook's Claude Code timeout from 5 s to 15 s.
638
+ - Linux: the observer no longer watches `.git` directories. Before, each new
639
+ directory git created there (on most commits) was an observation gap: status
640
+ was UNVERIFIED until a full reindex and probe finished, about 5 s on a
641
+ 26k-file project. Input patterns that name a `.git` directory are now
642
+ refused; REDUE never observed changes there.
643
+ - Direct TypeScript recipe: runs with `declaration: true` are reusable. tsc's
644
+ declaration checks look up files that building the program does not, and
645
+ read dependencies' `package.json`; before, any such lookup made the run
646
+ UNVERIFIED. The receipt now keeps those existence, `realpath` and
647
+ `package.json` answers as run facts, and status asks them again before every
648
+ CURRENT answer, including when a cached status is read. Every direct run is
649
+ now recorded, also one checked by full probes. The probe also records
650
+ `realpath` while it parses a tsconfig `extends` from a package.
651
+ Behavior change: a direct receipt recorded by an earlier version is
652
+ UNVERIFIED until the check runs again (macOS and Linux). Limit: Windows does
653
+ not record direct runs, so declaration-only lookups are not checked there.
654
+ - Direct TypeScript recipe: a root tsconfig with `incremental: true` is
655
+ supported. Its build-info file is left out of the inputs, and the run may
656
+ write only that file. A root tsconfig that references a composite config
657
+ (such as Vite's `tsconfig.node.json`) is supported when the program does not
658
+ use the referenced project's files. A `composite` root is still refused.
659
+ - Releases are published to the `latest` npm tag as well as `alpha`, so
660
+ `npm install -g @redue/cli` installs the newest release.
661
+
662
+ ## 0.1.0-alpha.11 — 2026-10-18
663
+
664
+ Bench numbers below are from one 800-file project on macOS arm64, Node 22.13.0.
665
+ Released alpha.10 and this build ran back to back on the same machine.
666
+
667
+ - Faster status decisions for the direct TypeScript recipe on macOS and Linux.
668
+ The observer checks the compiler's recorded filesystem questions in-process
669
+ instead of starting a probe that rebuilds the whole program. A full probe runs
670
+ only when that check fails, the plan or toolchain changes, or observation was
671
+ interrupted. While idle it no longer starts any probe process.
672
+ - warm `status --sync`: 741 → 194 ms (+683 → +154 ms over cached `status`)
673
+ - `status --sync` after an unrelated edit: 619 → 219 ms
674
+ - `status --sync` after a relevant edit: 1472 → 321 ms. It answers STALE without
675
+ a full probe when the edited inputs already differ from the receipt.
676
+ - probe processes started in 20 s idle: 4 → 0
677
+ - Cheaper `redue run` on macOS and Linux. The compiler records its own inputs
678
+ while it runs, so REDUE no longer probes before and after the compile. After
679
+ a relevant edit, the run builds the new certificate from that recording instead
680
+ of running a full probe. Output and exit code are those of plain `tsc`.
681
+ - repeat run: 4143 → 2752 ms, overhead over plain `tsc` 72% → 16%
682
+ - run right after a relevant edit: 3990 → 2802 ms, overhead 65% → 18%
683
+ - The direct TypeScript recipe accepts inert Node settings. Before, any non-empty
684
+ `NODE_*` setting other than `NODE_ENV` kept a check from becoming CURRENT.
685
+ Now accepted: `NODE_EXTRA_CA_CERTS`, `NODE_PATH`, and `NODE_OPTIONS` made only of
686
+ `--max-old-space-size`, `--max-semi-space-size`, `--use-openssl-ca`,
687
+ `--use-bundled-ca`, `--use-system-ca` and `--dns-result-order`. A run under one
688
+ value is not reused under another. See [Node settings](docs/user/direct-typescript.md#node-settings).
689
+ - `redue agent setup claude --apply` adds a Claude Code hook to
690
+ `.claude/settings.local.json`. When the agent reruns a configured typecheck
691
+ that is CURRENT and PASS, the hook blocks it and names the passing run. When
692
+ the check is not CURRENT, it rewrites the command to `redue run CHECK`, so the
693
+ result is recorded and the next identical command can be skipped. Prefix a
694
+ command with `REDUE_FORCE=1` to always run it. On the bench: a skip decision
695
+ takes about 155 ms; a forced command adds 39 ms. Tested live with Claude Code
696
+ 2.1.302 (`claude -p`). See [the hook](docs/user/agents.md#claude-code-typecheck-hook).
697
+ - Unstable-run and observation-gap reasons now name the failed check or operation.
698
+ - macOS counts each input event once, which removes an intermittent UNVERIFIED
699
+ after an edit.
700
+
701
+ Known limits:
702
+
703
+ - Two bench targets are still missed: warm sync adds 154 ms over cached status
704
+ (target < 100 ms), and `redue run` adds 16–18% over plain `tsc` (target < 10%).
705
+ - An edit that changes imports, configuration or lib files still costs one full
706
+ probe, at the end of the next run.
707
+ - Windows keeps the earlier probe-based path, except the STALE shortcut. Yarn
708
+ and pnpm recipes still probe on each decision. The bench was not run on Linux.
709
+ - The Claude hook covers the Bash tool only, from the project root. It allows the
710
+ rewritten command without a permission prompt. It judges its own environment,
711
+ not variables the Bash tool adds from your shell profile.
712
+ - To upgrade, stop observers, install into the same prefix, and keep config, state
713
+ and receipts. Rerun `redue agent setup claude --apply` to add the hook.
714
+
715
+ ## 0.1.0-alpha.10 — 2026-10-10
716
+
717
+ - Combine guarded caller-discovery reuse and cheaper non-reusable recording on
718
+ the existing macOS direct-TypeScript path. Healthy runs still validate both
719
+ boundaries in the caller context, falling back to full probes when necessary.
720
+ - Once a healthy start observation is missing, omit qualification-only work that
721
+ cannot repair it. Execute the configured compiler and durably record its true
722
+ outcome; later observer recovery cannot make that invocation reusable.
723
+ - Refuse missing, malformed or mismatched state ownership before execution.
724
+ Preserve cancellation, immutable history and newest-receipt selection.
725
+ - Three fixed A–H cycles cost 15.16/15.35/15.82 seconds versus matched ordinary
726
+ compiler totals of 16.69/16.66/16.56 seconds. These modest CLI savings do not
727
+ establish real-world reuse frequency, CPU/memory or whole-agent benefit.
728
+ - Provide a [fixed-build opt-in pilot guide](docs/user/pilot.md). External usage
729
+ has not started. No compiler/platform expansion or policy redesign is included;
730
+ Claude behavior and cross-host handoff remain untested.
731
+ - Stop observers before upgrading in the same prefix, preserve config/state and
732
+ receipts, preview/apply project-local policy updates, then restart and reassess.
733
+ Never silently migrate a check. Alpha.9 remains an unshipped candidate.
734
+
735
+ ## 0.1.0-alpha.9 — unshipped candidate (2026-10-09)
736
+
737
+ - Reduce repeated caller discovery on the guarded macOS direct-TypeScript path.
738
+ Both execution boundaries still validate in the actual caller environment,
739
+ with full-probe fallback when a discovery certificate cannot be used.
740
+ - Preserve required content/membership, compiler/context, observation and durable
741
+ receipt-selection guards. The configured compiler still executes on every run.
742
+ - Recording overhead fell in the measured debugger-project sample, but every
743
+ complete A–H candidate cycle remained slower than eight ordinary compiler runs.
744
+ No net workflow saving, broader support or CPU/memory improvement is claimed.
745
+ - Stop observers before upgrading in the existing prefix, retain config/state
746
+ and receipts, then restart. No automatic migration is performed.
747
+
748
+ ## 0.1.0-alpha.8 — 2026-10-08
749
+
750
+ - Consume compiler-certificate input asynchronously while preserving the input-size
751
+ limit, parent deadline, complete-input validation and conservative fallbacks.
752
+ - Support the exact reviewed TypeScript 5.5.2 distribution in the explicitly selected
753
+ single-package npm direct-compiler recipe. Enforce implementation membership and
754
+ reject ETW module overrides before compiler API loading.
755
+ - Real independent Codex/macOS sessions reused compiler evidence on the pinned
756
+ vscode-js-debug project. Cross-platform CLI/package acceptance is separate;
757
+ Claude behavior and cross-host handoff remain untested.
758
+ - The measured eight-case workflow avoided four compiler executions but cost
759
+ 20.01 seconds versus 16.97 seconds for eight ordinary compiler runs. No net
760
+ workflow or whole-agent speedup is claimed. This verifies compiler inputs only,
761
+ not npm lifecycle behavior or application correctness.
762
+ - Stop observers before upgrading, retain the same configuration/state, then
763
+ restart. Do not delete receipts or automatically convert existing checks.
764
+
765
+ ## 0.1.0-alpha.7 — 2026-10-07
766
+
767
+ - Guide explicitly configured direct-compiler reuse through one caller-aware
768
+ synchronized query; skip reuse queries when fresh execution is already required.
769
+ - Update intact project-local agent instructions safely; installation alone does
770
+ not update them. See the [existing-user procedure](docs/user/agents.md#update-an-existing-connection).
771
+ - In the finite Codex/macOS comparison, revised guidance reached eligible evidence
772
+ and reused it in 4/4 opportunities versus 1/4; verification tool calls fell
773
+ from 28 to 14. Evidence semantics are unchanged. No universal compliance,
774
+ tail-latency or causal agent-task speedup is claimed. Claude behavior and
775
+ cross-host handoff remain untested.
776
+
777
+ ## 0.1.0-alpha.6 — 2026-10-07
778
+
779
+ - Reuse guarded compiler discovery for warm direct-TypeScript decisions on macOS
780
+ with healthy historical observation. Membership, absence, compiler bytes,
781
+ caller context and receipt selection remain validated independently.
782
+ - Keep full discovery/reconciliation fallbacks and existing platform boundaries.
783
+ - On one measured project, complete warm decision median fell from roughly
784
+ 791 to 474 ms. This is not a universal speedup, agent-task acceleration,
785
+ memory improvement, or a faster relevant-edit/rebuild claim.
786
+ - Stop observers before upgrading and restart with the same config/state.
787
+ Preserve receipts; no configuration migration is performed.
788
+
789
+ ## 0.1.0-alpha.5 — 2026-10-07
790
+
791
+ - Add opt-in project-local agent activation and direct TypeScript evidence, with
792
+ fresh-session reuse demonstrated in the tested Codex/macOS configuration.
793
+ - Preserve ordinary npm execution as a separate, recording-only obligation.
794
+ Direct compilation requires explicit selection and a fresh baseline receipt.
795
+ - Initial direct recipe supports reviewed TypeScript 5.6.3/5.9.3 in single-package
796
+ npm projects, with documented Node/environment restrictions.
797
+ - Claude integration mechanics are tested; Claude behavior and cross-host reuse
798
+ remain untested. No universal compliance or inexpensive-check speedup is claimed.
799
+
800
+ ## 0.1.0-alpha.4 — 2026-10-07
801
+
802
+ - Withdraw automatic npm-launcher applicability because update notifications consume
803
+ unobserved remote/cache/time state. Npm scripts still run and record outcomes.
804
+ - Preserve historical PASS/FAIL and require stop/start when upgrading an observer.
805
+ Do not delete receipts. See the [maintainer notice](docs/user/npm-launcher-notice.md).
806
+ - Supported Yarn/pnpm and explicit reviewed contracts are unchanged. No agent
807
+ activation or npm direct-compiler recipe is included in this correction.
808
+
3
809
  ## 0.1.0-alpha.3 — 2026-10-06
4
810
 
5
811
  Install: `npm install --global @redue/cli@alpha`.