@deftai/directive-core 0.71.1 → 0.73.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.
Files changed (94) hide show
  1. package/dist/category-b-namespace/index.js +16 -2
  2. package/dist/codebase/default-extractor.js +9 -1
  3. package/dist/codebase/map.js +1 -1
  4. package/dist/doctor/checks.d.ts +9 -0
  5. package/dist/doctor/checks.js +85 -5
  6. package/dist/doctor/main.js +2 -1
  7. package/dist/eval/health.js +7 -1
  8. package/dist/eval/readback.js +7 -1
  9. package/dist/events/attribution-enrichment.d.ts +35 -0
  10. package/dist/events/attribution-enrichment.js +74 -0
  11. package/dist/events/attribution-ledger.js +6 -1
  12. package/dist/init-deposit/gitignore.js +6 -0
  13. package/dist/init-deposit/hygiene.d.ts +24 -0
  14. package/dist/init-deposit/hygiene.js +55 -0
  15. package/dist/init-deposit/refresh.js +22 -6
  16. package/dist/init-deposit/scaffold.d.ts +11 -1
  17. package/dist/init-deposit/scaffold.js +4 -4
  18. package/dist/integration-e2e/helpers.js +7 -7
  19. package/dist/layout/index.d.ts +1 -1
  20. package/dist/layout/index.js +1 -1
  21. package/dist/layout/resolve.d.ts +47 -31
  22. package/dist/layout/resolve.js +93 -36
  23. package/dist/lifecycle/lifecycle-hygiene.d.ts +1 -1
  24. package/dist/lifecycle/lifecycle-hygiene.js +1 -1
  25. package/dist/migrate-preflight/index.js +10 -10
  26. package/dist/policy/index.js +3 -3
  27. package/dist/policy/resolve.d.ts +2 -2
  28. package/dist/policy/resolve.js +11 -3
  29. package/dist/policy/value-feedback-autoenable.d.ts +33 -0
  30. package/dist/policy/value-feedback-autoenable.js +67 -0
  31. package/dist/policy/value-feedback.d.ts +30 -5
  32. package/dist/policy/value-feedback.js +52 -34
  33. package/dist/policy/wip.d.ts +1 -1
  34. package/dist/policy/wip.js +15 -3
  35. package/dist/preflight-cache/evaluate.js +1 -1
  36. package/dist/release/native-steps.js +14 -2
  37. package/dist/render/export-spec.js +2 -2
  38. package/dist/render/project-render.js +40 -9
  39. package/dist/scope/decompose.js +12 -2
  40. package/dist/session/resume-conditions.js +2 -2
  41. package/dist/session/ritual-sentinel.d.ts +1 -1
  42. package/dist/session/ritual-sentinel.js +6 -4
  43. package/dist/slice/constants.d.ts +1 -1
  44. package/dist/slice/constants.js +1 -1
  45. package/dist/slice/project-context.js +1 -1
  46. package/dist/spec-authority/resolver.js +9 -2
  47. package/dist/swarm/complete-cohort.js +14 -1
  48. package/dist/swarm/readiness.js +33 -3
  49. package/dist/task-surface/index.js +3 -3
  50. package/dist/triage/actions/candidates-log.d.ts +1 -1
  51. package/dist/triage/bootstrap/gitignore.js +22 -10
  52. package/dist/triage/bootstrap/index.d.ts +1 -1
  53. package/dist/triage/bootstrap/index.js +9 -3
  54. package/dist/triage/cache-path.d.ts +1 -1
  55. package/dist/triage/cache-path.js +32 -6
  56. package/dist/triage/classify/index.d.ts +1 -1
  57. package/dist/triage/classify/index.js +11 -4
  58. package/dist/triage/help/registry-data.d.ts +2 -2
  59. package/dist/triage/help/registry-data.js +2 -2
  60. package/dist/triage/queue/constants.d.ts +4 -4
  61. package/dist/triage/queue/constants.js +4 -4
  62. package/dist/triage/queue/scope-walk.js +7 -1
  63. package/dist/triage/reconcile/reconcile.js +23 -3
  64. package/dist/triage/reconcile/types.d.ts +1 -1
  65. package/dist/triage/reconcile/types.js +1 -1
  66. package/dist/triage/refresh/refresh.js +9 -2
  67. package/dist/triage/scope/constants.d.ts +2 -2
  68. package/dist/triage/scope/constants.js +2 -2
  69. package/dist/triage/scope/renderers.js +7 -1
  70. package/dist/triage/smoketest/index.js +9 -6
  71. package/dist/triage/subscribe/index.d.ts +2 -2
  72. package/dist/triage/subscribe/index.js +2 -2
  73. package/dist/triage/summary/index.d.ts +2 -2
  74. package/dist/triage/summary/index.js +1 -1
  75. package/dist/triage/summary/reconcilable.d.ts +1 -1
  76. package/dist/triage/welcome/constants.d.ts +2 -2
  77. package/dist/triage/welcome/constants.js +2 -2
  78. package/dist/triage/welcome/onboard.js +8 -1
  79. package/dist/triage/welcome/prior-state.js +14 -2
  80. package/dist/triage/welcome/summary.js +14 -2
  81. package/dist/triage/welcome/writers.js +7 -1
  82. package/dist/validate-content/validate-strategy-output.js +11 -1
  83. package/dist/vbrief-build/parity-scenarios.js +3 -3
  84. package/dist/vbrief-reconcile/labels.js +16 -1
  85. package/dist/vbrief-reconcile/parity-scenarios.js +10 -10
  86. package/dist/vbrief-reconcile/umbrellas.js +16 -1
  87. package/dist/vbrief-validate/main.js +13 -1
  88. package/dist/vbrief-validate/precutover.js +33 -5
  89. package/dist/vbrief-validate/staleness.d.ts +1 -1
  90. package/dist/vbrief-validate/staleness.js +5 -2
  91. package/dist/verify-source/code-structure-validate.js +7 -1
  92. package/dist/xbrief-migrate/signpost.d.ts +4 -4
  93. package/dist/xbrief-migrate/signpost.js +11 -15
  94. package/package.json +3 -3
@@ -1,6 +1,6 @@
1
1
  import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
2
2
  import { dirname, relative } from "node:path";
3
- import { resolveLifecycleLayout } from "../../layout/resolve.js";
3
+ import { MIGRATED_ARTIFACT_DIR, resolveLifecycleLayout } from "../../layout/resolve.js";
4
4
  import { resolveCandidatesLogPath, resolveTriageCachePath, TRIAGE_CACHE_DIR_NAME, triageCacheRelPath, } from "../cache-path.js";
5
5
  /** POSIX-style display path for `absPath` relative to `projectRoot` (#2109). */
6
6
  function evalRelDisplay(projectRoot, absPath) {
@@ -13,11 +13,11 @@ export const GITIGNORE_DEFT_RUNTIME_SENTINELS = [
13
13
  ];
14
14
  /** Legacy static vbrief paths kept for tests referencing the pre-#1703 constant shape. */
15
15
  export const GITIGNORE_EVAL_ENTRIES = [
16
- "vbrief/.triage-cache/candidates.jsonl",
17
- "vbrief/.triage-cache/summary-history.jsonl",
18
- "vbrief/.triage-cache/scope-lifecycle.jsonl",
19
- "vbrief/.triage-cache/decompositions/",
20
- "vbrief/.triage-cache/doctor-state.json",
16
+ "xbrief/.triage-cache/candidates.jsonl",
17
+ "xbrief/.triage-cache/summary-history.jsonl",
18
+ "xbrief/.triage-cache/scope-lifecycle.jsonl",
19
+ "xbrief/.triage-cache/decompositions/",
20
+ "xbrief/.triage-cache/doctor-state.json",
21
21
  ];
22
22
  /** Layout-aware gitignore lines for triage working-set files (#1703). */
23
23
  export function gitignoreTriageCacheEntries(projectRoot) {
@@ -31,8 +31,14 @@ export function gitignoreTriageCacheEntries(projectRoot) {
31
31
  ];
32
32
  }
33
33
  export function gitattributesTriageCacheGlob(projectRoot) {
34
- const layout = resolveLifecycleLayout(projectRoot);
35
- return `${layout.artifactDir}/${TRIAGE_CACHE_DIR_NAME}/*.jsonl`;
34
+ let artifactDir;
35
+ try {
36
+ artifactDir = resolveLifecycleLayout(projectRoot).artifactDir;
37
+ }
38
+ catch {
39
+ artifactDir = MIGRATED_ARTIFACT_DIR; // No layout; default to xbrief/.
40
+ }
41
+ return `${artifactDir}/${TRIAGE_CACHE_DIR_NAME}/*.jsonl`;
36
42
  }
37
43
  export const GITATTRIBUTES_EVAL_RULE = "vbrief/.triage-cache/*.jsonl merge=union";
38
44
  export const FORBIDDEN_BLANKET_EVAL_LINES = [
@@ -154,8 +160,14 @@ operators should know:
154
160
  `;
155
161
  /** Layout-aware triage-cache README body for the active lifecycle tree (#2344 / #2349). */
156
162
  export function generateTriageCacheReadmeBody(projectRoot) {
157
- const layout = resolveLifecycleLayout(projectRoot);
158
- const triagePrefix = `${layout.artifactDir}/${TRIAGE_CACHE_DIR_NAME}`;
163
+ let artifactDir;
164
+ try {
165
+ artifactDir = resolveLifecycleLayout(projectRoot).artifactDir;
166
+ }
167
+ catch {
168
+ artifactDir = MIGRATED_ARTIFACT_DIR; // No layout; default to xbrief/.
169
+ }
170
+ const triagePrefix = `${artifactDir}/${TRIAGE_CACHE_DIR_NAME}`;
159
171
  return EVAL_README_BODY.replaceAll("vbrief/.triage-cache", triagePrefix);
160
172
  }
161
173
  function stepOutcome(name, ok, message, details = {}, error = null) {
@@ -2,7 +2,7 @@ import type { BootstrapResult, CacheModule, RunBootstrapOptions, StepOutcome } f
2
2
  export * from "./gitignore.js";
3
3
  export * from "./types.js";
4
4
  export declare const CACHE_DIR_NAME = ".deft-cache";
5
- export declare const AUDIT_LOG_RELPATH = "vbrief/.triage-cache/candidates.jsonl";
5
+ export declare const AUDIT_LOG_RELPATH = "xbrief/.triage-cache/candidates.jsonl";
6
6
  export declare const BACKFILL_FOLDERS: readonly ["proposed", "pending", "active"];
7
7
  export declare const BOOTSTRAP_ACTOR = "agent:bootstrap";
8
8
  export declare const DEFAULT_FETCH_TIMEOUT_S = 3600;
@@ -11,7 +11,7 @@ import { PROGRESS_DEFAULT } from "./types.js";
11
11
  export * from "./gitignore.js";
12
12
  export * from "./types.js";
13
13
  export const CACHE_DIR_NAME = ".deft-cache";
14
- export const AUDIT_LOG_RELPATH = "vbrief/.triage-cache/candidates.jsonl";
14
+ export const AUDIT_LOG_RELPATH = "xbrief/.triage-cache/candidates.jsonl";
15
15
  export const BACKFILL_FOLDERS = ["proposed", "pending", "active"];
16
16
  export const BOOTSTRAP_ACTOR = "agent:bootstrap";
17
17
  export const DEFAULT_FETCH_TIMEOUT_S = 3600;
@@ -374,9 +374,15 @@ export function stepBackfillAuditLog(projectRoot, repo, options = {}) {
374
374
  if (repo === null) {
375
375
  return stepOutcome("backfill_audit_log", true, "skipped (no --repo provided; pass --repo OWNER/NAME to backfill)", { skipped: "no-repo" });
376
376
  }
377
- const vbriefRoot = resolveLifecycleRoot(projectRoot);
377
+ let vbriefRoot;
378
+ try {
379
+ vbriefRoot = resolveLifecycleRoot(projectRoot);
380
+ }
381
+ catch {
382
+ return stepOutcome("backfill_audit_log", true, `skipped (no xbrief/ layout under ${projectRoot})`, { skipped: "no-xbrief" });
383
+ }
378
384
  if (!existsSync(vbriefRoot)) {
379
- return stepOutcome("backfill_audit_log", true, `skipped (no vbrief/ directory under ${projectRoot})`, { skipped: "no-vbrief" });
385
+ return stepOutcome("backfill_audit_log", true, `skipped (no xbrief/ directory under ${projectRoot})`, { skipped: "no-xbrief" });
380
386
  }
381
387
  const auditPath = resolveCandidatesLogPath(projectRoot);
382
388
  const alreadyLogged = existingAuditIssueNumbers(auditPath);
@@ -33,7 +33,7 @@ export declare function resolveTriageCachePath(projectRoot: string, ...segments:
33
33
  /** Display helper: project-root-relative POSIX path for logs and gitignore copy. */
34
34
  export declare function triageCacheDisplayPath(projectRoot: string, absPath: string): string;
35
35
  /** Back-compat display constant; resolution flows through `resolveTriageCachePath`. */
36
- export declare const TRIAGE_CANDIDATES_LOG_REL_PATH = "vbrief/.triage-cache/candidates.jsonl";
36
+ export declare const TRIAGE_CANDIDATES_LOG_REL_PATH = "xbrief/.triage-cache/candidates.jsonl";
37
37
  /** Layout-aware candidates audit-log path. */
38
38
  export declare function resolveCandidatesLogPath(projectRoot: string): string;
39
39
  /** Ensure the triage cache directory exists (post-migration). */
@@ -6,7 +6,7 @@
6
6
  */
7
7
  import { existsSync, mkdirSync, renameSync, unlinkSync, writeFileSync } from "node:fs";
8
8
  import { join, relative } from "node:path";
9
- import { resolveEvalDir, resolveLifecycleLayout, resolveLifecycleRoot } from "../layout/resolve.js";
9
+ import { MIGRATED_ARTIFACT_DIR, resolveEvalDir, resolveLifecycleLayout, resolveLifecycleRoot, } from "../layout/resolve.js";
10
10
  import { generateTriageCacheReadmeBody } from "./bootstrap/gitignore.js";
11
11
  /** Directory name for the triage working-set cache (not version-eval results). */
12
12
  export const TRIAGE_CACHE_DIR_NAME = ".triage-cache";
@@ -26,19 +26,45 @@ export const TRIAGE_CACHE_FILE_NAMES = [
26
26
  export const TRIAGE_CACHE_DIR_NAMES = ["decompositions"];
27
27
  /** Absolute path to the layout-aware `.triage-cache/` directory. */
28
28
  export function resolveTriageCacheDir(projectRoot) {
29
- return join(resolveLifecycleRoot(projectRoot), TRIAGE_CACHE_DIR_NAME);
29
+ let layoutRoot;
30
+ try {
31
+ layoutRoot = resolveLifecycleRoot(projectRoot);
32
+ }
33
+ catch {
34
+ layoutRoot = join(projectRoot, MIGRATED_ARTIFACT_DIR); // No xbrief/ layout; use canonical path.
35
+ }
36
+ return join(layoutRoot, TRIAGE_CACHE_DIR_NAME);
30
37
  }
31
38
  /** POSIX-style path relative to project root (e.g. `xbrief/.triage-cache/foo`). */
32
39
  export function triageCacheRelPath(projectRoot, ...segments) {
33
- const layout = resolveLifecycleLayout(projectRoot);
34
- return [layout.artifactDir, TRIAGE_CACHE_DIR_NAME, ...segments].join("/");
40
+ let artifactDir;
41
+ try {
42
+ const layout = resolveLifecycleLayout(projectRoot);
43
+ artifactDir = layout.artifactDir;
44
+ }
45
+ catch {
46
+ artifactDir = "xbrief"; // No layout; default to xbrief/ path for display purposes.
47
+ }
48
+ return [artifactDir, TRIAGE_CACHE_DIR_NAME, ...segments].join("/");
35
49
  }
36
50
  /**
37
51
  * Idempotently move triage working-set artefacts from legacy `.eval/` into
38
52
  * `.triage-cache/` when the new location is absent.
39
53
  */
40
54
  export function migrateLegacyTriageCacheFromEval(projectRoot) {
41
- const legacyDir = resolveEvalDir(projectRoot);
55
+ let legacyDir;
56
+ try {
57
+ legacyDir = resolveEvalDir(projectRoot);
58
+ }
59
+ catch {
60
+ return {
61
+ migratedFiles: [],
62
+ skippedFiles: [],
63
+ migratedDirs: [],
64
+ regeneratedFiles: [],
65
+ removedLegacyFiles: [],
66
+ };
67
+ }
42
68
  const targetDir = resolveTriageCacheDir(projectRoot);
43
69
  const migratedFiles = [];
44
70
  const skippedFiles = [];
@@ -100,7 +126,7 @@ export function triageCacheDisplayPath(projectRoot, absPath) {
100
126
  return relative(projectRoot, absPath).split(/[\\/]/).join("/");
101
127
  }
102
128
  /** Back-compat display constant; resolution flows through `resolveTriageCachePath`. */
103
- export const TRIAGE_CANDIDATES_LOG_REL_PATH = "vbrief/.triage-cache/candidates.jsonl";
129
+ export const TRIAGE_CANDIDATES_LOG_REL_PATH = "xbrief/.triage-cache/candidates.jsonl";
104
130
  /** Layout-aware candidates audit-log path. */
105
131
  export function resolveCandidatesLogPath(projectRoot) {
106
132
  return resolveTriageCachePath(projectRoot, "candidates.jsonl");
@@ -1,5 +1,5 @@
1
1
  /** Filesystem-relative location of the PROJECT-DEFINITION vBRIEF. */
2
- export declare const PROJECT_DEFINITION_REL_PATH = "vbrief/PROJECT-DEFINITION.vbrief.json";
2
+ export declare const PROJECT_DEFINITION_REL_PATH = "xbrief/PROJECT-DEFINITION.xbrief.json";
3
3
  /** Threshold in days for the "dormant" universal rule (Decision 1). */
4
4
  export declare const DORMANT_AGE_DAYS = 90;
5
5
  /** Threshold in characters for "thin body" used by the dormant rule. */
@@ -30,7 +30,7 @@ function pythonRepr(value) {
30
30
  return pyRepr(value);
31
31
  }
32
32
  /** Filesystem-relative location of the PROJECT-DEFINITION vBRIEF. */
33
- export const PROJECT_DEFINITION_REL_PATH = "vbrief/PROJECT-DEFINITION.vbrief.json";
33
+ export const PROJECT_DEFINITION_REL_PATH = "xbrief/PROJECT-DEFINITION.xbrief.json";
34
34
  /** Threshold in days for the "dormant" universal rule (Decision 1). */
35
35
  export const DORMANT_AGE_DAYS = 90;
36
36
  /** Threshold in characters for "thin body" used by the dormant rule. */
@@ -255,7 +255,14 @@ export function validateHoldMarkers(markers) {
255
255
  return { errors, warnings };
256
256
  }
257
257
  export function projectDefinitionPath(projectRoot) {
258
- return resolveProjectDefinitionPath(projectRoot ?? process.cwd());
258
+ const root = projectRoot ?? process.cwd();
259
+ try {
260
+ return resolveProjectDefinitionPath(root);
261
+ }
262
+ catch {
263
+ // No xbrief/ layout; return canonical path so callers get a predictable "not found" result.
264
+ return join(root, "xbrief", "PROJECT-DEFINITION.xbrief.json");
265
+ }
259
266
  }
260
267
  function loadProjectDefinition(projectRoot) {
261
268
  const path = projectDefinitionPath(projectRoot);
@@ -698,7 +705,7 @@ export function validateProject(projectRoot) {
698
705
  return {
699
706
  code: 0,
700
707
  stdout: "OK: no PROJECT-DEFINITION at " +
701
- `${resolveProjectDefinitionPath(root)} -- ` +
708
+ `${projectDefinitionPath(root)} -- ` +
702
709
  "framework defaults apply with no consumer overrides.\n",
703
710
  stderr: "",
704
711
  };
@@ -711,7 +718,7 @@ export function validateProject(projectRoot) {
711
718
  stderr: "FAIL: PROJECT-DEFINITION.plan is not an object\n",
712
719
  };
713
720
  }
714
- const rel = resolveProjectDefinitionPath(root);
721
+ const rel = projectDefinitionPath(root);
715
722
  const classifyErrs = validateTriageAutoClassifyOnPlan(plan, rel);
716
723
  const holderErrs = validateTriageHoldMarkersOnPlan(plan, rel);
717
724
  const errors = [...classifyErrs, ...holderErrs];
@@ -1,11 +1,11 @@
1
- /** Auto-generated from scripts/triage_help.py -- do not edit by hand. */
1
+ /** Hand-maintained help registry. Edit directly; no generator script. */
2
2
  export declare const registryData: {
3
3
  readonly registry: {
4
4
  readonly "task triage:summary": {
5
5
  readonly name: "task triage:summary";
6
6
  readonly summary: "One-line state for session-start ritual";
7
7
  readonly refs: "(D2 / #1122)";
8
- readonly description: "Emit the one-line triage state consumed by the session-start ritual. Always exits 0 (status surface, not a gate); appends a JSONL record to vbrief/.triage-cache/summary-history.jsonl for observability.";
8
+ readonly description: "Emit the one-line triage state consumed by the session-start ritual. Always exits 0 (status surface, not a gate); appends a JSONL record to <lifecycle-root>/.triage-cache/summary-history.jsonl for observability.";
9
9
  readonly usage: "task triage:summary [-- --json] [--no-history]";
10
10
  readonly flags: readonly [readonly ["--json", "(off)", "Emit the structured record as JSON instead of the one-liner."], readonly ["--no-history", "(off)", "Suppress the history sidecar append (test-only)."], readonly ["--project-root PATH", "(cwd)", "Project root override (Taskfile threads USER_WORKING_DIR)."]];
11
11
  readonly examples: readonly ["task triage:summary", "task triage:summary -- --json | jq"];
@@ -1,11 +1,11 @@
1
- /** Auto-generated from scripts/triage_help.py -- do not edit by hand. */
1
+ /** Hand-maintained help registry. Edit directly; no generator script. */
2
2
  export const registryData = {
3
3
  registry: {
4
4
  "task triage:summary": {
5
5
  name: "task triage:summary",
6
6
  summary: "One-line state for session-start ritual",
7
7
  refs: "(D2 / #1122)",
8
- description: "Emit the one-line triage state consumed by the session-start ritual. Always exits 0 (status surface, not a gate); appends a JSONL record to vbrief/.triage-cache/summary-history.jsonl for observability.",
8
+ description: "Emit the one-line triage state consumed by the session-start ritual. Always exits 0 (status surface, not a gate); appends a JSONL record to <lifecycle-root>/.triage-cache/summary-history.jsonl for observability.",
9
9
  usage: "task triage:summary [-- --json] [--no-history]",
10
10
  flags: [
11
11
  ["--json", "(off)", "Emit the structured record as JSON instead of the one-liner."],
@@ -4,14 +4,14 @@ export declare const CACHE_DIR_NAME = ".deft-cache";
4
4
  export declare const CACHE_SOURCE_GITHUB_ISSUE = "github-issue";
5
5
  /** Env var honoured for repo inference when `--repo` is absent (#1238). */
6
6
  export declare const ENV_TRIAGE_REPO = "DEFT_TRIAGE_REPO";
7
- /** PROJECT-DEFINITION vBRIEF location for typed-policy lookup. */
8
- export declare const PROJECT_DEFINITION_REL_PATH = "vbrief/PROJECT-DEFINITION.vbrief.json";
7
+ /** PROJECT-DEFINITION xBRIEF location for typed-policy lookup. */
8
+ export declare const PROJECT_DEFINITION_REL_PATH = "xbrief/PROJECT-DEFINITION.xbrief.json";
9
9
  /** Default queue limit when `--limit` is omitted on the CLI surface. */
10
10
  export declare const DEFAULT_QUEUE_LIMIT = 25;
11
11
  /** Default audit log path relative to the deft framework root (candidates_log.REPO_ROOT). */
12
- export declare const DEFAULT_AUDIT_LOG_REL_PATH = "vbrief/.eval/candidates.jsonl";
12
+ export declare const DEFAULT_AUDIT_LOG_REL_PATH = "xbrief/.triage-cache/candidates.jsonl";
13
13
  /** Default slices log path relative to project root. */
14
- export declare const DEFAULT_SLICES_LOG_REL_PATH = "vbrief/.eval/slices.jsonl";
14
+ export declare const DEFAULT_SLICES_LOG_REL_PATH = "xbrief/.triage-cache/slices.jsonl";
15
15
  /** Group display order (#1128 / D13 / #1286). */
16
16
  export declare const GROUP_ORDER: readonly ["ORPHAN", "RESUME", "URGENT", "untriaged", "other", "BLOCKED"];
17
17
  export type QueueGroup = (typeof GROUP_ORDER)[number];
@@ -4,14 +4,14 @@ export const CACHE_DIR_NAME = ".deft-cache";
4
4
  export const CACHE_SOURCE_GITHUB_ISSUE = "github-issue";
5
5
  /** Env var honoured for repo inference when `--repo` is absent (#1238). */
6
6
  export const ENV_TRIAGE_REPO = "DEFT_TRIAGE_REPO";
7
- /** PROJECT-DEFINITION vBRIEF location for typed-policy lookup. */
8
- export const PROJECT_DEFINITION_REL_PATH = "vbrief/PROJECT-DEFINITION.vbrief.json";
7
+ /** PROJECT-DEFINITION xBRIEF location for typed-policy lookup. */
8
+ export const PROJECT_DEFINITION_REL_PATH = "xbrief/PROJECT-DEFINITION.xbrief.json";
9
9
  /** Default queue limit when `--limit` is omitted on the CLI surface. */
10
10
  export const DEFAULT_QUEUE_LIMIT = 25;
11
11
  /** Default audit log path relative to the deft framework root (candidates_log.REPO_ROOT). */
12
- export const DEFAULT_AUDIT_LOG_REL_PATH = "vbrief/.eval/candidates.jsonl";
12
+ export const DEFAULT_AUDIT_LOG_REL_PATH = "xbrief/.triage-cache/candidates.jsonl";
13
13
  /** Default slices log path relative to project root. */
14
- export const DEFAULT_SLICES_LOG_REL_PATH = "vbrief/.eval/slices.jsonl";
14
+ export const DEFAULT_SLICES_LOG_REL_PATH = "xbrief/.triage-cache/slices.jsonl";
15
15
  /** Group display order (#1128 / D13 / #1286). */
16
16
  export const GROUP_ORDER = ["ORPHAN", "RESUME", "URGENT", "untriaged", "other", "BLOCKED"];
17
17
  /** Display labels per group (left-of-issue marker). */
@@ -113,7 +113,13 @@ export function scopeIsBlocked(plan, completedIds) {
113
113
  return deps.length > 0 && deps.some((dep) => !completedIds.has(dep));
114
114
  }
115
115
  function walkScopeFolders(projectRoot, folders, visitor) {
116
- const base = resolveLifecycleRoot(projectRoot);
116
+ let base;
117
+ try {
118
+ base = resolveLifecycleRoot(projectRoot);
119
+ }
120
+ catch {
121
+ return; // No xbrief/ layout present -- nothing to walk.
122
+ }
117
123
  for (const folder of folders) {
118
124
  const folderDir = join(base, folder);
119
125
  if (!existsSync(folderDir)) {
@@ -40,7 +40,13 @@ export function findReconcilable(projectRoot, options = {}) {
40
40
  const items = [];
41
41
  const seen = new Set();
42
42
  for (const folderName of BACKFILL_FOLDERS) {
43
- const folderPath = resolveLifecycleFolder(root, folderName);
43
+ let folderPath;
44
+ try {
45
+ folderPath = resolveLifecycleFolder(root, folderName);
46
+ }
47
+ catch {
48
+ continue; // No xbrief/ layout; skip this folder.
49
+ }
44
50
  for (const [refRepo, number, path] of scanLifecycleRefs(folderPath)) {
45
51
  const effectiveRepo = refRepo ?? defaultRepo;
46
52
  if (effectiveRepo === null)
@@ -65,7 +71,14 @@ function countSkippedExisting(projectRoot, defaultRepo, auditPath) {
65
71
  let count = 0;
66
72
  const root = resolve(projectRoot);
67
73
  for (const folderName of BACKFILL_FOLDERS) {
68
- for (const [refRepo, number] of scanLifecycleRefs(resolveLifecycleFolder(root, folderName))) {
74
+ let folderPath;
75
+ try {
76
+ folderPath = resolveLifecycleFolder(root, folderName);
77
+ }
78
+ catch {
79
+ continue; // No xbrief/ layout; skip this folder.
80
+ }
81
+ for (const [refRepo, number] of scanLifecycleRefs(folderPath)) {
69
82
  const effectiveRepo = refRepo ?? defaultRepo;
70
83
  if (effectiveRepo === null)
71
84
  continue;
@@ -88,7 +101,14 @@ function countNoRepo(projectRoot, defaultRepo, auditPath) {
88
101
  let count = 0;
89
102
  const root = resolve(projectRoot);
90
103
  for (const folderName of BACKFILL_FOLDERS) {
91
- for (const [refRepo, number] of scanLifecycleRefs(resolveLifecycleFolder(root, folderName))) {
104
+ let folderPath;
105
+ try {
106
+ folderPath = resolveLifecycleFolder(root, folderName);
107
+ }
108
+ catch {
109
+ continue; // No xbrief/ layout; skip this folder.
110
+ }
111
+ for (const [refRepo, number] of scanLifecycleRefs(folderPath)) {
92
112
  if ((refRepo ?? defaultRepo) === null && !existingNumbers.has(number))
93
113
  count += 1;
94
114
  }
@@ -1,4 +1,4 @@
1
- export declare const AUDIT_LOG_RELPATH = "vbrief/.eval/candidates.jsonl";
1
+ export declare const AUDIT_LOG_RELPATH = "xbrief/.triage-cache/candidates.jsonl";
2
2
  export declare const BACKFILL_FOLDERS: readonly ["proposed", "pending", "active"];
3
3
  export declare const RECONCILE_ACTOR = "agent:reconcile";
4
4
  export interface ReconcileItem {
@@ -1,4 +1,4 @@
1
- export const AUDIT_LOG_RELPATH = "vbrief/.eval/candidates.jsonl";
1
+ export const AUDIT_LOG_RELPATH = "xbrief/.triage-cache/candidates.jsonl";
2
2
  export const BACKFILL_FOLDERS = ["proposed", "pending", "active"];
3
3
  export const RECONCILE_ACTOR = "agent:reconcile";
4
4
  export function reconcileSummary(result) {
@@ -1,4 +1,4 @@
1
- import { resolve } from "node:path";
1
+ import { join, resolve } from "node:path";
2
2
  import { resolveLifecycleFolder } from "../../layout/resolve.js";
3
3
  import { detectDrift } from "./drift.js";
4
4
  import { iterActiveVbriefs } from "./extract.js";
@@ -21,7 +21,14 @@ function defaultAuditWriter(repo, issueNumber, annotation, log) {
21
21
  }
22
22
  export function refreshActive(projectRoot, options = {}) {
23
23
  const root = resolve(projectRoot);
24
- const activeDir = options.activeDir ?? resolveLifecycleFolder(root, "active");
24
+ let defaultActiveDir;
25
+ try {
26
+ defaultActiveDir = resolveLifecycleFolder(root, "active");
27
+ }
28
+ catch {
29
+ defaultActiveDir = join(root, "xbrief", "active"); // No xbrief/ layout; use canonical path.
30
+ }
31
+ const activeDir = options.activeDir ?? defaultActiveDir;
25
32
  const log = options.log ?? ((line) => process.stdout.write(`${line}\n`));
26
33
  const inputFn = options.inputFn ?? (() => "");
27
34
  const refreshLocal = options.refreshLocal ?? (() => { });
@@ -1,6 +1,6 @@
1
1
  /** Framework default when plan.policy.triageScope is unset (#1131). */
2
2
  export declare const DEFAULT_TRIAGE_SCOPE: ReadonlyArray<Record<string, unknown>>;
3
- export declare const PROJECT_DEFINITION_REL_PATH = "vbrief/PROJECT-DEFINITION.vbrief.json";
3
+ export declare const PROJECT_DEFINITION_REL_PATH = "xbrief/PROJECT-DEFINITION.xbrief.json";
4
4
  export declare const CACHE_DIR_NAME = ".deft-cache";
5
5
  export declare const COVERAGE_FILENAME = "coverage.json";
6
6
  export declare const ENV_COVERAGE_TTL_HOURS = "DEFT_COVERAGE_MAX_AGE_HOURS";
@@ -11,6 +11,6 @@ export declare const VALID_IGNORE_KEYS: Set<string>;
11
11
  export declare const VALID_IGNORE_RULES: Set<string>;
12
12
  export declare const REFERENCED_BY_VBRIEF_SCOPES: Set<string>;
13
13
  export declare const SLICED_FROM_SCOPES: Set<string>;
14
- export declare const SUBSCRIPTION_HISTORY_REL_PATH = "vbrief/.eval/subscription-history.jsonl";
14
+ export declare const SUBSCRIPTION_HISTORY_REL_PATH = "xbrief/.triage-cache/subscription-history.jsonl";
15
15
  export declare const SUBSCRIPTION_HISTORY_SCHEMA = "deft.triage.subscription-change.v1";
16
16
  //# sourceMappingURL=constants.d.ts.map
@@ -1,6 +1,6 @@
1
1
  /** Framework default when plan.policy.triageScope is unset (#1131). */
2
2
  export const DEFAULT_TRIAGE_SCOPE = [{ rule: "all-open" }];
3
- export const PROJECT_DEFINITION_REL_PATH = "vbrief/PROJECT-DEFINITION.vbrief.json";
3
+ export const PROJECT_DEFINITION_REL_PATH = "xbrief/PROJECT-DEFINITION.xbrief.json";
4
4
  export const CACHE_DIR_NAME = ".deft-cache";
5
5
  export const COVERAGE_FILENAME = "coverage.json";
6
6
  export const ENV_COVERAGE_TTL_HOURS = "DEFT_COVERAGE_MAX_AGE_HOURS";
@@ -20,6 +20,6 @@ export const VALID_IGNORE_KEYS = new Set(["label", "milestone"]);
20
20
  export const VALID_IGNORE_RULES = new Set(["author"]);
21
21
  export const REFERENCED_BY_VBRIEF_SCOPES = new Set(["any", "active"]);
22
22
  export const SLICED_FROM_SCOPES = new Set(["any-umbrella-in-cache"]);
23
- export const SUBSCRIPTION_HISTORY_REL_PATH = "vbrief/.eval/subscription-history.jsonl";
23
+ export const SUBSCRIPTION_HISTORY_REL_PATH = "xbrief/.triage-cache/subscription-history.jsonl";
24
24
  export const SUBSCRIPTION_HISTORY_SCHEMA = "deft.triage.subscription-change.v1";
25
25
  //# sourceMappingURL=constants.js.map
@@ -6,7 +6,13 @@ import { subscriptionHash } from "./normalize.js";
6
6
  import { pyListRepr } from "./python-repr.js";
7
7
  const LIFECYCLE_FOLDERS = ["proposed", "pending", "active", "completed", "cancelled"];
8
8
  export function extractReferencedIssues(projectRoot, lifecycleFolders = LIFECYCLE_FOLDERS) {
9
- const root = resolveLifecycleRoot(projectRoot);
9
+ let root;
10
+ try {
11
+ root = resolveLifecycleRoot(projectRoot);
12
+ }
13
+ catch {
14
+ return { any: new Set(), active: new Set() };
15
+ }
10
16
  const anySet = new Set();
11
17
  const activeSet = new Set();
12
18
  if (!existsSync(root))
@@ -119,21 +119,24 @@ function defaultScriptRunner(scriptsDir) {
119
119
  export function copyFixtureToTmp(fixtureRoot, tmpRoot) {
120
120
  const project = tmpRoot;
121
121
  mkdirSync(project, { recursive: true });
122
- mkdirSync(join(project, "vbrief"), { recursive: true });
123
- copyFileSync(join(fixtureRoot, "PROJECT-DEFINITION.vbrief.json"), join(project, "vbrief", "PROJECT-DEFINITION.vbrief.json"));
122
+ mkdirSync(join(project, "xbrief"), { recursive: true });
123
+ const srcPD = join(fixtureRoot, "PROJECT-DEFINITION.xbrief.json");
124
+ if (existsSync(srcPD)) {
125
+ copyFileSync(srcPD, join(project, "xbrief", "PROJECT-DEFINITION.xbrief.json"));
126
+ }
124
127
  for (const sub of ["active", "proposed", "pending", "completed", "cancelled"]) {
125
- const srcDir = join(fixtureRoot, "vbrief", sub);
126
- const dstDir = join(project, "vbrief", sub);
128
+ const srcDir = join(fixtureRoot, "xbrief", sub);
129
+ const dstDir = join(project, "xbrief", sub);
127
130
  mkdirSync(dstDir, { recursive: true });
128
131
  if (existsSync(srcDir)) {
129
132
  for (const name of readdirSync(srcDir)) {
130
- if (name.endsWith(".vbrief.json")) {
133
+ if (name.endsWith(".xbrief.json")) {
131
134
  copyFileSync(join(srcDir, name), join(dstDir, name));
132
135
  }
133
136
  }
134
137
  }
135
138
  }
136
- mkdirSync(join(project, "vbrief", ".eval"), { recursive: true });
139
+ mkdirSync(join(project, "xbrief", ".eval"), { recursive: true });
137
140
  return project;
138
141
  }
139
142
  function defaultInlineRunner() {
@@ -1,6 +1,6 @@
1
- export declare const SUBSCRIPTION_HISTORY_REL_PATH = "vbrief/.triage-cache/subscription-history.jsonl";
1
+ export declare const SUBSCRIPTION_HISTORY_REL_PATH = "xbrief/.triage-cache/subscription-history.jsonl";
2
2
  export declare const SUBSCRIPTION_HISTORY_SCHEMA = "deft.triage.subscription-change.v1";
3
- export declare const PROJECT_DEFINITION_REL_PATH = "vbrief/PROJECT-DEFINITION.vbrief.json";
3
+ export declare const PROJECT_DEFINITION_REL_PATH = "xbrief/PROJECT-DEFINITION.xbrief.json";
4
4
  /** Python ``!r``-style quoting for parity with triage_subscribe.py messages. */
5
5
  export declare function pyRepr(value: string): string;
6
6
  export declare class ProjectDefinitionIOError extends Error {
@@ -5,9 +5,9 @@ import { resolveProjectDefinitionPath } from "../../layout/resolve.js";
5
5
  import { migrateLegacyPolicyKey, PLAN_POLICY_KEY } from "../../policy/plan-extensions.js";
6
6
  import { projectDefinitionMutationLock } from "../../vbrief-build/project-definition-io.js";
7
7
  import { resolveTriageCachePath } from "../cache-path.js";
8
- export const SUBSCRIPTION_HISTORY_REL_PATH = "vbrief/.triage-cache/subscription-history.jsonl";
8
+ export const SUBSCRIPTION_HISTORY_REL_PATH = "xbrief/.triage-cache/subscription-history.jsonl";
9
9
  export const SUBSCRIPTION_HISTORY_SCHEMA = "deft.triage.subscription-change.v1";
10
- export const PROJECT_DEFINITION_REL_PATH = "vbrief/PROJECT-DEFINITION.vbrief.json";
10
+ export const PROJECT_DEFINITION_REL_PATH = "xbrief/PROJECT-DEFINITION.xbrief.json";
11
11
  /** Python ``!r``-style quoting for parity with triage_subscribe.py messages. */
12
12
  export function pyRepr(value) {
13
13
  return `'${value.replace(/\\/g, "\\\\").replace(/'/g, "\\'")}'`;
@@ -4,9 +4,9 @@ export declare const MAX_LINE_CHARS = 120;
4
4
  export { DEFAULT_WIP_CAP, PROJECT_DEFINITION_REL_PATH };
5
5
  export declare const CACHE_DIR_NAME = ".deft-cache";
6
6
  export declare const CACHE_SOURCE = "github-issue";
7
- export declare const CANDIDATES_LOG_REL_PATH = "vbrief/.triage-cache/candidates.jsonl";
7
+ export declare const CANDIDATES_LOG_REL_PATH = "xbrief/.triage-cache/candidates.jsonl";
8
8
  export { latestDecisions, readAuditLog } from "../actions/candidates-log.js";
9
- export declare const SUMMARY_HISTORY_REL_PATH = "vbrief/.triage-cache/summary-history.jsonl";
9
+ export declare const SUMMARY_HISTORY_REL_PATH = "xbrief/.triage-cache/summary-history.jsonl";
10
10
  export declare const SUMMARY_HISTORY_SCHEMA = "deft.triage.summary.v1";
11
11
  /** D2 repeat-suppression window for session-start triage one-liner (#1122 / #1279). */
12
12
  export declare const D2_SUPPRESSION_WINDOW_HOURS = 4;
@@ -18,7 +18,7 @@ export const CACHE_DIR_NAME = ".deft-cache";
18
18
  export const CACHE_SOURCE = "github-issue";
19
19
  export const CANDIDATES_LOG_REL_PATH = AUDIT_LOG_REL_PATH;
20
20
  export { latestDecisions, readAuditLog } from "../actions/candidates-log.js";
21
- export const SUMMARY_HISTORY_REL_PATH = "vbrief/.triage-cache/summary-history.jsonl";
21
+ export const SUMMARY_HISTORY_REL_PATH = "xbrief/.triage-cache/summary-history.jsonl";
22
22
  export const SUMMARY_HISTORY_SCHEMA = "deft.triage.summary.v1";
23
23
  /** D2 repeat-suppression window for session-start triage one-liner (#1122 / #1279). */
24
24
  export const D2_SUPPRESSION_WINDOW_HOURS = 4;
@@ -1,6 +1,6 @@
1
1
  /** Lifecycle folders scanned for reconcilable vBRIEFs (#1468). */
2
2
  export declare const BACKFILL_FOLDERS: readonly ["proposed", "pending", "active"];
3
- export declare const CANDIDATES_LOG_REL_PATH = "vbrief/.triage-cache/candidates.jsonl";
3
+ export declare const CANDIDATES_LOG_REL_PATH = "xbrief/.triage-cache/candidates.jsonl";
4
4
  /**
5
5
  * Count reconcilable issues (#1468) — mirrors `triage_reconcile.count_reconcilable`.
6
6
  */
@@ -1,13 +1,13 @@
1
1
  export declare const CACHE_DIR_NAME = ".deft-cache";
2
2
  export declare const CACHE_SOURCE = "github-issue";
3
- export declare const CANDIDATES_RELPATH: readonly ["vbrief", ".triage-cache", "candidates.jsonl"];
3
+ export declare const CANDIDATES_RELPATH: readonly ["xbrief", ".triage-cache", "candidates.jsonl"];
4
4
  export declare const WIP_LIFECYCLE_DIRS: readonly ["pending", "active"];
5
5
  export declare const AUDIT_LOG_REL_PATH = "meta/policy-changes.log";
6
6
  export declare const DEFAULT_WIP_CAP = 20;
7
7
  export declare const DEFAULT_RELIEF_AGE_DAYS = 30;
8
8
  export declare const TRIAGE_SKILL_PATH = "skills/deft-directive-triage/SKILL.md";
9
9
  export declare const WELCOME_AUDIT_TAG = "triage-welcome";
10
- export declare const SUMMARY_HISTORY_REL_PATH = "vbrief/.triage-cache/summary-history.jsonl";
10
+ export declare const SUMMARY_HISTORY_REL_PATH = "xbrief/.triage-cache/summary-history.jsonl";
11
11
  export declare const SUMMARY_HISTORY_SCHEMA = "deft.triage.summary.v1";
12
12
  export declare const EMPTY_CACHE_LINE = "[triage] cache empty -- run task triage:bootstrap";
13
13
  export declare const MAX_LINE_CHARS = 120;
@@ -1,13 +1,13 @@
1
1
  export const CACHE_DIR_NAME = ".deft-cache";
2
2
  export const CACHE_SOURCE = "github-issue";
3
- export const CANDIDATES_RELPATH = ["vbrief", ".triage-cache", "candidates.jsonl"];
3
+ export const CANDIDATES_RELPATH = ["xbrief", ".triage-cache", "candidates.jsonl"];
4
4
  export const WIP_LIFECYCLE_DIRS = ["pending", "active"];
5
5
  export const AUDIT_LOG_REL_PATH = "meta/policy-changes.log";
6
6
  export const DEFAULT_WIP_CAP = 20;
7
7
  export const DEFAULT_RELIEF_AGE_DAYS = 30;
8
8
  export const TRIAGE_SKILL_PATH = "skills/deft-directive-triage/SKILL.md";
9
9
  export const WELCOME_AUDIT_TAG = "triage-welcome";
10
- export const SUMMARY_HISTORY_REL_PATH = "vbrief/.triage-cache/summary-history.jsonl";
10
+ export const SUMMARY_HISTORY_REL_PATH = "xbrief/.triage-cache/summary-history.jsonl";
11
11
  export const SUMMARY_HISTORY_SCHEMA = "deft.triage.summary.v1";
12
12
  export const EMPTY_CACHE_LINE = "[triage] cache empty -- run task triage:bootstrap";
13
13
  export const MAX_LINE_CHARS = 120;
@@ -43,7 +43,14 @@ export function runOnboardMode(projectRoot, options = {}) {
43
43
  out(`[welcome] --wip-cap must be a positive integer, got ${JSON.stringify(options.wipCap)}.`);
44
44
  return failure(2);
45
45
  }
46
- const pdPath = resolveProjectDefinitionPath(projectRoot);
46
+ let pdPath;
47
+ try {
48
+ pdPath = resolveProjectDefinitionPath(projectRoot);
49
+ }
50
+ catch {
51
+ out(`[welcome] No xbrief/ layout found at ${projectRoot}. Run \`deft migrate:xbrief\` to convert your project from the legacy vbrief/ layout, or run project setup first (deft-directive-setup).`);
52
+ return failure(2);
53
+ }
47
54
  if (!existsSync(pdPath)) {
48
55
  out(`[welcome] No project definition found at ${pdPath}. Run project setup first (deft-directive-setup) before onboarding triage.`);
49
56
  return failure(2);
@@ -5,7 +5,13 @@ import { readPlanPolicy } from "../../policy/plan-extensions.js";
5
5
  import { resolveCandidatesLogPath } from "../cache-path.js";
6
6
  import { CACHE_DIR_NAME, CACHE_SOURCE, DEFAULT_WIP_CAP, SUBSCRIPTION_PRESETS, WIP_LIFECYCLE_DIRS, } from "./constants.js";
7
7
  function loadProjectDefinition(projectRoot) {
8
- const path = resolveProjectDefinitionPath(projectRoot);
8
+ let path;
9
+ try {
10
+ path = resolveProjectDefinitionPath(projectRoot);
11
+ }
12
+ catch {
13
+ return null; // No xbrief/ layout; no project definition.
14
+ }
9
15
  if (!existsSync(path))
10
16
  return null;
11
17
  try {
@@ -44,7 +50,13 @@ export function candidatesLogPath(projectRoot) {
44
50
  }
45
51
  function countWip(projectRoot) {
46
52
  let total = 0;
47
- const root = resolveLifecycleRoot(projectRoot);
53
+ let root;
54
+ try {
55
+ root = resolveLifecycleRoot(projectRoot);
56
+ }
57
+ catch {
58
+ return 0; // No xbrief/ layout; no WIP.
59
+ }
48
60
  for (const sub of WIP_LIFECYCLE_DIRS) {
49
61
  const folder = join(root, sub);
50
62
  if (!existsSync(folder))