molecule-core/workspace-server
Hongming Wang 44bb35a926 feat(delegations): wire ledger Insert+SetStatus from production code paths (RFC #2829 #318)
PR-1 shipped the `delegations` table + `DelegationLedger` helper. PR-3
wired the sweeper. PR-4 wired the dashboard. But no PR ever wired
`ledger.Insert` from a production code path — the table stayed empty,
the sweeper had nothing to sweep, the dashboard had nothing to show.

This PR closes that gap. Behind feature flag `DELEGATION_LEDGER_WRITE=1`
(default off), the legacy activity_logs writes are mirrored to the
durable ledger:

  - insertDelegationRow → ledger.Insert (queued)
  - updateDelegationStatus → ledger.SetStatus on every status transition
  - executeDelegation completion path → ledger.SetStatus(completed,
    result_preview) for the result preview that activity_logs already
    stores in response_body
  - Record handler → ledger.Insert + ledger.SetStatus(dispatched) so
    agent-initiated delegations land in the same table

## Why a flag

The legacy flow has ~30 strict-sqlmock tests pinning exactly which SQL
statements fire per handler. Adding ledger writes always-on would
force adding ExpectExec stanzas to each. Flag-off keeps all 30 green
without churn; flag-on lets operators populate the table in staging
to feed the sweeper + dashboard once the agent-side cutover (RFC #2829
PR-5) has proven the round-trip end-to-end.

Default off → byte-identical to pre-#318 behavior.

## Status vocabulary mapping

activity_logs uses a freer status vocabulary than the ledger's CHECK
constraint allows. updateDelegationStatus is called with values like
"received" that the ledger doesn't accept; the wiring filters via a
switch to only forward known-good values, skipping anything else.

Record's first activity_logs row is `dispatched` but the ledger's
Insert path requires `queued` as initial state. Insert as queued first;
the very next SetStatus(..., dispatched) promotes it on the same row.

## Coverage

8 wiring tests (delegation_ledger_writes_test.go):

  - flag off → no SQL fired (rollout safety contract)
  - flag on → INSERT + UPDATE fire as expected
  - flag rejects loose truthy values (true/yes/0/on/TRUE) — only "1"
    is the on signal, matching PR-2 + PR-5 conventions
  - terminal-state replay swallows ErrInvalidTransition (legacy is
    authoritative; ledger replay error is not a delegation failure)

All 30 existing delegation_test.go tests still pass — flag default off
keeps the strict-sqlmock surface unchanged.

Refs RFC #2829.
2026-05-05 02:26:06 -07:00
..
cmd feat(delegations): wire RFC #2829 sweeper + admin routes into platform server 2026-05-04 22:00:59 -07:00
internal feat(delegations): wire ledger Insert+SetStatus from production code paths (RFC #2829 #318) 2026-05-05 02:26:06 -07:00
migrations feat(delegations): durable per-task ledger + audit-write helper (RFC #2829 PR-1) 2026-05-04 20:43:06 -07:00
pkg/provisionhook feat(#1957): wire gh-identity plugin into workspace-server 2026-04-24 15:01:41 +00:00
.ci-force chore: force Platform(Go) CI run on main — validate go vet clean 2026-04-21 15:43:19 +00:00
.gitignore feat(ws-server): pull env from CP on startup 2026-04-19 02:41:15 -07:00
.golangci.yaml chore(workspace-server): add golangci.yaml disabling errcheck 2026-04-24 07:16:54 +00:00
Dockerfile feat(deploy): verify each tenant /buildinfo matches published SHA after redeploy 2026-04-30 10:55:08 -07:00
Dockerfile.tenant feat(deploy): verify each tenant /buildinfo matches published SHA after redeploy 2026-04-30 10:55:08 -07:00
entrypoint-tenant.sh fix(security): add USER directive before ENTRYPOINT in all tenant images (#1155) 2026-04-20 23:51:33 +00:00
go.mod chore(deps)(deps): bump github.com/creack/pty in /workspace-server 2026-05-02 19:22:48 +00:00
go.sum chore(deps)(deps): bump github.com/creack/pty in /workspace-server 2026-05-02 19:22:48 +00:00