merge: maestro/tsk_oTFzOMeAU20D [tsk_oTFzOMeAU20D]

This commit is contained in:
maestro
2026-06-13 15:51:31 +08:00
4 changed files with 546 additions and 2 deletions
+10 -2
View File
@@ -7,6 +7,7 @@ import { rankByScore } from '../model/scoring.js';
import { branchFor, worktreeDirFor } from '../executor/worktree.js';
import { writeJobSpec, isWorkerAlive, heartbeatAgeMs, type JobSpec } from '../executor/protocol.js';
import { pickModel } from '../executor/models.js';
import { prepareSandboxedSpawn, describeSandbox } from '../executor/sandbox.js';
import { ingestAll, type IngestLogger } from './ingest.js';
/** 失败后默认最多自动重试次数(项目级 maxRetries 未设置时回退此值)。失败/退避策略本体在 store.failTaskAttempt。 */
@@ -56,10 +57,16 @@ export function workerEnv(src: NodeJS.ProcessEnv = process.env): NodeJS.ProcessE
* daemon 的鉴权上下文(本机无 API_KEY/凭证文件,鉴权走 macOS keychaindetached 后新会话读不到 → Not logged in)。
* 存活性不依赖 detachedunref 后 daemon 退出,worker 作为孤儿被 init/launchd 收养、继续运行(daemon 无控制终端,
* 不会有进程组 SIGHUP;重启用单 pid kill 不波及 worker)。
*
* OS 级沙箱(可选,默认关):MAESTRO_SANDBOX 开启时,prepareSandboxedSpawn 把命令包成
* `sh -c 'ulimit…; exec sandbox-exec -f profile <原命令>'`——文件写围栏 + 资源上限。
* 末尾 exec 链保证 pid 不变(仍是真 worker 的 pid),unref/同会话/keychain 等约束不受影响。
*/
function defaultSpawnWorker(runId: string): number {
const [cmd, ...args] = workerEntry();
const child = spawn(cmd, [...args, runId], {
const base = [...workerEntry(), runId];
const wrapped = prepareSandboxedSpawn(base, runId); // 沙箱关闭 → null,按原命令直接 spawn
const [cmd, ...args] = wrapped ? [wrapped.cmd, ...wrapped.args] : base;
const child = spawn(cmd, args, {
detached: false,
stdio: 'ignore',
env: workerEnv(),
@@ -242,5 +249,6 @@ export function startOrchestrator(
const timer = setInterval(() => orch.tick(), intervalSec * 1000);
timer.unref();
app.log.info(`编排器已启用:每 ${intervalSec}s 一轮(ingest→回收→领取,autonomy≠manual 的 active 项目)`);
app.log.info(describeSandbox()); // 记录当前生效的沙箱/资源上限策略
return timer;
}