@deftai/directive 0.62.0 → 0.63.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/{branch-parity.d.ts → branch-fixtures.d.ts} +1 -3
- package/dist/{branch-parity.js → branch-fixtures.js} +3 -110
- package/dist/dispatch.d.ts +1 -1
- package/dist/dispatch.js +0 -1
- package/dist/orchestration-cli/coverage-map.js +1 -1
- package/dist/{policy-parity.d.ts → policy-fixtures.d.ts} +1 -3
- package/dist/{policy-parity.js → policy-fixtures.js} +4 -100
- package/dist/{release-e2e-parity.d.ts → release-e2e-fixtures.d.ts} +1 -3
- package/dist/release-e2e-fixtures.js +38 -0
- package/dist/{story-ready-parity.d.ts → story-ready-fixtures.d.ts} +1 -3
- package/dist/{story-ready-parity.js → story-ready-fixtures.js} +4 -121
- package/dist/{triage-aux-a-parity.d.ts → triage-aux-a-fixtures.d.ts} +1 -3
- package/dist/{triage-aux-a-parity.js → triage-aux-a-fixtures.js} +3 -73
- package/dist/{triage-aux-b-parity.d.ts → triage-aux-b-fixtures.d.ts} +1 -3
- package/dist/triage-aux-b-fixtures.js +167 -0
- package/dist/{triage-bootstrap-parity.d.ts → triage-bootstrap-fixtures.d.ts} +1 -3
- package/dist/{triage-bootstrap-parity.js → triage-bootstrap-fixtures.js} +4 -91
- package/dist/{triage-classify-parity.d.ts → triage-classify-fixtures.d.ts} +1 -3
- package/dist/{triage-classify-parity.js → triage-classify-fixtures.js} +4 -94
- package/dist/{triage-queue-parity.d.ts → triage-queue-fixtures.d.ts} +1 -3
- package/dist/{triage-queue-parity.js → triage-queue-fixtures.js} +4 -86
- package/dist/{triage-scope-parity.d.ts → triage-scope-fixtures.d.ts} +1 -3
- package/dist/{triage-scope-parity.js → triage-scope-fixtures.js} +4 -91
- package/dist/{vbrief-preflight-parity.d.ts → vbrief-preflight-fixtures.d.ts} +1 -3
- package/dist/vbrief-preflight-fixtures.js +79 -0
- package/dist/{wip-cap-parity.d.ts → wip-cap-fixtures.d.ts} +1 -3
- package/dist/{wip-cap-parity.js → wip-cap-fixtures.js} +4 -91
- package/package.json +4 -15
- package/dist/cache-parity.d.ts +0 -36
- package/dist/cache-parity.js +0 -165
- package/dist/codebase-parity.d.ts +0 -31
- package/dist/codebase-parity.js +0 -303
- package/dist/doc-cli-parity.d.ts +0 -29
- package/dist/doc-cli-parity.js +0 -159
- package/dist/doctor-parity.d.ts +0 -42
- package/dist/doctor-parity.js +0 -157
- package/dist/intake-parity.d.ts +0 -30
- package/dist/intake-parity.js +0 -203
- package/dist/lifecycle-packs-parity.d.ts +0 -30
- package/dist/lifecycle-packs-parity.js +0 -377
- package/dist/orchestration-parity.d.ts +0 -38
- package/dist/orchestration-parity.js +0 -364
- package/dist/parity.d.ts +0 -36
- package/dist/parity.js +0 -176
- package/dist/platform-parity.d.ts +0 -26
- package/dist/platform-parity.js +0 -309
- package/dist/pr-closing-keywords-parity.d.ts +0 -45
- package/dist/pr-closing-keywords-parity.js +0 -259
- package/dist/pr-merge-readiness-parity.d.ts +0 -44
- package/dist/pr-merge-readiness-parity.js +0 -296
- package/dist/pr-monitor-parity.d.ts +0 -44
- package/dist/pr-monitor-parity.js +0 -283
- package/dist/pr-protected-issues-parity.d.ts +0 -41
- package/dist/pr-protected-issues-parity.js +0 -220
- package/dist/pr-wait-mergeable-parity.d.ts +0 -45
- package/dist/pr-wait-mergeable-parity.js +0 -340
- package/dist/release-e2e-parity.js +0 -114
- package/dist/release-parity.d.ts +0 -40
- package/dist/release-parity.js +0 -226
- package/dist/release-publish-parity.d.ts +0 -36
- package/dist/release-publish-parity.js +0 -138
- package/dist/release-rollback-parity.d.ts +0 -37
- package/dist/release-rollback-parity.js +0 -161
- package/dist/render-parity.d.ts +0 -36
- package/dist/render-parity.js +0 -385
- package/dist/scm-parity.d.ts +0 -39
- package/dist/scm-parity.js +0 -181
- package/dist/scope-lifecycle-parity.d.ts +0 -35
- package/dist/scope-lifecycle-parity.js +0 -177
- package/dist/session-parity.d.ts +0 -39
- package/dist/session-parity.js +0 -262
- package/dist/slice-parity.d.ts +0 -36
- package/dist/slice-parity.js +0 -304
- package/dist/swarm-parity.d.ts +0 -28
- package/dist/swarm-parity.js +0 -327
- package/dist/triage-actions-parity.d.ts +0 -36
- package/dist/triage-actions-parity.js +0 -357
- package/dist/triage-aux-b-parity.js +0 -308
- package/dist/triage-summary-parity.d.ts +0 -50
- package/dist/triage-summary-parity.js +0 -306
- package/dist/validate-content-parity.d.ts +0 -33
- package/dist/validate-content-parity.js +0 -356
- package/dist/vbrief-activate-parity.d.ts +0 -39
- package/dist/vbrief-activate-parity.js +0 -216
- package/dist/vbrief-build-parity.d.ts +0 -28
- package/dist/vbrief-build-parity.js +0 -399
- package/dist/vbrief-preflight-parity.js +0 -163
- package/dist/vbrief-reconcile-parity.d.ts +0 -23
- package/dist/vbrief-reconcile-parity.js +0 -609
- package/dist/vbrief-validate-parity.d.ts +0 -27
- package/dist/vbrief-validate-parity.js +0 -122
- package/dist/vbrief-validation-parity.d.ts +0 -28
- package/dist/vbrief-validation-parity.js +0 -645
- package/dist/verify-env-parity.d.ts +0 -28
- package/dist/verify-env-parity.js +0 -272
- package/dist/verify-source-parity.d.ts +0 -26
- package/dist/verify-source-parity.js +0 -178
|
@@ -1,13 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
* Golden-output parity harness (#1725): runs BOTH the Python oracle and the
|
|
4
|
-
* ported TS triage aux-A CLIs with identical argv on throwaway fixtures,
|
|
5
|
-
* then diffs exit codes + stdout/stderr (cache-off).
|
|
6
|
-
*
|
|
7
|
-
* Exit codes: 0 parity / 1 divergence / 2 harness setup error.
|
|
8
|
-
*/
|
|
9
|
-
import { spawnSync } from "node:child_process";
|
|
10
|
-
import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from "node:fs";
|
|
1
|
+
/** Test fixtures extracted from legacy parity harness (#2083). */
|
|
2
|
+
import { mkdirSync, mkdtempSync, writeFileSync } from "node:fs";
|
|
11
3
|
import { tmpdir } from "node:os";
|
|
12
4
|
import { dirname, join, resolve } from "node:path";
|
|
13
5
|
import { fileURLToPath } from "node:url";
|
|
@@ -23,19 +15,6 @@ export function normalizeOutput(text) {
|
|
|
23
15
|
.replace(/Creating virtual environment[^\n]*\n/g, "")
|
|
24
16
|
.replace(/Installed \d+ packages[^\n]*\n/g, "");
|
|
25
17
|
}
|
|
26
|
-
function runCapture(cmd, args, cwd) {
|
|
27
|
-
const result = spawnSync(cmd, args, {
|
|
28
|
-
cwd,
|
|
29
|
-
encoding: "utf8",
|
|
30
|
-
env: { ...process.env },
|
|
31
|
-
stdio: ["ignore", "pipe", "pipe"],
|
|
32
|
-
});
|
|
33
|
-
return {
|
|
34
|
-
status: result.status ?? 2,
|
|
35
|
-
stdout: typeof result.stdout === "string" ? result.stdout : "",
|
|
36
|
-
stderr: typeof result.stderr === "string" ? result.stderr : "",
|
|
37
|
-
};
|
|
38
|
-
}
|
|
39
18
|
function resolveDeftRoot() {
|
|
40
19
|
if (process.env.DEFT_ROOT !== undefined && process.env.DEFT_ROOT.length > 0) {
|
|
41
20
|
return resolve(process.env.DEFT_ROOT);
|
|
@@ -43,14 +22,6 @@ function resolveDeftRoot() {
|
|
|
43
22
|
return resolve(dirname(fileURLToPath(import.meta.url)), "..", "..", "..");
|
|
44
23
|
}
|
|
45
24
|
export { resolveDeftRoot };
|
|
46
|
-
function runPython(deftRoot, script, repo, argv) {
|
|
47
|
-
const cap = runCapture("uv", ["run", "python", join(deftRoot, "scripts", script), ...argv, "--project-root", repo], deftRoot);
|
|
48
|
-
return { exitCode: cap.status, stdout: cap.stdout, stderr: cap.stderr };
|
|
49
|
-
}
|
|
50
|
-
function runTs(deftRoot, cli, repo, argv) {
|
|
51
|
-
const cap = runCapture("node", [join(deftRoot, "packages", "cli", "dist", cli), ...argv, "--project-root", repo], deftRoot);
|
|
52
|
-
return { exitCode: cap.status, stdout: cap.stdout, stderr: cap.stderr };
|
|
53
|
-
}
|
|
54
25
|
export function diffCase(python, ts, caseName) {
|
|
55
26
|
const pyOut = normalizeOutput(python.stdout);
|
|
56
27
|
const tsOut = normalizeOutput(ts.stdout);
|
|
@@ -115,32 +86,6 @@ export function buildFixtureRepo(setup) {
|
|
|
115
86
|
setup?.(root);
|
|
116
87
|
return root;
|
|
117
88
|
}
|
|
118
|
-
export function runParity() {
|
|
119
|
-
const deftRoot = resolveDeftRoot();
|
|
120
|
-
const diffs = [];
|
|
121
|
-
for (const testCase of PARITY_CASES) {
|
|
122
|
-
if (testCase.name === "welcome-bad-root") {
|
|
123
|
-
const badRoot = join(tmpdir(), "deft-triage-missing-dir-never-created");
|
|
124
|
-
const python = runPython(deftRoot, testCase.script, badRoot, testCase.argv);
|
|
125
|
-
const ts = runTs(deftRoot, testCase.tsCli, badRoot, testCase.argv);
|
|
126
|
-
diffs.push(diffCase(python, ts, testCase.name));
|
|
127
|
-
continue;
|
|
128
|
-
}
|
|
129
|
-
const pyRepo = buildFixtureRepo(testCase.setup);
|
|
130
|
-
const tsRepo = buildFixtureRepo(testCase.setup);
|
|
131
|
-
try {
|
|
132
|
-
const python = runPython(deftRoot, testCase.script, pyRepo, testCase.argv);
|
|
133
|
-
const ts = runTs(deftRoot, testCase.tsCli, tsRepo, testCase.argv);
|
|
134
|
-
diffs.push(diffCase(python, ts, testCase.name));
|
|
135
|
-
}
|
|
136
|
-
finally {
|
|
137
|
-
rmSync(pyRepo, { recursive: true, force: true });
|
|
138
|
-
rmSync(tsRepo, { recursive: true, force: true });
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
const ok = diffs.every((d) => !d.exitMismatch && !d.stdoutMismatch && !d.stderrMismatch);
|
|
142
|
-
return { ok, diffs };
|
|
143
|
-
}
|
|
144
89
|
export function renderReport(result) {
|
|
145
90
|
if (result.ok) {
|
|
146
91
|
return `triage-aux-a parity: CLEAN -- Python and TS agree on ${PARITY_CASES.length} cases.`;
|
|
@@ -159,19 +104,4 @@ export function renderReport(result) {
|
|
|
159
104
|
}
|
|
160
105
|
return lines.join("\n");
|
|
161
106
|
}
|
|
162
|
-
|
|
163
|
-
try {
|
|
164
|
-
const result = runParity();
|
|
165
|
-
if (result.ok) {
|
|
166
|
-
process.stdout.write(`${renderReport(result)}\n`);
|
|
167
|
-
process.exit(0);
|
|
168
|
-
}
|
|
169
|
-
process.stderr.write(`${renderReport(result)}\n`);
|
|
170
|
-
process.exit(1);
|
|
171
|
-
}
|
|
172
|
-
catch (err) {
|
|
173
|
-
process.stderr.write(`triage-aux-a parity: harness error -- ${String(err)}\n`);
|
|
174
|
-
process.exit(2);
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
|
-
//# sourceMappingURL=triage-aux-a-parity.js.map
|
|
107
|
+
//# sourceMappingURL=triage-aux-a-fixtures.js.map
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
1
|
export interface CommandCapture {
|
|
3
2
|
readonly exitCode: number;
|
|
4
3
|
readonly stdout: string;
|
|
@@ -27,6 +26,5 @@ export declare function normalizeOutput(text: string): string;
|
|
|
27
26
|
export declare function buildFixtureRepo(kind: "subscribe" | "bulk-empty" | "bulk-filter"): string;
|
|
28
27
|
export declare function diffCase(python: CommandCapture, ts: CommandCapture, caseName: string): ParityDiff;
|
|
29
28
|
export declare const PARITY_CASES: readonly ParityCase[];
|
|
30
|
-
export declare function runParity(): ParityResult;
|
|
31
29
|
export declare function renderReport(result: ParityResult): string;
|
|
32
|
-
//# sourceMappingURL=triage-aux-b-
|
|
30
|
+
//# sourceMappingURL=triage-aux-b-fixtures.d.ts.map
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
/** Test fixtures extracted from legacy parity harness (#2083). */
|
|
2
|
+
import { copyFileSync, mkdirSync, mkdtempSync, readdirSync, writeFileSync } from "node:fs";
|
|
3
|
+
import { tmpdir } from "node:os";
|
|
4
|
+
import { join } from "node:path";
|
|
5
|
+
export function normalizeOutput(text) {
|
|
6
|
+
return text
|
|
7
|
+
.replace(/project_root=[^\s)]+/g, "project_root=<ROOT>")
|
|
8
|
+
.replace(/\/tmp\/deft-[^\s/]+/g, "<TMPROOT>")
|
|
9
|
+
.replace(/change_id": "[^"]+"/g, 'change_id": "<UUID>"')
|
|
10
|
+
.replace(/Using CPython[^\n]*\n/g, "")
|
|
11
|
+
.replace(/Creating virtual environment[^\n]*\n/g, "")
|
|
12
|
+
.replace(/Installed \d+ packages[^\n]*\n/g, "");
|
|
13
|
+
}
|
|
14
|
+
function writeProjectDefinition(root, policy = {}) {
|
|
15
|
+
mkdirSync(join(root, "vbrief"), { recursive: true });
|
|
16
|
+
writeFileSync(join(root, "vbrief", "PROJECT-DEFINITION.vbrief.json"), `${JSON.stringify({
|
|
17
|
+
vBRIEFInfo: { version: "0.6" },
|
|
18
|
+
plan: { title: "T", status: "running", items: [], policy },
|
|
19
|
+
}, null, 2)}\n`, { encoding: "utf8" });
|
|
20
|
+
}
|
|
21
|
+
function populateCache(cacheRoot, repo, issues) {
|
|
22
|
+
const [owner, name] = repo.split("/");
|
|
23
|
+
if (owner === undefined || name === undefined) {
|
|
24
|
+
throw new Error(`invalid repo ${repo}`);
|
|
25
|
+
}
|
|
26
|
+
for (const issue of issues) {
|
|
27
|
+
const n = String(issue.number);
|
|
28
|
+
const entryDir = join(cacheRoot, "github-issue", owner, name, n);
|
|
29
|
+
mkdirSync(entryDir, { recursive: true });
|
|
30
|
+
writeFileSync(join(entryDir, "raw.json"), JSON.stringify(issue), { encoding: "utf8" });
|
|
31
|
+
writeFileSync(join(entryDir, "meta.json"), JSON.stringify({
|
|
32
|
+
source: "github-issue",
|
|
33
|
+
key: `${repo}/${n}`,
|
|
34
|
+
fetched_at: "2026-05-05T00:00:00Z",
|
|
35
|
+
ttl_seconds: 604800,
|
|
36
|
+
expires_at: "2099-01-01T00:00:00Z",
|
|
37
|
+
scan_result: {
|
|
38
|
+
passed: true,
|
|
39
|
+
scanned_at: "2026-05-05T00:00:00Z",
|
|
40
|
+
scanner_version: "2.0.0",
|
|
41
|
+
flags: [],
|
|
42
|
+
},
|
|
43
|
+
size_bytes: 100,
|
|
44
|
+
stale: false,
|
|
45
|
+
}), { encoding: "utf8" });
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
export function buildFixtureRepo(kind) {
|
|
49
|
+
const root = mkdtempSync(join(tmpdir(), "deft-triage-aux-b-parity-"));
|
|
50
|
+
if (kind === "subscribe") {
|
|
51
|
+
writeProjectDefinition(root);
|
|
52
|
+
return root;
|
|
53
|
+
}
|
|
54
|
+
if (kind === "bulk-empty") {
|
|
55
|
+
writeProjectDefinition(root);
|
|
56
|
+
mkdirSync(join(root, ".deft-cache"), { recursive: true });
|
|
57
|
+
return root;
|
|
58
|
+
}
|
|
59
|
+
writeProjectDefinition(root);
|
|
60
|
+
populateCache(join(root, ".deft-cache"), "deftai/parity", [
|
|
61
|
+
{
|
|
62
|
+
number: 99,
|
|
63
|
+
title: "parity issue",
|
|
64
|
+
labels: [{ name: "other-label" }],
|
|
65
|
+
author: { login: "bot" },
|
|
66
|
+
createdAt: "2020-01-01T00:00:00Z",
|
|
67
|
+
},
|
|
68
|
+
]);
|
|
69
|
+
return root;
|
|
70
|
+
}
|
|
71
|
+
const _PY_SCRIPT = {
|
|
72
|
+
help: "triage_help.py",
|
|
73
|
+
subscribe: "triage_subscribe.py",
|
|
74
|
+
bulk: "triage_bulk.py",
|
|
75
|
+
smoketest: "triage_smoketest.py",
|
|
76
|
+
};
|
|
77
|
+
const _TS_CLI = {
|
|
78
|
+
help: "triage-help.js",
|
|
79
|
+
subscribe: "triage-subscribe.js",
|
|
80
|
+
bulk: "triage-bulk.js",
|
|
81
|
+
smoketest: "triage-smoketest.js",
|
|
82
|
+
};
|
|
83
|
+
export function diffCase(python, ts, caseName) {
|
|
84
|
+
return {
|
|
85
|
+
caseName,
|
|
86
|
+
exitMismatch: python.exitCode !== ts.exitCode,
|
|
87
|
+
stdoutMismatch: normalizeOutput(python.stdout) !== normalizeOutput(ts.stdout),
|
|
88
|
+
stderrMismatch: normalizeOutput(python.stderr) !== normalizeOutput(ts.stderr),
|
|
89
|
+
pythonExit: python.exitCode,
|
|
90
|
+
tsExit: ts.exitCode,
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
export const PARITY_CASES = [
|
|
94
|
+
{ name: "help-triage-list", verb: "help", argv: ["triage"] },
|
|
95
|
+
{ name: "help-scope-list", verb: "help", argv: ["scope"] },
|
|
96
|
+
{ name: "help-verb-queue", verb: "help", argv: ["help", "task triage:queue"] },
|
|
97
|
+
{ name: "help-registry-list", verb: "help", argv: ["list"] },
|
|
98
|
+
{ name: "help-bulk-intercept", verb: "bulk", argv: ["accept", "--help"] },
|
|
99
|
+
{
|
|
100
|
+
name: "subscribe-label-create",
|
|
101
|
+
verb: "subscribe",
|
|
102
|
+
argv: ["subscribe", "--label", "area:parity"],
|
|
103
|
+
fixtureRoot: "subscribe",
|
|
104
|
+
},
|
|
105
|
+
{
|
|
106
|
+
name: "subscribe-label-idempotent",
|
|
107
|
+
verb: "subscribe",
|
|
108
|
+
argv: ["subscribe", "--label", "dup-label"],
|
|
109
|
+
fixtureRoot: "subscribe",
|
|
110
|
+
env: { DEFT_TRIAGE_ACTOR: "agent:parity" },
|
|
111
|
+
},
|
|
112
|
+
{
|
|
113
|
+
name: "subscribe-unsubscribe-missing",
|
|
114
|
+
verb: "subscribe",
|
|
115
|
+
argv: ["unsubscribe", "--label", "ghost"],
|
|
116
|
+
fixtureRoot: "subscribe",
|
|
117
|
+
},
|
|
118
|
+
{
|
|
119
|
+
name: "bulk-empty-cache",
|
|
120
|
+
verb: "bulk",
|
|
121
|
+
argv: ["accept", "--repo", "deftai/parity"],
|
|
122
|
+
fixtureRoot: "bulk-empty",
|
|
123
|
+
},
|
|
124
|
+
{
|
|
125
|
+
name: "bulk-zero-match",
|
|
126
|
+
verb: "bulk",
|
|
127
|
+
argv: ["defer", "--repo", "deftai/parity", "--label", "no-such-label"],
|
|
128
|
+
fixtureRoot: "bulk-filter",
|
|
129
|
+
},
|
|
130
|
+
{
|
|
131
|
+
name: "smoketest-missing-fixture",
|
|
132
|
+
verb: "smoketest",
|
|
133
|
+
argv: ["--fixture", "/nonexistent/deft-smoketest-fixture"],
|
|
134
|
+
},
|
|
135
|
+
];
|
|
136
|
+
function _cpRecursive(src, dest) {
|
|
137
|
+
mkdirSync(dest, { recursive: true });
|
|
138
|
+
for (const entry of readdirSync(src, { withFileTypes: true })) {
|
|
139
|
+
const s = join(src, entry.name);
|
|
140
|
+
const d = join(dest, entry.name);
|
|
141
|
+
if (entry.isDirectory()) {
|
|
142
|
+
_cpRecursive(s, d);
|
|
143
|
+
}
|
|
144
|
+
else {
|
|
145
|
+
copyFileSync(s, d);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
export function renderReport(result) {
|
|
150
|
+
if (result.ok) {
|
|
151
|
+
return `triage-aux-b parity: CLEAN -- Python and TS agree on ${PARITY_CASES.length} cases.`;
|
|
152
|
+
}
|
|
153
|
+
const lines = ["triage-aux-b parity: DIVERGENCE"];
|
|
154
|
+
for (const d of result.diffs) {
|
|
155
|
+
if (d.exitMismatch || d.stdoutMismatch || d.stderrMismatch) {
|
|
156
|
+
lines.push(` case: ${d.caseName}`);
|
|
157
|
+
if (d.exitMismatch)
|
|
158
|
+
lines.push(` exit: python=${d.pythonExit} ts=${d.tsExit}`);
|
|
159
|
+
if (d.stdoutMismatch)
|
|
160
|
+
lines.push(" stdout mismatch");
|
|
161
|
+
if (d.stderrMismatch)
|
|
162
|
+
lines.push(" stderr mismatch");
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
return lines.join("\n");
|
|
166
|
+
}
|
|
167
|
+
//# sourceMappingURL=triage-aux-b-fixtures.js.map
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
1
|
export interface CommandCapture {
|
|
3
2
|
readonly exitCode: number;
|
|
4
3
|
readonly stdout: string;
|
|
@@ -39,6 +38,5 @@ export declare function buildFixtureRepo(options?: FixtureOptions): string;
|
|
|
39
38
|
export declare function diffCase(python: CommandCapture, ts: CommandCapture, caseName: string): ParityDiff;
|
|
40
39
|
export declare const PARITY_CASES: readonly ParityCase[];
|
|
41
40
|
/** Run all parity cases; returns aggregate result. */
|
|
42
|
-
export declare function runParity(): ParityResult;
|
|
43
41
|
export declare function renderReport(result: ParityResult): string;
|
|
44
|
-
//# sourceMappingURL=triage-bootstrap-
|
|
42
|
+
//# sourceMappingURL=triage-bootstrap-fixtures.d.ts.map
|
|
@@ -1,16 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
* Golden-output parity harness (#1725): builds throwaway fixture repos, runs
|
|
4
|
-
* BOTH the Python oracle (`scripts/triage_bootstrap.py`) and the ported TS
|
|
5
|
-
* triage:bootstrap CLI, and diffs exit codes + stdout/stderr (cache-off).
|
|
6
|
-
*
|
|
7
|
-
* Exit codes: 0 parity / 1 divergence / 2 harness setup error.
|
|
8
|
-
*/
|
|
9
|
-
import { spawnSync } from "node:child_process";
|
|
10
|
-
import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from "node:fs";
|
|
1
|
+
/** Test fixtures extracted from legacy parity harness (#2083). */
|
|
2
|
+
import { mkdirSync, mkdtempSync, writeFileSync } from "node:fs";
|
|
11
3
|
import { tmpdir } from "node:os";
|
|
12
|
-
import {
|
|
13
|
-
import { fileURLToPath } from "node:url";
|
|
4
|
+
import { join } from "node:path";
|
|
14
5
|
/** Strip volatile absolute paths before compare. */
|
|
15
6
|
export function normalizeOutput(text) {
|
|
16
7
|
return text
|
|
@@ -61,24 +52,6 @@ export function normalizeStdout(text) {
|
|
|
61
52
|
}
|
|
62
53
|
return normalizeOutput(text);
|
|
63
54
|
}
|
|
64
|
-
function runCapture(cmd, args, cwd, env = {}) {
|
|
65
|
-
const merged = { ...process.env, ...env };
|
|
66
|
-
for (const key of Object.keys(merged)) {
|
|
67
|
-
if (merged[key] === undefined)
|
|
68
|
-
delete merged[key];
|
|
69
|
-
}
|
|
70
|
-
const result = spawnSync(cmd, args, {
|
|
71
|
-
cwd,
|
|
72
|
-
encoding: "utf8",
|
|
73
|
-
env: merged,
|
|
74
|
-
stdio: ["ignore", "pipe", "pipe"],
|
|
75
|
-
});
|
|
76
|
-
return {
|
|
77
|
-
status: result.status ?? 2,
|
|
78
|
-
stdout: typeof result.stdout === "string" ? result.stdout : "",
|
|
79
|
-
stderr: typeof result.stderr === "string" ? result.stderr : "",
|
|
80
|
-
};
|
|
81
|
-
}
|
|
82
55
|
function writeScopeVbrief(root, folder, slug, issueNumber) {
|
|
83
56
|
const dir = join(root, "vbrief", folder);
|
|
84
57
|
mkdirSync(dir, { recursive: true });
|
|
@@ -106,28 +79,6 @@ export function buildFixtureRepo(options = {}) {
|
|
|
106
79
|
}
|
|
107
80
|
return root;
|
|
108
81
|
}
|
|
109
|
-
function resolveDeftRoot() {
|
|
110
|
-
if (process.env.DEFT_ROOT !== undefined && process.env.DEFT_ROOT.length > 0) {
|
|
111
|
-
return resolve(process.env.DEFT_ROOT);
|
|
112
|
-
}
|
|
113
|
-
return resolve(dirname(fileURLToPath(import.meta.url)), "..", "..", "..");
|
|
114
|
-
}
|
|
115
|
-
function runPythonBootstrap(deftRoot, repo, argv) {
|
|
116
|
-
const args = ["run", "python", join(deftRoot, "scripts", "triage_bootstrap.py"), ...argv];
|
|
117
|
-
if (!argv.some((a) => a === "--project-root" || a.startsWith("--project-root="))) {
|
|
118
|
-
args.push("--project-root", repo);
|
|
119
|
-
}
|
|
120
|
-
const cap = runCapture("uv", args, deftRoot);
|
|
121
|
-
return { exitCode: cap.status, stdout: cap.stdout, stderr: cap.stderr };
|
|
122
|
-
}
|
|
123
|
-
function runTsBootstrap(deftRoot, repo, argv) {
|
|
124
|
-
const args = [join(deftRoot, "packages", "cli", "dist", "triage-bootstrap.js"), ...argv];
|
|
125
|
-
if (!argv.some((a) => a === "--project-root" || a.startsWith("--project-root="))) {
|
|
126
|
-
args.push("--project-root", repo);
|
|
127
|
-
}
|
|
128
|
-
const cap = runCapture("node", args, deftRoot);
|
|
129
|
-
return { exitCode: cap.status, stdout: cap.stdout, stderr: cap.stderr };
|
|
130
|
-
}
|
|
131
82
|
/** Diff one parity case between Python oracle and TS CLI. */
|
|
132
83
|
export function diffCase(python, ts, caseName) {
|
|
133
84
|
const pyOut = normalizeStdout(python.stdout);
|
|
@@ -167,29 +118,6 @@ export const PARITY_CASES = [
|
|
|
167
118
|
},
|
|
168
119
|
];
|
|
169
120
|
/** Run all parity cases; returns aggregate result. */
|
|
170
|
-
export function runParity() {
|
|
171
|
-
const deftRoot = resolveDeftRoot();
|
|
172
|
-
const diffs = [];
|
|
173
|
-
for (const testCase of PARITY_CASES) {
|
|
174
|
-
const pyRepo = buildFixtureRepo(testCase.fixture ?? {});
|
|
175
|
-
const tsRepo = buildFixtureRepo(testCase.fixture ?? {});
|
|
176
|
-
try {
|
|
177
|
-
if (testCase.fixture?.preRunBootstrap === true) {
|
|
178
|
-
runPythonBootstrap(deftRoot, pyRepo, ["--quiet"]);
|
|
179
|
-
runTsBootstrap(deftRoot, tsRepo, ["--quiet"]);
|
|
180
|
-
}
|
|
181
|
-
const python = runPythonBootstrap(deftRoot, pyRepo, testCase.argv);
|
|
182
|
-
const ts = runTsBootstrap(deftRoot, tsRepo, testCase.argv);
|
|
183
|
-
diffs.push(diffCase(python, ts, testCase.name));
|
|
184
|
-
}
|
|
185
|
-
finally {
|
|
186
|
-
rmSync(pyRepo, { recursive: true, force: true });
|
|
187
|
-
rmSync(tsRepo, { recursive: true, force: true });
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
const ok = diffs.every((d) => !d.exitMismatch && !d.stdoutMismatch && !d.stderrMismatch);
|
|
191
|
-
return { ok, diffs };
|
|
192
|
-
}
|
|
193
121
|
export function renderReport(result) {
|
|
194
122
|
if (result.ok) {
|
|
195
123
|
return `triage:bootstrap parity: CLEAN -- Python and TS agree on ${PARITY_CASES.length} cases.`;
|
|
@@ -208,19 +136,4 @@ export function renderReport(result) {
|
|
|
208
136
|
}
|
|
209
137
|
return lines.join("\n");
|
|
210
138
|
}
|
|
211
|
-
|
|
212
|
-
try {
|
|
213
|
-
const result = runParity();
|
|
214
|
-
if (result.ok) {
|
|
215
|
-
process.stdout.write(`${renderReport(result)}\n`);
|
|
216
|
-
process.exit(0);
|
|
217
|
-
}
|
|
218
|
-
process.stderr.write(`${renderReport(result)}\n`);
|
|
219
|
-
process.exit(1);
|
|
220
|
-
}
|
|
221
|
-
catch (err) {
|
|
222
|
-
process.stderr.write(`triage:bootstrap parity: harness error -- ${String(err)}\n`);
|
|
223
|
-
process.exit(2);
|
|
224
|
-
}
|
|
225
|
-
}
|
|
226
|
-
//# sourceMappingURL=triage-bootstrap-parity.js.map
|
|
139
|
+
//# sourceMappingURL=triage-bootstrap-fixtures.js.map
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
1
|
export interface CommandCapture {
|
|
3
2
|
readonly exitCode: number;
|
|
4
3
|
readonly stdout: string;
|
|
@@ -35,6 +34,5 @@ export declare function buildFixtureRepo(options?: FixtureOptions): string;
|
|
|
35
34
|
export declare function diffCase(python: CommandCapture, ts: CommandCapture, caseName: string): ParityDiff;
|
|
36
35
|
export declare const PARITY_CASES: readonly ParityCase[];
|
|
37
36
|
/** Run all parity cases; returns aggregate result. */
|
|
38
|
-
export declare function runParity(): ParityResult;
|
|
39
37
|
export declare function renderReport(result: ParityResult): string;
|
|
40
|
-
//# sourceMappingURL=triage-classify-
|
|
38
|
+
//# sourceMappingURL=triage-classify-fixtures.d.ts.map
|
|
@@ -1,16 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
* Golden-output parity harness (#1725): runs BOTH the Python oracle
|
|
4
|
-
* (`scripts/triage_classify.py`) and the ported TS triage-classify CLI with
|
|
5
|
-
* identical argv, then diffs exit codes and normalised stdout/stderr.
|
|
6
|
-
*
|
|
7
|
-
* Exit codes: 0 parity / 1 divergence / 2 harness setup error.
|
|
8
|
-
*/
|
|
9
|
-
import { spawnSync } from "node:child_process";
|
|
10
|
-
import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from "node:fs";
|
|
1
|
+
/** Test fixtures extracted from legacy parity harness (#2083). */
|
|
2
|
+
import { mkdirSync, mkdtempSync, writeFileSync } from "node:fs";
|
|
11
3
|
import { tmpdir } from "node:os";
|
|
12
|
-
import {
|
|
13
|
-
import { fileURLToPath } from "node:url";
|
|
4
|
+
import { join } from "node:path";
|
|
14
5
|
/** Strip volatile absolute paths before compare. */
|
|
15
6
|
export function normalizeOutput(text) {
|
|
16
7
|
return (text
|
|
@@ -19,24 +10,6 @@ export function normalizeOutput(text) {
|
|
|
19
10
|
// (/tmp on Linux, /var/folders/... on macOS, etc.).
|
|
20
11
|
.replace(/\S*deft-triage-classify-parity-[^\s/]+/g, "<TMPROOT>"));
|
|
21
12
|
}
|
|
22
|
-
function runCapture(cmd, args, cwd, env = {}) {
|
|
23
|
-
const merged = { ...process.env, ...env };
|
|
24
|
-
for (const key of Object.keys(merged)) {
|
|
25
|
-
if (merged[key] === undefined)
|
|
26
|
-
delete merged[key];
|
|
27
|
-
}
|
|
28
|
-
const result = spawnSync(cmd, args, {
|
|
29
|
-
cwd,
|
|
30
|
-
encoding: "utf8",
|
|
31
|
-
env: merged,
|
|
32
|
-
stdio: ["ignore", "pipe", "pipe"],
|
|
33
|
-
});
|
|
34
|
-
return {
|
|
35
|
-
status: result.status ?? 2,
|
|
36
|
-
stdout: typeof result.stdout === "string" ? result.stdout : "",
|
|
37
|
-
stderr: typeof result.stderr === "string" ? result.stderr : "",
|
|
38
|
-
};
|
|
39
|
-
}
|
|
40
13
|
function writeProjectDefinition(root, plan) {
|
|
41
14
|
const dir = join(root, "vbrief");
|
|
42
15
|
mkdirSync(dir, { recursive: true });
|
|
@@ -60,32 +33,6 @@ export function buildFixtureRepo(options = {}) {
|
|
|
60
33
|
}
|
|
61
34
|
return root;
|
|
62
35
|
}
|
|
63
|
-
function resolveDeftRoot() {
|
|
64
|
-
if (process.env.DEFT_ROOT !== undefined && process.env.DEFT_ROOT.length > 0) {
|
|
65
|
-
return resolve(process.env.DEFT_ROOT);
|
|
66
|
-
}
|
|
67
|
-
return resolve(dirname(fileURLToPath(import.meta.url)), "..", "..", "..");
|
|
68
|
-
}
|
|
69
|
-
function runPythonClassify(deftRoot, repo, argv) {
|
|
70
|
-
const cap = runCapture("uv", [
|
|
71
|
-
"run",
|
|
72
|
-
"python",
|
|
73
|
-
join(deftRoot, "scripts", "triage_classify.py"),
|
|
74
|
-
...argv,
|
|
75
|
-
"--project-root",
|
|
76
|
-
repo,
|
|
77
|
-
], deftRoot);
|
|
78
|
-
return { exitCode: cap.status, stdout: cap.stdout, stderr: cap.stderr };
|
|
79
|
-
}
|
|
80
|
-
function runTsClassify(deftRoot, repo, argv) {
|
|
81
|
-
const cap = runCapture("node", [
|
|
82
|
-
join(deftRoot, "packages", "cli", "dist", "triage-classify.js"),
|
|
83
|
-
...argv,
|
|
84
|
-
"--project-root",
|
|
85
|
-
repo,
|
|
86
|
-
], deftRoot);
|
|
87
|
-
return { exitCode: cap.status, stdout: cap.stdout, stderr: cap.stderr };
|
|
88
|
-
}
|
|
89
36
|
/** Diff one parity case between Python oracle and TS CLI. */
|
|
90
37
|
export function diffCase(python, ts, caseName) {
|
|
91
38
|
const pyOut = normalizeOutput(python.stdout);
|
|
@@ -169,28 +116,6 @@ export const PARITY_CASES = [
|
|
|
169
116
|
},
|
|
170
117
|
];
|
|
171
118
|
/** Run all parity cases; returns aggregate result. */
|
|
172
|
-
export function runParity() {
|
|
173
|
-
const deftRoot = resolveDeftRoot();
|
|
174
|
-
const diffs = [];
|
|
175
|
-
for (const testCase of PARITY_CASES) {
|
|
176
|
-
const pyRepo = testCase.useRepoRoot === true ? deftRoot : buildFixtureRepo(testCase.fixture ?? {});
|
|
177
|
-
const tsRepo = testCase.useRepoRoot === true ? deftRoot : buildFixtureRepo(testCase.fixture ?? {});
|
|
178
|
-
const ownsFixture = testCase.useRepoRoot !== true;
|
|
179
|
-
try {
|
|
180
|
-
const python = runPythonClassify(deftRoot, pyRepo, testCase.argv);
|
|
181
|
-
const ts = runTsClassify(deftRoot, tsRepo, testCase.argv);
|
|
182
|
-
diffs.push(diffCase(python, ts, testCase.name));
|
|
183
|
-
}
|
|
184
|
-
finally {
|
|
185
|
-
if (ownsFixture) {
|
|
186
|
-
rmSync(pyRepo, { recursive: true, force: true });
|
|
187
|
-
rmSync(tsRepo, { recursive: true, force: true });
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
}
|
|
191
|
-
const ok = diffs.every((d) => !d.exitMismatch && !d.stdoutMismatch && !d.stderrMismatch);
|
|
192
|
-
return { ok, diffs };
|
|
193
|
-
}
|
|
194
119
|
export function renderReport(result) {
|
|
195
120
|
if (result.ok) {
|
|
196
121
|
return `triage:classify parity: CLEAN -- Python and TS agree on ${PARITY_CASES.length} cases.`;
|
|
@@ -209,19 +134,4 @@ export function renderReport(result) {
|
|
|
209
134
|
}
|
|
210
135
|
return lines.join("\n");
|
|
211
136
|
}
|
|
212
|
-
|
|
213
|
-
try {
|
|
214
|
-
const result = runParity();
|
|
215
|
-
if (result.ok) {
|
|
216
|
-
process.stdout.write(`${renderReport(result)}\n`);
|
|
217
|
-
process.exit(0);
|
|
218
|
-
}
|
|
219
|
-
process.stderr.write(`${renderReport(result)}\n`);
|
|
220
|
-
process.exit(1);
|
|
221
|
-
}
|
|
222
|
-
catch (err) {
|
|
223
|
-
process.stderr.write(`triage:classify parity: harness error -- ${String(err)}\n`);
|
|
224
|
-
process.exit(2);
|
|
225
|
-
}
|
|
226
|
-
}
|
|
227
|
-
//# sourceMappingURL=triage-classify-parity.js.map
|
|
137
|
+
//# sourceMappingURL=triage-classify-fixtures.js.map
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
1
|
export interface CommandCapture {
|
|
3
2
|
readonly exitCode: number;
|
|
4
3
|
readonly stdout: string;
|
|
@@ -54,6 +53,5 @@ export declare const PARITY_CASES: readonly ParityCase[];
|
|
|
54
53
|
/** Augment argv with fixture audit/slices hooks when present. */
|
|
55
54
|
export declare function augmentParityArgv(testCase: ParityCase, root: string): readonly string[];
|
|
56
55
|
/** Run all parity cases; returns aggregate result. */
|
|
57
|
-
export declare function runParity(): ParityResult;
|
|
58
56
|
export declare function renderReport(result: ParityResult): string;
|
|
59
|
-
//# sourceMappingURL=triage-queue-
|
|
57
|
+
//# sourceMappingURL=triage-queue-fixtures.d.ts.map
|