Skip to content

feat(delegations): operator dashboard endpoint over the durable ledger (RFC #2829 PR-4) - #2837

Merged
HongmingWang-Rabbit merged 1 commit into
stagingfrom
feat/rfc2829-pr4-operator-dashboard
May 5, 2026
Merged

feat(delegations): operator dashboard endpoint over the durable ledger (RFC #2829 PR-4)#2837
HongmingWang-Rabbit merged 1 commit into
stagingfrom
feat/rfc2829-pr4-operator-dashboard

Conversation

@HongmingWang-Rabbit

Copy link
Copy Markdown
Contributor

Fourth of 4 PRs implementing RFC #2829. Built on PR-1 (#2832, schema, merged).

Two read endpoints over the `delegations` table:

```
GET /admin/delegations[?status=in_flight|stuck|failed|completed&limit=N]
GET /admin/delegations/stats
```

What this gives operators

Without this, post-incident investigation requires direct DB access — only the on-call SRE can answer "is workspace X delegating to a wedged callee?". This moves that visibility into the same surface as /admin/queue, /admin/schedules-health, /admin/memories.

List

Status filter via tight allowlist (no string-concat of user input into SQL):

  • `in_flight` (default) → status IN (queued, dispatched, in_progress)
  • `stuck` → status='stuck' (rows the PR-3 sweeper marked)
  • `failed` → status='failed'
  • `completed` → status='completed'

Unknown status → 400 with allowlist. Limit 1..1000, default 100.

Nullable fields (`last_heartbeat`, `result_preview`, `error_detail`) use pointer types so JSON omits them when NULL.

Stats

Zero-fills every status key so the dashboard summary card doesn't branch on missing-vs-zero.

Out of scope (deferred per RFC)

  • "Retry this stuck task" mutation — needs agent-side cutover (PR-5) first
  • p95/p99 duration metrics — separate metric exposure, not row-level read
  • Canvas UI — this is the JSON contract; canvas panel consumes it in a follow-up canvas PR

Wiring

NOT wired into the router in this PR. Ships separately in the `enable-rfc2829-server-side` follow-up alongside the sweeper Start call + result-push flag flip.

Coverage (11 unit tests)

List (8): default in_flight, stuck, failed, unknown→400, negative limit→400, over-cap→400, custom limit echoed, nullable fields populated correctly.

Stats (2): zero-fills missing keys, empty table.

Contract pin (1): statusFilters table shape (drift catches accidental edits).

Test plan

  • 11 unit tests pass
  • Existing tests untouched
  • Wiring follow-up: register routes in router.go
  • Staging E2E once wired

Refs RFC #2829.

…r (RFC #2829 PR-4)

Two read endpoints over the `delegations` table (PR-1 schema):

  GET /admin/delegations[?status=in_flight|stuck|failed|completed&limit=N]
  GET /admin/delegations/stats

## What this gives operators

Without this, post-incident investigation requires direct DB access —
only the on-call SRE can answer "is workspace X delegating to a wedged
callee?". This moves that visibility into the same surface as
/admin/queue, /admin/schedules-health, /admin/memories.

## List endpoint

Status filter via tight allowlist:

  - in_flight (default) → status IN (queued, dispatched, in_progress)
  - stuck               → status='stuck' (rows the PR-3 sweeper marked)
  - failed              → status='failed'
  - completed           → status='completed'

Unknown status → 400 with the allowlist in the error body. Limit
1..1000, default 100.

The status allowlist drives a parameterized IN clause (no string-
concatenation of user-controlled values into SQL).

Result rows expose all the audit-grade fields the dashboard needs:
delegation_id, caller_id, callee_id, task_preview, status,
last_heartbeat, deadline, result_preview, error_detail, retry_count,
created_at, updated_at. Nullable fields use pointer types so JSON
omits them when NULL (no false-zero "" for missing values).

## Stats endpoint

Zero-fills every known status key (queued, dispatched, in_progress,
completed, failed, stuck) so the dashboard summary card doesn't have
to handle "missing key vs zero" branching.

## Out of scope (deferred)

  - "retry this stuck task" mutation: needs the agent-side cutover
    (RFC #2829 PR-5 plan) before re-fire is safe
  - p95 / p99 duration aggregates: separate metric exposure, not a
    row-level read endpoint
  - Canvas UI: this is the JSON contract; the canvas operator panel
    consumes it in a follow-up canvas PR

## Wiring

NOT wired into the router in this PR — ships separately to keep
PR-by-PR review surface tight. Wiring will land in the
`enable-rfc2829-server-side` follow-up PR alongside the sweeper Start
call and the result-push flag flip.

## Coverage

11 unit tests:

List (8):
  - default status=in_flight, IN(queued,dispatched,in_progress)
  - status=stuck → IN(stuck)
  - status=failed → IN(failed)
  - unknown status → 400 with allowlist
  - negative limit → 400
  - over-cap limit → 400
  - custom limit accepted + echoed in response
  - nullable fields populated correctly (pointer-omitempty)

Stats (2):
  - zero-fills missing status keys
  - empty table → all counts zero

Contract pin (1):
  - statusFilters table shape — every documented key + value pair
    pinned. Drift catches accidental edits (forward defense).

Refs RFC #2829.
@HongmingWang-Rabbit
HongmingWang-Rabbit added this pull request to the merge queue May 5, 2026
Merged via the queue into staging with commit aca7d99 May 5, 2026
22 checks passed
@HongmingWang-Rabbit
HongmingWang-Rabbit deleted the feat/rfc2829-pr4-operator-dashboard branch May 5, 2026 04:07
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