@ngockhoale/ukit 3.4.20 → 3.4.22

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.
@@ -280,13 +280,25 @@ Internals: `src/core/permissionPolicy.js` compiles the semantic policy (preceden
280
280
  non-zero on its own), `output-overflow` (capture exceeded the 2 MiB maxBuffer and the
281
281
  tree was culled), `timeout` (the runner killed the child at its deadline), `signal`
282
282
  (the child died from a signal the runner did not send), `error` (the child never
283
- spawned), `budget-exhausted` (the script never ran — the chain total budget was spent
284
- first). The `--emit-verdict` contract maps them onto one exit code: `ok`/`exit-code 0`
283
+ spawned), `spawn-unavailable` (win32 only: no usable bash could be found or started for
284
+ a `.sh` script — see the launcher bullet below), `budget-exhausted` (the script never
285
+ ran — the chain total budget was spent first). The `--emit-verdict` contract maps them onto one exit code: `ok`/`exit-code 0`
285
286
  and any non-fail-closed failure → exit 0 (fail OPEN); a real `exit-code 2` block, or
286
287
  ANY failure on a fail-closed gate (`output-overflow`, `timeout`, `signal`, `error`,
287
288
  `budget-exhausted`) → exit 2 (fail CLOSED). An overflowed capture is dropped whole
288
289
  before it can be replayed, so a truncated stream can never masquerade as a verdict.
289
290
  `tests/hooks/hookChainFailureSurface.test.js` pins these surfaces.
291
+ - **Windows bash launcher.** On win32 a `.sh` hook is not executed directly; the runner
292
+ launches it through Git Bash. The bash binary is the first hit of: an absolute
293
+ `UKIT_BASH_BIN` → `CLAUDE_CODE_GIT_BASH_PATH` → the Git for Windows default install
294
+ paths → absolute `PATH` entries (the System32 and WindowsApps `bash.exe`, i.e. WSL, are
295
+ skipped; a relative or cwd `bash.exe` is never used). The script path is passed with
296
+ forward slashes. When no candidate exists or the spawn fails, the entry is
297
+ `spawn-unavailable`: it warns instead of denying every Edit/Write/Bash. That kind is
298
+ win32-launcher-only — POSIX spawn errors stay `error` and fail closed, and timeouts,
299
+ real `exit-code 2` blocks, missing gate files and `block-dangerous.sh` stay fail closed
300
+ on every platform. `UKIT_HOOK_SHELL_PLATFORM` is a diagnostic override of the platform
301
+ the launcher assumes.
290
302
  - **stderr is a diagnostic channel, not verdict payload.** Under `--emit-verdict` the
291
303
  runner drops the stderr of every non-verdict script: stdout is the verdict and Claude
292
304
  Code parses it as ONE JSON document, so interleaving arbitrary hook diagnostics there