@deftai/directive-core 0.65.0 → 0.66.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.
Files changed (152) hide show
  1. package/dist/architecture/sor-preflight.js +6 -4
  2. package/dist/capacity/backfill.js +5 -3
  3. package/dist/capacity/show.js +5 -3
  4. package/dist/category-b-namespace/index.d.ts +39 -0
  5. package/dist/category-b-namespace/index.js +120 -0
  6. package/dist/codebase/default-extractor.js +2 -1
  7. package/dist/codebase/map.js +2 -1
  8. package/dist/codebase/provider.js +4 -2
  9. package/dist/content-contracts/standards/_helpers.js +1 -1
  10. package/dist/doctor/checks.js +2 -1
  11. package/dist/doctor/doctor-state.js +2 -2
  12. package/dist/encoding/patterns.js +19 -0
  13. package/dist/encoding/scan.js +3 -2
  14. package/dist/index.d.ts +2 -0
  15. package/dist/index.js +2 -0
  16. package/dist/init-deposit/refresh.js +2 -1
  17. package/dist/init-deposit/scaffold.js +2 -1
  18. package/dist/install-upgrade/index.d.ts +2 -0
  19. package/dist/install-upgrade/index.js +31 -2
  20. package/dist/intake/issue-emit.d.ts +1 -1
  21. package/dist/intake/issue-emit.js +3 -2
  22. package/dist/intake/issue-ingest.d.ts +24 -0
  23. package/dist/intake/issue-ingest.js +113 -16
  24. package/dist/intake/reconcile-issues.js +11 -4
  25. package/dist/layout/index.d.ts +2 -0
  26. package/dist/layout/index.js +2 -0
  27. package/dist/layout/resolve.d.ts +87 -0
  28. package/dist/layout/resolve.js +159 -0
  29. package/dist/lifecycle/lifecycle-hygiene.d.ts +1 -1
  30. package/dist/lifecycle/lifecycle-hygiene.js +8 -5
  31. package/dist/orchestration/judgment-policy.js +4 -6
  32. package/dist/orchestration/verify-judgment-gates.d.ts +1 -0
  33. package/dist/orchestration/verify-judgment-gates.js +4 -2
  34. package/dist/policy/autonomy.js +4 -6
  35. package/dist/policy/capacity.js +4 -6
  36. package/dist/policy/decisions.d.ts +1 -0
  37. package/dist/policy/decisions.js +4 -2
  38. package/dist/policy/index.d.ts +1 -0
  39. package/dist/policy/index.js +3 -1
  40. package/dist/policy/plan-extensions.d.ts +35 -0
  41. package/dist/policy/plan-extensions.js +57 -0
  42. package/dist/policy/resolve.d.ts +6 -2
  43. package/dist/policy/resolve.js +18 -8
  44. package/dist/policy/wip.js +6 -4
  45. package/dist/preflight-cache/evaluate.js +8 -5
  46. package/dist/release/native-steps.js +4 -3
  47. package/dist/render/framework-commands.js +2 -1
  48. package/dist/render/prd-render.js +2 -2
  49. package/dist/render/project-render.js +23 -5
  50. package/dist/render/roadmap-render.js +36 -8
  51. package/dist/render/scope-outlook.js +3 -2
  52. package/dist/scope/audit-log.js +3 -2
  53. package/dist/scope/capacity-stamp.js +2 -1
  54. package/dist/scope/decompose.js +6 -4
  55. package/dist/scope/decomposed-refs.js +2 -1
  56. package/dist/scope/demote.js +5 -4
  57. package/dist/scope/project-context.js +2 -1
  58. package/dist/scope/project-definition-sync.js +4 -3
  59. package/dist/scope/transition.js +6 -2
  60. package/dist/scope/undo.js +2 -1
  61. package/dist/scope/vbrief-ref.js +5 -3
  62. package/dist/session/resume-conditions.js +2 -1
  63. package/dist/session/ritual-sentinel.js +2 -1
  64. package/dist/session/staleness.js +2 -1
  65. package/dist/slice/record.js +4 -4
  66. package/dist/spec-authority/resolver.js +5 -5
  67. package/dist/swarm/complete-cohort.js +5 -4
  68. package/dist/swarm/launch.js +6 -7
  69. package/dist/swarm/readiness.js +22 -20
  70. package/dist/swarm/subagent-backend.js +2 -5
  71. package/dist/swarm/verify-review-clean.js +2 -1
  72. package/dist/triage/actions/candidates-log.d.ts +3 -0
  73. package/dist/triage/actions/candidates-log.js +8 -2
  74. package/dist/triage/bootstrap/gitignore.js +22 -13
  75. package/dist/triage/bootstrap/index.js +7 -4
  76. package/dist/triage/bulk/index.js +2 -1
  77. package/dist/triage/classify/index.js +13 -11
  78. package/dist/triage/queue/audit.js +3 -3
  79. package/dist/triage/queue/cache.js +3 -2
  80. package/dist/triage/queue/ranking-labels.js +2 -1
  81. package/dist/triage/queue/scope-walk.js +8 -6
  82. package/dist/triage/reconcile/audit.js +2 -1
  83. package/dist/triage/reconcile/parse-uri.js +2 -1
  84. package/dist/triage/reconcile/reconcile.js +8 -7
  85. package/dist/triage/refresh/extract.js +4 -2
  86. package/dist/triage/refresh/refresh.js +3 -2
  87. package/dist/triage/scope/mutations-core.js +13 -9
  88. package/dist/triage/scope/renderers.js +5 -3
  89. package/dist/triage/scope/resolve.js +6 -5
  90. package/dist/triage/scope/validate.js +3 -6
  91. package/dist/triage/scope-drift/add-ignore.js +4 -2
  92. package/dist/triage/scope-drift/scope-rules.js +3 -2
  93. package/dist/triage/subscribe/index.js +13 -7
  94. package/dist/triage/summary/index.js +7 -5
  95. package/dist/triage/summary/reconcilable.js +6 -4
  96. package/dist/triage/summary/scope-drift.js +2 -1
  97. package/dist/triage/welcome/prior-state.js +9 -9
  98. package/dist/triage/welcome/summary.js +9 -8
  99. package/dist/triage/welcome/writers.js +12 -10
  100. package/dist/validate-content/capacity-policy.js +5 -4
  101. package/dist/validate-content/capacity-show.js +5 -3
  102. package/dist/validate-content/filename.d.ts +1 -1
  103. package/dist/validate-content/filename.js +5 -4
  104. package/dist/validate-content/validate-strategy-output.js +14 -5
  105. package/dist/vbrief-build/build.js +1 -1
  106. package/dist/vbrief-build/constants.js +7 -0
  107. package/dist/vbrief-build/speckit.js +3 -2
  108. package/dist/vbrief-reconcile/graph.js +3 -2
  109. package/dist/vbrief-reconcile/labels.js +4 -3
  110. package/dist/vbrief-reconcile/reconciliation.js +5 -1
  111. package/dist/vbrief-reconcile/swarm-deps.js +6 -5
  112. package/dist/vbrief-reconcile/umbrellas.d.ts +1 -1
  113. package/dist/vbrief-reconcile/umbrellas.js +9 -7
  114. package/dist/vbrief-validate/conformance.d.ts +1 -2
  115. package/dist/vbrief-validate/conformance.js +29 -14
  116. package/dist/vbrief-validate/constants.d.ts +18 -1
  117. package/dist/vbrief-validate/constants.js +32 -3
  118. package/dist/vbrief-validate/epic-links.js +3 -2
  119. package/dist/vbrief-validate/filename.js +5 -3
  120. package/dist/vbrief-validate/index.d.ts +3 -1
  121. package/dist/vbrief-validate/index.js +2 -1
  122. package/dist/vbrief-validate/main.js +17 -6
  123. package/dist/vbrief-validate/origin.js +1 -1
  124. package/dist/vbrief-validate/paths.js +2 -1
  125. package/dist/vbrief-validate/plan-hooks.js +4 -3
  126. package/dist/vbrief-validate/registry-status.d.ts +1 -0
  127. package/dist/vbrief-validate/registry-status.js +3 -1
  128. package/dist/vbrief-validate/roundtrip.d.ts +36 -0
  129. package/dist/vbrief-validate/roundtrip.js +168 -0
  130. package/dist/vbrief-validate/schema.d.ts +1 -1
  131. package/dist/vbrief-validate/schema.js +62 -19
  132. package/dist/vbrief-validate/validate-all.js +12 -4
  133. package/dist/verify-source/code-structure-validate.js +8 -4
  134. package/dist/verify-source/contract-drift.d.ts +7 -3
  135. package/dist/verify-source/contract-drift.js +40 -22
  136. package/dist/xbrief-migrate/constants.d.ts +13 -0
  137. package/dist/xbrief-migrate/constants.js +14 -0
  138. package/dist/xbrief-migrate/detect.d.ts +11 -0
  139. package/dist/xbrief-migrate/detect.js +81 -0
  140. package/dist/xbrief-migrate/drift-gate.d.ts +56 -0
  141. package/dist/xbrief-migrate/drift-gate.js +205 -0
  142. package/dist/xbrief-migrate/index.d.ts +7 -0
  143. package/dist/xbrief-migrate/index.js +7 -0
  144. package/dist/xbrief-migrate/migrate-project.d.ts +33 -0
  145. package/dist/xbrief-migrate/migrate-project.js +189 -0
  146. package/dist/xbrief-migrate/signpost.d.ts +5 -0
  147. package/dist/xbrief-migrate/signpost.js +19 -0
  148. package/dist/xbrief-migrate/transforms.d.ts +46 -0
  149. package/dist/xbrief-migrate/transforms.js +182 -0
  150. package/dist/xbrief-migrate/version.d.ts +8 -0
  151. package/dist/xbrief-migrate/version.js +25 -0
  152. package/package.json +11 -3
@@ -0,0 +1,182 @@
1
+ import { LEGACY_ARTIFACT_DIR, LEGACY_ARTIFACT_SUFFIX, LEGACY_INFO_ROOT_KEY, LEGACY_VBRIEF_VERSION, MIGRATED_ARTIFACT_DIR, MIGRATED_ARTIFACT_SUFFIX, MIGRATED_INFO_ROOT_KEY, V08_CONTAINER_ITEM_TYPES, V08_ITEM_STATUS_AUTO, VBRIEF_REFERENCE_PREFIX, VBRIEF_VERSION, XBRIEF_REFERENCE_PREFIX, } from "./constants.js";
2
+ export class TransformError extends Error {
3
+ constructor(message) {
4
+ super(message);
5
+ this.name = "TransformError";
6
+ }
7
+ }
8
+ export class FeatureEmissionRejectedError extends Error {
9
+ constructor(message) {
10
+ super(message);
11
+ this.name = "FeatureEmissionRejectedError";
12
+ }
13
+ }
14
+ export class SplitLayoutRejectedError extends Error {
15
+ constructor(message) {
16
+ super(message);
17
+ this.name = "SplitLayoutRejectedError";
18
+ }
19
+ }
20
+ function isPlainObject(value) {
21
+ return typeof value === "object" && value !== null && !Array.isArray(value);
22
+ }
23
+ /** Return the artifact's declared `*BRIEFInfo.version`, if present. */
24
+ export function readDeclaredArtifactVersion(artifact) {
25
+ for (const key of [MIGRATED_INFO_ROOT_KEY, LEGACY_INFO_ROOT_KEY]) {
26
+ const block = artifact[key];
27
+ if (!isPlainObject(block)) {
28
+ continue;
29
+ }
30
+ const version = block.version;
31
+ if (typeof version === "string") {
32
+ return version;
33
+ }
34
+ }
35
+ return null;
36
+ }
37
+ /** Rewrite embedded path and reference tokens inside a string (idempotent). */
38
+ export function rewriteEmbeddedTokens(value) {
39
+ if (/^https?:\/\//i.test(value)) {
40
+ return value;
41
+ }
42
+ let next = value;
43
+ if (next.includes(VBRIEF_REFERENCE_PREFIX)) {
44
+ next = next.replaceAll(VBRIEF_REFERENCE_PREFIX, XBRIEF_REFERENCE_PREFIX);
45
+ }
46
+ if (next.includes(LEGACY_ARTIFACT_SUFFIX)) {
47
+ next = next.replaceAll(LEGACY_ARTIFACT_SUFFIX, MIGRATED_ARTIFACT_SUFFIX);
48
+ }
49
+ if (next.includes(`${LEGACY_ARTIFACT_DIR}/`)) {
50
+ next = next.replaceAll(`${LEGACY_ARTIFACT_DIR}/`, `${MIGRATED_ARTIFACT_DIR}/`);
51
+ }
52
+ return next;
53
+ }
54
+ function deepRewriteValues(value) {
55
+ if (typeof value === "string") {
56
+ return rewriteEmbeddedTokens(value);
57
+ }
58
+ if (Array.isArray(value)) {
59
+ return value.map((entry) => deepRewriteValues(entry));
60
+ }
61
+ if (isPlainObject(value)) {
62
+ const out = {};
63
+ for (const [key, entry] of Object.entries(value)) {
64
+ out[key] = deepRewriteValues(entry);
65
+ }
66
+ return out;
67
+ }
68
+ return value;
69
+ }
70
+ function isAlreadyV08Artifact(artifact) {
71
+ if (!(MIGRATED_INFO_ROOT_KEY in artifact)) {
72
+ return false;
73
+ }
74
+ const info = artifact[MIGRATED_INFO_ROOT_KEY];
75
+ return isPlainObject(info) && info.version === VBRIEF_VERSION;
76
+ }
77
+ /**
78
+ * Convert a single v0.6 in-document artifact to v0.8 semantics.
79
+ * Idempotent: v0.8 artifacts are returned unchanged (deep-cloned).
80
+ * Transactional: on failure the original input object is not mutated.
81
+ */
82
+ export function transformArtifactV06ToV08(input) {
83
+ const working = structuredClone(input);
84
+ if (isAlreadyV08Artifact(working)) {
85
+ return working;
86
+ }
87
+ if (!(LEGACY_INFO_ROOT_KEY in working)) {
88
+ throw new TransformError(`missing required legacy info block '${LEGACY_INFO_ROOT_KEY}' for v0.6 -> v0.8 transform`);
89
+ }
90
+ const legacyInfo = working[LEGACY_INFO_ROOT_KEY];
91
+ if (!isPlainObject(legacyInfo)) {
92
+ throw new TransformError(`'${LEGACY_INFO_ROOT_KEY}' must be an object`);
93
+ }
94
+ const declaredVersion = legacyInfo.version;
95
+ if (declaredVersion !== LEGACY_VBRIEF_VERSION) {
96
+ throw new TransformError(`expected ${LEGACY_INFO_ROOT_KEY}.version ${LEGACY_VBRIEF_VERSION}, got ${String(declaredVersion)}`);
97
+ }
98
+ delete working[LEGACY_INFO_ROOT_KEY];
99
+ working[MIGRATED_INFO_ROOT_KEY] = {
100
+ ...legacyInfo,
101
+ version: VBRIEF_VERSION,
102
+ };
103
+ const rewritten = deepRewriteValues(working);
104
+ return rewritten;
105
+ }
106
+ /**
107
+ * Apply `transformArtifactV06ToV08` inside a try/catch boundary.
108
+ * On error, returns the original artifact reference unchanged.
109
+ */
110
+ export function transformArtifactV06ToV08Transactional(input) {
111
+ try {
112
+ const artifact = transformArtifactV06ToV08(input);
113
+ const changed = JSON.stringify(artifact) !== JSON.stringify(input);
114
+ return { ok: true, artifact, changed };
115
+ }
116
+ catch (err) {
117
+ const message = err instanceof Error ? err.message : String(err);
118
+ return { ok: false, artifact: input, error: message };
119
+ }
120
+ }
121
+ function walkForV08FeatureEmission(value, path, violations) {
122
+ if (Array.isArray(value)) {
123
+ for (let index = 0; index < value.length; index += 1) {
124
+ walkForV08FeatureEmission(value[index], `${path}[${index}]`, violations);
125
+ }
126
+ return;
127
+ }
128
+ if (!isPlainObject(value)) {
129
+ return;
130
+ }
131
+ if (MIGRATED_INFO_ROOT_KEY in value) {
132
+ violations.push(`${path}: must not emit '${MIGRATED_INFO_ROOT_KEY}' into a v0.6 artifact`);
133
+ }
134
+ if (value.status === V08_ITEM_STATUS_AUTO) {
135
+ violations.push(`${path}.status: must not emit '${V08_ITEM_STATUS_AUTO}' into a v0.6 artifact`);
136
+ }
137
+ if (typeof value.type === "string" && V08_CONTAINER_ITEM_TYPES.has(value.type)) {
138
+ violations.push(`${path}.type: must not emit container type '${value.type}' into a v0.6 artifact`);
139
+ }
140
+ for (const [key, entry] of Object.entries(value)) {
141
+ walkForV08FeatureEmission(entry, `${path}.${key}`, violations);
142
+ }
143
+ }
144
+ /**
145
+ * Locked rule #1 (#2034): refuse v0.8-only constructs unless the artifact declares v0.8.
146
+ * Fail closed when the version block is missing or unreadable.
147
+ */
148
+ export function assertFeatureEmissionAllowed(targetArtifact, emission) {
149
+ const declared = readDeclaredArtifactVersion(targetArtifact);
150
+ if (declared === VBRIEF_VERSION) {
151
+ return;
152
+ }
153
+ const violations = [];
154
+ walkForV08FeatureEmission(emission, "emission", violations);
155
+ if (violations.length === 0) {
156
+ return;
157
+ }
158
+ const context = declared === null
159
+ ? "artifact has no declared version"
160
+ : `artifact declares version ${declared}`;
161
+ throw new FeatureEmissionRejectedError(`${context}; ${violations.join("; ")}`);
162
+ }
163
+ /** Map a desired migrated-relative path to the legacy tree when required. */
164
+ export function resolveLayoutAwareRelativePath(legacyLayout, relativePath) {
165
+ if (!legacyLayout) {
166
+ return relativePath;
167
+ }
168
+ return relativePath
169
+ .replaceAll(`${MIGRATED_ARTIFACT_DIR}/`, `${LEGACY_ARTIFACT_DIR}/`)
170
+ .replaceAll(MIGRATED_ARTIFACT_SUFFIX, LEGACY_ARTIFACT_SUFFIX);
171
+ }
172
+ /**
173
+ * Locked rule #2 (#2034): never target `xbrief/` when the project still uses `vbrief/`.
174
+ */
175
+ export function assertLayoutAwareWritePath(projectRoot, relativePath, legacyLayout) {
176
+ const normalized = relativePath.replace(/\\/g, "/");
177
+ if (legacyLayout && normalized.includes(`${MIGRATED_ARTIFACT_DIR}/`)) {
178
+ throw new SplitLayoutRejectedError(`refusing to write into '${MIGRATED_ARTIFACT_DIR}/' while legacy '${LEGACY_ARTIFACT_DIR}/' layout is present at ${projectRoot}`);
179
+ }
180
+ return resolveLayoutAwareRelativePath(legacyLayout, normalized);
181
+ }
182
+ //# sourceMappingURL=transforms.js.map
@@ -0,0 +1,8 @@
1
+ /** Parse a semver prefix from a deft version marker or manifest tag. */
2
+ export declare function parseSemverPrefix(version: string): [number, number, number] | null;
3
+ /**
4
+ * True when `to` is a strict patch bump over `from` (same major/minor, higher patch).
5
+ * Non-semver inputs are treated as not patch-only (#2034 patch-inert rule).
6
+ */
7
+ export declare function isPatchOnlyUpgrade(from: string | null, to: string): boolean;
8
+ //# sourceMappingURL=version.d.ts.map
@@ -0,0 +1,25 @@
1
+ /** Parse a semver prefix from a deft version marker or manifest tag. */
2
+ export function parseSemverPrefix(version) {
3
+ const normalized = version.trim().replace(/^v/i, "");
4
+ const match = normalized.match(/^(\d+)\.(\d+)\.(\d+)$/);
5
+ if (!match) {
6
+ return null;
7
+ }
8
+ return [Number(match[1]), Number(match[2]), Number(match[3])];
9
+ }
10
+ /**
11
+ * True when `to` is a strict patch bump over `from` (same major/minor, higher patch).
12
+ * Non-semver inputs are treated as not patch-only (#2034 patch-inert rule).
13
+ */
14
+ export function isPatchOnlyUpgrade(from, to) {
15
+ if (from === null) {
16
+ return false;
17
+ }
18
+ const a = parseSemverPrefix(from);
19
+ const b = parseSemverPrefix(to);
20
+ if (a === null || b === null) {
21
+ return false;
22
+ }
23
+ return a[0] === b[0] && a[1] === b[1] && b[2] > a[2];
24
+ }
25
+ //# sourceMappingURL=version.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@deftai/directive-core",
3
- "version": "0.65.0",
3
+ "version": "0.66.1",
4
4
  "description": "TypeScript engine core for the Directive framework.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -30,6 +30,14 @@
30
30
  "types": "./dist/wip-cap/index.d.ts",
31
31
  "default": "./dist/wip-cap/index.js"
32
32
  },
33
+ "./xbrief-migrate": {
34
+ "types": "./dist/xbrief-migrate/index.d.ts",
35
+ "default": "./dist/xbrief-migrate/index.js"
36
+ },
37
+ "./category-b-namespace": {
38
+ "types": "./dist/category-b-namespace/index.d.ts",
39
+ "default": "./dist/category-b-namespace/index.js"
40
+ },
33
41
  "./scm": {
34
42
  "types": "./dist/scm/index.d.ts",
35
43
  "default": "./dist/scm/index.js"
@@ -229,8 +237,8 @@
229
237
  "provenance": true
230
238
  },
231
239
  "dependencies": {
232
- "@deftai/directive-content": "^0.65.0",
233
- "@deftai/directive-types": "^0.65.0",
240
+ "@deftai/directive-content": "^0.66.1",
241
+ "@deftai/directive-types": "^0.66.1",
234
242
  "archiver": "^8.0.0"
235
243
  },
236
244
  "scripts": {