@oisincoveney/pipeline 3.19.4 → 3.19.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (81) hide show
  1. package/dist/argo-submit.d.ts +2 -0
  2. package/dist/argo-submit.js +27 -16
  3. package/dist/cli/doctor.d.ts +1 -1
  4. package/dist/cli/doctor.js +2 -2
  5. package/dist/cli/format.js +1 -1
  6. package/dist/cli/program.d.ts +1 -1
  7. package/dist/cli/run-command.d.ts +1 -1
  8. package/dist/cli/run-resolver.d.ts +1 -1
  9. package/dist/cli/run-service.d.ts +1 -1
  10. package/dist/cli/submit-options.js +22 -5
  11. package/dist/commands/pipeline-command.js +1 -1
  12. package/dist/commands/ticket/shared.d.ts +1 -1
  13. package/dist/commands/ticket-command.d.ts +2 -1
  14. package/dist/config/schemas.d.ts +1 -1
  15. package/dist/context/repo-map.js +2 -2
  16. package/dist/credentials/broker.d.ts +1 -1
  17. package/dist/install-commands/opencode.js +1 -1
  18. package/dist/install-commands/planner.js +1 -1
  19. package/dist/install-hooks.js +1 -1
  20. package/dist/loop/argo-poll.js +2 -2
  21. package/dist/loop/loop-command.js +1 -1
  22. package/dist/loop/merge.js +1 -1
  23. package/dist/moka-global-config.d.ts +1 -0
  24. package/dist/moka-global-config.js +1 -0
  25. package/dist/moka-submit.d.ts +5 -0
  26. package/dist/moka-submit.js +1 -0
  27. package/dist/planning/generate.js +1 -1
  28. package/dist/remote/submit/argo-submission.d.ts +1 -0
  29. package/dist/remote/submit/argo-submission.js +1 -0
  30. package/dist/remote/submit/io.js +2 -2
  31. package/dist/run-control/contracts.d.ts +1 -1
  32. package/dist/run-control/contracts.js +1 -1
  33. package/dist/run-control/detach.js +1 -1
  34. package/dist/run-control/next-node.js +1 -1
  35. package/dist/run-control/postgres/postgres-run-control-store.js +4 -5
  36. package/dist/run-control/run-artifacts-command.js +1 -1
  37. package/dist/run-control/run-command-domain.js +2 -2
  38. package/dist/run-control/run-control-store.js +5 -1
  39. package/dist/run-control/runtime-reporter.js +1 -1
  40. package/dist/run-control/store-paths.js +1 -1
  41. package/dist/run-control/submit-result.js +1 -1
  42. package/dist/run-control/supervisor.js +2 -2
  43. package/dist/run-state/git-refs.js +1 -1
  44. package/dist/runner-command/run.js +1 -1
  45. package/dist/runtime/actor-ids.d.ts +1 -1
  46. package/dist/runtime/agent-node/index.js +2 -2
  47. package/dist/runtime/builtins/index.js +2 -2
  48. package/dist/runtime/changed-files/changed-files.js +1 -1
  49. package/dist/runtime/changed-files/index.js +2 -2
  50. package/dist/runtime/command-executor/index.js +2 -2
  51. package/dist/runtime/context/index.js +2 -2
  52. package/dist/runtime/contracts/index.d.ts +2 -1
  53. package/dist/runtime/drain-merge/index.js +2 -2
  54. package/dist/runtime/durable-store/acquisition.js +2 -1
  55. package/dist/runtime/durable-store/postgres/migrate-substrate.js +29 -0
  56. package/dist/runtime/durable-store/postgres/postgres-store.js +2 -4
  57. package/dist/runtime/events/events.js +2 -2
  58. package/dist/runtime/events/index.js +2 -2
  59. package/dist/runtime/gates/index.js +5 -5
  60. package/dist/runtime/gates/kinds/acceptance/acceptance.js +1 -1
  61. package/dist/runtime/hooks/command-hook.js +1 -1
  62. package/dist/runtime/hooks/index.js +2 -2
  63. package/dist/runtime/json-validation/index.js +2 -2
  64. package/dist/runtime/node-protocol/node-protocol.js +1 -1
  65. package/dist/runtime/node-state-store.js +1 -1
  66. package/dist/runtime/open-pull-request/index.js +2 -2
  67. package/dist/runtime/opencode-session-executor.js +1 -1
  68. package/dist/runtime/parallel-node/index.js +2 -2
  69. package/dist/runtime/retry.js +1 -1
  70. package/dist/runtime/scheduler.js +1 -1
  71. package/dist/runtime/services/backlog-service.d.ts +1 -1
  72. package/dist/runtime/services/backlog-service.js +1 -1
  73. package/dist/runtime/services/drain-merge-git-service.js +2 -2
  74. package/dist/runtime/services/kubernetes-argo-service.js +5 -1
  75. package/dist/runtime/services/run-journal-file-service.js +1 -1
  76. package/dist/tickets/backlog-task-store.js +1 -1
  77. package/dist/tickets/completion/complete-ticket.js +1 -1
  78. package/dist/tickets/ticket-graph.js +2 -2
  79. package/dist/tickets/ticket-plan.d.ts +1 -1
  80. package/docs/adr-two-stage-submit-scheduling.md +112 -0
  81. package/package.json +6 -1
@@ -26,6 +26,7 @@ declare const submitRunnerArgoWorkflowOptionsSchema: z.ZodObject<{
26
26
  Never: "Never";
27
27
  }>>;
28
28
  imagePullSecretName: z.ZodOptional<z.ZodString>;
29
+ kubeContext: z.ZodOptional<z.ZodString>;
29
30
  kubeconfigPath: z.ZodOptional<z.ZodString>;
30
31
  mcpGatewayAuth: z.ZodOptional<z.ZodObject<{
31
32
  secretKey: z.ZodDefault<z.ZodString>;
@@ -59,6 +60,7 @@ declare const submitDynamicRunnerArgoWorkflowOptionsSchema: z.ZodObject<{
59
60
  Never: "Never";
60
61
  }>>;
61
62
  imagePullSecretName: z.ZodOptional<z.ZodString>;
63
+ kubeContext: z.ZodOptional<z.ZodString>;
62
64
  kubeconfigPath: z.ZodOptional<z.ZodString>;
63
65
  mcpGatewayAuth: z.ZodOptional<z.ZodObject<{
64
66
  secretKey: z.ZodDefault<z.ZodString>;
@@ -43,6 +43,7 @@ const submitRunnerArgoWorkflowBaseOptionShape = {
43
43
  "Never"
44
44
  ]).optional(),
45
45
  imagePullSecretName: z.string().min(1).optional(),
46
+ kubeContext: z.string().min(1).optional(),
46
47
  kubeconfigPath: z.string().min(1).optional(),
47
48
  mcpGatewayAuth: mcpGatewayAuthOptionSchema.optional(),
48
49
  name: z.string().min(1).optional(),
@@ -166,16 +167,16 @@ function submitRunnerArgoWorkflowEffect(rawOptions, dependencies) {
166
167
  namespace: options.namespace,
167
168
  options
168
169
  });
169
- return workflowSubmitResult(yield* service.createWorkflow({
170
- body: runnerArgoWorkflowManifestSchema.parse(workflow),
170
+ return yield* submitWorkflowManifest({
171
171
  dependencies,
172
172
  namespace: options.namespace,
173
- options
174
- }), workflow, {
175
- namespace: options.namespace,
176
- payloadConfigMapName,
177
- scheduleConfigMapName: scheduleArtifactConfigMapName,
178
- taskDescriptorConfigMapName
173
+ options,
174
+ resultExtras: {
175
+ payloadConfigMapName,
176
+ scheduleConfigMapName: scheduleArtifactConfigMapName,
177
+ taskDescriptorConfigMapName
178
+ },
179
+ workflow
179
180
  });
180
181
  });
181
182
  }
@@ -219,8 +220,7 @@ function submitDynamicRunnerArgoWorkflowEffect(rawOptions, dependencies) {
219
220
  workflowId: options.workflowId
220
221
  });
221
222
  return Effect.gen(function* () {
222
- const service = yield* KubernetesArgoService;
223
- yield* service.createConfigMap({
223
+ yield* (yield* KubernetesArgoService).createConfigMap({
224
224
  body: configMapSchema.parse({
225
225
  apiVersion: "v1",
226
226
  data: { "payload.json": payloadJson },
@@ -235,14 +235,25 @@ function submitDynamicRunnerArgoWorkflowEffect(rawOptions, dependencies) {
235
235
  namespace: options.namespace,
236
236
  options
237
237
  });
238
- return workflowSubmitResult(yield* service.createWorkflow({
239
- body: runnerArgoWorkflowManifestSchema.parse(workflow),
238
+ return yield* submitWorkflowManifest({
240
239
  dependencies,
241
240
  namespace: options.namespace,
242
- options
243
- }), workflow, {
244
- namespace: options.namespace,
245
- payloadConfigMapName
241
+ options,
242
+ resultExtras: { payloadConfigMapName },
243
+ workflow
244
+ });
245
+ });
246
+ }
247
+ function submitWorkflowManifest(input) {
248
+ return Effect.gen(function* () {
249
+ return workflowSubmitResult(yield* (yield* KubernetesArgoService).createWorkflow({
250
+ body: runnerArgoWorkflowManifestSchema.parse(input.workflow),
251
+ dependencies: input.dependencies,
252
+ namespace: input.namespace,
253
+ options: input.options
254
+ }), input.workflow, {
255
+ namespace: input.namespace,
256
+ ...input.resultExtras
246
257
  });
247
258
  });
248
259
  }
@@ -18,4 +18,4 @@ interface DoctorFlags {
18
18
  }
19
19
  declare function runDoctor(cwd: string, options?: DoctorFlags): Promise<DoctorResult>;
20
20
  //#endregion
21
- export { runDoctor };
21
+ export { DoctorCheck, DoctorFlags, DoctorResult, runDoctor };
@@ -9,8 +9,8 @@ import { execa } from "execa";
9
9
  import { join } from "node:path";
10
10
  import matter from "gray-matter";
11
11
  //#region src/cli/doctor.ts
12
- const HEADLESS_AGENT_PERMISSION_VALUES = new Set(["ask"]);
13
- const RUN_READINESS_CATEGORIES = new Set([
12
+ const HEADLESS_AGENT_PERMISSION_VALUES = /* @__PURE__ */ new Set(["ask"]);
13
+ const RUN_READINESS_CATEGORIES = /* @__PURE__ */ new Set([
14
14
  "acceptance",
15
15
  "green",
16
16
  "intake",
@@ -137,4 +137,4 @@ function truncateMiddle(text, maxLength) {
137
137
  return `${text.slice(0, keep)}\n... truncated ...\n${text.slice(-keep)}`;
138
138
  }
139
139
  //#endregion
140
- export { createTerminalRuntimeReporter, formatDoctorResult, formatRuntimeFailure, formatRuntimeResult };
140
+ export { createTerminalRuntimeReporter, formatDoctorResult, formatRuntimeFailure, formatRuntimeProgressMessage, formatRuntimeResult };
@@ -11,4 +11,4 @@ interface CliProgramOptions {
11
11
  declare function createCliProgram(options?: CliProgramOptions): Command;
12
12
  declare function runCli(argv: string[]): Promise<void>;
13
13
  //#endregion
14
- export { createCliProgram, runCli };
14
+ export { CliProgramOptions, createCliProgram, runCli };
@@ -10,4 +10,4 @@ interface RunCommandCall {
10
10
  }
11
11
  type RunCommand = (call: RunCommandCall) => Promise<void> | void;
12
12
  //#endregion
13
- export { RunCommand };
13
+ export { RunCommand, RunCommandCall };
@@ -33,4 +33,4 @@ interface RunResolution {
33
33
  target: MokaRunTarget;
34
34
  }
35
35
  //#endregion
36
- export { RunResolution, RunResolverFlags };
36
+ export { LocalRuntimeExecution, MOKA_RUN_EFFORTS, MOKA_RUN_TARGETS, MokaRunEffort, MokaRunMode, MokaRunTarget, RemoteSubmitExecution, RunResolution, RunResolverFlags };
@@ -26,4 +26,4 @@ interface RunControlOptions {
26
26
  declare function execute(description: string, options?: ExecuteOptions): Promise<void>;
27
27
  declare function quick(description: string, options?: Omit<ExecuteOptions, "entrypoint">): Promise<void>;
28
28
  //#endregion
29
- export { execute, quick };
29
+ export { ExecuteOptions, RunControlOptions, RunStoreMode, execute, quick };
@@ -4,8 +4,16 @@ import { loadMokaGlobalConfig } from "../moka-global-config.js";
4
4
  import { submitMoka } from "../moka-submit.js";
5
5
  import { Option } from "commander";
6
6
  //#region src/cli/submit-options.ts
7
+ function resolveOptionalSecretRef(flags, fromGlobalConfig) {
8
+ if (flags.skip) return;
9
+ if (flags.secretName) return {
10
+ secretName: flags.secretName,
11
+ ...flags.secretKey ? { secretKey: flags.secretKey } : {}
12
+ };
13
+ return fromGlobalConfig;
14
+ }
7
15
  function addMokaSubmitOptions(command) {
8
- return addRunnerArgoOptions(command.option("--quick", "submit the compact graph").option("--command", "treat input after -- as explicit argv").option("--schedule <path>", "approved schedule YAML to submit").option("--event-url <url>", "runner event sink URL").option("--open-pr", "append an open-pull-request delivery node (preview-labelled PR)").option("--task <text>", "task description for command-mode metadata"), { kubeconfig: true });
16
+ return addRunnerArgoOptions(command.option("--quick", "submit the compact graph").option("--command", "treat input after -- as explicit argv").option("--schedule <path>", "approved schedule YAML to submit").option("--event-url <url>", "runner event sink URL").option("--open-pr", "append an open-pull-request delivery node (preview-labelled PR)").option("--task <text>", "task description for command-mode metadata").option("--db-auth-secret-name <name>", "override momokaya.submit.dbAuth secret name").option("--db-auth-secret-key <key>", "override momokaya.submit.dbAuth secret key").option("--skip-db-auth", "omit MOKA_DB_URL injection regardless of global config").option("--mcp-gateway-auth-secret-name <name>", "override momokaya.submit.mcpGatewayAuth secret name").option("--mcp-gateway-auth-secret-key <key>", "override momokaya.submit.mcpGatewayAuth secret key").option("--skip-mcp-gateway-auth", "omit PIPELINE_MCP_GATEWAY_AUTHORIZATION injection regardless of global config"), { kubeconfig: true });
9
17
  }
10
18
  function runMokaSubmitFromCli(input, flags) {
11
19
  const cwd = process.env.PIPELINE_TARGET_PATH ?? process.cwd();
@@ -36,8 +44,16 @@ function mokaCommonSubmitOptions(input) {
36
44
  return {
37
45
  brokerAuth: resolveMokaBrokerAuth(input.globalConfig),
38
46
  config: input.config,
39
- dbAuth: momokaya?.submit.dbAuth,
40
- mcpGatewayAuth: momokaya?.submit.mcpGatewayAuth,
47
+ dbAuth: resolveOptionalSecretRef({
48
+ secretKey: input.flags.dbAuthSecretKey,
49
+ secretName: input.flags.dbAuthSecretName,
50
+ skip: input.flags.skipDbAuth
51
+ }, momokaya?.submit.dbAuth),
52
+ mcpGatewayAuth: resolveOptionalSecretRef({
53
+ secretKey: input.flags.mcpGatewayAuthSecretKey,
54
+ secretName: input.flags.mcpGatewayAuthSecretName,
55
+ skip: input.flags.skipMcpGatewayAuth
56
+ }, momokaya?.submit.mcpGatewayAuth),
41
57
  delivery: { pullRequest: input.flags.openPr === true },
42
58
  eventUrl: input.eventUrl,
43
59
  eventAuthSecretKey: momokaya?.submit.eventAuthSecretKey,
@@ -48,6 +64,7 @@ function mokaCommonSubmitOptions(input) {
48
64
  image: input.flags.image,
49
65
  imagePullPolicy: parseImagePullPolicy(input.flags.imagePullPolicy),
50
66
  imagePullSecretName: input.flags.imagePullSecret ?? momokaya?.submit.imagePullSecretName,
67
+ kubeContext: input.flags.kubeContext ?? momokaya?.kubernetes.context,
51
68
  kubeconfigPath: input.flags.kubeconfig ?? momokaya?.kubernetes.kubeconfig,
52
69
  name: input.flags.name,
53
70
  namespace: input.flags.namespace ?? momokaya?.kubernetes.namespace,
@@ -83,7 +100,7 @@ function submitMokaGraphInput(input, flags, commonOptions) {
83
100
  }
84
101
  function addRunnerArgoOptions(command, options = {}) {
85
102
  command.option("--name <name>", "Workflow metadata.name").option("--generate-name <prefix>", "Workflow metadata.generateName").option("--namespace <namespace>", "Workflow namespace");
86
- if (options.kubeconfig) command.option("--kubeconfig <path>", "kubeconfig path");
103
+ if (options.kubeconfig) command.option("--kubeconfig <path>", "kubeconfig path").option("--kube-context <name>", "kubeconfig context to target");
87
104
  return command.option("--service-account <name>", "Workflow service account").option("--image <image>", "runner image").addOption(new Option("--image-pull-policy <policy>", "runner image pull policy").choices([
88
105
  "Always",
89
106
  "IfNotPresent",
@@ -95,4 +112,4 @@ function parseImagePullPolicy(value) {
95
112
  return "Always";
96
113
  }
97
114
  //#endregion
98
- export { addMokaSubmitOptions, buildMokaSubmitInputFromCli, runMokaSubmitFromCli };
115
+ export { addMokaSubmitOptions, buildMokaSubmitInputFromCli, parseImagePullPolicy, runMokaSubmitFromCli };
@@ -1,6 +1,6 @@
1
1
  import { Context, Effect, Layer } from "effect";
2
2
  //#region src/commands/pipeline-command.ts
3
- const BUILTIN_PIPE_COMMANDS = new Set([
3
+ const BUILTIN_PIPE_COMMANDS = /* @__PURE__ */ new Set([
4
4
  "run",
5
5
  "validate",
6
6
  "explain-plan",
@@ -11,4 +11,4 @@ interface TicketCommandOptions {
11
11
  readonly ticketPlanExecutor?: TicketPlanExecutor;
12
12
  }
13
13
  //#endregion
14
- export { TicketCommandOptions };
14
+ export { TicketCommandOptions, TicketPlanExecutor };
@@ -1,2 +1,3 @@
1
1
  import { TicketCommandOptions } from "./ticket/shared.js";
2
- import { Command } from "commander";
2
+ import { Command } from "commander";
3
+ export type { TicketCommandOptions };
@@ -583,4 +583,4 @@ interface PipelineConfigValidationOptions {
583
583
  allowMissingLintFileReferences?: boolean;
584
584
  }
585
585
  //#endregion
586
- export { GateKind, HookEvent, McpGatewayBackendLocality, McpGatewayWorkspacePathSource, PipelineConfig, PipelineConfigError, PipelineConfigErrorCode, PipelineConfigIssue, PipelineConfigParts, PipelineConfigValidationOptions, RunnerType, ScheduleBaseline, SchedulingRole, WorkflowNodeKind, workflowSchema };
586
+ export { GateKind, HookEvent, McpGatewayBackendLocality, McpGatewayWorkspacePathSource, PipelineConfig, PipelineConfigError, PipelineConfigErrorCode, PipelineConfigIssue, PipelineConfigParts, PipelineConfigValidationOptions, RunnerType, ScheduleBaseline, SchedulingRole, WorkflowNodeKind, configSchema, workflowSchema };
@@ -7,7 +7,7 @@ import { Query } from "web-tree-sitter";
7
7
  import Graph from "graphology";
8
8
  import pagerank from "graphology-metrics/centrality/pagerank.js";
9
9
  //#region src/context/repo-map.ts
10
- const SOURCE_EXTENSIONS = new Set([
10
+ const SOURCE_EXTENSIONS = /* @__PURE__ */ new Set([
11
11
  ".cjs",
12
12
  ".js",
13
13
  ".jsx",
@@ -15,7 +15,7 @@ const SOURCE_EXTENSIONS = new Set([
15
15
  ".ts",
16
16
  ".tsx"
17
17
  ]);
18
- const SKIP_DIRS = new Set([
18
+ const SKIP_DIRS = /* @__PURE__ */ new Set([
19
19
  "node_modules",
20
20
  ".git",
21
21
  "dist",
@@ -12,4 +12,4 @@ declare const brokerAuthOptionSchema: z.ZodObject<{
12
12
  }, z.core.$strict>;
13
13
  type BrokerAuthOption = z.input<typeof brokerAuthOptionSchema>;
14
14
  //#endregion
15
- export { BrokerAuthOption };
15
+ export { BrokerAuthOption, brokerAuthOptionSchema };
@@ -413,4 +413,4 @@ const opencodeAdapter = {
413
413
  }
414
414
  };
415
415
  //#endregion
416
- export { agentDispatchRoutes, entrypointDispatchBlock, grants, header, markdown, opencodeAdapter, projectAgentsMdDefinition, resolvedHostModel };
416
+ export { agentDispatchRoutes, entrypointDispatchBlock, grants, header, markdown, opencodeAdapter, projectAgentsMdDefinition, resolvedHostModel, shouldEmbedProjectGateway };
@@ -15,7 +15,7 @@ const ADAPTERS = {
15
15
  opencode: opencodeAdapter,
16
16
  "claude-code": claudeCodeAdapter
17
17
  };
18
- const GLOBAL_EXCLUDED_PATHS = new Set(["AGENTS.md"]);
18
+ const GLOBAL_EXCLUDED_PATHS = /* @__PURE__ */ new Set(["AGENTS.md"]);
19
19
  const GENERATED_CONTENT_MARKERS = [
20
20
  GENERATED_MARKER,
21
21
  GENERATED_TS_MARKER,
@@ -20,7 +20,7 @@ const HOST_TARGET_ROOT = {
20
20
  codex: ".codex",
21
21
  opencode: ".opencode"
22
22
  };
23
- const NON_HOOK_OWNED_TARGETS = new Set([".opencode/opencode.json"]);
23
+ const NON_HOOK_OWNED_TARGETS = /* @__PURE__ */ new Set([".opencode/opencode.json"]);
24
24
  function hashContent(content) {
25
25
  return createHash("sha256").update(content).digest("hex");
26
26
  }
@@ -2,12 +2,12 @@ import { isRecord } from "../safe-json.js";
2
2
  import { Duration, Effect } from "effect";
3
3
  import { CustomObjectsApi, KubeConfig } from "@kubernetes/client-node";
4
4
  //#region src/loop/argo-poll.ts
5
- const TERMINAL_PHASES = new Set([
5
+ const TERMINAL_PHASES = /* @__PURE__ */ new Set([
6
6
  "Succeeded",
7
7
  "Failed",
8
8
  "Error"
9
9
  ]);
10
- const KNOWN_RUNNING_PHASES = new Set([
10
+ const KNOWN_RUNNING_PHASES = /* @__PURE__ */ new Set([
11
11
  "Running",
12
12
  "Pending",
13
13
  ""
@@ -88,4 +88,4 @@ function loopControllerSubmitInput(input) {
88
88
  };
89
89
  }
90
90
  //#endregion
91
- export { parseLoopFlags, runLoopSubmit };
91
+ export { loopControllerArgv, parseLoopFlags, runLoopSubmit };
@@ -117,4 +117,4 @@ function mergeForClassification(input) {
117
117
  return adminMerge(input.pr, token, input.gh);
118
118
  }
119
119
  //#endregion
120
- export { mergeForClassification };
120
+ export { adminMerge, enableAutoMerge, mergeForClassification, secretToken, selectMergeAction };
@@ -9,6 +9,7 @@ declare const mokaGlobalConfigSchema: z.ZodObject<{
9
9
  url: z.ZodString;
10
10
  }, z.core.$strict>>;
11
11
  kubernetes: z.ZodObject<{
12
+ context: z.ZodOptional<z.ZodString>;
12
13
  kubeconfig: z.ZodOptional<z.ZodString>;
13
14
  namespace: z.ZodString;
14
15
  }, z.core.$strict>;
@@ -29,6 +29,7 @@ const mokaSubmitGlobalConfigSchema = z.object({
29
29
  serviceAccountName: z.string().min(1)
30
30
  }).strict();
31
31
  const mokaKubernetesGlobalConfigSchema = z.object({
32
+ context: z.string().min(1).optional(),
32
33
  kubeconfig: z.string().min(1).optional(),
33
34
  namespace: z.string().min(1)
34
35
  }).strict();
@@ -197,6 +197,7 @@ declare const mokaSubmitBaseOptionsSchema: z.ZodObject<{
197
197
  Never: "Never";
198
198
  }>>;
199
199
  imagePullSecretName: z.ZodOptional<z.ZodString>;
200
+ kubeContext: z.ZodOptional<z.ZodString>;
200
201
  kubeconfigPath: z.ZodOptional<z.ZodString>;
201
202
  name: z.ZodOptional<z.ZodString>;
202
203
  namespace: z.ZodOptional<z.ZodString>;
@@ -310,6 +311,7 @@ declare const mokaGraphSubmitOptionsSchema: z.ZodObject<{
310
311
  Never: "Never";
311
312
  }>>;
312
313
  imagePullSecretName: z.ZodOptional<z.ZodString>;
314
+ kubeContext: z.ZodOptional<z.ZodString>;
313
315
  kubeconfigPath: z.ZodOptional<z.ZodString>;
314
316
  name: z.ZodOptional<z.ZodString>;
315
317
  namespace: z.ZodOptional<z.ZodString>;
@@ -440,6 +442,7 @@ declare const mokaCommandSubmitOptionsSchema: z.ZodObject<{
440
442
  Never: "Never";
441
443
  }>>;
442
444
  imagePullSecretName: z.ZodOptional<z.ZodString>;
445
+ kubeContext: z.ZodOptional<z.ZodString>;
443
446
  kubeconfigPath: z.ZodOptional<z.ZodString>;
444
447
  name: z.ZodOptional<z.ZodString>;
445
448
  namespace: z.ZodOptional<z.ZodString>;
@@ -565,6 +568,7 @@ declare const mokaSubmitOptionsSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
565
568
  Never: "Never";
566
569
  }>>;
567
570
  imagePullSecretName: z.ZodOptional<z.ZodString>;
571
+ kubeContext: z.ZodOptional<z.ZodString>;
568
572
  kubeconfigPath: z.ZodOptional<z.ZodString>;
569
573
  name: z.ZodOptional<z.ZodString>;
570
574
  namespace: z.ZodOptional<z.ZodString>;
@@ -694,6 +698,7 @@ declare const mokaSubmitOptionsSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
694
698
  Never: "Never";
695
699
  }>>;
696
700
  imagePullSecretName: z.ZodOptional<z.ZodString>;
701
+ kubeContext: z.ZodOptional<z.ZodString>;
697
702
  kubeconfigPath: z.ZodOptional<z.ZodString>;
698
703
  name: z.ZodOptional<z.ZodString>;
699
704
  namespace: z.ZodOptional<z.ZodString>;
@@ -66,6 +66,7 @@ const mokaSubmitBaseOptionsSchema = z.object({
66
66
  image: z.string().min(1).optional(),
67
67
  imagePullPolicy: imagePullPolicySchema,
68
68
  imagePullSecretName: z.string().min(1).optional(),
69
+ kubeContext: z.string().min(1).optional(),
69
70
  kubeconfigPath: z.string().min(1).optional(),
70
71
  name: z.string().min(1).optional(),
71
72
  namespace: z.string().min(1).optional(),
@@ -41,7 +41,7 @@ const SCHEDULE_BUILTINS = [
41
41
  "test",
42
42
  "typecheck"
43
43
  ];
44
- const PARALLEL_MERGE_BUILTINS = new Set(["drain-merge"]);
44
+ const PARALLEL_MERGE_BUILTINS = /* @__PURE__ */ new Set(["drain-merge"]);
45
45
  const scheduleArtifactSchema = z.object({
46
46
  generated_at: z.string().datetime(),
47
47
  kind: z.literal(SCHEDULE_KIND),
@@ -18,6 +18,7 @@ interface MokaWorkflowSubmitOptions {
18
18
  image?: string;
19
19
  imagePullPolicy?: "Always" | "IfNotPresent" | "Never";
20
20
  imagePullSecretName?: string;
21
+ kubeContext?: string;
21
22
  kubeconfigPath?: string;
22
23
  mcpGatewayAuth?: {
23
24
  secretKey?: string;
@@ -50,6 +50,7 @@ function workflowSubmitOptions(options) {
50
50
  image: options.image,
51
51
  imagePullPolicy: options.imagePullPolicy,
52
52
  imagePullSecretName: options.imagePullSecretName,
53
+ kubeContext: options.kubeContext,
53
54
  kubeconfigPath: options.kubeconfigPath,
54
55
  name: options.name,
55
56
  namespace: requireSubmitOption(options.namespace, "namespace"),
@@ -1,6 +1,6 @@
1
1
  import { normalizeRunnerRepositoryForSubmit } from "../../git-remote-url.js";
2
2
  import { readFileSync } from "node:fs";
3
- import { simpleGit } from "simple-git";
3
+ import { simpleGit as simpleGit$1 } from "simple-git";
4
4
  import parseGitUrl from "git-url-parse";
5
5
  //#region src/remote/submit/io.ts
6
6
  function readScheduleFile(dependencies, path) {
@@ -47,7 +47,7 @@ function runContext(options, git, runId) {
47
47
  }
48
48
  async function resolveGit(worktreePath, dependencies) {
49
49
  if (dependencies.resolveGitContext) return dependencies.resolveGitContext(worktreePath);
50
- const git = simpleGit({ baseDir: worktreePath });
50
+ const git = simpleGit$1({ baseDir: worktreePath });
51
51
  const [branchResult, sha, remoteConfig] = await Promise.all([
52
52
  git.branch(),
53
53
  git.revparse(["HEAD"]),
@@ -103,4 +103,4 @@ type RunEffort = z.infer<typeof runEffortSchema>;
103
103
  type RunMode = z.infer<typeof runModeSchema>;
104
104
  type MokaRunManifest = z.infer<typeof mokaRunManifestSchema>;
105
105
  //#endregion
106
- export { MokaRunManifest, RunEffort, RunMode, RunTarget };
106
+ export { MokaRunManifest, RunEffort, RunMode, RunTarget, mokaRunManifestSchema, runEffortSchema, runModeSchema, runTargetSchema };
@@ -127,4 +127,4 @@ function parseMokaRunManifest(input) {
127
127
  return mokaRunManifestSchema.parse(input);
128
128
  }
129
129
  //#endregion
130
- export { DEFAULT_RUN_CONTROL_HEARTBEAT_INTERVAL_MS, DEFAULT_RUN_CONTROL_NODE_STALE_AFTER_MS, DEFAULT_RUN_CONTROL_STALE_DETECTION, mokaNodeStatusSchema, mokaRunStatusSchema, parseMokaNodeStatus, parseMokaRunController, parseMokaRunEvent, parseMokaRunManifest, parseMokaRunStatus, parseRunControlStaleDetection, parseRunEffort, parseRunMode, parseRunTarget };
130
+ export { DEFAULT_RUN_CONTROL_HEARTBEAT_INTERVAL_MS, DEFAULT_RUN_CONTROL_NODE_STALE_AFTER_MS, DEFAULT_RUN_CONTROL_STALE_DETECTION, MOKA_NODE_STATUSES, MOKA_RUN_STATUSES, RUN_EFFORTS, RUN_MODES, RUN_TARGETS, mokaNodeStatusEventSchema, mokaNodeStatusSchema, mokaRunControlEventSchema, mokaRunControllerSchema, mokaRunEventSchema, mokaRunHeartbeatEventSchema, mokaRunManifestSchema, mokaRunStatusEventSchema, mokaRunStatusSchema, parseMokaNodeStatus, parseMokaRunController, parseMokaRunEvent, parseMokaRunManifest, parseMokaRunStatus, parseRunControlStaleDetection, parseRunEffort, parseRunMode, parseRunTarget, runControlStaleDetectionSchema, runEffortSchema, runModeSchema, runTargetSchema };
@@ -76,4 +76,4 @@ function waitForControllerSpawnEffect(child) {
76
76
  });
77
77
  }
78
78
  //#endregion
79
- export { startDetachedRunController };
79
+ export { startDetachedRunController, startDetachedRunControllerEffect };
@@ -115,4 +115,4 @@ function printNextNodeEnvelopeScoped(runId) {
115
115
  });
116
116
  }
117
117
  //#endregion
118
- export { readPersistedScheduleEffect, readyNodeIdsFromRunStore, registerNextNodeSubcommand };
118
+ export { buildNextNodeEnvelope, buildNextNodeEnvelopeFromRunStore, readPersistedScheduleEffect, readyNodeIdsFromRunStore, registerNextNodeSubcommand };
@@ -1,13 +1,12 @@
1
+ import "../../runtime/durable-store/postgres/migrate-substrate.js";
1
2
  import { DEFAULT_RUN_CONTROL_STALE_DETECTION, parseMokaNodeStatus, parseMokaRunController, parseMokaRunEvent, parseMokaRunManifest, parseMokaRunStatus, parseRunControlStaleDetection, parseRunEffort, parseRunMode, parseRunTarget } from "../contracts.js";
2
3
  import { publishScheduleManifest } from "../store-manifest.js";
3
4
  import { runControlEvent, runControlNodeArtifact, runControlNodeSession, runControlRun } from "./schema.js";
4
5
  import { Effect } from "effect";
5
- import { fileURLToPath } from "node:url";
6
- import { asc, eq, inArray } from "drizzle-orm";
7
6
  import { drizzle } from "drizzle-orm/postgres-js";
8
- import "drizzle-orm/postgres-js/migrator";
9
7
  import postgres from "postgres";
10
- fileURLToPath(new URL("../../runtime/durable-store/postgres/migrations", import.meta.url));
8
+ import { asc, eq, inArray } from "drizzle-orm";
9
+ //#region src/run-control/postgres/postgres-run-control-store.ts
11
10
  function openClient(dbUrl) {
12
11
  return postgres(dbUrl, { max: 1 });
13
12
  }
@@ -39,7 +38,7 @@ function createRun(db, input) {
39
38
  manifest,
40
39
  runId: manifest.runId
41
40
  }).onConflictDoNothing());
42
- const existing = yield* readRun(db, manifest.runId);
41
+ const existing = yield* loadBaseManifest(db, manifest.runId);
43
42
  if (existing === void 0) return yield* Effect.fail(/* @__PURE__ */ new Error(`Run ${manifest.runId} not found after createRun upsert.`));
44
43
  return existing;
45
44
  });
@@ -14,7 +14,7 @@ const WATCH_INTERVAL_MS = 1e3;
14
14
  const SENSITIVE_BASENAME_PARTS = ["prompt", "session"];
15
15
  const SENSITIVE_BASENAME_PREFIXES = ["body."];
16
16
  const SENSITIVE_PATH_PARTS = ["session-body", "session_body"];
17
- const SENSITIVE_BASENAMES = new Set(["body"]);
17
+ const SENSITIVE_BASENAMES = /* @__PURE__ */ new Set(["body"]);
18
18
  function printLogsEffect(input) {
19
19
  return Effect.gen(function* () {
20
20
  const run = yield* requireRunEffect(input.store, input.runId);
@@ -1,13 +1,13 @@
1
1
  import { parseLogicalSegment } from "./logical-segment.js";
2
2
  import { Effect } from "effect";
3
3
  //#region src/run-control/run-command-domain.ts
4
- const ACTIVE_RUN_STATUSES = new Set([
4
+ const ACTIVE_RUN_STATUSES = /* @__PURE__ */ new Set([
5
5
  "queued",
6
6
  "starting",
7
7
  "running",
8
8
  "stalled"
9
9
  ]);
10
- const ACTIVE_NODE_STATUSES = new Set([
10
+ const ACTIVE_NODE_STATUSES = /* @__PURE__ */ new Set([
11
11
  "queued",
12
12
  "starting",
13
13
  "running",
@@ -1,4 +1,5 @@
1
1
  import { loadMokaDbUrl, requireMokaDbUrl } from "../moka-global-config.js";
2
+ import { migratePostgresSubstrate } from "../runtime/durable-store/postgres/migrate-substrate.js";
2
3
  import { postgresRunControlStore } from "./postgres/postgres-run-control-store.js";
3
4
  import "./store-paths.js";
4
5
  import "./store.js";
@@ -19,7 +20,10 @@ import { Effect } from "effect";
19
20
  * filesystem store holds no resources, so it is returned directly.
20
21
  */
21
22
  function resolveRunControlStore(dbUrl, _workspaceRoot) {
22
- return requireMokaDbUrl(dbUrl).pipe(Effect.flatMap((requiredDbUrl) => Effect.acquireRelease(Effect.sync(() => postgresRunControlStore(requiredDbUrl)), (store) => Effect.promise(() => store.close()))));
23
+ return requireMokaDbUrl(dbUrl).pipe(Effect.flatMap((requiredDbUrl) => Effect.tryPromise({
24
+ catch: (error) => error,
25
+ try: () => migratePostgresSubstrate(requiredDbUrl)
26
+ }).pipe(Effect.flatMap(() => Effect.acquireRelease(Effect.sync(() => postgresRunControlStore(requiredDbUrl)), (store) => Effect.promise(() => store.close()))))));
23
27
  }
24
28
  /**
25
29
  * PIPE-91.14: the single store-lifecycle wrapper shared by every run-control
@@ -132,4 +132,4 @@ function errorMessage(error) {
132
132
  return error instanceof Error ? error.message : String(error);
133
133
  }
134
134
  //#endregion
135
- export { createRunStoreRuntimeReporter };
135
+ export { createRunStoreRuntimeReporter, createRunStoreRuntimeReporterEffect };
@@ -20,4 +20,4 @@ function runPaths(workspaceRoot, runId) {
20
20
  };
21
21
  }
22
22
  //#endregion
23
- export { runPaths };
23
+ export { RUNS_DIRECTORY, runPaths };
@@ -57,4 +57,4 @@ function submitResultEffect(runId, nodeId, resultJson) {
57
57
  }));
58
58
  }
59
59
  //#endregion
60
- export { registerSubmitResultSubcommand };
60
+ export { recordSubmitResult, registerSubmitResultSubcommand };
@@ -3,7 +3,7 @@ import { createSerializedWriteQueue } from "../serialized-write-queue.js";
3
3
  import { createRunStoreRuntimeReporter } from "./runtime-reporter.js";
4
4
  import { Effect } from "effect";
5
5
  //#region src/run-control/supervisor.ts
6
- const RUNNING_NODE_EVENT_TYPES = new Set([
6
+ const RUNNING_NODE_EVENT_TYPES = /* @__PURE__ */ new Set([
7
7
  "agent.start",
8
8
  "artifact.check.start",
9
9
  "gate.start",
@@ -193,4 +193,4 @@ function shouldMarkNodeRunning(event) {
193
193
  }
194
194
  }
195
195
  //#endregion
196
- export { createRunControlSupervisor };
196
+ export { createRunControlSupervisor, createRunControlSupervisorEffect };
@@ -347,4 +347,4 @@ function shellQuote(value) {
347
347
  return `'${value.replaceAll("'", `'\\''`)}'`;
348
348
  }
349
349
  //#endregion
350
- export { commitAndPushNodeRef, mergeDependencyRefs, prepareRunnerGitWorkspace, promoteFinalRef, runAuthenticatedGit };
350
+ export { commitAndPushNodeRef, mergeDependencyRefs, prepareRunnerGitWorkspace, promoteFinalRef, runAuthenticatedGit, runnerCommitMessage };
@@ -572,4 +572,4 @@ function createRunnerLogger(options) {
572
572
  }, pino.multistream(streams, { dedupe: true }));
573
573
  }
574
574
  //#endregion
575
- export { runRunnerCommand, runnerTaskTextEffect };
575
+ export { nodeProcessExitCode, runRunnerCommand, runnerTaskTextEffect };
@@ -124,4 +124,4 @@ type RuntimeObservabilityEvent = {
124
124
  type: "runtime.retry.exhausted";
125
125
  };
126
126
  //#endregion
127
- export { RuntimeActorDescriptor, RuntimeObservabilityEvent };
127
+ export { RetryReason, RuntimeActorDescriptor, RuntimeActorKind, RuntimeObservabilityEvent };
@@ -1,2 +1,2 @@
1
- import "./agent-node.js";
2
- export {};
1
+ import { executeAgentNode } from "./agent-node.js";
2
+ export { executeAgentNode };
@@ -1,2 +1,2 @@
1
- import "./builtins.js";
2
- export {};
1
+ import { executeBuiltin } from "./builtins.js";
2
+ export { executeBuiltin };
@@ -35,7 +35,7 @@ function pathFromPorcelainEntry(entry) {
35
35
  return path ? [path] : [];
36
36
  }
37
37
  function diffChangedFiles(before, after, worktreePath) {
38
- const files = [...new Set([...before.files, ...after.files])].filter((file) => !before.files.has(file) || before.fingerprints.get(file) !== (after.fingerprints.get(file) ?? fileFingerprint(worktreePath, file)));
38
+ const files = [.../* @__PURE__ */ new Set([...before.files, ...after.files])].filter((file) => !before.files.has(file) || before.fingerprints.get(file) !== (after.fingerprints.get(file) ?? fileFingerprint(worktreePath, file)));
39
39
  return {
40
40
  files: new Set(files),
41
41
  fingerprints: new Map(files.map((file) => [file, after.fingerprints.get(file) ?? fileFingerprint(worktreePath, file)]))
@@ -1,2 +1,2 @@
1
- import "./changed-files.js";
2
- export {};
1
+ import { diffChangedFiles, snapshotChangedFiles } from "./changed-files.js";
2
+ export { diffChangedFiles, snapshotChangedFiles };
@@ -1,2 +1,2 @@
1
- import "./command-executor.js";
2
- export {};
1
+ import { executeCommand } from "./command-executor.js";
2
+ export { executeCommand };
@@ -1,2 +1,2 @@
1
- import "./context.js";
2
- export {};
1
+ import { createRuntimeContext, generateRuntimeRunId, resolveWorkflowSelection } from "./context.js";
2
+ export { createRuntimeContext, generateRuntimeRunId, resolveWorkflowSelection };
@@ -1 +1,2 @@
1
- import { AcceptanceCriterion, HookRuntimePolicy, NodeExecutionState, NodeStatus, PipelineRuntimeEvent, PipelineRuntimeObservabilityLevel, PipelineRuntimeOptions, PipelineRuntimeResult, PipelineTaskContext, RuntimeFailure, RuntimeGateResult, RuntimeNodeResult, RuntimeStructuredOutput, UnmetCriterion } from "./contracts.js";
1
+ import { AcceptanceCriterion, HookRuntimePolicy, NodeExecutionState, NodeStatus, PipelineRuntimeEvent, PipelineRuntimeObservabilityLevel, PipelineRuntimeOptions, PipelineRuntimeResult, PipelineTaskContext, RuntimeFailure, RuntimeGateResult, RuntimeNodeResult, RuntimeStructuredOutput, UnmetCriterion } from "./contracts.js";
2
+ export { AcceptanceCriterion, HookRuntimePolicy, NodeExecutionState, NodeStatus, PipelineRuntimeEvent, PipelineRuntimeObservabilityLevel, PipelineRuntimeOptions, PipelineRuntimeResult, PipelineTaskContext, RuntimeFailure, RuntimeGateResult, RuntimeNodeResult, RuntimeStructuredOutput, UnmetCriterion };
@@ -1,2 +1,2 @@
1
- import "./drain-merge.js";
2
- export {};
1
+ import { executeDrainMergeBuiltin } from "./drain-merge.js";
2
+ export { executeDrainMergeBuiltin };
@@ -1,9 +1,10 @@
1
1
  import { requireMokaDbUrl } from "../../moka-global-config.js";
2
+ import { migratePostgresSubstrate } from "./postgres/migrate-substrate.js";
2
3
  import { postgresDurableRunStore } from "./postgres/postgres-store.js";
3
4
  import { Effect } from "effect";
4
5
  //#region src/runtime/durable-store/acquisition.ts
5
6
  function resolveDurableStore(dbUrl, runId) {
6
- return requireMokaDbUrl(dbUrl).pipe(Effect.flatMap((requiredDbUrl) => Effect.acquireRelease(Effect.tryPromise(() => postgresDurableRunStore(requiredDbUrl, runId)), (store) => Effect.promise(() => store.close()))));
7
+ return requireMokaDbUrl(dbUrl).pipe(Effect.flatMap((requiredDbUrl) => Effect.tryPromise(() => migratePostgresSubstrate(requiredDbUrl)).pipe(Effect.flatMap(() => Effect.acquireRelease(Effect.tryPromise(() => postgresDurableRunStore(requiredDbUrl, runId)), (store) => Effect.promise(() => store.close()))))));
7
8
  }
8
9
  //#endregion
9
10
  export { resolveDurableStore };
@@ -0,0 +1,29 @@
1
+ import { fileURLToPath } from "node:url";
2
+ import { drizzle } from "drizzle-orm/postgres-js";
3
+ import { migrate } from "drizzle-orm/postgres-js/migrator";
4
+ import postgres from "postgres";
5
+ //#region src/runtime/durable-store/postgres/migrate-substrate.ts
6
+ const migrationsFolder = fileURLToPath(new URL("./migrations", import.meta.url));
7
+ const MIGRATION_LOCK_KEY = 8942017;
8
+ /**
9
+ * Apply the Drizzle migrations shared by the run-control and durable stores to
10
+ * `dbUrl`. Idempotent (Drizzle tracks applied migrations in
11
+ * `__drizzle_migrations` by content hash) and safe under concurrent callers
12
+ * (Postgres advisory lock serializes them). Opens and closes its own
13
+ * single-connection client.
14
+ */
15
+ async function migratePostgresSubstrate(dbUrl) {
16
+ const client = postgres(dbUrl, { max: 1 });
17
+ try {
18
+ await client`select pg_advisory_lock(${MIGRATION_LOCK_KEY}::bigint)`;
19
+ try {
20
+ await migrate(drizzle(client), { migrationsFolder });
21
+ } finally {
22
+ await client`select pg_advisory_unlock(${MIGRATION_LOCK_KEY}::bigint)`;
23
+ }
24
+ } finally {
25
+ await client.end();
26
+ }
27
+ }
28
+ //#endregion
29
+ export { migratePostgresSubstrate };
@@ -1,15 +1,13 @@
1
+ import "./migrate-substrate.js";
1
2
  import { createSerializedWriteQueue } from "../../../serialized-write-queue.js";
2
3
  import { buildRunJournal } from "../../run-journal.js";
3
4
  import { durableNodeRecord, durableRun } from "./schema.js";
4
- import { fileURLToPath } from "node:url";
5
- import { eq } from "drizzle-orm";
6
5
  import { drizzle } from "drizzle-orm/postgres-js";
7
- import "drizzle-orm/postgres-js/migrator";
8
6
  import postgres from "postgres";
7
+ import { eq } from "drizzle-orm";
9
8
  import pino from "pino";
10
9
  //#region src/runtime/durable-store/postgres/postgres-store.ts
11
10
  const logger = pino({ name: "postgres-durable-store" });
12
- fileURLToPath(new URL("./migrations", import.meta.url));
13
11
  function openClient(dbUrl) {
14
12
  return postgres(dbUrl, { max: 1 });
15
13
  }
@@ -3,7 +3,7 @@ import { runtimeActorId } from "../actor-ids.js";
3
3
  import { parseRuntimeOutput, validateJsonSchemaSource } from "../json-validation/json-validation.js";
4
4
  import "../json-validation/index.js";
5
5
  //#region src/runtime/events/events.ts
6
- const warningRuntimeObservabilityTypes = new Set([
6
+ const warningRuntimeObservabilityTypes = /* @__PURE__ */ new Set([
7
7
  "runtime.gate.cancelled",
8
8
  "runtime.gate.failed",
9
9
  "runtime.hook.failed",
@@ -15,7 +15,7 @@ const primaryRuntimeObservabilityPrefixes = [
15
15
  "runtime.hook.",
16
16
  "runtime.state."
17
17
  ];
18
- const structuredOutputFormats = new Set([
18
+ const structuredOutputFormats = /* @__PURE__ */ new Set([
19
19
  "json",
20
20
  "json_schema",
21
21
  "jsonl"
@@ -1,2 +1,2 @@
1
- import "./events.js";
2
- export {};
1
+ import { childReporter, createPublicRuntimeObservabilityEmitter, emit, emitAgentFinish, emitAgentStart, emitGateFinish, emitGateStart, emitNodeFinish, emitNodeOutputRecorded, emitNodeStart, emitWorkflowFinish, emitWorkflowPlanned, emitWorkflowStarted, runtimeNodeActorDescriptor, runtimeSystemId } from "./events.js";
2
+ export { childReporter, createPublicRuntimeObservabilityEmitter, emit, emitAgentFinish, emitAgentStart, emitGateFinish, emitGateStart, emitNodeFinish, emitNodeOutputRecorded, emitNodeStart, emitWorkflowFinish, emitWorkflowPlanned, emitWorkflowStarted, runtimeNodeActorDescriptor, runtimeSystemId };
@@ -1,5 +1,5 @@
1
- import "./contract.js";
2
- import "./gates.js";
3
- import "./registry.js";
4
- import "./orchestrator.js";
5
- export {};
1
+ import { forKind } from "./contract.js";
2
+ import { parseGateJson } from "./gates.js";
3
+ import { evaluateGate, gateRegistry } from "./registry.js";
4
+ import { evaluateNodeGates } from "./orchestrator.js";
5
+ export { evaluateGate, evaluateNodeGates, forKind, gateRegistry, parseGateJson };
@@ -106,4 +106,4 @@ function hasNonEmptyEvidence(value) {
106
106
  return Array.isArray(value) && value.filter((item) => typeof item === "string" && item.trim()).length > 0;
107
107
  }
108
108
  //#endregion
109
- export { evaluateAcceptanceGate };
109
+ export { acceptanceUnmetCriteria, evaluateAcceptanceGate };
@@ -20,7 +20,7 @@ function hookEnv(hook, context) {
20
20
  };
21
21
  }
22
22
  function commandHookEnvEntries(hook, context) {
23
- return [...new Set([...context.hookPolicy.envPassthrough, ...hook.env?.passthrough ?? []])].flatMap(commandHookEnvEntry);
23
+ return [.../* @__PURE__ */ new Set([...context.hookPolicy.envPassthrough, ...hook.env?.passthrough ?? []])].flatMap(commandHookEnvEntry);
24
24
  }
25
25
  function commandHookEnvEntry(name) {
26
26
  const value = process.env[name];
@@ -1,2 +1,2 @@
1
- import "./hooks.js";
2
- export {};
1
+ import { dispatchHooks } from "./hooks.js";
2
+ export { dispatchHooks };
@@ -1,2 +1,2 @@
1
- import "./json-validation.js";
2
- export {};
1
+ import { normalizeJsonSource, parseJsonObject, parseRuntimeOutput, readJsonSchemaSource, readOptionalFile, validateJsonSchemaSource } from "./json-validation.js";
2
+ export { normalizeJsonSource, parseJsonObject, parseRuntimeOutput, readJsonSchemaSource, readOptionalFile, validateJsonSchemaSource };
@@ -80,4 +80,4 @@ function parseSubmitResult(value) {
80
80
  return submitResultSchema.parse(value);
81
81
  }
82
82
  //#endregion
83
- export { parseSubmitResult };
83
+ export { parseSubmitResult, submitResultSchema };
@@ -95,4 +95,4 @@ function pendingNodeState(id) {
95
95
  };
96
96
  }
97
97
  //#endregion
98
- export { initialNodeStateStore };
98
+ export { NodeStateStore, initialNodeStateStore };
@@ -1,2 +1,2 @@
1
- import "./open-pull-request.js";
2
- export {};
1
+ import { executeOpenPullRequestBuiltin, openPullRequestProgram } from "./open-pull-request.js";
2
+ export { executeOpenPullRequestBuiltin, openPullRequestProgram };
@@ -200,7 +200,7 @@ function promptBody(plan) {
200
200
  ...plan.variant ? { variant: plan.variant } : {}
201
201
  };
202
202
  }
203
- const FLAGS_TAKING_VALUE = new Set([
203
+ const FLAGS_TAKING_VALUE = /* @__PURE__ */ new Set([
204
204
  "--agent",
205
205
  "--dir",
206
206
  "--file",
@@ -1,2 +1,2 @@
1
- import "./parallel-node.js";
2
- export {};
1
+ import { executeParallelNode } from "./parallel-node.js";
2
+ export { executeParallelNode };
@@ -30,4 +30,4 @@ function decideNodeRetry(input) {
30
30
  };
31
31
  }
32
32
  //#endregion
33
- export { decideNodeRetry, nodeRetryPolicy };
33
+ export { decideNodeRetry, nodeRetryPolicy, retryDelayMs };
@@ -132,7 +132,7 @@ function computeReadyNodeIds(input) {
132
132
  const completedIds = new Set((input.completed ?? []).map((r) => r.nodeId));
133
133
  const runningIds = new Set(input.running ?? []);
134
134
  const blockedIds = new Set(input.blocked ?? []);
135
- const settled = new Set([...completedIds, ...runningIds]);
135
+ const settled = /* @__PURE__ */ new Set([...completedIds, ...runningIds]);
136
136
  return orderedNodes(input.nodes).filter((node) => !(settled.has(node.id) || blockedIds.has(node.id))).filter((node) => node.needs.every((needId) => {
137
137
  const result = (input.completed ?? []).find((r) => r.nodeId === needId);
138
138
  if (result === void 0) return false;
@@ -13,4 +13,4 @@ declare const BacklogService_base: Context.ServiceClass<BacklogService, "Backlog
13
13
  }>;
14
14
  declare class BacklogService extends BacklogService_base {}
15
15
  //#endregion
16
- export { BacklogService };
16
+ export { BacklogCommandError, BacklogService };
@@ -21,4 +21,4 @@ const BacklogServiceLive = Layer.succeed(BacklogService, { run: (args, cwd) => E
21
21
  try: () => execa("backlog", [...args], { cwd })
22
22
  }).pipe(Effect.map((result) => result.stdout)) });
23
23
  //#endregion
24
- export { BacklogService, BacklogServiceLive };
24
+ export { BacklogCommandError, BacklogService, BacklogServiceLive };
@@ -1,9 +1,9 @@
1
1
  import { Context, Effect, Layer } from "effect";
2
- import simpleGit$1 from "simple-git";
2
+ import simpleGit from "simple-git";
3
3
  //#region src/runtime/services/drain-merge-git-service.ts
4
4
  var DrainMergeGitService = class extends Context.Service()("DrainMergeGitService") {};
5
5
  const DrainMergeGitServiceLive = Layer.succeed(DrainMergeGitService, { create: (baseDir) => Effect.sync(() => {
6
- const git = simpleGit$1({ baseDir });
6
+ const git = simpleGit({ baseDir });
7
7
  return { raw: (args) => Effect.tryPromise(() => git.raw(args)) };
8
8
  }) });
9
9
  //#endregion
@@ -62,6 +62,10 @@ function resolveKubeConfig(options, dependencies) {
62
62
  const kubeConfig = new KubeConfig();
63
63
  if (options.kubeconfigPath) kubeConfig.loadFromFile(options.kubeconfigPath);
64
64
  else kubeConfig.loadFromDefault();
65
+ if (options.kubeContext) {
66
+ if (!kubeConfig.getContextObject(options.kubeContext)) throw new Error(`Kube context '${options.kubeContext}' was not found in the resolved kubeconfig`);
67
+ kubeConfig.setCurrentContext(options.kubeContext);
68
+ }
65
69
  return kubeConfig;
66
70
  }
67
71
  function apiClients(options, dependencies) {
@@ -96,4 +100,4 @@ function kubectlErrorStdout(error) {
96
100
  return (error.stdout || "").trim();
97
101
  }
98
102
  //#endregion
99
- export { KubernetesArgoService, KubernetesArgoServiceLive };
103
+ export { KubernetesArgoService, KubernetesArgoServiceLive, resolveKubeConfig };
@@ -17,4 +17,4 @@ Layer.succeed(RunJournalFileService, {
17
17
  })
18
18
  });
19
19
  //#endregion
20
- export {};
20
+ export { RunJournalFileService };
@@ -127,4 +127,4 @@ function storeError(path, message) {
127
127
  });
128
128
  }
129
129
  //#endregion
130
- export { loadBacklogTaskStoreEffect };
130
+ export { BacklogTaskStoreError, loadBacklogTaskStoreEffect };
@@ -93,4 +93,4 @@ function errorMessage(error) {
93
93
  return error instanceof Error ? error.message : String(error);
94
94
  }
95
95
  //#endregion
96
- export { backlogTicketCompletionStoreEffect, completeTicket, conservativeLayerAJudge };
96
+ export { TicketCompletionError, backlogTicketCompletionStoreEffect, completeTicket, conservativeLayerAJudge };
@@ -21,7 +21,7 @@ function sequenceTicketBatchesEffect(graph, ticketIds = dependencyGraphNodeIds(g
21
21
  function scopedTicketIds(graph, rootId) {
22
22
  if (!rootId) return dependencyGraphNodeIds(graph.dependencyGraph).sort(compareTaskIds);
23
23
  if (!dependencyGraphHasNode(graph.dependencyGraph, rootId)) return [];
24
- const ids = new Set([rootId]);
24
+ const ids = /* @__PURE__ */ new Set([rootId]);
25
25
  const visit = (id) => {
26
26
  for (const child of graph.childrenByParentId.get(id) ?? []) {
27
27
  ids.add(child.id);
@@ -71,4 +71,4 @@ function compareTasks(a, b) {
71
71
  return compareBacklogTasks(a, b);
72
72
  }
73
73
  //#endregion
74
- export { buildTicketGraphEffect, compareTaskIds, predecessorIds, scopedTicketIds, sequenceTicketBatchesEffect };
74
+ export { TicketGraphError, buildTicketGraphEffect, compareTaskIds, predecessorIds, scopedTicketIds, sequenceTicketBatchesEffect };
@@ -41,4 +41,4 @@ declare const ticketPlanSchema: z.ZodObject<{
41
41
  }, z.core.$strict>;
42
42
  type TicketPlan = z.output<typeof ticketPlanSchema>;
43
43
  //#endregion
44
- export { TicketPlan };
44
+ export { TicketPlan, ticketPlanSchema };
@@ -0,0 +1,112 @@
1
+ # ADR: Two-Stage `moka submit` — Schedule-Then-Dispatch
2
+
3
+ Status: Accepted
4
+
5
+ Date: 2026-07-01
6
+
7
+ ## Decision
8
+
9
+ `moka submit` is one flow with two stages, not two separate commands and not two
10
+ separate code paths:
11
+
12
+ 1. **Schedule** — research, planning, and graph generation, producing a
13
+ `ScheduleArtifact` and persisting it to the durable Postgres run-control
14
+ store before any Argo Workflow exists.
15
+ 2. **Dispatch** — compile the persisted (or explicitly supplied) schedule into
16
+ an Argo Workflow manifest and submit it, targeting whatever Kubernetes
17
+ cluster/context the operator configured.
18
+
19
+ Both stages run inside the single call chain:
20
+
21
+ ```
22
+ moka submit [args]
23
+ -> registerSubmitCommand() src/cli/program.ts:71
24
+ -> runMokaSubmitFromCli() src/cli/submit-options.ts:55
25
+ -> submitMoka() src/moka-submit.ts:238
26
+ -> submitParsedMoka() src/remote/submit/service.ts:47
27
+ - compileMokaSubmitPlan() src/remote/submit/compilation.ts:32
28
+ - upsertRunRecord() [Schedule -> DB]
29
+ - submitCompiledMokaWorkflow() src/remote/submit/argo-submission.ts:46 [Dispatch]
30
+ ```
31
+
32
+ There is exactly one WorkflowSpec builder chain (`buildRunnerArgoWorkflowManifest`
33
+ / `buildDynamicRunnerArgoWorkflowManifest` in `src/argo-workflow.ts`) and exactly
34
+ one Kubernetes/Argo client (`KubernetesArgoService` in
35
+ `src/runtime/services/kubernetes-argo-service.ts`). Static and dynamic
36
+ scheduling are a discriminated union (`dynamicScheduling: boolean` on
37
+ `CompiledMokaSubmitPlan`), not parallel implementations.
38
+
39
+ ## Stage 1 — Schedule (research -> planning -> graph, persisted)
40
+
41
+ When no `scheduleYaml`/`schedulePath` is supplied at submit time
42
+ (`dynamicScheduling: true`), the schedule is produced inside the runner pod by
43
+ three sequential phases, run via `moka runner-pre-schedule --phase <phase>`
44
+ (`src/runner-command/pre-schedule.ts`):
45
+
46
+ 1. `pre-research` — produces research context (findings, risks, target).
47
+ 2. `pre-planning` — consumes research, produces a `TicketPlan` (tickets +
48
+ dependencies), via `ticketPlanPlanningContext()`
49
+ (`src/planning/generate.ts:343`).
50
+ 3. `generate-schedule` — calls the configured planner profile to produce the
51
+ final `ScheduleArtifact`. If the planner fails or emits an invalid
52
+ artifact, `ticketPlanScheduleArtifact()` (`src/planning/generate.ts:497`)
53
+ deterministically derives a schedule directly from the `TicketPlan` graph
54
+ instead — this is the accepted fallback shape, not a patch to remove.
55
+
56
+ The result is written once via `publishSchedule()`
57
+ (`src/run-control/run-control-store.ts:60`) into the run's manifest
58
+ (`moka_run_control_run.manifest` JSONB). `publishSchedule` is idempotent for an
59
+ identical schedule and rejects a conflicting one for the same run
60
+ (`tests/run-control-store-contract.test.ts:423`).
61
+
62
+ ## Stage 2 — Dispatch (compile -> submit)
63
+
64
+ `submitParsedMoka()` (`src/remote/submit/service.ts:47`) upserts the run record
65
+ to Postgres **before** calling Argo, but a DB write failure never blocks
66
+ dispatch — the guard at `service.ts:56-61` logs and proceeds, because the
67
+ in-pod runner lifecycle (`src/runner-command/lifecycle.ts`) re-creates the same
68
+ run record idempotently once the pod starts. Postgres is a durability/inspection
69
+ substrate for `moka status`/`moka logs`/`moka resume`, not a precondition for
70
+ submission.
71
+
72
+ `submitCompiledMokaWorkflow()` then calls `submitRunnerArgoWorkflow()` (static,
73
+ schedule already known) or `submitDynamicRunnerArgoWorkflow()` (dynamic,
74
+ schedule generated in-pod) — both in `src/argo-submit.ts`, both routed through
75
+ the same `KubernetesArgoService`.
76
+
77
+ ## Cluster targeting is one seam, not per-caller
78
+
79
+ Kubernetes context/kubeconfig resolution is a single function,
80
+ `resolveKubeConfig()` (`src/runtime/services/kubernetes-argo-service.ts`), used
81
+ by every Argo/K8s call (`createConfigMap`, `createWorkflow`,
82
+ `getWorkflowPhase`). Precedence, highest wins:
83
+
84
+ 1. `--kube-context <name>` / `--kubeconfig <path>` CLI flags
85
+ (`src/cli/submit-options.ts`)
86
+ 2. `momokaya.kubernetes.context` / `momokaya.kubernetes.kubeconfig` in
87
+ `~/.config/moka/config.yaml` (`src/moka-global-config.ts`)
88
+ 3. The kubeconfig's own `current-context` (`KubeConfig.loadFromDefault()`)
89
+
90
+ An unresolvable `kubeContext` fails loud at resolution time (`kubeConfig.
91
+ getContextObject()` check) rather than silently falling through to whatever
92
+ context happened to be current — this is what makes "point submit at momokaya
93
+ or at a local orbstack context" a config change, never a code change. Prior to
94
+ this ADR, `kubeContext` existed for the `kubectl`-shellout polling path
95
+ (`cluster-doctor.ts`) but not for the actual submission API calls; that gap is
96
+ closed as part of this decision.
97
+
98
+ ## Consequences
99
+
100
+ - Do not add a second "generate the graph" path or a second Argo client.
101
+ Static vs. dynamic scheduling is a data flag on `CompiledMokaSubmitPlan`, not
102
+ a reason to fork the builder or the service.
103
+ - Do not gate submission on the DB write succeeding — the guard in
104
+ `service.ts` is intentional, not a missing try/catch to "fix".
105
+ - Any new cluster-targeting option (a third context source, a per-namespace
106
+ override) is added to `resolveKubeConfig`'s precedence list, not threaded
107
+ ad hoc through individual call sites.
108
+
109
+ ## References
110
+
111
+ - Run-control persistence model: `./run-control.md`
112
+ - PIPE-94 durable substrate: `oisin-ee` backlog PIPE-94.3/94.4/94.5/94.8
package/package.json CHANGED
@@ -32,6 +32,8 @@
32
32
  "devDependencies": {
33
33
  "@biomejs/biome": "2.4.15",
34
34
  "@effect/vitest": "^4.0.0-beta.90",
35
+ "@mpsuesser/oxlint-plugin-effect": "0.3.0",
36
+ "@oisin-ee/oxlint-config": "1.0.0",
35
37
  "@semantic-release/commit-analyzer": "^13.0.1",
36
38
  "@semantic-release/exec": "^7.1.0",
37
39
  "@semantic-release/github": "^12.0.8",
@@ -42,6 +44,9 @@
42
44
  "@typescript/native-preview": "7.0.0-dev.20260629.1",
43
45
  "drizzle-kit": "0.31.10",
44
46
  "jscpd": "^4.0.5",
47
+ "oxfmt": "^0.56.0",
48
+ "oxlint": "^1.71.0",
49
+ "oxlint-tsgolint": "^0.23.0",
45
50
  "semantic-release": "^25.0.3",
46
51
  "tsdown": "^0.22.0",
47
52
  "typescript": "rc",
@@ -132,7 +137,7 @@
132
137
  "prepack": "nub run build:cli"
133
138
  },
134
139
  "type": "module",
135
- "version": "3.19.4",
140
+ "version": "3.19.6",
136
141
  "description": "Config-driven multi-agent pipeline runner for repository work",
137
142
  "main": "./dist/index.js",
138
143
  "types": "./dist/index.d.ts",