Scope agent cron operations to the calling agent#96883
Conversation
|
Codex review: needs maintainer review before merge. Reviewed June 26, 2026, 10:31 PM ET / 02:31 UTC. Summary PR surface: Source +916, Tests +1471, Config +1, Other +328. Total +2716 across 59 files. Reproducibility: yes. at source level: current main creates the MCP cron tool without a session key, sends agent Gateway cron calls without agent identity, and cron handlers mutate by job id without caller scope. I did not run a local failing scenario in this read-only pass. Review metrics: 3 noteworthy metrics.
Stored data model Root-cause cluster Members:
Proposal only: this assessment does not dispatch repair, suppress jobs, mutate sibling items, close, or merge anything. Merge readiness Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch. Risk before merge
Maintainer options:
Next step before merge
Security Review detailsBest possible solution: Land this scoped mitigation only after maintainers accept the internal Gateway auth field, managed MCP session-key env contract, and fail-closed mixed-version behavior while keeping the broader scheduling RFC open. Do we have a high-confidence way to reproduce the issue? Yes, at source level: current main creates the MCP cron tool without a session key, sends agent Gateway cron calls without agent identity, and cron handlers mutate by job id without caller scope. I did not run a local failing scenario in this read-only pass. Is this the best way to solve the issue? Mostly yes: the mitigation is enforced at tool assembly, the local Gateway client, Gateway handshake, ACPX managed bridge, and cron handlers. The remaining question is maintainer acceptance of the compatibility and security-boundary contracts, not a narrow code defect. AGENTS.md: found and applied where relevant. Codex review notes: model internal, reasoning high; reviewed against 552ec2b49d4a. Label changesLabel justifications:
Evidence reviewedPR surface: Source +916, Tests +1471, Config +1, Other +328. Total +2716 across 59 files. View PR surface stats
What I checked:
Likely related people:
What the crustacean ranks mean
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
|
…files + finish conflict cleanup Phase-2 silent-keep-ours review (merge=ours discards upstream's changes with no conflict). 3 parallel reviewers triaged the 17 guarded prod files upstream touched; grafted the 14 with real value, several of which fixed features the partial merge left BROKEN (backend/consumers merged, producer discarded): - agent-tools.before-tool-call.ts: unify the before_tool_call marker Symbols onto the net-new before-tool-call-metadata.js (the partial merge created a split-brain where 5 modules read a different Symbol set → marker copy silently no-op'd). - message-handler.ts + openclaw-tools.ts: restore the openclaw#96883 agent-runtime cron scoping (verify agentRuntimeIdentity token / establish the ambient identity); consumers had merged but both producers were discarded → feature inert. - skills.ts + agents-models-skills schema + app-render/app/app-view-state: wire the ClawHub risk-acknowledge install end-to-end (backend + controller + view merged; the gateway handler, schema gate, and the UI onClawHubInstall args were missing → acknowledge button re-failed). - edit/edit-diff/write/apply-patch: adopt upstream's no-op edit/write/patch = terminal result (the upstream tests had merged and were red; now green). - bash-tools.exec-runtime.ts: finalize the sandbox exec on spawn-failure paths (was leaking; only clean exit finalized). - google-shared.ts: only promote toolCall→toolUse on stopReason===stop (a MAX_TOKENS-truncated partial call must not become an executable turn). - subagent-registry.ts: let wakeOnDescendantSettle orchestrators reach the wake path past the yield gate. KEEP (no graft): bash-tools.exec.ts (fork superseded the deferral machinery), sandbox.ts (already converged). Also finished the merge conflict cleanup: drop the unused upstream assistant- message-update helpers from agent-loop.ts (fork uses only removeNonExecutableToolCalls) and the unused assignTransportErrorDetails import. tsgo:core/extensions at the pre-merge baseline (error-set diff); missing-export scan clean; edit/write/apply-patch + exec-runtime + gateway-caller-identity tests green. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
* Scope agent cron operations to caller * Scope OpenClaw tools MCP cron by session * Address cron scope review feedback * Preserve unscoped cron update retargeting * Move cron caller identity into gateway context * Clarify Gateway restart guidance * Add cron caller identity regression proof
* Scope agent cron operations to caller * Scope OpenClaw tools MCP cron by session * Address cron scope review feedback * Preserve unscoped cron update retargeting * Move cron caller identity into gateway context * Clarify Gateway restart guidance * Add cron caller identity regression proof
* Scope agent cron operations to caller * Scope OpenClaw tools MCP cron by session * Address cron scope review feedback * Preserve unscoped cron update retargeting * Move cron caller identity into gateway context * Clarify Gateway restart guidance * Add cron caller identity regression proof
The Gateway caller-identity pattern established in openclaw/openclaw#96883 is the seam this RFC's session-scoped attribution builds on. Co-Authored-By: Claude Opus 4 <[email protected]>
What Problem This Solves
Agent-originated cron tool operations now carry the calling agent identity through the Gateway cron API, so cron reads and mutations made from an agent tool session are limited to that same agent's jobs.
Why This Change Was Made
Cron APIs are also used by operator and internal flows, so this keeps the existing unscoped/operator behavior unchanged while adding an explicit scope only for agent-tool calls. The Gateway enforces the scope server-side, and the agent cron tool stamps newly created jobs with the calling agent before persistence.
User Impact
Existing cron configurations and operator-managed cron jobs should continue to work normally. The new scope is only applied to agent-tool cron calls; direct unscoped cron RPC callers retain the current global behavior.
Agent-tool cron calls can still create, list, update, run, inspect history for, and remove jobs owned by the calling agent. Attempts from that path to target another agent's jobs or session references are rejected.
If a running older Gateway rejects the new internal agent cron connection metadata, the agent-facing error now remains fail-closed and tells the user to restart the Gateway with
openclaw gateway restartbefore retrying. Installer and Control UI update paths also surface an explicit manual Gateway restart/update command when an automatic handoff cannot be completed.Evidence
pnpm buildgit diff --check origin/main...HEADnode scripts/run-vitest.mjs packages/gateway-protocol/src/cron-validators.test.ts src/gateway/server-methods/cron.validation.test.ts src/gateway/server.cron.test.ts src/agents/tools/cron-tool.test.ts src/agents/tools/cron-tool.flat-params.test.tsed53735bc561fa51fba75e292071fedc88827a11):blacksmith-testboxtbx_01kw0rg2xd3ek7jdgkf411k3wqblacksmith-testboxtbx_01kw0rg159zn0myaxqvvxhxemmblacksmith-testboxtbx_01kw0qk6n3ye3v3e5gmx5x5y87cron-single-run-no-duplicate,cron-natural-fire-no-duplicate,personal-reminder-roundtripcallerScopeis not persisted into stored cron jobsLatest validation after restart/update guidance changes (
543705877f):git diff --checkbash -n scripts/install.sh && bash -n scripts/install-cli.shnode scripts/run-tsgo.mjs -b tsconfig.projects.jsonpwshwas not installed, so directinstall.ps1parse was skipped locally; the PowerShell installer Vitest coverage above passed.blacksmith-testboxtbx_01kw2sxj346th07qtc8akrez78Final production-path validation after
b9b90fef12:pnpm test:docker:cron-cli, coveringcron status,add,list,show,disable,enable,run --wait,runs, andrmthrough the packaged CLI against a packaged Gateway.src/agents/openclaw-tools.gateway-caller-identity.test.ts.pnpm buildpassed:blacksmith-testboxtbx_01kw307fpaght5rr6f3t002wg3blacksmith-testboxtbx_01kw31d4xg3n89qekrfsjta017blacksmith-testboxtbx_01kw31wm36fwch2mxkbcv0ztfzblacksmith-testboxtbx_01kw323nafqv6vmwrajq84qhch2026.6.10,2026.6.9,2026.6.8,2026.6.6):blacksmith-testboxtbx_01kw32h1kwbp8ajzxz02xvjkfqblacksmith-testboxtbx_01kw3919zh8b7enbjm060b2kgtblacksmith-testboxtbx_01kw395dv0sb7367f1dse79wtzblacksmith-testboxtbx_01kw39kt3tde4ns1wd6cz7q9bwbash -n scripts/e2e/cron-cli-docker.shnode scripts/run-vitest.mjs test/scripts/docker-e2e-observability.test.ts -- --reporter=verbosegit diff --checkautoreview clean: no accepted/actionable findings reportedAdditional packaged cron lifecycle soak:
blacksmith-testboxtbx_01kw3dndfsbm8p1wz7rbv4jc2w