docs: tighten prose audit after master retarget
This commit is contained in:
@@ -19,7 +19,7 @@ Why a shared lib at all: Codex deliberately reimplements a *subset* of the Claud
|
||||
|
||||
- **`matchesMatcher(matcher, query, mode)`** — match-all on absent/`''`/`'*'`; `claude` mode treats a pure `[A-Za-z0-9_|]+` pattern as a literal (pipe = exact-match alternation) and anything else as a regex; `codex` mode is always an unanchored regex. An invalid regex matches nothing (never throws).
|
||||
- **`runHook(bash, hook, options, now)`** — serialize `options.payload` to the hook's stdin (with a trailing newline iff `options.trailingNewline`), merge `options.env` after the executor's credential scrub (the `dsh-bash` trusted-plugin surface), honor the hook's `timeoutSec` (else `options.defaultTimeoutMs` — the bridge owns the default, its config defaulting to the lib's `DEFAULT_HOOK_TIMEOUT_MS` 10-minute reference), and decode the result (threading `options.expectedEventName` to the codec). Never throws: an executor rejection (infra fault) becomes a `HookOutput` with `exitCode: undefined` (a non-blocking error). `now` is injected for testable durations.
|
||||
- **`parseHookOutput(exitCode, stdout, stderr, expectedEventName?)`** — the exit-code + structured-stdout codec. Exit `0` → parse JSON stdout (lenient: non-JSON is left for the bridge); exit `2` → blocking error, `stderr` is the block reason (surfaced as `decision: 'block'`); other → non-blocking error. `hookSpecificOutput.permissionDecision` (allow/deny/ask) overrides a legacy top-level `decision`; `additionalContext`/`updatedInput`/`systemMessage`/`continue`/`stopReason` are parsed too. The schemas key the `hookSpecificOutput` block by `hookEventName`, so passing `expectedEventName` (the firing event) DISCARDS a block whose `hookEventName` names a different event — or omits it entirely — its event-scoped fields don't take effect (a `PreToolUse` block on a `Stop` hook is malformed, and so is a discriminator-less block that would otherwise apply to any event), while the event-agnostic top-level fields still apply. Pure and total.
|
||||
- **`parseHookOutput(exitCode, stdout, stderr, expectedEventName?)`** decodes exit status and structured stdout. Exit 2 blocks with stderr; other failures are non-blocking. Event-specific output applies only when its discriminator matches the firing event, while top-level fields remain event-agnostic. The parser is total and leaves successful non-JSON output to the bridge.
|
||||
- **`mergeHookOutputs(outputs)`** — fold the results of every hook that matched one point: permission precedence **deny > ask > allow**, halt sticky on the first `continue:false`, block reasons joined with `\n\n`, `additionalContext`/`systemMessages` accumulated in order.
|
||||
- **`createDetachedRuns()`** — quiescence tracking for the emit-shaped points, which run detached (no seam awaits them). The bridge tracks each run chain — the hook run PLUS its continuation — and registers `drain()` as its effect disposer: drain fires the tracker's abort `signal` (so a still-running hook process is killed via `runHook`, not awaited out to its timeout), then resolves once every tracked chain has settled. `fiber.dispose()` resolving therefore means no detached hook work is left to fire into a disposed context ([defensive patterns](../../../docs/defensive-patterns.md): dispose must reach quiescence).
|
||||
|
||||
|
||||
@@ -83,12 +83,8 @@ export function appendHookInvoked(session: Session, invocation: HookInvocation):
|
||||
}
|
||||
|
||||
/**
|
||||
* Append a `hook/result` outcome event to `session` (pairs with a prior
|
||||
* `hook/invoked`). Owns the durable event's semantics: `decision` is the hook's
|
||||
* parsed decision, else `'stop'` when it asked to halt (`continue: false`),
|
||||
* else `'pass'`; `stderrSummary` is the trimmed stderr truncated to
|
||||
* `record.stderrSummaryMaxChars` characters (omitted when empty); `exitCode`
|
||||
* is omitted when the hook never ran.
|
||||
* Append the durable result paired with `hook/invoked`, normalizing its decision,
|
||||
* bounded stderr summary, and optional exit code.
|
||||
* @param session - the session whose open turn records the event.
|
||||
* @param record - the outcome to record: the decoded output plus the summary cap and duration.
|
||||
*/
|
||||
|
||||
@@ -116,14 +116,8 @@ export interface HookOutput {
|
||||
/** The reason/explanation accompanying {@link decision}. */
|
||||
reason?: string
|
||||
/**
|
||||
* The `hookSpecificOutput.hookEventName` discriminator, when the hook emitted
|
||||
* a `hookSpecificOutput` block. The reference schemas key that block by event,
|
||||
* so a block whose `hookEventName` names a DIFFERENT event than the one firing
|
||||
* is malformed: {@link parseHookOutput} DISCARDS its event-scoped fields when
|
||||
* given the firing event's `expectedEventName` (a hook claiming `PreToolUse`
|
||||
* output on a `Stop` event does not affect the `Stop`). This field is still
|
||||
* surfaced even on a mismatch — the record shows what the block claimed. Absent
|
||||
* when the hook emitted no `hookSpecificOutput`.
|
||||
* Event discriminator claimed by `hookSpecificOutput`. On mismatch,
|
||||
* {@link parseHookOutput} preserves this value but discards event-scoped fields.
|
||||
*/
|
||||
hookEventName?: string
|
||||
/** Extra context to inject for the next model request (CC `additionalContext`). */
|
||||
|
||||
Reference in New Issue
Block a user