@deftai/directive-core 0.98.1 → 0.100.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/actions.d.ts +6 -0
- package/dist/authz/actions.js +3 -0
- package/dist/authz/classify.js +401 -75
- package/dist/authz/decompose-apply.d.ts +67 -0
- package/dist/authz/decompose-apply.js +302 -0
- package/dist/authz/index.d.ts +3 -1
- package/dist/authz/index.js +3 -1
- package/dist/authz/store.d.ts +53 -0
- package/dist/authz/store.js +219 -1
- package/dist/authz/types.d.ts +19 -2
- package/dist/authz/types.js +5 -1
- package/dist/consumer-check-contract/evaluate.d.ts +40 -0
- package/dist/consumer-check-contract/evaluate.js +188 -3
- package/dist/consumer-check-contract/index.d.ts +1 -1
- package/dist/consumer-check-contract/index.js +1 -1
- package/dist/content-contracts/skills/greptile-detector.d.ts +42 -0
- package/dist/content-contracts/skills/greptile-detector.js +202 -4
- package/dist/decision/index.d.ts +17 -0
- package/dist/decision/index.js +35 -0
- package/dist/decision/list.d.ts +47 -0
- package/dist/decision/list.js +250 -0
- package/dist/decision/schema.d.ts +88 -0
- package/dist/decision/schema.js +293 -0
- package/dist/decision/write.d.ts +82 -0
- package/dist/decision/write.js +427 -0
- package/dist/doctor/checks.d.ts +44 -0
- package/dist/doctor/checks.js +428 -2
- package/dist/doctor/main.d.ts +6 -7
- package/dist/doctor/main.js +72 -79
- package/dist/doctor/which.d.ts +20 -1
- package/dist/doctor/which.js +67 -1
- package/dist/eval/report.d.ts +29 -0
- package/dist/eval/report.js +69 -0
- package/dist/eval/run.d.ts +9 -0
- package/dist/eval/run.js +40 -4
- package/dist/eval/version-pin.d.ts +99 -0
- package/dist/eval/version-pin.js +181 -0
- package/dist/finish-loop/pr-finish-loop.d.ts +13 -2
- package/dist/finish-loop/pr-finish-loop.js +116 -5
- package/dist/finish-loop/types.d.ts +1 -1
- package/dist/hooks/dispatcher.d.ts +9 -5
- package/dist/hooks/dispatcher.js +23 -15
- package/dist/hooks/readonly.d.ts +6 -3
- package/dist/hooks/readonly.js +44 -25
- package/dist/index.d.ts +2 -0
- package/dist/index.js +2 -0
- package/dist/init-deposit/agent-hooks.d.ts +20 -0
- package/dist/init-deposit/agent-hooks.js +51 -31
- package/dist/intake/issue-ingest.js +29 -0
- package/dist/lifecycle/completed-consistency.d.ts +60 -0
- package/dist/lifecycle/completed-consistency.js +443 -0
- package/dist/lifecycle/completed-tracked-on-delivery.d.ts +47 -0
- package/dist/lifecycle/completed-tracked-on-delivery.js +415 -0
- package/dist/lifecycle/index.d.ts +2 -0
- package/dist/lifecycle/index.js +2 -0
- package/dist/literal-acceptance/capture.d.ts +52 -0
- package/dist/literal-acceptance/capture.js +658 -0
- package/dist/literal-acceptance/evaluate.d.ts +47 -0
- package/dist/literal-acceptance/evaluate.js +193 -0
- package/dist/literal-acceptance/index.d.ts +12 -0
- package/dist/literal-acceptance/index.js +12 -0
- package/dist/literal-acceptance/run.d.ts +38 -0
- package/dist/literal-acceptance/run.js +216 -0
- package/dist/literal-acceptance/safety.d.ts +24 -0
- package/dist/literal-acceptance/safety.js +251 -0
- package/dist/literal-acceptance/types.d.ts +82 -0
- package/dist/literal-acceptance/types.js +26 -0
- package/dist/platform/host-content-surface.d.ts +74 -0
- package/dist/platform/host-content-surface.js +214 -0
- package/dist/platform/index.d.ts +1 -0
- package/dist/platform/index.js +1 -0
- package/dist/policy/ceremony-dial.d.ts +289 -0
- package/dist/policy/ceremony-dial.js +980 -0
- package/dist/policy/deft-directive-disable.js +12 -2
- package/dist/policy/index.d.ts +2 -0
- package/dist/policy/index.js +16 -1
- package/dist/policy/merge-approval-head.d.ts +129 -0
- package/dist/policy/merge-approval-head.js +461 -0
- package/dist/policy/require-human-merge.d.ts +5 -0
- package/dist/policy/require-human-merge.js +5 -0
- package/dist/pr-merge-readiness/ci-gate.d.ts +20 -3
- package/dist/pr-merge-readiness/ci-gate.js +65 -5
- package/dist/pr-merge-readiness/compute.d.ts +13 -0
- package/dist/pr-merge-readiness/compute.js +99 -14
- package/dist/pr-merge-readiness/evaluate.js +10 -0
- package/dist/pr-merge-readiness/gh.d.ts +49 -0
- package/dist/pr-merge-readiness/gh.js +268 -0
- package/dist/pr-merge-readiness/index.d.ts +2 -2
- package/dist/pr-merge-readiness/index.js +2 -2
- package/dist/pr-merge-readiness/mergeability.js +5 -0
- package/dist/pr-merge-readiness/output.js +2 -0
- package/dist/pr-merge-readiness/parse.js +4 -0
- package/dist/pr-merge-readiness/test-gh-fixtures.helpers.js +4 -0
- package/dist/pr-merge-readiness/types.d.ts +6 -0
- package/dist/pr-wait-mergeable/cascade.d.ts +11 -0
- package/dist/pr-wait-mergeable/cascade.js +115 -1
- package/dist/pr-wait-mergeable/main.d.ts +4 -0
- package/dist/pr-wait-mergeable/main.js +4 -0
- package/dist/pr-wait-mergeable/types.d.ts +3 -1
- package/dist/pr-wait-mergeable/wrappers.d.ts +6 -1
- package/dist/pr-wait-mergeable/wrappers.js +7 -1
- package/dist/preflight/evaluate.d.ts +15 -1
- package/dist/preflight/evaluate.js +33 -2
- package/dist/render/framework-commands.js +4 -0
- package/dist/scope/acceptance-evidence.d.ts +76 -0
- package/dist/scope/acceptance-evidence.js +348 -0
- package/dist/scope/coverage-map.d.ts +98 -0
- package/dist/scope/coverage-map.js +558 -0
- package/dist/scope/decompose.js +125 -11
- package/dist/scope/effort-activate-gate.d.ts +28 -0
- package/dist/scope/effort-activate-gate.js +64 -0
- package/dist/scope/index.d.ts +4 -0
- package/dist/scope/index.js +4 -0
- package/dist/scope/parent-lineage.d.ts +125 -0
- package/dist/scope/parent-lineage.js +626 -0
- package/dist/scope/transition.d.ts +8 -0
- package/dist/scope/transition.js +69 -2
- package/dist/session/active-cli.d.ts +79 -0
- package/dist/session/active-cli.js +382 -0
- package/dist/session/effort-budget.d.ts +130 -0
- package/dist/session/effort-budget.js +334 -0
- package/dist/session/index.d.ts +2 -0
- package/dist/session/index.js +2 -0
- package/dist/session/session-start.d.ts +30 -1
- package/dist/session/session-start.js +234 -26
- package/dist/session/verify-session-ritual.d.ts +14 -0
- package/dist/session/verify-session-ritual.js +33 -0
- package/dist/story-ready/evaluate.d.ts +11 -0
- package/dist/story-ready/evaluate.js +41 -3
- package/dist/swarm/index.d.ts +2 -0
- package/dist/swarm/index.js +2 -0
- package/dist/swarm/pre-dispatch-cli.d.ts +19 -0
- package/dist/swarm/pre-dispatch-cli.js +143 -0
- package/dist/swarm/pre-dispatch.d.ts +87 -0
- package/dist/swarm/pre-dispatch.js +373 -0
- package/dist/triage/actions/candidates-log.d.ts +1 -2
- package/dist/triage/actions/candidates-log.js +37 -6
- package/dist/vbrief-activate/activate.js +6 -0
- package/dist/vbrief-validate/constants.d.ts +2 -0
- package/dist/vbrief-validate/constants.js +2 -0
- package/dist/vbrief-validate/schema.js +4 -1
- package/dist/xbrief-migrate/migrate-project.d.ts +4 -0
- package/dist/xbrief-migrate/migrate-project.js +92 -3
- package/package.json +19 -3
package/dist/doctor/main.js
CHANGED
|
@@ -1,22 +1,18 @@
|
|
|
1
1
|
import { existsSync, readFileSync, statSync, writeFileSync } from "node:fs";
|
|
2
2
|
import { join, resolve } from "node:path";
|
|
3
|
-
import { VBRIEF_VERSION } from "@deftai/directive-types";
|
|
4
3
|
import { evaluate as evaluateAgentsMdAdvisory } from "../agents-md-advisory/evaluate.js";
|
|
5
4
|
import { evaluateConsumerGateIntegrity, formatConsumerGateIntegrityFailure, } from "../check/consumer-gate-integrity.js";
|
|
6
5
|
import { contentRoot } from "../content-root.js";
|
|
7
|
-
import { resolveProjectDefinitionPath } from "../layout/resolve.js";
|
|
8
6
|
import { DEFT_DIRECTIVE_DISABLE_FLAG_NAME, DEFT_DIRECTIVE_DISABLE_STATUS, DEFT_DIRECTIVE_DISABLE_TRACKED_WARNING, detectDeftDirectiveDisable, formatDeftDirectiveDisableMessage, isDeftDirectiveDisableActive, } from "../policy/deft-directive-disable.js";
|
|
9
7
|
import { detectNoDeftDirective, NO_DEFT_DIRECTIVE_DISABLED_MESSAGE, NO_DEFT_DIRECTIVE_FLAG_NAME, NO_DEFT_DIRECTIVE_INCONSISTENT_MESSAGE, NO_DEFT_DIRECTIVE_INCONSISTENT_POLICY, } from "../policy/no-deft-directive.js";
|
|
10
8
|
import { describeShadowedPlanExtension, detectShadowedPlanExtensions, } from "../policy/plan-extensions.js";
|
|
11
9
|
import { loadProjectDefinition } from "../policy/resolve.js";
|
|
12
10
|
import { checkLocalEngineIntegrity, classify, detectPackageManager, evaluateSkew, reconcileVersions, plan as resolvePlan, } from "../resolution/index.js";
|
|
13
|
-
import { classifyXbriefSchemaDistance } from "../staleness-tickler/probe-xbrief.js";
|
|
14
11
|
import { resolveUserMdPath } from "../user-config/resolve-user-md.js";
|
|
15
12
|
import { evaluateAgentHooks } from "../verify-env/agent-hooks.js";
|
|
16
13
|
import { probeAgentHooksLive } from "../verify-env/agent-hooks-live-probe.js";
|
|
17
|
-
import { readDeclaredArtifactVersion } from "../xbrief-migrate/transforms.js";
|
|
18
14
|
import { agentsRefreshPlan, hasV3ManagedMarker } from "./agents-md.js";
|
|
19
|
-
import { runChecks } from "./checks.js";
|
|
15
|
+
import { checkXbriefEnvelopeMajorVersion, runChecks, XBRIEF_ENVELOPE_MAJOR_CHECK, XBRIEF_ENVELOPE_MIGRATE_COMMAND, } from "./checks.js";
|
|
20
16
|
import { CONSUMER_FRAMEWORK_DIRS, EXPECTED_CONTENT_DIRS, EXPECTED_FRAMEWORK_DIRS, NETWORK_DISCLOSURE_LINE, PAYLOAD_STALENESS_OFFLINE_SKIP_MESSAGE, TASKFILE_INCLUDE_SNIPPET, UV_INSTALL_URL, } from "./constants.js";
|
|
21
17
|
import { decideThrottle, formatIsoZ, readState, renderDoctorStatusLine, writeState, } from "./doctor-state.js";
|
|
22
18
|
import { formatAllowedFlagsHint, formatUnknownFlagsError, parseDoctorFlags } from "./flags.js";
|
|
@@ -33,8 +29,6 @@ import { runLocalSignpostChecks } from "./signpost-checks.js";
|
|
|
33
29
|
import { classifyTaskfileInclude, formatGatesSurfaceDualRemediation, formatMissingIncludeSnippet, GATES_SURFACE_DEFT_REMEDIATION, includesBlockHasDeftTaskfile, resolveConsumerTaskfile, } from "./taskfile.js";
|
|
34
30
|
import { defaultWhich } from "./which.js";
|
|
35
31
|
const DEFAULT_RESOLUTION_PLATFORMS = ["linux", "darwin", "win32"];
|
|
36
|
-
/** Next-action command for project-envelope behind-major (#2971). */
|
|
37
|
-
const XBRIEF_ENVELOPE_MIGRATE_COMMAND = "deft migrate:xbrief";
|
|
38
32
|
/**
|
|
39
33
|
* Read the `packageManager` field (Corepack) from a project package.json, or
|
|
40
34
|
* null when absent/unreadable. Lets the doctor detect a pnpm project that has
|
|
@@ -653,6 +647,11 @@ function runInstallIntegrityChecks(projectRoot, sink, addFinding, seams) {
|
|
|
653
647
|
const name = String(entry.name ?? "install-integrity");
|
|
654
648
|
const status = String(entry.status ?? "");
|
|
655
649
|
const detail = String(entry.detail ?? "");
|
|
650
|
+
// Authoritative envelope-major emission is runXbriefEnvelopeVersionCheck
|
|
651
|
+
// (runs for framework repo + consumers). Skip install-integrity duplicate.
|
|
652
|
+
if (name === XBRIEF_ENVELOPE_MAJOR_CHECK) {
|
|
653
|
+
continue;
|
|
654
|
+
}
|
|
656
655
|
if (status === "pass") {
|
|
657
656
|
sink.success(`${name}: pass`);
|
|
658
657
|
continue;
|
|
@@ -954,105 +953,99 @@ function runTaskfileIncludeCheck(projectRoot, fixMode, jsonMode, sink, addFindin
|
|
|
954
953
|
});
|
|
955
954
|
}
|
|
956
955
|
/**
|
|
957
|
-
* Fail closed when
|
|
958
|
-
*
|
|
959
|
-
*
|
|
960
|
-
* (
|
|
961
|
-
*
|
|
962
|
-
*
|
|
963
|
-
* must NOT route to migrate:xbrief when only framework schema files are stale.
|
|
956
|
+
* Fail closed when any scanned project xbrief lifecycle `*.xbrief.json` envelope
|
|
957
|
+
* declares a schema major behind the framework target (#2971 / #3243). Greenfield
|
|
958
|
+
* (no envelopes) skips. Behind-major records `deft migrate:xbrief` as the next
|
|
959
|
+
* action (hybrid in-place rewrite on already-xbrief trees — #3236). Distinct from
|
|
960
|
+
* deposited-schema (`stale-xbrief-schema-deposit`) which must NOT route to
|
|
961
|
+
* migrate:xbrief when only framework schema files are stale.
|
|
964
962
|
*/
|
|
965
963
|
export function runXbriefEnvelopeVersionCheck(projectRoot, sink, addFinding, seams) {
|
|
966
|
-
const checkName =
|
|
967
|
-
const isFile = seams.isFile ?? ((p) => existsSync(p));
|
|
968
|
-
const readText = seams.readText ?? readTextSafe;
|
|
969
|
-
const targetVersion = VBRIEF_VERSION;
|
|
964
|
+
const checkName = XBRIEF_ENVELOPE_MAJOR_CHECK;
|
|
970
965
|
if (seams.probeXbriefEnvelope) {
|
|
971
966
|
const probe = seams.probeXbriefEnvelope(projectRoot);
|
|
972
967
|
emitXbriefEnvelopeFinding(checkName, probe, sink, addFinding);
|
|
973
968
|
return;
|
|
974
969
|
}
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
}
|
|
990
|
-
return;
|
|
991
|
-
}
|
|
992
|
-
if (!isFile(definitionPath)) {
|
|
993
|
-
const skipMessage = `${checkName}: skip -- no PROJECT-DEFINITION yet (greenfield)`;
|
|
994
|
-
sink.info(skipMessage);
|
|
995
|
-
addFinding({
|
|
996
|
-
severity: "skip",
|
|
997
|
-
message: skipMessage,
|
|
998
|
-
check: checkName,
|
|
999
|
-
status: "skip",
|
|
1000
|
-
reason: "no-project-definition",
|
|
1001
|
-
});
|
|
1002
|
-
return;
|
|
1003
|
-
}
|
|
1004
|
-
const text = readText(definitionPath);
|
|
1005
|
-
if (text === null) {
|
|
1006
|
-
// Unreadable path (permissions or injectable seams) is not proof of 0.6.
|
|
1007
|
-
const skipMessage = `${checkName}: skip -- PROJECT-DEFINITION unreadable`;
|
|
970
|
+
const result = checkXbriefEnvelopeMajorVersion(projectRoot, {
|
|
971
|
+
...(seams.readText ? { readText: seams.readText } : {}),
|
|
972
|
+
...(seams.isFile ? { isFile: seams.isFile } : {}),
|
|
973
|
+
...(seams.isDir ? { isDir: seams.isDir } : {}),
|
|
974
|
+
});
|
|
975
|
+
const data = (result.data ?? {});
|
|
976
|
+
const targetVersion = typeof data.target_version === "string"
|
|
977
|
+
? data.target_version
|
|
978
|
+
: String(data.target_version ?? "");
|
|
979
|
+
const declaredFromData = data.declared_versions;
|
|
980
|
+
const declaredVersion = Array.isArray(declaredFromData)
|
|
981
|
+
? (declaredFromData.find((v) => typeof v === "string") ?? null)
|
|
982
|
+
: null;
|
|
983
|
+
if (result.status === "skip") {
|
|
984
|
+
const skipMessage = `${checkName}: skip -- ${result.detail}`;
|
|
1008
985
|
sink.info(skipMessage);
|
|
1009
986
|
addFinding({
|
|
1010
987
|
severity: "skip",
|
|
1011
988
|
message: skipMessage,
|
|
1012
989
|
check: checkName,
|
|
1013
990
|
status: "skip",
|
|
1014
|
-
reason: "
|
|
991
|
+
reason: typeof data.reason === "string" ? data.reason : "skip",
|
|
992
|
+
target_version: targetVersion || undefined,
|
|
1015
993
|
});
|
|
1016
994
|
return;
|
|
1017
995
|
}
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
const skipMessage = `${checkName}: skip -- PROJECT-DEFINITION is not a JSON object`;
|
|
1026
|
-
sink.info(skipMessage);
|
|
996
|
+
if (result.status === "pass") {
|
|
997
|
+
const status = typeof data.status === "string" ? data.status : "current";
|
|
998
|
+
if (status === "behind-minor") {
|
|
999
|
+
// Major-only check (#3243) does not fail closed, but surface an advisory
|
|
1000
|
+
// when the shared scan observed behind-minor distance.
|
|
1001
|
+
const warnMessage = `${checkName}: behind-minor -- ${result.detail}. Prefer \`${XBRIEF_ENVELOPE_MIGRATE_COMMAND}\` when convenient.`;
|
|
1002
|
+
sink.warn(warnMessage);
|
|
1027
1003
|
addFinding({
|
|
1028
|
-
severity: "
|
|
1029
|
-
message:
|
|
1004
|
+
severity: "warning",
|
|
1005
|
+
message: warnMessage,
|
|
1030
1006
|
check: checkName,
|
|
1031
|
-
status: "
|
|
1032
|
-
|
|
1007
|
+
status: "behind-minor",
|
|
1008
|
+
suggestion: XBRIEF_ENVELOPE_MIGRATE_COMMAND,
|
|
1009
|
+
target_version: targetVersion || undefined,
|
|
1010
|
+
next_command: XBRIEF_ENVELOPE_MIGRATE_COMMAND,
|
|
1033
1011
|
});
|
|
1034
1012
|
return;
|
|
1035
1013
|
}
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
const skipMessage = `${checkName}: skip -- PROJECT-DEFINITION JSON parse failed`;
|
|
1039
|
-
sink.info(skipMessage);
|
|
1014
|
+
const okMessage = `${checkName}: ${result.detail}`;
|
|
1015
|
+
sink.success(okMessage);
|
|
1040
1016
|
addFinding({
|
|
1041
1017
|
severity: "skip",
|
|
1042
|
-
message:
|
|
1018
|
+
message: okMessage,
|
|
1043
1019
|
check: checkName,
|
|
1044
|
-
status: "
|
|
1045
|
-
|
|
1020
|
+
status: "current",
|
|
1021
|
+
target_version: targetVersion || undefined,
|
|
1046
1022
|
});
|
|
1047
1023
|
return;
|
|
1048
1024
|
}
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1025
|
+
// fail / error → behind-major fail closed (migratable 0.6 or non-migratable)
|
|
1026
|
+
const status = typeof data.status === "string" ? data.status : "behind-major";
|
|
1027
|
+
const nextCommand = typeof data.next_command === "string"
|
|
1028
|
+
? data.next_command
|
|
1029
|
+
: data.next_command === null
|
|
1030
|
+
? null
|
|
1031
|
+
: XBRIEF_ENVELOPE_MIGRATE_COMMAND;
|
|
1032
|
+
const suggestion = typeof data.suggestion === "string"
|
|
1033
|
+
? data.suggestion
|
|
1034
|
+
: (nextCommand ?? `set xBRIEFInfo.version to framework target`);
|
|
1035
|
+
const message = `${checkName}: ${result.detail}`;
|
|
1036
|
+
sink.error(message);
|
|
1037
|
+
addFinding({
|
|
1038
|
+
severity: "error",
|
|
1039
|
+
message,
|
|
1040
|
+
check: checkName,
|
|
1041
|
+
status,
|
|
1042
|
+
suggestion,
|
|
1043
|
+
declared_version: declaredVersion,
|
|
1044
|
+
target_version: targetVersion || undefined,
|
|
1045
|
+
next_command: nextCommand,
|
|
1046
|
+
sample_paths: data.sample_paths,
|
|
1047
|
+
behind_major_count: data.behind_major_count,
|
|
1048
|
+
});
|
|
1056
1049
|
}
|
|
1057
1050
|
function emitXbriefEnvelopeFinding(checkName, probe, sink, addFinding) {
|
|
1058
1051
|
if (probe.distance === "current") {
|
package/dist/doctor/which.d.ts
CHANGED
|
@@ -1,3 +1,22 @@
|
|
|
1
|
-
|
|
1
|
+
export interface WhichAllOptions {
|
|
2
|
+
readonly env?: NodeJS.ProcessEnv;
|
|
3
|
+
readonly platform?: NodeJS.Platform;
|
|
4
|
+
readonly exists?: (path: string) => boolean;
|
|
5
|
+
/** Optional executable predicate (defaults to file + X_OK on posix). */
|
|
6
|
+
readonly isExecutable?: (path: string) => boolean;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Enumerate every PATH match for `name` (PATH order, first = highest precedence).
|
|
10
|
+
* Pure PATH scan — no shell locator — so tests and win32/posix stay hermetic and
|
|
11
|
+
* gated ritual never executes a PATH-substituted `which`/`where` (#3233).
|
|
12
|
+
* Only files (posix: executable bit) are accepted — not bare directories.
|
|
13
|
+
*/
|
|
14
|
+
export declare function whichAllFromPath(name: string, options?: WhichAllOptions): string[];
|
|
15
|
+
/**
|
|
16
|
+
* All PATH matches for `name` without shelling out (#3233 security).
|
|
17
|
+
* Alias of {@link whichAllFromPath} — never runs bare `which` / `where`.
|
|
18
|
+
*/
|
|
19
|
+
export declare function defaultWhichAll(name: string, options?: WhichAllOptions): string[];
|
|
20
|
+
/** Default PATH lookup mirroring Python `shutil.which` (first match only). */
|
|
2
21
|
export declare function defaultWhich(name: string): string | null;
|
|
3
22
|
//# sourceMappingURL=which.d.ts.map
|
package/dist/doctor/which.js
CHANGED
|
@@ -1,5 +1,71 @@
|
|
|
1
1
|
import { execFileSync } from "node:child_process";
|
|
2
|
-
|
|
2
|
+
import { accessSync, constants, existsSync, statSync } from "node:fs";
|
|
3
|
+
import { posix, win32 } from "node:path";
|
|
4
|
+
function defaultIsExecutable(path, platform) {
|
|
5
|
+
try {
|
|
6
|
+
const st = statSync(path);
|
|
7
|
+
// Directories named `deft` must not shadow later executables (#3233 Greptile).
|
|
8
|
+
if (st.isDirectory())
|
|
9
|
+
return false;
|
|
10
|
+
if (!st.isFile() && !st.isSymbolicLink())
|
|
11
|
+
return false;
|
|
12
|
+
if (platform === "win32") {
|
|
13
|
+
return true;
|
|
14
|
+
}
|
|
15
|
+
accessSync(path, constants.X_OK);
|
|
16
|
+
return true;
|
|
17
|
+
}
|
|
18
|
+
catch {
|
|
19
|
+
return false;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Enumerate every PATH match for `name` (PATH order, first = highest precedence).
|
|
24
|
+
* Pure PATH scan — no shell locator — so tests and win32/posix stay hermetic and
|
|
25
|
+
* gated ritual never executes a PATH-substituted `which`/`where` (#3233).
|
|
26
|
+
* Only files (posix: executable bit) are accepted — not bare directories.
|
|
27
|
+
*/
|
|
28
|
+
export function whichAllFromPath(name, options = {}) {
|
|
29
|
+
const env = options.env ?? process.env;
|
|
30
|
+
const platform = options.platform ?? process.platform;
|
|
31
|
+
const exists = options.exists ?? existsSync;
|
|
32
|
+
const isExecutable = options.isExecutable ?? ((p) => defaultIsExecutable(p, platform));
|
|
33
|
+
const pathValue = env.PATH ?? env.Path ?? "";
|
|
34
|
+
if (pathValue === "") {
|
|
35
|
+
return [];
|
|
36
|
+
}
|
|
37
|
+
const isWindows = platform === "win32";
|
|
38
|
+
const exts = isWindows ? (env.PATHEXT ?? ".COM;.EXE;.BAT;.CMD").split(";") : [""];
|
|
39
|
+
const sep = isWindows ? ";" : ":";
|
|
40
|
+
const joinPath = isWindows ? win32.join : posix.join;
|
|
41
|
+
const seen = new Set();
|
|
42
|
+
const out = [];
|
|
43
|
+
for (const dir of pathValue.split(sep)) {
|
|
44
|
+
if (dir === "")
|
|
45
|
+
continue;
|
|
46
|
+
for (const ext of exts) {
|
|
47
|
+
const candidate = joinPath(dir, `${name}${ext}`);
|
|
48
|
+
const key = isWindows ? candidate.toLowerCase() : candidate;
|
|
49
|
+
if (seen.has(key))
|
|
50
|
+
continue;
|
|
51
|
+
if (exists(candidate) && isExecutable(candidate)) {
|
|
52
|
+
seen.add(key);
|
|
53
|
+
out.push(candidate);
|
|
54
|
+
// One match per PATH directory (first PATHEXT hit wins on win32).
|
|
55
|
+
break;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
return out;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* All PATH matches for `name` without shelling out (#3233 security).
|
|
63
|
+
* Alias of {@link whichAllFromPath} — never runs bare `which` / `where`.
|
|
64
|
+
*/
|
|
65
|
+
export function defaultWhichAll(name, options = {}) {
|
|
66
|
+
return whichAllFromPath(name, options);
|
|
67
|
+
}
|
|
68
|
+
/** Default PATH lookup mirroring Python `shutil.which` (first match only). */
|
|
3
69
|
export function defaultWhich(name) {
|
|
4
70
|
const locator = process.platform === "win32" ? "where" : "which";
|
|
5
71
|
try {
|
package/dist/eval/report.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { type GoldenRunRecord } from "./run.js";
|
|
2
|
+
import { type CellVersionPurity, type MixedVersionPolicy } from "./version-pin.js";
|
|
2
3
|
export declare const REPORT_SCHEMA_VERSION: 1;
|
|
3
4
|
/** Metric delta with a simple two-proportion significance test (#896). */
|
|
4
5
|
export interface MetricDelta {
|
|
@@ -17,6 +18,15 @@ export interface HoldoutTripwire {
|
|
|
17
18
|
readonly primaryDelta: number;
|
|
18
19
|
readonly holdoutDelta: number;
|
|
19
20
|
}
|
|
21
|
+
/** Version purity evidence for report consumers (#3215). */
|
|
22
|
+
export interface VersionPurityEvidence {
|
|
23
|
+
readonly pure: boolean;
|
|
24
|
+
readonly summary: string;
|
|
25
|
+
readonly cells: readonly CellVersionPurity[];
|
|
26
|
+
readonly championCellAllowed: boolean;
|
|
27
|
+
readonly challengerCellAllowed: boolean;
|
|
28
|
+
readonly policy: MixedVersionPolicy;
|
|
29
|
+
}
|
|
20
30
|
/** Version-diff report between champion and challenger golden runs. */
|
|
21
31
|
export interface GoldenEvalReport {
|
|
22
32
|
readonly schemaVersion: typeof REPORT_SCHEMA_VERSION;
|
|
@@ -27,12 +37,19 @@ export interface GoldenEvalReport {
|
|
|
27
37
|
readonly challengerRunId: string;
|
|
28
38
|
readonly deltas: readonly MetricDelta[];
|
|
29
39
|
readonly holdoutTripwire: HoldoutTripwire;
|
|
40
|
+
/** Cell-level framework version purity for the reported model (#3215). */
|
|
41
|
+
readonly versionPurity: VersionPurityEvidence;
|
|
30
42
|
}
|
|
31
43
|
export interface ReportGoldenEvalOptions {
|
|
32
44
|
readonly projectRoot?: string;
|
|
33
45
|
readonly championVersion: string;
|
|
34
46
|
readonly challengerVersion: string;
|
|
35
47
|
readonly model: string;
|
|
48
|
+
/**
|
|
49
|
+
* Mixed-version cell policy (#3215). Default `refuse` fails the report when
|
|
50
|
+
* ledger runs for this model disagree on framework version within a treatment.
|
|
51
|
+
*/
|
|
52
|
+
readonly mixedVersionPolicy?: MixedVersionPolicy;
|
|
36
53
|
}
|
|
37
54
|
export interface ReportGoldenEvalResult {
|
|
38
55
|
readonly code: 0 | 1 | 2;
|
|
@@ -48,6 +65,18 @@ export declare function twoProportionZTest(passedA: number, totalA: number, pass
|
|
|
48
65
|
};
|
|
49
66
|
/** Detect holdout tripwire: primary improves while holdout regresses (#1703). */
|
|
50
67
|
export declare function evaluateHoldoutTripwire(champion: GoldenRunRecord, challenger: GoldenRunRecord): HoldoutTripwire;
|
|
68
|
+
/**
|
|
69
|
+
* Map a golden-run ledger row to the #3215 versioned-run identity.
|
|
70
|
+
* Treatment is model@harness@version so cross-version champion/challenger
|
|
71
|
+
* comparisons stay distinct cells; pin disagreements under one version refuse.
|
|
72
|
+
*/
|
|
73
|
+
export declare function goldenRunToVersionedRun(record: GoldenRunRecord): {
|
|
74
|
+
frameworkVersion: string;
|
|
75
|
+
treatment: string;
|
|
76
|
+
model: string;
|
|
77
|
+
harness: string;
|
|
78
|
+
runId: string;
|
|
79
|
+
};
|
|
51
80
|
/** Diff two directive versions with metric deltas and significance (#1703 Tier 2). */
|
|
52
81
|
export declare function reportGoldenEval(options: ReportGoldenEvalOptions): ReportGoldenEvalResult;
|
|
53
82
|
//# sourceMappingURL=report.d.ts.map
|
package/dist/eval/report.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { existsSync, readFileSync } from "node:fs";
|
|
2
2
|
import { resolveEvalPath } from "../layout/resolve.js";
|
|
3
3
|
import { GOLDEN_RUNS_HISTORY_REL } from "./run.js";
|
|
4
|
+
import { aggregateCellWithVersionPurity, evaluateLedgerVersionPurity, } from "./version-pin.js";
|
|
4
5
|
export const REPORT_SCHEMA_VERSION = 1;
|
|
5
6
|
function readGoldenRuns(projectRoot) {
|
|
6
7
|
const path = resolveEvalPath(projectRoot, GOLDEN_RUNS_HISTORY_REL);
|
|
@@ -89,6 +90,21 @@ export function evaluateHoldoutTripwire(champion, challenger) {
|
|
|
89
90
|
function formatPercent(value) {
|
|
90
91
|
return `${(value * 100).toFixed(1)}%`;
|
|
91
92
|
}
|
|
93
|
+
/**
|
|
94
|
+
* Map a golden-run ledger row to the #3215 versioned-run identity.
|
|
95
|
+
* Treatment is model@harness@version so cross-version champion/challenger
|
|
96
|
+
* comparisons stay distinct cells; pin disagreements under one version refuse.
|
|
97
|
+
*/
|
|
98
|
+
export function goldenRunToVersionedRun(record) {
|
|
99
|
+
const pin = record.frameworkVersionPin?.frameworkVersion ?? record.directiveVersion;
|
|
100
|
+
return {
|
|
101
|
+
frameworkVersion: pin,
|
|
102
|
+
treatment: `${record.model}@${record.harness}@${record.directiveVersion}`,
|
|
103
|
+
model: record.model,
|
|
104
|
+
harness: record.harness,
|
|
105
|
+
runId: record.runId,
|
|
106
|
+
};
|
|
107
|
+
}
|
|
92
108
|
/** Diff two directive versions with metric deltas and significance (#1703 Tier 2). */
|
|
93
109
|
export function reportGoldenEval(options) {
|
|
94
110
|
if (!options.championVersion.trim() || !options.challengerVersion.trim()) {
|
|
@@ -102,7 +118,48 @@ export function reportGoldenEval(options) {
|
|
|
102
118
|
return { code: 2, report: null, message: "eval:report: --model is required" };
|
|
103
119
|
}
|
|
104
120
|
const projectRoot = options.projectRoot ?? process.cwd();
|
|
121
|
+
const policy = options.mixedVersionPolicy ?? "refuse";
|
|
105
122
|
const records = readGoldenRuns(projectRoot);
|
|
123
|
+
const modelRecords = records.filter((r) => r.model === options.model);
|
|
124
|
+
// Within each version×model×harness cell, refuse/flag if pins disagree (#3215).
|
|
125
|
+
// Cross-version champion vs challenger is intentional and uses distinct cells.
|
|
126
|
+
const championCellRuns = modelRecords
|
|
127
|
+
.filter((r) => r.directiveVersion === options.championVersion)
|
|
128
|
+
.map(goldenRunToVersionedRun);
|
|
129
|
+
const challengerCellRuns = modelRecords
|
|
130
|
+
.filter((r) => r.directiveVersion === options.challengerVersion)
|
|
131
|
+
.map(goldenRunToVersionedRun);
|
|
132
|
+
const championAgg = aggregateCellWithVersionPurity({
|
|
133
|
+
runs: championCellRuns,
|
|
134
|
+
treatment: `champion@${options.model}@${options.championVersion}`,
|
|
135
|
+
policy,
|
|
136
|
+
});
|
|
137
|
+
const challengerAgg = aggregateCellWithVersionPurity({
|
|
138
|
+
runs: challengerCellRuns,
|
|
139
|
+
treatment: `challenger@${options.model}@${options.challengerVersion}`,
|
|
140
|
+
policy,
|
|
141
|
+
});
|
|
142
|
+
const ledgerPurity = evaluateLedgerVersionPurity(modelRecords.map(goldenRunToVersionedRun));
|
|
143
|
+
if (!championAgg.allowed || !challengerAgg.allowed) {
|
|
144
|
+
const versionPurity = {
|
|
145
|
+
pure: false,
|
|
146
|
+
summary: [
|
|
147
|
+
!championAgg.allowed ? championAgg.purity.message : null,
|
|
148
|
+
!challengerAgg.allowed ? challengerAgg.purity.message : null,
|
|
149
|
+
]
|
|
150
|
+
.filter((line) => line !== null)
|
|
151
|
+
.join(" "),
|
|
152
|
+
cells: [championAgg.purity, challengerAgg.purity],
|
|
153
|
+
championCellAllowed: championAgg.allowed,
|
|
154
|
+
challengerCellAllowed: challengerAgg.allowed,
|
|
155
|
+
policy,
|
|
156
|
+
};
|
|
157
|
+
return {
|
|
158
|
+
code: 1,
|
|
159
|
+
report: null,
|
|
160
|
+
message: `eval:report: mixed framework versions in treatment cell(s) — aggregation refused (#3215)\n ${versionPurity.summary}`,
|
|
161
|
+
};
|
|
162
|
+
}
|
|
106
163
|
const champion = findLatestGoldenRun(records, options.championVersion, options.model);
|
|
107
164
|
const challenger = findLatestGoldenRun(records, options.challengerVersion, options.model);
|
|
108
165
|
if (champion === null) {
|
|
@@ -133,6 +190,14 @@ export function reportGoldenEval(options) {
|
|
|
133
190
|
metricDelta("overallPassRate", champion.summary.passRate, challenger.summary.passRate, countPasses(champion.results).passed, countPasses(champion.results).total, countPasses(challenger.results).passed, countPasses(challenger.results).total),
|
|
134
191
|
];
|
|
135
192
|
const holdoutTripwire = evaluateHoldoutTripwire(champion, challenger);
|
|
193
|
+
const versionPurity = {
|
|
194
|
+
pure: championAgg.purity.pure && challengerAgg.purity.pure && ledgerPurity.pure,
|
|
195
|
+
summary: `${championAgg.purity.message} ${challengerAgg.purity.message}`,
|
|
196
|
+
cells: [championAgg.purity, challengerAgg.purity, ...ledgerPurity.cells],
|
|
197
|
+
championCellAllowed: championAgg.allowed,
|
|
198
|
+
challengerCellAllowed: challengerAgg.allowed,
|
|
199
|
+
policy,
|
|
200
|
+
};
|
|
136
201
|
const report = {
|
|
137
202
|
schemaVersion: REPORT_SCHEMA_VERSION,
|
|
138
203
|
championVersion: options.championVersion,
|
|
@@ -142,6 +207,7 @@ export function reportGoldenEval(options) {
|
|
|
142
207
|
challengerRunId: challenger.runId,
|
|
143
208
|
deltas,
|
|
144
209
|
holdoutTripwire,
|
|
210
|
+
versionPurity,
|
|
145
211
|
};
|
|
146
212
|
const lines = [
|
|
147
213
|
`eval:report champion=v${options.championVersion} challenger=v${options.challengerVersion} model=${options.model}`,
|
|
@@ -154,6 +220,9 @@ export function reportGoldenEval(options) {
|
|
|
154
220
|
return ` ${d.metric}: ${formatPercent(d.champion)} -> ${formatPercent(d.challenger)} (delta ${(d.delta * 100).toFixed(1)}pp, ${sig})`;
|
|
155
221
|
}),
|
|
156
222
|
` ${holdoutTripwire.summary}`,
|
|
223
|
+
` version purity: ${versionPurity.pure ? "ok" : "mixed"} — ${versionPurity.summary}`,
|
|
224
|
+
` champion cell pin: v${champion.frameworkVersionPin?.frameworkVersion ?? champion.directiveVersion}`,
|
|
225
|
+
` challenger cell pin: v${challenger.frameworkVersionPin?.frameworkVersion ?? challenger.directiveVersion}`,
|
|
157
226
|
];
|
|
158
227
|
const code = holdoutTripwire.triggered ? 1 : 0;
|
|
159
228
|
return { code, report, message: lines.join("\n") };
|
package/dist/eval/run.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type FrameworkVersionPin } from "./version-pin.js";
|
|
1
2
|
export declare const GOLDEN_RUNS_HISTORY_REL = "results/golden-runs.jsonl";
|
|
2
3
|
export declare const GOLDEN_RUN_SCHEMA_VERSION: 1;
|
|
3
4
|
export declare const GOLDEN_CORPUS_VERSION = "2026-07-05-tier2-fixture-v1";
|
|
@@ -32,7 +33,13 @@ export interface GoldenTaskResult {
|
|
|
32
33
|
export interface GoldenRunRecord {
|
|
33
34
|
readonly schemaVersion: typeof GOLDEN_RUN_SCHEMA_VERSION;
|
|
34
35
|
readonly runId: string;
|
|
36
|
+
/** Framework version pin for this run (alias of frameworkVersionPin.frameworkVersion). */
|
|
35
37
|
readonly directiveVersion: string;
|
|
38
|
+
/**
|
|
39
|
+
* Resolved framework version pin captured at run start (#3215).
|
|
40
|
+
* Optional for ledger rows written before the purity gate shipped.
|
|
41
|
+
*/
|
|
42
|
+
readonly frameworkVersionPin?: FrameworkVersionPin;
|
|
36
43
|
readonly model: string;
|
|
37
44
|
readonly harness: string;
|
|
38
45
|
readonly seeds: readonly number[];
|
|
@@ -63,6 +70,8 @@ export interface RunGoldenEvalResult {
|
|
|
63
70
|
readonly code: 0 | 1 | 2;
|
|
64
71
|
readonly record: GoldenRunRecord | null;
|
|
65
72
|
readonly message: string;
|
|
73
|
+
/** #1584 shared-benchmark manifest after version pin wire, when present on disk. */
|
|
74
|
+
readonly sharedBenchmarkManifest?: Record<string, unknown> | null;
|
|
66
75
|
}
|
|
67
76
|
/** Fixed golden corpus with objective graders (#1703 Tier 2). */
|
|
68
77
|
export declare const GOLDEN_CORPUS: readonly GoldenTaskDefinition[];
|
package/dist/eval/run.js
CHANGED
|
@@ -2,11 +2,11 @@ import { createHash } from "node:crypto";
|
|
|
2
2
|
import { mkdirSync, mkdtempSync, rmSync } from "node:fs";
|
|
3
3
|
import { tmpdir } from "node:os";
|
|
4
4
|
import { join, resolve } from "node:path";
|
|
5
|
-
import { readCorePackageVersion } from "../engine-version.js";
|
|
6
5
|
import { containedWrite } from "../fs/contained-write.js";
|
|
7
6
|
import { resolveEvalPath } from "../layout/resolve.js";
|
|
8
7
|
import { BYTE_DIFF_WHOLE_FILE_THRESHOLD, InstrumentedVbriefCrud } from "./crud-telemetry.js";
|
|
9
8
|
import { evaluateHealth } from "./health.js";
|
|
9
|
+
import { applyVersionPinToSharedBenchmark, resolveFrameworkVersionPin, } from "./version-pin.js";
|
|
10
10
|
export const GOLDEN_RUNS_HISTORY_REL = "results/golden-runs.jsonl";
|
|
11
11
|
export const GOLDEN_RUN_SCHEMA_VERSION = 1;
|
|
12
12
|
export const GOLDEN_CORPUS_VERSION = "2026-07-05-tier2-fixture-v1";
|
|
@@ -250,10 +250,15 @@ export function runGoldenEval(options) {
|
|
|
250
250
|
return { code: 2, record: null, message: "eval:run: --model is required" };
|
|
251
251
|
}
|
|
252
252
|
const projectRoot = options.projectRoot ?? process.cwd();
|
|
253
|
-
const
|
|
253
|
+
const now = options.now ?? (() => new Date());
|
|
254
|
+
// #3215: resolve framework version once at run start (package.json pin or override).
|
|
255
|
+
const frameworkVersionPin = resolveFrameworkVersionPin({
|
|
256
|
+
override: options.directiveVersion,
|
|
257
|
+
now,
|
|
258
|
+
});
|
|
259
|
+
const directiveVersion = frameworkVersionPin.frameworkVersion;
|
|
254
260
|
const harness = options.harness ?? "deterministic-fixture";
|
|
255
261
|
const seeds = options.seeds ?? [1, 2, 3];
|
|
256
|
-
const now = options.now ?? (() => new Date());
|
|
257
262
|
const persist = options.persist ?? true;
|
|
258
263
|
if (seeds.length === 0) {
|
|
259
264
|
return { code: 2, record: null, message: "eval:run: at least one seed is required" };
|
|
@@ -293,6 +298,7 @@ export function runGoldenEval(options) {
|
|
|
293
298
|
schemaVersion: GOLDEN_RUN_SCHEMA_VERSION,
|
|
294
299
|
runId: runIdFor(directiveVersion, options.model, harness, seeds),
|
|
295
300
|
directiveVersion,
|
|
301
|
+
frameworkVersionPin,
|
|
296
302
|
model: options.model,
|
|
297
303
|
harness,
|
|
298
304
|
seeds,
|
|
@@ -303,6 +309,8 @@ export function runGoldenEval(options) {
|
|
|
303
309
|
results,
|
|
304
310
|
summary,
|
|
305
311
|
};
|
|
312
|
+
// Persist ledger first so a failed golden-run write never leaves a dangling
|
|
313
|
+
// shared-benchmark pin without a matching run row (#3215 Greptile).
|
|
306
314
|
if (persist) {
|
|
307
315
|
try {
|
|
308
316
|
persistGoldenRun(projectRoot, record);
|
|
@@ -312,16 +320,44 @@ export function runGoldenEval(options) {
|
|
|
312
320
|
code: 2,
|
|
313
321
|
record,
|
|
314
322
|
message: `eval:run: failed to persist golden run: ${String(err)}`,
|
|
323
|
+
sharedBenchmarkManifest: null,
|
|
315
324
|
};
|
|
316
325
|
}
|
|
317
326
|
}
|
|
327
|
+
// #1584 / #3215: wire (+ persist when ledger was written) shared-benchmark pin.
|
|
328
|
+
let sharedBenchmark;
|
|
329
|
+
try {
|
|
330
|
+
sharedBenchmark = applyVersionPinToSharedBenchmark(projectRoot, frameworkVersionPin, {
|
|
331
|
+
persist,
|
|
332
|
+
});
|
|
333
|
+
}
|
|
334
|
+
catch (err) {
|
|
335
|
+
return {
|
|
336
|
+
code: 2,
|
|
337
|
+
record,
|
|
338
|
+
message: `eval:run: failed to wire shared-benchmark pin: ${String(err)}`,
|
|
339
|
+
sharedBenchmarkManifest: null,
|
|
340
|
+
};
|
|
341
|
+
}
|
|
318
342
|
const lines = [
|
|
319
343
|
`eval:run v${record.directiveVersion} model=${record.model} harness=${record.harness} seeds=[${record.seeds.join(",")}]`,
|
|
344
|
+
` framework version pin: ${frameworkVersionPin.frameworkVersion} (source=${frameworkVersionPin.source})`,
|
|
320
345
|
` primary pass rate: ${(summary.primaryPassRate * 100).toFixed(1)}% (${summary.primaryTotal} trials)`,
|
|
321
346
|
` holdout pass rate: ${(summary.holdoutPassRate * 100).toFixed(1)}% (${summary.holdoutTotal} trials)`,
|
|
322
347
|
` rotating holdout task: ${rotatingHoldout?.id ?? "none"}`,
|
|
323
348
|
` runId=${record.runId}`,
|
|
324
349
|
];
|
|
325
|
-
|
|
350
|
+
if (sharedBenchmark.persisted) {
|
|
351
|
+
lines.push(" shared-benchmark manifest: frameworkVersion pin persisted (#1584 / #3215)");
|
|
352
|
+
}
|
|
353
|
+
else if (sharedBenchmark.applied) {
|
|
354
|
+
lines.push(" shared-benchmark manifest: frameworkVersion wired in-memory (#1584 / #3215)");
|
|
355
|
+
}
|
|
356
|
+
return {
|
|
357
|
+
code: 0,
|
|
358
|
+
record,
|
|
359
|
+
message: lines.join("\n"),
|
|
360
|
+
sharedBenchmarkManifest: sharedBenchmark.manifest,
|
|
361
|
+
};
|
|
326
362
|
}
|
|
327
363
|
//# sourceMappingURL=run.js.map
|