惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
V
Visual Studio Blog
The GitHub Blog
The GitHub Blog
Apple Machine Learning Research
Apple Machine Learning Research
J
Java Code Geeks
T
Tailwind CSS Blog
大猫的无限游戏
大猫的无限游戏
Jina AI
Jina AI
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Hugging Face - Blog
Hugging Face - Blog
WordPress大学
WordPress大学
宝玉的分享
宝玉的分享
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
罗磊的独立博客
人人都是产品经理
人人都是产品经理
H
Heimdal Security Blog
Last Week in AI
Last Week in AI
博客园 - 【当耐特】
Cyberwarzone
Cyberwarzone
Google DeepMind News
Google DeepMind News
雷峰网
雷峰网
Hacker News: Ask HN
Hacker News: Ask HN
Webroot Blog
Webroot Blog
Microsoft Azure Blog
Microsoft Azure Blog
MyScale Blog
MyScale Blog
A
About on SuperTechFans
V2EX - 技术
V2EX - 技术
小众软件
小众软件
博客园 - Franky
博客园 - 司徒正美
P
Privacy International News Feed
爱范儿
爱范儿
U
Unit 42
博客园 - 叶小钗
The Hacker News
The Hacker News
C
Check Point Blog
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Simon Willison's Weblog
Simon Willison's Weblog
N
News and Events Feed by Topic
D
Docker
T
Threatpost
MongoDB | Blog
MongoDB | Blog
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
H
Help Net Security
L
LINUX DO - 最新话题
Security Latest
Security Latest
T
The Exploit Database - CXSecurity.com
S
SegmentFault 最新的问题
A
Arctic Wolf
Spread Privacy
Spread Privacy

Recent Commits to openclaw:main

test: merge chat side-result checks · openclaw/openclaw@ddd2c2a test: merge cron history checks · openclaw/openclaw@f7eb746 test: merge responsive navigation shell checks · openclaw/openclaw@c2e4b47 docs(changelog): add codex oauth fixes · openclaw/openclaw@628e6cd test: merge navigation routing cases · openclaw/openclaw@5d8cecb Tests: mock channel registry bundled fallback · openclaw/openclaw@2b08233 Secrets: avoid broad web search discovery for single plugin config · openclaw/openclaw@a464f59 test: merge config view browser checks · openclaw/openclaw@20cf511 fix(status): align oauth health with runtime · openclaw/openclaw@eed7116 feat: add macOS screen snapshots for monitor preview (#67954) thanks … · openclaw/openclaw@f377db1 fix: report shared auth scopes in hello-ok (#67810) thanks @BunsDev · openclaw/openclaw@0b6c39b Auto-reply: avoid eager bundled route fallback · openclaw/openclaw@3ea1bf4 Tests: narrow session binding contract setup · openclaw/openclaw@54e4e16 fix(macOS): enable undo/redo in webchat composer text input (#34962) · openclaw/openclaw@00951dc Tests: speed up channel setup promotion · openclaw/openclaw@82b529a Docs: refresh agent instructions · openclaw/openclaw@5775fe2 fix(auth): serialize OAuth refresh across agents to fix #26322 (#67876) · openclaw/openclaw@8e79080 test: allow ollama public surface boundary test · openclaw/openclaw@7d4f1a6 Docs: add test performance guardrails · openclaw/openclaw@89706d3 Tests: restore context-engine usage proof · openclaw/openclaw@e4c4f95 Tests: slim context engine runtime coverage · openclaw/openclaw@74c198f ci: retry failed custom checkouts · openclaw/openclaw@0ee5baf test: trim duplicate provider auth onboarding cases · openclaw/openclaw@1ffc02e matrix: fix sessions_spawn --thread subagent session spawning (#67643) · openclaw/openclaw@1ce2596 test: reduce auth choice fixture churn · openclaw/openclaw@857b9cd test: mock health status config boundaries · openclaw/openclaw@9d5ab4a test: mock onboard config io boundary · openclaw/openclaw@299694d test: mock legacy state plugin boundaries · openclaw/openclaw@2713089 test: mock channel install boundaries · openclaw/openclaw@b945248 test: mock doctor preview channel boundaries · openclaw/openclaw@b1a3ad4 test: trim doctor command hotspots · openclaw/openclaw@c66f16a test: isolate agent auth and spawn hotspots · openclaw/openclaw@9285935 test: stabilize MCP startup disposal race · openclaw/openclaw@dd9d2eb test: merge browser contract server suites · openclaw/openclaw@5817a76 test: narrow ollama provider discovery setup · openclaw/openclaw@a0d9598 build: declare qa-lab aimock runtime dependency · openclaw/openclaw@24431e5 test: speed up safe-bins exec harness · openclaw/openclaw@ee856ab test: preserve tool helpers in embedded runner mocks · openclaw/openclaw@acd86a0 refactor: move memory embeddings into provider plugins · openclaw/openclaw@77e6e4c test: reuse system-run temp fixtures · openclaw/openclaw@7e9ff0f test: trim hotspot wait overhead · openclaw/openclaw@12a59b0 Check: avoid duplicate boundary prep · openclaw/openclaw@baf11b8 test: reduce hotspot fixture overhead · openclaw/openclaw@3a59edd feat(ui): overhaul settings and slash command UX (#67819) thanks @Bun… · openclaw/openclaw@2cfb660 QA Matrix: exit cleanly on failure · openclaw/openclaw@42805d2 QA Matrix: isolate scenario coverage · openclaw/openclaw@7e659e1 Matrix: refresh crypto bootstrap state · openclaw/openclaw@94081d8 QA Lab: add provider registry · openclaw/openclaw@bb7e982 Matrix: add plugin changelog · openclaw/openclaw@4acab55 test: trim more hotspot overhead · openclaw/openclaw@f485311 test: trim remaining hotspot tests · openclaw/openclaw@6ba8626 test: narrow hotspot mocks · openclaw/openclaw@dbc8179 test: isolate gemini embedding request helpers · openclaw/openclaw@cd330f5 test: trim memory and mcp hotspots · openclaw/openclaw@fd48dfa test: slim provider registry mocks · openclaw/openclaw@2e08c77 test: harden Parallels update smoke · openclaw/openclaw@1a98090 feat: default Anthropic to Opus 4.7 · openclaw/openclaw@628b454 fix: harden node-host shell payload mutability checks · openclaw/openclaw@75c551e fix: land node-host approval binding for native binaries (#66731) (th… · openclaw/openclaw@29919bb CI: add daily schedule to CodeQL workflow (#67645) · openclaw/openclaw@69d25f5 fix(gateway): capture config hash after plugin auto-enable to prevent… · openclaw/openclaw@8c11210 fix: repair sanitized replay tool results before send (#67620) (thank… · openclaw/openclaw@c3c7a99 fix: restrict HTML timeout short-circuit to transient statuses · openclaw/openclaw@de129a6 fix: keep TUI watchdog bound to active run (#67401) (thanks @xantorres) · openclaw/openclaw@3525273 Gateway/skills: dedupe skills prefix-match + drop dead fallback on log · openclaw/openclaw@d7f489f Extensions/lmstudio: back off inference preload after consecutive fai… · openclaw/openclaw@b555214 TUI/streaming: add watchdog that resets the activity indicator after … · openclaw/openclaw@f44ab20 Agents/tool-loop: enable unknown-tool stream guard by default · openclaw/openclaw@36ed367 Gateway/skills: invalidate session skills snapshot on config write · openclaw/openclaw@b23d59a fix: classify HTML provider error pages correctly (#67642) (thanks @s… · openclaw/openclaw@e588e90 fix(skills): remove unused model-usage import (#67641) · openclaw/openclaw@55f05df docs(changelog): credit codex fix superseded PRs · openclaw/openclaw@e485f24 fix(openai-codex): normalize stale transport metadata in resolution a… · openclaw/openclaw@90801ba CI: pin Docker-related GitHub Actions (#67632) · openclaw/openclaw@f697b01 Android: modernize WebView and discovery API usage (#67627) · openclaw/openclaw@44a6e50 fix(deps): bump hono to 4.12.14 and @hono/node-server to 1.19.14 (GHS… · openclaw/openclaw@fbccc18 fix(deps): bump dompurify to 3.4.0 (#67614) · openclaw/openclaw@2c2dc00 CI: add explicit permissions to all workflow jobs (fixes code-scannin… · openclaw/openclaw@01b7516 fix: register bundled TTS providers and route overrides correctly (#6… · openclaw/openclaw@6ea3cdd fix: align host tilde paths with OS home (#62804) (thanks @stainlu) · openclaw/openclaw@ecfaf64 fix: flush creds queue before reconnect socket open (#67464) (thanks … · openclaw/openclaw@405c63f fix: strip standalone <function> tool call tags from visible text (#6… · openclaw/openclaw@78df859 fix(agents): preserve cli session metadata before transcript persist … · openclaw/openclaw@898fd04 docs(changelog): move cli transcript entry · openclaw/openclaw@c1817c6 fix(agents): normalize cli transcript api field · openclaw/openclaw@3a3fae0 docs(changelog): note cli transcript persistence · openclaw/openclaw@6c343f1 fix(agents): persist cli transcript turns · openclaw/openclaw@b8ef507 fix(msteams): harden security-sensitive flows (#65841) · openclaw/openclaw@c56b56e [Dashboard] Fix exec approval modal overflow for long command content… · openclaw/openclaw@053c5b0 Docs: remove QA changelog entry · openclaw/openclaw@7fd5771 QA: fix private runtime source loading (#67428) · openclaw/openclaw@d5933af docs(gateway): correct protocol.md schema path, hello-ok example, aut… · openclaw/openclaw@489404d CI: pin Node 22 runners to 22.18.0 · openclaw/openclaw@4ffa621 models.authStatus: normalize provider ids + tighten env-backed escape… · openclaw/openclaw@f2fdb9d Update CHANGELOG.md · openclaw/openclaw@7694a92 test(parallels): clean up npm update guard jobs · openclaw/openclaw@045ea7b Plugins: prefer scanDir override paths · openclaw/openclaw@b2974da fix(dreaming): default storage.mode to "separate" so phase blocks sto… · openclaw/openclaw@8c392f0 fix(memory-core): skip dreaming transcript ingestion via session stor… · openclaw/openclaw@a1b01f0 fix: dedupe replayed exec.finished node events (#67281) · openclaw/openclaw@5dcf526
fix(cron): stop stamping an unenforceable default toolsAllow cap on C… · openclaw/openclaw@9aea104
anagnorisis2 · 2026-06-24 · via Recent Commits to openclaw:main
Original file line numberDiff line numberDiff line change

@@ -27,6 +27,12 @@ function cronAgentTurnPayloadSchema(params: {

2727

allowUnsafeExternalContent: Type.Optional(Type.Boolean()),

2828

lightContext: Type.Optional(Type.Boolean()),

2929

toolsAllow: Type.Optional(params.toolsAllow),

30+

// Server-managed marker: set when toolsAllow is an auto-applied creator

31+

// default (vs an explicit per-cron restriction). The cron tool stamps it,

32+

// and it round-trips through persistence so a CLI-resolved run can drop an

33+

// unenforceable default cap. Must be on the wire contract or the stamped

34+

// payload is rejected by additionalProperties:false.

35+

toolsAllowIsDefault: Type.Optional(Type.Boolean()),

3036

},

3137

{ additionalProperties: false },

3238

);

Original file line numberDiff line numberDiff line change

@@ -2167,6 +2167,7 @@ describe("cron tool", () => {

21672167

expect(params?.patch?.payload).toEqual({

21682168

kind: "agentTurn",

21692169

toolsAllow: ["read", "cron"],

2170+

toolsAllowIsDefault: true,

21702171

});

21712172

});

21722173

@@ -2202,6 +2203,7 @@ describe("cron tool", () => {

22022203

payload: {

22032204

kind: "agentTurn",

22042205

toolsAllow: ["read", "cron"],

2206+

toolsAllowIsDefault: true,

22052207

},

22062208

},

22072209

},

@@ -2278,6 +2280,51 @@ describe("cron tool", () => {

22782280

});

22792281

});

22802282
2283+

it("preserves the default toolsAllow flag across an update that omits toolsAllow", async () => {

2284+

// Regression guard: a routine update (here, toggling enabled) of an

2285+

// agentTurn job whose cap was an auto-stamped default must keep

2286+

// toolsAllowIsDefault set. Otherwise the run-time CLI drop (which keys off

2287+

// the flag) stops applying and the job fails closed again after a restart —

2288+

// re-breaking the exact #91499 regression this change fixes.

2289+

callGatewayMock

2290+

.mockResolvedValueOnce({

2291+

id: "job-13",

2292+

payload: {

2293+

kind: "agentTurn",

2294+

message: "hi",

2295+

toolsAllow: ["read", "cron"],

2296+

toolsAllowIsDefault: true,

2297+

},

2298+

})

2299+

.mockResolvedValueOnce({ ok: true });

2300+
2301+

const tool = createTestCronTool({

2302+

agentSessionKey: "agent:main:telegram:group:restricted-room",

2303+

creatorToolAllowlist: ["read", "cron"],

2304+

});

2305+

await tool.execute("call-update-preserve-default-flag", {

2306+

action: "update",

2307+

id: "job-13",

2308+

patch: { enabled: false },

2309+

});

2310+
2311+

expect(callGatewayMock).toHaveBeenCalledTimes(2);

2312+

expect(readGatewayCall(1)).toEqual({

2313+

method: "cron.update",

2314+

params: {

2315+

id: "job-13",

2316+

patch: {

2317+

enabled: false,

2318+

payload: {

2319+

kind: "agentTurn",

2320+

toolsAllow: ["read", "cron"],

2321+

toolsAllowIsDefault: true,

2322+

},

2323+

},

2324+

},

2325+

});

2326+

});

2327+
22812328

it("adds the creator tool surface when converting an existing job to agentTurn", async () => {

22822329

callGatewayMock

22832330

.mockResolvedValueOnce({

@@ -2310,6 +2357,7 @@ describe("cron tool", () => {

23102357

kind: "agentTurn",

23112358

message: "run later",

23122359

toolsAllow: ["read", "cron"],

2360+

toolsAllowIsDefault: true,

23132361

},

23142362

},

23152363

},

Original file line numberDiff line numberDiff line change

@@ -465,18 +465,28 @@ function capCronAgentTurnToolsAllow(params: {

465465

? params.payload.toolsAllow

466466

: params.defaultToolsAllow;

467467

if (!Array.isArray(requestedRaw)) {

468+

// No explicit user toolsAllow: stamp the full creator surface as the default

469+

// cap and flag it so a CLI-resolved run (which cannot enforce a runtime

470+

// toolsAllow) drops it rather than failing to start.

468471

params.payload.toolsAllow = creatorToolNames;

472+

params.payload.toolsAllowIsDefault = true;

469473

return;

470474

}

471475

const requestedToolsAllow = normalizeCronToolsAllow(

472476

requestedRaw.filter((entry): entry is string => typeof entry === "string"),

473477

);

474478

if (requestedToolsAllow.length === 0) {

479+

// Explicit empty allow-list is a real restriction (no tools): keep it

480+

// fail-closed, never flagged as a droppable default.

475481

params.payload.toolsAllow = [];

482+

delete params.payload.toolsAllowIsDefault;

476483

return;

477484

}

478485

if (requestedToolsAllow.includes("*")) {

486+

// Wildcard requests the creator's full surface with no narrowing — a

487+

// non-restrictive default, droppable on a non-enforcing CLI backend.

479488

params.payload.toolsAllow = creatorToolNames;

489+

params.payload.toolsAllowIsDefault = true;

480490

return;

481491

}

482492

const pluginGroups = buildPluginToolGroups({

@@ -487,9 +497,13 @@ function capCronAgentTurnToolsAllow(params: {

487497

{ allow: requestedToolsAllow },

488498

pluginGroups,

489499

);

500+

// Explicit narrowing restriction: keep it fail-closed (no default flag) so a

501+

// CLI backend that cannot enforce it surfaces the error instead of silently

502+

// widening the requested tool surface.

490503

params.payload.toolsAllow = creatorToolNames.filter((toolName) =>

491504

isToolAllowedByPolicyName(toolName, requestedPolicy),

492505

);

506+

delete params.payload.toolsAllowIsDefault;

493507

}

494508
495509

function capCronAgentTurnJobToolsAllow(

@@ -549,8 +563,17 @@ async function capCronAgentTurnUpdatePatchToolsAllow(params: {

549563

capCronAgentTurnToolsAllow({

550564

payload: nextPayload,

551565

creatorToolAllowlist: params.creatorToolAllowlist,

566+

// Carry the existing cap forward across a no-toolsAllow update ONLY when it

567+

// was an explicit per-cron restriction. A previously auto-stamped default

568+

// (toolsAllowIsDefault === true) must NOT be carried forward as a literal

569+

// value: that would route it through the explicit-narrowing branch, strip

570+

// the default flag, and re-break the job on a CLI backend after the next

571+

// restart (the run-time drop keys off the flag). Omitting it lets the cap

572+

// be re-derived as a flagged default from the current creator surface.

552573

defaultToolsAllow:

553-

existingPayloadKind === "agentTurn" && isRecord(existingPayload)

574+

existingPayloadKind === "agentTurn" &&

575+

isRecord(existingPayload) &&

576+

existingPayload.toolsAllowIsDefault !== true

554577

? existingPayload.toolsAllow

555578

: undefined,

556579

});

Original file line numberDiff line numberDiff line change

@@ -161,8 +161,30 @@ function buildCronDeliveryTargetRuntimeContext(params: {

161161

].join("\n");

162162

}

163163
164-

function resolveCliRuntimeToolsAllow(toolsAllow?: string[]): string[] | undefined {

165-

return toolsAllow?.some((toolName) => normalizeToolName(toolName) === "*")

164+

function resolveCliRuntimeToolsAllow(

165+

toolsAllow?: string[],

166+

toolsAllowIsDefault?: boolean,

167+

): string[] | undefined {

168+

if (toolsAllow === undefined) {

169+

return undefined;

170+

}

171+

// CLI backends do not enforce a runtime toolsAllow: cli-runner/prepare.ts

172+

// rejects any defined allow-list, and a CLI backend runs with its own

173+

// configured tool set as the operator on the local machine — it is not a

174+

// runtime tool-policy boundary. #91499 auto-stamps the creator surface as a

175+

// *default* cap on agentTurn payloads (toolsAllowIsDefault); on a CLI backend

176+

// that default is unenforceable theatre, so drop it and let the scheduled run

177+

// proceed instead of failing to start.

178+

//

179+

// An EXPLICIT per-cron restriction (the user narrowed this job; no isDefault

180+

// flag) is deliberately NOT dropped: it falls through and prepare.ts fails it

181+

// closed, surfacing that the requested policy needs an embedded runtime. So

182+

// only the unenforceable inherited default is relaxed on CLI; explicit intent

183+

// is still honoured.

184+

if (toolsAllowIsDefault) {

185+

return undefined;

186+

}

187+

return toolsAllow.some((toolName) => normalizeToolName(toolName) === "*")

166188

? undefined

167189

: toolsAllow;

168190

}

@@ -326,7 +348,10 @@ export function createCronPromptExecutor(params: {

326348

messageChannel,

327349

sourceReplyDeliveryMode,

328350

requireExplicitMessageTarget: params.sourceDelivery.messageTool.requireExplicitTarget,

329-

toolsAllow: resolveCliRuntimeToolsAllow(params.agentPayload?.toolsAllow),

351+

toolsAllow: resolveCliRuntimeToolsAllow(

352+

params.agentPayload?.toolsAllow,

353+

params.agentPayload?.toolsAllowIsDefault,

354+

),

330355

abortSignal: params.abortSignal,

331356

onExecutionStarted: params.onExecutionStarted,

332357

onExecutionPhase: params.onExecutionPhase,

Original file line numberDiff line numberDiff line change

@@ -825,6 +825,41 @@ describe("runCronIsolatedAgentTurn message tool policy", () => {

825825

expect(cliRun.prompt).toContain("Message delivery destination metadata");

826826

});

827827
828+

it("drops the auto-applied default toolsAllow cap for CLI-backed runs instead of failing", async () => {

829+

// A CLI backend cannot enforce a runtime toolsAllow, so the auto-applied

830+

// creator-surface cap (#91499, flagged toolsAllowIsDefault) is dropped at

831+

// run time rather than handed to the CLI runner — which would otherwise

832+

// reject the run. An explicit user restriction (no flag) is still

833+

// propagated; see the "restricted toolsAllow" case above.

834+

mockRunCronFallbackPassthrough();

835+

resolveCronDeliveryPlanMock.mockReturnValue(makeAnnounceDeliveryPlan());

836+

isCliProviderMock.mockReturnValue(true);

837+

runCliAgentMock.mockResolvedValue({

838+

payloads: [{ text: "done" }],

839+

meta: { agentMeta: { usage: { input: 10, output: 20 } } },

840+

});

841+
842+

await runCronIsolatedAgentTurn({

843+

...makeParams(),

844+

job: makeMessageToolPolicyJob(

845+

{ mode: "announce", channel: "messagechat", to: "123" },

846+

{

847+

kind: "agentTurn",

848+

message: "send a message",

849+

toolsAllow: ["read", "cron"],

850+

toolsAllowIsDefault: true,

851+

},

852+

),

853+

});

854+
855+

const cliRun = expectRecordFields(

856+

getMockCallArg(runCliAgentMock, 0, 0, "CLI run"),

857+

{},

858+

"CLI run params",

859+

);

860+

expect(cliRun.toolsAllow).toBeUndefined();

861+

});

862+
828863

it("keeps automatic exec completion notifications when announce delivery is active", async () => {

829864

mockRunCronFallbackPassthrough();

830865

resolveCronDeliveryPlanMock.mockReturnValue(makeAnnounceDeliveryPlan());

Original file line numberDiff line numberDiff line change

@@ -522,6 +522,48 @@ describe("cron store", () => {

522522

});

523523

});

524524
525+

it("round-trips the toolsAllow default-cap flag through SQLite", async () => {

526+

// The flag must survive a gateway restart: without it, a CLI-resolved run

527+

// would re-hit the prepare.ts toolsAllow rejection after reload (#91499).

528+

const store = await makeStorePath();

529+

const payload = makeStore("tools-allow-default-job", true);

530+

payload.jobs[0].sessionTarget = "isolated";

531+

payload.jobs[0].payload = {

532+

kind: "agentTurn",

533+

message: "scheduled continuation",

534+

toolsAllow: ["read", "cron"],

535+

toolsAllowIsDefault: true,

536+

};

537+
538+

await saveCronStore(store.storePath, payload);

539+
540+

expect((await loadCronStore(store.storePath)).jobs[0]?.payload).toMatchObject({

541+

kind: "agentTurn",

542+

toolsAllow: ["read", "cron"],

543+

toolsAllowIsDefault: true,

544+

});

545+

});

546+
547+

it("does not persist a default-cap flag for an explicit toolsAllow restriction", async () => {

548+

// An explicit user restriction is fail-closed: it carries no flag, so a CLI

549+

// run still surfaces the prepare.ts rejection rather than silently dropping

550+

// the requested policy.

551+

const store = await makeStorePath();

552+

const payload = makeStore("tools-allow-explicit-job", true);

553+

payload.jobs[0].sessionTarget = "isolated";

554+

payload.jobs[0].payload = {

555+

kind: "agentTurn",

556+

message: "scheduled continuation",

557+

toolsAllow: ["read"],

558+

};

559+
560+

await saveCronStore(store.storePath, payload);

561+
562+

const reloaded = (await loadCronStore(store.storePath)).jobs[0]?.payload;

563+

expect(reloaded).toMatchObject({ kind: "agentTurn", toolsAllow: ["read"] });

564+

expect(reloaded && "toolsAllowIsDefault" in reloaded).toBe(false);

565+

});

566+
525567

it("round-trips command payloads through SQLite", async () => {

526568

const store = await makeStorePath();

527569

const payload = makeStore("command-job", true);

Original file line numberDiff line numberDiff line change

@@ -75,6 +75,7 @@ export function bindPayloadColumns(

7575

| "payload_thinking"

7676

| "payload_timeout_seconds"

7777

| "payload_tools_allow_json"

78+

| "payload_tools_allow_is_default"

7879

> {

7980

if (payload.kind === "systemEvent") {

8081

return {

@@ -88,6 +89,7 @@ export function bindPayloadColumns(

8889

payload_external_content_source_json: null,

8990

payload_light_context: null,

9091

payload_tools_allow_json: null,

92+

payload_tools_allow_is_default: null,

9193

};

9294

}

9395

if (payload.kind === "command") {

@@ -103,6 +105,7 @@ export function bindPayloadColumns(

103105

payload_external_content_source_json: null,

104106

payload_light_context: null,

105107

payload_tools_allow_json: null,

108+

payload_tools_allow_is_default: null,

106109

};

107110

}

108111

return {

@@ -116,6 +119,12 @@ export function bindPayloadColumns(

116119

payload_external_content_source_json: serializeJson(payload.externalContentSource),

117120

payload_light_context: booleanToInteger(payload.lightContext),

118121

payload_tools_allow_json: serializeJson(payload.toolsAllow),

122+

// Persist whether toolsAllow is the auto-applied creator-surface default

123+

// (#91499) so a CLI-resolved run can drop the unenforceable cap after a

124+

// restart instead of failing. Only meaningful when toolsAllow is set.

125+

payload_tools_allow_is_default: payload.toolsAllow

126+

? booleanToInteger(payload.toolsAllowIsDefault)

127+

: null,

119128

};

120129

}

121130

@@ -144,6 +153,10 @@ export function payloadFromRow(row: CronJobRow): CronPayload | null {

144153

const toolsAllow = row.payload_tools_allow_json

145154

? parseJsonArray(row.payload_tools_allow_json)

146155

: undefined;

156+

const toolsAllowIsDefault =

157+

row.payload_tools_allow_is_default != null

158+

? integerToBoolean(row.payload_tools_allow_is_default)

159+

: undefined;

147160

return {

148161

kind: "agentTurn",

149162

message: row.payload_message,

@@ -155,6 +168,7 @@ export function payloadFromRow(row: CronJobRow): CronPayload | null {

155168

...(externalContentSource ? { externalContentSource } : {}),

156169

...(lightContext != null ? { lightContext } : {}),

157170

...(toolsAllow ? { toolsAllow } : {}),

171+

...(toolsAllow && toolsAllowIsDefault ? { toolsAllowIsDefault: true } : {}),

158172

};

159173

}

160174

if (row.payload_kind === "command") {

Original file line numberDiff line numberDiff line change

@@ -248,6 +248,14 @@ type CronAgentTurnPayloadFields = {

248248

lightContext?: boolean;

249249

/** Optional tool allow-list; when set, only these tools are sent to the model. */

250250

toolsAllow?: string[];

251+

/**

252+

* Set by the server when `toolsAllow` is the auto-applied creator-surface cap

253+

* (#91499) rather than an explicit user restriction. CLI backends cannot

254+

* enforce a runtime `toolsAllow`, so a CLI-resolved run drops this default cap

255+

* (it is unenforceable) instead of failing; an explicit user restriction has

256+

* no flag and stays fail-closed. Not user-settable.

257+

*/

258+

toolsAllowIsDefault?: boolean;

251259

};

252260
253261

type CronAgentTurnPayload = {

Original file line numberDiff line numberDiff line change

@@ -288,6 +288,7 @@ export interface CronJobs {

288288

payload_model: string | null;

289289

payload_thinking: string | null;

290290

payload_timeout_seconds: number | null;

291+

payload_tools_allow_is_default: number | null;

291292

payload_tools_allow_json: string | null;

292293

running_at_ms: number | null;

293294

runtime_updated_at_ms: number | null;

Original file line numberDiff line numberDiff line change

@@ -712,6 +712,7 @@ function ensureAdditiveStateColumns(db: DatabaseSync): void {

712712

ensureColumn(db, "cron_jobs", "payload_external_content_source_json TEXT");

713713

ensureColumn(db, "cron_jobs", "payload_light_context INTEGER");

714714

ensureColumn(db, "cron_jobs", "payload_tools_allow_json TEXT");

715+

ensureColumn(db, "cron_jobs", "payload_tools_allow_is_default INTEGER");

715716

ensureColumn(db, "cron_jobs", "delivery_mode TEXT");

716717

ensureColumn(db, "cron_jobs", "delivery_channel TEXT");

717718

ensureColumn(db, "cron_jobs", "delivery_to TEXT");