@lannguyensi/harness 0.57.0 → 0.58.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 +33 -0
- package/README.md +1 -1
- package/dist/cli/apply/generate-codex-config.js +3 -3
- package/dist/cli/apply/generate-codex-config.js.map +1 -1
- package/dist/cli/approve/understanding.d.ts +4 -4
- package/dist/cli/index.js +3 -4
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/pack/hook-codex-user-prompt-submit.d.ts +0 -32
- package/dist/cli/pack/hook-codex-user-prompt-submit.js +11 -118
- package/dist/cli/pack/hook-codex-user-prompt-submit.js.map +1 -1
- package/dist/cli/pack/hook-solution-acceptance.d.ts +55 -0
- package/dist/cli/pack/hook-solution-acceptance.js +210 -23
- package/dist/cli/pack/hook-solution-acceptance.js.map +1 -1
- package/dist/cli/pack/hook-track-active-claim.d.ts +1 -0
- package/dist/cli/pack/hook-track-active-claim.js +91 -8
- package/dist/cli/pack/hook-track-active-claim.js.map +1 -1
- package/dist/cli/validate/checks.js +11 -1
- package/dist/cli/validate/checks.js.map +1 -1
- package/dist/io/lock.d.ts +26 -0
- package/dist/io/lock.js +25 -0
- package/dist/io/lock.js.map +1 -1
- package/dist/policy-packs/builtin/solution-acceptance-reconnect.d.ts +9 -7
- package/dist/policy-packs/builtin/solution-acceptance-reconnect.js +25 -20
- package/dist/policy-packs/builtin/solution-acceptance-reconnect.js.map +1 -1
- package/dist/policy-packs/builtin/solution-acceptance-runtime.d.ts +43 -4
- package/dist/policy-packs/builtin/solution-acceptance-runtime.js +40 -26
- package/dist/policy-packs/builtin/solution-acceptance-runtime.js.map +1 -1
- package/dist/policy-packs/builtin/understanding-before-execution.js +7 -5
- package/dist/policy-packs/builtin/understanding-before-execution.js.map +1 -1
- package/dist/runtime/task-providers/agent-tasks.d.ts +65 -3
- package/dist/runtime/task-providers/agent-tasks.js +145 -3
- package/dist/runtime/task-providers/agent-tasks.js.map +1 -1
- package/package.json +3 -1
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,39 @@ and this project adheres to [Semantic Versioning](https://semver.org/).
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.58.0] - 2026-09-23
|
|
11
|
+
|
|
12
|
+
### Fixed
|
|
13
|
+
|
|
14
|
+
- Corrected the 0.57.0 CLI-floor claim: `harness validate` does not execute
|
|
15
|
+
manifest version commands and now refers `tools.cli[].min_version` checks
|
|
16
|
+
to `harness doctor`, while callers supplying `versionProbe` retain comparison
|
|
17
|
+
(task `b32fdea2`).
|
|
18
|
+
|
|
19
|
+
- **Codex `UserPromptSubmit` now injects whenever Codex invokes the hook**
|
|
20
|
+
(task `f062b9f6`). The adapter no longer guesses from stdin prompt-field aliases
|
|
21
|
+
that a blank value represents an inter-agent notification. It still consumes
|
|
22
|
+
stdin, but event dispatch is the injection boundary. Pause remains first;
|
|
23
|
+
disabled-pack and manifest-load failures remain fail-open. A redacted genuine
|
|
24
|
+
Codex 0.156.1 operator fixture backs injection, and blank-prompt input is an
|
|
25
|
+
explicitly synthetic regression case that must still inject.
|
|
26
|
+
|
|
27
|
+
- **`harness.generated/active-claim` no longer clears on a `task_finish` that lands the task in `review`, and `task_merge` is now a tracked, dispatched verb end to end** (task `c86e3c4a`). `claimEffectForAgentTasksTool` (`src/runtime/task-providers/agent-tasks.ts`), the SINGLE decider for this classification, used to treat every `task_finish` as a release, disagreeing with agent-tasks's own documented v2 semantics (the work claim is cleared going to `done`, kept going to `review`); the two disagreeing left a session wedged (`task_start` on another task returns `already_claimed`, `task_abandon` on the review-state task returns `bad_state`, and the completion gate refuses every push/`task_merge` with "no active-claim task id recorded"). It now takes the tool RESULT as an optional third parameter and reads `task_finish`'s resulting `task.status` (via the new exported `taskFinishResultingStatus`, reading the mcp-server v1 receipt `{ ok, task: { id, status }, deviations? }`): only a resulting status of `review` returns `"none"` (keep); `done`, any other resolvable status, and an unreadable result all return `"release"`. `task_abandon` and `task_merge` both always release. `hook-track-active-claim.ts` no longer re-derives any of this locally (the round-1 fix's own local override is gone): it calls the classifier with `event.tool_response` and only presents the returned effect, one decider, no duplicate logic. `task_merge` is also now a member of `ACTIVE_CLAIM_TOOL_NAMES`, which feeds the generated PostToolUse matcher (`understanding-before-execution.ts`'s `TRACK_ACTIVE_CLAIM_MATCH` / `_CODEX`, both Claude and Codex variants) -- previously `task_merge` was untracked there too, so a real `task_merge` tool call never dispatched to this hook at all; every consumer of `ACTIVE_CLAIM_TOOL_NAMES` was enumerated (`rg`) and only these two matcher constants and this hook's own re-export consume it, none of them treating membership as "claim-acquiring" (acquire vs. release is a separate decision made by the classifier), so widening the set changes only which tools dispatch to this hook. The recovery path (`task_start` on the SAME review-state task) still needs no code change: `writeActiveClaim` already overwrites unconditionally. Pinned by: `tests/cli/pack-hook-track-active-claim.test.ts` (finish-to-done clears, finish-to-review keeps, finish-with-no-result and finish-with-malformed-status both fail safe, `task_merge` clears, review-then-restart recovery); `tests/runtime/task-providers/agent-tasks.test.ts` (the classifier's result-aware decision directly, `taskFinishResultingStatus`'s extraction, `task_merge` in `ACTIVE_CLAIM_TOOL_NAMES`); `tests/policy-packs/expand.test.ts` and `tests/cli/apply/generate-codex-config.test.ts` (the generated Claude and Codex matchers both now match `task_merge`, both the exact string and a live regex test, plus a negative control). Mutation probes (`agent-primitives probe --pre 'npm run build'`) reverting to clear-on-every-finish, keeping the marker on `done`, and removing `task_merge` from the tracked set all killed by these fixtures. Upgrade: the review-keep fix is in the hook itself and needs no re-apply; to dispatch `task_merge` to the hook, re-run `harness apply` (and re-merge the generated settings into your live Claude Code settings or Codex config) so the widened PostToolUse matcher is installed.
|
|
28
|
+
|
|
29
|
+
- **Round-2 review fix (commit `8dfba1b`): the round-1 fix was INERT in production -- Claude Code's real MCP `tool_response` is a content-block array, not the plain receipt object round 1 read** (task `c86e3c4a`, HIGH). Live capture, claude 2.1.280: a PostToolUse event for an MCP tool call carries `tool_response` shaped `[{ "type": "text", "text": "<json>" }]`, not `{ ok, task: { status } }` directly; `taskFinishResultingStatus` read only the latter, so `taskFinishResultingStatus(toolResponse)` always answered `null` against the real payload and `claimEffectForAgentTasksTool` always fell to its fail-safe `"release"` branch, exactly reproducing the pre-fix wedge the round-1 fix claimed to close. `taskFinishResultingStatus` (and the new `taskIdFromToolResponse`) now unwrap, recursively: (a) the plain receipt object itself (unchanged, also covers the `include:["task"]` full-task variant); (b) the measured content-block array, first `type: "text"` block JSON-parsed; (c) an MCP `CallToolResult` object, `{ content: [...] }` (plausible on Codex, **UNMEASURED** here); (d) a bare JSON string. Verbatim redacted live capture committed at `tests/fixtures/track-active-claim/real-posttooluse-task-finish-2.1.280.json`; driven end to end through `runPackHookTrackActiveClaimCli` for both the finish-to-review (marker kept) and finish-to-done (marker cleared, only the status changed from the same capture) outcomes, plus an `include:["task"]` full-object receipt inside the same content-block envelope. Also corrected: the fail-safe rationale in `claimEffectForAgentTasksTool`'s doc comment, this entry, and the pack doc previously said releasing-on-unreadable "costs only" an "ergonomic shortcut" -- the marker actually feeds the FAIL-CLOSED completion gate (`hook-solution-acceptance.ts`'s `readActiveClaim`), so releasing is chosen because a KEPT marker for an already-finished task would misroute that gate, at the cost of a possible wedge, not because the marker is low-stakes. An unreadable result's release now also logs a distinct diagnostic naming the shape it fell back from (`unreadable tool_response, shape=array|string|object|absent`), pinned in tests, so it no longer looks identical to an intentional `done` release in the operator's stderr trail. Separately, `task_abandon` / `task_merge` / a non-review `task_finish` now clear the marker only when it already names the SAME task id as the call acted on (input `taskId`, falling back to the result's `task.id`); a mismatch keeps the marker and logs the near-miss (`kept active-claim <B>: <verb> on <A>`) -- round 1 cleared unconditionally, so a caller holding a work-claim marker for task B lost it to an unrelated `task_merge` (or finish/abandon) on task A, including finishing a REVIEW claim on A while B's work claim was live. Class closure: every `tool_response` consumer under `src/cli/pack/` and `src/runtime/` was enumerated (`rg tool_response`); `hook-stay-in-scope.ts`'s `extractTaskId` reads `tool_response.task.id` / `tool_response.id` through the same plain-object-only accessor this hook had before this fix, so it likely has the identical content-block blind spot against a real Claude Code MCP payload -- reported here as a risk/follow-up, not fixed (out of this task's scope). `hook-post-merge-gate-record.ts`'s `tool_response` reads are for the Bash tool (its own separately-measured `{ stdout, stderr, interrupted }` shape, not an MCP content-block array) and are not the same class. New tests: a golden-fixture describe block (real payload assertion, finish-to-review, finish-to-done, `include:["task"]` full-object variant), a defensive-shapes describe block (`CallToolResult` object, bare JSON string), an unreadable-diagnostic describe block (all four shapes plus a negative control), and an id-equality describe block (task_merge / task_abandon on an unrelated id, same-id clear, review-claim-of-another-task, result-`task.id` fallback, no-marker fail-safe). Mutation probes (`agent-primitives probe --pre 'npm run build'`): the content-block/CallToolResult/string unwrap reverted to plain-object-only (killed by the golden fixture), the id-equality check removed (killed by the marker-B fixture), and the unreadable-shape diagnostic removed (killed) -- plus the three round-1 probes replayed at their moved anchor, still killed.
|
|
30
|
+
|
|
31
|
+
### Changed
|
|
32
|
+
|
|
33
|
+
- **`harness pack hook solution-acceptance`'s completion-gate deny text now distinguishes the three `gate.verdict === null` readings instead of appending the same reconnect-vs-retry paragraph to all three** (task `799de976`). The hook reads grounding-mcp's documented attempt-lock anchor (`<verdict dir>/<id>.attempt-lock`, README "Attempt lock anchor" row at `grounding-mcp-v0.12.0`) via `proper-lockfile`'s own read-only `checkSync` (already a harness dependency; no new one added) to tell "an attempt is live" apart from "never evaluated" and "a marker path exists but what is there was not accepted as a verdict"; liveness is three-valued (`live`, `not-live`, `unknown`, through a read-only `checkFileLock` in `src/io/lock.ts`), and a note never asserts an absent attempt or a missing marker when the check could not read; the full reconnect-vs-retry paragraph (`solution-acceptance-reconnect.ts`) is now appended only for the live-attempt reading, and the other two readings get their own short, reading-named line instead; the paragraph's own wording is corrected to say the hook itself read the anchor and detected the live-attempt reading, not that it cannot tell the three readings apart (its shared facts, `RECONNECT_FACT_*` and `renderReconnectInstructionsSection`, stay byte-identical). A lock directory left behind by a dead process is read as stale using the producer's OWN staleness window (`DEFAULT_ATTEMPT_LOCK_STALE_MS = 30_000`, `grounding-mcp-v0.12.0` `solution-attempt-log.ts:102`, the default `acquireAttemptLock` passes to `proper-lockfile` when no caller overrides `staleMs`), so this hook's "live" reading and the producer's reclamation rule agree as long as the producer keeps that default and no caller overrides it: an operational pin re-checked on every grounding-mcp bump, not a guarantee. `instructions.md` and grounding-mcp's lock layout are unchanged. See `docs/policy-packs/solution-acceptance.md`, "Reading the attempt-lock anchor to distinguish the three readings", for the full decision record and source citations. Pinned in `tests/cli/pack-hook-solution-acceptance.test.ts` (one case per reading, the overlap of a live lock with an unreadable marker, a stale-lock regression, two check-error-path regressions, a symlinked anchor) and in `tests/io/lock.test.ts` and a literal-wording pin in `tests/policy-packs/solution-acceptance-reconnect.test.ts`; mutation probes removing the live-attempt branch, neutralising the stale rule, substituting a hand-copied paragraph, flipping the check-error catch arm, and reverting the corrected wording (`agent-primitives probe --pre 'npm run build'`) all killed.
|
|
34
|
+
|
|
35
|
+
- **Review-round fixes: the deny note now states only what the hook established** (task `799de976`, commit `3d3bddf`; the same defect class recurred in four consecutive rounds, so this round closes the CLASS). Each round's note asserted something the hook had not established, and each fix replaced one guessed cause with a narrower guess that the next reachable state falsified: first "no attempt reads as currently live" where the liveness check had thrown, then "the verdict directory could not be read" where only the lock path was unreadable, then "the verdict directory or the attempt-lock path could not be read" for an id from which NEITHER path can be derived. An id `sanitizeVerdictId` rejects (`.`, `..`, anything sanitizing to an empty basename, reachable from an active claim; the `SOLUTION_VERDICT_ID` path validates through the same function and answers null instead) is now its own `NullVerdictInfo` union member, settled before anything is read and carrying no `liveness` field, so "the id was unusable" has no field left to render as "a path could not be read"; its note names that one fact, points at the active claim, and asks for a usable id instead of repeating `solution_evaluate` for an id that can never be accepted. The remaining unknown-liveness line names no cause at all. Reading (3) no longer says "could not be read or parsed" for a marker `readVerdict` refuses by policy (a symlink, a non-regular file); it names the complete set of ways that read answers null for a present path, at the hook and at the shared reading-label site (`RECONNECT_THREE_READINGS_LABELS`). A state table in `tests/cli/pack-hook-solution-acceptance.test.ts` ("null-verdict deny note: one exact line per reachable state") pins one exact expected line per reachable (id-usability, reading, liveness) combination, nine rows, and asserts no other state's line appears, so this class fails there rather than reaching an agent; it doubles as the checklist for extending the classifier. The stale-lock fixture's back-date is a literal (90 s) rather than derived from `ATTEMPT_LOCK_STALE_MS`, so it discriminates a widened window instead of staying stale under every mutation of the constant it was meant to pin. Mutation probes restoring the guessed cause, narrowing reading (3)'s wording back, and widening the stale window to 300 s (`agent-primitives probe`, the last one scoped to the stale test alone) all killed.
|
|
36
|
+
|
|
37
|
+
- **Round-6 review fix: the deny text is classified from ONE read of the marker** (task `799de976`, commit `244f9c3`). The gate read the marker at the decision site and the deny text classified it again a few statements later, so the two could disagree: a background attempt finishing in that window, the case this pack exists for, made the note tell the agent its fresh marker had been rejected when the gate had simply not seen it yet, and the reasons the note enumerated did not include the one that actually applied. A new `readVerdictDetailed` reports WHY a read yielded no verdict (`invalid-id`, `missing`, the shared reader's `symlink` / `not-regular` / `unreadable`, plus `invalid-record`) in one observation; `readVerdict` is the same function with the reason dropped, so every caller that needs only the gate decision is unchanged. Reading (3) no longer restates a disjunction over the rejection kinds: each kind renders its own line naming what that read established. The lines are a `Record` keyed by the exported `NULL_VERDICT_NOTE_STATES`, so a state with no line fails the build, and the state table's new coverage test fails when a listed state has no fixture, which makes the table a checklist rather than a convention. Two fixtures are added (a schema-invalid record, and a regular file the process may not read), the symlink and directory fixtures now pin their own distinct lines, and the unusable-id remedy names the verb that clears the claim instead of asking for an impossible re-run. The liveness helper loses a `catch` that became unreachable once id usability was settled first: an arm no mutant can kill is worse than no arm. Mutation probes collapsing one rejection line into another, and adding a note state with no fixture, both killed; the removed race itself is not fixture-testable, which is why the fix removes the second observation rather than adding a test for it.
|
|
38
|
+
|
|
39
|
+
### Added
|
|
40
|
+
|
|
41
|
+
- **Two release-hygiene CI gates: README's release sentence must match `package.json`, and the tagged CHANGELOG section must stay under a size ceiling** (task `3a910716`). `npm run check:readme-release-version` (`scripts/check-readme-release-version.mjs`) fails when README.md's "The current release is `` `vX.Y.Z` ``." sentence names a different version than `package.json`, wired into `ci.yml` next to `check:changelog-coverage`. `npm run check:release-notes-size` (`scripts/check-release-notes-size.mjs`) measures the CHANGELOG.md section for `package.json`'s version the same way `release.yml`'s awk extraction does and fails above a 115,000-character ceiling (the `0.57.0` section measured 110,880 characters when this gate was written; GitHub's release/tag body limit is roughly 125,000); `release.yml` runs the same measurement again at tag time, next to its existing empty-notes guard, so an oversized section is caught both before the tag and at release time. CONTRIBUTING.md's Releasing section now lists the release-prep steps in order (`npm version --no-git-tag-version`, CHANGELOG heading insertion, README sentence, bundle re-verification, the checks above, PR, merge, read the merge commit's CI, annotated tag). Also fixed two stale line-number citations of `CHANGELOG.md` (a `:141` in `docs/okf/log.md`, an `:18` in `src/cli/approve/understanding.ts`) into the repo's shift-proof `` `CHANGELOG.md:#x.y.z` `` heading-anchor form.
|
|
42
|
+
|
|
10
43
|
## [0.57.0] - 2026-09-21
|
|
11
44
|
|
|
12
45
|
### Fixed
|
package/README.md
CHANGED
|
@@ -224,7 +224,7 @@ the `&`-as-command-boundary trigger fix in `v0.43.0`, per-policy
|
|
|
224
224
|
cross-repository attribution for `${REPO}`/`${BRANCH}` preflight
|
|
225
225
|
facts in `v0.44.0`, and `apply --runtime codex|opencode` next-steps
|
|
226
226
|
hints in `v0.46.0`.
|
|
227
|
-
The current release is `v0.
|
|
227
|
+
The current release is `v0.58.0`.
|
|
228
228
|
|
|
229
229
|
The phase-by-phase plan with acceptance criteria lives in
|
|
230
230
|
[`docs/ROADMAP.md`](docs/ROADMAP.md); what shipped in each version is
|
|
@@ -46,15 +46,15 @@ const HEADER = [
|
|
|
46
46
|
"# Operator-owned settings (model, auth, sandbox profile, MCP servers)",
|
|
47
47
|
"# stay in your own config; harness owns hook wiring only.",
|
|
48
48
|
"#",
|
|
49
|
-
"# Wire format the
|
|
49
|
+
"# Wire format the tool-event adapter scripts expect on stdin (per",
|
|
50
50
|
'# docs/policy-packs/understanding-before-execution.md "Adapter notes /',
|
|
51
51
|
'# Codex"):',
|
|
52
52
|
"#",
|
|
53
53
|
"# { session_id?: string, tool_name?: string, raw_input?: any, event?: string }",
|
|
54
54
|
"#",
|
|
55
55
|
"# PreToolUse blocker exit-code contract: 0 = allow, 2 = block (with reason",
|
|
56
|
-
"# on stderr). UserPromptSubmit
|
|
57
|
-
"#
|
|
56
|
+
"# on stderr). UserPromptSubmit emits developer-context instructions on stdout",
|
|
57
|
+
"# whenever Codex invokes that event; it does not inspect stdin to suppress turns.",
|
|
58
58
|
"",
|
|
59
59
|
].join("\n");
|
|
60
60
|
// Control-character regex covering U+0000..U+001F + U+007F. Constructed
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generate-codex-config.js","sourceRoot":"","sources":["../../../src/cli/apply/generate-codex-config.ts"],"names":[],"mappings":"AAAA,gDAAgD;AAChD,EAAE;AACF,oEAAoE;AACpE,+DAA+D;AAC/D,yEAAyE;AACzE,sCAAsC;AACtC,mEAAmE;AACnE,qEAAqE;AACrE,uEAAuE;AACvE,EAAE;AACF,gDAAgD;AAChD,sEAAsE;AACtE,6DAA6D;AAC7D,EAAE;AACF,wEAAwE;AACxE,kBAAkB;AAClB,oDAAoD;AACpD,4DAA4D;AAC5D,EAAE;AACF,kCAAkC;AAClC,uEAAuE;AACvE,wEAAwE;AACxE,wEAAwE;AACxE,oEAAoE;AACpE,uDAAuD;AACvD,qEAAqE;AACrE,qEAAqE;AACrE,2CAA2C;AAG3C,OAAO,EAAE,2BAA2B,EAAE,MAAM,oCAAoC,CAAC;AACjF,OAAO,EAAE,qBAAqB,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAOnF;;;;;GAKG;AACH,MAAM,CAAC,MAAM,2BAA2B,GACtC,+CAA+C,CAAC;AAElD,MAAM,MAAM,GAAG;IACb,2BAA2B;IAC3B,sEAAsE;IACtE,GAAG;IACH,2CAA2C;IAC3C,6CAA6C;IAC7C,GAAG;IACH,sEAAsE;IACtE,uEAAuE;IACvE,2DAA2D;IAC3D,GAAG;IACH,
|
|
1
|
+
{"version":3,"file":"generate-codex-config.js","sourceRoot":"","sources":["../../../src/cli/apply/generate-codex-config.ts"],"names":[],"mappings":"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"}
|
|
@@ -319,10 +319,10 @@ export declare function renderMalformedSectionsNotice(sections: string[]): strin
|
|
|
319
319
|
* Approve-time content validation. v1 enforces the one rule the dogfood
|
|
320
320
|
* loop discovered today (2026-05-24): a `grill_me` Report must declare a
|
|
321
321
|
* non-empty `priorArt` list with no literal `- None`. The structural
|
|
322
|
-
* parser in `@lannguyensi/understanding-gate`
|
|
323
|
-
*
|
|
324
|
-
*
|
|
325
|
-
*
|
|
322
|
+
* parser in `@lannguyensi/understanding-gate` only checks that the
|
|
323
|
+
* Prior Art section is present (required since 0.4.0,
|
|
324
|
+
* `CHANGELOG.md:#0.28.0`); it cannot judge the content, so the approve
|
|
325
|
+
* CLI is the boundary that refuses a hollow list here, so an agent
|
|
326
326
|
* cannot ship a hollow Understanding Report and still get the gate open.
|
|
327
327
|
*
|
|
328
328
|
* Modes that skip validation:
|
package/dist/cli/index.js
CHANGED
|
@@ -944,7 +944,7 @@ export function buildProgram(opts = {}) {
|
|
|
944
944
|
});
|
|
945
945
|
packHookCmd
|
|
946
946
|
.command("track-active-claim")
|
|
947
|
-
.description("PostToolUse: read tool-event JSON from stdin, maintain ~/.claude/harness.generated/active-claim on agent-tasks task_start / task_finish / task_abandon so `harness approve understanding` can auto-resolve the task id without --task (harness/494fd1e5).")
|
|
947
|
+
.description("PostToolUse: read tool-event JSON from stdin, maintain ~/.claude/harness.generated/active-claim on agent-tasks task_start / task_finish / task_abandon / task_merge so `harness approve understanding` can auto-resolve the task id without --task (harness/494fd1e5). task_finish keeps the marker when the resulting status is review and clears it otherwise (task c86e3c4a); task_abandon / task_merge / a non-review task_finish clear it only when the marker already names the same task id, otherwise it is left in place (task c86e3c4a round 2).")
|
|
948
948
|
.option("--config <path>", "manifest path (default: ~/.harness/harness.yaml; legacy fallback ~/.claude/harness.yaml)")
|
|
949
949
|
.option("--project <name>", "apply per-project overrides")
|
|
950
950
|
.option("--pack <name>", "pack name to evaluate (default: understanding-before-execution)")
|
|
@@ -1004,8 +1004,7 @@ export function buildProgram(opts = {}) {
|
|
|
1004
1004
|
await runPackHookSubagentStopCli(cliOpts);
|
|
1005
1005
|
});
|
|
1006
1006
|
// Phase 6 #6 — Codex adapter sub-commands. Mirror the pre-tool-use
|
|
1007
|
-
// shape; UserPromptSubmit
|
|
1008
|
-
// on stdout for Codex to prepend to additional_instructions.
|
|
1007
|
+
// shape; UserPromptSubmit emits developer-context instructions on stdout.
|
|
1009
1008
|
packHookCmd
|
|
1010
1009
|
.command("codex-pre-tool-use")
|
|
1011
1010
|
.description("Codex PreToolUse blocker: read tool-event JSON from stdin, consult the signed approval marker (persisted report and ledger are audit evidence only), exit 2 with stderr reason on block")
|
|
@@ -1055,7 +1054,7 @@ export function buildProgram(opts = {}) {
|
|
|
1055
1054
|
});
|
|
1056
1055
|
packHookCmd
|
|
1057
1056
|
.command("codex-user-prompt-submit")
|
|
1058
|
-
.description("Codex UserPromptSubmit injector: emit
|
|
1057
|
+
.description("Codex UserPromptSubmit injector: emit developer-context instructions on stdout whenever Codex invokes the event")
|
|
1059
1058
|
.option("--config <path>", "manifest path (default: ~/.harness/harness.yaml; legacy fallback ~/.claude/harness.yaml)")
|
|
1060
1059
|
.option("--project <name>", "apply per-project overrides")
|
|
1061
1060
|
.option("--pack <name>", "pack name to evaluate (default: understanding-before-execution)")
|