tickmarkr 2.7.9 → 2.8.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/dist/adapters/codex.d.ts +1 -1
- package/dist/adapters/codex.js +18 -6
- package/dist/adapters/fake.js +42 -4
- package/dist/cli/commands/approve.js +33 -8
- package/dist/cli/commands/doctor.js +11 -2
- package/dist/cli/commands/verify.js +32 -12
- package/dist/gates/acceptance.d.ts +1 -1
- package/dist/gates/acceptance.js +75 -68
- package/dist/gates/baseline.d.ts +5 -1
- package/dist/gates/baseline.js +31 -6
- package/dist/gates/operation-facts.d.ts +47 -0
- package/dist/gates/operation-facts.js +84 -0
- package/dist/gates/run-gates.js +81 -12
- package/dist/run/daemon.d.ts +77 -13
- package/dist/run/daemon.js +348 -94
- package/dist/run/git.d.ts +21 -4
- package/dist/run/git.js +26 -9
- package/dist/run/launchservices-check.d.ts +23 -1
- package/dist/run/launchservices-check.js +88 -3
- package/dist/run/merge.d.ts +114 -7
- package/dist/run/merge.js +146 -44
- package/package.json +1 -1
- package/skills/tickmarkr-overseer/SKILL.md +8 -0
package/dist/gates/run-gates.js
CHANGED
|
@@ -7,7 +7,7 @@ import { TIER_RANK } from "../config/config.js";
|
|
|
7
7
|
import { getAdapter } from "../adapters/registry.js";
|
|
8
8
|
import { GATE_NAMES } from "../graph/schema.js";
|
|
9
9
|
import { acceptanceGate } from "./acceptance.js";
|
|
10
|
-
import { classifiedFileDurations, compareToBaseline, effectiveCeilingMs, waitForCalmWindow, calmWindowReady } from "./baseline.js";
|
|
10
|
+
import { classifiedFileDurations, compareToBaseline, effectiveCeilingMs, waitForCalmWindow, calmWindowReady, SIGNAL_EXIT_RE } from "./baseline.js";
|
|
11
11
|
import { evidenceGate } from "./evidence.js";
|
|
12
12
|
import { captureLlmOutput, SeatLaunchError } from "./llm.js";
|
|
13
13
|
import { withLaunchGuard } from "../drivers/orca.js";
|
|
@@ -19,7 +19,7 @@ import { discoverTestManifest, evaluateManifestedTest, isVitestTestCommand, mani
|
|
|
19
19
|
import { RUNNER_INFRA_DIAGNOSTIC_RE, timeoutShaped } from "./timeout-shaped.js";
|
|
20
20
|
import { executionSignal } from "../run/execution-budget.js";
|
|
21
21
|
import { failureDisposition } from "../run/recovery.js";
|
|
22
|
-
import { dependencyLinkRefusal, preserveWorktree, producerFields, readCapacity, shGit, resolvedCapacity, sameCapacity, verificationProtocol } from "../run/git.js";
|
|
22
|
+
import { dependencyLinkRefusal, preserveWorktree, producerFields, readCapacity, reflogWitness, shGit, resolvedCapacity, sameCapacity, verificationProtocol } from "../run/git.js";
|
|
23
23
|
import { withJudgeInvocationEvidence } from "../run/journal.js";
|
|
24
24
|
import { computeVerificationIdentity, verificationIdentityKey, formatReusedRow, getVerdictStore, isInfraResult, resolveStateDir, reusedIdentity, } from "./cache.js";
|
|
25
25
|
const productionLoadProvider = () => loadavg()[0] ?? 0;
|
|
@@ -364,30 +364,36 @@ export async function reobserveTestFiles(worktree, testCmd, baseline, files, art
|
|
|
364
364
|
return r.meta?.recovery === undefined ? r
|
|
365
365
|
: { ...r, pass: false, meta: { ...r.meta, classification: "infra", infra: true, retryable: false, recoveryRefused: true } };
|
|
366
366
|
}
|
|
367
|
-
const SIGNAL_EXIT_RE = /\b(?:SIGTERM|SIGKILL|signal\s+(?:9|15)|exit(?:s|ed|\s+code)?\s+(?:137|143))\b/i;
|
|
368
367
|
const FAILURE_IDENTITY_RE = /\b(?:AssertionError|FAIL\s+\S|Tests?\s+\d+\s+failed|expected\s+.+\s+to\s+)\b/i;
|
|
369
368
|
/** D1: apply the daemon's signal-only rider before either battery cache read or write. Its onGate
|
|
370
369
|
* classification happens after persistence, too late to keep a scripted runner's non-verdict out.
|
|
371
370
|
* Keep named failures as work verdicts and preserve details for failure-policy fingerprinting.
|
|
372
371
|
* A baseline-forgiven "green" whose runner was signal-killed is the same non-verdict: a killed job
|
|
373
|
-
* completed no suite
|
|
374
|
-
*
|
|
375
|
-
*
|
|
376
|
-
*
|
|
377
|
-
*
|
|
372
|
+
* completed no suite. The termination receipt decides first: a signal-terminated job is killed whatever its
|
|
373
|
+
* details say, and a green stands only on a receipt showing a normal exit — a receiptless CACHED one (an
|
|
374
|
+
* older or planted entry) is unavailable proof, so a fresh job measures instead. A normal exit 1 can still
|
|
375
|
+
* be a kill (a wrapper reports its killed worker and exits 1), and a forgiven green's details never carry
|
|
376
|
+
* the runner's output, so this rider cannot see it: S19m4 — the shared forgiveness decision
|
|
377
|
+
* (baseline.ts freshFailures) reads kill text beside a forgiven pass itself, turns one into infra that is
|
|
378
|
+
* never cached, and marks the green it does publish `killTextRead`. A cached forgiven green without that
|
|
379
|
+
* marker was written by an engine that never read kill text, so it is refused here — a normal exit 1
|
|
380
|
+
* receipt included — and the job runs again. A fresh row is this invocation's own: every production
|
|
381
|
+
* runner attaches its receipt, and the manifest path's verdict already requires a clean exit
|
|
378
382
|
* (test-manifest.ts verifyManifestReport). A no-command skip ran nothing and claims none. */
|
|
379
383
|
function classifySignalOnlyTest(g, cached = false) {
|
|
380
384
|
const termination = g.evidenceReceipt?.termination.kind;
|
|
381
385
|
const exitCode = g.evidenceReceipt?.termination.exitCode;
|
|
382
386
|
const killed = termination === "signal" || exitCode === 137 || exitCode === 143 || (!g.pass && SIGNAL_EXIT_RE.test(g.details));
|
|
383
|
-
const
|
|
387
|
+
const killTextUnread = cached && Array.isArray(g.meta?.forgivenFingerprints) && g.meta.killTextRead !== true;
|
|
388
|
+
const unproven = g.pass && g.meta?.skipped !== true && (killTextUnread || termination !== "exit" && (cached || termination !== undefined));
|
|
384
389
|
if (g.gate !== "test" || g.meta?.infra === true || !(killed || unproven))
|
|
385
390
|
return;
|
|
386
391
|
const named = Array.isArray(g.meta?.failingTests) && g.meta.failingTests.length > 0;
|
|
387
392
|
if (!g.pass && (named || FAILURE_IDENTITY_RE.test(g.details)))
|
|
388
393
|
return;
|
|
389
394
|
g.pass = false;
|
|
390
|
-
g.meta = { ...g.meta, classification: "infra", infra: true, retryable: false,
|
|
395
|
+
g.meta = { ...g.meta, classification: "infra", infra: true, retryable: false,
|
|
396
|
+
kind: killed || (termination && termination !== "exit") ? "signal-exit" : termination ? "kill-text-unread" : "no-exit-receipt" };
|
|
391
397
|
}
|
|
392
398
|
/** OBS-1151: a criterion's comparable subject — its canonical text, the task's declared bounds and the
|
|
393
399
|
* operator context. The cited files' blobs are compared separately, over the union of both citations. */
|
|
@@ -431,6 +437,49 @@ export async function judgeContradictions(worktree, head, fresh, priors) {
|
|
|
431
437
|
}
|
|
432
438
|
return found;
|
|
433
439
|
}
|
|
440
|
+
const SUBJECT_LEG_TEXT = {
|
|
441
|
+
moved: "moved", restored: "moved and restored", witness: "could not be witnessed", unreadable: "is unreadable",
|
|
442
|
+
};
|
|
443
|
+
/** ANL-023 §7.4 S0, read-only: HEAD's symbolic state and its reflog W(HEAD) — plus, when attached, its branch's
|
|
444
|
+
* W(R) — each valid for the sampled `commit`. A move made inside the checkout writes both logs, a branch move from
|
|
445
|
+
* another worktree only the branch's, a same-commit retarget only HEAD's, so both are kept. */
|
|
446
|
+
async function openSubjectWitness(dir, commit) {
|
|
447
|
+
const sym = await shGit("git symbolic-ref -q HEAD", dir);
|
|
448
|
+
if (sym.code !== 0 && sym.code !== 1)
|
|
449
|
+
return { leg: "unreadable" };
|
|
450
|
+
const ref = sym.code === 0 ? sym.stdout.trim() : undefined;
|
|
451
|
+
const logs = [];
|
|
452
|
+
for (const name of ref ? ["HEAD", ref] : ["HEAD"]) {
|
|
453
|
+
const w = await reflogWitness(dir, name);
|
|
454
|
+
if (w.code !== 0 || w.lines[0] !== commit)
|
|
455
|
+
return { leg: "witness" };
|
|
456
|
+
logs.push(w.lines.join("\n"));
|
|
457
|
+
}
|
|
458
|
+
return { ref, logs };
|
|
459
|
+
}
|
|
460
|
+
/** ANL-023 §7.4, after the seat returns: HEAD = `commit`, its symbolic state and referent unchanged, and both logs
|
|
461
|
+
* line for line as S0 found them — or the leg that changed, with the HEAD it found. */
|
|
462
|
+
async function adjudicationSubjectChange(dir, commit, s0) {
|
|
463
|
+
const head = await shGit("git rev-parse HEAD", dir);
|
|
464
|
+
if (head.code !== 0)
|
|
465
|
+
return { leg: "unreadable", found: "unreadable" };
|
|
466
|
+
const found = head.stdout.trim();
|
|
467
|
+
if (found !== commit)
|
|
468
|
+
return { leg: "moved", found };
|
|
469
|
+
const sym = await shGit("git symbolic-ref -q HEAD", dir);
|
|
470
|
+
if (sym.code !== 0 && sym.code !== 1)
|
|
471
|
+
return { leg: "unreadable", found: "unreadable" };
|
|
472
|
+
if ((sym.code === 0 ? sym.stdout.trim() : undefined) !== s0.ref)
|
|
473
|
+
return { leg: "moved", found };
|
|
474
|
+
for (const [i, name] of (s0.ref ? ["HEAD", s0.ref] : ["HEAD"]).entries()) {
|
|
475
|
+
const w = await reflogWitness(dir, name);
|
|
476
|
+
if (w.code !== 0)
|
|
477
|
+
return { leg: "unreadable", found: "unreadable" };
|
|
478
|
+
if (w.lines.join("\n") !== s0.logs[i])
|
|
479
|
+
return { leg: "restored", found };
|
|
480
|
+
}
|
|
481
|
+
return undefined;
|
|
482
|
+
}
|
|
434
483
|
export async function runGates(task, ctx) {
|
|
435
484
|
const results = [];
|
|
436
485
|
const evidence = {
|
|
@@ -1141,6 +1190,11 @@ export async function runGates(task, ctx) {
|
|
|
1141
1190
|
// reused. Only a criterion that REVERSES the newest prior ruling on the same subject key over
|
|
1142
1191
|
// identical cited blobs needs a second, distinct judge; agreement stands (a sound FAIL included),
|
|
1143
1192
|
// and a split, no distinct eligible seat or an unreadable adjudication parks for the operator.
|
|
1193
|
+
// 2.8.1 T4 (ANL-023 §7.4): the record names the commit it judged, under a validated subject witness. Only when
|
|
1194
|
+
// a second seat is about to run, the subject witness (HEAD's reflog and, when attached, its branch's reflog) is
|
|
1195
|
+
// validated for the sampled HEAD before the second seat runs, read-only, and re-read after it returns with HEAD
|
|
1196
|
+
// and its symbolic state; a move, a move-and-restore or an unwitnessable (or unreadable) subject parks infra with
|
|
1197
|
+
// no record stamped and no worker charge.
|
|
1144
1198
|
const adjudicate = async (fresh) => {
|
|
1145
1199
|
const primary = String(fresh.meta?.judge ?? channelKey({ adapter: ctx.cfg.judge.adapter, model: ctx.cfg.judge.model }));
|
|
1146
1200
|
const head = await shGit("git rev-parse HEAD", ctx.worktree);
|
|
@@ -1173,7 +1227,19 @@ export async function runGates(task, ctx) {
|
|
|
1173
1227
|
const seatVia = via
|
|
1174
1228
|
? { driver: via.driver, keep: via.keep, onSlot: via.onSlot, name: via.nameFor("judge", seatAdapter.id) + "-r2", label: via.labelFor("judge") }
|
|
1175
1229
|
: undefined;
|
|
1230
|
+
const subjectPark = (leg, found, ran) => ({
|
|
1231
|
+
gate: "acceptance", pass: false,
|
|
1232
|
+
details: `the adjudication subject ${SUBJECT_LEG_TEXT[leg]}: sampled ${commit.slice(0, 12)}, found ${found.slice(0, 12)} (${leg}); parked for an operator ruling, no worker charge`,
|
|
1233
|
+
meta: { classification: "infra", infra: true, retryable: false, cause: "subject-moved", judge: primary,
|
|
1234
|
+
adjudication: { primary, ...(ran ? { adjudicator: ran } : {}), sampled: commit, found, leg } },
|
|
1235
|
+
});
|
|
1236
|
+
const s0 = await openSubjectWitness(ctx.worktree, commit);
|
|
1237
|
+
if ("leg" in s0)
|
|
1238
|
+
return subjectPark(s0.leg, s0.leg === "unreadable" ? "unreadable" : commit);
|
|
1176
1239
|
const second = await invokeJudge(seatAdapter, seat.model, seatVia, configuredEffort(ctx.cfg, seat));
|
|
1240
|
+
const changed = await adjudicationSubjectChange(ctx.worktree, commit, s0);
|
|
1241
|
+
if (changed)
|
|
1242
|
+
return subjectPark(changed.leg, changed.found, adjudicator);
|
|
1177
1243
|
const rulings = Array.isArray(second.meta?.judgment) ? second.meta.judgment : undefined;
|
|
1178
1244
|
// A citation-less ruling cannot be compared, so it confirms nothing (invented evidence is already unparseable,
|
|
1179
1245
|
// and an internally inconsistent verdict carries no judgment rows at all).
|
|
@@ -1193,7 +1259,7 @@ export async function runGates(task, ctx) {
|
|
|
1193
1259
|
// details. The v1.1 badReviewers precedent's TIMING can't transfer: its failover lands on the NEXT
|
|
1194
1260
|
// worker attempt — exactly what this fix forbids; only its meta-carries-channel pattern is mirrored.
|
|
1195
1261
|
// Straight-line single `if` — NO loop/counter/knob: exactly-once by construction (a knob is a
|
|
1196
|
-
// fail-closed weakening vector); a second garbage verdict fails the gate closed
|
|
1262
|
+
// fail-closed weakening vector); a second garbage verdict fails the gate closed as terminal infra (S23-F11).
|
|
1197
1263
|
// T6: exclusion mirrors consult reroute semantics — the flaked channel's whole adapter is banned, not
|
|
1198
1264
|
// just its exact channel key, so an outage window cannot re-select the vendor being routed around.
|
|
1199
1265
|
// If no other adapter is live, the exclusion degrades to a channel-level reroute within the same
|
|
@@ -1226,8 +1292,11 @@ export async function runGates(task, ctx) {
|
|
|
1226
1292
|
}
|
|
1227
1293
|
// OBS-1168(b): the re-routed seat could not launch either — no seat produced a verdict, so this is
|
|
1228
1294
|
// an infra park over whatever the deterministic gates proved, never a charge against the worker.
|
|
1229
|
-
|
|
1295
|
+
// S23-F11: the same holds for a retry whose verdict is still unparseable: two seats delivered no readable
|
|
1296
|
+
// verdict, which judges nothing about the worker's diff, so the row is terminal infra, never a charged red.
|
|
1297
|
+
if (a.meta?.cause === "seat-launch-failed" || (a.meta?.judgeRetry !== undefined && a.meta.unparseable === true)) {
|
|
1230
1298
|
a = { ...a, meta: { ...a.meta, classification: "infra", infra: true, retryable: false } };
|
|
1299
|
+
}
|
|
1231
1300
|
else if (!cancelled && Array.isArray(a.meta?.judgment))
|
|
1232
1301
|
a = await adjudicate(a);
|
|
1233
1302
|
// No dispatch, no key: a deterministic-oracle round writes no `invocations` field rather than an
|
package/dist/run/daemon.d.ts
CHANGED
|
@@ -5,8 +5,9 @@ import { type ExecutorDriver, type Slot } from "../drivers/types.js";
|
|
|
5
5
|
import { type Baseline, type BaselineProvenance, type GateEvidenceOptions } from "../gates/baseline.js";
|
|
6
6
|
import type { GateResult } from "../gates/types.js";
|
|
7
7
|
import { type RunGraph, type Task } from "../graph/schema.js";
|
|
8
|
-
import { type PreserveProducer } from "./git.js";
|
|
8
|
+
import { type PreserveProducer, type RunCapacity } from "./git.js";
|
|
9
9
|
import { Journal, type JournalEvent } from "./journal.js";
|
|
10
|
+
import { type IntegrationLeg, type IntegrationRefState, type TipVerifyResult } from "./merge.js";
|
|
10
11
|
export declare function closeLiveSlot(liveSlots: Set<Slot>, driver: Pick<ExecutorDriver, "close">, slot: Slot): Promise<void>;
|
|
11
12
|
export declare function setContactUnreadableDeadlineMsForTests(ms: number): void;
|
|
12
13
|
export declare function resetContactUnreadableDeadlineMsForTests(): void;
|
|
@@ -246,23 +247,86 @@ export interface TipProof {
|
|
|
246
247
|
export declare function runEndTipProof(events: readonly JournalEvent[]): TipProof;
|
|
247
248
|
/** The close notification's statement of the proof — one clause per kind. */
|
|
248
249
|
export declare function formatTipProof(p: TipProof): string;
|
|
250
|
+
/** 2.8.1 T1 (ANL-023 §7.1): what run end checks the integration ref against; `expected` absent = the opening read. */
|
|
251
|
+
export interface TipIdentity {
|
|
252
|
+
repo: string;
|
|
253
|
+
branch: string;
|
|
254
|
+
expected?: string;
|
|
255
|
+
}
|
|
256
|
+
export type IdentityLeg = IntegrationLeg | "setup" | "witness" | "checkout";
|
|
257
|
+
type DeferredVerdict = NonNullable<TipVerifyResult["deferredVerdict"]>;
|
|
258
|
+
/** One close under an identity: `expected` is what the closing check must find; `identityFailed` skips it. */
|
|
259
|
+
export interface TipClose {
|
|
260
|
+
failed: boolean;
|
|
261
|
+
expected?: string;
|
|
262
|
+
identityFailed: boolean;
|
|
263
|
+
deferred: DeferredVerdict[];
|
|
264
|
+
}
|
|
265
|
+
interface TipVerifyOptions {
|
|
266
|
+
lastMergedTask?: string;
|
|
267
|
+
baseline?: Baseline;
|
|
268
|
+
signal?: AbortSignal;
|
|
269
|
+
evidence?: GateEvidenceOptions;
|
|
270
|
+
}
|
|
271
|
+
/**
|
|
272
|
+
* 2.8.1 T3 (ANL-023 §7.3): anchor A of a run whose run-start carries `integrationAnchor: "journal"` — the newest merge
|
|
273
|
+
* row's commit (that row must carry a `from`), else the run-start base; any of them not an object id is unreadable.
|
|
274
|
+
* No marker: undefined (legacy-ref). Resume and approve both read it.
|
|
275
|
+
*/
|
|
276
|
+
export declare function integrationAnchor(events: readonly JournalEvent[]): {
|
|
277
|
+
anchor: string;
|
|
278
|
+
} | {
|
|
279
|
+
unreadable: string;
|
|
280
|
+
} | undefined;
|
|
281
|
+
/** The ref legs' details: the leg, both commits, the symbolic target and the repair text. */
|
|
282
|
+
export declare function identityDetails(leg: IntegrationLeg, state: IntegrationRefState, branch: string, runId: string, expected: string | undefined): string;
|
|
283
|
+
/**
|
|
284
|
+
* The one closed outcome row for every identity leg: an integration `tip-verify-failed` (preceded by a start row
|
|
285
|
+
* with no gates when this close appended none), which runEndTipProof and every consumer already read as failure.
|
|
286
|
+
*/
|
|
287
|
+
export declare function appendIdentityFailure(journal: Journal, f: {
|
|
288
|
+
started: boolean;
|
|
289
|
+
branch: string;
|
|
290
|
+
expected?: string;
|
|
291
|
+
leg: IdentityLeg;
|
|
292
|
+
details: string;
|
|
293
|
+
state?: IntegrationRefState;
|
|
294
|
+
cmdHash: string;
|
|
295
|
+
capacity: RunCapacity;
|
|
296
|
+
infra?: boolean;
|
|
297
|
+
}): void;
|
|
298
|
+
/** O: I(expected) — or, with no expected value, the ref must be regular and its commit becomes the expected. */
|
|
299
|
+
export declare function openingIdentity(identity: TipIdentity, journal: Journal): Promise<{
|
|
300
|
+
ok: true;
|
|
301
|
+
expected: string;
|
|
302
|
+
} | {
|
|
303
|
+
ok: false;
|
|
304
|
+
leg: IntegrationLeg;
|
|
305
|
+
state: IntegrationRefState;
|
|
306
|
+
expected?: string;
|
|
307
|
+
details: string;
|
|
308
|
+
}>;
|
|
249
309
|
/**
|
|
250
310
|
* OBS-34's strict tip verify, but it stops re-paying for an unmoved tip (~334m corpus-wide; 69.5m in
|
|
251
311
|
* one park-heavy run whose 18 resume cycles merged nothing new). The verify journals the SHA it
|
|
252
312
|
* verified and the hash of the command set, so a later run-end can recognize the same verified state:
|
|
253
|
-
*
|
|
254
|
-
* `tip-verify-cached` and skip. ANY doubt — moved
|
|
255
|
-
* from that cycle's green set, a failure recorded in it, a cycle older than the last one —
|
|
256
|
-
* full verify.
|
|
257
|
-
*
|
|
258
|
-
*
|
|
313
|
+
* the expected commit equals the LAST green verified SHA and the commands are unchanged → journal
|
|
314
|
+
* `tip-verify-cached` and skip, with no checkout. ANY doubt — moved tip, changed commands, a gate
|
|
315
|
+
* missing from that cycle's green set, a failure recorded in it, a cycle older than the last one —
|
|
316
|
+
* runs the full verify. 2.8.1 T1 (ANL-023 §7.1): with `identity` (the daemon always passes it) run end
|
|
317
|
+
* verifies a fresh detached checkout of the expected commit under a validated HEAD reflog, never the
|
|
318
|
+
* integration checkout; it checks tracked content after the battery (the battery-end check also proves
|
|
319
|
+
* the checkout's HEAD and its reflog unchanged), defers verdict-store writes to the caller, and the
|
|
320
|
+
* caller closes on an identity check taken after the approval serialization with no await before the
|
|
321
|
+
* run-end row. The opening check reads the ref before the cycle decision, so a cached green is carried
|
|
322
|
+
* only for the commit the ref holds now. A caller without `identity` keeps the integration checkout's
|
|
323
|
+
* head and clean tree as the cache key, exactly as before.
|
|
324
|
+
* Returns whether the tip is failing (without `identity`) or the close's TipClose (with it).
|
|
259
325
|
*/
|
|
260
|
-
export declare function verifyIntegrationTipCached(intWt: string, commands: Record<string, string>, journal: Journal, opts
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
evidence?: GateEvidenceOptions;
|
|
265
|
-
}): Promise<boolean>;
|
|
326
|
+
export declare function verifyIntegrationTipCached(intWt: string, commands: Record<string, string>, journal: Journal, opts: TipVerifyOptions & {
|
|
327
|
+
identity: TipIdentity;
|
|
328
|
+
}): Promise<TipClose>;
|
|
329
|
+
export declare function verifyIntegrationTipCached(intWt: string, commands: Record<string, string>, journal: Journal, opts?: TipVerifyOptions): Promise<boolean>;
|
|
266
330
|
type WorkerProcessTree = "empty" | "running" | "unmeasurable";
|
|
267
331
|
export declare function observeWorkerProcessTree(marker: string, cwd: string): Promise<WorkerProcessTree>;
|
|
268
332
|
type SuitePidProbe = (pid: number) => number | undefined;
|