pumuki 6.3.28 → 6.3.30
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 +57 -0
- package/core/gate/conditionMatches.test.ts +34 -0
- package/core/gate/evaluateRules.test.ts +46 -0
- package/core/gate/scopeMatcher.ts +46 -45
- package/docs/API_REFERENCE.md +5 -0
- package/docs/CONFIGURATION.md +20 -0
- package/docs/README.md +4 -11
- package/docs/registro-maestro-de-seguimiento.md +18 -0
- package/docs/{validation/p9-ruralgo-fork-validation-tracking.md → seguimiento-completo-validacion-ruralgo-03-03-2026.md} +1290 -27
- package/docs/validation/README.md +6 -13
- package/docs/validation/c022-phase-acceptance-contract.md +1 -1
- package/integrations/evidence/evidenceChain.ts +89 -0
- package/integrations/evidence/readEvidence.test.ts +121 -50
- package/integrations/evidence/readEvidence.ts +91 -6
- package/integrations/evidence/rulesCoverage.ts +0 -94
- package/integrations/evidence/schema.test.ts +0 -16
- package/integrations/evidence/schema.ts +13 -41
- package/integrations/evidence/writeEvidence.test.ts +82 -69
- package/integrations/evidence/writeEvidence.ts +35 -24
- package/integrations/gate/evaluateAiGate.ts +43 -229
- package/integrations/gate/stagePolicies.ts +261 -50
- package/integrations/git/EvidenceService.ts +9 -0
- package/integrations/git/findingTraceability.ts +3 -3
- package/integrations/git/gateWaiver.ts +143 -0
- package/integrations/git/resolveGitRefs.ts +11 -0
- package/integrations/git/runCliCommand.ts +0 -16
- package/integrations/git/runPlatformGate.ts +354 -38
- package/integrations/git/runPlatformGateEvaluation.ts +0 -13
- package/integrations/git/runPlatformGateEvidence.ts +17 -1
- package/integrations/git/stageRunners.ts +118 -145
- package/integrations/lifecycle/cli.ts +301 -233
- package/integrations/lifecycle/doctor.ts +363 -465
- package/integrations/lifecycle/hookBlock.ts +6 -2
- package/integrations/lifecycle/hookManager.ts +20 -2
- package/integrations/lifecycle/install.ts +3 -115
- package/integrations/lifecycle/openSpecBootstrap.ts +8 -68
- package/integrations/lifecycle/preWriteAutomation.ts +74 -14
- package/integrations/lifecycle/remoteCiDiagnostics.ts +382 -0
- package/integrations/mcp/aiGateCheck.ts +0 -2
- package/integrations/sdd/index.ts +1 -2
- package/integrations/sdd/openSpecCli.ts +2 -4
- package/integrations/sdd/policy.ts +146 -155
- package/integrations/sdd/sessionStore.ts +28 -138
- package/integrations/sdd/syncDocs.ts +168 -150
- package/integrations/sdd/types.ts +2 -3
- package/integrations/telemetry/gateTelemetry.ts +372 -0
- package/package.json +7 -20
- package/scripts/build-phase8-ready-handoff-summary.sh +1 -1
- package/scripts/check-package-manifest.ts +0 -49
- package/scripts/check-refactor-progress-single-active.sh +1 -1
- package/scripts/check-tracking-single-active.sh +3 -5
- package/scripts/close-phase5-escalation-submission.sh +1 -1
- package/scripts/framework-menu-consumer-preflight-lib.ts +1 -31
- package/scripts/framework-menu-consumer-runtime-lib.ts +3 -3
- package/scripts/framework-menu-legacy-audit-lib.ts +7 -35
- package/scripts/framework-menu-matrix-evidence-lib.ts +2 -6
- package/scripts/package-manifest-lib.ts +16 -13
- package/core/gate/evaluateGate.js +0 -5
- package/core/gate/evaluateRules.js +0 -5
- package/docs/EXECUTION_BOARD.md +0 -794
- package/docs/REFRACTOR_PROGRESS.md +0 -1917
- package/docs/validation/p9-ruralgo-bug-registry.md +0 -607
- package/docs/validation/real-repo-manual-e2e-ruralgo-fork.md +0 -372
- package/integrations/config/skillsCompliance.ts +0 -212
- package/integrations/evidence/integrity.ts +0 -352
- package/integrations/gate/waivers.ts +0 -209
- package/integrations/git/index.js +0 -5
- package/integrations/lifecycle/index.js +0 -5
- package/integrations/mcp/index.js +0 -5
- package/integrations/sdd/index.js +0 -5
- package/integrations/telemetry/structuredTelemetry.ts +0 -197
- package/scripts/build-p9-validation-manifests.ts +0 -53
- package/scripts/check-p9-ruralgo-baseline-clean.ts +0 -200
- package/scripts/check-p9-ruralgo-baseline-versioned.ts +0 -198
- package/scripts/check-p9-ruralgo-branch-ready.ts +0 -215
- package/scripts/check-p9-ruralgo-install-health.ts +0 -288
- package/scripts/check-p9-ruralgo-runtime-ready.ts +0 -188
- package/scripts/p9-ruralgo-baseline-clean-lib.ts +0 -117
- package/scripts/p9-ruralgo-baseline-versioned-lib.ts +0 -119
- package/scripts/p9-ruralgo-branch-ready-lib.ts +0 -128
- package/scripts/p9-ruralgo-install-health-lib.ts +0 -121
- package/scripts/p9-ruralgo-runtime-ready-lib.ts +0 -149
- package/scripts/p9-validation-manifests-lib.ts +0 -366
package/README.md
CHANGED
|
@@ -124,6 +124,63 @@ Rule modes:
|
|
|
124
124
|
9. Provider-agnostic adapter scaffolding (`codex`, `claude`, `cursor`, `windsurf`, `opencode`).
|
|
125
125
|
10. Optional MCP servers for evidence and enterprise context.
|
|
126
126
|
|
|
127
|
+
## Policy-as-Code (Enterprise)
|
|
128
|
+
|
|
129
|
+
Pumuki supports a signed and versioned stage-policy contract at:
|
|
130
|
+
|
|
131
|
+
- `.pumuki/policy-as-code.json`
|
|
132
|
+
|
|
133
|
+
Minimal contract:
|
|
134
|
+
|
|
135
|
+
```json
|
|
136
|
+
{
|
|
137
|
+
"version": "1.0",
|
|
138
|
+
"source": "default",
|
|
139
|
+
"expires_at": "2026-12-31T23:59:59.000Z",
|
|
140
|
+
"signatures": {
|
|
141
|
+
"PRE_COMMIT": "<sha256-hex>",
|
|
142
|
+
"PRE_PUSH": "<sha256-hex>",
|
|
143
|
+
"CI": "<sha256-hex>"
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
Runtime behavior:
|
|
149
|
+
|
|
150
|
+
- If the contract is missing, Pumuki computes deterministic local metadata and still emits `policy_version`, `policy_signature`, and `policy_source`.
|
|
151
|
+
- If present, the contract is validated against active runtime policy for source/stage/signature.
|
|
152
|
+
- Validation states are emitted as `valid`, `invalid`, `expired`, or `unknown-source`.
|
|
153
|
+
- `PUMUKI_POLICY_STRICT=1` turns non-valid states into blocking findings (`governance.policy-as-code.invalid`).
|
|
154
|
+
|
|
155
|
+
Operational fallback:
|
|
156
|
+
|
|
157
|
+
- Keep strict mode disabled while bootstrapping a repo without a canonical contract.
|
|
158
|
+
- Enable strict mode once contract generation/signatures are part of your baseline pipeline.
|
|
159
|
+
|
|
160
|
+
## Telemetry Export (Enterprise)
|
|
161
|
+
|
|
162
|
+
Pumuki can export structured gate telemetry with a stable event schema (`telemetry_event_v1`) for SIEM/observability pipelines.
|
|
163
|
+
|
|
164
|
+
Default behavior remains unchanged: telemetry export is disabled unless explicitly configured.
|
|
165
|
+
|
|
166
|
+
Enable one or both outputs:
|
|
167
|
+
|
|
168
|
+
- `PUMUKI_TELEMETRY_JSONL_PATH`: local JSONL target (absolute or repo-relative path)
|
|
169
|
+
- `PUMUKI_TELEMETRY_OTEL_ENDPOINT`: OTLP HTTP logs endpoint (`/v1/logs`)
|
|
170
|
+
- `PUMUKI_TELEMETRY_OTEL_SERVICE_NAME`: optional OTel service name (default: `pumuki`)
|
|
171
|
+
- `PUMUKI_TELEMETRY_OTEL_TIMEOUT_MS`: optional OTel timeout in ms (default: `1500`)
|
|
172
|
+
|
|
173
|
+
Example:
|
|
174
|
+
|
|
175
|
+
```bash
|
|
176
|
+
export PUMUKI_TELEMETRY_JSONL_PATH=".pumuki/artifacts/gate-telemetry.jsonl"
|
|
177
|
+
export PUMUKI_TELEMETRY_OTEL_ENDPOINT="https://otel.example/v1/logs"
|
|
178
|
+
export PUMUKI_TELEMETRY_OTEL_SERVICE_NAME="pumuki-enterprise"
|
|
179
|
+
npx --yes pumuki-pre-commit
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
Each event captures deterministic stage/outcome/policy/repo context per gate execution.
|
|
183
|
+
|
|
127
184
|
## Framework Maintainer Flow (This Repo)
|
|
128
185
|
|
|
129
186
|
Use this only when working in the Pumuki framework repository itself:
|
|
@@ -108,3 +108,37 @@ test('conditionMatches soporta condiciones compuestas All, Any y Not', () => {
|
|
|
108
108
|
|
|
109
109
|
assert.equal(conditionMatches(composedCondition, facts), true);
|
|
110
110
|
});
|
|
111
|
+
|
|
112
|
+
test('conditionMatches respeta include glob swift y no matchea archivos no swift', () => {
|
|
113
|
+
const scopedCondition: Condition = {
|
|
114
|
+
kind: 'All',
|
|
115
|
+
conditions: [
|
|
116
|
+
{
|
|
117
|
+
kind: 'FileContent',
|
|
118
|
+
contains: ['!'],
|
|
119
|
+
},
|
|
120
|
+
{
|
|
121
|
+
kind: 'Not',
|
|
122
|
+
condition: {
|
|
123
|
+
kind: 'FileContent',
|
|
124
|
+
contains: ['IBOutlet'],
|
|
125
|
+
},
|
|
126
|
+
},
|
|
127
|
+
],
|
|
128
|
+
};
|
|
129
|
+
const scopedFacts = [
|
|
130
|
+
{
|
|
131
|
+
kind: 'FileContent' as const,
|
|
132
|
+
path: 'apps/admin-dashboard/middleware.ts',
|
|
133
|
+
content: 'if (token != null) { return NextResponse.next(); }',
|
|
134
|
+
source: 'repo',
|
|
135
|
+
},
|
|
136
|
+
];
|
|
137
|
+
|
|
138
|
+
assert.equal(
|
|
139
|
+
conditionMatches(scopedCondition, scopedFacts, {
|
|
140
|
+
include: ['**/*.swift'],
|
|
141
|
+
}),
|
|
142
|
+
false
|
|
143
|
+
);
|
|
144
|
+
});
|
|
@@ -199,3 +199,49 @@ test('evaluateRules genera un finding por cada heuristica coincidente', () => {
|
|
|
199
199
|
);
|
|
200
200
|
assert.equal(findings.every((finding) => finding.matchedBy === 'Heuristic'), true);
|
|
201
201
|
});
|
|
202
|
+
|
|
203
|
+
test('evaluateRules no genera finding de iOS cuando el scope es swift y el archivo es TypeScript', () => {
|
|
204
|
+
const rules: RuleSet = [
|
|
205
|
+
{
|
|
206
|
+
id: 'ios.no-force-unwrap',
|
|
207
|
+
description: 'Disallows force unwraps in iOS code.',
|
|
208
|
+
severity: 'CRITICAL',
|
|
209
|
+
scope: {
|
|
210
|
+
include: ['**/*.swift'],
|
|
211
|
+
},
|
|
212
|
+
when: {
|
|
213
|
+
kind: 'All',
|
|
214
|
+
conditions: [
|
|
215
|
+
{
|
|
216
|
+
kind: 'FileContent',
|
|
217
|
+
contains: ['!'],
|
|
218
|
+
},
|
|
219
|
+
{
|
|
220
|
+
kind: 'Not',
|
|
221
|
+
condition: {
|
|
222
|
+
kind: 'FileContent',
|
|
223
|
+
contains: ['IBOutlet'],
|
|
224
|
+
},
|
|
225
|
+
},
|
|
226
|
+
],
|
|
227
|
+
},
|
|
228
|
+
then: {
|
|
229
|
+
kind: 'Finding',
|
|
230
|
+
message: 'Force unwraps are not allowed in iOS code.',
|
|
231
|
+
code: 'IOS_NO_FORCE_UNWRAP',
|
|
232
|
+
},
|
|
233
|
+
},
|
|
234
|
+
];
|
|
235
|
+
const facts = [
|
|
236
|
+
{
|
|
237
|
+
kind: 'FileContent',
|
|
238
|
+
path: 'apps/admin-dashboard/middleware.ts',
|
|
239
|
+
content: 'if (token != null) { return NextResponse.next(); }',
|
|
240
|
+
source: 'repo',
|
|
241
|
+
},
|
|
242
|
+
] as const;
|
|
243
|
+
|
|
244
|
+
const findings = evaluateRules(rules, facts);
|
|
245
|
+
|
|
246
|
+
assert.deepEqual(findings, []);
|
|
247
|
+
});
|
|
@@ -1,68 +1,70 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
const SPECIAL_REGEX_CHARS = /[|\\{}()[\]^$+?.]/;
|
|
6
|
-
const regexCache = new Map<string, RegExp>();
|
|
1
|
+
type ScopePattern = {
|
|
2
|
+
include?: ReadonlyArray<string>;
|
|
3
|
+
exclude?: ReadonlyArray<string>;
|
|
4
|
+
};
|
|
7
5
|
|
|
8
|
-
const
|
|
6
|
+
const normalizePath = (value: string): string => {
|
|
9
7
|
return value.replace(/\\/g, '/');
|
|
10
8
|
};
|
|
11
9
|
|
|
12
|
-
const
|
|
13
|
-
return
|
|
10
|
+
const escapeRegex = (value: string): string => {
|
|
11
|
+
return value.replace(/[|\\{}()[\]^$+?.]/g, '\\$&');
|
|
14
12
|
};
|
|
15
13
|
|
|
16
14
|
const toGlobRegex = (pattern: string): RegExp => {
|
|
17
|
-
const cached = regexCache.get(pattern);
|
|
18
|
-
if (cached) {
|
|
19
|
-
return cached;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
15
|
let regex = '^';
|
|
23
|
-
for (let index = 0; index < pattern.length;) {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
index
|
|
16
|
+
for (let index = 0; index < pattern.length; index += 1) {
|
|
17
|
+
const current = pattern[index];
|
|
18
|
+
if (current === '*') {
|
|
19
|
+
const next = pattern[index + 1];
|
|
20
|
+
if (next === '*') {
|
|
21
|
+
const nextNext = pattern[index + 2];
|
|
22
|
+
if (nextNext === '/') {
|
|
23
|
+
regex += '(?:.*/)?';
|
|
24
|
+
index += 2;
|
|
25
|
+
} else {
|
|
26
|
+
regex += '.*';
|
|
27
|
+
index += 1;
|
|
28
|
+
}
|
|
29
|
+
} else {
|
|
30
|
+
regex += '[^/]*';
|
|
31
|
+
}
|
|
27
32
|
continue;
|
|
28
33
|
}
|
|
29
|
-
if (
|
|
30
|
-
regex += '
|
|
31
|
-
index += 2;
|
|
34
|
+
if (current === '?') {
|
|
35
|
+
regex += '[^/]';
|
|
32
36
|
continue;
|
|
33
37
|
}
|
|
34
|
-
|
|
35
|
-
const char = pattern[index];
|
|
36
|
-
if (char === '*') {
|
|
37
|
-
regex += '[^/]*';
|
|
38
|
-
index += 1;
|
|
39
|
-
continue;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
regex += escapeRegexChar(char);
|
|
43
|
-
index += 1;
|
|
38
|
+
regex += escapeRegex(current);
|
|
44
39
|
}
|
|
45
40
|
regex += '$';
|
|
41
|
+
return new RegExp(regex);
|
|
42
|
+
};
|
|
46
43
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
return
|
|
44
|
+
const extractPrefix = (pattern: string): string => {
|
|
45
|
+
const wildcardIndex = pattern.search(/[*?]/);
|
|
46
|
+
return wildcardIndex === -1 ? pattern : pattern.slice(0, wildcardIndex);
|
|
50
47
|
};
|
|
51
48
|
|
|
52
|
-
const
|
|
53
|
-
const
|
|
54
|
-
|
|
49
|
+
const isTrailingWildcardPattern = (pattern: string): boolean => {
|
|
50
|
+
const wildcardIndex = pattern.search(/[*?]/);
|
|
51
|
+
if (wildcardIndex === -1) {
|
|
52
|
+
return false;
|
|
53
|
+
}
|
|
54
|
+
const suffix = pattern.slice(wildcardIndex);
|
|
55
|
+
return /^[*?]+$/.test(suffix);
|
|
56
|
+
};
|
|
55
57
|
|
|
56
|
-
|
|
58
|
+
export const matchesPattern = (path: string, pattern: string): boolean => {
|
|
59
|
+
const normalizedPath = normalizePath(path);
|
|
60
|
+
const normalizedPattern = normalizePath(pattern);
|
|
61
|
+
const wildcardIndex = normalizedPattern.search(/[*?]/);
|
|
57
62
|
if (wildcardIndex === -1) {
|
|
58
63
|
return normalizedPath.startsWith(normalizedPattern);
|
|
59
64
|
}
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
if (prefix.length > 0 && normalizedPath.startsWith(prefix)) {
|
|
63
|
-
return true;
|
|
65
|
+
if (isTrailingWildcardPattern(normalizedPattern)) {
|
|
66
|
+
return normalizedPath.startsWith(extractPrefix(normalizedPattern));
|
|
64
67
|
}
|
|
65
|
-
|
|
66
68
|
return toGlobRegex(normalizedPattern).test(normalizedPath);
|
|
67
69
|
};
|
|
68
70
|
|
|
@@ -70,10 +72,9 @@ const matchesAnyPattern = (path: string, patterns: ReadonlyArray<string>): boole
|
|
|
70
72
|
return patterns.some((pattern) => matchesPattern(path, pattern));
|
|
71
73
|
};
|
|
72
74
|
|
|
73
|
-
export const matchesScope = (path: string, scope?:
|
|
75
|
+
export const matchesScope = (path: string, scope?: ScopePattern): boolean => {
|
|
74
76
|
const include = scope?.include;
|
|
75
77
|
const exclude = scope?.exclude;
|
|
76
|
-
|
|
77
78
|
if (exclude && exclude.length > 0 && matchesAnyPattern(path, exclude)) {
|
|
78
79
|
return false;
|
|
79
80
|
}
|
package/docs/API_REFERENCE.md
CHANGED
|
@@ -110,6 +110,11 @@ Contract:
|
|
|
110
110
|
- evidence `ai_gate.status = BLOCKED`
|
|
111
111
|
- protected branch use (`main/master/develop/dev` by default)
|
|
112
112
|
- Returns deterministic payload: `status`, `allowed`, `violations[]`, `evidence`, `repo_state`.
|
|
113
|
+
- Evidence source contract (auditability):
|
|
114
|
+
- `evidence.source.source`
|
|
115
|
+
- `evidence.source.path`
|
|
116
|
+
- `evidence.source.digest`
|
|
117
|
+
- `evidence.source.generated_at`
|
|
113
118
|
|
|
114
119
|
## PRE_WRITE JSON envelope
|
|
115
120
|
|
package/docs/CONFIGURATION.md
CHANGED
|
@@ -97,6 +97,26 @@ Defined in `integrations/gate/stagePolicies.ts`:
|
|
|
97
97
|
- `PRE_PUSH`: block `ERROR`, warn from `WARN`
|
|
98
98
|
- `CI`: block `ERROR`, warn from `WARN`
|
|
99
99
|
|
|
100
|
+
## Gate telemetry export (optional)
|
|
101
|
+
|
|
102
|
+
Structured telemetry output is disabled by default and can be enabled with environment variables:
|
|
103
|
+
|
|
104
|
+
- `PUMUKI_TELEMETRY_JSONL_PATH`:
|
|
105
|
+
- JSONL file path for `telemetry_event_v1` records.
|
|
106
|
+
- Accepts absolute path or repo-relative path.
|
|
107
|
+
- `PUMUKI_TELEMETRY_OTEL_ENDPOINT`:
|
|
108
|
+
- OTLP HTTP logs endpoint (`/v1/logs`).
|
|
109
|
+
- `PUMUKI_TELEMETRY_OTEL_SERVICE_NAME`:
|
|
110
|
+
- Optional service name for OTel payload (`default: pumuki`).
|
|
111
|
+
- `PUMUKI_TELEMETRY_OTEL_TIMEOUT_MS`:
|
|
112
|
+
- Optional timeout for OTel dispatch in milliseconds (`default: 1500`).
|
|
113
|
+
|
|
114
|
+
Notes:
|
|
115
|
+
|
|
116
|
+
- You can enable JSONL only, OTel only, or both.
|
|
117
|
+
- If unset, no telemetry export is attempted.
|
|
118
|
+
- Gate execution remains deterministic even when OTel endpoint is unavailable (best-effort dispatch).
|
|
119
|
+
|
|
100
120
|
## Heuristic pilot flag
|
|
101
121
|
|
|
102
122
|
Enable semantic heuristic rules:
|
package/docs/README.md
CHANGED
|
@@ -2,18 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
Canonical index for active Pumuki documentation.
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## Seguimiento Activo (único)
|
|
6
6
|
|
|
7
|
-
-
|
|
8
|
-
-
|
|
9
|
-
-
|
|
10
|
-
- Alcance activo actual: `P9` (validación manual guiada en repo real externo `ruralgo-fork`) en `docs/validation/p9-ruralgo-fork-validation-tracking.md`.
|
|
11
|
-
- Ultimo cierre oficial previo: ciclo `022` consolidado en `docs/validation/c022-phase-acceptance-contract.md`.
|
|
12
|
-
- Politica: una sola tarea en construccion (`🚧`) en todo momento.
|
|
7
|
+
- Maestro: `docs/registro-maestro-de-seguimiento.md`
|
|
8
|
+
- Plan activo: `docs/seguimiento-completo-validacion-ruralgo-03-03-2026.md`
|
|
9
|
+
- Política: una sola tarea en construcción (`🚧`) en el plan activo.
|
|
13
10
|
|
|
14
11
|
## Product and Architecture
|
|
15
12
|
|
|
16
|
-
- `docs/EXECUTION_BOARD.md`: tablero activo de seguimiento (simple).
|
|
17
13
|
- `docs/ARCHITECTURE.md`: normative architecture contract.
|
|
18
14
|
- `docs/HOW_IT_WORKS.md`: facts-to-gate execution flow.
|
|
19
15
|
- `docs/API_REFERENCE.md`: public APIs, binaries, and command surfaces.
|
|
@@ -55,9 +51,6 @@ Canonical index for active Pumuki documentation.
|
|
|
55
51
|
- `docs/validation/c022-phase-acceptance-contract.md`
|
|
56
52
|
- `docs/validation/enterprise-consumer-isolation-policy.md`
|
|
57
53
|
- `docs/validation/mock-consumer-integration-runbook.md`
|
|
58
|
-
- `docs/validation/p9-ruralgo-bug-registry.md`
|
|
59
|
-
- `docs/validation/p9-ruralgo-fork-validation-tracking.md`
|
|
60
|
-
- `docs/validation/real-repo-manual-e2e-ruralgo-fork.md`
|
|
61
54
|
- `docs/validation/detection-audit-baseline.md`
|
|
62
55
|
- `docs/validation/skills-rollout-consumer-repositories.md`
|
|
63
56
|
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# Registro Maestro de Seguimiento
|
|
2
|
+
|
|
3
|
+
## Objetivo
|
|
4
|
+
- Mantener trazabilidad ejecutiva en un solo punto.
|
|
5
|
+
- Referenciar un único plan activo con fases, tasks y leyenda.
|
|
6
|
+
|
|
7
|
+
## Estado actual
|
|
8
|
+
- Plan activo: `docs/seguimiento-completo-validacion-ruralgo-03-03-2026.md`
|
|
9
|
+
- Estado del plan: EN CURSO
|
|
10
|
+
- Task activa (`🚧`): `P12.F1.T42` (sincronizar canónico RuralGO tras cierre de `#543` y actualizar refs reales en feedback/master plan).
|
|
11
|
+
|
|
12
|
+
## Historial resumido
|
|
13
|
+
- No se mantienen MDs históricos de seguimiento en este repositorio.
|
|
14
|
+
- La trazabilidad histórica relevante debe consolidarse dentro del plan activo o en documentación oficial no temporal.
|
|
15
|
+
|
|
16
|
+
## Regla de operación
|
|
17
|
+
- Debe existir exactamente una task `🚧` en el plan activo.
|
|
18
|
+
- No se crean nuevos MDs de seguimiento salvo instrucción explícita.
|