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