pumuki 6.3.113 → 6.3.115

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 (99) hide show
  1. package/CHANGELOG.md +52 -5
  2. package/README.md +4 -2
  3. package/VERSION +1 -1
  4. package/core/facts/detectors/typescript/index.test.ts +0 -229
  5. package/core/facts/detectors/typescript/index.ts +0 -278
  6. package/core/facts/extractHeuristicFacts.ts +0 -4
  7. package/core/rules/presets/heuristics/typescript.test.ts +1 -21
  8. package/core/rules/presets/heuristics/typescript.ts +0 -72
  9. package/docs/README.md +13 -9
  10. package/docs/codex-skills/backend-enterprise-rules.md +3 -3
  11. package/docs/operations/RELEASE_NOTES.md +41 -4
  12. package/docs/product/API_REFERENCE.md +1 -1
  13. package/docs/product/HOW_IT_WORKS.md +6 -0
  14. package/docs/product/INSTALLATION.md +1 -1
  15. package/docs/product/USAGE.md +42 -5
  16. package/docs/tracking/plan-curso-pumuki-stack-my-architecture.md +100 -44
  17. package/docs/validation/README.md +6 -3
  18. package/integrations/config/skillsDetectorRegistry.ts +0 -24
  19. package/integrations/config/skillsMarkdownRules.ts +0 -57
  20. package/integrations/evidence/buildEvidence.ts +0 -24
  21. package/integrations/evidence/repoState.ts +9 -7
  22. package/integrations/evidence/schema.ts +0 -18
  23. package/integrations/evidence/writeEvidence.ts +0 -24
  24. package/integrations/gate/evaluateAiGate.ts +8 -251
  25. package/integrations/gate/remediationCatalog.ts +0 -8
  26. package/integrations/git/GitService.ts +44 -5
  27. package/integrations/git/aiGateRepoPolicyFindings.ts +86 -17
  28. package/integrations/git/runPlatformGate.ts +1 -9
  29. package/integrations/git/runPlatformGateFacts.ts +19 -1
  30. package/integrations/git/runPlatformGateOutput.ts +41 -42
  31. package/integrations/lifecycle/adapter.templates.json +1 -0
  32. package/integrations/lifecycle/adapter.ts +0 -24
  33. package/integrations/lifecycle/audit.ts +101 -0
  34. package/integrations/lifecycle/cli.ts +120 -99
  35. package/integrations/lifecycle/cliSdd.ts +4 -26
  36. package/integrations/lifecycle/doctor.ts +40 -102
  37. package/integrations/lifecycle/index.ts +2 -0
  38. package/integrations/lifecycle/install.ts +0 -21
  39. package/integrations/lifecycle/packageInfo.ts +1 -118
  40. package/integrations/lifecycle/state.ts +1 -8
  41. package/integrations/lifecycle/status.ts +40 -59
  42. package/integrations/lifecycle/watch.ts +1 -1
  43. package/integrations/mcp/aiGateCheck.ts +10 -194
  44. package/integrations/mcp/autoExecuteAiStart.ts +116 -92
  45. package/integrations/mcp/enterpriseServer.ts +7 -23
  46. package/integrations/mcp/enterpriseStdioServer.cli.ts +4 -31
  47. package/integrations/mcp/preFlightCheck.ts +5 -67
  48. package/integrations/platform/detectPlatforms.ts +37 -0
  49. package/integrations/sdd/policy.ts +28 -20
  50. package/package.json +1 -1
  51. package/scripts/check-tracking-single-active.sh +1 -1
  52. package/scripts/consumer-menu-matrix-baseline-report-lib.ts +13 -38
  53. package/scripts/consumer-postinstall-resolve-args.cjs +44 -0
  54. package/scripts/consumer-postinstall.cjs +76 -21
  55. package/scripts/framework-menu-advanced-view-lib.ts +0 -49
  56. package/scripts/framework-menu-consumer-actions-lib.ts +28 -4
  57. package/scripts/framework-menu-consumer-preflight-hints.ts +5 -2
  58. package/scripts/framework-menu-consumer-preflight-render.ts +0 -10
  59. package/scripts/framework-menu-consumer-preflight-run.ts +0 -23
  60. package/scripts/framework-menu-consumer-preflight-types.ts +0 -12
  61. package/scripts/framework-menu-consumer-runtime-actions.ts +87 -17
  62. package/scripts/framework-menu-consumer-runtime-audit.ts +36 -2
  63. package/scripts/framework-menu-consumer-runtime-evidence-classic.ts +140 -0
  64. package/scripts/framework-menu-consumer-runtime-lib.ts +2 -38
  65. package/scripts/framework-menu-consumer-runtime-menu.ts +4 -31
  66. package/scripts/framework-menu-consumer-runtime-types.ts +3 -5
  67. package/scripts/framework-menu-evidence-summary-lib.ts +1 -0
  68. package/scripts/framework-menu-evidence-summary-read.ts +57 -5
  69. package/scripts/framework-menu-evidence-summary-severity.ts +3 -1
  70. package/scripts/framework-menu-evidence-summary-types.ts +7 -0
  71. package/scripts/framework-menu-gate-lib.ts +9 -0
  72. package/scripts/framework-menu-layout-data.ts +5 -0
  73. package/scripts/framework-menu-matrix-baseline-lib.ts +15 -14
  74. package/scripts/framework-menu-matrix-canary-lib.ts +22 -1
  75. package/scripts/framework-menu-matrix-evidence-lib.ts +1 -0
  76. package/scripts/framework-menu-matrix-evidence-types.ts +13 -1
  77. package/scripts/framework-menu-matrix-runner-lib.ts +35 -0
  78. package/scripts/framework-menu-system-notifications-cause.ts +0 -3
  79. package/scripts/framework-menu-system-notifications-macos-swift-source.ts +24 -204
  80. package/scripts/framework-menu-system-notifications-macos.ts +4 -0
  81. package/scripts/framework-menu-system-notifications-payloads-blocked.ts +1 -1
  82. package/scripts/framework-menu-system-notifications-text.ts +1 -7
  83. package/scripts/framework-menu.ts +3 -24
  84. package/scripts/package-install-smoke-consumer-git-repo-lib.ts +1 -10
  85. package/scripts/package-install-smoke-consumer-npm-lib.ts +9 -46
  86. package/scripts/pumuki-full-surface-smoke-lib.ts +37 -0
  87. package/scripts/pumuki-full-surface-smoke.ts +346 -0
  88. package/scripts/pumuki-smoke-installed-wrapper.cjs +31 -0
  89. package/integrations/evidence/trackingContract.ts +0 -17
  90. package/integrations/gate/governanceActionCatalog.ts +0 -275
  91. package/integrations/lifecycle/bootstrapManifest.ts +0 -248
  92. package/integrations/lifecycle/cliGovernanceConsole.ts +0 -69
  93. package/integrations/lifecycle/governanceNextAction.ts +0 -171
  94. package/integrations/lifecycle/governanceObservationSnapshot.ts +0 -369
  95. package/integrations/lifecycle/trackingState.ts +0 -403
  96. package/integrations/mcp/alignedPlatformGate.ts +0 -232
  97. package/integrations/mcp/readMcpPrePushStdin.ts +0 -7
  98. package/scripts/build-ruralgo-s1-evidence-pack.ts +0 -85
  99. package/scripts/ruralgo-s1-evidence-pack-lib.ts +0 -200
@@ -4,19 +4,15 @@ import type { GatePolicy } from '../../core/gate/GatePolicy';
4
4
  import { runPlatformGate } from '../git/runPlatformGate';
5
5
  import { collectWorktreeAtomicSlices } from '../git/worktreeAtomicSlices';
6
6
  import {
7
- doctorCommandShouldFailExit,
8
- doctorCommandShouldWarnHuman,
9
7
  doctorHasBlockingIssues,
10
- doctorHasGovernanceAttention,
11
8
  doctorHasParityMismatch,
12
9
  runLifecycleDoctor,
13
10
  type LifecycleDoctorReport,
14
11
  } from './doctor';
15
- import { printGovernanceConsoleHuman } from './cliGovernanceConsole';
16
12
  import { runLifecycleInstall } from './install';
17
13
  import { runLifecycleRemove } from './remove';
18
- import { readLifecycleStatus } from './status';
19
14
  import { getCurrentPumukiVersion } from './packageInfo';
15
+ import { readLifecycleStatus } from './status';
20
16
  import {
21
17
  readLifecycleExperimentalFeaturesSnapshot,
22
18
  type LifecycleExperimentalFeaturesSnapshot,
@@ -77,6 +73,7 @@ import {
77
73
  type RemoteCiDiagnostics,
78
74
  } from './remoteCiDiagnostics';
79
75
  import { runPolicyReconcile } from './policyReconcile';
76
+ import { runLifecycleAudit, type LifecycleAuditStage } from './audit';
80
77
  import { resolvePreWriteEnforcement, type PreWriteEnforcementResolution } from '../policy/preWriteEnforcement';
81
78
 
82
79
  type LifecycleCommand =
@@ -92,7 +89,8 @@ type LifecycleCommand =
92
89
  | 'sdd'
93
90
  | 'adapter'
94
91
  | 'analytics'
95
- | 'policy';
92
+ | 'policy'
93
+ | 'audit';
96
94
 
97
95
  type SddCommand =
98
96
  | 'status'
@@ -178,6 +176,8 @@ export type ParsedArgs = {
178
176
  policyCommand?: PolicyCommand;
179
177
  policyStrict?: boolean;
180
178
  policyApply?: boolean;
179
+ auditStage?: LifecycleAuditStage;
180
+ auditEngine?: boolean;
181
181
  };
182
182
 
183
183
  const HELP_TEXT = `
@@ -188,6 +188,7 @@ Pumuki lifecycle commands:
188
188
  pumuki remove
189
189
  pumuki update [--latest|--spec=<package-spec>]
190
190
  pumuki doctor [--remote-checks] [--deep] [--parity] [--json]
191
+ pumuki audit [--stage=PRE_COMMIT|PRE_PUSH|CI] [--engine] [--json]
191
192
  pumuki status [--json] [--remote-checks]
192
193
  pumuki watch [--stage=PRE_COMMIT|PRE_PUSH|CI] [--scope=workingTree|staged|repoAndStaged|repo] [--severity=critical|high|medium|low] [--interval-ms=<n>] [--notify-cooldown-ms=<n>] [--no-notify] [--once|--iterations=<n>] [--json]
193
194
  pumuki loop run --objective=<text> [--max-attempts=<n>] [--json]
@@ -233,7 +234,8 @@ const isLifecycleCommand = (value: string): value is LifecycleCommand =>
233
234
  value === 'sdd' ||
234
235
  value === 'adapter' ||
235
236
  value === 'analytics' ||
236
- value === 'policy';
237
+ value === 'policy' ||
238
+ value === 'audit';
237
239
 
238
240
  const parseAdapterAgent = (value?: string): AdapterAgent => {
239
241
  const normalized = (value ?? '').trim();
@@ -263,6 +265,16 @@ const parseSddStage = (value?: string): SddStage => {
263
265
  throw new Error(`Unsupported SDD stage "${value}". Use PRE_WRITE, PRE_COMMIT, PRE_PUSH or CI.`);
264
266
  };
265
267
 
268
+ const parseAuditStage = (value?: string): LifecycleAuditStage => {
269
+ const stage = parseSddStage(value);
270
+ if (stage === 'PRE_WRITE') {
271
+ throw new Error(
272
+ 'PRE_WRITE is not supported for "pumuki audit". Use PRE_COMMIT, PRE_PUSH or CI (aliases GREEN, REFACTOR, CLOSE).'
273
+ );
274
+ }
275
+ return stage;
276
+ };
277
+
266
278
  const parseSddEvidencePath = (value: string): string => {
267
279
  const normalized = value.trim();
268
280
  if (normalized.length === 0) {
@@ -628,6 +640,8 @@ export const parseLifecycleCliArgs = (argv: ReadonlyArray<string>): ParsedArgs =
628
640
  let analyticsSinceDays: ParsedArgs['analyticsSinceDays'];
629
641
  let analyticsJsonOutputPath: ParsedArgs['analyticsJsonOutputPath'];
630
642
  let analyticsMarkdownOutputPath: ParsedArgs['analyticsMarkdownOutputPath'];
643
+ let auditStage: LifecycleAuditStage | undefined;
644
+ let auditEngine = false;
631
645
 
632
646
  if (commandRaw === 'watch') {
633
647
  for (const arg of argv.slice(1)) {
@@ -811,6 +825,31 @@ export const parseLifecycleCliArgs = (argv: ReadonlyArray<string>): ParsedArgs =
811
825
  };
812
826
  }
813
827
 
828
+ if (commandRaw === 'audit') {
829
+ for (const arg of argv.slice(1)) {
830
+ if (arg === '--json') {
831
+ json = true;
832
+ continue;
833
+ }
834
+ if (arg === '--engine') {
835
+ auditEngine = true;
836
+ continue;
837
+ }
838
+ if (arg.startsWith('--stage=')) {
839
+ auditStage = parseAuditStage(arg.slice('--stage='.length));
840
+ continue;
841
+ }
842
+ throw new Error(`Unsupported argument "${arg}".\n\n${HELP_TEXT}`);
843
+ }
844
+ return {
845
+ command: commandRaw,
846
+ purgeArtifacts: false,
847
+ json,
848
+ auditStage: auditStage ?? 'PRE_COMMIT',
849
+ ...(auditEngine ? { auditEngine: true } : {}),
850
+ };
851
+ }
852
+
814
853
  if (commandRaw === 'loop') {
815
854
  const subcommandRaw = argv[1] ?? '';
816
855
  if (
@@ -1522,12 +1561,11 @@ const printDoctorReport = (
1522
1561
  writeInfo(
1523
1562
  `[pumuki] hook pre-push: ${report.hookStatus['pre-push'].managedBlockPresent ? 'managed' : 'missing'}`
1524
1563
  );
1525
- printGovernanceConsoleHuman({
1526
- governanceObservation: report.governanceObservation,
1527
- governanceNextAction: report.governanceNextAction,
1528
- policyValidation: report.policyValidation,
1529
- experimentalFeatures: report.experimentalFeatures,
1530
- });
1564
+ writeInfo(
1565
+ `[pumuki] policy-as-code: PRE_COMMIT=${report.policyValidation.stages.PRE_COMMIT.validationCode ?? 'n/a'} strict=${report.policyValidation.stages.PRE_COMMIT.strict ? 'yes' : 'no'} ` +
1566
+ `PRE_PUSH=${report.policyValidation.stages.PRE_PUSH.validationCode ?? 'n/a'} strict=${report.policyValidation.stages.PRE_PUSH.strict ? 'yes' : 'no'} ` +
1567
+ `CI=${report.policyValidation.stages.CI.validationCode ?? 'n/a'} strict=${report.policyValidation.stages.CI.strict ? 'yes' : 'no'}`
1568
+ );
1531
1569
 
1532
1570
  for (const issue of report.issues) {
1533
1571
  writeInfo(`[pumuki] ${issue.severity.toUpperCase()}: ${issue.message}`);
@@ -1560,19 +1598,17 @@ const printDoctorReport = (
1560
1598
  }
1561
1599
  }
1562
1600
 
1563
- const hasBlocking = doctorCommandShouldFailExit(report);
1564
- const hasWarnings = doctorCommandShouldWarnHuman(report);
1601
+ const hasBlocking =
1602
+ doctorHasBlockingIssues(report) || doctorHasParityMismatch(report);
1603
+ const hasWarnings =
1604
+ report.issues.length > 0 ||
1605
+ report.deep?.checks.some((check) => check.status !== 'pass') === true;
1565
1606
 
1566
1607
  if (!hasWarnings && !hasBlocking) {
1567
1608
  writeInfo('[pumuki] doctor verdict: PASS');
1568
1609
  } else {
1569
1610
  writeInfo(`[pumuki] doctor verdict: ${hasBlocking ? 'BLOCKED' : 'WARN'}`);
1570
1611
  }
1571
- if (!hasBlocking && doctorHasGovernanceAttention(report)) {
1572
- writeInfo(
1573
- '[pumuki] doctor: governance_effective is not GREEN (see governance truth).'
1574
- );
1575
- }
1576
1612
 
1577
1613
  if (remoteCiDiagnostics) {
1578
1614
  printRemoteCiDiagnostics(remoteCiDiagnostics);
@@ -1605,12 +1641,6 @@ type PreWriteValidationEnvelope = {
1605
1641
  sdd: SddEvaluateResult;
1606
1642
  ai_gate: ReturnType<typeof evaluateAiGate>;
1607
1643
  pre_write_enforcement: PreWriteEnforcementResolution;
1608
- prewrite_effective: {
1609
- mode: PreWriteEnforcementResolution['mode'];
1610
- source: PreWriteEnforcementResolution['source'];
1611
- blocking: boolean;
1612
- strict_policy: boolean;
1613
- };
1614
1644
  experimental_features: LifecycleExperimentalFeaturesSnapshot;
1615
1645
  policy_validation: LifecyclePolicyValidationSnapshot;
1616
1646
  automation: PreWriteAutomationTrace;
@@ -1621,8 +1651,6 @@ type PreWriteValidationEnvelope = {
1621
1651
  actions: ReadonlyArray<string>;
1622
1652
  details?: string;
1623
1653
  };
1624
- reason_code: string;
1625
- instruction: string;
1626
1654
  next_action?: {
1627
1655
  reason: string;
1628
1656
  command: string;
@@ -1642,10 +1670,19 @@ export type PreWriteOpenSpecBootstrapTrace = {
1642
1670
  details?: string;
1643
1671
  };
1644
1672
 
1645
- export const PRE_WRITE_ENABLE_STRICT_COMMAND =
1646
- `PUMUKI_EXPERIMENTAL_PRE_WRITE=strict ${buildPreWriteValidateCommand({ stage: 'PRE_WRITE' })}`;
1647
- export const buildSddExperimentalEnableAdvisoryCommand = (stage: SddStage): string =>
1648
- `PUMUKI_EXPERIMENTAL_SDD=advisory ${buildPreWriteValidateCommand({ stage })}`;
1673
+ export const buildPreWriteExperimentalEnableAdvisoryCommand = (
1674
+ repoRoot: string = process.cwd()
1675
+ ): string =>
1676
+ `PUMUKI_EXPERIMENTAL_PRE_WRITE=advisory ${buildPinnedPumukiNpxCommand(
1677
+ getCurrentPumukiVersion({ repoRoot })
1678
+ )} sdd validate --stage=PRE_WRITE --json`;
1679
+ export const buildSddExperimentalEnableAdvisoryCommand = (
1680
+ stage: SddStage,
1681
+ repoRoot: string = process.cwd()
1682
+ ): string =>
1683
+ `PUMUKI_EXPERIMENTAL_SDD=advisory ${buildPinnedPumukiNpxCommand(
1684
+ getCurrentPumukiVersion({ repoRoot })
1685
+ )} sdd validate --stage=${stage} --json`;
1649
1686
  const buildAnalyticsExperimentalEnableCommand = (action: AnalyticsHotspotsCommand): string =>
1650
1687
  `PUMUKI_EXPERIMENTAL_ANALYTICS=advisory npx --yes --package pumuki@latest pumuki analytics hotspots ${action} --json`;
1651
1688
  const SAAS_INGESTION_ENABLE_ADVISORY_COMMAND =
@@ -1737,7 +1774,6 @@ const buildSaasIngestionExperimentalDisabledEnvelope = (
1737
1774
  export const buildPreWriteExperimentalDisabledResult = (params: {
1738
1775
  stage: SddStage;
1739
1776
  status: SddEvaluateResult['status'];
1740
- source: 'env' | 'legacy-env' | 'default';
1741
1777
  }): SddEvaluateResult => ({
1742
1778
  stage: params.stage,
1743
1779
  status: params.status,
@@ -1745,16 +1781,14 @@ export const buildPreWriteExperimentalDisabledResult = (params: {
1745
1781
  allowed: true,
1746
1782
  code: 'PRE_WRITE_EXPERIMENTAL_DISABLED',
1747
1783
  message:
1748
- 'PRE_WRITE está desactivado explícitamente. Reactívalo con PUMUKI_EXPERIMENTAL_PRE_WRITE=strict si necesitas recuperar el gate previo a escritura.',
1784
+ 'PRE_WRITE pertenece al namespace experimental y está desactivado por defecto. Actívalo explícitamente con PUMUKI_EXPERIMENTAL_PRE_WRITE=advisory o strict si necesitas este flujo.',
1749
1785
  details: {
1750
1786
  experimental: true,
1751
- default_off: false,
1752
- disabled_explicitly: true,
1753
- disabled_source: params.source,
1787
+ default_off: true,
1754
1788
  layer: 'experimental',
1755
1789
  activation_env: 'PUMUKI_EXPERIMENTAL_PRE_WRITE',
1756
1790
  legacy_activation_env: 'PUMUKI_PREWRITE_ENFORCEMENT',
1757
- activation_command: PRE_WRITE_ENABLE_STRICT_COMMAND,
1791
+ activation_command: PRE_WRITE_ENABLE_ADVISORY_COMMAND,
1758
1792
  },
1759
1793
  },
1760
1794
  });
@@ -1892,25 +1926,6 @@ export const resolvePreWriteBlockedRemediation = (params: {
1892
1926
  return PRE_WRITE_HINTS_BY_CODE[params.causeCode] ?? buildPreWriteDefaultRemediation();
1893
1927
  };
1894
1928
 
1895
- export const buildPreWriteReasonCode = (params: {
1896
- sdd: SddEvaluateResult;
1897
- aiGate: ReturnType<typeof evaluateAiGate>;
1898
- }): string => params.aiGate.violations[0]?.code ?? params.sdd.decision.code;
1899
-
1900
- export const buildPreWriteInstruction = (params: {
1901
- sdd: SddEvaluateResult;
1902
- aiGate: ReturnType<typeof evaluateAiGate>;
1903
- nextAction?: PreWriteValidationEnvelope['next_action'];
1904
- }): string => {
1905
- if (params.nextAction?.command) {
1906
- return `Ejecuta la remediación canónica y vuelve a validar PRE_WRITE: ${params.nextAction.command}`;
1907
- }
1908
- if (!params.sdd.decision.allowed) {
1909
- return `Corrige la decisión SDD ${params.sdd.decision.code} y vuelve a validar PRE_WRITE.`;
1910
- }
1911
- return 'Corrige el bloqueante primario y vuelve a validar PRE_WRITE.';
1912
- };
1913
-
1914
1929
  const wrapPreWritePanelLine = (value: string, width: number): string[] => {
1915
1930
  if (width < 20 || value.length <= width) {
1916
1931
  return [value];
@@ -2046,12 +2061,6 @@ export const buildPreWriteValidationEnvelope = (
2046
2061
  sdd: result,
2047
2062
  ai_gate: aiGate,
2048
2063
  pre_write_enforcement: preWriteEnforcement,
2049
- prewrite_effective: {
2050
- mode: preWriteEnforcement.mode,
2051
- source: preWriteEnforcement.source,
2052
- blocking: preWriteEnforcement.blocking,
2053
- strict_policy: policyValidation.stages.PRE_WRITE.strict,
2054
- },
2055
2064
  experimental_features: experimentalFeatures,
2056
2065
  policy_validation: policyValidation,
2057
2066
  automation: {
@@ -2065,15 +2074,6 @@ export const buildPreWriteValidationEnvelope = (
2065
2074
  actions: [...bootstrap.actions],
2066
2075
  details: bootstrap.details,
2067
2076
  },
2068
- reason_code: buildPreWriteReasonCode({
2069
- sdd: result,
2070
- aiGate,
2071
- }),
2072
- instruction: buildPreWriteInstruction({
2073
- sdd: result,
2074
- aiGate,
2075
- nextAction,
2076
- }),
2077
2077
  next_action: nextAction,
2078
2078
  telemetry: {
2079
2079
  chain: PRE_WRITE_TELEMETRY_CHAIN,
@@ -2179,10 +2179,6 @@ export const runLifecycleCli = async (
2179
2179
  repo_root: installResult.repoRoot,
2180
2180
  version: installResult.version,
2181
2181
  hooks_changed: installResult.changedHooks,
2182
- bootstrap_manifest: {
2183
- path: installResult.bootstrapManifest.path,
2184
- changed: installResult.bootstrapManifest.changed,
2185
- },
2186
2182
  openspec: installResult.openSpecBootstrap
2187
2183
  ? {
2188
2184
  installed: installResult.openSpecBootstrap.packageInstalled,
@@ -2195,10 +2191,6 @@ export const runLifecycleCli = async (
2195
2191
  mcp: {
2196
2192
  agent: adapterResult.agent,
2197
2193
  changed_files: adapterResult.changedFiles,
2198
- bootstrap_manifest: {
2199
- path: adapterResult.bootstrapManifest.path,
2200
- changed: adapterResult.bootstrapManifest.changed,
2201
- },
2202
2194
  adapter_health: adapterCheck
2203
2195
  ? {
2204
2196
  status: adapterCheck.status,
@@ -2225,9 +2217,6 @@ export const runLifecycleCli = async (
2225
2217
  writeInfo(
2226
2218
  `[pumuki] bootstrap install: hooks changed=${installResult.changedHooks.join(', ') || 'none'}`
2227
2219
  );
2228
- writeInfo(
2229
- `[pumuki] bootstrap manifest: path=${installResult.bootstrapManifest.path} changed=${installResult.bootstrapManifest.changed ? 'yes' : 'no'}`
2230
- );
2231
2220
  if (installResult.openSpecBootstrap) {
2232
2221
  writeInfo(
2233
2222
  `[pumuki] bootstrap openspec: installed=${installResult.openSpecBootstrap.packageInstalled ? 'yes' : 'no'} project=${installResult.openSpecBootstrap.projectInitialized ? 'yes' : 'no'} actions=${installResult.openSpecBootstrap.actions.join(', ') || 'none'}`
@@ -2268,9 +2257,6 @@ export const runLifecycleCli = async (
2268
2257
  writeInfo(
2269
2258
  `[pumuki] installed ${result.version} at ${result.repoRoot} (hooks changed: ${result.changedHooks.join(', ') || 'none'})`
2270
2259
  );
2271
- writeInfo(
2272
- `[pumuki] bootstrap manifest: path=${result.bootstrapManifest.path} changed=${result.bootstrapManifest.changed ? 'yes' : 'no'}`
2273
- );
2274
2260
  if (result.openSpecBootstrap) {
2275
2261
  writeInfo(
2276
2262
  `[pumuki] openspec bootstrap: installed=${result.openSpecBootstrap.packageInstalled ? 'yes' : 'no'} project=${result.openSpecBootstrap.projectInitialized ? 'yes' : 'no'} actions=${result.openSpecBootstrap.actions.join(', ') || 'none'}`
@@ -2286,9 +2272,6 @@ export const runLifecycleCli = async (
2286
2272
  writeInfo(
2287
2273
  `[pumuki] mcp wiring: agent=${adapterResult.agent} changed=${adapterResult.changedFiles.length}`
2288
2274
  );
2289
- writeInfo(
2290
- `[pumuki] mcp manifest: path=${adapterResult.bootstrapManifest.path} changed=${adapterResult.bootstrapManifest.changed ? 'yes' : 'no'}`
2291
- );
2292
2275
  if (adapterResult.changedFiles.length > 0) {
2293
2276
  writeInfo(`[pumuki] mcp files: ${adapterResult.changedFiles.join(', ')}`);
2294
2277
  }
@@ -2345,6 +2328,24 @@ export const runLifecycleCli = async (
2345
2328
  );
2346
2329
  return 0;
2347
2330
  }
2331
+ case 'audit': {
2332
+ const result = await runLifecycleAudit({
2333
+ stage: parsed.auditStage ?? 'PRE_COMMIT',
2334
+ auditMode: parsed.auditEngine === true ? 'engine' : 'gate',
2335
+ });
2336
+ if (parsed.json) {
2337
+ writeInfo(JSON.stringify(result, null, 2));
2338
+ } else {
2339
+ writeInfo(
2340
+ `[pumuki] audit: repo=${result.repo_root} stage=${result.stage} mode=${result.audit_mode} exit=${result.gate_exit_code}`
2341
+ );
2342
+ writeInfo(
2343
+ `[pumuki] audit: files_scanned=${result.files_scanned ?? 'n/a'} untracked_matching_extensions=${result.untracked_matching_extensions_count} outcome=${result.snapshot_outcome ?? 'n/a'}`
2344
+ );
2345
+ writeInfo(`[pumuki] audit: hint=${result.policy_reconcile_hint}`);
2346
+ }
2347
+ return result.gate_exit_code;
2348
+ }
2348
2349
  case 'doctor': {
2349
2350
  const report = runLifecycleDoctor({
2350
2351
  deep: parsed.doctorDeep === true,
@@ -2371,7 +2372,7 @@ export const runLifecycleCli = async (
2371
2372
  } else {
2372
2373
  printDoctorReport(report, remoteCiDiagnostics);
2373
2374
  }
2374
- return doctorCommandShouldFailExit(report) ? 1 : 0;
2375
+ return doctorHasBlockingIssues(report) || doctorHasParityMismatch(report) ? 1 : 0;
2375
2376
  }
2376
2377
  case 'status': {
2377
2378
  const status = readLifecycleStatus();
@@ -2424,15 +2425,38 @@ export const runLifecycleCli = async (
2424
2425
  writeInfo(
2425
2426
  `[pumuki] hooks: pre-commit=${status.hookStatus['pre-commit'].managedBlockPresent ? 'managed' : 'missing'}, pre-push=${status.hookStatus['pre-push'].managedBlockPresent ? 'managed' : 'missing'}`
2426
2427
  );
2427
- printGovernanceConsoleHuman({
2428
- governanceObservation: status.governanceObservation,
2429
- governanceNextAction: status.governanceNextAction,
2430
- policyValidation: status.policyValidation,
2431
- experimentalFeatures: status.experimentalFeatures,
2432
- });
2433
2428
  writeInfo(
2434
2429
  `[pumuki] tracked node_modules paths: ${status.trackedNodeModulesCount}`
2435
2430
  );
2431
+ writeInfo(
2432
+ `[pumuki] policy-as-code: PRE_COMMIT=${status.policyValidation.stages.PRE_COMMIT.validationCode ?? 'n/a'} strict=${status.policyValidation.stages.PRE_COMMIT.strict ? 'yes' : 'no'} ` +
2433
+ `PRE_PUSH=${status.policyValidation.stages.PRE_PUSH.validationCode ?? 'n/a'} strict=${status.policyValidation.stages.PRE_PUSH.strict ? 'yes' : 'no'} ` +
2434
+ `CI=${status.policyValidation.stages.CI.validationCode ?? 'n/a'} strict=${status.policyValidation.stages.CI.strict ? 'yes' : 'no'}`
2435
+ );
2436
+ writeInfo(
2437
+ `[pumuki] experimental: ANALYTICS=${status.experimentalFeatures.features.analytics.mode} source=${status.experimentalFeatures.features.analytics.source} layer=${status.experimentalFeatures.features.analytics.layer} blocking=${status.experimentalFeatures.features.analytics.blocking ? 'yes' : 'no'} env=${status.experimentalFeatures.features.analytics.activationVariable}`
2438
+ );
2439
+ writeInfo(
2440
+ `[pumuki] experimental: HEURISTICS=${status.experimentalFeatures.features.heuristics.mode} source=${status.experimentalFeatures.features.heuristics.source} layer=${status.experimentalFeatures.features.heuristics.layer} blocking=${status.experimentalFeatures.features.heuristics.blocking ? 'yes' : 'no'} env=${status.experimentalFeatures.features.heuristics.activationVariable}`
2441
+ );
2442
+ writeInfo(
2443
+ `[pumuki] experimental: LEARNING_CONTEXT=${status.experimentalFeatures.features.learning_context.mode} source=${status.experimentalFeatures.features.learning_context.source} layer=${status.experimentalFeatures.features.learning_context.layer} blocking=${status.experimentalFeatures.features.learning_context.blocking ? 'yes' : 'no'} env=${status.experimentalFeatures.features.learning_context.activationVariable}`
2444
+ );
2445
+ writeInfo(
2446
+ `[pumuki] experimental: MCP_ENTERPRISE=${status.experimentalFeatures.features.mcp_enterprise.mode} source=${status.experimentalFeatures.features.mcp_enterprise.source} layer=${status.experimentalFeatures.features.mcp_enterprise.layer} blocking=${status.experimentalFeatures.features.mcp_enterprise.blocking ? 'yes' : 'no'} env=${status.experimentalFeatures.features.mcp_enterprise.activationVariable}`
2447
+ );
2448
+ writeInfo(
2449
+ `[pumuki] experimental: OPERATIONAL_MEMORY=${status.experimentalFeatures.features.operational_memory.mode} source=${status.experimentalFeatures.features.operational_memory.source} layer=${status.experimentalFeatures.features.operational_memory.layer} blocking=${status.experimentalFeatures.features.operational_memory.blocking ? 'yes' : 'no'} env=${status.experimentalFeatures.features.operational_memory.activationVariable}`
2450
+ );
2451
+ writeInfo(
2452
+ `[pumuki] experimental: PRE_WRITE=${status.experimentalFeatures.features.pre_write.mode} source=${status.experimentalFeatures.features.pre_write.source} layer=${status.experimentalFeatures.features.pre_write.layer} blocking=${status.experimentalFeatures.features.pre_write.blocking ? 'yes' : 'no'} env=${status.experimentalFeatures.features.pre_write.activationVariable}`
2453
+ );
2454
+ writeInfo(
2455
+ `[pumuki] experimental: SAAS_INGESTION=${status.experimentalFeatures.features.saas_ingestion.mode} source=${status.experimentalFeatures.features.saas_ingestion.source} layer=${status.experimentalFeatures.features.saas_ingestion.layer} blocking=${status.experimentalFeatures.features.saas_ingestion.blocking ? 'yes' : 'no'} env=${status.experimentalFeatures.features.saas_ingestion.activationVariable}`
2456
+ );
2457
+ writeInfo(
2458
+ `[pumuki] experimental: SDD=${status.experimentalFeatures.features.sdd.mode} source=${status.experimentalFeatures.features.sdd.source} layer=${status.experimentalFeatures.features.sdd.layer} blocking=${status.experimentalFeatures.features.sdd.blocking ? 'yes' : 'no'} env=${status.experimentalFeatures.features.sdd.activationVariable}`
2459
+ );
2436
2460
  if (remoteCiDiagnostics) {
2437
2461
  printRemoteCiDiagnostics(remoteCiDiagnostics);
2438
2462
  }
@@ -2772,9 +2796,6 @@ export const runLifecycleCli = async (
2772
2796
  `[pumuki] adapter files: ${result.changedFiles.join(', ')}`
2773
2797
  );
2774
2798
  }
2775
- writeInfo(
2776
- `[pumuki] adapter manifest: path=${result.bootstrapManifest.path} changed=${result.bootstrapManifest.changed ? 'yes' : 'no'}`
2777
- );
2778
2799
  }
2779
2800
  return 0;
2780
2801
  }
@@ -36,7 +36,7 @@ import {
36
36
  buildPreWriteExperimentalDisabledResult,
37
37
  buildSddExperimentalEnableAdvisoryCommand,
38
38
  runRawPreWriteAiGateCheck,
39
- PRE_WRITE_ENABLE_STRICT_COMMAND,
39
+ buildPreWriteExperimentalEnableAdvisoryCommand,
40
40
  } from './cli';
41
41
 
42
42
  export const runSddCommand = async (parsed: ParsedArgs, activeDependencies: LifecycleCliDependencies): Promise<number> => {
@@ -84,7 +84,6 @@ export const runSddCommand = async (parsed: ParsedArgs, activeDependencies: Life
84
84
  const disabledResult = buildPreWriteExperimentalDisabledResult({
85
85
  stage: requestedStage,
86
86
  status: readSddStatus(process.cwd()),
87
- source: preWriteEnforcement.source,
88
87
  });
89
88
  if (parsed.json) {
90
89
  writeInfo(
@@ -92,12 +91,6 @@ export const runSddCommand = async (parsed: ParsedArgs, activeDependencies: Life
92
91
  {
93
92
  sdd: disabledResult,
94
93
  pre_write_enforcement: preWriteEnforcement,
95
- prewrite_effective: {
96
- mode: preWriteEnforcement.mode,
97
- source: preWriteEnforcement.source,
98
- blocking: false,
99
- strict_policy: policyValidation.stages.PRE_WRITE.strict,
100
- },
101
94
  experimental_features: experimentalFeatures,
102
95
  policy_validation: policyValidation,
103
96
  automation: {
@@ -111,12 +104,9 @@ export const runSddCommand = async (parsed: ParsedArgs, activeDependencies: Life
111
104
  actions: [],
112
105
  details: 'PRE_WRITE experimental/default-off.',
113
106
  },
114
- reason_code: 'PRE_WRITE_EXPERIMENTAL_DISABLED',
115
- instruction:
116
- `Activa PRE_WRITE en modo estricto y vuelve a ejecutar la validación: ${PRE_WRITE_ENABLE_STRICT_COMMAND}`,
117
107
  next_action: {
118
108
  reason: 'PRE_WRITE_EXPERIMENTAL_DISABLED',
119
- command: PRE_WRITE_ENABLE_STRICT_COMMAND,
109
+ command: buildPreWriteExperimentalEnableAdvisoryCommand(process.cwd()),
120
110
  },
121
111
  },
122
112
  null,
@@ -137,14 +127,7 @@ export const runSddCommand = async (parsed: ParsedArgs, activeDependencies: Life
137
127
  `[pumuki][sdd] pre-write enforcement: mode=${preWriteEnforcement.mode} source=${preWriteEnforcement.source} blocking=no`
138
128
  );
139
129
  writeInfo(
140
- `[pumuki][sdd] prewrite_effective: mode=${preWriteEnforcement.mode} source=${preWriteEnforcement.source} blocking=no strict_policy=${policyValidation.stages.PRE_WRITE.strict ? 'yes' : 'no'}`
141
- );
142
- writeInfo('[pumuki][sdd] reason_code=PRE_WRITE_EXPERIMENTAL_DISABLED');
143
- writeInfo(
144
- `[pumuki][sdd] instruction=Activa PRE_WRITE en modo estricto y vuelve a ejecutar la validación: ${PRE_WRITE_ENABLE_STRICT_COMMAND}`
145
- );
146
- writeInfo(
147
- `[pumuki][sdd] next action (PRE_WRITE_EXPERIMENTAL_DISABLED): ${PRE_WRITE_ENABLE_STRICT_COMMAND}`
130
+ `[pumuki][sdd] next action (PRE_WRITE_EXPERIMENTAL_DISABLED): ${buildPreWriteExperimentalEnableAdvisoryCommand(process.cwd())}`
148
131
  );
149
132
  }
150
133
  return 0;
@@ -226,7 +209,7 @@ export const runSddCommand = async (parsed: ParsedArgs, activeDependencies: Life
226
209
  !aiGate && result.decision.code === 'SDD_EXPERIMENTAL_DISABLED'
227
210
  ? {
228
211
  reason: 'SDD_EXPERIMENTAL_DISABLED',
229
- command: buildSddExperimentalEnableAdvisoryCommand(result.stage),
212
+ command: buildSddExperimentalEnableAdvisoryCommand(result.stage, process.cwd()),
230
213
  }
231
214
  : undefined;
232
215
  if (parsed.json) {
@@ -283,9 +266,6 @@ export const runSddCommand = async (parsed: ParsedArgs, activeDependencies: Life
283
266
  writeInfo(
284
267
  `[pumuki][sdd] pre-write enforcement: mode=${preWriteEnforcement.mode} source=${preWriteEnforcement.source} blocking=${preWriteEnforcement.blocking ? 'yes' : 'no'}`
285
268
  );
286
- writeInfo(
287
- `[pumuki][sdd] prewrite_effective: mode=${preWriteEnforcement.mode} source=${preWriteEnforcement.source} blocking=${preWriteEnforcement.blocking ? 'yes' : 'no'} strict_policy=${policyValidation.stages.PRE_WRITE.strict ? 'yes' : 'no'}`
288
- );
289
269
  if (preWriteBootstrapTrace.details) {
290
270
  writeInfo(
291
271
  `[pumuki][sdd] openspec auto-bootstrap details: ${preWriteBootstrapTrace.details}`
@@ -301,8 +281,6 @@ export const runSddCommand = async (parsed: ParsedArgs, activeDependencies: Life
301
281
  writeInfo(
302
282
  `[pumuki][ai-gate] stage=${aiGate.stage} status=${aiGate.status} violations=${aiGate.violations.length}`
303
283
  );
304
- writeInfo(`[pumuki][ai-gate] reason_code=${aiGate.reason_code}`);
305
- writeInfo(`[pumuki][ai-gate] instruction=${aiGate.instruction}`);
306
284
  for (const violation of aiGate.violations) {
307
285
  writeInfo(
308
286
  withOptionalLocation(