instar 1.3.897 → 1.3.899

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 (32) hide show
  1. package/.claude/skills/autonomous/hooks/autonomous-stop-hook.sh +19 -2
  2. package/dist/core/AutonomousRealCheckAnnotator.d.ts +2 -3
  3. package/dist/core/AutonomousRealCheckAnnotator.d.ts.map +1 -1
  4. package/dist/core/AutonomousRealCheckAnnotator.js +2 -25
  5. package/dist/core/AutonomousRealCheckAnnotator.js.map +1 -1
  6. package/dist/core/AutonomousRunStore.d.ts +7 -0
  7. package/dist/core/AutonomousRunStore.d.ts.map +1 -1
  8. package/dist/core/AutonomousRunStore.js.map +1 -1
  9. package/dist/core/PostUpdateMigrator.d.ts +2 -0
  10. package/dist/core/PostUpdateMigrator.d.ts.map +1 -1
  11. package/dist/core/PostUpdateMigrator.js +117 -2
  12. package/dist/core/PostUpdateMigrator.js.map +1 -1
  13. package/dist/data/provenanceCoverage.d.ts +15 -0
  14. package/dist/data/provenanceCoverage.d.ts.map +1 -1
  15. package/dist/data/provenanceCoverage.js +61 -0
  16. package/dist/data/provenanceCoverage.js.map +1 -1
  17. package/dist/server/CapabilityIndex.js +1 -1
  18. package/dist/server/CapabilityIndex.js.map +1 -1
  19. package/dist/server/routes.d.ts.map +1 -1
  20. package/dist/server/routes.js +105 -3
  21. package/dist/server/routes.js.map +1 -1
  22. package/package.json +2 -1
  23. package/scripts/feature-maturation-plan-gate.mjs +1 -0
  24. package/skills/spec-converge/scripts/write-convergence-tag.mjs +13 -0
  25. package/src/core/FeatureMaturationPlanGate.mjs +58 -0
  26. package/src/data/builtin-manifest.json +63 -63
  27. package/src/data/provenanceCoverage.ts +74 -0
  28. package/src/scaffold/templates/jobs/instar/llm-decision-grading.md +2 -2
  29. package/upgrades/1.3.898.md +24 -0
  30. package/upgrades/1.3.899.md +28 -0
  31. package/upgrades/side-effects/decision-quality-grading.md +86 -0
  32. package/upgrades/side-effects/feature-maturation-plan-visibility.md +84 -0
@@ -115,6 +115,12 @@ export interface ProvenanceCoverageEntry {
115
115
  /** REQUIRED (≥40 chars, ratchet-enforced) for pending/exempt entries — a real
116
116
  * argument, never a lazy "n/a". Optional color for wired entries. */
117
117
  readonly reason?: string;
118
+ /** A wired point normally has at least one RULE_REGISTRY row. This explicit
119
+ * posture is the only honest exception: measurement-only means provenance is
120
+ * intentionally collected before an outcome rule exists; exempt means an
121
+ * outcome is structurally unavailable. Both require gradingReason. */
122
+ readonly gradingPosture?: 'measurement-only' | 'exempt';
123
+ readonly gradingReason?: string;
118
124
  }
119
125
 
120
126
  // ───────────────────────────────────────────────────────────────────────────
@@ -215,6 +221,9 @@ export const PROVENANCE_COVERAGE: ReadonlyArray<ProvenanceCoverageEntry> = [
215
221
  contentClass: 'content-bearing',
216
222
  reason:
217
223
  'The outbound tone/leak authority (spec §5.6 named high-volume point). Enrolled at budget:500/day, identity-only content — never the message body.',
224
+ gradingPosture: 'measurement-only',
225
+ gradingReason:
226
+ 'Phase B will define a reviewed evidence rule and owner; Tier 1 records measurements without pretending they are outcome grades.',
218
227
  },
219
228
  {
220
229
  decisionPoint: DP_CORRECTION_CLASS_REVIEW,
@@ -224,6 +233,9 @@ export const PROVENANCE_COVERAGE: ReadonlyArray<ProvenanceCoverageEntry> = [
224
233
  contentClass: 'content-bearing',
225
234
  reason:
226
235
  'Each durable correction receives one bounded standards/process proposal; identity-only context supports outcome grading without archiving correction text.',
236
+ gradingPosture: 'measurement-only',
237
+ gradingReason:
238
+ 'Phase B will define a reviewed evidence rule and owner; Tier 1 records measurements without pretending they are outcome grades.',
227
239
  },
228
240
  {
229
241
  decisionPoint: DP_COMPLETION_CLAIM_VERIFY,
@@ -233,6 +245,9 @@ export const PROVENANCE_COVERAGE: ReadonlyArray<ProvenanceCoverageEntry> = [
233
245
  contentClass: 'content-bearing',
234
246
  reason:
235
247
  'Completion-language turns receive clause arbitration before optional suppression authority; identity-only context preserves auditability without transcript content.',
248
+ gradingPosture: 'measurement-only',
249
+ gradingReason:
250
+ 'Phase B will define a reviewed evidence rule and owner; Tier 1 records measurements without pretending they are outcome grades.',
236
251
  },
237
252
  {
238
253
  decisionPoint: DP_FEEDBACK_READINESS,
@@ -242,6 +257,9 @@ export const PROVENANCE_COVERAGE: ReadonlyArray<ProvenanceCoverageEntry> = [
242
257
  contentClass: 'content-bearing',
243
258
  reason:
244
259
  'A bounded frontier-model judgment authorizes cluster-to-work readiness; provenance stores packet identity and enumerated outcomes, never feedback text or model output.',
260
+ gradingPosture: 'measurement-only',
261
+ gradingReason:
262
+ 'Phase B will define a reviewed evidence rule and owner; Tier 1 records measurements without pretending they are outcome grades.',
245
263
  },
246
264
 
247
265
  // ── Pending (the ACT-1193 uniform-provenance retrofit backlog — §5.6: "Not
@@ -764,6 +782,8 @@ export type EvidenceStrength = (typeof EVIDENCE_STRENGTHS)[number];
764
782
 
765
783
  export interface EvidenceRule {
766
784
  readonly ruleId: string;
785
+ /** Census decision point whose outcomes this rule grades. */
786
+ readonly decisionPoint: string;
767
787
  readonly rung: EvidenceRung;
768
788
  readonly evidenceStrength: EvidenceStrength;
769
789
  /** The ONLY component whose gradedBy.component the annotate chokepoint
@@ -785,6 +805,7 @@ export const RULE_REGISTRY: Readonly<Record<string, EvidenceRule>> = {
785
805
  // Positive-evidence grading runs in the sentinel's scan ticks + grade-on-supersede.
786
806
  'hog-respawn-wrong-v1': {
787
807
  ruleId: 'hog-respawn-wrong-v1',
808
+ decisionPoint: DP_EXTERNAL_HOG_KILL_LEAVE,
788
809
  rung: 'deterministic-ground-truth',
789
810
  evidenceStrength: 'deterministic-proof',
790
811
  owningComponent: 'ExternalHogSentinel',
@@ -796,6 +817,7 @@ export const RULE_REGISTRY: Readonly<Record<string, EvidenceRule>> = {
796
817
  // close grading runs in the grading job reading the durable hog store.
797
818
  'hog-sustained-right-v1': {
798
819
  ruleId: 'hog-sustained-right-v1',
820
+ decisionPoint: DP_EXTERNAL_HOG_KILL_LEAVE,
799
821
  rung: 'deterministic-ground-truth',
800
822
  evidenceStrength: 'negative-evidence',
801
823
  owningComponent: 'DecisionGrading',
@@ -808,6 +830,7 @@ export const RULE_REGISTRY: Readonly<Record<string, EvidenceRule>> = {
808
830
  // sentinel's scan ticks + grade-on-supersede.
809
831
  'hog-leave-recurrence-v1': {
810
832
  ruleId: 'hog-leave-recurrence-v1',
833
+ decisionPoint: DP_EXTERNAL_HOG_KILL_LEAVE,
811
834
  rung: 'recurrence',
812
835
  evidenceStrength: 'recurrence-proxy',
813
836
  owningComponent: 'ExternalHogSentinel',
@@ -819,6 +842,7 @@ export const RULE_REGISTRY: Readonly<Record<string, EvidenceRule>> = {
819
842
  // wiring binds gradedBy.component to this owner).
820
843
  'completion-realcheck-v1': {
821
844
  ruleId: 'completion-realcheck-v1',
845
+ decisionPoint: DP_COMPLETION_EVALUATE,
822
846
  rung: 'deterministic-ground-truth',
823
847
  evidenceStrength: 'deterministic-proof',
824
848
  owningComponent: 'AutonomousRealCheck',
@@ -828,18 +852,68 @@ export const RULE_REGISTRY: Readonly<Record<string, EvidenceRule>> = {
828
852
  // as a self-report-rung annotation (never overrides an independent grader).
829
853
  'hog-enacted-disposition-v1': {
830
854
  ruleId: 'hog-enacted-disposition-v1',
855
+ decisionPoint: DP_EXTERNAL_HOG_KILL_LEAVE,
831
856
  rung: 'self-report',
832
857
  evidenceStrength: 'self-report',
833
858
  owningComponent: 'ExternalHogSentinel',
834
859
  },
835
860
  'completion-enacted-disposition-v1': {
836
861
  ruleId: 'completion-enacted-disposition-v1',
862
+ decisionPoint: DP_COMPLETION_STOP_RATIONALE,
837
863
  rung: 'self-report',
838
864
  evidenceStrength: 'self-report',
839
865
  owningComponent: 'CompletionChokepoint',
840
866
  },
841
867
  };
842
868
 
869
+ /** Loud class contradiction: a wired provenance point that cannot produce an
870
+ * outcome grade and has not explicitly declared measurement-only/exempt. */
871
+ export function findWiredWithoutGraders(
872
+ coverage: ReadonlyArray<ProvenanceCoverageEntry> = PROVENANCE_COVERAGE,
873
+ registry: Readonly<Record<string, EvidenceRule>> = RULE_REGISTRY,
874
+ ): string[] {
875
+ const graded = new Set(Object.values(registry).map((rule) => rule.decisionPoint));
876
+ return coverage
877
+ .filter((entry) => {
878
+ if (entry.status !== 'wired' || graded.has(entry.decisionPoint)) return false;
879
+ const explicit = entry.gradingPosture === 'measurement-only' || entry.gradingPosture === 'exempt';
880
+ return !explicit || (entry.gradingReason ?? '').trim().length < 40;
881
+ })
882
+ .map((entry) => entry.decisionPoint)
883
+ .sort();
884
+ }
885
+
886
+ /** Full declaration-consistency audit used by the developer-process ratchet.
887
+ * Runtime reads surface the primary wired-but-no-grader subset; CI refuses all
888
+ * mutually contradictory source shapes. */
889
+ export function findGradingContradictions(
890
+ coverage: ReadonlyArray<ProvenanceCoverageEntry> = PROVENANCE_COVERAGE,
891
+ registry: Readonly<Record<string, EvidenceRule>> = RULE_REGISTRY,
892
+ ): string[] {
893
+ const findings: string[] = [];
894
+ const counts = new Map<string, number>();
895
+ for (const entry of coverage) counts.set(entry.decisionPoint, (counts.get(entry.decisionPoint) ?? 0) + 1);
896
+ for (const [decisionPoint, count] of counts) {
897
+ if (count > 1) findings.push(`duplicate-census:${decisionPoint}`);
898
+ }
899
+ const byPoint = new Map(coverage.map((entry) => [entry.decisionPoint, entry]));
900
+ const graded = new Set<string>();
901
+ for (const rule of Object.values(registry)) {
902
+ graded.add(rule.decisionPoint);
903
+ const entry = byPoint.get(rule.decisionPoint);
904
+ if (!entry || entry.status !== 'wired') findings.push(`rule-target-not-wired:${rule.ruleId}:${rule.decisionPoint}`);
905
+ }
906
+ for (const entry of coverage) {
907
+ if (entry.status !== 'wired') continue;
908
+ const hasRule = graded.has(entry.decisionPoint);
909
+ const explicit = entry.gradingPosture === 'measurement-only' || entry.gradingPosture === 'exempt';
910
+ const validReason = (entry.gradingReason ?? '').trim().length >= 40;
911
+ if (hasRule && explicit) findings.push(`grader-and-${entry.gradingPosture}:${entry.decisionPoint}`);
912
+ if (!hasRule && (!explicit || !validReason)) findings.push(`wired-but-no-grader:${entry.decisionPoint}`);
913
+ }
914
+ return [...new Set(findings)].sort();
915
+ }
916
+
843
917
  // ───────────────────────────────────────────────────────────────────────────
844
918
  // Lookup helpers (imported by the settlement seam, the annotate chokepoint,
845
919
  // the grading endpoint, and the read surface).
@@ -1,12 +1,12 @@
1
1
  ---
2
2
  name: LLM-Decision Grading Pass
3
- description: "Hourly deterministic grading pass over the LLM-decision quality substrate. Runs POST /decision-quality/grade-pass: the endpoint walks NEW outcome evidence since the durable per-decision-point cursor (keyset (ts, correlation_id) — same-ms bursts cannot skip rows), applies the registered deterministic evidence rules, and upserts right/wrong/unknown grades idempotently (re-runs converge, never multiply; bounded per pass by provenance.quality.maxDecisionsPerPass). ZERO LLM spend in the pass itself — the grading ladder in this build is deterministic-only (FD11; the LLM evidence-interpreter rung ships NO code, ACT-1198). Ships enabled:false (cost-bearing job class); the operator read surface is GET /decision-quality. NEVER messages the user (FD5 — the meter is observe-only; grading produces rows, not messages). Runs per machine over that machine's local rows (the ratified machine-local data posture). Tier-1 supervised (this haiku job wraps the deterministic endpoint and sanity-checks the response shape). Spec docs/specs/llm-decision-quality-meter.md §5.5."
3
+ description: "Hourly deterministic grading pass over the LLM-decision quality substrate. Runs POST /decision-quality/grade-pass: the endpoint walks NEW outcome evidence since the durable per-decision-point cursor (keyset (ts, correlation_id) — same-ms bursts cannot skip rows), applies the registered deterministic evidence rules, and upserts right/wrong/unknown grades idempotently (re-runs converge, never multiply; bounded per pass by provenance.quality.maxDecisionsPerPass). ZERO LLM spend in the pass itself — the grading ladder in this build is deterministic-only. Ships enabled:true under the newer operator-directed goal-4 Tier-1 activation, superseding the original scaffold-dark default; the operator read surface is GET /decision-quality. NEVER messages the user (the meter is observe-only; grading produces rows, not messages). Runs per machine over that machine's local rows. Tier-1 supervised (this haiku job wraps the deterministic endpoint and sanity-checks the response shape). Substrate: docs/specs/llm-decision-quality-meter.md §5.5."
4
4
  schedule: "0 * * * *"
5
5
  priority: low
6
6
  expectedDurationMinutes: 2
7
7
  model: haiku
8
8
  supervision: tier1
9
- enabled: false
9
+ enabled: true
10
10
  tags:
11
11
  - cat:observability
12
12
  - decision-quality
@@ -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,28 @@
1
+ # Upgrade Guide — vNEXT
2
+
3
+ <!-- assembled-by: assemble-next-md -->
4
+ <!-- bump: patch -->
5
+
6
+ ## What Changed
7
+
8
+ - The provenance census now fails CI when a `wired` decision point has neither a registered evidence rule nor an explicit, reasoned measurement-only/exempt posture.
9
+ - `GET /decision-quality` reports the new `wiredButNoGrader` contradiction list.
10
+ - Autonomous run-end payloads carry real-check pass/fail/not-configured evidence into the existing outcome-annotation chokepoint.
11
+ - The existing hourly `llm-decision-grading` scaffold job now ships enabled.
12
+ - Existing deployed stock autonomous stop hooks are upgraded through the normal marker-based migration; customized hooks remain untouched.
13
+
14
+ ## What to Tell Your User
15
+
16
+ Instar’s decision-quality meter now receives real autonomous completion evidence and runs its existing grading cadence automatically. The meter remains observe-only and does not block decisions or send messages.
17
+
18
+ ## Summary of New Capabilities
19
+
20
+ - Loud detection of wired decision points that cannot actually be graded.
21
+ - Real autonomous completion pass/fail evidence on the existing quality read surface.
22
+ - Enabled bounded hourly grading cadence.
23
+
24
+ ## Evidence
25
+
26
+ - Unit: census class ratchet, negative synthetic enrollment, realcheck adapter, hook payload, job template, and stop-hook migration.
27
+ - Integration/E2E: a real AgentServer run registers a run, records a completion decision, posts run-end with a passing real check, and observes a non-zero right-grade count through `GET /decision-quality`.
28
+ - Build, lint, integration, E2E-alive, and repository suite evidence is recorded in the PR.
@@ -0,0 +1,86 @@
1
+ # Side-Effects Review — Decision-quality grading operationalization
2
+
3
+ **Version / slug:** `decision-quality-grading`
4
+ **Date:** `2026-07-21`
5
+ **Author:** `Instar Agent (instar-codey)`
6
+ **Second-pass reviewer:** `decision_quality_review`
7
+
8
+ ## Summary of the change
9
+
10
+ Extends the existing decision-quality census, rule registry, realcheck annotator, outcome chokepoint, run-end route, autonomous stop hook, and built-in grading job. It adds no second grading engine. The developer-process invariant refuses a malformed enrollment in CI; runtime grading remains observe-only.
11
+
12
+ ## Decision-point inventory
13
+
14
+ - `provenance census enrollment` — modify — a wired point must have a registered grader or explicit measurement-only/exempt posture.
15
+ - `/autonomous/:topic/run-end` — pass-through — carries server-bounded realcheck evidence into the existing annotator; it does not decide whether a run may stop.
16
+ - `llm-decision-grading` cadence — modify — enables the existing bounded deterministic pass.
17
+
18
+ ## 1. Over-block
19
+
20
+ The only new block is a developer-process ratchet. A legitimate new wired point would be blocked if its author omits both its real evidence rule and its explicit measurement-only/exempt posture. That is the intended malformed state. Runtime decisions and run shutdown are never blocked by grading.
21
+
22
+ ## 2. Under-block
23
+
24
+ An explicitly measurement-only point remains ungraded by design, and a dishonest explanation can still pass the length floor. Review owns the semantic quality of that declaration. The runtime contradiction list catches structural drift, not fabricated evidence semantics.
25
+
26
+ ## 3. Level-of-abstraction fit
27
+
28
+ The invariant lives beside `PROVENANCE_COVERAGE` and `RULE_REGISTRY`, the two sources whose contradiction it detects. Outcome evidence uses `AutonomousRealCheckAnnotator` and `annotateDecisionOutcome`; no parallel store, registry, adapter, or grading loop was added.
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 — runtime grading is an observe-only signal and has no block/allow surface.
35
+
36
+ The CI ratchet is a deterministic structural invariant over source declarations, not a semantic judgment about user or agent intent. The run-end annotation failure direction is named and non-blocking.
37
+
38
+ ## 4b. Judgment-point check
39
+
40
+ No static heuristic was added at a competing-signals decision point. Pass/fail comes from the already-authoritative deterministic real check; this change only transports and records that outcome.
41
+
42
+ ## 5. Interactions
43
+
44
+ - Shadowing: the annotation runs before terminal marking but catches every failure, so it cannot shadow run lifecycle.
45
+ - Double-fire: the run record persists the first accepted realcheck outcome per correlation id. Same-outcome replay is named duplicate; opposite replay is named conflict and cannot overwrite the grade. Evidence time derives from the persisted correlation timestamp, so identical replay is byte-stable.
46
+ - Races: before annotation, the route durably reserves the first outcome for the correlation. Reservation failure skips grading with `observation-persist-error` and cannot block terminal marking. A successful grade whose receipt-finalization write fails stays opposite-replay-safe via the reservation and is safely retried by same-outcome delivery.
47
+ - Feedback loops: grades are read-only observations and do not change model routing or gate decisions.
48
+
49
+ ## 6. External surfaces
50
+
51
+ `GET /decision-quality` gains `censusDebt.wiredButNoGrader`; the run-end response gains `realcheckAnnotation`. The built-in grading job is enabled on fresh scaffold installs. No operator action, outbound message, URL, or external service is added.
52
+
53
+ The original converged meter spec required the cost-bearing Haiku wrapper to ship `enabled:false`. The newer operator goal-4 instruction explicitly requires enabling this scaffold under the Tier-1 lane. This artifact records that authority/posture change rather than claiming the older text already authorized it. Existing operator-edited installed jobs retain their current enabled state because the built-in-job migrator preserves explicit state; fresh scaffolds receive `enabled:true`.
54
+
55
+ ## 6b. Operator-surface quality
56
+
57
+ No operator surface — not applicable.
58
+
59
+ ## 7. Multi-machine posture
60
+
61
+ Machine-local by design, proxied-on-read through the existing `GET /decision-quality?scope=pool` composition. Decisions and their realcheck evidence are written on the machine that ran the autonomous session. The job is `perMachineIndependent`; it emits no user-facing notice, creates no topic-keyed durable state of its own, and generates no URLs.
62
+
63
+ ## 8. Rollback cost
64
+
65
+ Revert and ship a patch. The schema is unchanged. Existing grade rows remain valid and idempotent; disabling the scaffold job stops future cadence without state repair. The stop-hook migration replaces only stock-recognized copies and preserves customized hooks.
66
+
67
+ ## Conclusion
68
+
69
+ The change closes the operational gap while preserving the existing authority boundaries and data model. Phase B owns reviewed rules and owners for the four explicitly measurement-only points: messaging tone, correction class review, completion claim verification, and feedback readiness. <!-- tracked: goal-4-phase-b -->
70
+
71
+ ## Second-pass review
72
+
73
+ **Reviewer:** `decision_quality_review`
74
+ **Independent read of the artifact:** concur
75
+
76
+ Concur with the review. The reservation-first state machine preserves terminal lifecycle under write failure, blocks conflicting replay, permits safe same-outcome retry, and keeps grading observe-only. The review’s final non-blocking hardening note was also applied: only a `met:true` observation may reserve an outcome.
77
+
78
+ ## Evidence pointers
79
+
80
+ - `tests/unit/provenance-coverage-ratchet.test.ts`
81
+ - `tests/unit/autonomous-stop-hook-realcheck.test.ts`
82
+ - `tests/e2e/decision-quality-alive.test.ts`
83
+
84
+ ## Class-Closure Declaration (display-only mirror)
85
+
86
+ This change enables an existing self-triggered hourly job. `defectClass: unbounded-self-action`; `closure: guard`; `guardEvidence`: the hourly cron is one trigger per period and `runDecisionGradingPass` is bounded by the configured per-pass maximum, uses durable cursors, and is idempotent. The existing job-template ratchet pins the cadence and endpoint-only body; the controller performs no recursive dispatch, retry loop, notification, or LLM call. The general forcing guard is `tests/unit/self-action-convergence.test.ts`; no new autonomous emitter was introduced for registry enrollment.
@@ -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.