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
@@ -1,248 +0,0 @@
1
- import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs'
2
- import { dirname, join } from 'node:path'
3
- import { getPumukiHooksStatus, resolvePumukiHooksDirectory } from './hookManager'
4
- import { LifecycleGitService, type ILifecycleGitService } from './gitService'
5
- import {
6
- readGovernanceObservationSnapshot,
7
- type GovernanceContractSurface,
8
- type GovernanceObservationSnapshot,
9
- } from './governanceObservationSnapshot'
10
- import { readGovernanceNextAction, type GovernanceNextActionSummary } from './governanceNextAction'
11
- import { getCurrentPumukiPackageName, getCurrentPumukiVersion } from './packageInfo'
12
- import { readLifecycleExperimentalFeaturesSnapshot } from './experimentalFeaturesSnapshot'
13
- import { readLifecyclePolicyValidationSnapshot } from './policyValidationSnapshot'
14
- import { readLifecycleState } from './state'
15
-
16
- export const BOOTSTRAP_MANIFEST_RELATIVE_PATH = '.pumuki/bootstrap-manifest.json'
17
-
18
- type AdapterCommandContract = {
19
- path: string
20
- present: boolean
21
- hooks: {
22
- pre_write?: string
23
- pre_commit?: string
24
- pre_push?: string
25
- ci?: string
26
- }
27
- mcp: {
28
- enterprise?: string
29
- evidence?: string
30
- }
31
- }
32
-
33
- export type LifecycleBootstrapManifest = {
34
- schema_version: '1'
35
- repo_root: string
36
- package: {
37
- name: string
38
- version: string
39
- }
40
- lifecycle: {
41
- installed: boolean
42
- version: string | null
43
- installed_at: string | null
44
- managed_hooks: ReadonlyArray<string>
45
- openspec_managed_artifacts: ReadonlyArray<string>
46
- }
47
- hooks_directory: {
48
- path: string
49
- source: 'git-rev-parse' | 'git-config' | 'default'
50
- }
51
- hook_status: Record<string, { managed_block_present: boolean; exists: boolean }>
52
- contract_surface: GovernanceContractSurface
53
- governance: {
54
- effective: GovernanceObservationSnapshot['governance_effective']
55
- attention_codes: ReadonlyArray<string>
56
- next_action: GovernanceNextActionSummary
57
- bootstrap_hints: ReadonlyArray<string>
58
- }
59
- sdd: {
60
- effective_mode: GovernanceObservationSnapshot['sdd']['effective_mode']
61
- experimental_source: string
62
- session_active: boolean
63
- session_valid: boolean
64
- change_id: string | null
65
- }
66
- policy_strict: GovernanceObservationSnapshot['policy_strict']
67
- git: GovernanceObservationSnapshot['git']
68
- adapter: AdapterCommandContract
69
- }
70
-
71
- export type LifecycleBootstrapManifestWriteResult = {
72
- path: string
73
- changed: boolean
74
- manifest: LifecycleBootstrapManifest
75
- }
76
-
77
- const isRecord = (value: unknown): value is Record<string, unknown> =>
78
- typeof value === 'object' && value !== null && !Array.isArray(value)
79
-
80
- const readOptionalCommand = (source: unknown): string | undefined => {
81
- if (!isRecord(source)) {
82
- return undefined
83
- }
84
- const command = source.command
85
- return typeof command === 'string' && command.trim().length > 0 ? command.trim() : undefined
86
- }
87
-
88
- const readAdapterCommandContract = (repoRoot: string): AdapterCommandContract => {
89
- const path = join(repoRoot, '.pumuki', 'adapter.json')
90
- if (!existsSync(path)) {
91
- return {
92
- path: BOOTSTRAP_MANIFEST_RELATIVE_PATH.replace('bootstrap-manifest.json', 'adapter.json'),
93
- present: false,
94
- hooks: {},
95
- mcp: {},
96
- }
97
- }
98
-
99
- try {
100
- const parsed = JSON.parse(readFileSync(path, 'utf8')) as unknown
101
- const hooks = isRecord(parsed) && isRecord(parsed.hooks) ? parsed.hooks : {}
102
- const mcp = isRecord(parsed) && isRecord(parsed.mcp) ? parsed.mcp : {}
103
- return {
104
- path: '.pumuki/adapter.json',
105
- present: true,
106
- hooks: {
107
- pre_write: readOptionalCommand(isRecord(hooks) ? hooks.pre_write : undefined),
108
- pre_commit: readOptionalCommand(isRecord(hooks) ? hooks.pre_commit : undefined),
109
- pre_push: readOptionalCommand(isRecord(hooks) ? hooks.pre_push : undefined),
110
- ci: readOptionalCommand(isRecord(hooks) ? hooks.ci : undefined),
111
- },
112
- mcp: {
113
- enterprise: readOptionalCommand(isRecord(mcp) ? mcp.enterprise : undefined),
114
- evidence: readOptionalCommand(isRecord(mcp) ? mcp.evidence : undefined),
115
- },
116
- }
117
- } catch {
118
- return {
119
- path: '.pumuki/adapter.json',
120
- present: false,
121
- hooks: {},
122
- mcp: {},
123
- }
124
- }
125
- }
126
-
127
- const parseManagedHooks = (raw?: string): string[] => {
128
- if (typeof raw !== 'string' || raw.trim().length === 0) {
129
- return []
130
- }
131
- return raw
132
- .split(',')
133
- .map((value) => value.trim())
134
- .filter((value) => value.length > 0)
135
- }
136
-
137
- const parseManagedArtifacts = (raw?: string): string[] => {
138
- if (typeof raw !== 'string' || raw.trim().length === 0) {
139
- return []
140
- }
141
- return raw
142
- .split(',')
143
- .map((value) => value.trim())
144
- .filter((value) => value.length > 0)
145
- }
146
-
147
- const toHookStatusSummary = (
148
- hookStatus: ReturnType<typeof getPumukiHooksStatus>
149
- ): Record<string, { managed_block_present: boolean; exists: boolean }> =>
150
- Object.fromEntries(
151
- Object.entries(hookStatus).map(([hook, entry]) => [
152
- hook,
153
- {
154
- managed_block_present: entry.managedBlockPresent,
155
- exists: entry.exists,
156
- },
157
- ])
158
- )
159
-
160
- export const buildLifecycleBootstrapManifest = (params: {
161
- repoRoot: string
162
- git?: ILifecycleGitService
163
- }): LifecycleBootstrapManifest => {
164
- const git = params.git ?? new LifecycleGitService()
165
- const repoRoot = git.resolveRepoRoot(params.repoRoot)
166
- const lifecycleState = readLifecycleState(git, repoRoot)
167
- const experimentalFeatures = readLifecycleExperimentalFeaturesSnapshot()
168
- const policyValidation = readLifecyclePolicyValidationSnapshot(repoRoot)
169
- const governanceObservation = readGovernanceObservationSnapshot({
170
- repoRoot,
171
- experimentalFeatures,
172
- policyValidation,
173
- git,
174
- })
175
- const governanceNextAction = readGovernanceNextAction({
176
- repoRoot,
177
- stage: governanceObservation.evidence.snapshot_stage ?? 'PRE_WRITE',
178
- governanceObservation,
179
- })
180
- const hooksDirectory = resolvePumukiHooksDirectory(repoRoot)
181
- const hookStatus = getPumukiHooksStatus(repoRoot)
182
- const adapter = readAdapterCommandContract(repoRoot)
183
-
184
- return {
185
- schema_version: '1',
186
- repo_root: repoRoot,
187
- package: {
188
- name: getCurrentPumukiPackageName(),
189
- version: getCurrentPumukiVersion({ repoRoot }),
190
- },
191
- lifecycle: {
192
- installed: lifecycleState.installed === 'true',
193
- version: typeof lifecycleState.version === 'string' && lifecycleState.version.length > 0
194
- ? lifecycleState.version
195
- : null,
196
- installed_at:
197
- typeof lifecycleState.installedAt === 'string' && lifecycleState.installedAt.length > 0
198
- ? lifecycleState.installedAt
199
- : null,
200
- managed_hooks: parseManagedHooks(lifecycleState.hooks),
201
- openspec_managed_artifacts: parseManagedArtifacts(lifecycleState.openSpecManagedArtifacts),
202
- },
203
- hooks_directory: hooksDirectory,
204
- hook_status: toHookStatusSummary(hookStatus),
205
- contract_surface: governanceObservation.contract_surface,
206
- governance: {
207
- effective: governanceObservation.governance_effective,
208
- attention_codes: governanceObservation.attention_codes,
209
- next_action: governanceNextAction,
210
- bootstrap_hints: governanceObservation.agent_bootstrap_hints,
211
- },
212
- sdd: {
213
- effective_mode: governanceObservation.sdd.effective_mode,
214
- experimental_source: governanceObservation.sdd.experimental_source,
215
- session_active: governanceObservation.sdd_session.active,
216
- session_valid: governanceObservation.sdd_session.valid,
217
- change_id: governanceObservation.sdd_session.change_id,
218
- },
219
- policy_strict: governanceObservation.policy_strict,
220
- git: governanceObservation.git,
221
- adapter,
222
- }
223
- }
224
-
225
- const serializeManifest = (manifest: LifecycleBootstrapManifest): string =>
226
- `${JSON.stringify(manifest, null, 2)}\n`
227
-
228
- export const writeLifecycleBootstrapManifest = (params: {
229
- repoRoot: string
230
- git?: ILifecycleGitService
231
- }): LifecycleBootstrapManifestWriteResult => {
232
- const git = params.git ?? new LifecycleGitService()
233
- const repoRoot = git.resolveRepoRoot(params.repoRoot)
234
- const path = join(repoRoot, BOOTSTRAP_MANIFEST_RELATIVE_PATH)
235
- const manifest = buildLifecycleBootstrapManifest({ repoRoot, git })
236
- const nextContents = serializeManifest(manifest)
237
- const currentContents = existsSync(path) ? readFileSync(path, 'utf8') : ''
238
- const changed = currentContents !== nextContents
239
- if (changed) {
240
- mkdirSync(dirname(path), { recursive: true })
241
- writeFileSync(path, nextContents, 'utf8')
242
- }
243
- return {
244
- path,
245
- changed,
246
- manifest,
247
- }
248
- }
@@ -1,69 +0,0 @@
1
- import type { LifecycleExperimentalFeaturesSnapshot } from './experimentalFeaturesSnapshot';
2
- import type { GovernanceNextActionSummary } from './governanceNextAction';
3
- import { buildGovernanceNextActionSummaryLines } from './governanceNextAction';
4
- import type { GovernanceObservationSnapshot } from './governanceObservationSnapshot';
5
- import { buildGovernanceObservationSummaryLines } from './governanceObservationSnapshot';
6
- import { writeInfo } from './cliOutputs';
7
- import type { LifecyclePolicyValidationSnapshot } from './policyValidationSnapshot';
8
-
9
- export type GovernanceConsoleSnapshot = {
10
- governanceObservation: GovernanceObservationSnapshot;
11
- governanceNextAction: GovernanceNextActionSummary;
12
- policyValidation: LifecyclePolicyValidationSnapshot;
13
- experimentalFeatures: LifecycleExperimentalFeaturesSnapshot;
14
- };
15
-
16
- const GOVERNANCE_CONSOLE_FEATURE_ORDER = [
17
- 'analytics',
18
- 'heuristics',
19
- 'learning_context',
20
- 'mcp_enterprise',
21
- 'operational_memory',
22
- 'pre_write',
23
- 'saas_ingestion',
24
- 'sdd',
25
- ] as const;
26
-
27
- const buildGovernancePolicySummaryLine = (
28
- policyValidation: LifecyclePolicyValidationSnapshot
29
- ): string =>
30
- `Policy-as-code: PRE_WRITE=${policyValidation.stages.PRE_WRITE.validationCode ?? 'n/a'} strict=${policyValidation.stages.PRE_WRITE.strict ? 'yes' : 'no'} ` +
31
- `PRE_COMMIT=${policyValidation.stages.PRE_COMMIT.validationCode ?? 'n/a'} strict=${policyValidation.stages.PRE_COMMIT.strict ? 'yes' : 'no'} ` +
32
- `PRE_PUSH=${policyValidation.stages.PRE_PUSH.validationCode ?? 'n/a'} strict=${policyValidation.stages.PRE_PUSH.strict ? 'yes' : 'no'} ` +
33
- `CI=${policyValidation.stages.CI.validationCode ?? 'n/a'} strict=${policyValidation.stages.CI.strict ? 'yes' : 'no'}`;
34
-
35
- const buildGovernanceExperimentalSummaryLines = (
36
- experimentalFeatures: LifecycleExperimentalFeaturesSnapshot
37
- ): string[] =>
38
- GOVERNANCE_CONSOLE_FEATURE_ORDER.map((featureKey) => {
39
- const feature = experimentalFeatures.features[featureKey];
40
- return `Experimental: ${featureKey.toUpperCase()}=${feature.mode} source=${feature.source} layer=${feature.layer} blocking=${feature.blocking ? 'yes' : 'no'} env=${feature.activationVariable}`;
41
- });
42
-
43
- export const buildGovernanceConsoleSummaryLines = (
44
- snapshot: GovernanceConsoleSnapshot
45
- ): string[] => {
46
- const lines = ['Governance truth:'];
47
- for (const line of buildGovernanceObservationSummaryLines(snapshot.governanceObservation)) {
48
- lines.push(` ${line}`);
49
- }
50
- for (const hint of snapshot.governanceObservation.evidence.human_summary_preview) {
51
- lines.push(` Evidence hint: ${hint}`);
52
- }
53
- lines.push('Governance next action:');
54
- for (const line of buildGovernanceNextActionSummaryLines(snapshot.governanceNextAction)) {
55
- lines.push(` ${line}`);
56
- }
57
- lines.push(buildGovernancePolicySummaryLine(snapshot.policyValidation));
58
- lines.push(...buildGovernanceExperimentalSummaryLines(snapshot.experimentalFeatures));
59
- return lines;
60
- };
61
-
62
- export const printGovernanceConsoleHuman = (
63
- snapshot: GovernanceConsoleSnapshot
64
- ): void => {
65
- writeInfo('[pumuki] governance console (S1 / shared status-doctor baseline):');
66
- for (const line of buildGovernanceConsoleSummaryLines(snapshot)) {
67
- writeInfo(`[pumuki] ${line}`);
68
- }
69
- };
@@ -1,171 +0,0 @@
1
- import type { AiGateStage } from '../gate/evaluateAiGate';
2
- import { resolveGovernanceCatalogAction } from '../gate/governanceActionCatalog';
3
- import type { GovernanceObservationSnapshot } from './governanceObservationSnapshot';
4
- import { writeInfo } from './cliOutputs';
5
-
6
- export type GovernanceNextActionSummary = {
7
- stage: AiGateStage;
8
- phase: 'GREEN' | 'RED';
9
- action: 'proceed' | 'ask';
10
- confidence_pct: number;
11
- reason_code: string;
12
- instruction: string;
13
- message: string;
14
- next_action: {
15
- kind: 'info' | 'run_command';
16
- message: string;
17
- command?: string;
18
- };
19
- };
20
-
21
- export type GovernanceNextActionReader = (params: {
22
- repoRoot: string;
23
- stage?: AiGateStage;
24
- governanceObservation: GovernanceObservationSnapshot;
25
- }) => GovernanceNextActionSummary;
26
-
27
- const POLICY_ATTENTION_CODE_BY_STAGE: Record<AiGateStage, string> = {
28
- PRE_WRITE: 'POLICY_PRE_WRITE_NOT_STRICT',
29
- PRE_COMMIT: 'POLICY_PRE_COMMIT_NOT_STRICT',
30
- PRE_PUSH: 'POLICY_PRE_PUSH_NOT_STRICT',
31
- CI: 'POLICY_CI_NOT_STRICT',
32
- };
33
-
34
- const resolveBlockedAction = (
35
- snapshot: GovernanceObservationSnapshot,
36
- stage: AiGateStage
37
- ): GovernanceNextActionSummary => {
38
- if (snapshot.attention_codes.includes('EVIDENCE_INVALID_OR_CHAIN')) {
39
- return {
40
- stage,
41
- phase: 'RED',
42
- action: 'ask',
43
- confidence_pct: 80,
44
- ...resolveGovernanceCatalogAction({ code: 'EVIDENCE_INVALID_OR_CHAIN', stage }),
45
- message: 'La evidencia actual no es fiable; detén la ejecución automática hasta regenerarla.',
46
- };
47
- }
48
- if (
49
- snapshot.attention_codes.includes('AI_GATE_BLOCKED')
50
- || snapshot.attention_codes.includes('EVIDENCE_SNAPSHOT_BLOCK')
51
- ) {
52
- return {
53
- stage,
54
- phase: 'RED',
55
- action: 'ask',
56
- confidence_pct: 75,
57
- ...resolveGovernanceCatalogAction({ code: 'AI_GATE_BLOCKED', stage }),
58
- message: 'El gate efectivo sigue bloqueado; Pumuki no debe marcar verde ni dejar continuar.',
59
- };
60
- }
61
- if (snapshot.attention_codes.includes('SDD_SESSION_INVALID_OR_EXPIRED')) {
62
- return {
63
- stage,
64
- phase: 'RED',
65
- action: 'ask',
66
- confidence_pct: 70,
67
- ...resolveGovernanceCatalogAction({ code: 'SDD_SESSION_INVALID_OR_EXPIRED', stage }),
68
- message: 'Hay una sesión SDD activa pero inválida; eso rompe el loop documental esperado.',
69
- };
70
- }
71
- if (snapshot.attention_codes.includes('GITFLOW_PROTECTED_BRANCH_CONTEXT')) {
72
- return {
73
- stage,
74
- phase: 'RED',
75
- action: 'ask',
76
- confidence_pct: 65,
77
- ...resolveGovernanceCatalogAction({ code: 'GITFLOW_PROTECTED_BRANCH_CONTEXT', stage }),
78
- message: 'El contexto actual cae sobre una rama protegida; el flujo enterprise no debe continuar ahí.',
79
- };
80
- }
81
- if (
82
- snapshot.attention_codes.includes(POLICY_ATTENTION_CODE_BY_STAGE[stage])
83
- || snapshot.enterprise_warn_as_block_env
84
- ) {
85
- return {
86
- stage,
87
- phase: 'RED',
88
- action: 'ask',
89
- confidence_pct: 60,
90
- ...resolveGovernanceCatalogAction({ code: 'POLICY_STAGE_NOT_STRICT', stage }),
91
- message: 'La política efectiva todavía no es estricta en todos los stages requeridos.',
92
- };
93
- }
94
- if (!snapshot.contract_surface.skills_lock_json || !snapshot.contract_surface.skills_sources_json) {
95
- return {
96
- stage,
97
- phase: 'RED',
98
- action: 'ask',
99
- confidence_pct: 55,
100
- ...resolveGovernanceCatalogAction({ code: 'SKILLS_CONTRACT_SURFACE_INCOMPLETE', stage }),
101
- message: 'El contrato de skills todavía no está completamente materializado en el repo.',
102
- };
103
- }
104
- if (!snapshot.contract_surface.pumuki_adapter_json) {
105
- return {
106
- stage,
107
- phase: 'RED',
108
- action: 'ask',
109
- confidence_pct: 50,
110
- ...resolveGovernanceCatalogAction({ code: 'ADAPTER_WIRING_MISSING', stage }),
111
- message: 'La línea base Git puede operar, pero el wiring adaptador aún no está materializado.',
112
- };
113
- }
114
- if (snapshot.attention_codes.includes('EVIDENCE_SNAPSHOT_WARN')) {
115
- return {
116
- stage,
117
- phase: 'RED',
118
- action: 'ask',
119
- confidence_pct: 50,
120
- ...resolveGovernanceCatalogAction({ code: 'EVIDENCE_SNAPSHOT_WARN', stage }),
121
- message: 'La evidencia está en WARN; no conviene tratar el repo como completamente verde.',
122
- };
123
- }
124
- return {
125
- stage,
126
- phase: 'RED',
127
- action: 'ask',
128
- confidence_pct: 40,
129
- ...resolveGovernanceCatalogAction({ code: 'GOVERNANCE_ATTENTION', stage }),
130
- message: 'Todavía hay señales de governance no resueltas.',
131
- };
132
- };
133
-
134
- export const readGovernanceNextAction: GovernanceNextActionReader = (params) => {
135
- const stage = params.stage ?? 'PRE_WRITE';
136
- const snapshot = params.governanceObservation;
137
- if (snapshot.governance_effective === 'green') {
138
- return {
139
- stage,
140
- phase: 'GREEN',
141
- action: 'proceed',
142
- confidence_pct: 90,
143
- ...resolveGovernanceCatalogAction({ code: 'READY', stage }),
144
- message: 'Governance efectiva en verde: continúa con la implementación mínima.',
145
- };
146
- }
147
- return resolveBlockedAction(snapshot, stage);
148
- };
149
-
150
- export const buildGovernanceNextActionSummaryLines = (
151
- snapshot: GovernanceNextActionSummary
152
- ): string[] => {
153
- const lines = [
154
- `Next action: stage=${snapshot.stage} phase=${snapshot.phase} action=${snapshot.action} confidence=${snapshot.confidence_pct}% reason=${snapshot.reason_code}`,
155
- `Instruction: ${snapshot.instruction}`,
156
- `Action detail: ${snapshot.next_action.message}`,
157
- ];
158
- if (snapshot.next_action.command) {
159
- lines.push(`Command: ${snapshot.next_action.command}`);
160
- }
161
- return lines;
162
- };
163
-
164
- export const printGovernanceNextActionHuman = (
165
- snapshot: GovernanceNextActionSummary
166
- ): void => {
167
- writeInfo('[pumuki] governance next action (S1 / governance console baseline):');
168
- for (const line of buildGovernanceNextActionSummaryLines(snapshot)) {
169
- writeInfo(`[pumuki] ${line}`);
170
- }
171
- };