Skip to content

feat(workboard): add worker dispatch CLI#88555

Merged
steipete merged 3 commits into
mainfrom
feat/workboard-dispatch-cli-docs
May 31, 2026
Merged

feat(workboard): add worker dispatch CLI#88555
steipete merged 3 commits into
mainfrom
feat/workboard-dispatch-cli-docs

Conversation

@steipete

Copy link
Copy Markdown
Contributor

Summary

  • Start ready Workboard cards from dispatch by claiming a bounded batch and launching Gateway subagent worker runs with persisted session/run metadata.
  • Add openclaw workboard CLI plus /workboard slash command parity for list, show, create, and dispatch.
  • Expand Workboard plugin docs and add a dedicated CLI reference covering SQLite state, dispatch behavior, permissions, fallback, JSON redaction, and troubleshooting.

Verification

  • pnpm test extensions/workboard -- --reporter=verbose
  • node scripts/run-oxlint.mjs --tsconfig config/tsconfig/oxlint.extensions.json extensions/workboard/src/card-lookup.ts extensions/workboard/src/cli.ts extensions/workboard/src/cli.test.ts extensions/workboard/src/command.ts extensions/workboard/src/command.test.ts extensions/workboard/src/dispatcher.ts extensions/workboard/src/dispatcher.test.ts
  • pnpm docs:list
  • pnpm format:docs:check
  • git diff --check
  • .agents/skills/autoreview/scripts/autoreview --mode local
  • env -u OPENCLAW_TESTBOX pnpm check:changed reached extension lint after typecheck; latest origin/main broad extension lint currently reports pre-existing unsafe-assertion findings outside this PR (for example qqbot/codex/line plus existing Workboard store/sqlite/tool files). Touched Workboard CLI/dispatcher files were linted directly above.

Real behavior proof

Behavior addressed: Workboard dispatch can now start bounded subagent worker lanes, and operators can inspect/create/dispatch cards from CLI or slash command surfaces.
Real environment tested: Local OpenClaw source checkout on the rebased branch.
Exact steps or command run after this patch: pnpm test extensions/workboard -- --reporter=verbose; targeted Workboard run-oxlint; docs list/format checks; autoreview.
Evidence after fix: Workboard extension suite passed 7 files / 94 tests, including dispatcher worker-start, slash write-scope, CLI claim-token redaction, explicit Gateway target fallback, and ambiguous prefix tests; autoreview reported no accepted/actionable findings.
Observed result after fix: Ready cards are claimed and receive persisted worker run metadata; claim tokens are redacted from new CLI JSON read paths; explicit remote Gateway dispatch failures do not mutate local state.
What was not tested: A live provider-backed subagent run from a real Gateway was not exercised locally; unit tests cover the subagent runtime call and Workboard state transitions.

@openclaw-barnacle openclaw-barnacle Bot added docs Improvements or additions to documentation plugin: workboard size: XL maintainer Maintainer-authored PR labels May 31, 2026
@clawsweeper

clawsweeper Bot commented May 31, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs real behavior proof before merge. Reviewed May 31, 2026, 5:29 AM ET / 09:29 UTC.

Summary
This PR adds Workboard CLI and /workboard command surfaces, changes Workboard dispatch to claim ready cards and start subagent worker runs with persisted session/run metadata, updates Workboard docs, and adjusts SMS tests.

PR surface: Source +689, Tests +387, Docs +325. Total +1401 across 16 files.

Reproducibility: yes. for the PR defects by source inspection: PR-head list/create/show use params.store directly while current Gateway calls honor remote target configuration, and PR-head dispatch changes the existing Gateway method to start workers. I did not run a live command because this review is read-only.

Review metrics: 1 noteworthy metric.

  • Workboard command/API surfaces: 1 existing Gateway method changed; 1 CLI root added; 1 slash alias added. This is a new operator surface plus a changed existing RPC contract, so compatibility and permission semantics need explicit review before merge.

Merge readiness
Overall: 🧂 unranked krab
Proof: 🧂 unranked krab
Patch quality: 🦐 gold shrimp
Result: blocked until real behavior proof from a real setup is added.

Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch.

Rank-up moves:

  • [P1] Add redacted terminal/log/recording proof of a real openclaw workboard dispatch through a live Gateway/provider starting a worker and persisting run metadata.
  • Preserve or explicitly split the data-only dispatch RPC before worker-starting behavior ships.
  • [P1] Route or block remote-profile workboard list/create/show so operators do not silently use local SQLite when targeting a remote Gateway.

Proof guidance:

  • [P1] Needs real behavior proof before merge: The PR body reports tests, lint, docs checks, and autoreview only, and explicitly says no live provider-backed Gateway subagent run was exercised. After adding proof, update the PR body; ClawSweeper should re-review automatically. If it does not, the PR author or someone with repository write access can comment @clawsweeper re-review.

Risk before merge

  • [P1] Existing callers of workboard.cards.dispatch with operator.write could start subagent worker sessions after merge instead of only running data-side cleanup.
  • [P1] The new local workboard list/create/show commands can ignore a configured remote Gateway target and inspect or mutate a different local SQLite board.
  • [P1] Session/run metadata and claim ownership become part of dispatch, so upgrade safety needs live proof and explicit maintainer approval.
  • [P1] The PR body still reports only local tests/lint/autoreview and explicitly says no live provider-backed Gateway subagent run was exercised.
  • [P1] The live PR context reports mergeableState: dirty, so the head needs a refresh before it is a viable merge candidate.

Maintainer options:

  1. Preserve contracts before merge (recommended)
    Keep workboard.cards.dispatch data-only or add an explicit worker-start method/option with reviewed permissions, and route or block remote-profile CLI reads/writes before landing.
  2. Accept the worker-start scope change
    Maintainers can explicitly approve that existing operator.write dispatch callers may now launch subagent runs and document the upgrade/security impact.
  3. Pause for Workboard design review
    If dispatch ownership, remote CLI behavior, and worker permissions are not settled, keep the PR paused rather than merging a new public command contract now.

Next step before merge

  • [P1] Human review is needed for the protected maintainer label, changed dispatch permission/session semantics, dirty merge state, and missing live behavior proof.

Security
Needs attention: The diff changes an existing write-scoped dispatch method into a worker-launching operation, which needs explicit permission/security review before merge.

Review findings

  • [P1] Preserve the data-only dispatch contract — extensions/workboard/src/gateway.ts:387-390
  • [P1] Route remote-profile Workboard CLI reads and writes — extensions/workboard/src/cli.ts:133
  • [P3] Use a WebSocket URL in the CLI docs — docs/cli/workboard.md:97
Review details

Best possible solution:

Land a narrower Workboard CLI/dispatch design that honors remote Gateway targets, keeps the existing data-only dispatch contract or gates worker starts behind an explicit reviewed surface/scope, and includes redacted live Gateway/provider proof.

Do we have a high-confidence way to reproduce the issue?

Yes for the PR defects by source inspection: PR-head list/create/show use params.store directly while current Gateway calls honor remote target configuration, and PR-head dispatch changes the existing Gateway method to start workers. I did not run a live command because this review is read-only.

Is this the best way to solve the issue?

No. The CLI feature is useful, but the safer design is to preserve or explicitly split the existing data-only dispatch contract, route or block remote-profile local reads/writes, and add live Gateway/provider proof before merge.

Full review comments:

  • [P1] Preserve the data-only dispatch contract — extensions/workboard/src/gateway.ts:387-390
    Current main's workboard.cards.dispatch only runs data-side cleanup/promotion, and workboard_dispatch is documented as a nudge for dependency promotion and stale-claim cleanup. This patch changes the existing RPC to claim cards and launch subagent runs under the same write scope, so existing callers can unexpectedly start workers; keep the current method data-only or add an explicit worker-dispatch method/option with reviewed permissions.
    Confidence: 0.88
  • [P1] Route remote-profile Workboard CLI reads and writes — extensions/workboard/src/cli.ts:133
    list, create, and show read or mutate params.store directly, so a profile or OPENCLAW_GATEWAY_URL pointing at a remote Gateway can still operate on the CLI process's local SQLite board. Route these commands through the resolved Gateway target or fail clearly in remote mode instead of silently showing or changing a different board.
    Confidence: 0.86
  • [P3] Use a WebSocket URL in the CLI docs — docs/cli/workboard.md:97
    The dispatch --url example uses an http:// URL, but the shared Gateway CLI option is documented and tested as a WebSocket target (ws:// or wss://). Copying this example can send users to the wrong scheme, so update the Workboard CLI reference to use the Gateway WebSocket URL.
    Confidence: 0.78

Overall correctness: patch is incorrect
Overall confidence: 0.86

AGENTS.md: found and applied where relevant.

Codex review notes: model gpt-5.5, reasoning high; reviewed against 9e2bd8b2f7eb.

Label changes

Label changes:

  • add merge-risk: 🚨 security-boundary: The existing operator.write dispatch scope would gain the ability to launch subagent worker sessions and pass claim authority into worker prompts.

Label justifications:

  • P2: This is a substantial Workboard plugin feature with limited blast radius but real compatibility, session-state, and proof blockers.
  • merge-risk: 🚨 compatibility: The PR changes the behavior of an existing Workboard Gateway dispatch method and adds CLI behavior that can ignore configured remote Gateway targets.
  • merge-risk: 🚨 session-state: Dispatch now claims cards, starts subagent runs, and writes session/run metadata, so merge mistakes can mis-associate or stale Workboard worker state.
  • merge-risk: 🚨 security-boundary: The existing operator.write dispatch scope would gain the ability to launch subagent worker sessions and pass claim authority into worker prompts.
  • rating: 🧂 unranked krab: Overall readiness is 🧂 unranked krab; proof is 🧂 unranked krab and patch quality is 🦐 gold shrimp.
  • status: 📣 needs proof: The PR needs real behavior proof before ClawSweeper can clear the contributor ask. Needs real behavior proof before merge: The PR body reports tests, lint, docs checks, and autoreview only, and explicitly says no live provider-backed Gateway subagent run was exercised. After adding proof, update the PR body; ClawSweeper should re-review automatically. If it does not, the PR author or someone with repository write access can comment @clawsweeper re-review.
Evidence reviewed

PR surface:

Source +689, Tests +387, Docs +325. Total +1401 across 16 files.

View PR surface stats
Area Files Added Removed Net
Source 7 691 2 +689
Tests 5 398 11 +387
Docs 4 335 10 +325
Config 0 0 0 0
Generated 0 0 0 0
Other 0 0 0 0
Total 16 1424 23 +1401

Security concerns:

  • [medium] Existing write scope can launch workers — extensions/workboard/src/gateway.ts:387
    workboard.cards.dispatch keeps the existing write-scoped Gateway surface but now starts subagent worker runs and passes claim authority into worker prompts. Existing clients with permission to nudge dispatch cleanup would gain a stronger operation unless maintainers explicitly approve the scope or split the API.
    Confidence: 0.82

What I checked:

  • Repository policy applied: Root AGENTS.md requires full policy review and treats plugin APIs, provider routing, auth/session state, persisted preferences, setup, startup checks, and fallback behavior as compatibility-sensitive merge risk. (AGENTS.md:24, 9e2bd8b2f7eb)
  • Extension boundary applied: extensions/AGENTS.md says bundled plugins share the third-party plugin boundary and must keep metadata accurate while using plugin SDK seams. (extensions/AGENTS.md:3, 9e2bd8b2f7eb)
  • Current main dispatch is data-only: Current main registers workboard.cards.dispatch as a Gateway method that calls store.dispatch() and redacts returned cards; the adjacent tool description says it only nudges dependency promotion and reclaims expired/timed-out runs. (extensions/workboard/src/gateway.ts:383, 9e2bd8b2f7eb)
  • PR head changes existing dispatch behavior: At PR head, the existing workboard.cards.dispatch method calls dispatchAndStartWorkboardCards, which claims cards and starts subagent runs rather than preserving the current data-only dispatch contract. (extensions/workboard/src/gateway.ts:387, 720a3cd8ab3b)
  • PR head local CLI reads/writes bypass Gateway: The new list, create, and show commands read or mutate params.store directly, while current Gateway CLI resolution honors OPENCLAW_GATEWAY_URL and remote-mode config for Gateway calls. (extensions/workboard/src/cli.ts:133, 720a3cd8ab3b)
  • Proof remains mock-only: The PR body lists tests, targeted lint, docs checks, autoreview, and explicitly says a live provider-backed subagent run from a real Gateway was not exercised. (720a3cd8ab3b)

Likely related people:

  • steipete: Current main blame and git log --follow show Peter Steinberger introduced the central Workboard dispatch/store/gateway surfaces and the Gateway URL-resolution code in commit e678225. (role: feature-history owner and recent area contributor; confidence: high; commits: e6782254e457, f5eca3f84c; files: extensions/workboard/src/gateway.ts, extensions/workboard/src/store.ts, extensions/workboard/src/tools.ts)
What the crustacean ranks mean
  • 🦀 challenger crab: rare, exceptional readiness with strong proof, clean implementation, and convincing validation.
  • 🦞 diamond lobster: very strong readiness with only minor maintainer review expected.
  • 🐚 platinum hermit: good normal PR, likely mergeable with ordinary maintainer review.
  • 🦐 gold shrimp: useful signal, but proof or patch confidence is still limited.
  • 🦪 silver shellfish: thin signal; proof, validation, or implementation needs work.
  • 🧂 unranked krab: not merge-ready because proof is missing/unusable or there are serious correctness or safety concerns.
  • 🌊 off-meta tidepool: rating does not apply to this item.

Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics.

How this review workflow works
  • ClawSweeper keeps one durable marker-backed review comment per issue or PR.
  • Re-runs edit this comment so the latest verdict, findings, and automation markers stay together instead of adding duplicate bot comments.
  • A fresh review can be triggered by eligible @clawsweeper re-review comments, exact-item GitHub events, scheduled/background review runs, or manual workflow dispatch.
  • PR/issue authors and users with repository write access can comment @clawsweeper re-review or @clawsweeper re-run on an open PR or issue to request a fresh review only.
  • Maintainers can also comment @clawsweeper review to request a fresh review only.
  • Fresh-review commands do not start repair, autofix, rebase, CI repair, or automerge.
  • Maintainer-only repair and merge flows require explicit commands such as @clawsweeper autofix, @clawsweeper automerge, @clawsweeper fix ci, or @clawsweeper address review.
  • Maintainers can comment @clawsweeper explain to ask for more context, or @clawsweeper stop to stop active automation.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 871715c697

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread extensions/workboard/src/cli.ts Outdated
Comment on lines +206 to +209
if (!isGatewayUnavailableError(error) || hasExplicitGatewayTarget(options)) {
throw error;
}
const result = redactDispatchResult(await params.store.dispatch());

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Avoid local fallback for configured remote gateways

When openclaw workboard dispatch is run without --url/--token but the profile (or OPENCLAW_GATEWAY_URL) points at a remote Gateway, callGatewayFromCli still targets that configured URL (see src/cli/gateway-rpc.ts and src/gateway/connection-details.ts). If that connection is refused or reset, this branch treats it as an implicit local Gateway outage and runs params.store.dispatch() against local SQLite, so a remote-profile operator can mutate stale local Workboard state instead of failing without changing the remote board. Please only use the data-only fallback when the resolved target is the local loopback Gateway, or treat config/env Gateway targets as explicit.

Useful? React with 👍 / 👎.

@clawsweeper clawsweeper Bot added rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. labels May 31, 2026
@steipete
steipete force-pushed the feat/workboard-dispatch-cli-docs branch from 871715c to 5ef3867 Compare May 31, 2026 08:24

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 5ef38671a5

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

.option("--status <status>", "Filter by status")
.option("--json", "Print JSON", false)
.action(async (options: JsonOptions & { board?: string; status?: string }) => {
let cards = await params.store.list({ boardId: options.board });

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Route remote-profile Workboard CLI reads through Gateway

When an operator's profile or OPENCLAW_GATEWAY_URL points at a remote Gateway, this direct store read still opens the CLI process's local Workboard SQLite instead of the Gateway's plugin state. The same local-only path is used by create and show, while only dispatch has Gateway options, so openclaw workboard list/create/show can display or mutate a different board than the remote dashboard and Workboard RPC methods that already exist for these operations. Please send these subcommands through the resolved Gateway target, or explicitly block remote-profile use instead of silently using local state.

Useful? React with 👍 / 👎.

@clawsweeper clawsweeper Bot added rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. and removed rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. labels May 31, 2026
@clawsweeper clawsweeper Bot added P2 Normal backlog priority with limited blast radius. merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. merge-risk: 🚨 session-state 🚨 May lose, corrupt, stale, or mis-associate session, agent, or context state. labels May 31, 2026
@steipete
steipete force-pushed the feat/workboard-dispatch-cli-docs branch from adcb9ec to 720a3cd Compare May 31, 2026 09:24
@openclaw-barnacle openclaw-barnacle Bot added channel: sms Channel integration: sms and removed extensions: copilot labels May 31, 2026
@steipete
steipete force-pushed the feat/workboard-dispatch-cli-docs branch from 720a3cd to b05e146 Compare May 31, 2026 09:27

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 720a3cd8ab

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +185 to +196
const updated = await params.store.update(card.id, {
sessionKey,
runId: run.runId,
execution: buildExecution({
card: claimed.card,
sessionKey,
runId: run.runId,
model,
now,
}),
});
await params.store.addWorkerLog(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Don't block cards after a worker has already started

If params.subagent.run succeeds but either of the following persistence writes fails (for example a transient SQLite/write error while saving runId/execution or appending the worker log), this shared catch records a start failure and calls store.block, clearing the claim even though a live worker was already launched with that token. That leaves the running worker unable to heartbeat/complete the card and lets a later dispatch start duplicate work; split the pre-run failure path from the post-run persistence/logging path once a runId exists.

Useful? React with 👍 / 👎.

@openclaw-barnacle openclaw-barnacle Bot removed the channel: sms Channel integration: sms label May 31, 2026
@steipete
steipete merged commit ed46e62 into main May 31, 2026
137 of 139 checks passed
@steipete
steipete deleted the feat/workboard-dispatch-cli-docs branch May 31, 2026 09:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

docs Improvements or additions to documentation maintainer Maintainer-authored PR merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. merge-risk: 🚨 session-state 🚨 May lose, corrupt, stale, or mis-associate session, agent, or context state. P2 Normal backlog priority with limited blast radius. plugin: workboard rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. size: XL status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant