@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,2 +1,2 @@
1
- export { ARTIFACT_SUFFIXES, hasArtifactSuffix, isLifecycleArtifactPath, LEGACY_ARTIFACT_DIR, LEGACY_ARTIFACT_SUFFIX, LEGACY_INFO_ROOT_KEY, LIFECYCLE_DIR_NAMES, MIGRATED_ARTIFACT_DIR, MIGRATED_ARTIFACT_SUFFIX, MIGRATED_INFO_ROOT_KEY, projectDefinitionFilename, projectDefinitionRelPath, resolveAuditDir, resolveAuditPath, resolveEvalDir, resolveEvalPath, resolveLifecycleFolder, resolveLifecycleLayout, resolveLifecycleRoot, resolveProjectDefinitionPath, resolveSpecArtifactPath, specArtifactRelPath, stripArtifactSuffix, } from "./resolve.js";
1
+ export { ARTIFACT_SUFFIXES, hasArtifactSuffix, isLifecycleArtifactPath, LIFECYCLE_DIR_NAMES, MIGRATED_ARTIFACT_DIR, MIGRATED_ARTIFACT_SUFFIX, MIGRATED_INFO_ROOT_KEY, projectDefinitionFilename, projectDefinitionRelPath, resolveAuditDir, resolveAuditPath, resolveEvalDir, resolveEvalPath, resolveLifecycleFolder, resolveLifecycleLayout, resolveLifecycleRoot, resolveProjectDefinitionPath, resolveSpecArtifactPath, specArtifactRelPath, stripArtifactSuffix, } from "./resolve.js";
2
2
  //# sourceMappingURL=index.js.map
@@ -1,28 +1,39 @@
1
- import { LEGACY_ARTIFACT_DIR, LEGACY_ARTIFACT_SUFFIX, LEGACY_INFO_ROOT_KEY, MIGRATED_ARTIFACT_DIR, MIGRATED_ARTIFACT_SUFFIX, MIGRATED_INFO_ROOT_KEY } from "../xbrief-migrate/constants.js";
2
- export { LEGACY_ARTIFACT_DIR, LEGACY_ARTIFACT_SUFFIX, LEGACY_INFO_ROOT_KEY, MIGRATED_ARTIFACT_DIR, MIGRATED_ARTIFACT_SUFFIX, MIGRATED_INFO_ROOT_KEY, };
1
+ import { LEGACY_ARTIFACT_DIR, MIGRATED_ARTIFACT_DIR, MIGRATED_ARTIFACT_SUFFIX, MIGRATED_INFO_ROOT_KEY } from "../xbrief-migrate/constants.js";
2
+ export { LEGACY_ARTIFACT_DIR, MIGRATED_ARTIFACT_DIR, MIGRATED_ARTIFACT_SUFFIX, MIGRATED_INFO_ROOT_KEY, };
3
3
  /**
4
- * Lifecycle directory names recognized by the layout-aware resolver, in
5
- * preference order (migrated `xbrief` first, legacy `vbrief` second).
4
+ * Lifecycle directory names recognized by the layout-aware resolver and path
5
+ * validators. Includes both `xbrief` (canonical) and `vbrief` (legacy) so that
6
+ * path-validation helpers remain accurate during and after migration.
6
7
  */
7
8
  export declare const LIFECYCLE_DIR_NAMES: readonly ["xbrief", "vbrief"];
8
9
  /**
9
- * Artifact filename suffixes recognized by the layout-aware resolver, in
10
- * preference order (`.xbrief.json` first, `.vbrief.json` second).
10
+ * Artifact filename suffixes recognized by the layout-aware resolver and path
11
+ * validators. Includes both `.xbrief.json` (canonical) and `.vbrief.json`
12
+ * (legacy) so that path-validation helpers remain accurate during and after
13
+ * migration.
11
14
  */
12
15
  export declare const ARTIFACT_SUFFIXES: readonly [".xbrief.json", ".vbrief.json"];
13
- /** The on-disk lifecycle layout an engine call site should resolve against (#2109). */
16
+ /** The on-disk lifecycle layout an engine call site should resolve against (#2109 / #2112). */
14
17
  export interface LifecycleLayout {
15
- /** The lifecycle directory name -- `xbrief` when migrated, else `vbrief`. */
16
- readonly artifactDir: typeof MIGRATED_ARTIFACT_DIR | typeof LEGACY_ARTIFACT_DIR;
17
- /** The artifact filename suffix matching `artifactDir`. */
18
- readonly artifactSuffix: typeof MIGRATED_ARTIFACT_SUFFIX | typeof LEGACY_ARTIFACT_SUFFIX;
19
- /** The `*BRIEFInfo` root key matching `artifactDir`. */
20
- readonly infoRootKey: typeof MIGRATED_INFO_ROOT_KEY | typeof LEGACY_INFO_ROOT_KEY;
21
- /** Absolute path to the resolved lifecycle root (`<projectRoot>/<artifactDir>`). */
18
+ /** The lifecycle directory name -- always `xbrief` after the vbrief read path removal (#2112). */
19
+ readonly artifactDir: typeof MIGRATED_ARTIFACT_DIR;
20
+ /** The artifact filename suffix -- always `.xbrief.json` after #2112. */
21
+ readonly artifactSuffix: typeof MIGRATED_ARTIFACT_SUFFIX;
22
+ /** The `xBRIEFInfo` root key. */
23
+ readonly infoRootKey: typeof MIGRATED_INFO_ROOT_KEY;
24
+ /** Absolute path to the resolved lifecycle root (`<projectRoot>/xbrief`). */
22
25
  readonly root: string;
23
- /** True when the resolved layout is the migrated `xbrief` layout. */
24
- readonly migrated: boolean;
26
+ /** Always `true` -- the legacy vbrief read path was removed in #2112. */
27
+ readonly migrated: true;
25
28
  }
29
+ /**
30
+ * Returns the layout root for non-layout-sensitive helpers (#2112).
31
+ *
32
+ * - If a valid `xbrief/` layout exists, returns its root.
33
+ * - If only `vbrief/` exists (legacy-only), throws so the caller surfaces the migrate hint.
34
+ * - If neither exists (empty/new project), falls back to `<projectRoot>/xbrief/` canonical path.
35
+ */
36
+ export declare function resolveLayoutRootOrCanonical(projectRoot: string): string;
26
37
  /** True when `name` ends with any recognized artifact suffix (.xbrief.json or .vbrief.json). */
27
38
  export declare function hasArtifactSuffix(name: string): boolean;
28
39
  /**
@@ -31,24 +42,30 @@ export declare function hasArtifactSuffix(name: string): boolean;
31
42
  */
32
43
  export declare function stripArtifactSuffix(name: string): string;
33
44
  /**
34
- * True when a POSIX-style path is a lifecycle artifact under either layout
35
- * root (`xbrief/` or `vbrief/`) carrying either artifact suffix.
45
+ * True when a POSIX-style path is a lifecycle artifact path carrying a
46
+ * recognized lifecycle directory prefix (`xbrief/` or `vbrief/`) and a
47
+ * recognized artifact suffix. The `vbrief/` prefix and `.vbrief.json` suffix
48
+ * remain recognized for path-validation purposes during and after migration.
36
49
  */
37
50
  export declare function isLifecycleArtifactPath(posix: string): boolean;
38
51
  /**
39
- * Resolve the active lifecycle layout for `projectRoot` (#2109 part 1).
52
+ * Resolve the active lifecycle layout for `projectRoot` (#2109 part 1 / #2112).
53
+ *
54
+ * Requires the migrated `xbrief/` layout: the `xbrief/` directory must exist
55
+ * AND contain at least one `.xbrief.json` artifact. If no such layout is found,
56
+ * throws with a clear error directing the operator to run `deft migrate:xbrief`.
57
+ *
58
+ * The legacy `vbrief/` read-path fallback was removed in #2112 (0.73.0 MINOR).
59
+ * Projects that have not migrated must run `deft migrate:xbrief` first.
40
60
  *
41
- * Prefers the migrated `xbrief/` layout only when BOTH the `xbrief/` directory
42
- * exists AND it contains at least one `.xbrief.json` artifact; otherwise falls
43
- * back to the legacy `vbrief/` layout. With only `vbrief/` present (today's
44
- * repo) the result is the legacy layout, so existing behavior is unchanged.
61
+ * @throws {Error} When no `xbrief/` layout with `.xbrief.json` artifacts exists.
45
62
  */
46
63
  export declare function resolveLifecycleLayout(projectRoot: string): LifecycleLayout;
47
64
  /** Convenience accessor for the absolute resolved lifecycle root directory. */
48
65
  export declare function resolveLifecycleRoot(projectRoot: string): string;
49
66
  /**
50
- * Absolute path to a lifecycle folder under the resolved layout root
51
- * (e.g. `<root>/<xbrief|vbrief>/active`). Layout-aware (#2109 part 2a).
67
+ * Absolute path to a lifecycle folder under the resolved `xbrief/` layout root
68
+ * (e.g. `<root>/xbrief/active`). Layout-aware (#2109 part 2a / #2112).
52
69
  */
53
70
  export declare function resolveLifecycleFolder(projectRoot: string, folder: string): string;
54
71
  /** Absolute path to the layout-aware `.eval/` directory for version-eval results (#1703). */
@@ -68,20 +85,19 @@ export declare function projectDefinitionFilename(projectRoot: string): string;
68
85
  export declare function resolveProjectDefinitionPath(projectRoot: string): string;
69
86
  /**
70
87
  * POSIX-style display path to the resolved PROJECT-DEFINITION artifact relative
71
- * to the project root (e.g. `vbrief/PROJECT-DEFINITION.vbrief.json`).
88
+ * to the project root (e.g. `xbrief/PROJECT-DEFINITION.xbrief.json`).
72
89
  */
73
90
  export declare function projectDefinitionRelPath(projectRoot: string): string;
74
91
  /**
75
- * Absolute path to the resolved specification artifact (#2132).
92
+ * Absolute path to the resolved specification artifact (#2132 / #2112).
76
93
  *
77
- * Prefers `xbrief/specification.xbrief.json` on a migrated tree; falls back to
78
- * `vbrief/specification.vbrief.json` on an unmigrated tree. Consistent with the
79
- * layout resolver used by the #2109 Part-2a call-site sweep.
94
+ * Returns `xbrief/specification.xbrief.json`; throws when no migrated xbrief/
95
+ * layout is present (see `resolveLifecycleLayout`).
80
96
  */
81
97
  export declare function resolveSpecArtifactPath(projectRoot: string): string;
82
98
  /**
83
99
  * POSIX-style display path to the resolved specification artifact relative to
84
- * the project root (e.g. `xbrief/specification.xbrief.json`).
100
+ * the project root (`xbrief/specification.xbrief.json`).
85
101
  */
86
102
  export declare function specArtifactRelPath(projectRoot: string): string;
87
103
  //# sourceMappingURL=resolve.d.ts.map
@@ -1,15 +1,18 @@
1
1
  import { readdirSync, statSync } from "node:fs";
2
2
  import { join } from "node:path";
3
- import { LEGACY_ARTIFACT_DIR, LEGACY_ARTIFACT_SUFFIX, LEGACY_INFO_ROOT_KEY, MIGRATED_ARTIFACT_DIR, MIGRATED_ARTIFACT_SUFFIX, MIGRATED_INFO_ROOT_KEY, } from "../xbrief-migrate/constants.js";
4
- export { LEGACY_ARTIFACT_DIR, LEGACY_ARTIFACT_SUFFIX, LEGACY_INFO_ROOT_KEY, MIGRATED_ARTIFACT_DIR, MIGRATED_ARTIFACT_SUFFIX, MIGRATED_INFO_ROOT_KEY, };
3
+ import { LEGACY_ARTIFACT_DIR, LEGACY_ARTIFACT_SUFFIX, MIGRATED_ARTIFACT_DIR, MIGRATED_ARTIFACT_SUFFIX, MIGRATED_INFO_ROOT_KEY, } from "../xbrief-migrate/constants.js";
4
+ export { LEGACY_ARTIFACT_DIR, MIGRATED_ARTIFACT_DIR, MIGRATED_ARTIFACT_SUFFIX, MIGRATED_INFO_ROOT_KEY, };
5
5
  /**
6
- * Lifecycle directory names recognized by the layout-aware resolver, in
7
- * preference order (migrated `xbrief` first, legacy `vbrief` second).
6
+ * Lifecycle directory names recognized by the layout-aware resolver and path
7
+ * validators. Includes both `xbrief` (canonical) and `vbrief` (legacy) so that
8
+ * path-validation helpers remain accurate during and after migration.
8
9
  */
9
10
  export const LIFECYCLE_DIR_NAMES = [MIGRATED_ARTIFACT_DIR, LEGACY_ARTIFACT_DIR];
10
11
  /**
11
- * Artifact filename suffixes recognized by the layout-aware resolver, in
12
- * preference order (`.xbrief.json` first, `.vbrief.json` second).
12
+ * Artifact filename suffixes recognized by the layout-aware resolver and path
13
+ * validators. Includes both `.xbrief.json` (canonical) and `.vbrief.json`
14
+ * (legacy) so that path-validation helpers remain accurate during and after
15
+ * migration.
13
16
  */
14
17
  export const ARTIFACT_SUFFIXES = [MIGRATED_ARTIFACT_SUFFIX, LEGACY_ARTIFACT_SUFFIX];
15
18
  function isDirectory(path) {
@@ -20,6 +23,25 @@ function isDirectory(path) {
20
23
  return false;
21
24
  }
22
25
  }
26
+ /**
27
+ * Returns the layout root for non-layout-sensitive helpers (#2112).
28
+ *
29
+ * - If a valid `xbrief/` layout exists, returns its root.
30
+ * - If only `vbrief/` exists (legacy-only), throws so the caller surfaces the migrate hint.
31
+ * - If neither exists (empty/new project), falls back to `<projectRoot>/xbrief/` canonical path.
32
+ */
33
+ export function resolveLayoutRootOrCanonical(projectRoot) {
34
+ try {
35
+ return resolveLifecycleRoot(projectRoot);
36
+ }
37
+ catch (err) {
38
+ if (isDirectory(join(projectRoot, LEGACY_ARTIFACT_DIR)) &&
39
+ !isDirectory(join(projectRoot, MIGRATED_ARTIFACT_DIR))) {
40
+ throw err; // Legacy-only project: operator must run deft migrate:xbrief.
41
+ }
42
+ return join(projectRoot, MIGRATED_ARTIFACT_DIR); // New/empty project; use canonical path.
43
+ }
44
+ }
23
45
  /** True when `name` ends with any recognized artifact suffix (.xbrief.json or .vbrief.json). */
24
46
  export function hasArtifactSuffix(name) {
25
47
  return ARTIFACT_SUFFIXES.some((suffix) => name.endsWith(suffix));
@@ -37,8 +59,10 @@ export function stripArtifactSuffix(name) {
37
59
  return name;
38
60
  }
39
61
  /**
40
- * True when a POSIX-style path is a lifecycle artifact under either layout
41
- * root (`xbrief/` or `vbrief/`) carrying either artifact suffix.
62
+ * True when a POSIX-style path is a lifecycle artifact path carrying a
63
+ * recognized lifecycle directory prefix (`xbrief/` or `vbrief/`) and a
64
+ * recognized artifact suffix. The `vbrief/` prefix and `.vbrief.json` suffix
65
+ * remain recognized for path-validation purposes during and after migration.
42
66
  */
43
67
  export function isLifecycleArtifactPath(posix) {
44
68
  const underLifecycleDir = LIFECYCLE_DIR_NAMES.some((dir) => posix.startsWith(`${dir}/`));
@@ -64,12 +88,16 @@ function containsMigratedArtifact(root) {
64
88
  return false;
65
89
  }
66
90
  /**
67
- * Resolve the active lifecycle layout for `projectRoot` (#2109 part 1).
91
+ * Resolve the active lifecycle layout for `projectRoot` (#2109 part 1 / #2112).
92
+ *
93
+ * Requires the migrated `xbrief/` layout: the `xbrief/` directory must exist
94
+ * AND contain at least one `.xbrief.json` artifact. If no such layout is found,
95
+ * throws with a clear error directing the operator to run `deft migrate:xbrief`.
68
96
  *
69
- * Prefers the migrated `xbrief/` layout only when BOTH the `xbrief/` directory
70
- * exists AND it contains at least one `.xbrief.json` artifact; otherwise falls
71
- * back to the legacy `vbrief/` layout. With only `vbrief/` present (today's
72
- * repo) the result is the legacy layout, so existing behavior is unchanged.
97
+ * The legacy `vbrief/` read-path fallback was removed in #2112 (0.73.0 MINOR).
98
+ * Projects that have not migrated must run `deft migrate:xbrief` first.
99
+ *
100
+ * @throws {Error} When no `xbrief/` layout with `.xbrief.json` artifacts exists.
73
101
  */
74
102
  export function resolveLifecycleLayout(projectRoot) {
75
103
  const migratedRoot = join(projectRoot, MIGRATED_ARTIFACT_DIR);
@@ -82,28 +110,26 @@ export function resolveLifecycleLayout(projectRoot) {
82
110
  migrated: true,
83
111
  };
84
112
  }
85
- return {
86
- artifactDir: LEGACY_ARTIFACT_DIR,
87
- artifactSuffix: LEGACY_ARTIFACT_SUFFIX,
88
- infoRootKey: LEGACY_INFO_ROOT_KEY,
89
- root: join(projectRoot, LEGACY_ARTIFACT_DIR),
90
- migrated: false,
91
- };
113
+ throw new Error(`No xbrief/ layout found at ${projectRoot}. ` +
114
+ "Run `deft migrate:xbrief` to convert your project from the legacy vbrief/ layout.");
92
115
  }
93
116
  /** Convenience accessor for the absolute resolved lifecycle root directory. */
94
117
  export function resolveLifecycleRoot(projectRoot) {
95
118
  return resolveLifecycleLayout(projectRoot).root;
96
119
  }
97
120
  /**
98
- * Absolute path to a lifecycle folder under the resolved layout root
99
- * (e.g. `<root>/<xbrief|vbrief>/active`). Layout-aware (#2109 part 2a).
121
+ * Absolute path to a lifecycle folder under the resolved `xbrief/` layout root
122
+ * (e.g. `<root>/xbrief/active`). Layout-aware (#2109 part 2a / #2112).
100
123
  */
101
124
  export function resolveLifecycleFolder(projectRoot, folder) {
102
- return join(resolveLifecycleRoot(projectRoot), folder);
125
+ // Throws on a pure vbrief/-only tree (#2112). Falls back to xbrief/ when neither layout exists.
126
+ return join(resolveLayoutRootOrCanonical(projectRoot), folder);
103
127
  }
104
128
  /** Absolute path to the layout-aware `.eval/` directory for version-eval results (#1703). */
105
129
  export function resolveEvalDir(projectRoot) {
106
- return join(resolveLifecycleRoot(projectRoot), ".eval");
130
+ // Throws on a pure vbrief/-only tree (#2112). Falls back to xbrief/ when neither layout exists.
131
+ const layoutRoot = resolveLayoutRootOrCanonical(projectRoot);
132
+ return join(layoutRoot, ".eval");
107
133
  }
108
134
  /** Absolute path under `.eval/` for version-eval artefacts (not triage working-set). */
109
135
  export function resolveEvalPath(projectRoot, ...segments) {
@@ -111,7 +137,9 @@ export function resolveEvalPath(projectRoot, ...segments) {
111
137
  }
112
138
  /** Absolute path to the resolved lifecycle `.audit` directory (#2109 part 2a). */
113
139
  export function resolveAuditDir(projectRoot) {
114
- return join(resolveLifecycleRoot(projectRoot), ".audit");
140
+ // Throws on a pure vbrief/-only tree (#2112). Falls back to xbrief/ when neither layout exists.
141
+ const layoutRoot = resolveLayoutRootOrCanonical(projectRoot);
142
+ return join(layoutRoot, ".audit");
115
143
  }
116
144
  /** Absolute path to a file or subpath under the resolved `.audit` directory. */
117
145
  export function resolveAuditPath(projectRoot, ...segments) {
@@ -122,27 +150,56 @@ export function resolveAuditPath(projectRoot, ...segments) {
122
150
  * (`PROJECT-DEFINITION.xbrief.json` when migrated, else `.vbrief.json`).
123
151
  */
124
152
  export function projectDefinitionFilename(projectRoot) {
125
- return `PROJECT-DEFINITION${resolveLifecycleLayout(projectRoot).artifactSuffix}`;
153
+ // Throws on a pure vbrief/-only tree (#2112). Falls back to xbrief/ when neither layout exists.
154
+ try {
155
+ return `PROJECT-DEFINITION${resolveLifecycleLayout(projectRoot).artifactSuffix}`;
156
+ }
157
+ catch (err) {
158
+ if (isDirectory(join(projectRoot, LEGACY_ARTIFACT_DIR)) &&
159
+ !isDirectory(join(projectRoot, MIGRATED_ARTIFACT_DIR))) {
160
+ throw err;
161
+ }
162
+ return `PROJECT-DEFINITION${MIGRATED_ARTIFACT_SUFFIX}`;
163
+ }
126
164
  }
127
165
  /** Absolute path to the resolved PROJECT-DEFINITION artifact (#2109 part 2a). */
128
166
  export function resolveProjectDefinitionPath(projectRoot) {
129
- const layout = resolveLifecycleLayout(projectRoot);
130
- return join(layout.root, `PROJECT-DEFINITION${layout.artifactSuffix}`);
167
+ // Throws on a pure vbrief/-only tree (#2112). Falls back to xbrief/ when neither layout exists.
168
+ try {
169
+ const layout = resolveLifecycleLayout(projectRoot);
170
+ return join(layout.root, `PROJECT-DEFINITION${layout.artifactSuffix}`);
171
+ }
172
+ catch (err) {
173
+ if (isDirectory(join(projectRoot, LEGACY_ARTIFACT_DIR)) &&
174
+ !isDirectory(join(projectRoot, MIGRATED_ARTIFACT_DIR))) {
175
+ throw err; // Legacy-only project: operator must run deft migrate:xbrief.
176
+ }
177
+ return join(projectRoot, MIGRATED_ARTIFACT_DIR, `PROJECT-DEFINITION${MIGRATED_ARTIFACT_SUFFIX}`);
178
+ }
131
179
  }
132
180
  /**
133
181
  * POSIX-style display path to the resolved PROJECT-DEFINITION artifact relative
134
- * to the project root (e.g. `vbrief/PROJECT-DEFINITION.vbrief.json`).
182
+ * to the project root (e.g. `xbrief/PROJECT-DEFINITION.xbrief.json`).
135
183
  */
136
184
  export function projectDefinitionRelPath(projectRoot) {
137
- const layout = resolveLifecycleLayout(projectRoot);
138
- return `${layout.artifactDir}/PROJECT-DEFINITION${layout.artifactSuffix}`;
185
+ // Throws on a pure vbrief/-only tree (#2112). Falls back to xbrief/ when neither layout exists.
186
+ try {
187
+ const layout = resolveLifecycleLayout(projectRoot);
188
+ return `${layout.artifactDir}/PROJECT-DEFINITION${layout.artifactSuffix}`;
189
+ }
190
+ catch (err) {
191
+ if (isDirectory(join(projectRoot, LEGACY_ARTIFACT_DIR)) &&
192
+ !isDirectory(join(projectRoot, MIGRATED_ARTIFACT_DIR))) {
193
+ throw err;
194
+ }
195
+ return `${MIGRATED_ARTIFACT_DIR}/PROJECT-DEFINITION${MIGRATED_ARTIFACT_SUFFIX}`;
196
+ }
139
197
  }
140
198
  /**
141
- * Absolute path to the resolved specification artifact (#2132).
199
+ * Absolute path to the resolved specification artifact (#2132 / #2112).
142
200
  *
143
- * Prefers `xbrief/specification.xbrief.json` on a migrated tree; falls back to
144
- * `vbrief/specification.vbrief.json` on an unmigrated tree. Consistent with the
145
- * layout resolver used by the #2109 Part-2a call-site sweep.
201
+ * Returns `xbrief/specification.xbrief.json`; throws when no migrated xbrief/
202
+ * layout is present (see `resolveLifecycleLayout`).
146
203
  */
147
204
  export function resolveSpecArtifactPath(projectRoot) {
148
205
  const layout = resolveLifecycleLayout(projectRoot);
@@ -150,7 +207,7 @@ export function resolveSpecArtifactPath(projectRoot) {
150
207
  }
151
208
  /**
152
209
  * POSIX-style display path to the resolved specification artifact relative to
153
- * the project root (e.g. `xbrief/specification.xbrief.json`).
210
+ * the project root (`xbrief/specification.xbrief.json`).
154
211
  */
155
212
  export function specArtifactRelPath(projectRoot) {
156
213
  const layout = resolveLifecycleLayout(projectRoot);
@@ -11,7 +11,7 @@ export declare const TERMINAL_STATUSES: Set<string>;
11
11
  /** Child reference type that marks an epic as decomposed. */
12
12
  export declare const CHILD_REF_TYPE = "x-xbrief/plan";
13
13
  /** Durable tech-debt acceptance ledger relative path segments. */
14
- export declare const TECH_DEBT_LEDGER_RELPATH: readonly ["vbrief", ".audit", "epic-tech-debt-accepted.jsonl"];
14
+ export declare const TECH_DEBT_LEDGER_RELPATH: readonly ["xbrief", ".audit", "epic-tech-debt-accepted.jsonl"];
15
15
  /** Session-start nudge tiers (rate-of-harm ranking). */
16
16
  export declare const TIER_STRANDED = 1;
17
17
  export declare const TIER_STALE_EPIC = 2;
@@ -26,7 +26,7 @@ export const TERMINAL_STATUSES = new Set(["completed", "cancelled", "failed"]);
26
26
  export const CHILD_REF_TYPE = "x-xbrief/plan";
27
27
  /** Durable tech-debt acceptance ledger relative path segments. */
28
28
  export const TECH_DEBT_LEDGER_RELPATH = [
29
- "vbrief",
29
+ "xbrief",
30
30
  ".audit",
31
31
  "epic-tech-debt-accepted.jsonl",
32
32
  ];
@@ -14,7 +14,7 @@ function resolveContentRoot(frameworkRoot) {
14
14
  return frameworkRoot;
15
15
  }
16
16
  export function checkLayout(deftRoot, projectRoot) {
17
- const schemasDir = join(resolveContentRoot(deftRoot), "vbrief", "schemas");
17
+ const schemasDir = join(resolveContentRoot(deftRoot), "xbrief", "schemas");
18
18
  if (!existsSync(schemasDir) || !statSync(schemasDir).isDirectory()) {
19
19
  return {
20
20
  name: "layout",
@@ -22,18 +22,18 @@ export function checkLayout(deftRoot, projectRoot) {
22
22
  message: `Framework schemas dir missing at ${schemasDir}. Refresh the deft checkout (see deft/QUICK-START.md).`,
23
23
  };
24
24
  }
25
- const projectVbrief = join(projectRoot, "vbrief");
26
- if (!existsSync(projectVbrief)) {
25
+ const projectXbrief = join(projectRoot, "xbrief");
26
+ if (!existsSync(projectXbrief)) {
27
27
  return {
28
28
  name: "layout",
29
29
  status: "WARN",
30
- message: `Project vbrief/ not present at ${projectVbrief} -- expected for greenfield projects.`,
30
+ message: `Project xbrief/ not present at ${projectXbrief} -- expected for greenfield projects.`,
31
31
  };
32
32
  }
33
33
  return {
34
34
  name: "layout",
35
35
  status: "PASS",
36
- message: `Framework schemas present; project vbrief/ at ${projectVbrief}.`,
36
+ message: `Framework schemas present; project xbrief/ at ${projectXbrief}.`,
37
37
  };
38
38
  }
39
39
  export function checkGitClean(projectRoot) {
@@ -91,7 +91,7 @@ export function checkDocumentModel(projectRoot) {
91
91
  return {
92
92
  name: "document-model",
93
93
  status: "FAIL",
94
- message: `Generated SPECIFICATION.md detected (source: vbrief/specification.vbrief.json); repair missing lifecycle folder(s) instead of migrating: ${missing.join(", ")}.`,
94
+ message: `Generated SPECIFICATION.md detected (source: xbrief/specification.xbrief.json); repair missing lifecycle folder(s) instead of migrating: ${missing.join(", ")}.`,
95
95
  };
96
96
  }
97
97
  }
@@ -99,18 +99,18 @@ export function checkDocumentModel(projectRoot) {
99
99
  return {
100
100
  name: "document-model",
101
101
  status: "PASS",
102
- message: "Current generated SPECIFICATION.md detected (source: vbrief/specification.vbrief.json); pre-v0.20 migration is not needed.",
102
+ message: "Current generated SPECIFICATION.md detected (source: xbrief/specification.xbrief.json); pre-v0.20 migration is not needed.",
103
103
  };
104
104
  }
105
105
  }
106
- const vbriefRoot = join(projectRoot, "vbrief");
107
- if (existsSync(vbriefRoot)) {
106
+ const xbriefRoot = join(projectRoot, "xbrief");
107
+ if (existsSync(xbriefRoot)) {
108
108
  const missing = missingLifecycleFolders(projectRoot);
109
109
  if (missing.length > 0) {
110
110
  return {
111
111
  name: "document-model",
112
112
  status: "FAIL",
113
- message: `Partial vBRIEF layout detected; missing lifecycle folder(s): ${missing.join(", ")}. Create the folders or follow ${frozenPreCutoverMigrationGuidance()}`,
113
+ message: `Partial xBRIEF layout detected; missing lifecycle folder(s): ${missing.join(", ")}. Create the folders or follow ${frozenPreCutoverMigrationGuidance()}`,
114
114
  };
115
115
  }
116
116
  }
@@ -215,8 +215,8 @@ function inspectSwarmSubagentBackend(data) {
215
215
  source: "default-on-error",
216
216
  };
217
217
  }
218
- function inspectValueFeedbackField(data) {
219
- const field = inspectValueFeedback(data);
218
+ function inspectValueFeedbackField(data, projectRoot) {
219
+ const field = inspectValueFeedback(data, projectRoot);
220
220
  return {
221
221
  name: field.name,
222
222
  current: field.current,
@@ -241,7 +241,7 @@ const REGISTERED_POLICIES = [
241
241
  /** Walk registered inspectors and return one row per field (#1148). */
242
242
  export function inspectAllPolicies(projectRoot) {
243
243
  const [data] = loadProjectDefinition(projectRoot);
244
- return REGISTERED_POLICIES.map((inspect) => inspect(data));
244
+ return REGISTERED_POLICIES.map((inspect) => inspect(data, projectRoot));
245
245
  }
246
246
  /** Look up a single registered field by canonical dotted-path name (or CLI alias). */
247
247
  export function inspectOnePolicy(name, projectRoot) {
@@ -1,5 +1,5 @@
1
- /** Filesystem-relative location of the project-definition vBRIEF (display/back-compat). */
2
- export declare const PROJECT_DEFINITION_REL_PATH = "vbrief/PROJECT-DEFINITION.vbrief.json";
1
+ /** Filesystem-relative location of the project-definition xBRIEF (display/back-compat). */
2
+ export declare const PROJECT_DEFINITION_REL_PATH = "xbrief/PROJECT-DEFINITION.xbrief.json";
3
3
  /** Environment variable emergency bypass for branch protection (#747). */
4
4
  export declare const ENV_BYPASS = "DEFT_ALLOW_DEFAULT_BRANCH_COMMIT";
5
5
  /** Legacy narrative key replaced by the typed flag (#746). */
@@ -3,8 +3,8 @@ import { join, resolve as pathResolve } from "node:path";
3
3
  import { resolveProjectDefinitionPath } from "../layout/resolve.js";
4
4
  import { atomicWriteProjectDefinition, projectDefinitionMutationLock, } from "../vbrief-build/project-definition-io.js";
5
5
  import { migrateLegacyPolicyKey, PLAN_POLICY_KEY, readPlanPolicy } from "./plan-extensions.js";
6
- /** Filesystem-relative location of the project-definition vBRIEF (display/back-compat). */
7
- export const PROJECT_DEFINITION_REL_PATH = "vbrief/PROJECT-DEFINITION.vbrief.json";
6
+ /** Filesystem-relative location of the project-definition xBRIEF (display/back-compat). */
7
+ export const PROJECT_DEFINITION_REL_PATH = "xbrief/PROJECT-DEFINITION.xbrief.json";
8
8
  /** Environment variable emergency bypass for branch protection (#747). */
9
9
  export const ENV_BYPASS = "DEFT_ALLOW_DEFAULT_BRANCH_COMMIT";
10
10
  /** Legacy narrative key replaced by the typed flag (#746). */
@@ -18,7 +18,15 @@ const TRUTHY = new Set(["1", "true", "yes", "on"]);
18
18
  * else PROJECT-DEFINITION.vbrief.json (unchanged on today's tree).
19
19
  */
20
20
  export function projectDefinitionPath(projectRoot) {
21
- return resolveProjectDefinitionPath(pathResolve(projectRoot));
21
+ const root = pathResolve(projectRoot);
22
+ try {
23
+ return resolveProjectDefinitionPath(root);
24
+ }
25
+ catch {
26
+ // No xbrief/ layout; return canonical xbrief path so callers get a predictable
27
+ // "not found" result rather than a thrown error.
28
+ return join(root, PROJECT_DEFINITION_REL_PATH);
29
+ }
22
30
  }
23
31
  function envBypassActive() {
24
32
  const raw = process.env[ENV_BYPASS] ?? "";
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Company-owned GitHub orgs whose repos auto-enable LOCAL value-feedback
3
+ * collection (#2376). Org membership is the consent for local, no-egress
4
+ * collection; network/upstream surfaces stay opt-in regardless.
5
+ */
6
+ export declare const DEFAULT_AUTOENABLE_ORGS: readonly string[];
7
+ /** Optional comma-separated env override that EXTENDS the built-in trusted-org set. */
8
+ export declare const AUTOENABLE_ORGS_ENV = "DEFT_VALUE_AUTOENABLE_ORGS";
9
+ /** Built-in trusted orgs plus any from the env override, normalized to lowercase. */
10
+ export declare function resolveTrustedOrgs(env?: NodeJS.ProcessEnv): Set<string>;
11
+ /** Test/hygiene hook: drop the memoized origin-org lookups. */
12
+ export declare function clearOriginOrgCache(): void;
13
+ export interface OriginOrgOptions {
14
+ /** Test seam for origin-repo resolution; defaults to `inferRepoFromGit`. */
15
+ readonly repoResolver?: (projectRoot: string) => string | null;
16
+ /** Override caching; defaults to caching only when no custom resolver is supplied. */
17
+ readonly useCache?: boolean;
18
+ }
19
+ /**
20
+ * Lowercased owner of the origin remote for `projectRoot`, or null when there is
21
+ * no remote / not a git checkout. Memoized per projectRoot (the org does not
22
+ * change within a session) to keep the resolver off the hot emit path.
23
+ */
24
+ export declare function detectOriginOrg(projectRoot: string, options?: OriginOrgOptions): string | null;
25
+ export interface OrgAutoEnableOptions extends OriginOrgOptions {
26
+ readonly env?: NodeJS.ProcessEnv;
27
+ }
28
+ /**
29
+ * True when `projectRoot`'s origin org is in the trusted-org set (#2376).
30
+ * Fail-safe: any resolution failure (no remote, non-GitHub, git absent) is false.
31
+ */
32
+ export declare function isTrustedOrgAutoEnable(projectRoot: string, options?: OrgAutoEnableOptions): boolean;
33
+ //# sourceMappingURL=value-feedback-autoenable.d.ts.map
@@ -0,0 +1,67 @@
1
+ import { inferRepoFromGit } from "../triage/queue/repo.js";
2
+ /**
3
+ * Company-owned GitHub orgs whose repos auto-enable LOCAL value-feedback
4
+ * collection (#2376). Org membership is the consent for local, no-egress
5
+ * collection; network/upstream surfaces stay opt-in regardless.
6
+ */
7
+ export const DEFAULT_AUTOENABLE_ORGS = ["deftai"];
8
+ /** Optional comma-separated env override that EXTENDS the built-in trusted-org set. */
9
+ export const AUTOENABLE_ORGS_ENV = "DEFT_VALUE_AUTOENABLE_ORGS";
10
+ /** Built-in trusted orgs plus any from the env override, normalized to lowercase. */
11
+ export function resolveTrustedOrgs(env = process.env) {
12
+ const orgs = new Set(DEFAULT_AUTOENABLE_ORGS.map((o) => o.toLowerCase()));
13
+ const raw = env[AUTOENABLE_ORGS_ENV];
14
+ if (typeof raw === "string") {
15
+ for (const part of raw.split(",")) {
16
+ const trimmed = part.trim().toLowerCase();
17
+ if (trimmed.length > 0) {
18
+ orgs.add(trimmed);
19
+ }
20
+ }
21
+ }
22
+ return orgs;
23
+ }
24
+ const originOrgCache = new Map();
25
+ /** Test/hygiene hook: drop the memoized origin-org lookups. */
26
+ export function clearOriginOrgCache() {
27
+ originOrgCache.clear();
28
+ }
29
+ /**
30
+ * Lowercased owner of the origin remote for `projectRoot`, or null when there is
31
+ * no remote / not a git checkout. Memoized per projectRoot (the org does not
32
+ * change within a session) to keep the resolver off the hot emit path.
33
+ */
34
+ export function detectOriginOrg(projectRoot, options = {}) {
35
+ const useCache = options.useCache ?? options.repoResolver === undefined;
36
+ if (useCache && originOrgCache.has(projectRoot)) {
37
+ return originOrgCache.get(projectRoot) ?? null;
38
+ }
39
+ const resolver = options.repoResolver ?? inferRepoFromGit;
40
+ let org = null;
41
+ try {
42
+ const repo = resolver(projectRoot);
43
+ if (typeof repo === "string") {
44
+ const owner = repo.split("/")[0]?.trim().toLowerCase() ?? "";
45
+ org = owner.length > 0 ? owner : null;
46
+ }
47
+ }
48
+ catch {
49
+ org = null;
50
+ }
51
+ if (useCache) {
52
+ originOrgCache.set(projectRoot, org);
53
+ }
54
+ return org;
55
+ }
56
+ /**
57
+ * True when `projectRoot`'s origin org is in the trusted-org set (#2376).
58
+ * Fail-safe: any resolution failure (no remote, non-GitHub, git absent) is false.
59
+ */
60
+ export function isTrustedOrgAutoEnable(projectRoot, options = {}) {
61
+ const org = detectOriginOrg(projectRoot, options);
62
+ if (org === null) {
63
+ return false;
64
+ }
65
+ return resolveTrustedOrgs(options.env).has(org);
66
+ }
67
+ //# sourceMappingURL=value-feedback-autoenable.js.map