@devtrack-solution/codesdd 1.2.3 → 1.2.4-rc3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (139) hide show
  1. package/.sdd/skills/curated/devtrack-api/SKILL.md +12 -5
  2. package/.sdd/skills/curated/devtrack-api/agents/claude-code.yaml +8 -0
  3. package/.sdd/skills/curated/devtrack-api/agents/codex.yaml +8 -0
  4. package/.sdd/skills/curated/devtrack-api/agents/cursor.yaml +8 -0
  5. package/.sdd/skills/curated/devtrack-api/agents/gemini.yaml +8 -0
  6. package/.sdd/skills/curated/devtrack-api/agents/kimi.yaml +8 -0
  7. package/.sdd/skills/curated/devtrack-api/agents/openai.yaml +4 -2
  8. package/.sdd/skills/curated/devtrack-api/agents/opencode.yaml +10 -0
  9. package/.sdd/skills/curated/devtrack-api/references/application-presentation.md +2 -2
  10. package/.sdd/skills/curated/devtrack-api/references/contract-pack.yaml +55 -0
  11. package/.sdd/skills/curated/devtrack-api/references/domain-modeling.md +13 -13
  12. package/.sdd/skills/curated/devtrack-api/references/foundation-layout.md +2 -3
  13. package/.sdd/skills/curated/devtrack-api/references/implementation-checklist.md +1 -1
  14. package/.sdd/skills/curated/devtrack-api/references/portable-agent-contract.md +41 -0
  15. package/.sdd/skills/curated/devtrack-api/references/typeorm-infrastructure.md +7 -9
  16. package/README.md +159 -5
  17. package/dist/applications/sdd/index.d.ts +16 -0
  18. package/dist/applications/sdd/index.js +16 -0
  19. package/dist/commands/config.js +171 -10
  20. package/dist/commands/sdd/execution.js +345 -15
  21. package/dist/commands/sdd/plugin.js +5 -0
  22. package/dist/commands/sdd/shared.d.ts +1 -0
  23. package/dist/commands/sdd/shared.js +10 -0
  24. package/dist/commands/sdd.js +38 -3
  25. package/dist/core/cli/command-matrix.js +9 -0
  26. package/dist/core/cli-command-quality.js +9 -0
  27. package/dist/core/completions/command-registry.js +45 -0
  28. package/dist/core/config-schema.d.ts +18 -1
  29. package/dist/core/config-schema.js +48 -5
  30. package/dist/core/global-config.d.ts +16 -0
  31. package/dist/core/sdd/agent-binding.d.ts +10 -10
  32. package/dist/core/sdd/agent-runtime-contract.d.ts +204 -0
  33. package/dist/core/sdd/agent-runtime-contract.js +200 -0
  34. package/dist/core/sdd/check.d.ts +2 -0
  35. package/dist/core/sdd/check.js +40 -2
  36. package/dist/core/sdd/coordination/coordination-adapters.d.ts +15 -8
  37. package/dist/core/sdd/coordination/coordination-adapters.js +43 -15
  38. package/dist/core/sdd/coordination/index.d.ts +1 -0
  39. package/dist/core/sdd/coordination/index.js +1 -0
  40. package/dist/core/sdd/coordination/redis-runtime.d.ts +131 -0
  41. package/dist/core/sdd/coordination/redis-runtime.js +698 -0
  42. package/dist/core/sdd/deepagent-contracts.d.ts +98 -4
  43. package/dist/core/sdd/deepagent-contracts.js +62 -0
  44. package/dist/core/sdd/default-bootstrap-files.d.ts +2 -2
  45. package/dist/core/sdd/default-bootstrap-files.js +14 -8
  46. package/dist/core/sdd/default-skills.js +108 -4
  47. package/dist/core/sdd/devtrack-api-appliance.d.ts +8 -1
  48. package/dist/core/sdd/devtrack-api-appliance.js +46 -23
  49. package/dist/core/sdd/docs-sync.js +21 -15
  50. package/dist/core/sdd/domain/capability-diff.d.ts +63 -0
  51. package/dist/core/sdd/domain/capability-diff.js +200 -0
  52. package/dist/core/sdd/domain/change-safety-guardrails.d.ts +74 -0
  53. package/dist/core/sdd/domain/change-safety-guardrails.js +333 -0
  54. package/dist/core/sdd/domain/semantic-intent-classifier.d.ts +29 -0
  55. package/dist/core/sdd/domain/semantic-intent-classifier.js +117 -0
  56. package/dist/core/sdd/foundation-artifact-map-validator.d.ts +16 -0
  57. package/dist/core/sdd/foundation-artifact-map-validator.js +71 -0
  58. package/dist/core/sdd/foundation-layer-manifest.d.ts +24 -0
  59. package/dist/core/sdd/foundation-layer-manifest.js +117 -0
  60. package/dist/core/sdd/intent-guard.d.ts +22 -0
  61. package/dist/core/sdd/intent-guard.js +67 -0
  62. package/dist/core/sdd/json-schema.js +9 -1
  63. package/dist/core/sdd/legacy-operations.js +76 -1
  64. package/dist/core/sdd/migrate-workspace.js +39 -0
  65. package/dist/core/sdd/package-security-gates.d.ts +21 -0
  66. package/dist/core/sdd/package-security-gates.js +119 -0
  67. package/dist/core/sdd/package-structure-gate.js +3 -8
  68. package/dist/core/sdd/parallel-feat-automation.d.ts +181 -3
  69. package/dist/core/sdd/parallel-feat-automation.js +212 -0
  70. package/dist/core/sdd/plugin-broker.d.ts +223 -4
  71. package/dist/core/sdd/plugin-broker.js +10 -0
  72. package/dist/core/sdd/plugin-cli.d.ts +30 -0
  73. package/dist/core/sdd/plugin-cli.js +70 -3
  74. package/dist/core/sdd/plugin-evidence.d.ts +73 -0
  75. package/dist/core/sdd/plugin-manifest.d.ts +69 -1
  76. package/dist/core/sdd/plugin-manifest.js +10 -0
  77. package/dist/core/sdd/plugin-policy-pack.d.ts +1 -1
  78. package/dist/core/sdd/plugin-registry.d.ts +141 -5
  79. package/dist/core/sdd/plugin-sdk-contract.d.ts +363 -0
  80. package/dist/core/sdd/plugin-sdk-contract.js +268 -0
  81. package/dist/core/sdd/plugin-skill-binding.d.ts +1 -1
  82. package/dist/core/sdd/quality-validation.d.ts +84 -11
  83. package/dist/core/sdd/release-readiness.d.ts +19 -0
  84. package/dist/core/sdd/release-readiness.js +472 -0
  85. package/dist/core/sdd/runtime-boundary-contract.d.ts +45 -0
  86. package/dist/core/sdd/runtime-boundary-contract.js +90 -0
  87. package/dist/core/sdd/sdk-agent-plugin-quality-gates.d.ts +150 -0
  88. package/dist/core/sdd/sdk-agent-plugin-quality-gates.js +258 -0
  89. package/dist/core/sdd/services/agent-run.service.d.ts +38 -6
  90. package/dist/core/sdd/services/agent-run.service.js +73 -1
  91. package/dist/core/sdd/services/capability-diff.service.d.ts +18 -0
  92. package/dist/core/sdd/services/capability-diff.service.js +26 -0
  93. package/dist/core/sdd/services/change-safety-preflight.service.d.ts +17 -0
  94. package/dist/core/sdd/services/change-safety-preflight.service.js +17 -0
  95. package/dist/core/sdd/services/context.service.d.ts +43 -340
  96. package/dist/core/sdd/services/context.service.js +323 -9
  97. package/dist/core/sdd/services/finalize.service.d.ts +25 -0
  98. package/dist/core/sdd/services/finalize.service.js +178 -16
  99. package/dist/core/sdd/services/frontend-impact.service.d.ts +1 -1
  100. package/dist/core/sdd/services/semantic-intent-classifier.service.d.ts +6 -0
  101. package/dist/core/sdd/services/semantic-intent-classifier.service.js +7 -0
  102. package/dist/core/sdd/state.d.ts +1 -0
  103. package/dist/core/sdd/state.js +251 -29
  104. package/dist/core/sdd/store/sdd-stores.js +2 -2
  105. package/dist/core/sdd/structural-health.d.ts +13 -13
  106. package/dist/core/sdd/types.d.ts +27 -12
  107. package/dist/core/sdd/types.js +4 -0
  108. package/dist/core/sdd/views.js +17 -0
  109. package/dist/core/sdd/workspace-schemas.d.ts +387 -7
  110. package/dist/core/sdd/workspace-schemas.js +196 -64
  111. package/dist/domains/sdd/index.d.ts +6 -0
  112. package/dist/domains/sdd/index.js +6 -0
  113. package/dist/infrastructures/sdd/index.d.ts +7 -0
  114. package/dist/infrastructures/sdd/index.js +6 -0
  115. package/dist/presentations/cli/sdd/index.d.ts +3 -0
  116. package/dist/presentations/cli/sdd/index.js +3 -0
  117. package/dist/shared/sdd/index.d.ts +3 -0
  118. package/dist/shared/sdd/index.js +2 -0
  119. package/package.json +9 -6
  120. package/schemas/sdd/2-plan.schema.json +207 -2
  121. package/schemas/sdd/5-quality.schema.json +281 -25
  122. package/schemas/sdd/agent-runtime-command-plan.schema.json +212 -0
  123. package/schemas/sdd/agent-runtime-opencode-run-evidence.schema.json +270 -0
  124. package/schemas/sdd/codesdd-plugin.schema.json +171 -0
  125. package/schemas/sdd/deepagent-run-request.schema.json +316 -0
  126. package/schemas/sdd/parallel-feat-automation-plan.schema.json +89 -0
  127. package/schemas/sdd/parallel-feat-scheduler-request.schema.json +116 -0
  128. package/schemas/sdd/parallel-feat-scheduler-result.schema.json +404 -0
  129. package/schemas/sdd/plugin-artifact-manifest.schema.json +109 -0
  130. package/schemas/sdd/plugin-artifact-map.schema.json +223 -0
  131. package/schemas/sdd/plugin-evidence-manifest.schema.json +109 -0
  132. package/schemas/sdd/plugin-language-runtime.schema.json +103 -0
  133. package/schemas/sdd/plugin-package-governance.schema.json +74 -0
  134. package/schemas/sdd/plugin-registry.schema.json +171 -0
  135. package/schemas/sdd/plugin-runtime-invocation-plan.schema.json +109 -0
  136. package/schemas/sdd/quality-evidence-bundle.schema.json +109 -0
  137. package/schemas/sdd/sdk-agent-plugin-quality-gate-input.schema.json +168 -0
  138. package/schemas/sdd/sdk-agent-plugin-quality-gate-report.schema.json +160 -0
  139. package/schemas/sdd/workspace-catalog.schema.json +3776 -398
@@ -10,12 +10,71 @@ import { normalizeArchivedFeatureActiveReferences, validatePostActiveFeaturePlac
10
10
  import { loadStateSnapshot, nowIso, saveStateTransaction } from "../state.js";
11
11
  import { syncSddGuideDocs } from "../docs-sync.js";
12
12
  import { mergeArchitectureNode, mergeFrontendDecisionRecord, mergeRepoMapRecord, mergeServiceRecord, mergeTechStackRecord, stableUniqueStrings, upsertByKey } from "../merge-catalog.js";
13
- import { getRuntime, persistAndRender, relProjectPath, coreDocRef, activeDocNamesForLayout, activeDocCandidateNames, unresolvedDependencies, updateDependencyMetadata, gitChangedFiles, detectFrontendImpactEvidence, maybeCreateAutomaticFrontendGap, buildFinalizeQueue, evaluateFeatureQuality, buildAdrMarkdown, applyLoggedTransition, gateSatisfied, pathExists, RADAR_TO_DISCOVERY_STATUS } from "../legacy-operations.js";
13
+ import { getRuntime, persistAndRender, relProjectPath, coreDocRef, activeDocNamesForLayout, activeDocCandidateNames, unresolvedDependencies, updateDependencyMetadata, gitChangedFiles, detectFrontendImpactEvidence, maybeCreateAutomaticFrontendGap, buildFinalizeQueue, evaluateFeatureQuality, buildAdrMarkdown, applyLoggedTransition, gateSatisfied, pathExists, computeReadyFeatures, extractFeatureNumber, buildDependentsMap, scoreReadyItem, RADAR_TO_DISCOVERY_STATUS } from "../legacy-operations.js";
14
14
  import { SddWriteTransaction } from "../write-manifest.js";
15
15
  import { withStateLock } from "../state-lock.js";
16
16
  import { activeWorkspaceDeclaresMandatoryAdrImpact } from "../adr-policy.js";
17
17
  import { normalizeFeatRef } from "../entity-reference.js";
18
18
  import { parseWorkspaceYamlDocument, stringifyWorkspaceYamlDocument, } from "../workspace-schemas.js";
19
+ function recordFinalizeHistory(history, item) {
20
+ const index = history.findIndex((entry) => entry.feature_id === item.feature_id);
21
+ if (index >= 0) {
22
+ history[index] = item;
23
+ return;
24
+ }
25
+ history.push(item);
26
+ history.sort((a, b) => a.feature_id.localeCompare(b.feature_id));
27
+ }
28
+ function moveCompletedFinalizeItemsToHistory(state) {
29
+ const activeItems = [];
30
+ for (const item of state.items) {
31
+ if (item.status === 'DONE') {
32
+ recordFinalizeHistory(state.history, {
33
+ feature_id: item.feature_id,
34
+ status: 'DONE',
35
+ summary: item.summary,
36
+ created_at: item.created_at,
37
+ completed_at: item.completed_at || item.created_at || '',
38
+ });
39
+ }
40
+ else {
41
+ activeItems.push(item);
42
+ }
43
+ }
44
+ state.items = activeItems;
45
+ }
46
+ function buildPostFinalizeReplan(items, finalized, unlocked, generatedAt) {
47
+ const rank = 'impact';
48
+ const computed = computeReadyFeatures(items, { rank });
49
+ const dependentsMap = buildDependentsMap(items);
50
+ const ready = computed.ready
51
+ .map((item) => {
52
+ const scored = scoreReadyItem(item, items, dependentsMap, rank);
53
+ return {
54
+ id: item.id,
55
+ title: item.title,
56
+ recommended_skills: item.recommended_skills.slice(0, 3),
57
+ score: scored.score,
58
+ reasons: scored.reasons,
59
+ };
60
+ })
61
+ .sort((left, right) => {
62
+ if (right.score !== left.score)
63
+ return right.score - left.score;
64
+ return extractFeatureNumber(left.id) - extractFeatureNumber(right.id);
65
+ })
66
+ .slice(0, 10);
67
+ return {
68
+ rank,
69
+ generated_at: generatedAt,
70
+ finalized,
71
+ unlocked,
72
+ ready,
73
+ waves: computed.waves,
74
+ blocked_count: computed.blocked.length,
75
+ conflicts_count: computed.conflicts.length,
76
+ };
77
+ }
19
78
  export class FinalizeService {
20
79
  stores;
21
80
  constructor(stores) {
@@ -25,6 +84,7 @@ export class FinalizeService {
25
84
  const { config, paths } = await getRuntime(projectRoot);
26
85
  return withStateLock(paths.stateDir, async () => {
27
86
  const snapshot = await loadStateSnapshot(paths, config);
87
+ moveCompletedFinalizeItemsToHistory(snapshot.finalizeQueue);
28
88
  snapshot.finalizeQueue.items = await buildFinalizeQueue(paths, snapshot.backlog.items, snapshot.finalizeQueue.items);
29
89
  const pending = snapshot.finalizeQueue.items.filter((item) => item.status === 'PENDING');
30
90
  const inferredRef = options?.allReady
@@ -47,6 +107,7 @@ export class FinalizeService {
47
107
  finalized: [],
48
108
  unblocked: [],
49
109
  pending: pending.length,
110
+ post_finalize_replan: buildPostFinalizeReplan(snapshot.backlog.items, [], [], nowIso()),
50
111
  updated_core_docs: [],
51
112
  updated_readme: false,
52
113
  updated_agent_guide: false,
@@ -275,19 +336,14 @@ export class FinalizeService {
275
336
  continue;
276
337
  }
277
338
  const queue = snapshot.finalizeQueue.items.find((item) => item.feature_id === featureId);
278
- if (queue) {
279
- queue.status = 'DONE';
280
- queue.completed_at = now;
281
- }
282
- else {
283
- snapshot.finalizeQueue.items.push({
284
- feature_id: featureId,
285
- status: 'DONE',
286
- summary: `Finalizado manualmente: ${featureId}`,
287
- created_at: now,
288
- completed_at: now,
289
- });
290
- }
339
+ snapshot.finalizeQueue.items = snapshot.finalizeQueue.items.filter((item) => item.feature_id !== featureId);
340
+ recordFinalizeHistory(snapshot.finalizeQueue.history, {
341
+ feature_id: featureId,
342
+ status: 'DONE',
343
+ summary: queue?.summary || `Finalizado manualmente: ${featureId}`,
344
+ created_at: queue?.created_at || now,
345
+ completed_at: now,
346
+ });
291
347
  if ((feature.origin_type === 'radar' || feature.origin_type === 'epic') && feature.origin_ref) {
292
348
  const siblings = snapshot.backlog.items.filter((item) => (item.origin_type === 'radar' || item.origin_type === 'epic') && item.origin_ref === feature.origin_ref);
293
349
  if (siblings.every((item) => item.status === 'DONE' || item.status === 'ARCHIVED')) {
@@ -421,6 +477,7 @@ export class FinalizeService {
421
477
  });
422
478
  }
423
479
  updateDependencyMetadata(snapshot.backlog.items);
480
+ const postFinalizeReplan = buildPostFinalizeReplan(snapshot.backlog.items, finalized, Array.from(unblocked).sort(), now);
424
481
  const stateUpdates = {
425
482
  discoveryIndex: snapshot.discoveryIndex,
426
483
  backlog: snapshot.backlog,
@@ -454,6 +511,7 @@ export class FinalizeService {
454
511
  finalized,
455
512
  unblocked: Array.from(unblocked).sort(),
456
513
  pending: remaining,
514
+ post_finalize_replan: postFinalizeReplan,
457
515
  updated_core_docs: Array.from(updatedCoreDocs).sort(),
458
516
  updated_readme: syncResult.updatedReadme,
459
517
  updated_agent_guide: syncResult.updatedAgentGuide || syncResult.updatedRootAgents,
@@ -825,12 +883,59 @@ export function computeIntegrityAxis(document) {
825
883
  integritySignalScore(security.sensitive_data_exposure_review),
826
884
  integritySignalScore(security.incident_response_review),
827
885
  ].reduce((acc, value) => acc + value, 0) / 3);
828
- const raw = round2(skillScore * 0.7 + securityScore * 0.3);
886
+ const runtimeQuality = computeRuntimeQualityAxis(document);
887
+ const raw = round2(skillScore * 0.55 + securityScore * 0.25 + runtimeQuality.raw_score * 0.2);
829
888
  return {
830
889
  raw_score: raw,
831
- rationale: `skill_evidence=${skillScore.toFixed(2)} security_integrity=${securityScore.toFixed(2)}`,
890
+ rationale: `skill_evidence=${skillScore.toFixed(2)} security_integrity=${securityScore.toFixed(2)} runtime_quality=${runtimeQuality.raw_score.toFixed(2)} (${runtimeQuality.rationale})`,
891
+ };
892
+ }
893
+ export function computeRuntimeQualityAxis(document) {
894
+ const gates = document.runtime_quality_gates;
895
+ const performance = gates?.performance ?? [];
896
+ const flakiness = gates?.flakiness ?? [];
897
+ const entries = [
898
+ ...performance.map((entry) => ({ kind: 'performance', gate: entry.gate, evidence: entry.evidence_ref, score: runtimePerformanceScore(entry) })),
899
+ ...flakiness.map((entry) => ({ kind: 'flakiness', gate: entry.gate, evidence: entry.evidence_ref, score: runtimeFlakinessScore(entry) })),
900
+ ];
901
+ if (entries.length === 0) {
902
+ return {
903
+ raw_score: 100,
904
+ rationale: 'runtime quality telemetry not provided; neutral score applied',
905
+ };
906
+ }
907
+ const scores = entries.map((entry) => {
908
+ if (entry.gate === 'fail')
909
+ return Math.min(entry.score, 70);
910
+ if (entry.gate === 'warn')
911
+ return Math.min(entry.score, 85);
912
+ return entry.score;
913
+ });
914
+ const worst = Math.min(...scores);
915
+ const failed = entries.filter((entry) => entry.gate === 'fail').map((entry) => `${entry.kind}:${entry.evidence ?? 'runtime evidence'}`);
916
+ const warned = entries.filter((entry) => entry.gate === 'warn').map((entry) => `${entry.kind}:${entry.evidence ?? 'runtime evidence'}`);
917
+ const notes = [...failed.map((value) => `${value} failed`), ...warned.map((value) => `${value} warned`)];
918
+ return {
919
+ raw_score: worst,
920
+ rationale: `runtime quality gate scored ${worst.toFixed(2)}${notes.length > 0 ? `; ${notes.join('; ')}` : ''}`,
832
921
  };
833
922
  }
923
+ function runtimePerformanceScore(entry) {
924
+ if (entry.actual !== undefined && entry.threshold !== undefined && entry.threshold > 0) {
925
+ return clampPercent((entry.threshold / Math.max(entry.actual, 1)) * 100);
926
+ }
927
+ return entry.gate === 'pass' ? 100 : entry.gate === 'warn' ? 85 : 70;
928
+ }
929
+ function runtimeFlakinessScore(entry) {
930
+ let failureRate = entry.failure_rate_percent;
931
+ if (failureRate === undefined && entry.attempts !== undefined && entry.failures !== undefined && entry.attempts > 0) {
932
+ failureRate = clampPercent((entry.failures / entry.attempts) * 100);
933
+ }
934
+ if (failureRate === undefined) {
935
+ return entry.gate === 'pass' ? 100 : entry.gate === 'warn' ? 85 : 70;
936
+ }
937
+ return clampPercent(100 - failureRate);
938
+ }
834
939
  const LEGACY_NAMING_PATTERNS = [
835
940
  /\bcoachsdd\b/u,
836
941
  /\bcoach\s+sdd\b/u,
@@ -861,6 +966,10 @@ export function computeNamingAxis(feature, document) {
861
966
  };
862
967
  }
863
968
  export function computeTokenAxis(document) {
969
+ const structuredTelemetry = document.token_budget_gates?.telemetry ?? [];
970
+ if (structuredTelemetry.length > 0) {
971
+ return computeStructuredTokenAxis(document);
972
+ }
864
973
  const tokenEntries = document.evidence_log.filter((entry) => {
865
974
  const label = `${entry.kind} ${entry.result}`.toLowerCase();
866
975
  return label.includes('token');
@@ -893,6 +1002,59 @@ export function computeTokenAxis(document) {
893
1002
  rationale: 'token evidence found but no numeric percentage; conservative score applied',
894
1003
  };
895
1004
  }
1005
+ export function computeStructuredTokenAxis(document) {
1006
+ const gates = document.token_budget_gates;
1007
+ const telemetry = gates?.telemetry ?? [];
1008
+ const requireNumeric = gates?.require_numeric_efficiency ?? true;
1009
+ const failBelow = gates?.fail_below_percent ?? 95;
1010
+ const scores = [];
1011
+ const reasons = [];
1012
+ let hardFailure = false;
1013
+ for (const entry of telemetry) {
1014
+ let score = entry.efficiency_percent;
1015
+ if (score === undefined && entry.budget_chars !== undefined && entry.actual_chars !== undefined) {
1016
+ score = entry.actual_chars === 0 ? 100 : clampPercent((entry.budget_chars / entry.actual_chars) * 100);
1017
+ }
1018
+ if (score === undefined && entry.actual_chars !== undefined && gates?.max_context_chars !== undefined) {
1019
+ score = entry.actual_chars === 0 ? 100 : clampPercent((gates.max_context_chars / entry.actual_chars) * 100);
1020
+ }
1021
+ if (score === undefined) {
1022
+ if (requireNumeric) {
1023
+ scores.push(70);
1024
+ reasons.push(`${entry.evidence_ref ?? 'token telemetry'} lacks numeric efficiency`);
1025
+ }
1026
+ continue;
1027
+ }
1028
+ const normalized = clampPercent(score);
1029
+ scores.push(normalized);
1030
+ if (entry.gate === 'fail' || normalized < failBelow) {
1031
+ hardFailure = true;
1032
+ reasons.push(`${entry.evidence_ref ?? 'token telemetry'} below ${failBelow}%`);
1033
+ }
1034
+ else if (entry.gate === 'warn') {
1035
+ reasons.push(`${entry.evidence_ref ?? 'token telemetry'} warned at ${normalized.toFixed(2)}%`);
1036
+ }
1037
+ }
1038
+ if (scores.length === 0) {
1039
+ return {
1040
+ raw_score: requireNumeric ? 70 : 100,
1041
+ rationale: requireNumeric
1042
+ ? 'token budget gate requires numeric efficiency but no numeric telemetry was provided'
1043
+ : 'token budget telemetry provided without numeric scoring requirement',
1044
+ };
1045
+ }
1046
+ const worst = Math.min(...scores);
1047
+ if (hardFailure) {
1048
+ return {
1049
+ raw_score: Math.min(worst, 70),
1050
+ rationale: `token budget gate failed: ${reasons.join('; ')}`,
1051
+ };
1052
+ }
1053
+ return {
1054
+ raw_score: worst,
1055
+ rationale: `token budget gate satisfied (${worst.toFixed(2)}% worst-case efficiency)${reasons.length > 0 ? `; ${reasons.join('; ')}` : ''}`,
1056
+ };
1057
+ }
896
1058
  export function extractCoveragePerformance(document, kind) {
897
1059
  const target = kind === 'unit' ? document.coverage_targets.unit : document.coverage_targets.integration;
898
1060
  const relevant = document.evidence_log.filter((entry) => {
@@ -10,7 +10,7 @@ export declare class FrontendImpactService {
10
10
  render?: boolean;
11
11
  }): Promise<{
12
12
  feature_id: string;
13
- frontend_impact_status: "unknown" | "none" | "required";
13
+ frontend_impact_status: "none" | "unknown" | "required";
14
14
  frontend_impact_reason: string;
15
15
  frontend_impact_declared_at: string;
16
16
  frontend_surface_tokens: string[];
@@ -0,0 +1,6 @@
1
+ import { type SemanticIntentClassification, type SemanticIntentClassifierInput } from '../domain/semantic-intent-classifier.js';
2
+ export type SemanticIntentClassifierServiceResult = SemanticIntentClassification;
3
+ export declare class SemanticIntentClassifierService {
4
+ execute(input: SemanticIntentClassifierInput): SemanticIntentClassifierServiceResult;
5
+ }
6
+ //# sourceMappingURL=semantic-intent-classifier.service.d.ts.map
@@ -0,0 +1,7 @@
1
+ import { classifySemanticIntent, } from '../domain/semantic-intent-classifier.js';
2
+ export class SemanticIntentClassifierService {
3
+ execute(input) {
4
+ return classifySemanticIntent(input);
5
+ }
6
+ }
7
+ //# sourceMappingURL=semantic-intent-classifier.service.js.map
@@ -24,6 +24,7 @@ export interface SddRuntimeConfig {
24
24
  autoRender: boolean;
25
25
  };
26
26
  }
27
+ export declare function buildDefaultSkillRoutingState(): SkillRoutingState;
27
28
  export interface SddPaths {
28
29
  projectRoot: string;
29
30
  memoryRoot: string;
@@ -9,6 +9,254 @@ import { CURRENT_SDD_STATE_VERSION, buildSddContractConfig } from './contract.js
9
9
  import { DEFAULT_CURATED_SKILL_CATALOG, BUILT_IN_SDD_SKILLS, buildCuratedBundlesMarkdown, buildCuratedBundlesCurationData, } from './default-skills.js';
10
10
  import { buildSddInternalReadme, PROMPT_00_COMECE_POR_AQUI_MD, PROMPT_01_INGESTAO_DEPOSITO_MD, PROMPT_02_NORMALIZAR_PLANEJAMENTO_MD, PROMPT_03_EXECUCAO_FEATURE_MD, PROMPT_04_CONSOLIDACAO_FINALIZE_MD, PROMPTS_README_MD, TEMPLATE_1_SPEC_MD, TEMPLATE_2_PLAN_MD, TEMPLATE_QUALITY_MD, TEMPLATE_3_TASKS_MD, TEMPLATE_4_CHANGELOG_MD, } from './default-bootstrap-files.js';
11
11
  import { SddWriteTransaction } from './transaction.js';
12
+ export function buildDefaultSkillRoutingState() {
13
+ return {
14
+ version: 1,
15
+ default_skills: ['architecture', 'concise-planning', 'context-window-management'],
16
+ routes: [
17
+ {
18
+ domain: 'backend',
19
+ skills: ['devtrack-api', 'architecture', 'api-design-principles'],
20
+ bundles: ['architecture-backend'],
21
+ },
22
+ {
23
+ domain: 'api',
24
+ skills: ['devtrack-api', 'api-design-principles'],
25
+ bundles: ['architecture-backend'],
26
+ },
27
+ {
28
+ domain: 'nestjs',
29
+ skills: ['devtrack-api', 'architecture'],
30
+ bundles: ['architecture-backend'],
31
+ },
32
+ {
33
+ domain: 'typeorm',
34
+ skills: ['devtrack-api', 'database-design'],
35
+ bundles: ['architecture-backend'],
36
+ },
37
+ {
38
+ domain: 'devtrack',
39
+ skills: ['devtrack-api'],
40
+ bundles: ['architecture-backend'],
41
+ },
42
+ {
43
+ domain: 'python',
44
+ skills: ['api-clean-flask-langgraph', 'architecture'],
45
+ bundles: ['python-agentic-backend'],
46
+ },
47
+ {
48
+ domain: 'flask',
49
+ skills: ['api-clean-flask-langgraph'],
50
+ bundles: ['python-agentic-backend'],
51
+ },
52
+ {
53
+ domain: 'frontend',
54
+ skills: ['frontend-design', 'react-patterns'],
55
+ bundles: ['frontend-product'],
56
+ },
57
+ {
58
+ domain: 'angular',
59
+ skills: ['frontend-design', 'frontend-security-coder'],
60
+ bundles: ['frontend-product', 'security-quality'],
61
+ },
62
+ {
63
+ domain: 'flutter',
64
+ skills: ['devtrack-flutter', 'mobile-design', 'frontend-design'],
65
+ bundles: ['frontend-product'],
66
+ },
67
+ {
68
+ domain: 'dart',
69
+ skills: ['devtrack-flutter', 'architecture'],
70
+ bundles: ['frontend-product', 'architecture-backend'],
71
+ },
72
+ {
73
+ domain: 'cross-platform',
74
+ skills: ['devtrack-flutter', 'mobile-design'],
75
+ bundles: ['frontend-product'],
76
+ },
77
+ {
78
+ domain: 'flutter-ui',
79
+ skills: ['devtrack-flutter', 'frontend-design'],
80
+ bundles: ['frontend-product'],
81
+ },
82
+ {
83
+ domain: 'flutter-layout',
84
+ skills: ['devtrack-flutter', 'frontend-design'],
85
+ bundles: ['frontend-product'],
86
+ },
87
+ {
88
+ domain: 'flutter-routing',
89
+ skills: ['devtrack-flutter', 'architecture'],
90
+ bundles: ['frontend-product', 'architecture-backend'],
91
+ },
92
+ {
93
+ domain: 'flutter-l10n',
94
+ skills: ['devtrack-flutter'],
95
+ bundles: ['frontend-product'],
96
+ },
97
+ {
98
+ domain: 'flutter-http',
99
+ skills: ['devtrack-flutter', 'frontend-security-coder'],
100
+ bundles: ['frontend-product', 'security-quality'],
101
+ },
102
+ {
103
+ domain: 'flutter-json',
104
+ skills: ['devtrack-flutter'],
105
+ bundles: ['frontend-product'],
106
+ },
107
+ {
108
+ domain: 'widget-preview',
109
+ skills: ['devtrack-flutter', 'frontend-design'],
110
+ bundles: ['frontend-product'],
111
+ },
112
+ {
113
+ domain: 'widget-test',
114
+ skills: ['devtrack-flutter'],
115
+ bundles: ['frontend-product'],
116
+ },
117
+ {
118
+ domain: 'integration-test',
119
+ skills: ['devtrack-flutter'],
120
+ bundles: ['frontend-product'],
121
+ },
122
+ {
123
+ domain: 'go-router',
124
+ skills: ['devtrack-flutter', 'architecture'],
125
+ bundles: ['frontend-product', 'architecture-backend'],
126
+ },
127
+ {
128
+ domain: 'arb',
129
+ skills: ['devtrack-flutter'],
130
+ bundles: ['frontend-product'],
131
+ },
132
+ {
133
+ domain: 'l10n',
134
+ skills: ['devtrack-flutter'],
135
+ bundles: ['frontend-product'],
136
+ },
137
+ {
138
+ domain: 'admin',
139
+ skills: ['devtrack-angular', 'frontend-design', 'frontend-security-coder'],
140
+ bundles: ['frontend-product', 'security-quality'],
141
+ },
142
+ {
143
+ domain: 'angular-admin',
144
+ skills: ['devtrack-angular', 'frontend-design', 'frontend-security-coder'],
145
+ bundles: ['frontend-product', 'security-quality'],
146
+ },
147
+ {
148
+ domain: 'backoffice',
149
+ skills: ['devtrack-angular', 'frontend-design', 'frontend-security-coder'],
150
+ bundles: ['frontend-product', 'security-quality'],
151
+ },
152
+ {
153
+ domain: 'dashboard',
154
+ skills: ['devtrack-angular', 'frontend-design'],
155
+ bundles: ['frontend-product'],
156
+ },
157
+ {
158
+ domain: 'crud',
159
+ skills: ['devtrack-angular', 'architecture'],
160
+ bundles: ['frontend-product', 'architecture-backend'],
161
+ },
162
+ {
163
+ domain: 'data-grid',
164
+ skills: ['devtrack-angular', 'frontend-design'],
165
+ bundles: ['frontend-product'],
166
+ },
167
+ {
168
+ domain: 'formly',
169
+ skills: ['frontend-design'],
170
+ bundles: ['frontend-product'],
171
+ },
172
+ {
173
+ domain: 'ngxs',
174
+ skills: ['architecture'],
175
+ bundles: ['frontend-product', 'architecture-backend'],
176
+ },
177
+ {
178
+ domain: 'admin-formly',
179
+ skills: ['devtrack-angular', 'frontend-design'],
180
+ bundles: ['frontend-product'],
181
+ },
182
+ {
183
+ domain: 'admin-state',
184
+ skills: ['devtrack-angular', 'architecture'],
185
+ bundles: ['frontend-product', 'architecture-backend'],
186
+ },
187
+ {
188
+ domain: 'ngxs-admin',
189
+ skills: ['devtrack-angular', 'architecture'],
190
+ bundles: ['frontend-product', 'architecture-backend'],
191
+ },
192
+ {
193
+ domain: 'uiux',
194
+ skills: ['frontend-design', 'ui-ux-pro-max'],
195
+ bundles: ['frontend-product'],
196
+ },
197
+ {
198
+ domain: 'permissions',
199
+ skills: ['devtrack-angular', 'frontend-security-coder'],
200
+ bundles: ['frontend-product', 'security-quality'],
201
+ },
202
+ {
203
+ domain: 'reports',
204
+ skills: ['devtrack-angular', 'frontend-design'],
205
+ bundles: ['frontend-product'],
206
+ },
207
+ {
208
+ domain: 'workflow',
209
+ skills: ['devtrack-angular', 'architecture'],
210
+ bundles: ['frontend-product', 'architecture-backend'],
211
+ },
212
+ {
213
+ domain: 'realtime',
214
+ skills: ['architecture'],
215
+ bundles: ['frontend-product'],
216
+ },
217
+ {
218
+ domain: 'rtc',
219
+ skills: ['architecture'],
220
+ bundles: ['frontend-product'],
221
+ },
222
+ {
223
+ domain: 'chat',
224
+ skills: ['frontend-design'],
225
+ bundles: ['frontend-product'],
226
+ },
227
+ {
228
+ domain: 'admin-realtime',
229
+ skills: ['devtrack-angular', 'architecture'],
230
+ bundles: ['frontend-product'],
231
+ },
232
+ {
233
+ domain: 'admin-chat',
234
+ skills: ['devtrack-angular', 'frontend-design'],
235
+ bundles: ['frontend-product'],
236
+ },
237
+ {
238
+ domain: 'mobile',
239
+ skills: ['mobile-design'],
240
+ bundles: ['frontend-product'],
241
+ },
242
+ {
243
+ domain: 'ionic',
244
+ skills: ['mobile-design'],
245
+ bundles: ['frontend-product'],
246
+ },
247
+ {
248
+ domain: 'nativescript',
249
+ skills: ['mobile-design'],
250
+ bundles: ['frontend-product'],
251
+ },
252
+ {
253
+ domain: 'infra',
254
+ skills: ['terraform-specialist', 'docker-expert'],
255
+ bundles: [],
256
+ },
257
+ ],
258
+ };
259
+ }
12
260
  const LEGACY_LAYOUT_FOLDERS = {
13
261
  discovery: 'discovery',
14
262
  planning: 'pendencias',
@@ -606,7 +854,7 @@ export async function ensureBaseFiles(paths, config) {
606
854
  });
607
855
  await writeYamlIfMissing(paths.stateFiles.backlog, { version: 1, items: [] });
608
856
  await writeYamlIfMissing(paths.stateFiles.techDebt, { version: 1, items: [] });
609
- await writeYamlIfMissing(paths.stateFiles.finalizeQueue, { version: 1, items: [] });
857
+ await writeYamlIfMissing(paths.stateFiles.finalizeQueue, { version: 1, items: [], history: [] });
610
858
  await ensureCuratedSkillCatalog(paths.stateFiles.skillCatalog);
611
859
  await writeYamlIfMissing(paths.stateFiles.unblockEvents, { version: 1, events: [] });
612
860
  await writeYamlIfMissing(paths.stateFiles.transitionLog, { version: 1, events: [] });
@@ -623,21 +871,7 @@ export async function ensureBaseFiles(paths, config) {
623
871
  jurisdiction_profiles: [],
624
872
  control_catalog: [],
625
873
  });
626
- await writeYamlIfMissing(paths.stateFiles.skillRouting, {
627
- version: 1,
628
- default_skills: ['architecture', 'concise-planning', 'context-window-management'],
629
- routes: [
630
- { domain: 'backend', skills: ['devtrack-api', 'architecture', 'api-design-principles'], bundles: ['architecture-backend'] },
631
- { domain: 'api', skills: ['devtrack-api', 'api-design-principles'], bundles: ['architecture-backend'] },
632
- { domain: 'python', skills: ['api-clean-flask-langgraph', 'architecture'], bundles: ['python-agentic-backend'] },
633
- { domain: 'flask', skills: ['api-clean-flask-langgraph'], bundles: ['python-agentic-backend'] },
634
- { domain: 'nestjs', skills: ['devtrack-api', 'architecture'], bundles: ['architecture-backend'] },
635
- { domain: 'typeorm', skills: ['devtrack-api', 'database-design'], bundles: ['architecture-backend'] },
636
- { domain: 'devtrack', skills: ['devtrack-api'], bundles: ['architecture-backend'] },
637
- { domain: 'frontend', skills: ['frontend-design', 'react-patterns'], bundles: [] },
638
- { domain: 'infra', skills: ['terraform-specialist', 'docker-expert'], bundles: [] }
639
- ]
640
- });
874
+ await writeYamlIfMissing(paths.stateFiles.skillRouting, buildDefaultSkillRoutingState());
641
875
  if (config.frontend.enabled) {
642
876
  await writeYamlIfMissing(paths.stateFiles.frontendGaps, { version: 1, items: [] });
643
877
  await writeYamlIfMissing(paths.stateFiles.frontendMap, { version: 1, routes: [] });
@@ -724,19 +958,7 @@ export async function loadStateSnapshot(paths, config) {
724
958
  skillRouting = SkillRoutingStateSchema.parse(await readYaml(paths.stateFiles.skillRouting));
725
959
  }
726
960
  catch (e) {
727
- skillRouting = {
728
- version: 1,
729
- default_skills: ['architecture', 'concise-planning', 'context-window-management'],
730
- routes: [
731
- { domain: 'backend', skills: ['devtrack-api', 'architecture', 'api-design-principles'], bundles: ['architecture-backend'] },
732
- { domain: 'api', skills: ['devtrack-api', 'api-design-principles'], bundles: ['architecture-backend'] },
733
- { domain: 'python', skills: ['api-clean-flask-langgraph', 'architecture'], bundles: ['python-agentic-backend'] },
734
- { domain: 'flask', skills: ['api-clean-flask-langgraph'], bundles: ['python-agentic-backend'] },
735
- { domain: 'nestjs', skills: ['devtrack-api', 'architecture'], bundles: ['architecture-backend'] },
736
- { domain: 'typeorm', skills: ['devtrack-api', 'database-design'], bundles: ['architecture-backend'] },
737
- { domain: 'devtrack', skills: ['devtrack-api'], bundles: ['architecture-backend'] }
738
- ]
739
- };
961
+ skillRouting = buildDefaultSkillRoutingState();
740
962
  }
741
963
  let frontendGaps;
742
964
  let frontendMap;
@@ -7,7 +7,7 @@ export function createSddStores(paths) {
7
7
  discoveryIndex: new YamlFileAdapter(stateFiles.discoveryIndex, DiscoveryIndexStateSchema, () => ({ version: 1, counters: { INS: 0, DEB: 0, RAD: 0, EPIC: 0, FEAT: 0, FGAP: 0, TD: 0 }, records: [] })),
8
8
  backlog: new YamlFileAdapter(stateFiles.backlog, BacklogStateSchema, () => ({ version: 1, items: [] })),
9
9
  techDebt: new YamlFileAdapter(stateFiles.techDebt, TechDebtStateSchema, () => ({ version: 1, items: [] })),
10
- finalizeQueue: new YamlFileAdapter(stateFiles.finalizeQueue, FinalizeQueueStateSchema, () => ({ version: 1, items: [] })),
10
+ finalizeQueue: new YamlFileAdapter(stateFiles.finalizeQueue, FinalizeQueueStateSchema, () => ({ version: 1, items: [], history: [] })),
11
11
  skillCatalog: new YamlFileAdapter(stateFiles.skillCatalog, SkillCatalogStateSchema, () => ({ version: 1, skills: [], bundles: [] })),
12
12
  unblockEvents: new YamlFileAdapter(stateFiles.unblockEvents, UnblockEventsStateSchema, () => ({ version: 1, events: [] })),
13
13
  transitionLog: new YamlFileAdapter(stateFiles.transitionLog, TransitionLogStateSchema, () => ({ version: 1, events: [] })),
@@ -34,7 +34,7 @@ export function createInMemorySddStores() {
34
34
  discoveryIndex: new InMemoryAdapter(DiscoveryIndexStateSchema, () => ({ version: 1, counters: { INS: 0, DEB: 0, RAD: 0, EPIC: 0, FEAT: 0, FGAP: 0, TD: 0 }, records: [] })),
35
35
  backlog: new InMemoryAdapter(BacklogStateSchema, () => ({ version: 1, items: [] })),
36
36
  techDebt: new InMemoryAdapter(TechDebtStateSchema, () => ({ version: 1, items: [] })),
37
- finalizeQueue: new InMemoryAdapter(FinalizeQueueStateSchema, () => ({ version: 1, items: [] })),
37
+ finalizeQueue: new InMemoryAdapter(FinalizeQueueStateSchema, () => ({ version: 1, items: [], history: [] })),
38
38
  skillCatalog: new InMemoryAdapter(SkillCatalogStateSchema, () => ({ version: 1, skills: [], bundles: [] })),
39
39
  unblockEvents: new InMemoryAdapter(UnblockEventsStateSchema, () => ({ version: 1, events: [] })),
40
40
  transitionLog: new InMemoryAdapter(TransitionLogStateSchema, () => ({ version: 1, events: [] })),