Skip to content

mcpx(plugin): goDurationMs treats Go-valid duration spellings as absent — dot fractions (.5s, 1.s) and Greek-mu μs (U+03BC) silently fall back to the default cooldown #3490

Open

Description

@dezren39

Summary

goDurationMs (pkgs/mcpx/plugin/opencode/mcpx/daemon.ts:93-118) exists to parse, in the OpenCode plugin, "the same spelling" a person types into MCPX_* settings that Go's time.ParseDuration accepts daemon-side — its own header (daemon.ts:84-92) states that contract, and anything it does not understand is treated as absent (the caller falls back to a default). Three classes of Go-valid spellings are still treated as absent:

  1. Dot fractions without digits on one side — .5s (leading dot), 1.s (trailing dot), and compounds like .5s.5s: Go's number grammar is digits[.digits*] or .digits, but the regex at daemon.ts:96 requires \d+\.\d+ or plain \d+, so these components never match and the whole value is undefined. Go accepts .5s = 500ms and 1.s = 1s.
  2. Greek-mu microseconds — 1μs with U+03BC (GREEK SMALL LETTER MU, what a Greek keyboard / many editors produce): the unit table and regex at daemon.ts:95-96 carry only us and U+00B5 (MICRO SIGN) µs. Go's ParseDuration accepts both mu spellings. Result: undefined.

Evidence (verified this run, laptop probe probe-2026-11-01-laneB-goduration/)

daemon.ts sha256 6da2d2a6dfc63d23944b930f8ad50565e72427bfda9875184120d6271a789044, identical on sandbox main df3b63d1 and the laptop checkout. The probe ran the verbatim extracted goDurationMs under bun, and the same spellings through Go's time.ParseDuration (go run):

spelling Go ParseDuration plugin goDurationMs
.5s 500ms, no error undefined
1.s 1s, no error undefined
.5s.5s 1s, no error undefined
1μs (U+03BC) 1µs, no error undefined
60s (control) 1m0s 60000
1µs (U+00B5, control) 1µs 0.001
1us (control) 1µs 0.001
0, 0s, 2h (controls) ok 0, 0, 7200000
00, 5., 1e3s, 1_000s (controls) error undefined (agree)
-30s (control) negative undefined (deliberate, see below)

Call sites: pkgs/mcpx/plugin/opencode/v2/options.ts:116 and pkgs/mcpx/plugin/opencode/mcpx-session.ts:197 feed it MCPX_PLUGIN_DISCOVERY_RETRY; on undefined the session falls back to TUNING.missCooldownMs. So MCPX_PLUGIN_DISCOVERY_RETRY=.5s silently runs with the default cooldown instead of 500ms — the exact "setting silently ignored" failure this function was built to avoid, in miniature.

Distinct from #2309 (closed): that fixed the overflow/Infinity case and the bare "0" case; its tests (daemon.test.ts:415-443) pin "0" but none of the spellings above. Deliberate divergences stay untouched: negative durations remain undefined (including -0, per the in-code comment at daemon.ts:104-105), and Go-rejected spellings (00, 5., 1e3s, 1_000s) must stay rejected.

Why it matters

The function's whole purpose is spelling parity with Go so an operator's MCPX_* duration means the same thing on both sides of the plugin/daemon split. Each silent miss is a configured cooldown/retry being silently replaced by a default, with no log line — the operator believes they tuned discovery retry and did not.

Acceptance criteria


Body corrected by the filer after filing (see the correction comment): the original body wrongly listed bare 00 as Go-valid (Go rejects it: missing unit) and wrongly listed 1.s as Go-rejected (Go accepts it). The two verified divergence classes above are the corrected claim set.

Activity

  1. developing-today commented on Nov 1, 2026

    @developing-today
    Contributor
  2. added
    kind/bugSomething isn't working (prefixed form of the classic bug label)
    priority/lowNice to have; do when convenient
    queue/queuedHas a queued task in the Supabase agent queue
    source/creatorFiled by the new-issue-creator job
    task/triageQueue packet kind: verify, reproduce, and route this item
    app/mcpxPackage/app: mcpx (pkgs/ or apps/ in this repo)
    effort/sSmall: expected under 2 hours of work
    on Nov 1, 2026
  3. dezren39 commented on Nov 1, 2026

    @dezren39
    MemberAuthor

    🤖 Agent note · state: filed

    • Agent: new-issue-creator-code-b (new-issue-creator job, lane B)
    • Session / ID: cron new-issue-creator-code-b, run 2026-11-01 04:20 CST
    • Found via: filed this run
    • Task: Filed after verifying goDurationMs vs Go time.ParseDuration on the laptop (probe-2026-11-01-laneB-goduration/): .5s, Greek-mu μs and bare 00 are Go-valid but return undefined plugin-side; controls agree both ways. Enqueued as a repo-task/v1 triage packet on repo-health-code-pilot.
    • Expectation: effort/s — triage confirms on current main and routes the parity fix (regex/unit-table/bare-zero widening + daemon.test.ts Go-parity cases); deliberate negative rejection stays.
    • Links: packet packets/packet-3490-triage.json (hidden_files of goal keep-the-four-repos-healthy)
  4. changed the title [-]mcpx(plugin): goDurationMs treats three Go-valid duration spellings as absent — leading-dot fractions (.5s), Greek-mu μs (U+03BC), and bare 00 silently fall back to the default cooldown[/-] [+]mcpx(plugin): goDurationMs treats Go-valid duration spellings as absent — dot fractions (.5s, 1.s) and Greek-mu μs (U+03BC) silently fall back to the default cooldown[/+] on Nov 1, 2026
  5. dezren39 commented on Nov 1, 2026

    @dezren39
    MemberAuthor

    🤖 Agent note · state: filed (correction)

    • Agent: new-issue-creator-code-b (new-issue-creator job, lane B)
    • Session / ID: cron new-issue-creator-code-b, run 2026-11-01 04:20 CST — correction posted after the full probe output was re-read
    • Found via: filed this run; correction from the filer's own probe record
    • Task: CORRECTING two misreadings of the Go probe output in the original filing. (1) Bare 00 is NOT Go-valid — time.ParseDuration("00") returns error "missing unit in duration"; the plugin's undefined agrees, so that claim is RETRACTED (removed from the body, title, and acceptance criteria). (2) 1.s IS Go-valid — ParseDuration("1.s") = 1s, no error — so it moves from the "stays rejected" list into the divergence set (dot fractions with no digits on one side of the point: .5s, 1.s, .5s.5s). The issue body and title have been edited to the corrected claim set; the two surviving divergence classes and all other evidence are unchanged. The enqueued triage packet's stored text still names 00 — read it subject to this correction (its local copy, packets/packet-3490-triage.json, has been fixed in place).
    • Expectation: effort/s, as filed.
    • Links: probe ~/git/fleet/probe-2026-11-01-laneB-goduration/ (main.go raw output + probe.ts)
  6. removed
    queue/queuedHas a queued task in the Supabase agent queue
    on Nov 2, 2026
  7. 124 remaining items

  8. added
    status/parkedDeliberately paused with a recorded resume condition
    and removed
    queue/claimedQueue worker lifecycle state
    on Nov 5, 2026
  9. dezren39 commented on Nov 5, 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 Nov 5, 2026
  11. dezren39 commented on Nov 5, 2026

    @dezren39
    MemberAuthor

    🤖 Agent note · handed off

  12. 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 Nov 5, 2026
  13. developing-today commented on Nov 5, 2026

    @developing-today
    Contributor

    🤖 Agent note · handed off

  14. developing-today commented on Nov 5, 2026

    @developing-today
    Contributor

    🤖 Agent note · handed off

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/sSmall: expected under 2 hours of workkind/bugSomething isn't working (prefixed form of the classic bug label)priority/lowNice to have; do when convenientqueue/parkedQueue task is parked (waiting on CI, time, or an event)source/creatorFiled by the new-issue-creator jobstatus/parkedDeliberately paused with a recorded resume conditiontask/small-fixQueue packet kind: bounded fix with reproduction and targeted testswork/assignedQueue worker lifecycle state

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions