@redue/cli 0.1.0-alpha.4 → 0.1.0-alpha.6

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 CHANGED
@@ -1,5 +1,28 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.1.0-alpha.6 — 2026-10-07
4
+
5
+ - Reuse guarded compiler discovery for warm direct-TypeScript decisions on macOS
6
+ with healthy historical observation. Membership, absence, compiler bytes,
7
+ caller context and receipt selection remain validated independently.
8
+ - Keep full discovery/reconciliation fallbacks and existing platform boundaries.
9
+ - On one measured project, complete warm decision median fell from roughly
10
+ 791 to 474 ms. This is not a universal speedup, agent-task acceleration,
11
+ memory improvement, or a faster relevant-edit/rebuild claim.
12
+ - Stop observers before upgrading and restart with the same config/state.
13
+ Preserve receipts; no configuration migration is performed.
14
+
15
+ ## 0.1.0-alpha.5 — 2026-10-07
16
+
17
+ - Add opt-in project-local agent activation and direct TypeScript evidence, with
18
+ fresh-session reuse demonstrated in the tested Codex/macOS configuration.
19
+ - Preserve ordinary npm execution as a separate, recording-only obligation.
20
+ Direct compilation requires explicit selection and a fresh baseline receipt.
21
+ - Initial direct recipe supports reviewed TypeScript 5.6.3/5.9.3 in single-package
22
+ npm projects, with documented Node/environment restrictions.
23
+ - Claude integration mechanics are tested; Claude behavior and cross-host reuse
24
+ remain untested. No universal compliance or inexpensive-check speedup is claimed.
25
+
3
26
  ## 0.1.0-alpha.4 — 2026-10-07
4
27
 
5
28
  - Withdraw automatic npm-launcher applicability because update notifications consume
package/README.md CHANGED
@@ -37,6 +37,11 @@ it; relevant source edits make it stale. [Run the reproducible demo](docs/contri
37
37
 
38
38
  ## Install the alpha
39
39
 
40
+ This branch prepares **alpha.5**, not yet published. Its opt-in agent activation
41
+ and npm direct-compiler recipe require the candidate tarball; public alpha.4
42
+ contains only the applicability correction.
43
+
44
+
40
45
  REDUE is published on npm as `@redue/cli`. The installed command is `redue`.
41
46
 
42
47
  ```sh
@@ -71,6 +76,30 @@ Start with ordinary `status`. When it cannot establish caller context, use
71
76
  **Synchronization can cost more than rerunning a cheap check, particularly on
72
77
  Windows.** REDUE does not choose or execute that tradeoff for you.
73
78
 
79
+ Since alpha.4, ordinary npm scripts are recording-only after
80
+ [an npm launcher applicability gap](docs/acceptance/npm-launcher-boundary.md).
81
+ A separate explicit [direct compiler recipe](docs/user/direct-typescript.md) can
82
+ qualify supported npm typechecks. It does not claim that npm/lifecycle scripts ran.
83
+
84
+ ## Connect your agent (candidate)
85
+
86
+ ```sh
87
+ redue agent setup codex --dry-run
88
+ redue agent setup codex --apply # or claude
89
+ redue agent doctor
90
+ ```
91
+
92
+ Start a fresh agent session and give it an ordinary task. Project-local guidance
93
+ teaches it to inspect evidence before deciding whether verification needs repeating.
94
+ Setup is explicit, reversible, and does not change tool permissions or run checks.
95
+ [Activation, removal, and generic-agent guidance](docs/user/agents.md).
96
+
97
+ Alpha.5's claim is **opt-in project-local agent activation and direct TypeScript
98
+ evidence, with fresh-session reuse demonstrated in the tested Codex/macOS
99
+ configuration**. Claude setup/removal mechanics are tested; Claude behavior and
100
+ cross-host reuse are not. This is experimental guidance, not guaranteed agent
101
+ compliance, general sandbox compatibility, or a promise of time savings.
102
+
74
103
  ## What the states mean
75
104
 
76
105
  | State | Meaning | Normal next step |
@@ -89,8 +118,10 @@ has been verified.
89
118
  - macOS, Linux, and Windows on supported local filesystems; Node 22+.
90
119
  - Linux also requires Python 3 for observation. No WSL or Git Bash needed on Windows.
91
120
  - npm, pinned Yarn `node-modules`, and pinned pnpm 12 isolated/hoisted layouts.
92
- - Automatic qualification for the supported Yarn/pnpm TypeScript invocations; npm
93
- launcher checks are recording-only in alpha.4. Workspace
121
+ - Automatic qualification for supported Yarn/pnpm TypeScript invocations; ordinary npm
122
+ launcher checks remain recording-only. The alpha.5 candidate adds an explicit
123
+ [direct local compiler recipe](docs/user/direct-typescript.md) for the reviewed
124
+ npm/TypeScript boundary. Workspace
94
125
  boundaries follow the files actually consumed, including built declarations.
95
126
  - Existing test/lint/build and arbitrary commands can record results while
96
127
  their applicability remains unqualified.
package/bin/redue.mjs CHANGED
@@ -1,5 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  import fs from 'node:fs';
3
+ import {directCompiler,directQualification,directEnvironment,directInterpretation} from '../src/direct-typescript.mjs';
3
4
  import os from 'node:os';
4
5
  import path from 'node:path';
5
6
  import {createHash} from 'node:crypto';
@@ -9,7 +10,8 @@ import {fileURLToPath} from 'node:url';
9
10
  import {discoverNodeProject} from '../src/node-onboarding.mjs';
10
11
  import {processAlive} from '../src/process-liveness.mjs';
11
12
  import {samePath,withinPath,realObservedPath} from '../src/path-identity.mjs';
12
- import {stateIdentity,userStateBase} from '../src/platform-state.mjs';
13
+ import {discoverConfig,projectState,canonicalConfig} from '../src/project-location.mjs';
14
+ import {agentCommand} from '../src/agent-integration.mjs';
13
15
  import {findExecutable} from '../src/executable-lookup.mjs';
14
16
  import {readCachedStatus} from '../src/cached-state.mjs';
15
17
  import {assertOwnedStatePlacement} from '../src/owned-state.mjs';
@@ -22,8 +24,12 @@ const help=`REDUE ${version}
22
24
  Usage: redue [--config FILE] [--state-dir DIR] COMMAND [OPTIONS]
23
25
 
24
26
  Commands:
25
- init [--dry-run] [--workspace NAME] [--check KIND]
27
+ init [--dry-run] [--workspace NAME] [--check KIND] [--recipe typescript-direct]
26
28
  Discover existing scripts; optionally select one workspace/check
29
+ agent setup codex|claude [--dry-run|--apply] [--json]
30
+ agent doctor [codex|claude] [--json]
31
+ agent remove codex|claude [--dry-run|--apply] [--json]
32
+ Connect project instructions; explicit setup only
27
33
  start Start the local observer
28
34
  stop Stop this observer
29
35
  status [--json|--short] Read conservative cached status
@@ -39,10 +45,7 @@ function error(message){console.error(`redue: ${message}`);process.exit(2);}
39
45
  const args=process.argv.slice(2);
40
46
  if(args.length===1&&args[0]==='--version'){console.log(version);process.exit(0);}
41
47
  if(args.includes('--help')||args.includes('-h')||!args.length){console.log(help);process.exit(0);}
42
- const preferredConfig=path.resolve('redue.config.json');
43
- const legacyConfig=path.resolve('vstate.config.json');
44
- let configFile=fs.existsSync(preferredConfig)||!fs.existsSync(legacyConfig)?
45
- preferredConfig:legacyConfig,stateOverride=null;
48
+ let configFile=null,stateOverride=null;
46
49
  for(let i=0;i<args.length;){
47
50
  if(args[i]==='--config'||args[i]==='--state-dir'){
48
51
  const flag=args[i],value=args[i+1];if(!value)error(`${flag} requires a path`);
@@ -51,17 +54,26 @@ for(let i=0;i<args.length;){
51
54
  }else i++;
52
55
  }
53
56
  const command=args.shift();
57
+ try{configFile??=command==='init'||stateOverride&&['stop','remove-state'].includes(command)?
58
+ path.resolve(fs.existsSync('redue.config.json')||!fs.existsSync('vstate.config.json')?'redue.config.json':'vstate.config.json'):discoverConfig();}
59
+ catch(e){error(e.message);}
60
+ if(fs.existsSync(path.dirname(configFile)))configFile=canonicalConfig(configFile);
61
+ if(command==='agent'){
62
+ try{await agentCommand(args,{configFile,stateOverride,entry:fileURLToPath(import.meta.url)});}
63
+ catch(e){error(e.message);}
64
+ process.exit(0);
65
+ }
54
66
  if(!['init','start','stop','status','detail','explain','run','remove-state'].includes(command))
55
67
  error(`unknown command ${command||'<none>'}; use --help`);
56
68
  const json=args.includes('--json');
57
69
  const sync=args.includes('--sync');
58
70
  const dryRun=args.includes('--dry-run');
59
71
  const short=args.includes('--short');
60
- let workspaceSelection=null,checkSelection=null;
72
+ let workspaceSelection=null,checkSelection=null,recipeSelection=null;
61
73
  if(command==='init')for(let i=0;i<args.length;){
62
- if(args[i]==='--workspace'||args[i]==='--check'){
74
+ if(args[i]==='--workspace'||args[i]==='--check'||args[i]==='--recipe'){
63
75
  const flag=args[i],value=args[i+1];if(!value||value.startsWith('--'))error(`${flag} requires a name`);
64
- if(flag==='--workspace')workspaceSelection=value;else checkSelection=value;
76
+ if(flag==='--workspace')workspaceSelection=value;else if(flag==='--recipe')recipeSelection=value;else checkSelection=value;
65
77
  args.splice(i,2);
66
78
  }else i++;
67
79
  }
@@ -73,7 +85,7 @@ if(short&&(command!=='status'||json||sync))error('--short is a cached status opt
73
85
  if(dryRun&&command!=='init')error('--dry-run is for init');
74
86
 
75
87
  if(command==='init'){
76
- let discovery;try{discovery=discoverNodeProject(process.cwd());}
88
+ let discovery;try{discovery=discoverNodeProject(process.cwd(),{recipe:recipeSelection});}
77
89
  catch(e){error(e.message);}
78
90
  if(workspaceSelection||checkSelection){
79
91
  const chosen=discovery.checks.filter(row=>
@@ -104,7 +116,7 @@ if(command==='init'){
104
116
  console.log(` ${row.name} (${row.script||row.command?.join(' ')}) — `+
105
117
  `${{ready:'ready to qualify',recording:'recording-only',unsupported:'unsupported'}[row.level]||row.level}: ${row.reason}`);
106
118
  if(row.script&&row.command)console.log(` Recorded invocation: ${row.command.map(value=>
107
- value==='@node'?'node':value.startsWith('@typescript-bin:')?
119
+ value==='@node'?'node':value==='@typescript-compiler:.'?'[reviewed local TypeScript compiler implementation]':value.startsWith('@typescript-bin:')?
108
120
  `[installed TypeScript in ${value.slice('@typescript-bin:'.length)}]`:value).join(' ')}`);
109
121
  }
110
122
  for(const row of summary.ambiguous)
@@ -121,6 +133,7 @@ if(command==='init'){
121
133
  if(!json){console.log(`Created ${configFile}. No checks were executed.`);
122
134
  console.log('Ready to qualify means the supported contract will be validated; it is not verification evidence.');
123
135
  console.log(`Next: review the config, then redue start and redue run ${JSON.stringify(discovery.checks[0].config.name)}.`);
136
+ console.log('Connect your agent: redue agent setup codex (or claude). Preview with --dry-run.');
124
137
  console.log('Use redue status first. --sync can establish applicability, but may cost more than rerunning a cheap check.');}
125
138
  } else if(unsupported&&!json)console.log(`No config written: ${summary.issue||'unsupported discovery boundary'}.`);
126
139
  if(json)console.log(JSON.stringify({...summary,proposed_config:discovery.config}));
@@ -157,10 +170,7 @@ for(const key of Object.keys(publicConfig))
157
170
  if(!['schema','root','checks','packageManager'].includes(key))error(`unsupported config field ${key}`);
158
171
  if(check&&!publicConfig.checks.some(row=>row.name===check))error(`unknown check ${check}; use redue status to list configured checks`);
159
172
  const root=realObservedPath(path.resolve(path.dirname(configFile),publicConfig.root||'.'));
160
- const stateBase=userStateBase(process.platform,process.env,os.homedir());
161
- const state=stateOverride||path.join(stateBase,'vstate',
162
- `vstate-${createHash('sha256').update(stateIdentity(root)+'\0'+
163
- stateIdentity(configFile)).digest('hex').slice(0,16)}`);
173
+ const state=stateOverride||projectState(root,configFile);
164
174
  if(!/^(?:vstate|redue)-/.test(path.basename(state)))
165
175
  error('--state-dir must name a dedicated redue-* directory outside the checkout (legacy vstate-* is also supported)');
166
176
  const runtimeFile=path.join(state,'project-runtime-v1.json');
@@ -172,6 +182,10 @@ function which(name){
172
182
  function token(value){
173
183
  if(value==='@node')return process.execPath;
174
184
  if(value==='@project')return root;
185
+ if(value==='@typescript-compiler:.'){
186
+ try{return directCompiler(root,{verify:false}).entry;}catch(e){error(`direct compiler unavailable: ${e.code||e.message}`);}
187
+ }
188
+ if(value==='@vstate/direct-typescript-probe')return path.join(productRoot,'src','direct-typescript-probe.mjs');
175
189
  if(value.startsWith('@typescript-bin:')){
176
190
  const dir=value.slice('@typescript-bin:'.length);
177
191
  if(!dir||path.isAbsolute(dir)||dir.split('/').includes('..'))
@@ -208,8 +222,9 @@ const checks=publicConfig.checks.map(check=>{
208
222
  for(const category of categories)if(check.coverage?.[category]&&
209
223
  typeof check.coverageReview?.[category]!=='string')
210
224
  error(`${check.name}: reviewed coverage ${category} needs a rationale`);
225
+ const npmDirect=check.qualification===directQualification;
211
226
  const pnpmTypecheck=check.qualification==='pnpm-tsc-v1';
212
- if(check.script&&check.command&&!pnpmTypecheck)
227
+ if(check.script&&check.command&&!pnpmTypecheck&&!npmDirect)
213
228
  error(`${check.name}: choose script or command, not both`);
214
229
  const manager=publicConfig.packageManager;
215
230
  if(check.script&&!['npm','yarn','pnpm'].includes(manager))
@@ -218,8 +233,11 @@ const checks=publicConfig.checks.map(check=>{
218
233
  [`@which:${manager}`,'run',check.script]:null;
219
234
  const npmAutomatic=check.qualification==='typescript-noemit-v1';
220
235
  const yarnWorkspace=check.qualification==='yarn-workspace-tsc-v1';
221
- if(check.qualification&&!npmAutomatic&&!yarnWorkspace&&!pnpmTypecheck)
236
+ if(check.qualification&&!npmAutomatic&&!npmDirect&&!yarnWorkspace&&!pnpmTypecheck)
222
237
  error(`${check.name}: unknown qualification contract`);
238
+ if(npmDirect&&(manager!=='npm'||!check.script||check.cwd&&check.cwd!=='.'||
239
+ JSON.stringify(check.command)!==JSON.stringify(['@node','@typescript-compiler:.','--noEmit'])))
240
+ error(`${check.name}: direct recipe requires its explicit local compiler command`);
223
241
  if(npmAutomatic&&(manager!=='npm'||check.cwd&&check.cwd!=='.'))
224
242
  error(`${check.name}: automatic TypeScript qualification currently needs root npm script`);
225
243
  if(yarnWorkspace&&(manager!=='yarn'||!check.workspace||check.cwd&&check.cwd!=='.'||
@@ -237,7 +255,7 @@ const checks=publicConfig.checks.map(check=>{
237
255
  check.kind==='lint'?'lint plugins, config and resolver inputs need review':
238
256
  check.kind==='build'?'build environment and generated inputs need review':
239
257
  'check inputs need review';
240
- const autoProbes=npmAutomatic?[['@node','@vstate/typescript-contract-probe',
258
+ const autoProbes=npmDirect?[['@node','@vstate/direct-typescript-probe','@project',check.script]]:npmAutomatic?[['@node','@vstate/typescript-contract-probe',
241
259
  '@project',check.script,'@which:npm']]:yarnWorkspace?
242
260
  [['@node','@vstate/yarn-workspace-typecheck-probe','@project',
243
261
  check.workspace,check.command[4],'@which:yarn']]:pnpmTypecheck?
@@ -245,7 +263,7 @@ const checks=publicConfig.checks.map(check=>{
245
263
  check.workspace||'.',check.script]]:[];
246
264
  const windowsContext=process.platform==='win32'?
247
265
  ['ComSpec','COMSPEC','PATHEXT','USERPROFILE']:[];
248
- const autoEnvironment=npmAutomatic?{variables:['NODE_OPTIONS','NODE_PATH','CI','HOME',
266
+ const autoEnvironment=npmDirect?directEnvironment:npmAutomatic?{variables:['NODE_OPTIONS','NODE_PATH','CI','HOME',
249
267
  'NODE_ENV','BASH_ENV','ENV',...windowsContext],prefixes:['npm_config_','DYLD_','TSGO_'],
250
268
  pathExecutables:['node','npm'],executableIdentity:true}:yarnWorkspace?
251
269
  {variables:['NODE_OPTIONS','NODE_PATH','CI','HOME','NODE_ENV','BASH_ENV','ENV',...windowsContext],
@@ -257,7 +275,7 @@ const checks=publicConfig.checks.map(check=>{
257
275
  return {name:check.name,command:argv(scriptCommand||check.command,`${check.name}.command`),
258
276
  cwd:check.cwd,inputs:check.inputs||[],generatedInputs:check.generatedInputs||[],
259
277
  installedInputs:check.installedInputs||(
260
- npmAutomatic?['node_modules/**']:[]),
278
+ npmAutomatic||npmDirect?['node_modules/**']:[]),
261
279
  allowedExternalRoots:check.allowedExternalRoots||[],
262
280
  probes:[...(check.probes||[]),...autoProbes]
263
281
  .map((p,i)=>argv(p,`${check.name}.probes[${i}]`)),
@@ -267,6 +285,7 @@ const checks=publicConfig.checks.map(check=>{
267
285
  categories.map(category=>[category,reason])),
268
286
  qualification:check.qualification||null,script:check.script||null,
269
287
  ...(npmAutomatic?{qualificationInterpretation:'npm-launcher-withheld@1'}:{}),
288
+ ...(npmDirect?{qualificationInterpretation:directInterpretation}:{}),
270
289
  workspace:check.workspace||null,kind:check.kind||null};
271
290
  });
272
291
  const runtime={schema:1,provider:'declared-project@1',root,state,checks};
package/docs/README.md CHANGED
@@ -5,7 +5,7 @@ For users:
5
5
  - [Install, initialize, run, and remove](user/getting-started.md)
6
6
  - [Supported projects and conservative boundaries](user/supported-projects.md)
7
7
  - [Configuration](user/configuration.md)
8
- - [Coding-agent decision policy](user/agents.md)
8
+ - [Connect coding agents and apply the decision policy](user/agents.md)
9
9
  - [JSON contract](user/json.md)
10
10
  - [Shell usage](user/shell.md)
11
11
 
@@ -1,11 +1,11 @@
1
1
  # Agent decision policy
2
2
 
3
- Use the CLI; no SDK or bespoke agent integration is required. Add these
4
- instructions to a session or project only with its owner's permission.
3
+ Use the CLI with explicit project-local activation below, or add this policy to a
4
+ generic agent's instructions with the project owner's permission.
5
5
 
6
6
  1. Query ordinary `redue status --json` first.
7
- 2. If a check has `freshness: "CURRENT"`, `result: "PASS"`, and
8
- `reuse_eligible: true`, reuse it. Do not rerun merely for freshness.
7
+ 2. Require schema 1 and healthy observation. If a check has `freshness: "CURRENT"`, `result: "PASS"`, and
8
+ `reuse_eligible: true`, reuse it. Missing eligibility means false. Do not rerun merely for freshness.
9
9
  3. If STALE, run `redue run CHECK` when that verification is needed.
10
10
  4. If the historical `result` is FAIL, report it honestly. The human CLI calls
11
11
  this FAILED; applicability is a separate field, never an excuse to call it green.
@@ -25,8 +25,138 @@ check is not universal product correctness. Report additional uncaptured checks
25
25
  separately. Do not infer that an outer invocation's success proves a specific
26
26
  check ran or that an upstream cache was hit; inspect `target_provenance`.
27
27
 
28
+ Reassess at the decision point after edits or context changes; previous CURRENT is
29
+ not continuing authorization. A status exit code of zero is not proof of CURRENT.
30
+ An empty changed-input list does not prove nothing changed. `run CHECK --json`
31
+ streams check output; use a subsequent status/explain query for structured evidence.
32
+ Explicit fresh-execution requests still require execution.
33
+
28
34
  On a CLI error, unhealthy observation, or unavailable context, do not infer
29
35
  CURRENT. Do not delete state or reset receipts to make the output green.
30
36
 
31
37
  REDUE tells you what evidence exists and whether it still applies. It does not
32
38
  promise that establishing applicability is cheaper than every possible check.
39
+
40
+ ## Connect once (candidate)
41
+
42
+ The alpha.5 candidate supports opt-in project-local activation and direct
43
+ TypeScript evidence, with fresh-session reuse demonstrated for Codex CLI 0.160.1
44
+ on macOS under the documented owner-approved checkout/state/socket route. CLI
45
+ mechanics are tested on macOS/Linux/Windows; model behavior is not claimed for
46
+ every host/platform or sandbox policy. Claude setup/removal mechanics are tested,
47
+ but Claude behavior and cross-host reuse remain untested. Reuse is not guaranteed,
48
+ and the existing subsecond example establishes no meaningful net time saving.
49
+
50
+ After installing this candidate and running `redue init` in a trusted project:
51
+
52
+ ```sh
53
+ redue agent setup codex --dry-run
54
+ redue agent setup codex --apply
55
+ # Or: redue agent setup claude --apply
56
+ redue agent doctor
57
+ ```
58
+
59
+ Start a fresh agent session in this checkout, then give it your ordinary task.
60
+ Interactive setup shows the changes and asks before applying; noninteractive
61
+ setup requires `--apply`. `--dry-run` never writes. Installing REDUE or running
62
+ `init` does not connect an agent automatically. Setup does not start an observer
63
+ or execute verification. Use `redue start` when you want observation.
64
+
65
+ Codex gets a short managed section in project `AGENTS.md` and
66
+ `.agents/skills/redue-verification/SKILL.md`. Claude Code gets a managed section
67
+ in `CLAUDE.md` and `.claude/skills/redue-verification/SKILL.md`. Each uses the same
68
+ policy source; detailed guidance is loaded when verification is relevant. Small
69
+ ownership records in `.redue/agents/` support safe updates/removal. These are
70
+ portable project files, not receipts; review and commit them if the team wants
71
+ this integration. Do not ignore just the ownership records while committing the
72
+ managed files.
73
+
74
+ Existing instruction text is retained. Review it in the preview: setup cannot
75
+ prove arbitrary natural-language policies are consistent. Conflicts such as a
76
+ root `AGENTS.override.md` or an alternative `.claude/CLAUDE.md` are reported
77
+ instead of silently outranked. Global/managed policies, nested instructions,
78
+ Codex instruction-size limits, skill disabling, and host-specific exclusions
79
+ still apply. Complete the host's ordinary trust/permission prompts yourself;
80
+ REDUE never grants tool permission. Sandboxed hosts may need owner-approved access
81
+ to the checkout, owned state directory and local observer socket. A healthy daemon
82
+ does not establish that the agent can reach it; doctor reports control access
83
+ separately. Do not disable sandbox protections to make this work. Do not use a mode that disables project
84
+ instructions and expect automatic activation.
85
+
86
+ Control access is not simply file-read permission. The observer can reconcile and
87
+ write its owned index, run the trusted configuration's probes in its own process
88
+ context, reload receipts, and stop. Approve only the intended checkout/state and
89
+ endpoint, accounting for that authority. Doctor sends only a bounded metrics
90
+ request; it does not synchronize or run these probes.
91
+
92
+ `agent doctor [codex|claude] --json` is read-only. It distinguishes command lookup,
93
+ config resolution, cached observer health, a bounded read-only control-access probe,
94
+ managed-file integrity, detected host
95
+ version, and loading guidance. `behavior_verified: false` is deliberate: intact
96
+ files do not prove the agent followed them. No hooks are installed. Doctor neither
97
+ executes checks nor starts observers, reconciles inputs, or installs a host.
98
+
99
+ Doctor separates missing/unreadable state, a missing or refused endpoint, an
100
+ explicit EPERM/EACCES access denial, and timeout/invalid response. A denial does
101
+ not identify whether OS permissions or host policy caused it. A live PID and
102
+ healthy cached observation do not prove control access. An older cached response
103
+ without receipt-selection validation gets stop/start guidance. Windows command
104
+ shims whose target has not been established are reported as unknown, not a
105
+ proven installation mismatch.
106
+
107
+ Codex CLI 0.160.1 on macOS can use the approved exact observer-socket route while
108
+ other sockets and direct network access remain denied. Its independent sessions
109
+ receive different proxy values. Ordinary npm invocation is **not** equivalent
110
+ across arbitrary notifier state: this candidate withholds automatic npm-launcher
111
+ reuse. Do not change proxy settings or permissions to get green evidence.
112
+
113
+ The separate opt-in [direct local compiler recipe](direct-typescript.md) does not
114
+ run npm. Its reviewed compiler implementation does not consume npm/proxy settings;
115
+ a digest preserves their observed provenance without treating them as compiler
116
+ inputs. Other execution context remains strict, and cached status still cannot
117
+ assert caller eligibility. An explicit user request for `npm run typecheck` still
118
+ requires npm execution; direct compiler evidence is not a substitute.
119
+
120
+ Before model trials, run `redue agent doctor --json` and
121
+ `redue status --sync --json` inside the agent's actual command boundary. The
122
+ contributor helper `test/acceptance/codex-preflight.mjs --config FILE --check CHECK`
123
+ performs the same bounded, read-only decision check and exits 2 when reuse is not
124
+ eligible. It neither executes verification nor grants access; synchronization
125
+ may run configured probes. A successful outside-shell result is insufficient.
126
+
127
+ Use the same setup command after a candidate upgrade; it updates intact managed
128
+ content idempotently. Changed skill text or a changed managed block causes a
129
+ conflict instead of an overwrite. Review your edits before retrying.
130
+
131
+ ```sh
132
+ redue agent remove codex --dry-run
133
+ redue agent remove codex --apply
134
+ redue agent remove claude --apply
135
+ ```
136
+
137
+ Removal deletes only intact REDUE-owned content for that host. Unrelated text,
138
+ other integrations, project config, receipts and installed dependencies remain.
139
+ User edits outside the managed section survive. Modified managed content is left
140
+ intact with a diagnostic; compare it with a preview and resolve manually. Empty
141
+ parent directories may remain. If the selected config has been deleted, restore
142
+ it or manually remove only the marked REDUE section, that host's skill, and its
143
+ `.redue/agents/HOST.json` ownership record after review. Do not delete an entire
144
+ instruction file containing user content.
145
+
146
+ ## Project identity and generic agents
147
+
148
+ Commands from nested directories search toward the nearest Git root. If more than
149
+ one configuration applies, select one with `--config FILE`; REDUE refuses to guess.
150
+ The generated instruction names its project-relative configuration and applies it
151
+ to status/run/explain. External configs or custom machine-local `--state-dir`
152
+ setups should use a reviewed generic instruction instead of committing absolute
153
+ paths. Other worktrees and remote containers have separate local evidence.
154
+
155
+ For another agent, put a short instruction in its documented project mechanism:
156
+ “Before deciding whether configured verification needs repeating, read REDUE's
157
+ agent policy, query ordinary `redue status --json` for the intended config, and
158
+ apply the schema/health/reuse rules.” Supply this document and the
159
+ [JSON contract](json.md) as the detailed policy. Review the agent's actual tool
160
+ trace before calling activation verified. A local npm installation does not install
161
+ REDUE in a remote container; that environment needs its own CLI, checkout,
162
+ dependencies and state. There is no cloud/team receipt synchronization.
@@ -1,7 +1,7 @@
1
1
  # Configuration
2
2
 
3
- Prefer `redue init` over hand-authoring a qualified contract. A typical generated
4
- npm configuration is concise and portable:
3
+ Prefer `redue init` over hand-authoring a contract. An ordinary generated npm script (recording-only in this candidate)
4
+ configuration is concise and portable:
5
5
 
6
6
  ```json
7
7
  {
@@ -28,6 +28,9 @@ Use `--config FILE` to select an external configuration. `root` is relative to
28
28
  that file. Runtime paths, resolved executables, local evidence, and sockets stay
29
29
  out of version-controlled configuration.
30
30
 
31
+ For the explicit direct compiler choice and generated exact argv, see
32
+ [direct TypeScript](direct-typescript.md). Existing script receipts cannot satisfy it.
33
+
31
34
  ## Arbitrary commands
32
35
 
33
36
  An unrecognized ecosystem can still record ordinary execution:
@@ -0,0 +1,96 @@
1
+ # Explicit local TypeScript verification (unreleased candidate)
2
+
3
+ This check means: the reviewed local TypeScript compiler completed the configured
4
+ check against declared, observed inputs and relevant execution context. It does
5
+ not mean npm or npm lifecycle scripts completed.
6
+
7
+ For a supported single-package npm project with an existing standalone
8
+ `tsc --noEmit` script, installed dependencies, Node 22/24 and TypeScript 5.6.3/5.9.3:
9
+
10
+ ```sh
11
+ redue init --recipe typescript-direct --check typecheck --dry-run
12
+ redue init --recipe typescript-direct --check typecheck
13
+ redue start
14
+ redue run typecheck
15
+ redue status --sync
16
+ ```
17
+
18
+ The preview shows the discovered script and recorded direct invocation. Nothing
19
+ executes during init. package.json, environment and dependencies remain unchanged.
20
+ A generated check contains:
21
+
22
+ ```json
23
+ {
24
+ "name": "typecheck",
25
+ "script": "typecheck",
26
+ "kind": "typecheck",
27
+ "command": ["@node", "@typescript-compiler:.", "--noEmit"],
28
+ "cwd": ".",
29
+ "qualification": "npm-typescript-direct-v1",
30
+ "inputs": ["package.json", "package-lock.json", "tsconfig.json", "**/*.{ts,tsx,mts,cts,js,jsx,mjs,cjs,json,jsonc}", "!node_modules/**", "!.git/**"]
31
+ }
32
+ ```
33
+
34
+ `script` identifies the reviewed source recipe; `command` is what actually runs:
35
+ the resolved Node executable and local TypeScript implementation, with exact argv
36
+ and no shell. TypeScript 5.6.3 uses `lib/tsc.js`; 5.9.3 uses `lib/_tsc.js` directly,
37
+ without its outer compile-cache-enabling shim. No compiler is fetched or bundled.
38
+ The entire installed package must match reviewed official distribution bytes.
39
+
40
+ Existing configs are never overwritten. To compare choices, use a new project-local
41
+ `--config redue.direct.config.json` with init; this explicitly selects separate
42
+ state. To replace an existing check deliberately, preview JSON, stop its observer,
43
+ review/edit that check's config, and restart using the same config/state. Existing
44
+ npm receipts remain historical; the new command/interpretation needs a fresh run.
45
+ Do not delete receipts. `redue run` always executes the configured command.
46
+
47
+ ## Existing npm configuration: deliberate replacement
48
+
49
+ First upgrade through the [alpha.4 containment](npm-launcher-notice.md), stopping
50
+ observers before the installation change and restarting with the same config/state.
51
+ The old npm check becomes recording-only; its receipts remain historical.
52
+ To opt into this candidate afterward:
53
+
54
+ 1. Stop the observer, install the reviewed candidate tarball into the same prefix,
55
+ and keep the original `redue.config.json` and any explicit `--state-dir` selection.
56
+ 2. Run `redue init --recipe typescript-direct --check typecheck --dry-run --json`
57
+ using that config selection. Inspect `proposed_config.checks` and the recorded
58
+ invocation. This does not write anything, even when the config already exists.
59
+ 3. In your editor, replace only the intended check object with the reviewed proposed
60
+ object. Preserve its name, the top-level project configuration, and every other
61
+ check. Do not replace the whole config with a one-check preview. Keep a local
62
+ backup outside observed inputs if desired.
63
+ 4. Run `redue start` with the same config/state. `redue status --sync --json` must
64
+ not treat the old npm receipt as eligible compiler evidence.
65
+ 5. Run `redue run typecheck`, then `redue status --sync --json`. A qualified success
66
+ now records the direct compiler recipe with a new run ID. Old npm runs remain
67
+ immutable history. Other check definitions are unchanged.
68
+
69
+ Substitute the actual selected check name throughout. Repeating plain `init`
70
+ does **not** migrate an existing config. A deliberately separate `--config` file
71
+ is useful for comparison, but has separate state by design. Do not create one
72
+ accidentally when intending to preserve the original selection.
73
+
74
+ Pre/post scripts, compound commands, wrappers, environment assignments, workspace
75
+ projects and unsupported compiler versions are not automatically converted.
76
+ Init retains the original script with a reason. Development-mode source-map helpers,
77
+ Node preloads/loaders/compile-cache settings, unsupported compiler plugins or
78
+ incremental/composite configuration, outside-root inputs and uncertain observation
79
+ withhold applicability. Extra custom probes cannot inherit this recipe's context
80
+ exception. Relevant source, declaration, config, membership and installed-content
81
+ changes invalidate or withdraw applicability normally.
82
+
83
+ The versioned `npm-direct-typescript@1` interpretation retains relevant Node context
84
+ and identity. Reviewed compiler code does not parse npm settings or proxy variables;
85
+ these remain untouched in the child environment and are recorded only as a digest
86
+ of observed provenance. This is not an environment ignore option for arbitrary
87
+ commands or other providers. No remote service equivalence is claimed. Ordinary
88
+ cached status remains conservative; synchronize deliberately when worth the cost.
89
+
90
+ Explain/JSON report `verification_recipe: "npm-direct-typescript@1"` for receipts
91
+ recorded with this recipe. Report compiler evidence as compiler evidence. A user's
92
+ explicit request for `npm run typecheck` is not satisfied by this different command.
93
+
94
+ The injected `NODE_USE_ENV_PROXY=1` setting is admitted only on Node 22.13.0,
95
+ where it is inert; it remains strictly tracked. Other Node versions with this
96
+ setting need review and stay unqualified. REDUE does not alter the setting.
@@ -90,7 +90,10 @@ reusability. Qualification can change when configuration or installation changes
90
90
 
91
91
  `run` streams normal output and preserves execution environment and cancellation.
92
92
  For the narrow pnpm TypeScript contract, `init` explicitly shows the direct installed
93
- compiler invocation it selects; other scripts run through the package manager.
93
+ compiler invocation it selects. In this candidate, npm scripts remain recording-only;
94
+ use `redue init --recipe typescript-direct --dry-run` to preview a distinct,
95
+ explicit [local compiler recipe](direct-typescript.md). Other scripts run through
96
+ the package manager. No existing configuration is silently migrated.
94
97
  Only use configs and probes from trusted repositories: these execute local code.
95
98
 
96
99
  `status` is cached and conservative. `status --sync` and `explain` revalidate caller
@@ -133,3 +136,11 @@ all observed roots; its basename must start with `redue-` or legacy `vstate-`.
133
136
  For a removed checkout, `redue --state-dir /your/owned/redue-project-state remove-state`
134
137
  still works without rebuilding its compiler/configuration. Ownership/active-run conflicts
135
138
  are actionable errors, never resolved merely by deleting an old lock.
139
+
140
+ ## Connect an agent explicitly
141
+
142
+ After initialization, use `redue agent setup codex --dry-run` (or `claude`) to
143
+ review project-local instructions, then repeat with `--apply`. Start a fresh host
144
+ session. `redue agent doctor` checks prerequisites without running verification.
145
+ See [agent activation](agents.md) for loading rules, generic agents, and removal.
146
+ The released alpha.2 does not contain these candidate commands yet.
@@ -15,13 +15,15 @@ At the repository root, `init` looks for existing typecheck, test, lint, and
15
15
  build scripts. It prefers familiar script names, then unique recognizable
16
16
  `tsc`, Vitest/Jest, ESLint, or Vite commands under other names. Multiple
17
17
  matches are reported as ambiguous rather than guessed. It never creates a new
18
- project script. Canonical `tsc --noEmit` npm scripts are discovered and recorded, but their
19
- automatic applicability is withdrawn in alpha.4: npm's update notification uses
20
- remote/cache/time inputs outside the observed contract. Even a successful run
21
- remains UNVERIFIED/PASS. Historical receipts are retained. See the
22
- [maintainer notice](npm-launcher-notice.md). A separately selected verification
23
- obligation would require an explicit configuration and fresh evidence; alpha.4
24
- does not provide the unreleased npm direct-compiler recipe. Root and package-level npm/Yarn workspace scripts are discovered from
18
+ project script. Automatic npm-launcher applicability was withdrawn in alpha.4;
19
+ ordinary npm scripts remain recording-only. See the [maintainer notice](npm-launcher-notice.md).
20
+ The following direct recipe is opt-in and new in the alpha.5 candidate. The opt-in `init --recipe typescript-direct` supports
21
+ a standalone `tsc --noEmit` script in a single-package npm installation using
22
+ reviewed TypeScript 5.6.3/5.9.3 and Node 22/24. It executes the local compiler,
23
+ not npm. Full installed compiler identity, config/membership, installed inputs
24
+ and relevant Node environment are checked before reuse. See the
25
+ [exact direct boundary](direct-typescript.md). Unsupported plugins, preloads,
26
+ configuration or outside-root inputs remain UNVERIFIED. Root and package-level npm/Yarn workspace scripts are discovered from
25
27
  `package.json` workspace declarations. Pinned Yarn 4 `node-modules`/classic
26
28
  workspaces with a standalone `tsc -p .` script, local TypeScript, a conventional
27
29
  `src` include, and Node module resolution can qualify automatically. For one
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@redue/cli",
3
3
  "private": false,
4
- "version": "0.1.0-alpha.4",
4
+ "version": "0.1.0-alpha.6",
5
5
  "publishConfig": {
6
6
  "access": "public",
7
7
  "tag": "alpha"