Files
pad/cmd
xarmian 55d3a078a8 fix(mcp): standup CLI ref + classifier polish for BUG-987 round 2 (#362)
Round-2 hotfix on top of PR #361 (which shipped to v0.1.0-rc.4).
Claude Desktop's re-review of rc.4 surfaced two fixes that didn't
fully land:

- Bug 8 (round 1 went to wrong layer). My HTTPHandlerDispatcher fix
  populated ref on standup blockers, but Claude Desktop's path is
  ExecDispatcher → CLI subprocess → standupCmd, which has its own
  JSON composition struct. That struct's Attention + SuggestedNext
  anonymous types didn't even define ItemRef as a parseable field.
  Now both define `item_ref` and the JSON-emit loops set Ref from it.
  Verified live: blockers now carry refs (TASK-X), not empty strings.

- Bug 11 part 2. Round 1 stripped the cobra Usage block but two
  artifacts still leaked:
  1. The "pad <verb> failed: <stderr>" prefix on server_error fallback
     messages. The verb name is the OLD CLI verb (e.g. `pad item
     block`) which doesn't match the v0.2 catalog actions agents see,
     and the cmdPath is already implicit from the invoked tool. Drop
     the prefix; emit the cleaned stderr directly.
  2. Self-link / "cannot ..." validation rejections classified as
     server_error instead of validation_failed. Extended the
     validation regex with `cannot ` so server-side rejections like
     "cannot link an item to itself" / "cannot modify archived item"
     route to ErrValidationFailed. Verified live with a self-link
     attempt — now returns code=validation_failed, hint="cannot link
     an item to itself", no prefix.
- New stripErrorPrefix helper trims leading `Error:` / `error:` /
  `ERROR:` from every classified hint+message so the envelope text
  isn't redundant with the envelope's `code` signal.

Bug 13 / Bug 14: my round-1 fixes verified working locally on rc.4
(tested with a fresh Task → convention=None; dashboard by_role shows
"Unassigned"/"unassigned" for the bucket). The reviewer's stale
results almost certainly reflect a pad server process that wasn't
restarted with the rc.4 binary swap.

Tests:
- TestClassifyExecError_CannotPhrasingClassifiesAsValidation —
  three "cannot ..." stderr cases must classify validation_failed.
- TestClassifyExecError_NoLegacyVerbPrefixInMessage — pins the
  prefix-strip behaviour on the server_error fallback path.
- TestStripErrorPrefix — trim-rule round-trip across casing
  variations and empty input.

Parent: BUG-987.
2026-05-01 21:04:26 -04:00
..