instar 1.3.897 → 1.3.898
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/dist/core/PostUpdateMigrator.d.ts +2 -0
- package/dist/core/PostUpdateMigrator.d.ts.map +1 -1
- package/dist/core/PostUpdateMigrator.js +112 -0
- package/dist/core/PostUpdateMigrator.js.map +1 -1
- package/package.json +2 -1
- package/scripts/feature-maturation-plan-gate.mjs +1 -0
- package/skills/spec-converge/scripts/write-convergence-tag.mjs +13 -0
- package/src/core/FeatureMaturationPlanGate.mjs +58 -0
- package/src/data/builtin-manifest.json +19 -19
- package/upgrades/1.3.898.md +24 -0
- package/upgrades/side-effects/feature-maturation-plan-visibility.md +84 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "instar",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.898",
|
|
4
4
|
"description": "Coherence infrastructure for self-evolving AI agents — on the Claude Code or Codex subscription you already have.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -93,6 +93,7 @@
|
|
|
93
93
|
"src/templates",
|
|
94
94
|
"src/data",
|
|
95
95
|
"src/threadline/data",
|
|
96
|
+
"src/core/FeatureMaturationPlanGate.mjs",
|
|
96
97
|
"skills",
|
|
97
98
|
"playbook-scripts",
|
|
98
99
|
"scripts",
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from '../src/core/FeatureMaturationPlanGate.mjs';
|
|
@@ -48,6 +48,7 @@ import fs from 'node:fs';
|
|
|
48
48
|
import path from 'node:path';
|
|
49
49
|
import { fileURLToPath } from 'node:url';
|
|
50
50
|
import { checkEli16Overview } from '../../../scripts/eli16-overview-check.mjs';
|
|
51
|
+
import { findMaturationPlanGaps } from '../../../scripts/feature-maturation-plan-gate.mjs';
|
|
51
52
|
|
|
52
53
|
function parseArgs() {
|
|
53
54
|
const args = process.argv.slice(2);
|
|
@@ -282,6 +283,18 @@ if (!dpGate.ok) {
|
|
|
282
283
|
process.exit(1);
|
|
283
284
|
}
|
|
284
285
|
|
|
286
|
+
// Feature Maturation Discipline v1: SIGNAL only. Missing/partial structure is
|
|
287
|
+
// visible during convergence but MUST NOT change the stamp's exit status.
|
|
288
|
+
const maturationGate = findMaturationPlanGaps(content);
|
|
289
|
+
if (!maturationGate.ok) {
|
|
290
|
+
const details = [
|
|
291
|
+
maturationGate.reason,
|
|
292
|
+
maturationGate.missing?.length ? `missing=${maturationGate.missing.join(',')}` : '',
|
|
293
|
+
maturationGate.duplicates?.length ? `duplicates=${maturationGate.duplicates.join(',')}` : '',
|
|
294
|
+
].filter(Boolean).join(' ');
|
|
295
|
+
console.error(`MATURATION_PLAN_WARN ${specArg}: ${details}`);
|
|
296
|
+
}
|
|
297
|
+
|
|
285
298
|
// Parse YAML frontmatter manually (no dependency).
|
|
286
299
|
// Expect: /^---\n<body>\n---\n<rest>/
|
|
287
300
|
const FM_RE = /^---\n([\s\S]*?)\n---\n([\s\S]*)$/;
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure WARN-stage structural detector for `## Maturation plan`.
|
|
3
|
+
* Semantic adequacy belongs to spec-converge's lessons-aware reviewer.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
const REQUIRED_FIELDS = [
|
|
7
|
+
'test-agent-live',
|
|
8
|
+
'dev-agent-live',
|
|
9
|
+
'fleet',
|
|
10
|
+
'graduation criterion',
|
|
11
|
+
'dark-window',
|
|
12
|
+
];
|
|
13
|
+
|
|
14
|
+
function reviewableMarkdown(input) {
|
|
15
|
+
let body = String(input).replace(/^---\r?\n[\s\S]*?\r?\n---\r?\n/, '');
|
|
16
|
+
body = body.replace(/<!--[^]*?-->/g, '');
|
|
17
|
+
const lines = body.split(/\r?\n/);
|
|
18
|
+
let fence = null;
|
|
19
|
+
return lines.map((line) => {
|
|
20
|
+
const marker = line.match(/^\s*(`{3,}|~{3,})/);
|
|
21
|
+
if (marker) {
|
|
22
|
+
const token = marker[1][0];
|
|
23
|
+
if (fence === null) fence = token;
|
|
24
|
+
else if (fence === token) fence = null;
|
|
25
|
+
return '';
|
|
26
|
+
}
|
|
27
|
+
if (fence !== null || /^\s*>/.test(line)) return '';
|
|
28
|
+
return line;
|
|
29
|
+
}).join('\n');
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export function findMaturationPlanGaps(specBody) {
|
|
33
|
+
const body = reviewableMarkdown(specBody);
|
|
34
|
+
const headings = [...body.matchAll(/^##[ \t]+Maturation plan[ \t]*$/gim)];
|
|
35
|
+
if (headings.length === 0) return { ok: false, reason: 'missing-section' };
|
|
36
|
+
if (headings.length > 1) return { ok: false, reason: 'duplicate-section' };
|
|
37
|
+
|
|
38
|
+
const start = headings[0].index + headings[0][0].length;
|
|
39
|
+
const rest = body.slice(start);
|
|
40
|
+
const nextH2 = rest.search(/^##[ \t]+/m);
|
|
41
|
+
const section = nextH2 === -1 ? rest : rest.slice(0, nextH2);
|
|
42
|
+
const found = new Map();
|
|
43
|
+
for (const line of section.split('\n')) {
|
|
44
|
+
const match = line.match(/^\s*[-*+]\s+\*\*([^*]+):\*\*\s+(.+?)\s*$/);
|
|
45
|
+
if (!match) continue;
|
|
46
|
+
const label = match[1].trim().toLowerCase();
|
|
47
|
+
if (!REQUIRED_FIELDS.includes(label)) continue;
|
|
48
|
+
found.set(label, [...(found.get(label) ?? []), match[2].trim()]);
|
|
49
|
+
}
|
|
50
|
+
const missing = REQUIRED_FIELDS.filter((field) => !found.has(field));
|
|
51
|
+
const duplicates = REQUIRED_FIELDS.filter((field) => (found.get(field)?.length ?? 0) > 1);
|
|
52
|
+
if (missing.length || duplicates.length) {
|
|
53
|
+
return { ok: false, reason: 'invalid-fields', missing, duplicates };
|
|
54
|
+
}
|
|
55
|
+
return { ok: true };
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export { REQUIRED_FIELDS };
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "./builtin-manifest.schema.json",
|
|
3
3
|
"schemaVersion": 1,
|
|
4
|
-
"generatedAt": "2026-07-
|
|
5
|
-
"instarVersion": "1.3.
|
|
4
|
+
"generatedAt": "2026-07-21T19:01:03.327Z",
|
|
5
|
+
"instarVersion": "1.3.898",
|
|
6
6
|
"entryCount": 202,
|
|
7
7
|
"entries": {
|
|
8
8
|
"hook:session-start": {
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
"domain": "identity",
|
|
12
12
|
"sourcePath": "src/core/PostUpdateMigrator.ts",
|
|
13
13
|
"installedPath": ".instar/hooks/instar/session-start.sh",
|
|
14
|
-
"contentHash": "
|
|
14
|
+
"contentHash": "450f643c7131816527081601898528e6e46263d8a0bc87127dbd28136b0e1471",
|
|
15
15
|
"since": "2025-01-01"
|
|
16
16
|
},
|
|
17
17
|
"hook:dangerous-command-guard": {
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
"domain": "safety",
|
|
21
21
|
"sourcePath": "src/core/PostUpdateMigrator.ts",
|
|
22
22
|
"installedPath": ".instar/hooks/instar/dangerous-command-guard.sh",
|
|
23
|
-
"contentHash": "
|
|
23
|
+
"contentHash": "450f643c7131816527081601898528e6e46263d8a0bc87127dbd28136b0e1471",
|
|
24
24
|
"since": "2025-01-01"
|
|
25
25
|
},
|
|
26
26
|
"hook:grounding-before-messaging": {
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
"domain": "safety",
|
|
30
30
|
"sourcePath": "src/core/PostUpdateMigrator.ts",
|
|
31
31
|
"installedPath": ".instar/hooks/instar/grounding-before-messaging.sh",
|
|
32
|
-
"contentHash": "
|
|
32
|
+
"contentHash": "450f643c7131816527081601898528e6e46263d8a0bc87127dbd28136b0e1471",
|
|
33
33
|
"since": "2025-01-01"
|
|
34
34
|
},
|
|
35
35
|
"hook:compaction-recovery": {
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
"domain": "identity",
|
|
39
39
|
"sourcePath": "src/core/PostUpdateMigrator.ts",
|
|
40
40
|
"installedPath": ".instar/hooks/instar/compaction-recovery.sh",
|
|
41
|
-
"contentHash": "
|
|
41
|
+
"contentHash": "450f643c7131816527081601898528e6e46263d8a0bc87127dbd28136b0e1471",
|
|
42
42
|
"since": "2025-01-01"
|
|
43
43
|
},
|
|
44
44
|
"hook:external-operation-gate": {
|
|
@@ -47,7 +47,7 @@
|
|
|
47
47
|
"domain": "safety",
|
|
48
48
|
"sourcePath": "src/core/PostUpdateMigrator.ts",
|
|
49
49
|
"installedPath": ".instar/hooks/instar/external-operation-gate.js",
|
|
50
|
-
"contentHash": "
|
|
50
|
+
"contentHash": "450f643c7131816527081601898528e6e46263d8a0bc87127dbd28136b0e1471",
|
|
51
51
|
"since": "2025-01-01"
|
|
52
52
|
},
|
|
53
53
|
"hook:deferral-detector": {
|
|
@@ -56,7 +56,7 @@
|
|
|
56
56
|
"domain": "safety",
|
|
57
57
|
"sourcePath": "src/core/PostUpdateMigrator.ts",
|
|
58
58
|
"installedPath": ".instar/hooks/instar/deferral-detector.js",
|
|
59
|
-
"contentHash": "
|
|
59
|
+
"contentHash": "450f643c7131816527081601898528e6e46263d8a0bc87127dbd28136b0e1471",
|
|
60
60
|
"since": "2025-01-01"
|
|
61
61
|
},
|
|
62
62
|
"hook:self-stop-guard": {
|
|
@@ -65,7 +65,7 @@
|
|
|
65
65
|
"domain": "coherence",
|
|
66
66
|
"sourcePath": "src/core/PostUpdateMigrator.ts",
|
|
67
67
|
"installedPath": ".instar/hooks/instar/self-stop-guard.js",
|
|
68
|
-
"contentHash": "
|
|
68
|
+
"contentHash": "450f643c7131816527081601898528e6e46263d8a0bc87127dbd28136b0e1471",
|
|
69
69
|
"since": "2025-01-01"
|
|
70
70
|
},
|
|
71
71
|
"hook:post-action-reflection": {
|
|
@@ -74,7 +74,7 @@
|
|
|
74
74
|
"domain": "evolution",
|
|
75
75
|
"sourcePath": "src/core/PostUpdateMigrator.ts",
|
|
76
76
|
"installedPath": ".instar/hooks/instar/post-action-reflection.js",
|
|
77
|
-
"contentHash": "
|
|
77
|
+
"contentHash": "450f643c7131816527081601898528e6e46263d8a0bc87127dbd28136b0e1471",
|
|
78
78
|
"since": "2025-01-01"
|
|
79
79
|
},
|
|
80
80
|
"hook:external-communication-guard": {
|
|
@@ -83,7 +83,7 @@
|
|
|
83
83
|
"domain": "safety",
|
|
84
84
|
"sourcePath": "src/core/PostUpdateMigrator.ts",
|
|
85
85
|
"installedPath": ".instar/hooks/instar/external-communication-guard.js",
|
|
86
|
-
"contentHash": "
|
|
86
|
+
"contentHash": "450f643c7131816527081601898528e6e46263d8a0bc87127dbd28136b0e1471",
|
|
87
87
|
"since": "2025-01-01"
|
|
88
88
|
},
|
|
89
89
|
"hook:scope-coherence-collector": {
|
|
@@ -92,7 +92,7 @@
|
|
|
92
92
|
"domain": "coherence",
|
|
93
93
|
"sourcePath": "src/core/PostUpdateMigrator.ts",
|
|
94
94
|
"installedPath": ".instar/hooks/instar/scope-coherence-collector.js",
|
|
95
|
-
"contentHash": "
|
|
95
|
+
"contentHash": "450f643c7131816527081601898528e6e46263d8a0bc87127dbd28136b0e1471",
|
|
96
96
|
"since": "2025-01-01"
|
|
97
97
|
},
|
|
98
98
|
"hook:scope-coherence-checkpoint": {
|
|
@@ -101,7 +101,7 @@
|
|
|
101
101
|
"domain": "coherence",
|
|
102
102
|
"sourcePath": "src/core/PostUpdateMigrator.ts",
|
|
103
103
|
"installedPath": ".instar/hooks/instar/scope-coherence-checkpoint.js",
|
|
104
|
-
"contentHash": "
|
|
104
|
+
"contentHash": "450f643c7131816527081601898528e6e46263d8a0bc87127dbd28136b0e1471",
|
|
105
105
|
"since": "2025-01-01"
|
|
106
106
|
},
|
|
107
107
|
"hook:free-text-guard": {
|
|
@@ -110,7 +110,7 @@
|
|
|
110
110
|
"domain": "safety",
|
|
111
111
|
"sourcePath": "src/core/PostUpdateMigrator.ts",
|
|
112
112
|
"installedPath": ".instar/hooks/instar/free-text-guard.sh",
|
|
113
|
-
"contentHash": "
|
|
113
|
+
"contentHash": "450f643c7131816527081601898528e6e46263d8a0bc87127dbd28136b0e1471",
|
|
114
114
|
"since": "2025-01-01"
|
|
115
115
|
},
|
|
116
116
|
"hook:claim-intercept": {
|
|
@@ -119,7 +119,7 @@
|
|
|
119
119
|
"domain": "coherence",
|
|
120
120
|
"sourcePath": "src/core/PostUpdateMigrator.ts",
|
|
121
121
|
"installedPath": ".instar/hooks/instar/claim-intercept.js",
|
|
122
|
-
"contentHash": "
|
|
122
|
+
"contentHash": "450f643c7131816527081601898528e6e46263d8a0bc87127dbd28136b0e1471",
|
|
123
123
|
"since": "2025-01-01"
|
|
124
124
|
},
|
|
125
125
|
"hook:claim-intercept-response": {
|
|
@@ -128,7 +128,7 @@
|
|
|
128
128
|
"domain": "coherence",
|
|
129
129
|
"sourcePath": "src/core/PostUpdateMigrator.ts",
|
|
130
130
|
"installedPath": ".instar/hooks/instar/claim-intercept-response.js",
|
|
131
|
-
"contentHash": "
|
|
131
|
+
"contentHash": "450f643c7131816527081601898528e6e46263d8a0bc87127dbd28136b0e1471",
|
|
132
132
|
"since": "2025-01-01"
|
|
133
133
|
},
|
|
134
134
|
"hook:stop-gate-router": {
|
|
@@ -137,7 +137,7 @@
|
|
|
137
137
|
"domain": "safety",
|
|
138
138
|
"sourcePath": "src/core/PostUpdateMigrator.ts",
|
|
139
139
|
"installedPath": ".instar/hooks/instar/stop-gate-router.js",
|
|
140
|
-
"contentHash": "
|
|
140
|
+
"contentHash": "450f643c7131816527081601898528e6e46263d8a0bc87127dbd28136b0e1471",
|
|
141
141
|
"since": "2025-01-01"
|
|
142
142
|
},
|
|
143
143
|
"hook:auto-approve-permissions": {
|
|
@@ -146,7 +146,7 @@
|
|
|
146
146
|
"domain": "safety",
|
|
147
147
|
"sourcePath": "src/core/PostUpdateMigrator.ts",
|
|
148
148
|
"installedPath": ".instar/hooks/instar/auto-approve-permissions.js",
|
|
149
|
-
"contentHash": "
|
|
149
|
+
"contentHash": "450f643c7131816527081601898528e6e46263d8a0bc87127dbd28136b0e1471",
|
|
150
150
|
"since": "2025-01-01"
|
|
151
151
|
},
|
|
152
152
|
"job:health-check": {
|
|
@@ -1562,7 +1562,7 @@
|
|
|
1562
1562
|
"type": "subsystem",
|
|
1563
1563
|
"domain": "updates",
|
|
1564
1564
|
"sourcePath": "src/core/PostUpdateMigrator.ts",
|
|
1565
|
-
"contentHash": "
|
|
1565
|
+
"contentHash": "450f643c7131816527081601898528e6e46263d8a0bc87127dbd28136b0e1471",
|
|
1566
1566
|
"since": "2025-01-01"
|
|
1567
1567
|
},
|
|
1568
1568
|
"subsystem:scheduler": {
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# Upgrade Guide — vNEXT
|
|
2
|
+
|
|
3
|
+
<!-- assembled-by: assemble-next-md -->
|
|
4
|
+
<!-- bump: patch -->
|
|
5
|
+
|
|
6
|
+
## What Changed
|
|
7
|
+
|
|
8
|
+
- Strengthened the existing Maturation Path standard around the fixed test-agent → development-agent → fleet ladder.
|
|
9
|
+
- Added a WARN-only structural check for `## Maturation plan`; convergence still succeeds while missing or partial plans emit `MATURATION_PLAN_WARN`.
|
|
10
|
+
- Added durable, customization-safe update delivery for existing agent installations.
|
|
11
|
+
|
|
12
|
+
## What to Tell Your User
|
|
13
|
+
|
|
14
|
+
New staged-feature specs now make their graduation plan visible during review. This first increment warns without blocking so the format can mature safely before enforcement becomes hard.
|
|
15
|
+
|
|
16
|
+
## Summary of New Capabilities
|
|
17
|
+
|
|
18
|
+
- Detect missing or incomplete three-rung maturation plans during spec convergence.
|
|
19
|
+
- Preserve customized installed tooling while safely updating recognized stock files.
|
|
20
|
+
|
|
21
|
+
## Evidence
|
|
22
|
+
|
|
23
|
+
- 44 targeted tests pass across the new parser, convergence wiring, migration failures, existing decision-point parsing, and standards enforcement audit.
|
|
24
|
+
- Full TypeScript and repository lint pass.
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
# Side-Effects Review — Feature maturation plan visibility
|
|
2
|
+
|
|
3
|
+
**Version / slug:** `feature-maturation-plan-visibility`
|
|
4
|
+
**Date:** `2026-07-21`
|
|
5
|
+
**Author:** `Instar-codey`
|
|
6
|
+
**Second-pass reviewer:** `maturation_second_pass`
|
|
7
|
+
|
|
8
|
+
## Summary of the change
|
|
9
|
+
|
|
10
|
+
This strengthens the existing Maturation Path registry article, adds a pure Markdown structure detector, emits a WARN-only diagnostic from the existing convergence tag writer, and delivers both files through PostUpdateMigrator with hash-based customization detection and durable replacement.
|
|
11
|
+
|
|
12
|
+
## Decision-point inventory
|
|
13
|
+
|
|
14
|
+
- `findMaturationPlanGaps` — add — pure structural signal with no blocking authority.
|
|
15
|
+
- convergence tag writer — modify — reports the signal but retains exit status and stamping behavior.
|
|
16
|
+
- migration stock/custom classification — add — deterministic closed-world content-hash invariant protecting user customizations.
|
|
17
|
+
|
|
18
|
+
## 1. Over-block
|
|
19
|
+
|
|
20
|
+
No runtime block exists. A valid non-canonical plan can warn, but v1 still stamps convergence. The canonical accepted form is documented and tested.
|
|
21
|
+
|
|
22
|
+
## 2. Under-block
|
|
23
|
+
|
|
24
|
+
A syntactically complete but poor plan is not rejected. This is intentional: structural parsing is a cheap signal; the lessons-aware reviewer holds semantic authority.
|
|
25
|
+
|
|
26
|
+
## 3. Level-of-abstraction fit
|
|
27
|
+
|
|
28
|
+
The validator sits beside the existing `findDecisionPointGaps` convergence seam. The standard is updated in place. Runtime graduation remains owned by FeatureRolloutReconciler and InitiativeTracker; no parallel engine exists.
|
|
29
|
+
|
|
30
|
+
## 4. Signal vs authority compliance
|
|
31
|
+
|
|
32
|
+
**Required reference:** [docs/signal-vs-authority.md](../../docs/signal-vs-authority.md)
|
|
33
|
+
|
|
34
|
+
- [x] No — this change produces a signal consumed by an existing smart gate.
|
|
35
|
+
|
|
36
|
+
The Markdown parser only reports missing deterministic structure. It cannot veto convergence or judge plan quality.
|
|
37
|
+
|
|
38
|
+
## 4b. Judgment-point check
|
|
39
|
+
|
|
40
|
+
No new heuristic at a competing-signals decision point. Stock-file hash membership and structural field presence are closed-world invariants. Semantic maturation quality remains a reviewer judgment.
|
|
41
|
+
|
|
42
|
+
## 5. Interactions
|
|
43
|
+
|
|
44
|
+
- **Shadowing:** the warning runs after existing open-question and decision-point hard gates, and before tag writing. It cannot shadow either gate.
|
|
45
|
+
- **Double-fire:** one invocation emits at most one stable warning line.
|
|
46
|
+
- **Races:** migration writes use unique sibling temps, exclusive create, file and directory sync, and same-filesystem rename.
|
|
47
|
+
- **Feedback loops:** none in v1; no scheduler or initiative cadence is added.
|
|
48
|
+
|
|
49
|
+
## 6. External surfaces
|
|
50
|
+
|
|
51
|
+
Developers may see a new stderr warning during spec convergence. No messages, routes, external APIs, persistent runtime records, or operator actions are added.
|
|
52
|
+
|
|
53
|
+
## 6b. Operator-surface quality
|
|
54
|
+
|
|
55
|
+
No operator surface — not applicable.
|
|
56
|
+
|
|
57
|
+
## 7. Multi-machine posture
|
|
58
|
+
|
|
59
|
+
Unified: the detector, tag writer, and standard are git/package artifacts delivered identically to each machine. V1 emits no notice, durable rollout state, or URL. Existing customized targets remain local by user choice and are reported untouched.
|
|
60
|
+
|
|
61
|
+
## 8. Rollback cost
|
|
62
|
+
|
|
63
|
+
Revert and ship a patch. The warning creates no data. Installed stock files retain durable pre-migration backups; customized files are never modified.
|
|
64
|
+
|
|
65
|
+
## Conclusion
|
|
66
|
+
|
|
67
|
+
The change is bounded to warning visibility, extends the correct existing owners, and preserves semantic authority. The main risks—parser false positives and migration corruption—are non-blocking or covered by adversarial and injected-failure tests.
|
|
68
|
+
|
|
69
|
+
## Second-pass review (if required)
|
|
70
|
+
|
|
71
|
+
**Reviewer:** maturation_second_pass
|
|
72
|
+
**Independent read of the artifact:** concur
|
|
73
|
+
|
|
74
|
+
Concur with the review — the implementation now preserves WARN-only signal authority, exact gate classification, customization-safe durable migration parity, and the v1-only boundary with all 26 targeted tests passing.
|
|
75
|
+
|
|
76
|
+
## Evidence pointers
|
|
77
|
+
|
|
78
|
+
- `tests/unit/feature-maturation-plan-gate.test.ts`
|
|
79
|
+
- `tests/unit/write-convergence-tag-maturation-plan.test.ts`
|
|
80
|
+
- `tests/unit/PostUpdateMigrator-feature-maturation.test.ts`
|
|
81
|
+
|
|
82
|
+
## Class-Closure Declaration (display-only mirror)
|
|
83
|
+
|
|
84
|
+
No agent-authored-artifact defect — not applicable. This is a new WARN-stage guard, not a defect repair or self-triggered controller.
|