@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
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
export const SEMANTIC_INTENT_CLASSES = ['incremental', 'refactor', 'replacement', 'ambiguous'];
|
|
2
|
+
const REPLACEMENT_PATTERNS = [
|
|
3
|
+
/\breplace\b/iu,
|
|
4
|
+
/\brewrite\b/iu,
|
|
5
|
+
/\brebuild\b/iu,
|
|
6
|
+
/\bfrom scratch\b/iu,
|
|
7
|
+
/\boverwrite\b/iu,
|
|
8
|
+
/\bsubstitu(?:ir|icao|ição)\b/iu,
|
|
9
|
+
/\bsobrescrev/iu,
|
|
10
|
+
/\breescrev/iu,
|
|
11
|
+
/\bdo zero\b/iu,
|
|
12
|
+
];
|
|
13
|
+
const REFACTOR_PATTERNS = [/\brefactor\b/iu, /\brefator/iu, /\boptimi[sz]e\b/iu, /\botimiz/iu];
|
|
14
|
+
const INCREMENTAL_PATTERNS = [
|
|
15
|
+
/\badd\b/iu,
|
|
16
|
+
/\bcreate\b/iu,
|
|
17
|
+
/\bextend\b/iu,
|
|
18
|
+
/\bincremental\b/iu,
|
|
19
|
+
/\bcriar\b/iu,
|
|
20
|
+
/\badicionar\b/iu,
|
|
21
|
+
/\bincrement/iu,
|
|
22
|
+
];
|
|
23
|
+
const HIGH_RISK_LEVELS = new Set(['high', 'critical']);
|
|
24
|
+
export function shouldRunSemanticIntentClassifier(input) {
|
|
25
|
+
return Boolean(input.deterministic_risk && HIGH_RISK_LEVELS.has(input.deterministic_risk.level));
|
|
26
|
+
}
|
|
27
|
+
export function classifySemanticIntent(input) {
|
|
28
|
+
const triggered = shouldRunSemanticIntentClassifier(input);
|
|
29
|
+
const signals = collectSignals(input);
|
|
30
|
+
const classification = resolveClassification(input, signals);
|
|
31
|
+
const highRisk = Boolean(input.deterministic_risk && HIGH_RISK_LEVELS.has(input.deterministic_risk.level));
|
|
32
|
+
const blocked = triggered &&
|
|
33
|
+
(classification === 'replacement' ||
|
|
34
|
+
classification === 'ambiguous' ||
|
|
35
|
+
(highRisk && input.declared_operation === 'add' && hasRemovedCapability(input.capability_diff)));
|
|
36
|
+
return {
|
|
37
|
+
schema_version: 1,
|
|
38
|
+
contract: 'semantic-intent-classification/v1',
|
|
39
|
+
status: blocked ? 'blocked' : 'allowed',
|
|
40
|
+
classification,
|
|
41
|
+
fail_closed: true,
|
|
42
|
+
triggered,
|
|
43
|
+
confidence: confidenceFor(classification, signals),
|
|
44
|
+
reasons: blocked ? blockedReasons(classification, input) : [],
|
|
45
|
+
signals,
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
function collectSignals(input) {
|
|
49
|
+
const objective = input.objective ?? '';
|
|
50
|
+
const signals = [];
|
|
51
|
+
collectPatternSignals(objective, REPLACEMENT_PATTERNS, signals, 'replacement_language', 50);
|
|
52
|
+
collectPatternSignals(objective, REFACTOR_PATTERNS, signals, 'refactor_language', 30);
|
|
53
|
+
collectPatternSignals(objective, INCREMENTAL_PATTERNS, signals, 'incremental_language', 30);
|
|
54
|
+
if (input.declared_operation === 'replace' || input.declared_operation === 'remove') {
|
|
55
|
+
signals.push({
|
|
56
|
+
code: 'declared_replacement_operation',
|
|
57
|
+
message: `Declared operation ${input.declared_operation} is replacement-class.`,
|
|
58
|
+
weight: 60,
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
if (hasRemovedCapability(input.capability_diff)) {
|
|
62
|
+
signals.push({
|
|
63
|
+
code: 'removed_capability_present',
|
|
64
|
+
message: 'Capability diff contains removed capabilities.',
|
|
65
|
+
weight: 45,
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
if (input.deterministic_risk?.level === 'critical') {
|
|
69
|
+
signals.push({
|
|
70
|
+
code: 'critical_deterministic_risk',
|
|
71
|
+
message: 'Deterministic risk is critical.',
|
|
72
|
+
weight: 50,
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
return signals.sort((left, right) => right.weight - left.weight || left.code.localeCompare(right.code));
|
|
76
|
+
}
|
|
77
|
+
function collectPatternSignals(value, patterns, signals, code, weight) {
|
|
78
|
+
if (patterns.some((pattern) => pattern.test(value))) {
|
|
79
|
+
signals.push({ code, message: `Objective matched ${code}.`, weight });
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
function resolveClassification(input, signals) {
|
|
83
|
+
const hasReplacement = signals.some((signal) => ['replacement_language', 'declared_replacement_operation', 'removed_capability_present'].includes(signal.code));
|
|
84
|
+
const hasIncremental = signals.some((signal) => signal.code === 'incremental_language') || input.declared_operation === 'add';
|
|
85
|
+
const hasRefactor = signals.some((signal) => signal.code === 'refactor_language') || input.declared_operation === 'refactor';
|
|
86
|
+
if (hasReplacement && (hasIncremental || hasRefactor))
|
|
87
|
+
return 'ambiguous';
|
|
88
|
+
if (hasReplacement)
|
|
89
|
+
return 'replacement';
|
|
90
|
+
if (hasRefactor)
|
|
91
|
+
return 'refactor';
|
|
92
|
+
if (hasIncremental)
|
|
93
|
+
return 'incremental';
|
|
94
|
+
return input.deterministic_risk && HIGH_RISK_LEVELS.has(input.deterministic_risk.level) ? 'ambiguous' : 'incremental';
|
|
95
|
+
}
|
|
96
|
+
function hasRemovedCapability(diff) {
|
|
97
|
+
return Boolean(diff?.entries.some((entry) => entry.change === 'removed'));
|
|
98
|
+
}
|
|
99
|
+
function confidenceFor(classification, signals) {
|
|
100
|
+
if (classification === 'ambiguous')
|
|
101
|
+
return 50;
|
|
102
|
+
const total = Math.min(100, signals.filter((signal) => signal.weight > 0).reduce((sum, signal) => sum + signal.weight, 40));
|
|
103
|
+
return total;
|
|
104
|
+
}
|
|
105
|
+
function blockedReasons(classification, input) {
|
|
106
|
+
if (classification === 'replacement') {
|
|
107
|
+
return ['Semantic intent classifier fail-closed because the request is replacement-class.'];
|
|
108
|
+
}
|
|
109
|
+
if (classification === 'ambiguous') {
|
|
110
|
+
return ['Semantic intent classifier fail-closed because high-risk intent is ambiguous.'];
|
|
111
|
+
}
|
|
112
|
+
if (input.declared_operation === 'add' && hasRemovedCapability(input.capability_diff)) {
|
|
113
|
+
return ['Semantic intent classifier fail-closed because add intent conflicts with removed capabilities.'];
|
|
114
|
+
}
|
|
115
|
+
return [];
|
|
116
|
+
}
|
|
117
|
+
//# sourceMappingURL=semantic-intent-classifier.js.map
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { ArtifactAllocatorLease } from './artifact-id-allocator.js';
|
|
2
|
+
import type { EnterpriseProvisioningPolicyReport } from './enterprise-provisioning-policy.js';
|
|
3
|
+
export type EnterpriseCommandGateDecision = 'allow' | 'block' | 'bypass-detected';
|
|
4
|
+
export interface EnterpriseMutatingCommandGateRequest {
|
|
5
|
+
command: string;
|
|
6
|
+
mutates_numbered_artifacts: boolean;
|
|
7
|
+
provisioning: EnterpriseProvisioningPolicyReport;
|
|
8
|
+
project_id?: string;
|
|
9
|
+
tenant_id?: string;
|
|
10
|
+
artifact_type?: ArtifactAllocatorLease['artifact_type'];
|
|
11
|
+
lease?: ArtifactAllocatorLease;
|
|
12
|
+
fencing_token?: number;
|
|
13
|
+
now: string;
|
|
14
|
+
bypass_requested?: boolean;
|
|
15
|
+
bypass_reason?: string;
|
|
16
|
+
}
|
|
17
|
+
export interface EnterpriseMutatingCommandGateResult {
|
|
18
|
+
decision: EnterpriseCommandGateDecision;
|
|
19
|
+
reason: string;
|
|
20
|
+
required: boolean;
|
|
21
|
+
bypass_detected: boolean;
|
|
22
|
+
requested_mode: 'local' | 'enterprise';
|
|
23
|
+
effective_mode: 'local' | 'enterprise';
|
|
24
|
+
local_mode_exception_accepted: boolean;
|
|
25
|
+
}
|
|
26
|
+
export declare function evaluateEnterpriseMutatingCommandGate(request: EnterpriseMutatingCommandGateRequest): EnterpriseMutatingCommandGateResult;
|
|
27
|
+
//# sourceMappingURL=enterprise-mutating-command-gate.d.ts.map
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { validateAllocatorFencingToken } from './artifact-id-allocator.js';
|
|
2
|
+
export function evaluateEnterpriseMutatingCommandGate(request) {
|
|
3
|
+
const requestedMode = request.provisioning.requested_mode ?? request.provisioning.mode;
|
|
4
|
+
const effectiveMode = request.provisioning.effective_mode ??
|
|
5
|
+
(request.provisioning.requested && request.provisioning.status !== 'disabled' ? 'enterprise' : 'local');
|
|
6
|
+
const localModeExceptionAccepted = request.provisioning.local_mode_exception_accepted ??
|
|
7
|
+
(!request.provisioning.requested || request.provisioning.status === 'disabled');
|
|
8
|
+
if (!request.mutates_numbered_artifacts) {
|
|
9
|
+
return {
|
|
10
|
+
decision: 'allow',
|
|
11
|
+
reason: `Command ${request.command} does not mutate numbered artifacts.`,
|
|
12
|
+
required: false,
|
|
13
|
+
bypass_detected: false,
|
|
14
|
+
requested_mode: requestedMode,
|
|
15
|
+
effective_mode: effectiveMode,
|
|
16
|
+
local_mode_exception_accepted: localModeExceptionAccepted,
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
if (request.bypass_requested) {
|
|
20
|
+
return {
|
|
21
|
+
decision: 'bypass-detected',
|
|
22
|
+
reason: request.bypass_reason
|
|
23
|
+
? `Bypass requested for ${request.command}: ${request.bypass_reason}`
|
|
24
|
+
: `Bypass requested for ${request.command} without an auditable reason.`,
|
|
25
|
+
required: true,
|
|
26
|
+
bypass_detected: true,
|
|
27
|
+
requested_mode: requestedMode,
|
|
28
|
+
effective_mode: effectiveMode,
|
|
29
|
+
local_mode_exception_accepted: localModeExceptionAccepted,
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
if (!request.provisioning.requested || request.provisioning.status === 'disabled') {
|
|
33
|
+
return {
|
|
34
|
+
decision: 'allow',
|
|
35
|
+
reason: 'Enterprise provisioning is not requested for this mutation; local mode exception is accepted and numbered artifact mutation is allowed.',
|
|
36
|
+
required: false,
|
|
37
|
+
bypass_detected: false,
|
|
38
|
+
requested_mode: requestedMode,
|
|
39
|
+
effective_mode: 'local',
|
|
40
|
+
local_mode_exception_accepted: true,
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
if (request.provisioning.status !== 'ready') {
|
|
44
|
+
return {
|
|
45
|
+
decision: 'block',
|
|
46
|
+
reason: `Enterprise provisioning is ${request.provisioning.status} with requested_mode=${requestedMode} and effective_mode=enterprise: ` +
|
|
47
|
+
request.provisioning.reason,
|
|
48
|
+
required: true,
|
|
49
|
+
bypass_detected: false,
|
|
50
|
+
requested_mode: requestedMode,
|
|
51
|
+
effective_mode: 'enterprise',
|
|
52
|
+
local_mode_exception_accepted: false,
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
if (!request.lease || request.fencing_token === undefined) {
|
|
56
|
+
return {
|
|
57
|
+
decision: 'block',
|
|
58
|
+
reason: `Command ${request.command} requires an active allocator lease and fencing token in Enterprise mode.`,
|
|
59
|
+
required: true,
|
|
60
|
+
bypass_detected: false,
|
|
61
|
+
requested_mode: requestedMode,
|
|
62
|
+
effective_mode: 'enterprise',
|
|
63
|
+
local_mode_exception_accepted: false,
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
if ((request.project_id !== undefined && request.lease.project_id !== request.project_id) ||
|
|
67
|
+
(request.tenant_id !== undefined && request.lease.tenant_id !== request.tenant_id) ||
|
|
68
|
+
(request.artifact_type !== undefined && request.lease.artifact_type !== request.artifact_type)) {
|
|
69
|
+
return {
|
|
70
|
+
decision: 'block',
|
|
71
|
+
reason: `Command ${request.command} allocator lease scope does not match the requested mutation scope.`,
|
|
72
|
+
required: true,
|
|
73
|
+
bypass_detected: false,
|
|
74
|
+
requested_mode: requestedMode,
|
|
75
|
+
effective_mode: 'enterprise',
|
|
76
|
+
local_mode_exception_accepted: false,
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
const fencing = validateAllocatorFencingToken(request.lease, {
|
|
80
|
+
fencing_token: request.fencing_token,
|
|
81
|
+
now: request.now,
|
|
82
|
+
});
|
|
83
|
+
if (!fencing.valid) {
|
|
84
|
+
return {
|
|
85
|
+
decision: 'block',
|
|
86
|
+
reason: `Command ${request.command} allocator fencing token is ${fencing.reason}.`,
|
|
87
|
+
required: true,
|
|
88
|
+
bypass_detected: false,
|
|
89
|
+
requested_mode: requestedMode,
|
|
90
|
+
effective_mode: 'enterprise',
|
|
91
|
+
local_mode_exception_accepted: false,
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
return {
|
|
95
|
+
decision: 'allow',
|
|
96
|
+
reason: `Command ${request.command} has a valid Enterprise allocator lease and fencing token.`,
|
|
97
|
+
required: true,
|
|
98
|
+
bypass_detected: false,
|
|
99
|
+
requested_mode: requestedMode,
|
|
100
|
+
effective_mode: 'enterprise',
|
|
101
|
+
local_mode_exception_accepted: false,
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
//# sourceMappingURL=enterprise-mutating-command-gate.js.map
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { ArtifactIdAllocatorState } from './artifact-id-allocator.js';
|
|
2
|
+
export interface EnterpriseProvenanceFinding {
|
|
3
|
+
severity: 'blocker' | 'warning';
|
|
4
|
+
code: string;
|
|
5
|
+
message: string;
|
|
6
|
+
ref?: string;
|
|
7
|
+
}
|
|
8
|
+
export interface EnterpriseProvenanceReport {
|
|
9
|
+
valid: boolean;
|
|
10
|
+
findings: EnterpriseProvenanceFinding[];
|
|
11
|
+
counters: {
|
|
12
|
+
reservations: number;
|
|
13
|
+
leases: number;
|
|
14
|
+
canonical_writes: number;
|
|
15
|
+
drafts: number;
|
|
16
|
+
audit_events: number;
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
export declare function evaluateEnterpriseAllocatorProvenance(state: ArtifactIdAllocatorState): EnterpriseProvenanceReport;
|
|
20
|
+
//# sourceMappingURL=enterprise-provenance-gates.d.ts.map
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
export function evaluateEnterpriseAllocatorProvenance(state) {
|
|
2
|
+
const findings = [];
|
|
3
|
+
for (const reservation of state.reservations) {
|
|
4
|
+
const hasAudit = state.audit_log.some((event) => event.idempotency_key === reservation.idempotency_key &&
|
|
5
|
+
(event.event_type === 'reservation_created' || event.event_type === 'reservation_replayed'));
|
|
6
|
+
if (!hasAudit) {
|
|
7
|
+
findings.push({
|
|
8
|
+
severity: 'blocker',
|
|
9
|
+
code: 'reservation-missing-audit',
|
|
10
|
+
message: `Reservation ${reservation.artifact_id} has no allocator audit event.`,
|
|
11
|
+
ref: reservation.artifact_id,
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
for (const lease of state.leases) {
|
|
16
|
+
const hasAudit = state.audit_log.some((event) => event.lease_id === lease.lease_id && event.event_type === 'lease_acquired');
|
|
17
|
+
if (!hasAudit) {
|
|
18
|
+
findings.push({
|
|
19
|
+
severity: 'blocker',
|
|
20
|
+
code: 'lease-missing-audit',
|
|
21
|
+
message: `Lease ${lease.lease_id} has no acquisition audit event.`,
|
|
22
|
+
ref: lease.lease_id,
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
for (const write of state.canonical_writes) {
|
|
27
|
+
const hasAudit = state.audit_log.some((event) => event.idempotency_key === write.idempotency_key &&
|
|
28
|
+
(event.event_type === 'canonical_write_committed' || event.event_type === 'canonical_write_replayed'));
|
|
29
|
+
if (!hasAudit) {
|
|
30
|
+
findings.push({
|
|
31
|
+
severity: 'blocker',
|
|
32
|
+
code: 'canonical-write-missing-audit',
|
|
33
|
+
message: `Canonical write ${write.artifact_id}@${write.revision} has no write audit event.`,
|
|
34
|
+
ref: write.artifact_id,
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
for (const draft of state.drafts) {
|
|
39
|
+
if (draft.converted_artifact_id) {
|
|
40
|
+
const reservation = state.reservations.find((candidate) => candidate.artifact_id === draft.converted_artifact_id);
|
|
41
|
+
if (!reservation) {
|
|
42
|
+
findings.push({
|
|
43
|
+
severity: 'blocker',
|
|
44
|
+
code: 'draft-conversion-missing-reservation',
|
|
45
|
+
message: `Draft ${draft.draft_id} converted to ${draft.converted_artifact_id} without a reservation record.`,
|
|
46
|
+
ref: draft.draft_id,
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
return {
|
|
52
|
+
valid: findings.every((finding) => finding.severity !== 'blocker'),
|
|
53
|
+
findings,
|
|
54
|
+
counters: {
|
|
55
|
+
reservations: state.reservations.length,
|
|
56
|
+
leases: state.leases.length,
|
|
57
|
+
canonical_writes: state.canonical_writes.length,
|
|
58
|
+
drafts: state.drafts.length,
|
|
59
|
+
audit_events: state.audit_log.length,
|
|
60
|
+
},
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
//# sourceMappingURL=enterprise-provenance-gates.js.map
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { GlobalConfig } from '../global-config.js';
|
|
2
|
+
export type EnterpriseProvisioningStatus = 'disabled' | 'ready' | 'blocked';
|
|
3
|
+
export interface EnterpriseProvisioningPolicyReport {
|
|
4
|
+
schema_version: 1;
|
|
5
|
+
mode: 'local' | 'enterprise';
|
|
6
|
+
requested_mode?: 'local' | 'enterprise';
|
|
7
|
+
effective_mode?: 'local' | 'enterprise';
|
|
8
|
+
local_mode_exception_accepted?: boolean;
|
|
9
|
+
requested: boolean;
|
|
10
|
+
required_for_numbered_artifacts: boolean;
|
|
11
|
+
status: EnterpriseProvisioningStatus;
|
|
12
|
+
project_id?: string;
|
|
13
|
+
tenant_id?: string;
|
|
14
|
+
authority_url_env?: string;
|
|
15
|
+
redacted_authority_url?: string;
|
|
16
|
+
reason: string;
|
|
17
|
+
next_action: string;
|
|
18
|
+
validation_errors: string[];
|
|
19
|
+
rules: {
|
|
20
|
+
canonical_numbered_artifacts: string;
|
|
21
|
+
offline_enterprise: string;
|
|
22
|
+
local_mode: string;
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
export declare function buildEnterpriseProvisioningPolicyReport(config: GlobalConfig, env?: NodeJS.ProcessEnv): EnterpriseProvisioningPolicyReport;
|
|
26
|
+
//# sourceMappingURL=enterprise-provisioning-policy.d.ts.map
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
const DEFAULT_RULES = {
|
|
2
|
+
canonical_numbered_artifacts: 'Enterprise multi-agent mode must reserve DEB, INS, EPIC, FEAT, and other numbered artifacts through the online provisioning authority before canonical writes.',
|
|
3
|
+
offline_enterprise: 'When the authority is unavailable, Enterprise agents may create noncanonical drafts only; conversion to canonical artifacts requires a later online reservation.',
|
|
4
|
+
local_mode: 'Local/single-agent mode may keep using repository-local CodeSDD state and is not required to contact the provisioning authority.',
|
|
5
|
+
};
|
|
6
|
+
export function buildEnterpriseProvisioningPolicyReport(config, env = process.env) {
|
|
7
|
+
const provisioning = config.enterprise?.provisioning ?? {};
|
|
8
|
+
const mode = provisioning.mode ?? 'local';
|
|
9
|
+
const required = Boolean(provisioning.required_for_numbered_artifacts || mode === 'enterprise');
|
|
10
|
+
const requestedMode = mode;
|
|
11
|
+
const effectiveMode = required ? 'enterprise' : 'local';
|
|
12
|
+
const localModeExceptionAccepted = !required;
|
|
13
|
+
const authorityUrl = resolveAuthorityUrl(provisioning.authority_url, provisioning.authority_url_env, env);
|
|
14
|
+
const validationErrors = [];
|
|
15
|
+
if (required && !provisioning.project_id) {
|
|
16
|
+
validationErrors.push('enterprise.provisioning.project_id is required in Enterprise provisioning mode.');
|
|
17
|
+
}
|
|
18
|
+
if (required && !authorityUrl) {
|
|
19
|
+
validationErrors.push('enterprise.provisioning.authority_url or authority_url_env is required in Enterprise provisioning mode.');
|
|
20
|
+
}
|
|
21
|
+
if (authorityUrl && !isValidAuthorityUrl(authorityUrl)) {
|
|
22
|
+
validationErrors.push('enterprise.provisioning authority URL must be http(s) and include a hostname.');
|
|
23
|
+
}
|
|
24
|
+
if (mode === 'local' && !required) {
|
|
25
|
+
return {
|
|
26
|
+
schema_version: 1,
|
|
27
|
+
mode,
|
|
28
|
+
requested_mode: requestedMode,
|
|
29
|
+
effective_mode: effectiveMode,
|
|
30
|
+
local_mode_exception_accepted: localModeExceptionAccepted,
|
|
31
|
+
requested: false,
|
|
32
|
+
required_for_numbered_artifacts: false,
|
|
33
|
+
status: 'disabled',
|
|
34
|
+
project_id: provisioning.project_id,
|
|
35
|
+
tenant_id: provisioning.tenant_id,
|
|
36
|
+
authority_url_env: provisioning.authority_url_env,
|
|
37
|
+
redacted_authority_url: authorityUrl ? redactUrl(authorityUrl) : undefined,
|
|
38
|
+
reason: 'Enterprise provisioning requested mode is local and no Enterprise reservation request is active; local mode exception is accepted.',
|
|
39
|
+
next_action: 'none',
|
|
40
|
+
validation_errors: validationErrors,
|
|
41
|
+
rules: DEFAULT_RULES,
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
const status = validationErrors.length === 0 ? 'ready' : 'blocked';
|
|
45
|
+
return {
|
|
46
|
+
schema_version: 1,
|
|
47
|
+
mode,
|
|
48
|
+
requested_mode: requestedMode,
|
|
49
|
+
effective_mode: effectiveMode,
|
|
50
|
+
local_mode_exception_accepted: localModeExceptionAccepted,
|
|
51
|
+
requested: true,
|
|
52
|
+
required_for_numbered_artifacts: required,
|
|
53
|
+
status,
|
|
54
|
+
project_id: provisioning.project_id,
|
|
55
|
+
tenant_id: provisioning.tenant_id,
|
|
56
|
+
authority_url_env: provisioning.authority_url_env,
|
|
57
|
+
redacted_authority_url: authorityUrl ? redactUrl(authorityUrl) : undefined,
|
|
58
|
+
reason: status === 'ready'
|
|
59
|
+
? requestedMode === 'enterprise'
|
|
60
|
+
? 'Enterprise provisioning policy is configured for canonical numbered artifact reservations.'
|
|
61
|
+
: 'Enterprise provisioning is requested by required_for_numbered_artifacts despite local requested mode and is configured for canonical numbered artifact reservations.'
|
|
62
|
+
: 'Enterprise provisioning policy is requested but missing required project identity or authority configuration.',
|
|
63
|
+
next_action: status === 'ready'
|
|
64
|
+
? 'none'
|
|
65
|
+
: 'Configure enterprise.provisioning.project_id and enterprise.provisioning.authority_url or authority_url_env in ~/.codesdd/config.toml, or keep enterprise.provisioning.mode=local with required_for_numbered_artifacts=false when Enterprise reservations are not intended.',
|
|
66
|
+
validation_errors: validationErrors,
|
|
67
|
+
rules: DEFAULT_RULES,
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
function resolveAuthorityUrl(explicitUrl, authorityUrlEnv, env) {
|
|
71
|
+
if (explicitUrl)
|
|
72
|
+
return explicitUrl;
|
|
73
|
+
if (authorityUrlEnv)
|
|
74
|
+
return env[authorityUrlEnv];
|
|
75
|
+
return undefined;
|
|
76
|
+
}
|
|
77
|
+
function isValidAuthorityUrl(value) {
|
|
78
|
+
try {
|
|
79
|
+
const parsed = new URL(value);
|
|
80
|
+
return (parsed.protocol === 'https:' || parsed.protocol === 'http:') && parsed.hostname.length > 0;
|
|
81
|
+
}
|
|
82
|
+
catch {
|
|
83
|
+
return false;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
function redactUrl(value) {
|
|
87
|
+
try {
|
|
88
|
+
const parsed = new URL(value);
|
|
89
|
+
if (parsed.username)
|
|
90
|
+
parsed.username = '[REDACTED]';
|
|
91
|
+
if (parsed.password)
|
|
92
|
+
parsed.password = '[REDACTED]';
|
|
93
|
+
for (const key of [...parsed.searchParams.keys()]) {
|
|
94
|
+
if (/key|secret|token|password|credential|private|auth/i.test(key)) {
|
|
95
|
+
parsed.searchParams.set(key, '[REDACTED]');
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
return parsed.toString();
|
|
99
|
+
}
|
|
100
|
+
catch {
|
|
101
|
+
return '[REDACTED]';
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
//# sourceMappingURL=enterprise-provisioning-policy.js.map
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { type PluginArtifactMap } from './plugin-sdk-contract.js';
|
|
2
|
+
export type FoundationArtifactMapFindingCode = 'FOUNDATION_ARTIFACT_SCHEMA_INVALID' | 'FOUNDATION_LAYER_PATH_MISMATCH' | 'FOUNDATION_DOMAIN_BO_PATH_INVALID' | 'FOUNDATION_DOMAIN_VO_PATH_INVALID' | 'FOUNDATION_APPLICATION_PORT_PATH_INVALID' | 'FOUNDATION_INFRASTRUCTURE_ENTITY_PATH_INVALID';
|
|
3
|
+
export interface FoundationArtifactMapFinding {
|
|
4
|
+
code: FoundationArtifactMapFindingCode;
|
|
5
|
+
severity: 'warn';
|
|
6
|
+
path?: string;
|
|
7
|
+
message: string;
|
|
8
|
+
remediation: string;
|
|
9
|
+
}
|
|
10
|
+
export interface FoundationArtifactMapValidationResult {
|
|
11
|
+
status: 'passed' | 'warning';
|
|
12
|
+
artifact_map?: PluginArtifactMap;
|
|
13
|
+
findings: FoundationArtifactMapFinding[];
|
|
14
|
+
}
|
|
15
|
+
export declare function validateFoundationArtifactMapArchitecture(value: unknown): FoundationArtifactMapValidationResult;
|
|
16
|
+
//# sourceMappingURL=foundation-artifact-map-validator.d.ts.map
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { pluginArtifactMapSchema, } from './plugin-sdk-contract.js';
|
|
2
|
+
const LAYER_PATH_PREFIXES = {
|
|
3
|
+
domain: 'src/domain/',
|
|
4
|
+
application: 'src/application/',
|
|
5
|
+
infrastructure: 'src/infrastructure/',
|
|
6
|
+
presentation: 'src/presentation/',
|
|
7
|
+
tests: 'test/',
|
|
8
|
+
docs: 'docs/',
|
|
9
|
+
sdd: '.sdd/',
|
|
10
|
+
config: '.',
|
|
11
|
+
};
|
|
12
|
+
const DOMAIN_BO_PATTERN = /^src\/domain\/[^/]+\/business-objects\/[^/]+\.bo\.ts$/u;
|
|
13
|
+
const DOMAIN_VO_PATTERN = /^src\/domain\/[^/]+\/value-objects\/[^/]+\.vo\.ts$/u;
|
|
14
|
+
const APPLICATION_PORT_PATTERN = /^src\/application\/business\/[^/]+\/ports\/out\/[^/]+\.port\.ts$/u;
|
|
15
|
+
const INFRASTRUCTURE_ENTITY_PATTERN = /^src\/infrastructure\/adapters\/orm\/entities\/[^/]+\.orm-entity\.ts$/u;
|
|
16
|
+
export function validateFoundationArtifactMapArchitecture(value) {
|
|
17
|
+
const parsed = pluginArtifactMapSchema.safeParse(value);
|
|
18
|
+
if (!parsed.success) {
|
|
19
|
+
return {
|
|
20
|
+
status: 'warning',
|
|
21
|
+
findings: [
|
|
22
|
+
{
|
|
23
|
+
code: 'FOUNDATION_ARTIFACT_SCHEMA_INVALID',
|
|
24
|
+
severity: 'warn',
|
|
25
|
+
message: `Artifact map failed SDK schema validation: ${parsed.error.issues.map(formatIssue).join('; ')}`,
|
|
26
|
+
remediation: 'Validate the artifact map with @devtrack-solution/codesdd-plugin-sdk before applying Foundation architecture checks.',
|
|
27
|
+
},
|
|
28
|
+
],
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
const findings = parsed.data.artifacts.flatMap(validateEntry);
|
|
32
|
+
return {
|
|
33
|
+
status: findings.length > 0 ? 'warning' : 'passed',
|
|
34
|
+
artifact_map: parsed.data,
|
|
35
|
+
findings,
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
function validateEntry(entry) {
|
|
39
|
+
const findings = [];
|
|
40
|
+
const expectedPrefix = LAYER_PATH_PREFIXES[entry.layer];
|
|
41
|
+
if (expectedPrefix && !entry.path.startsWith(expectedPrefix)) {
|
|
42
|
+
findings.push(finding('FOUNDATION_LAYER_PATH_MISMATCH', entry, `Artifact declares layer "${entry.layer}" but path "${entry.path}" does not use the expected prefix "${expectedPrefix}".`, `Move the artifact under ${expectedPrefix} or correct the layer metadata before execution.`));
|
|
43
|
+
}
|
|
44
|
+
if (entry.layer === 'domain' && entry.role === 'business-object' && !DOMAIN_BO_PATTERN.test(entry.path)) {
|
|
45
|
+
findings.push(finding('FOUNDATION_DOMAIN_BO_PATH_INVALID', entry, `Domain business object path "${entry.path}" does not match the Foundation BO-pattern.`, 'Use src/domain/<context>/business-objects/<name>.bo.ts for new Foundation contexts.'));
|
|
46
|
+
}
|
|
47
|
+
if (entry.layer === 'domain' && entry.role === 'value-object' && !DOMAIN_VO_PATTERN.test(entry.path)) {
|
|
48
|
+
findings.push(finding('FOUNDATION_DOMAIN_VO_PATH_INVALID', entry, `Domain value object path "${entry.path}" does not match the Foundation VO-pattern.`, 'Use src/domain/<context>/value-objects/<name>.vo.ts for value objects.'));
|
|
49
|
+
}
|
|
50
|
+
if (entry.role === 'repository-port' && !APPLICATION_PORT_PATTERN.test(entry.path)) {
|
|
51
|
+
findings.push(finding('FOUNDATION_APPLICATION_PORT_PATH_INVALID', entry, `Repository port path "${entry.path}" does not match the Foundation application ports/out pattern.`, 'Use src/application/business/<context>/ports/out/<name>.port.ts for BO-pattern repository ports.'));
|
|
52
|
+
}
|
|
53
|
+
if (entry.layer === 'infrastructure' && entry.role === 'entity' && !INFRASTRUCTURE_ENTITY_PATTERN.test(entry.path)) {
|
|
54
|
+
findings.push(finding('FOUNDATION_INFRASTRUCTURE_ENTITY_PATH_INVALID', entry, `Infrastructure entity path "${entry.path}" does not match the centralized TypeORM entity pattern.`, 'Use src/infrastructure/adapters/orm/entities/<name>.orm-entity.ts for TypeORM entities.'));
|
|
55
|
+
}
|
|
56
|
+
return findings;
|
|
57
|
+
}
|
|
58
|
+
function finding(code, entry, message, remediation) {
|
|
59
|
+
return {
|
|
60
|
+
code,
|
|
61
|
+
severity: 'warn',
|
|
62
|
+
path: entry.path,
|
|
63
|
+
message,
|
|
64
|
+
remediation,
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
function formatIssue(issue) {
|
|
68
|
+
const issuePath = issue.path.length > 0 ? issue.path.join('.') : '<root>';
|
|
69
|
+
return `${issuePath}: ${issue.message}`;
|
|
70
|
+
}
|
|
71
|
+
//# sourceMappingURL=foundation-artifact-map-validator.js.map
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export declare const CODESDD_FOUNDATION_LAYER_IDS: readonly ["domains", "applications", "infrastructures", "presentations", "shared"];
|
|
2
|
+
export type CodesddFoundationLayerId = (typeof CODESDD_FOUNDATION_LAYER_IDS)[number];
|
|
3
|
+
export interface CodesddFoundationLayerMapping {
|
|
4
|
+
layer: CodesddFoundationLayerId;
|
|
5
|
+
root: `src/${CodesddFoundationLayerId}`;
|
|
6
|
+
entrypoint: `src/${CodesddFoundationLayerId}/${string}`;
|
|
7
|
+
legacy_roots: string[];
|
|
8
|
+
role: string;
|
|
9
|
+
migration_status: 'active-facade' | 'legacy-source';
|
|
10
|
+
}
|
|
11
|
+
export interface CodesddFoundationLayerFinding {
|
|
12
|
+
code: 'FOUNDATION_LAYER_MISSING' | 'FOUNDATION_LAYER_ROOT_MISMATCH' | 'FOUNDATION_LAYER_ENTRYPOINT_MISMATCH' | 'FOUNDATION_LAYER_DUPLICATE' | 'FOUNDATION_LAYER_FORBIDDEN_PROJECT_RUNTIME';
|
|
13
|
+
layer?: string;
|
|
14
|
+
path?: string;
|
|
15
|
+
message: string;
|
|
16
|
+
}
|
|
17
|
+
export interface CodesddFoundationLayerValidationReport {
|
|
18
|
+
valid: boolean;
|
|
19
|
+
findings: CodesddFoundationLayerFinding[];
|
|
20
|
+
}
|
|
21
|
+
export declare const CODESDD_FOUNDATION_LAYER_MANIFEST: readonly CodesddFoundationLayerMapping[];
|
|
22
|
+
export declare function listCodesddFoundationLayerRoots(manifest?: readonly CodesddFoundationLayerMapping[]): string[];
|
|
23
|
+
export declare function validateCodesddFoundationLayerManifest(manifest?: readonly CodesddFoundationLayerMapping[]): CodesddFoundationLayerValidationReport;
|
|
24
|
+
//# sourceMappingURL=foundation-layer-manifest.d.ts.map
|