@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.
- package/.sdd/skills/curated/devtrack-api/SKILL.md +98 -12
- package/.sdd/skills/curated/devtrack-api/agents/claude-code.yaml +10 -0
- package/.sdd/skills/curated/devtrack-api/agents/codex.yaml +10 -0
- package/.sdd/skills/curated/devtrack-api/agents/cursor.yaml +10 -0
- package/.sdd/skills/curated/devtrack-api/agents/gemini.yaml +10 -0
- package/.sdd/skills/curated/devtrack-api/agents/kimi.yaml +10 -0
- package/.sdd/skills/curated/devtrack-api/agents/openai.yaml +5 -3
- package/.sdd/skills/curated/devtrack-api/agents/opencode.yaml +12 -0
- package/.sdd/skills/curated/devtrack-api/references/application-presentation.md +61 -5
- package/.sdd/skills/curated/devtrack-api/references/consumer-sync-policy.md +15 -3
- package/.sdd/skills/curated/devtrack-api/references/contract-pack.yaml +1951 -0
- package/.sdd/skills/curated/devtrack-api/references/domain-modeling.md +16 -14
- package/.sdd/skills/curated/devtrack-api/references/field-validation-protocol.md +40 -0
- package/.sdd/skills/curated/devtrack-api/references/foundation-layout.md +19 -2
- package/.sdd/skills/curated/devtrack-api/references/generated-artifact-invalidation.md +97 -0
- package/.sdd/skills/curated/devtrack-api/references/implementation-checklist.md +30 -1
- package/.sdd/skills/curated/devtrack-api/references/portable-agent-contract.md +42 -0
- package/.sdd/skills/curated/devtrack-api/references/testing-validation.md +22 -1
- package/.sdd/skills/curated/devtrack-api/references/typeorm-infrastructure.md +9 -7
- package/README.md +280 -29
- package/dist/applications/sdd/index.d.ts +16 -0
- package/dist/applications/sdd/index.js +16 -0
- package/dist/cli/program.js +180 -11
- package/dist/commands/config.js +197 -10
- package/dist/commands/sdd/execution.js +408 -16
- package/dist/commands/sdd/plugin.js +5 -0
- package/dist/commands/sdd/shared.d.ts +1 -0
- package/dist/commands/sdd/shared.js +10 -0
- package/dist/commands/sdd.js +157 -7
- package/dist/core/cli/command-matrix.d.ts +18 -0
- package/dist/core/cli/command-matrix.js +157 -0
- package/dist/core/cli-command-quality.js +11 -0
- package/dist/core/completions/command-registry.js +45 -0
- package/dist/core/config-schema.d.ts +31 -1
- package/dist/core/config-schema.js +79 -5
- package/dist/core/config.d.ts +1 -0
- package/dist/core/config.js +11 -0
- package/dist/core/global-config.d.ts +29 -0
- package/dist/core/init.d.ts +2 -2
- package/dist/core/init.js +13 -14
- package/dist/core/sdd/agent-binding.d.ts +19 -19
- package/dist/core/sdd/agent-runtime-contract.d.ts +204 -0
- package/dist/core/sdd/agent-runtime-contract.js +200 -0
- package/dist/core/sdd/allocator-recovery.d.ts +14 -0
- package/dist/core/sdd/allocator-recovery.js +30 -0
- package/dist/core/sdd/allocator-security.d.ts +18 -0
- package/dist/core/sdd/allocator-security.js +36 -0
- package/dist/core/sdd/api-foundation-baseline.d.ts +111 -0
- package/dist/core/sdd/api-foundation-baseline.js +151 -0
- package/dist/core/sdd/api-foundation-parity.d.ts +114 -0
- package/dist/core/sdd/api-foundation-parity.js +131 -0
- package/dist/core/sdd/api-profile-catalog.d.ts +36 -0
- package/dist/core/sdd/api-profile-catalog.js +132 -0
- package/dist/core/sdd/api-profile-dry-run-projection.d.ts +93 -0
- package/dist/core/sdd/api-profile-dry-run-projection.js +370 -0
- package/dist/core/sdd/api-profile-recipes.d.ts +82 -0
- package/dist/core/sdd/api-profile-recipes.js +484 -0
- package/dist/core/sdd/artifact-id-allocator.d.ts +368 -0
- package/dist/core/sdd/artifact-id-allocator.js +510 -0
- package/dist/core/sdd/check.d.ts +52 -1
- package/dist/core/sdd/check.js +326 -11
- package/dist/core/sdd/coordination/coordination-adapters.d.ts +15 -8
- package/dist/core/sdd/coordination/coordination-adapters.js +43 -15
- package/dist/core/sdd/coordination/index.d.ts +1 -0
- package/dist/core/sdd/coordination/index.js +1 -0
- package/dist/core/sdd/coordination/redis-runtime.d.ts +131 -0
- package/dist/core/sdd/coordination/redis-runtime.js +698 -0
- package/dist/core/sdd/deepagent-contracts.d.ts +99 -5
- package/dist/core/sdd/deepagent-contracts.js +62 -0
- package/dist/core/sdd/deepagents/reversa-subagents.d.ts +3 -3
- package/dist/core/sdd/default-bootstrap-files.d.ts +2 -2
- package/dist/core/sdd/default-bootstrap-files.js +14 -10
- package/dist/core/sdd/default-skills.js +115 -9
- package/dist/core/sdd/devtrack-api-appliance.d.ts +42 -1
- package/dist/core/sdd/devtrack-api-appliance.js +159 -32
- package/dist/core/sdd/devtrack-api-architecture.d.ts +16 -0
- package/dist/core/sdd/devtrack-api-architecture.js +86 -0
- package/dist/core/sdd/docs-sync.js +24 -18
- package/dist/core/sdd/domain/capability-diff.d.ts +63 -0
- package/dist/core/sdd/domain/capability-diff.js +200 -0
- package/dist/core/sdd/domain/change-safety-guardrails.d.ts +74 -0
- package/dist/core/sdd/domain/change-safety-guardrails.js +333 -0
- package/dist/core/sdd/domain/semantic-intent-classifier.d.ts +29 -0
- package/dist/core/sdd/domain/semantic-intent-classifier.js +117 -0
- package/dist/core/sdd/enterprise-mutating-command-gate.d.ts +27 -0
- package/dist/core/sdd/enterprise-mutating-command-gate.js +104 -0
- package/dist/core/sdd/enterprise-provenance-gates.d.ts +20 -0
- package/dist/core/sdd/enterprise-provenance-gates.js +63 -0
- package/dist/core/sdd/enterprise-provisioning-policy.d.ts +26 -0
- package/dist/core/sdd/enterprise-provisioning-policy.js +104 -0
- package/dist/core/sdd/foundation-artifact-map-validator.d.ts +16 -0
- package/dist/core/sdd/foundation-artifact-map-validator.js +71 -0
- package/dist/core/sdd/foundation-layer-manifest.d.ts +24 -0
- package/dist/core/sdd/foundation-layer-manifest.js +117 -0
- package/dist/core/sdd/governance-schemas.d.ts +2 -2
- package/dist/core/sdd/governance-schemas.js +11 -2
- package/dist/core/sdd/intent-guard.d.ts +22 -0
- package/dist/core/sdd/intent-guard.js +67 -0
- package/dist/core/sdd/json-schema.js +13 -1
- package/dist/core/sdd/legacy-operations.js +169 -5
- package/dist/core/sdd/migrate-workspace.js +39 -0
- package/dist/core/sdd/package-security-gates.d.ts +21 -0
- package/dist/core/sdd/package-security-gates.js +121 -0
- package/dist/core/sdd/package-structure-gate.d.ts +85 -3
- package/dist/core/sdd/package-structure-gate.js +384 -11
- package/dist/core/sdd/parallel-feat-automation.d.ts +185 -7
- package/dist/core/sdd/parallel-feat-automation.js +212 -0
- package/dist/core/sdd/plugin-broker.d.ts +223 -4
- package/dist/core/sdd/plugin-broker.js +10 -0
- package/dist/core/sdd/plugin-cli.d.ts +30 -0
- package/dist/core/sdd/plugin-cli.js +70 -3
- package/dist/core/sdd/plugin-evidence.d.ts +73 -0
- package/dist/core/sdd/plugin-manifest.d.ts +69 -1
- package/dist/core/sdd/plugin-manifest.js +10 -0
- package/dist/core/sdd/plugin-policy-pack.d.ts +1 -1
- package/dist/core/sdd/plugin-policy.js +6 -1
- package/dist/core/sdd/plugin-registry.d.ts +138 -2
- package/dist/core/sdd/plugin-sdk-contract.d.ts +363 -0
- package/dist/core/sdd/plugin-sdk-contract.js +268 -0
- package/dist/core/sdd/plugin-skill-binding.d.ts +1 -1
- package/dist/core/sdd/quality-validation.d.ts +89 -16
- package/dist/core/sdd/release-readiness.d.ts +68 -0
- package/dist/core/sdd/release-readiness.js +767 -0
- package/dist/core/sdd/reversa-architecture-extractor.d.ts +13 -0
- package/dist/core/sdd/reversa-architecture-extractor.js +89 -0
- package/dist/core/sdd/reversa-artifact-writer.d.ts +18 -0
- package/dist/core/sdd/reversa-artifact-writer.js +40 -0
- package/dist/core/sdd/reversa-command-policy.d.ts +136 -0
- package/dist/core/sdd/reversa-command-policy.js +361 -0
- package/dist/core/sdd/reversa-data-extractor.d.ts +11 -0
- package/dist/core/sdd/reversa-data-extractor.js +73 -0
- package/dist/core/sdd/reversa-equivalence.d.ts +20 -0
- package/dist/core/sdd/reversa-equivalence.js +34 -0
- package/dist/core/sdd/reversa-evidence.d.ts +298 -0
- package/dist/core/sdd/reversa-evidence.js +118 -0
- package/dist/core/sdd/reversa-reconstruction.d.ts +29 -0
- package/dist/core/sdd/reversa-reconstruction.js +32 -0
- package/dist/core/sdd/reversa-rules-extractor.d.ts +12 -0
- package/dist/core/sdd/reversa-rules-extractor.js +86 -0
- package/dist/core/sdd/reversa-source-safety.d.ts +19 -0
- package/dist/core/sdd/reversa-source-safety.js +105 -0
- package/dist/core/sdd/reversa-surface-scout.d.ts +13 -0
- package/dist/core/sdd/reversa-surface-scout.js +85 -0
- package/dist/core/sdd/reversa-ux-mapper.d.ts +11 -0
- package/dist/core/sdd/reversa-ux-mapper.js +73 -0
- package/dist/core/sdd/runtime-boundary-contract.d.ts +45 -0
- package/dist/core/sdd/runtime-boundary-contract.js +90 -0
- package/dist/core/sdd/sdk-agent-plugin-quality-gates.d.ts +150 -0
- package/dist/core/sdd/sdk-agent-plugin-quality-gates.js +258 -0
- package/dist/core/sdd/services/agent-run.service.d.ts +38 -6
- package/dist/core/sdd/services/agent-run.service.js +73 -1
- package/dist/core/sdd/services/archive-quality-coherence.service.d.ts +17 -0
- package/dist/core/sdd/services/archive-quality-coherence.service.js +141 -0
- package/dist/core/sdd/services/capability-diff.service.d.ts +18 -0
- package/dist/core/sdd/services/capability-diff.service.js +26 -0
- package/dist/core/sdd/services/change-safety-preflight.service.d.ts +17 -0
- package/dist/core/sdd/services/change-safety-preflight.service.js +17 -0
- package/dist/core/sdd/services/context.service.d.ts +43 -340
- package/dist/core/sdd/services/context.service.js +323 -9
- package/dist/core/sdd/services/decide.service.js +1 -1
- package/dist/core/sdd/services/finalize.service.d.ts +27 -0
- package/dist/core/sdd/services/finalize.service.js +226 -18
- package/dist/core/sdd/services/frontend-impact.service.d.ts +1 -1
- package/dist/core/sdd/services/historical-quality-regression.service.d.ts +35 -0
- package/dist/core/sdd/services/historical-quality-regression.service.js +228 -0
- package/dist/core/sdd/services/ingest-deposito.service.js +1 -1
- package/dist/core/sdd/services/planning-execution-coherence.service.d.ts +45 -0
- package/dist/core/sdd/services/planning-execution-coherence.service.js +225 -0
- package/dist/core/sdd/services/semantic-intent-classifier.service.d.ts +6 -0
- package/dist/core/sdd/services/semantic-intent-classifier.service.js +7 -0
- package/dist/core/sdd/state.d.ts +1 -0
- package/dist/core/sdd/state.js +266 -34
- package/dist/core/sdd/store/sdd-stores.js +2 -2
- package/dist/core/sdd/structural-health.d.ts +13 -13
- package/dist/core/sdd/types.d.ts +30 -15
- package/dist/core/sdd/types.js +4 -0
- package/dist/core/sdd/views.js +17 -0
- package/dist/core/sdd/workspace-schemas.d.ts +428 -7
- package/dist/core/sdd/workspace-schemas.js +223 -70
- package/dist/core/shared/skill-generation.d.ts +2 -0
- package/dist/core/shared/skill-generation.js +19 -2
- package/dist/core/shared/tool-detection.d.ts +19 -0
- package/dist/core/shared/tool-detection.js +89 -0
- package/dist/domains/sdd/index.d.ts +6 -0
- package/dist/domains/sdd/index.js +6 -0
- package/dist/infrastructures/sdd/index.d.ts +7 -0
- package/dist/infrastructures/sdd/index.js +6 -0
- package/dist/presentations/cli/sdd/index.d.ts +3 -0
- package/dist/presentations/cli/sdd/index.js +3 -0
- package/dist/shared/sdd/index.d.ts +3 -0
- package/dist/shared/sdd/index.js +2 -0
- package/package.json +14 -10
- package/schemas/sdd/2-plan.schema.json +207 -2
- package/schemas/sdd/5-quality.schema.json +324 -25
- package/schemas/sdd/agent-runtime-command-plan.schema.json +212 -0
- package/schemas/sdd/agent-runtime-opencode-run-evidence.schema.json +270 -0
- package/schemas/sdd/codesdd-plugin.schema.json +171 -0
- package/schemas/sdd/deepagent-run-request.schema.json +316 -0
- package/schemas/sdd/parallel-feat-automation-plan.schema.json +89 -0
- package/schemas/sdd/parallel-feat-scheduler-request.schema.json +116 -0
- package/schemas/sdd/parallel-feat-scheduler-result.schema.json +404 -0
- package/schemas/sdd/plugin-artifact-manifest.schema.json +109 -0
- package/schemas/sdd/plugin-artifact-map.schema.json +223 -0
- package/schemas/sdd/plugin-evidence-manifest.schema.json +109 -0
- package/schemas/sdd/plugin-language-runtime.schema.json +103 -0
- package/schemas/sdd/plugin-package-governance.schema.json +74 -0
- package/schemas/sdd/plugin-registry.schema.json +171 -0
- package/schemas/sdd/plugin-runtime-invocation-plan.schema.json +109 -0
- package/schemas/sdd/quality-evidence-bundle.schema.json +109 -0
- package/schemas/sdd/reversa-evidence-bundle.schema.json +466 -0
- package/schemas/sdd/sdk-agent-plugin-quality-gate-input.schema.json +168 -0
- package/schemas/sdd/sdk-agent-plugin-quality-gate-report.schema.json +160 -0
- 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:
|
|
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
|
-
|
|
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
|
-
|
|
213
|
-
artifact('package.json', 'root', 'application/json', 'Foundation-compatible package metadata, scripts, and dependencies.'),
|
|
214
|
-
artifact('
|
|
215
|
-
artifact('
|
|
216
|
-
artifact('
|
|
217
|
-
artifact('
|
|
218
|
-
artifact('
|
|
219
|
-
artifact('src/
|
|
220
|
-
artifact('src/
|
|
221
|
-
artifact('src/application/
|
|
222
|
-
artifact('src/
|
|
223
|
-
artifact('src/
|
|
224
|
-
artifact('src/
|
|
225
|
-
artifact('src/
|
|
226
|
-
artifact('src/
|
|
227
|
-
artifact('src/
|
|
228
|
-
artifact('src/
|
|
229
|
-
artifact('src/
|
|
230
|
-
artifact('src/
|
|
231
|
-
artifact('src/
|
|
232
|
-
artifact('
|
|
233
|
-
artifact('
|
|
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
|
|
237
|
-
|
|
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
|
-
-
|
|
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
|
-
-
|
|
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
|
-
-
|
|
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
|
-
|
|
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(
|
|
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
|
-
|
|
244
|
-
|
|
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
|