Skip to content

mcpx: Phase 1 of #2497 — limits in the task store: requestor key, TTL clamp, per-requestor cap, tasks/* window, 128-bit IDs #2498

Closed

Description

@dezren39

Phase 1 of design #2497 (mcpx tasks, bounded — operational limits, cooperative cancel, audit, and the small truths). Design doc: files/designs/code-mcpx-tasks-operational-limits.md in the keep-the-four-repos-healthy goal workspace. The decisions are recorded on #2497; this phase implements its first slice. Independent of Phase 2.

Scope

Limits in the store, keyed by requestor, valued in protoTasks.*:

  • Store.Start (internal/tasks/tasks.go:355) gains a requestor key (optional parameter / options field). Every creation site passes what it holds: the MCP seam (internal/mcpserver/tasks.go startTask, which already tracks taskOwners), the modern-task seam, and the daemon's /v1 Start sites (internal/daemon/ops.go:525, routes_proto.go:434, routes_exec.go:245, input_required.go:100). The empty key is a real bucket named "unbound", capped like any other — never a bypass.
  • protoTasks.maxTTL (duration, default 1h) in internal/settings/prototasks.go: a requested TTL above the cap is clamped, not refused; the stored/returned task shows the capped TTL. Default TTL (10m) unchanged.
  • protoTasks.maxPerRequestor (int, default 32): concurrent non-terminal tasks per requestor key, counted in the store. Creation beyond the cap is refused at the seam with a named error (-32603 on MCP, 429 on /v1) naming the limit.
  • protoTasks.perMinute (int, default 120, 0 disables): one fixed-window counter per requestor key over all tasks/* method calls (get/list/result/update/cancel), counted on admission at the two dispatch seams (MCP tasks handler, daemon /v1 task routes); refusal shaped like the cap refusal. Use a shared fixed-window limiter type if one has landed from Design: mcpx upstream question rate limits — one limiter at the client choke point, keyed by the configured server #2333/design(mcpx): completion, finished — one rate limit at the /v1 choke point, relevance-ranked local answers #2386 by implementation time; otherwise keep the copy local to the tasks seams — do not build a general rate-limit framework. (Design-doc open question: triage may exempt tasks/result long polls from the window if it can say why in one sentence on this issue.)
  • NewID (tasks.go:344) moves from 8 to 16 random bytes (128 bits).

Acceptance

  • A task requested with a TTL above protoTasks.maxTTL runs with the capped TTL, and the returned task object shows the capped value, on both the MCP and /v1 surfaces
  • The 33rd concurrent non-terminal task for one requestor key is refused with the named error while another requestor's creation still succeeds; the unbound bucket is capped the same way
  • tasks/* calls beyond protoTasks.perMinute for one requestor are refused with the named error / 429; 0 disables the window
  • Every Store.Start call site in the tree passes a requestor key or is explicitly the unbound bucket (grep-verifiable)
  • New task IDs are 128-bit; existing ID parsing/lookup is unaffected
  • The conformance gap rows tasks-resource-limits and tasks-rate-limit in internal/conformance/coverage_stateful.go are retired (or reworded to name what remains)
  • Tests run via CI per fleet policy (no builds on the sandbox)

Out of scope: cooperative cancel and statusMessage (Phase 2), audit logging and docs (Phase 3), per-server (upstream) concurrency caps, any change to task shapes on the wire.

🤖 Design-architect pass 17 — agent note: triage this phase against design #2497's recorded decisions; do not re-derive the limit values or the clamp-vs-refuse choice in triage.

Acceptance criteria

  • Store.Start takes a requestor key from every creation seam (MCP startTask, modern-task seam, the four /v1 Start sites); the empty key is the capped unbound bucket, never a bypass
  • protoTasks.maxTTL (default 1h) clamps requested TTLs (stored/returned task shows the capped TTL); protoTasks.maxPerRequestor (default 32) refuses creation beyond the cap with a named error (-32603 MCP / 429 /v1); protoTasks.perMinute (default 120, 0 disables) windows all tasks/* calls per requestor
  • Tests pin clamp-not-refuse for TTL, refusal naming the limit for the cap, and the unbound bucket being capped like any other

Activity

  1. added
    task/triageQueue packet kind: verify, reproduce, and route this item
    priority/normalOrdinary priority (the default)
    on Oct 30, 2026
  2. developing-today commented on Oct 30, 2026

    @developing-today
    Contributor
  3. added
    queue/queuedHas a queued task in the Supabase agent queue
    app/mcpxPackage/app: mcpx (pkgs/ or apps/ in this repo)
    effort/mMedium: expected under 1 day of work
    on Oct 30, 2026
  4. dezren39 commented on Oct 30, 2026

    @dezren39
    MemberAuthor

    🤖 agent-note:v1 — design-architect pass 17 (2026-10-29). Phase 1 of design #2497. Triage packet enqueued: pilot task 3733 (queue=repo-health-code-pilot, status=queued, verified; packet self-corrected once in-pass for a stale template acceptance line — the live payload is the corrected one). Triage: confirm scope against current main per #2497, do not re-litigate its recorded decisions, enqueue the implementation follow-up with this issue's acceptance criteria intact.

  5. added
    meta/enrichedIntake review done: acceptance criteria, links, and normalized labels added
    on Oct 30, 2026
  6. dezren39 commented on Oct 30, 2026

    @dezren39
    MemberAuthor

    Intake review

    Related: #2497 (design), #2499 (Phase 2, independent), #2500 (Phase 3 — audits these refusals), #2387/#2388 (the completion-limiter phases of #2386 — sibling fixed-window pattern)

    Notes: Phase 1 of the #2497 design: requestor key, TTL clamp, per-requestor cap, and tasks/* window in the task store, valued in protoTasks.* settings. Already fully labelled by the filer. This pass appends acceptance criteria and marks enriched.

    Risks: A creation seam missed (four /v1 sites are listed) leaves an uncapped path that makes the limits decorative; the empty-key bucket is the easiest seam to get wrong.

    Suggested approach: Add the settings + store counting first, then wire each creation seam in the body's list one by one with a test per seam; verify via CI.

    🤖 Agent note · filed

    • Agent: fleet monitor (repo-fleet-monitor)
    • Session / ID: repo-fleet-monitor run 2026-10-30T02:12Z (2026-10-29 21:12 CDT)
    • Found via: monitor reconciliation
    • Task: Duty 2 intake enrichment — labels normalized and meta/enriched applied; 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.
    • Expectation: see the effort label; done = the acceptance criteria are met.
    • Links: this issue
  7. 298 remaining items

  8. added
    queue/parkedQueue task is parked (waiting on CI, time, or an event)
    status/parkedDeliberately paused with a recorded resume condition
    and removed
    queue/claimedQueue worker lifecycle state
    on Oct 31, 2026
  9. dezren39 commented on Oct 31, 2026

    @dezren39
    MemberAuthor

    🤖 Agent note · parked

  10. added
    queue/claimedQueue worker lifecycle state
    and removed
    status/parkedDeliberately paused with a recorded resume condition
    queue/parkedQueue task is parked (waiting on CI, time, or an event)
    on Oct 31, 2026
  11. dezren39 commented on Oct 31, 2026

    @dezren39
    MemberAuthor

    🤖 Agent note · picked up

  12. added a commit that references this issue on Oct 31, 2026
  13. dezren39 commented on Oct 31, 2026

    @dezren39
    MemberAuthor

    🤖 Agent note · done

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

app/mcpxPackage/app: mcpx (pkgs/ or apps/ in this repo)effort/mMedium: expected under 1 day of workkind/enhancementmeta/enrichedIntake review done: acceptance criteria, links, and normalized labels addedpriority/normalOrdinary priority (the default)source/design-architectFiled by the repo design architect jobtask/triageQueue packet kind: verify, reproduce, and route this item

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions