Repository navigation
Description
Relocated from dezren39/darwin-nix#112 on 2026-10-28 (placement audit): mcpx's single source lives in developing-today/code (pkgs/mcpx); re-home tracked at #309. Original body below; issue references inside it are historical (dezren39/nix numbering).
Parent: #176
Summary
mcpx exec runs a script and returns what it produced. This asks for the caller to be able to attach natural-language instructions to the edges of that run — before it, after it, on failure, on success — so the deterministic script stays deterministic and the fuzzy parts sit outside it.
That is a better factoring than it first appears. The script is the part that must be reproducible; "make sure these dependencies exist wherever this runs" and "clean up the results and transform them" are the parts that legitimately vary by environment and by caller. Keeping them out of the script means the same script file works everywhere and the variation is in the options, which is exactly the shape ExecOptions was designed for (#40, step 7: "not a new method, an option").
Original notes
- mcp-owned opencode api support
- accept prompt/prePrompt/postPrompt/onErrorPrompt/onSuccessPrompt
- the script interface just runs the scripts, but you can provide a prePrompt saying hey i added a bunch of dependencies please make sure they exist where the job runs, postPrompt to clean up the results and transform, either prompt/pre/post could say to fix error thing but onError gets provided above or below the error and is first seen with the error if theres an error. prompts can use templatevars to put content where they want it or for prompt overall to be stopped/resumed maybe.
Current state (what mcpx does today, with file refs)
execsvc.Options(internal/execsvc/execsvc.go:101) is the designated growth point: "Deliberately one flat struct that grows rather than a new endpoint per capability." It carriesRuntime,Timeout,Permissions,Placeholders,Session,Cwd,Env,Stdin,Output,Capabilities,Artifacts,Task,NS,Args,Export. There are no prompt fields.- Placeholders already exist and already have substitution semantics worth copying. Recipes declare holes in a header comment (
// @param repo:string) and reference them as@repo; values are substituted as JSON, never as text, because "a recipe runs with the user's credentials; raw substitution would make every placeholder an injection site" (docs/consumer.md§3). Launchers use the same@placeholderspelling (Bump build/buck/preludes/buck2-prelude from3a02ea3toc77fc97#7). A recipe with an unfilled required hole is an invalid script, which is the right way round. ScriptConfig.Prefix(internal/config/config.go:236-248) already layers code in front of a script from config, resolved across the config chain (docs/proposals.md§"Layered script prefixes"). It is the deterministic sibling of a prePrompt and the precedent for how layering should work.- Deterministic edge hooks already ship — for the CLI and config, not for
/v1/exec. (Added in the 2026-09-30 issues pass, at 05c78b2; this issue predated them being noticed.) Five settings —script.before,script.prefix,script.onSuccess,script.onError,script.suffix(internal/settings/registry.go:212-242), layered throughScriptConfig(internal/config/config.go:236-257) and rendered asrunner.Phases(internal/runner/runner.go:190-205) — inject source into a file script's launcher:onSuccessseesresult.value,onErrorseesresult.errorand the error is rethrown ("a hook, not a handler"),suffixruns in afinally. They run inside the script's own process, and they are deliberately not on the wireOptions:execsvc.RunWithkeeps phases CLI-only (internal/execsvc/execsvc.go:358-366). So Approach B below is partly built already, in a different shape; what is missing is per-call hooks over/v1and MCP, a typed context, and prompt hooks. The shipped names are one of the four hook vocabularies in Phase 3: sync, blob gate, and relays #181 collision 2. - The exec stream has an ordering contract:
start, thenlog/emit/stdoutinterleaved, thenartifact, thenresultorerror, thenend, with bodies strictly afterend(execsvc.Frame,docs/exec.md). Any hook output has to find a place in that order, and that is a real design constraint, not a formality. internal/diagnoseproduces structured diagnostics that already sit next to an error.- Tasks (
internal/tasks) provide the pause/resume machinery the note's "stopped/resumed maybe" is reaching for, and2026-07-28's MRTR pattern gives a caller-facing way to resume a request mid-flight. - mcpx has no model; see Bump build/buck/preludes/buck2-prelude from
d956689to52604b1#110. Every rung below degrades to a no-op without one.
Approaches
Approach A — least recommended: five new string options, each handed to a model, each running arbitrary code
Options.Prompt, .PrePrompt, .PostPrompt, .OnErrorPrompt, .OnSuccessPrompt, each sent to a model with a general-purpose agent loop that can do whatever it decides is needed.
Why not:
- Four of the five are the same thing at different times. Five independent fields means five code paths, five sets of semantics, and five places to fix a bug. Lifecycle hooks are a list of (phase, instruction), and modelling them as one list with a phase is strictly better —
promptis then just "the phase ismain", which is also what makes "either prompt/pre/post could say to fix error thing" fall out naturally instead of needing to be special-cased. - An unbounded prePrompt is arbitrary code execution as a side door. "make sure these dependencies exist where the job runs" resolved by a general agent means installing packages, which is the provisioning problem from Update module github.com/jackc/pgx/v5 to v5.5.4 [SECURITY] - autoclosed #113 and needs its own confinement decisions. An exec option should not quietly be the more powerful interface.
- It puts the model on the default path. Every run pays a round trip even when the hooks do nothing surprising.
docs/consumer.md's rule — "never sample on a path that doesn't need it" — is violated by construction if hooks are evaluated eagerly. - Nothing is reproducible. The same script plus the same prompts gives different behaviour run to run, which destroys the one property that makes
execworth having over a chat turn.
Approach B — middle: one hooks list, deterministic hooks only
Add one field:
"options": {
"hooks": [
{ "phase": "pre", "script": "ensure-deps.ts" },
{ "phase": "post", "script": "normalise.ts" },
{ "phase": "onError", "script": "cleanup.ts" }
]
}Phases: pre, main, post, onError, onSuccess. Each hook is a script, run in the same content-addressed workdir with the same runtime and permissions, receiving a typed context (the run id, the result or the error plus its diagnose.Diagnostic, the artifact list). post transforms the result; onError sees the error first and may return a replacement result or re-raise — which differs from the shipped script.onError, where the error always propagates.
The phase names and hook semantics are not this issue's to decide (#181 collision 2). Four vocabularies exist or are proposed — the shipped script.* phases, #81's hook points, #82's runtime hooks and this list — and the one vocabulary is being decided in a decision record SURFACES is writing under pkgs/mcpx/docs/decisions/, carried by #81. The phases here are input to that record; this issue adopts what it decides.
This is genuinely useful on its own — ScriptConfig.Prefix proves the demand for "run this code around my code" and hooks generalise it to the other three edges — and it is the thing the prompt version needs underneath it anyway, because a prompt hook's output has to become something executable. It is also fully deterministic, cacheable, and testable.
What it does not give you is the actual ask: "hey i added a bunch of dependencies please make sure they exist where the job runs" is a sentence, not a script, and the whole point is not having to write the script.
Approach C — recommended: one hooks list where a hook is either a script or a prompt, with a declared effect
Build B's structure, and let each entry be a script or a prompt:
"options": {
"hooks": [
{ "phase": "pre", "prompt": "I added @deps — make sure they exist where this runs",
"effect": "script", "model": "cheap" },
{ "phase": "post", "prompt": "flatten the result to {id, title} and drop nulls",
"effect": "transform" },
{ "phase": "onError", "prompt": "if this is a rate limit, wait and say so; otherwise explain",
"effect": "advise" }
]
}Four decisions make this safe and small:
1. A hook declares its effect, and the effect bounds what it may do.
effect |
what the hook's output may be | runs code? |
|---|---|---|
advise |
text, attached to the result or error | no |
transform |
a replacement for the result value only | no |
script |
TypeScript, diagnosed and typechecked, then run in the same sandbox | yes |
retry |
a decision: retry / retry-with-changes / give up | via the repair ladder |
advise is the default. This is the same dial as repair.level in #111 and should use the same vocabulary; a user who understands one understands the other. #181 collision 3: #111 carries that one dial vocabulary, via the SURFACES decision record under pkgs/mcpx/docs/decisions/; the effect values in this table are input to it, and #112 adopts what it decides rather than shipping its own. The ceiling a daemon puts on it is #185 (collision 5). A prompt hook whose effect is script is the only one that can execute anything, and it inherits Options.Permissions unchanged — a hook must never be able to do what the script it wraps could not.
2. Template variables reuse the placeholder machinery that exists, including its safety property. @name is already the spelling in recipes and launchers, and recipe values are JSON-encoded, not text-substituted, precisely so a placeholder cannot become an injection site. A prompt is text and the same discipline applies at a different layer: the substituted value must be delimited and marked as data, and a hook prompt must never be able to redefine the hook's own effect. Beyond user placeholders, offer a small set of built-ins the note is clearly asking for — @result, @error, @diagnostic, @calls, @artifacts, @source — so "onError gets provided above or below the error" is expressible as "Here is what happened:\n@error\n@diagnostic\nWhat should I do?" rather than being a positioning rule mcpx has to guess. Position by template, not by convention; when a prompt contains no built-in reference, mcpx appends the context after it, which is the sensible default the note describes.
3. Hooks are declarable in config, not just per call. ScriptConfig.Prefix and the shipped script.before/onSuccess/onError/suffix already layer across the config chain; script.hooks (or whatever collision 2's record names it) should layer the same way, so "always check dependencies before any run in this project" is written once. Per-call hooks append to config hooks rather than replacing them, with the same nearest-wins resolution ResolveLines already implements.
4. Stop/resume is internal/tasks, not a new mechanism. "for prompt overall to be stopped/resumed maybe" — a hook that needs a decision raises an elicitation through the existing broker (with a default and a deadline, as elicit.Ask enforces), and a run that must wait becomes a task with a handle, collectable from /v1/tasks/{id}. Both already exist and both already work for the recipe path. On 2026-07-28 this is also exactly MRTR: resultType: "input_required", the client answers, the request is retried.
Stream placement, since the Frame order is a contract (docs/exec.md:137). #181 collision 7: #111 owns the rule every new frame kind follows (declared placement relative to result, listed in the documented order, asserted by a test comparing documented and emitted order); the hook frame is added under that rule and the placement below is input to it: a hook emits log/emit/stdout frames tagged with its phase and a hook frame recording phase, effect, model used, duration and whether it changed anything. pre frames come after start; post/onSuccess frames come after the result frame and before end; onError frames come after error and before end. The final result reflects a transform hook's output, with the original preserved in the hook frame — a caller must be able to see what mcpx changed.
Cost and default posture. Hooks are off unless declared. A prompt hook without an available model is a warning on the run, not a failure — the script still ran, and that is the honest degradation. pre hooks with effect: script should be cached by (prompt, placeholder values, catalogue fingerprint) so the same "ensure my dependencies" instruction resolves to the same generated script on every run instead of re-generating it; that caching is also what makes the generated script reviewable and promotable to a real hook script, which is how this feature should be expected to be used — prompt once, keep the script.
Recommended because the structure is one list rather than five fields, because effect-declaration is what keeps a convenience feature from being an execution back door, because everything it needs — placeholders, prefixes, tasks, elicitation, diagnostics, artifacts — already exists and this mostly wires them to four new points in time, and because the deterministic half (Approach B) is independently valuable and ships first.
Open questions
- Does
onSuccessearn its own phase whenpostexists?postrunning only on success andonErroron failure covers it; a separateonSuccessis only distinct ifpostis meant to run on both. Pick one and document it — this is the note's ambiguity, not a design difficulty. - Ordering when several hooks share a phase: declaration order across config layers, or an explicit
order? Declaration order plus nearest-wins layering matchesScriptPrefix. - Should a
transformhook be allowed to change artifacts, or only the result value? Only the value is far simpler and probably enough. - Timeout accounting: does a hook's time count against
Options.Timeoutor get its own budget? Its own, or a slow model silently eats the script's budget. - Is there a case for hooks on a tool call rather than a run (
before every call to this server, ...)? That is closer to a server-level middleware feature and may belong with tool views. - Should a hook be able to abort the run before it starts (
prereturning refuse)? Useful and cheap, but then aprehook is a policy mechanism and needs the floor/ceiling clamping Phase 5: who may clear a tag claim #185 owns.
Ease · Impact · Related
Ease M (S for the deterministic half — much of it already ships as script.* launcher phases, so what remains is exposing them per call with a typed context; M with prompt hooks and effects; L if stop/resume gets its own machinery rather than reusing tasks) · Impact medium-high — it is what makes one script file portable across environments without the script knowing where it runs, which is the same goal #40 had for artifacts.
Depends on / related: #81 (owns the hook vocabulary via the SURFACES decision record — #181 collision 2), #111 (owns the autonomy dial and the frame-order rule — collisions 3 and 7), #185 (owns ClampedBy — collision 5), #82 (runtime hook registration, the fourth vocabulary), #40 (closed, fixed in #57: ExecOptions is the home; "not a new method, an option" is the governing precedent), #41 (closed, fixed in #58: placeholders, elicitation defaults/deadlines, diagnostics as hook context), #7 (launcher @placeholder spelling), #5 (config chain, for layered hooks), #79 (hook cost must not regress exec latency). Siblings: #110 (where a prompt hook's model comes from), #113 (the dependency-provisioning half of the pre example; also #103/#104 in #175).
Security/auth deferred; see tracker.
Activity
developing-today commentedon Oct 28, 2026
CODE-855
dezren39 commentedon Oct 28, 2026
History carried over from dezren39/darwin-nix#112 (verbatim, oldest first):
@dezren39 · 2026-09-30T07:21:51Z
Integration pass. Placed in the DAG rooted at #181.
d956689tod460fcc#109 Bump build/buck/preludes/buck2-prelude fromd956689to52604b1#110 Bump checkmarx/ast-github-action from 2.0.19 to 2.0.23 #111 Update module github.com/jackc/pgx/v5 to v5.5.4 [SECURITY] - autoclosed #113 Update checkmarx/ast-github-action digest to 6c56658 - autoclosed #114 Update github.com/charmbracelet/promwish digest to 6c16e8f - autoclosed #115@dezren39 · 2026-09-30T07:27:50Z
Integration pass -- cross-theme collision. Surfaced only when the themes were put side by side; the authors of these issues could not see each other's work. Recorded at the root in #181.
Four hook vocabularies, and no issue owns the reconciliation
script.*(shipped), #81's hook-point table, #82's runtime hook registration, and #112'sprePrompt/postPrompt/onErrorlist are four vocabularies for one concept. #112 sits in a different theme (#176) from #81/#82 (#173), so nobody currently owns the overlap. Reconciling them after the fact is a breaking config change -- design them as one.Also on: #81 #82. Nobody currently owns this.
@dezren39 · 2026-09-30T07:27:53Z
Integration pass -- cross-theme collision. Surfaced only when the themes were put side by side; the authors of these issues could not see each other's work. Recorded at the root in #181.
Three autonomy dials, independently invented
#111's
repair.level, #112's hookeffect, and #113'sprompt.mode: planare the same dial. Settle it in #111, which is the earliest of the three. Otherwise a user learns three vocabularies for one concept.Also on: #111 #113. Nobody currently owns this.
@dezren39 · 2026-09-30T07:28:01Z
Integration pass -- cross-theme collision. Surfaced only when the themes were put side by side; the authors of these issues could not see each other's work. Recorded at the root in #181.
ClampedByis a settings-registry feature with no owner#111 proposes floor/ceiling clamping -- a daemon sets a maximum, a caller may lower but not raise -- and #112 and #113 both need it. It currently exists only as a paragraph inside #111. It is an
internal/settingscapability, not a repair feature; whoever reaches it first will implement it, and the other two will implement it again differently.Also on: #111 #113 #172. Nobody currently owns this.
@dezren39 · 2026-09-30T07:28:09Z
Integration pass -- cross-theme collision. Surfaced only when the themes were put side by side; the authors of these issues could not see each other's work. Recorded at the root in #181.
The exec
Frameordering contract is extended by two issues independently#111 adds a
callframe; #112 adds ahookframe with explicit before/after-resultplacement rules.docs/exec.mdstates the frame order as a contract. Neither issue knows about the other's placement rules, and no issue owns updating the contract.Also on: #111. Nobody currently owns this.
@dezren39 · 2026-09-30T11:06:07Z
Collision ownership (issues pass, 2026-09-30, at 05c78b2). #181 listed these cross-theme collisions with no owner. Each now has one:
script.*shipped, #81, #82, #112)pkgs/mcpx/docs/decisions/(in flight; linked here when it merges)repair.level, #112 hookeffect, #113prompt.mode: plan)pkgs/mcpx/docs/decisions/(in flight; linked here when it merges)ClampedBy-- a daemon ceiling a caller may lower but not raiseFrameordering contract, extended by #111 (call) and #112 (hook)docs/exec.md's order first and states the rule every new frame kind follows (declared placement relative toresult, listed in the documented order, asserted by a test that compares documented and emitted order). #112 adds its kind under that rule.Where this issue is the owner, the decision is made here; where it is not, it adopts the owner's decision rather than making its own.
@dezren39 · 2026-09-30T11:57:45Z
Issues pass (2026-09-30, at 05c78b2).
Parent: #176.script.before,script.prefix,script.onSuccess,script.onErrorandscript.suffix(internal/settings/registry.go:212-242,ScriptConfiginternal/config/config.go:236-257,runner.Phasesinternal/runner/runner.go:190-205). They inject source into the launcher.onErrorrethrows ("a hook, not a handler") andsuffixruns in afinally. They are CLI and config only;/v1/execdoes not carry them by design (internal/execsvc/execsvc.go:358-366). Approach B is therefore partly built already. The body says so and flags that B'sonError(may replace the result) differs from the shipped one (always rethrows).effectdefers to Bump checkmarx/ast-github-action from 2.0.19 to 2.0.23 #111's dial (collision 3), with Phase 5: who may clear a tag claim #185 as its ceiling (collision 5). Thehookframe is added under Bump checkmarx/ast-github-action from 2.0.19 to 2.0.23 #111's frame-order rule (collision 7). The design text is kept as input to those owners.Related:adds chore(deps): bump stefanzweifel/git-auto-commit-action from 4 to 5 #81, chore(deps): bump build/buck/preludes/buck2-prelude fromd956689to5f79ad1#82, Bump checkmarx/ast-github-action from 2.0.19 to 2.0.23 #111 and Phase 5: who may clear a tag claim #185, marks Bump openssl from 0.10.54 to 0.10.55 in /sources/pavex/examples/realworld #40 and Bump build/buck/preludes/buck2-prelude fromd956689to6f75473#41 as closed (fixed in chore(deps): bump build/buck/preludes/buck2-prelude fromd956689to677e9eb#57 and chore(deps): bump rustix from 0.38.3 to 0.38.21 in /build/nix/setup #58), and names siblings by number. Labeldesignadded.@dezren39 · 2026-09-30T16:58:17Z
Decided (SURFACES, 0001 and 0002, merged in #228).
What changes in this issue:
pre→before,post→onSuccess;mainis not a hook, it is/v1/intent.prePrompt/postPrompt/onErrorPromptare thepromptaction atbefore/onSuccess/onError.effecttakes the autonomy levels:transform→apply;script→run(orproposeto hand the script back);retry→run; aprehook that refuses isask.script.hooksbecomes entries of the onehookssetting withon: script.result/error; suffix after it.mcpx execaccepts--before/--on-success/--on-errorand drops them; a top-level throw skipsonErrorandsuffixbecause the import sits outside the launcher'stry; no phase reaches/v1/execor--remote.@dezren39 · 2026-09-30T19:35:58Z
Follow-up: two of the three phase holes named in the decision comment are closed in #265 --
mcpx execnow runs--before/--on-success/--on-error(andscript.before/onSuccess/onError), and a top-level throw runsonErrorandsuffix(the import moved inside the launcher'stry). The third, phases on/v1/execand--remote, is #192. #265 also fixedmcpx exec --remotelosing its output.@dezren39 · 2026-10-28T22:22:42Z
Triage verdict (task 2154, repo-health-nix-pilot): PARTIALLY LANDED + CONFIRMED remainder, RELOCATED — deterministic script phases are now on the wire; prompt hooks (the actual ask) are unimplemented. Implementation routes in developing-today/code; no fix packet in this repo.
Verified against current main on both sides (nix
224c7b738e88c7a8e5d406987a7d88257e229db2, coded2cb60fe8e08cd6fee149b930187b610299c1fa7):enhancement,design— no hard-stop labels. Parent tracker Nix Playwright E2E suite fails after vendoring dependencies #176 is OPEN.pkgs/mcpxat HEAD; the extraction plan (planning/plans/mcpx-extraction.md, steps 4–5, lab-ops-hub container crawler accepts inet_aton IPv4 spellings (127.1, 2130706433, 0x7f.1) — loopback SSRF bypass in validate_crawl_url #468) records the build switch and deletion done 2026-10-19, and this repo now only builds mcpx from the pinned code rev.execsvc.Optionsnow carriesPhases *Phases(pkgs/mcpx/internal/execsvc/execsvc.go, wire struct) withbefore/prefix/onSuccess/onError/suffixsource lines, and the comment records why: "Before Phase 4 fix: a joiner fetches the epoch it missed #192 a remotemcpx execparsed every one of these and sent none, so the daemon ran a different program from the one asked for." Per-call script hooks over/v1therefore exist; thescript.before/script.onErrorsettings family is still registered for the CLI (internal/settings/registry.go:291,309).Optionshas noprePrompt/postPrompt/onErrorPrompt/onSuccessPromptfields and no declared prompt-hook list with a declared effect — the fields areRuntime…Exportplus the program-shaping group (TypeCheck,Launcher,AllowRepeat,CaptureConsole,Phases), all deterministic source, no natural-language hook anywhere inexecsvcorinternal/api/ops_exec.go. Prompt hooks also depend on Bump build/buck/preludes/buck2-prelude fromd956689to52604b1#110's unsettled question of where a model comes from, so they cannot land before that design does.Route: no
small_fixpacket in dezren39/nix — this repo holds no mcpx source to fix. The remainder (one declared hook list unifying the scriptPhasesvocabulary with prompt hooks, gated on #110) belongs with the source in developing-today/code, referencing #112, via the #309 relocation pass; per the cross-repo rule, do not re-file it there. #112 stays open on the nix side until implemented there or transferred.dezren39 commentedon Oct 29, 2026
🤖 Agent note · picked up
dezren39 commentedon Oct 29, 2026
Triage verdict — task 2825 (2026-10-29)
Scope confirmed against current
pkgs/mcpxmain (verified viagh apion current main, 2026-10-29):execsvc.Options(pkgs/mcpx/internal/execsvc/execsvc.go, ~:101) still has no hooks or prompt fields — noHooks,Prompt,PrePrompt, orPostPrompt. The issue's premise holds unchanged.script.before,script.prefix,script.onSuccess,script.onError,script.suffix(pkgs/mcpx/internal/settings/registry.go:291-317), layered throughScriptConfigand not on the wireOptions.Dedupe — not a duplicate. Searched open code issues for mcpx hooks: #1872 (config-declared hooks over the event bus) and #1873 (privileged plugin surface / runtime hook registration) are the sibling scopes #1929 itself names as separate vocabularies — neither covers a per-call hooks list on
ExecOptions. Trackers #1885, #1891, #1900 aggregate related work but do not cover this. No closure, no duplicate link needed.Split, per the issue's own recommendation ("the deterministic half is independently valuable and ships first"):
hookslist onexecsvc.Options({phase, script}; phases pre/main/post/onError/onSuccess adopting the shippedscript.*semantics), typed hook context (run id, result/error + diagnostic, artifacts), same runtime/permissions as the wrapped script, config layering append/nearest-wins likeScriptConfig.Prefix, and hook frames placed per thedocs/exec.mdstream-order contract. Verification for the follow-up:pkgs/mcpx: go test ./...via CI, including tests for pre/post/onError execution and frame placement.This issue stays open as the tracker for both halves.
dezren39 commentedon Oct 29, 2026
🤖 Agent note · done
62 remaining items
dezren39 commentedon Nov 3, 2026
agent-note:v1
state: triaged (coverage pass)
Coverage pass 2026-11-03: reviewed in the fleet-wide per-issue pass (drift / overlap / already-handled / stale / blockers / ordering). Verdict: still live; queued in repo-health-code-pilot as triage at priority 30 (priority/none). If this is already handled at current main, the triage closes it with evidence; if it needs splitting, the triage files the split.
Found via: coverage pass 2026-11-03
dezren39 commentedon Nov 4, 2026
agent-note:v1
task: 8728
queue: repo-health-code-pilot
worker: repo-worker-code
lane: openchamber-scheduled-lane
lane_id: c29174f1-48e0-4b13-b4ff-9b73ab67e9ab
event: picked_up
at: 2026-11-04T04:04:22Z
Picked up triage task 8728 for #1929. Fresh GitHub state: issue OPEN; no open PR found by searching for #1929; no held/user-owned/do-not-merge/do-not-auto-edit labels. Scope is triage only, no implementation. Verification will use a dedicated worktree based on freshly fetched origin/main
eb362463a; the primary clone has diverged local history, so it was preserved rather than rewritten.Branch:
queue/8728-1929-lifecycle-hooks-triage· worktree:/home/user/git/fleet/8728-1929-lifecycle-hooks-triage.dezren39 commentedon Nov 4, 2026
🤖 Agent note · done — triaged and routed (task 8728)
c29174f1-48e0-4b13-b4ff-9b73ab67e9ab1fb0ae473caf5aedd12f0374be5c0d488808fcde). The prompt-action half is still missing: currentexecsvc.Hookonly accepts scripts, and its implementation explicitly says promptrun/askeffects are not implemented.internal/model.Providerlayer and cross-provider profiles are on main (mcpx: thin provider layer core — internal/model, model.* settings, intent routing (#1925 slice 1) #2592, mcpx: provider-keyed model settings and model profiles (#1925 slice 2) #4836), and the accepted hook vocabulary/autonomy decisions (0001/0002) plus settings clamps are implemented.#1925remains open only for its plugin-provider remainder; that backend is not needed when using an already-configured provider.effect: advise, using data-safe placeholders and deterministic fallback), and enqueued implementation task 9174. The old fix task 3224 for mcpx: lifecycle hooks on exec — prePrompt/postPrompt/onError as one declared list, script or prompt, with a declared effect #1929 is already done and owns that issue dedupe key, so the child issue avoids a terminal dedupe hit. Remaining prompt effects and plugin provider are explicitly deferred.eb362463a5d4295d96564563da11f44970763fb1; mcpx: lifecycle hooks on exec — prePrompt/postPrompt/onError as one declared list, script or prompt, with a declared effect #1929 open, PR feat(mcpx): per-call script hooks on exec — one hooks list on execsvc.Options (#1929) #2616 merged; no open PR or other active queued/claimed/parked/blocked task for this remainder at triage time.