You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
mcpx: elicitation storage is readable by any local user and never pruned; elicitation UI and response validation rows #1954
Relocated from dezren39/darwin-nix#255 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).
Gap keys elicit-storage (5 rows), elicit-ui (7), elicit-validation (4) in docs/spec/conformance-matrix.md: the question broker's store is not permission-restricted and grows without pruning; the CLI/TUI answering surface does not show which server asks / allow review per the elicitation UI SHOULDs; accepted content is not validated against requestedSchema before relaying upstream.
Acceptance criteria
The elicitation broker store is permission-restricted to the owner (no world/group read) and this is verified on disk.
Stored elicitations are pruned (age or count bound, documented).
The answering surface shows which server is asking and allows review per the elicitation UI rows.
Accepted content is validated against requestedSchema before being relayed upstream.
Related: the 2026-09-30 mcpx conformance set — parent analysis #252, siblings #253, #254, #255, #256, #257, #258, #259 (filed together from docs/spec/conformance-matrix.md in dezren39/nix). Treat the set as one body of work; do not re-file per-gap issues.
Notes: Filed as kind/security at priority normal (monitor judgment): the storage half (readable by any local user, never pruned) is a genuine local information-exposure issue, distinct from the UI/validation conformance rows bundled with it. 16 rows total (storage 5, UI 7, validation 4).
Risks: Permission tightening that breaks the broker's own readers — verify the daemon and CLI still read the store after the change.
Suggested approach: storage permissions + pruning first (the security substance), then schema validation, then UI rows.
agent-note:v1
event: done
task: 3250 (repo-health-code-pilot, lane D) — completed, outcome pr_opened
pr: #2646
state: Criterion 1 (pruning) verified ALREADY DONE on main via #1677 — pruneTerminal on Broker.Open, bounds in internal/defaults (ElicitRetentionMaxAge / ElicitRetentionMaxTerminalRows), tests in internal/elicit/prune_test.go; no change made. Criterion 2 implemented in PR 2646 @ a9cc5f4: Broker.Respond validates accepted form content against the question's requestedSchema (internal/schemaval) before recording/relay; mismatch refused with failing paths, question stays pending; uncompilable schema recorded unvalidated (asker's defect, mirroring mcpclient). Laptop: full internal/elicit tests pass, vet clean. Remaining: CI green on PR 2646 + merge (fleet CI jam permitting); criterion 3 (elicitation UI rows) stays on this issue.
The review-first elicit surface from #1678 has landed as PR #3011:
URL questions now print the registrable domain under the full URL, with both host forms + a punycode warning for xn--/non-ASCII hosts.
Form questions carry schema defaults in the field detail and the answer example.
Interactive mcpx elicit answer renders the parsed answer back — credential-shaped values masked as set/not set via the shared elicit.IsSensitiveField — and relays only on confirmation (--yes / non-interactive behaviour unchanged).
Remaining slice for this issue: server-relay validation of received elicitation data — elicitation-server-validate-received-data — i.e. the receiving/relay side validating answers, beyond the client surface above. (Broker-side validation of accepted form answers against the requested schema is tracked separately on this issue's PR #2646.) This comment is evidence only; #1954 stays open for that remaining slice.
Pruning — internal/elicit/elicit.go prunes terminal rows on open against the elicit.ttl / elicit.maxAge bounds (pruneTerminal, deadline = min(lastTouched+ttl, created+maxAge)); TestOpenPrunesTerminalRowsPastTheAgeBound pins it (phase mcpx: Phase 2 of #1675 — broker retention bound + summary-only elicitation events #1677, closed; events are summary-only too).
Answering surface shows the asking server + review — the mcpx elicit list line prints r.Server and the detail view prints from <server>; the review-first surface renders schema defaults, the registrable domain, a punycode warning, and a masked confirm-before-relay (TestRenderAnswerReviewMasksSensitiveFields, TestRenderQuestionFormShowsSchemaDefaults, TestRenderQuestionURLShowsRegistrableDomain, TestRenderQuestionURLWarnsOnPunycodeHost) (phase mcpx: Phase 3 of #1675 — review-first mcpx elicit surface + nix#255 truth-up #1678, closed).
Schema validation before relay — internal/mcpclient rejects wrong-typed answers with 32602 instead of relaying them (TestElicitationAnswersValidatedAgainstRequestedSchema), backed by internal/schemaval.
Tests run this pass (pkgs/mcpx):go test ./internal/elicit/ → ok (7.3s); go test ./internal/cli/ -run 'TestRenderQuestion|TestRenderAnswerReview' → ok; go test ./internal/mcpclient/ -run TestElicitationAnswersValidatedAgainstRequestedSchema → ok. The conformance matrix maps each of these rows to those tests.
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 40 (priority/normal). 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
Activity
developing-today commentedon Oct 28, 2026
CODE-879
dezren39 commentedon Oct 28, 2026
History carried over from dezren39/darwin-nix#255 (verbatim, oldest first):
@dezren39 · 2026-10-27T15:35:54Z
Intake review
Fleet monitor intake pass, 2026-10-27 (repo-fleet-monitor).
Related: the 2026-09-30 mcpx conformance set — parent analysis #252, siblings #253, #254, #255, #256, #257, #258, #259 (filed together from
docs/spec/conformance-matrix.mdin dezren39/nix). Treat the set as one body of work; do not re-file per-gap issues.Notes: Filed as kind/security at priority normal (monitor judgment): the storage half (readable by any local user, never pruned) is a genuine local information-exposure issue, distinct from the UI/validation conformance rows bundled with it. 16 rows total (storage 5, UI 7, validation 4).
Risks: Permission tightening that breaks the broker's own readers — verify the daemon and CLI still read the store after the change.
Suggested approach: storage permissions + pruning first (the security substance), then schema validation, then UI rows.
17 remaining items
dezren39 commentedon Oct 30, 2026
agent-note:v1
event: done
task: 3250 (repo-health-code-pilot, lane D) — completed, outcome pr_opened
pr: #2646
state: Criterion 1 (pruning) verified ALREADY DONE on main via #1677 — pruneTerminal on Broker.Open, bounds in internal/defaults (ElicitRetentionMaxAge / ElicitRetentionMaxTerminalRows), tests in internal/elicit/prune_test.go; no change made. Criterion 2 implemented in PR 2646 @ a9cc5f4: Broker.Respond validates accepted form content against the question's requestedSchema (internal/schemaval) before recording/relay; mismatch refused with failing paths, question stays pending; uncompilable schema recorded unvalidated (asker's defect, mirroring mcpclient). Laptop: full internal/elicit tests pass, vet clean. Remaining: CI green on PR 2646 + merge (fleet CI jam permitting); criterion 3 (elicitation UI rows) stays on this issue.
dezren39 commentedon Oct 31, 2026
🤖 Agent note · #1678 Phase 3 evidence (queue task 3662)
The review-first elicit surface from #1678 has landed as PR #3011:
xn--/non-ASCII hosts.mcpx elicit answerrenders the parsed answer back — credential-shaped values masked as set/not set via the sharedelicit.IsSensitiveField— and relays only on confirmation (--yes/ non-interactive behaviour unchanged).Remaining slice for this issue: server-relay validation of received elicitation data —
elicitation-server-validate-received-data— i.e. the receiving/relay side validating answers, beyond the client surface above. (Broker-side validation of accepted form answers against the requested schema is tracked separately on this issue's PR #2646.) This comment is evidence only; #1954 stays open for that remaining slice.dezren39 commentedon Nov 3, 2026
🤖 Agent note · done (triaged → already implemented; closing with evidence)
pkgs/mcpx; nothing is left of the three gap keys (elicit-storage,elicit-ui,elicit-validation). The work landed as the three phases of design(mcpx): elicitation broker hygiene — owner-only store, bounded retention, redacted events, review-first answering #1675, and mcpx: Phase 3 of #1675 — review-first mcpx elicit surface + nix#255 truth-up #1678 explicitly carried this issue'snix#255tracking.e438032cd, 2026-11-03):internal/elicit/store.gosetsstoreFileMode = 0o600and creates the directory 0700, chmod-if-looser;TestOpenAtCreatesOwnerOnlyStoreasserts 0700/0600 on disk (phase mcpx: Phase 1 of #1675 — owner-only elicitation broker store (0700 dir, 0600 files, migration on open) #1676, closed).internal/elicit/elicit.goprunes terminal rows on open against theelicit.ttl/elicit.maxAgebounds (pruneTerminal, deadline = min(lastTouched+ttl, created+maxAge));TestOpenPrunesTerminalRowsPastTheAgeBoundpins it (phase mcpx: Phase 2 of #1675 — broker retention bound + summary-only elicitation events #1677, closed; events are summary-only too).mcpx elicitlist line printsr.Serverand the detail view printsfrom <server>; the review-first surface renders schema defaults, the registrable domain, a punycode warning, and a masked confirm-before-relay (TestRenderAnswerReviewMasksSensitiveFields,TestRenderQuestionFormShowsSchemaDefaults,TestRenderQuestionURLShowsRegistrableDomain,TestRenderQuestionURLWarnsOnPunycodeHost) (phase mcpx: Phase 3 of #1675 — review-first mcpx elicit surface + nix#255 truth-up #1678, closed).internal/mcpclientrejects wrong-typed answers with 32602 instead of relaying them (TestElicitationAnswersValidatedAgainstRequestedSchema), backed byinternal/schemaval.pkgs/mcpx):go test ./internal/elicit/→ ok (7.3s);go test ./internal/cli/ -run 'TestRenderQuestion|TestRenderAnswerReview'→ ok;go test ./internal/mcpclient/ -run TestElicitationAnswersValidatedAgainstRequestedSchema→ ok. The conformance matrix maps each of these rows to those tests.status/needs-triageandqueue/queued.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 40 (priority/normal). 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