pumuki 6.3.97 → 6.3.98

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 (95) hide show
  1. package/AGENTS.md +269 -0
  2. package/CHANGELOG.md +688 -0
  3. package/README.md +4 -2
  4. package/VERSION +1 -1
  5. package/docs/README.md +13 -9
  6. package/docs/operations/RELEASE_NOTES.md +9 -78
  7. package/docs/product/HOW_IT_WORKS.md +6 -0
  8. package/docs/product/INSTALLATION.md +1 -1
  9. package/docs/product/USAGE.md +41 -4
  10. package/docs/tracking/plan-curso-pumuki-stack-my-architecture.md +118 -0
  11. package/docs/validation/README.md +6 -3
  12. package/integrations/config/skillsCustomRules.ts +18 -99
  13. package/integrations/evidence/buildEvidence.ts +0 -24
  14. package/integrations/evidence/repoState.ts +0 -3
  15. package/integrations/evidence/schema.ts +0 -18
  16. package/integrations/evidence/writeEvidence.ts +0 -24
  17. package/integrations/gate/evaluateAiGate.ts +15 -232
  18. package/integrations/gate/remediationCatalog.ts +0 -8
  19. package/integrations/git/GitService.ts +44 -5
  20. package/integrations/git/aiGateRepoPolicyFindings.ts +0 -4
  21. package/integrations/git/runPlatformGate.ts +1 -9
  22. package/integrations/git/runPlatformGateFacts.ts +19 -1
  23. package/integrations/git/runPlatformGateOutput.ts +27 -36
  24. package/integrations/lifecycle/adapter.templates.json +7 -13
  25. package/integrations/lifecycle/adapter.ts +0 -24
  26. package/integrations/lifecycle/artifacts.ts +1 -6
  27. package/integrations/lifecycle/audit.ts +101 -0
  28. package/integrations/lifecycle/cli.ts +110 -70
  29. package/integrations/lifecycle/cliSdd.ts +13 -8
  30. package/integrations/lifecycle/doctor.ts +16 -48
  31. package/integrations/lifecycle/hookManager.ts +0 -77
  32. package/integrations/lifecycle/index.ts +2 -0
  33. package/integrations/lifecycle/install.ts +0 -21
  34. package/integrations/lifecycle/npmService.ts +3 -155
  35. package/integrations/lifecycle/preWriteAutomation.ts +7 -77
  36. package/integrations/lifecycle/state.ts +1 -8
  37. package/integrations/lifecycle/status.ts +2 -29
  38. package/integrations/mcp/aiGateCheck.ts +26 -206
  39. package/integrations/mcp/autoExecuteAiStart.ts +85 -92
  40. package/integrations/mcp/enterpriseServer.ts +7 -23
  41. package/integrations/mcp/enterpriseStdioServer.cli.ts +4 -31
  42. package/integrations/mcp/preFlightCheck.ts +5 -51
  43. package/integrations/platform/detectPlatforms.ts +37 -0
  44. package/integrations/policy/experimentalFeatures.ts +1 -1
  45. package/integrations/sdd/evidenceScaffold.ts +2 -109
  46. package/package.json +10 -2
  47. package/scripts/check-tracking-single-active.sh +1 -1
  48. package/scripts/consumer-menu-matrix-baseline-report-lib.ts +13 -38
  49. package/scripts/consumer-postinstall-resolve-args.cjs +44 -0
  50. package/scripts/consumer-postinstall.cjs +76 -21
  51. package/scripts/framework-menu-advanced-view-lib.ts +0 -15
  52. package/scripts/framework-menu-consumer-actions-lib.ts +28 -4
  53. package/scripts/framework-menu-consumer-preflight-hints.ts +5 -2
  54. package/scripts/framework-menu-consumer-preflight-render.ts +0 -10
  55. package/scripts/framework-menu-consumer-preflight-run.ts +0 -23
  56. package/scripts/framework-menu-consumer-preflight-types.ts +0 -12
  57. package/scripts/framework-menu-consumer-runtime-actions.ts +87 -17
  58. package/scripts/framework-menu-consumer-runtime-audit.ts +36 -2
  59. package/scripts/framework-menu-consumer-runtime-evidence-classic.ts +140 -0
  60. package/scripts/framework-menu-consumer-runtime-lib.ts +2 -10
  61. package/scripts/framework-menu-consumer-runtime-menu.ts +4 -18
  62. package/scripts/framework-menu-consumer-runtime-types.ts +3 -3
  63. package/scripts/framework-menu-evidence-summary-lib.ts +1 -0
  64. package/scripts/framework-menu-evidence-summary-read.ts +57 -5
  65. package/scripts/framework-menu-evidence-summary-severity.ts +3 -1
  66. package/scripts/framework-menu-evidence-summary-types.ts +7 -0
  67. package/scripts/framework-menu-gate-lib.ts +9 -0
  68. package/scripts/framework-menu-layout-data.ts +5 -0
  69. package/scripts/framework-menu-matrix-baseline-lib.ts +15 -14
  70. package/scripts/framework-menu-matrix-canary-lib.ts +22 -1
  71. package/scripts/framework-menu-matrix-evidence-lib.ts +1 -0
  72. package/scripts/framework-menu-matrix-evidence-types.ts +13 -1
  73. package/scripts/framework-menu-matrix-runner-lib.ts +35 -0
  74. package/scripts/framework-menu-system-notifications-cause.ts +0 -24
  75. package/scripts/framework-menu-system-notifications-macos-swift-source.ts +24 -204
  76. package/scripts/framework-menu-system-notifications-macos.ts +4 -0
  77. package/scripts/framework-menu-system-notifications-payloads-blocked.ts +1 -1
  78. package/scripts/framework-menu-system-notifications-remediation.ts +13 -24
  79. package/scripts/framework-menu-system-notifications-text.ts +1 -7
  80. package/scripts/framework-menu.ts +3 -2
  81. package/scripts/package-install-smoke-consumer-git-repo-lib.ts +1 -10
  82. package/scripts/package-install-smoke-consumer-npm-lib.ts +9 -46
  83. package/scripts/pumuki-full-surface-smoke-lib.ts +37 -0
  84. package/scripts/pumuki-full-surface-smoke.ts +346 -0
  85. package/scripts/pumuki-smoke-installed-wrapper.cjs +31 -0
  86. package/integrations/evidence/trackingContract.ts +0 -150
  87. package/integrations/gate/governanceActionCatalog.ts +0 -275
  88. package/integrations/lifecycle/bootstrapManifest.ts +0 -248
  89. package/integrations/lifecycle/cliGovernanceConsole.ts +0 -69
  90. package/integrations/lifecycle/governanceNextAction.ts +0 -164
  91. package/integrations/lifecycle/governanceObservationSnapshot.ts +0 -613
  92. package/integrations/mcp/alignedPlatformGate.ts +0 -232
  93. package/integrations/mcp/readMcpPrePushStdin.ts +0 -7
  94. package/scripts/build-ruralgo-s1-evidence-pack.ts +0 -85
  95. package/scripts/ruralgo-s1-evidence-pack-lib.ts +0 -200
@@ -27,81 +27,6 @@ export type PumukiHooksDirectoryResolution = {
27
27
  };
28
28
 
29
29
  const HOOK_FILE_MODE = 0o755;
30
- const PUMUKI_WORKTREE_HOOKS_PATH = '.pumuki/git-hooks';
31
-
32
- const readLocalGitConfigValue = (repoRoot: string, key: string): string | null => {
33
- try {
34
- const value = execFileSync('git', ['config', '--local', '--get', key], {
35
- cwd: repoRoot,
36
- encoding: 'utf8',
37
- stdio: ['ignore', 'pipe', 'ignore'],
38
- }).trim();
39
- return value.length > 0 ? value : null;
40
- } catch {
41
- return null;
42
- }
43
- };
44
-
45
- const writeLocalGitConfigValue = (repoRoot: string, key: string, value: string): void => {
46
- execFileSync('git', ['config', '--local', key, value], {
47
- cwd: repoRoot,
48
- stdio: ['ignore', 'ignore', 'ignore'],
49
- });
50
- };
51
-
52
- const unsetLocalGitConfigValue = (repoRoot: string, key: string): void => {
53
- try {
54
- execFileSync('git', ['config', '--local', '--unset-all', key], {
55
- cwd: repoRoot,
56
- stdio: ['ignore', 'ignore', 'ignore'],
57
- });
58
- } catch {
59
- // noop
60
- }
61
- };
62
-
63
- const isWorktreeCheckout = (repoRoot: string): boolean => {
64
- try {
65
- const gitPointer = readFileSync(join(repoRoot, '.git'), 'utf8').trim();
66
- return /^gitdir:\s+/i.test(gitPointer);
67
- } catch {
68
- return false;
69
- }
70
- };
71
-
72
- const isPumukiManagedWorktreeHooksPath = (repoRoot: string, hooksPath: string): boolean => {
73
- const normalizedHooksPath = hooksPath.trim();
74
- return (
75
- normalizedHooksPath === PUMUKI_WORKTREE_HOOKS_PATH ||
76
- normalizedHooksPath === resolve(repoRoot, PUMUKI_WORKTREE_HOOKS_PATH)
77
- );
78
- };
79
-
80
- const ensureWorktreeLocalHooksPath = (repoRoot: string): void => {
81
- if (!isWorktreeCheckout(repoRoot)) {
82
- return;
83
- }
84
-
85
- const currentHooksPath = readLocalGitConfigValue(repoRoot, 'core.hooksPath');
86
- if (currentHooksPath) {
87
- return;
88
- }
89
-
90
- writeLocalGitConfigValue(repoRoot, 'core.hooksPath', PUMUKI_WORKTREE_HOOKS_PATH);
91
- };
92
-
93
- const clearWorktreeLocalHooksPath = (repoRoot: string): void => {
94
- if (!isWorktreeCheckout(repoRoot)) {
95
- return;
96
- }
97
-
98
- const currentHooksPath = readLocalGitConfigValue(repoRoot, 'core.hooksPath');
99
- if (!currentHooksPath || !isPumukiManagedWorktreeHooksPath(repoRoot, currentHooksPath)) {
100
- return;
101
- }
102
-
103
- unsetLocalGitConfigValue(repoRoot, 'core.hooksPath');
104
- };
105
30
 
106
31
  const resolveGitPath = (repoRoot: string, gitPathTarget: string): string | null => {
107
32
  try {
@@ -212,7 +137,6 @@ const ensureHooksDirectory = (repoRoot: string): void => {
212
137
  };
213
138
 
214
139
  export const installPumukiHooks = (repoRoot: string): HookInstallResult => {
215
- ensureWorktreeLocalHooksPath(repoRoot);
216
140
  ensureHooksDirectory(repoRoot);
217
141
  const changedHooks: PumukiManagedHook[] = [];
218
142
 
@@ -256,7 +180,6 @@ export const uninstallPumukiHooks = (repoRoot: string): HookUninstallResult => {
256
180
  changedHooks.push(hook);
257
181
  }
258
182
 
259
- clearWorktreeLocalHooksPath(repoRoot);
260
183
  return { changedHooks };
261
184
  };
262
185
 
@@ -1,4 +1,6 @@
1
1
  export { runLifecycleDoctor, doctorHasBlockingIssues } from './doctor';
2
+ export { runLifecycleAudit } from './audit';
3
+ export type { LifecycleAuditResult, LifecycleAuditStage } from './audit';
2
4
  export { runLifecycleInstall } from './install';
3
5
  export { runLifecycleUninstall } from './uninstall';
4
6
  export { runLifecycleRemove } from './remove';
@@ -13,7 +13,6 @@ import { createEmptyEvaluationMetrics } from '../evidence/evaluationMetrics';
13
13
  import { readOpenSpecManagedArtifacts, writeLifecycleState } from './state';
14
14
  import { ensureRuntimeArtifactsIgnored } from './artifacts';
15
15
  import { runLifecycleAdapterInstall } from './adapter';
16
- import { writeLifecycleBootstrapManifest } from './bootstrapManifest';
17
16
 
18
17
  export type LifecycleInstallResult = {
19
18
  repoRoot: string;
@@ -21,10 +20,6 @@ export type LifecycleInstallResult = {
21
20
  changedHooks: ReadonlyArray<string>;
22
21
  openSpecBootstrap?: OpenSpecBootstrapResult;
23
22
  degradedDoctorBypass?: boolean;
24
- bootstrapManifest: {
25
- path: string;
26
- changed: boolean;
27
- };
28
23
  };
29
24
 
30
25
  const shouldBootstrapEvidence = (repoRoot: string): boolean =>
@@ -108,20 +103,12 @@ export const runLifecycleInstall = (params?: {
108
103
  openSpecManagedArtifacts: priorArtifacts.length > 0 ? priorArtifacts : undefined,
109
104
  });
110
105
  ensureRepoBaselineAdapter(report.repoRoot);
111
- const bootstrapManifest = writeLifecycleBootstrapManifest({
112
- git,
113
- repoRoot: report.repoRoot,
114
- });
115
106
  return {
116
107
  repoRoot: report.repoRoot,
117
108
  version,
118
109
  changedHooks,
119
110
  openSpecBootstrap: undefined,
120
111
  degradedDoctorBypass: true,
121
- bootstrapManifest: {
122
- path: bootstrapManifest.path,
123
- changed: bootstrapManifest.changed,
124
- },
125
112
  };
126
113
  }
127
114
  const renderedIssues = report.issues.map((issue) => `- [${issue.severity}] ${issue.message}`).join('\n');
@@ -155,19 +142,11 @@ export const runLifecycleInstall = (params?: {
155
142
  openSpecManagedArtifacts: Array.from(mergedOpenSpecArtifacts),
156
143
  });
157
144
  ensureRepoBaselineAdapter(report.repoRoot);
158
- const bootstrapManifest = writeLifecycleBootstrapManifest({
159
- git,
160
- repoRoot: report.repoRoot,
161
- });
162
145
 
163
146
  return {
164
147
  repoRoot: report.repoRoot,
165
148
  version,
166
149
  changedHooks,
167
150
  openSpecBootstrap,
168
- bootstrapManifest: {
169
- path: bootstrapManifest.path,
170
- changed: bootstrapManifest.changed,
171
- },
172
151
  };
173
152
  };
@@ -1,173 +1,21 @@
1
- import { existsSync, readFileSync } from 'node:fs';
2
- import { join } from 'node:path';
3
1
  import { spawnSync as runSpawnSync } from 'node:child_process';
4
2
 
5
3
  export interface ILifecycleNpmService {
6
4
  runNpm(args: ReadonlyArray<string>, cwd: string): void;
7
5
  }
8
6
 
9
- type LifecyclePackageManager = 'npm' | 'pnpm' | 'yarn';
10
-
11
- type PackageManagerManifest = {
12
- packageManager?: string;
13
- workspaces?: unknown;
14
- };
15
-
16
- const resolvePackageManagerFromManifest = (cwd: string): LifecyclePackageManager | undefined => {
17
- const packageJsonPath = join(cwd, 'package.json');
18
- if (!existsSync(packageJsonPath)) {
19
- return undefined;
20
- }
21
-
22
- try {
23
- const raw = readFileSync(packageJsonPath, 'utf8');
24
- const manifest = JSON.parse(raw) as PackageManagerManifest;
25
- const packageManager = manifest.packageManager?.trim().toLowerCase();
26
- if (!packageManager) {
27
- return undefined;
28
- }
29
- if (packageManager.startsWith('pnpm@')) {
30
- return 'pnpm';
31
- }
32
- if (packageManager.startsWith('yarn@')) {
33
- return 'yarn';
34
- }
35
- if (packageManager.startsWith('npm@')) {
36
- return 'npm';
37
- }
38
- } catch {
39
- return undefined;
40
- }
41
-
42
- return undefined;
43
- };
44
-
45
- export const resolveLifecyclePackageManager = (cwd: string): LifecyclePackageManager => {
46
- const fromManifest = resolvePackageManagerFromManifest(cwd);
47
- if (fromManifest) {
48
- return fromManifest;
49
- }
50
- if (existsSync(join(cwd, 'pnpm-lock.yaml'))) {
51
- return 'pnpm';
52
- }
53
- if (existsSync(join(cwd, 'yarn.lock'))) {
54
- return 'yarn';
55
- }
56
- return 'npm';
57
- };
58
-
59
- const isWorkspaceRoot = (cwd: string): boolean => {
60
- if (existsSync(join(cwd, 'pnpm-workspace.yaml'))) {
61
- return true;
62
- }
63
- const packageJsonPath = join(cwd, 'package.json');
64
- if (!existsSync(packageJsonPath)) {
65
- return false;
66
- }
67
- try {
68
- const raw = readFileSync(packageJsonPath, 'utf8');
69
- const manifest = JSON.parse(raw) as PackageManagerManifest;
70
- return Array.isArray(manifest.workspaces) || typeof manifest.workspaces === 'object';
71
- } catch {
72
- return false;
73
- }
74
- };
75
-
76
- const translateInstallLikeArgs = (
77
- packageManager: Exclude<LifecyclePackageManager, 'npm'>,
78
- args: ReadonlyArray<string>,
79
- cwd: string
80
- ): ReadonlyArray<string> => {
81
- const packageSpecs = args.filter((arg) => !arg.startsWith('-')).slice(1);
82
- if (packageSpecs.length === 0) {
83
- return args;
84
- }
85
-
86
- const useExact = args.includes('--save-exact');
87
- const useDev = args.includes('--save-dev');
88
-
89
- if (packageManager === 'pnpm') {
90
- return [
91
- 'add',
92
- ...(isWorkspaceRoot(cwd) ? ['-w'] : []),
93
- ...(useDev ? ['-D'] : []),
94
- ...(useExact ? ['-E'] : []),
95
- ...packageSpecs,
96
- ];
97
- }
98
-
99
- return [
100
- 'add',
101
- ...(useDev ? ['--dev'] : []),
102
- ...(useExact ? ['--exact'] : []),
103
- ...packageSpecs,
104
- ];
105
- };
106
-
107
- const translateUninstallLikeArgs = (
108
- packageManager: Exclude<LifecyclePackageManager, 'npm'>,
109
- args: ReadonlyArray<string>,
110
- cwd: string
111
- ): ReadonlyArray<string> => {
112
- const packageSpecs = args.filter((arg) => !arg.startsWith('-')).slice(1);
113
- if (packageSpecs.length === 0) {
114
- return args;
115
- }
116
- if (packageManager === 'pnpm') {
117
- return ['remove', ...(isWorkspaceRoot(cwd) ? ['-w'] : []), ...packageSpecs];
118
- }
119
- return ['remove', ...packageSpecs];
120
- };
121
-
122
- export const resolveLifecyclePackageManagerCommand = (
123
- args: ReadonlyArray<string>,
124
- cwd: string
125
- ): {
126
- command: LifecyclePackageManager;
127
- args: ReadonlyArray<string>;
128
- } => {
129
- const packageManager = resolveLifecyclePackageManager(cwd);
130
- if (packageManager === 'npm') {
131
- return {
132
- command: 'npm',
133
- args,
134
- };
135
- }
136
-
137
- const primaryCommand = args[0];
138
- if (primaryCommand === 'install') {
139
- return {
140
- command: packageManager,
141
- args: translateInstallLikeArgs(packageManager, args, cwd),
142
- };
143
- }
144
- if (primaryCommand === 'uninstall') {
145
- return {
146
- command: packageManager,
147
- args: translateUninstallLikeArgs(packageManager, args, cwd),
148
- };
149
- }
150
-
151
- return {
152
- command: packageManager,
153
- args,
154
- };
155
- };
156
-
157
7
  export class LifecycleNpmService implements ILifecycleNpmService {
158
8
  runNpm(args: ReadonlyArray<string>, cwd: string): void {
159
- const execution = resolveLifecyclePackageManagerCommand(args, cwd);
160
- const renderedCommand = `${execution.command} ${execution.args.join(' ')}`.trim();
161
- const result = runSpawnSync(execution.command, execution.args, {
9
+ const result = runSpawnSync('npm', args, {
162
10
  cwd,
163
11
  stdio: 'inherit',
164
12
  env: process.env,
165
13
  });
166
14
  if (result.error) {
167
- throw new Error(`${renderedCommand} failed: ${result.error.message}`);
15
+ throw new Error(`npm ${args.join(' ')} failed: ${result.error.message}`);
168
16
  }
169
17
  if (typeof result.status !== 'number' || result.status !== 0) {
170
- throw new Error(`${renderedCommand} failed with exit code ${result.status ?? 'unknown'}`);
18
+ throw new Error(`npm ${args.join(' ')} failed with exit code ${result.status ?? 'unknown'}`);
171
19
  }
172
20
  }
173
21
  }
@@ -68,24 +68,16 @@ const hasAutoFixableEvidenceViolation = (aiGate: ReturnType<typeof evaluateAiGat
68
68
  const hasEvidenceGateBlockedViolation = (aiGate: ReturnType<typeof evaluateAiGate>): boolean =>
69
69
  aiGate.violations.some((violation) => violation.code === 'EVIDENCE_GATE_BLOCKED');
70
70
 
71
- const hasAdapterMissingViolation = (aiGate: ReturnType<typeof evaluateAiGate>): boolean =>
72
- aiGate.violations.some((violation) => violation.code === 'MCP_ENTERPRISE_ADAPTER_MISSING');
73
-
74
71
  const hasAutoFixableMcpReceiptViolation = (aiGate: ReturnType<typeof evaluateAiGate>): boolean =>
75
- !hasAdapterMissingViolation(aiGate)
76
- && aiGate.violations.some((violation) => PRE_WRITE_AUTOFIXABLE_MCP_RECEIPT_CODES.has(violation.code));
72
+ aiGate.violations.some((violation) => PRE_WRITE_AUTOFIXABLE_MCP_RECEIPT_CODES.has(violation.code));
77
73
 
78
74
  const collectAutoFixableViolationCodes = (aiGate: ReturnType<typeof evaluateAiGate>): string[] =>
79
75
  aiGate.violations
80
- .filter((violation) => {
81
- if (PRE_WRITE_AUTOFIXABLE_EVIDENCE_CODES.has(violation.code)) {
82
- return true;
83
- }
84
- if (!PRE_WRITE_AUTOFIXABLE_MCP_RECEIPT_CODES.has(violation.code)) {
85
- return false;
86
- }
87
- return !hasAdapterMissingViolation(aiGate);
88
- })
76
+ .filter(
77
+ (violation) =>
78
+ PRE_WRITE_AUTOFIXABLE_EVIDENCE_CODES.has(violation.code)
79
+ || PRE_WRITE_AUTOFIXABLE_MCP_RECEIPT_CODES.has(violation.code)
80
+ )
89
81
  .map((violation) => violation.code)
90
82
  .sort((left, right) => left.localeCompare(right));
91
83
 
@@ -106,7 +98,7 @@ export const buildPreWriteAutomationTrace = async (params: {
106
98
  attempted: false,
107
99
  actions: [],
108
100
  };
109
- if (params.sdd.stage !== 'PRE_WRITE') {
101
+ if (params.sdd.stage !== 'PRE_WRITE' || params.aiGate.allowed) {
110
102
  return {
111
103
  aiGate: params.aiGate,
112
104
  trace,
@@ -114,42 +106,6 @@ export const buildPreWriteAutomationTrace = async (params: {
114
106
  }
115
107
 
116
108
  let aiGate = params.aiGate;
117
- if (aiGate.allowed) {
118
- trace.attempted = true;
119
- try {
120
- const gateExitCode = await params.runPlatformGate({
121
- policy: {
122
- stage: 'PRE_COMMIT',
123
- blockOnOrAbove: 'ERROR',
124
- warnOnOrAbove: 'WARN',
125
- },
126
- scope: {
127
- kind: 'workingTree',
128
- },
129
- auditMode: 'gate',
130
- dependencies: {
131
- printGateFindings: () => {},
132
- },
133
- });
134
- trace.actions.push({
135
- action: 'refresh_evidence',
136
- status: 'OK',
137
- details: `stage=PRE_COMMIT runPlatformGate exit_code=${gateExitCode} parity_probe=allowed_initial`,
138
- });
139
- aiGate = activeDependencies.runEnterpriseAiGateCheck({
140
- repoRoot: params.repoRoot,
141
- stage: 'PRE_WRITE',
142
- requireMcpReceipt: true,
143
- }).result;
144
- } catch (error) {
145
- trace.actions.push({
146
- action: 'refresh_evidence',
147
- status: 'FAILED',
148
- details: error instanceof Error ? error.message : 'Unknown PRE_COMMIT parity refresh error',
149
- });
150
- }
151
- }
152
-
153
109
  if (hasAutoFixableEvidenceViolation(aiGate)) {
154
110
  trace.attempted = true;
155
111
  try {
@@ -246,32 +202,6 @@ export const buildPreWriteAutomationTrace = async (params: {
246
202
  stage: 'PRE_WRITE',
247
203
  requireMcpReceipt: true,
248
204
  }).result;
249
- if (aiGate.allowed) {
250
- const gateExitCode = await params.runPlatformGate({
251
- policy: {
252
- stage: 'PRE_COMMIT',
253
- blockOnOrAbove: 'ERROR',
254
- warnOnOrAbove: 'WARN',
255
- },
256
- scope: {
257
- kind: 'workingTree',
258
- },
259
- auditMode: 'gate',
260
- dependencies: {
261
- printGateFindings: () => {},
262
- },
263
- });
264
- trace.actions.push({
265
- action: 'refresh_evidence',
266
- status: 'OK',
267
- details: `stage=PRE_COMMIT runPlatformGate exit_code=${gateExitCode} parity_probe=allowed_after_mcp_receipt_refresh`,
268
- });
269
- aiGate = activeDependencies.runEnterpriseAiGateCheck({
270
- repoRoot: params.repoRoot,
271
- stage: 'PRE_WRITE',
272
- requireMcpReceipt: true,
273
- }).result;
274
- }
275
205
  } catch (error) {
276
206
  trace.actions.push({
277
207
  action: 'refresh_mcp_receipt',
@@ -49,17 +49,10 @@ export const writeLifecycleState = (params: {
49
49
  openSpecManagedArtifacts?: ReadonlyArray<string>;
50
50
  }): void => {
51
51
  const { git, repoRoot, version } = params;
52
- const existingInstalledAt = git.localConfig(repoRoot, PUMUKI_CONFIG_KEYS.installedAt);
53
52
  git.applyLocalConfig(repoRoot, PUMUKI_CONFIG_KEYS.installed, 'true');
54
53
  git.applyLocalConfig(repoRoot, PUMUKI_CONFIG_KEYS.version, version);
55
54
  git.applyLocalConfig(repoRoot, PUMUKI_CONFIG_KEYS.hooks, PUMUKI_MANAGED_HOOKS.join(','));
56
- git.applyLocalConfig(
57
- repoRoot,
58
- PUMUKI_CONFIG_KEYS.installedAt,
59
- typeof existingInstalledAt === 'string' && existingInstalledAt.trim().length > 0
60
- ? existingInstalledAt
61
- : new Date().toISOString()
62
- );
55
+ git.applyLocalConfig(repoRoot, PUMUKI_CONFIG_KEYS.installedAt, new Date().toISOString());
63
56
  if (params.openSpecManagedArtifacts) {
64
57
  const serialized = serializeManagedArtifacts(params.openSpecManagedArtifacts);
65
58
  if (serialized) {
@@ -9,15 +9,6 @@ import {
9
9
  readLifecyclePolicyValidationSnapshot,
10
10
  type LifecyclePolicyValidationSnapshot,
11
11
  } from './policyValidationSnapshot';
12
- import {
13
- readGovernanceObservationSnapshot,
14
- type GovernanceObservationSnapshot,
15
- } from './governanceObservationSnapshot';
16
- import {
17
- readGovernanceNextAction,
18
- type GovernanceNextActionReader,
19
- type GovernanceNextActionSummary,
20
- } from './governanceNextAction';
21
12
  import { readLifecycleState, type LifecycleState } from './state';
22
13
 
23
14
  export type LifecycleStatus = {
@@ -31,14 +22,11 @@ export type LifecycleStatus = {
31
22
  trackedNodeModulesCount: number;
32
23
  policyValidation: LifecyclePolicyValidationSnapshot;
33
24
  experimentalFeatures: LifecycleExperimentalFeaturesSnapshot;
34
- governanceObservation: GovernanceObservationSnapshot;
35
- governanceNextAction: GovernanceNextActionSummary;
36
25
  };
37
26
 
38
27
  export const readLifecycleStatus = (params?: {
39
28
  cwd?: string;
40
29
  git?: ILifecycleGitService;
41
- governanceNextActionReader?: GovernanceNextActionReader;
42
30
  }): LifecycleStatus => {
43
31
  const git = params?.git ?? new LifecycleGitService();
44
32
  const cwd = params?.cwd ?? process.cwd();
@@ -50,19 +38,6 @@ export const readLifecycleStatus = (params?: {
50
38
  repoRoot,
51
39
  lifecycleVersion: lifecycleState.version,
52
40
  });
53
- const policyValidation = readLifecyclePolicyValidationSnapshot(repoRoot);
54
- const experimentalFeatures = readLifecycleExperimentalFeaturesSnapshot();
55
- const governanceObservation = readGovernanceObservationSnapshot({
56
- repoRoot,
57
- experimentalFeatures,
58
- policyValidation,
59
- git,
60
- });
61
- const governanceNextAction = (params?.governanceNextActionReader ?? readGovernanceNextAction)({
62
- repoRoot,
63
- stage: 'PRE_WRITE',
64
- governanceObservation,
65
- });
66
41
 
67
42
  return {
68
43
  repoRoot,
@@ -73,9 +48,7 @@ export const readLifecycleStatus = (params?: {
73
48
  hooksDirectory: hooksDirectory.path,
74
49
  hooksDirectoryResolution: hooksDirectory.source,
75
50
  trackedNodeModulesCount,
76
- policyValidation,
77
- experimentalFeatures,
78
- governanceNextAction,
79
- governanceObservation,
51
+ policyValidation: readLifecyclePolicyValidationSnapshot(repoRoot),
52
+ experimentalFeatures: readLifecycleExperimentalFeaturesSnapshot(),
80
53
  };
81
54
  };