@revisium/orchestrator 0.0.0

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 (176) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +20 -0
  3. package/bin/revo.js +2 -0
  4. package/control-plane/bootstrap.config.json +931 -0
  5. package/dist/app.module.js +28 -0
  6. package/dist/app.module.js.map +1 -0
  7. package/dist/cli/commands/bootstrap.js +39 -0
  8. package/dist/cli/commands/bootstrap.js.map +1 -0
  9. package/dist/cli/commands/dev.js +143 -0
  10. package/dist/cli/commands/dev.js.map +1 -0
  11. package/dist/cli/commands/inbox.js +288 -0
  12. package/dist/cli/commands/inbox.js.map +1 -0
  13. package/dist/cli/commands/mcp.js +16 -0
  14. package/dist/cli/commands/mcp.js.map +1 -0
  15. package/dist/cli/commands/playbook.js +74 -0
  16. package/dist/cli/commands/playbook.js.map +1 -0
  17. package/dist/cli/commands/poll-workflow-state.js +144 -0
  18. package/dist/cli/commands/poll-workflow-state.js.map +1 -0
  19. package/dist/cli/commands/revisium-context.js +23 -0
  20. package/dist/cli/commands/revisium-context.js.map +1 -0
  21. package/dist/cli/commands/revisium-helpers.js +61 -0
  22. package/dist/cli/commands/revisium-helpers.js.map +1 -0
  23. package/dist/cli/commands/revisium.js +89 -0
  24. package/dist/cli/commands/revisium.js.map +1 -0
  25. package/dist/cli/commands/run.js +426 -0
  26. package/dist/cli/commands/run.js.map +1 -0
  27. package/dist/cli/commands/work.js +149 -0
  28. package/dist/cli/commands/work.js.map +1 -0
  29. package/dist/cli/config.js +2 -0
  30. package/dist/cli/config.js.map +1 -0
  31. package/dist/cli/index.js +32 -0
  32. package/dist/cli/index.js.map +1 -0
  33. package/dist/cli/live-guard.js +49 -0
  34. package/dist/cli/live-guard.js.map +1 -0
  35. package/dist/cli/needs-host.js +78 -0
  36. package/dist/cli/needs-host.js.map +1 -0
  37. package/dist/cli/program.js +37 -0
  38. package/dist/cli/program.js.map +1 -0
  39. package/dist/config.js +102 -0
  40. package/dist/config.js.map +1 -0
  41. package/dist/control-plane/client-transport.js +146 -0
  42. package/dist/control-plane/client-transport.js.map +1 -0
  43. package/dist/control-plane/data-access.js +99 -0
  44. package/dist/control-plane/data-access.js.map +1 -0
  45. package/dist/control-plane/definitions.js +120 -0
  46. package/dist/control-plane/definitions.js.map +1 -0
  47. package/dist/control-plane/errors.js +13 -0
  48. package/dist/control-plane/errors.js.map +1 -0
  49. package/dist/control-plane/inbox.js +261 -0
  50. package/dist/control-plane/inbox.js.map +1 -0
  51. package/dist/control-plane/index.js +6 -0
  52. package/dist/control-plane/index.js.map +1 -0
  53. package/dist/control-plane/json-fields.js +68 -0
  54. package/dist/control-plane/json-fields.js.map +1 -0
  55. package/dist/control-plane/resolve-cwd.js +75 -0
  56. package/dist/control-plane/resolve-cwd.js.map +1 -0
  57. package/dist/control-plane/steps.js +381 -0
  58. package/dist/control-plane/steps.js.map +1 -0
  59. package/dist/control-plane/tables.js +13 -0
  60. package/dist/control-plane/tables.js.map +1 -0
  61. package/dist/control-plane/versioned-meaning.js +53 -0
  62. package/dist/control-plane/versioned-meaning.js.map +1 -0
  63. package/dist/engine/dbos.module.js +18 -0
  64. package/dist/engine/dbos.module.js.map +1 -0
  65. package/dist/engine/dbos.service.js +296 -0
  66. package/dist/engine/dbos.service.js.map +1 -0
  67. package/dist/engine/ensure-postgres.js +80 -0
  68. package/dist/engine/ensure-postgres.js.map +1 -0
  69. package/dist/engine/types.js +2 -0
  70. package/dist/engine/types.js.map +1 -0
  71. package/dist/host/ensure-revisium.js +269 -0
  72. package/dist/host/ensure-revisium.js.map +1 -0
  73. package/dist/host/host.lifecycle.js +75 -0
  74. package/dist/host/host.lifecycle.js.map +1 -0
  75. package/dist/mcp/mcp-capabilities.js +47 -0
  76. package/dist/mcp/mcp-capabilities.js.map +1 -0
  77. package/dist/mcp/mcp-facade.service.js +130 -0
  78. package/dist/mcp/mcp-facade.service.js.map +1 -0
  79. package/dist/mcp/mcp-stdio.service.js +48 -0
  80. package/dist/mcp/mcp-stdio.service.js.map +1 -0
  81. package/dist/mcp/mcp-tools.js +264 -0
  82. package/dist/mcp/mcp-tools.js.map +1 -0
  83. package/dist/mcp/mcp.module.js +21 -0
  84. package/dist/mcp/mcp.module.js.map +1 -0
  85. package/dist/package-info.js +10 -0
  86. package/dist/package-info.js.map +1 -0
  87. package/dist/pipeline/await-human.js +62 -0
  88. package/dist/pipeline/await-human.js.map +1 -0
  89. package/dist/pipeline/develop-task.workflow.js +497 -0
  90. package/dist/pipeline/develop-task.workflow.js.map +1 -0
  91. package/dist/pipeline/pipeline.module.js +34 -0
  92. package/dist/pipeline/pipeline.module.js.map +1 -0
  93. package/dist/playbook/catalog-loader.js +145 -0
  94. package/dist/playbook/catalog-loader.js.map +1 -0
  95. package/dist/playbook/errors.js +14 -0
  96. package/dist/playbook/errors.js.map +1 -0
  97. package/dist/playbook/import-mapper.js +186 -0
  98. package/dist/playbook/import-mapper.js.map +1 -0
  99. package/dist/playbook/manifest.js +60 -0
  100. package/dist/playbook/manifest.js.map +1 -0
  101. package/dist/playbook/playbook-installer.js +51 -0
  102. package/dist/playbook/playbook-installer.js.map +1 -0
  103. package/dist/playbook/prompt-composer.js +34 -0
  104. package/dist/playbook/prompt-composer.js.map +1 -0
  105. package/dist/playbook/source-resolver.js +105 -0
  106. package/dist/playbook/source-resolver.js.map +1 -0
  107. package/dist/poller/pr-readiness-core.js +656 -0
  108. package/dist/poller/pr-readiness-core.js.map +1 -0
  109. package/dist/poller/pr-readiness.js +91 -0
  110. package/dist/poller/pr-readiness.js.map +1 -0
  111. package/dist/revisium/inbox.service.js +67 -0
  112. package/dist/revisium/inbox.service.js.map +1 -0
  113. package/dist/revisium/playbooks.service.js +99 -0
  114. package/dist/revisium/playbooks.service.js.map +1 -0
  115. package/dist/revisium/revisium.module.js +55 -0
  116. package/dist/revisium/revisium.module.js.map +1 -0
  117. package/dist/revisium/roles.service.js +79 -0
  118. package/dist/revisium/roles.service.js.map +1 -0
  119. package/dist/revisium/run.service.js +182 -0
  120. package/dist/revisium/run.service.js.map +1 -0
  121. package/dist/revisium/tokens.js +7 -0
  122. package/dist/revisium/tokens.js.map +1 -0
  123. package/dist/run/append-event.js +112 -0
  124. package/dist/run/append-event.js.map +1 -0
  125. package/dist/run/cancel-run.js +47 -0
  126. package/dist/run/cancel-run.js.map +1 -0
  127. package/dist/run/create-run.js +208 -0
  128. package/dist/run/create-run.js.map +1 -0
  129. package/dist/run/fail-run.js +20 -0
  130. package/dist/run/fail-run.js.map +1 -0
  131. package/dist/run/inspect-run.js +287 -0
  132. package/dist/run/inspect-run.js.map +1 -0
  133. package/dist/run/terminal-run-status.js +45 -0
  134. package/dist/run/terminal-run-status.js.map +1 -0
  135. package/dist/runners/claude-code.service.js +48 -0
  136. package/dist/runners/claude-code.service.js.map +1 -0
  137. package/dist/runners/gh-identity.js +108 -0
  138. package/dist/runners/gh-identity.js.map +1 -0
  139. package/dist/runners/integrator.js +417 -0
  140. package/dist/runners/integrator.js.map +1 -0
  141. package/dist/runners/runner.module.js +40 -0
  142. package/dist/runners/runner.module.js.map +1 -0
  143. package/dist/runners/tokens.js +7 -0
  144. package/dist/runners/tokens.js.map +1 -0
  145. package/dist/task-control-plane/pr-readiness.service.js +33 -0
  146. package/dist/task-control-plane/pr-readiness.service.js.map +1 -0
  147. package/dist/task-control-plane/task-control-plane-api.service.js +440 -0
  148. package/dist/task-control-plane/task-control-plane-api.service.js.map +1 -0
  149. package/dist/task-control-plane/task-control-plane.module.js +23 -0
  150. package/dist/task-control-plane/task-control-plane.module.js.map +1 -0
  151. package/dist/worker/build-context.js +39 -0
  152. package/dist/worker/build-context.js.map +1 -0
  153. package/dist/worker/claude-code-runner.js +135 -0
  154. package/dist/worker/claude-code-runner.js.map +1 -0
  155. package/dist/worker/git-worktree-manager.js +84 -0
  156. package/dist/worker/git-worktree-manager.js.map +1 -0
  157. package/dist/worker/loop.js +122 -0
  158. package/dist/worker/loop.js.map +1 -0
  159. package/dist/worker/process-executor.js +62 -0
  160. package/dist/worker/process-executor.js.map +1 -0
  161. package/dist/worker/result-envelope.js +134 -0
  162. package/dist/worker/result-envelope.js.map +1 -0
  163. package/dist/worker/runner-dispatch.js +20 -0
  164. package/dist/worker/runner-dispatch.js.map +1 -0
  165. package/dist/worker/runner.js +2 -0
  166. package/dist/worker/runner.js.map +1 -0
  167. package/dist/worker/script-runner.js +28 -0
  168. package/dist/worker/script-runner.js.map +1 -0
  169. package/dist/worker/stub-runner.js +59 -0
  170. package/dist/worker/stub-runner.js.map +1 -0
  171. package/dist/worker/worker-id.js +18 -0
  172. package/dist/worker/worker-id.js.map +1 -0
  173. package/dist/worker/worktree-manager.js +7 -0
  174. package/dist/worker/worktree-manager.js.map +1 -0
  175. package/package.json +66 -0
  176. package/revisium.config.json +10 -0
@@ -0,0 +1,182 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ var __metadata = (this && this.__metadata) || function (k, v) {
8
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
9
+ };
10
+ var __param = (this && this.__param) || function (paramIndex, decorator) {
11
+ return function (target, key) { decorator(target, key, paramIndex); }
12
+ };
13
+ import { Injectable, Inject } from '@nestjs/common';
14
+ import { createControlPlaneDataAccessForTransport } from '../control-plane/data-access.js';
15
+ import { ControlPlaneError } from '../control-plane/errors.js';
16
+ import { fnv1a64Hex } from '../control-plane/steps.js';
17
+ import { makeResolveCwd, makeResolveTaskCwd } from '../control-plane/resolve-cwd.js';
18
+ import { createRunWorkflow } from '../run/create-run.js';
19
+ import { listRuns, showRun, listRunEvents, listRunAttempts, getRunFailure } from '../run/inspect-run.js';
20
+ import { cancelRun } from '../run/cancel-run.js';
21
+ import { failRun } from '../run/fail-run.js';
22
+ import { appendRunEvent, appendRunCost, appendRunAttempt } from '../run/append-event.js';
23
+ import { REVISIUM_TRANSPORT_DRAFT } from './tokens.js';
24
+ /**
25
+ * RunService — thin DI wrapper over the run verbs.
26
+ * Injects the DRAFT transport (runtime/draft table writes).
27
+ *
28
+ * G3: da is initialized in the constructor BODY (not a class-field initializer).
29
+ * A class-field initializer for `da` would run before the constructor assigns the
30
+ * `draftTransport` parameter property under ES2023/NodeNext emit, so it would read
31
+ * this.draftTransport as undefined. The constructor-body form is safe.
32
+ */
33
+ let RunService = class RunService {
34
+ draftTransport;
35
+ da;
36
+ constructor(draftTransport) {
37
+ this.draftTransport = draftTransport;
38
+ // Must build da in the constructor body — see G3 note above.
39
+ this.da = createControlPlaneDataAccessForTransport(this.draftTransport);
40
+ }
41
+ createRun(input) {
42
+ return createRunWorkflow(this.da, input);
43
+ }
44
+ listRuns(filter) {
45
+ return listRuns(this.da, filter);
46
+ }
47
+ showRun(id) {
48
+ return showRun(this.da, id);
49
+ }
50
+ listRunEvents(id, filter) {
51
+ return listRunEvents(this.da, id, filter);
52
+ }
53
+ /** List per-attempt observability rows for a run (0008 #4 — `revo run log`). */
54
+ listRunAttempts(id, filter) {
55
+ return listRunAttempts(this.da, id, filter);
56
+ }
57
+ cancelRun(id, opts) {
58
+ return cancelRun(this.da, id, opts);
59
+ }
60
+ /**
61
+ * failRun — patch task_runs to `failed` + write a run_failed event (0008 #2).
62
+ * Event-first + idempotent. Called by the pipeline workflow body on a terminal step failure
63
+ * so the Revisium run-row reflects the failure (DBOS=progress, Revisium=meaning).
64
+ */
65
+ failRun(id, reason, opts) {
66
+ return failRun(this.da, id, reason, opts);
67
+ }
68
+ /** Expose getRun for events pre-check (run not found guard in CLI). */
69
+ getRun(id) {
70
+ return this.da.getRow('task_runs', id);
71
+ }
72
+ /** Read run-row status + the run_failed reason (0008 #2 — surfaced by `run start --wait`). */
73
+ getRunFailure(id) {
74
+ return getRunFailure(this.da, id);
75
+ }
76
+ /**
77
+ * loadPipelineContext — M3 (TASK 0003).
78
+ *
79
+ * Exposes the private draft `da` via a typed verb (never widening the field to public).
80
+ * Synthesizes an in-memory Step with the real taskId from showRun (B6: tasks[0].taskId).
81
+ * `modelProfile` is the caller-supplied role-derived level (B7 — not hardcoded 'standard').
82
+ *
83
+ * B6: `RunDetail = { run, tasks: TaskSummary[] }` — taskId is on TaskSummary, NOT top-level.
84
+ * `createRunWorkflow` writes exactly ONE task per run, so tasks[0] is THE task.
85
+ */
86
+ async loadPipelineContext(runId, role, stepKey, stepInput, modelProfile) {
87
+ const detail = await showRun(this.da, runId);
88
+ if (!detail) {
89
+ throw new ControlPlaneError('ROW_NOT_FOUND', `run not found: ${runId}`);
90
+ }
91
+ const taskId = detail.tasks[0]?.taskId;
92
+ if (!taskId) {
93
+ throw new ControlPlaneError('ROW_NOT_FOUND', `run ${runId} has no task`);
94
+ }
95
+ const step = {
96
+ id: `pstep_${fnv1a64Hex(`${runId}|${stepKey}`)}`,
97
+ taskId,
98
+ runId,
99
+ role,
100
+ kind: 'pipeline',
101
+ status: 'running',
102
+ input: stepInput,
103
+ output: null,
104
+ modelProfile,
105
+ runAfter: '',
106
+ attemptCount: 0,
107
+ maxAttempts: 1,
108
+ priority: 0,
109
+ leaseOwner: '',
110
+ leaseExpiresAt: '',
111
+ deadReason: '',
112
+ };
113
+ return { da: this.da, step };
114
+ }
115
+ /**
116
+ * makeResolveCwd — STEP-level cwd resolver (M3).
117
+ * Returns (step: Step) => Promise<string>; reads tasks.repo_ref via the draft da.
118
+ * Used by ClaudeCodeService.
119
+ */
120
+ makeResolveCwd(base = process.cwd()) {
121
+ return makeResolveCwd(this.da, base);
122
+ }
123
+ /**
124
+ * makeResolveTaskCwd — TASK-level cwd resolver (M3).
125
+ * Returns (taskId: string) => Promise<string>; reads tasks.repo_ref via the draft da.
126
+ * Used by IntegratorService + the live preflight (no Step available).
127
+ */
128
+ makeResolveTaskCwd(base = process.cwd()) {
129
+ return makeResolveTaskCwd(this.da, base);
130
+ }
131
+ /**
132
+ * loadRunTaskContext — B6: resolve { taskId, title, base, repoRef } from run input.
133
+ *
134
+ * Backed by showRun(da, runId). base is always 'master' (no base field in run input —
135
+ * verified: create-run.ts stores only repos/repo_ref). Throws a clear error if the run
136
+ * or its task is missing.
137
+ */
138
+ async loadRunTaskContext(runId) {
139
+ const detail = await showRun(this.da, runId);
140
+ if (!detail) {
141
+ throw new ControlPlaneError('ROW_NOT_FOUND', `loadRunTaskContext: run ${runId} not found`);
142
+ }
143
+ const task = detail.tasks[0];
144
+ if (!task) {
145
+ throw new ControlPlaneError('ROW_NOT_FOUND', `loadRunTaskContext: run ${runId} has no task`);
146
+ }
147
+ return {
148
+ taskId: task.taskId,
149
+ title: task.title,
150
+ base: 'master', // MVP: base branch pinned to 'master' (see plan 0005); dynamic default-branch detection is post-MVP.
151
+ repoRef: detail.run.repos[0] ?? '',
152
+ };
153
+ }
154
+ /**
155
+ * appendEvent — write an idempotent event to the draft events table.
156
+ * Wraps appendRunEvent over the service's draft da.
157
+ */
158
+ appendEvent(input) {
159
+ return appendRunEvent(this.da, input);
160
+ }
161
+ /**
162
+ * appendCost — write an idempotent cost row to the draft cost_ledger table.
163
+ * Wraps appendRunCost over the service's draft da.
164
+ */
165
+ appendCost(input) {
166
+ return appendRunCost(this.da, input);
167
+ }
168
+ /**
169
+ * appendAttempt — write an idempotent per-attempt observability row to the draft attempts table.
170
+ * Wraps appendRunAttempt over the service's draft da (0008 #4).
171
+ */
172
+ appendAttempt(input) {
173
+ return appendRunAttempt(this.da, input);
174
+ }
175
+ };
176
+ RunService = __decorate([
177
+ Injectable(),
178
+ __param(0, Inject(REVISIUM_TRANSPORT_DRAFT)),
179
+ __metadata("design:paramtypes", [Object])
180
+ ], RunService);
181
+ export { RunService };
182
+ //# sourceMappingURL=run.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run.service.js","sourceRoot":"","sources":["../../src/revisium/run.service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Injection tokens for RevisiumModule transports.
3
+ * Shared between the module and the service constructors.
4
+ */
5
+ export const REVISIUM_TRANSPORT_DRAFT = 'REVISIUM_TRANSPORT_DRAFT';
6
+ export const REVISIUM_TRANSPORT_HEAD = 'REVISIUM_TRANSPORT_HEAD';
7
+ //# sourceMappingURL=tokens.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tokens.js","sourceRoot":"","sources":["../../src/revisium/tokens.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,CAAC,MAAM,wBAAwB,GAAG,0BAA0B,CAAC;AACnE,MAAM,CAAC,MAAM,uBAAuB,GAAG,yBAAyB,CAAC"}
@@ -0,0 +1,112 @@
1
+ import { ControlPlaneError } from '../control-plane/errors.js';
2
+ import { fnv1a64Hex } from '../control-plane/steps.js';
3
+ import { redactSecrets } from '../control-plane/inbox.js';
4
+ import { redactTokens } from '../runners/gh-identity.js';
5
+ /**
6
+ * Write a single event row to the `events` table.
7
+ *
8
+ * eventId = `event_${fnv1a64Hex(`${runId}|${stepKey}|${type}`)}` → 22 chars ≤ 64
9
+ *
10
+ * Idempotent: catches ROW_CONFLICT and returns (no-op on replay).
11
+ */
12
+ export async function appendRunEvent(da, input) {
13
+ const { runId, taskId, stepId, stepKey, type, payload, actor, createdAt } = input;
14
+ const eventId = `event_${fnv1a64Hex(`${runId}|${stepKey}|${type}`)}`;
15
+ const createdAtIso = (createdAt ?? new Date()).toISOString();
16
+ try {
17
+ await da.createRow('events', eventId, {
18
+ id: eventId,
19
+ run_id: runId,
20
+ task_id: taskId,
21
+ step_id: stepId,
22
+ type,
23
+ payload,
24
+ actor: actor ?? 'orchestrator',
25
+ created_at: createdAtIso,
26
+ });
27
+ }
28
+ catch (e) {
29
+ if (e instanceof ControlPlaneError && e.code === 'ROW_CONFLICT')
30
+ return;
31
+ throw e;
32
+ }
33
+ }
34
+ /** Cap the serialized output summary so a giant agent payload can't bloat the attempts row. */
35
+ const OUTPUT_SUMMARY_MAX = 4_000;
36
+ /**
37
+ * Write a single per-attempt observability row to the `attempts` table (0008 #4).
38
+ *
39
+ * Populates the previously-unused `attempts` table so `revo run log` can show output summary,
40
+ * verdict, model, tokens, cost, duration, and iteration per attempt — the dogfood's observability
41
+ * gap (agent output was only recoverable indirectly via plan files / commit diffs).
42
+ *
43
+ * SECRET BOUNDARY: the output summary, lesson, and error are secret-redacted (object keys via
44
+ * redactSecrets, token shapes via redactTokens) before persisting — attempts live in Revisium.
45
+ *
46
+ * Idempotent: the row id IS the deterministic attemptId; ROW_CONFLICT is a no-op on replay.
47
+ */
48
+ export async function appendRunAttempt(da, input) {
49
+ const summaryRaw = JSON.stringify(redactSecrets(input.output) ?? null);
50
+ const outputSummary = redactTokens(summaryRaw).slice(0, OUTPUT_SUMMARY_MAX);
51
+ try {
52
+ await da.createRow('attempts', input.attemptId, {
53
+ id: input.attemptId,
54
+ step_id: input.stepId,
55
+ run_id: input.runId,
56
+ worker_id: '',
57
+ attempt_no: input.attemptNo,
58
+ iteration: input.iteration,
59
+ status: input.status,
60
+ idempotency_key: input.attemptId,
61
+ model_profile: input.modelProfile,
62
+ verdict: input.verdict,
63
+ input_tokens: input.inputTokens,
64
+ output_tokens: input.outputTokens,
65
+ cost_amount: input.costAmount,
66
+ currency: input.currency ?? 'USD',
67
+ duration_ms: input.durationMs,
68
+ output_summary: outputSummary,
69
+ lesson: input.lesson ? redactTokens(input.lesson).slice(0, OUTPUT_SUMMARY_MAX) : '',
70
+ error: input.error ? redactTokens(input.error).slice(0, OUTPUT_SUMMARY_MAX) : '',
71
+ started_at: (input.startedAt ?? new Date()).toISOString(),
72
+ finished_at: (input.finishedAt ?? new Date()).toISOString(),
73
+ });
74
+ }
75
+ catch (e) {
76
+ if (e instanceof ControlPlaneError && e.code === 'ROW_CONFLICT')
77
+ return;
78
+ throw e;
79
+ }
80
+ }
81
+ /**
82
+ * Write a single cost row to the `cost_ledger` table.
83
+ *
84
+ * costId = `cost_${fnv1a64Hex(`${runId}|${stepKey}|${index}`)}` → 21 chars ≤ 64
85
+ *
86
+ * Idempotent: catches ROW_CONFLICT and returns (no-op on replay).
87
+ */
88
+ export async function appendRunCost(da, input) {
89
+ const { runId, stepId, stepKey, attemptId, cost, index, recordedAt } = input;
90
+ const costId = `cost_${fnv1a64Hex(`${runId}|${stepKey}|${index}`)}`;
91
+ const recordedAtIso = (recordedAt ?? new Date()).toISOString();
92
+ try {
93
+ await da.createRow('cost_ledger', costId, {
94
+ id: costId,
95
+ run_id: runId,
96
+ step_id: stepId,
97
+ attempt_id: attemptId,
98
+ model_profile: cost.modelProfile,
99
+ input_tokens: cost.inputTokens,
100
+ output_tokens: cost.outputTokens,
101
+ cost_amount: cost.costAmount,
102
+ currency: cost.currency ?? 'USD',
103
+ recorded_at: recordedAtIso,
104
+ });
105
+ }
106
+ catch (e) {
107
+ if (e instanceof ControlPlaneError && e.code === 'ROW_CONFLICT')
108
+ return;
109
+ throw e;
110
+ }
111
+ }
112
+ //# sourceMappingURL=append-event.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"append-event.js","sourceRoot":"","sources":["../../src/run/append-event.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,47 @@
1
+ import { recordTerminalRunStatus } from './terminal-run-status.js';
2
+ /**
3
+ * cancelRun — patch task_runs to cancelled + write a run_cancelled event.
4
+ *
5
+ * G3 (0004): the event id is NOW DETERMINISTIC: `event_${fnv1a64Hex(`${runId}|run_cancelled`)}`.
6
+ * This mirrors append-event.ts's pattern (22 chars ≤ 64; no timestamp).
7
+ * createRow is wrapped in a ROW_CONFLICT catch so a workflow-body replay does NOT
8
+ * duplicate or fail the event insert (idempotent under DBOS recovery).
9
+ *
10
+ * CR-A (0004 CR): EVENT-FIRST ordering — the run_cancelled event is written BEFORE the
11
+ * task_runs status patch. This preserves correct `previous_status` on replay:
12
+ * 1. Read run → capture prev = run.status.
13
+ * 2. If prev === 'cancelled': the event already exists (ROW_CONFLICT no-op) with the TRUE
14
+ * prior status written on the first run. Skip the status patch too. Return.
15
+ * 3. createRow the deterministic event with previous_status: prev (FIRST write — immutable
16
+ * because ROW_CONFLICT means the first write always wins on replay).
17
+ * 4. idempotently patch task_runs.status → 'cancelled' (only if not already cancelled).
18
+ * If a replay stops between steps 3 and 4, the next replay re-reads prev, sees the event
19
+ * already exists (ROW_CONFLICT no-op at step 3), and idemptently applies the patch at step 4.
20
+ * The event's `previous_status` is ALWAYS the true prior status captured on the FIRST execution.
21
+ *
22
+ * CR-B (0004 CR): caller-aware actor/source — the pipeline gate reject path passes
23
+ * actor:'pipeline', source:'plan-gate-reject'; the CLI `run cancel` path keeps the
24
+ * default actor:'cli', source:'revo run cancel'. Thread via opts.
25
+ *
26
+ * C1 (0004 review): read-then-guard — if the run is already cancelled, skip both the
27
+ * event write (ROW_CONFLICT no-op) and the task_runs patch (C1: no fresh updated_at on replay).
28
+ *
29
+ * The `opts.idSuffix` parameter is kept for signature back-compat (0002 `run cancel` CLI
30
+ * passes it) but no longer influences the event id — it is intentionally unused here.
31
+ */
32
+ export async function cancelRun(da, runId, opts) {
33
+ // CR-A/G3/C1: event-first, deterministic id, ROW_CONFLICT-idempotent, no fresh updated_at when
34
+ // already cancelled — all provided by the shared writer (terminal-run-status.ts). `idSuffix` is
35
+ // kept on the signature for back-compat (0002 `run cancel`) but does NOT influence the event id.
36
+ const result = await recordTerminalRunStatus(da, runId, {
37
+ status: 'cancelled',
38
+ eventType: 'run_cancelled',
39
+ actor: opts?.actor ?? 'cli',
40
+ payload: { source: opts?.source ?? 'revo run cancel' },
41
+ now: opts?.now ?? new Date(),
42
+ });
43
+ if (!result)
44
+ return null;
45
+ return { runId, previousStatus: result.previousStatus, status: 'cancelled' };
46
+ }
47
+ //# sourceMappingURL=cancel-run.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cancel-run.js","sourceRoot":"","sources":["../../src/run/cancel-run.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,uBAAuB,EAAE,MAAM,0BAA0B,CAAC;AAQnE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,MAAM,CAAC,KAAK,UAAU,SAAS,CAC7B,EAA0B,EAC1B,KAAa,EACb,IAAyE;IAEzE,+FAA+F;IAC/F,gGAAgG;IAChG,iGAAiG;IACjG,MAAM,MAAM,GAAG,MAAM,uBAAuB,CAAC,EAAE,EAAE,KAAK,EAAE;QACtD,MAAM,EAAE,WAAW;QACnB,SAAS,EAAE,eAAe;QAC1B,KAAK,EAAE,IAAI,EAAE,KAAK,IAAI,KAAK;QAC3B,OAAO,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,IAAI,iBAAiB,EAAE;QACtD,GAAG,EAAE,IAAI,EAAE,GAAG,IAAI,IAAI,IAAI,EAAE;KAC7B,CAAC,CAAC;IACH,IAAI,CAAC,MAAM;QAAE,OAAO,IAAI,CAAC;IACzB,OAAO,EAAE,KAAK,EAAE,cAAc,EAAE,MAAM,CAAC,cAAc,EAAE,MAAM,EAAE,WAAW,EAAE,CAAC;AAC/E,CAAC"}
@@ -0,0 +1,208 @@
1
+ import { existsSync, statSync } from 'node:fs';
2
+ import os from 'node:os';
3
+ import path from 'node:path';
4
+ import { randomUUID } from 'node:crypto';
5
+ export class CreateRunWorkflowError extends Error {
6
+ createdIds;
7
+ cause;
8
+ constructor(message, createdIds, cause) {
9
+ super(message);
10
+ this.name = 'CreateRunWorkflowError';
11
+ this.createdIds = createdIds;
12
+ this.cause = cause;
13
+ }
14
+ }
15
+ function compactUtcStamp(date) {
16
+ const pad = (value, length = 2) => String(value).padStart(length, '0');
17
+ return [
18
+ date.getUTCFullYear(),
19
+ pad(date.getUTCMonth() + 1),
20
+ pad(date.getUTCDate()),
21
+ 'T',
22
+ pad(date.getUTCHours()),
23
+ pad(date.getUTCMinutes()),
24
+ pad(date.getUTCSeconds()),
25
+ pad(date.getUTCMilliseconds(), 3),
26
+ 'Z',
27
+ ].join('');
28
+ }
29
+ export const KNOWN_ROLES = ['architect', 'developer', 'reviewer', 'integrator', 'pr-watcher'];
30
+ const DEFAULT_ROLE = 'architect';
31
+ const maxSlugLength = 21;
32
+ function slugTitle(title) {
33
+ let slug = '';
34
+ let needsSeparator = false;
35
+ for (const char of title.toLowerCase()) {
36
+ const isAlphanumeric = (char >= 'a' && char <= 'z') || (char >= '0' && char <= '9');
37
+ if (!isAlphanumeric) {
38
+ needsSeparator = slug.length > 0;
39
+ continue;
40
+ }
41
+ if (needsSeparator && slug.length < maxSlugLength)
42
+ slug += '-';
43
+ needsSeparator = false;
44
+ if (slug.length < maxSlugLength)
45
+ slug += char;
46
+ if (slug.length >= maxSlugLength)
47
+ break;
48
+ }
49
+ while (slug.endsWith('-'))
50
+ slug = slug.slice(0, -1);
51
+ return slug || 'run';
52
+ }
53
+ function expandHome(value) {
54
+ if (value === '~')
55
+ return os.homedir();
56
+ if (value.startsWith('~/'))
57
+ return path.join(os.homedir(), value.slice(2));
58
+ return value;
59
+ }
60
+ function isExplicitPath(value) {
61
+ return value.startsWith('/') || value.startsWith('./') || value.startsWith('../') || value.startsWith('~/');
62
+ }
63
+ function isDirectory(value) {
64
+ try {
65
+ return existsSync(value) && statSync(value).isDirectory();
66
+ }
67
+ catch {
68
+ return false;
69
+ }
70
+ }
71
+ function normalizeInput(input) {
72
+ const title = input.title?.trim() ?? '';
73
+ if (!title)
74
+ throw new Error('title is required');
75
+ const originalRepo = input.repo?.trim() ?? '';
76
+ if (!originalRepo)
77
+ throw new Error('repo is required');
78
+ const priority = input.priority ?? 0;
79
+ if (!Number.isFinite(priority) || !Number.isInteger(priority)) {
80
+ throw new TypeError('priority must be a finite integer');
81
+ }
82
+ const role = (input.role?.trim() || DEFAULT_ROLE);
83
+ if (!KNOWN_ROLES.includes(role)) {
84
+ throw new Error(`role must be one of: ${KNOWN_ROLES.join(', ')}`);
85
+ }
86
+ const expandedRepo = expandHome(originalRepo);
87
+ const existingDirectory = isDirectory(expandedRepo);
88
+ if (isExplicitPath(originalRepo) && !existingDirectory) {
89
+ throw new Error(`repo path must exist and be a directory: ${originalRepo}`);
90
+ }
91
+ const repoRef = existingDirectory ? path.resolve(expandedRepo) : originalRepo;
92
+ return {
93
+ title,
94
+ repoRef,
95
+ repoInfo: {
96
+ input: originalRepo,
97
+ ref: repoRef,
98
+ mode: existingDirectory ? 'path' : 'name',
99
+ },
100
+ description: input.description?.trim() ?? '',
101
+ scope: input.scope?.trim() ?? '',
102
+ priority,
103
+ role: role,
104
+ now: input.now ?? new Date(),
105
+ idSuffix: input.idSuffix ?? randomUUID().replaceAll('-', '').slice(0, 8),
106
+ };
107
+ }
108
+ function buildIds(input) {
109
+ const stamp = compactUtcStamp(input.now);
110
+ const slug = slugTitle(input.title);
111
+ const stem = `${stamp}_${slug}_${input.idSuffix}`;
112
+ return {
113
+ runId: `run_${stem}`,
114
+ taskId: `task_${stem}`,
115
+ stepId: `step_${stem}`,
116
+ eventId: `event_${stem}_created`,
117
+ status: 'ready',
118
+ };
119
+ }
120
+ export async function createRunWorkflow(dataAccess, input) {
121
+ const normalized = normalizeInput(input);
122
+ await dataAccess.assertReady();
123
+ const ids = buildIds(normalized);
124
+ const createdIds = {};
125
+ const nowIso = normalized.now.toISOString();
126
+ try {
127
+ await dataAccess.createRow('task_runs', ids.runId, {
128
+ id: ids.runId,
129
+ project_id: '',
130
+ title: normalized.title,
131
+ description: normalized.description,
132
+ status: 'ready',
133
+ repos: [normalized.repoRef],
134
+ scope: normalized.scope,
135
+ priority: normalized.priority,
136
+ created_by: 'cli',
137
+ created_at: nowIso,
138
+ updated_at: nowIso,
139
+ });
140
+ createdIds.runId = ids.runId;
141
+ await dataAccess.createRow('tasks', ids.taskId, {
142
+ id: ids.taskId,
143
+ run_id: ids.runId,
144
+ repo_ref: normalized.repoRef,
145
+ role_hint: normalized.role,
146
+ title: normalized.title,
147
+ status: 'ready',
148
+ depends_on: [],
149
+ scope: normalized.scope,
150
+ priority: normalized.priority,
151
+ created_at: nowIso,
152
+ updated_at: nowIso,
153
+ });
154
+ createdIds.taskId = ids.taskId;
155
+ await dataAccess.createRow('steps', ids.stepId, {
156
+ id: ids.stepId,
157
+ task_id: ids.taskId,
158
+ run_id: ids.runId,
159
+ role: normalized.role,
160
+ kind: 'plan_run',
161
+ status: 'ready',
162
+ input: {
163
+ title: normalized.title,
164
+ description: normalized.description,
165
+ scope: normalized.scope,
166
+ repo: normalized.repoInfo,
167
+ run_id: ids.runId,
168
+ task_id: ids.taskId,
169
+ },
170
+ output: null,
171
+ model_profile: 'standard',
172
+ run_after: '',
173
+ attempt_count: 0,
174
+ max_attempts: 3,
175
+ priority: normalized.priority,
176
+ lease_owner: '',
177
+ lease_expires_at: '',
178
+ dead_reason: '',
179
+ created_at: nowIso,
180
+ updated_at: nowIso,
181
+ });
182
+ createdIds.stepId = ids.stepId;
183
+ await dataAccess.createRow('events', ids.eventId, {
184
+ id: ids.eventId,
185
+ run_id: ids.runId,
186
+ task_id: ids.taskId,
187
+ step_id: ids.stepId,
188
+ type: 'run_created',
189
+ payload: {
190
+ source: 'revo run create',
191
+ title: normalized.title,
192
+ description: normalized.description,
193
+ scope: normalized.scope,
194
+ repo: normalized.repoInfo,
195
+ priority: normalized.priority,
196
+ ids: { run_id: ids.runId, task_id: ids.taskId, step_id: ids.stepId },
197
+ },
198
+ actor: 'cli',
199
+ created_at: nowIso,
200
+ });
201
+ createdIds.eventId = ids.eventId;
202
+ }
203
+ catch (error) {
204
+ throw new CreateRunWorkflowError('Failed to create run workflow rows', createdIds, error);
205
+ }
206
+ return ids;
207
+ }
208
+ //# sourceMappingURL=create-run.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create-run.js","sourceRoot":"","sources":["../../src/run/create-run.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ import { redactTokens } from '../runners/gh-identity.js';
2
+ import { recordTerminalRunStatus } from './terminal-run-status.js';
3
+ /** Cap the persisted reason so a giant stack/stderr dump can't bloat the event row. */
4
+ const REASON_MAX = 2_000;
5
+ export async function failRun(da, runId, reason, opts) {
6
+ // Reason is token-redacted before persistence — a gh/git error could echo a token, and events
7
+ // live in Revisium (where secrets must never land). Capped so a stack dump can't bloat the row.
8
+ const safeReason = redactTokens(reason).slice(0, REASON_MAX);
9
+ const result = await recordTerminalRunStatus(da, runId, {
10
+ status: 'failed',
11
+ eventType: 'run_failed',
12
+ actor: opts?.actor ?? 'pipeline',
13
+ payload: { source: opts?.source ?? 'workflow-failure', reason: safeReason },
14
+ now: opts?.now ?? new Date(),
15
+ });
16
+ if (!result)
17
+ return null;
18
+ return { runId, previousStatus: result.previousStatus, status: 'failed' };
19
+ }
20
+ //# sourceMappingURL=fail-run.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fail-run.js","sourceRoot":"","sources":["../../src/run/fail-run.ts"],"names":[],"mappings":"AAiBA,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AACzD,OAAO,EAAE,uBAAuB,EAAE,MAAM,0BAA0B,CAAC;AAQnE,uFAAuF;AACvF,MAAM,UAAU,GAAG,KAAK,CAAC;AAEzB,MAAM,CAAC,KAAK,UAAU,OAAO,CAC3B,EAA0B,EAC1B,KAAa,EACb,MAAc,EACd,IAAsD;IAEtD,8FAA8F;IAC9F,gGAAgG;IAChG,MAAM,UAAU,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC;IAE7D,MAAM,MAAM,GAAG,MAAM,uBAAuB,CAAC,EAAE,EAAE,KAAK,EAAE;QACtD,MAAM,EAAE,QAAQ;QAChB,SAAS,EAAE,YAAY;QACvB,KAAK,EAAE,IAAI,EAAE,KAAK,IAAI,UAAU;QAChC,OAAO,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,IAAI,kBAAkB,EAAE,MAAM,EAAE,UAAU,EAAE;QAC3E,GAAG,EAAE,IAAI,EAAE,GAAG,IAAI,IAAI,IAAI,EAAE;KAC7B,CAAC,CAAC;IACH,IAAI,CAAC,MAAM;QAAE,OAAO,IAAI,CAAC;IACzB,OAAO,EAAE,KAAK,EAAE,cAAc,EAAE,MAAM,CAAC,cAAc,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC;AAC5E,CAAC"}