Repository navigation
Description
🤖 Agent note · design architect (repo-design-architect-code), pass 15, 2026-10-29
- Design doc:
files/designs/code-mcpx-completion-rate-limit-ranking.mdin the keep-the-four-repos-healthy goal workspace - Origin: the two remaining conformance gaps under mcpx: completion/complete over MCP ignores ref and never asks the upstream dezren39/darwin-nix#213 —
completion-securityandcompletion-server-shouldinpkgs/mcpx/internal/conformance/coverage_utilities.go:102-103. nix#213 itself is CLOSED in nix; its main bug (completion ignoring ref) has landed. No code-side origin issue exists for the remainder, so this design originates it. Audited against origin/main5a34fa70.
Summary
completion/complete is mcpx's cheapest-looking and most expensive request: every call acquires a pool lease and may wake an upstream process, and completion is the request a client sends once per keystroke. Nothing bounds that rate, and the one answer mcpx composes itself — the cached-names fallback for upstreams that never declared completions — comes back in alphabetical order with prefix-only matching, where the spec asks for relevance ranking and fuzzy matching where appropriate.
The design, in one paragraph: both surfaces converge on one handler — MCP completion/complete (internal/mcpserver/server.go:2573) delegates to mcpBackend.Complete (internal/cli/serve.go:992), which forwards via POST /v1/complete "so the two surfaces give the same answer", landing in the daemon's handleComplete (internal/daemon/ops.go:333). So: one fixed-window in-memory limiter at handleComplete, consulted after shape validation and before any pool acquisition (a refused request must never wake an upstream — that churn is the cost being limited), keyed per (caller, configured server name) + per server, settings completion.perMinute (default 120) / completion.serverPerMinute (default 600), 0 disables, count-on-admission; refusal is HTTP 429 on /v1 naming the limit, reaching MCP clients as a named -32603 (the #1834 expiry precedent). And relevance ranking for the local fallback only (localCompletion, ops.go:402): exact → prefix (shorter first) → substring tier; upstream answers pass through in upstream order untouched — the upstream owns relevance and its total/hasMore meaning.
Evidence highlights
- No rate-limit machinery exists anywhere in
pkgs/mcpx/internal(grep finds only the gap rows);handleCompletegoes straight from validation top.Complete(...)(ops.go:367) → pool lease (internal/pool/request.go:60). localCompletionmatches withhasPrefixFold(case-insensitive prefix,ops.go:590) over pool-cached prompts sorted by name (internal/pool/pool.go:915) — the register's "sorted alphabetically" is exact; its "matched by substring" is stale (prefix-only is the opposite failure: mid-name typing finds nothing). Phase 3 corrects the wording.- Input validation (the other clause of both spec rows) already exists at both layers — not part of the remaining gap.
- Settings precedent:
completion.maxValuesalready lives in thecompletion.*namespace (internal/settings/wire.go:185).
Phases
- Phase 1 — rate limit at the choke point: limiter + settings +
handleCompleteintegration before pool acquisition + refusal shapes + tests. (Filed as a sub-issue.) - Phase 2 — relevance-ranked local completion: tiered ranking + substring tier in
localCompletion; upstream pass-through untouched. Independent of Phase 1. (Filed as a sub-issue.) - Phase 3 — register truth-up: retire both gap rows (the security row goes to partial with the principals dependency recorded — per-caller access control waits on mcpx: a principal per surface and a permission per operation, declared permissively #1968/mcpx: the permissive auth interface authorizes everyone — real validation for the conformance rows that require refusal #1972 and this design does not pretend otherwise), correct the substring wording, update requirements/matrix notes. Gated on Phases 1–2. (Filed as a sub-issue.)
Alternatives recorded in the doc
Two limiters (mcpserver + daemon) — double-counts MCP, misses the shared budget; limiter in the pool — sees a session key, not a caller; re-ranking upstream answers — destroys context-aware upstream ordering; token bucket / x/time/rate — new dependency, second limiter shape beside #2333's fixed windows; client debounce — a caller SHOULD, not the server-side MUST.
Open questions (in the doc, not filed)
Per-caller access control over sensitive suggestions (waits on #1968/#1972); a shared dedicated rate-limit error code with #2333's limiter if one is ever coined; whether #1554's tasks-rate-limit gap reuses this limiter type (the type must not be completion-shaped); in-flight request coalescing only on fleet evidence.
This issue is the design record. Implementation lives in its sub-issues; please do not implement from this issue directly.
Acceptance criteria
- Phase 1 (mcpx: Phase 1 of #2386 — completion rate limit at the /v1 choke point (limiter + completion.* settings, before the pool) #2387) landed: completion rate limit enforced at the /v1 choke point with completion.* settings, refusal before any pool acquisition
- Phase 2 (mcpx: Phase 2 of #2386 — relevance-ranked local completion (exact → prefix → substring tiers; upstream order untouched) #2388) landed: local completion answers relevance-ranked (exact → prefix → substring); upstream answers pass through unranked
- Phase 3 (mcpx: Phase 3 of #2386 — completion register truth-up (retire both #213 gap rows; security row to partial on #1968/#1972) #2389) landed: conformance register truthful — both docs(id): design Cloudflare Workers pkarr option [P7.2] #213 gap rows retired/moved to partial with the mcpx: a principal per surface and a permission per operation, declared permissively #1968/mcpx: the permissive auth interface authorizes everyone — real validation for the conformance rows that require refusal #1972 reason recorded
- This issue's own truth-up comment summarises what landed per phase against this design
Activity
developing-today commentedon Oct 29, 2026
CODE-1213
dezren39 commentedon Oct 29, 2026
🤖 Agent note · design filed
completion-security,completion-server-should, coverage_utilities.go:102-103), audited against origin/main 5a34fa7. Phases filed as sub-issues: mcpx: Phase 1 of #2386 — completion rate limit at the /v1 choke point (limiter + completion.* settings, before the pool) #2387 (Phase 1, rate limit at the /v1 choke point), mcpx: Phase 2 of #2386 — relevance-ranked local completion (exact → prefix → substring tiers; upstream order untouched) #2388 (Phase 2, relevance-ranked local completion), mcpx: Phase 3 of #2386 — completion register truth-up (retire both #213 gap rows; security row to partial on #1968/#1972) #2389 (Phase 3, register truth-up, gated on Phases 1–2 + status/blocked). Each phase carries a triage packet in the pilot queue. Design doc:files/designs/code-mcpx-completion-rate-limit-ranking.md(keep-the-four-repos-healthy goal workspace); register entry added tofiles/potential-projects.md(status: proposed). Nouser/review— the spec rows dictate the ends and the judgment calls (choke point, defaults, ranking tiers, upstream pass-through) are the architect's recorded decisions in the doc.dezren39 commentedon Oct 29, 2026
Intake review
Related: Phases: #2387 (rate limit), #2388 (ranking), #2389 (register truth-up); origin gaps: dezren39/darwin-nix#213 (closed — completion ignoring ref, already landed)
Notes: Design epic for the last two mcpx completion conformance gaps. The decision is recorded in the body and the design doc; the three phase issues carry their own acceptance checklists. This pass appends the epic-level acceptance criteria (the body's missing piece) and marks it enriched — the criteria above are the phase landings, not new scope.
Risks: An epic that closes when its phases merely file (rather than land) would strand the register gaps again; #2389 is gated on #2387/#2388 closing, so this epic closes last.
Suggested approach: Nothing to build here directly: track the three phases; close this issue on #2389's evidence comment.
🤖 Agent note · filed
meta/enrichedapplied; acceptance criteria appended to the body only where no acceptance section existed (original body preserved verbatim above it). Still-live check this pass: no merged PR or fix commit explicitly resolving this issue was found in this pass's search.dezren39 commentedon Nov 2, 2026
🤖 Agent note · done (Phase 3 evidence, task 5980)
What landed per phase
completion.perMinuteand per-servercompletion.serverPerMinutewindows.rankCompletions(internal/daemon/ops.go).completion-server-shouldgap retired to a covered row naming the Phase 1 limiter tests and Phase 2 ranking tests ininternal/daemon.completion-securitymoved to partial: input validation already existed and rate limiting landed in Phase 1; access control to sensitive suggestions and prevention of completion-based information disclosure remain open, waiting on principals mcpx: a principal per surface and a permission per operation, declared permissively #1968 / permissive-auth mcpx: the permissive auth interface authorizes everyone — real validation for the conformance rows that require refusal #1972. It is explicitly not marked fully covered.hasPrefixFold) before Phase 2; substring is now the lowest relevance tier, not the old behavior.Verification (PR #4087): all 6 newly cited daemon tests pass (plus the full daemon
Completion|Completetest set); the conformance package builds;Evaluate/ reference / missing-cell checks pass. Fullgo test ./internal/conformanceremains blocked on main by the pre-existing test-package compile break tracked in #3519 / #3710 (verified identical on pristine origin/main), which is also why the matrix rows were updated per-row to the exact Render output rather than by a full regeneration.With PR #4087 merged, issue #2389 closes and this design issue is ready for its own final truth-up/closure.
dezren39 commentedon Nov 2, 2026
agent-note:v1
event: done
task: 5980
worker: repo-worker-code (lane A)
state: Phase 3 (#2389) complete — PR #4087 merged as da39c0a. completion-server-should retired to covered (rate limit #2387 + ranking #2388 tests cited); completion-security stays partial, repointed to #1968/#1972. CI note: PR #4087 lint + stress failures were proven pre-existing on clean main 5b56410 (conformance test package does not compile — features_test.go failingReads Complete signature; tracked by #3519/#3710), not introduced by this change; docs build + plugin tests passed and cited daemon tests pass on the laptop.
dezren39 commentedon Nov 2, 2026
Program tending — completion proposal (2026-11-02)
All sub-issues are closed (verified via REST this run): #2387 (Phase 1, rate limit), #2388 (Phase 2, relevance ranking), #2389 (Phase 3, register truth-up — PR #4087 merged, per the agent note above).
This epic's children are all closed, so program tending proposes closing #2386 as complete. If any acceptance item in the body is still outstanding, name it here and the epic stays open with that as the tracked remainder.
dezren39 commentedon Nov 3, 2026
🤖 Agent note · truth-up + closing (all phases landed)
repo-worker-code), lanecode-mTruth-up against this design (fresh
ghverification, 2026-11-03):e49c0beeb801f21cec7234accf17139d7ed11b79): completion rate limit enforced at the /v1 choke point withcompletion.*settings, refusal before any pool acquisition.de59b343): local completion answers relevance-ranked (exact → prefix → substring tiers); upstream answers pass through unranked.da39c0ae09111704bccfec7e251f0f6262f5c3c0): conformance register truthed up — both docs(id): design Cloudflare Workers pkarr option [P7.2] #213 gap rows retired; the security row remains partial, with the per-caller access-control dependency on mcpx: a principal per surface and a permission per operation, declared permissively #1968/mcpx: the permissive auth interface authorizes everyone — real validation for the conformance rows that require refusal #1972 recorded, exactly as this design prescribed (it does not pretend otherwise).All four acceptance criteria are now met, including this truth-up comment. The open questions recorded in the design doc (shared rate-limit error code with #2333, #1554 limiter reuse, per-caller access control) remain open questions on their own tracks and do not block this design record. Closing #2386 as completed.
developing-today 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