Skip to content

feat(server): REST endpoints for project next/standup/changelog + WebMCP wiring (TASK-1894)#791

Merged
xarmian merged 4 commits into
mainfrom
feat/project-intel-rest-endpoints
Jul 3, 2026
Merged

feat(server): REST endpoints for project next/standup/changelog + WebMCP wiring (TASK-1894)#791
xarmian merged 4 commits into
mainfrom
feat/project-intel-rest-endpoints

Conversation

@xarmian

@xarmian xarmian commented Jul 3, 2026

Copy link
Copy Markdown
Collaborator

Summary

WebMCP Phase 3c (TASK-1894): the catalog actions pad_project.next / .standup / .changelog had no REST endpoint, so the browser WebMCP dispatcher returned honest "not available in the browser" errors. This adds three session-authed GET endpoints under the existing /workspaces/{slug} access-controlled group and wires the browser surface to them:

  • GET /workspaces/{slug}/next — bare array, parity with dashboard.suggested_next (the CLI's exact contract post BUG-987)
  • GET /workspaces/{slug}/standup?days=N (default 1)
  • GET /workspaces/{slug}/changelog?days=N&since=YYYY-MM-DD&parent=REF (default 7; silent since-wins matching both siblings)

Frontend: client.ts gets top-level next()/standup()/changelog() methods; dispatch.ts HANDLERS replace the honest-error stubs; new TS types mirror the Go response shapes (extracting DashboardSuggestion also fixed its previously missing item_ref field).

The third-sibling problem (deliberate)

These handlers are the third reproduction of this reshaping contract, alongside the CLI (cmd/pad/main.go) and the MCP HTTP dispatcher (internal/mcp/dispatch_http_slice4.go) — the latter exists only because these endpoints didn't. All three sites now carry KEEP IN SYNC cross-references (storetest-mirror precedent). TASK-1916 (filed, blocked by this PR) consolidates the MCP dispatcher onto these endpoints and deletes its custom reshaping.

Deliberate semantics, pinned by tests: days is lenient (absent/malformed/≤0 → default, matching both siblings and the REST convention for depth/window); malformed since → 400 (matching the CLI's hard error); parent filter matches ref/UUID/title case-insensitively via enriched parent fields (using resolveParentFilter instead would have silently dropped title matching vs both siblings).

Review

2+ codex rounds, rotated framing. R1 (plain) caught a real ACL finding: the visibility helper reproduced the ungated visibleCollectionIDs admin bypass, so a bearer-authed platform admin who is only a restricted member would see unfiltered results. Investigation showed that pattern is pre-existing and pervasive (dashboard/bootstrap/items/graph all ungated on main; reportVisibleCollections is the one bearer-aware exception) — filed as BUG-1917. Fix in eaaef80, scoped to what this PR owns: standup's direct queries and all of changelog get the bearer-aware gate (mirroring reportVisibleCollections, keeping item-grant granularity); next and standup's dashboard-derived sections keep dashboard parity and inherit BUG-1917's resolution (asymmetry documented in the file header). The regression test was revert-verified (fails on the ungated code). R2 (cross-surface parity lens) confirmed no divergence in field names, day defaults, since precedence, terminal-status ordering, per-status best-effort behavior, group ordering, or limit values; its only two findings were restatements of the documented-deliberate scoping decisions from R1's fix. Converged.

Test plan

  • go test ./... (SQLite) — all green, 14 new endpoint tests incl. bearer-admin scoping regression
  • make test-pg — full suite green (dual-driver mandatory: endpoints read the store)
  • make lint — 0 issues
  • npm test (109/109) / npm run check / npm run build — green

Refs: TASK-1894, TASK-1916, BUG-1917, TASK-1893

https://claude.ai/code/session_01CL1pBjNpPUX6SWkuAuYXHS

xarmian added 4 commits July 3, 2026 17:14
Adds GET /workspaces/{ws}/next, /standup, /changelog — session-authed
reads mirroring `pad project next|standup|changelog --format json`,
reusing buildDashboardResponse + store.ListItems so the browser
WebMCP surface stops returning "not available" for these catalog
actions (TASK-1894). Cross-references the MCP HTTP transport's
existing dispatchProjectNext/Standup/Changelog (dispatch_http_slice4.go)
with KEEP IN SYNC comments at both sites, since this is now a third
reproduction of the same reshaping contract pending a follow-up
consolidation.
Adds client.ts next()/standup()/changelog() methods and replaces the
three "not available in the browser" dispatch.ts stubs with real
handlers now that the backend endpoints exist (TASK-1894). Extracts
DashboardSuggestion as a shared type and adds StandupResponse /
ChangelogResponse types mirroring the Go response shapes.
…x R1)

standup/changelog's own item-list scoping used visibleCollectionIDs, which
has no bearer gate: a platform admin authenticated via a bearer token
(PAT/CLI/OAuth) who is only a restricted member of a workspace got the
unrestricted admin view instead of being scoped to their real membership.
Adds bearerAwareVisibleCollectionIDs, mirroring reportVisibleCollections'
existing BUG-1616/1617 gate, and switches projectIntelVisibility onto it
while preserving its item-level grant handling (which reportVisibleCollections
deliberately drops for aggregate reports).

buildDashboardResponse (and therefore /next, and standup's blockers/
suggested_next sections) is intentionally left ungated in this change —
gating it would break next's parity with dashboard.suggested_next and
diverge it from the CLI and MCP siblings. The resulting asymmetry is
documented inline pending a follow-up fix to buildDashboardResponse itself.
Replaces the textual placeholder ("the visibleCollectionIDs bearer-gate
bug filed from TASK-1894 review") with the actual bug number now that
it's been filed. Comment-only change, no behavior difference.
@xarmian
xarmian merged commit 7c0b137 into main Jul 3, 2026
4 checks passed
@xarmian
xarmian deleted the feat/project-intel-rest-endpoints branch July 3, 2026 17:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant