From bbb43f97a35e5b163699b75f1f840289b1445ce4 Mon Sep 17 00:00:00 2001 From: john Date: Fri, 24 Jul 2026 23:07:46 +0800 Subject: [PATCH] feat: persist blocked executor jobs --- .../memind-orchestrator-boundary.md | 22 +- ops/src/api/admin.ts | 5 + ops/src/pages/admin/OrchestratorPage.tsx | 5 +- services/orchestrator/README.md | 24 ++- services/orchestrator/admin-config.mjs | 10 + services/orchestrator/admin-config.test.mjs | 11 + services/orchestrator/app.test.mjs | 8 +- .../orchestrator/code-run-shadow-graph.mjs | 47 ++++- services/orchestrator/executor-gateway.mjs | 3 +- services/orchestrator/executor-job-store.mjs | 191 ++++++++++++++++++ .../orchestrator/executor-job-store.test.mjs | 183 +++++++++++++++++ services/orchestrator/package-lock.json | 3 +- services/orchestrator/package.json | 3 +- services/orchestrator/runtime.mjs | 14 +- services/orchestrator/runtime.test.mjs | 42 ++++ services/orchestrator/server.mjs | 56 ++++- services/orchestrator/server.test.mjs | 48 +++++ 17 files changed, 649 insertions(+), 26 deletions(-) create mode 100644 services/orchestrator/executor-job-store.mjs create mode 100644 services/orchestrator/executor-job-store.test.mjs create mode 100644 services/orchestrator/server.test.mjs diff --git a/docs/architecture/memind-orchestrator-boundary.md b/docs/architecture/memind-orchestrator-boundary.md index 339b283..2e4c022 100644 --- a/docs/architecture/memind-orchestrator-boundary.md +++ b/docs/architecture/memind-orchestrator-boundary.md @@ -102,6 +102,20 @@ not a deployment backend. The compile-time dispatch capability remains false, so creating a job records `blocked` state without importing an executor SDK, launching a process, or touching a workspace. +Phase 3.3 persists that state in the Orchestrator-owned PostgreSQL database. +LangGraph checkpoint tables and `executor_jobs` share the isolated +`memind_orchestrator` schema and credentials, but remain behind separate +storage interfaces and readiness probes. This is a deployment simplification, +not a domain ownership leak: neither store can access Memind business tables, +and the Executor Job Store can move to a separate database without changing +the graph or the Memind-facing protocol. + +The `build_plan` node creates the deterministic preview job +`:executor-preview` with idempotency key +`:build_plan:v1`. The stored result is terminal `blocked` state with +`executor_dispatch_not_implemented`; it is a durable audit and recovery +boundary, not an execution claim. + The implemented internal API is: ```text @@ -123,8 +137,9 @@ validate_run -> build_plan -> finalize_run ``` It requires `policy.executionMode=observe-only` and -`policy.sideEffectsAllowed=false`. It projects the Native executor boundary but -cannot call Goosed, Aider, OpenHands, Tool Gateway, or the filesystem. +`policy.sideEffectsAllowed=false`. It projects the Native executor boundary and +persists a blocked Executor Job, but cannot dispatch Goosed, Aider, OpenHands, +Tool Gateway, or the filesystem. ## Failure isolation @@ -139,7 +154,8 @@ failure: service URL boundary. Successful observations are projected as `workflow_shadow_completed`; graph -checkpoints stay in the Orchestrator-owned PostgreSQL database. +checkpoints and blocked Executor Jobs stay in the Orchestrator-owned PostgreSQL +database. Both terminal projection events contain bounded observation latency. The Memind-owned observability service aggregates those events and may join them to diff --git a/ops/src/api/admin.ts b/ops/src/api/admin.ts index 4fd8d61..c3bbd7e 100644 --- a/ops/src/api/admin.ts +++ b/ops/src/api/admin.ts @@ -268,6 +268,11 @@ export type OrchestratorServiceHealth = { service: string | null; checkpoint: { kind?: string; durable?: boolean } | null; execution: string | null; + executorGateway: { + dispatchImplemented: boolean; + executionEnabled: boolean; + store: { kind: string | null; durable: boolean } | null; + } | null; } | null; }; diff --git a/ops/src/pages/admin/OrchestratorPage.tsx b/ops/src/pages/admin/OrchestratorPage.tsx index 01e4c36..35a8f2c 100644 --- a/ops/src/pages/admin/OrchestratorPage.tsx +++ b/ops/src/pages/admin/OrchestratorPage.tsx @@ -173,7 +173,7 @@ export function OrchestratorPage() {

Executor Gateway

- Phase 3.2 仅注册版本化适配器契约;所有执行器均为 contract-only,不会启动进程或接管任务。 + Phase 3.3 已持久化 blocked 预览任务;所有执行器仍为 contract-only,不会启动进程或接管任务。

@@ -264,6 +264,9 @@ export function OrchestratorPage() { {serviceHealth?.details?.checkpoint ? ` · checkpoint ${serviceHealth.details.checkpoint.kind ?? 'unknown'}` : ''} + {serviceHealth?.details?.executorGateway?.store + ? ` · executor jobs ${serviceHealth.details.executorGateway.store.kind ?? 'unknown'}` + : ''}