Skip to content

mcpx(docs-history): a value-taking flag as the last argument panics — stamp/check arg loops index rest[i] after i++ with no bounds check #3312

Open

Description

@dezren39

Bug

docs-history (the mcpx compendium history / release-stamping tool, landed today in #3266 for #1865) panics with a Go runtime stack trace when a value-taking flag is the last argument of stamp or check.

Both subcommands parse flags with a hand-rolled loop that does i++; value = rest[i] with no bounds check:

  • pkgs/mcpx/tools/docs-history/main.go:1119-1127 — stamp: --version, --date, --changes-dir
  • pkgs/mcpx/tools/docs-history/main.go:1146-1153 — check: --diff, --changes-dir

Evidence (verified this run)

Probe on the laptop (~/git/fleet/probe-2026-10-31-laneA-docshistory/): main.go copied verbatim from main 2cc551cd, sha256 12e1888103e770ed83476d6a65695f978e0c9cfa95e39915c54ba1948dec37b6 on both sides, built with Go 1.26.8.

Bug cases — every one panics:

$ docs-history stamp --version
panic: runtime error: index out of range [1] with length 1
goroutine 1 [running]: main.main() …

$ docs-history stamp --version 1.2.3 --date        → panic: index out of range [3] with length 3
$ docs-history stamp --changes-dir                 → panic: index out of range [1] with length 1
$ docs-history check --diff                        → panic: index out of range [1] with length 1
$ docs-history check --changes-dir                 → panic: index out of range [1] with length 1
$ docs-history check doc.md --diff                 → panic: index out of range [2] with length 2

Controls — the tool's own intended behaviour for bad usage is a clean usage message:

$ docs-history stamp --version file.md   → usage text, exit 2 (no panic)
$ docs-history check                     → usage text, exit 2
$ docs-history bogus-subcommand          → usage text, exit 2
$ docs-history stamp --version 1.2.3 --date 2026-10-31 doc.md
    → exit 0; `since: unreleased` correctly rewritten to `since: 1.2.3`

Why it matters

stamp is the release step (docs/release-runbook.md) and check is a CI gate. A mistyped release command — a flag whose value was forgotten, or a shell variable that expanded to nothing — currently produces a runtime panic and stack trace instead of the usage text the tool already prints for every other usage error. In CI the panic output buries the actual mistake; at release time it looks like the tool itself is broken. The exit code happens to also be 2 (Go runtime), so scripts cannot distinguish a usage error from a crash by code alone.

Acceptance criteria

  • stamp/check with any value-taking flag (--version, --date, --changes-dir, --diff) as the final argument print the usage text (or a message naming the flag and its missing value) to stderr and exit 2 — no panic, no stack trace.
  • All currently-valid invocations behave exactly as before (valid stamp still stamps and exits 0; missing required values still usage + exit 2).
  • A regression test covers each value-taking flag in trailing position for both subcommands (the existing main_test.go suite tests the library functions; the arg-parsing path in main() needs coverage, e.g. by factoring the parse into a testable function or an exec-based test).

Related: #1865 (the tool's implementation issue). Distinct from the unrecognized-argument class filed for other scripts (#3264/#3278/#3281/#3287/#3296/#3297): those silently ignore unknown flags; this one crashes on a known flag missing its value.

Activity

  1. added
    kind/bugSomething isn't working (prefixed form of the classic bug label)
    priority/normalOrdinary priority (the default)
    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
  2. dezren39 commented on Nov 1, 2026

    @dezren39
    MemberAuthor

    🤖 Agent note · filed

  3. dezren39 commented on Nov 1, 2026

    @dezren39
    MemberAuthor

    Adopted as Phase 2 of design #3352 (corollary 3: a trailing value flag is a usage error — usage text + exit 2, the tool's own established behaviour, never a panic). The design records the contract this issue's fix must follow: every argument is accounted for before any side effect; unknown/typo'd arguments are a usage error naming the argument (exit non-zero, 2 where no usage code is established) before any subprocess/network/file/lock/deploy step. Triage: do NOT re-file, re-scope or split this issue — record the phase structure and verdict, and keep this issue's own acceptance criteria as the phase's acceptance. Design doc: files/designs/code-operator-argument-contract.md (keep-the-four-repos-healthy goal workspace).

  4. added
    work/assignedQueue worker lifecycle state
    and removed on Nov 1, 2026
  5. 31 remaining items

  6. dezren39 commented on Nov 4, 2026

    @dezren39
    MemberAuthor

    agent-note:v1
    event: handed-off
    task: 8218 (triage, repo-health-code-pilot; worker repo-worker-code; lane code-t)
    by: repo-queue-worker lane T

    Handed off to the opencode claimant (execution lane: opencode, lane-assignment row 1383). The claimant launches the bound session that drives task 8218 to its terminal state.

  7. dezren39 commented on Nov 4, 2026

    @dezren39
    MemberAuthor

    agent-note:v1
    task 8218 picked up by lane code-g; execution lane assigned opencode — handed off to the opencode claimant, which will launch the bound session and drive task 8218 to its terminal state. Issue #3312 verified OPEN with no hard-stop labels at handoff.

  8. dezren39 commented on Nov 4, 2026

    @dezren39
    MemberAuthor

    🤖 Agent note · handed off

  9. added
    queue/queuedHas a queued task in the Supabase agent queue
    and removed
    queue/claimedQueue worker lifecycle state
    work/assignedQueue worker lifecycle state
    on Nov 5, 2026
  10. dezren39 commented on Nov 5, 2026

    @dezren39
    MemberAuthor

    🤖 Agent note · handed off

    • Agent: fleet monitor
    • Session / ID: task 8218 (repo-fleet-monitor run 2026-11-05T15:45:48Z)
    • Found via: monitor reconciliation (Duty 1 claim/label divergence repair)
    • Task: Claim evaporated: task 8218 is queued and unclaimed in repo-health-code-pilot, but this issue still carried claimed labels. Labels reset to the truth (queue/queued + status/needs-triage). Checkpoint stage at evaporation: handed_off.
    • Expectation: The next lane claim picks task 8218 up from the queued state and posts a fresh pickup note.
  11. dezren39 commented on Nov 8, 2026

    @dezren39
    MemberAuthor

    🤖 Agent note · handed off

  12. added
    work/assignedQueue worker lifecycle state
    queue/claimedQueue worker lifecycle state
    and removed
    queue/queuedHas a queued task in the Supabase agent queue
    on Nov 8, 2026
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/normalOrdinary priority (the default)queue/claimedQueue worker lifecycle statesource/creatorFiled by the new-issue-creator jobsource/design-architectFiled by the repo design architect jobstatus/in-progressQueue worker lifecycle statetask/triageQueue packet kind: verify, reproduce, and route this itemwork/assignedQueue worker lifecycle state

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions