Repository navigation
Description
Relocated from dezren39/darwin-nix#176 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: #181
Purpose
Everything in mcpx that would use a model, plus the search that should not.
Nine issues: better tool search, a provider layer mcpx owns, a graded
check/refuse/repair ladder, lifecycle hooks on exec, administration by intent,
composed tool views and generated tool sets, and the servers-and-feedback loop —
plus two small design issues split out because three of the others were each
about to build the same thing: one near-miss matcher (#186) and one settings
ceiling (#185).
The finding that shapes the whole tracker is that every one of these has a
deterministic lower half that ships without a model and a model-backed upper
half that does not — and in every case the deterministic half is the larger
share of the value. Tags and word-splitting beat embeddings on a catalogue of a
few hundred short identifiers; a schema-change diagnostic beats a model
rewording it; toolViews.from answers the tailscale request outright; /v1/stats
already measures the thing "this server is slow, host it locally" is about. So
the order is: build every deterministic half first, then #110, then the model
halves. #110 is not first despite being the dependency, because nothing above it
is blocked on it until the deterministic work is done. Its decision is another
matter: choosing Approach C (a thin Provider interface) and correcting
docs/consumer.md's "should not be built" sentence is cheap and can be taken
early, which is why #181 places #110 in its design phase.
Children
- Phase 4: held application messages need a bound #186 mcpx: one definition of 'close' -- a shared near-miss matcher for search, diagnostics and launcher placeholders — first: S and deterministic; Bump build/buck/preludes/buck2-prelude from
d956689tod460fcc#109's typo tolerance and Bump checkmarx/ast-github-action from 2.0.19 to 2.0.23 #111's rung 1 both call it, and the two matchers already shipped disagree on transpositions. - Bump build/buck/preludes/buck2-prelude from
d956689tod460fcc#109 mcpx: better tool search — tags, word-splitting, typo tolerance, synonyms, and what 'natural language' would actually cost — second, beside Bump checkmarx/ast-github-action from 2.0.19 to 2.0.23 #111: entirely deterministic,--explainand tags are S, typo tolerance calls Phase 4: held application messages need a bound #186. - Bump checkmarx/ast-github-action from 2.0.19 to 2.0.23 #111 mcpx: checking, refusing and repairing a request — a graded ladder from deterministic diagnostics to rewrite-and-run — second, beside Bump build/buck/preludes/buck2-prelude from
d956689tod460fcc#109:callframes, the frame-order rule and rung 1 are S and need no model; rung 0 is chore(deps): update github.com/developing-today-forks/charm digest to 15e844d - autoclosed #116 (in flight, not a child); it carries the one autonomy-dial vocabulary Update module gopkg.in/go-jose/go-jose.v2 to v2.6.3 [SECURITY] - autoclosed #112 and Update module github.com/jackc/pgx/v5 to v5.5.4 [SECURITY] - autoclosed #113 adopt. - Phase 5: who may clear a tag claim #185 mcpx settings: a ceiling the daemon sets and a caller may lower but not raise (ClampedBy) — third, with the dial decision: must be designed before any dial ships in Bump checkmarx/ast-github-action from 2.0.19 to 2.0.23 #111, Update module gopkg.in/go-jose/go-jose.v2 to v2.6.3 [SECURITY] - autoclosed #112 or Update module github.com/jackc/pgx/v5 to v5.5.4 [SECURITY] - autoclosed #113.
- Update checkmarx/ast-github-action digest to 6c56658 - autoclosed #114 mcpx: tool views and composed tool sets — rename/pin/hide, cross-server namespaces, script-backed tools, and generators that emit declarations — fourth:
toolViews.from/pin/hideis S–M and unblocks the concrete tailscale request; script-backed tools make recipes first-class with no model at all, on chore(deps): bump build/buck/preludes/buck2-prelude fromd956689to36464cf#83's tool-source rules. - Update github.com/charmbracelet/promwish digest to 6c16e8f - autoclosed #115 mcpx: Dropbox/Drive/Outlook/Tailscale, and a feedback loop built from evidence mcpx already collects — fourth, beside Update checkmarx/ast-github-action digest to 6c56658 - autoclosed #114: richer registry metadata and the four adapter declarations are S (its registry-dedup item is struck — mcpx never had duplicates, Phase 3: /id-sync/1 is used by both range and LogSync handshakes #179), and the doctor recommendation is built purely from
/v1/statsdata that already flows. - Bump build/buck/preludes/buck2-prelude from
d956689to52604b1#110 mcpx: where the model comes from — a provider layer mcpx owns, model profiles, and life after MCP Sampling's deprecation — fifth to build (decide early): the gate every model-backed rung above waits on, and the answer to Sampling being deprecated in MCP 2026-07-28. - Update module gopkg.in/go-jose/go-jose.v2 to v2.6.3 [SECURITY] - autoclosed #112 mcpx: lifecycle hooks on exec — prePrompt/postPrompt/onError as one declared list, script or prompt, with a declared effect — sixth: much of its deterministic half already ships as
script.*launcher phases; per-call hooks follow the hook vocabulary (chore(deps): bump stefanzweifel/git-auto-commit-action from 4 to 5 #81's decision record) and Bump checkmarx/ast-github-action from 2.0.19 to 2.0.23 #111's frame rule; prompt hooks need Bump build/buck/preludes/buck2-prelude fromd956689to52604b1#110. - Update module github.com/jackc/pgx/v5 to v5.5.4 [SECURITY] - autoclosed #113 mcpx: administration by intent — finish the operation surface, then route a sentence to a declared operation — last: hard-blocked on Update Rust crate clap to 4.5.4 - autoclosed #76 (in flight); the router's entire vocabulary is the ops table, and its model is Bump build/buck/preludes/buck2-prelude from
d956689to52604b1#110's.
#181 collisions that touch this tracker
| Row | Collision | Owner | Here |
|---|---|---|---|
| 2 | four hook vocabularies | #81 (#173), via a decision record SURFACES is writing under pkgs/mcpx/docs/decisions/ (in flight) |
#112 adopts it; its phase names are input |
| 3 | three autonomy dials | #111, via a decision record SURFACES is writing under pkgs/mcpx/docs/decisions/ (in flight) |
#112's effect and #113's prompt.mode: plan adopt it |
| 4 | namespacing and collision rules | #83 (#173) | #114's views, virtual namespaces and script-backed tools build on it |
| 5 | ClampedBy |
#185 | #111, #112, #113 consume it |
| 6 | the near-miss matcher | #186 | #109 and #111 call it |
| 7 | the exec frame-order rule | #111 | #112 adds its hook frame under it |
Proposed order
Phase 1 — the free wins, in parallel. #186 first: one normalisation,
distance and threshold, replacing the two that exist
(internal/diagnose/diagnose.go:417-455, internal/launcher/template.go:341-381,
which disagree on transpositions). Then #109's --explain → tags →
normalisation/stemming → typo tolerance, and #111's first items: a call frame
type in the exec stream under the frame-order rule #111 owns (docs/exec.md:137),
and rung 1 near-miss detection. Note rung 1 needs two signals, not one: #186's
closeness for typos, and argument-shape fit for the note's own example —
search→query is edit distance 5, so no typo threshold finds it. Rung 0,
wiring diagnose.CallError, is #116 in the cross-cutting tracker (#177), in
flight with SURFACES; at 05c78b2 it still has no caller outside tests
(internal/diagnose/diagnose.go:483). When it lands, the structured diagnostic
it attaches is the shape #111's rungs read.
Phase 2 — the vocabulary, before any dial is implemented. #111's
repair.level (off | explain | confirm | propose | retry | rewrite) is the
same dial as #112's hook effect (advise | transform | script | retry) and
#113's prompt.mode: plan. Three children independently invented a
policy-with-named-stops. It is decided once, in the autonomy-dial decision
record SURFACES is writing under pkgs/mcpx/docs/decisions/, and carried by
#111; #112 and #113 adopt it. The floor/ceiling clamping (the daemon sets the
maximum autonomy, a caller may lower it and never raise it) is #185 — a
settings-registry feature, not an auth feature. Both precede #111's rungs 2–6,
#112's effects and #113's plan mode. The hook vocabulary (#81's decision
record) likewise precedes #112's per-call hooks.
Phase 3 — #114 and #115, in parallel, both deterministic. #114's view layer
(from, pin, hide) is the one-field change that answers the tailscale
request; script-backed tools are the highest-value missing piece and need no
model. Both sit on #83's tool-source interface, which owns namespaces and
collision rules — script-backed tools are #83's first ship step, recipes as
tools. #115's richer search metadata and the four example declarations are S
(its registry-dedup item is struck: mcpx pins version=latest,
internal/registry/registry.go:158, and never sees duplicates — #179), and
#115 concludes that an adapter spec over the local tailscale CLI is a better
answer than any third-party server — which makes #115 a consumer of #114's
generators and a proof of them. Both also want #109's tags (#115's miss log and
#109's failed-search record are the same record).
Phase 4 — #110. By now the deterministic halves are shipped and it is clear
exactly which five jobs want a model: query expansion (#109 rung 7), explain and
propose (#111 rungs 2–6), prompt hooks (#112), operation routing (#113), and
spec generation (#114). That is five one-shot completions, which is the evidence
for #110's Approach C (a thin Provider interface mcpx owns) over its Approach
B (a Go agent framework) — none of the five is an agent loop.
Phase 5 — #112's prompt half, then #113's router. #112 is the smaller of the
two and its pre/post/onError hooks exercise the provider layer at low
blast radius. #113 comes last because its Approach B (session operations,
force-detach, resume, mcpx install) depends on #76 and on settling what a
session even is (#6, #78), and its router cannot be better than the operation
surface it routes to.
Explicitly deferred, from #113 itself: arbitrary provisioning ("install any
language/tool/framework/library, clone whatever repo" by prompt) is the only
genuinely agentic operation in the theme and #113 defers it pending a
confinement answer. The declared-dependency and managed-provisioning rungs
below it belong with the runtimes-and-dependencies tracker (#103, #104), not
here.
Ease / impact
| Issue | Ease | Impact | Note |
|---|---|---|---|
| #186 | S | med | one definition of "close" for search, diagnostics and the launcher; fixing a false positive once fixes it everywhere |
| #109 | M (S for tags + typos alone; M for the full lexical ladder; L if the semantic rung is included) | high | "search is the entry point to zero-context discovery, and a miss there costs an agent a full catalogue load" |
| #111 | L overall; the first two items (wire diagnose.CallError — now #116's, in flight — and add call frames) are S and should ship independently of everything else here |
high | "the difference between 'it failed' and 'here is what worked, here is exactly what was wrong, here is the one-line fix'" |
| #185 | M | med (high once #111, #112 or #113 implements a dial) | one clamp in the resolver instead of one per dial |
| #114 | L overall; the tailscale-unblocking toolViews.from/pin/hide is S–M, script-backed tools M, virtual cross-server namespaces M–L, spec generation L |
high | "turns mcpx from a router into a place where a personal tool surface is composed, and script-backed tools alone make recipes first-class" |
| #115 | M (S for richer metadata + the four example declarations — registry dedup struck, see #179; M for mcpx registry add end-to-end and the doctor recommendation; M for the feedback/miss store) |
medium-high | "the doctor recommendation and the miss log are the parts that keep paying; the four servers are a day's config each once adapters are the route" |
| #110 | L (M for the Provider interface + one provider + settings; L including profiles, plugin backend and local sampling answers; XL if mcpx-as-an-OpenAI-proxy is in scope — it should not be, split it) |
high | "every other issue in this theme depends on where the model comes from" |
| #112 | 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) |
medium-high | "what makes one script file portable across environments without the script knowing where it runs, which is the same goal #40 had for artifacts" |
| #113 | L overall; the session/detach operations are M, the prompt-routing layer is M given /v1/intent exists, mcpx install is M, and provisioning is L–XL and should be split out |
medium-high | "mostly it makes an existing surface reachable by people who do not have the ops table memorised, which is the actual complaint" |
Warnings
- MCP Sampling is deprecated, and mcpx's own documentation recommends the
opposite of the spec's migration. Revision2026-07-28deprecates Roots,
Sampling and Logging (SEP-2577) and names the migration explicitly:
integrate directly with LLM provider APIs instead of Sampling.
pkgs/mcpx/docs/consumer.md:195-196says a configured provider with an API
key "was not built and should not be. It is the one that makes mcpx an agent."
That conclusion is now inverted by the spec it was reasoning from. Bump build/buck/preludes/buck2-prelude fromd956689to52604b1#110 must
be read with this in mind, and the doc sentence must be corrected in the same
change — otherwise the repo keeps an authoritative-sounding recommendation the
protocol contradicts, which is exactly the Root flake check fails on nixosConfigurations due to missing clan-core.clanModules #159 class. - mcpx's only existing model path cannot be answered by its primary
consumer. Neither opencode v1 nor v2 declares thesamplingcapability
(docs/opencode-plugin.md§2.6 — v1 comments it out, v2 declaresroots+
elicitation).prompt.sampledefaults tonever
(internal/settings/consumer.go:105), so today this is invisible rather than
broken; it becomes visible the moment anyone sets it toask. Any plan that
treats sampling as the long-term channel is planning on a dead one. The
upstream direction has the same gap: the daemon always installs its broker
hook (internal/daemon/hooks.go:69), so it declaressamplingto every
upstream server (internal/mcpclient/modern.go:46-57) whether or not any
caller can answer. - chore(deps): update github.com/developing-today-forks/charm digest to 15e844d - autoclosed #116 is rung 0 of Bump checkmarx/ast-github-action from 2.0.19 to 2.0.23 #111, it is S, and it is not a child here.
diagnose.CallError(internal/diagnose/diagnose.go:483) is built, tested
and, at 05c78b2, called by nothing outside tests. chore(deps): update github.com/developing-today-forks/charm digest to 15e844d - autoclosed #116 wires it at the
daemon's call boundary and is in flight with SURFACES; it improves/v1/call,
MCPtools/calland scripts at once. It belongs to the cross-cutting tracker
(feat(nix): Android SDK + JDK 21 in the system and dev shells, and the OpenChamber release signing key #177). chore(deps): update github.com/developing-today-forks/charm digest to 15e844d - autoclosed #116 is choosing the structured-diagnostic shape as it lands; Bump checkmarx/ast-github-action from 2.0.19 to 2.0.23 #111's
rungs read that shape rather than defining another. - Three children independently invented the same dial.
repair.level
(Bump checkmarx/ast-github-action from 2.0.19 to 2.0.23 #111), hookeffect(Update module gopkg.in/go-jose/go-jose.v2 to v2.6.3 [SECURITY] - autoclosed #112),prompt.mode: plan(Update module github.com/jackc/pgx/v5 to v5.5.4 [SECURITY] - autoclosed #113). Shipping all three
means a user learns three vocabularies for one concept: how much autonomy is
mcpx allowed here. Owned: Bump checkmarx/ast-github-action from 2.0.19 to 2.0.23 #111 carries it, decided in SURFACES's decision
record (Phase 3: sync, blob gate, and relays #181 collision 3); the ceiling is Phase 5: who may clear a tag claim #185 (collision 5). - Update module github.com/jackc/pgx/v5 to v5.5.4 [SECURITY] - autoclosed #113 is hard-blocked on Update Rust crate clap to 4.5.4 - autoclosed #76. The router's entire vocabulary is the ops
table. Routing a sentence to operations that have no CLI command produces a
capability reachable by prose and not by hand — the inverse of the parity rule
the repo enforces withinternal/api/parity_test.go. Update Rust crate clap to 4.5.4 - autoclosed #76 is in flight with
SURFACES. The op annotations Update module github.com/jackc/pgx/v5 to v5.5.4 [SECURITY] - autoclosed #113's confirmation gate needs mostly exist
already:Op.Admin/Mutating/Destructive(internal/api/ops.go:59-67)
map to MCPreadOnlyHint/destructiveHint(:654-667); what remains is an
audit of which operations carry them. - Update github.com/charmbracelet/promwish digest to 6c16e8f - autoclosed #115's registry dedup was a false premise and is struck. An earlier
version of this tracker saidinternal/registryreturns the same package up
to nine times across versions. It does not:Searchpinsversion=latest
on every query (internal/registry/registry.go:158) and five live searches
returned all-distinct names. The duplicates came from querying the raw API
without the pin, which mcpx never does. The real registry gaps — an
unreachableregistry.pageSizeand a droppednextCursor— are Phase 3: /id-sync/1 is used by both range and LogSync handshakes #179's. - The scope guard needs to be a review item, not prose in one issue. Bump build/buck/preludes/buck2-prelude from
d956689to52604b1#110
states it: no mcpx operation may call a model on a path where a deterministic
answer exists — diagnostics before repair, recipe matching before generation,
lexical search before query expansion. It is the only thing keeping this
tracker from being "make mcpx an agent", and it is currently a sentence inside
the issue most likely to be read last. Every child should be reviewable
against "what happens when the provider returns an error", with the answer
always "the deterministic result, plus a sentence saying the model was
unavailable." - Tool renaming (Update checkmarx/ast-github-action digest to 6c56658 - autoclosed #114) collides with everything that keys on a tool name.
codegen.ToolFuncName,catalog-history.json,internal/diagnose's
namespace filter and Bump checkmarx/ast-github-action from 2.0.19 to 2.0.23 #111's diagnostics all key on names. A view must show its
own name and record the target's, and those two must never be confused — or
Bump checkmarx/ast-github-action from 2.0.19 to 2.0.23 #111's schema-change diagnostics start naming tools the caller has never heard
of. The namespace and collision rules themselves are chore(deps): bump build/buck/preludes/buck2-prelude fromd956689to36464cf#83's (Phase 3: sync, blob gate, and relays #181 collision 4). - Bump build/buck/preludes/buck2-prelude from
d956689tod460fcc#109 warns against the obvious first move and it is worth repeating here.
Embedding search over the tool catalogue is the highest-cost, lowest-ratio
rung: it needs a model, a cache keyed on the catalogue fingerprint (the
cacheVersiontrap indocs/consumer.mdis a live source of silent
wrongness), and it gives up determinism on a command people put in scripts,
over a corpus of a few hundred short identifiers where the problem is
vocabulary and not semantics. - Update module gopkg.in/go-jose/go-jose.v2 to v2.6.3 [SECURITY] - autoclosed #112's
prehook witheffect: scriptis an execution back door if the
effect declaration is not enforced. "Make sure these dependencies exist
where the job runs", resolved by a general agent, means installing packages —
which is Update module github.com/jackc/pgx/v5 to v5.5.4 [SECURITY] - autoclosed #113's deferred provisioning problem arriving through a convenience
option. A hook must never be able to do what the script it wraps could not;
Options.Permissionshas to be inherited unchanged.
Related
Related: #177 (cross-cutting: a promise and a behaviour that disagree), #173 (extensibility), #174 (surfaces). #116 (diagnose.CallError built, tested, never called — rung 0 of
#111, in flight, claimed by the cross-cutting "a promise and a behaviour that disagree"
tracker, referenced here and not a child), #179 (registry search gaps; disproved
#115's dedup premise), #102 (an adapted binary is not script-callable — same
tracker, and the structural reason behind #83 which #114 builds on), #83
(tool sources, namespaces and collision rules — owner of #181 collision 4), #81
(hook vocabulary — owner of collision 2), #6 (event store — the home for #115's
miss records and #113's session resume), #40 (closed, fixed in #57: artifacts
and ExecOptions — the vehicle for #111's proposed scripts and the home for
#112's hooks; "not a new method, an option" is the governing precedent for this
whole tracker), #41 (closed, fixed in #58: diagnose, recipes, /v1/intent,
elicitation defaults — #109, #111, #112 and #113 are all direct continuations
of it), #47 (opencode v2 plugin — ctx.generate.text is one of #110's
backends), #48 (harness-free plugin core), #52 (closed, fixed in #182: e2e
daemons are now stopped via the info files and exit after 60 s idle), #76 (CLI
for /v1-only ops — a hard prerequisite for #113; in flight), #77 (protocol
follow-ups — error-code renumbering in 2026-07-28 affects #111's -32602
catch, and Sampling's deprecation belongs there too), #78 (daemon state and
cache correctness — the schema-cache trap already silently disabled the
destructive-call policy once), #79 (faster CLI and exec — search must stay
instant and hooks must not regress exec latency), #80–#88 (extensibility and
surfaces; #83 in particular is the design #114's script-backed tools and #102
both belong to), #159 (docs that contradict the code — docs/consumer.md's
provider recommendation is now an instance), #172 (undeclared MCPX_*
variables — every model.*, repair.* and hook setting proposed here must go
through the one registry).
Security/auth deferred; see tracker.
Activity
developing-today commentedon Oct 28, 2026
CODE-818
dezren39 commentedon Oct 28, 2026
History carried over from dezren39/darwin-nix#176 (verbatim, oldest first):
@dezren39 · 2026-09-30T11:57:54Z
Issues pass (2026-09-30, at 05c78b2).
Parent: #181(was "super tracker, to be linked"); agrees with the native parent.d956689tod460fcc#109 and Bump checkmarx/ast-github-action from 2.0.19 to 2.0.23 #111 both call one matcher. Phase 5: who may clear a tag claim #185 and the autonomy-dial decision record land before any dial ships in Bump checkmarx/ast-github-action from 2.0.19 to 2.0.23 #111, Update module gopkg.in/go-jose/go-jose.v2 to v2.6.3 [SECURITY] - autoclosed #112 or Update module github.com/jackc/pgx/v5 to v5.5.4 [SECURITY] - autoclosed #113. Bump build/buck/preludes/buck2-prelude fromd956689to52604b1#110's decision can be taken early, which reconciles this tracker with Phase 3: sync, blob gate, and relays #181 putting Bump build/buck/preludes/buck2-prelude fromd956689to52604b1#110 in its design phase.internal/registryreturns packages "up to nine times" is false (registry.go:158pinsversion=latest; Phase 3: /id-sync/1 is used by both range and LogSync handshakes #179), and Update github.com/charmbracelet/promwish digest to 6c16e8f - autoclosed #115's dedup item is struck. The claim that Update Rust crate clap to 4.5.4 - autoclosed #76 "owns the Destructive/Irreversible annotations" is wrong:Op.Admin/Mutating/Destructiveexist (internal/api/ops.go:59-67) and map to MCP hints (:654-667). chore(deps): bump build/buck/preludes/buck2-prelude fromd956689toe7457f6#52 is closed (fixed in Phase 5: tag event bodies must travel with the event #182). 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 are marked closed. TheCallErrorcitation is re-cited at 05c78b2 (diagnose.go:483), and chore(deps): update github.com/developing-today-forks/charm digest to 15e844d - autoclosed #116 is noted as in flight. Added that the daemon declaressamplingupstream unconditionally.script.*phases; dedup struck); the Bump checkmarx/ast-github-action from 2.0.19 to 2.0.23 #111 note saysCallErroris chore(deps): update github.com/developing-today-forks/charm digest to 15e844d - autoclosed #116's. Ratings are otherwise unchanged.dezren39 commentedon Oct 29, 2026
🤖 Agent note · picked up
14 remaining items
dezren39 commentedon Nov 3, 2026
🤖 Agent note · handed off
opencode; the laptop claimant launches the bound opencode session, which drives the triage to its terminal state. This lane does not work the task directly.dezren39 commentedon Nov 3, 2026
🤖 Agent note · handed off
handed_off— the laptop claimant launches the bound opencode session, which drives task 7777 to its terminal state.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