@devtrack-solution/codesdd 1.2.4-rc3 → 1.2.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (128) hide show
  1. package/.sdd/skills/curated/devtrack-api/SKILL.md +91 -12
  2. package/.sdd/skills/curated/devtrack-api/agents/claude-code.yaml +2 -0
  3. package/.sdd/skills/curated/devtrack-api/agents/codex.yaml +2 -0
  4. package/.sdd/skills/curated/devtrack-api/agents/cursor.yaml +2 -0
  5. package/.sdd/skills/curated/devtrack-api/agents/gemini.yaml +2 -0
  6. package/.sdd/skills/curated/devtrack-api/agents/kimi.yaml +2 -0
  7. package/.sdd/skills/curated/devtrack-api/agents/openai.yaml +3 -3
  8. package/.sdd/skills/curated/devtrack-api/agents/opencode.yaml +2 -0
  9. package/.sdd/skills/curated/devtrack-api/references/application-presentation.md +59 -3
  10. package/.sdd/skills/curated/devtrack-api/references/consumer-sync-policy.md +15 -3
  11. package/.sdd/skills/curated/devtrack-api/references/contract-pack.yaml +1898 -2
  12. package/.sdd/skills/curated/devtrack-api/references/domain-modeling.md +3 -1
  13. package/.sdd/skills/curated/devtrack-api/references/field-validation-protocol.md +40 -0
  14. package/.sdd/skills/curated/devtrack-api/references/foundation-layout.md +20 -2
  15. package/.sdd/skills/curated/devtrack-api/references/generated-artifact-invalidation.md +97 -0
  16. package/.sdd/skills/curated/devtrack-api/references/implementation-checklist.md +30 -1
  17. package/.sdd/skills/curated/devtrack-api/references/portable-agent-contract.md +4 -3
  18. package/.sdd/skills/curated/devtrack-api/references/testing-validation.md +22 -1
  19. package/.sdd/skills/curated/devtrack-api/references/typeorm-infrastructure.md +9 -5
  20. package/README.md +122 -25
  21. package/dist/cli/program.js +180 -11
  22. package/dist/commands/config.js +27 -1
  23. package/dist/commands/sdd/execution.js +64 -2
  24. package/dist/commands/sdd.js +119 -4
  25. package/dist/core/cli/command-matrix.d.ts +18 -0
  26. package/dist/core/cli/command-matrix.js +148 -0
  27. package/dist/core/cli-command-quality.js +2 -0
  28. package/dist/core/config-schema.d.ts +14 -1
  29. package/dist/core/config-schema.js +32 -1
  30. package/dist/core/config.d.ts +1 -0
  31. package/dist/core/config.js +11 -0
  32. package/dist/core/global-config.d.ts +13 -0
  33. package/dist/core/init.d.ts +2 -2
  34. package/dist/core/init.js +13 -14
  35. package/dist/core/sdd/agent-binding.d.ts +9 -9
  36. package/dist/core/sdd/agent-runtime-contract.d.ts +4 -4
  37. package/dist/core/sdd/allocator-recovery.d.ts +14 -0
  38. package/dist/core/sdd/allocator-recovery.js +30 -0
  39. package/dist/core/sdd/allocator-security.d.ts +18 -0
  40. package/dist/core/sdd/allocator-security.js +36 -0
  41. package/dist/core/sdd/api-foundation-baseline.d.ts +111 -0
  42. package/dist/core/sdd/api-foundation-baseline.js +151 -0
  43. package/dist/core/sdd/api-foundation-parity.d.ts +114 -0
  44. package/dist/core/sdd/api-foundation-parity.js +131 -0
  45. package/dist/core/sdd/api-profile-catalog.d.ts +36 -0
  46. package/dist/core/sdd/api-profile-catalog.js +132 -0
  47. package/dist/core/sdd/api-profile-dry-run-projection.d.ts +93 -0
  48. package/dist/core/sdd/api-profile-dry-run-projection.js +370 -0
  49. package/dist/core/sdd/api-profile-recipes.d.ts +82 -0
  50. package/dist/core/sdd/api-profile-recipes.js +484 -0
  51. package/dist/core/sdd/artifact-id-allocator.d.ts +368 -0
  52. package/dist/core/sdd/artifact-id-allocator.js +510 -0
  53. package/dist/core/sdd/check.d.ts +50 -1
  54. package/dist/core/sdd/check.js +286 -9
  55. package/dist/core/sdd/deepagent-contracts.d.ts +4 -4
  56. package/dist/core/sdd/deepagents/reversa-subagents.d.ts +3 -3
  57. package/dist/core/sdd/default-bootstrap-files.d.ts +1 -1
  58. package/dist/core/sdd/default-bootstrap-files.js +0 -2
  59. package/dist/core/sdd/default-skills.js +7 -5
  60. package/dist/core/sdd/devtrack-api-appliance.d.ts +34 -0
  61. package/dist/core/sdd/devtrack-api-appliance.js +138 -34
  62. package/dist/core/sdd/devtrack-api-architecture.d.ts +16 -0
  63. package/dist/core/sdd/devtrack-api-architecture.js +86 -0
  64. package/dist/core/sdd/docs-sync.js +3 -3
  65. package/dist/core/sdd/enterprise-mutating-command-gate.d.ts +27 -0
  66. package/dist/core/sdd/enterprise-mutating-command-gate.js +104 -0
  67. package/dist/core/sdd/enterprise-provenance-gates.d.ts +20 -0
  68. package/dist/core/sdd/enterprise-provenance-gates.js +63 -0
  69. package/dist/core/sdd/enterprise-provisioning-policy.d.ts +26 -0
  70. package/dist/core/sdd/enterprise-provisioning-policy.js +104 -0
  71. package/dist/core/sdd/governance-schemas.d.ts +2 -2
  72. package/dist/core/sdd/governance-schemas.js +11 -2
  73. package/dist/core/sdd/json-schema.js +4 -0
  74. package/dist/core/sdd/legacy-operations.js +93 -4
  75. package/dist/core/sdd/package-security-gates.js +2 -0
  76. package/dist/core/sdd/package-structure-gate.d.ts +85 -3
  77. package/dist/core/sdd/package-structure-gate.js +386 -8
  78. package/dist/core/sdd/parallel-feat-automation.d.ts +6 -6
  79. package/dist/core/sdd/plugin-policy.js +6 -1
  80. package/dist/core/sdd/plugin-registry.d.ts +3 -3
  81. package/dist/core/sdd/quality-validation.d.ts +5 -5
  82. package/dist/core/sdd/release-readiness.d.ts +49 -0
  83. package/dist/core/sdd/release-readiness.js +303 -8
  84. package/dist/core/sdd/reversa-architecture-extractor.d.ts +13 -0
  85. package/dist/core/sdd/reversa-architecture-extractor.js +89 -0
  86. package/dist/core/sdd/reversa-artifact-writer.d.ts +18 -0
  87. package/dist/core/sdd/reversa-artifact-writer.js +40 -0
  88. package/dist/core/sdd/reversa-command-policy.d.ts +136 -0
  89. package/dist/core/sdd/reversa-command-policy.js +361 -0
  90. package/dist/core/sdd/reversa-data-extractor.d.ts +11 -0
  91. package/dist/core/sdd/reversa-data-extractor.js +73 -0
  92. package/dist/core/sdd/reversa-equivalence.d.ts +20 -0
  93. package/dist/core/sdd/reversa-equivalence.js +34 -0
  94. package/dist/core/sdd/reversa-evidence.d.ts +298 -0
  95. package/dist/core/sdd/reversa-evidence.js +118 -0
  96. package/dist/core/sdd/reversa-reconstruction.d.ts +29 -0
  97. package/dist/core/sdd/reversa-reconstruction.js +32 -0
  98. package/dist/core/sdd/reversa-rules-extractor.d.ts +12 -0
  99. package/dist/core/sdd/reversa-rules-extractor.js +86 -0
  100. package/dist/core/sdd/reversa-source-safety.d.ts +19 -0
  101. package/dist/core/sdd/reversa-source-safety.js +105 -0
  102. package/dist/core/sdd/reversa-surface-scout.d.ts +13 -0
  103. package/dist/core/sdd/reversa-surface-scout.js +85 -0
  104. package/dist/core/sdd/reversa-ux-mapper.d.ts +11 -0
  105. package/dist/core/sdd/reversa-ux-mapper.js +73 -0
  106. package/dist/core/sdd/sdk-agent-plugin-quality-gates.d.ts +1 -1
  107. package/dist/core/sdd/services/archive-quality-coherence.service.d.ts +17 -0
  108. package/dist/core/sdd/services/archive-quality-coherence.service.js +141 -0
  109. package/dist/core/sdd/services/decide.service.js +1 -1
  110. package/dist/core/sdd/services/finalize.service.d.ts +2 -0
  111. package/dist/core/sdd/services/finalize.service.js +48 -2
  112. package/dist/core/sdd/services/historical-quality-regression.service.d.ts +35 -0
  113. package/dist/core/sdd/services/historical-quality-regression.service.js +228 -0
  114. package/dist/core/sdd/services/ingest-deposito.service.js +1 -1
  115. package/dist/core/sdd/services/planning-execution-coherence.service.d.ts +45 -0
  116. package/dist/core/sdd/services/planning-execution-coherence.service.js +225 -0
  117. package/dist/core/sdd/state.js +15 -5
  118. package/dist/core/sdd/types.d.ts +3 -3
  119. package/dist/core/sdd/workspace-schemas.d.ts +45 -4
  120. package/dist/core/sdd/workspace-schemas.js +27 -6
  121. package/dist/core/shared/skill-generation.d.ts +2 -0
  122. package/dist/core/shared/skill-generation.js +19 -2
  123. package/dist/core/shared/tool-detection.d.ts +19 -0
  124. package/dist/core/shared/tool-detection.js +89 -0
  125. package/package.json +6 -5
  126. package/schemas/sdd/5-quality.schema.json +43 -0
  127. package/schemas/sdd/reversa-evidence-bundle.schema.json +466 -0
  128. package/schemas/sdd/workspace-catalog.schema.json +511 -0
@@ -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
@@ -91,10 +91,10 @@ export declare const debateFrontmatterSchema: z.ZodObject<{
91
91
  mediator: z.ZodObject<{
92
92
  choice: z.ZodString;
93
93
  rationale: z.ZodString;
94
- accepted_risks: z.ZodDefault<z.ZodArray<z.ZodObject<{
94
+ accepted_risks: z.ZodDefault<z.ZodArray<z.ZodPreprocess<z.ZodObject<{
95
95
  risk: z.ZodString;
96
96
  mitigation: z.ZodString;
97
- }, z.core.$strict>>>;
97
+ }, z.core.$strict>>>>;
98
98
  reversal_conditions: z.ZodDefault<z.ZodArray<z.ZodString>>;
99
99
  }, z.core.$strict>;
100
100
  output: z.ZodEnum<{
@@ -59,12 +59,21 @@ const debateScoringSchema = z
59
59
  scores: z.record(z.string().regex(/^[A-Z]$/), z.number()),
60
60
  })
61
61
  .strict();
62
- const debateAcceptedRiskSchema = z
62
+ const DEFAULT_ACCEPTED_RISK_MITIGATION = 'Mitigation not provided by the source artifact; preserve this risk and require explicit mitigation before finalize.';
63
+ const debateAcceptedRiskSchema = z.preprocess((value) => {
64
+ if (typeof value !== 'string')
65
+ return value;
66
+ const risk = value.trim();
67
+ return {
68
+ risk,
69
+ mitigation: DEFAULT_ACCEPTED_RISK_MITIGATION,
70
+ };
71
+ }, z
63
72
  .object({
64
73
  risk: z.string().min(1),
65
74
  mitigation: z.string().min(1),
66
75
  })
67
- .strict();
76
+ .strict());
68
77
  const debateDecisionSchema = z
69
78
  .object({
70
79
  question: z.string().min(1),
@@ -13,6 +13,7 @@ import { buildAgentRuntimeJsonSchemas } from './agent-runtime-contract.js';
13
13
  import { parallelFeatAutomationPlanSchema, parallelFeatAutomationRequestSchema, parallelFeatSchedulerRequestSchema, parallelFeatSchedulerResultSchema, } from './parallel-feat-automation.js';
14
14
  import { backlogProjectionPlanSchema, backlogProviderContractSchema, } from './backlog-provider-contract.js';
15
15
  import { qualityArchitectureSchema, qualityEvidenceBundleSchema, qualityRunSchema, qualityScenarioSchema, } from './quality-validation.js';
16
+ import { reversaEvidenceBundleSchema } from './reversa-evidence.js';
16
17
  import { buildSdkAgentPluginQualityGateJsonSchemas } from './sdk-agent-plugin-quality-gates.js';
17
18
  import { deepagentDecisionEvidenceSchema, deepagentEnvContractSchema, deepagentQualityEvidenceSchema, deepagentRunEvidenceSchema, deepagentRunPlanSchema, deepagentRunRequestSchema, deepagentSubagentEvidenceSchema, deepagentToolCallEvidenceSchema, } from './deepagent-contracts.js';
18
19
  import { adrFrontmatterSchema, debateFrontmatterSchema, discardedFrontmatterSchema, epicFrontmatterSchema, insightFrontmatterSchema, } from './governance-schemas.js';
@@ -137,6 +138,9 @@ export function buildWorkspaceJsonSchemaCatalog() {
137
138
  'quality-evidence-bundle.yaml': normalizeJsonSchemaDocument(toJSONSchema(qualityEvidenceBundleSchema), 'CodeSDD Quality Evidence Bundle', 'Machine-readable evidence bundle contract tying scenario, run, artifacts, checksums, findings, and exceptions together.'),
138
139
  ...buildSdkAgentPluginQualityGateJsonSchemas(),
139
140
  },
141
+ reversa_contracts: {
142
+ 'reversa-evidence-bundle.yaml': normalizeJsonSchemaDocument(toJSONSchema(reversaEvidenceBundleSchema), 'CodeSDD Reversa Evidence Bundle', 'Machine-readable evidence bundle contract for Reversa intake, extraction, generation, migration, reconstruction, and equivalence phases.'),
143
+ },
140
144
  deepagent_execution: {
141
145
  'deepagent-run-request.yaml': normalizeJsonSchemaDocument(toJSONSchema(deepagentRunRequestSchema), 'CodeSDD DeepAgent Run Request', 'Machine-readable request contract for governed DeepAgents execution with scoped tools, write policy, env contract, and expected evidence.'),
142
146
  'deepagent-run-plan.yaml': normalizeJsonSchemaDocument(toJSONSchema(deepagentRunPlanSchema), 'CodeSDD DeepAgent Run Plan', 'Machine-readable tactical plan contract for DeepAgents runs with subagent routing, approvals, validation matrix, and residual risks.'),
@@ -136,16 +136,19 @@ Decide ____ instead of ____ to solve ____.
136
136
 
137
137
  ## 3) Options Considered (Minimum 2)
138
138
  ### Option A
139
+ - Status (selected/discarded):
139
140
  - Proposal:
140
141
  - Pros:
141
142
  - Cons:
142
143
 
143
144
  ### Option B
145
+ - Status (selected/discarded):
144
146
  - Proposal:
145
147
  - Pros:
146
148
  - Cons:
147
149
 
148
150
  ### Option C (Optional)
151
+ - Status (selected/discarded):
149
152
  - Proposal:
150
153
  - Pros:
151
154
  - Cons:
@@ -194,7 +197,15 @@ Decide ____ instead of ____ to solve ____.
194
197
  - APPROVED -> EPIC-####
195
198
  - DISCARDED -> Record in discarded
196
199
 
197
- ## Metadata
200
+ ## 10) Planning Completeness Gate (Required before promotion)
201
+ - Measurable acceptance:
202
+ - Non-scope:
203
+ - Definition of Done:
204
+ - Validation commands:
205
+ -
206
+ - Residual risk:
207
+
208
+ ## 11) Metadata
198
209
  - Source insight: ${insight.id}
199
210
  - Insight title: ${insight.title}
200
211
  - Created at: ${insight.created_at || now}
@@ -745,19 +756,92 @@ export async function findDebateFile(paths, debateId) {
745
756
  return null;
746
757
  return path.join(debateDir, found.name);
747
758
  }
759
+ const GENERIC_DECISION_QUESTION_PATTERNS = [
760
+ /^decide\s+____\s+instead\s+of\s+____\s+to\s+solve\s+____\.?$/i,
761
+ /^decidir\s+____\s+em\s+vez\s+de\s+____\s+para\s+resolver\s+____\.?$/i,
762
+ /which option should we choose\??$/i,
763
+ /qual opcao devemos escolher\??$/i,
764
+ /decide between option [a-z] and option [a-z]\.?$/i,
765
+ /decidir entre opcao [a-z] e opcao [a-z]\.?$/i,
766
+ ];
767
+ function isPlaceholderLike(value) {
768
+ const normalized = value.trim().toLowerCase();
769
+ if (!normalized)
770
+ return true;
771
+ const placeholderTokens = ['____', '(fill in', '(preencher', 'todo', 'tbd', 'n/a'];
772
+ return placeholderTokens.some((token) => normalized.includes(token));
773
+ }
774
+ function isGenericDecisionQuestion(question) {
775
+ const normalized = question.trim().replace(/\s+/g, ' ').toLowerCase();
776
+ if (normalized.length < 30)
777
+ return true;
778
+ return GENERIC_DECISION_QUESTION_PATTERNS.some((pattern) => pattern.test(normalized));
779
+ }
780
+ function extractNamedListValue(content, labels) {
781
+ const escaped = labels.map((label) => label.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')).join('|');
782
+ const match = content.match(new RegExp(`-\\s*(?:${escaped}):\\s*(.+)`, 'i'));
783
+ if (!match)
784
+ return '';
785
+ return match[1].trim();
786
+ }
787
+ function hasValidationCommand(content) {
788
+ const sectionMatch = content.match(/-\s*Validation commands:\s*([\s\S]*?)(?=\n-\s*Residual risk:|\n##\s+\d+\)|$)/i);
789
+ if (!sectionMatch)
790
+ return false;
791
+ const lines = sectionMatch[1]
792
+ .split(/\r?\n/)
793
+ .map((line) => line.trim())
794
+ .filter((line) => line.startsWith('-'))
795
+ .map((line) => line.replace(/^-\s*/, '').replace(/`/g, '').trim())
796
+ .filter((line) => line.length > 0);
797
+ if (lines.length === 0)
798
+ return false;
799
+ return lines.some((line) => line.includes('pnpm') || line.includes('npm') || line.includes('vitest'));
800
+ }
801
+ function collectPlanningGateMissing(content, selectedOption, optionIds) {
802
+ const missing = [];
803
+ const nonSelectedOptionIds = optionIds.filter((optionId) => optionId !== selectedOption);
804
+ if (nonSelectedOptionIds.length === 0) {
805
+ missing.push('Provide at least one discarded alternative option different from mediator choice');
806
+ }
807
+ const measurableAcceptance = extractNamedListValue(content, ['Measurable acceptance']);
808
+ if (isPlaceholderLike(measurableAcceptance) || !/\d|%|<=|>=|\bwithin\b|\bunder\b|\bmax\b/i.test(measurableAcceptance)) {
809
+ missing.push('Define measurable acceptance criteria in the planning completeness gate');
810
+ }
811
+ const nonScope = extractNamedListValue(content, ['Non-scope', 'Nao-escopo']);
812
+ if (isPlaceholderLike(nonScope)) {
813
+ missing.push('Document non-scope in the planning completeness gate');
814
+ }
815
+ const definitionOfDone = extractNamedListValue(content, ['Definition of Done', 'DoD']);
816
+ if (isPlaceholderLike(definitionOfDone)) {
817
+ missing.push('Document Definition of Done (DoD) in the planning completeness gate');
818
+ }
819
+ if (!hasValidationCommand(content)) {
820
+ missing.push('Document executable validation commands in the planning completeness gate');
821
+ }
822
+ const residualRisk = extractNamedListValue(content, ['Residual risk', 'Risco residual']);
823
+ if (isPlaceholderLike(residualRisk)) {
824
+ missing.push('Document residual risk in the planning completeness gate');
825
+ }
826
+ return missing;
827
+ }
748
828
  export function validateDebateDocument(content) {
749
829
  try {
750
830
  const parsed = parseGovernanceFile('inline-content', content, debateFrontmatterSchema);
751
831
  if (parsed.hasFrontmatter && parsed.frontmatter) {
752
832
  const missing = [];
753
833
  const question = parsed.frontmatter.decision.question.trim().toLowerCase();
754
- if (!question || question.includes('____')) {
834
+ if (isGenericDecisionQuestion(question) || question.includes('____')) {
755
835
  missing.push('Fill the decision question with real context');
756
836
  }
837
+ if (parsed.frontmatter.decision.options.length < 2) {
838
+ missing.push('Provide at least two options in the decision matrix');
839
+ }
757
840
  const rationale = parsed.frontmatter.decision.mediator.rationale.trim().toLowerCase();
758
841
  if (!rationale || rationale.includes('____') || rationale.includes('(fill in') || rationale.includes('(preencher')) {
759
842
  missing.push('Inform the mediator decision rationale');
760
843
  }
844
+ missing.push(...collectPlanningGateMissing(parsed.body, parsed.frontmatter.decision.mediator.choice.trim().toUpperCase(), parsed.frontmatter.decision.options.map((option) => option.id.trim().toUpperCase())));
761
845
  if (/\- Unit coverage:\s*$/m.test(parsed.body)) {
762
846
  missing.push('Inform required unit coverage evidence in the quality contract');
763
847
  }
@@ -770,7 +854,7 @@ export function validateDebateDocument(content) {
770
854
  if (/\- Exceptions:\s*\n\s+- None, or formal exception/m.test(parsed.body)) {
771
855
  missing.push('Confirm there is no quality exception or document the formal exception');
772
856
  }
773
- return missing;
857
+ return Array.from(new Set(missing));
774
858
  }
775
859
  }
776
860
  catch (error) {
@@ -782,6 +866,11 @@ export function validateDebateDocument(content) {
782
866
  content.includes('Decide ____ instead of ____ to solve ____.')) {
783
867
  missing.push('Fill the decision question with real context');
784
868
  }
869
+ const selectedChoice = content.match(/-\s+(?:Escolha|Choice)(?:\s+\(A\/B\/C\))?:\s*(?:op(?:c|ç)[aã]o\s*)?([ABC])\b/i)?.[1] ||
870
+ content.match(/-\s+Op(?:c|ç)[aã]o\s+escolhida:\s*([ABC])\b/i)?.[1] ||
871
+ 'A';
872
+ const optionIds = Array.from(content.matchAll(/###\s+Option\s+([A-Z])/gi)).map((match) => match[1]);
873
+ missing.push(...collectPlanningGateMissing(content, selectedChoice.toUpperCase(), optionIds));
785
874
  if (/\- (?:Escolha|Choice) \(A\/B\/C\):\s*$/m.test(content)) {
786
875
  missing.push('Inform the mediator choice in "Choice (A/B/C)"');
787
876
  }
@@ -800,7 +889,7 @@ export function validateDebateDocument(content) {
800
889
  if (/\- Exceptions:\s*\n\s+- None, or formal exception/m.test(content)) {
801
890
  missing.push('Confirm there is no quality exception or document the formal exception');
802
891
  }
803
- return missing;
892
+ return Array.from(new Set(missing));
804
893
  }
805
894
  export function pickTopSkills(catalogSkills, ids, max = 3) {
806
895
  if (!ids || ids.length === 0)
@@ -23,9 +23,11 @@ const SECRET_SIGNATURES = [
23
23
  ];
24
24
  const SECRET_SCAN_IGNORE = [
25
25
  'node_modules/**',
26
+ '**/node_modules/**',
26
27
  'dist/**',
27
28
  'coverage/**',
28
29
  '.git/**',
30
+ '.temp/**',
29
31
  '.sdd/state/**',
30
32
  '.sdd/archived/**',
31
33
  '.sdd/active/**',
@@ -1,7 +1,7 @@
1
1
  import { z } from 'zod';
2
2
  export declare const DerivationProfileSchema: z.ZodEnum<{
3
- prototype: "prototype";
4
3
  "foundation-compatible": "foundation-compatible";
4
+ prototype: "prototype";
5
5
  "enterprise-strict": "enterprise-strict";
6
6
  }>;
7
7
  export declare const PreviewGateStatusSchema: z.ZodEnum<{
@@ -14,20 +14,92 @@ export declare const PackageStructureNodeKindSchema: z.ZodEnum<{
14
14
  file: "file";
15
15
  dir: "dir";
16
16
  }>;
17
+ export declare const PreviewContextPatternSchema: z.ZodEnum<{
18
+ "bo-pattern": "bo-pattern";
19
+ "entity-pattern": "entity-pattern";
20
+ "application-only": "application-only";
21
+ }>;
22
+ export declare const PreviewDiagnosticSeveritySchema: z.ZodEnum<{
23
+ block: "block";
24
+ warn: "warn";
25
+ }>;
17
26
  export declare const PackageStructureNodeSchema: z.ZodSchema<PackageStructureNode>;
27
+ export declare const ApplicationOnlyContextSchema: z.ZodObject<{
28
+ context: z.ZodString;
29
+ path: z.ZodString;
30
+ reason: z.ZodString;
31
+ adr_required: z.ZodDefault<z.ZodBoolean>;
32
+ contract_rule_ref: z.ZodLiteral<"DTAPI-P1-APPONLY-001">;
33
+ }, z.core.$strip>;
34
+ export declare const PreviewContextClassificationSchema: z.ZodObject<{
35
+ context: z.ZodString;
36
+ pattern: z.ZodEnum<{
37
+ "bo-pattern": "bo-pattern";
38
+ "entity-pattern": "entity-pattern";
39
+ "application-only": "application-only";
40
+ }>;
41
+ source_paths: z.ZodDefault<z.ZodArray<z.ZodString>>;
42
+ decision_refs: z.ZodDefault<z.ZodArray<z.ZodString>>;
43
+ }, z.core.$strip>;
44
+ export declare const PreviewDiagnosticSchema: z.ZodObject<{
45
+ code: z.ZodString;
46
+ severity: z.ZodEnum<{
47
+ block: "block";
48
+ warn: "warn";
49
+ }>;
50
+ message: z.ZodString;
51
+ remediation: z.ZodString;
52
+ path: z.ZodOptional<z.ZodString>;
53
+ }, z.core.$strip>;
18
54
  export declare const PackageStructurePreviewSchema: z.ZodObject<{
19
55
  schema_version: z.ZodLiteral<1>;
20
56
  generated_at: z.ZodString;
21
57
  project_name: z.ZodString;
22
58
  profile: z.ZodEnum<{
23
- prototype: "prototype";
24
59
  "foundation-compatible": "foundation-compatible";
60
+ prototype: "prototype";
25
61
  "enterprise-strict": "enterprise-strict";
26
62
  }>;
63
+ source: z.ZodDefault<z.ZodEnum<{
64
+ template: "template";
65
+ "artifact-map": "artifact-map";
66
+ }>>;
27
67
  contexts: z.ZodArray<z.ZodString>;
28
68
  subsystems: z.ZodArray<z.ZodString>;
29
69
  transports: z.ZodArray<z.ZodString>;
30
70
  tree: z.ZodType<PackageStructureNode, unknown, z.core.$ZodTypeInternals<PackageStructureNode, unknown>>;
71
+ foundation_tests_projection: z.ZodOptional<z.ZodType<PackageStructureNode, unknown, z.core.$ZodTypeInternals<PackageStructureNode, unknown>>>;
72
+ runtime_scripts_projection: z.ZodOptional<z.ZodType<PackageStructureNode, unknown, z.core.$ZodTypeInternals<PackageStructureNode, unknown>>>;
73
+ application_only_contexts: z.ZodDefault<z.ZodArray<z.ZodObject<{
74
+ context: z.ZodString;
75
+ path: z.ZodString;
76
+ reason: z.ZodString;
77
+ adr_required: z.ZodDefault<z.ZodBoolean>;
78
+ contract_rule_ref: z.ZodLiteral<"DTAPI-P1-APPONLY-001">;
79
+ }, z.core.$strip>>>;
80
+ context_classification: z.ZodDefault<z.ZodArray<z.ZodObject<{
81
+ context: z.ZodString;
82
+ pattern: z.ZodEnum<{
83
+ "bo-pattern": "bo-pattern";
84
+ "entity-pattern": "entity-pattern";
85
+ "application-only": "application-only";
86
+ }>;
87
+ source_paths: z.ZodDefault<z.ZodArray<z.ZodString>>;
88
+ decision_refs: z.ZodDefault<z.ZodArray<z.ZodString>>;
89
+ }, z.core.$strip>>>;
90
+ contract_pack_refs: z.ZodDefault<z.ZodArray<z.ZodString>>;
91
+ diagnostics: z.ZodDefault<z.ZodArray<z.ZodObject<{
92
+ code: z.ZodString;
93
+ severity: z.ZodEnum<{
94
+ block: "block";
95
+ warn: "warn";
96
+ }>;
97
+ message: z.ZodString;
98
+ remediation: z.ZodString;
99
+ path: z.ZodOptional<z.ZodString>;
100
+ }, z.core.$strip>>>;
101
+ artifact_languages: z.ZodDefault<z.ZodArray<z.ZodString>>;
102
+ material_signature: z.ZodString;
31
103
  }, z.core.$strip>;
32
104
  export declare const HumanValidationGateSchema: z.ZodObject<{
33
105
  gate_id: z.ZodString;
@@ -43,6 +115,9 @@ export declare const HumanValidationGateSchema: z.ZodObject<{
43
115
  approved_by: z.ZodOptional<z.ZodString>;
44
116
  correction_notes: z.ZodOptional<z.ZodString>;
45
117
  exception_refs: z.ZodDefault<z.ZodArray<z.ZodString>>;
118
+ contract_pack_refs: z.ZodDefault<z.ZodArray<z.ZodString>>;
119
+ material_signature: z.ZodString;
120
+ serialized_at: z.ZodString;
46
121
  }, z.core.$strip>;
47
122
  export interface HumanValidationGateData {
48
123
  selected_profile: z.infer<typeof DerivationProfileSchema>;
@@ -62,16 +137,23 @@ export interface DebGateInput {
62
137
  subsystems?: string[];
63
138
  transports?: string[];
64
139
  generated_at?: string;
140
+ artifact_map?: unknown;
141
+ previous_human_validation_gate?: z.infer<typeof HumanValidationGateSchema>;
142
+ contract_pack_refs?: string[];
65
143
  }
66
144
  export declare function generatePackageStructurePreview(input: DebGateInput): z.infer<typeof PackageStructurePreviewSchema>;
67
145
  export declare function formatPreviewAsTree(node: z.infer<typeof PackageStructureNodeSchema>, prefix?: string): string;
68
- export declare function buildHumanValidationGate(preview: z.infer<typeof PackageStructurePreviewSchema>): z.infer<typeof HumanValidationGateSchema>;
146
+ export declare function buildHumanValidationGate(preview: z.infer<typeof PackageStructurePreviewSchema>, options?: {
147
+ previous_gate?: z.infer<typeof HumanValidationGateSchema>;
148
+ exception_refs?: string[];
149
+ }): z.infer<typeof HumanValidationGateSchema>;
69
150
  export declare function generateDevtrackApiDebGate(input: DebGateInput): HumanValidationGateData;
70
151
  export declare function isGatePending(gate: z.infer<typeof HumanValidationGateSchema>): boolean;
71
152
  export declare function isGateApproved(gate: z.infer<typeof HumanValidationGateSchema>): boolean;
72
153
  export type DerivationProfile = z.infer<typeof DerivationProfileSchema>;
73
154
  export type PreviewGateStatus = z.infer<typeof PreviewGateStatusSchema>;
74
155
  export type PackageStructureNodeKind = z.infer<typeof PackageStructureNodeKindSchema>;
156
+ export type PreviewContextPattern = z.infer<typeof PreviewContextPatternSchema>;
75
157
  export type PackageStructureNode = {
76
158
  name: string;
77
159
  kind: PackageStructureNodeKind;