@deftai/directive 0.72.0 → 0.73.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/branch-fixtures.js +3 -3
- package/dist/dispatch.d.ts +2 -0
- package/dist/dispatch.js +24 -10
- package/dist/doctor.d.ts +1 -1
- package/dist/doctor.js +4 -3
- package/dist/gates-cli/_helpers.js +3 -3
- package/dist/policy-fixtures.js +4 -4
- package/dist/policy.js +9 -7
- package/dist/story-ready-fixtures.js +9 -9
- package/dist/triage-aux-a-fixtures.js +3 -3
- package/dist/triage-aux-b-fixtures.js +3 -3
- package/dist/triage-bootstrap-fixtures.d.ts +1 -1
- package/dist/triage-bootstrap-fixtures.js +6 -6
- package/dist/triage-classify-fixtures.js +6 -6
- package/dist/triage-queue-fixtures.js +13 -13
- package/dist/triage-scope-fixtures.js +4 -4
- package/dist/vbrief-preflight-fixtures.js +1 -1
- package/dist/wip-cap-fixtures.js +9 -9
- package/package.json +3 -3
package/dist/branch-fixtures.js
CHANGED
|
@@ -16,10 +16,10 @@ function gitCommit(cwd, message) {
|
|
|
16
16
|
});
|
|
17
17
|
}
|
|
18
18
|
function writeProjectDef(root, plan) {
|
|
19
|
-
const dir = join(root, "
|
|
19
|
+
const dir = join(root, "xbrief");
|
|
20
20
|
mkdirSync(dir, { recursive: true });
|
|
21
|
-
writeFileSync(join(dir, "PROJECT-DEFINITION.
|
|
22
|
-
|
|
21
|
+
writeFileSync(join(dir, "PROJECT-DEFINITION.xbrief.json"), `${JSON.stringify({
|
|
22
|
+
xBRIEFInfo: { version: "0.8" },
|
|
23
23
|
plan: { title: "T", status: "running", items: [], ...plan },
|
|
24
24
|
}, null, 2)}\n`, { encoding: "utf8" });
|
|
25
25
|
}
|
package/dist/dispatch.d.ts
CHANGED
|
@@ -15,6 +15,8 @@ export declare const CLI_MODULE_VERBS: readonly ["agents-refresh", "cache", "che
|
|
|
15
15
|
export declare const CORE_MODULE_VERBS: readonly ["scm", "github-auth-modes", "github-body", "issue-emit", "issue-ingest", "reconcile-issues", "swarm-launch", "swarm-complete-cohort", "swarm-finalize-cohort", "swarm-readiness", "swarm-routing-verify", "swarm-routing-set", "swarm-verify-review-clean", "swarm-worktrees", "framework-commands", "pack-render", "packs-slice", "prd-render", "export-spec", "project-render", "roadmap-render", "spec-render", "spec-validate", "code-structure-validate", "pack-migrate-skills", "pack-migrate-rules", "pack-migrate-strategies", "pack-migrate-patterns", "pack-migrate-swarm-spec", "policy-set", "setup-ghx", "scope-undo", "scope-demote", "scope-decompose", "changelog-resolve-unreleased", "architecture-preflight-sor", "feedback-file", "value-readback"];
|
|
16
16
|
/** Colon aliases for triage-actions (mirrors cli-router SUBCOMMAND_ROUTES). */
|
|
17
17
|
export declare const TRIAGE_ACTION_ALIAS_SUBCOMMANDS: Readonly<Record<string, string>>;
|
|
18
|
+
/** Colon aliases for policy subcommands (mirrors cli-router SUBCOMMAND_ROUTES). */
|
|
19
|
+
export declare const POLICY_ACTION_ALIAS_SUBCOMMANDS: Readonly<Record<string, string>>;
|
|
18
20
|
/** Task-style aliases (framework_commands / Taskfile names). */
|
|
19
21
|
export declare const VERB_ALIASES: Readonly<Record<string, string>>;
|
|
20
22
|
/** Pinned ghx version (display only) — keep in lockstep with .github/workflows/ci.yml env.GHX_VERSION. */
|
package/dist/dispatch.js
CHANGED
|
@@ -9,7 +9,7 @@ import { homedir, tmpdir } from "node:os";
|
|
|
9
9
|
import { basename, dirname, isAbsolute, join, relative, resolve } from "node:path";
|
|
10
10
|
import { engineInfo, userConfig } from "@deftai/directive-core";
|
|
11
11
|
import { parseInitArgv, runInitDepositCli } from "@deftai/directive-core/init-deposit";
|
|
12
|
-
import { appendAuditLog, disclosureLine, migrateLegacyPolicyKey, PLAN_POLICY_KEY, projectDefinitionPath, resolvePolicy, resolveWipCap, setPolicy, } from "@deftai/directive-core/policy";
|
|
12
|
+
import { appendAuditLog, disclosureLine, migrateLegacyPolicyKey, PLAN_POLICY_KEY, policyColonInvocation, policySetInvocation, projectDefinitionPath, resolvePolicy, resolveWipCap, setPolicy, } from "@deftai/directive-core/policy";
|
|
13
13
|
import { defaultWhich } from "@deftai/directive-core/scm";
|
|
14
14
|
import { KNOWN_SUBAGENT_BACKEND_IDS, probeSubagentBackends, resolveSwarmSubagentBackend, } from "@deftai/directive-core/swarm";
|
|
15
15
|
const HANDLER_KEYS = [
|
|
@@ -168,6 +168,14 @@ export const TRIAGE_ACTION_ALIAS_SUBCOMMANDS = {
|
|
|
168
168
|
"triage:history": "history",
|
|
169
169
|
};
|
|
170
170
|
const TRIAGE_ACTION_COLON_ALIASES = Object.fromEntries(Object.keys(TRIAGE_ACTION_ALIAS_SUBCOMMANDS).map((alias) => [alias, "triage-actions"]));
|
|
171
|
+
/** Colon aliases for policy subcommands (mirrors cli-router SUBCOMMAND_ROUTES). */
|
|
172
|
+
export const POLICY_ACTION_ALIAS_SUBCOMMANDS = {
|
|
173
|
+
"policy:show": "show",
|
|
174
|
+
"policy:enforce-branches": "enforce-branches",
|
|
175
|
+
"policy:allow-direct-commits": "allow-direct-commits",
|
|
176
|
+
"policy:enable-value-feedback": "enable-value-feedback",
|
|
177
|
+
};
|
|
178
|
+
const POLICY_ACTION_COLON_ALIASES = Object.fromEntries(Object.keys(POLICY_ACTION_ALIAS_SUBCOMMANDS).map((alias) => [alias, "policy"]));
|
|
171
179
|
/** Task-style aliases (framework_commands / Taskfile names). */
|
|
172
180
|
export const VERB_ALIASES = {
|
|
173
181
|
"verify:encoding": "verify-encoding",
|
|
@@ -211,6 +219,7 @@ export const VERB_ALIASES = {
|
|
|
211
219
|
"triage:queue": "triage-queue",
|
|
212
220
|
"triage:scope": "triage-scope",
|
|
213
221
|
...TRIAGE_ACTION_COLON_ALIASES,
|
|
222
|
+
...POLICY_ACTION_COLON_ALIASES,
|
|
214
223
|
"agents:refresh": "agents-refresh",
|
|
215
224
|
"migrate:preflight": "migrate-preflight",
|
|
216
225
|
"migrate:xbrief": "migrate-xbrief",
|
|
@@ -1747,7 +1756,9 @@ const POLICY_CAPABILITY_COST_DISCLOSURE = "\u26a0 Capability-cost disclosure --
|
|
|
1747
1756
|
" \u2022 verify:branch will pass on the default branch.\n" +
|
|
1748
1757
|
" \u2022 The CI sanity check (head_ref != base_ref) is still independent and " +
|
|
1749
1758
|
"will continue to flag master->master PRs.\n" +
|
|
1750
|
-
" \u2022 This change is reversible: run `
|
|
1759
|
+
" \u2022 This change is reversible: run `" +
|
|
1760
|
+
policyColonInvocation("enforce-branches") +
|
|
1761
|
+
"` to " +
|
|
1751
1762
|
"re-enable the gate.\n" +
|
|
1752
1763
|
" \u2022 The change is recorded to meta/policy-changes.log for auditability.";
|
|
1753
1764
|
const POLICY_WIP_CAP_DISCLOSURE = "\u26a0 Capability-cost disclosure -- changing plan.policy.wipCap " +
|
|
@@ -1802,15 +1813,15 @@ function sanitizeNote(note) {
|
|
|
1802
1813
|
function defaultPolicySetActor(cmd) {
|
|
1803
1814
|
switch (cmd) {
|
|
1804
1815
|
case "enforce-branches":
|
|
1805
|
-
return "
|
|
1816
|
+
return policyColonInvocation("enforce-branches");
|
|
1806
1817
|
case "allow-direct-commits":
|
|
1807
|
-
return "
|
|
1818
|
+
return policyColonInvocation("allow-direct-commits");
|
|
1808
1819
|
case "wip-cap":
|
|
1809
|
-
return "
|
|
1820
|
+
return policySetInvocation("wip-cap");
|
|
1810
1821
|
case "subagent-backend":
|
|
1811
|
-
return "
|
|
1822
|
+
return policySetInvocation("subagent-backend");
|
|
1812
1823
|
case "subagent-backends":
|
|
1813
|
-
return "
|
|
1824
|
+
return policySetInvocation("subagent-backends");
|
|
1814
1825
|
}
|
|
1815
1826
|
}
|
|
1816
1827
|
/** Mirror Python `Path(...).expanduser()` for a leading `~` / `~/` segment. */
|
|
@@ -2027,7 +2038,7 @@ function applyBranchPolicy(args, io) {
|
|
|
2027
2038
|
if (!args.confirm) {
|
|
2028
2039
|
io.writeOut(`${POLICY_CAPABILITY_COST_DISCLOSURE}\n`);
|
|
2029
2040
|
io.writeOut("\n");
|
|
2030
|
-
io.writeOut(
|
|
2041
|
+
io.writeOut(`Re-run with --confirm to apply: ${policyColonInvocation("allow-direct-commits", " -- --confirm")}\n`);
|
|
2031
2042
|
return 1;
|
|
2032
2043
|
}
|
|
2033
2044
|
target = true;
|
|
@@ -2071,7 +2082,7 @@ function applyWipCap(args, io) {
|
|
|
2071
2082
|
if (!args.confirm) {
|
|
2072
2083
|
io.writeOut(`${POLICY_WIP_CAP_DISCLOSURE}\n`);
|
|
2073
2084
|
io.writeOut("\n");
|
|
2074
|
-
io.writeOut(`Re-run with --confirm to apply:
|
|
2085
|
+
io.writeOut(`Re-run with --confirm to apply: ${policySetInvocation("wip-cap", ` -- --set ${cap} --confirm`)}\n`);
|
|
2075
2086
|
return 1;
|
|
2076
2087
|
}
|
|
2077
2088
|
let res;
|
|
@@ -2401,11 +2412,14 @@ export async function dispatch(argv, io = defaultIo()) {
|
|
|
2401
2412
|
try {
|
|
2402
2413
|
const handler = await loadHandler(canonical, io);
|
|
2403
2414
|
const triageSubcommand = verb !== undefined ? TRIAGE_ACTION_ALIAS_SUBCOMMANDS[verb] : undefined;
|
|
2415
|
+
const policySubcommand = verb !== undefined ? POLICY_ACTION_ALIAS_SUBCOMMANDS[verb] : undefined;
|
|
2404
2416
|
const handlerArgv = canonical === "framework-commands" && verb !== undefined && verb !== canonical
|
|
2405
2417
|
? [verb, ...rest]
|
|
2406
2418
|
: triageSubcommand !== undefined && canonical === "triage-actions"
|
|
2407
2419
|
? [triageSubcommand, ...rest]
|
|
2408
|
-
:
|
|
2420
|
+
: policySubcommand !== undefined && canonical === "policy"
|
|
2421
|
+
? [policySubcommand, ...rest]
|
|
2422
|
+
: rest;
|
|
2409
2423
|
return await invokeHandler(handler, handlerArgv);
|
|
2410
2424
|
}
|
|
2411
2425
|
catch (err) {
|
package/dist/doctor.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
/** Advisory when a consumer deposit carries git-vendored framework source (#2142). */
|
|
2
|
+
/** Advisory when a consumer deposit carries git-vendored framework source (#2142 / #2347). */
|
|
3
3
|
export declare function renderStrayPackagesAdvisoryLine(projectRoot: string): string;
|
|
4
4
|
export declare function run(argv: string[]): number;
|
|
5
5
|
//# sourceMappingURL=doctor.d.ts.map
|
package/dist/doctor.js
CHANGED
|
@@ -6,15 +6,16 @@ import { parseDoctorFlags } from "@deftai/directive-core/dist/doctor/flags.js";
|
|
|
6
6
|
import { cmdDoctor } from "@deftai/directive-core/dist/doctor/main.js";
|
|
7
7
|
import { renderPrecutoverLine } from "@deftai/directive-core/dist/vbrief-validate/precutover.js";
|
|
8
8
|
import { renderStaleHeaderLine, renderXbriefMigrationLine, } from "@deftai/directive-core/xbrief-migrate";
|
|
9
|
-
/** Advisory when a consumer deposit carries git-vendored framework source (#2142). */
|
|
9
|
+
/** Advisory when a consumer deposit carries git-vendored framework source (#2142 / #2347). */
|
|
10
10
|
export function renderStrayPackagesAdvisoryLine(projectRoot) {
|
|
11
11
|
const packagesDir = join(projectRoot, ".deft", "core", "packages");
|
|
12
12
|
if (!existsSync(packagesDir)) {
|
|
13
13
|
return "Deposit hygiene: none -- .deft/core contains no stray packages/ source tree.";
|
|
14
14
|
}
|
|
15
15
|
return ("Deposit hygiene: advisory -- .deft/core/packages/ is present (git-vendored framework source, " +
|
|
16
|
-
"not shipped by npm @deftai/directive-content).
|
|
17
|
-
"
|
|
16
|
+
"not shipped by npm @deftai/directive-content). " +
|
|
17
|
+
"Run `directive update` to auto-prune this stray tree, then commit the result (#2347). " +
|
|
18
|
+
"Or remove it manually: `git rm -r --cached .deft/core/packages && git commit -m 'chore: remove stray framework source'`.");
|
|
18
19
|
}
|
|
19
20
|
export function run(argv) {
|
|
20
21
|
// #2022: surface pre-cutover (pre-v0.20 document model) migration state alongside the
|
|
@@ -56,9 +56,9 @@ export function initGitRepo(root) {
|
|
|
56
56
|
return execFileSync("git", ["rev-parse", "HEAD"], { cwd: root, encoding: "utf8" }).trim();
|
|
57
57
|
}
|
|
58
58
|
export function writeProjectDef(root, policy = {}) {
|
|
59
|
-
mkdirSync(join(root, "
|
|
60
|
-
writeFileSync(join(root, "
|
|
61
|
-
|
|
59
|
+
mkdirSync(join(root, "xbrief"), { recursive: true });
|
|
60
|
+
writeFileSync(join(root, "xbrief", "PROJECT-DEFINITION.xbrief.json"), JSON.stringify({
|
|
61
|
+
xBRIEFInfo: { version: "0.8" },
|
|
62
62
|
plan: { title: "T", status: "running", items: [], policy },
|
|
63
63
|
}), "utf8");
|
|
64
64
|
}
|
package/dist/policy-fixtures.js
CHANGED
|
@@ -10,17 +10,17 @@ export function normalizeOutput(text) {
|
|
|
10
10
|
.replace(/fail-closed: PROJECT-DEFINITION not found at [^)]+/g, "fail-closed: PROJECT-DEFINITION not found at <ROOT>");
|
|
11
11
|
}
|
|
12
12
|
function writeFixture(root, plan) {
|
|
13
|
-
const dir = join(root, "
|
|
13
|
+
const dir = join(root, "xbrief");
|
|
14
14
|
mkdirSync(dir, { recursive: true });
|
|
15
|
-
writeFileSync(join(dir, "PROJECT-DEFINITION.
|
|
16
|
-
|
|
15
|
+
writeFileSync(join(dir, "PROJECT-DEFINITION.xbrief.json"), `${JSON.stringify({
|
|
16
|
+
xBRIEFInfo: { version: "0.8" },
|
|
17
17
|
plan: { title: "T", status: "running", items: [], ...plan },
|
|
18
18
|
}, null, 2)}\n`, { encoding: "utf8" });
|
|
19
19
|
}
|
|
20
20
|
/** Build a throwaway project root with optional PROJECT-DEFINITION plan payload. */
|
|
21
21
|
export function buildFixtureRepo(plan) {
|
|
22
22
|
const root = mkdtempSync(join(tmpdir(), "deft-policy-parity-"));
|
|
23
|
-
mkdirSync(join(root, "
|
|
23
|
+
mkdirSync(join(root, "xbrief"), { recursive: true });
|
|
24
24
|
if (plan !== undefined) {
|
|
25
25
|
writeFixture(root, plan);
|
|
26
26
|
}
|
package/dist/policy.js
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
import { existsSync } from "node:fs";
|
|
7
7
|
import { resolve as pathResolve, relative } from "node:path";
|
|
8
8
|
import { fileURLToPath } from "node:url";
|
|
9
|
-
import { describeShadowedPlanExtension, detectShadowedPlanExtensions, disclosureLine, enableValueFeedback, FIELD_VALUE_FEEDBACK, FIELD_VALUE_FEEDBACK_CLI_ALIAS, formatValueFeedbackStatusLine, inspectAllPolicies, inspectOnePolicy, loadProjectDefinition, projectDefinitionPath, pythonListRepr, pythonStringRepr, registeredPolicyNames, renderJson, renderText, resolvePolicy, resolveValueFeedback, setPolicy, } from "@deftai/directive-core/policy";
|
|
9
|
+
import { describeShadowedPlanExtension, detectShadowedPlanExtensions, disclosureLine, enableValueFeedback, FIELD_VALUE_FEEDBACK, FIELD_VALUE_FEEDBACK_CLI_ALIAS, formatValueFeedbackStatusLine, inspectAllPolicies, inspectOnePolicy, loadProjectDefinition, policyColonInvocation, projectDefinitionPath, pythonListRepr, pythonStringRepr, registeredPolicyNames, renderJson, renderText, resolvePolicy, resolveValueFeedback, setPolicy, } from "@deftai/directive-core/policy";
|
|
10
10
|
const CAPABILITY_COST_DISCLOSURE = "\u26a0 Capability-cost disclosure -- enabling direct commits to the default " +
|
|
11
11
|
"branch turns OFF the deft branch-protection policy.\n" +
|
|
12
12
|
" \u2022 Pre-commit + pre-push hooks will no longer block default-branch " +
|
|
@@ -14,7 +14,9 @@ const CAPABILITY_COST_DISCLOSURE = "\u26a0 Capability-cost disclosure -- enablin
|
|
|
14
14
|
" \u2022 verify:branch will pass on the default branch.\n" +
|
|
15
15
|
" \u2022 The CI sanity check (head_ref != base_ref) is still independent and " +
|
|
16
16
|
"will continue to flag master->master PRs.\n" +
|
|
17
|
-
" \u2022 This change is reversible: run `
|
|
17
|
+
" \u2022 This change is reversible: run `" +
|
|
18
|
+
policyColonInvocation("enforce-branches") +
|
|
19
|
+
"` to " +
|
|
18
20
|
"re-enable the gate.\n" +
|
|
19
21
|
" \u2022 The change is recorded to meta/policy-changes.log for auditability.";
|
|
20
22
|
function makeSetError(message) {
|
|
@@ -121,7 +123,7 @@ export function parseArgs(argv) {
|
|
|
121
123
|
return {
|
|
122
124
|
cmd: "show",
|
|
123
125
|
confirm: false,
|
|
124
|
-
actor: "
|
|
126
|
+
actor: policyColonInvocation("show"),
|
|
125
127
|
note: "",
|
|
126
128
|
projectRoot: show.projectRoot,
|
|
127
129
|
format: show.format,
|
|
@@ -149,10 +151,10 @@ export function parseArgs(argv) {
|
|
|
149
151
|
cmd === "enable-value-feedback") {
|
|
150
152
|
let confirm = false;
|
|
151
153
|
let actor = cmd === "enforce-branches"
|
|
152
|
-
? "
|
|
154
|
+
? policyColonInvocation("enforce-branches")
|
|
153
155
|
: cmd === "allow-direct-commits"
|
|
154
|
-
? "
|
|
155
|
-
: "
|
|
156
|
+
? policyColonInvocation("allow-direct-commits")
|
|
157
|
+
: policyColonInvocation("enable-value-feedback");
|
|
156
158
|
let note = "";
|
|
157
159
|
let projectRoot = ".";
|
|
158
160
|
for (let i = 1; i < argv.length; i += 1) {
|
|
@@ -291,7 +293,7 @@ function runSet(args) {
|
|
|
291
293
|
const projectRoot = pathResolve(args.projectRoot);
|
|
292
294
|
if (args.cmd === "allow-direct-commits" && !args.confirm) {
|
|
293
295
|
process.stdout.write(`${CAPABILITY_COST_DISCLOSURE}\n\n`);
|
|
294
|
-
process.stdout.write(
|
|
296
|
+
process.stdout.write(`Re-run with --confirm to apply: ${policyColonInvocation("allow-direct-commits", " -- --confirm")}\n`);
|
|
295
297
|
return 1;
|
|
296
298
|
}
|
|
297
299
|
const target = args.cmd === "allow-direct-commits";
|
|
@@ -4,11 +4,11 @@ import { mkdirSync, mkdtempSync, writeFileSync } from "node:fs";
|
|
|
4
4
|
import { tmpdir } from "node:os";
|
|
5
5
|
import { dirname, join } from "node:path";
|
|
6
6
|
function writeVbrief(root, rel, status = "running", folder = "active") {
|
|
7
|
-
const full = join(root, "
|
|
7
|
+
const full = join(root, "xbrief", folder, rel);
|
|
8
8
|
mkdirSync(dirname(full), { recursive: true });
|
|
9
9
|
const payload = {
|
|
10
10
|
plan: { status, title: "T", items: [] },
|
|
11
|
-
|
|
11
|
+
xBRIEFInfo: { version: "0.8" },
|
|
12
12
|
};
|
|
13
13
|
writeFileSync(full, `${JSON.stringify(payload)}\n`, "utf8");
|
|
14
14
|
}
|
|
@@ -23,7 +23,7 @@ function renderAllocation(fields) {
|
|
|
23
23
|
const VALID_COHORT = {
|
|
24
24
|
allocation_plan_id: "orchestrator-run-019e80bd",
|
|
25
25
|
batching_rationale: "Three disjoint-file-scope stories from #1378.",
|
|
26
|
-
cohort_vbriefs: "[
|
|
26
|
+
cohort_vbriefs: "[xbrief/active/a.json, xbrief/active/b.json]",
|
|
27
27
|
dispatch_kind: "swarm-cohort",
|
|
28
28
|
operator_approval_evidence: "user directive 2026-06-01T02:26Z",
|
|
29
29
|
};
|
|
@@ -31,29 +31,29 @@ const VALID_COHORT = {
|
|
|
31
31
|
export const PARITY_SCENARIOS = [
|
|
32
32
|
{
|
|
33
33
|
name: "clean-active-running-solo",
|
|
34
|
-
vbriefRel: "2026-06-01-story.
|
|
34
|
+
vbriefRel: "2026-06-01-story.xbrief.json",
|
|
35
35
|
envelopeRel: null,
|
|
36
36
|
},
|
|
37
37
|
{
|
|
38
38
|
name: "dirty-tree",
|
|
39
|
-
vbriefRel: "2026-06-01-story.
|
|
39
|
+
vbriefRel: "2026-06-01-story.xbrief.json",
|
|
40
40
|
envelopeRel: null,
|
|
41
41
|
dirty: true,
|
|
42
42
|
},
|
|
43
43
|
{
|
|
44
44
|
name: "non-running-vbrief",
|
|
45
|
-
vbriefRel: "2026-06-01-pending.
|
|
45
|
+
vbriefRel: "2026-06-01-pending.xbrief.json",
|
|
46
46
|
vbriefStatus: "approved",
|
|
47
47
|
envelopeRel: null,
|
|
48
48
|
},
|
|
49
49
|
{
|
|
50
50
|
name: "satisfied-swarm-cohort",
|
|
51
|
-
vbriefRel: "2026-06-01-story.
|
|
51
|
+
vbriefRel: "2026-06-01-story.xbrief.json",
|
|
52
52
|
envelopeRel: "envelope-cohort.md",
|
|
53
53
|
},
|
|
54
54
|
{
|
|
55
55
|
name: "malformed-allocation",
|
|
56
|
-
vbriefRel: "2026-06-01-story.
|
|
56
|
+
vbriefRel: "2026-06-01-story.xbrief.json",
|
|
57
57
|
envelopeRel: "envelope-bad.md",
|
|
58
58
|
},
|
|
59
59
|
];
|
|
@@ -99,7 +99,7 @@ export function buildScenarioRepo(scenario) {
|
|
|
99
99
|
if (!scenario.dirty) {
|
|
100
100
|
gitCommit(root, "init");
|
|
101
101
|
}
|
|
102
|
-
const vbriefPath = join(root, "
|
|
102
|
+
const vbriefPath = join(root, "xbrief", "active", vbriefName);
|
|
103
103
|
return { root, vbriefPath, envelopePath };
|
|
104
104
|
}
|
|
105
105
|
/** Diff python vs TS gate outputs across all parity scenarios. */
|
|
@@ -37,8 +37,8 @@ export function diffCase(python, ts, caseName) {
|
|
|
37
37
|
};
|
|
38
38
|
}
|
|
39
39
|
function writeProjectDefinition(root, policy = {}) {
|
|
40
|
-
mkdirSync(join(root, "
|
|
41
|
-
writeFileSync(join(root, "
|
|
40
|
+
mkdirSync(join(root, "xbrief"), { recursive: true });
|
|
41
|
+
writeFileSync(join(root, "xbrief", "PROJECT-DEFINITION.xbrief.json"), `${JSON.stringify({ xBRIEFInfo: { version: "0.8" }, plan: { policy } }, null, 2)}\n`, "utf8");
|
|
42
42
|
}
|
|
43
43
|
export const PARITY_CASES = [
|
|
44
44
|
{
|
|
@@ -82,7 +82,7 @@ export const PARITY_CASES = [
|
|
|
82
82
|
];
|
|
83
83
|
export function buildFixtureRepo(setup) {
|
|
84
84
|
const root = mkdtempSync(join(tmpdir(), "deft-triage-aux-a-parity-"));
|
|
85
|
-
mkdirSync(join(root, "
|
|
85
|
+
mkdirSync(join(root, "xbrief"), { recursive: true });
|
|
86
86
|
setup?.(root);
|
|
87
87
|
return root;
|
|
88
88
|
}
|
|
@@ -12,9 +12,9 @@ export function normalizeOutput(text) {
|
|
|
12
12
|
.replace(/Installed \d+ packages[^\n]*\n/g, "");
|
|
13
13
|
}
|
|
14
14
|
function writeProjectDefinition(root, policy = {}) {
|
|
15
|
-
mkdirSync(join(root, "
|
|
16
|
-
writeFileSync(join(root, "
|
|
17
|
-
|
|
15
|
+
mkdirSync(join(root, "xbrief"), { recursive: true });
|
|
16
|
+
writeFileSync(join(root, "xbrief", "PROJECT-DEFINITION.xbrief.json"), `${JSON.stringify({
|
|
17
|
+
xBRIEFInfo: { version: "0.8" },
|
|
18
18
|
plan: { title: "T", status: "running", items: [], policy },
|
|
19
19
|
}, null, 2)}\n`, { encoding: "utf8" });
|
|
20
20
|
}
|
|
@@ -32,7 +32,7 @@ export interface ParityResult {
|
|
|
32
32
|
export declare function normalizeOutput(text: string): string;
|
|
33
33
|
/** Compare stdout, parsing JSON payloads when present. */
|
|
34
34
|
export declare function normalizeStdout(text: string): string;
|
|
35
|
-
/** Build a throwaway project root with optional
|
|
35
|
+
/** Build a throwaway project root with optional xBRIEF fixtures. */
|
|
36
36
|
export declare function buildFixtureRepo(options?: FixtureOptions): string;
|
|
37
37
|
/** Diff one parity case between Python oracle and TS CLI. */
|
|
38
38
|
export declare function diffCase(python: CommandCapture, ts: CommandCapture, caseName: string): ParityDiff;
|
|
@@ -33,7 +33,7 @@ export function normalizeStdout(text) {
|
|
|
33
33
|
if (typeof details === "object" && details !== null) {
|
|
34
34
|
const detailRecord = details;
|
|
35
35
|
if (typeof detailRecord.audit_path === "string") {
|
|
36
|
-
detailRecord.audit_path = "<ROOT>/
|
|
36
|
+
detailRecord.audit_path = "<ROOT>/xbrief/.triage-cache/candidates.jsonl";
|
|
37
37
|
}
|
|
38
38
|
if (typeof detailRecord.fetch_timeout_s === "number") {
|
|
39
39
|
detailRecord.fetch_timeout_s = Math.trunc(detailRecord.fetch_timeout_s);
|
|
@@ -53,10 +53,10 @@ export function normalizeStdout(text) {
|
|
|
53
53
|
return normalizeOutput(text);
|
|
54
54
|
}
|
|
55
55
|
function writeScopeVbrief(root, folder, slug, issueNumber) {
|
|
56
|
-
const dir = join(root, "
|
|
56
|
+
const dir = join(root, "xbrief", folder);
|
|
57
57
|
mkdirSync(dir, { recursive: true });
|
|
58
|
-
writeFileSync(join(dir, `${slug}.
|
|
59
|
-
|
|
58
|
+
writeFileSync(join(dir, `${slug}.xbrief.json`), `${JSON.stringify({
|
|
59
|
+
xBRIEFInfo: { version: "0.8" },
|
|
60
60
|
plan: {
|
|
61
61
|
id: slug,
|
|
62
62
|
title: slug,
|
|
@@ -70,10 +70,10 @@ function writeScopeVbrief(root, folder, slug, issueNumber) {
|
|
|
70
70
|
},
|
|
71
71
|
})}\n`, { encoding: "utf8" });
|
|
72
72
|
}
|
|
73
|
-
/** Build a throwaway project root with optional
|
|
73
|
+
/** Build a throwaway project root with optional xBRIEF fixtures. */
|
|
74
74
|
export function buildFixtureRepo(options = {}) {
|
|
75
75
|
const root = mkdtempSync(join(tmpdir(), "deft-triage-bootstrap-parity-"));
|
|
76
|
-
mkdirSync(join(root, "
|
|
76
|
+
mkdirSync(join(root, "xbrief"), { recursive: true });
|
|
77
77
|
for (const item of options.scopeVbriefs ?? []) {
|
|
78
78
|
writeScopeVbrief(root, item.folder, item.slug, item.issue);
|
|
79
79
|
}
|
|
@@ -11,19 +11,19 @@ export function normalizeOutput(text) {
|
|
|
11
11
|
.replace(/\S*deft-triage-classify-parity-[^\s/]+/g, "<TMPROOT>"));
|
|
12
12
|
}
|
|
13
13
|
function writeProjectDefinition(root, plan) {
|
|
14
|
-
const dir = join(root, "
|
|
14
|
+
const dir = join(root, "xbrief");
|
|
15
15
|
mkdirSync(dir, { recursive: true });
|
|
16
|
-
writeFileSync(join(dir, "PROJECT-DEFINITION.
|
|
17
|
-
|
|
16
|
+
writeFileSync(join(dir, "PROJECT-DEFINITION.xbrief.json"), `${JSON.stringify({
|
|
17
|
+
xBRIEFInfo: { version: "0.8" },
|
|
18
18
|
plan: { title: "T", status: "running", items: [], ...plan },
|
|
19
19
|
}, null, 2)}\n`, { encoding: "utf8" });
|
|
20
20
|
}
|
|
21
21
|
/** Build a throwaway project root with optional PROJECT-DEFINITION. */
|
|
22
22
|
export function buildFixtureRepo(options = {}) {
|
|
23
23
|
const root = mkdtempSync(join(tmpdir(), "deft-triage-classify-parity-"));
|
|
24
|
-
mkdirSync(join(root, "
|
|
24
|
+
mkdirSync(join(root, "xbrief"), { recursive: true });
|
|
25
25
|
if (options.rawProjectDefinition !== undefined) {
|
|
26
|
-
writeFileSync(join(root, "
|
|
26
|
+
writeFileSync(join(root, "xbrief", "PROJECT-DEFINITION.xbrief.json"), `${JSON.stringify(options.rawProjectDefinition, null, 2)}\n`, { encoding: "utf8" });
|
|
27
27
|
}
|
|
28
28
|
else if (!options.omitProjectDefinition && options.plan !== undefined) {
|
|
29
29
|
writeProjectDefinition(root, options.plan);
|
|
@@ -109,7 +109,7 @@ export const PARITY_CASES = [
|
|
|
109
109
|
argv: ["--validate"],
|
|
110
110
|
fixture: {
|
|
111
111
|
rawProjectDefinition: {
|
|
112
|
-
|
|
112
|
+
xBRIEFInfo: { version: "0.8" },
|
|
113
113
|
plan: null,
|
|
114
114
|
},
|
|
115
115
|
},
|
|
@@ -29,7 +29,7 @@ function writeCachedIssue(root, repo, issue) {
|
|
|
29
29
|
writeFileSync(join(dir, "raw.json"), `${JSON.stringify(raw)}\n`, { encoding: "utf8" });
|
|
30
30
|
}
|
|
31
31
|
function writeAuditLog(root, repo, entries) {
|
|
32
|
-
const dir = join(root, "
|
|
32
|
+
const dir = join(root, "xbrief", ".triage-cache");
|
|
33
33
|
mkdirSync(dir, { recursive: true });
|
|
34
34
|
const lines = entries.map((entry) => JSON.stringify({
|
|
35
35
|
decision_id: `id-${entry.issueNumber}-${entry.decision}`,
|
|
@@ -42,19 +42,19 @@ function writeAuditLog(root, repo, entries) {
|
|
|
42
42
|
writeFileSync(join(dir, "candidates.jsonl"), `${lines.join("\n")}\n`, { encoding: "utf8" });
|
|
43
43
|
}
|
|
44
44
|
function writeProjectDefinition(root, rankingLabels) {
|
|
45
|
-
const dir = join(root, "
|
|
45
|
+
const dir = join(root, "xbrief");
|
|
46
46
|
mkdirSync(dir, { recursive: true });
|
|
47
47
|
const plan = { title: "T", status: "running", items: [] };
|
|
48
48
|
if (rankingLabels !== undefined && rankingLabels.length > 0) {
|
|
49
49
|
plan.policy = { triageRankingLabels: [...rankingLabels] };
|
|
50
50
|
}
|
|
51
|
-
writeFileSync(join(dir, "PROJECT-DEFINITION.
|
|
51
|
+
writeFileSync(join(dir, "PROJECT-DEFINITION.xbrief.json"), `${JSON.stringify({ xBRIEFInfo: { version: "0.8" }, plan }, null, 2)}\n`, { encoding: "utf8" });
|
|
52
52
|
}
|
|
53
53
|
function writeActiveScope(root, repo, issueNumber, filename) {
|
|
54
|
-
const dir = join(root, "
|
|
54
|
+
const dir = join(root, "xbrief", "active");
|
|
55
55
|
mkdirSync(dir, { recursive: true });
|
|
56
56
|
writeFileSync(join(dir, filename), `${JSON.stringify({
|
|
57
|
-
|
|
57
|
+
xBRIEFInfo: { version: "0.8" },
|
|
58
58
|
plan: {
|
|
59
59
|
title: "Active scope",
|
|
60
60
|
status: "running",
|
|
@@ -69,10 +69,10 @@ function writeActiveScope(root, repo, issueNumber, filename) {
|
|
|
69
69
|
})}\n`, { encoding: "utf8" });
|
|
70
70
|
}
|
|
71
71
|
function writeBlockedScope(root, repo, issueNumber, filename) {
|
|
72
|
-
const dir = join(root, "
|
|
72
|
+
const dir = join(root, "xbrief", "active");
|
|
73
73
|
mkdirSync(dir, { recursive: true });
|
|
74
74
|
writeFileSync(join(dir, filename), `${JSON.stringify({
|
|
75
|
-
|
|
75
|
+
xBRIEFInfo: { version: "0.8" },
|
|
76
76
|
plan: {
|
|
77
77
|
title: "Blocked scope",
|
|
78
78
|
status: "blocked",
|
|
@@ -87,7 +87,7 @@ function writeBlockedScope(root, repo, issueNumber, filename) {
|
|
|
87
87
|
})}\n`, { encoding: "utf8" });
|
|
88
88
|
}
|
|
89
89
|
function writeSliceRecords(root, records) {
|
|
90
|
-
const dir = join(root, "
|
|
90
|
+
const dir = join(root, "xbrief", ".triage-cache");
|
|
91
91
|
mkdirSync(dir, { recursive: true });
|
|
92
92
|
writeFileSync(join(dir, "slices.jsonl"), `${records.map((record) => JSON.stringify(record)).join("\n")}\n`, { encoding: "utf8" });
|
|
93
93
|
}
|
|
@@ -95,7 +95,7 @@ function writeSliceRecords(root, records) {
|
|
|
95
95
|
export function buildFixtureRepo(options = {}) {
|
|
96
96
|
const root = mkdtempSync(join(tmpdir(), "deft-triage-queue-parity-"));
|
|
97
97
|
const repo = options.repo ?? DEFAULT_REPO;
|
|
98
|
-
mkdirSync(join(root, "
|
|
98
|
+
mkdirSync(join(root, "xbrief"), { recursive: true });
|
|
99
99
|
writeProjectDefinition(root, options.rankingLabels);
|
|
100
100
|
for (const issue of options.issues ?? []) {
|
|
101
101
|
writeCachedIssue(root, repo, issue);
|
|
@@ -104,10 +104,10 @@ export function buildFixtureRepo(options = {}) {
|
|
|
104
104
|
writeAuditLog(root, repo, options.auditEntries);
|
|
105
105
|
}
|
|
106
106
|
for (const issueNumber of options.activeIssueNumbers ?? []) {
|
|
107
|
-
writeActiveScope(root, repo, issueNumber, `active-${issueNumber}.
|
|
107
|
+
writeActiveScope(root, repo, issueNumber, `active-${issueNumber}.xbrief.json`);
|
|
108
108
|
}
|
|
109
109
|
for (const issueNumber of options.blockedIssueNumbers ?? []) {
|
|
110
|
-
writeBlockedScope(root, repo, issueNumber, `blocked-${issueNumber}.
|
|
110
|
+
writeBlockedScope(root, repo, issueNumber, `blocked-${issueNumber}.xbrief.json`);
|
|
111
111
|
}
|
|
112
112
|
if (options.sliceRecords !== undefined && options.sliceRecords.length > 0) {
|
|
113
113
|
writeSliceRecords(root, options.sliceRecords);
|
|
@@ -251,10 +251,10 @@ export function augmentParityArgv(testCase, root) {
|
|
|
251
251
|
}
|
|
252
252
|
const extras = [];
|
|
253
253
|
if (testCase.fixture.auditEntries !== undefined && testCase.fixture.auditEntries.length > 0) {
|
|
254
|
-
extras.push("--audit-log", join(root, "
|
|
254
|
+
extras.push("--audit-log", join(root, "xbrief", ".triage-cache", "candidates.jsonl"));
|
|
255
255
|
}
|
|
256
256
|
if (testCase.fixture.sliceRecords !== undefined && testCase.fixture.sliceRecords.length > 0) {
|
|
257
|
-
extras.push("--slices-log", join(root, "
|
|
257
|
+
extras.push("--slices-log", join(root, "xbrief", ".triage-cache", "slices.jsonl"));
|
|
258
258
|
}
|
|
259
259
|
return [...argv, ...extras];
|
|
260
260
|
}
|
|
@@ -10,16 +10,16 @@ export function normalizeOutput(text) {
|
|
|
10
10
|
.replace(/path=[^\s\n]+coverage\.json/g, "path=<ROOT>/coverage.json");
|
|
11
11
|
}
|
|
12
12
|
function writeProjectDefinition(root, policy = {}) {
|
|
13
|
-
const dir = join(root, "
|
|
13
|
+
const dir = join(root, "xbrief");
|
|
14
14
|
mkdirSync(dir, { recursive: true });
|
|
15
|
-
writeFileSync(join(dir, "PROJECT-DEFINITION.
|
|
16
|
-
|
|
15
|
+
writeFileSync(join(dir, "PROJECT-DEFINITION.xbrief.json"), `${JSON.stringify({
|
|
16
|
+
xBRIEFInfo: { version: "0.8" },
|
|
17
17
|
plan: { title: "T", status: "running", items: [], policy },
|
|
18
18
|
}, null, 2)}\n`, "utf8");
|
|
19
19
|
}
|
|
20
20
|
export function buildFixtureRepo(options = {}) {
|
|
21
21
|
const root = mkdtempSync(join(tmpdir(), "deft-triage-scope-parity-"));
|
|
22
|
-
mkdirSync(join(root, "
|
|
22
|
+
mkdirSync(join(root, "xbrief"), { recursive: true });
|
|
23
23
|
writeProjectDefinition(root, options.policy ?? {});
|
|
24
24
|
return root;
|
|
25
25
|
}
|
|
@@ -49,7 +49,7 @@ export function buildFixtures(root) {
|
|
|
49
49
|
for (const [label, folder, content] of PARITY_FIXTURES) {
|
|
50
50
|
const dir = join(root, folder);
|
|
51
51
|
mkdirSync(dir, { recursive: true });
|
|
52
|
-
const file = join(dir, `${label}.
|
|
52
|
+
const file = join(dir, `${label}.xbrief.json`);
|
|
53
53
|
writeFileSync(file, content, { encoding: "utf8" });
|
|
54
54
|
paths.set(label, file);
|
|
55
55
|
}
|
package/dist/wip-cap-fixtures.js
CHANGED
|
@@ -7,30 +7,30 @@ export function normalizeOutput(text) {
|
|
|
7
7
|
return text.replace(/project_root=[^\s)]+/g, "project_root=<ROOT>");
|
|
8
8
|
}
|
|
9
9
|
function writeProjectDefinition(root, plan) {
|
|
10
|
-
const dir = join(root, "
|
|
10
|
+
const dir = join(root, "xbrief");
|
|
11
11
|
mkdirSync(dir, { recursive: true });
|
|
12
|
-
writeFileSync(join(dir, "PROJECT-DEFINITION.
|
|
13
|
-
|
|
12
|
+
writeFileSync(join(dir, "PROJECT-DEFINITION.xbrief.json"), `${JSON.stringify({
|
|
13
|
+
xBRIEFInfo: { version: "0.8" },
|
|
14
14
|
plan: { title: "T", status: "running", items: [], ...plan },
|
|
15
15
|
}, null, 2)}\n`, { encoding: "utf8" });
|
|
16
16
|
}
|
|
17
|
-
function
|
|
18
|
-
const dir = join(root, "
|
|
17
|
+
function writeXbrief(root, folder, name) {
|
|
18
|
+
const dir = join(root, "xbrief", folder);
|
|
19
19
|
mkdirSync(dir, { recursive: true });
|
|
20
|
-
writeFileSync(join(dir, name), `${JSON.stringify({
|
|
20
|
+
writeFileSync(join(dir, name), `${JSON.stringify({ xBRIEFInfo: { version: "0.8" }, plan: { status: "approved", title: "T", items: [] } })}\n`, { encoding: "utf8" });
|
|
21
21
|
}
|
|
22
22
|
/** Build a throwaway project root with optional PROJECT-DEFINITION and WIP files. */
|
|
23
23
|
export function buildFixtureRepo(options = {}) {
|
|
24
24
|
const root = mkdtempSync(join(tmpdir(), "deft-wip-cap-parity-"));
|
|
25
|
-
mkdirSync(join(root, "
|
|
25
|
+
mkdirSync(join(root, "xbrief"), { recursive: true });
|
|
26
26
|
if (options.plan !== undefined) {
|
|
27
27
|
writeProjectDefinition(root, options.plan);
|
|
28
28
|
}
|
|
29
29
|
for (let i = 0; i < (options.pendingFiles ?? 0); i += 1) {
|
|
30
|
-
|
|
30
|
+
writeXbrief(root, "pending", `pending-${i}.xbrief.json`);
|
|
31
31
|
}
|
|
32
32
|
for (let i = 0; i < (options.activeFiles ?? 0); i += 1) {
|
|
33
|
-
|
|
33
|
+
writeXbrief(root, "active", `active-${i}.xbrief.json`);
|
|
34
34
|
}
|
|
35
35
|
return root;
|
|
36
36
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@deftai/directive",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.73.1",
|
|
4
4
|
"description": "Directive CLI — npm install path for the Deft Directive framework.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -31,8 +31,8 @@
|
|
|
31
31
|
"provenance": true
|
|
32
32
|
},
|
|
33
33
|
"dependencies": {
|
|
34
|
-
"@deftai/directive-core": "^0.
|
|
35
|
-
"@deftai/directive-content": "^0.
|
|
34
|
+
"@deftai/directive-core": "^0.73.1",
|
|
35
|
+
"@deftai/directive-content": "^0.73.1"
|
|
36
36
|
},
|
|
37
37
|
"scripts": {
|
|
38
38
|
"build": "tsc -b"
|