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.
- package/CHANGELOG.md +52 -5
- package/README.md +4 -2
- package/VERSION +1 -1
- package/core/facts/detectors/typescript/index.test.ts +0 -229
- package/core/facts/detectors/typescript/index.ts +0 -278
- package/core/facts/extractHeuristicFacts.ts +0 -4
- package/core/rules/presets/heuristics/typescript.test.ts +1 -21
- package/core/rules/presets/heuristics/typescript.ts +0 -72
- package/docs/README.md +13 -9
- package/docs/codex-skills/backend-enterprise-rules.md +3 -3
- package/docs/operations/RELEASE_NOTES.md +41 -4
- package/docs/product/API_REFERENCE.md +1 -1
- package/docs/product/HOW_IT_WORKS.md +6 -0
- package/docs/product/INSTALLATION.md +1 -1
- package/docs/product/USAGE.md +42 -5
- package/docs/tracking/plan-curso-pumuki-stack-my-architecture.md +100 -44
- package/docs/validation/README.md +6 -3
- package/integrations/config/skillsDetectorRegistry.ts +0 -24
- package/integrations/config/skillsMarkdownRules.ts +0 -57
- package/integrations/evidence/buildEvidence.ts +0 -24
- package/integrations/evidence/repoState.ts +9 -7
- package/integrations/evidence/schema.ts +0 -18
- package/integrations/evidence/writeEvidence.ts +0 -24
- package/integrations/gate/evaluateAiGate.ts +8 -251
- package/integrations/gate/remediationCatalog.ts +0 -8
- package/integrations/git/GitService.ts +44 -5
- package/integrations/git/aiGateRepoPolicyFindings.ts +86 -17
- package/integrations/git/runPlatformGate.ts +1 -9
- package/integrations/git/runPlatformGateFacts.ts +19 -1
- package/integrations/git/runPlatformGateOutput.ts +41 -42
- package/integrations/lifecycle/adapter.templates.json +1 -0
- package/integrations/lifecycle/adapter.ts +0 -24
- package/integrations/lifecycle/audit.ts +101 -0
- package/integrations/lifecycle/cli.ts +120 -99
- package/integrations/lifecycle/cliSdd.ts +4 -26
- package/integrations/lifecycle/doctor.ts +40 -102
- package/integrations/lifecycle/index.ts +2 -0
- package/integrations/lifecycle/install.ts +0 -21
- package/integrations/lifecycle/packageInfo.ts +1 -118
- package/integrations/lifecycle/state.ts +1 -8
- package/integrations/lifecycle/status.ts +40 -59
- package/integrations/lifecycle/watch.ts +1 -1
- package/integrations/mcp/aiGateCheck.ts +10 -194
- package/integrations/mcp/autoExecuteAiStart.ts +116 -92
- package/integrations/mcp/enterpriseServer.ts +7 -23
- package/integrations/mcp/enterpriseStdioServer.cli.ts +4 -31
- package/integrations/mcp/preFlightCheck.ts +5 -67
- package/integrations/platform/detectPlatforms.ts +37 -0
- package/integrations/sdd/policy.ts +28 -20
- package/package.json +1 -1
- package/scripts/check-tracking-single-active.sh +1 -1
- package/scripts/consumer-menu-matrix-baseline-report-lib.ts +13 -38
- package/scripts/consumer-postinstall-resolve-args.cjs +44 -0
- package/scripts/consumer-postinstall.cjs +76 -21
- package/scripts/framework-menu-advanced-view-lib.ts +0 -49
- package/scripts/framework-menu-consumer-actions-lib.ts +28 -4
- package/scripts/framework-menu-consumer-preflight-hints.ts +5 -2
- package/scripts/framework-menu-consumer-preflight-render.ts +0 -10
- package/scripts/framework-menu-consumer-preflight-run.ts +0 -23
- package/scripts/framework-menu-consumer-preflight-types.ts +0 -12
- package/scripts/framework-menu-consumer-runtime-actions.ts +87 -17
- package/scripts/framework-menu-consumer-runtime-audit.ts +36 -2
- package/scripts/framework-menu-consumer-runtime-evidence-classic.ts +140 -0
- package/scripts/framework-menu-consumer-runtime-lib.ts +2 -38
- package/scripts/framework-menu-consumer-runtime-menu.ts +4 -31
- package/scripts/framework-menu-consumer-runtime-types.ts +3 -5
- package/scripts/framework-menu-evidence-summary-lib.ts +1 -0
- package/scripts/framework-menu-evidence-summary-read.ts +57 -5
- package/scripts/framework-menu-evidence-summary-severity.ts +3 -1
- package/scripts/framework-menu-evidence-summary-types.ts +7 -0
- package/scripts/framework-menu-gate-lib.ts +9 -0
- package/scripts/framework-menu-layout-data.ts +5 -0
- package/scripts/framework-menu-matrix-baseline-lib.ts +15 -14
- package/scripts/framework-menu-matrix-canary-lib.ts +22 -1
- package/scripts/framework-menu-matrix-evidence-lib.ts +1 -0
- package/scripts/framework-menu-matrix-evidence-types.ts +13 -1
- package/scripts/framework-menu-matrix-runner-lib.ts +35 -0
- package/scripts/framework-menu-system-notifications-cause.ts +0 -3
- package/scripts/framework-menu-system-notifications-macos-swift-source.ts +24 -204
- package/scripts/framework-menu-system-notifications-macos.ts +4 -0
- package/scripts/framework-menu-system-notifications-payloads-blocked.ts +1 -1
- package/scripts/framework-menu-system-notifications-text.ts +1 -7
- package/scripts/framework-menu.ts +3 -24
- package/scripts/package-install-smoke-consumer-git-repo-lib.ts +1 -10
- package/scripts/package-install-smoke-consumer-npm-lib.ts +9 -46
- package/scripts/pumuki-full-surface-smoke-lib.ts +37 -0
- package/scripts/pumuki-full-surface-smoke.ts +346 -0
- package/scripts/pumuki-smoke-installed-wrapper.cjs +31 -0
- package/integrations/evidence/trackingContract.ts +0 -17
- package/integrations/gate/governanceActionCatalog.ts +0 -275
- package/integrations/lifecycle/bootstrapManifest.ts +0 -248
- package/integrations/lifecycle/cliGovernanceConsole.ts +0 -69
- package/integrations/lifecycle/governanceNextAction.ts +0 -171
- package/integrations/lifecycle/governanceObservationSnapshot.ts +0 -369
- package/integrations/lifecycle/trackingState.ts +0 -403
- package/integrations/mcp/alignedPlatformGate.ts +0 -232
- package/integrations/mcp/readMcpPrePushStdin.ts +0 -7
- package/scripts/build-ruralgo-s1-evidence-pack.ts +0 -85
- 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
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
policyValidation
|
|
1529
|
-
|
|
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 =
|
|
1564
|
-
|
|
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
|
|
1646
|
-
|
|
1647
|
-
|
|
1648
|
-
`
|
|
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
|
|
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:
|
|
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:
|
|
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
|
|
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
|
-
|
|
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:
|
|
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]
|
|
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(
|