@lannguyensi/harness 0.40.0 → 0.42.0
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 +68 -0
- package/README.md +9 -0
- package/dist/cli/adopt/derive.d.ts +15 -0
- package/dist/cli/adopt/derive.js +34 -7
- package/dist/cli/adopt/derive.js.map +1 -1
- package/dist/cli/adopt/index.d.ts +30 -0
- package/dist/cli/adopt/index.js +23 -3
- package/dist/cli/adopt/index.js.map +1 -1
- package/dist/cli/apply/generate-settings.d.ts +14 -1
- package/dist/cli/apply/generate-settings.js +7 -3
- package/dist/cli/apply/generate-settings.js.map +1 -1
- package/dist/cli/approve/stdin-report.js +2 -0
- package/dist/cli/approve/stdin-report.js.map +1 -1
- package/dist/cli/approve/understanding.js +28 -0
- package/dist/cli/approve/understanding.js.map +1 -1
- package/dist/cli/doctor/claude-mcp.d.ts +50 -0
- package/dist/cli/doctor/claude-mcp.js +170 -0
- package/dist/cli/doctor/claude-mcp.js.map +1 -0
- package/dist/cli/doctor/codex.d.ts +8 -0
- package/dist/cli/doctor/codex.js +8 -1
- package/dist/cli/doctor/codex.js.map +1 -1
- package/dist/cli/doctor/format.js +60 -11
- package/dist/cli/doctor/format.js.map +1 -1
- package/dist/cli/doctor/index.d.ts +46 -0
- package/dist/cli/doctor/index.js +155 -29
- package/dist/cli/doctor/index.js.map +1 -1
- package/dist/cli/doctor/npm-bin-path.js +42 -0
- package/dist/cli/doctor/npm-bin-path.js.map +1 -1
- package/dist/cli/doctor/types.d.ts +37 -0
- package/dist/cli/doctor/types.js.map +1 -1
- package/dist/cli/dry-run.js +5 -0
- package/dist/cli/dry-run.js.map +1 -1
- package/dist/cli/explain.js +16 -3
- package/dist/cli/explain.js.map +1 -1
- package/dist/cli/index.js +328 -11
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/init/agent-tasks-auth.js +32 -0
- package/dist/cli/init/agent-tasks-auth.js.map +1 -1
- package/dist/cli/init/composer.js +13 -40
- package/dist/cli/init/composer.js.map +1 -1
- package/dist/cli/init/dependencies.js +21 -0
- package/dist/cli/init/dependencies.js.map +1 -1
- package/dist/cli/init/detect.d.ts +20 -3
- package/dist/cli/init/detect.js +34 -36
- package/dist/cli/init/detect.js.map +1 -1
- package/dist/cli/init/index.d.ts +18 -0
- package/dist/cli/init/index.js +28 -2
- package/dist/cli/init/index.js.map +1 -1
- package/dist/cli/init/interactive.d.ts +41 -0
- package/dist/cli/init/interactive.js +421 -6
- package/dist/cli/init/interactive.js.map +1 -1
- package/dist/cli/init/profiles.d.ts +2 -2
- package/dist/cli/init/profiles.js +10 -1
- package/dist/cli/init/profiles.js.map +1 -1
- package/dist/cli/init/templates.d.ts +1 -1
- package/dist/cli/init/templates.js +217 -8
- package/dist/cli/init/templates.js.map +1 -1
- package/dist/cli/list.js +3 -1
- package/dist/cli/list.js.map +1 -1
- package/dist/cli/main.js +10 -0
- package/dist/cli/main.js.map +1 -1
- package/dist/cli/pack/hook-bootstrap.d.ts +24 -0
- package/dist/cli/pack/hook-bootstrap.js +47 -1
- package/dist/cli/pack/hook-bootstrap.js.map +1 -1
- package/dist/cli/pack/hook-branch-protection.js +9 -1
- package/dist/cli/pack/hook-branch-protection.js.map +1 -1
- package/dist/cli/pack/hook-codex-post-tool-use.d.ts +25 -0
- package/dist/cli/pack/hook-codex-post-tool-use.js +160 -0
- package/dist/cli/pack/hook-codex-post-tool-use.js.map +1 -0
- package/dist/cli/pack/hook-codex-pre-tool-use.d.ts +1 -0
- package/dist/cli/pack/hook-codex-pre-tool-use.js +43 -10
- package/dist/cli/pack/hook-codex-pre-tool-use.js.map +1 -1
- package/dist/cli/pack/hook-codex-stop.js +1 -8
- package/dist/cli/pack/hook-codex-stop.js.map +1 -1
- package/dist/cli/pack/hook-post-merge-gate-record.d.ts +30 -0
- package/dist/cli/pack/hook-post-merge-gate-record.js +153 -0
- package/dist/cli/pack/hook-post-merge-gate-record.js.map +1 -0
- package/dist/cli/pack/hook-post-merge-gate.d.ts +28 -0
- package/dist/cli/pack/hook-post-merge-gate.js +244 -0
- package/dist/cli/pack/hook-post-merge-gate.js.map +1 -0
- package/dist/cli/pack/hook-post-tool-use.js +16 -131
- package/dist/cli/pack/hook-post-tool-use.js.map +1 -1
- package/dist/cli/pack/hook-pre-tool-use.js +54 -2
- package/dist/cli/pack/hook-pre-tool-use.js.map +1 -1
- package/dist/cli/pack/hook-solution-acceptance-writeguard.js +148 -2
- package/dist/cli/pack/hook-solution-acceptance-writeguard.js.map +1 -1
- package/dist/cli/pack/hook-stay-in-scope.js +63 -20
- package/dist/cli/pack/hook-stay-in-scope.js.map +1 -1
- package/dist/cli/pack/hook-track-active-claim.js +33 -9
- package/dist/cli/pack/hook-track-active-claim.js.map +1 -1
- package/dist/cli/pack/index.d.ts +2 -1
- package/dist/cli/pack/index.js +2 -1
- package/dist/cli/pack/index.js.map +1 -1
- package/dist/cli/pack/mutate.d.ts +19 -0
- package/dist/cli/pack/mutate.js +38 -0
- package/dist/cli/pack/mutate.js.map +1 -1
- package/dist/cli/pack/reseed.d.ts +19 -0
- package/dist/cli/pack/reseed.js +118 -0
- package/dist/cli/pack/reseed.js.map +1 -0
- package/dist/cli/pack/understanding-report-schema-hint.js +1 -1
- package/dist/cli/pack/understanding-report-schema-hint.js.map +1 -1
- package/dist/cli/pause/index.js +12 -3
- package/dist/cli/pause/index.js.map +1 -1
- package/dist/cli/record/index.d.ts +64 -0
- package/dist/cli/record/index.js +211 -0
- package/dist/cli/record/index.js.map +1 -0
- package/dist/cli/session-start/index.d.ts +21 -0
- package/dist/cli/session-start/index.js +160 -25
- package/dist/cli/session-start/index.js.map +1 -1
- package/dist/cli/session-start/toolchain-parity.d.ts +149 -0
- package/dist/cli/session-start/toolchain-parity.js +618 -0
- package/dist/cli/session-start/toolchain-parity.js.map +1 -0
- package/dist/cli/uninstall/index.d.ts +73 -1
- package/dist/cli/uninstall/index.js +134 -2
- package/dist/cli/uninstall/index.js.map +1 -1
- package/dist/cli/validate/checks.js +8 -0
- package/dist/cli/validate/checks.js.map +1 -1
- package/dist/io/claude-mcp.d.ts +258 -0
- package/dist/io/claude-mcp.js +544 -0
- package/dist/io/claude-mcp.js.map +1 -0
- package/dist/policies/ledger-client.d.ts +34 -1
- package/dist/policies/ledger-client.js +21 -16
- package/dist/policies/ledger-client.js.map +1 -1
- package/dist/policy-packs/builtin/branch-protection-runtime.d.ts +4 -2
- package/dist/policy-packs/builtin/branch-protection-runtime.js +4 -2
- package/dist/policy-packs/builtin/branch-protection-runtime.js.map +1 -1
- package/dist/policy-packs/builtin/branch-protection.d.ts +10 -1
- package/dist/policy-packs/builtin/branch-protection.js +17 -0
- package/dist/policy-packs/builtin/branch-protection.js.map +1 -1
- package/dist/policy-packs/builtin/post-merge-gate-runtime.d.ts +195 -0
- package/dist/policy-packs/builtin/post-merge-gate-runtime.js +290 -0
- package/dist/policy-packs/builtin/post-merge-gate-runtime.js.map +1 -0
- package/dist/policy-packs/builtin/post-merge-gate.d.ts +56 -0
- package/dist/policy-packs/builtin/post-merge-gate.js +291 -0
- package/dist/policy-packs/builtin/post-merge-gate.js.map +1 -0
- package/dist/policy-packs/builtin/solution-acceptance-runtime.js +28 -13
- package/dist/policy-packs/builtin/solution-acceptance-runtime.js.map +1 -1
- package/dist/policy-packs/builtin/understanding-before-execution-runtime.d.ts +197 -24
- package/dist/policy-packs/builtin/understanding-before-execution-runtime.js +342 -40
- package/dist/policy-packs/builtin/understanding-before-execution-runtime.js.map +1 -1
- package/dist/policy-packs/builtin/understanding-before-execution.d.ts +26 -1
- package/dist/policy-packs/builtin/understanding-before-execution.js +302 -17
- package/dist/policy-packs/builtin/understanding-before-execution.js.map +1 -1
- package/dist/policy-packs/registry.d.ts +23 -2
- package/dist/policy-packs/registry.js +31 -2
- package/dist/policy-packs/registry.js.map +1 -1
- package/dist/policy-packs/ux-compare.d.ts +14 -0
- package/dist/policy-packs/ux-compare.js +58 -0
- package/dist/policy-packs/ux-compare.js.map +1 -0
- package/dist/policy-packs/ux-drift-check.d.ts +27 -0
- package/dist/policy-packs/ux-drift-check.js +78 -0
- package/dist/policy-packs/ux-drift-check.js.map +1 -0
- package/dist/probes/mcp.d.ts +13 -0
- package/dist/probes/mcp.js +57 -0
- package/dist/probes/mcp.js.map +1 -1
- package/dist/runtime/approval-signing.d.ts +82 -0
- package/dist/runtime/approval-signing.js +275 -0
- package/dist/runtime/approval-signing.js.map +1 -0
- package/dist/runtime/git-context.d.ts +50 -0
- package/dist/runtime/git-context.js +108 -1
- package/dist/runtime/git-context.js.map +1 -1
- package/dist/runtime/hermetic-spawn-guard.d.ts +25 -0
- package/dist/runtime/hermetic-spawn-guard.js +136 -0
- package/dist/runtime/hermetic-spawn-guard.js.map +1 -0
- package/dist/runtime/intercept.js +62 -5
- package/dist/runtime/intercept.js.map +1 -1
- package/dist/runtime/ledger-writer.d.ts +27 -0
- package/dist/runtime/ledger-writer.js +46 -0
- package/dist/runtime/ledger-writer.js.map +1 -0
- package/dist/runtime/pause-sentinel.js +14 -3
- package/dist/runtime/pause-sentinel.js.map +1 -1
- package/dist/runtime/read-only-bash.js +118 -0
- package/dist/runtime/read-only-bash.js.map +1 -1
- package/dist/runtime/recovery-git-commit.d.ts +22 -0
- package/dist/runtime/recovery-git-commit.js +284 -0
- package/dist/runtime/recovery-git-commit.js.map +1 -0
- package/dist/runtime/tool-name-aliases.d.ts +1 -0
- package/dist/runtime/tool-name-aliases.js +7 -1
- package/dist/runtime/tool-name-aliases.js.map +1 -1
- package/dist/schema/index.d.ts +94 -42
- package/dist/schema/index.js +5 -0
- package/dist/schema/index.js.map +1 -1
- package/dist/schema/policies.d.ts +56 -44
- package/dist/schema/policies.js +79 -9
- package/dist/schema/policies.js.map +1 -1
- package/dist/schema/toolchain-parity.d.ts +18 -0
- package/dist/schema/toolchain-parity.js +35 -0
- package/dist/schema/toolchain-parity.js.map +1 -0
- package/package.json +4 -2
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Classify a Bash/shell command string as the narrow "recovery commit"
|
|
3
|
+
* shape: a bare, unchained `git commit` invocation carrying only
|
|
4
|
+
* `-a`/`--all`/`--allow-empty` and one or more `-m`/`--message`/`-am`
|
|
5
|
+
* message flags. `true` means the understanding-gate PreToolUse hooks
|
|
6
|
+
* may admit this ONE call without a fresh Understanding Report, provided
|
|
7
|
+
* the caller has already established that this session/task had a real
|
|
8
|
+
* (now-expired) operator approval — see module header for the full
|
|
9
|
+
* safety argument and why that precondition is load-bearing.
|
|
10
|
+
*
|
|
11
|
+
* A properly single- or double-quoted `-m`/`--message` value may contain
|
|
12
|
+
* ANY text, including characters like `<`/`>`/`;`/`&`/`|` that would be
|
|
13
|
+
* dangerous unquoted — that is what lets a real trailer such as
|
|
14
|
+
* `Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>` through (see
|
|
15
|
+
* `hasUnsafeMetachar`'s doc for the exact quote-aware rule). Anything
|
|
16
|
+
* outside this narrow shape — `--amend`, `--no-verify`, `-C <dir>`
|
|
17
|
+
* (rejected implicitly: it does not appear directly after `git commit`),
|
|
18
|
+
* a pathspec, UNQUOTED chaining/redirection, command substitution that
|
|
19
|
+
* is live where it appears, an unrecognised flag — fails closed
|
|
20
|
+
* (`false`) and the caller falls through to the ordinary hard block.
|
|
21
|
+
*/
|
|
22
|
+
export declare function isRecoveryGitCommit(command: string): boolean;
|
|
@@ -0,0 +1,284 @@
|
|
|
1
|
+
// Recovery git-commit exemption for the understanding-gate PreToolUse
|
|
2
|
+
// hooks (task 6e888423).
|
|
3
|
+
//
|
|
4
|
+
// The problem: `approval_lifecycle.max_age` (default 4h, see
|
|
5
|
+
// src/cli/init/templates.ts) expires the operator-approval MARKER
|
|
6
|
+
// independently of any task-completion boundary. That is by design for
|
|
7
|
+
// genuinely new work — a session idle for hours should re-justify itself
|
|
8
|
+
// before its next Edit/Write/Bash. But it also fires mid-task, e.g. while
|
|
9
|
+
// an agent is deep in a reviewer-amendment loop (apply fixes, wait on CI,
|
|
10
|
+
// iterate again) that outlives the window. When the marker ages out at
|
|
11
|
+
// exactly the moment the agent needs to run the recovery `git commit`
|
|
12
|
+
// that consolidates already-approved Edit/Write output into a new HEAD
|
|
13
|
+
// (so `preflight` / solution-acceptance can re-pin their verdict there),
|
|
14
|
+
// the gate hard-blocks that Bash call — including the recovery commit
|
|
15
|
+
// itself — and only the operator can unblock it (agent-grounding
|
|
16
|
+
// frictions #2/#9/#58/#71).
|
|
17
|
+
//
|
|
18
|
+
// The fix is narrow on purpose. A `git commit` records whatever is
|
|
19
|
+
// ALREADY sitting in the working tree; it introduces no new file
|
|
20
|
+
// content. Every byte in that working tree was necessarily produced by
|
|
21
|
+
// an Edit/Write/Bash call that was itself gated at the time it ran, so
|
|
22
|
+
// letting a bare, unchained `git commit` through does not let unreviewed
|
|
23
|
+
// content sneak past the Understanding Gate — it only lets the agent
|
|
24
|
+
// finish recording work that was already approved once. This is
|
|
25
|
+
// deliberately NOT a blanket "any Bash whitelist" or "ignore
|
|
26
|
+
// max_age" fix:
|
|
27
|
+
// - The caller (hook-pre-tool-use.ts / hook-codex-pre-tool-use.ts)
|
|
28
|
+
// gates this classifier behind `expired === true` from
|
|
29
|
+
// `checkOperatorApprovalMarkers` — i.e. a real operator-written
|
|
30
|
+
// marker for THIS session/task existed and simply aged past
|
|
31
|
+
// max_age. A session that was NEVER approved (marker absent) gets
|
|
32
|
+
// no exemption: `isRecoveryGitCommit` alone is not a bypass, it
|
|
33
|
+
// only matters once the caller has already proven prior approval.
|
|
34
|
+
// - A marker CLEARED by a task-completion boundary tool
|
|
35
|
+
// (`task_finish`, `pull_requests_merge`, ...) reads as "missing",
|
|
36
|
+
// not "expired" (`clearApprovalMarker` deletes the file rather than
|
|
37
|
+
// leaving a stale one behind). The exemption therefore does not
|
|
38
|
+
// fire for a fresh task's first commit — the gate still re-arms
|
|
39
|
+
// exactly as `approval_lifecycle` intends.
|
|
40
|
+
// - Edit / Write and every other Bash shape stay hard-gated
|
|
41
|
+
// regardless of this exemption; only the exact `git commit`
|
|
42
|
+
// invocation classified below is admitted.
|
|
43
|
+
// - The matcher refuses chaining (`;`, `&`, `|`, `&&`, `||`) and
|
|
44
|
+
// redirection (`<`, `>`) that appear OUTSIDE a quoted span, and
|
|
45
|
+
// command substitution (backtick, `$(...)`) that appears outside a
|
|
46
|
+
// quote OR inside a DOUBLE-quoted span (both are still expanded by
|
|
47
|
+
// bash there) — so a compound command cannot ride a legitimate
|
|
48
|
+
// commit past the gate. `;`/`&`/`|`/`<`/`>` are treated as literal
|
|
49
|
+
// when they appear inside a quoted span (single OR double), exactly
|
|
50
|
+
// as bash treats them: this is what lets a real commit-message
|
|
51
|
+
// trailer like `Co-Authored-By: Claude Fable 5
|
|
52
|
+
// <noreply@anthropic.com>` (this very repo's own commit convention)
|
|
53
|
+
// through a quoted `-m` value without opening a metachar hole,
|
|
54
|
+
// because git only ever sees the trailer as inert message text, not
|
|
55
|
+
// as shell syntax. A backtick or `$(` inside a SINGLE-quoted span is
|
|
56
|
+
// also literal (single quotes suppress all expansion) and therefore
|
|
57
|
+
// safe to admit. Newlines are rejected unconditionally regardless of
|
|
58
|
+
// quoting (see `isRecoveryGitCommit`): multiple `-m` flags are the
|
|
59
|
+
// supported shape for a multi-paragraph message, so no caller needs
|
|
60
|
+
// an embedded newline inside one quoted token. The matcher also
|
|
61
|
+
// fails closed on any flag it does not recognise, in particular
|
|
62
|
+
// `--amend` (rewrites a commit that may have been approved under an
|
|
63
|
+
// entirely different, unrelated window) and `--no-verify` (skips
|
|
64
|
+
// local hooks, which this exemption has no mandate to waive — see
|
|
65
|
+
// AGENTS.md "no workarounds").
|
|
66
|
+
// - ANY backslash in the command rejects the whole thing outright, in
|
|
67
|
+
// `isRecoveryGitCommit` before the quote-aware scan even runs. The
|
|
68
|
+
// quote-toggling in `hasUnsafeMetachar`/`tokenize` has no concept of
|
|
69
|
+
// backslash-escaping, so a payload like `git commit -am a\" ; echo
|
|
70
|
+
// INJECTED ; \"` was, for one commit on this branch, misclassified
|
|
71
|
+
// as a single safely-quoted message — the classifier "entered" a
|
|
72
|
+
// phantom quote span at the escaped `"` and read the live `;` inside
|
|
73
|
+
// it as literal text, while bash itself never entered a quote at all
|
|
74
|
+
// and executed `echo INJECTED` as a separate command (confirmed
|
|
75
|
+
// end-to-end for `;`, `||`, and `|`). Rejecting every backslash
|
|
76
|
+
// up front closes the whole escape-based attack surface: without a
|
|
77
|
+
// backslash present, naive quote-toggling matches bash's real
|
|
78
|
+
// quoting exactly. A hand-rolled bash-accurate escape state machine
|
|
79
|
+
// is deliberately NOT built here — too risky for a security boundary
|
|
80
|
+
// to get subtly wrong twice.
|
|
81
|
+
/** Flags that take no following value. */
|
|
82
|
+
const FLAG_ONLY_TOKENS = new Set(["-a", "--all", "--allow-empty"]);
|
|
83
|
+
/**
|
|
84
|
+
* Flags that consume the NEXT token as their value. `-am` is the common
|
|
85
|
+
* combined `-a -m` shorthand — the LAST flag in a short-option cluster is
|
|
86
|
+
* the one that takes an argument, so `-am <value>` clusters to `-a` (no
|
|
87
|
+
* value) followed by `-m <value>` exactly like a real shell/getopt would
|
|
88
|
+
* parse it. `-ma` is deliberately NOT included: there `-m` is NOT last in
|
|
89
|
+
* the cluster, so getopt takes the cluster's OWN remainder ("a") as `-m`'s
|
|
90
|
+
* value and the flag `-a` is never set at all — the next token (the
|
|
91
|
+
* agent's intended message) would be consumed by git as a pathspec
|
|
92
|
+
* instead, silently restricting the commit to files matching that
|
|
93
|
+
* pathspec. Admitting `-ma` here would therefore misclassify a command
|
|
94
|
+
* whose ACTUAL git semantics differ from what this exemption assumes.
|
|
95
|
+
* Multiple `-m`/`--message` occurrences are allowed (git concatenates
|
|
96
|
+
* them as separate paragraphs — the idiomatic way to express a subject
|
|
97
|
+
* line, a body, and a trailer such as `Co-Authored-By:` without embedding
|
|
98
|
+
* a literal newline in one token).
|
|
99
|
+
*/
|
|
100
|
+
const MESSAGE_FLAG_TOKENS = new Set(["-m", "--message", "-am"]);
|
|
101
|
+
/**
|
|
102
|
+
* Quote-aware scan for shell metacharacters that are unsafe given WHERE
|
|
103
|
+
* they appear. Unlike a flat regex, this walks the string tracking
|
|
104
|
+
* whether we are inside a single-quoted span, a double-quoted span, or
|
|
105
|
+
* neither:
|
|
106
|
+
* - Outside any quote: `;`, `&`, `|`, `<`, `>`, backtick, and `$(` are
|
|
107
|
+
* all live shell syntax — any of them is unsafe.
|
|
108
|
+
* - Inside a single-quoted span: everything is inert (bash disables
|
|
109
|
+
* ALL expansion inside single quotes, including backtick and `$(`),
|
|
110
|
+
* so nothing here is unsafe.
|
|
111
|
+
* - Inside a double-quoted span: `;`, `&`, `|`, `<`, `>` are literal
|
|
112
|
+
* characters (bash does NOT treat them specially inside double
|
|
113
|
+
* quotes) and therefore safe, but backtick and `$(` are STILL
|
|
114
|
+
* expanded by bash inside double quotes and therefore still unsafe.
|
|
115
|
+
* An unterminated quote (the scan ends still "inside" one) is itself
|
|
116
|
+
* unsafe: the caller's tokenizer performs the authoritative parse and
|
|
117
|
+
* would also reject it, but this scan must not silently pass through
|
|
118
|
+
* content it could not fully account for.
|
|
119
|
+
*/
|
|
120
|
+
function hasUnsafeMetachar(command) {
|
|
121
|
+
let quote = null;
|
|
122
|
+
for (let i = 0; i < command.length; i += 1) {
|
|
123
|
+
const ch = command[i];
|
|
124
|
+
if (quote === "'") {
|
|
125
|
+
if (ch === "'")
|
|
126
|
+
quote = null;
|
|
127
|
+
continue; // single-quoted: fully inert, including ` and $(
|
|
128
|
+
}
|
|
129
|
+
if (quote === '"') {
|
|
130
|
+
if (ch === '"') {
|
|
131
|
+
quote = null;
|
|
132
|
+
continue;
|
|
133
|
+
}
|
|
134
|
+
if (ch === "`")
|
|
135
|
+
return true;
|
|
136
|
+
if (ch === "$" && command[i + 1] === "(")
|
|
137
|
+
return true;
|
|
138
|
+
continue; // ; & | < > are literal inside double quotes
|
|
139
|
+
}
|
|
140
|
+
// Outside any quote: every metacharacter is live.
|
|
141
|
+
if (ch === '"' || ch === "'") {
|
|
142
|
+
quote = ch;
|
|
143
|
+
continue;
|
|
144
|
+
}
|
|
145
|
+
if (ch === ";" || ch === "&" || ch === "|" || ch === "<" || ch === ">")
|
|
146
|
+
return true;
|
|
147
|
+
if (ch === "`")
|
|
148
|
+
return true;
|
|
149
|
+
if (ch === "$" && command[i + 1] === "(")
|
|
150
|
+
return true;
|
|
151
|
+
}
|
|
152
|
+
return quote !== null; // unterminated quote: unsafe/unparseable
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Quote-aware tokenizer for the residual argv after `git commit`, mimicking
|
|
156
|
+
* plain shell word-splitting: a "word" runs until unquoted whitespace, and a
|
|
157
|
+
* quoted region (single OR double quotes) within a word contributes its
|
|
158
|
+
* literal contents to that same word, quotes stripped. This is what lets
|
|
159
|
+
* both the standalone-token shape (`-m "a message"`) and the glued shape
|
|
160
|
+
* (`--message="a message"`, where the shell concatenates the flag prefix
|
|
161
|
+
* and the quoted value into ONE argv word) tokenize the same way a real
|
|
162
|
+
* shell would. An unterminated quote fails the parse (`null`); the caller
|
|
163
|
+
* treats that as "not a recognised recovery commit" and falls through to
|
|
164
|
+
* the ordinary gate block rather than guessing at the intended word.
|
|
165
|
+
*/
|
|
166
|
+
function tokenize(rest) {
|
|
167
|
+
const tokens = [];
|
|
168
|
+
const n = rest.length;
|
|
169
|
+
let i = 0;
|
|
170
|
+
while (i < n) {
|
|
171
|
+
while (i < n && /\s/.test(rest[i]))
|
|
172
|
+
i += 1;
|
|
173
|
+
if (i >= n)
|
|
174
|
+
break;
|
|
175
|
+
let token = "";
|
|
176
|
+
while (i < n && !/\s/.test(rest[i])) {
|
|
177
|
+
const ch = rest[i];
|
|
178
|
+
if (ch === '"' || ch === "'") {
|
|
179
|
+
const close = rest.indexOf(ch, i + 1);
|
|
180
|
+
if (close === -1)
|
|
181
|
+
return null;
|
|
182
|
+
token += rest.slice(i + 1, close);
|
|
183
|
+
i = close + 1;
|
|
184
|
+
continue;
|
|
185
|
+
}
|
|
186
|
+
token += ch;
|
|
187
|
+
i += 1;
|
|
188
|
+
}
|
|
189
|
+
tokens.push(token);
|
|
190
|
+
}
|
|
191
|
+
return tokens;
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* Classify a Bash/shell command string as the narrow "recovery commit"
|
|
195
|
+
* shape: a bare, unchained `git commit` invocation carrying only
|
|
196
|
+
* `-a`/`--all`/`--allow-empty` and one or more `-m`/`--message`/`-am`
|
|
197
|
+
* message flags. `true` means the understanding-gate PreToolUse hooks
|
|
198
|
+
* may admit this ONE call without a fresh Understanding Report, provided
|
|
199
|
+
* the caller has already established that this session/task had a real
|
|
200
|
+
* (now-expired) operator approval — see module header for the full
|
|
201
|
+
* safety argument and why that precondition is load-bearing.
|
|
202
|
+
*
|
|
203
|
+
* A properly single- or double-quoted `-m`/`--message` value may contain
|
|
204
|
+
* ANY text, including characters like `<`/`>`/`;`/`&`/`|` that would be
|
|
205
|
+
* dangerous unquoted — that is what lets a real trailer such as
|
|
206
|
+
* `Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>` through (see
|
|
207
|
+
* `hasUnsafeMetachar`'s doc for the exact quote-aware rule). Anything
|
|
208
|
+
* outside this narrow shape — `--amend`, `--no-verify`, `-C <dir>`
|
|
209
|
+
* (rejected implicitly: it does not appear directly after `git commit`),
|
|
210
|
+
* a pathspec, UNQUOTED chaining/redirection, command substitution that
|
|
211
|
+
* is live where it appears, an unrecognised flag — fails closed
|
|
212
|
+
* (`false`) and the caller falls through to the ordinary hard block.
|
|
213
|
+
*/
|
|
214
|
+
export function isRecoveryGitCommit(command) {
|
|
215
|
+
const trimmed = command.trim();
|
|
216
|
+
if (trimmed === "")
|
|
217
|
+
return false;
|
|
218
|
+
if (trimmed.includes("\n") || trimmed.includes("\r"))
|
|
219
|
+
return false;
|
|
220
|
+
// CRITICAL (found on re-review of the quote-aware rewrite): reject ANY
|
|
221
|
+
// backslash before doing anything else. `hasUnsafeMetachar` and
|
|
222
|
+
// `tokenize` both toggle quote state on every `"`/`'` character with no
|
|
223
|
+
// concept of backslash-escaping, but bash does: `\"` outside a quote is
|
|
224
|
+
// a LITERAL `"` that does NOT open a quote context. Without this
|
|
225
|
+
// check, a payload like `git commit -am a\" ; echo INJECTED ; \"` gets
|
|
226
|
+
// classified as one big safely-quoted message (the classifier "enters"
|
|
227
|
+
// a phantom quote span at the escaped `"` and treats the live `;`
|
|
228
|
+
// inside it as literal), while bash itself never entered a quote at
|
|
229
|
+
// all and executes `echo INJECTED` as a separate command — confirmed
|
|
230
|
+
// end-to-end (classifier ADMIT + a live shell actually running the
|
|
231
|
+
// injected command) for `;`, `||`, and `|` riding this exact shape.
|
|
232
|
+
// Same bug class the 0.40.0 CHANGELOG already documents once for the
|
|
233
|
+
// `harness approve` heredoc matcher (a backslash-escaped redirect
|
|
234
|
+
// smuggled past a quote-blind check there too).
|
|
235
|
+
//
|
|
236
|
+
// The fix is deliberately blunt rather than a full escape-aware state
|
|
237
|
+
// machine: modeling bash's actual backslash rules (live outside
|
|
238
|
+
// quotes and inside double quotes for a few characters, entirely inert
|
|
239
|
+
// inside single quotes, `$'...'` ANSI-C quoting has its own escape
|
|
240
|
+
// grammar again) is exactly the kind of bash-parser-in-miniature this
|
|
241
|
+
// module's design explicitly avoids building for a security boundary.
|
|
242
|
+
// Without any backslash present, the naive quote-toggling in
|
|
243
|
+
// `hasUnsafeMetachar`/`tokenize` matches bash's real quoting exactly,
|
|
244
|
+
// so rejecting every backslash closes the whole escape-based attack
|
|
245
|
+
// surface at the cost of not admitting messages that happen to contain
|
|
246
|
+
// one — an acceptable narrowing (the documented main case, this repo's
|
|
247
|
+
// own `Co-Authored-By: ... <noreply@anthropic.com>` trailer, has no
|
|
248
|
+
// backslash) for a fail-closed exemption gate.
|
|
249
|
+
if (trimmed.includes("\\"))
|
|
250
|
+
return false;
|
|
251
|
+
if (hasUnsafeMetachar(trimmed))
|
|
252
|
+
return false;
|
|
253
|
+
const m = /^git\s+commit\b/.exec(trimmed);
|
|
254
|
+
if (!m)
|
|
255
|
+
return false;
|
|
256
|
+
const rest = trimmed.slice(m[0].length);
|
|
257
|
+
const tokens = tokenize(rest);
|
|
258
|
+
if (tokens === null)
|
|
259
|
+
return false;
|
|
260
|
+
let i = 0;
|
|
261
|
+
while (i < tokens.length) {
|
|
262
|
+
const t = tokens[i];
|
|
263
|
+
if (FLAG_ONLY_TOKENS.has(t)) {
|
|
264
|
+
i += 1;
|
|
265
|
+
continue;
|
|
266
|
+
}
|
|
267
|
+
if (MESSAGE_FLAG_TOKENS.has(t)) {
|
|
268
|
+
i += 1;
|
|
269
|
+
if (i >= tokens.length)
|
|
270
|
+
return false; // dangling flag, no message value
|
|
271
|
+
i += 1; // consume the message token (already quote-aware metachar-screened above)
|
|
272
|
+
continue;
|
|
273
|
+
}
|
|
274
|
+
if (/^--message=.+/.test(t)) {
|
|
275
|
+
i += 1;
|
|
276
|
+
continue;
|
|
277
|
+
}
|
|
278
|
+
// Unrecognised token (e.g. --amend, --no-verify, a pathspec, an
|
|
279
|
+
// unknown flag): fail closed.
|
|
280
|
+
return false;
|
|
281
|
+
}
|
|
282
|
+
return true;
|
|
283
|
+
}
|
|
284
|
+
//# sourceMappingURL=recovery-git-commit.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"recovery-git-commit.js","sourceRoot":"","sources":["../../src/runtime/recovery-git-commit.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
export declare const SHELL_ALIASES: readonly ["Bash", "shell", "exec_command", "functions.exec_command"];
|
|
1
2
|
export declare function expandToolNameAliases(toolName: string): string[];
|
|
2
3
|
export declare function expandCodexHookMatchPattern(match: string): string;
|
|
3
4
|
export declare function extractShellCommand(event: {
|
|
@@ -1,4 +1,10 @@
|
|
|
1
|
-
|
|
1
|
+
// Canonical shell-tool alias set: Claude Code's single "Bash" tool plus
|
|
2
|
+
// the Codex shell-tool names current runtimes emit. Exported so callers
|
|
3
|
+
// elsewhere in the layering (e.g. policy-packs/builtin, which may import
|
|
4
|
+
// from runtime/ but not from cli/) can derive their own shell-alias
|
|
5
|
+
// lists from this one definition instead of hand-copying the literal
|
|
6
|
+
// array (task bea04a03 review finding).
|
|
7
|
+
export const SHELL_ALIASES = [
|
|
2
8
|
"Bash",
|
|
3
9
|
"shell",
|
|
4
10
|
"exec_command",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tool-name-aliases.js","sourceRoot":"","sources":["../../src/runtime/tool-name-aliases.ts"],"names":[],"mappings":"AAAA,MAAM,aAAa,GAAG;
|
|
1
|
+
{"version":3,"file":"tool-name-aliases.js","sourceRoot":"","sources":["../../src/runtime/tool-name-aliases.ts"],"names":[],"mappings":"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"}
|