pumuki 6.3.49 → 6.3.51
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/README.md +19 -19
- package/core/facts/detectors/text/ios.test.ts +13 -0
- package/core/rules/presets/iosEnterpriseRuleSet.test.ts +46 -0
- package/core/rules/presets/iosEnterpriseRuleSet.ts +4 -2
- package/docs/README.md +42 -63
- package/docs/validation/README.md +25 -31
- package/integrations/git/gitAtomicity.ts +32 -7
- package/integrations/git/runPlatformGate.ts +6 -4
- package/integrations/git/runPlatformGateOutput.ts +2 -2
- package/integrations/git/stageRunners.ts +156 -8
- package/integrations/lifecycle/watch.ts +5 -4
- package/integrations/sdd/evidenceScaffold.ts +6 -2
- package/integrations/sdd/policy.ts +6 -5
- package/package.json +1 -1
- package/scripts/adapter-readiness-markdown-next-actions-lib.ts +1 -1
- package/scripts/build-phase8-ready-handoff-summary.sh +1 -1
- package/scripts/check-refactor-progress-single-active.sh +1 -1
- package/scripts/check-tracking-single-active.sh +19 -2
- package/scripts/close-phase5-escalation-submission.sh +1 -1
- package/scripts/phase5-blockers-markdown-next-actions-blocked-lib.ts +1 -1
- package/docs/API_REFERENCE.md +0 -338
- package/docs/ARCHITECTURE.md +0 -190
- package/docs/BRANCH_PROTECTION_GUIDE.md +0 -50
- package/docs/CODE_STANDARDS.md +0 -73
- package/docs/CONFIGURATION.md +0 -366
- package/docs/CONTRIBUTING.md +0 -92
- package/docs/DEPENDENCIES.md +0 -54
- package/docs/HOW_IT_WORKS.md +0 -160
- package/docs/INSTALLATION.md +0 -270
- package/docs/MCP_AGENT_CONTEXT_CONSUMPTION.md +0 -188
- package/docs/MCP_EVIDENCE_CONTEXT_SERVER.md +0 -244
- package/docs/MCP_SERVERS.md +0 -280
- package/docs/OPERATIONS.md +0 -74
- package/docs/README_MENU_WALKTHROUGH.md +0 -65
- package/docs/RELEASE_NOTES.md +0 -562
- package/docs/TESTING.md +0 -114
- package/docs/USAGE.md +0 -749
- package/docs/evidence-v2.1.md +0 -98
- package/docs/registro-maestro-de-seguimiento.md +0 -20
- package/docs/seguimiento-activo-pumuki-saas-supermercados.md +0 -2591
- package/docs/seguimiento-completo-validacion-ruralgo-03-03-2026.md +0 -2507
- package/docs/validation/c022-phase-acceptance-contract.md +0 -172
- /package/docs/validation/{adapter-hook-runtime-validation.md → adapter-hook-runtime-runbook.md} +0 -0
- /package/docs/validation/{skills-rollout-consumer-repositories.md → consumer-repositories-skills-rollout-validation.md} +0 -0
- /package/docs/validation/{detection-audit-baseline.md → full-repo-detection-audit-baseline.md} +0 -0
package/README.md
CHANGED
|
@@ -337,13 +337,13 @@ Important:
|
|
|
337
337
|
|
|
338
338
|
Extended annotated walkthrough:
|
|
339
339
|
|
|
340
|
-
- `docs/
|
|
340
|
+
- `docs/operations/framework-menu-option-1-walkthrough.md`
|
|
341
341
|
|
|
342
342
|
## Enterprise Operations Baseline
|
|
343
343
|
|
|
344
344
|
Pumuki production SaaS operation baseline is defined in:
|
|
345
345
|
|
|
346
|
-
- `docs/OPERATIONS.md`
|
|
346
|
+
- `docs/operations/OPERATIONS.md`
|
|
347
347
|
|
|
348
348
|
Highlights:
|
|
349
349
|
|
|
@@ -363,29 +363,29 @@ Highlights:
|
|
|
363
363
|
|
|
364
364
|
## Documentation Index
|
|
365
365
|
|
|
366
|
-
- Installation: `docs/INSTALLATION.md`
|
|
367
|
-
- Usage: `docs/USAGE.md`
|
|
368
|
-
- Backlog tooling quick nav (incluye snippet terminal): `docs/USAGE.md#backlog-tooling`
|
|
369
|
-
- Backlog reasons shared module: `docs/USAGE.md#backlog-reasons`
|
|
370
|
-
- Testing: `docs/TESTING.md`
|
|
371
|
-
- API reference: `docs/API_REFERENCE.md`
|
|
372
|
-
- Architecture: `docs/ARCHITECTURE.md`
|
|
373
|
-
- Configuration: `docs/CONFIGURATION.md`
|
|
374
|
-
- Code standards: `docs/CODE_STANDARDS.md`
|
|
375
|
-
- Branch protection: `docs/BRANCH_PROTECTION_GUIDE.md`
|
|
376
|
-
- MCP servers: `docs/MCP_SERVERS.md`
|
|
377
|
-
- MCP evidence server: `docs/MCP_EVIDENCE_CONTEXT_SERVER.md`
|
|
378
|
-
- MCP consumption: `docs/MCP_AGENT_CONTEXT_CONSUMPTION.md`
|
|
379
|
-
- Evidence schema v2.1: `docs/evidence-v2.1.md`
|
|
380
|
-
- Operations policy (SLA/SLO): `docs/OPERATIONS.md`
|
|
381
|
-
- Release notes: `docs/RELEASE_NOTES.md`
|
|
366
|
+
- Installation: `docs/product/INSTALLATION.md`
|
|
367
|
+
- Usage: `docs/product/USAGE.md`
|
|
368
|
+
- Backlog tooling quick nav (incluye snippet terminal): `docs/product/USAGE.md#backlog-tooling`
|
|
369
|
+
- Backlog reasons shared module: `docs/product/USAGE.md#backlog-reasons`
|
|
370
|
+
- Testing: `docs/product/TESTING.md`
|
|
371
|
+
- API reference: `docs/product/API_REFERENCE.md`
|
|
372
|
+
- Architecture: `docs/product/ARCHITECTURE.md`
|
|
373
|
+
- Configuration: `docs/product/CONFIGURATION.md`
|
|
374
|
+
- Code standards: `docs/governance/CODE_STANDARDS.md`
|
|
375
|
+
- Branch protection: `docs/governance/BRANCH_PROTECTION_GUIDE.md`
|
|
376
|
+
- MCP servers: `docs/mcp/MCP_SERVERS.md`
|
|
377
|
+
- MCP evidence server: `docs/mcp/MCP_EVIDENCE_CONTEXT_SERVER.md`
|
|
378
|
+
- MCP consumption: `docs/mcp/MCP_AGENT_CONTEXT_CONSUMPTION.md`
|
|
379
|
+
- Evidence schema v2.1: `docs/mcp/ai-evidence-v2.1-contract.md`
|
|
380
|
+
- Operations policy (SLA/SLO): `docs/operations/OPERATIONS.md`
|
|
381
|
+
- Release notes: `docs/operations/RELEASE_NOTES.md`
|
|
382
382
|
- Changelog: `CHANGELOG.md`
|
|
383
383
|
|
|
384
384
|
## Collaboration
|
|
385
385
|
|
|
386
386
|
Contributions are welcome. For high-quality collaboration:
|
|
387
387
|
|
|
388
|
-
1. Read `docs/CONTRIBUTING.md` and `docs/CODE_STANDARDS.md`.
|
|
388
|
+
1. Read `docs/governance/CONTRIBUTING.md` and `docs/governance/CODE_STANDARDS.md`.
|
|
389
389
|
2. Create a dedicated branch per change.
|
|
390
390
|
3. Keep scope focused and include deterministic evidence when relevant.
|
|
391
391
|
4. Before opening a PR, run at least:
|
|
@@ -37,6 +37,19 @@ let flag = value!!
|
|
|
37
37
|
assert.equal(hasSwiftForceUnwrap(source), false);
|
|
38
38
|
});
|
|
39
39
|
|
|
40
|
+
test('hasSwiftForceUnwrap excluye comparaciones seguras contra nil', () => {
|
|
41
|
+
const source = `
|
|
42
|
+
if ProcessInfo.processInfo.environment["SIMULATOR_UDID"] != nil {
|
|
43
|
+
return
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
if waitersByKey[key] != nil {
|
|
47
|
+
consume()
|
|
48
|
+
}
|
|
49
|
+
`;
|
|
50
|
+
assert.equal(hasSwiftForceUnwrap(source), false);
|
|
51
|
+
});
|
|
52
|
+
|
|
40
53
|
test('hasSwiftAnyViewUsage detecta AnyView en codigo real', () => {
|
|
41
54
|
const source = `
|
|
42
55
|
func render() -> some View {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import assert from 'node:assert/strict';
|
|
2
2
|
import test from 'node:test';
|
|
3
3
|
import { iosEnterpriseRuleSet } from './iosEnterpriseRuleSet';
|
|
4
|
+
import { evaluateRules } from '../../gate/evaluateRules';
|
|
4
5
|
|
|
5
6
|
test('iosEnterpriseRuleSet define reglas locked para plataforma ios', () => {
|
|
6
7
|
assert.equal(iosEnterpriseRuleSet.length, 8);
|
|
@@ -23,6 +24,8 @@ test('iosEnterpriseRuleSet define reglas locked para plataforma ios', () => {
|
|
|
23
24
|
assert.equal(byId.get('ios.no-gcd')?.severity, 'CRITICAL');
|
|
24
25
|
assert.equal(byId.get('ios.tdd.domain-changes-require-tests')?.when.kind, 'All');
|
|
25
26
|
assert.equal(byId.get('ios.no-completion-handlers-outside-bridges')?.when.kind, 'Any');
|
|
27
|
+
assert.equal(byId.get('ios.no-force-unwrap')?.when.kind, 'All');
|
|
28
|
+
assert.equal(byId.get('ios.no-force-unwrap')?.when.conditions[0]?.kind, 'Heuristic');
|
|
26
29
|
|
|
27
30
|
for (const rule of iosEnterpriseRuleSet) {
|
|
28
31
|
assert.equal(rule.platform, 'ios');
|
|
@@ -31,3 +34,46 @@ test('iosEnterpriseRuleSet define reglas locked para plataforma ios', () => {
|
|
|
31
34
|
assert.ok(rule.scope?.include?.includes('**/*.swift'));
|
|
32
35
|
}
|
|
33
36
|
});
|
|
37
|
+
|
|
38
|
+
test('ios.no-force-unwrap no bloquea comparaciones seguras != nil', () => {
|
|
39
|
+
const rule = iosEnterpriseRuleSet.find((candidate) => candidate.id === 'ios.no-force-unwrap');
|
|
40
|
+
assert.ok(rule);
|
|
41
|
+
|
|
42
|
+
const findings = evaluateRules([rule], [
|
|
43
|
+
{
|
|
44
|
+
kind: 'FileContent',
|
|
45
|
+
path: 'apps/ios/Sources/ListRouting/Application/UseCases/SyncShoppingListUseCase.swift',
|
|
46
|
+
content: 'if waitersByKey[key] != nil { consume() }',
|
|
47
|
+
source: 'unit-test',
|
|
48
|
+
},
|
|
49
|
+
]);
|
|
50
|
+
|
|
51
|
+
assert.deepEqual(findings, []);
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
test('ios.no-force-unwrap bloquea cuando la heuristica detecta force unwrap real', () => {
|
|
55
|
+
const rule = iosEnterpriseRuleSet.find((candidate) => candidate.id === 'ios.no-force-unwrap');
|
|
56
|
+
assert.ok(rule);
|
|
57
|
+
|
|
58
|
+
const findings = evaluateRules([rule], [
|
|
59
|
+
{
|
|
60
|
+
kind: 'FileContent',
|
|
61
|
+
path: 'apps/ios/Sources/ListRouting/Application/UseCases/SyncShoppingListUseCase.swift',
|
|
62
|
+
content: 'let user = repository.currentUser!',
|
|
63
|
+
source: 'unit-test',
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
kind: 'Heuristic',
|
|
67
|
+
ruleId: 'heuristics.ios.force-unwrap.ast',
|
|
68
|
+
severity: 'WARN',
|
|
69
|
+
code: 'HEURISTICS_IOS_FORCE_UNWRAP_AST',
|
|
70
|
+
message: 'AST heuristic detected force unwrap usage.',
|
|
71
|
+
filePath: 'apps/ios/Sources/ListRouting/Application/UseCases/SyncShoppingListUseCase.swift',
|
|
72
|
+
source: 'heuristics:ast',
|
|
73
|
+
},
|
|
74
|
+
]);
|
|
75
|
+
|
|
76
|
+
assert.equal(findings.length, 1);
|
|
77
|
+
assert.equal(findings[0]?.ruleId, 'ios.no-force-unwrap');
|
|
78
|
+
assert.equal(findings[0]?.code, 'IOS_NO_FORCE_UNWRAP');
|
|
79
|
+
});
|
|
@@ -153,8 +153,10 @@ export const iosEnterpriseRuleSet: RuleSet = [
|
|
|
153
153
|
kind: 'All',
|
|
154
154
|
conditions: [
|
|
155
155
|
{
|
|
156
|
-
kind: '
|
|
157
|
-
|
|
156
|
+
kind: 'Heuristic',
|
|
157
|
+
where: {
|
|
158
|
+
ruleId: 'heuristics.ios.force-unwrap.ast',
|
|
159
|
+
},
|
|
158
160
|
},
|
|
159
161
|
{
|
|
160
162
|
kind: 'Not',
|
package/docs/README.md
CHANGED
|
@@ -1,78 +1,57 @@
|
|
|
1
1
|
# Documentation Index
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Mapa corto y humano de la documentación oficial de Pumuki.
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## Estructura
|
|
6
6
|
|
|
7
|
-
-
|
|
8
|
-
-
|
|
9
|
-
-
|
|
7
|
+
- `docs/product/`
|
|
8
|
+
- Manual funcional y técnico del producto.
|
|
9
|
+
- Archivos clave: `ARCHITECTURE.md`, `HOW_IT_WORKS.md`, `API_REFERENCE.md`, `INSTALLATION.md`, `USAGE.md`, `CONFIGURATION.md`, `DEPENDENCIES.md`, `TESTING.md`.
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
- `docs/governance/`
|
|
12
|
+
- Reglas de contribución y gobierno del repo.
|
|
13
|
+
- Archivos clave: `CODE_STANDARDS.md`, `CONTRIBUTING.md`, `BRANCH_PROTECTION_GUIDE.md`.
|
|
12
14
|
|
|
13
|
-
- `docs/
|
|
14
|
-
-
|
|
15
|
-
- `
|
|
15
|
+
- `docs/mcp/`
|
|
16
|
+
- Contratos MCP, evidence y consumo por agentes.
|
|
17
|
+
- Archivos clave: `MCP_SERVERS.md`, `MCP_EVIDENCE_CONTEXT_SERVER.md`, `MCP_AGENT_CONTEXT_CONSUMPTION.md`, `ai-evidence-v2.1-contract.md`.
|
|
16
18
|
|
|
17
|
-
|
|
19
|
+
- `docs/operations/`
|
|
20
|
+
- Operación diaria, walkthroughs y notas de release.
|
|
21
|
+
- Archivos clave: `OPERATIONS.md`, `framework-menu-option-1-walkthrough.md`, `RELEASE_NOTES.md`.
|
|
18
22
|
|
|
19
|
-
- `docs/
|
|
20
|
-
-
|
|
21
|
-
- `docs/
|
|
22
|
-
- `docs/CONFIGURATION.md`: runtime and repository configuration.
|
|
23
|
-
- `docs/CODE_STANDARDS.md`: coding standards for framework contributors.
|
|
24
|
-
- `docs/CONTRIBUTING.md`: contribution workflow.
|
|
25
|
-
- `docs/DEPENDENCIES.md`: dependency policy and maintenance.
|
|
26
|
-
- `docs/TESTING.md`: test strategy and validation commands.
|
|
27
|
-
- `docs/BRANCH_PROTECTION_GUIDE.md`: branch protection baseline.
|
|
28
|
-
- `docs/README_MENU_WALKTHROUGH.md`: visual walkthrough of menu Option 1 flow.
|
|
23
|
+
- `docs/validation/`
|
|
24
|
+
- Runbooks y contratos estables de validación.
|
|
25
|
+
- Punto de entrada: `docs/validation/README.md`.
|
|
29
26
|
|
|
30
|
-
|
|
27
|
+
- `docs/rule-packs/`
|
|
28
|
+
- Packs de reglas oficiales por ámbito.
|
|
31
29
|
|
|
32
|
-
- `docs/
|
|
33
|
-
-
|
|
34
|
-
- `docs/MCP_SERVERS.md`: MCP integration overview.
|
|
35
|
-
- `docs/MCP_AGENT_CONTEXT_CONSUMPTION.md`: deterministic MCP consumption model.
|
|
30
|
+
- `docs/codex-skills/`
|
|
31
|
+
- Skills vendorizadas que el repo usa como contrato local.
|
|
36
32
|
|
|
37
|
-
|
|
33
|
+
- `docs/tracking/`
|
|
34
|
+
- Seguimiento permitido y solo el imprescindible.
|
|
35
|
+
- Maestro: `docs/tracking/maestro-de-seguimiento.md`
|
|
36
|
+
- Plan activo: `docs/tracking/plan-activo-pumuki.md`
|
|
37
|
+
- Históricos técnicos permitidos:
|
|
38
|
+
- `docs/tracking/historico-validacion-ruralgo-03-03-2026.md`
|
|
39
|
+
- `docs/tracking/historico-c022-contrato-aceptacion.md`
|
|
40
|
+
- Regla hard: solo puede existir una tarea `🚧` en el plan activo.
|
|
38
41
|
|
|
39
|
-
|
|
40
|
-
- `docs/rule-packs/engineering-baseline.md`
|
|
41
|
-
- `docs/rule-packs/ios.md`
|
|
42
|
-
- `docs/rule-packs/backend.md`
|
|
43
|
-
- `docs/rule-packs/frontend.md`
|
|
44
|
-
- `docs/rule-packs/android.md`
|
|
45
|
-
- `docs/rule-packs/heuristics.md`
|
|
42
|
+
## Fuera de `docs/`
|
|
46
43
|
|
|
47
|
-
|
|
44
|
+
- Gobierno raíz:
|
|
45
|
+
- `README.md`
|
|
46
|
+
- `ARCHITECTURE.md`
|
|
47
|
+
- `CHANGELOG.md`
|
|
48
|
+
- `AGENTS.md`
|
|
49
|
+
- `PUMUKI.md`
|
|
48
50
|
|
|
49
|
-
|
|
50
|
-
- `docs/validation/adapter-hook-runtime-validation.md`
|
|
51
|
-
- `docs/validation/ast-intelligence-roadmap.md`
|
|
52
|
-
- `docs/validation/c022-phase-acceptance-contract.md`
|
|
53
|
-
- `docs/validation/enterprise-consumer-isolation-policy.md`
|
|
54
|
-
- `docs/validation/mock-consumer-integration-runbook.md`
|
|
55
|
-
- `docs/validation/detection-audit-baseline.md`
|
|
56
|
-
- `docs/validation/skills-rollout-consumer-repositories.md`
|
|
51
|
+
## Lo que no se conserva
|
|
57
52
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
-
|
|
61
|
-
-
|
|
62
|
-
-
|
|
63
|
-
- `docs/codex-skills/windsurf-rules-backend.md`
|
|
64
|
-
- `docs/codex-skills/windsurf-rules-frontend.md`
|
|
65
|
-
- `docs/codex-skills/windsurf-rules-ios.md`
|
|
66
|
-
|
|
67
|
-
## Releases
|
|
68
|
-
|
|
69
|
-
- `docs/RELEASE_NOTES.md`
|
|
70
|
-
- `CHANGELOG.md`
|
|
71
|
-
|
|
72
|
-
## Root-Level Governance Docs
|
|
73
|
-
|
|
74
|
-
- `README.md`
|
|
75
|
-
- `ARCHITECTURE.md`
|
|
76
|
-
- `CHANGELOG.md`
|
|
77
|
-
- `AGENTS.md`
|
|
78
|
-
- `PUMUKI.md`
|
|
53
|
+
- No se guardan en `docs/` reportes ad-hoc de ejecución.
|
|
54
|
+
- Los artefactos efímeros se limpian al cerrar ciclo:
|
|
55
|
+
- `.audit-reports/**`
|
|
56
|
+
- `.coverage/**`
|
|
57
|
+
- `.ai_evidence.json`
|
|
@@ -1,42 +1,36 @@
|
|
|
1
|
-
# Validation Docs
|
|
1
|
+
# Validation Docs
|
|
2
2
|
|
|
3
|
-
Este directorio contiene solo documentación
|
|
3
|
+
Este directorio contiene solo documentación estable de validación y runbooks oficiales.
|
|
4
4
|
|
|
5
|
-
## Documentación
|
|
5
|
+
## Documentación vigente
|
|
6
6
|
|
|
7
|
-
- `adapter-hook-runtime-
|
|
7
|
+
- `adapter-hook-runtime-runbook.md`
|
|
8
8
|
- `ast-intelligence-roadmap.md`
|
|
9
|
-
- `
|
|
10
|
-
- `detection-audit-baseline.md`
|
|
9
|
+
- `full-repo-detection-audit-baseline.md`
|
|
11
10
|
- `enterprise-consumer-isolation-policy.md`
|
|
12
11
|
- `mock-consumer-integration-runbook.md`
|
|
13
|
-
- `skills-rollout-
|
|
12
|
+
- `consumer-repositories-skills-rollout-validation.md`
|
|
14
13
|
|
|
15
|
-
## Estado
|
|
14
|
+
## Estado de seguimiento
|
|
16
15
|
|
|
17
|
-
-
|
|
18
|
-
- Plan activo: `docs/
|
|
19
|
-
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
- `telemetry-rotation`
|
|
16
|
+
- Maestro: `docs/tracking/maestro-de-seguimiento.md`
|
|
17
|
+
- Plan activo: `docs/tracking/plan-activo-pumuki.md`
|
|
18
|
+
- Histórico permitido: `docs/tracking/historico-validacion-ruralgo-03-03-2026.md`
|
|
19
|
+
|
|
20
|
+
## Histórico técnico conservado
|
|
21
|
+
|
|
22
|
+
- `docs/tracking/historico-c022-contrato-aceptacion.md`
|
|
25
23
|
|
|
26
24
|
## Política de higiene
|
|
27
25
|
|
|
28
|
-
-
|
|
29
|
-
-
|
|
30
|
-
-
|
|
31
|
-
-
|
|
32
|
-
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
- El cierre de `C025` (auditoría exhaustiva de funcionalidades + reglas) quedó consolidado en:
|
|
40
|
-
- `docs/seguimiento-completo-validacion-ruralgo-03-03-2026.md` (estado, evidencia y cierre del bloque P5).
|
|
41
|
-
- El cierre de `P6` (verificación exhaustiva real/mock) quedó consolidado en:
|
|
42
|
-
- `docs/seguimiento-completo-validacion-ruralgo-03-03-2026.md` (checklist unificada, veredicto y transición).
|
|
26
|
+
- `docs/validation/` no guarda reportes temporales.
|
|
27
|
+
- Los artefactos efímeros se generan fuera de `docs/` y deben limpiarse antes de cerrar un ciclo:
|
|
28
|
+
- `.audit-reports/**`
|
|
29
|
+
- `.coverage/**`
|
|
30
|
+
- `.ai_evidence.json`
|
|
31
|
+
- La evidencia histórica que sí aporta contexto se consolida en documentación estable o en el histórico permitido.
|
|
32
|
+
|
|
33
|
+
## Comprobaciones útiles
|
|
34
|
+
|
|
35
|
+
- Suite contractual enterprise: `npm run -s validation:contract-suite:enterprise`
|
|
36
|
+
- Verificación de plan activo único: `npm run -s validation:tracking-single-active`
|
|
@@ -172,6 +172,26 @@ const resolveScopeKey = (filePath: string): string => {
|
|
|
172
172
|
return segments[0] ?? '';
|
|
173
173
|
};
|
|
174
174
|
|
|
175
|
+
const collectScopePaths = (
|
|
176
|
+
changedPaths: ReadonlyArray<string>
|
|
177
|
+
): ReadonlyMap<string, ReadonlyArray<string>> => {
|
|
178
|
+
const buckets = new Map<string, Array<string>>();
|
|
179
|
+
for (const path of changedPaths) {
|
|
180
|
+
const scope = resolveScopeKey(path);
|
|
181
|
+
if (scope.length === 0) {
|
|
182
|
+
continue;
|
|
183
|
+
}
|
|
184
|
+
const current = buckets.get(scope) ?? [];
|
|
185
|
+
current.push(path.replace(/\\/g, '/'));
|
|
186
|
+
buckets.set(scope, current);
|
|
187
|
+
}
|
|
188
|
+
const normalized = new Map<string, ReadonlyArray<string>>();
|
|
189
|
+
for (const [scope, paths] of buckets.entries()) {
|
|
190
|
+
normalized.set(scope, [...new Set(paths)].sort());
|
|
191
|
+
}
|
|
192
|
+
return normalized;
|
|
193
|
+
};
|
|
194
|
+
|
|
175
195
|
const collectChangedPaths = (params: {
|
|
176
196
|
git: IGitService;
|
|
177
197
|
repoRoot: string;
|
|
@@ -259,25 +279,30 @@ export const evaluateGitAtomicity = (params: {
|
|
|
259
279
|
});
|
|
260
280
|
}
|
|
261
281
|
|
|
262
|
-
const
|
|
263
|
-
|
|
264
|
-
.map((filePath) => resolveScopeKey(filePath))
|
|
265
|
-
.filter((scopeKey) => scopeKey.length > 0)
|
|
266
|
-
);
|
|
282
|
+
const scopePaths = collectScopePaths(changedPaths);
|
|
283
|
+
const scopeKeys = new Set(scopePaths.keys());
|
|
267
284
|
if (scopeKeys.size > config.maxScopes) {
|
|
268
285
|
const sortedScopes = [...scopeKeys].sort();
|
|
269
286
|
const suggestedScopeAdds = sortedScopes
|
|
270
287
|
.slice(0, Math.max(1, Math.min(config.maxScopes + 1, 3)))
|
|
271
288
|
.map((scope) => `git add ${scope}/`)
|
|
272
289
|
.join(' && ');
|
|
290
|
+
const scopeBreakdown = sortedScopes
|
|
291
|
+
.map((scope) => {
|
|
292
|
+
const paths = scopePaths.get(scope) ?? [];
|
|
293
|
+
const sample = paths.slice(0, 3);
|
|
294
|
+
return `${scope}{count=${paths.length}; sample=[${sample.join(', ')}]}`;
|
|
295
|
+
})
|
|
296
|
+
.join(' | ');
|
|
273
297
|
violations.push({
|
|
274
298
|
code: 'GIT_ATOMICITY_TOO_MANY_SCOPES',
|
|
275
299
|
message:
|
|
276
|
-
`Git atomicity guard blocked at ${params.stage}: changed_scopes=${scopeKeys.size} exceeds max_scopes=${config.maxScopes}
|
|
300
|
+
`Git atomicity guard blocked at ${params.stage}: changed_scopes=${scopeKeys.size} exceeds max_scopes=${config.maxScopes}. ` +
|
|
301
|
+
`scope_files=${scopeBreakdown}.`,
|
|
277
302
|
remediation:
|
|
278
303
|
`Agrupa cambios por ámbito funcional (máximo ${config.maxScopes} scopes por commit). ` +
|
|
279
304
|
`scopes_detectados=[${sortedScopes.join(', ')}]. ` +
|
|
280
|
-
`Sugerencia: git restore --staged . && ${suggestedScopeAdds} && git commit -m "<tipo>: <scope>".`,
|
|
305
|
+
`Sugerencia split: git restore --staged . && ${suggestedScopeAdds} && git commit -m "<tipo>: <scope>".`,
|
|
281
306
|
});
|
|
282
307
|
}
|
|
283
308
|
|
|
@@ -771,6 +771,7 @@ export async function runPlatformGate(params: {
|
|
|
771
771
|
scope: GateScope;
|
|
772
772
|
silent?: boolean;
|
|
773
773
|
sddShortCircuit?: boolean;
|
|
774
|
+
sddDecisionOverride?: Pick<SddDecision, 'allowed' | 'code' | 'message'>;
|
|
774
775
|
services?: Partial<GateServices>;
|
|
775
776
|
dependencies?: Partial<GateDependencies>;
|
|
776
777
|
}): Promise<number> {
|
|
@@ -793,10 +794,11 @@ export async function runPlatformGate(params: {
|
|
|
793
794
|
params.policy.stage === 'PRE_PUSH' ||
|
|
794
795
|
params.policy.stage === 'CI'
|
|
795
796
|
) {
|
|
796
|
-
sddDecision =
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
797
|
+
sddDecision = params.sddDecisionOverride
|
|
798
|
+
?? dependencies.evaluateSddForStage(
|
|
799
|
+
params.policy.stage,
|
|
800
|
+
repoRoot
|
|
801
|
+
);
|
|
800
802
|
if (!sddDecision.allowed) {
|
|
801
803
|
if (params.silent !== true) {
|
|
802
804
|
process.stdout.write(`[pumuki][sdd] ${sddDecision.code}: ${sddDecision.message}\n`);
|
|
@@ -2,7 +2,7 @@ import type { Finding } from '../../core/gate/Finding';
|
|
|
2
2
|
|
|
3
3
|
const BLOCK_NEXT_ACTION_BY_CODE: Readonly<Record<string, string>> = {
|
|
4
4
|
SDD_SESSION_MISSING:
|
|
5
|
-
'npx --yes --package pumuki@latest pumuki sdd session --open --change
|
|
5
|
+
'npx --yes --package pumuki@latest pumuki sdd session --open --change=<id>',
|
|
6
6
|
SDD_SESSION_INVALID:
|
|
7
7
|
'npx --yes --package pumuki@latest pumuki sdd session --refresh --ttl-minutes=90',
|
|
8
8
|
PRE_PUSH_UPSTREAM_MISSING:
|
|
@@ -16,7 +16,7 @@ const BLOCK_NEXT_ACTION_BY_CODE: Readonly<Record<string, string>> = {
|
|
|
16
16
|
GIT_ATOMICITY_TOO_MANY_FILES:
|
|
17
17
|
'git restore --staged . && separa cambios en commits más pequeños',
|
|
18
18
|
GIT_ATOMICITY_TOO_MANY_SCOPES:
|
|
19
|
-
'git restore --staged . && git add <scope>/ && git commit -m "<tipo>: <scope>"',
|
|
19
|
+
'Revisa scope_files del bloqueo y aplica: git restore --staged . && git add <scope>/ && git commit -m "<tipo>: <scope>"',
|
|
20
20
|
ACTIVE_RULE_IDS_EMPTY_FOR_CODE_CHANGES_HIGH:
|
|
21
21
|
'Reconcilia policy/skills y reintenta PRE_COMMIT: npx --yes --package pumuki@latest pumuki policy reconcile --strict --json && npx --yes --package pumuki@latest pumuki-pre-commit',
|
|
22
22
|
SKILLS_SKILLS_FRONTEND_NO_SOLID_VIOLATIONS:
|