@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
@@ -1,27 +1,166 @@
1
1
  import chalk from 'chalk';
2
- import { loadProjectSddConfig, resolveSddPaths } from '../../core/sdd/state.js';
2
+ import { loadProjectSddConfig, loadStateSnapshot, resolveSddPaths } from '../../core/sdd/state.js';
3
3
  import { createSddStores } from '../../core/sdd/store/sdd-stores.js';
4
4
  import { StartService } from '../../core/sdd/services/start.service.js';
5
5
  import { FrontendImpactService } from '../../core/sdd/services/frontend-impact.service.js';
6
6
  import { FinalizeService } from '../../core/sdd/services/finalize.service.js';
7
- import { ContextService } from '../../core/sdd/services/context.service.js';
7
+ import { ContextService, CONTEXT_PACK_BUDGET_MODES } from '../../core/sdd/services/context.service.js';
8
8
  import { OnboardService } from '../../core/sdd/services/onboard.service.js';
9
9
  import { ApproveService } from '../../core/sdd/services/approve.service.js';
10
10
  import { NextService } from '../../core/sdd/services/next.service.js';
11
11
  import { AuditService } from '../../core/sdd/services/audit.service.js';
12
12
  import { McpRuntimeService } from '../../core/sdd/services/mcp-runtime.service.js';
13
- import { DeepAgentsRunService } from '../../core/sdd/services/agent-run.service.js';
13
+ import { DeepAgentsRunService, } from '../../core/sdd/services/agent-run.service.js';
14
+ import { evaluateReleaseReadiness, formatReleaseReadinessReport } from '../../core/sdd/release-readiness.js';
14
15
  import { ensureMandatorySddMigration, parseCsvOption, parseFlowModeOption, resolveRoot } from './shared.js';
15
- function parseJsonObjectOption(value) {
16
+ const PREFLIGHT_MUTATING_PLUGIN_FLOW = [
17
+ 'plugin-inspect',
18
+ 'plugin-plan',
19
+ 'plugin-dry-run',
20
+ 'policy-evaluation',
21
+ 'artifact-manifest',
22
+ 'evidence-manifest',
23
+ 'validation-manifest',
24
+ 'rollback-manifest',
25
+ ];
26
+ function parseJsonObjectOption(value, optionName = '--input') {
16
27
  if (!value)
17
28
  return {};
18
29
  const parsed = JSON.parse(value);
19
30
  if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {
20
- throw new Error('--input must be a JSON object.');
31
+ throw new Error(`${optionName} must be a JSON object.`);
21
32
  }
22
33
  return parsed;
23
34
  }
35
+ function parseGovernedOverrideOption(value) {
36
+ if (!value)
37
+ return undefined;
38
+ return parseJsonObjectOption(value, '--governed-override');
39
+ }
40
+ function buildChangeSafetyFromOptions(options) {
41
+ return {
42
+ explicit_modification_intent: {
43
+ operation: options.intentOperation,
44
+ },
45
+ context_lock: {
46
+ allowed_paths: parseCsvOption(options.allowedPaths ?? options.writeScope),
47
+ forbidden_paths: parseCsvOption(options.forbiddenPaths),
48
+ protected_core: parseCsvOption(options.protectedCore),
49
+ },
50
+ change_budget: {
51
+ max_files_changed: parseNonNegativeNumberOption(options.maxFilesChanged, '--max-files-changed'),
52
+ max_new_files: parseNonNegativeNumberOption(options.maxNewFiles, '--max-new-files'),
53
+ max_deleted_files: parseNonNegativeNumberOption(options.maxDeletedFiles, '--max-deleted-files'),
54
+ },
55
+ governed_override: parseGovernedOverrideOption(options.governedOverride),
56
+ };
57
+ }
58
+ function resolvePreflightMode(lifecycle) {
59
+ return lifecycle === 'finalize' ? 'apply-approved' : 'apply-sandbox';
60
+ }
61
+ function buildPreflightRequest(options) {
62
+ const mode = resolvePreflightMode(options.lifecycle ?? 'custom');
63
+ return {
64
+ provider: 'deepagents',
65
+ mode,
66
+ objective: options.objective,
67
+ plugin_execution_path: 'broker',
68
+ plugin_flow: [...PREFLIGHT_MUTATING_PLUGIN_FLOW, mode],
69
+ operations: ['read', 'write', 'execute', 'plugin-apply'],
70
+ write_scope: parseCsvOption(options.writeScope),
71
+ planned_writes: parseCsvOption(options.plannedWrites),
72
+ change_safety: buildChangeSafetyFromOptions(options),
73
+ approval_grants: ['all'],
74
+ };
75
+ }
76
+ function resolveContextBudgetModeOption(options) {
77
+ const requested = options?.compact
78
+ ? 'compact'
79
+ : options?.full
80
+ ? 'full'
81
+ : options?.budget ?? 'standard';
82
+ if (!CONTEXT_PACK_BUDGET_MODES.includes(requested)) {
83
+ throw new Error(`Modo de budget invalido: ${requested}. Use compact, standard ou full.`);
84
+ }
85
+ return requested;
86
+ }
87
+ function parsePositiveNumberOption(value, name) {
88
+ if (!value)
89
+ return undefined;
90
+ const parsed = Number(value);
91
+ if (!Number.isFinite(parsed) || parsed <= 0) {
92
+ throw new Error(`Valor invalido em ${name}. Use um numero positivo.`);
93
+ }
94
+ return parsed;
95
+ }
96
+ function parseNonNegativeNumberOption(value, name) {
97
+ if (!value)
98
+ return undefined;
99
+ const parsed = Number(value);
100
+ if (!Number.isFinite(parsed) || parsed < 0) {
101
+ throw new Error(`Valor invalido em ${name}. Use um numero nao negativo.`);
102
+ }
103
+ return parsed;
104
+ }
105
+ async function buildPlanStatus(root, stores, options) {
106
+ const config = await loadProjectSddConfig(root);
107
+ const paths = resolveSddPaths(root, config);
108
+ const snapshot = await loadStateSnapshot(paths, config);
109
+ const next = await new NextService(stores).execute(root, {
110
+ rank: options?.rank,
111
+ limit: parsePositiveNumberOption(options?.limit, '--limit'),
112
+ maxAgents: parsePositiveNumberOption(options?.maxAgents, '--max-agents'),
113
+ });
114
+ const active = snapshot.backlog.items
115
+ .filter((item) => item.status === 'IN_PROGRESS')
116
+ .map((item) => ({
117
+ id: item.id,
118
+ title: item.title,
119
+ current_stage: item.current_stage,
120
+ frontend_impact_status: item.frontend_impact_status,
121
+ next_action: `codesdd sdd finalize --ref ${item.id}`,
122
+ }))
123
+ .sort((a, b) => a.id.localeCompare(b.id));
124
+ const counts = snapshot.backlog.items.reduce((acc, item) => {
125
+ acc.total += 1;
126
+ acc.by_status[item.status] = (acc.by_status[item.status] ?? 0) + 1;
127
+ return acc;
128
+ }, { total: 0, by_status: {} });
129
+ return {
130
+ schema_version: 1,
131
+ generated_at: new Date().toISOString(),
132
+ active,
133
+ next,
134
+ counts,
135
+ recommended_action: active.length > 0
136
+ ? `Finalize active feature ${active[0].id} before starting more work.`
137
+ : next.ready.length > 0
138
+ ? `Run codesdd sdd execute-next to start ${next.ready[0].id}.`
139
+ : 'No ready feature is available.',
140
+ };
141
+ }
24
142
  export function registerExecutionCommands(sddCmd) {
143
+ sddCmd
144
+ .command('release-readiness')
145
+ .description('Report non-mutating release readiness gates and CI parity commands')
146
+ .alias('prontidao-release')
147
+ .option('--strict', 'Return exit code 1 when readiness is blocked')
148
+ .option('--json', 'JSON output')
149
+ .action(async (options) => {
150
+ const root = resolveRoot();
151
+ await ensureMandatorySddMigration(root);
152
+ const report = await evaluateReleaseReadiness(root);
153
+ if (options?.json) {
154
+ console.log(JSON.stringify(report, null, 2));
155
+ }
156
+ else {
157
+ const color = report.status === 'ready' ? chalk.green : report.status === 'warning' ? chalk.yellow : chalk.red;
158
+ console.log(color(formatReleaseReadinessReport(report)));
159
+ }
160
+ if (options?.strict && report.status === 'blocked') {
161
+ process.exitCode = 1;
162
+ }
163
+ });
25
164
  sddCmd
26
165
  .command('mcp-manifest')
27
166
  .description('Render a provider-agnostic MCP manifest for CodeSDD execution tools')
@@ -132,6 +271,56 @@ export function registerExecutionCommands(sddCmd) {
132
271
  console.log(`Invoked at: ${response.invoked_at}`);
133
272
  console.log(JSON.stringify(response.result, null, 2));
134
273
  });
274
+ sddCmd
275
+ .command('preflight <featureId>')
276
+ .description('Run governed mutation preflight without invoking an agent runtime')
277
+ .option('--objective <text>', 'Natural-language objective for semantic intent checks')
278
+ .option('--intent-operation <operation>', 'Explicit modification intent: add|modify|remove|replace|refactor|optimize')
279
+ .option('--write-scope <list>', 'CSV project-relative write scopes allowed for the runtime')
280
+ .option('--planned-writes <list>', 'CSV project-relative files the runtime plans to write')
281
+ .option('--allowed-paths <list>', 'CSV context-lock allowed project paths')
282
+ .option('--forbidden-paths <list>', 'CSV context-lock forbidden project paths')
283
+ .option('--protected-core <list>', 'CSV protected project paths requiring explicit override')
284
+ .option('--max-files-changed <count>', 'Change budget limit for changed paths')
285
+ .option('--max-new-files <count>', 'Change budget limit for new files')
286
+ .option('--max-deleted-files <count>', 'Change budget limit for deleted files')
287
+ .option('--governed-override <json>', 'JSON governed override contract for protected or replacement changes')
288
+ .option('--lifecycle <name>', 'Lifecycle context: start|finalize|execute-next|custom', 'custom')
289
+ .option('--json', 'JSON output')
290
+ .action(async (featureId, options) => {
291
+ const root = resolveRoot();
292
+ const __config = await loadProjectSddConfig(root);
293
+ const __paths = resolveSddPaths(root, __config);
294
+ const stores = createSddStores(__paths);
295
+ await ensureMandatorySddMigration(root);
296
+ if (options.lifecycle && !['start', 'finalize', 'execute-next', 'custom'].includes(options.lifecycle)) {
297
+ throw new Error('Valor invalido em --lifecycle. Use start, finalize, execute-next ou custom.');
298
+ }
299
+ const result = await new DeepAgentsRunService().execute(featureId, buildPreflightRequest(options), { projectRoot: root, stores, skipRuntime: true });
300
+ if (options.json) {
301
+ console.log(JSON.stringify(result, null, 2));
302
+ if (result.status === 'blocked') {
303
+ process.exitCode = 1;
304
+ }
305
+ return;
306
+ }
307
+ if (result.status === 'allowed') {
308
+ console.log(chalk.green(`CodeSDD preflight: ${result.status}`));
309
+ }
310
+ else {
311
+ console.log(chalk.red(`CodeSDD preflight: ${result.status}`));
312
+ }
313
+ console.log(`Feature: ${result.feature_id}`);
314
+ console.log(`Mode: ${result.mode}`);
315
+ console.log(`Runtime skipped: ${result.evidence.runtime_skipped ? 'yes' : 'no'}`);
316
+ console.log(`Evidence run id: ${result.evidence.run_id}`);
317
+ if (result.reasons.length > 0) {
318
+ console.log(`Reasons: ${result.reasons.join(' | ')}`);
319
+ }
320
+ if (result.status === 'blocked') {
321
+ process.exitCode = 1;
322
+ }
323
+ });
135
324
  const agentCmd = sddCmd
136
325
  .command('agent')
137
326
  .description('Governed agent execution commands for external providers');
@@ -140,11 +329,20 @@ export function registerExecutionCommands(sddCmd) {
140
329
  .description('Run DeepAgents mode policy gate with fail-closed enforcement')
141
330
  .requiredOption('--provider <provider>', 'Execution provider (FEAT-0243 accepts only deepagents)')
142
331
  .option('--mode <mode>', 'Execution mode: read-only|plan|validate|apply-sandbox|apply-approved')
332
+ .option('--objective <text>', 'Natural-language objective for semantic intent checks')
143
333
  .option('--plugin-execution-path <path>', 'Plugin execution path: broker|direct', 'broker')
144
334
  .option('--plugin-flow <list>', 'CSV plugin broker/evidence checkpoints for mutation modes')
145
335
  .option('--operations <list>', 'CSV runtime operations requested by this run: read|write|execute|network|plugin-apply|finalize|dependency-change|process-spawn')
146
336
  .option('--write-scope <list>', 'CSV project-relative write scopes allowed for the runtime')
147
337
  .option('--planned-writes <list>', 'CSV project-relative files the runtime plans to write')
338
+ .option('--intent-operation <operation>', 'Explicit modification intent: add|modify|remove|replace|refactor|optimize')
339
+ .option('--allowed-paths <list>', 'CSV context-lock allowed project paths')
340
+ .option('--forbidden-paths <list>', 'CSV context-lock forbidden project paths')
341
+ .option('--protected-core <list>', 'CSV protected project paths requiring explicit override')
342
+ .option('--max-files-changed <count>', 'Change budget limit for changed paths')
343
+ .option('--max-new-files <count>', 'Change budget limit for new files')
344
+ .option('--max-deleted-files <count>', 'Change budget limit for deleted files')
345
+ .option('--governed-override <json>', 'JSON governed override contract for protected or replacement changes')
148
346
  .option('--requested-env <list>', 'CSV environment variables requested for runtime passthrough')
149
347
  .option('--network-domains <list>', 'CSV network domains requested by this run')
150
348
  .option('--approval-grants <list>', 'CSV HITL approval grants: operation names or all')
@@ -160,11 +358,13 @@ export function registerExecutionCommands(sddCmd) {
160
358
  const result = await command.execute(featureId, {
161
359
  provider: options.provider,
162
360
  mode: options.mode,
361
+ objective: options.objective,
163
362
  plugin_execution_path: options.pluginExecutionPath,
164
363
  plugin_flow: parseCsvOption(options.pluginFlow),
165
364
  operations: parseCsvOption(options.operations),
166
365
  write_scope: parseCsvOption(options.writeScope),
167
366
  planned_writes: parseCsvOption(options.plannedWrites),
367
+ change_safety: buildChangeSafetyFromOptions(options),
168
368
  requested_env: parseCsvOption(options.requestedEnv),
169
369
  network_domains: parseCsvOption(options.networkDomains),
170
370
  approval_grants: parseCsvOption(options.approvalGrants),
@@ -320,6 +520,12 @@ export function registerExecutionCommands(sddCmd) {
320
520
  }
321
521
  console.log(`Liberadas: ${result.unblocked.join(', ') || '-'}`);
322
522
  console.log(`Pendentes na fila: ${result.pending}`);
523
+ if (result.post_finalize_replan?.ready?.length) {
524
+ console.log(`Proximas FEATs: ${result.post_finalize_replan.ready
525
+ .slice(0, 5)
526
+ .map((entry) => entry.id)
527
+ .join(', ')}`);
528
+ }
323
529
  console.log(`Docs core atualizados: ${result.updated_core_docs?.join(', ') || '-'}`);
324
530
  console.log(`README sincronizado: ${result.updated_readme ? 'sim' : 'nao'}`);
325
531
  console.log(`Guia do agente sincronizado: ${result.updated_agent_guide ? 'sim' : 'nao'}`);
@@ -339,6 +545,9 @@ export function registerExecutionCommands(sddCmd) {
339
545
  .command('context <ref>')
340
546
  .description('Gera contexto objetivo para FEAT/EPIC/FGAP/TD (RAD legado ainda aceito)')
341
547
  .alias('contexto')
548
+ .option('--budget <mode>', 'Modo de orcamento do pacote de contexto: compact, standard ou full', 'standard')
549
+ .option('--compact', 'Atalho para --budget compact')
550
+ .option('--full', 'Atalho para --budget full')
342
551
  .option('--json', 'Saida em JSON')
343
552
  .action(async (ref, options) => {
344
553
  const root = resolveRoot();
@@ -347,28 +556,47 @@ export function registerExecutionCommands(sddCmd) {
347
556
  const stores = createSddStores(__paths);
348
557
  await ensureMandatorySddMigration(root);
349
558
  const command = new ContextService(stores);
350
- const context = await command.execute(root, ref);
559
+ const budgetMode = resolveContextBudgetModeOption(options);
560
+ const context = await command.execute(root, ref, { budgetMode });
351
561
  if (options?.json) {
352
562
  console.log(JSON.stringify(context, null, 2));
353
563
  return;
354
564
  }
565
+ const contextRecord = context;
355
566
  console.log(`Contexto de ${context.target_id} (${context.target_type})`);
356
567
  console.log(`Resumo: ${context.summary}`);
357
- console.log(`Core docs: ${context.core_docs.join(', ')}`);
358
- if (context.origin) {
359
- const origin = context.origin;
568
+ console.log(`Budget: ${context.context_budget.mode} (${context.context_budget.estimated_chars_after_budget} chars)`);
569
+ if (context.context_budget.deduped_fields?.length) {
570
+ const removed = context.context_budget.deduped_fields.reduce((sum, field) => sum + field.removed, 0);
571
+ console.log(`Dedupe: ${removed} entradas removidas`);
572
+ }
573
+ if (contextRecord.progressive_disclosure) {
574
+ const disclosure = contextRecord.progressive_disclosure;
575
+ const omitted = disclosure.omitted_fields
576
+ .map((field) => `${field.field}:${field.omitted_count}`)
577
+ .join(', ');
578
+ console.log(`Disclosure: ${omitted || '-'} | ${disclosure.reveal_command}`);
579
+ }
580
+ if (contextRecord.context_cache) {
581
+ const cache = contextRecord.context_cache;
582
+ console.log(`Cache: ${cache.hit ? 'hit' : 'miss'} (${cache.key})`);
583
+ }
584
+ const coreDocs = Array.isArray(contextRecord.core_docs) ? contextRecord.core_docs : [];
585
+ console.log(`Core docs: ${coreDocs.join(', ')}`);
586
+ if (contextRecord.origin) {
587
+ const origin = contextRecord.origin;
360
588
  console.log(`Origem: ${origin.type}${origin.ref ? ` (${origin.ref})` : ''}`);
361
589
  }
362
- if (context.related_features) {
363
- const refs = context.related_features;
590
+ if (contextRecord.related_features) {
591
+ const refs = contextRecord.related_features;
364
592
  console.log(`Features relacionadas: ${refs.join(', ') || '-'}`);
365
593
  }
366
- if (context.recommended_skills) {
367
- const skills = context.recommended_skills;
594
+ if (contextRecord.recommended_skills) {
595
+ const skills = contextRecord.recommended_skills;
368
596
  console.log(`Skills sugeridas: ${skills.join(', ') || '-'}`);
369
597
  }
370
- if (context.skill_execution_contract) {
371
- const skillContract = context.skill_execution_contract;
598
+ if (contextRecord.skill_execution_contract) {
599
+ const skillContract = contextRecord.skill_execution_contract;
372
600
  if (skillContract.required) {
373
601
  console.log(`Evidencia de skill: ${skillContract.required_skill_ids.join(', ')} -> ${skillContract.verification_location}`);
374
602
  }
@@ -504,6 +732,108 @@ export function registerExecutionCommands(sddCmd) {
504
732
  }
505
733
  }
506
734
  });
735
+ sddCmd
736
+ .command('plan-status [path]')
737
+ .description('Mostra status operacional do plano CodeSDD e a proxima acao recomendada')
738
+ .alias('status-plano')
739
+ .option('--rank <mode>', 'Ranking: impact|criticality|fifo (padrao: impact)')
740
+ .option('--limit <n>', 'Limite de itens prontos (padrao: 10)')
741
+ .option('--max-agents <n>', 'Limite de itens por onda (padrao: sem limite)')
742
+ .option('--json', 'Saida em JSON')
743
+ .action(async (targetPath = '.', options) => {
744
+ const root = resolveRoot(targetPath);
745
+ const __config = await loadProjectSddConfig(root);
746
+ const __paths = resolveSddPaths(root, __config);
747
+ const stores = createSddStores(__paths);
748
+ await ensureMandatorySddMigration(root);
749
+ if (options?.rank && !['impact', 'criticality', 'fifo'].includes(options.rank)) {
750
+ throw new Error('Valor invalido em --rank. Use impact, criticality ou fifo.');
751
+ }
752
+ const result = await buildPlanStatus(root, stores, options);
753
+ if (options?.json) {
754
+ console.log(JSON.stringify(result, null, 2));
755
+ return;
756
+ }
757
+ console.log(chalk.green('Status do plano CodeSDD'));
758
+ console.log(`Ativas: ${result.active.length}`);
759
+ for (const item of result.active) {
760
+ console.log(`- ${item.id}: ${item.title} | etapa=${item.current_stage} | frontend=${item.frontend_impact_status}`);
761
+ }
762
+ console.log(`Prontas: ${result.next.ready.length}`);
763
+ if (result.next.ready[0]) {
764
+ const first = result.next.ready[0];
765
+ console.log(`Proxima recomendada: ${first.id}: ${first.title}`);
766
+ }
767
+ console.log(`Bloqueadas: ${result.next.blocked.length}`);
768
+ console.log(`Conflitos de lock: ${result.next.conflicts.length}`);
769
+ console.log(`Acao recomendada: ${result.recommended_action}`);
770
+ });
771
+ sddCmd
772
+ .command('execute-next [path]')
773
+ .description('Inicia a proxima FEAT pronta pelo ranking CodeSDD')
774
+ .alias('executar-proxima')
775
+ .option('--rank <mode>', 'Ranking: impact|criticality|fifo (padrao: impact)')
776
+ .option('--limit <n>', 'Limite de itens prontos avaliados (padrao: 10)')
777
+ .option('--max-agents <n>', 'Limite de itens por onda (padrao: sem limite)')
778
+ .option('--dry-run', 'Mostra qual FEAT seria iniciada sem alterar estado')
779
+ .option('--force', 'Bypass de bloqueios e conflitos de lock no start')
780
+ .option('--force-transition', 'Bypass das restrições e violações das lentes estruturais')
781
+ .option('--flow-mode <flowMode>', 'Flow: direct|standard|rigorous')
782
+ .option('--fluxo <flowMode>', 'Legacy Portuguese alias for --flow-mode')
783
+ .option('--json', 'Saida em JSON')
784
+ .option('--no-render', 'Nao gera views apos atualizar estado')
785
+ .action(async (targetPath = '.', options) => {
786
+ const root = resolveRoot(targetPath);
787
+ const __config = await loadProjectSddConfig(root);
788
+ const __paths = resolveSddPaths(root, __config);
789
+ const stores = createSddStores(__paths);
790
+ await ensureMandatorySddMigration(root);
791
+ if (options?.rank && !['impact', 'criticality', 'fifo'].includes(options.rank)) {
792
+ throw new Error('Valor invalido em --rank. Use impact, criticality ou fifo.');
793
+ }
794
+ const next = await new NextService(stores).execute(root, {
795
+ rank: options?.rank,
796
+ limit: parsePositiveNumberOption(options?.limit, '--limit'),
797
+ maxAgents: parsePositiveNumberOption(options?.maxAgents, '--max-agents'),
798
+ });
799
+ const selected = next.ready[0];
800
+ if (!selected) {
801
+ const result = { schema_version: 1, started: false, dry_run: !!options?.dryRun, selected: null, next };
802
+ if (options?.json) {
803
+ console.log(JSON.stringify(result, null, 2));
804
+ }
805
+ else {
806
+ console.log('Nenhuma FEAT pronta para iniciar.');
807
+ }
808
+ return;
809
+ }
810
+ if (options?.dryRun) {
811
+ const result = { schema_version: 1, started: false, dry_run: true, selected, next };
812
+ if (options?.json) {
813
+ console.log(JSON.stringify(result, null, 2));
814
+ return;
815
+ }
816
+ console.log(`Proxima FEAT: ${selected.id}: ${selected.title}`);
817
+ console.log(`Comando: codesdd sdd start ${selected.id}`);
818
+ return;
819
+ }
820
+ const flow = parseFlowModeOption(options?.flowMode || options?.fluxo);
821
+ const startResult = await new StartService(stores).execute(root, selected.id, {
822
+ force: options?.force,
823
+ forceTransition: options?.forceTransition,
824
+ flowMode: flow,
825
+ render: options?.render,
826
+ });
827
+ const result = { schema_version: 1, started: true, dry_run: false, selected, start: startResult, next };
828
+ if (options?.json) {
829
+ console.log(JSON.stringify(result, null, 2));
830
+ return;
831
+ }
832
+ console.log(chalk.green(`Proxima FEAT iniciada: ${startResult.featureId}`));
833
+ console.log(`Titulo: ${selected.title}`);
834
+ console.log(`Workspace ativo: ${startResult.active_path}`);
835
+ console.log(`Proximo passo: codesdd sdd context ${startResult.featureId} --compact`);
836
+ });
507
837
  sddCmd
508
838
  .command('audit [path]')
509
839
  .description('Audita a saude de meta-evolucao do SDD (placeholders, deliberacao, ADR e forced transition)')
@@ -32,6 +32,7 @@ export function registerPluginCommands(sddCmd) {
32
32
  .option('--env <list>', 'Comma-separated requested environment variables')
33
33
  .option('--network-domains <list>', 'Comma-separated requested network domains')
34
34
  .option('--process-spawn', 'Declare that the operation requests process spawning')
35
+ .option('--project-root <path>', 'Project root used for standalone storage-boundary validation')
35
36
  .option('--language <language>', 'Technology language constraint')
36
37
  .option('--framework <framework>', 'Technology framework constraint')
37
38
  .option('--json', 'Return invocation plan as JSON')
@@ -50,6 +51,7 @@ export function registerPluginCommands(sddCmd) {
50
51
  requested_env: parseCsvOption(options.env),
51
52
  network_domains: parseCsvOption(options.networkDomains),
52
53
  process_spawn_requested: options.processSpawn ?? false,
54
+ project_root: options.projectRoot,
53
55
  technology: resolveTechnologyConstraint(options),
54
56
  });
55
57
  if (options.json) {
@@ -124,6 +126,9 @@ function printPlanResult(result) {
124
126
  console.log(chalk.green(`Plugin plan: ${plan.status}`));
125
127
  console.log(`Manifest: ${result.manifest_path}`);
126
128
  console.log(`Policy: ${plan.policy?.decision ?? 'not-evaluated'}`);
129
+ console.log(`Standalone runner: ${result.workcell_runner.standalone.status}`);
130
+ console.log(`Package governance: ${result.workcell_runner.standalone.package_governance.status}`);
131
+ console.log(`Storage boundary: ${result.workcell_runner.standalone.storage_boundary.status}`);
127
132
  if (plan.envelope) {
128
133
  console.log(`Operation: ${plan.envelope.operation_id}`);
129
134
  console.log(`Plugin: ${plan.envelope.plugin_ref.id}@${plan.envelope.plugin_ref.version}`);
@@ -2,6 +2,7 @@ import { type SddLanguage, type SddLayout } from '../../core/sdd/state.js';
2
2
  import type { FlowMode } from '../../core/sdd/types.js';
3
3
  export declare function parseCsvOption(value?: string): string[];
4
4
  export declare function resolveRoot(targetPath?: string): string;
5
+ export declare function resolveInitRoot(targetPath?: string): string;
5
6
  export declare function parseLangOption(value?: string): SddLanguage | undefined;
6
7
  export declare function parseLayoutOption(value?: string): SddLayout | undefined;
7
8
  export declare function parseFlowModeOption(value?: string): FlowMode | undefined;
@@ -1,4 +1,5 @@
1
1
  import { promises as fs } from 'node:fs';
2
+ import path from 'node:path';
2
3
  import { resolveProjectRoot } from '../../core/sdd/resolve-project-root.js';
3
4
  import { loadProjectSddConfig, resolveSddPaths, } from '../../core/sdd/state.js';
4
5
  import { assessSddMigration } from '../../core/sdd/migrate.js';
@@ -13,6 +14,15 @@ export function parseCsvOption(value) {
13
14
  export function resolveRoot(targetPath = '.') {
14
15
  return resolveProjectRoot(targetPath === '.' ? undefined : targetPath);
15
16
  }
17
+ export function resolveInitRoot(targetPath = '.') {
18
+ const absoluteTarget = path.resolve(targetPath);
19
+ const segments = absoluteTarget.split(path.sep);
20
+ const sddIndex = segments.lastIndexOf('.sdd');
21
+ if (sddIndex >= 0) {
22
+ return segments.slice(0, sddIndex).join(path.sep) || path.parse(absoluteTarget).root;
23
+ }
24
+ return absoluteTarget;
25
+ }
16
26
  export function parseLangOption(value) {
17
27
  if (!value)
18
28
  return undefined;
@@ -23,8 +23,9 @@ import { SddRebuildService, formatSddRebuildReport } from "../core/sdd/services/
23
23
  import { SddMetricsService, formatSddMetricsReport } from "../core/sdd/services/metrics.service.js";
24
24
  import { FeatureLintService, formatFeatureLintReport } from "../core/sdd/services/feature-lint.service.js";
25
25
  import { SddDedupApplyService, formatSddDedupApplyReport } from "../core/sdd/services/dedup-apply.service.js";
26
+ import { evaluateSddIntentGuard } from '../core/sdd/intent-guard.js';
26
27
  import { captureFingerprintsForChange, writeMeta } from '../core/sdd/fingerprint.js';
27
- import { ensureMandatorySddMigration, parseCsvOption, parseFlowModeOption, parseLangOption, parseLayoutOption, resolveRoot, } from './sdd/shared.js';
28
+ import { ensureMandatorySddMigration, parseCsvOption, parseFlowModeOption, parseLangOption, parseLayoutOption, resolveInitRoot, resolveRoot, } from './sdd/shared.js';
28
29
  import { registerExecutionCommands } from './sdd/execution.js';
29
30
  import { registerPluginCommands } from './sdd/plugin.js';
30
31
  import { registerSkillsCommands } from './sdd/skills.js';
@@ -32,6 +33,40 @@ import { registerBacklogCommands } from './sdd/backlog.js';
32
33
  import { displayLegacySpecPath, resolveLegacySpecSubpath, } from '../core/sdd/services/legacy-capability.service.js';
33
34
  export function registerSddCommand(program) {
34
35
  const sddCmd = program.command('sdd').description('SDD memory operations');
36
+ sddCmd
37
+ .command('intent-guard')
38
+ .description('Classifica uma solicitacao e informa quando o fluxo CodeSDD e obrigatorio')
39
+ .alias('guarda-intencao')
40
+ .requiredOption('--request <text>', 'Texto da solicitacao do usuario/agente')
41
+ .option('--feat <FEAT-ID>', 'FEAT ja selecionada para o contexto CodeSDD')
42
+ .option('--strict', 'Retorna exit code 2 quando a solicitacao exige CodeSDD e nenhuma FEAT foi informada')
43
+ .option('--json', 'Saida em JSON')
44
+ .action((options) => {
45
+ const result = evaluateSddIntentGuard({
46
+ request: options?.request ?? '',
47
+ featureRef: options?.feat,
48
+ });
49
+ if (options?.json) {
50
+ console.log(JSON.stringify(result, null, 2));
51
+ }
52
+ else {
53
+ console.log(`Classificacao: ${result.classification}`);
54
+ console.log(`Requer CodeSDD: ${result.requires_codesdd_planning ? 'sim' : 'nao'}`);
55
+ console.log(`Motivo: ${result.reason}`);
56
+ if (result.required_commands.length > 0) {
57
+ console.log('Comandos obrigatorios:');
58
+ for (const command of result.required_commands) {
59
+ console.log(`- ${command}`);
60
+ }
61
+ }
62
+ for (const warning of result.warnings) {
63
+ console.log(chalk.yellow(`Aviso: ${warning}`));
64
+ }
65
+ }
66
+ if (options?.strict && result.requires_codesdd_planning && !result.feature_ref) {
67
+ process.exitCode = 2;
68
+ }
69
+ });
35
70
  sddCmd
36
71
  .command('init [path]')
37
72
  .description('Initializes the .sdd structure and base state files')
@@ -41,7 +76,7 @@ export function registerSddCommand(program) {
41
76
  .option('--layout <layout>', 'Folder layout: en-US|legacy|pt-BR')
42
77
  .option('--no-render', 'Does not generate Markdown views after initialization')
43
78
  .action(async (targetPath = '.', options) => {
44
- const root = resolveRoot(targetPath);
79
+ const root = resolveInitRoot(targetPath);
45
80
  const __config = await loadProjectSddConfig(root);
46
81
  const __paths = resolveSddPaths(root, __config);
47
82
  const stores = createSddStores(__paths);
@@ -378,7 +413,7 @@ export function registerSddCommand(program) {
378
413
  console.log(`Registros de discovery: ${report.summary.discovery}`);
379
414
  console.log(`Itens de backlog: ${report.summary.backlog}`);
380
415
  console.log(`Itens de divida tecnica: ${report.summary.techDebt}`);
381
- console.log(`Itens na fila de finalize: ${report.summary.finalizeQueue}`);
416
+ console.log(`Registros de finalize: ${report.summary.finalizeQueue} (pendentes: ${report.summary.finalizeQueuePending}; concluidos: ${report.summary.finalizeQueueDone})`);
382
417
  console.log(`Frontend ativado: ${report.summary.frontendEnabled ? 'sim' : 'nao'}`);
383
418
  console.log(`Progresso global: ${report.summary.progress_global.percent}% (${report.summary.progress_global.done}/${report.summary.progress_global.total})`);
384
419
  console.log(`Prontas para paralelo: ${report.summary.ready_for_parallel}`);
@@ -46,12 +46,17 @@ export const CLI_COMMAND_MATRIX = [
46
46
  { commandPath: 'config:reset', strategy: 'contract', rationale: 'Reset behavior is deterministic once prompts are bypassed in tests.' },
47
47
  { commandPath: 'config:edit', strategy: 'exception', rationale: 'This command delegates to an external editor process and only needs focused environment-sensitive coverage.' },
48
48
  { commandPath: 'config:profile', strategy: 'contract', rationale: 'Profile inspection is scriptable and deterministic.' },
49
+ { commandPath: 'config:redis:status', strategy: 'contract', rationale: 'Redis status reports the governed runtime backend without exposing secrets.' },
50
+ { commandPath: 'config:redis:ping', strategy: 'contract', rationale: 'Redis ping is a deterministic readiness contract with mocked and unavailable paths.' },
51
+ { commandPath: 'config:redis:bench', strategy: 'contract', rationale: 'Redis benchmark output is bounded, redacted, and suitable for direct contract assertions.' },
52
+ { commandPath: 'config:redis:flush-namespace', strategy: 'contract', rationale: 'Redis namespace cleanup is explicitly scoped and guarded by confirmation.' },
49
53
  { commandPath: 'schema:which', strategy: 'contract', rationale: 'Schema resolution is deterministic with fixture directories.' },
50
54
  { commandPath: 'schema:validate', strategy: 'contract', rationale: 'Schema validation produces deterministic reports from fixture inputs.' },
51
55
  { commandPath: 'schema:fork', strategy: 'contract', rationale: 'Schema fork output is a filesystem contract that can be asserted directly.' },
52
56
  { commandPath: 'schema:init', strategy: 'contract', rationale: 'Schema initialization is deterministic over temporary workspaces.' },
53
57
  { commandPath: 'sdd:init', strategy: 'spawned-e2e', rationale: 'SDD init seeds canonical state and generated views, so it should keep lifecycle smoke coverage.' },
54
58
  { commandPath: 'sdd:init-context', strategy: 'spawned-e2e', rationale: 'Context bootstrap reads repository structure and writes canonical state, which benefits from spawned smoke coverage.' },
59
+ { commandPath: 'sdd:intent-guard', strategy: 'contract', rationale: 'Intent guard classification is deterministic and should stay covered with direct contract tests.' },
55
60
  { commandPath: 'sdd:fingerprint', strategy: 'contract', rationale: 'Fingerprint backfill is a deterministic batch operation over change fixtures.' },
56
61
  { commandPath: 'sdd:insight', strategy: 'spawned-e2e', rationale: 'Insight creation is the first discovery lifecycle write and should stay covered in spawned flow tests.' },
57
62
  { commandPath: 'sdd:ingest-deposito', strategy: 'spawned-e2e', rationale: 'Ingestion coordinates discovery inputs, indexing, and trail generation across filesystem boundaries.' },
@@ -60,7 +65,9 @@ export const CLI_COMMAND_MATRIX = [
60
65
  { commandPath: 'sdd:breakdown', strategy: 'spawned-e2e', rationale: 'Breakdown materializes executable FEAT workspaces and needs lifecycle smoke coverage.' },
61
66
  { commandPath: 'sdd:mcp-manifest', strategy: 'contract', rationale: 'Manifest rendering is deterministic and provider-profile driven.' },
62
67
  { commandPath: 'sdd:mcp-call', strategy: 'contract', rationale: 'The MCP bridge reuses canonical services and is best guarded with direct contract assertions.' },
68
+ { commandPath: 'sdd:preflight', strategy: 'contract', rationale: 'Preflight reuses deterministic mutation guardrails without invoking agent runtime.' },
63
69
  { commandPath: 'sdd:agent:run', strategy: 'contract', rationale: 'DeepAgents run gating is a deterministic fail-closed policy contract with no direct state writes.' },
70
+ { commandPath: 'sdd:release-readiness', strategy: 'contract', rationale: 'Release readiness aggregates static gates and CI parity commands without publishing or mutating release state.' },
64
71
  { commandPath: 'sdd:start', strategy: 'spawned-e2e', rationale: 'Start transitions planned work into active execution and is a core lifecycle boundary.' },
65
72
  { commandPath: 'sdd:frontend-impact', strategy: 'spawned-e2e', rationale: 'Frontend impact is a required lifecycle declaration that should remain part of spawned finalize-path smoke.' },
66
73
  { commandPath: 'sdd:finalize', strategy: 'spawned-e2e', rationale: 'Finalize is the highest-risk lifecycle transition and must keep spawned smoke coverage.' },
@@ -68,6 +75,8 @@ export const CLI_COMMAND_MATRIX = [
68
75
  { commandPath: 'sdd:onboard', strategy: 'contract', rationale: 'Onboard is a read-oriented guidance surface with deterministic ranking output.' },
69
76
  { commandPath: 'sdd:aprovar', strategy: 'contract', rationale: 'Approval transitions are deterministic and fit fixture-driven lifecycle assertions.' },
70
77
  { commandPath: 'sdd:next', strategy: 'contract', rationale: 'Next is ranking logic over canonical state and is naturally contract-testable.' },
78
+ { commandPath: 'sdd:plan-status', strategy: 'contract', rationale: 'Plan status aggregates active and ready work without mutating state.' },
79
+ { commandPath: 'sdd:execute-next', strategy: 'spawned-e2e', rationale: 'Execute next bridges ranking into start and must preserve lifecycle guardrails.' },
71
80
  { commandPath: 'sdd:audit', strategy: 'contract', rationale: 'Audit is a deterministic report over canonical state.' },
72
81
  { commandPath: 'sdd:plugin:inspect', strategy: 'contract', rationale: 'Plugin inspect is a read-only manifest parser surface.' },
73
82
  { commandPath: 'sdd:plugin:plan', strategy: 'contract', rationale: 'Plugin plan builds a non-executing runtime envelope from a manifest fixture.' },
@@ -43,6 +43,7 @@ export const CLI_COMMAND_QUALITY_MATRIX = [
43
43
  'sdd aprovar',
44
44
  'sdd start',
45
45
  'sdd context',
46
+ 'sdd execute-next',
46
47
  'sdd frontend-impact',
47
48
  'sdd finalize',
48
49
  'sdd init-context',
@@ -69,6 +70,10 @@ export const CLI_COMMAND_QUALITY_MATRIX = [
69
70
  'config init',
70
71
  'config list',
71
72
  'config path',
73
+ 'config redis bench',
74
+ 'config redis flush-namespace',
75
+ 'config redis ping',
76
+ 'config redis status',
72
77
  'config reset',
73
78
  'config set',
74
79
  'config unset',
@@ -107,6 +112,10 @@ export const CLI_COMMAND_QUALITY_MATRIX = [
107
112
  'sdd migrate-workspace',
108
113
  'sdd next',
109
114
  'sdd onboard',
115
+ 'sdd plan-status',
116
+ 'sdd preflight',
117
+ 'sdd release-readiness',
118
+ 'sdd intent-guard',
110
119
  'sdd backlog project',
111
120
  'sdd plugin devtrack-api scaffold-dry-run',
112
121
  'sdd plugin inspect',