@markstanden/opencode-test-container 0.0.0-stage → 0.1.1
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/LICENSE +21 -0
- package/README.md +263 -2
- package/container/Containerfile +24 -0
- package/container/README.md +29 -0
- package/dist/adapters/opencode/events.d.ts +90 -0
- package/dist/adapters/opencode/events.js +213 -0
- package/dist/adapters/opencode/runtime.d.ts +87 -0
- package/dist/adapters/opencode/runtime.js +136 -0
- package/dist/adapters/podman/container.d.ts +62 -0
- package/dist/adapters/podman/container.js +119 -0
- package/dist/adapters/podman/image.d.ts +50 -0
- package/dist/adapters/podman/image.js +124 -0
- package/dist/adapters/process.d.ts +38 -0
- package/dist/adapters/process.js +71 -0
- package/dist/campaign/assess.d.ts +45 -0
- package/dist/campaign/assess.js +208 -0
- package/dist/campaign/close.d.ts +17 -0
- package/dist/campaign/close.js +112 -0
- package/dist/campaign/evidence-guard.d.ts +24 -0
- package/dist/campaign/evidence-guard.js +49 -0
- package/dist/campaign/freeze.d.ts +94 -0
- package/dist/campaign/freeze.js +297 -0
- package/dist/campaign/inventory.d.ts +62 -0
- package/dist/campaign/inventory.js +192 -0
- package/dist/campaign/judge.d.ts +209 -0
- package/dist/campaign/judge.js +1285 -0
- package/dist/campaign/ledger.d.ts +64 -0
- package/dist/campaign/ledger.js +149 -0
- package/dist/campaign/prepare.d.ts +129 -0
- package/dist/campaign/prepare.js +483 -0
- package/dist/campaign/primary.d.ts +96 -0
- package/dist/campaign/primary.js +189 -0
- package/dist/campaign/run.d.ts +151 -0
- package/dist/campaign/run.js +562 -0
- package/dist/campaign/status.d.ts +76 -0
- package/dist/campaign/status.js +237 -0
- package/dist/cli/otc.d.ts +51 -0
- package/dist/cli/otc.js +435 -0
- package/dist/contracts/canonical.d.ts +21 -0
- package/dist/contracts/canonical.js +44 -0
- package/dist/contracts/types.d.ts +261 -0
- package/dist/contracts/types.js +9 -0
- package/dist/contracts/validate.d.ts +72 -0
- package/dist/contracts/validate.js +1021 -0
- package/dist/contracts/version.d.ts +44 -0
- package/dist/contracts/version.js +147 -0
- package/dist/evaluators/docs/analysis/accounting.d.ts +140 -0
- package/dist/evaluators/docs/analysis/accounting.js +237 -0
- package/dist/evaluators/docs/analysis/blinding.d.ts +40 -0
- package/dist/evaluators/docs/analysis/blinding.js +80 -0
- package/dist/evaluators/docs/analysis/bounds.d.ts +40 -0
- package/dist/evaluators/docs/analysis/bounds.js +31 -0
- package/dist/evaluators/docs/analysis/budget.d.ts +137 -0
- package/dist/evaluators/docs/analysis/budget.js +305 -0
- package/dist/evaluators/docs/analysis/closure.d.ts +175 -0
- package/dist/evaluators/docs/analysis/closure.js +251 -0
- package/dist/evaluators/docs/analysis/decision.d.ts +59 -0
- package/dist/evaluators/docs/analysis/decision.js +161 -0
- package/dist/evaluators/docs/analysis/freeze.d.ts +201 -0
- package/dist/evaluators/docs/analysis/freeze.js +395 -0
- package/dist/evaluators/docs/analysis/guardrails.d.ts +51 -0
- package/dist/evaluators/docs/analysis/guardrails.js +194 -0
- package/dist/evaluators/docs/analysis/journal.d.ts +150 -0
- package/dist/evaluators/docs/analysis/journal.js +475 -0
- package/dist/evaluators/docs/analysis/ledger.d.ts +78 -0
- package/dist/evaluators/docs/analysis/ledger.js +145 -0
- package/dist/evaluators/docs/analysis/measures.d.ts +302 -0
- package/dist/evaluators/docs/analysis/measures.js +1069 -0
- package/dist/evaluators/docs/analysis/model.d.ts +236 -0
- package/dist/evaluators/docs/analysis/model.js +740 -0
- package/dist/evaluators/docs/analysis/pairing.d.ts +68 -0
- package/dist/evaluators/docs/analysis/pairing.js +95 -0
- package/dist/evaluators/docs/analysis/records.d.ts +229 -0
- package/dist/evaluators/docs/analysis/records.js +935 -0
- package/dist/evaluators/docs/analysis/recovery.d.ts +225 -0
- package/dist/evaluators/docs/analysis/recovery.js +507 -0
- package/dist/evaluators/docs/analysis/render.d.ts +235 -0
- package/dist/evaluators/docs/analysis/render.js +566 -0
- package/dist/evaluators/docs/analysis/replay.d.ts +15 -0
- package/dist/evaluators/docs/analysis/replay.js +1272 -0
- package/dist/evaluators/docs/analysis/screening/inventory.d.ts +136 -0
- package/dist/evaluators/docs/analysis/screening/inventory.js +307 -0
- package/dist/evaluators/docs/analysis/screening/noteVersion.d.ts +15 -0
- package/dist/evaluators/docs/analysis/screening/noteVersion.js +46 -0
- package/dist/evaluators/docs/analysis/screening/reconcile.d.ts +38 -0
- package/dist/evaluators/docs/analysis/screening/reconcile.js +40 -0
- package/dist/evaluators/docs/analysis/screening/rules.d.ts +163 -0
- package/dist/evaluators/docs/analysis/screening/rules.js +330 -0
- package/dist/evaluators/docs/analysis/screening/scan.d.ts +72 -0
- package/dist/evaluators/docs/analysis/screening/scan.js +362 -0
- package/dist/evaluators/docs/analysis/selector.d.ts +68 -0
- package/dist/evaluators/docs/analysis/selector.js +123 -0
- package/dist/evaluators/docs/assess.d.ts +129 -0
- package/dist/evaluators/docs/assess.js +433 -0
- package/dist/evaluators/docs/campaign.d.ts +133 -0
- package/dist/evaluators/docs/campaign.js +222 -0
- package/dist/evaluators/docs/index.d.ts +25 -0
- package/dist/evaluators/docs/index.js +25 -0
- package/dist/evaluators/docs/journal.d.ts +150 -0
- package/dist/evaluators/docs/journal.js +475 -0
- package/dist/evaluators/docs/scoring.d.ts +367 -0
- package/dist/evaluators/docs/scoring.js +662 -0
- package/dist/evaluators/skills/assess.d.ts +94 -0
- package/dist/evaluators/skills/assess.js +207 -0
- package/dist/index.d.ts +46 -0
- package/dist/index.js +29 -0
- package/dist/legacy/prod014.d.ts +86 -0
- package/dist/legacy/prod014.js +209 -0
- package/dist/reporting/report.d.ts +79 -0
- package/dist/reporting/report.js +242 -0
- package/docs/architecture.md +106 -0
- package/docs/capability-matrix.md +84 -0
- package/docs/offline-rehearsal.md +75 -0
- package/docs/parity-record.md +81 -0
- package/docs/pr-description.md +103 -0
- package/docs/release-0.1.0.md +52 -0
- package/docs/releasing.md +82 -0
- package/docs/schema.md +97 -0
- package/examples/skills/README.md +13 -0
- package/examples/skills/campaign.json +73 -0
- package/examples/skills/skills/otel-helper/SKILL.md +10 -0
- package/examples/skills/suite.json +29 -0
- package/package.json +45 -5
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Product-supplied primary-check execution.
|
|
3
|
+
*
|
|
4
|
+
* A checker is trusted product data staged during preparation. It runs after
|
|
5
|
+
* the trial in its own container, with the completed workspace and the
|
|
6
|
+
* pristine workspace mounted read-only and no provider environment. Its
|
|
7
|
+
* source is never mounted into the trial, so expectations cannot leak to the
|
|
8
|
+
* subject.
|
|
9
|
+
*/
|
|
10
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
11
|
+
import { join } from "node:path";
|
|
12
|
+
import { sha256Bytes } from "../contracts/canonical.js";
|
|
13
|
+
import { normaliseMounts, runContainer, } from "../adapters/podman/container.js";
|
|
14
|
+
/** The container-side checker paths. */
|
|
15
|
+
export const CONTAINER_CHECKER = "/checker";
|
|
16
|
+
/** The container-side completed workspace. */
|
|
17
|
+
export const CONTAINER_CHECKER_LIVE = "/live";
|
|
18
|
+
/** The container-side pristine workspace. */
|
|
19
|
+
export const CONTAINER_CHECKER_PRISTINE = "/pristine";
|
|
20
|
+
/** Classify one completed checker process. */
|
|
21
|
+
function statusOf(result) {
|
|
22
|
+
if (result.timedOut)
|
|
23
|
+
return "timeout";
|
|
24
|
+
if (result.error !== null || result.status === null)
|
|
25
|
+
return "error";
|
|
26
|
+
return result.status === 0 ? "pass" : "fail";
|
|
27
|
+
}
|
|
28
|
+
/** Write the checker's minimal environment file. */
|
|
29
|
+
function writeCheckerEnvironment(directory) {
|
|
30
|
+
mkdirSync(directory, { recursive: true });
|
|
31
|
+
const path = join(directory, "checker.env");
|
|
32
|
+
writeFileSync(path, [
|
|
33
|
+
"HOME=/tmp/checker-home",
|
|
34
|
+
"XDG_DATA_HOME=/tmp/checker-home/.local/share",
|
|
35
|
+
"XDG_CACHE_HOME=/tmp/checker-home/.cache",
|
|
36
|
+
].join("\n") + "\n", { encoding: "utf8", mode: 0o600 });
|
|
37
|
+
return path;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* The checker plan: no network, no provider variables, no evidence root.
|
|
41
|
+
* @param options The resolved paths and identity.
|
|
42
|
+
* @param options.imageId The frozen image.
|
|
43
|
+
* @param options.checkerDir The staged checker directory.
|
|
44
|
+
* @param options.script The suite-relative script.
|
|
45
|
+
* @param options.workspace The completed trial workspace.
|
|
46
|
+
* @param options.pristine The prepared pristine workspace.
|
|
47
|
+
* @param options.envFile The 0600 environment file.
|
|
48
|
+
* @param options.timeoutMs The wall-clock bound.
|
|
49
|
+
* @returns The validated container plan.
|
|
50
|
+
*/
|
|
51
|
+
export function primaryCheckPlan(options) {
|
|
52
|
+
return {
|
|
53
|
+
imageId: options.imageId,
|
|
54
|
+
mounts: normaliseMounts([
|
|
55
|
+
{
|
|
56
|
+
source: options.workspace,
|
|
57
|
+
target: CONTAINER_CHECKER_LIVE,
|
|
58
|
+
readOnly: true,
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
source: options.pristine,
|
|
62
|
+
target: CONTAINER_CHECKER_PRISTINE,
|
|
63
|
+
readOnly: true,
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
source: options.checkerDir,
|
|
67
|
+
target: CONTAINER_CHECKER,
|
|
68
|
+
readOnly: true,
|
|
69
|
+
},
|
|
70
|
+
]),
|
|
71
|
+
workdir: "/tmp",
|
|
72
|
+
network: "none",
|
|
73
|
+
argv: [
|
|
74
|
+
"node",
|
|
75
|
+
`${CONTAINER_CHECKER}/${options.script}`,
|
|
76
|
+
CONTAINER_CHECKER_LIVE,
|
|
77
|
+
CONTAINER_CHECKER_PRISTINE,
|
|
78
|
+
],
|
|
79
|
+
envNames: ["HOME", "XDG_DATA_HOME", "XDG_CACHE_HOME"],
|
|
80
|
+
envFile: options.envFile,
|
|
81
|
+
timeoutMs: options.timeoutMs,
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Run one product primary check against a completed trial.
|
|
86
|
+
* @param options The case, prepared identities and trial directory.
|
|
87
|
+
* @param options.root The campaign root.
|
|
88
|
+
* @param options.testCase The docs case with a declared checker.
|
|
89
|
+
* @param options.prepared The prepared case record.
|
|
90
|
+
* @param options.trialDir The trial evidence directory.
|
|
91
|
+
* @param options.workspace The completed trial workspace.
|
|
92
|
+
* @param options.imageId The frozen image identity.
|
|
93
|
+
* @param options.run Process adapter, injected for tests.
|
|
94
|
+
* @param options.now Injected clock.
|
|
95
|
+
* @returns The recorded outcome and the readable record.
|
|
96
|
+
*/
|
|
97
|
+
export async function executePrimaryCheck(options) {
|
|
98
|
+
const spec = options.testCase.primaryCheck;
|
|
99
|
+
const prepared = options.prepared.primaryCheck;
|
|
100
|
+
if (spec === undefined || prepared === undefined) {
|
|
101
|
+
return { ok: true, record: null, problem: null };
|
|
102
|
+
}
|
|
103
|
+
const checkerDir = join(options.root, "prepare", prepared.directory);
|
|
104
|
+
const scriptPath = join(checkerDir, prepared.script);
|
|
105
|
+
const now = options.now ?? (() => new Date().toISOString());
|
|
106
|
+
const startedAt = now();
|
|
107
|
+
const started = Date.now();
|
|
108
|
+
const base = {
|
|
109
|
+
schemaVersion: 1,
|
|
110
|
+
id: prepared.id,
|
|
111
|
+
script: prepared.script,
|
|
112
|
+
sourceHash: existsSync(scriptPath)
|
|
113
|
+
? sha256Bytes(readFileSync(scriptPath))
|
|
114
|
+
: "missing",
|
|
115
|
+
command: "node",
|
|
116
|
+
args: [
|
|
117
|
+
`${CONTAINER_CHECKER}/${prepared.script}`,
|
|
118
|
+
CONTAINER_CHECKER_LIVE,
|
|
119
|
+
CONTAINER_CHECKER_PRISTINE,
|
|
120
|
+
],
|
|
121
|
+
timeoutMs: prepared.timeoutMs,
|
|
122
|
+
startedAt,
|
|
123
|
+
};
|
|
124
|
+
const finish = (patch) => {
|
|
125
|
+
const record = {
|
|
126
|
+
...base,
|
|
127
|
+
durationMs: Date.now() - started,
|
|
128
|
+
...patch,
|
|
129
|
+
stdout: patch.stdout.slice(0, 16_000),
|
|
130
|
+
stderr: patch.stderr.slice(0, 16_000),
|
|
131
|
+
};
|
|
132
|
+
writeFileSync(join(options.trialDir, "primary-check.json"), `${JSON.stringify(record, null, 2)}\n`, "utf8");
|
|
133
|
+
return {
|
|
134
|
+
ok: record.status === "pass" || record.status === "fail",
|
|
135
|
+
record,
|
|
136
|
+
problem: record.status === "timeout" || record.status === "error"
|
|
137
|
+
? `primary check ${record.id} ${record.status}: ${record.reason ?? record.stderr.trim()}`
|
|
138
|
+
: null,
|
|
139
|
+
};
|
|
140
|
+
};
|
|
141
|
+
if (!existsSync(scriptPath)) {
|
|
142
|
+
return finish({
|
|
143
|
+
status: "error",
|
|
144
|
+
exit: null,
|
|
145
|
+
signal: null,
|
|
146
|
+
reason: `primary checker ${prepared.script} is missing from the staged payload`,
|
|
147
|
+
stdout: "",
|
|
148
|
+
stderr: "",
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
const envFile = writeCheckerEnvironment(options.trialDir);
|
|
152
|
+
const plan = primaryCheckPlan({
|
|
153
|
+
imageId: options.imageId,
|
|
154
|
+
checkerDir,
|
|
155
|
+
script: prepared.script,
|
|
156
|
+
workspace: options.workspace,
|
|
157
|
+
pristine: join(options.root, "prepare", "workspaces", options.testCase.caseId),
|
|
158
|
+
envFile,
|
|
159
|
+
timeoutMs: prepared.timeoutMs,
|
|
160
|
+
});
|
|
161
|
+
const result = await (options.run ?? runContainer)(plan);
|
|
162
|
+
return finish({
|
|
163
|
+
status: statusOf(result),
|
|
164
|
+
exit: result.status,
|
|
165
|
+
signal: result.signal,
|
|
166
|
+
reason: result.error,
|
|
167
|
+
stdout: result.stdout,
|
|
168
|
+
stderr: result.stderr,
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Read a recorded primary check without trusting its shape.
|
|
173
|
+
* @param trialDir The trial evidence directory.
|
|
174
|
+
* @returns The record, or null when absent or unreadable.
|
|
175
|
+
*/
|
|
176
|
+
export function readPrimaryCheck(trialDir) {
|
|
177
|
+
const path = join(trialDir, "primary-check.json");
|
|
178
|
+
if (!existsSync(path))
|
|
179
|
+
return null;
|
|
180
|
+
try {
|
|
181
|
+
const value = JSON.parse(readFileSync(path, "utf8"));
|
|
182
|
+
return typeof value === "object" && value !== null
|
|
183
|
+
? value
|
|
184
|
+
: null;
|
|
185
|
+
}
|
|
186
|
+
catch {
|
|
187
|
+
return null;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
import type { ToolIdentity } from "../contracts/version.ts";
|
|
2
|
+
import type { Slot, SuiteCase } from "../contracts/types.ts";
|
|
3
|
+
import { type ContainerPlan } from "../adapters/podman/container.ts";
|
|
4
|
+
import type { CommandResult } from "../adapters/process.ts";
|
|
5
|
+
import { type FrozenRecord } from "./freeze.ts";
|
|
6
|
+
import { type PreparedManifest, type StagedArm } from "./prepare.ts";
|
|
7
|
+
/** The receipt written before any dispatch. */
|
|
8
|
+
export interface LaunchReceipt {
|
|
9
|
+
/** The schema version value. */
|
|
10
|
+
schemaVersion: 1;
|
|
11
|
+
/** The campaign id value. */
|
|
12
|
+
campaignId: string;
|
|
13
|
+
/** The slot id value. */
|
|
14
|
+
slotId: string;
|
|
15
|
+
/** The case id value. */
|
|
16
|
+
caseId: string;
|
|
17
|
+
/** The arm id value. */
|
|
18
|
+
armId: string;
|
|
19
|
+
/** The repetition id value. */
|
|
20
|
+
repetitionId: string;
|
|
21
|
+
/** The image id value. */
|
|
22
|
+
imageId: string;
|
|
23
|
+
/** The prompt sha256 value. */
|
|
24
|
+
promptSha256: string;
|
|
25
|
+
/** The config sha256 value. */
|
|
26
|
+
configSha256: string;
|
|
27
|
+
/** The started at value. */
|
|
28
|
+
startedAt: string;
|
|
29
|
+
/** The argv value. */
|
|
30
|
+
argv: string[];
|
|
31
|
+
/** The env names value. */
|
|
32
|
+
envNames: string[];
|
|
33
|
+
}
|
|
34
|
+
/** The completion record written after the container exits. */
|
|
35
|
+
export interface TrialMeta {
|
|
36
|
+
/** The schema version value. */
|
|
37
|
+
schemaVersion: 1;
|
|
38
|
+
/** The campaign id value. */
|
|
39
|
+
campaignId: string;
|
|
40
|
+
/** The slot id value. */
|
|
41
|
+
slotId: string;
|
|
42
|
+
/** The case id value. */
|
|
43
|
+
caseId: string;
|
|
44
|
+
/** The arm id value. */
|
|
45
|
+
armId: string;
|
|
46
|
+
/** The repetition id value. */
|
|
47
|
+
repetitionId: string;
|
|
48
|
+
/** The exit value. */
|
|
49
|
+
exit: number | null;
|
|
50
|
+
/** The signal value. */
|
|
51
|
+
signal: string | null;
|
|
52
|
+
/** The timed out value. */
|
|
53
|
+
timedOut: boolean;
|
|
54
|
+
/** The error value. */
|
|
55
|
+
error: string | null;
|
|
56
|
+
/** The duration ms value. */
|
|
57
|
+
durationMs: number;
|
|
58
|
+
/** The capture valid value. */
|
|
59
|
+
captureValid: boolean;
|
|
60
|
+
/** The capture problems value. */
|
|
61
|
+
captureProblems: string[];
|
|
62
|
+
/** The text parts value. */
|
|
63
|
+
textParts: number;
|
|
64
|
+
/** The last part kind value. */
|
|
65
|
+
lastPartKind: string | null;
|
|
66
|
+
/** The parse failures value. */
|
|
67
|
+
parseFailures: number;
|
|
68
|
+
/** The events value. */
|
|
69
|
+
events: number;
|
|
70
|
+
/** The prompt sha256 value. */
|
|
71
|
+
promptSha256: string;
|
|
72
|
+
/** The answer sha256 value. */
|
|
73
|
+
answerSha256: string;
|
|
74
|
+
/** The image id value. */
|
|
75
|
+
imageId: string;
|
|
76
|
+
/** The completed at value. */
|
|
77
|
+
completedAt: string;
|
|
78
|
+
}
|
|
79
|
+
/** What one run invocation did. */
|
|
80
|
+
export interface RunSummary {
|
|
81
|
+
/** The ok value. */
|
|
82
|
+
ok: boolean;
|
|
83
|
+
/** The ran value. */
|
|
84
|
+
ran: string[];
|
|
85
|
+
/** The refused value. */
|
|
86
|
+
refused: string[];
|
|
87
|
+
/** The problems value. */
|
|
88
|
+
problems: string[];
|
|
89
|
+
}
|
|
90
|
+
/** Dependencies the runner accepts, so ordinary tests need no Podman. */
|
|
91
|
+
export interface RunDeps {
|
|
92
|
+
/** The run container value. */
|
|
93
|
+
runContainer?: (plan: ContainerPlan) => Promise<CommandResult>;
|
|
94
|
+
/** The now value. */
|
|
95
|
+
now?: () => string;
|
|
96
|
+
/** The executing tool identity, injected for drift tests. */
|
|
97
|
+
tool?: ToolIdentity;
|
|
98
|
+
}
|
|
99
|
+
/** Path of one trial's evidence directory. */
|
|
100
|
+
export declare function trialDirectory(root: string, slotId: string): string;
|
|
101
|
+
/**
|
|
102
|
+
* Build the container plan for one trial without dispatching it. Dry runs and
|
|
103
|
+
* tests use the same plan the real runner executes.
|
|
104
|
+
* @param options The resolved trial inputs.
|
|
105
|
+
* @returns The validated plan, or the problems found while staging.
|
|
106
|
+
* @param options.root The root value.
|
|
107
|
+
* @param options.manifest The manifest value.
|
|
108
|
+
* @param options.frozen The frozen value.
|
|
109
|
+
* @param options.slot The slot value.
|
|
110
|
+
* @param options.testCase The testCase value.
|
|
111
|
+
* @param options.arm The arm value.
|
|
112
|
+
* @param options.trialDir The trialDir value.
|
|
113
|
+
* @param options.passthrough The passthrough value.
|
|
114
|
+
*/
|
|
115
|
+
export declare function planTrial(options: {
|
|
116
|
+
root: string;
|
|
117
|
+
manifest: PreparedManifest;
|
|
118
|
+
frozen: FrozenRecord;
|
|
119
|
+
slot: Slot;
|
|
120
|
+
testCase: SuiteCase;
|
|
121
|
+
arm: StagedArm;
|
|
122
|
+
trialDir: string;
|
|
123
|
+
passthrough?: readonly string[];
|
|
124
|
+
}): {
|
|
125
|
+
ok: true;
|
|
126
|
+
plan: ContainerPlan;
|
|
127
|
+
argv: string[];
|
|
128
|
+
configSha256: string;
|
|
129
|
+
} | {
|
|
130
|
+
ok: false;
|
|
131
|
+
problems: string[];
|
|
132
|
+
};
|
|
133
|
+
/**
|
|
134
|
+
* Execute one or more scheduled slots. A launch receipt and ledger event are
|
|
135
|
+
* written before the container starts, so an interrupted dispatch remains
|
|
136
|
+
* visibly claimed rather than looking blank.
|
|
137
|
+
* @param root The frozen campaign root.
|
|
138
|
+
* @param options Slot selection and dry-run choice.
|
|
139
|
+
* @param options.slotIds The selected slots.
|
|
140
|
+
* @param options.dryRun Plan without dispatch.
|
|
141
|
+
* @param options.passthrough Named environment values to pass through.
|
|
142
|
+
* @param deps Injected process runner and clock.
|
|
143
|
+
* @returns What ran and what was refused.
|
|
144
|
+
*/
|
|
145
|
+
export declare function runCampaign(root: string, options?: {
|
|
146
|
+
slotIds?: readonly string[];
|
|
147
|
+
dryRun?: boolean;
|
|
148
|
+
passthrough?: readonly string[];
|
|
149
|
+
}, deps?: RunDeps): Promise<RunSummary>;
|
|
150
|
+
/** The canonical identity of a trial's immutable launch receipt. */
|
|
151
|
+
export declare function launchSha256(launch: LaunchReceipt): string;
|