@devtrack-solution/codesdd 1.2.3 → 1.2.4

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 (213) hide show
  1. package/.sdd/skills/curated/devtrack-api/SKILL.md +98 -12
  2. package/.sdd/skills/curated/devtrack-api/agents/claude-code.yaml +10 -0
  3. package/.sdd/skills/curated/devtrack-api/agents/codex.yaml +10 -0
  4. package/.sdd/skills/curated/devtrack-api/agents/cursor.yaml +10 -0
  5. package/.sdd/skills/curated/devtrack-api/agents/gemini.yaml +10 -0
  6. package/.sdd/skills/curated/devtrack-api/agents/kimi.yaml +10 -0
  7. package/.sdd/skills/curated/devtrack-api/agents/openai.yaml +5 -3
  8. package/.sdd/skills/curated/devtrack-api/agents/opencode.yaml +12 -0
  9. package/.sdd/skills/curated/devtrack-api/references/application-presentation.md +61 -5
  10. package/.sdd/skills/curated/devtrack-api/references/consumer-sync-policy.md +15 -3
  11. package/.sdd/skills/curated/devtrack-api/references/contract-pack.yaml +1951 -0
  12. package/.sdd/skills/curated/devtrack-api/references/domain-modeling.md +16 -14
  13. package/.sdd/skills/curated/devtrack-api/references/field-validation-protocol.md +40 -0
  14. package/.sdd/skills/curated/devtrack-api/references/foundation-layout.md +19 -2
  15. package/.sdd/skills/curated/devtrack-api/references/generated-artifact-invalidation.md +97 -0
  16. package/.sdd/skills/curated/devtrack-api/references/implementation-checklist.md +30 -1
  17. package/.sdd/skills/curated/devtrack-api/references/portable-agent-contract.md +42 -0
  18. package/.sdd/skills/curated/devtrack-api/references/testing-validation.md +22 -1
  19. package/.sdd/skills/curated/devtrack-api/references/typeorm-infrastructure.md +9 -7
  20. package/README.md +280 -29
  21. package/dist/applications/sdd/index.d.ts +16 -0
  22. package/dist/applications/sdd/index.js +16 -0
  23. package/dist/cli/program.js +180 -11
  24. package/dist/commands/config.js +197 -10
  25. package/dist/commands/sdd/execution.js +408 -16
  26. package/dist/commands/sdd/plugin.js +5 -0
  27. package/dist/commands/sdd/shared.d.ts +1 -0
  28. package/dist/commands/sdd/shared.js +10 -0
  29. package/dist/commands/sdd.js +157 -7
  30. package/dist/core/cli/command-matrix.d.ts +18 -0
  31. package/dist/core/cli/command-matrix.js +157 -0
  32. package/dist/core/cli-command-quality.js +11 -0
  33. package/dist/core/completions/command-registry.js +45 -0
  34. package/dist/core/config-schema.d.ts +31 -1
  35. package/dist/core/config-schema.js +79 -5
  36. package/dist/core/config.d.ts +1 -0
  37. package/dist/core/config.js +11 -0
  38. package/dist/core/global-config.d.ts +29 -0
  39. package/dist/core/init.d.ts +2 -2
  40. package/dist/core/init.js +13 -14
  41. package/dist/core/sdd/agent-binding.d.ts +19 -19
  42. package/dist/core/sdd/agent-runtime-contract.d.ts +204 -0
  43. package/dist/core/sdd/agent-runtime-contract.js +200 -0
  44. package/dist/core/sdd/allocator-recovery.d.ts +14 -0
  45. package/dist/core/sdd/allocator-recovery.js +30 -0
  46. package/dist/core/sdd/allocator-security.d.ts +18 -0
  47. package/dist/core/sdd/allocator-security.js +36 -0
  48. package/dist/core/sdd/api-foundation-baseline.d.ts +111 -0
  49. package/dist/core/sdd/api-foundation-baseline.js +151 -0
  50. package/dist/core/sdd/api-foundation-parity.d.ts +114 -0
  51. package/dist/core/sdd/api-foundation-parity.js +131 -0
  52. package/dist/core/sdd/api-profile-catalog.d.ts +36 -0
  53. package/dist/core/sdd/api-profile-catalog.js +132 -0
  54. package/dist/core/sdd/api-profile-dry-run-projection.d.ts +93 -0
  55. package/dist/core/sdd/api-profile-dry-run-projection.js +370 -0
  56. package/dist/core/sdd/api-profile-recipes.d.ts +82 -0
  57. package/dist/core/sdd/api-profile-recipes.js +484 -0
  58. package/dist/core/sdd/artifact-id-allocator.d.ts +368 -0
  59. package/dist/core/sdd/artifact-id-allocator.js +510 -0
  60. package/dist/core/sdd/check.d.ts +52 -1
  61. package/dist/core/sdd/check.js +326 -11
  62. package/dist/core/sdd/coordination/coordination-adapters.d.ts +15 -8
  63. package/dist/core/sdd/coordination/coordination-adapters.js +43 -15
  64. package/dist/core/sdd/coordination/index.d.ts +1 -0
  65. package/dist/core/sdd/coordination/index.js +1 -0
  66. package/dist/core/sdd/coordination/redis-runtime.d.ts +131 -0
  67. package/dist/core/sdd/coordination/redis-runtime.js +698 -0
  68. package/dist/core/sdd/deepagent-contracts.d.ts +99 -5
  69. package/dist/core/sdd/deepagent-contracts.js +62 -0
  70. package/dist/core/sdd/deepagents/reversa-subagents.d.ts +3 -3
  71. package/dist/core/sdd/default-bootstrap-files.d.ts +2 -2
  72. package/dist/core/sdd/default-bootstrap-files.js +14 -10
  73. package/dist/core/sdd/default-skills.js +115 -9
  74. package/dist/core/sdd/devtrack-api-appliance.d.ts +42 -1
  75. package/dist/core/sdd/devtrack-api-appliance.js +159 -32
  76. package/dist/core/sdd/devtrack-api-architecture.d.ts +16 -0
  77. package/dist/core/sdd/devtrack-api-architecture.js +86 -0
  78. package/dist/core/sdd/docs-sync.js +24 -18
  79. package/dist/core/sdd/domain/capability-diff.d.ts +63 -0
  80. package/dist/core/sdd/domain/capability-diff.js +200 -0
  81. package/dist/core/sdd/domain/change-safety-guardrails.d.ts +74 -0
  82. package/dist/core/sdd/domain/change-safety-guardrails.js +333 -0
  83. package/dist/core/sdd/domain/semantic-intent-classifier.d.ts +29 -0
  84. package/dist/core/sdd/domain/semantic-intent-classifier.js +117 -0
  85. package/dist/core/sdd/enterprise-mutating-command-gate.d.ts +27 -0
  86. package/dist/core/sdd/enterprise-mutating-command-gate.js +104 -0
  87. package/dist/core/sdd/enterprise-provenance-gates.d.ts +20 -0
  88. package/dist/core/sdd/enterprise-provenance-gates.js +63 -0
  89. package/dist/core/sdd/enterprise-provisioning-policy.d.ts +26 -0
  90. package/dist/core/sdd/enterprise-provisioning-policy.js +104 -0
  91. package/dist/core/sdd/foundation-artifact-map-validator.d.ts +16 -0
  92. package/dist/core/sdd/foundation-artifact-map-validator.js +71 -0
  93. package/dist/core/sdd/foundation-layer-manifest.d.ts +24 -0
  94. package/dist/core/sdd/foundation-layer-manifest.js +117 -0
  95. package/dist/core/sdd/governance-schemas.d.ts +2 -2
  96. package/dist/core/sdd/governance-schemas.js +11 -2
  97. package/dist/core/sdd/intent-guard.d.ts +22 -0
  98. package/dist/core/sdd/intent-guard.js +67 -0
  99. package/dist/core/sdd/json-schema.js +13 -1
  100. package/dist/core/sdd/legacy-operations.js +169 -5
  101. package/dist/core/sdd/migrate-workspace.js +39 -0
  102. package/dist/core/sdd/package-security-gates.d.ts +21 -0
  103. package/dist/core/sdd/package-security-gates.js +121 -0
  104. package/dist/core/sdd/package-structure-gate.d.ts +85 -3
  105. package/dist/core/sdd/package-structure-gate.js +384 -11
  106. package/dist/core/sdd/parallel-feat-automation.d.ts +185 -7
  107. package/dist/core/sdd/parallel-feat-automation.js +212 -0
  108. package/dist/core/sdd/plugin-broker.d.ts +223 -4
  109. package/dist/core/sdd/plugin-broker.js +10 -0
  110. package/dist/core/sdd/plugin-cli.d.ts +30 -0
  111. package/dist/core/sdd/plugin-cli.js +70 -3
  112. package/dist/core/sdd/plugin-evidence.d.ts +73 -0
  113. package/dist/core/sdd/plugin-manifest.d.ts +69 -1
  114. package/dist/core/sdd/plugin-manifest.js +10 -0
  115. package/dist/core/sdd/plugin-policy-pack.d.ts +1 -1
  116. package/dist/core/sdd/plugin-policy.js +6 -1
  117. package/dist/core/sdd/plugin-registry.d.ts +138 -2
  118. package/dist/core/sdd/plugin-sdk-contract.d.ts +363 -0
  119. package/dist/core/sdd/plugin-sdk-contract.js +268 -0
  120. package/dist/core/sdd/plugin-skill-binding.d.ts +1 -1
  121. package/dist/core/sdd/quality-validation.d.ts +89 -16
  122. package/dist/core/sdd/release-readiness.d.ts +68 -0
  123. package/dist/core/sdd/release-readiness.js +767 -0
  124. package/dist/core/sdd/reversa-architecture-extractor.d.ts +13 -0
  125. package/dist/core/sdd/reversa-architecture-extractor.js +89 -0
  126. package/dist/core/sdd/reversa-artifact-writer.d.ts +18 -0
  127. package/dist/core/sdd/reversa-artifact-writer.js +40 -0
  128. package/dist/core/sdd/reversa-command-policy.d.ts +136 -0
  129. package/dist/core/sdd/reversa-command-policy.js +361 -0
  130. package/dist/core/sdd/reversa-data-extractor.d.ts +11 -0
  131. package/dist/core/sdd/reversa-data-extractor.js +73 -0
  132. package/dist/core/sdd/reversa-equivalence.d.ts +20 -0
  133. package/dist/core/sdd/reversa-equivalence.js +34 -0
  134. package/dist/core/sdd/reversa-evidence.d.ts +298 -0
  135. package/dist/core/sdd/reversa-evidence.js +118 -0
  136. package/dist/core/sdd/reversa-reconstruction.d.ts +29 -0
  137. package/dist/core/sdd/reversa-reconstruction.js +32 -0
  138. package/dist/core/sdd/reversa-rules-extractor.d.ts +12 -0
  139. package/dist/core/sdd/reversa-rules-extractor.js +86 -0
  140. package/dist/core/sdd/reversa-source-safety.d.ts +19 -0
  141. package/dist/core/sdd/reversa-source-safety.js +105 -0
  142. package/dist/core/sdd/reversa-surface-scout.d.ts +13 -0
  143. package/dist/core/sdd/reversa-surface-scout.js +85 -0
  144. package/dist/core/sdd/reversa-ux-mapper.d.ts +11 -0
  145. package/dist/core/sdd/reversa-ux-mapper.js +73 -0
  146. package/dist/core/sdd/runtime-boundary-contract.d.ts +45 -0
  147. package/dist/core/sdd/runtime-boundary-contract.js +90 -0
  148. package/dist/core/sdd/sdk-agent-plugin-quality-gates.d.ts +150 -0
  149. package/dist/core/sdd/sdk-agent-plugin-quality-gates.js +258 -0
  150. package/dist/core/sdd/services/agent-run.service.d.ts +38 -6
  151. package/dist/core/sdd/services/agent-run.service.js +73 -1
  152. package/dist/core/sdd/services/archive-quality-coherence.service.d.ts +17 -0
  153. package/dist/core/sdd/services/archive-quality-coherence.service.js +141 -0
  154. package/dist/core/sdd/services/capability-diff.service.d.ts +18 -0
  155. package/dist/core/sdd/services/capability-diff.service.js +26 -0
  156. package/dist/core/sdd/services/change-safety-preflight.service.d.ts +17 -0
  157. package/dist/core/sdd/services/change-safety-preflight.service.js +17 -0
  158. package/dist/core/sdd/services/context.service.d.ts +43 -340
  159. package/dist/core/sdd/services/context.service.js +323 -9
  160. package/dist/core/sdd/services/decide.service.js +1 -1
  161. package/dist/core/sdd/services/finalize.service.d.ts +27 -0
  162. package/dist/core/sdd/services/finalize.service.js +226 -18
  163. package/dist/core/sdd/services/frontend-impact.service.d.ts +1 -1
  164. package/dist/core/sdd/services/historical-quality-regression.service.d.ts +35 -0
  165. package/dist/core/sdd/services/historical-quality-regression.service.js +228 -0
  166. package/dist/core/sdd/services/ingest-deposito.service.js +1 -1
  167. package/dist/core/sdd/services/planning-execution-coherence.service.d.ts +45 -0
  168. package/dist/core/sdd/services/planning-execution-coherence.service.js +225 -0
  169. package/dist/core/sdd/services/semantic-intent-classifier.service.d.ts +6 -0
  170. package/dist/core/sdd/services/semantic-intent-classifier.service.js +7 -0
  171. package/dist/core/sdd/state.d.ts +1 -0
  172. package/dist/core/sdd/state.js +266 -34
  173. package/dist/core/sdd/store/sdd-stores.js +2 -2
  174. package/dist/core/sdd/structural-health.d.ts +13 -13
  175. package/dist/core/sdd/types.d.ts +30 -15
  176. package/dist/core/sdd/types.js +4 -0
  177. package/dist/core/sdd/views.js +17 -0
  178. package/dist/core/sdd/workspace-schemas.d.ts +428 -7
  179. package/dist/core/sdd/workspace-schemas.js +223 -70
  180. package/dist/core/shared/skill-generation.d.ts +2 -0
  181. package/dist/core/shared/skill-generation.js +19 -2
  182. package/dist/core/shared/tool-detection.d.ts +19 -0
  183. package/dist/core/shared/tool-detection.js +89 -0
  184. package/dist/domains/sdd/index.d.ts +6 -0
  185. package/dist/domains/sdd/index.js +6 -0
  186. package/dist/infrastructures/sdd/index.d.ts +7 -0
  187. package/dist/infrastructures/sdd/index.js +6 -0
  188. package/dist/presentations/cli/sdd/index.d.ts +3 -0
  189. package/dist/presentations/cli/sdd/index.js +3 -0
  190. package/dist/shared/sdd/index.d.ts +3 -0
  191. package/dist/shared/sdd/index.js +2 -0
  192. package/package.json +14 -10
  193. package/schemas/sdd/2-plan.schema.json +207 -2
  194. package/schemas/sdd/5-quality.schema.json +324 -25
  195. package/schemas/sdd/agent-runtime-command-plan.schema.json +212 -0
  196. package/schemas/sdd/agent-runtime-opencode-run-evidence.schema.json +270 -0
  197. package/schemas/sdd/codesdd-plugin.schema.json +171 -0
  198. package/schemas/sdd/deepagent-run-request.schema.json +316 -0
  199. package/schemas/sdd/parallel-feat-automation-plan.schema.json +89 -0
  200. package/schemas/sdd/parallel-feat-scheduler-request.schema.json +116 -0
  201. package/schemas/sdd/parallel-feat-scheduler-result.schema.json +404 -0
  202. package/schemas/sdd/plugin-artifact-manifest.schema.json +109 -0
  203. package/schemas/sdd/plugin-artifact-map.schema.json +223 -0
  204. package/schemas/sdd/plugin-evidence-manifest.schema.json +109 -0
  205. package/schemas/sdd/plugin-language-runtime.schema.json +103 -0
  206. package/schemas/sdd/plugin-package-governance.schema.json +74 -0
  207. package/schemas/sdd/plugin-registry.schema.json +171 -0
  208. package/schemas/sdd/plugin-runtime-invocation-plan.schema.json +109 -0
  209. package/schemas/sdd/quality-evidence-bundle.schema.json +109 -0
  210. package/schemas/sdd/reversa-evidence-bundle.schema.json +466 -0
  211. package/schemas/sdd/sdk-agent-plugin-quality-gate-input.schema.json +168 -0
  212. package/schemas/sdd/sdk-agent-plugin-quality-gate-report.schema.json +160 -0
  213. package/schemas/sdd/workspace-catalog.schema.json +5298 -1409
@@ -1,6 +1,10 @@
1
1
  import { buildPluginRuntimeInvocationPlan, pluginArtifactManifestSchema, } from './plugin-broker.js';
2
2
  import { pluginManifestSchema } from './plugin-manifest.js';
3
3
  import { createPluginRegistryState } from './plugin-registry.js';
4
+ import { DEFAULT_CODESDD_API_PROFILE_ID, resolveCodeSddApiProfile, } from './api-profile-catalog.js';
5
+ import { CODESDD_API_FOUNDATION_SHARED_BASELINE, CODESDD_API_SHARED_BASELINE_QUALITY_GATES, CODESDD_API_SHARED_BASELINE_REQUIREMENTS, getCodeSddApiSharedBaselineRequirements, } from './api-foundation-baseline.js';
6
+ import { CODESDD_FULL_FOUNDATION_COMPATIBLE_PROFILE_ID, CODESDD_FULL_FOUNDATION_PARITY_DIMENSIONS, CODESDD_FULL_FOUNDATION_PARITY_MATRIX, CODESDD_FULL_FOUNDATION_PARITY_QUALITY_GATES, getCodeSddFullFoundationParityMatrix, } from './api-foundation-parity.js';
7
+ import { buildCodeSddApiProfileDryRunProjection, getCodeSddApiProfileDryRunExpectation, } from './api-profile-dry-run-projection.js';
4
8
  export const DEVTRACK_API_APPLIANCE_PLUGIN_ID = 'codesdd-plugin-devtrack-api';
5
9
  export const DEVTRACK_API_APPLIANCE_CAPABILITIES = [
6
10
  'scaffold.project',
@@ -17,10 +21,12 @@ const DEVTRACK_API_SCAFFOLD_WRITE_SCOPE = [
17
21
  'src',
18
22
  'tests',
19
23
  'docs',
24
+ '.env.example',
20
25
  'package.json',
21
26
  'tsconfig.json',
22
27
  'nest-cli.json',
23
28
  'eslint.config.mjs',
29
+ '.sdd/plugin-evidence',
24
30
  ];
25
31
  export function evaluateDevTrackApiApplianceConformance(manifest) {
26
32
  const parsed = pluginManifestSchema.parse(manifest);
@@ -52,6 +58,9 @@ export function buildDevTrackApiScaffoldDryRunPlan(manifest, input) {
52
58
  const parsed = pluginManifestSchema.parse(manifest);
53
59
  const createdAt = input.created_at ?? new Date().toISOString();
54
60
  const packageName = normalizePackageName(input.package_name ?? input.project_name);
61
+ const apiProfile = resolveCodeSddApiProfile(input.api_profile, {
62
+ defaultProfile: DEFAULT_CODESDD_API_PROFILE_ID,
63
+ });
55
64
  const conformance = evaluateDevTrackApiApplianceConformance(parsed);
56
65
  if (!conformance.valid) {
57
66
  return {
@@ -64,8 +73,8 @@ export function buildDevTrackApiScaffoldDryRunPlan(manifest, input) {
64
73
  issues: conformance.issues,
65
74
  };
66
75
  }
67
- const artifacts = buildScaffoldArtifacts();
68
- const runtimePlan = buildRuntimePlan(parsed, input, packageName, createdAt, artifacts);
76
+ const artifacts = buildScaffoldArtifacts(apiProfile.profile_id);
77
+ const runtimePlan = buildRuntimePlan(parsed, input, packageName, createdAt, artifacts, apiProfile);
69
78
  if (runtimePlan.status !== 'ready' || !runtimePlan.envelope) {
70
79
  return {
71
80
  schema_version: 1,
@@ -89,6 +98,7 @@ export function buildDevTrackApiScaffoldDryRunPlan(manifest, input) {
89
98
  status: 'planned',
90
99
  created_at: createdAt,
91
100
  operation_id: operationId,
101
+ api_profile: apiProfile,
92
102
  project_name: input.project_name,
93
103
  package_name: packageName,
94
104
  runtime_plan: runtimePlan,
@@ -107,6 +117,14 @@ export function buildDevTrackApiScaffoldDryRunPlan(manifest, input) {
107
117
  operation: artifact.operation,
108
118
  reason: artifact.reason,
109
119
  content_type: artifact.content_type,
120
+ artifact_kind: artifact.artifact_kind,
121
+ role: artifact.role,
122
+ layer: artifact.layer,
123
+ language: artifact.language,
124
+ implementation: artifact.implementation,
125
+ decision_refs: artifact.decision_refs,
126
+ source_refs: [artifact.source_reference],
127
+ tags: artifact.tags,
110
128
  })),
111
129
  validation_evidence: parsed.validation.commands.map((command) => ({
112
130
  command,
@@ -121,6 +139,9 @@ export function buildDevTrackApiScaffoldDryRunPlan(manifest, input) {
121
139
  projectName: input.project_name,
122
140
  packageName,
123
141
  validationCommands: parsed.validation.commands,
142
+ apiProfile,
143
+ expectedWriteScope: runtimePlan.envelope.write_scope,
144
+ artifacts,
124
145
  }),
125
146
  issues: [],
126
147
  };
@@ -138,7 +159,7 @@ function collectIdentityIssues(manifest) {
138
159
  }
139
160
  return issues;
140
161
  }
141
- function buildRuntimePlan(manifest, input, packageName, createdAt, artifacts) {
162
+ function buildRuntimePlan(manifest, input, packageName, createdAt, artifacts, apiProfile) {
142
163
  const registry = createPluginRegistryState([
143
164
  {
144
165
  manifest,
@@ -153,10 +174,12 @@ function buildRuntimePlan(manifest, input, packageName, createdAt, artifacts) {
153
174
  return buildPluginRuntimeInvocationPlan(registry, {
154
175
  feature_ref: input.feature_ref,
155
176
  capability: DEVTRACK_API_SCAFFOLD_CAPABILITY,
156
- skill_ref: 'devtrack-api',
177
+ skill_ref: apiProfile.profile_id,
157
178
  inputs: {
158
179
  project_name: input.project_name,
159
180
  package_name: packageName,
181
+ api_profile: apiProfile.profile_id,
182
+ api_profile_family: apiProfile.family_id,
160
183
  persistence: {
161
184
  provider: 'typeorm',
162
185
  },
@@ -179,6 +202,35 @@ function buildRuntimePlan(manifest, input, packageName, createdAt, artifacts) {
179
202
  });
180
203
  }
181
204
  function buildEvidenceManifest(input) {
205
+ const sharedBaselineRequirements = getCodeSddApiSharedBaselineRequirements();
206
+ const fullFoundationCompatibility = input.apiProfile.profile_id === CODESDD_FULL_FOUNDATION_COMPATIBLE_PROFILE_ID
207
+ ? {
208
+ id: CODESDD_FULL_FOUNDATION_PARITY_MATRIX.id,
209
+ version: CODESDD_FULL_FOUNDATION_PARITY_MATRIX.version,
210
+ profile_id: CODESDD_FULL_FOUNDATION_COMPATIBLE_PROFILE_ID,
211
+ source: CODESDD_FULL_FOUNDATION_PARITY_MATRIX.foundation_reference,
212
+ dimension_ids: CODESDD_FULL_FOUNDATION_PARITY_DIMENSIONS,
213
+ quality_gates: CODESDD_FULL_FOUNDATION_PARITY_QUALITY_GATES,
214
+ dimensions: getCodeSddFullFoundationParityMatrix().map((dimension) => ({
215
+ ...dimension,
216
+ status: 'pending',
217
+ })),
218
+ }
219
+ : undefined;
220
+ const profileProjection = buildCodeSddApiProfileDryRunProjection({
221
+ apiProfile: input.apiProfile,
222
+ expectedWriteScope: input.expectedWriteScope,
223
+ artifactMapRefs: input.artifacts.map((artifactEntry) => ({
224
+ path: artifactEntry.path,
225
+ layer: artifactEntry.layer,
226
+ artifact_kind: artifactEntry.artifact_kind,
227
+ role: artifactEntry.role,
228
+ content_type: artifactEntry.content_type,
229
+ source_reference: artifactEntry.source_reference,
230
+ tags: artifactEntry.tags,
231
+ })),
232
+ validationCommands: input.validationCommands,
233
+ });
182
234
  return {
183
235
  schema_version: 1,
184
236
  operation_id: input.operationId,
@@ -199,48 +251,120 @@ function buildEvidenceManifest(input) {
199
251
  command,
200
252
  status: 'pending',
201
253
  })),
202
- quality_gates: [
203
- 'typeorm-only-persistence',
254
+ quality_gates: unique([
255
+ ...profileProjection.expected_quality_gates,
204
256
  'no-secret-fixtures',
205
257
  'no-out-of-root-writes',
206
258
  'artifact-manifest-required',
207
259
  'evidence-manifest-required',
208
- ],
260
+ ]),
261
+ api_profile: {
262
+ family_id: input.apiProfile.family_id,
263
+ selected_profile: input.apiProfile.profile_id,
264
+ requested_profile: input.apiProfile.input,
265
+ legacy_alias: input.apiProfile.legacy_alias,
266
+ migration_notice: input.apiProfile.migration_notice,
267
+ inherited_baseline: CODESDD_API_SHARED_BASELINE_REQUIREMENTS,
268
+ },
269
+ profile_projection: profileProjection,
270
+ foundation_baseline: {
271
+ id: CODESDD_API_FOUNDATION_SHARED_BASELINE.id,
272
+ version: CODESDD_API_FOUNDATION_SHARED_BASELINE.version,
273
+ source: CODESDD_API_FOUNDATION_SHARED_BASELINE.foundation_reference,
274
+ requirement_ids: CODESDD_API_SHARED_BASELINE_REQUIREMENTS,
275
+ quality_gates: CODESDD_API_SHARED_BASELINE_QUALITY_GATES,
276
+ requirements: sharedBaselineRequirements,
277
+ },
278
+ ...(fullFoundationCompatibility
279
+ ? {
280
+ full_foundation_compatibility: fullFoundationCompatibility,
281
+ }
282
+ : {}),
209
283
  };
210
284
  }
211
- function buildScaffoldArtifacts() {
212
- return [
213
- artifact('package.json', 'root', 'application/json', 'Foundation-compatible package metadata, scripts, and dependencies.'),
214
- artifact('tsconfig.json', 'root', 'application/json', 'TypeScript path aliases and compiler settings aligned to Foundation API.'),
215
- artifact('nest-cli.json', 'root', 'application/json', 'Nest CLI configuration with Swagger plugin support.'),
216
- artifact('eslint.config.mjs', 'root', 'text/javascript', 'Foundation-compatible lint rules and import-boundary checks.'),
217
- artifact('docs/foundation-backend-reference-structure.md', 'docs', 'text/markdown', 'Derived Foundation package structure reference for maintainers.'),
218
- artifact('src/main.ts', 'root', 'text/typescript', 'NestJS bootstrap entrypoint.'),
219
- artifact('src/app.module.ts', 'root', 'text/typescript', 'Root module composing application, infrastructure, and presentation layers.'),
220
- artifact('src/application/application.module.ts', 'application', 'text/typescript', 'Application layer module boundary.'),
221
- artifact('src/application/runtime-settings.ts', 'application', 'text/typescript', 'Application runtime settings boundary.'),
222
- artifact('src/domain/auth/api-keys.domain.ts', 'domain', 'text/typescript', 'Initial domain object example from Foundation API.'),
223
- artifact('src/infrastructure/infrastructure.module.ts', 'infrastructure', 'text/typescript', 'Infrastructure layer module boundary.'),
224
- artifact('src/infrastructure/settings/app-configuration.ts', 'infrastructure', 'text/typescript', 'Typed application configuration source.'),
225
- artifact('src/presentation/presentation.module.ts', 'presentation', 'text/typescript', 'Presentation layer module boundary.'),
226
- artifact('src/presentation/rest/rest.presentation.module.ts', 'presentation', 'text/typescript', 'REST channel module boundary.'),
227
- artifact('src/presentation/graphql/graphql.presentation.module.ts', 'presentation', 'text/typescript', 'GraphQL channel module boundary.'),
228
- artifact('src/presentation/cli/cli.presentation.module.ts', 'presentation', 'text/typescript', 'CLI channel module boundary.'),
229
- artifact('src/presentation/websocket/websocket.module.ts', 'presentation', 'text/typescript', 'WebSocket channel module boundary.'),
230
- artifact('src/shared/domain/generic-business-object.ts', 'shared', 'text/typescript', 'Shared domain primitive used by Foundation packages.'),
231
- artifact('src/shared/presentation/generic-controller.ts', 'shared', 'text/typescript', 'Shared presentation primitive used by REST controllers.'),
232
- artifact('tests/app.e2e-spec.ts', 'tests', 'text/typescript', 'Initial E2E smoke test for the generated API scaffold.'),
233
- artifact('tests/jest-e2e.json', 'tests', 'application/json', 'Jest E2E configuration for the scaffold.'),
285
+ function buildScaffoldArtifacts(apiProfile) {
286
+ const baselineArtifacts = [
287
+ artifact('package.json', 'root', 'package-metadata', 'manifest', 'application/json', 'Foundation-compatible package metadata, scripts, and dependencies.', apiProfile),
288
+ artifact('.env.example', 'config', 'configuration', 'manifest', 'text/plain', 'Safe placeholder environment contract, including app, database, JWT, and Swagger server variables.', apiProfile),
289
+ artifact('tsconfig.json', 'config', 'configuration', 'manifest', 'application/json', 'TypeScript path aliases and compiler settings aligned to Foundation API.', apiProfile),
290
+ artifact('nest-cli.json', 'config', 'configuration', 'manifest', 'application/json', 'Nest CLI configuration with Swagger plugin support.', apiProfile),
291
+ artifact('eslint.config.mjs', 'config', 'configuration', 'policy', 'text/javascript', 'Foundation-compatible lint rules and import-boundary checks.', apiProfile),
292
+ artifact('docs/foundation-backend-reference-structure.md', 'docs', 'documentation', 'documentation', 'text/markdown', 'Derived Foundation package structure reference for maintainers.', apiProfile),
293
+ artifact('src/main.ts', 'root', 'source', 'implementation', 'text/typescript', 'NestJS bootstrap entrypoint with validation pipe and Swagger/OpenAPI /docs setup.', apiProfile),
294
+ artifact('src/app.module.ts', 'root', 'source', 'module', 'text/typescript', 'Root module composing application, infrastructure, and presentation layers.', apiProfile),
295
+ artifact('src/application/application.module.ts', 'application', 'source', 'module', 'text/typescript', 'Application layer module boundary.', apiProfile),
296
+ artifact('src/application/runtime-settings.ts', 'application', 'source', 'type', 'text/typescript', 'Application runtime settings boundary.', apiProfile),
297
+ artifact('src/domain/auth/business-objects/api-keys.bo.ts', 'domain', 'source', 'business-object', 'text/typescript', 'Initial BO-pattern domain object example from Foundation API.', apiProfile),
298
+ artifact('src/application/business/auth/ports/out/api-key-repository.port.ts', 'application', 'source', 'repository-port', 'text/typescript', 'BO-pattern repository port owned by application ports/out.', apiProfile),
299
+ artifact('src/application/business/auth/ports/in/register.use-case.port.ts', 'application', 'source', 'interface', 'text/typescript', 'Application input port for a user-facing auth route.', apiProfile),
300
+ artifact('src/application/business/auth/use-cases/register.use-case.ts', 'application', 'source', 'use-case', 'text/typescript', 'Application use case backing a user-facing route before presentation wiring.', apiProfile),
301
+ artifact('src/application/business/auth/auth.application.module.ts', 'application', 'source', 'module', 'text/typescript', 'Application auth module wiring input ports, use cases, services, and output ports.', apiProfile),
302
+ artifact('src/infrastructure/infrastructure.module.ts', 'infrastructure', 'source', 'module', 'text/typescript', 'Infrastructure layer module boundary.', apiProfile),
303
+ artifact('src/infrastructure/settings/app-configuration.ts', 'infrastructure', 'source', 'implementation', 'text/typescript', 'Typed application configuration source.', apiProfile),
304
+ artifact('src/infrastructure/adapters/orm/entities/api-key.orm-entity.ts', 'infrastructure', 'source', 'entity', 'text/typescript', 'TypeORM persistence entity kept in the centralized orm subsystem.', apiProfile),
305
+ artifact('src/presentation/presentation.module.ts', 'presentation', 'source', 'module', 'text/typescript', 'Presentation layer module boundary.', apiProfile),
306
+ artifact('src/presentation/rest/rest.presentation.module.ts', 'presentation', 'source', 'module', 'text/typescript', 'REST channel module boundary.', apiProfile),
307
+ artifact('src/presentation/rest/auth/auth.module.ts', 'presentation', 'source', 'module', 'text/typescript', 'REST auth module registering controllers, guards, and decorators.', apiProfile),
308
+ artifact('src/presentation/rest/auth/controllers/register.controller.ts', 'presentation', 'source', 'controller', 'text/typescript', 'Swagger-documented REST controller that injects an application input port.', apiProfile),
309
+ artifact('src/presentation/rest/auth/dtos/register-input.dto.ts', 'presentation', 'source', 'dto', 'text/typescript', 'Swagger-documented REST input DTO for a user-facing route.', apiProfile),
310
+ artifact('src/presentation/rest/auth/dtos/auth-session-output.dto.ts', 'presentation', 'source', 'dto', 'text/typescript', 'Swagger-documented REST output DTO for session responses.', apiProfile),
311
+ artifact('src/presentation/rest/auth/guards/jwt-auth.guard.ts', 'presentation', 'source', 'implementation', 'text/typescript', 'REST route guard baseline for protected bearer routes.', apiProfile),
312
+ artifact('src/presentation/rest/auth/guards/permission.guard.ts', 'presentation', 'source', 'implementation', 'text/typescript', 'REST authorization guard baseline for permission-protected routes.', apiProfile),
313
+ artifact('src/presentation/rest/auth/decorators/permission.decorator.ts', 'presentation', 'source', 'policy', 'text/typescript', 'REST authorization decorator baseline for permission metadata.', apiProfile),
314
+ artifact('src/presentation/dtos/api-error-response.dto.ts', 'presentation', 'source', 'dto', 'text/typescript', 'Swagger-documented error response DTO for controller response metadata.', apiProfile),
315
+ artifact('src/presentation/graphql/graphql.presentation.module.ts', 'presentation', 'source', 'module', 'text/typescript', 'GraphQL channel module boundary.', apiProfile),
316
+ artifact('src/presentation/cli/cli.presentation.module.ts', 'presentation', 'source', 'module', 'text/typescript', 'CLI channel module boundary.', apiProfile),
317
+ artifact('src/presentation/websocket/websocket.module.ts', 'presentation', 'source', 'module', 'text/typescript', 'WebSocket channel module boundary.', apiProfile),
318
+ artifact('src/shared/domain/generic-business-object.ts', 'shared', 'source', 'abstraction', 'text/typescript', 'Shared domain primitive used by Foundation packages.', apiProfile),
319
+ artifact('src/shared/presentation/generic-controller.ts', 'shared', 'source', 'abstraction', 'text/typescript', 'Shared presentation primitive used by REST controllers.', apiProfile),
320
+ artifact('tests/app.e2e-spec.ts', 'tests', 'test', 'test', 'text/typescript', 'Initial E2E smoke test for the generated API scaffold.', apiProfile),
321
+ artifact('tests/jest-e2e.json', 'tests', 'configuration', 'manifest', 'application/json', 'Jest E2E configuration for the scaffold.', apiProfile),
234
322
  ];
323
+ const plannedPaths = new Set(baselineArtifacts.map((entry) => entry.path));
324
+ const profileOverlayArtifacts = getCodeSddApiProfileDryRunExpectation(apiProfile).expected_writes
325
+ .filter((expectedWrite) => !plannedPaths.has(expectedWrite.path))
326
+ .map((expectedWrite) => artifact(expectedWrite.path, expectedWrite.layer, expectedWrite.artifact_kind, expectedWrite.role, contentTypeForScaffoldPath(expectedWrite.path, expectedWrite.artifact_kind), `${expectedWrite.reason} (Profile overlay for ${apiProfile}.)`, apiProfile));
327
+ return [...baselineArtifacts, ...profileOverlayArtifacts];
235
328
  }
236
- function artifact(artifactPath, layer, contentType, reason) {
237
- return {
329
+ function contentTypeForScaffoldPath(artifactPath, artifactKind) {
330
+ if (artifactPath.endsWith('.ts')) {
331
+ return 'text/typescript';
332
+ }
333
+ if (artifactPath.endsWith('.json')) {
334
+ return 'application/json';
335
+ }
336
+ if (artifactPath.endsWith('.md')) {
337
+ return 'text/markdown';
338
+ }
339
+ if (artifactPath.endsWith('.yaml') || artifactPath.endsWith('.yml')) {
340
+ return 'text/yaml';
341
+ }
342
+ if (artifactKind === 'documentation') {
343
+ return 'text/markdown';
344
+ }
345
+ return 'text/plain';
346
+ }
347
+ function artifact(artifactPath, layer, artifactKind, role, contentType, reason, apiProfile) {
348
+ const mapEntry = {
238
349
  path: artifactPath,
239
350
  layer,
240
351
  operation: 'planned',
352
+ artifact_kind: artifactKind,
353
+ role,
241
354
  content_type: contentType,
242
355
  reason,
356
+ language: contentType.includes('typescript') || contentType.includes('javascript') ? 'typescript' : undefined,
357
+ implementation: role === 'interface' || role === 'repository-port' ? 'contract' : 'generated',
358
+ decision_refs: ['EPIC-0075'],
359
+ source_refs: [`${DEVTRACK_API_REFERENCE_ROOT}/${artifactPath}`],
360
+ tags: ['devtrack-api', 'foundation-api', 'codesdd-api-profile', apiProfile],
361
+ metadata: {},
362
+ };
363
+ return {
364
+ ...mapEntry,
243
365
  source_reference: `${DEVTRACK_API_REFERENCE_ROOT}/${artifactPath}`,
366
+ decision_refs: mapEntry.decision_refs,
367
+ tags: mapEntry.tags,
244
368
  };
245
369
  }
246
370
  function normalizePackageName(value) {
@@ -254,4 +378,7 @@ function normalizePackageName(value) {
254
378
  }
255
379
  return normalized;
256
380
  }
381
+ function unique(values) {
382
+ return [...new Set(values)];
383
+ }
257
384
  //# sourceMappingURL=devtrack-api-appliance.js.map
@@ -24,6 +24,22 @@ export interface DevTrackApiArchitectureValidationResult {
24
24
  architecture_schema: QualityArchitectureSchema;
25
25
  import_graph: QualityImportGraph;
26
26
  findings: DevTrackApiArchitectureFinding[];
27
+ drift_signals: DevTrackApiDriftSignal[];
28
+ profile_outcomes: DevTrackApiProfileOutcome[];
29
+ }
30
+ export type DevTrackApiDriftClass = 'CVD-01' | 'CVD-02' | 'CVD-03' | 'CVD-04' | 'CVD-05' | 'CVD-06' | 'CVD-07' | 'CVD-08' | 'CVD-09' | 'WCA-01' | 'WCA-02' | 'WCA-03';
31
+ export interface DevTrackApiDriftSignal {
32
+ drift_class: DevTrackApiDriftClass;
33
+ observed: string;
34
+ mapped_rules: string[];
35
+ finding_codes: DevTrackApiArchitectureIssueCode[];
36
+ }
37
+ export interface DevTrackApiProfileOutcome {
38
+ profile: 'prototype' | 'foundation-compatible' | 'enterprise-strict';
39
+ status: 'passed' | 'warning' | 'blocked';
40
+ blocking_rules: string[];
41
+ blocking_drift_classes: DevTrackApiDriftClass[];
42
+ exception_candidate_rules: string[];
27
43
  }
28
44
  export declare function buildDevTrackApiArchitectureSchema(): QualityArchitectureSchema;
29
45
  export declare function collectDevTrackApiImportGraph(input: CollectDevTrackApiImportGraphInput): Promise<QualityImportGraph>;
@@ -1,6 +1,8 @@
1
1
  import { promises as fs } from 'node:fs';
2
2
  import path from 'node:path';
3
+ import { fileURLToPath } from 'node:url';
3
4
  import ts from 'typescript';
5
+ import { parse as parseYaml } from 'yaml';
4
6
  import { parseQualityArchitectureSchema, } from './quality-validation.js';
5
7
  export const DEVTRACK_API_ARCHITECTURE_SCHEMA_ID = 'ARCH-GATE-devtrack-api-p0';
6
8
  const DEFAULT_SOURCE_ROOTS = ['src', 'prisma'];
@@ -17,6 +19,30 @@ const DEVTRACK_ALIAS_PREFIXES = [
17
19
  '@shared/',
18
20
  '@src/',
19
21
  ];
22
+ const DEVTRACK_API_CONTRACT_PACK_PATH = fileURLToPath(new URL('../../../.sdd/skills/curated/devtrack-api/references/contract-pack.yaml', import.meta.url));
23
+ const DRIFT_CLASS_TO_FINDING_CODES = {
24
+ 'CVD-02': [
25
+ 'ARCH_RELATIVE_IMPORT_FORBIDDEN',
26
+ 'ARCH_APPLICATION_PRESENTATION_IMPORT',
27
+ 'ARCH_APPLICATION_CONCRETE_INFRA_IMPORT',
28
+ 'ARCH_PRESENTATION_INFRA_IMPORT',
29
+ 'ARCH_TYPEORM_IMPORT_OUTSIDE_INFRASTRUCTURE',
30
+ 'ARCH_TYPEORM_ENTITY_PATH_INVALID',
31
+ 'ARCH_TYPEORM_ENTITY_SUFFIX_INVALID',
32
+ 'ARCH_TYPEORM_REPOSITORY_PATH_INVALID',
33
+ 'ARCH_TYPEORM_REPOSITORY_SUFFIX_INVALID',
34
+ 'ARCH_PRESENTATION_TRANSPORT_MISSING',
35
+ 'ARCH_INFRASTRUCTURE_CONTEXT_PERSISTENCE_FORBIDDEN',
36
+ ],
37
+ 'CVD-03': ['ARCH_TYPEORM_REPOSITORY_FAKE'],
38
+ 'CVD-04': ['ARCH_PRESENTATION_COMPOSITION_ROOT', 'ARCH_AGGREGATE_MODULE_MISSING', 'ARCH_AGGREGATE_MODULE_NOT_NESTJS'],
39
+ 'CVD-05': ['ARCH_PORT_MISSING_SYMBOL', 'ARCH_PORT_GROUPED_UNRELATED'],
40
+ 'CVD-06': ['ARCH_BO_MISSING_METHODS', 'ARCH_VO_MISSING_METHODS'],
41
+ 'CVD-07': ['ARCH_MISSING_DATASOURCE', 'ARCH_MISSING_MIGRATIONS', 'ARCH_MISSING_TYPEORM_MODULE_FORFEATURE'],
42
+ 'CVD-09': ['ARCH_DOMAIN_REPOSITORY_PORT_CONTEXT_FORBIDDEN'],
43
+ 'WCA-02': ['ARCH_RELATIVE_IMPORT_FORBIDDEN'],
44
+ 'WCA-03': ['ARCH_TYPEORM_REPOSITORY_FAKE', 'ARCH_MISSING_TYPEORM_MODULE_FORFEATURE'],
45
+ };
20
46
  export function buildDevTrackApiArchitectureSchema() {
21
47
  return parseQualityArchitectureSchema({
22
48
  schema_version: 1,
@@ -157,13 +183,73 @@ export async function validateDevTrackApiArchitecture(input) {
157
183
  detectMissingAggregateModules(files, fileContents, findings);
158
184
  detectMissingRuntimePersistence(files, fileContents, findings);
159
185
  const dedupedFindings = dedupeFindings(findings);
186
+ const contractPack = await loadDevTrackApiContractPack();
187
+ const driftSignals = mapFindingsToDriftSignals(dedupedFindings, contractPack);
188
+ const profileOutcomes = buildProfileOutcomes(driftSignals, contractPack);
160
189
  return {
161
190
  status: dedupedFindings.length > 0 ? 'warning' : 'passed',
162
191
  architecture_schema: buildDevTrackApiArchitectureSchema(),
163
192
  import_graph: importGraph,
164
193
  findings: dedupedFindings,
194
+ drift_signals: driftSignals,
195
+ profile_outcomes: profileOutcomes,
165
196
  };
166
197
  }
198
+ async function loadDevTrackApiContractPack() {
199
+ const raw = await fs.readFile(DEVTRACK_API_CONTRACT_PACK_PATH, 'utf-8');
200
+ return parseYaml(raw);
201
+ }
202
+ function mapFindingsToDriftSignals(findings, contractPack) {
203
+ const findingCodes = new Set(findings.map((finding) => finding.code));
204
+ const driftSignals = [];
205
+ for (const [driftClass, mappedFindingCodes] of Object.entries(DRIFT_CLASS_TO_FINDING_CODES)) {
206
+ const matchedCodes = mappedFindingCodes.filter((code) => findingCodes.has(code));
207
+ if (matchedCodes.length === 0)
208
+ continue;
209
+ const mapping = contractPack.codesdd_validate_drift_map[driftClass] ?? contractPack.field_evidence_drift_map[driftClass];
210
+ driftSignals.push({
211
+ drift_class: driftClass,
212
+ observed: mapping?.observed ?? 'Observed semantic drift mapped from validator findings.',
213
+ mapped_rules: [...new Set(mapping?.mapped_rules ?? [])],
214
+ finding_codes: matchedCodes,
215
+ });
216
+ }
217
+ return driftSignals.sort((left, right) => left.drift_class.localeCompare(right.drift_class));
218
+ }
219
+ function buildProfileOutcomes(driftSignals, contractPack) {
220
+ const ruleSeverity = new Map(contractPack.rules.map((rule) => [rule.id, rule.severity]));
221
+ const ruleIds = [...new Set(driftSignals.flatMap((signal) => signal.mapped_rules))];
222
+ const p0Rules = ruleIds.filter((ruleId) => ruleSeverity.get(ruleId) === 'P0');
223
+ const p1Rules = ruleIds.filter((ruleId) => ruleSeverity.get(ruleId) === 'P1');
224
+ const p2Rules = ruleIds.filter((ruleId) => ruleSeverity.get(ruleId) === 'P2');
225
+ return [
226
+ {
227
+ profile: 'prototype',
228
+ status: driftSignals.length > 0 ? 'warning' : 'passed',
229
+ blocking_rules: [],
230
+ blocking_drift_classes: [],
231
+ exception_candidate_rules: [],
232
+ },
233
+ {
234
+ profile: 'foundation-compatible',
235
+ status: p0Rules.length > 0 ? 'blocked' : driftSignals.length > 0 ? 'warning' : 'passed',
236
+ blocking_rules: p0Rules,
237
+ blocking_drift_classes: driftSignals
238
+ .filter((signal) => signal.mapped_rules.some((ruleId) => p0Rules.includes(ruleId)))
239
+ .map((signal) => signal.drift_class),
240
+ exception_candidate_rules: [...new Set([...p1Rules, ...p2Rules])],
241
+ },
242
+ {
243
+ profile: 'enterprise-strict',
244
+ status: p0Rules.length > 0 || p1Rules.length > 0 ? 'blocked' : driftSignals.length > 0 ? 'warning' : 'passed',
245
+ blocking_rules: [...new Set([...p0Rules, ...p1Rules])],
246
+ blocking_drift_classes: driftSignals
247
+ .filter((signal) => signal.mapped_rules.some((ruleId) => p0Rules.includes(ruleId) || p1Rules.includes(ruleId)))
248
+ .map((signal) => signal.drift_class),
249
+ exception_candidate_rules: p2Rules,
250
+ },
251
+ ];
252
+ }
167
253
  function finding(code, filePath, importSpecifier, message, remediation) {
168
254
  return {
169
255
  code,
@@ -31,6 +31,16 @@ function upsertMarkedBlock(source, startMarker, endMarker, blockContent) {
31
31
  const next = `${prefix}${replacement}\n`;
32
32
  return { content: next, changed: true, hasMarkers: false };
33
33
  }
34
+ function validateManagedBlock(source, startMarker, endMarker, expectedBlock, label, missingBlocks) {
35
+ if (!source.includes(startMarker) || !source.includes(endMarker)) {
36
+ missingBlocks.push(label);
37
+ return;
38
+ }
39
+ const expected = upsertMarkedBlock(source, startMarker, endMarker, expectedBlock);
40
+ if (expected.changed) {
41
+ missingBlocks.push(`${label}:DRIFT`);
42
+ }
43
+ }
34
44
  function buildReadmeBlock(memoryDir, config) {
35
45
  return `## Onboarding SDD
36
46
 
@@ -41,7 +51,9 @@ Operational authority:
41
51
 
42
52
  Initial operational directives:
43
53
  - CodeSDD is the official planner for any build request; other planners or agent-native plans are secondary execution aids only.
44
- - For API/backend work, use \`devtrack-api\` by default unless the user or SDD context explicitly selects another skill/profile; Python/Flask API work stays routed to \`api-clean-flask-langgraph\`.
54
+ - In initialized CodeSDD repositories, any user request that implies implementation, file edits, validation, execution, or finalize must be treated as requiring CodeSDD planning unless the user explicitly marks it as read-only or outside CodeSDD.
55
+ - For change requests, agents must bind the work to an active or ready FEAT through \`${CLI_NAME} sdd next\` and \`${CLI_NAME} sdd context <FEAT-ID>\` before implementation; agent-native plans may only decompose execution after that CodeSDD context exists.
56
+ - For API/backend work, select a CodeSDD API profile (\`minimal-rest\`, \`rest-auth-rbac\`, \`rest-crud-typeorm\`, \`evented-api\`, \`ai-agent-api\`, or \`full-foundation-compatible\`); \`devtrack-api\` remains the compatibility skill/alias and Python/Flask API work stays routed to \`api-clean-flask-langgraph\`.
45
57
  - During init, onboard, insight, and debate flows, CodeSDD-managed agent instruction blocks must be inspected and reconfigured when they drift from this contract.
46
58
  - Commit requests must follow Conventional Commits, selective staging, and grouping by modified directory plus change protocol (\`src\`, \`${memoryDir}\`, docs, config, infra, dependencies, or generated files).
47
59
 
@@ -102,7 +114,9 @@ Operational exclusivity:
102
114
 
103
115
  Initial directives:
104
116
  - CodeSDD is the official planner for requested work; model-native plans and other planning tools are subordinate to CodeSDD artifacts.
105
- - API/backend work uses \`devtrack-api\` by default unless an explicit skill/profile says otherwise; Python/Flask API work uses \`api-clean-flask-langgraph\`.
117
+ - In initialized CodeSDD repositories, implementation, edit, validation, execution, and finalize requests implicitly require CodeSDD planning unless the user explicitly marks the request as read-only or outside CodeSDD.
118
+ - A change request must use the active or ready FEAT returned by \`${CLI_NAME} sdd next\` and must load \`${CLI_NAME} sdd context <FEAT-ID>\` before coding; model-native plans may only refine execution after that context exists.
119
+ - API/backend work selects a CodeSDD API profile (\`minimal-rest\`, \`rest-auth-rbac\`, \`rest-crud-typeorm\`, \`evented-api\`, \`ai-agent-api\`, or \`full-foundation-compatible\`); \`devtrack-api\` remains the compatibility skill/alias, and Python/Flask API work uses \`api-clean-flask-langgraph\`.
106
120
  - CodeSDD-managed blocks in \`AGENTS.md\`, \`AGENT.md\`, \`CLAUDE.md\`, \`GEMINI.md\`, \`.codex\`, \`.opencode\`, \`.ai\`, \`.cloud\`, or equivalent agent files must be inspected and normalized during init/onboard/insight/debate when CodeSDD owns project governance.
107
121
  - Commits must use Conventional Commits, selective staging, and grouping by modified directory plus protocol: source, \`${memoryDir}\`, docs, config, infra, dependencies, generated files, renames, or deletions.`;
108
122
  }
@@ -134,7 +148,9 @@ Do not use external context, memory, workflow, backlog, scratchpad, or handoff t
134
148
 
135
149
  Initial directives:
136
150
  - CodeSDD is the official planner. Other planning systems may assist execution only after CodeSDD context exists.
137
- - API/backend work defaults to \`devtrack-api\` unless an explicit skill/profile overrides it; Python/Flask API work remains a documented exception routed to \`api-clean-flask-langgraph\`.
151
+ - In initialized CodeSDD repositories, implementation, edit, validation, execution, and finalize requests implicitly require CodeSDD planning unless the user explicitly marks the request as read-only or outside CodeSDD.
152
+ - Agents must bind each change request to the active or ready FEAT returned by \`${CLI_NAME} sdd next\` and load \`${CLI_NAME} sdd context <FEAT-ID>\` before coding.
153
+ - API/backend work selects a CodeSDD API profile (\`minimal-rest\`, \`rest-auth-rbac\`, \`rest-crud-typeorm\`, \`evented-api\`, \`ai-agent-api\`, or \`full-foundation-compatible\`); \`devtrack-api\` remains the compatibility skill/alias, and Python/Flask API work remains a documented exception routed to \`api-clean-flask-langgraph\`.
138
154
  - CodeSDD lifecycle entrypoints must inspect and normalize CodeSDD-managed agent instruction blocks in root and tool-specific agent files.
139
155
  - Commit work must use Conventional Commits, selective staging, and directory/protocol grouping. Source changes, \`${memoryDir}\` governance, docs, config, infra, dependencies, generated files, renames, and deletions should be staged and committed separately unless indivisible.`;
140
156
  }
@@ -225,11 +241,9 @@ export async function validateSddGuideDocs(projectRoot, paths, config) {
225
241
  const agentCompatRaw = (await fileExists(agentCompatPath))
226
242
  ? await fs.readFile(agentCompatPath, 'utf-8')
227
243
  : '';
228
- if (!readmeRaw.includes(README_SDD_BLOCK_START) || !readmeRaw.includes(README_SDD_BLOCK_END)) {
229
- missingBlocks.push('README.md::SDD:ONBOARDING');
230
- }
244
+ validateManagedBlock(readmeRaw, README_SDD_BLOCK_START, README_SDD_BLOCK_END, buildReadmeBlock(memoryDirName, config), 'README.md::SDD:ONBOARDING', missingBlocks);
231
245
  if (internalReadmeRaw !==
232
- buildSddInternalReadme(path.relative(projectRoot, paths.memoryRoot) || '.sdd', {
246
+ buildSddInternalReadme(memoryDirName, {
233
247
  discovery: config?.folders.discovery,
234
248
  planning: config?.folders.planning,
235
249
  skills: config?.folders.skills,
@@ -240,17 +254,9 @@ export async function validateSddGuideDocs(projectRoot, paths, config) {
240
254
  })) {
241
255
  missingBlocks.push(`${memoryDirName}/README.md::SDD:INTERNAL`);
242
256
  }
243
- if (!agentRaw.includes(AGENT_SDD_BLOCK_START) || !agentRaw.includes(AGENT_SDD_BLOCK_END)) {
244
- missingBlocks.push(`${memoryDirName}/AGENT.md::SDD:GUIA`);
245
- }
246
- if (!agentsRaw.includes(ROOT_AGENTS_SDD_BLOCK_START) ||
247
- !agentsRaw.includes(ROOT_AGENTS_SDD_BLOCK_END)) {
248
- missingBlocks.push('AGENTS.md::SDD:ROOT-AGENTS');
249
- }
250
- if (!agentCompatRaw.includes(ROOT_AGENTS_SDD_BLOCK_START) ||
251
- !agentCompatRaw.includes(ROOT_AGENTS_SDD_BLOCK_END)) {
252
- missingBlocks.push('AGENT.md::SDD:ROOT-AGENTS');
253
- }
257
+ validateManagedBlock(agentRaw, AGENT_SDD_BLOCK_START, AGENT_SDD_BLOCK_END, buildAgentGuideBlock(memoryDirName, config), `${memoryDirName}/AGENT.md::SDD:GUIA`, missingBlocks);
258
+ validateManagedBlock(agentsRaw, ROOT_AGENTS_SDD_BLOCK_START, ROOT_AGENTS_SDD_BLOCK_END, buildRootAgentsBlock(memoryDirName), 'AGENTS.md::SDD:ROOT-AGENTS', missingBlocks);
259
+ validateManagedBlock(agentCompatRaw, ROOT_AGENTS_SDD_BLOCK_START, ROOT_AGENTS_SDD_BLOCK_END, buildRootAgentsBlock(memoryDirName), 'AGENT.md::SDD:ROOT-AGENTS', missingBlocks);
254
260
  return {
255
261
  documentationSync: missingBlocks.length === 0,
256
262
  missingBlocks,
@@ -0,0 +1,63 @@
1
+ import type { ChangeSafetyEvaluation, PlannedFileChange } from './change-safety-guardrails.js';
2
+ export declare const CAPABILITY_KINDS: readonly ["route", "page", "cli_command", "public_contract", "schema", "event", "core_flow", "governance_state"];
3
+ export declare const CAPABILITY_CHANGE_TYPES: readonly ["added", "removed", "modified", "unchanged"];
4
+ export declare const CAPABILITY_RISK_LEVELS: readonly ["none", "low", "medium", "high", "critical"];
5
+ export type CapabilityKind = (typeof CAPABILITY_KINDS)[number];
6
+ export type CapabilityChangeType = (typeof CAPABILITY_CHANGE_TYPES)[number];
7
+ export type CapabilityRiskLevel = (typeof CAPABILITY_RISK_LEVELS)[number];
8
+ export interface CapabilityInventoryItem {
9
+ kind: CapabilityKind;
10
+ id: string;
11
+ path?: string;
12
+ fingerprint?: string;
13
+ metadata?: Record<string, unknown>;
14
+ }
15
+ export interface CapabilityInventory {
16
+ schema_version: 1;
17
+ contract: 'capability-inventory/v1';
18
+ items: CapabilityInventoryItem[];
19
+ }
20
+ export interface CapabilityDiffEntry {
21
+ kind: CapabilityKind;
22
+ id: string;
23
+ change: CapabilityChangeType;
24
+ before?: CapabilityInventoryItem;
25
+ after?: CapabilityInventoryItem;
26
+ }
27
+ export interface CapabilityDiffCounts {
28
+ added: number;
29
+ removed: number;
30
+ modified: number;
31
+ unchanged: number;
32
+ }
33
+ export interface CapabilityDiffReport {
34
+ schema_version: 1;
35
+ contract: 'capability-diff-report/v1';
36
+ entries: CapabilityDiffEntry[];
37
+ counts: CapabilityDiffCounts;
38
+ }
39
+ export interface CapabilityRiskSignal {
40
+ code: string;
41
+ level: Exclude<CapabilityRiskLevel, 'none'>;
42
+ message: string;
43
+ capability_ref?: string;
44
+ path?: string;
45
+ }
46
+ export interface CapabilityRiskReport {
47
+ schema_version: 1;
48
+ contract: 'deterministic-capability-risk/v1';
49
+ level: CapabilityRiskLevel;
50
+ score: number;
51
+ signals: CapabilityRiskSignal[];
52
+ }
53
+ export interface CapabilityRiskInput {
54
+ diff: CapabilityDiffReport;
55
+ change_safety?: ChangeSafetyEvaluation;
56
+ planned_changes?: PlannedFileChange[];
57
+ required_kinds?: CapabilityKind[];
58
+ }
59
+ export declare function buildCapabilityInventory(items: CapabilityInventoryItem[]): CapabilityInventory;
60
+ export declare function diffCapabilityInventories(before: CapabilityInventory, after: CapabilityInventory): CapabilityDiffReport;
61
+ export declare function scoreCapabilityDiffRisk(input: CapabilityRiskInput): CapabilityRiskReport;
62
+ export declare function capabilityKey(item: Pick<CapabilityInventoryItem, 'kind' | 'id'>): string;
63
+ //# sourceMappingURL=capability-diff.d.ts.map