@devtrack-solution/codesdd 1.2.3 → 1.2.4-rc3

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 (139) hide show
  1. package/.sdd/skills/curated/devtrack-api/SKILL.md +12 -5
  2. package/.sdd/skills/curated/devtrack-api/agents/claude-code.yaml +8 -0
  3. package/.sdd/skills/curated/devtrack-api/agents/codex.yaml +8 -0
  4. package/.sdd/skills/curated/devtrack-api/agents/cursor.yaml +8 -0
  5. package/.sdd/skills/curated/devtrack-api/agents/gemini.yaml +8 -0
  6. package/.sdd/skills/curated/devtrack-api/agents/kimi.yaml +8 -0
  7. package/.sdd/skills/curated/devtrack-api/agents/openai.yaml +4 -2
  8. package/.sdd/skills/curated/devtrack-api/agents/opencode.yaml +10 -0
  9. package/.sdd/skills/curated/devtrack-api/references/application-presentation.md +2 -2
  10. package/.sdd/skills/curated/devtrack-api/references/contract-pack.yaml +55 -0
  11. package/.sdd/skills/curated/devtrack-api/references/domain-modeling.md +13 -13
  12. package/.sdd/skills/curated/devtrack-api/references/foundation-layout.md +2 -3
  13. package/.sdd/skills/curated/devtrack-api/references/implementation-checklist.md +1 -1
  14. package/.sdd/skills/curated/devtrack-api/references/portable-agent-contract.md +41 -0
  15. package/.sdd/skills/curated/devtrack-api/references/typeorm-infrastructure.md +7 -9
  16. package/README.md +159 -5
  17. package/dist/applications/sdd/index.d.ts +16 -0
  18. package/dist/applications/sdd/index.js +16 -0
  19. package/dist/commands/config.js +171 -10
  20. package/dist/commands/sdd/execution.js +345 -15
  21. package/dist/commands/sdd/plugin.js +5 -0
  22. package/dist/commands/sdd/shared.d.ts +1 -0
  23. package/dist/commands/sdd/shared.js +10 -0
  24. package/dist/commands/sdd.js +38 -3
  25. package/dist/core/cli/command-matrix.js +9 -0
  26. package/dist/core/cli-command-quality.js +9 -0
  27. package/dist/core/completions/command-registry.js +45 -0
  28. package/dist/core/config-schema.d.ts +18 -1
  29. package/dist/core/config-schema.js +48 -5
  30. package/dist/core/global-config.d.ts +16 -0
  31. package/dist/core/sdd/agent-binding.d.ts +10 -10
  32. package/dist/core/sdd/agent-runtime-contract.d.ts +204 -0
  33. package/dist/core/sdd/agent-runtime-contract.js +200 -0
  34. package/dist/core/sdd/check.d.ts +2 -0
  35. package/dist/core/sdd/check.js +40 -2
  36. package/dist/core/sdd/coordination/coordination-adapters.d.ts +15 -8
  37. package/dist/core/sdd/coordination/coordination-adapters.js +43 -15
  38. package/dist/core/sdd/coordination/index.d.ts +1 -0
  39. package/dist/core/sdd/coordination/index.js +1 -0
  40. package/dist/core/sdd/coordination/redis-runtime.d.ts +131 -0
  41. package/dist/core/sdd/coordination/redis-runtime.js +698 -0
  42. package/dist/core/sdd/deepagent-contracts.d.ts +98 -4
  43. package/dist/core/sdd/deepagent-contracts.js +62 -0
  44. package/dist/core/sdd/default-bootstrap-files.d.ts +2 -2
  45. package/dist/core/sdd/default-bootstrap-files.js +14 -8
  46. package/dist/core/sdd/default-skills.js +108 -4
  47. package/dist/core/sdd/devtrack-api-appliance.d.ts +8 -1
  48. package/dist/core/sdd/devtrack-api-appliance.js +46 -23
  49. package/dist/core/sdd/docs-sync.js +21 -15
  50. package/dist/core/sdd/domain/capability-diff.d.ts +63 -0
  51. package/dist/core/sdd/domain/capability-diff.js +200 -0
  52. package/dist/core/sdd/domain/change-safety-guardrails.d.ts +74 -0
  53. package/dist/core/sdd/domain/change-safety-guardrails.js +333 -0
  54. package/dist/core/sdd/domain/semantic-intent-classifier.d.ts +29 -0
  55. package/dist/core/sdd/domain/semantic-intent-classifier.js +117 -0
  56. package/dist/core/sdd/foundation-artifact-map-validator.d.ts +16 -0
  57. package/dist/core/sdd/foundation-artifact-map-validator.js +71 -0
  58. package/dist/core/sdd/foundation-layer-manifest.d.ts +24 -0
  59. package/dist/core/sdd/foundation-layer-manifest.js +117 -0
  60. package/dist/core/sdd/intent-guard.d.ts +22 -0
  61. package/dist/core/sdd/intent-guard.js +67 -0
  62. package/dist/core/sdd/json-schema.js +9 -1
  63. package/dist/core/sdd/legacy-operations.js +76 -1
  64. package/dist/core/sdd/migrate-workspace.js +39 -0
  65. package/dist/core/sdd/package-security-gates.d.ts +21 -0
  66. package/dist/core/sdd/package-security-gates.js +119 -0
  67. package/dist/core/sdd/package-structure-gate.js +3 -8
  68. package/dist/core/sdd/parallel-feat-automation.d.ts +181 -3
  69. package/dist/core/sdd/parallel-feat-automation.js +212 -0
  70. package/dist/core/sdd/plugin-broker.d.ts +223 -4
  71. package/dist/core/sdd/plugin-broker.js +10 -0
  72. package/dist/core/sdd/plugin-cli.d.ts +30 -0
  73. package/dist/core/sdd/plugin-cli.js +70 -3
  74. package/dist/core/sdd/plugin-evidence.d.ts +73 -0
  75. package/dist/core/sdd/plugin-manifest.d.ts +69 -1
  76. package/dist/core/sdd/plugin-manifest.js +10 -0
  77. package/dist/core/sdd/plugin-policy-pack.d.ts +1 -1
  78. package/dist/core/sdd/plugin-registry.d.ts +141 -5
  79. package/dist/core/sdd/plugin-sdk-contract.d.ts +363 -0
  80. package/dist/core/sdd/plugin-sdk-contract.js +268 -0
  81. package/dist/core/sdd/plugin-skill-binding.d.ts +1 -1
  82. package/dist/core/sdd/quality-validation.d.ts +84 -11
  83. package/dist/core/sdd/release-readiness.d.ts +19 -0
  84. package/dist/core/sdd/release-readiness.js +472 -0
  85. package/dist/core/sdd/runtime-boundary-contract.d.ts +45 -0
  86. package/dist/core/sdd/runtime-boundary-contract.js +90 -0
  87. package/dist/core/sdd/sdk-agent-plugin-quality-gates.d.ts +150 -0
  88. package/dist/core/sdd/sdk-agent-plugin-quality-gates.js +258 -0
  89. package/dist/core/sdd/services/agent-run.service.d.ts +38 -6
  90. package/dist/core/sdd/services/agent-run.service.js +73 -1
  91. package/dist/core/sdd/services/capability-diff.service.d.ts +18 -0
  92. package/dist/core/sdd/services/capability-diff.service.js +26 -0
  93. package/dist/core/sdd/services/change-safety-preflight.service.d.ts +17 -0
  94. package/dist/core/sdd/services/change-safety-preflight.service.js +17 -0
  95. package/dist/core/sdd/services/context.service.d.ts +43 -340
  96. package/dist/core/sdd/services/context.service.js +323 -9
  97. package/dist/core/sdd/services/finalize.service.d.ts +25 -0
  98. package/dist/core/sdd/services/finalize.service.js +178 -16
  99. package/dist/core/sdd/services/frontend-impact.service.d.ts +1 -1
  100. package/dist/core/sdd/services/semantic-intent-classifier.service.d.ts +6 -0
  101. package/dist/core/sdd/services/semantic-intent-classifier.service.js +7 -0
  102. package/dist/core/sdd/state.d.ts +1 -0
  103. package/dist/core/sdd/state.js +251 -29
  104. package/dist/core/sdd/store/sdd-stores.js +2 -2
  105. package/dist/core/sdd/structural-health.d.ts +13 -13
  106. package/dist/core/sdd/types.d.ts +27 -12
  107. package/dist/core/sdd/types.js +4 -0
  108. package/dist/core/sdd/views.js +17 -0
  109. package/dist/core/sdd/workspace-schemas.d.ts +387 -7
  110. package/dist/core/sdd/workspace-schemas.js +196 -64
  111. package/dist/domains/sdd/index.d.ts +6 -0
  112. package/dist/domains/sdd/index.js +6 -0
  113. package/dist/infrastructures/sdd/index.d.ts +7 -0
  114. package/dist/infrastructures/sdd/index.js +6 -0
  115. package/dist/presentations/cli/sdd/index.d.ts +3 -0
  116. package/dist/presentations/cli/sdd/index.js +3 -0
  117. package/dist/shared/sdd/index.d.ts +3 -0
  118. package/dist/shared/sdd/index.js +2 -0
  119. package/package.json +9 -6
  120. package/schemas/sdd/2-plan.schema.json +207 -2
  121. package/schemas/sdd/5-quality.schema.json +281 -25
  122. package/schemas/sdd/agent-runtime-command-plan.schema.json +212 -0
  123. package/schemas/sdd/agent-runtime-opencode-run-evidence.schema.json +270 -0
  124. package/schemas/sdd/codesdd-plugin.schema.json +171 -0
  125. package/schemas/sdd/deepagent-run-request.schema.json +316 -0
  126. package/schemas/sdd/parallel-feat-automation-plan.schema.json +89 -0
  127. package/schemas/sdd/parallel-feat-scheduler-request.schema.json +116 -0
  128. package/schemas/sdd/parallel-feat-scheduler-result.schema.json +404 -0
  129. package/schemas/sdd/plugin-artifact-manifest.schema.json +109 -0
  130. package/schemas/sdd/plugin-artifact-map.schema.json +223 -0
  131. package/schemas/sdd/plugin-evidence-manifest.schema.json +109 -0
  132. package/schemas/sdd/plugin-language-runtime.schema.json +103 -0
  133. package/schemas/sdd/plugin-package-governance.schema.json +74 -0
  134. package/schemas/sdd/plugin-registry.schema.json +171 -0
  135. package/schemas/sdd/plugin-runtime-invocation-plan.schema.json +109 -0
  136. package/schemas/sdd/quality-evidence-bundle.schema.json +109 -0
  137. package/schemas/sdd/sdk-agent-plugin-quality-gate-input.schema.json +168 -0
  138. package/schemas/sdd/sdk-agent-plugin-quality-gate-report.schema.json +160 -0
  139. package/schemas/sdd/workspace-catalog.schema.json +3776 -398
@@ -0,0 +1,333 @@
1
+ export const CHANGE_SAFETY_OPERATIONS = ['add', 'modify', 'remove', 'replace', 'refactor', 'optimize'];
2
+ const DESTRUCTIVE_ADD_OPERATIONS = new Set(['delete', 'replace', 'rename']);
3
+ const GOVERNED_OVERRIDE_REQUIRED_FIELDS = [
4
+ 'feature_id',
5
+ 'intent',
6
+ 'rationale',
7
+ 'rollback_plan',
8
+ 'compensating_control',
9
+ 'approver',
10
+ 'expires_at',
11
+ ];
12
+ export function isChangeSafetyOperation(value) {
13
+ return CHANGE_SAFETY_OPERATIONS.includes(value);
14
+ }
15
+ export function evaluateChangeSafety(contract, plannedChanges, options = {}) {
16
+ const violations = [];
17
+ const operation = contract.explicit_modification_intent?.operation ?? contract.intent?.operation;
18
+ if (plannedChanges.length === 0) {
19
+ violations.push({
20
+ code: 'planned_changes_missing',
21
+ message: 'Mutating change requires at least one planned file change.',
22
+ });
23
+ }
24
+ if (!operation) {
25
+ violations.push({
26
+ code: 'intent_missing',
27
+ message: 'Mutating change requires explicit_modification_intent.operation.',
28
+ });
29
+ }
30
+ else if (!isChangeSafetyOperation(operation)) {
31
+ violations.push({
32
+ code: 'intent_invalid',
33
+ message: `Invalid explicit_modification_intent.operation "${operation}".`,
34
+ });
35
+ }
36
+ const normalizedOperation = isChangeSafetyOperation(operation) ? operation : '';
37
+ const contextLock = contract.context_lock ?? {};
38
+ const governedOverride = evaluateGovernedOverride(contract, plannedChanges, normalizedOperation, options);
39
+ violations.push(...governedOverride.violations);
40
+ const hasValidGovernedOverride = governedOverride.status === 'valid';
41
+ for (const change of plannedChanges) {
42
+ const normalizedPath = normalizeProjectPath(change.path);
43
+ const previousPath = change.previous_path ? normalizeProjectPath(change.previous_path) : '';
44
+ const pathsToCheck = previousPath ? [normalizedPath, previousPath] : [normalizedPath];
45
+ if (normalizedOperation === 'add' && DESTRUCTIVE_ADD_OPERATIONS.has(change.operation)) {
46
+ violations.push({
47
+ code: 'add_intent_destructive_change',
48
+ message: '`operation: add` cannot delete, rename, or replace existing files.',
49
+ path: normalizedPath,
50
+ });
51
+ }
52
+ for (const candidatePath of pathsToCheck) {
53
+ if (isOutsideAllowedPaths(candidatePath, contextLock.allowed_paths)) {
54
+ violations.push({
55
+ code: 'context_lock_outside_allowed_paths',
56
+ message: `Path "${candidatePath}" is outside context_lock.allowed_paths.`,
57
+ path: candidatePath,
58
+ });
59
+ }
60
+ if (matchesAnyPattern(candidatePath, contextLock.forbidden_paths)) {
61
+ violations.push({
62
+ code: 'context_lock_forbidden_path',
63
+ message: `Path "${candidatePath}" matches context_lock.forbidden_paths.`,
64
+ path: candidatePath,
65
+ });
66
+ }
67
+ if (matchesAnyPattern(candidatePath, contextLock.protected_core) && !hasValidGovernedOverride) {
68
+ violations.push({
69
+ code: 'protected_core_change',
70
+ message: `Path "${candidatePath}" matches context_lock.protected_core and requires explicit override.`,
71
+ path: candidatePath,
72
+ });
73
+ }
74
+ }
75
+ }
76
+ const counts = countPlannedChanges(plannedChanges);
77
+ violations.push(...evaluateChangeBudget(contract.change_budget, counts));
78
+ return {
79
+ status: violations.length > 0 ? 'blocked' : 'allowed',
80
+ operation: normalizedOperation,
81
+ violations,
82
+ counts,
83
+ governed_override: governedOverride,
84
+ };
85
+ }
86
+ export function countPlannedChanges(plannedChanges) {
87
+ const changedPaths = new Set();
88
+ let newFiles = 0;
89
+ let deletedFiles = 0;
90
+ for (const change of plannedChanges) {
91
+ changedPaths.add(normalizeProjectPath(change.path));
92
+ if (change.previous_path) {
93
+ changedPaths.add(normalizeProjectPath(change.previous_path));
94
+ }
95
+ if (change.operation === 'create') {
96
+ newFiles += 1;
97
+ }
98
+ if (change.operation === 'delete' || change.operation === 'replace') {
99
+ deletedFiles += 1;
100
+ }
101
+ if (change.operation === 'rename') {
102
+ newFiles += 1;
103
+ deletedFiles += 1;
104
+ }
105
+ }
106
+ return {
107
+ files_changed: changedPaths.size,
108
+ new_files: newFiles,
109
+ deleted_files: deletedFiles,
110
+ };
111
+ }
112
+ export function normalizeProjectPath(value) {
113
+ return value
114
+ .replace(/\\/g, '/')
115
+ .replace(/^\.\/+/, '')
116
+ .split('/')
117
+ .filter((segment) => segment.length > 0 && segment !== '.')
118
+ .join('/');
119
+ }
120
+ function evaluateGovernedOverride(contract, plannedChanges, operation, options) {
121
+ const requiredPaths = collectGovernedOverrideRequiredPaths(contract.context_lock, plannedChanges);
122
+ if (requiredPaths.length === 0) {
123
+ return {
124
+ required: false,
125
+ status: 'not_required',
126
+ violations: [],
127
+ };
128
+ }
129
+ const override = contract.governed_override;
130
+ if (!override) {
131
+ return {
132
+ required: true,
133
+ status: 'invalid',
134
+ violations: [
135
+ {
136
+ code: 'governed_override_required',
137
+ message: 'Replacement or protected-core change requires change_safety.governed_override.',
138
+ },
139
+ ],
140
+ };
141
+ }
142
+ const violations = [];
143
+ for (const field of GOVERNED_OVERRIDE_REQUIRED_FIELDS) {
144
+ if (!isNonEmptyString(override[field])) {
145
+ violations.push({
146
+ code: 'governed_override_field_missing',
147
+ message: `change_safety.governed_override.${field} is required.`,
148
+ });
149
+ }
150
+ }
151
+ if (!Array.isArray(override.write_scope) || override.write_scope.length === 0) {
152
+ violations.push({
153
+ code: 'governed_override_field_missing',
154
+ message: 'change_safety.governed_override.write_scope must include at least one path pattern.',
155
+ });
156
+ }
157
+ if (!Array.isArray(override.expected_deletions)) {
158
+ violations.push({
159
+ code: 'governed_override_field_missing',
160
+ message: 'change_safety.governed_override.expected_deletions must be declared.',
161
+ });
162
+ }
163
+ if (options.feature_id && override.feature_id && override.feature_id !== options.feature_id) {
164
+ violations.push({
165
+ code: 'governed_override_feature_mismatch',
166
+ message: `change_safety.governed_override.feature_id "${override.feature_id}" does not match "${options.feature_id}".`,
167
+ });
168
+ }
169
+ if (operation && override.intent && override.intent !== operation) {
170
+ violations.push({
171
+ code: 'governed_override_intent_mismatch',
172
+ message: `change_safety.governed_override.intent "${override.intent}" does not match explicit intent "${operation}".`,
173
+ });
174
+ }
175
+ violations.push(...evaluateOverrideExpiration(override.expires_at, options.now));
176
+ const writeScope = override.write_scope ?? [];
177
+ for (const candidatePath of requiredPaths) {
178
+ if (!matchesAnyPattern(candidatePath, writeScope)) {
179
+ violations.push({
180
+ code: 'governed_override_scope_mismatch',
181
+ message: `Path "${candidatePath}" is outside change_safety.governed_override.write_scope.`,
182
+ path: candidatePath,
183
+ });
184
+ }
185
+ }
186
+ const expectedDeletions = override.expected_deletions;
187
+ if (Array.isArray(expectedDeletions)) {
188
+ const actualDeletions = collectDestructivePaths(plannedChanges);
189
+ const declaredDeletions = normalizeSortedUnique(expectedDeletions);
190
+ if (!sameStringList(actualDeletions, declaredDeletions)) {
191
+ violations.push({
192
+ code: 'governed_override_deletions_mismatch',
193
+ message: `change_safety.governed_override.expected_deletions must match planned destructive paths. Expected ${JSON.stringify(actualDeletions)}, received ${JSON.stringify(declaredDeletions)}.`,
194
+ });
195
+ }
196
+ }
197
+ return {
198
+ required: true,
199
+ status: violations.length === 0 ? 'valid' : 'invalid',
200
+ violations,
201
+ };
202
+ }
203
+ function collectGovernedOverrideRequiredPaths(contextLock, plannedChanges) {
204
+ const required = new Set();
205
+ for (const change of plannedChanges) {
206
+ const affectedPaths = getAffectedPaths(change);
207
+ if (change.operation === 'replace') {
208
+ affectedPaths.forEach((path) => required.add(path));
209
+ }
210
+ for (const candidatePath of affectedPaths) {
211
+ if (matchesAnyPattern(candidatePath, contextLock?.protected_core)) {
212
+ required.add(candidatePath);
213
+ }
214
+ }
215
+ }
216
+ return [...required].sort();
217
+ }
218
+ function collectDestructivePaths(plannedChanges) {
219
+ const paths = new Set();
220
+ for (const change of plannedChanges) {
221
+ if (change.operation === 'delete' || change.operation === 'replace') {
222
+ paths.add(normalizeProjectPath(change.path));
223
+ }
224
+ if (change.operation === 'rename') {
225
+ paths.add(normalizeProjectPath(change.previous_path ?? change.path));
226
+ }
227
+ }
228
+ return [...paths].sort();
229
+ }
230
+ function getAffectedPaths(change) {
231
+ const paths = [normalizeProjectPath(change.path)];
232
+ if (change.previous_path) {
233
+ paths.push(normalizeProjectPath(change.previous_path));
234
+ }
235
+ return paths;
236
+ }
237
+ function evaluateOverrideExpiration(expiresAt, now) {
238
+ if (!expiresAt)
239
+ return [];
240
+ const expiresAtMs = Date.parse(expiresAt);
241
+ if (!Number.isFinite(expiresAtMs)) {
242
+ return [
243
+ {
244
+ code: 'governed_override_expires_at_invalid',
245
+ message: 'change_safety.governed_override.expires_at must be a valid ISO timestamp.',
246
+ },
247
+ ];
248
+ }
249
+ const nowMs = now ? new Date(now).getTime() : Date.now();
250
+ if (expiresAtMs <= nowMs) {
251
+ return [
252
+ {
253
+ code: 'governed_override_expired',
254
+ message: 'change_safety.governed_override.expires_at has expired.',
255
+ },
256
+ ];
257
+ }
258
+ return [];
259
+ }
260
+ function normalizeSortedUnique(values) {
261
+ return [...new Set(values.map(normalizeProjectPath))].sort();
262
+ }
263
+ function sameStringList(left, right) {
264
+ return left.length === right.length && left.every((value, index) => value === right[index]);
265
+ }
266
+ function isNonEmptyString(value) {
267
+ return typeof value === 'string' && value.trim().length > 0;
268
+ }
269
+ function evaluateChangeBudget(budget, counts) {
270
+ if (!budget)
271
+ return [];
272
+ const violations = [];
273
+ if (exceedsBudget(counts.files_changed, budget.max_files_changed)) {
274
+ violations.push({
275
+ code: 'change_budget_files_exceeded',
276
+ message: `Changed files count ${counts.files_changed} exceeds change_budget.max_files_changed ${budget.max_files_changed}.`,
277
+ limit: budget.max_files_changed,
278
+ actual: counts.files_changed,
279
+ });
280
+ }
281
+ if (exceedsBudget(counts.new_files, budget.max_new_files)) {
282
+ violations.push({
283
+ code: 'change_budget_new_files_exceeded',
284
+ message: `New files count ${counts.new_files} exceeds change_budget.max_new_files ${budget.max_new_files}.`,
285
+ limit: budget.max_new_files,
286
+ actual: counts.new_files,
287
+ });
288
+ }
289
+ if (exceedsBudget(counts.deleted_files, budget.max_deleted_files)) {
290
+ violations.push({
291
+ code: 'change_budget_deleted_files_exceeded',
292
+ message: `Deleted files count ${counts.deleted_files} exceeds change_budget.max_deleted_files ${budget.max_deleted_files}.`,
293
+ limit: budget.max_deleted_files,
294
+ actual: counts.deleted_files,
295
+ });
296
+ }
297
+ return violations;
298
+ }
299
+ function exceedsBudget(actual, limit) {
300
+ return typeof limit === 'number' && actual > limit;
301
+ }
302
+ function isOutsideAllowedPaths(candidatePath, allowedPatterns) {
303
+ if (!allowedPatterns || allowedPatterns.length === 0)
304
+ return false;
305
+ return !matchesAnyPattern(candidatePath, allowedPatterns);
306
+ }
307
+ function matchesAnyPattern(candidatePath, patterns) {
308
+ if (!patterns || patterns.length === 0)
309
+ return false;
310
+ return patterns.some((pattern) => pathMatchesPattern(candidatePath, pattern));
311
+ }
312
+ export function pathMatchesPattern(candidatePath, pattern) {
313
+ const normalizedPath = normalizeProjectPath(candidatePath);
314
+ const exactDirectory = /[\\/]$/.test(pattern);
315
+ const normalizedPattern = normalizeProjectPath(pattern);
316
+ if (!normalizedPattern)
317
+ return false;
318
+ if (exactDirectory) {
319
+ return normalizedPath === normalizedPattern || normalizedPath.startsWith(`${normalizedPattern}/`);
320
+ }
321
+ const regex = globToRegExp(normalizedPattern);
322
+ return regex.test(normalizedPath);
323
+ }
324
+ function globToRegExp(pattern) {
325
+ const placeholder = '\u0000';
326
+ const escaped = pattern
327
+ .split('**')
328
+ .map((part) => part.replace(/[.+^${}()|[\]\\]/g, '\\$&').replace(/\*/g, '[^/]*'))
329
+ .join(placeholder);
330
+ const source = escaped.replaceAll(placeholder, '.*');
331
+ return new RegExp(`^${source}$`);
332
+ }
333
+ //# sourceMappingURL=change-safety-guardrails.js.map
@@ -0,0 +1,29 @@
1
+ import type { CapabilityDiffReport, CapabilityRiskReport } from './capability-diff.js';
2
+ import type { ChangeSafetyOperation } from './change-safety-guardrails.js';
3
+ export declare const SEMANTIC_INTENT_CLASSES: readonly ["incremental", "refactor", "replacement", "ambiguous"];
4
+ export type SemanticIntentClass = (typeof SEMANTIC_INTENT_CLASSES)[number];
5
+ export interface SemanticIntentClassifierInput {
6
+ objective?: string;
7
+ declared_operation?: ChangeSafetyOperation | '';
8
+ capability_diff?: CapabilityDiffReport;
9
+ deterministic_risk?: CapabilityRiskReport;
10
+ }
11
+ export interface SemanticIntentSignal {
12
+ code: string;
13
+ message: string;
14
+ weight: number;
15
+ }
16
+ export interface SemanticIntentClassification {
17
+ schema_version: 1;
18
+ contract: 'semantic-intent-classification/v1';
19
+ status: 'allowed' | 'blocked';
20
+ classification: SemanticIntentClass;
21
+ fail_closed: true;
22
+ triggered: boolean;
23
+ confidence: number;
24
+ reasons: string[];
25
+ signals: SemanticIntentSignal[];
26
+ }
27
+ export declare function shouldRunSemanticIntentClassifier(input: SemanticIntentClassifierInput): boolean;
28
+ export declare function classifySemanticIntent(input: SemanticIntentClassifierInput): SemanticIntentClassification;
29
+ //# sourceMappingURL=semantic-intent-classifier.d.ts.map
@@ -0,0 +1,117 @@
1
+ export const SEMANTIC_INTENT_CLASSES = ['incremental', 'refactor', 'replacement', 'ambiguous'];
2
+ const REPLACEMENT_PATTERNS = [
3
+ /\breplace\b/iu,
4
+ /\brewrite\b/iu,
5
+ /\brebuild\b/iu,
6
+ /\bfrom scratch\b/iu,
7
+ /\boverwrite\b/iu,
8
+ /\bsubstitu(?:ir|icao|ição)\b/iu,
9
+ /\bsobrescrev/iu,
10
+ /\breescrev/iu,
11
+ /\bdo zero\b/iu,
12
+ ];
13
+ const REFACTOR_PATTERNS = [/\brefactor\b/iu, /\brefator/iu, /\boptimi[sz]e\b/iu, /\botimiz/iu];
14
+ const INCREMENTAL_PATTERNS = [
15
+ /\badd\b/iu,
16
+ /\bcreate\b/iu,
17
+ /\bextend\b/iu,
18
+ /\bincremental\b/iu,
19
+ /\bcriar\b/iu,
20
+ /\badicionar\b/iu,
21
+ /\bincrement/iu,
22
+ ];
23
+ const HIGH_RISK_LEVELS = new Set(['high', 'critical']);
24
+ export function shouldRunSemanticIntentClassifier(input) {
25
+ return Boolean(input.deterministic_risk && HIGH_RISK_LEVELS.has(input.deterministic_risk.level));
26
+ }
27
+ export function classifySemanticIntent(input) {
28
+ const triggered = shouldRunSemanticIntentClassifier(input);
29
+ const signals = collectSignals(input);
30
+ const classification = resolveClassification(input, signals);
31
+ const highRisk = Boolean(input.deterministic_risk && HIGH_RISK_LEVELS.has(input.deterministic_risk.level));
32
+ const blocked = triggered &&
33
+ (classification === 'replacement' ||
34
+ classification === 'ambiguous' ||
35
+ (highRisk && input.declared_operation === 'add' && hasRemovedCapability(input.capability_diff)));
36
+ return {
37
+ schema_version: 1,
38
+ contract: 'semantic-intent-classification/v1',
39
+ status: blocked ? 'blocked' : 'allowed',
40
+ classification,
41
+ fail_closed: true,
42
+ triggered,
43
+ confidence: confidenceFor(classification, signals),
44
+ reasons: blocked ? blockedReasons(classification, input) : [],
45
+ signals,
46
+ };
47
+ }
48
+ function collectSignals(input) {
49
+ const objective = input.objective ?? '';
50
+ const signals = [];
51
+ collectPatternSignals(objective, REPLACEMENT_PATTERNS, signals, 'replacement_language', 50);
52
+ collectPatternSignals(objective, REFACTOR_PATTERNS, signals, 'refactor_language', 30);
53
+ collectPatternSignals(objective, INCREMENTAL_PATTERNS, signals, 'incremental_language', 30);
54
+ if (input.declared_operation === 'replace' || input.declared_operation === 'remove') {
55
+ signals.push({
56
+ code: 'declared_replacement_operation',
57
+ message: `Declared operation ${input.declared_operation} is replacement-class.`,
58
+ weight: 60,
59
+ });
60
+ }
61
+ if (hasRemovedCapability(input.capability_diff)) {
62
+ signals.push({
63
+ code: 'removed_capability_present',
64
+ message: 'Capability diff contains removed capabilities.',
65
+ weight: 45,
66
+ });
67
+ }
68
+ if (input.deterministic_risk?.level === 'critical') {
69
+ signals.push({
70
+ code: 'critical_deterministic_risk',
71
+ message: 'Deterministic risk is critical.',
72
+ weight: 50,
73
+ });
74
+ }
75
+ return signals.sort((left, right) => right.weight - left.weight || left.code.localeCompare(right.code));
76
+ }
77
+ function collectPatternSignals(value, patterns, signals, code, weight) {
78
+ if (patterns.some((pattern) => pattern.test(value))) {
79
+ signals.push({ code, message: `Objective matched ${code}.`, weight });
80
+ }
81
+ }
82
+ function resolveClassification(input, signals) {
83
+ const hasReplacement = signals.some((signal) => ['replacement_language', 'declared_replacement_operation', 'removed_capability_present'].includes(signal.code));
84
+ const hasIncremental = signals.some((signal) => signal.code === 'incremental_language') || input.declared_operation === 'add';
85
+ const hasRefactor = signals.some((signal) => signal.code === 'refactor_language') || input.declared_operation === 'refactor';
86
+ if (hasReplacement && (hasIncremental || hasRefactor))
87
+ return 'ambiguous';
88
+ if (hasReplacement)
89
+ return 'replacement';
90
+ if (hasRefactor)
91
+ return 'refactor';
92
+ if (hasIncremental)
93
+ return 'incremental';
94
+ return input.deterministic_risk && HIGH_RISK_LEVELS.has(input.deterministic_risk.level) ? 'ambiguous' : 'incremental';
95
+ }
96
+ function hasRemovedCapability(diff) {
97
+ return Boolean(diff?.entries.some((entry) => entry.change === 'removed'));
98
+ }
99
+ function confidenceFor(classification, signals) {
100
+ if (classification === 'ambiguous')
101
+ return 50;
102
+ const total = Math.min(100, signals.filter((signal) => signal.weight > 0).reduce((sum, signal) => sum + signal.weight, 40));
103
+ return total;
104
+ }
105
+ function blockedReasons(classification, input) {
106
+ if (classification === 'replacement') {
107
+ return ['Semantic intent classifier fail-closed because the request is replacement-class.'];
108
+ }
109
+ if (classification === 'ambiguous') {
110
+ return ['Semantic intent classifier fail-closed because high-risk intent is ambiguous.'];
111
+ }
112
+ if (input.declared_operation === 'add' && hasRemovedCapability(input.capability_diff)) {
113
+ return ['Semantic intent classifier fail-closed because add intent conflicts with removed capabilities.'];
114
+ }
115
+ return [];
116
+ }
117
+ //# sourceMappingURL=semantic-intent-classifier.js.map
@@ -0,0 +1,16 @@
1
+ import { type PluginArtifactMap } from './plugin-sdk-contract.js';
2
+ export type FoundationArtifactMapFindingCode = 'FOUNDATION_ARTIFACT_SCHEMA_INVALID' | 'FOUNDATION_LAYER_PATH_MISMATCH' | 'FOUNDATION_DOMAIN_BO_PATH_INVALID' | 'FOUNDATION_DOMAIN_VO_PATH_INVALID' | 'FOUNDATION_APPLICATION_PORT_PATH_INVALID' | 'FOUNDATION_INFRASTRUCTURE_ENTITY_PATH_INVALID';
3
+ export interface FoundationArtifactMapFinding {
4
+ code: FoundationArtifactMapFindingCode;
5
+ severity: 'warn';
6
+ path?: string;
7
+ message: string;
8
+ remediation: string;
9
+ }
10
+ export interface FoundationArtifactMapValidationResult {
11
+ status: 'passed' | 'warning';
12
+ artifact_map?: PluginArtifactMap;
13
+ findings: FoundationArtifactMapFinding[];
14
+ }
15
+ export declare function validateFoundationArtifactMapArchitecture(value: unknown): FoundationArtifactMapValidationResult;
16
+ //# sourceMappingURL=foundation-artifact-map-validator.d.ts.map
@@ -0,0 +1,71 @@
1
+ import { pluginArtifactMapSchema, } from './plugin-sdk-contract.js';
2
+ const LAYER_PATH_PREFIXES = {
3
+ domain: 'src/domain/',
4
+ application: 'src/application/',
5
+ infrastructure: 'src/infrastructure/',
6
+ presentation: 'src/presentation/',
7
+ tests: 'test/',
8
+ docs: 'docs/',
9
+ sdd: '.sdd/',
10
+ config: '.',
11
+ };
12
+ const DOMAIN_BO_PATTERN = /^src\/domain\/[^/]+\/business-objects\/[^/]+\.bo\.ts$/u;
13
+ const DOMAIN_VO_PATTERN = /^src\/domain\/[^/]+\/value-objects\/[^/]+\.vo\.ts$/u;
14
+ const APPLICATION_PORT_PATTERN = /^src\/application\/business\/[^/]+\/ports\/out\/[^/]+\.port\.ts$/u;
15
+ const INFRASTRUCTURE_ENTITY_PATTERN = /^src\/infrastructure\/adapters\/orm\/entities\/[^/]+\.orm-entity\.ts$/u;
16
+ export function validateFoundationArtifactMapArchitecture(value) {
17
+ const parsed = pluginArtifactMapSchema.safeParse(value);
18
+ if (!parsed.success) {
19
+ return {
20
+ status: 'warning',
21
+ findings: [
22
+ {
23
+ code: 'FOUNDATION_ARTIFACT_SCHEMA_INVALID',
24
+ severity: 'warn',
25
+ message: `Artifact map failed SDK schema validation: ${parsed.error.issues.map(formatIssue).join('; ')}`,
26
+ remediation: 'Validate the artifact map with @devtrack-solution/codesdd-plugin-sdk before applying Foundation architecture checks.',
27
+ },
28
+ ],
29
+ };
30
+ }
31
+ const findings = parsed.data.artifacts.flatMap(validateEntry);
32
+ return {
33
+ status: findings.length > 0 ? 'warning' : 'passed',
34
+ artifact_map: parsed.data,
35
+ findings,
36
+ };
37
+ }
38
+ function validateEntry(entry) {
39
+ const findings = [];
40
+ const expectedPrefix = LAYER_PATH_PREFIXES[entry.layer];
41
+ if (expectedPrefix && !entry.path.startsWith(expectedPrefix)) {
42
+ findings.push(finding('FOUNDATION_LAYER_PATH_MISMATCH', entry, `Artifact declares layer "${entry.layer}" but path "${entry.path}" does not use the expected prefix "${expectedPrefix}".`, `Move the artifact under ${expectedPrefix} or correct the layer metadata before execution.`));
43
+ }
44
+ if (entry.layer === 'domain' && entry.role === 'business-object' && !DOMAIN_BO_PATTERN.test(entry.path)) {
45
+ findings.push(finding('FOUNDATION_DOMAIN_BO_PATH_INVALID', entry, `Domain business object path "${entry.path}" does not match the Foundation BO-pattern.`, 'Use src/domain/<context>/business-objects/<name>.bo.ts for new Foundation contexts.'));
46
+ }
47
+ if (entry.layer === 'domain' && entry.role === 'value-object' && !DOMAIN_VO_PATTERN.test(entry.path)) {
48
+ findings.push(finding('FOUNDATION_DOMAIN_VO_PATH_INVALID', entry, `Domain value object path "${entry.path}" does not match the Foundation VO-pattern.`, 'Use src/domain/<context>/value-objects/<name>.vo.ts for value objects.'));
49
+ }
50
+ if (entry.role === 'repository-port' && !APPLICATION_PORT_PATTERN.test(entry.path)) {
51
+ findings.push(finding('FOUNDATION_APPLICATION_PORT_PATH_INVALID', entry, `Repository port path "${entry.path}" does not match the Foundation application ports/out pattern.`, 'Use src/application/business/<context>/ports/out/<name>.port.ts for BO-pattern repository ports.'));
52
+ }
53
+ if (entry.layer === 'infrastructure' && entry.role === 'entity' && !INFRASTRUCTURE_ENTITY_PATTERN.test(entry.path)) {
54
+ findings.push(finding('FOUNDATION_INFRASTRUCTURE_ENTITY_PATH_INVALID', entry, `Infrastructure entity path "${entry.path}" does not match the centralized TypeORM entity pattern.`, 'Use src/infrastructure/adapters/orm/entities/<name>.orm-entity.ts for TypeORM entities.'));
55
+ }
56
+ return findings;
57
+ }
58
+ function finding(code, entry, message, remediation) {
59
+ return {
60
+ code,
61
+ severity: 'warn',
62
+ path: entry.path,
63
+ message,
64
+ remediation,
65
+ };
66
+ }
67
+ function formatIssue(issue) {
68
+ const issuePath = issue.path.length > 0 ? issue.path.join('.') : '<root>';
69
+ return `${issuePath}: ${issue.message}`;
70
+ }
71
+ //# sourceMappingURL=foundation-artifact-map-validator.js.map
@@ -0,0 +1,24 @@
1
+ export declare const CODESDD_FOUNDATION_LAYER_IDS: readonly ["domains", "applications", "infrastructures", "presentations", "shared"];
2
+ export type CodesddFoundationLayerId = (typeof CODESDD_FOUNDATION_LAYER_IDS)[number];
3
+ export interface CodesddFoundationLayerMapping {
4
+ layer: CodesddFoundationLayerId;
5
+ root: `src/${CodesddFoundationLayerId}`;
6
+ entrypoint: `src/${CodesddFoundationLayerId}/${string}`;
7
+ legacy_roots: string[];
8
+ role: string;
9
+ migration_status: 'active-facade' | 'legacy-source';
10
+ }
11
+ export interface CodesddFoundationLayerFinding {
12
+ code: 'FOUNDATION_LAYER_MISSING' | 'FOUNDATION_LAYER_ROOT_MISMATCH' | 'FOUNDATION_LAYER_ENTRYPOINT_MISMATCH' | 'FOUNDATION_LAYER_DUPLICATE' | 'FOUNDATION_LAYER_FORBIDDEN_PROJECT_RUNTIME';
13
+ layer?: string;
14
+ path?: string;
15
+ message: string;
16
+ }
17
+ export interface CodesddFoundationLayerValidationReport {
18
+ valid: boolean;
19
+ findings: CodesddFoundationLayerFinding[];
20
+ }
21
+ export declare const CODESDD_FOUNDATION_LAYER_MANIFEST: readonly CodesddFoundationLayerMapping[];
22
+ export declare function listCodesddFoundationLayerRoots(manifest?: readonly CodesddFoundationLayerMapping[]): string[];
23
+ export declare function validateCodesddFoundationLayerManifest(manifest?: readonly CodesddFoundationLayerMapping[]): CodesddFoundationLayerValidationReport;
24
+ //# sourceMappingURL=foundation-layer-manifest.d.ts.map