@on-par/factory-core 0.9.27-next.1 → 0.9.27-next.3

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 (41) hide show
  1. package/dist/index.d.ts +4 -27
  2. package/dist/index.d.ts.map +1 -1
  3. package/dist/index.js +2 -16
  4. package/dist/index.js.map +1 -1
  5. package/package.json +5 -5
  6. package/dist/hosted/control-plane.d.ts +0 -40
  7. package/dist/hosted/control-plane.d.ts.map +0 -1
  8. package/dist/hosted/control-plane.js +0 -198
  9. package/dist/hosted/control-plane.js.map +0 -1
  10. package/dist/hosted/queue-client.d.ts +0 -51
  11. package/dist/hosted/queue-client.d.ts.map +0 -1
  12. package/dist/hosted/queue-client.js +0 -92
  13. package/dist/hosted/queue-client.js.map +0 -1
  14. package/dist/hosted/runner-client.d.ts +0 -78
  15. package/dist/hosted/runner-client.d.ts.map +0 -1
  16. package/dist/hosted/runner-client.js +0 -82
  17. package/dist/hosted/runner-client.js.map +0 -1
  18. package/dist/hosted/runner.d.ts +0 -74
  19. package/dist/hosted/runner.d.ts.map +0 -1
  20. package/dist/hosted/runner.js +0 -174
  21. package/dist/hosted/runner.js.map +0 -1
  22. package/dist/hosted/smoke.d.ts +0 -46
  23. package/dist/hosted/smoke.d.ts.map +0 -1
  24. package/dist/hosted/smoke.js +0 -56
  25. package/dist/hosted/smoke.js.map +0 -1
  26. package/dist/hosted/store-resolve.d.ts +0 -16
  27. package/dist/hosted/store-resolve.d.ts.map +0 -1
  28. package/dist/hosted/store-resolve.js +0 -13
  29. package/dist/hosted/store-resolve.js.map +0 -1
  30. package/dist/hosted/store-sqlite.d.ts +0 -10
  31. package/dist/hosted/store-sqlite.d.ts.map +0 -1
  32. package/dist/hosted/store-sqlite.js +0 -67
  33. package/dist/hosted/store-sqlite.js.map +0 -1
  34. package/dist/hosted/summary.d.ts +0 -26
  35. package/dist/hosted/summary.d.ts.map +0 -1
  36. package/dist/hosted/summary.js +0 -27
  37. package/dist/hosted/summary.js.map +0 -1
  38. package/dist/hosted/watchdog.d.ts +0 -38
  39. package/dist/hosted/watchdog.d.ts.map +0 -1
  40. package/dist/hosted/watchdog.js +0 -56
  41. package/dist/hosted/watchdog.js.map +0 -1
@@ -1,78 +0,0 @@
1
- import type { RunnerLease } from '@on-par/contracts';
2
- import type { HostedJobSummary } from './summary.js';
3
- export interface RegisteredRunner {
4
- runnerId: string;
5
- capabilities: string[];
6
- available: boolean;
7
- lastHeartbeatAt: string;
8
- }
9
- export type PollForLeaseResult = {
10
- ok: true;
11
- lease: RunnerLease;
12
- job: HostedJobSummary;
13
- } | {
14
- ok: false;
15
- reason: 'no-match';
16
- };
17
- export interface HostedControlPlaneClient {
18
- registerRunner(input: {
19
- runnerId: string;
20
- capabilities: string[];
21
- }): Promise<RegisteredRunner>;
22
- pollForLease(input: {
23
- runnerId: string;
24
- capabilities: string[];
25
- leaseId: string;
26
- ttlMs: number;
27
- heartbeatIntervalMs: number;
28
- }): Promise<PollForLeaseResult>;
29
- }
30
- /** Structurally identical to the router's FetchFn — defined here so this
31
- * module does not import from ../router (avoids an import cycle). */
32
- export type HostedControlPlaneFetchFn = (input: string, init?: {
33
- method?: string;
34
- headers?: Record<string, string>;
35
- body?: string;
36
- }) => Promise<{
37
- ok: boolean;
38
- status: number;
39
- json(): Promise<unknown>;
40
- }>;
41
- export interface HttpHostedControlPlaneClientOptions {
42
- /** e.g. 'http://127.0.0.1:8799'. Trailing slash tolerated. */
43
- baseUrl: string;
44
- /** default globalThis.fetch */
45
- fetchImpl?: HostedControlPlaneFetchFn;
46
- }
47
- /** Production client: talks to a running createHostedControlPlaneServer over
48
- * HTTP. Throws on transport/HTTP failure — the caller decides how to react. */
49
- export declare function createHttpHostedControlPlaneClient(options: HttpHostedControlPlaneClientOptions): HostedControlPlaneClient;
50
- export interface OneJobRunnerConfig {
51
- runnerId: string;
52
- capabilities: string[];
53
- leaseId: string;
54
- ttlMs: number;
55
- heartbeatIntervalMs: number;
56
- /** Bounded wait window for polling before giving up with no lease. Default 30_000. */
57
- timeoutMs?: number;
58
- /** Delay between poll attempts. Default 2_000. */
59
- pollIntervalMs?: number;
60
- /** default () => Date.now() */
61
- now?: () => number;
62
- /** default a real setTimeout-backed delay */
63
- sleep?: (ms: number) => Promise<void>;
64
- }
65
- export interface OneJobRunnerOutcome {
66
- leased: boolean;
67
- runner: RegisteredRunner;
68
- attempts: number;
69
- jobId?: string;
70
- lease?: RunnerLease;
71
- job?: HostedJobSummary;
72
- trace: string;
73
- }
74
- /** Registers once, then polls for a compatible job within a bounded wait
75
- * window, leasing at most one job. Exits (returns) cleanly — leased or not —
76
- * once a lease is acquired or the window elapses; never loops past that. */
77
- export declare function runOneJobRunner(client: HostedControlPlaneClient, config: OneJobRunnerConfig): Promise<OneJobRunnerOutcome>;
78
- //# sourceMappingURL=runner-client.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"runner-client.d.ts","sourceRoot":"","sources":["../../src/hosted/runner-client.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAErD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAErD,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,SAAS,EAAE,OAAO,CAAC;IACnB,eAAe,EAAE,MAAM,CAAC;CACzB;AAYD,MAAM,MAAM,kBAAkB,GAC5B;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,KAAK,EAAE,WAAW,CAAC;IAAC,GAAG,EAAE,gBAAgB,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,UAAU,CAAA;CAAE,CAAC;AAE9F,MAAM,WAAW,wBAAwB;IACvC,cAAc,CAAC,KAAK,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,EAAE,CAAA;KAAE,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAC;IAC/F,YAAY,CAAC,KAAK,EAAE;QAClB,QAAQ,EAAE,MAAM,CAAC;QACjB,YAAY,EAAE,MAAM,EAAE,CAAC;QACvB,OAAO,EAAE,MAAM,CAAC;QAChB,KAAK,EAAE,MAAM,CAAC;QACd,mBAAmB,EAAE,MAAM,CAAC;KAC7B,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAAC;CACjC;AAED;qEACqE;AACrE,MAAM,MAAM,yBAAyB,GAAG,CACtC,KAAK,EAAE,MAAM,EACb,IAAI,CAAC,EAAE;IAAE,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,KACxE,OAAO,CAAC;IAAE,EAAE,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,IAAI,OAAO,CAAC,OAAO,CAAC,CAAA;CAAE,CAAC,CAAC;AAExE,MAAM,WAAW,mCAAmC;IAClD,8DAA8D;IAC9D,OAAO,EAAE,MAAM,CAAC;IAChB,+BAA+B;IAC/B,SAAS,CAAC,EAAE,yBAAyB,CAAC;CACvC;AAED;+EAC+E;AAC/E,wBAAgB,kCAAkC,CAChD,OAAO,EAAE,mCAAmC,GAC3C,wBAAwB,CA8B1B;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,mBAAmB,EAAE,MAAM,CAAC;IAC5B,sFAAsF;IACtF,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,kDAAkD;IAClD,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,+BAA+B;IAC/B,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;IACnB,6CAA6C;IAC7C,KAAK,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACvC;AAED,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,OAAO,CAAC;IAChB,MAAM,EAAE,gBAAgB,CAAC;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,GAAG,CAAC,EAAE,gBAAgB,CAAC;IACvB,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;4EAE4E;AAC5E,wBAAsB,eAAe,CACnC,MAAM,EAAE,wBAAwB,EAChC,MAAM,EAAE,kBAAkB,GACzB,OAAO,CAAC,mBAAmB,CAAC,CA4C9B"}
@@ -1,82 +0,0 @@
1
- /** Linear-time trim (no regex) — baseUrl is caller-supplied library input, so a
2
- * `/\/+$/`-style pattern would flag as a polynomial-regex-on-untrusted-input risk. */
3
- function trimTrailingSlashes(value) {
4
- let end = value.length;
5
- while (end > 0 && value[end - 1] === '/') {
6
- end -= 1;
7
- }
8
- return value.slice(0, end);
9
- }
10
- /** Production client: talks to a running createHostedControlPlaneServer over
11
- * HTTP. Throws on transport/HTTP failure — the caller decides how to react. */
12
- export function createHttpHostedControlPlaneClient(options) {
13
- const baseUrl = trimTrailingSlashes(options.baseUrl);
14
- const fetchImpl = options.fetchImpl ?? globalThis.fetch;
15
- async function post(path, body) {
16
- const res = await fetchImpl(`${baseUrl}${path}`, {
17
- method: 'POST',
18
- headers: { 'content-type': 'application/json' },
19
- body: JSON.stringify(body),
20
- });
21
- const data = await res.json();
22
- if (!res.ok) {
23
- const message = data && typeof data === 'object' && 'error' in data ? String(data.error) : res.status;
24
- throw new Error(`hosted control plane ${path} failed: ${message}`);
25
- }
26
- return data;
27
- }
28
- return {
29
- async registerRunner(input) {
30
- const data = (await post('/runners', input));
31
- return data.runner;
32
- },
33
- async pollForLease(input) {
34
- const { runnerId, ...body } = input;
35
- const data = (await post(`/runners/${encodeURIComponent(runnerId)}/poll`, body));
36
- return data;
37
- },
38
- };
39
- }
40
- /** Registers once, then polls for a compatible job within a bounded wait
41
- * window, leasing at most one job. Exits (returns) cleanly — leased or not —
42
- * once a lease is acquired or the window elapses; never loops past that. */
43
- export async function runOneJobRunner(client, config) {
44
- const timeoutMs = config.timeoutMs ?? 30_000;
45
- const pollIntervalMs = config.pollIntervalMs ?? 2_000;
46
- const now = config.now ?? (() => Date.now());
47
- const sleep = config.sleep ?? ((ms) => new Promise((resolve) => setTimeout(resolve, ms)));
48
- const runner = await client.registerRunner({ runnerId: config.runnerId, capabilities: config.capabilities });
49
- const deadline = now() + timeoutMs;
50
- let attempts = 0;
51
- for (;;) {
52
- attempts += 1;
53
- const poll = await client.pollForLease({
54
- runnerId: config.runnerId,
55
- capabilities: config.capabilities,
56
- leaseId: config.leaseId,
57
- ttlMs: config.ttlMs,
58
- heartbeatIntervalMs: config.heartbeatIntervalMs,
59
- });
60
- if (poll.ok) {
61
- return {
62
- leased: true,
63
- runner,
64
- attempts,
65
- jobId: poll.job.jobId,
66
- lease: poll.lease,
67
- job: poll.job,
68
- trace: `registered ${config.runnerId} -> leased ${poll.job.jobId} after ${attempts} poll(s)`,
69
- };
70
- }
71
- if (now() >= deadline) {
72
- return {
73
- leased: false,
74
- runner,
75
- attempts,
76
- trace: `registered ${config.runnerId} -> no compatible job within ${timeoutMs}ms (${attempts} poll(s))`,
77
- };
78
- }
79
- await sleep(pollIntervalMs);
80
- }
81
- }
82
- //# sourceMappingURL=runner-client.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"runner-client.js","sourceRoot":"","sources":["../../src/hosted/runner-client.ts"],"names":[],"mappings":"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"}
@@ -1,74 +0,0 @@
1
- import type { HostedJobOutcome, HostedJobResult } from '@on-par/contracts';
2
- import type { ContainerCleanupProof, ContainerEngine } from './container.js';
3
- import { type GitHubAuthorityBrokerOptions } from './github-authority.js';
4
- import type { HostedJobStore, StoredRunner } from './store.js';
5
- export interface FakeRunnerConfig {
6
- runnerId: string;
7
- capabilities: string[];
8
- leaseId: string;
9
- ttlMs: number;
10
- heartbeatIntervalMs: number;
11
- /** Number of heartbeats to emit during fake no-op work (default 1). */
12
- heartbeats?: number;
13
- /** Force a failure result instead of completion (default false). */
14
- fail?: boolean;
15
- }
16
- export interface FakeRunnerOutcome {
17
- runner: StoredRunner;
18
- leased: boolean;
19
- jobId?: string;
20
- result?: HostedJobResult;
21
- trace: string;
22
- }
23
- export declare function runFakeRunner(store: HostedJobStore, config: FakeRunnerConfig): FakeRunnerOutcome;
24
- export interface DockerRunnerConfig {
25
- runnerId: string;
26
- capabilities: string[];
27
- leaseId: string;
28
- ttlMs: number;
29
- heartbeatIntervalMs: number;
30
- image: string;
31
- command: string[];
32
- /** default '/workspace' */
33
- mountPath?: string;
34
- timeoutMs: number;
35
- /** When set, brokers a per-job GitHub credential (#901) gated by FACTORY_HOSTED_EXEC. */
36
- authority?: GitHubAuthorityBrokerOptions;
37
- /** Injectable for tests; defaults to process.env. */
38
- env?: NodeJS.ProcessEnv;
39
- }
40
- export interface DockerRunnerOutcome {
41
- runner: StoredRunner;
42
- leased: boolean;
43
- jobId?: string;
44
- /** Number of running-state heartbeats posted to the control plane. */
45
- heartbeats: number;
46
- /** True when the store accepted the terminal complete/fail update. */
47
- terminalReported: boolean;
48
- outcome?: HostedJobOutcome;
49
- result?: HostedJobResult;
50
- cleanup?: ContainerCleanupProof;
51
- cleanupError?: string;
52
- finalizeRejected?: string;
53
- /** False when the job was never leased, or the workspace clone failed before the container ran. */
54
- ranContainer: boolean;
55
- containerName?: string;
56
- /** Docker process exit code. */
57
- exitCode?: number;
58
- /** Bounded tail of combined stdout+stderr, secret-redacted. */
59
- logsTail?: string;
60
- timedOut?: boolean;
61
- /** Redacted clone failure reason, when the workspace could not be prepared. */
62
- cloneError?: string;
63
- workspaceHostPath?: string;
64
- workspaceCommit?: string;
65
- trace: string;
66
- }
67
- /** Runs a leased job through the existing Docker ContainerEngine path (#899)
68
- * while posting periodic running-state heartbeats for the control plane to
69
- * observe. Reports the terminal result, records cleanup proof, and returns the
70
- * terminal outcome. No clock of its own: heartbeat cadence comes from a real
71
- * interval timer, and the container run itself comes from the injected engine,
72
- * so tests drive both deterministically (fake timers + a fake engine). */
73
- export declare function runDockerRunner(store: HostedJobStore, engine: ContainerEngine, config: DockerRunnerConfig): Promise<DockerRunnerOutcome>;
74
- //# sourceMappingURL=runner.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../../src/hosted/runner.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAE3E,OAAO,KAAK,EAAE,qBAAqB,EAAE,eAAe,EAAsB,MAAM,gBAAgB,CAAC;AACjG,OAAO,EAGL,KAAK,4BAA4B,EAClC,MAAM,uBAAuB,CAAC;AAC/B,OAAO,KAAK,EAAE,cAAc,EAAmB,YAAY,EAAE,MAAM,YAAY,CAAC;AAMhF,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,mBAAmB,EAAE,MAAM,CAAC;IAC5B,uEAAuE;IACvE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,oEAAoE;IACpE,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,YAAY,CAAC;IACrB,MAAM,EAAE,OAAO,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,eAAe,CAAC;IACzB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,cAAc,EAAE,MAAM,EAAE,gBAAgB,GAAG,iBAAiB,CA0ChG;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,mBAAmB,EAAE,MAAM,CAAC;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,2BAA2B;IAC3B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,yFAAyF;IACzF,SAAS,CAAC,EAAE,4BAA4B,CAAC;IACzC,qDAAqD;IACrD,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;CACzB;AAED,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,YAAY,CAAC;IACrB,MAAM,EAAE,OAAO,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,sEAAsE;IACtE,UAAU,EAAE,MAAM,CAAC;IACnB,sEAAsE;IACtE,gBAAgB,EAAE,OAAO,CAAC;IAC1B,OAAO,CAAC,EAAE,gBAAgB,CAAC;IAC3B,MAAM,CAAC,EAAE,eAAe,CAAC;IACzB,OAAO,CAAC,EAAE,qBAAqB,CAAC;IAChC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,mGAAmG;IACnG,YAAY,EAAE,OAAO,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,gCAAgC;IAChC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,+DAA+D;IAC/D,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,+EAA+E;IAC/E,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;;;;0EAK0E;AAC1E,wBAAsB,eAAe,CACnC,KAAK,EAAE,cAAc,EACrB,MAAM,EAAE,eAAe,EACvB,MAAM,EAAE,kBAAkB,GACzB,OAAO,CAAC,mBAAmB,CAAC,CA4I9B"}
@@ -1,174 +0,0 @@
1
- import { redactGitHubCredential, resolveHostedAuthority, } from './github-authority.js';
2
- /** Bound on the retained log tail — enough for diagnosis without unbounded growth. */
3
- const LOG_TAIL_LIMIT = 2000;
4
- const logTail = (logs) => logs.slice(-LOG_TAIL_LIMIT);
5
- export function runFakeRunner(store, config) {
6
- store.registerRunner({ runnerId: config.runnerId, capabilities: config.capabilities });
7
- const poll = store.pollForLease({
8
- runnerId: config.runnerId,
9
- capabilities: config.capabilities,
10
- leaseId: config.leaseId,
11
- ttlMs: config.ttlMs,
12
- heartbeatIntervalMs: config.heartbeatIntervalMs,
13
- });
14
- if (!poll.ok) {
15
- const runner = store.getRunner(config.runnerId);
16
- if (!runner) {
17
- throw new Error(`hosted runner disappeared after registration: ${config.runnerId}`);
18
- }
19
- return { runner, leased: false, trace: 'no compatible job to lease' };
20
- }
21
- const jobId = poll.job.request.jobId;
22
- const heartbeats = config.heartbeats ?? 1;
23
- for (let i = 0; i < heartbeats; i += 1) {
24
- store.heartbeat(jobId, config.leaseId);
25
- }
26
- const finalized = config.fail
27
- ? store.fail(jobId, config.leaseId, 'fake runner reported failure')
28
- : store.complete(jobId, config.leaseId, 'fake runner completed no-op work');
29
- const result = finalized.ok ? (finalized.job.result ?? undefined) : undefined;
30
- const runner = store.getRunner(config.runnerId);
31
- if (!runner) {
32
- throw new Error(`hosted runner disappeared after registration: ${config.runnerId}`);
33
- }
34
- return {
35
- runner,
36
- leased: true,
37
- jobId,
38
- result,
39
- trace: `registered -> leased ${jobId} -> ${heartbeats} heartbeats -> ${config.fail ? 'failed' : 'completed'}`,
40
- };
41
- }
42
- /** Runs a leased job through the existing Docker ContainerEngine path (#899)
43
- * while posting periodic running-state heartbeats for the control plane to
44
- * observe. Reports the terminal result, records cleanup proof, and returns the
45
- * terminal outcome. No clock of its own: heartbeat cadence comes from a real
46
- * interval timer, and the container run itself comes from the injected engine,
47
- * so tests drive both deterministically (fake timers + a fake engine). */
48
- export async function runDockerRunner(store, engine, config) {
49
- store.registerRunner({ runnerId: config.runnerId, capabilities: config.capabilities });
50
- const poll = store.pollForLease({
51
- runnerId: config.runnerId,
52
- capabilities: config.capabilities,
53
- leaseId: config.leaseId,
54
- ttlMs: config.ttlMs,
55
- heartbeatIntervalMs: config.heartbeatIntervalMs,
56
- });
57
- const getRunnerOrThrow = () => {
58
- const runner = store.getRunner(config.runnerId);
59
- if (!runner) {
60
- throw new Error(`hosted runner disappeared after registration: ${config.runnerId}`);
61
- }
62
- return runner;
63
- };
64
- if (!poll.ok) {
65
- return {
66
- runner: getRunnerOrThrow(),
67
- leased: false,
68
- heartbeats: 0,
69
- terminalReported: false,
70
- ranContainer: false,
71
- trace: 'no compatible job to lease',
72
- };
73
- }
74
- const jobId = poll.job.request.jobId;
75
- const credential = config.authority
76
- ? await resolveHostedAuthority(config.env ?? process.env, poll.job, config.authority)
77
- : null;
78
- const redact = (text) => (credential ? redactGitHubCredential(text, credential) : text);
79
- const workspace = await engine.prepareWorkspace(jobId, poll.job.request.taskPayload, poll.job.request.repoSlug, credential ?? undefined);
80
- let heartbeats = 0;
81
- const beat = () => {
82
- store.heartbeat(jobId, config.leaseId);
83
- heartbeats += 1;
84
- };
85
- beat();
86
- let run;
87
- let cleanup;
88
- let cleanupError;
89
- let finalizeResult;
90
- try {
91
- if (!workspace.clone.ok) {
92
- finalizeResult = store.fail(jobId, config.leaseId, redact(`repo clone failed: ${workspace.clone.error ?? 'unknown error'}`), { failurePhase: 'clone' });
93
- }
94
- else {
95
- const timer = setInterval(beat, config.heartbeatIntervalMs);
96
- try {
97
- run = await engine.run({
98
- jobId,
99
- image: config.image,
100
- command: config.command,
101
- workspaceHostPath: workspace.hostPath,
102
- mountPath: config.mountPath ?? '/workspace',
103
- timeoutMs: config.timeoutMs,
104
- });
105
- }
106
- finally {
107
- clearInterval(timer);
108
- }
109
- const redactedLogs = redact(logTail(run.logs));
110
- const success = run.exitCode === 0 && !run.timedOut;
111
- if (success) {
112
- finalizeResult = store.complete(jobId, config.leaseId, `container exited 0 (${run.containerName})`, {
113
- exitCode: run.exitCode,
114
- logsTail: redactedLogs,
115
- artifacts: run.artifacts,
116
- });
117
- }
118
- else {
119
- const why = run.timedOut ? `timed out after ${config.timeoutMs}ms` : `exit ${run.exitCode}`;
120
- finalizeResult = store.fail(jobId, config.leaseId, redact(`container ${why}`), {
121
- failurePhase: 'run',
122
- exitCode: run.exitCode,
123
- logsTail: redactedLogs,
124
- });
125
- }
126
- }
127
- }
128
- catch (err) {
129
- const message = err instanceof Error ? err.message : String(err);
130
- finalizeResult = store.fail(jobId, config.leaseId, redact(`container run error: ${message}`), {
131
- failurePhase: 'run',
132
- });
133
- }
134
- finally {
135
- try {
136
- cleanup = await engine.remove(jobId, workspace.hostPath);
137
- store.recordCleanup(jobId, redact(cleanup.evidence));
138
- }
139
- catch (err) {
140
- cleanupError = redact(err instanceof Error ? err.message : String(err));
141
- }
142
- }
143
- const finalJob = store.get(jobId);
144
- const outcome = finalJob?.result?.outcome;
145
- const finalizeRejected = finalizeResult && !finalizeResult.ok ? finalizeResult.reason : undefined;
146
- const runNote = run
147
- ? `container ${run.containerName} exit ${run.exitCode}${run.timedOut ? ' (timed out)' : ''}`
148
- : workspace.clone.ok
149
- ? 'run error'
150
- : 'clone failed';
151
- const cleanupNote = cleanupError ? `cleanup failed: ${cleanupError}` : 'cleaned';
152
- return {
153
- runner: getRunnerOrThrow(),
154
- leased: true,
155
- jobId,
156
- heartbeats,
157
- terminalReported: finalizeResult?.ok ?? false,
158
- outcome,
159
- result: finalJob?.result ?? undefined,
160
- cleanup,
161
- cleanupError,
162
- finalizeRejected,
163
- ranContainer: run !== undefined,
164
- containerName: run?.containerName,
165
- exitCode: run?.exitCode,
166
- logsTail: run ? redact(logTail(run.logs)) : undefined,
167
- timedOut: run?.timedOut,
168
- cloneError: !workspace.clone.ok ? redact(workspace.clone.error ?? 'unknown clone error') : undefined,
169
- workspaceHostPath: workspace.hostPath,
170
- workspaceCommit: workspace.clone.commit,
171
- trace: redact(`registered -> leased ${jobId} -> ${heartbeats} heartbeats -> ${runNote} -> ${outcome ?? 'unknown'}${finalizeRejected ? ` (finalize rejected: ${finalizeRejected})` : ''} -> ${cleanupNote}`),
172
- };
173
- }
174
- //# sourceMappingURL=runner.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"runner.js","sourceRoot":"","sources":["../../src/hosted/runner.ts"],"names":[],"mappings":"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"}
@@ -1,46 +0,0 @@
1
- import { type ContainerEngine, type ContainerJobOutcome } from './container.js';
2
- import { type HostedJobSummary } from './summary.js';
3
- import { type HostedClock } from './store.js';
4
- export interface HostedSmokeConfig {
5
- repoSlug: string;
6
- image: string;
7
- command: string[];
8
- now: HostedClock;
9
- /** default 'smoke-job-1' */
10
- jobId?: string;
11
- /** default 'smoke-runner-1' */
12
- runnerId?: string;
13
- /** default 'smoke-lease-1' */
14
- leaseId?: string;
15
- /** default ['git', 'node'] */
16
- capabilities?: string[];
17
- /** default 'repo:read' */
18
- requiredAuthority?: string;
19
- /** default 'hosted-exec smoke: run a minimal factory-safe command' */
20
- taskPayload?: string;
21
- /** default 300_000 */
22
- ttlMs?: number;
23
- /** default 30_000 */
24
- heartbeatIntervalMs?: number;
25
- /** default 120_000 */
26
- timeoutMs?: number;
27
- /** default '/workspace' */
28
- mountPath?: string;
29
- /** Injectable for tests; defaults to process.env for the gate. */
30
- env?: NodeJS.ProcessEnv;
31
- }
32
- export interface HostedSmokeOutcome {
33
- enabled: boolean;
34
- trace: string;
35
- jobId?: string;
36
- leaseId?: string;
37
- job?: ContainerJobOutcome;
38
- summary?: HostedJobSummary;
39
- }
40
- /** Runs the optimistic hosted-exec path against a real (injected) container
41
- * engine: creates a job, registers a runner, leases it, drives a disposable
42
- * container run against a fresh clone, then summarizes the terminal result.
43
- * Brokers no real credential — authority minting is out of scope for the
44
- * smoke run (#923). */
45
- export declare function runHostedSmoke(engine: ContainerEngine, config: HostedSmokeConfig): Promise<HostedSmokeOutcome>;
46
- //# sourceMappingURL=smoke.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"smoke.d.ts","sourceRoot":"","sources":["../../src/hosted/smoke.ts"],"names":[],"mappings":"AASA,OAAO,EAAmB,KAAK,eAAe,EAAE,KAAK,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AACjG,OAAO,EAAsB,KAAK,gBAAgB,EAAE,MAAM,cAAc,CAAC;AACzE,OAAO,EAAwB,KAAK,WAAW,EAAE,MAAM,YAAY,CAAC;AAEpE,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,GAAG,EAAE,WAAW,CAAC;IACjB,4BAA4B;IAC5B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,+BAA+B;IAC/B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,8BAA8B;IAC9B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,8BAA8B;IAC9B,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,0BAA0B;IAC1B,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,sEAAsE;IACtE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,sBAAsB;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,qBAAqB;IACrB,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,sBAAsB;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,2BAA2B;IAC3B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,kEAAkE;IAClE,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;CACzB;AAED,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,GAAG,CAAC,EAAE,mBAAmB,CAAC;IAC1B,OAAO,CAAC,EAAE,gBAAgB,CAAC;CAC5B;AAED;;;;uBAIuB;AACvB,wBAAsB,cAAc,CAAC,MAAM,EAAE,eAAe,EAAE,MAAM,EAAE,iBAAiB,GAAG,OAAO,CAAC,kBAAkB,CAAC,CA4CpH"}
@@ -1,56 +0,0 @@
1
- // src/hosted/smoke.ts — Local end-to-end hosted-exec smoke orchestrator (#923,
2
- // parent #895). Composes the already-proven building blocks (store, container
3
- // runner, summary) into one optimistic-path run: create -> lease -> disposable
4
- // Docker run against a fresh clone -> terminal result -> cleanup proof. Gated
5
- // by FACTORY_HOSTED_EXEC so the default-off local factory path is untouched.
6
- // No clock, fs, network, or Docker are touched directly — determinism comes
7
- // from the injected engine and the injected clock.
8
- import { hostedExecEnabled } from '@on-par/contracts';
9
- import { runContainerJob } from './container.js';
10
- import { summarizeHostedJob } from './summary.js';
11
- import { createHostedJobStore } from './store.js';
12
- /** Runs the optimistic hosted-exec path against a real (injected) container
13
- * engine: creates a job, registers a runner, leases it, drives a disposable
14
- * container run against a fresh clone, then summarizes the terminal result.
15
- * Brokers no real credential — authority minting is out of scope for the
16
- * smoke run (#923). */
17
- export async function runHostedSmoke(engine, config) {
18
- if (!hostedExecEnabled(config.env ?? process.env)) {
19
- return { enabled: false, trace: 'hosted execution disabled — local factory path unchanged' };
20
- }
21
- const jobId = config.jobId ?? 'smoke-job-1';
22
- const runnerId = config.runnerId ?? 'smoke-runner-1';
23
- const leaseId = config.leaseId ?? 'smoke-lease-1';
24
- const capabilities = config.capabilities ?? ['git', 'node'];
25
- const requiredAuthority = config.requiredAuthority ?? 'repo:read';
26
- const taskPayload = config.taskPayload ?? 'hosted-exec smoke: run a minimal factory-safe command';
27
- const ttlMs = config.ttlMs ?? 300_000;
28
- const heartbeatIntervalMs = config.heartbeatIntervalMs ?? 30_000;
29
- const timeoutMs = config.timeoutMs ?? 120_000;
30
- const mountPath = config.mountPath ?? '/workspace';
31
- const store = createHostedJobStore({ now: config.now });
32
- store.create({
33
- jobId,
34
- repoSlug: config.repoSlug,
35
- taskPayload,
36
- requiredCapabilities: capabilities,
37
- requiredAuthority,
38
- });
39
- store.registerRunner({ runnerId, capabilities });
40
- const lease = store.acquireLease({ jobId, runnerId, leaseId, ttlMs, heartbeatIntervalMs });
41
- if (!lease.ok) {
42
- return { enabled: true, jobId, trace: `lease failed: ${lease.reason}` };
43
- }
44
- const job = await runContainerJob(store, engine, {
45
- jobId,
46
- leaseId,
47
- image: config.image,
48
- command: config.command,
49
- mountPath,
50
- timeoutMs,
51
- });
52
- const finalJob = store.get(jobId);
53
- const summary = finalJob ? summarizeHostedJob(finalJob) : undefined;
54
- return { enabled: true, jobId, leaseId, job, summary, trace: `smoke: ${job.trace}` };
55
- }
56
- //# sourceMappingURL=smoke.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"smoke.js","sourceRoot":"","sources":["../../src/hosted/smoke.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,8EAA8E;AAC9E,+EAA+E;AAC/E,8EAA8E;AAC9E,6EAA6E;AAC7E,4EAA4E;AAC5E,mDAAmD;AACnD,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAEtD,OAAO,EAAE,eAAe,EAAkD,MAAM,gBAAgB,CAAC;AACjG,OAAO,EAAE,kBAAkB,EAAyB,MAAM,cAAc,CAAC;AACzE,OAAO,EAAE,oBAAoB,EAAoB,MAAM,YAAY,CAAC;AAwCpE;;;;uBAIuB;AACvB,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,MAAuB,EAAE,MAAyB;IACrF,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;QAClD,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,0DAA0D,EAAE,CAAC;IAC/F,CAAC;IAED,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,IAAI,aAAa,CAAC;IAC5C,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,IAAI,gBAAgB,CAAC;IACrD,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,IAAI,eAAe,CAAC;IAClD,MAAM,YAAY,GAAG,MAAM,CAAC,YAAY,IAAI,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;IAC5D,MAAM,iBAAiB,GAAG,MAAM,CAAC,iBAAiB,IAAI,WAAW,CAAC;IAClE,MAAM,WAAW,GAAG,MAAM,CAAC,WAAW,IAAI,uDAAuD,CAAC;IAClG,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,IAAI,OAAO,CAAC;IACtC,MAAM,mBAAmB,GAAG,MAAM,CAAC,mBAAmB,IAAI,MAAM,CAAC;IACjE,MAAM,SAAS,GAAG,MAAM,CAAC,SAAS,IAAI,OAAO,CAAC;IAC9C,MAAM,SAAS,GAAG,MAAM,CAAC,SAAS,IAAI,YAAY,CAAC;IAEnD,MAAM,KAAK,GAAG,oBAAoB,CAAC,EAAE,GAAG,EAAE,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC;IACxD,KAAK,CAAC,MAAM,CAAC;QACX,KAAK;QACL,QAAQ,EAAE,MAAM,CAAC,QAAQ;QACzB,WAAW;QACX,oBAAoB,EAAE,YAAY;QAClC,iBAAiB;KAClB,CAAC,CAAC;IACH,KAAK,CAAC,cAAc,CAAC,EAAE,QAAQ,EAAE,YAAY,EAAE,CAAC,CAAC;IAEjD,MAAM,KAAK,GAAG,KAAK,CAAC,YAAY,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,mBAAmB,EAAE,CAAC,CAAC;IAC3F,IAAI,CAAC,KAAK,CAAC,EAAE,EAAE,CAAC;QACd,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,iBAAiB,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC;IAC1E,CAAC;IAED,MAAM,GAAG,GAAG,MAAM,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE;QAC/C,KAAK;QACL,OAAO;QACP,KAAK,EAAE,MAAM,CAAC,KAAK;QACnB,OAAO,EAAE,MAAM,CAAC,OAAO;QACvB,SAAS;QACT,SAAS;KACV,CAAC,CAAC;IAEH,MAAM,QAAQ,GAAG,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IAClC,MAAM,OAAO,GAAG,QAAQ,CAAC,CAAC,CAAC,kBAAkB,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAEpE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,KAAK,EAAE,UAAU,GAAG,CAAC,KAAK,EAAE,EAAE,CAAC;AACvF,CAAC"}
@@ -1,16 +0,0 @@
1
- import { type HostedJobStore, type HostedJobStoreOptions } from './store.js';
2
- import { type SqliteHostedJobStore } from './store-sqlite.js';
3
- export type HostedJobStoreBackend = 'memory' | 'sqlite';
4
- export interface ResolveHostedJobStoreOptions extends HostedJobStoreOptions {
5
- /** Storage backend to use. Defaults to 'memory'. */
6
- backend?: HostedJobStoreBackend;
7
- /** SQLite only. Defaults to ':memory:'. */
8
- databasePath?: string;
9
- }
10
- export interface ResolveSqliteHostedJobStoreOptions extends ResolveHostedJobStoreOptions {
11
- backend: 'sqlite';
12
- }
13
- /** Defaults to the in-memory store. */
14
- export declare function resolveHostedJobStore(options: ResolveSqliteHostedJobStoreOptions): SqliteHostedJobStore;
15
- export declare function resolveHostedJobStore(options: ResolveHostedJobStoreOptions): HostedJobStore;
16
- //# sourceMappingURL=store-resolve.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"store-resolve.d.ts","sourceRoot":"","sources":["../../src/hosted/store-resolve.ts"],"names":[],"mappings":"AAGA,OAAO,EAAwB,KAAK,cAAc,EAAE,KAAK,qBAAqB,EAAE,MAAM,YAAY,CAAC;AACnG,OAAO,EAA8B,KAAK,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AAE1F,MAAM,MAAM,qBAAqB,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAExD,MAAM,WAAW,4BAA6B,SAAQ,qBAAqB;IACzE,oDAAoD;IACpD,OAAO,CAAC,EAAE,qBAAqB,CAAC;IAChC,2CAA2C;IAC3C,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,kCAAmC,SAAQ,4BAA4B;IACtF,OAAO,EAAE,QAAQ,CAAC;CACnB;AAED,uCAAuC;AACvC,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,kCAAkC,GAAG,oBAAoB,CAAC;AACzG,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,4BAA4B,GAAG,cAAc,CAAC"}
@@ -1,13 +0,0 @@
1
- // src/hosted/store-resolve.ts — config-driven adapter selection (#939).
2
- // Depends on both store.ts (memory) and store-sqlite.ts (sqlite) so neither
3
- // backend module needs to know about the other.
4
- import { createHostedJobStore } from './store.js';
5
- import { createSqliteHostedJobStore } from './store-sqlite.js';
6
- export function resolveHostedJobStore(options) {
7
- const { backend, databasePath, ...storeOptions } = options;
8
- if (backend === 'sqlite') {
9
- return createSqliteHostedJobStore({ ...storeOptions, databasePath: databasePath ?? ':memory:' });
10
- }
11
- return createHostedJobStore(storeOptions);
12
- }
13
- //# sourceMappingURL=store-resolve.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"store-resolve.js","sourceRoot":"","sources":["../../src/hosted/store-resolve.ts"],"names":[],"mappings":"AAAA,wEAAwE;AACxE,4EAA4E;AAC5E,gDAAgD;AAChD,OAAO,EAAE,oBAAoB,EAAmD,MAAM,YAAY,CAAC;AACnG,OAAO,EAAE,0BAA0B,EAA6B,MAAM,mBAAmB,CAAC;AAkB1F,MAAM,UAAU,qBAAqB,CAAC,OAAqC;IACzE,MAAM,EAAE,OAAO,EAAE,YAAY,EAAE,GAAG,YAAY,EAAE,GAAG,OAAO,CAAC;IAC3D,IAAI,OAAO,KAAK,QAAQ,EAAE,CAAC;QACzB,OAAO,0BAA0B,CAAC,EAAE,GAAG,YAAY,EAAE,YAAY,EAAE,YAAY,IAAI,UAAU,EAAE,CAAC,CAAC;IACnG,CAAC;IACD,OAAO,oBAAoB,CAAC,YAAY,CAAC,CAAC;AAC5C,CAAC"}
@@ -1,10 +0,0 @@
1
- import { type HostedJobStore, type HostedJobStoreOptions } from './store.js';
2
- export interface SqliteHostedJobStoreOptions extends HostedJobStoreOptions {
3
- /** Path to the SQLite database file. Defaults to ':memory:'. */
4
- databasePath?: string;
5
- }
6
- export type SqliteHostedJobStore = HostedJobStore & {
7
- close(): void;
8
- };
9
- export declare function createSqliteHostedJobStore(options: SqliteHostedJobStoreOptions): SqliteHostedJobStore;
10
- //# sourceMappingURL=store-sqlite.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"store-sqlite.d.ts","sourceRoot":"","sources":["../../src/hosted/store-sqlite.ts"],"names":[],"mappings":"AAQA,OAAO,EAEL,KAAK,cAAc,EACnB,KAAK,qBAAqB,EAI3B,MAAM,YAAY,CAAC;AAEpB,MAAM,WAAW,2BAA4B,SAAQ,qBAAqB;IACxE,gEAAgE;IAChE,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,MAAM,oBAAoB,GAAG,cAAc,GAAG;IAAE,KAAK,IAAI,IAAI,CAAA;CAAE,CAAC;AAyDtE,wBAAgB,0BAA0B,CAAC,OAAO,EAAE,2BAA2B,GAAG,oBAAoB,CAUrG"}