instar 1.2.65 → 1.2.67
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/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +21 -0
- package/dist/commands/init.js.map +1 -1
- package/dist/core/PostUpdateMigrator.d.ts.map +1 -1
- package/dist/core/PostUpdateMigrator.js +38 -1
- package/dist/core/PostUpdateMigrator.js.map +1 -1
- package/dist/core/codexCapabilities.d.ts +31 -0
- package/dist/core/codexCapabilities.d.ts.map +1 -0
- package/dist/core/codexCapabilities.js +56 -0
- package/dist/core/codexCapabilities.js.map +1 -0
- package/dist/core/frameworkSessionLaunch.d.ts.map +1 -1
- package/dist/core/frameworkSessionLaunch.js +13 -0
- package/dist/core/frameworkSessionLaunch.js.map +1 -1
- package/dist/core/installCodexHooks.d.ts +52 -0
- package/dist/core/installCodexHooks.d.ts.map +1 -0
- package/dist/core/installCodexHooks.js +113 -0
- package/dist/core/installCodexHooks.js.map +1 -0
- package/package.json +1 -1
- package/src/data/builtin-manifest.json +17 -17
- package/upgrades/1.2.66.md +57 -0
- package/upgrades/1.2.67.md +57 -0
- package/upgrades/side-effects/codex-enforcement-hooks-p1.md +32 -0
- package/upgrades/side-effects/codex-enforcement-hooks-p1b.md +29 -0
- package/upgrades/side-effects/codex-enforcement-hooks-p2.md +36 -0
- package/upgrades/side-effects/codex-enforcement-hooks-p3.md +25 -0
- package/upgrades/side-effects/codex-enforcement-hooks-p5c.md +38 -0
- package/upgrades/side-effects/codex-hook-trust-bypass.md +37 -0
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* codexCapabilities — runtime feature detection for the Codex CLI.
|
|
3
|
+
*
|
|
4
|
+
* Codex's flag surface changes across versions, and instar agents run whatever
|
|
5
|
+
* codex the operator has installed (0.130 → 0.133+ all observed). Rather than
|
|
6
|
+
* track a version matrix, we probe the binary's `--help` once per binary path
|
|
7
|
+
* and cache the answer. Builders gate version-specific flags on these probes so
|
|
8
|
+
* an older codex never receives a flag it would reject (which would fail the
|
|
9
|
+
* whole launch).
|
|
10
|
+
*/
|
|
11
|
+
/**
|
|
12
|
+
* Whether `<binaryPath>` accepts `--dangerously-bypass-hook-trust`.
|
|
13
|
+
*
|
|
14
|
+
* The flag was added in codex 0.133 ("Run enabled hooks without requiring
|
|
15
|
+
* persisted hook trust for this invocation") and is ABSENT in 0.131/0.130.
|
|
16
|
+
* instar launches codex with this flag so its OWN safety hooks
|
|
17
|
+
* (installCodexHooks) run automatically with no interactive "trust these hooks?"
|
|
18
|
+
* prompt — which would otherwise freeze an unattended/autonomous session. It is
|
|
19
|
+
* safe-by-construction here: instar both writes the hooks and owns the launch
|
|
20
|
+
* command, so there is no untrusted third-party hook to guard against, and the
|
|
21
|
+
* agent cannot strip a flag from a launch it doesn't construct.
|
|
22
|
+
*
|
|
23
|
+
* Fails closed: any probe error (missing binary, timeout, non-zero exit) returns
|
|
24
|
+
* false, so an undetectable/older codex simply omits the flag. The hooks still
|
|
25
|
+
* block dangerous actions in that case — they just sit behind codex's interactive
|
|
26
|
+
* trust prompt rather than running unprompted.
|
|
27
|
+
*/
|
|
28
|
+
export declare function codexSupportsHookTrustBypass(binaryPath: string): boolean;
|
|
29
|
+
/** Test-only: clear the memoization cache so a probe re-runs. */
|
|
30
|
+
export declare function __resetCodexCapabilityCache(): void;
|
|
31
|
+
//# sourceMappingURL=codexCapabilities.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"codexCapabilities.d.ts","sourceRoot":"","sources":["../../src/core/codexCapabilities.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAOH;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,4BAA4B,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAiBxE;AAED,iEAAiE;AACjE,wBAAgB,2BAA2B,IAAI,IAAI,CAElD"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* codexCapabilities — runtime feature detection for the Codex CLI.
|
|
3
|
+
*
|
|
4
|
+
* Codex's flag surface changes across versions, and instar agents run whatever
|
|
5
|
+
* codex the operator has installed (0.130 → 0.133+ all observed). Rather than
|
|
6
|
+
* track a version matrix, we probe the binary's `--help` once per binary path
|
|
7
|
+
* and cache the answer. Builders gate version-specific flags on these probes so
|
|
8
|
+
* an older codex never receives a flag it would reject (which would fail the
|
|
9
|
+
* whole launch).
|
|
10
|
+
*/
|
|
11
|
+
import { execFileSync } from 'node:child_process';
|
|
12
|
+
/** Memoized per binaryPath — `codex --help` is invoked at most once per path per process. */
|
|
13
|
+
const hookTrustBypassCache = new Map();
|
|
14
|
+
/**
|
|
15
|
+
* Whether `<binaryPath>` accepts `--dangerously-bypass-hook-trust`.
|
|
16
|
+
*
|
|
17
|
+
* The flag was added in codex 0.133 ("Run enabled hooks without requiring
|
|
18
|
+
* persisted hook trust for this invocation") and is ABSENT in 0.131/0.130.
|
|
19
|
+
* instar launches codex with this flag so its OWN safety hooks
|
|
20
|
+
* (installCodexHooks) run automatically with no interactive "trust these hooks?"
|
|
21
|
+
* prompt — which would otherwise freeze an unattended/autonomous session. It is
|
|
22
|
+
* safe-by-construction here: instar both writes the hooks and owns the launch
|
|
23
|
+
* command, so there is no untrusted third-party hook to guard against, and the
|
|
24
|
+
* agent cannot strip a flag from a launch it doesn't construct.
|
|
25
|
+
*
|
|
26
|
+
* Fails closed: any probe error (missing binary, timeout, non-zero exit) returns
|
|
27
|
+
* false, so an undetectable/older codex simply omits the flag. The hooks still
|
|
28
|
+
* block dangerous actions in that case — they just sit behind codex's interactive
|
|
29
|
+
* trust prompt rather than running unprompted.
|
|
30
|
+
*/
|
|
31
|
+
export function codexSupportsHookTrustBypass(binaryPath) {
|
|
32
|
+
if (!binaryPath)
|
|
33
|
+
return false;
|
|
34
|
+
const cached = hookTrustBypassCache.get(binaryPath);
|
|
35
|
+
if (cached !== undefined)
|
|
36
|
+
return cached;
|
|
37
|
+
let supported = false;
|
|
38
|
+
try {
|
|
39
|
+
const help = execFileSync(binaryPath, ['--help'], {
|
|
40
|
+
encoding: 'utf-8',
|
|
41
|
+
timeout: 5000,
|
|
42
|
+
stdio: ['ignore', 'pipe', 'ignore'],
|
|
43
|
+
});
|
|
44
|
+
supported = help.includes('--dangerously-bypass-hook-trust');
|
|
45
|
+
}
|
|
46
|
+
catch {
|
|
47
|
+
supported = false;
|
|
48
|
+
}
|
|
49
|
+
hookTrustBypassCache.set(binaryPath, supported);
|
|
50
|
+
return supported;
|
|
51
|
+
}
|
|
52
|
+
/** Test-only: clear the memoization cache so a probe re-runs. */
|
|
53
|
+
export function __resetCodexCapabilityCache() {
|
|
54
|
+
hookTrustBypassCache.clear();
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=codexCapabilities.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"codexCapabilities.js","sourceRoot":"","sources":["../../src/core/codexCapabilities.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAElD,6FAA6F;AAC7F,MAAM,oBAAoB,GAAG,IAAI,GAAG,EAAmB,CAAC;AAExD;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,UAAU,4BAA4B,CAAC,UAAkB;IAC7D,IAAI,CAAC,UAAU;QAAE,OAAO,KAAK,CAAC;IAC9B,MAAM,MAAM,GAAG,oBAAoB,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;IACpD,IAAI,MAAM,KAAK,SAAS;QAAE,OAAO,MAAM,CAAC;IACxC,IAAI,SAAS,GAAG,KAAK,CAAC;IACtB,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,YAAY,CAAC,UAAU,EAAE,CAAC,QAAQ,CAAC,EAAE;YAChD,QAAQ,EAAE,OAAO;YACjB,OAAO,EAAE,IAAI;YACb,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,CAAC;SACpC,CAAC,CAAC;QACH,SAAS,GAAG,IAAI,CAAC,QAAQ,CAAC,iCAAiC,CAAC,CAAC;IAC/D,CAAC;IAAC,MAAM,CAAC;QACP,SAAS,GAAG,KAAK,CAAC;IACpB,CAAC;IACD,oBAAoB,CAAC,GAAG,CAAC,UAAU,EAAE,SAAS,CAAC,CAAC;IAChD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,iEAAiE;AACjE,MAAM,UAAU,2BAA2B;IACzC,oBAAoB,CAAC,KAAK,EAAE,CAAC;AAC/B,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"frameworkSessionLaunch.d.ts","sourceRoot":"","sources":["../../src/core/frameworkSessionLaunch.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,kCAAkC,CAAC;
|
|
1
|
+
{"version":3,"file":"frameworkSessionLaunch.d.ts","sourceRoot":"","sources":["../../src/core/frameworkSessionLaunch.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,kCAAkC,CAAC;AAG9E;;;;;;GAMG;AACH,MAAM,MAAM,gBAAgB,GAAG,MAAM,GAAG,UAAU,GAAG,SAAS,CAAC;AAE/D;;;;;;;;;GASG;AACH,wBAAgB,wBAAwB,CACtC,SAAS,EAAE,qBAAqB,EAChC,WAAW,EAAE,MAAM,GAAG,SAAS,GAC9B,MAAM,GAAG,SAAS,CA6BpB;AAmBD,MAAM,WAAW,wBAAwB;IACvC,kEAAkE;IAClE,UAAU,EAAE,MAAM,CAAC;IACnB;;;;OAIG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB;;;;OAIG;IACH,gBAAgB,CAAC,EAAE,WAAW,GAAG,iBAAiB,GAAG,oBAAoB,CAAC;IAC1E;;;;;;OAMG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;;;OAIG;IACH,kBAAkB,CAAC,EAAE,QAAQ,GAAG,UAAU,CAAC;IAC3C;;;;;;OAMG;IACH,kBAAkB,CAAC,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC;CAC1D;AAED,MAAM,WAAW,qBAAqB;IACpC,kFAAkF;IAClF,IAAI,EAAE,MAAM,EAAE,CAAC;IACf;;;;OAIG;IACH,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACtC;AA8GD;;;;;;;;GAQG;AACH,wBAAgB,sBAAsB,CACpC,SAAS,EAAE,qBAAqB,EAChC,OAAO,EAAE,wBAAwB,GAChC,qBAAqB,CAMvB;AAED;;;;;GAKG;AACH,wBAAgB,2BAA2B,CAAC,KAAK,EAAE;IACjD,OAAO,CAAC,EAAE,qBAAqB,CAAC;IAChC,eAAe,CAAC,EAAE,qBAAqB,CAAC;IACxC,YAAY,CAAC,EAAE,qBAAqB,GAAG,IAAI,CAAC;CAC7C,GAAG,qBAAqB,CAExB;AAED;;;;;GAKG;AACH,MAAM,WAAW,qBAAqB;IACpC,kEAAkE;IAClE,UAAU,EAAE,MAAM,CAAC;IACnB,mCAAmC;IACnC,MAAM,EAAE,MAAM,CAAC;IACf;;;;;;;OAOG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;;;OAKG;IACH,gBAAgB,CAAC,EAAE,WAAW,GAAG,iBAAiB,GAAG,oBAAoB,CAAC;IAC1E;;;;;;;;OAQG;IACH,kBAAkB,CAAC,EAAE,QAAQ,GAAG,UAAU,CAAC;IAC3C;;;;;OAKG;IACH,kBAAkB,CAAC,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC;IACzD;;;;;;;OAOG;IACH,kBAAkB,CAAC,EAAE,OAAO,CAAC;CAC9B;AAED,MAAM,WAAW,kBAAkB;IACjC,kFAAkF;IAClF,IAAI,EAAE,MAAM,EAAE,CAAC;IACf;;;;OAIG;IACH,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACtC;AAyFD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,mBAAmB,CACjC,SAAS,EAAE,qBAAqB,EAChC,OAAO,EAAE,qBAAqB,GAC7B,kBAAkB,CAMpB"}
|
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
* `BUILDERS`. The exhaustiveness check in `buildInteractiveLaunch`
|
|
13
13
|
* forces a compile error if a case is missed.
|
|
14
14
|
*/
|
|
15
|
+
import { codexSupportsHookTrustBypass } from './codexCapabilities.js';
|
|
15
16
|
/**
|
|
16
17
|
* Map a generic tier or framework-specific name to the concrete model
|
|
17
18
|
* string that should be passed to the framework's CLI. Pass-through for
|
|
@@ -155,6 +156,13 @@ const codexCliBuilder = (options) => {
|
|
|
155
156
|
else {
|
|
156
157
|
argv.push('--dangerously-bypass-approvals-and-sandbox');
|
|
157
158
|
}
|
|
159
|
+
// Run instar's own safety hooks (installCodexHooks) without the interactive
|
|
160
|
+
// "trust these hooks?" prompt that would otherwise freeze an unattended
|
|
161
|
+
// session. Gated on a capability probe — codex <0.133 lacks the flag and would
|
|
162
|
+
// reject it. Safe-by-construction: instar writes the hooks and owns the launch.
|
|
163
|
+
if (codexSupportsHookTrustBypass(options.binaryPath)) {
|
|
164
|
+
argv.push('--dangerously-bypass-hook-trust');
|
|
165
|
+
}
|
|
158
166
|
argv.push(...codexThreadlineMcpFlags(options.codexThreadlineMcp));
|
|
159
167
|
return {
|
|
160
168
|
argv,
|
|
@@ -255,6 +263,11 @@ const codexCliHeadlessBuilder = (options) => {
|
|
|
255
263
|
else {
|
|
256
264
|
argv.push('-s', 'workspace-write');
|
|
257
265
|
}
|
|
266
|
+
// Run instar's own safety hooks without a persisted-trust requirement (same
|
|
267
|
+
// rationale as the interactive builder; capability-gated for codex <0.133).
|
|
268
|
+
if (codexSupportsHookTrustBypass(options.binaryPath)) {
|
|
269
|
+
argv.push('--dangerously-bypass-hook-trust');
|
|
270
|
+
}
|
|
258
271
|
// -c overrides must precede the positional prompt in `codex exec`.
|
|
259
272
|
argv.push(...codexThreadlineMcpFlags(options.codexThreadlineMcp));
|
|
260
273
|
argv.push('-m', model, options.prompt);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"frameworkSessionLaunch.js","sourceRoot":"","sources":["../../src/core/frameworkSessionLaunch.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;
|
|
1
|
+
{"version":3,"file":"frameworkSessionLaunch.js","sourceRoot":"","sources":["../../src/core/frameworkSessionLaunch.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAGH,OAAO,EAAE,4BAA4B,EAAE,MAAM,wBAAwB,CAAC;AAWtE;;;;;;;;;GASG;AACH,MAAM,UAAU,wBAAwB,CACtC,SAAgC,EAChC,WAA+B;IAE/B,IAAI,CAAC,WAAW;QAAE,OAAO,SAAS,CAAC;IACnC,MAAM,GAAG,GAAG,WAAW,CAAC,WAAW,EAAE,CAAC;IAEtC,IAAI,SAAS,KAAK,aAAa,EAAE,CAAC;QAChC,iEAAiE;QACjE,kEAAkE;QAClE,8DAA8D;QAC9D,IAAI,GAAG,KAAK,MAAM;YAAE,OAAO,OAAO,CAAC;QACnC,IAAI,GAAG,KAAK,UAAU;YAAE,OAAO,QAAQ,CAAC;QACxC,IAAI,GAAG,KAAK,SAAS;YAAE,OAAO,MAAM,CAAC;QACrC,OAAO,WAAW,CAAC;IACrB,CAAC;IACD,IAAI,SAAS,KAAK,WAAW,EAAE,CAAC;QAC9B,iEAAiE;QACjE,+DAA+D;QAC/D,4DAA4D;QAC5D,0DAA0D;QAC1D,6DAA6D;QAC7D,2BAA2B;QAC3B,yEAAyE;QACzE,0EAA0E;QAC1E,mEAAmE;QACnE,IAAI,GAAG,KAAK,MAAM,IAAI,GAAG,KAAK,OAAO;YAAE,OAAO,SAAS,CAAC,CAAQ,wBAAwB;QACxF,IAAI,GAAG,KAAK,UAAU,IAAI,GAAG,KAAK,QAAQ;YAAE,OAAO,cAAc,CAAC,CAAC,8BAA8B;QACjG,IAAI,GAAG,KAAK,SAAS,IAAI,GAAG,KAAK,MAAM;YAAE,OAAO,SAAS,CAAC,CAAM,6BAA6B;QAC7F,OAAO,WAAW,CAAC;IACrB,CAAC;IACD,OAAO,WAAW,CAAC;AACrB,CAAC;AAED;;;;;;;GAOG;AACH,SAAS,uBAAuB,CAAC,GAAyC;IACxE,IAAI,CAAC,GAAG;QAAE,OAAO,EAAE,CAAC;IACpB,OAAO;QACL,IAAI,EAAE,kCAAkC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE;QACrE,IAAI,EAAE,+BAA+B,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE;QAC/D,IAAI,EAAE,+BAA+B,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE;KAC/D,CAAC;AACJ,CAAC;AAsDD,MAAM,iBAAiB,GAAY,CAAC,OAAO,EAAE,EAAE;IAC7C,MAAM,IAAI,GAAa,CAAC,OAAO,CAAC,UAAU,EAAE,gCAAgC,CAAC,CAAC;IAC9E,IAAI,OAAO,CAAC,eAAe,EAAE,CAAC;QAC5B,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,OAAO,CAAC,eAAe,CAAC,CAAC;IACjD,CAAC;IACD,OAAO;QACL,IAAI;QACJ,YAAY,EAAE;YACZ,qEAAqE;YACrE,UAAU,EAAE,EAAE;SACf;KACF,CAAC;AACJ,CAAC,CAAC;AAEF,MAAM,eAAe,GAAY,CAAC,OAAO,EAAE,EAAE;IAC3C,oEAAoE;IACpE,mEAAmE;IACnE,8DAA8D;IAC9D,kEAAkE;IAClE,kEAAkE;IAClE,2DAA2D;IAC3D,+DAA+D;IAC/D,iEAAiE;IACjE,gEAAgE;IAChE,gEAAgE;IAChE,kEAAkE;IAClE,kEAAkE;IAClE,qCAAqC;IACrC,qEAAqE;IACrE,iEAAiE;IACjE,2DAA2D;IAC3D,qEAAqE;IACrE,kEAAkE;IAClE,uDAAuD;IACvD,oEAAoE;IACpE,kEAAkE;IAClE,oEAAoE;IACpE,oBAAoB;IACpB,mEAAmE;IACnE,mEAAmE;IACnE,qEAAqE;IACrE,gEAAgE;IAChE,kEAAkE;IAClE,4DAA4D;IAC5D,gEAAgE;IAChE,oCAAoC;IACpC,MAAM,OAAO,GAAG,OAAO,CAAC,kBAAkB,KAAK,SAAS,CAAC;IACzD,MAAM,aAAa,GAAG,OAAO;QAC3B,CAAC,CAAC,CAAC,OAAO,CAAC,YAAY,IAAI,iBAAiB,CAAC;QAC7C,CAAC,CAAC,CAAC,wBAAwB,CAAC,WAAW,EAAE,OAAO,CAAC,YAAY,CAAC,IAAI,SAAS,CAAC,CAAC;IAE/E,wEAAwE;IACxE,wEAAwE;IACxE,wEAAwE;IACxE,oEAAoE;IACpE,iEAAiE;IACjE,2DAA2D;IAC3D,EAAE;IACF,mEAAmE;IACnE,sEAAsE;IACtE,yEAAyE;IACzE,sEAAsE;IACtE,qEAAqE;IACrE,uEAAuE;IACvE,mDAAmD;IACnD,MAAM,YAAY,GAAa,OAAO,CAAC,eAAe;QACpD,CAAC,CAAC,CAAC,QAAQ,EAAE,OAAO,CAAC,eAAe,CAAC;QACrC,CAAC,CAAC,EAAE,CAAC;IAEP,MAAM,IAAI,GAAa;QACrB,OAAO,CAAC,UAAU;QAClB,GAAG,YAAY;QACf,SAAS,EAAE,aAAa;KACzB,CAAC;IACF,IAAI,OAAO,EAAE,CAAC;QACZ,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,kBAAkB,EAAE,OAAO,CAAC,kBAAmB,CAAC,CAAC;IACtE,CAAC;IACD,IAAI,OAAO,CAAC,gBAAgB,EAAE,CAAC;QAC7B,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,OAAO,CAAC,gBAAgB,EAAE,oBAAoB,EAAE,OAAO,CAAC,CAAC;IAClF,CAAC;SAAM,CAAC;QACN,IAAI,CAAC,IAAI,CAAC,4CAA4C,CAAC,CAAC;IAC1D,CAAC;IACD,4EAA4E;IAC5E,wEAAwE;IACxE,+EAA+E;IAC/E,gFAAgF;IAChF,IAAI,4BAA4B,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC;QACrD,IAAI,CAAC,IAAI,CAAC,iCAAiC,CAAC,CAAC;IAC/C,CAAC;IACD,IAAI,CAAC,IAAI,CAAC,GAAG,uBAAuB,CAAC,OAAO,CAAC,kBAAkB,CAAC,CAAC,CAAC;IAClE,OAAO;QACL,IAAI;QACJ,YAAY,EAAE;YACZ,uDAAuD;YACvD,+DAA+D;YAC/D,2DAA2D;YAC3D,UAAU,EAAE,EAAE;SACf;KACF,CAAC;AACJ,CAAC,CAAC;AAEF,MAAM,QAAQ,GAA2C;IACvD,aAAa,EAAE,iBAAiB;IAChC,WAAW,EAAE,eAAe;CAC7B,CAAC;AAEF;;;;;;;;GAQG;AACH,MAAM,UAAU,sBAAsB,CACpC,SAAgC,EAChC,OAAiC;IAEjC,MAAM,OAAO,GAAG,QAAQ,CAAC,SAAS,CAAC,CAAC;IACpC,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CAAC,2DAA2D,SAAS,GAAG,CAAC,CAAC;IAC3F,CAAC;IACD,OAAO,OAAO,CAAC,OAAO,CAAC,CAAC;AAC1B,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,2BAA2B,CAAC,KAI3C;IACC,OAAO,KAAK,CAAC,OAAO,IAAI,KAAK,CAAC,eAAe,IAAI,KAAK,CAAC,YAAY,IAAI,aAAa,CAAC;AACvF,CAAC;AAsED,MAAM,yBAAyB,GAAoB,CAAC,OAAO,EAAE,EAAE;IAC7D,MAAM,IAAI,GAAa,CAAC,OAAO,CAAC,UAAU,EAAE,gCAAgC,CAAC,CAAC;IAC9E,MAAM,QAAQ,GAAG,wBAAwB,CAAC,aAAa,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC;IACxE,IAAI,QAAQ,EAAE,CAAC;QACb,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;IACjC,CAAC;IACD,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;IAChC,OAAO;QACL,IAAI;QACJ,YAAY,EAAE;YACZ,4DAA4D;YAC5D,UAAU,EAAE,EAAE;SACf;KACF,CAAC;AACJ,CAAC,CAAC;AAEF,MAAM,uBAAuB,GAAoB,CAAC,OAAO,EAAE,EAAE;IAC3D,2DAA2D;IAC3D,qFAAqF;IACrF,oEAAoE;IACpE,oEAAoE;IACpE,sCAAsC;IACtC,kEAAkE;IAClE,gEAAgE;IAChE,6DAA6D;IAC7D,sEAAsE;IACtE,wCAAwC;IACxC,MAAM,OAAO,GAAG,OAAO,CAAC,kBAAkB,KAAK,SAAS,CAAC;IACzD,MAAM,KAAK,GAAG,OAAO;QACnB,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,IAAI,iBAAiB,CAAC;QACtC,CAAC,CAAC,CAAC,wBAAwB,CAAC,WAAW,EAAE,OAAO,CAAC,KAAK,CAAC,IAAI,SAAS,CAAC,CAAC;IACxE,MAAM,IAAI,GAAa;QACrB,OAAO,CAAC,UAAU;QAClB,MAAM;QACN,QAAQ;QACR,uBAAuB;KACxB,CAAC;IACF,IAAI,OAAO,EAAE,CAAC;QACZ,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,kBAAkB,EAAE,OAAO,CAAC,kBAAmB,CAAC,CAAC;IACtE,CAAC;IACD,8BAA8B;IAC9B,wEAAwE;IACxE,iFAAiF;IACjF,yDAAyD;IACzD,EAAE;IACF,yEAAyE;IACzE,4EAA4E;IAC5E,6EAA6E;IAC7E,8EAA8E;IAC9E,6EAA6E;IAC7E,4EAA4E;IAC5E,yEAAyE;IACzE,IAAI,OAAO,CAAC,gBAAgB,EAAE,CAAC;QAC7B,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,OAAO,CAAC,gBAAgB,EAAE,oBAAoB,EAAE,OAAO,CAAC,CAAC;IAC3E,CAAC;SAAM,IAAI,OAAO,CAAC,kBAAkB,EAAE,CAAC;QACtC,IAAI,CAAC,IAAI,CAAC,4CAA4C,CAAC,CAAC;IAC1D,CAAC;SAAM,CAAC;QACN,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,iBAAiB,CAAC,CAAC;IACrC,CAAC;IACD,4EAA4E;IAC5E,4EAA4E;IAC5E,IAAI,4BAA4B,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC;QACrD,IAAI,CAAC,IAAI,CAAC,iCAAiC,CAAC,CAAC;IAC/C,CAAC;IACD,mEAAmE;IACnE,IAAI,CAAC,IAAI,CAAC,GAAG,uBAAuB,CAAC,OAAO,CAAC,kBAAkB,CAAC,CAAC,CAAC;IAClE,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;IACvC,OAAO;QACL,IAAI;QACJ,YAAY,EAAE;YACZ,kEAAkE;YAClE,iEAAiE;YACjE,kEAAkE;YAClE,gEAAgE;YAChE,6CAA6C;YAC7C,UAAU,EAAE,EAAE;SACf;KACF,CAAC;AACJ,CAAC,CAAC;AAEF,MAAM,iBAAiB,GAAmD;IACxE,aAAa,EAAE,yBAAyB;IACxC,WAAW,EAAE,uBAAuB;CACrC,CAAC;AAEF;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,UAAU,mBAAmB,CACjC,SAAgC,EAChC,OAA8B;IAE9B,MAAM,OAAO,GAAG,iBAAiB,CAAC,SAAS,CAAC,CAAC;IAC7C,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CAAC,wDAAwD,SAAS,GAAG,CAAC,CAAC;IACxF,CAAC;IACD,OAAO,OAAO,CAAC,OAAO,CAAC,CAAC;AAC1B,CAAC"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* installCodexHooks — wire instar's safety gates into a Codex CLI agent's
|
|
3
|
+
* native hook system, the Codex mirror of `installClaudeSettings`.
|
|
4
|
+
*
|
|
5
|
+
* Spec: docs/specs/codex-enforcement-hook-layer.md
|
|
6
|
+
*
|
|
7
|
+
* WHY: on Claude agents, instar's gates (external-operation, response-review,
|
|
8
|
+
* grounding, deferral, session-start, topic-context) are enforced via
|
|
9
|
+
* `.claude/settings.json` hooks. On Codex agents nothing enforced them — the
|
|
10
|
+
* gates were awareness-only. Codex CLI supports a Claude-compatible blocking
|
|
11
|
+
* hook system (verified: developers.openai.com/codex/hooks — PreToolUse can
|
|
12
|
+
* deny via `permissionDecision` or exit-2; events incl. SessionStart,
|
|
13
|
+
* PreToolUse, PermissionRequest, PostToolUse, UserPromptSubmit, Stop). This
|
|
14
|
+
* writes the gate registrations into Codex's discovery path.
|
|
15
|
+
*
|
|
16
|
+
* SCOPING (correctness-critical): writes the **per-project**
|
|
17
|
+
* `<projectDir>/.codex/hooks.json`, NOT the global `~/.codex/hooks.json`.
|
|
18
|
+
* The global root is shared with the operator's personal desktop Codex and
|
|
19
|
+
* every other Codex project on the machine — global enforcement hooks would
|
|
20
|
+
* intercept the operator's personal sessions. Per-project `.codex/` is a
|
|
21
|
+
* documented Codex discovery path and scopes the gates to this agent only.
|
|
22
|
+
*
|
|
23
|
+
* Invocation contract (Codex): the command receives the event JSON on stdin
|
|
24
|
+
* (no args), runs with the session cwd as working directory. We register
|
|
25
|
+
* absolute paths so discovery does not depend on cwd. The gate scripts'
|
|
26
|
+
* Codex-payload parsing is handled by the framework shim (spec P2); this
|
|
27
|
+
* module only writes the registrations.
|
|
28
|
+
*
|
|
29
|
+
* Idempotent + merge-safe: instar-owned entries are identified by a command
|
|
30
|
+
* path under `.instar/hooks/instar/` and replaced on every run; any
|
|
31
|
+
* user-added Codex hooks are preserved untouched.
|
|
32
|
+
*/
|
|
33
|
+
/** Marker that identifies an instar-owned hook command (for merge-safe replace). */
|
|
34
|
+
export declare const INSTAR_HOOK_PATH_MARKER = ".instar/hooks/instar/";
|
|
35
|
+
interface CodexHookHandler {
|
|
36
|
+
type: 'command';
|
|
37
|
+
command: string;
|
|
38
|
+
timeout?: number;
|
|
39
|
+
}
|
|
40
|
+
interface CodexHookGroup {
|
|
41
|
+
matcher?: string;
|
|
42
|
+
hooks: CodexHookHandler[];
|
|
43
|
+
}
|
|
44
|
+
/** Build the instar-owned hook groups for each Codex event, with absolute script paths. */
|
|
45
|
+
export declare function buildInstarCodexHookGroups(projectDir: string): Record<string, CodexHookGroup[]>;
|
|
46
|
+
/**
|
|
47
|
+
* Write/merge instar gate hooks into `<projectDir>/.codex/hooks.json`.
|
|
48
|
+
* Preserves any user-added hooks; replaces instar-owned entries.
|
|
49
|
+
*/
|
|
50
|
+
export declare function installCodexHooks(projectDir: string): string;
|
|
51
|
+
export {};
|
|
52
|
+
//# sourceMappingURL=installCodexHooks.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"installCodexHooks.d.ts","sourceRoot":"","sources":["../../src/core/installCodexHooks.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAKH,oFAAoF;AACpF,eAAO,MAAM,uBAAuB,0BAA0B,CAAC;AAE/D,UAAU,gBAAgB;IACxB,IAAI,EAAE,SAAS,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AACD,UAAU,cAAc;IACtB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,gBAAgB,EAAE,CAAC;CAC3B;AAMD,2FAA2F;AAC3F,wBAAgB,0BAA0B,CACxC,UAAU,EAAE,MAAM,GACjB,MAAM,CAAC,MAAM,EAAE,cAAc,EAAE,CAAC,CA4ClC;AAQD;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAwB5D"}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* installCodexHooks — wire instar's safety gates into a Codex CLI agent's
|
|
3
|
+
* native hook system, the Codex mirror of `installClaudeSettings`.
|
|
4
|
+
*
|
|
5
|
+
* Spec: docs/specs/codex-enforcement-hook-layer.md
|
|
6
|
+
*
|
|
7
|
+
* WHY: on Claude agents, instar's gates (external-operation, response-review,
|
|
8
|
+
* grounding, deferral, session-start, topic-context) are enforced via
|
|
9
|
+
* `.claude/settings.json` hooks. On Codex agents nothing enforced them — the
|
|
10
|
+
* gates were awareness-only. Codex CLI supports a Claude-compatible blocking
|
|
11
|
+
* hook system (verified: developers.openai.com/codex/hooks — PreToolUse can
|
|
12
|
+
* deny via `permissionDecision` or exit-2; events incl. SessionStart,
|
|
13
|
+
* PreToolUse, PermissionRequest, PostToolUse, UserPromptSubmit, Stop). This
|
|
14
|
+
* writes the gate registrations into Codex's discovery path.
|
|
15
|
+
*
|
|
16
|
+
* SCOPING (correctness-critical): writes the **per-project**
|
|
17
|
+
* `<projectDir>/.codex/hooks.json`, NOT the global `~/.codex/hooks.json`.
|
|
18
|
+
* The global root is shared with the operator's personal desktop Codex and
|
|
19
|
+
* every other Codex project on the machine — global enforcement hooks would
|
|
20
|
+
* intercept the operator's personal sessions. Per-project `.codex/` is a
|
|
21
|
+
* documented Codex discovery path and scopes the gates to this agent only.
|
|
22
|
+
*
|
|
23
|
+
* Invocation contract (Codex): the command receives the event JSON on stdin
|
|
24
|
+
* (no args), runs with the session cwd as working directory. We register
|
|
25
|
+
* absolute paths so discovery does not depend on cwd. The gate scripts'
|
|
26
|
+
* Codex-payload parsing is handled by the framework shim (spec P2); this
|
|
27
|
+
* module only writes the registrations.
|
|
28
|
+
*
|
|
29
|
+
* Idempotent + merge-safe: instar-owned entries are identified by a command
|
|
30
|
+
* path under `.instar/hooks/instar/` and replaced on every run; any
|
|
31
|
+
* user-added Codex hooks are preserved untouched.
|
|
32
|
+
*/
|
|
33
|
+
import fs from 'node:fs';
|
|
34
|
+
import path from 'node:path';
|
|
35
|
+
/** Marker that identifies an instar-owned hook command (for merge-safe replace). */
|
|
36
|
+
export const INSTAR_HOOK_PATH_MARKER = '.instar/hooks/instar/';
|
|
37
|
+
/** Build the instar-owned hook groups for each Codex event, with absolute script paths. */
|
|
38
|
+
export function buildInstarCodexHookGroups(projectDir) {
|
|
39
|
+
const node = (script) => ({
|
|
40
|
+
type: 'command',
|
|
41
|
+
command: `node ${path.join(projectDir, INSTAR_HOOK_PATH_MARKER, script)}`,
|
|
42
|
+
timeout: 5000,
|
|
43
|
+
});
|
|
44
|
+
const sh = (script) => ({
|
|
45
|
+
type: 'command',
|
|
46
|
+
command: `bash ${path.join(projectDir, INSTAR_HOOK_PATH_MARKER, script)}`,
|
|
47
|
+
timeout: 5000,
|
|
48
|
+
});
|
|
49
|
+
return {
|
|
50
|
+
// Pre-action gate. matcher '.*' = all tool calls (Codex treats the matcher as
|
|
51
|
+
// a regex against the tool name; a bare '*' is an invalid quantifier that
|
|
52
|
+
// matches NOTHING, so the gate silently never fires — '.*' is required.
|
|
53
|
+
// Verified live 2026-05-24: with '.*', dangerous-command-guard fires on Codex's
|
|
54
|
+
// exec_command tool and blocks `rm -rf /`; with '*'/'' it did not fire at all).
|
|
55
|
+
// Each script classifies and decides: dangerous-command-guard covers Codex's
|
|
56
|
+
// native shell/exec_command (the main destructive surface); external-operation-gate
|
|
57
|
+
// covers mcp__* tools; grounding-before-messaging gates messaging commands. All
|
|
58
|
+
// read the command from Codex's stdin payload — Codex's exec_command puts it in
|
|
59
|
+
// tool_input.cmd (Claude uses tool_input.command); the scripts shim arg→stdin and
|
|
60
|
+
// accept both field names.
|
|
61
|
+
PreToolUse: [
|
|
62
|
+
{ matcher: '.*', hooks: [sh('dangerous-command-guard.sh'), node('external-operation-gate.js'), sh('grounding-before-messaging.sh')] },
|
|
63
|
+
],
|
|
64
|
+
// Codex-only checkpoint. Routes to the same gate; the trust system
|
|
65
|
+
// auto-decides (allow/deny) with NO human prompt so autonomy is preserved.
|
|
66
|
+
PermissionRequest: [
|
|
67
|
+
{ matcher: '.*', hooks: [node('external-operation-gate.js')] },
|
|
68
|
+
],
|
|
69
|
+
// End-of-turn review: coherence/tone + deferral detection.
|
|
70
|
+
Stop: [
|
|
71
|
+
{ matcher: '', hooks: [{ ...node('response-review.js'), timeout: 10000 }, node('deferral-detector.js')] },
|
|
72
|
+
],
|
|
73
|
+
// Identity/context injection.
|
|
74
|
+
SessionStart: [
|
|
75
|
+
{ matcher: '', hooks: [sh('session-start.sh')] },
|
|
76
|
+
],
|
|
77
|
+
UserPromptSubmit: [
|
|
78
|
+
{ matcher: '', hooks: [sh('telegram-topic-context.sh')] },
|
|
79
|
+
],
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
function groupIsInstarOwned(group) {
|
|
83
|
+
return (group.hooks ?? []).some((h) => typeof h.command === 'string' && h.command.includes(INSTAR_HOOK_PATH_MARKER));
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Write/merge instar gate hooks into `<projectDir>/.codex/hooks.json`.
|
|
87
|
+
* Preserves any user-added hooks; replaces instar-owned entries.
|
|
88
|
+
*/
|
|
89
|
+
export function installCodexHooks(projectDir) {
|
|
90
|
+
const codexDir = path.join(projectDir, '.codex');
|
|
91
|
+
fs.mkdirSync(codexDir, { recursive: true });
|
|
92
|
+
const hooksPath = path.join(codexDir, 'hooks.json');
|
|
93
|
+
let config = {};
|
|
94
|
+
if (fs.existsSync(hooksPath)) {
|
|
95
|
+
try {
|
|
96
|
+
const parsed = JSON.parse(fs.readFileSync(hooksPath, 'utf-8'));
|
|
97
|
+
if (parsed && typeof parsed === 'object')
|
|
98
|
+
config = parsed;
|
|
99
|
+
}
|
|
100
|
+
catch {
|
|
101
|
+
// Corrupted — start fresh rather than block install.
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
const hooks = (config.hooks ??= {});
|
|
105
|
+
const desired = buildInstarCodexHookGroups(projectDir);
|
|
106
|
+
for (const [event, instarGroups] of Object.entries(desired)) {
|
|
107
|
+
const userGroups = (hooks[event] ?? []).filter((g) => !groupIsInstarOwned(g));
|
|
108
|
+
hooks[event] = [...userGroups, ...instarGroups];
|
|
109
|
+
}
|
|
110
|
+
fs.writeFileSync(hooksPath, JSON.stringify(config, null, 2) + '\n');
|
|
111
|
+
return hooksPath;
|
|
112
|
+
}
|
|
113
|
+
//# sourceMappingURL=installCodexHooks.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"installCodexHooks.js","sourceRoot":"","sources":["../../src/core/installCodexHooks.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "./builtin-manifest.schema.json",
|
|
3
3
|
"schemaVersion": 1,
|
|
4
|
-
"generatedAt": "2026-05-
|
|
5
|
-
"instarVersion": "1.2.
|
|
4
|
+
"generatedAt": "2026-05-25T02:30:22.480Z",
|
|
5
|
+
"instarVersion": "1.2.67",
|
|
6
6
|
"entryCount": 191,
|
|
7
7
|
"entries": {
|
|
8
8
|
"hook:session-start": {
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
"domain": "identity",
|
|
12
12
|
"sourcePath": "src/core/PostUpdateMigrator.ts",
|
|
13
13
|
"installedPath": ".instar/hooks/instar/session-start.sh",
|
|
14
|
-
"contentHash": "
|
|
14
|
+
"contentHash": "12706baa0f474d541a3d47fb6548a02e988727c7b150ac6ac351adaed4480e19",
|
|
15
15
|
"since": "2025-01-01"
|
|
16
16
|
},
|
|
17
17
|
"hook:dangerous-command-guard": {
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
"domain": "safety",
|
|
21
21
|
"sourcePath": "src/core/PostUpdateMigrator.ts",
|
|
22
22
|
"installedPath": ".instar/hooks/instar/dangerous-command-guard.sh",
|
|
23
|
-
"contentHash": "
|
|
23
|
+
"contentHash": "12706baa0f474d541a3d47fb6548a02e988727c7b150ac6ac351adaed4480e19",
|
|
24
24
|
"since": "2025-01-01"
|
|
25
25
|
},
|
|
26
26
|
"hook:grounding-before-messaging": {
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
"domain": "safety",
|
|
30
30
|
"sourcePath": "src/core/PostUpdateMigrator.ts",
|
|
31
31
|
"installedPath": ".instar/hooks/instar/grounding-before-messaging.sh",
|
|
32
|
-
"contentHash": "
|
|
32
|
+
"contentHash": "12706baa0f474d541a3d47fb6548a02e988727c7b150ac6ac351adaed4480e19",
|
|
33
33
|
"since": "2025-01-01"
|
|
34
34
|
},
|
|
35
35
|
"hook:compaction-recovery": {
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
"domain": "identity",
|
|
39
39
|
"sourcePath": "src/core/PostUpdateMigrator.ts",
|
|
40
40
|
"installedPath": ".instar/hooks/instar/compaction-recovery.sh",
|
|
41
|
-
"contentHash": "
|
|
41
|
+
"contentHash": "12706baa0f474d541a3d47fb6548a02e988727c7b150ac6ac351adaed4480e19",
|
|
42
42
|
"since": "2025-01-01"
|
|
43
43
|
},
|
|
44
44
|
"hook:external-operation-gate": {
|
|
@@ -47,7 +47,7 @@
|
|
|
47
47
|
"domain": "safety",
|
|
48
48
|
"sourcePath": "src/core/PostUpdateMigrator.ts",
|
|
49
49
|
"installedPath": ".instar/hooks/instar/external-operation-gate.js",
|
|
50
|
-
"contentHash": "
|
|
50
|
+
"contentHash": "12706baa0f474d541a3d47fb6548a02e988727c7b150ac6ac351adaed4480e19",
|
|
51
51
|
"since": "2025-01-01"
|
|
52
52
|
},
|
|
53
53
|
"hook:deferral-detector": {
|
|
@@ -56,7 +56,7 @@
|
|
|
56
56
|
"domain": "safety",
|
|
57
57
|
"sourcePath": "src/core/PostUpdateMigrator.ts",
|
|
58
58
|
"installedPath": ".instar/hooks/instar/deferral-detector.js",
|
|
59
|
-
"contentHash": "
|
|
59
|
+
"contentHash": "12706baa0f474d541a3d47fb6548a02e988727c7b150ac6ac351adaed4480e19",
|
|
60
60
|
"since": "2025-01-01"
|
|
61
61
|
},
|
|
62
62
|
"hook:post-action-reflection": {
|
|
@@ -65,7 +65,7 @@
|
|
|
65
65
|
"domain": "evolution",
|
|
66
66
|
"sourcePath": "src/core/PostUpdateMigrator.ts",
|
|
67
67
|
"installedPath": ".instar/hooks/instar/post-action-reflection.js",
|
|
68
|
-
"contentHash": "
|
|
68
|
+
"contentHash": "12706baa0f474d541a3d47fb6548a02e988727c7b150ac6ac351adaed4480e19",
|
|
69
69
|
"since": "2025-01-01"
|
|
70
70
|
},
|
|
71
71
|
"hook:external-communication-guard": {
|
|
@@ -74,7 +74,7 @@
|
|
|
74
74
|
"domain": "safety",
|
|
75
75
|
"sourcePath": "src/core/PostUpdateMigrator.ts",
|
|
76
76
|
"installedPath": ".instar/hooks/instar/external-communication-guard.js",
|
|
77
|
-
"contentHash": "
|
|
77
|
+
"contentHash": "12706baa0f474d541a3d47fb6548a02e988727c7b150ac6ac351adaed4480e19",
|
|
78
78
|
"since": "2025-01-01"
|
|
79
79
|
},
|
|
80
80
|
"hook:scope-coherence-collector": {
|
|
@@ -83,7 +83,7 @@
|
|
|
83
83
|
"domain": "coherence",
|
|
84
84
|
"sourcePath": "src/core/PostUpdateMigrator.ts",
|
|
85
85
|
"installedPath": ".instar/hooks/instar/scope-coherence-collector.js",
|
|
86
|
-
"contentHash": "
|
|
86
|
+
"contentHash": "12706baa0f474d541a3d47fb6548a02e988727c7b150ac6ac351adaed4480e19",
|
|
87
87
|
"since": "2025-01-01"
|
|
88
88
|
},
|
|
89
89
|
"hook:scope-coherence-checkpoint": {
|
|
@@ -92,7 +92,7 @@
|
|
|
92
92
|
"domain": "coherence",
|
|
93
93
|
"sourcePath": "src/core/PostUpdateMigrator.ts",
|
|
94
94
|
"installedPath": ".instar/hooks/instar/scope-coherence-checkpoint.js",
|
|
95
|
-
"contentHash": "
|
|
95
|
+
"contentHash": "12706baa0f474d541a3d47fb6548a02e988727c7b150ac6ac351adaed4480e19",
|
|
96
96
|
"since": "2025-01-01"
|
|
97
97
|
},
|
|
98
98
|
"hook:free-text-guard": {
|
|
@@ -101,7 +101,7 @@
|
|
|
101
101
|
"domain": "safety",
|
|
102
102
|
"sourcePath": "src/core/PostUpdateMigrator.ts",
|
|
103
103
|
"installedPath": ".instar/hooks/instar/free-text-guard.sh",
|
|
104
|
-
"contentHash": "
|
|
104
|
+
"contentHash": "12706baa0f474d541a3d47fb6548a02e988727c7b150ac6ac351adaed4480e19",
|
|
105
105
|
"since": "2025-01-01"
|
|
106
106
|
},
|
|
107
107
|
"hook:claim-intercept": {
|
|
@@ -110,7 +110,7 @@
|
|
|
110
110
|
"domain": "coherence",
|
|
111
111
|
"sourcePath": "src/core/PostUpdateMigrator.ts",
|
|
112
112
|
"installedPath": ".instar/hooks/instar/claim-intercept.js",
|
|
113
|
-
"contentHash": "
|
|
113
|
+
"contentHash": "12706baa0f474d541a3d47fb6548a02e988727c7b150ac6ac351adaed4480e19",
|
|
114
114
|
"since": "2025-01-01"
|
|
115
115
|
},
|
|
116
116
|
"hook:claim-intercept-response": {
|
|
@@ -119,7 +119,7 @@
|
|
|
119
119
|
"domain": "coherence",
|
|
120
120
|
"sourcePath": "src/core/PostUpdateMigrator.ts",
|
|
121
121
|
"installedPath": ".instar/hooks/instar/claim-intercept-response.js",
|
|
122
|
-
"contentHash": "
|
|
122
|
+
"contentHash": "12706baa0f474d541a3d47fb6548a02e988727c7b150ac6ac351adaed4480e19",
|
|
123
123
|
"since": "2025-01-01"
|
|
124
124
|
},
|
|
125
125
|
"hook:auto-approve-permissions": {
|
|
@@ -128,7 +128,7 @@
|
|
|
128
128
|
"domain": "safety",
|
|
129
129
|
"sourcePath": "src/core/PostUpdateMigrator.ts",
|
|
130
130
|
"installedPath": ".instar/hooks/instar/auto-approve-permissions.js",
|
|
131
|
-
"contentHash": "
|
|
131
|
+
"contentHash": "12706baa0f474d541a3d47fb6548a02e988727c7b150ac6ac351adaed4480e19",
|
|
132
132
|
"since": "2025-01-01"
|
|
133
133
|
},
|
|
134
134
|
"job:health-check": {
|
|
@@ -1472,7 +1472,7 @@
|
|
|
1472
1472
|
"type": "subsystem",
|
|
1473
1473
|
"domain": "updates",
|
|
1474
1474
|
"sourcePath": "src/core/PostUpdateMigrator.ts",
|
|
1475
|
-
"contentHash": "
|
|
1475
|
+
"contentHash": "12706baa0f474d541a3d47fb6548a02e988727c7b150ac6ac351adaed4480e19",
|
|
1476
1476
|
"since": "2025-01-01"
|
|
1477
1477
|
},
|
|
1478
1478
|
"subsystem:scheduler": {
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# Upgrade Guide — Codex safety hooks now actually fire
|
|
2
|
+
|
|
3
|
+
<!-- bump: patch -->
|
|
4
|
+
<!-- patch = bug fixes, refactors, test additions, doc updates -->
|
|
5
|
+
|
|
6
|
+
## What Changed
|
|
7
|
+
|
|
8
|
+
**Fix: on Codex (codex-cli) agents, the PreToolUse safety guard now actually fires
|
|
9
|
+
and blocks dangerous commands. Previously it was registered but silently never ran.**
|
|
10
|
+
|
|
11
|
+
Two mismatches between how instar wrote the Codex hook config and how Codex actually
|
|
12
|
+
invokes hooks:
|
|
13
|
+
|
|
14
|
+
1. **Invalid tool-call matcher.** `installCodexHooks` emitted `matcher: "*"`. Codex
|
|
15
|
+
treats the matcher as a regex against the tool name, and a bare `*` is an invalid
|
|
16
|
+
quantifier that matches nothing — so the gate never fired. Session-level hooks
|
|
17
|
+
(SessionStart, UserPromptSubmit) fired fine because they aren't tool-matched, which
|
|
18
|
+
masked the problem. Changed to `".*"` (match all tool calls).
|
|
19
|
+
2. **Wrong command field.** Codex's shell tool is `exec_command` and puts the command
|
|
20
|
+
in `tool_input.cmd`; the guard's stdin shim only read `tool_input.command` (Claude's
|
|
21
|
+
shape), so even once it fired it saw an empty command. The shim now reads either.
|
|
22
|
+
|
|
23
|
+
Claude agents are unaffected — their existing argument path is unchanged and still tested.
|
|
24
|
+
|
|
25
|
+
## What to Tell Your User
|
|
26
|
+
|
|
27
|
+
If I'm running on the Codex engine, my safety guard that blocks catastrophic commands —
|
|
28
|
+
things like wiping a disk — now genuinely stops them before they run. Until this fix the
|
|
29
|
+
guard was installed but never actually triggered on Codex, so dangerous shell commands
|
|
30
|
+
could slip through. Nothing changes if I'm running on Claude; this only closes the gap on
|
|
31
|
+
the Codex side.
|
|
32
|
+
|
|
33
|
+
## Summary of New Capabilities
|
|
34
|
+
|
|
35
|
+
No new user-facing capabilities — this is a correctness fix to the existing Codex
|
|
36
|
+
enforcement-hook layer. Codex agents that update will have a working PreToolUse safety
|
|
37
|
+
gate (dangerous-command guard + external-operation gate + grounding check) where before it
|
|
38
|
+
was inert. Existing Codex agents receive it on update via PostUpdateMigrator (matcher +
|
|
39
|
+
stdin-shim fixes ship through both the init and update paths).
|
|
40
|
+
|
|
41
|
+
## Evidence
|
|
42
|
+
|
|
43
|
+
**Live reproduction (real Codex engine, not a simulation).** Regenerated a Codex test
|
|
44
|
+
agent's hooks from freshly-built source via the real `refreshHooksAndSettings` path (no
|
|
45
|
+
hand-editing, no debug instrumentation), launched real interactive Codex v0.133.0, and told
|
|
46
|
+
it to run `echo 'rm -rf /'`.
|
|
47
|
+
|
|
48
|
+
- **Before the fix:** identical setup — Codex ran the command unblocked; the guard never
|
|
49
|
+
fired (debug trace empty).
|
|
50
|
+
- **After the fix:** Codex displayed `• PreToolUse hook (blocked) — BLOCKED: Catastrophic
|
|
51
|
+
command detected: rm -rf /` and did not execute it. First confirmed firing of the Codex
|
|
52
|
+
enforcement guard in the real engine.
|
|
53
|
+
|
|
54
|
+
**Regression coverage:** the integration test now uses Codex's verified payload shape
|
|
55
|
+
(`tool_name: exec_command`, `tool_input.cmd`) — it would have failed before the shim fix —
|
|
56
|
+
plus a Claude-stdin case; a unit test asserts the matcher is `".*"`, not `"*"`. Full Codex
|
|
57
|
+
hook suite: 19 green. `tsc` clean.
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# Upgrade Guide — Codex safety hooks run unprompted in autonomous sessions
|
|
2
|
+
|
|
3
|
+
<!-- bump: patch -->
|
|
4
|
+
<!-- patch = bug fixes, refactors, test additions, doc updates -->
|
|
5
|
+
|
|
6
|
+
## What Changed
|
|
7
|
+
|
|
8
|
+
**Codex (codex-cli) agents now run instar's safety hooks without the interactive
|
|
9
|
+
"trust these hooks?" prompt that would otherwise freeze an unattended session.**
|
|
10
|
+
|
|
11
|
+
Codex requires a one-time review/trust of any command hook before it runs. In an
|
|
12
|
+
interactive session that prompt blocks until answered — and it even offers a
|
|
13
|
+
"continue without trusting (hooks won't run)" option, so an agent could decline its
|
|
14
|
+
own guards. instar now launches codex with `--dangerously-bypass-hook-trust` (added
|
|
15
|
+
in codex 0.133), which runs the already-vetted instar hooks with no prompt.
|
|
16
|
+
|
|
17
|
+
This is safe-by-construction: instar both writes the hooks (`installCodexHooks`) and
|
|
18
|
+
owns the launch command, so there's no untrusted third-party hook to guard against,
|
|
19
|
+
and the agent can't strip a flag from a launch it doesn't construct. It's a per-agent
|
|
20
|
+
launch setting — it touches nothing system-wide and does not affect the operator's own
|
|
21
|
+
personal codex sessions (those still prompt normally).
|
|
22
|
+
|
|
23
|
+
The flag is **capability-gated**: instar probes `codex --help` once per binary and only
|
|
24
|
+
adds the flag when present. On codex <0.133 (which lacks the flag and would reject it),
|
|
25
|
+
it's omitted and behaviour degrades to the safe-by-blocking trust-prompt path.
|
|
26
|
+
|
|
27
|
+
## What to Tell Your User
|
|
28
|
+
|
|
29
|
+
If I'm running on Codex without you watching, my safety guard now kicks in on its own
|
|
30
|
+
instead of stopping to ask you "do you trust this guard?" first — a question that would
|
|
31
|
+
have frozen me mid-task, and that technically let me wave my own guard off. Now the
|
|
32
|
+
guard just runs. This only applies to how I launch Codex; when you use Codex yourself it
|
|
33
|
+
behaves exactly as before.
|
|
34
|
+
|
|
35
|
+
## Summary of New Capabilities
|
|
36
|
+
|
|
37
|
+
No new user-facing capabilities — this completes the Codex enforcement-hook layer so its
|
|
38
|
+
guards work in unattended/autonomous sessions, not just interactive ones where a human can
|
|
39
|
+
answer the trust prompt. Internal: `codexCapabilities.codexSupportsHookTrustBypass()`
|
|
40
|
+
(memoized feature probe) + both codex launch builders append the flag when supported.
|
|
41
|
+
|
|
42
|
+
## Evidence
|
|
43
|
+
|
|
44
|
+
**Live reproduction (real codex 0.133, no trust ever granted).** Launched interactive
|
|
45
|
+
codex with `--dangerously-bypass-hook-trust` and a hook whose trust hash had been
|
|
46
|
+
invalidated:
|
|
47
|
+
|
|
48
|
+
- Codex launched **straight to the prompt — no "trust these hooks?" review** (banner:
|
|
49
|
+
`⚠ Enabled hooks may run without review for this invocation`).
|
|
50
|
+
- Told it to run `echo 'rm -rf /'` — the guard fired and blocked it; codex itself reported
|
|
51
|
+
it was blocked for the catastrophic `rm -rf /` pattern, and the guard's debug trace
|
|
52
|
+
logged the fire. Before this, the same setup either blocked on the trust prompt or ran
|
|
53
|
+
unguarded.
|
|
54
|
+
|
|
55
|
+
Also verified instar's builder emits the flag for the real codex binary, and the
|
|
56
|
+
capability probe correctly omits it for a binary whose `--help` lacks it. Unit coverage:
|
|
57
|
+
`codexCapabilities` (5) + `frameworkSessionLaunch` (+4). `tsc` clean.
|