@revisium/orchestrator 0.1.0 → 0.2.0-alpha.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.
- package/README.md +78 -0
- package/control-plane/bootstrap.config.json +43 -1
- package/control-plane/default-playbook/catalog/pipelines.json +941 -3
- package/control-plane/default-playbook/catalog/roles.json +54 -0
- package/dist/api/graphql-api/graphql-ws/pubsub.module.js +0 -1
- package/dist/api/graphql-api/graphql-ws/pubsub.module.js.map +1 -1
- package/dist/api/graphql-api/graphql-ws/run-progress-subscription-poller.service.js +0 -1
- package/dist/api/graphql-api/graphql-ws/run-progress-subscription-poller.service.js.map +1 -1
- package/dist/api/graphql-api/graphql-ws/subscription-bridge.service.js +0 -1
- package/dist/api/graphql-api/graphql-ws/subscription-bridge.service.js.map +1 -1
- package/dist/api/graphql-api/pr/model/pr-readiness.model.js +0 -4
- package/dist/api/graphql-api/pr/model/pr-readiness.model.js.map +1 -1
- package/dist/cli/commands/doctor-report.js +0 -18
- package/dist/cli/commands/doctor-report.js.map +1 -1
- package/dist/cli/commands/lifecycle.js +3 -71
- package/dist/cli/commands/lifecycle.js.map +1 -1
- package/dist/cli/commands/mcp.js +0 -14
- package/dist/cli/commands/mcp.js.map +1 -1
- package/dist/cli/commands/process-tree.js +4 -26
- package/dist/cli/commands/process-tree.js.map +1 -1
- package/dist/cli/commands/revisium-helpers.js +0 -6
- package/dist/cli/commands/revisium-helpers.js.map +1 -1
- package/dist/cli/commands/rogue-reaper.js +0 -34
- package/dist/cli/commands/rogue-reaper.js.map +1 -1
- package/dist/cli/index.js +0 -4
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/program.js +0 -5
- package/dist/cli/program.js.map +1 -1
- package/dist/config.js +0 -25
- package/dist/config.js.map +1 -1
- package/dist/control-plane/bootstrap.js +0 -28
- package/dist/control-plane/bootstrap.js.map +1 -1
- package/dist/control-plane/change-notifications.js +0 -1
- package/dist/control-plane/change-notifications.js.map +1 -1
- package/dist/control-plane/client-transport.js +0 -11
- package/dist/control-plane/client-transport.js.map +1 -1
- package/dist/control-plane/definitions.js +8 -17
- package/dist/control-plane/definitions.js.map +1 -1
- package/dist/control-plane/inbox.js +2 -120
- package/dist/control-plane/inbox.js.map +1 -1
- package/dist/control-plane/resolve-cwd.js +0 -61
- package/dist/control-plane/resolve-cwd.js.map +1 -1
- package/dist/control-plane/schema-migration.js +0 -9
- package/dist/control-plane/schema-migration.js.map +1 -1
- package/dist/control-plane/seed-default-playbook.js +5 -70
- package/dist/control-plane/seed-default-playbook.js.map +1 -1
- package/dist/control-plane/steps.js +0 -15
- package/dist/control-plane/steps.js.map +1 -1
- package/dist/e2e/kit/assertions.js +1 -1
- package/dist/e2e/kit/assertions.js.map +1 -1
- package/dist/engine/dbos.service.js +9 -179
- package/dist/engine/dbos.service.js.map +1 -1
- package/dist/engine/ensure-postgres.js +0 -48
- package/dist/engine/ensure-postgres.js.map +1 -1
- package/dist/host/daemon.js +2 -21
- package/dist/host/daemon.js.map +1 -1
- package/dist/host/dbos-identity.js +0 -31
- package/dist/host/dbos-identity.js.map +1 -1
- package/dist/host/ensure-host.js +1 -37
- package/dist/host/ensure-host.js.map +1 -1
- package/dist/host/ensure-revisium.js +1 -135
- package/dist/host/ensure-revisium.js.map +1 -1
- package/dist/host/host-runtime.js +0 -28
- package/dist/host/host-runtime.js.map +1 -1
- package/dist/host/host.lifecycle.js +0 -27
- package/dist/host/host.lifecycle.js.map +1 -1
- package/dist/host/queue-ownership.js +0 -42
- package/dist/host/queue-ownership.js.map +1 -1
- package/dist/host/queue-poller-census.js +1 -28
- package/dist/host/queue-poller-census.js.map +1 -1
- package/dist/http/graphql-host.module.js +0 -3
- package/dist/http/graphql-host.module.js.map +1 -1
- package/dist/mcp/mcp-capabilities.js +19 -14
- package/dist/mcp/mcp-capabilities.js.map +1 -1
- package/dist/mcp/mcp-facade.service.js +41 -23
- package/dist/mcp/mcp-facade.service.js.map +1 -1
- package/dist/mcp/mcp-http.service.js +0 -18
- package/dist/mcp/mcp-http.service.js.map +1 -1
- package/dist/mcp/mcp-tools.js +18 -40
- package/dist/mcp/mcp-tools.js.map +1 -1
- package/dist/observability/activity-signal.js +0 -4
- package/dist/observability/activity-signal.js.map +1 -1
- package/dist/observability/agent-activity-reporter.js +0 -4
- package/dist/observability/agent-activity-reporter.js.map +1 -1
- package/dist/pipeline/await-human.js +0 -40
- package/dist/pipeline/await-human.js.map +1 -1
- package/dist/pipeline/data-driven-task.workflow.js +106 -236
- package/dist/pipeline/data-driven-task.workflow.js.map +1 -1
- package/dist/pipeline/data-driven-template.js +0 -25
- package/dist/pipeline/data-driven-template.js.map +1 -1
- package/dist/pipeline/pipeline.module.js +0 -12
- package/dist/pipeline/pipeline.module.js.map +1 -1
- package/dist/pipeline/pipeline.service.js +10 -99
- package/dist/pipeline/pipeline.service.js.map +1 -1
- package/dist/pipeline-core/index.js +1 -13
- package/dist/pipeline-core/index.js.map +1 -1
- package/dist/pipeline-core/interpret.js +21 -94
- package/dist/pipeline-core/interpret.js.map +1 -1
- package/dist/pipeline-core/kit/assertions.js +0 -19
- package/dist/pipeline-core/kit/assertions.js.map +1 -1
- package/dist/pipeline-core/kit/builders.js +1 -21
- package/dist/pipeline-core/kit/builders.js.map +1 -1
- package/dist/pipeline-core/kit/drive.js +1 -31
- package/dist/pipeline-core/kit/drive.js.map +1 -1
- package/dist/pipeline-core/kit/fixtures.js +8 -82
- package/dist/pipeline-core/kit/fixtures.js.map +1 -1
- package/dist/pipeline-core/kit/index.js +0 -8
- package/dist/pipeline-core/kit/index.js.map +1 -1
- package/dist/pipeline-core/types.js +13 -52
- package/dist/pipeline-core/types.js.map +1 -1
- package/dist/pipeline-core/validate-capability.js +0 -3
- package/dist/pipeline-core/validate-capability.js.map +1 -1
- package/dist/pipeline-core/validate-conflicts.js +0 -9
- package/dist/pipeline-core/validate-conflicts.js.map +1 -1
- package/dist/pipeline-core/validate-dataflow.js +0 -17
- package/dist/pipeline-core/validate-dataflow.js.map +1 -1
- package/dist/pipeline-core/validate-diff.js +3 -36
- package/dist/pipeline-core/validate-diff.js.map +1 -1
- package/dist/pipeline-core/validate-edges.js +0 -6
- package/dist/pipeline-core/validate-edges.js.map +1 -1
- package/dist/pipeline-core/validate-graph.js +0 -11
- package/dist/pipeline-core/validate-graph.js.map +1 -1
- package/dist/pipeline-core/validate-loops.js +37 -44
- package/dist/pipeline-core/validate-loops.js.map +1 -1
- package/dist/pipeline-core/validate-parallel.js +9 -15
- package/dist/pipeline-core/validate-parallel.js.map +1 -1
- package/dist/pipeline-core/validate-sink.js +0 -7
- package/dist/pipeline-core/validate-sink.js.map +1 -1
- package/dist/pipeline-core/validate-topology.js +1 -20
- package/dist/pipeline-core/validate-topology.js.map +1 -1
- package/dist/pipeline-core/validate-verdict.js +52 -7
- package/dist/pipeline-core/validate-verdict.js.map +1 -1
- package/dist/pipeline-core/validate.js +5 -29
- package/dist/pipeline-core/validate.js.map +1 -1
- package/dist/playbook/catalog-loader.js +8 -3
- package/dist/playbook/catalog-loader.js.map +1 -1
- package/dist/playbook/import-mapper.js +1 -9
- package/dist/playbook/import-mapper.js.map +1 -1
- package/dist/poller/pr-readiness-core.js +0 -74
- package/dist/poller/pr-readiness-core.js.map +1 -1
- package/dist/revisium/inbox.service.js +0 -24
- package/dist/revisium/inbox.service.js.map +1 -1
- package/dist/revisium/playbooks.service.js +2 -4
- package/dist/revisium/playbooks.service.js.map +1 -1
- package/dist/revisium/revisium.module.js +0 -12
- package/dist/revisium/revisium.module.js.map +1 -1
- package/dist/revisium/roles.service.js +0 -6
- package/dist/revisium/roles.service.js.map +1 -1
- package/dist/revisium/run.service.js +1 -75
- package/dist/revisium/run.service.js.map +1 -1
- package/dist/revisium/tokens.js +0 -4
- package/dist/revisium/tokens.js.map +1 -1
- package/dist/run/append-event.js +0 -34
- package/dist/run/append-event.js.map +1 -1
- package/dist/run/block-run.js.map +1 -1
- package/dist/run/cancel-run.js +0 -33
- package/dist/run/cancel-run.js.map +1 -1
- package/dist/run/complete-run.js.map +1 -1
- package/dist/run/create-run.js +0 -7
- package/dist/run/create-run.js.map +1 -1
- package/dist/run/fail-run.js +0 -3
- package/dist/run/fail-run.js.map +1 -1
- package/dist/run/inspect-run.js +0 -26
- package/dist/run/inspect-run.js.map +1 -1
- package/dist/run/run-outputs.js +0 -19
- package/dist/run/run-outputs.js.map +1 -1
- package/dist/run/terminal-run-status.js +0 -12
- package/dist/run/terminal-run-status.js.map +1 -1
- package/dist/runners/claude-code.service.js +0 -11
- package/dist/runners/claude-code.service.js.map +1 -1
- package/dist/runners/codex.service.js +0 -9
- package/dist/runners/codex.service.js.map +1 -1
- package/dist/runners/gh-identity.js +0 -52
- package/dist/runners/gh-identity.js.map +1 -1
- package/dist/runners/integrator-branch-naming.js +3 -11
- package/dist/runners/integrator-branch-naming.js.map +1 -1
- package/dist/runners/integrator-git.js +0 -25
- package/dist/runners/integrator-git.js.map +1 -1
- package/dist/runners/integrator-remote.js +0 -2
- package/dist/runners/integrator-remote.js.map +1 -1
- package/dist/runners/integrator-types.js +0 -7
- package/dist/runners/integrator-types.js.map +1 -1
- package/dist/runners/integrator.js +3 -167
- package/dist/runners/integrator.js.map +1 -1
- package/dist/runners/runner.module.js +0 -6
- package/dist/runners/runner.module.js.map +1 -1
- package/dist/runners/tokens.js +0 -4
- package/dist/runners/tokens.js.map +1 -1
- package/dist/runners/worktree.service.js +1 -17
- package/dist/runners/worktree.service.js.map +1 -1
- package/dist/task-control-plane/run-watch.service.js +49 -173
- package/dist/task-control-plane/run-watch.service.js.map +1 -1
- package/dist/task-control-plane/task-control-plane-api.service.js +15 -17
- package/dist/task-control-plane/task-control-plane-api.service.js.map +1 -1
- package/dist/worker/build-context.js +0 -16
- package/dist/worker/build-context.js.map +1 -1
- package/dist/worker/claude-code-runner.js +9 -42
- package/dist/worker/claude-code-runner.js.map +1 -1
- package/dist/worker/codex-runner.js +88 -22
- package/dist/worker/codex-runner.js.map +1 -1
- package/dist/worker/git-worktree-manager.js +20 -67
- package/dist/worker/git-worktree-manager.js.map +1 -1
- package/dist/worker/process-executor.js +0 -12
- package/dist/worker/process-executor.js.map +1 -1
- package/dist/worker/result-envelope.js +33 -49
- package/dist/worker/result-envelope.js.map +1 -1
- package/dist/worker/runner-dispatch.js +0 -3
- package/dist/worker/runner-dispatch.js.map +1 -1
- package/dist/worker/runner.js.map +1 -1
- package/dist/worker/stub-runner.js +0 -7
- package/dist/worker/stub-runner.js.map +1 -1
- package/package.json +2 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"definitions.js","sourceRoot":"","sources":["../../src/control-plane/definitions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,EAAE,qBAAqB,EAA8B,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"definitions.js","sourceRoot":"","sources":["../../src/control-plane/definitions.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,36 +1,7 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* inbox.ts — PURE Revisium-table inbox verbs. NO DBOS imports anywhere in this file.
|
|
3
|
-
*
|
|
4
|
-
* Covers: pushInbox, listInbox, getInbox, resolveInbox.
|
|
5
|
-
*
|
|
6
|
-
* RESUMABILITY guarantee (G9): resolveInbox COMPLETES idempotently on every call.
|
|
7
|
-
* A crash between the inbox patch and the step patch is repaired by a retry — the
|
|
8
|
-
* retry re-reads the already-resolved inbox row, takes the stored answer (stored
|
|
9
|
-
* answer wins; first resolver is authoritative), and idempotently drives the step
|
|
10
|
-
* from awaiting_approval → ready. Calling resolveInbox twice converges to:
|
|
11
|
-
* inbox resolved + step unblocked exactly once.
|
|
12
|
-
*
|
|
13
|
-
* KNOWN LIMITATION (G5 residual): data-access.ts patchRow is a plain write — no
|
|
14
|
-
* CAS. Two truly-concurrent first-time resolvers can both pass the `pending` read
|
|
15
|
-
* before either writes, and both proceed (each re-flips the step — harmless
|
|
16
|
-
* idempotent duplicate writes, but no CAS prevents dual entry). In practice the
|
|
17
|
-
* inbox has a single human resolver, so this is acceptable for 0002. A full
|
|
18
|
-
* conditional pending→resolved transition is a data-access-seam enhancement
|
|
19
|
-
* (add CAS/conditional write to data-access.ts) and is out of scope for 0002.
|
|
20
|
-
* Do NOT "fix" this by adding DBOS or hand-rolling a lock.
|
|
21
|
-
*/
|
|
22
1
|
import { randomUUID } from 'node:crypto';
|
|
23
2
|
import { ControlPlaneError } from './errors.js';
|
|
24
|
-
import { compactStamp } from './steps.js';
|
|
25
|
-
// ─── secret redaction ────────────────────────────────────────
|
|
3
|
+
import { compactStamp } from './steps.js';
|
|
26
4
|
const SECRET_PATTERN = /(?:password|secret|token|key|credential|auth|api_key|apikey)/i;
|
|
27
|
-
/**
|
|
28
|
-
* Recursively strip obvious secret-shaped keys from a value before persisting.
|
|
29
|
-
* - Plain objects: redact matching keys at ANY depth, recurse into non-secret values.
|
|
30
|
-
* - Arrays: recurse into each element.
|
|
31
|
-
* - Primitives / null: return as-is.
|
|
32
|
-
* Full policy can firm up later; this covers the common cases.
|
|
33
|
-
*/
|
|
34
5
|
export function redactSecrets(value) {
|
|
35
6
|
if (value === null || typeof value !== 'object')
|
|
36
7
|
return value;
|
|
@@ -43,7 +14,6 @@ export function redactSecrets(value) {
|
|
|
43
14
|
}
|
|
44
15
|
return result;
|
|
45
16
|
}
|
|
46
|
-
// ─── row mapping ─────────────────────────────────────────────
|
|
47
17
|
function str(v) {
|
|
48
18
|
return typeof v === 'string' ? v : '';
|
|
49
19
|
}
|
|
@@ -65,47 +35,17 @@ function mapInboxRow(rowId, data) {
|
|
|
65
35
|
resolvedAt: str(data.resolved_at),
|
|
66
36
|
};
|
|
67
37
|
}
|
|
68
|
-
// ─── exported verbs ──────────────────────────────────────────
|
|
69
|
-
/**
|
|
70
|
-
* pushInbox — insert an inbox row; set the originating step to awaiting_approval
|
|
71
|
-
* (branch stops, siblings continue). Returns the inbox id.
|
|
72
|
-
*
|
|
73
|
-
* G10: seeds answer: null, resolved_by: '', resolved_at: '' so that the resolveInbox
|
|
74
|
-
* `replace` patches hit present paths (serializeData omits undefined fields, leaving
|
|
75
|
-
* absent paths that Revisium's patch handler rejects for `replace`).
|
|
76
|
-
*
|
|
77
|
-
* G1 (0004): accepts `opts.id` — when present, used VERBATIM (bypassing compactStamp+suffix).
|
|
78
|
-
* This is the fully-deterministic path used by gate pushes in the workflow body.
|
|
79
|
-
* Legacy callers pass no `id` → timestamp+suffix path is unchanged (backward-compatible).
|
|
80
|
-
*
|
|
81
|
-
* G1 idempotency: wraps createRow in a ROW_CONFLICT catch (mirrors append-event.ts:69-72).
|
|
82
|
-
* On a workflow-body replay the row already exists → swallows the conflict and returns the
|
|
83
|
-
* same id (no-op, no duplicate). Gate rows carry no stepId, so the step-park branch is moot
|
|
84
|
-
* on ROW_CONFLICT; we return before it.
|
|
85
|
-
*
|
|
86
|
-
* Redacts secrets in context before writing (contract line 163).
|
|
87
|
-
*/
|
|
88
38
|
export async function pushInbox(da, item, opts) {
|
|
89
39
|
await da.assertReady();
|
|
90
|
-
// CR-C (0004 CR): avoid computing non-deterministic values on the deterministic gate path.
|
|
91
|
-
// When opts.id is present, we do NOT call new Date() until we are inside the actual insert —
|
|
92
|
-
// at which point ROW_CONFLICT makes the row exactly-once (first write wins; any replayed
|
|
93
|
-
// new Date() is discarded by the conflict and never persisted). The timestamp is a real wall-
|
|
94
|
-
// clock value on the FIRST insert and is irrelevant on replay. Only the legacy path (no
|
|
95
|
-
// opts.id) needs now for the id itself, so it is computed first in that branch only.
|
|
96
40
|
let id;
|
|
97
41
|
let now;
|
|
98
42
|
if (opts?.id === undefined) {
|
|
99
|
-
// Legacy path: timestamp is part of the id — must be computed before createRow.
|
|
100
43
|
now = opts?.now ?? new Date();
|
|
101
44
|
const suffix = opts?.idSuffix ?? randomUUID().replaceAll('-', '').slice(0, 8);
|
|
102
45
|
id = `inbox_${compactStamp(now)}_${suffix}`;
|
|
103
46
|
}
|
|
104
47
|
else {
|
|
105
|
-
// Deterministic gate path: id is caller-supplied verbatim; timestamp is only needed
|
|
106
|
-
// for created_at in the insert — evaluated lazily inside the try block below.
|
|
107
48
|
id = opts.id;
|
|
108
|
-
// Use opts.now if provided (test-seeded), otherwise defer new Date() to the insert.
|
|
109
49
|
now = opts?.now ?? new Date();
|
|
110
50
|
}
|
|
111
51
|
const safeContext = redactSecrets(item.context);
|
|
@@ -121,33 +61,19 @@ export async function pushInbox(da, item, opts) {
|
|
|
121
61
|
context: safeContext,
|
|
122
62
|
options: item.options ?? [],
|
|
123
63
|
status: 'pending',
|
|
124
|
-
// G10 — seed every later-patched optional column as a present value (never undefined).
|
|
125
|
-
// serializeData (json-fields.ts:38) omits undefined fields; an absent path causes
|
|
126
|
-
// Revisium's patch handler to reject a replace → resolveInbox patches would fail.
|
|
127
|
-
// answer: null is serialized by json-fields as JSON null → 'null' string on the JSON field.
|
|
128
64
|
answer: null,
|
|
129
65
|
resolved_by: '',
|
|
130
66
|
resolved_at: '',
|
|
131
|
-
// On the opts.id (gate) path, created_at uses `now` computed above. On a workflow-body
|
|
132
|
-
// replay, ROW_CONFLICT fires BEFORE this value is persisted — so a different now per
|
|
133
|
-
// replay is harmless (it is discarded). The FIRST insert's timestamp is the real one.
|
|
134
67
|
created_at: now.toISOString(),
|
|
135
68
|
});
|
|
136
69
|
}
|
|
137
70
|
catch (e) {
|
|
138
|
-
// Idempotent on workflow-body replay (mirror append-event.ts:69-72). Same row already exists → no-op.
|
|
139
71
|
if (e instanceof ControlPlaneError && e.code === 'ROW_CONFLICT')
|
|
140
72
|
return id;
|
|
141
73
|
throw e;
|
|
142
74
|
}
|
|
143
|
-
// No `steps` row is parked: the data-driven engine carries no inbox stepId (await-human sets ''),
|
|
144
|
-
// so the legacy step-park is dead (audit §3.1). The DBOS workflow is parked by `DBOS.recv`, not a step row.
|
|
145
75
|
return id;
|
|
146
76
|
}
|
|
147
|
-
/**
|
|
148
|
-
* listInbox — read the inbox table, optionally filtered.
|
|
149
|
-
* Draft read; consumers never see Revisium types (returns InboxItem[]).
|
|
150
|
-
*/
|
|
151
77
|
export async function listInbox(da, filter) {
|
|
152
78
|
await da.assertReady();
|
|
153
79
|
const rows = await da.listRows('inbox', { first: filter?.limit ?? 500 });
|
|
@@ -158,11 +84,6 @@ export async function listInbox(da, filter) {
|
|
|
158
84
|
items = items.filter((i) => i.runId === filter.runId);
|
|
159
85
|
return items;
|
|
160
86
|
}
|
|
161
|
-
/**
|
|
162
|
-
* getInbox — read a single inbox row.
|
|
163
|
-
* G12: intentionally returns InboxItem | null (maps da.getRow's null-on-missing path),
|
|
164
|
-
* superseding repo-layer-contract.md:172's non-null signature. Null is the safer shape.
|
|
165
|
-
*/
|
|
166
87
|
export async function getInbox(da, id) {
|
|
167
88
|
await da.assertReady();
|
|
168
89
|
const row = await da.getRow('inbox', id);
|
|
@@ -170,66 +91,27 @@ export async function getInbox(da, id) {
|
|
|
170
91
|
return null;
|
|
171
92
|
return mapInboxRow(row.rowId, row.data);
|
|
172
93
|
}
|
|
173
|
-
/**
|
|
174
|
-
* resolveInbox — pure status flip + step unblock. NO DBOS signal (that is 0004).
|
|
175
|
-
*
|
|
176
|
-
* G2 (0004): now returns the STORED decision `{ status, answer }` so the caller (CLI gate path)
|
|
177
|
-
* can signal WHAT IS RECORDED, never the raw flag passed to this call.
|
|
178
|
-
* - `status` is the row's status BEFORE this call: 'pending' ⇒ just resolved; 'resolved' ⇒ already was.
|
|
179
|
-
* - `answer` is the EFFECTIVE stored answer (first-resolver wins; retry returns stored, not its arg).
|
|
180
|
-
*
|
|
181
|
-
* Existing 0002 callers (non-gate resolve, run cancel CLI) ignore the return — backward-compatible.
|
|
182
|
-
*
|
|
183
|
-
* RESUMABLE + idempotent (G9): COMPLETES on every call.
|
|
184
|
-
* - If inbox is pending: patch to resolved, then unblock the step.
|
|
185
|
-
* - If inbox is already resolved (retry / double-resolve): skip the inbox re-patch
|
|
186
|
-
* (stored answer wins), but STILL drive the step unblock from the stored answer.
|
|
187
|
-
* - This means a crash between the inbox patch and the step patch is repaired by a
|
|
188
|
-
* retry — the parked step is NEVER left stuck.
|
|
189
|
-
*
|
|
190
|
-
* CURRENT-STATE-SAFE (G5):
|
|
191
|
-
* - pending → resolved only (else VALIDATION_FAILURE).
|
|
192
|
-
* - Resurrection guard: if the step is no longer awaiting_approval (cancelled /
|
|
193
|
-
* re-driven / gone), console.warn and skip the step flip without throwing.
|
|
194
|
-
* - Deterministic continuation: step_cont_${itemId} so a re-run collides on the
|
|
195
|
-
* same id rather than creating a duplicate.
|
|
196
|
-
*
|
|
197
|
-
* KNOWN LIMITATION: no CAS (see module doc-comment above).
|
|
198
|
-
*/
|
|
199
94
|
export async function resolveInbox(da, itemId, answer, resolvedBy, opts) {
|
|
200
95
|
await da.assertReady();
|
|
201
|
-
// (1) READ. getRow returns null for a missing inbox row.
|
|
202
96
|
const inbox = await da.getRow('inbox', itemId);
|
|
203
97
|
if (!inbox) {
|
|
204
98
|
throw new ControlPlaneError('ROW_NOT_FOUND', `inbox item not found: ${itemId}`);
|
|
205
99
|
}
|
|
206
|
-
// (2) STATE GUARD. Only pending or resolved are valid states to act on.
|
|
207
100
|
const status = inbox.data.status;
|
|
208
101
|
if (status !== 'pending' && status !== 'resolved') {
|
|
209
102
|
throw new ControlPlaneError('VALIDATION_FAILURE', `inbox ${itemId} cannot be resolved from status '${String(status)}'`);
|
|
210
103
|
}
|
|
211
104
|
const now = opts?.now ?? new Date();
|
|
212
|
-
// (3) IDEMPOTENT INBOX WRITE.
|
|
213
|
-
// pending → patch to resolved carrying answer / resolved_by / resolved_at.
|
|
214
|
-
// resolved → SKIP the re-patch. The stored answer wins (first resolver is authoritative).
|
|
215
105
|
if (status === 'pending') {
|
|
216
106
|
await da.patchRow('inbox', itemId, [
|
|
217
|
-
{ op: 'replace', path: 'status', value: 'resolved' },
|
|
107
|
+
{ op: 'replace', path: 'status', value: 'resolved' },
|
|
218
108
|
{ op: 'replace', path: 'answer', value: answer },
|
|
219
109
|
{ op: 'replace', path: 'resolved_by', value: resolvedBy },
|
|
220
110
|
{ op: 'replace', path: 'resolved_at', value: now.toISOString() },
|
|
221
111
|
]);
|
|
222
112
|
}
|
|
223
|
-
// C2 (0004 review): the effective answer is ALWAYS the STORED (persisted) value — re-read
|
|
224
|
-
// from the row. On the already-resolved path the pre-read row carries the stored answer.
|
|
225
|
-
// On the first-resolve path, re-read after patching so we return what is durably recorded
|
|
226
|
-
// (guards against JSON-field round-trip canonicalization differences and concurrent resolvers).
|
|
227
|
-
// Both paths converge to: signal what is recorded, never the raw caller argument.
|
|
228
113
|
const resolvedInbox = status === 'pending' ? await da.getRow('inbox', itemId) : inbox;
|
|
229
114
|
const effectiveAnswer = resolvedInbox?.data.answer ?? answer;
|
|
230
|
-
// (4) The inbox flip is the WHOLE resolve. The data-driven engine carries no inbox stepId, so there
|
|
231
|
-
// is no originating `steps` row to unblock — the parked DBOS workflow resumes via `DBOS.send` on the
|
|
232
|
-
// signalled topic (the legacy step-unblock was retired — audit §3.1).
|
|
233
115
|
return { status, answer: effectiveAnswer };
|
|
234
116
|
}
|
|
235
117
|
//# sourceMappingURL=inbox.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"inbox.js","sourceRoot":"","sources":["../../src/control-plane/inbox.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"inbox.js","sourceRoot":"","sources":["../../src/control-plane/inbox.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,20 +1,6 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* resolve-cwd.ts — shared B1 contract for resolving the working directory from a repo_ref.
|
|
3
|
-
*
|
|
4
|
-
* B1 CONTRACT — the resolved working directory MUST be an existing directory. We accept:
|
|
5
|
-
* • '' or '.' → base (the workspace cwd)
|
|
6
|
-
* • an ABSOLUTE existing dir → that dir (the external target repo — the MVP case)
|
|
7
|
-
* • a relative path under base → resolve(base, ref), if it stays under base AND exists
|
|
8
|
-
* We REJECT (throw a lesson-bearing error):
|
|
9
|
-
* • a non-existent path → never launch claude in a directory that isn't there
|
|
10
|
-
* • a path that is not a dir → never launch claude against a file
|
|
11
|
-
* • a relative '../…' escape → traversal guard (only relative refs are guarded; an ABSOLUTE
|
|
12
|
-
* ref is taken as the literal target repo, existence-checked).
|
|
13
|
-
*/
|
|
14
1
|
import { resolve, isAbsolute, relative, sep, join } from 'node:path';
|
|
15
2
|
import { existsSync, lstatSync, realpathSync, statSync } from 'node:fs';
|
|
16
3
|
import { toStr } from './steps.js';
|
|
17
|
-
/** Resolve a repo_ref string to an absolute, existing directory path. */
|
|
18
4
|
export async function resolveRepoCwdFromRef(repoRef, base) {
|
|
19
5
|
if (repoRef === '' || repoRef === '.')
|
|
20
6
|
return base;
|
|
@@ -27,10 +13,6 @@ export async function resolveRepoCwdFromRef(repoRef, base) {
|
|
|
27
13
|
throw new Error(`resolveCwd: repo path ${JSON.stringify(resolved)} does not exist or is not a directory ` +
|
|
28
14
|
`— refusing to launch claude`);
|
|
29
15
|
}
|
|
30
|
-
// Symlink escape guard: canonicalize via realpathSync and re-check containment.
|
|
31
|
-
// This prevents a symlink inside the allowed base from pointing outside it.
|
|
32
|
-
// Only applied when the ref is relative (absolute refs designate an external target repo
|
|
33
|
-
// and are accepted as-is — their real path IS the intended target).
|
|
34
16
|
if (!isAbsolute(repoRef)) {
|
|
35
17
|
let realTarget;
|
|
36
18
|
let realBase;
|
|
@@ -39,7 +21,6 @@ export async function resolveRepoCwdFromRef(repoRef, base) {
|
|
|
39
21
|
realBase = realpathSync(base);
|
|
40
22
|
}
|
|
41
23
|
catch {
|
|
42
|
-
// realpathSync throws on non-existent paths — treat as non-existent (same as above check).
|
|
43
24
|
throw new Error(`resolveCwd: repo path ${JSON.stringify(resolved)} does not exist or is not a directory ` +
|
|
44
25
|
`— refusing to launch claude`);
|
|
45
26
|
}
|
|
@@ -58,15 +39,6 @@ async function readRepoRef(da, taskId) {
|
|
|
58
39
|
}
|
|
59
40
|
return toStr(task.data.repo_ref);
|
|
60
41
|
}
|
|
61
|
-
// ─── Per-run worktree isolation (plan 0017) ────────────────────────────────────
|
|
62
|
-
/**
|
|
63
|
-
* Deterministic per-run worktree path: `<dataDir>/worktrees/<runId>`. COMPUTED, never stored —
|
|
64
|
-
* preserving invariant #1 (no durable state in local files; the durable artifact is the pushed
|
|
65
|
-
* branch + DBOS progress, the worktree is execution scratch). Sited under the data dir, NOT inside
|
|
66
|
-
* the target repo, so a live worktree never pollutes the target's own `git status`.
|
|
67
|
-
*/
|
|
68
|
-
/** Guard a value used as a single filesystem path segment — refuse separators / traversal so a
|
|
69
|
-
* malformed runId can never make a worktree path escape `<dataDir>/worktrees/` (release rm's it). */
|
|
70
42
|
function assertPathSegment(value, label) {
|
|
71
43
|
if (value === '' || value === '.' || value === '..' || value.includes('/') || value.includes('\\') || value.includes('..') || value.includes('\0')) {
|
|
72
44
|
throw new Error(`${label} ${JSON.stringify(value)} must be a single safe path segment`);
|
|
@@ -76,22 +48,10 @@ export function worktreePathFor(dataDir, runId) {
|
|
|
76
48
|
assertPathSegment(runId, 'runId');
|
|
77
49
|
return join(dataDir, 'worktrees', runId);
|
|
78
50
|
}
|
|
79
|
-
/**
|
|
80
|
-
* Live-run worktree marker: `<dataDir>/worktrees/<runId>.live`. Its presence means "this run is live
|
|
81
|
-
* and MUST resolve to its worktree". It lets the run resolver FAIL LOUD when a live run's worktree is
|
|
82
|
-
* missing/lost instead of silently falling back to the shared base checkout (which would re-introduce
|
|
83
|
-
* the exact cross-run corruption worktree isolation exists to prevent). Written at create, removed at
|
|
84
|
-
* release.
|
|
85
|
-
*/
|
|
86
51
|
export function worktreeMarkerFor(dataDir, runId) {
|
|
87
52
|
assertPathSegment(runId, 'runId');
|
|
88
53
|
return join(dataDir, 'worktrees', `${runId}.live`);
|
|
89
54
|
}
|
|
90
|
-
/**
|
|
91
|
-
* A path is a usable LINKED git worktree iff it is a directory carrying a `.git` POINTER FILE (a linked
|
|
92
|
-
* worktree's `.git` is a file `gitdir: …`, never a directory). Requiring a file rejects a normal clone's
|
|
93
|
-
* `.git` directory and stale/corrupt paths, so a live run never silently runs effects in an invalid tree.
|
|
94
|
-
*/
|
|
95
55
|
export function isWorktreeDir(path) {
|
|
96
56
|
try {
|
|
97
57
|
return statSync(path).isDirectory() && lstatSync(join(path, '.git')).isFile();
|
|
@@ -100,12 +60,6 @@ export function isWorktreeDir(path) {
|
|
|
100
60
|
return false;
|
|
101
61
|
}
|
|
102
62
|
}
|
|
103
|
-
/**
|
|
104
|
-
* RUN-level resolver (plan 0017) — the cwd for every repo-touching LIVE effect (developer/rework steps
|
|
105
|
-
* + the integrator). Prefers the run's isolated worktree; FAILS LOUD for a live run whose worktree is
|
|
106
|
-
* missing (marker present, worktree gone); falls back to the shared base checkout ONLY for non-live
|
|
107
|
-
* runs (script/stub do no real git, so no worktree/marker is ever created for them).
|
|
108
|
-
*/
|
|
109
63
|
export async function resolveRunCwd(da, dataDir, runId, taskId, base = process.cwd()) {
|
|
110
64
|
const wt = worktreePathFor(dataDir, runId);
|
|
111
65
|
if (isWorktreeDir(wt))
|
|
@@ -116,27 +70,12 @@ export async function resolveRunCwd(da, dataDir, runId, taskId, base = process.c
|
|
|
116
70
|
}
|
|
117
71
|
return resolveRepoCwdFromRef(await readRepoRef(da, taskId), base);
|
|
118
72
|
}
|
|
119
|
-
/**
|
|
120
|
-
* STEP-level resolver (M3, plan 0017) — shape expected by the claude runner: (step) => Promise<string>.
|
|
121
|
-
* Now WORKTREE-AWARE: resolves to the run's isolated worktree (keyed by step.runId) for live runs,
|
|
122
|
-
* else the shared base checkout. Reads tasks.repo_ref via the data-access layer for the fallback.
|
|
123
|
-
*/
|
|
124
73
|
export function makeResolveCwd(da, dataDir, base = process.cwd()) {
|
|
125
74
|
return (step) => resolveRunCwd(da, dataDir, step.runId, step.taskId, base);
|
|
126
75
|
}
|
|
127
|
-
/**
|
|
128
|
-
* RUN-level resolver shape for the integrator: (runId, taskId) => Promise<string>. Same contract as
|
|
129
|
-
* the step resolver but keyed explicitly by runId (concurrent runs share a taskId, so the integrator
|
|
130
|
-
* MUST resolve by runId or two runs collide on one tree).
|
|
131
|
-
*/
|
|
132
76
|
export function makeResolveRunCwd(da, dataDir, base = process.cwd()) {
|
|
133
77
|
return (runId, taskId) => resolveRunCwd(da, dataDir, runId, taskId, base);
|
|
134
78
|
}
|
|
135
|
-
/**
|
|
136
|
-
* TASK-level resolver (M3) — the BASE checkout, keyed by taskId: (taskId: string) => Promise<string>.
|
|
137
|
-
* Used by the LIVE PREFLIGHT, which must run against the user's base checkout BEFORE the worktree is
|
|
138
|
-
* created (its fetch + clean/freshness checks protect the base repo). NOT worktree-aware by design.
|
|
139
|
-
*/
|
|
140
79
|
export function makeResolveTaskCwd(da, base = process.cwd()) {
|
|
141
80
|
return async (taskId) => resolveRepoCwdFromRef(await readRepoRef(da, taskId), base);
|
|
142
81
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resolve-cwd.js","sourceRoot":"","sources":["../../src/control-plane/resolve-cwd.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"resolve-cwd.js","sourceRoot":"","sources":["../../src/control-plane/resolve-cwd.ts"],"names":[],"mappings":"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"}
|
|
@@ -46,11 +46,6 @@ function loadBootstrapTables(configPath) {
|
|
|
46
46
|
return [{ id: item.id, schema: item.schema }];
|
|
47
47
|
});
|
|
48
48
|
}
|
|
49
|
-
/**
|
|
50
|
-
* Apply the bootstrap.config.json table schemas additively onto a caller-provided DRAFT scope:
|
|
51
|
-
* create missing tables, patch additive drift on existing ones. Does NOT commit — the caller owns the
|
|
52
|
-
* scope and commits the whole bootstrap once (one `client.revision('draft')` → tables + rows → commit).
|
|
53
|
-
*/
|
|
54
49
|
export async function applyAdditiveSchemaMigration(draft, configPath) {
|
|
55
50
|
const tables = loadBootstrapTables(configPath);
|
|
56
51
|
const updatedTables = [];
|
|
@@ -61,10 +56,6 @@ export async function applyAdditiveSchemaMigration(draft, configPath) {
|
|
|
61
56
|
currentSchema = await draft.getTableSchema(table.id);
|
|
62
57
|
}
|
|
63
58
|
catch {
|
|
64
|
-
// Table absent on an upgraded control-plane (e.g. `run_outputs`, added in 0016). The previous
|
|
65
|
-
// code only PATCHED existing tables, so a brand-new table would never land on an already-
|
|
66
|
-
// bootstrapped control-plane. Create it from the bootstrap schema (fresh bootstrap already
|
|
67
|
-
// creates every config table; this covers the upgrade path).
|
|
68
59
|
await draft.createTable(table.id, table.schema);
|
|
69
60
|
updatedTables.push(table.id);
|
|
70
61
|
patchCount += 1;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schema-migration.js","sourceRoot":"","sources":["../../src/control-plane/schema-migration.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"schema-migration.js","sourceRoot":"","sources":["../../src/control-plane/schema-migration.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,16 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* seed-default-playbook.ts — install the BUILT-IN DEFAULT playbook during `revo bootstrap` (slice 5,
|
|
3
|
-
* plan 0015).
|
|
4
|
-
*
|
|
5
|
-
* The default is DATA, not engine code: a committed playbook source under
|
|
6
|
-
* `control-plane/default-playbook/` (manifest + roles/pipelines catalogs carrying data-driven
|
|
7
|
-
* `template_json`). `revo bootstrap` seeds the control-plane SCHEMA (bootstrap.config.json), then this
|
|
8
|
-
* installs the default playbook so a FRESH control-plane has a working `feature-development` +
|
|
9
|
-
* `local-change` pipeline out-of-the-box — without depending on the external agent-playbook repo.
|
|
10
|
-
*
|
|
11
|
-
* Idempotent: skips when the default playbook is already installed (so re-running bootstrap is a
|
|
12
|
-
* no-op), and tolerates a benign concurrent/duplicate commit ("revision is not a draft").
|
|
13
|
-
*/
|
|
14
1
|
import { join } from 'node:path';
|
|
15
2
|
import { existsSync } from 'node:fs';
|
|
16
3
|
import { repoRoot } from '../config.js';
|
|
@@ -20,19 +7,8 @@ import { readPlaybookManifest } from '../playbook/manifest.js';
|
|
|
20
7
|
import { loadPlaybookCatalogs } from '../playbook/catalog-loader.js';
|
|
21
8
|
import { mapPlaybookRows } from '../playbook/import-mapper.js';
|
|
22
9
|
import { createVersionedMeaningAccess } from './versioned-meaning.js';
|
|
23
|
-
/** Installed row id of the built-in default playbook (distinct from the e2e fixture playbook). */
|
|
24
10
|
export const DEFAULT_PLAYBOOK_ID = 'revisium-default';
|
|
25
|
-
/**
|
|
26
|
-
* Source directory of the committed default playbook. Packaged at the repo/package root (see the
|
|
27
|
-
* package `files` allowlist) so the SHIPPED `revo bootstrap` (running from dist/) resolves it.
|
|
28
|
-
*/
|
|
29
11
|
export const DEFAULT_PLAYBOOK_SOURCE = join(repoRoot, 'control-plane', 'default-playbook');
|
|
30
|
-
/**
|
|
31
|
-
* Compare two `x.y.z` semver strings numerically: returns >0 when `a` is newer, <0 when older, 0 when
|
|
32
|
-
* equal. Missing/non-numeric components read as 0 (so `0.1` == `0.1.0`). We hand-roll this rather than
|
|
33
|
-
* pull in a `semver` dependency: the default playbook only ever carries simple dotted release versions,
|
|
34
|
-
* and an unparsable component degrades to "older" via the missing-version path in the caller.
|
|
35
|
-
*/
|
|
36
12
|
function compareSemver(a, b) {
|
|
37
13
|
const parse = (v) => v.split('.').map((part) => Number.parseInt(part, 10) || 0);
|
|
38
14
|
const left = parse(a);
|
|
@@ -45,55 +21,27 @@ function compareSemver(a, b) {
|
|
|
45
21
|
}
|
|
46
22
|
return 0;
|
|
47
23
|
}
|
|
48
|
-
/**
|
|
49
|
-
* True for a benign "already committed / nothing to do" race during a concurrent bootstrap. Matched
|
|
50
|
-
* narrowly against the explicit duplicate-commit signals (Revisium draft commit + control-plane
|
|
51
|
-
* ROW_CONFLICT) — a generic `already` substring would misclassify unrelated installer failures as a
|
|
52
|
-
* race and silently swallow them.
|
|
53
|
-
*/
|
|
54
24
|
function isBenignInstallRace(err) {
|
|
55
25
|
const message = err instanceof Error ? err.message : String(err);
|
|
56
26
|
return /revision is not a draft|nothing to commit|ROW_CONFLICT/i.test(message);
|
|
57
27
|
}
|
|
58
|
-
|
|
59
|
-
* Recompute the content fingerprint for the bundled default playbook at `source`. Exported so tests
|
|
60
|
-
* can compute the expected hash without a live daemon and pin the "identical content → skip" case.
|
|
61
|
-
* Uses the exact same path as the installer (mapPlaybookRows with nameOverride) so the two hashes
|
|
62
|
-
* are always in sync.
|
|
63
|
-
*/
|
|
64
|
-
export function bundledCatalogHash(source) {
|
|
28
|
+
export function playbookCatalogHash(source, nameOverride = DEFAULT_PLAYBOOK_ID) {
|
|
65
29
|
const resolved = resolvePlaybookSource(source);
|
|
66
30
|
const manifest = readPlaybookManifest(resolved.root);
|
|
67
31
|
const catalogs = loadPlaybookCatalogs(resolved.root, manifest);
|
|
68
|
-
return mapPlaybookRows({ root: resolved.root, source: resolved, manifest, catalogs, nameOverride
|
|
32
|
+
return mapPlaybookRows({ root: resolved.root, source: resolved, manifest, catalogs, nameOverride }).catalogHash;
|
|
33
|
+
}
|
|
34
|
+
export function bundledCatalogHash(source) {
|
|
35
|
+
return playbookCatalogHash(source, DEFAULT_PLAYBOOK_ID);
|
|
69
36
|
}
|
|
70
|
-
/**
|
|
71
|
-
* Install the built-in default playbook if it is not already present, OR re-install (overwrite) it
|
|
72
|
-
* when the bundled content has changed. Returns a status discriminant so the caller can log
|
|
73
|
-
* appropriately; never throws on a benign duplicate-install race.
|
|
74
|
-
*
|
|
75
|
-
* Decision priority (B1 content-hash re-seed):
|
|
76
|
-
* 1. catalogHash present on installed row → compare to bundledCatalogHash(source):
|
|
77
|
-
* - match → skip (content unchanged, any version).
|
|
78
|
-
* - differ → re-seed (the installer upserts by row id).
|
|
79
|
-
* 2. no catalogHash (legacy row predating B1) → fall back to version compare:
|
|
80
|
-
* - bundle NEWER → re-seed.
|
|
81
|
-
* - equal/older → skip (never downgrade).
|
|
82
|
-
* - no version → treat as "0.0.0" → re-seed once so the one-time upgrade lands.
|
|
83
|
-
* `install()` is the same upsert+commit path used for a fresh install, so re-seed is idempotent.
|
|
84
|
-
*/
|
|
85
37
|
export async function seedDefaultPlaybook(installer, source = DEFAULT_PLAYBOOK_SOURCE, log = () => { }) {
|
|
86
38
|
if (!existsSync(source)) {
|
|
87
39
|
throw new Error(`default playbook source not found: ${source}`);
|
|
88
40
|
}
|
|
89
|
-
// `listPlaybooks` is the accurate presence signal: bootstrap seeds role/profile rows but NOT a
|
|
90
|
-
// playbook record, so this is empty until the default playbook is installed.
|
|
91
41
|
const installed = await installer.listPlaybooks();
|
|
92
42
|
const existing = installed.find((p) => p.id === DEFAULT_PLAYBOOK_ID);
|
|
93
43
|
if (existing) {
|
|
94
44
|
if (existing.catalogHash) {
|
|
95
|
-
// Content-hash path (B1): detects any change — catalog records, pipelines, or prompt bodies —
|
|
96
|
-
// without requiring a manual version bump.
|
|
97
45
|
const currentHash = bundledCatalogHash(source);
|
|
98
46
|
if (currentHash === existing.catalogHash) {
|
|
99
47
|
log(`Default playbook ${DEFAULT_PLAYBOOK_ID} content unchanged (hash match) — skipping seed.`);
|
|
@@ -102,8 +50,6 @@ export async function seedDefaultPlaybook(installer, source = DEFAULT_PLAYBOOK_S
|
|
|
102
50
|
log(`Default playbook ${DEFAULT_PLAYBOOK_ID} content changed (hash mismatch) — re-seeding.`);
|
|
103
51
|
}
|
|
104
52
|
else {
|
|
105
|
-
// Legacy fallback: row predates the B1 content-hash signal; compare by version so pre-B1
|
|
106
|
-
// installs still get re-seeded when the bundle version advances.
|
|
107
53
|
const bundledVersion = resolvePlaybookSource(source).version;
|
|
108
54
|
const installedVersion = existing.version ?? '';
|
|
109
55
|
const comparison = compareSemver(bundledVersion, installedVersion || '0.0.0');
|
|
@@ -126,23 +72,12 @@ export async function seedDefaultPlaybook(installer, source = DEFAULT_PLAYBOOK_S
|
|
|
126
72
|
throw err;
|
|
127
73
|
}
|
|
128
74
|
}
|
|
129
|
-
/**
|
|
130
|
-
* Default-daemon installer adapter used by `revo bootstrap`: a minimal {@link DefaultPlaybookInstaller}
|
|
131
|
-
* backed by the live draft scope (the same versioned-meaning access the `revo playbook install` CLI
|
|
132
|
-
* uses). Reads the installed playbooks list from HEAD via the provided reader.
|
|
133
|
-
*/
|
|
134
75
|
export function createDaemonInstaller(listPlaybooks) {
|
|
135
76
|
return {
|
|
136
77
|
listPlaybooks,
|
|
137
78
|
install: (options) => new PlaybookInstaller({ access: createVersionedMeaningAccess({}) }).install(options),
|
|
138
79
|
};
|
|
139
80
|
}
|
|
140
|
-
/**
|
|
141
|
-
* Run {@link seedDefaultPlaybook} as a BEST-EFFORT step: report the outcome but never throw. The
|
|
142
|
-
* schema is the critical bootstrap artifact; a playbook-seed failure must not fail stack bring-up
|
|
143
|
-
* (it is logged so the operator can re-run the install). `runSeed`/`log` are injected so the logging
|
|
144
|
-
* policy is unit-testable without a live daemon.
|
|
145
|
-
*/
|
|
146
81
|
export async function seedDefaultPlaybookBestEffort(runSeed, log = (message) => console.error(message)) {
|
|
147
82
|
try {
|
|
148
83
|
const outcome = await runSeed();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"seed-default-playbook.js","sourceRoot":"","sources":["../../src/control-plane/seed-default-playbook.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"seed-default-playbook.js","sourceRoot":"","sources":["../../src/control-plane/seed-default-playbook.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,14 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Step types + deterministic id / format helpers for the control plane.
|
|
3
|
-
*
|
|
4
|
-
* NOTE: the legacy step-lifecycle verbs (`claimNextStep`/`startAttempt`/`writeResult`/`failStep`/
|
|
5
|
-
* `recoverInFlight`/`createSteps`) were the pre-pivot dumb-loop step queue. They are superseded by the
|
|
6
|
-
* DBOS-driven data-driven engine and were removed (audit §2.1). What remains here is the `Step` shape the
|
|
7
|
-
* runner machinery still consumes (synthesized in-memory by the engine — `RunService.loadPipelineContext` —
|
|
8
|
-
* not read from a `steps` row) plus a few pure id / format helpers reused across the run / inbox / pipeline
|
|
9
|
-
* layers.
|
|
10
|
-
*/
|
|
11
|
-
// ─── id / format helpers ─────────────────────────────────────
|
|
12
1
|
export function compactStamp(date) {
|
|
13
2
|
const pad = (v, l = 2) => String(v).padStart(l, '0');
|
|
14
3
|
return [
|
|
@@ -23,10 +12,6 @@ export function compactStamp(date) {
|
|
|
23
12
|
'Z',
|
|
24
13
|
].join('');
|
|
25
14
|
}
|
|
26
|
-
// Non-cryptographic FNV-1a 64-bit hash → 16 hex chars. Used to derive DETERMINISTIC, BOUNDED row ids
|
|
27
|
-
// (same input → same id, so a crash-retry is idempotent) that fit Revisium's 64-char rowId limit:
|
|
28
|
-
// `inbox_`/`event_`/`cost_`/`attempt_`/`out_`/`step_` + 16 hex stays well under the cap. Not crypto, so
|
|
29
|
-
// it does not trip the weak-hash security hotspot.
|
|
30
15
|
export function fnv1a64Hex(input) {
|
|
31
16
|
let hash = 0xcbf29ce484222325n;
|
|
32
17
|
const prime = 0x100000001b3n;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"steps.js","sourceRoot":"","sources":["../../src/control-plane/steps.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"steps.js","sourceRoot":"","sources":["../../src/control-plane/steps.ts"],"names":[],"mappings":"AAmDA,MAAM,UAAU,YAAY,CAAC,IAAU;IACrC,MAAM,GAAG,GAAG,CAAC,CAAS,EAAE,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IAC7D,OAAO;QACL,IAAI,CAAC,cAAc,EAAE;QACrB,GAAG,CAAC,IAAI,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC;QAC3B,GAAG,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC;QACtB,GAAG;QACH,GAAG,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;QACvB,GAAG,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC;QACzB,GAAG,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC;QACzB,GAAG,CAAC,IAAI,CAAC,kBAAkB,EAAE,EAAE,CAAC,CAAC;QACjC,GAAG;KACJ,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;AACb,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,KAAa;IACtC,IAAI,IAAI,GAAG,mBAAmB,CAAC;IAC/B,MAAM,KAAK,GAAG,cAAc,CAAC;IAC7B,MAAM,IAAI,GAAG,mBAAmB,CAAC;IACjC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACtC,IAAI,IAAI,MAAM,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;QAC1C,IAAI,GAAG,CAAC,IAAI,GAAG,KAAK,CAAC,GAAG,IAAI,CAAC;IAC/B,CAAC;IACD,OAAO,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC;AAC7C,CAAC;AAED,MAAM,UAAU,KAAK,CAAC,CAAU;IAC9B,IAAI,OAAO,CAAC,KAAK,QAAQ;QAAE,OAAO,CAAC,CAAC;IACpC,IAAI,OAAO,CAAC,KAAK,QAAQ;QAAE,OAAO,MAAM,CAAC,CAAC,CAAC,CAAC;IAC5C,OAAO,EAAE,CAAC;AACZ,CAAC"}
|