instar 1.3.470 → 1.3.472
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 +15 -0
- package/dist/core/PostUpdateMigrator.d.ts.map +1 -1
- package/dist/core/PostUpdateMigrator.js +41 -0
- package/dist/core/PostUpdateMigrator.js.map +1 -1
- package/dist/core/SessionManager.d.ts +7 -2
- package/dist/core/SessionManager.d.ts.map +1 -1
- package/dist/core/SessionManager.js +33 -10
- package/dist/core/SessionManager.js.map +1 -1
- package/package.json +1 -1
- package/skills/spec-converge/SKILL.md +1 -1
- package/src/data/builtin-manifest.json +20 -20
- package/upgrades/1.3.471.md +50 -0
- package/upgrades/1.3.472.md +40 -0
- package/upgrades/side-effects/pin-interactive-session-lane.md +47 -0
- package/upgrades/side-effects/spec-converge-foundation-audit.md +92 -0
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "./builtin-manifest.schema.json",
|
|
3
3
|
"schemaVersion": 1,
|
|
4
|
-
"generatedAt": "2026-06-
|
|
5
|
-
"instarVersion": "1.3.
|
|
4
|
+
"generatedAt": "2026-06-10T18:08:30.928Z",
|
|
5
|
+
"instarVersion": "1.3.472",
|
|
6
6
|
"entryCount": 201,
|
|
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": "91a08551e1f1c321ae5b923cc68577dd8bda1381bc810d8e3444295947b00ab4",
|
|
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": "91a08551e1f1c321ae5b923cc68577dd8bda1381bc810d8e3444295947b00ab4",
|
|
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": "91a08551e1f1c321ae5b923cc68577dd8bda1381bc810d8e3444295947b00ab4",
|
|
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": "91a08551e1f1c321ae5b923cc68577dd8bda1381bc810d8e3444295947b00ab4",
|
|
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": "91a08551e1f1c321ae5b923cc68577dd8bda1381bc810d8e3444295947b00ab4",
|
|
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": "91a08551e1f1c321ae5b923cc68577dd8bda1381bc810d8e3444295947b00ab4",
|
|
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": "91a08551e1f1c321ae5b923cc68577dd8bda1381bc810d8e3444295947b00ab4",
|
|
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": "91a08551e1f1c321ae5b923cc68577dd8bda1381bc810d8e3444295947b00ab4",
|
|
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": "91a08551e1f1c321ae5b923cc68577dd8bda1381bc810d8e3444295947b00ab4",
|
|
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": "91a08551e1f1c321ae5b923cc68577dd8bda1381bc810d8e3444295947b00ab4",
|
|
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": "91a08551e1f1c321ae5b923cc68577dd8bda1381bc810d8e3444295947b00ab4",
|
|
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": "91a08551e1f1c321ae5b923cc68577dd8bda1381bc810d8e3444295947b00ab4",
|
|
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": "91a08551e1f1c321ae5b923cc68577dd8bda1381bc810d8e3444295947b00ab4",
|
|
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": "91a08551e1f1c321ae5b923cc68577dd8bda1381bc810d8e3444295947b00ab4",
|
|
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": "91a08551e1f1c321ae5b923cc68577dd8bda1381bc810d8e3444295947b00ab4",
|
|
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": "91a08551e1f1c321ae5b923cc68577dd8bda1381bc810d8e3444295947b00ab4",
|
|
150
150
|
"since": "2025-01-01"
|
|
151
151
|
},
|
|
152
152
|
"job:health-check": {
|
|
@@ -1530,7 +1530,7 @@
|
|
|
1530
1530
|
"type": "subsystem",
|
|
1531
1531
|
"domain": "sessions",
|
|
1532
1532
|
"sourcePath": "src/core/SessionManager.ts",
|
|
1533
|
-
"contentHash": "
|
|
1533
|
+
"contentHash": "7c1e84f9d52be2ebff9c3701138f9b65d488ae7ff51ee1e8681d8476c66907fd",
|
|
1534
1534
|
"since": "2025-01-01"
|
|
1535
1535
|
},
|
|
1536
1536
|
"subsystem:auto-updater": {
|
|
@@ -1554,7 +1554,7 @@
|
|
|
1554
1554
|
"type": "subsystem",
|
|
1555
1555
|
"domain": "updates",
|
|
1556
1556
|
"sourcePath": "src/core/PostUpdateMigrator.ts",
|
|
1557
|
-
"contentHash": "
|
|
1557
|
+
"contentHash": "91a08551e1f1c321ae5b923cc68577dd8bda1381bc810d8e3444295947b00ab4",
|
|
1558
1558
|
"since": "2025-01-01"
|
|
1559
1559
|
},
|
|
1560
1560
|
"subsystem:scheduler": {
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# Upgrade Guide — vNEXT
|
|
2
|
+
|
|
3
|
+
<!-- assembled-by: assemble-next-md -->
|
|
4
|
+
<!-- bump: patch -->
|
|
5
|
+
|
|
6
|
+
## What Changed
|
|
7
|
+
|
|
8
|
+
The `/spec-converge` review's Lessons-aware reviewer gained a new mandate — clause
|
|
9
|
+
**(d) FOUNDATION/SUBSYSTEM AUDIT**: the review must now reach one layer below the spec
|
|
10
|
+
boundary and weigh the subsystem the spec *tests, extends, or builds on* against known
|
|
11
|
+
standards and lessons, not just the spec's own surface. When that foundation is flawed,
|
|
12
|
+
the finding is "this spec is sound but the subsystem it depends on violates standard X /
|
|
13
|
+
repeats mistake Y — surface it before building on/around it."
|
|
14
|
+
|
|
15
|
+
This closes a real review gap (2026-06-09): a test-harness spec converged cleanly while
|
|
16
|
+
the permission gate it proved still held brittle blocking authority in violation of
|
|
17
|
+
Signal-vs-Authority. The convergence audited only the harness and took the flawed
|
|
18
|
+
foundation as given. A new idempotent `PostUpdateMigrator` step
|
|
19
|
+
(`migrateSpecConvergeFoundationAudit`) backfills the clause into existing agents'
|
|
20
|
+
installed spec-converge skill on update (fingerprint-guarded; customized skills are left
|
|
21
|
+
untouched).
|
|
22
|
+
|
|
23
|
+
## What to Tell Your User
|
|
24
|
+
|
|
25
|
+
Nothing changes for end users — this is an internal hardening of the instar
|
|
26
|
+
spec-review process used by instar-developing agents. No runtime behavior, gate, or
|
|
27
|
+
message path changes. The practical effect is that future instar specs are reviewed one
|
|
28
|
+
layer deeper, so a spec can no longer pass review while quietly testing or extending a
|
|
29
|
+
component that itself violates a standard.
|
|
30
|
+
|
|
31
|
+
## Summary of New Capabilities
|
|
32
|
+
|
|
33
|
+
- `/spec-converge` Lessons-aware reviewer clause (d): foundation/subsystem audit one
|
|
34
|
+
layer below the spec boundary.
|
|
35
|
+
- `PostUpdateMigrator.migrateSpecConvergeFoundationAudit`: idempotent, fingerprint-guarded
|
|
36
|
+
backfill of the clause for existing agents (customized skills untouched).
|
|
37
|
+
|
|
38
|
+
## Evidence
|
|
39
|
+
|
|
40
|
+
- `skills/spec-converge/SKILL.md` — clause (d) added to the Lessons-aware bullet.
|
|
41
|
+
- `src/core/PostUpdateMigrator.ts` — `migrateSpecConvergeFoundationAudit` registered in
|
|
42
|
+
the migrate runner; mirrors the established fingerprint-guarded skill-content migration
|
|
43
|
+
idiom (`migrateInstarDevInternalOnlyReleaseNoteLane`, `migrateTestAsSelfSkill`).
|
|
44
|
+
- `tests/unit/migrate-spec-converge-foundation-audit.test.ts` — 5 tests: updates a stock
|
|
45
|
+
skill, idempotent when the marker is present, leaves a customized skill untouched,
|
|
46
|
+
no-ops when not installed, and a wiring-integrity test asserting the bundled source
|
|
47
|
+
actually carries the marker (so the migration cannot silently no-op for every agent).
|
|
48
|
+
- `tsc --noEmit` clean; sibling skill-migration + builtin-dev-skills suites green (19
|
|
49
|
+
tests across the touched area).
|
|
50
|
+
- Side-effects review: `upgrades/side-effects/spec-converge-foundation-audit.md`.
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# Upgrade Guide — vNEXT
|
|
2
|
+
|
|
3
|
+
<!-- assembled-by: assemble-next-md -->
|
|
4
|
+
<!-- bump: patch -->
|
|
5
|
+
|
|
6
|
+
## What Changed
|
|
7
|
+
|
|
8
|
+
The interactive (user-facing) session lane now pins to a subscription-pool account,
|
|
9
|
+
mirroring the headless lane. When `subscriptionPool.pinSessionsToPool` is enabled,
|
|
10
|
+
`SessionManager.spawnInteractiveSession` consults the same spawn-account resolver
|
|
11
|
+
that `spawnSession` uses (unless the caller passed an explicit `configHome`, e.g. the
|
|
12
|
+
account-swap path, which still wins). The session launches under the scheduler-picked
|
|
13
|
+
pool account's config home and is tagged with `subscriptionAccountId` — making the
|
|
14
|
+
user's own conversation directly eligible for proactive and reactive auto-swap,
|
|
15
|
+
instead of riding the default login untagged (rescuable only by the
|
|
16
|
+
ProactiveSwapMonitor's default-login fallback). The resolver-pinned home is seeded
|
|
17
|
+
onboarding-ready first, so a headless-enrolled home can't wedge the launch on the
|
|
18
|
+
first-launch wizard. Claude-code only; complete no-op when pinning is off.
|
|
19
|
+
|
|
20
|
+
## What to Tell Your User
|
|
21
|
+
|
|
22
|
+
The conversation you actually chat with is now protected the same first-class way
|
|
23
|
+
your background sessions are. When you pool several logins, your own chat session is
|
|
24
|
+
tagged to whichever login it is running on, so the moment that login gets close to
|
|
25
|
+
full I can move your conversation to a fresh login before it ever stalls — not just
|
|
26
|
+
rescue it after the fact. Nothing changes unless you have pooling turned on.
|
|
27
|
+
|
|
28
|
+
## Summary of New Capabilities
|
|
29
|
+
|
|
30
|
+
- The interactive session lane pins to a pool account and carries its account tag,
|
|
31
|
+
so the user's conversation is first-class for both proactive and reactive swap.
|
|
32
|
+
|
|
33
|
+
## Evidence
|
|
34
|
+
|
|
35
|
+
- `tests/unit/interactive-session-pin.test.ts` — 6 cases: resolver-pin, explicit
|
|
36
|
+
home wins, unwired no-op, empty-pool no-op, codex-not-pinned, onboarding-safe seeding.
|
|
37
|
+
- `tests/integration/subscription-pin-sessions.test.ts` — interactive lane pins via
|
|
38
|
+
the real `selectAccount`-wired resolver; empty-pool no-op.
|
|
39
|
+
- `tests/e2e/session-management-e2e.test.ts` — real tmux: an interactive session is
|
|
40
|
+
tagged with the resolver-picked account and its home is seeded onboarding-ready.
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# Side-effects review — Pin the interactive session lane (B1)
|
|
2
|
+
|
|
3
|
+
**Change:** `SessionManager.spawnInteractiveSession` now consults the wired
|
|
4
|
+
spawn-account resolver (set under `subscriptionPool.pinSessionsToPool`) when the
|
|
5
|
+
caller did not pass an explicit `configHome`. The interactive (user-facing) lane
|
|
6
|
+
launches under, and is tagged with, the scheduler-picked pool account — mirroring
|
|
7
|
+
the headless lane (`spawnSession`). One file: `src/core/SessionManager.ts`.
|
|
8
|
+
|
|
9
|
+
## Blast radius
|
|
10
|
+
|
|
11
|
+
- **Scope is gated three ways.** No-op unless (a) `pinSessionsToPool` wired the
|
|
12
|
+
resolver, (b) the framework is `claude-code`, and (c) the caller passed no
|
|
13
|
+
explicit `configHome`. With pooling off the resolver is never set → `pinnedAccount`
|
|
14
|
+
is null → `effectiveConfigHome`/`effectiveAccountId` are undefined → byte-for-byte
|
|
15
|
+
the prior default-login behavior.
|
|
16
|
+
- **Explicit configHome still wins.** The account-swap path (SessionRefresh) passes
|
|
17
|
+
a `configHome`; that suppresses the resolver, so a swap target is never overridden.
|
|
18
|
+
- **Non-claude lanes untouched.** Codex/Pi interactive sessions are never put on a
|
|
19
|
+
Claude pool home (the `framework === 'claude-code'` guard).
|
|
20
|
+
|
|
21
|
+
## Interactions considered
|
|
22
|
+
|
|
23
|
+
- **Onboarding-safe seeding (#1043):** `ensurePinnedHomeInteractiveReady` is now
|
|
24
|
+
invoked for the resolver-pinned home too (not only explicit-configHome), so a
|
|
25
|
+
headless-enrolled pool home is seeded interactive-ready before the launch — the
|
|
26
|
+
2026-06-09 wizard-wedge cannot recur via this new path. Tokens/oauthAccount are
|
|
27
|
+
never read or written by that helper.
|
|
28
|
+
- **ProactiveSwapMonitor / autoSwapOnRateLimit:** these key on
|
|
29
|
+
`session.subscriptionAccountId`. B1 makes the interactive session carry that tag,
|
|
30
|
+
so it becomes directly swap-eligible. The monitor's default-login resolution
|
|
31
|
+
remains the safety net for the still-untagged case (pooling off / empty pool).
|
|
32
|
+
- **`tmuxSessionExists` early-return:** an already-running session is reused and not
|
|
33
|
+
re-pinned — correct; live sessions are moved by the swap engine, not re-tagged here.
|
|
34
|
+
- **Fail-safe:** `ensureInteractiveReady` logs and continues on a missing/unwritable
|
|
35
|
+
home; a launch never crashes on it (verified by the unit case using a fake path).
|
|
36
|
+
|
|
37
|
+
## Migration / awareness
|
|
38
|
+
|
|
39
|
+
- No config default, hook, skill, or CLAUDE.md template change → no `PostUpdateMigrator`
|
|
40
|
+
entry required. B1 rides the existing `pinSessionsToPool` flag; the user-facing
|
|
41
|
+
continuity capability is already documented (template "Pre-limit (proactive) swap"
|
|
42
|
+
bullet). Existing agents pick up the behavior on the normal code update.
|
|
43
|
+
|
|
44
|
+
## Tests
|
|
45
|
+
|
|
46
|
+
Unit (6), integration (+2 interactive cases in the existing pin suite), e2e (+1 real
|
|
47
|
+
tmux case). Full sibling spawn/session/wiring suites green (96 tests). tsc clean.
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
# Side-Effects Review — spec-converge clause (d) foundation/subsystem audit
|
|
2
|
+
|
|
3
|
+
**Version / slug:** `spec-converge-foundation-audit`
|
|
4
|
+
**Date:** `2026-06-10`
|
|
5
|
+
**Author:** `echo`
|
|
6
|
+
**Tier:** `1` (skill-prompt clause + idempotent content migration + tests; no new runtime subsystem, route, or config)
|
|
7
|
+
**Second-pass reviewer:** `not required`
|
|
8
|
+
|
|
9
|
+
## Summary of the change
|
|
10
|
+
|
|
11
|
+
Extend the `/spec-converge` Lessons-aware reviewer's mandate with clause **(d)
|
|
12
|
+
FOUNDATION/SUBSYSTEM AUDIT**: the review must reach one layer below the spec boundary
|
|
13
|
+
and weigh the subsystem the spec *tests / extends / builds on* against known standards
|
|
14
|
+
and lessons — not just the spec's own surface. When that foundation is flawed, the
|
|
15
|
+
finding is "this spec is sound but the subsystem it depends on violates standard X /
|
|
16
|
+
repeats mistake Y — surface it before building on/around it."
|
|
17
|
+
|
|
18
|
+
Two edits + tests:
|
|
19
|
+
1. `skills/spec-converge/SKILL.md` — the bundled source skill gains clause (d) on the
|
|
20
|
+
Lessons-aware bullet (the `## Internal reviewers` section).
|
|
21
|
+
2. `src/core/PostUpdateMigrator.ts` — a new `migrateSpecConvergeFoundationAudit`
|
|
22
|
+
(registered in the migrate runner) so existing agents' installed
|
|
23
|
+
`.claude/skills/spec-converge/SKILL.md` receives clause (d) on update. Idempotent +
|
|
24
|
+
conservative: re-copies the bundled skill only when the installed copy (a) lacks the
|
|
25
|
+
`FOUNDATION/SUBSYSTEM AUDIT` marker AND (b) still matches the stock spec-converge
|
|
26
|
+
fingerprint (`# /spec-converge` + `**Internal reviewers (Claude subagents):**`). A
|
|
27
|
+
customized skill is skipped untouched.
|
|
28
|
+
3. `tests/unit/migrate-spec-converge-foundation-audit.test.ts` — 5 tests (update,
|
|
29
|
+
idempotent, customized-untouched, not-installed no-op, bundled-source wiring
|
|
30
|
+
integrity).
|
|
31
|
+
|
|
32
|
+
Motivation: the 2026-06-09 gap where a test-harness spec converged cleanly while the
|
|
33
|
+
permission gate it proved still held brittle blocking authority in violation of
|
|
34
|
+
Signal-vs-Authority. The convergence audited only the harness and took the flawed
|
|
35
|
+
foundation as given. This closes that gap structurally (Structure > Willpower): the
|
|
36
|
+
reviewer is *instructed* to look below the spec, rather than the author having to
|
|
37
|
+
remember to.
|
|
38
|
+
|
|
39
|
+
## Decision-point inventory
|
|
40
|
+
|
|
41
|
+
- **Migration content-sniff guard** — re-copy vs. skip. Inputs: installed skill text.
|
|
42
|
+
Branch 1: marker already present → return (idempotent no-op). Branch 2: stock
|
|
43
|
+
fingerprint missing → skip + record `customized`. Branch 3: stock fingerprint present
|
|
44
|
+
AND marker absent → re-copy the bundled skill. No LLM, no runtime authority — pure
|
|
45
|
+
string-presence checks at update time.
|
|
46
|
+
|
|
47
|
+
## 1. Over-block
|
|
48
|
+
|
|
49
|
+
**What legitimate inputs does this change reject?** Nothing is rejected at runtime — no
|
|
50
|
+
gate, no message path, no API. The migration's only "rejection" is *declining to update*
|
|
51
|
+
a skill it can't confidently recognize as stock (fingerprint missing → skipped). That is
|
|
52
|
+
the safe direction: a customized spec-converge skill keeps the operator's edits rather
|
|
53
|
+
than being clobbered. The reviewer clause makes the review *stricter* (one more thing to
|
|
54
|
+
check), but the Lessons-aware reviewer is signal-only — it surfaces findings, it does not
|
|
55
|
+
block; blocking authority remains the separate Standards-Conformance Gate path.
|
|
56
|
+
|
|
57
|
+
## 2. Under-block
|
|
58
|
+
|
|
59
|
+
**What does this still miss?** (a) The clause is a *prompt* instruction, so its
|
|
60
|
+
effectiveness depends on the reviewing model actually reaching one layer down — it is a
|
|
61
|
+
stronger signal, not a code-enforced guarantee (a future code-backed "foundation
|
|
62
|
+
referenced by the spec was audited" check could harden it, but that is out of scope for a
|
|
63
|
+
Tier-1 prompt change). (b) The migration re-copies the *whole* bundled skill (matching the
|
|
64
|
+
established skill-migration idiom); an agent on a much older stock version receives all
|
|
65
|
+
accumulated bundled changes, not just clause (d) — acceptable because the fingerprint
|
|
66
|
+
guard only fires on stock copies. (c) Agents who customized the skill are intentionally
|
|
67
|
+
not upgraded; they must adopt clause (d) by hand.
|
|
68
|
+
|
|
69
|
+
## 3. Level-of-abstraction fit
|
|
70
|
+
|
|
71
|
+
**Right layer?** Yes. The clause lives in the one reviewer whose job is standards/lessons
|
|
72
|
+
conformance (Lessons-aware), beside its existing (a)/(b)/(c) checks — not bolted onto an
|
|
73
|
+
unrelated reviewer. The migration lives beside the sibling skill-content migrations
|
|
74
|
+
(`migrateInstarDevInternalOnlyReleaseNoteLane`, `migrateTestAsSelfSkill`) and reuses their
|
|
75
|
+
exact fingerprint-guarded re-copy pattern, so it inherits the proven Migration-Parity
|
|
76
|
+
idiom rather than inventing a new one.
|
|
77
|
+
|
|
78
|
+
## Migration / rollback
|
|
79
|
+
|
|
80
|
+
- **Migration:** `migrateSpecConvergeFoundationAudit` runs on the normal post-update path.
|
|
81
|
+
Idempotent (marker check) and conservative (fingerprint guard). No state, no config.
|
|
82
|
+
- **Rollback:** pure revert — drop the clause from the bundled skill, remove the migration
|
|
83
|
+
method + its registration line, delete the test. No data migration to undo; the migration
|
|
84
|
+
only ever copied a newer skill prompt over a stock older one.
|
|
85
|
+
|
|
86
|
+
## Testing-integrity note
|
|
87
|
+
|
|
88
|
+
Unit tests cover both sides of the migration's decision boundary (updates stock /
|
|
89
|
+
skips customized / idempotent / not-installed) plus a wiring-integrity test asserting the
|
|
90
|
+
bundled source actually carries the marker (so the migration cannot silently no-op for
|
|
91
|
+
every agent). `tsc --noEmit` clean; sibling skill-migration + builtin-dev-skills suites
|
|
92
|
+
stay green (19 tests total across the touched area).
|