From a566bfb9cb097698a3e3b2668a763ab5fa3a434d Mon Sep 17 00:00:00 2001 From: Codex Date: Mon, 13 Jul 2026 17:48:27 +0200 Subject: [PATCH 1/3] =?UTF-8?q?docs:=20=E8=B7=9F=E8=B8=AA=20AgentRun=20ses?= =?UTF-8?q?sion=20timeout=20=E4=BF=AE=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/MDTODO/artificer-runtime-capabilities.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/MDTODO/artificer-runtime-capabilities.md b/docs/MDTODO/artificer-runtime-capabilities.md index c2b60016..9739ab6c 100644 --- a/docs/MDTODO/artificer-runtime-capabilities.md +++ b/docs/MDTODO/artificer-runtime-capabilities.md @@ -112,3 +112,7 @@ ### R7.3 [completed] 自动上线后以新 Artificer task input 与超过 30 分钟的真实或受控 canary 验证 2 小时 budget 生效,不修改当前 Monitor run 的既有 task policy,完成任务后将详细报告写入[任务报告](./details/artificer-runtime-capabilities/R7.3_Task_Report.md)。 + +## R8 [in_progress] + +解决 [UniDesk #1944](https://github.com/pikasTech/unidesk/issues/1944):修复 Artificer Aipod 已为 2 小时但 UniDesk session follow-up 仍使用 15 分钟 hard-timeout 的配置分裂;将 `config/agentrun.yaml#client.sessionPolicy.executionPolicy.timeoutMs` 调整为 7200000 ms,在配置解析/校验中拒绝任何低于 3600000 ms 的 hard-timeout,并更新中文长期参考与最小测试;属于 AgentRun 自身运行时,必须由原生子代理执行,禁止 Artificer 递归修复,不新增第二 timeout authority、续跑补丁、锁、租约或状态机,完成任务后将详细报告写入[任务报告](./details/artificer-runtime-capabilities/R8_Task_Report.md)。 From 38efb1605c7296c37d97695ab0d91c2ec85c13bc Mon Sep 17 00:00:00 2001 From: Codex Date: Mon, 13 Jul 2026 17:57:29 +0200 Subject: [PATCH 2/3] =?UTF-8?q?fix:=20=E7=BB=9F=E4=B8=80=20AgentRun=20sess?= =?UTF-8?q?ion=20hard-timeout?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- config/agentrun.yaml | 2 +- docs/reference/agentrun.md | 12 +++++++++++- scripts/src/agentrun-events.test.ts | 2 +- scripts/src/agentrun.test.ts | 16 ++++++++++++++-- scripts/src/agentrun/config.ts | 5 ++++- 5 files changed, 31 insertions(+), 6 deletions(-) diff --git a/config/agentrun.yaml b/config/agentrun.yaml index 40714f1b..d52c08c9 100644 --- a/config/agentrun.yaml +++ b/config/agentrun.yaml @@ -44,7 +44,7 @@ client: executionPolicy: sandbox: workspace-write approval: never - timeoutMs: 900000 + timeoutMs: 7200000 network: enabled secretScope: allowCredentialEcho: false diff --git a/docs/reference/agentrun.md b/docs/reference/agentrun.md index 367dd159..d32467b5 100644 --- a/docs/reference/agentrun.md +++ b/docs/reference/agentrun.md @@ -162,7 +162,17 @@ AgentRun Kafka closeout 需要同时验证 manager 和 runner 两条生产链路 - 终态命令仍被历史 claim、heartbeat、Pod 或 `runner-dispatch-retry` 保护时,修正 retention 分类; - 禁止强杀 Job/Pod 或手工补 CI/CD。 -AgentRun resource/session client policy 也由 `config/agentrun.yaml` 声明。`client.sessionPolicy` 是未显式选择 node/lane 时 `agentrun send session/...` 和相关 session payload 生成的默认 `tenantId`、`projectId`、`providerId`、`backendProfile`、`workspaceRef` 和 execution policy 来源;显式 `--node --lane ` 后,`explain session-policy`、`send session`、resource primitives 和 AipodSpec render 都必须改用目标 lane 的 YAML 事实。lane `secrets[].providerCredential.profile` 声明 provider credential Secret 归属,UniDesk CLI 只按 YAML 聚合 Secret name/key,不再用代码拼接 provider Secret 名称。只读入口 `bun scripts/cli.ts agentrun explain session-policy` 用于查看选中目标 lane、policy 来源、实际 executionPolicy payload 和 provider credential binding 来源;输出只能包含 Secret metadata、key 名和 `valuesPrinted=false`,不得打印 Secret value。 +- AgentRun resource/session client policy: + - 由 `config/agentrun.yaml` 声明; + - `client.sessionPolicy` 是未显式选择 node/lane 时 `agentrun send session/...` 和相关 session payload 生成的默认 `tenantId`、`projectId`、`providerId`、`backendProfile`、`workspaceRef` 和 execution policy 来源; + - `client.sessionPolicy.executionPolicy.timeoutMs` 是 session follow-up hard-timeout 的唯一事实来源; + - Artificer task 与 session follow-up 统一使用 2 小时 hard-timeout; + - 低于 1 小时的 hard-timeout 配置非法,必须在配置解析阶段明确拒绝; + - 显式 `--node --lane ` 后,`explain session-policy`、`send session`、resource primitives 和 AipodSpec render 都必须改用目标 lane 的 YAML 事实; + - lane `secrets[].providerCredential.profile` 声明 provider credential Secret 归属; + - UniDesk CLI 只按 YAML 聚合 Secret name/key,不再用代码拼接 provider Secret 名称; + - 只读入口 `bun scripts/cli.ts agentrun explain session-policy` 用于查看选中目标 lane、policy 来源、实际 executionPolicy payload 和 provider credential binding 来源; + - 输出只能包含 Secret metadata、key 名和 `valuesPrinted=false`,不得打印 Secret value。 非默认 lane 的 session follow-up 必须证明 `send session` 使用的是选中 node/lane 的 run policy。使用短命令形态前,先用 `agentrun explain session-policy --node --lane [--backend-profile ]` 或等价 dry-run/describe 路径确认 `backendProfile`、`providerId`、`workspaceRef`、execution policy 和 provider credential SecretRef 都来自目标 lane;`--prompt-stdin` 短命令形态和 `--json-stdin -o json` 显式 JSON 形态应披露同一份 `sessionPolicy` 摘要。渲染结果回退到全局默认 lane、显示错误的 default lane,或短命令与 JSON body 使用不同 policy,都是 lane policy 缺陷,应修复 YAML 目标解析或 CLI 渲染;不得通过手工创建默认 lane Secret、复制凭据、改写 JSON body 或修改 runtime namespace 来掩盖 policy 选错的问题。 diff --git a/scripts/src/agentrun-events.test.ts b/scripts/src/agentrun-events.test.ts index 5d2dfec9..f4e55f70 100644 --- a/scripts/src/agentrun-events.test.ts +++ b/scripts/src/agentrun-events.test.ts @@ -42,7 +42,7 @@ const agentRunClientYaml = [ " executionPolicy:", " sandbox: workspace-write", " approval: never", - " timeoutMs: 900000", + " timeoutMs: 7200000", " network: enabled", " secretScope:", " allowCredentialEcho: false", diff --git a/scripts/src/agentrun.test.ts b/scripts/src/agentrun.test.ts index 4b94923f..85cba155 100644 --- a/scripts/src/agentrun.test.ts +++ b/scripts/src/agentrun.test.ts @@ -76,7 +76,7 @@ const agentRunClientYaml = [ " executionPolicy:", " sandbox: workspace-write", " approval: never", - " timeoutMs: 900000", + " timeoutMs: 7200000", " network: enabled", " secretScope:", " allowCredentialEcho: false", @@ -108,7 +108,7 @@ const agentRunMinimalClientYaml = [ " executionPolicy:", " sandbox: workspace-write", " approval: never", - " timeoutMs: 900000", + " timeoutMs: 7200000", " network: enabled", " secretScope:", " allowCredentialEcho: false", @@ -166,6 +166,18 @@ describe("AgentRun render-only REST client config", () => { expect(config.client.transport).toBe("direct-http"); }); + test("uses the owning YAML two-hour session hard-timeout", () => { + const config = parseAgentRunClientConfigYaml(readFileSync("config/agentrun.yaml", "utf8"), "config/agentrun.yaml"); + expect(config.client.sessionPolicy.executionPolicy.timeoutMs).toBe(7_200_000); + }); + + test("rejects a session hard-timeout below one hour", () => { + const invalid = agentRunClientYaml.replace(" timeoutMs: 7200000", " timeoutMs: 3599999"); + expect(() => parseAgentRunClientConfigYaml(invalid, "config/agentrun.yaml")).toThrow( + "client.sessionPolicy.executionPolicy.timeoutMs hard-timeout must be at least 3600000 ms", + ); + }); + test("uses env auth before configured file auth without exposing the key", () => { const config = parseAgentRunClientConfigYaml(agentRunClientYaml, "config/agentrun.yaml"); const auth = resolveAgentRunAuth(config, { HWLAB_API_KEY: "secret-value" }); diff --git a/scripts/src/agentrun/config.ts b/scripts/src/agentrun/config.ts index ea2fd6cc..8ca1c052 100644 --- a/scripts/src/agentrun/config.ts +++ b/scripts/src/agentrun/config.ts @@ -124,7 +124,10 @@ export function readAgentRunSessionPolicyConfig(client: Record, stringFieldFromRecord(workspaceRef, "kind", `${pathValue}.workspaceRef`); stringFieldFromRecord(executionPolicy, "sandbox", `${pathValue}.executionPolicy`); stringFieldFromRecord(executionPolicy, "approval", `${pathValue}.executionPolicy`); - positiveIntegerFieldFromRecord(executionPolicy, "timeoutMs", `${pathValue}.executionPolicy`); + const timeoutMs = positiveIntegerFieldFromRecord(executionPolicy, "timeoutMs", `${pathValue}.executionPolicy`); + if (timeoutMs < 3_600_000) { + throw new Error(`${sourcePath}: ${pathValue}.executionPolicy.timeoutMs hard-timeout must be at least 3600000 ms`); + } stringFieldFromRecord(executionPolicy, "network", `${pathValue}.executionPolicy`); booleanFieldFromRecord(secretScope, "allowCredentialEcho", `${pathValue}.executionPolicy.secretScope`); return { From 8fe0837fae4041d32e45743fdcf8757deaf5acdb Mon Sep 17 00:00:00 2001 From: Codex Date: Mon, 13 Jul 2026 18:00:17 +0200 Subject: [PATCH 3/3] =?UTF-8?q?docs:=20=E8=AE=B0=E5=BD=95=20R8=20timeout?= =?UTF-8?q?=20=E4=BF=AE=E5=A4=8D=E6=8A=A5=E5=91=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../R8_Task_Report.md | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 docs/MDTODO/details/artificer-runtime-capabilities/R8_Task_Report.md diff --git a/docs/MDTODO/details/artificer-runtime-capabilities/R8_Task_Report.md b/docs/MDTODO/details/artificer-runtime-capabilities/R8_Task_Report.md new file mode 100644 index 00000000..237b77e8 --- /dev/null +++ b/docs/MDTODO/details/artificer-runtime-capabilities/R8_Task_Report.md @@ -0,0 +1,33 @@ +# R8 任务报告 + +## 结论 + +已解决 [UniDesk #1944](https://github.com/pikasTech/unidesk/issues/1944) 的 AgentRun session hard-timeout 配置分裂,并创建普通 [PR #1945](https://github.com/pikasTech/unidesk/pull/1945) 等待主代理审核、合并。 + +- 唯一事实来源保持为 `config/agentrun.yaml#client.sessionPolicy.executionPolicy.timeoutMs`。 +- 默认 hard-timeout 已由 15 分钟调整为 `7200000` ms,即 2 小时。 +- 既有通用 session policy 解析入口现在拒绝任何低于 `3600000` ms 的 hard-timeout。 +- 未新增第二 timeout authority、续跑补丁、锁、租约、状态机或交付控制入口。 +- 未执行部署、人工 PipelineRun、mirror sync、rollout 或 PR merge。 + +## 实现 + +- `config/agentrun.yaml`:将 session execution policy 的 `timeoutMs` 调整为 `7200000`。 +- `scripts/src/agentrun/config.ts`:在 `readAgentRunSessionPolicyConfig` 中保留正整数校验,并增加 1 小时通用下限;非法值在解析阶段明确报错。 +- `scripts/src/agentrun.test.ts`:覆盖真实 owning YAML 的 2 小时值和 `3599999` ms 拒绝。 +- `scripts/src/agentrun-events.test.ts`:同步既有合法 fixture,避免保留旧 15 分钟事实。 +- `docs/reference/agentrun.md`:将 session hard-timeout 的唯一 authority、2 小时口径和 1 小时配置下限固化为中文长期参考。 + +## 验证 + +- `bun test scripts/src/agentrun.test.ts scripts/src/agentrun-events.test.ts`:25 pass,0 fail,557 assertions。 +- `bun --check scripts/src/agentrun/config.ts`:通过。 +- `UNIDESK_AGENTRUN_TARGET_EXECUTED=NC01 bun scripts/cli.ts agentrun explain session-policy -o json`:选中 `NC01/nc01-v02`,`POLICY SOURCE=selected-lane`,effective `timeoutMs=7200000`,Secret 仅披露 metadata 且 `valuesPrinted=false`。 +- `git diff --check`:通过。 + +## 工件 + +- 实现 commit:`38efb160`。 +- PR:[pikasTech/unidesk#1945](https://github.com/pikasTech/unidesk/pull/1945)。 +- Issue:[pikasTech/unidesk#1944](https://github.com/pikasTech/unidesk/issues/1944)。 +- MDTODO:`docs/MDTODO/artificer-runtime-capabilities.md` R8。