@deftai/directive-core 0.102.0 → 0.104.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/dist/authz/classify.js +167 -4
- package/dist/check/gate-lists.d.ts +3 -2
- package/dist/check/gate-lists.js +5 -2
- package/dist/check/index.d.ts +1 -0
- package/dist/check/index.js +1 -0
- package/dist/check/session-completed-ac.d.ts +39 -0
- package/dist/check/session-completed-ac.js +198 -0
- package/dist/doctor/main.js +12 -7
- package/dist/fs/contained-write.js +2 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/init-deposit/hygiene.d.ts +7 -1
- package/dist/init-deposit/hygiene.js +11 -3
- package/dist/init-deposit/scaffold.d.ts +12 -0
- package/dist/init-deposit/scaffold.js +81 -8
- package/dist/intake/clause-derivation.d.ts +37 -0
- package/dist/intake/clause-derivation.js +207 -0
- package/dist/intake/index.d.ts +1 -0
- package/dist/intake/index.js +1 -0
- package/dist/intake/issue-ingest.js +2 -38
- package/dist/preflight/evaluate.d.ts +5 -0
- package/dist/preflight/evaluate.js +14 -0
- package/dist/preflight/index.d.ts +1 -1
- package/dist/product-first-done-gate/empty-resolution.d.ts +1 -1
- package/dist/product-first-done-gate/empty-resolution.js +1 -1
- package/dist/product-first-done-gate/evaluate.d.ts +29 -0
- package/dist/product-first-done-gate/evaluate.js +110 -23
- package/dist/product-first-done-gate/index.d.ts +1 -1
- package/dist/product-first-done-gate/index.js +1 -1
- package/dist/run-summary/emit.d.ts +42 -2
- package/dist/run-summary/emit.js +250 -25
- package/dist/run-summary/index.d.ts +1 -1
- package/dist/run-summary/index.js +1 -1
- package/dist/run-summary/share.d.ts +1 -1
- package/dist/run-summary/share.js +2 -2
- package/dist/run-summary/types.d.ts +10 -3
- package/dist/scope/acceptance-activate-gate.d.ts +1 -1
- package/dist/scope/acceptance-activate-gate.js +4 -4
- package/dist/scope/acceptance-evidence.d.ts +15 -0
- package/dist/scope/acceptance-evidence.js +39 -0
- package/dist/scope/capacity-stamp.d.ts +2 -0
- package/dist/scope/capacity-stamp.js +4 -0
- package/dist/scope/delivery-evidence.d.ts +6 -0
- package/dist/scope/delivery-evidence.js +17 -0
- package/dist/scope/transition.js +66 -4
- package/dist/session/ceremony-dial-evidence.d.ts +42 -0
- package/dist/session/ceremony-dial-evidence.js +194 -0
- package/dist/session/index.d.ts +1 -0
- package/dist/session/index.js +1 -0
- package/dist/session/session-start.js +21 -2
- package/dist/slice/existing.js +12 -1
- package/dist/slice/record.d.ts +8 -5
- package/dist/slice/record.js +21 -13
- package/dist/telemetry-coverage/evaluate.d.ts +42 -0
- package/dist/telemetry-coverage/evaluate.js +148 -0
- package/dist/telemetry-coverage/fake-trial.d.ts +45 -0
- package/dist/telemetry-coverage/fake-trial.js +194 -0
- package/dist/telemetry-coverage/index.d.ts +5 -0
- package/dist/telemetry-coverage/index.js +5 -0
- package/dist/telemetry-coverage/kinds.d.ts +19 -0
- package/dist/telemetry-coverage/kinds.js +52 -0
- package/dist/telemetry-coverage/scan-callers.d.ts +25 -0
- package/dist/telemetry-coverage/scan-callers.js +168 -0
- package/dist/vbrief-reconcile/index.d.ts +2 -0
- package/dist/vbrief-reconcile/index.js +1 -0
- package/dist/vbrief-reconcile/origin-freshness.d.ts +44 -0
- package/dist/vbrief-reconcile/origin-freshness.js +221 -0
- package/dist/verify-ac/evaluate.d.ts +18 -0
- package/dist/verify-ac/evaluate.js +24 -2
- package/dist/verify-ac/index.d.ts +1 -1
- package/dist/verify-ac/index.js +1 -1
- package/dist/verify-source/index.d.ts +1 -0
- package/dist/verify-source/index.js +1 -0
- package/package.json +3 -3
|
@@ -8,7 +8,8 @@
|
|
|
8
8
|
* floor, empty resolution is soft_empty — not a green run (#3334).
|
|
9
9
|
*/
|
|
10
10
|
import { existsSync, readFileSync } from "node:fs";
|
|
11
|
-
import { basename, resolve } from "node:path";
|
|
11
|
+
import { basename, isAbsolute, relative, resolve } from "node:path";
|
|
12
|
+
import { emitAcceptanceStampFromPlan } from "../intake/clause-derivation.js";
|
|
12
13
|
import { evaluateLiteralAcceptanceFromPlan, runLiteralAcceptanceCommands, } from "../literal-acceptance/index.js";
|
|
13
14
|
import { ENV_RUN_SUMMARY_PATH, RunSummaryEmitter, } from "../run-summary/index.js";
|
|
14
15
|
import { maybeBankOnAcPass } from "../session/ac-pass-banking.js";
|
|
@@ -26,6 +27,12 @@ function asRecord(value) {
|
|
|
26
27
|
* Evaluate product AC from an in-memory plan.
|
|
27
28
|
*/
|
|
28
29
|
export function evaluateVerifyAcFromPlan(plan, options = {}) {
|
|
30
|
+
const planId = typeof plan.id === "string" && plan.id.trim() ? plan.id.trim() : null;
|
|
31
|
+
const optionsWithScope = {
|
|
32
|
+
...options,
|
|
33
|
+
oracleScopeKey: options.oracleScopeKey?.trim() || planId || null,
|
|
34
|
+
observedAcceptance: options.observedAcceptance !== undefined ? options.observedAcceptance : plan.acceptance,
|
|
35
|
+
};
|
|
29
36
|
const acceptance = readPlanAcceptance(plan);
|
|
30
37
|
const schemaErrors = validatePlanAcceptance(plan.acceptance ?? acceptance);
|
|
31
38
|
// Only hard-fail schema when an explicit plan.acceptance object exists.
|
|
@@ -41,9 +48,9 @@ export function evaluateVerifyAcFromPlan(plan, options = {}) {
|
|
|
41
48
|
acceptance,
|
|
42
49
|
resolution: "config",
|
|
43
50
|
resolvedCommandCount: 0,
|
|
44
|
-
},
|
|
51
|
+
}, optionsWithScope);
|
|
45
52
|
}
|
|
46
|
-
const projectRoot = resolve(
|
|
53
|
+
const projectRoot = resolve(optionsWithScope.projectRoot ?? process.cwd());
|
|
47
54
|
// Prefer shared literal-acceptance path so safety / promotion rules stay one place.
|
|
48
55
|
// Empty plan.acceptance.commands still consults the #3267 rejected ledger
|
|
49
56
|
// (Greptile P1: rejected stated AC must never soft-pass).
|
|
@@ -51,12 +58,13 @@ export function evaluateVerifyAcFromPlan(plan, options = {}) {
|
|
|
51
58
|
// if the literal ledger is empty of executables.
|
|
52
59
|
const base = evaluateLiteralAcceptanceFromPlan(plan, {
|
|
53
60
|
projectRoot,
|
|
54
|
-
runner:
|
|
61
|
+
runner: optionsWithScope.runner,
|
|
55
62
|
// Check composition uses the stamped ledger only. Re-scanning issue prose
|
|
56
63
|
// during `task check` re-captures backtick `verify:ac` lines as rejected
|
|
57
64
|
// and deadlocks the graph (#3323 / #3284 check-integrated).
|
|
58
|
-
captureFromNarratives:
|
|
59
|
-
|
|
65
|
+
captureFromNarratives: optionsWithScope.captureFromNarratives ??
|
|
66
|
+
(optionsWithScope.checkIntegrated === true ? false : undefined),
|
|
67
|
+
quiet: optionsWithScope.quiet,
|
|
60
68
|
});
|
|
61
69
|
// When literal path had nothing executable but plan.acceptance has derived commands,
|
|
62
70
|
// run them directly with source=explicit semantics.
|
|
@@ -64,7 +72,7 @@ export function evaluateVerifyAcFromPlan(plan, options = {}) {
|
|
|
64
72
|
base.runs.length === 0 &&
|
|
65
73
|
acceptance.commands.length > 0 &&
|
|
66
74
|
(acceptance.source_rung === "derived" || acceptance.source_rung === "project_floor")) {
|
|
67
|
-
const runner =
|
|
75
|
+
const runner = optionsWithScope.runner;
|
|
68
76
|
const direct = runLiteralAcceptanceCommands(acceptance.commands.map((c) => ({
|
|
69
77
|
command: c.command,
|
|
70
78
|
cwd: c.cwd ?? null,
|
|
@@ -72,17 +80,21 @@ export function evaluateVerifyAcFromPlan(plan, options = {}) {
|
|
|
72
80
|
expectedExitCode: c.expectedExitCode ?? 0,
|
|
73
81
|
source: "explicit",
|
|
74
82
|
sourceSpan: "plan.acceptance.commands",
|
|
75
|
-
})), {
|
|
76
|
-
|
|
83
|
+
})), {
|
|
84
|
+
projectRoot,
|
|
85
|
+
runner,
|
|
86
|
+
allowTaskStatement: optionsWithScope.allowTaskStatement,
|
|
87
|
+
});
|
|
88
|
+
return applyOracle(annotate(direct, acceptance, optionsWithScope.quiet), optionsWithScope);
|
|
77
89
|
}
|
|
78
90
|
// Check composition: mid-story unpromoted capture-only may soft-pass so the
|
|
79
91
|
// framework graph is not deadlocked before agents promote peers.
|
|
80
92
|
// Greptile P1 #3284: safety-rejected stated commands NEVER soft-pass — they
|
|
81
93
|
// block product verification until a safe alternative is promoted.
|
|
82
|
-
if (
|
|
94
|
+
if (optionsWithScope.checkIntegrated === true && !base.ok && base.runs.length === 0) {
|
|
83
95
|
const hasRejected = (base.rejected?.length ?? 0) > 0;
|
|
84
96
|
if (hasRejected) {
|
|
85
|
-
return applyOracle(annotate(base, acceptance,
|
|
97
|
+
return applyOracle(annotate(base, acceptance, optionsWithScope.quiet), optionsWithScope);
|
|
86
98
|
}
|
|
87
99
|
const unpromoted = /capture-only|task_statement|no matching agent-promoted/i.test(base.message) ||
|
|
88
100
|
(base.commands.length > 0 && base.commands.every((c) => c.source === "task_statement"));
|
|
@@ -90,7 +102,7 @@ export function evaluateVerifyAcFromPlan(plan, options = {}) {
|
|
|
90
102
|
return applyOracle({
|
|
91
103
|
ok: true,
|
|
92
104
|
code: 0,
|
|
93
|
-
message:
|
|
105
|
+
message: optionsWithScope.quiet
|
|
94
106
|
? ""
|
|
95
107
|
: `verify:ac advisory (#3284 check-integrated): no executable AC peers yet ` +
|
|
96
108
|
`(capture-only / empty). Done-gate standalone verify:ac still requires promotion. ` +
|
|
@@ -110,10 +122,10 @@ export function evaluateVerifyAcFromPlan(plan, options = {}) {
|
|
|
110
122
|
rejectedCount: base.rejected?.length ?? 0,
|
|
111
123
|
}),
|
|
112
124
|
resolvedCommandCount: base.commands.length,
|
|
113
|
-
},
|
|
125
|
+
}, optionsWithScope);
|
|
114
126
|
}
|
|
115
127
|
}
|
|
116
|
-
return applyOracle(annotate(base, acceptance,
|
|
128
|
+
return applyOracle(annotate(base, acceptance, optionsWithScope.quiet), optionsWithScope);
|
|
117
129
|
}
|
|
118
130
|
function classifyResolution(input) {
|
|
119
131
|
if (input.resolution !== undefined) {
|
|
@@ -171,9 +183,11 @@ function acceptanceOutcomeOf(result) {
|
|
|
171
183
|
return "soft_empty";
|
|
172
184
|
if (result.resolution === "fail")
|
|
173
185
|
return "fail";
|
|
174
|
-
|
|
186
|
+
if (result.resolution === "config")
|
|
187
|
+
return "config-error";
|
|
188
|
+
return "soft-missing";
|
|
175
189
|
}
|
|
176
|
-
function
|
|
190
|
+
function emitAcceptanceObservedStamp(options, projectRoot) {
|
|
177
191
|
if (options.env === undefined) {
|
|
178
192
|
return;
|
|
179
193
|
}
|
|
@@ -181,8 +195,14 @@ function emitAcceptanceOutcome(result, options, projectRoot) {
|
|
|
181
195
|
if (dest === undefined || dest.trim().length === 0) {
|
|
182
196
|
return;
|
|
183
197
|
}
|
|
184
|
-
|
|
185
|
-
|
|
198
|
+
emitAcceptanceStampFromPlan(projectRoot, { acceptance: options.observedAcceptance }, options.env);
|
|
199
|
+
}
|
|
200
|
+
function emitAcceptanceOutcome(result, options, projectRoot) {
|
|
201
|
+
if (options.env === undefined) {
|
|
202
|
+
return;
|
|
203
|
+
}
|
|
204
|
+
const dest = options.env[ENV_RUN_SUMMARY_PATH];
|
|
205
|
+
if (dest === undefined || dest.trim().length === 0) {
|
|
186
206
|
return;
|
|
187
207
|
}
|
|
188
208
|
try {
|
|
@@ -194,7 +214,7 @@ function emitAcceptanceOutcome(result, options, projectRoot) {
|
|
|
194
214
|
});
|
|
195
215
|
emitter.emitAcceptance({
|
|
196
216
|
resolved_command_count: result.resolvedCommandCount,
|
|
197
|
-
outcome,
|
|
217
|
+
outcome: acceptanceOutcomeOf(result),
|
|
198
218
|
source_rung: result.sourceRung,
|
|
199
219
|
none_stated: result.noneStated,
|
|
200
220
|
clause_count: result.clauseOutcomes?.length,
|
|
@@ -208,6 +228,43 @@ function emitAcceptanceOutcome(result, options, projectRoot) {
|
|
|
208
228
|
// fail-open
|
|
209
229
|
}
|
|
210
230
|
}
|
|
231
|
+
/** Outcome on every terminal path; stamp from observed plan.acceptance (#3355). */
|
|
232
|
+
function emitAcceptanceTelemetry(result, options, projectRoot) {
|
|
233
|
+
emitAcceptanceObservedStamp(options, projectRoot);
|
|
234
|
+
emitAcceptanceOutcome(result, options, projectRoot);
|
|
235
|
+
}
|
|
236
|
+
/**
|
|
237
|
+
* CLI-only early returns that never reach evaluate still emit an acceptance
|
|
238
|
+
* outcome so field streams see config-error / soft-missing (#3355).
|
|
239
|
+
*/
|
|
240
|
+
export function emitVerifyAcTerminalOutcome(input) {
|
|
241
|
+
emitAcceptanceOutcome({
|
|
242
|
+
ok: input.outcome !== "config-error" && input.outcome !== "fail",
|
|
243
|
+
code: input.outcome === "config-error" ? 2 : input.outcome === "fail" ? 1 : 0,
|
|
244
|
+
message: "",
|
|
245
|
+
commands: [],
|
|
246
|
+
runs: [],
|
|
247
|
+
sourceRung: input.sourceRung ?? "project_floor",
|
|
248
|
+
noneStated: input.noneStated ?? true,
|
|
249
|
+
acceptance: {
|
|
250
|
+
commands: [],
|
|
251
|
+
none_stated: input.noneStated ?? true,
|
|
252
|
+
source_rung: input.sourceRung ?? "project_floor",
|
|
253
|
+
},
|
|
254
|
+
resolution: input.outcome === "config-error"
|
|
255
|
+
? "config"
|
|
256
|
+
: input.outcome === "soft-missing"
|
|
257
|
+
? "skipped"
|
|
258
|
+
: input.outcome === "fail"
|
|
259
|
+
? "fail"
|
|
260
|
+
: input.outcome === "soft_empty"
|
|
261
|
+
? "soft_empty"
|
|
262
|
+
: input.outcome === "verified-pass"
|
|
263
|
+
? "verified-pass"
|
|
264
|
+
: "empty-pass",
|
|
265
|
+
resolvedCommandCount: 0,
|
|
266
|
+
}, { projectRoot: input.projectRoot, env: input.env }, resolve(input.projectRoot));
|
|
267
|
+
}
|
|
211
268
|
function applyClauseWalk(result, options) {
|
|
212
269
|
const clauses = result.acceptance.clauses ?? [];
|
|
213
270
|
if (clauses.length === 0 || result.resolution === "config" || result.resolution === "skipped") {
|
|
@@ -242,6 +299,7 @@ function applyOracle(result, options) {
|
|
|
242
299
|
projectRoot,
|
|
243
300
|
runs: gated.runs,
|
|
244
301
|
env: options.env,
|
|
302
|
+
scopeKey: options.oracleScopeKey,
|
|
245
303
|
});
|
|
246
304
|
}
|
|
247
305
|
let next = gated;
|
|
@@ -257,7 +315,7 @@ function applyOracle(result, options) {
|
|
|
257
315
|
}
|
|
258
316
|
}
|
|
259
317
|
if (options.skipAcceptanceEmit !== true) {
|
|
260
|
-
|
|
318
|
+
emitAcceptanceTelemetry(next, options, projectRoot);
|
|
261
319
|
}
|
|
262
320
|
return next;
|
|
263
321
|
}
|
|
@@ -324,11 +382,40 @@ export function evaluateVerifyAcFromPath(xbriefPath, options = {}) {
|
|
|
324
382
|
if (plan === null) {
|
|
325
383
|
return applyOracle(configResult(`verify:ac: xBRIEF missing plan object: ${abs}`), options);
|
|
326
384
|
}
|
|
327
|
-
const
|
|
328
|
-
|
|
329
|
-
|
|
385
|
+
const projectRoot = resolve(options.projectRoot ?? process.cwd());
|
|
386
|
+
// Path-relative keys stay unique across xbrief/ vs vbrief/ and duplicate plan.id (#3337 Greptile).
|
|
387
|
+
const oracleScopeKey = options.oracleScopeKey?.trim() || resolveOracleScopeKey(plan, abs, projectRoot);
|
|
388
|
+
const emitOptions = {
|
|
389
|
+
...options,
|
|
390
|
+
oracleScopeKey,
|
|
391
|
+
observedAcceptance: plan.acceptance,
|
|
392
|
+
};
|
|
393
|
+
const result = evaluateVerifyAcFromPlan(plan, {
|
|
394
|
+
...emitOptions,
|
|
395
|
+
skipAcceptanceEmit: true,
|
|
396
|
+
});
|
|
397
|
+
const banked = maybeAttachAcPassBank(result, plan, abs, emitOptions);
|
|
398
|
+
emitAcceptanceTelemetry(banked, emitOptions, projectRoot);
|
|
330
399
|
return banked;
|
|
331
400
|
}
|
|
401
|
+
/**
|
|
402
|
+
* Unique product-oracle scope key for one active xBRIEF path (#3337).
|
|
403
|
+
* Relative path is always unique across active roots; plan.id alone is not
|
|
404
|
+
* (duplicate ids / same stem in xbrief+vbrief). Prefer `id@relPath` when both exist.
|
|
405
|
+
*/
|
|
406
|
+
export function resolveOracleScopeKey(plan, xbriefPath, projectRoot) {
|
|
407
|
+
const abs = resolve(xbriefPath);
|
|
408
|
+
const root = resolve(projectRoot);
|
|
409
|
+
let rel = relative(root, abs).replace(/\\/g, "/");
|
|
410
|
+
if (rel.length === 0 || rel.startsWith("..") || isAbsolute(rel)) {
|
|
411
|
+
rel = basename(abs);
|
|
412
|
+
}
|
|
413
|
+
const planId = typeof plan.id === "string" && plan.id.trim() ? plan.id.trim() : null;
|
|
414
|
+
if (planId !== null) {
|
|
415
|
+
return `${planId}@${rel}`;
|
|
416
|
+
}
|
|
417
|
+
return rel;
|
|
418
|
+
}
|
|
332
419
|
/**
|
|
333
420
|
* After executable AC pass, FINALIZE the banking checkpoint (#3285).
|
|
334
421
|
* Soft/advisory passes with zero runs do not bank. Fail-open on ledger errors.
|
|
@@ -7,6 +7,6 @@
|
|
|
7
7
|
export { attachPlanAcceptance, buildAcceptanceFromIntakeCapture, readPlanAcceptance, stampAcceptanceFromLiteralCapture, validatePlanAcceptance, } from "./acceptance.js";
|
|
8
8
|
export { applyProductFirstGateMode, isHygieneGate, isProductAcGate, type ProductFirstCheckModeResolution, type ResolveProductFirstCheckModeInput, resolveProductFirstCheckMode, } from "./check-mode.js";
|
|
9
9
|
export { EMPTY_AC_CAUSE, EMPTY_AC_OUTCOME, EMPTY_AC_REMEDY, formatSoftEmptyMessage, isEmptyAcResolution, isSoftEmptyAcText, projectHasSuiteFloor, type VerifyAcResolution, } from "./empty-resolution.js";
|
|
10
|
-
export { type EvaluateVerifyAcOptions, evaluateVerifyAcFromPath, evaluateVerifyAcFromPlan, isVerifyAcRequiredAtCeremonyDepth, type VerifyAcResult, } from "./evaluate.js";
|
|
10
|
+
export { type EvaluateVerifyAcOptions, emitVerifyAcTerminalOutcome, evaluateVerifyAcFromPath, evaluateVerifyAcFromPlan, isVerifyAcRequiredAtCeremonyDepth, resolveOracleScopeKey, type VerifyAcResult, } from "./evaluate.js";
|
|
11
11
|
export { type AcceptanceCommand, type AcSourceRung, ENV_CHECK_AC_ONLY, ENV_CHECK_MODE, ENV_HYGIENE_ADVISORY, HYGIENE_GATE_ID_PREFIXES, PLAN_ACCEPTANCE_KEY, type PlanAcceptance, PRODUCT_AC_GATE_ID, type ProductFirstCheckMode, } from "./types.js";
|
|
12
12
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -7,6 +7,6 @@
|
|
|
7
7
|
export { attachPlanAcceptance, buildAcceptanceFromIntakeCapture, readPlanAcceptance, stampAcceptanceFromLiteralCapture, validatePlanAcceptance, } from "./acceptance.js";
|
|
8
8
|
export { applyProductFirstGateMode, isHygieneGate, isProductAcGate, resolveProductFirstCheckMode, } from "./check-mode.js";
|
|
9
9
|
export { EMPTY_AC_CAUSE, EMPTY_AC_OUTCOME, EMPTY_AC_REMEDY, formatSoftEmptyMessage, isEmptyAcResolution, isSoftEmptyAcText, projectHasSuiteFloor, } from "./empty-resolution.js";
|
|
10
|
-
export { evaluateVerifyAcFromPath, evaluateVerifyAcFromPlan, isVerifyAcRequiredAtCeremonyDepth, } from "./evaluate.js";
|
|
10
|
+
export { emitVerifyAcTerminalOutcome, evaluateVerifyAcFromPath, evaluateVerifyAcFromPlan, isVerifyAcRequiredAtCeremonyDepth, resolveOracleScopeKey, } from "./evaluate.js";
|
|
11
11
|
export { ENV_CHECK_AC_ONLY, ENV_CHECK_MODE, ENV_HYGIENE_ADVISORY, HYGIENE_GATE_ID_PREFIXES, PLAN_ACCEPTANCE_KEY, PRODUCT_AC_GATE_ID, } from "./types.js";
|
|
12
12
|
//# sourceMappingURL=index.js.map
|
|
@@ -25,8 +25,27 @@ export interface EmitRunSummaryResult {
|
|
|
25
25
|
readonly line: RunSummaryLine | null;
|
|
26
26
|
readonly warning: boolean;
|
|
27
27
|
}
|
|
28
|
+
/** Owner token stored in `.seq.lock` so reclaim is not age-based (#3361). */
|
|
29
|
+
export interface SeqLockOwner {
|
|
30
|
+
readonly pid: number;
|
|
31
|
+
readonly nonce: string;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Reclaim `.seq.lock` only when the owner process is dead or the token is
|
|
35
|
+
* missing/unreadable/corrupt (unknown owner). Live holders are never stolen
|
|
36
|
+
* by mtime (#3361).
|
|
37
|
+
*/
|
|
38
|
+
export declare function tryReclaimSeqLock(lockPath: string): boolean;
|
|
39
|
+
/**
|
|
40
|
+
* Unlink `.seq.lock` only when the on-disk token still matches this holder
|
|
41
|
+
* (ownership-blind release must not delete a successor's lock).
|
|
42
|
+
*/
|
|
43
|
+
export declare function releaseSeqLockIfOwner(lockPath: string, owner: SeqLockOwner): boolean;
|
|
28
44
|
/**
|
|
29
|
-
* Stateful emitter: one instance
|
|
45
|
+
* Stateful emitter: one instance tracks seq and write-warning once.
|
|
46
|
+
* File destinations seed seq from the current JSONL line count so multiple
|
|
47
|
+
* CLI processes appending to one DEFT_RUN_SUMMARY_PATH share 1..N (#3350).
|
|
48
|
+
* Stdout destinations stay per-process (each constructor starts at 0).
|
|
30
49
|
*/
|
|
31
50
|
export declare class RunSummaryEmitter {
|
|
32
51
|
private seq;
|
|
@@ -41,6 +60,7 @@ export declare class RunSummaryEmitter {
|
|
|
41
60
|
private readonly writeStderr;
|
|
42
61
|
constructor(options: RunSummaryEmitterOptions);
|
|
43
62
|
getDestination(): RunSummaryDestination;
|
|
63
|
+
private buildLine;
|
|
44
64
|
emit(event: RunSummaryEventKind, payload: RunSummaryPayload): EmitRunSummaryResult;
|
|
45
65
|
emitSessionStart(payload: SessionStartRunSummaryPayload): EmitRunSummaryResult;
|
|
46
66
|
emitDialTransition(payload: DialTransitionRunSummaryPayload): EmitRunSummaryResult;
|
|
@@ -52,12 +72,32 @@ export declare class RunSummaryEmitter {
|
|
|
52
72
|
emitAcceptanceStamp(payload: AcceptanceStampRunSummaryPayload): EmitRunSummaryResult;
|
|
53
73
|
/** Emit the harness-supplied denominator when DEFT_TOTAL_TOOL_TURNS is set. */
|
|
54
74
|
emitKnownToolTurnDenominator(): EmitRunSummaryResult;
|
|
75
|
+
/**
|
|
76
|
+
* Always emit a session denominator when the destination is live (#3356).
|
|
77
|
+
* `emitKnownToolTurnDenominator` stays silent unless DEFT_TOTAL_TOOL_TURNS is
|
|
78
|
+
* set; this caller records host planned turns or the session:start CLI floor.
|
|
79
|
+
*/
|
|
80
|
+
emitSessionToolTurnDenominator(hostMaxTurns?: number | null): EmitRunSummaryResult;
|
|
55
81
|
}
|
|
56
82
|
/** Parse harness-supplied DEFT_TOTAL_TOOL_TURNS (integer > 0). Invalid/unset → omit. */
|
|
57
83
|
export declare function readEnvToolTurnDenominator(env: NodeJS.ProcessEnv): number | undefined;
|
|
84
|
+
/** Canonical host planned-turn budget recorded at session:start (#3356). */
|
|
85
|
+
export declare const ENV_MAX_TURNS_DENOMINATOR = "DEFT_MAX_TURNS";
|
|
86
|
+
/** session:start is one CLI invocation when no host/harness count is known (#3356). */
|
|
87
|
+
export declare const SESSION_START_CLI_INVOCATION_DENOMINATOR: 1;
|
|
88
|
+
/**
|
|
89
|
+
* Resolve the session tool/turn denominator (#3356).
|
|
90
|
+
*
|
|
91
|
+
* Prefer harness actuals (`DEFT_TOTAL_TOOL_TURNS`), then a host planned-turn
|
|
92
|
+
* budget (`DEFT_MAX_TURNS` or `hostMaxTurns` from the session:start descriptor),
|
|
93
|
+
* else this CLI invocation (1). An emitted proxy beats a perfect unused kind.
|
|
94
|
+
*/
|
|
95
|
+
export declare function resolveSessionToolTurnDenominator(env: NodeJS.ProcessEnv, hostMaxTurns?: number | null): number;
|
|
58
96
|
/**
|
|
59
97
|
* One-shot helper for call sites that do not hold an emitter (e.g. dial escalate).
|
|
60
|
-
* Still fail-open
|
|
98
|
+
* Still fail-open. File destinations seed seq from the existing JSONL line
|
|
99
|
+
* count so successive one-shot calls into the same path continue 1..N (#3350).
|
|
100
|
+
* Stdout destinations stay per-process (each call starts at seq=1).
|
|
61
101
|
*/
|
|
62
102
|
export declare function emitRunSummaryEvent(options: RunSummaryEmitterOptions & {
|
|
63
103
|
readonly event: RunSummaryEventKind;
|