Repository navigation
Description
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:
- Dot fractions without digits on one side —
.5s(leading dot),1.s(trailing dot), and compounds like.5s.5s: Go's number grammar isdigits[.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 isundefined. Go accepts.5s= 500ms and1.s= 1s. - Greek-mu microseconds —
1μswith U+03BC (GREEK SMALL LETTER MU, what a Greek keyboard / many editors produce): the unit table and regex at daemon.ts:95-96 carry onlyusand U+00B5 (MICRO SIGN)µs. Go'sParseDurationaccepts 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
-
goDurationMs(".5s")returns500,goDurationMs("1.s")returns1000, and compound components (.5s.5s) sum like Go's. -
goDurationMsaccepts U+03BCμsexactly as U+00B5µsandus. - Go-rejected spellings stay
undefined:00,5.,.s,1e3s,1_000s, unit-less non-zero (60), trailing junk (60s please); negative durations stayundefinedper the existing deliberate rule. - The int64-nanosecond ceiling behaviour from mcpx(plugin): goDurationMs returns Infinity for overflow durations Go rejects — one typo'd MCPX_PLUGIN_DISCOVERY_RETRY disables daemon rediscovery for the whole session #2309 is unchanged (fraction components count toward the total before the ceiling check).
- Regression tests in
daemon.test.tsnext to the existinggoDurationMsdescribe block cover each case above, ideally as a small Go-parity table.
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
developing-today commentedon Nov 1, 2026
CODE-1334
dezren39 commentedon Nov 1, 2026
🤖 Agent note · state: filed
[-]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[/+]dezren39 commentedon Nov 1, 2026
🤖 Agent note · state: filed (correction)
00is NOT Go-valid —time.ParseDuration("00")returns error "missing unit in duration"; the plugin'sundefinedagrees, so that claim is RETRACTED (removed from the body, title, and acceptance criteria). (2)1.sIS 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 names00— read it subject to this correction (its local copy, packets/packet-3490-triage.json, has been fixed in place).124 remaining items
dezren39 commentedon Nov 5, 2026
🤖 Agent note · parked
queue/6931-3490-goduration-parity; the PR contains the requested implementation and its production-line check is SUCCESS. This lane made no worktree or competing PR.dezren39 commentedon Nov 5, 2026
🤖 Agent note · handed off
developing-today commentedon Nov 5, 2026
🤖 Agent note · handed off
developing-today commentedon Nov 5, 2026
🤖 Agent note · handed off