instar 1.3.1321 → 1.3.1322
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.map +1 -1
- package/dist/core/PostUpdateMigrator.js +11 -0
- package/dist/core/PostUpdateMigrator.js.map +1 -1
- package/dist/data/standards-guard-index.json +1 -1
- package/dist/data/standards-guard-index.meta.json +2 -2
- package/dist/data/standards-registry.meta.json +1 -1
- package/dist/scaffold/templates.d.ts.map +1 -1
- package/dist/scaffold/templates.js +4 -0
- package/dist/scaffold/templates.js.map +1 -1
- package/dist/threadline/ThreadlineBootstrap.d.ts +9 -0
- package/dist/threadline/ThreadlineBootstrap.d.ts.map +1 -1
- package/dist/threadline/ThreadlineBootstrap.js +33 -3
- package/dist/threadline/ThreadlineBootstrap.js.map +1 -1
- package/dist/threadline/client/RelayClient.d.ts.map +1 -1
- package/dist/threadline/client/RelayClient.js +9 -0
- package/dist/threadline/client/RelayClient.js.map +1 -1
- package/dist/threadline/client/ThreadlineClient.d.ts +6 -0
- package/dist/threadline/client/ThreadlineClient.d.ts.map +1 -1
- package/dist/threadline/client/ThreadlineClient.js +10 -0
- package/dist/threadline/client/ThreadlineClient.js.map +1 -1
- package/dist/threadline/relayConnectionObserver.d.ts.map +1 -1
- package/dist/threadline/relayConnectionObserver.js +10 -3
- package/dist/threadline/relayConnectionObserver.js.map +1 -1
- package/package.json +1 -1
- package/src/data/builtin-manifest.json +19 -19
- package/src/data/standards-guard-index.json +1 -1
- package/src/data/standards-guard-index.meta.json +2 -2
- package/src/data/standards-registry.meta.json +1 -1
- package/src/scaffold/templates.ts +4 -0
- package/upgrades/1.3.1322.md +29 -0
- package/upgrades/relay-displaced-reclaim.eli16.md +12 -0
- package/upgrades/side-effects/relay-displaced-reclaim.md +24 -0
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "./builtin-manifest.schema.json",
|
|
3
3
|
"schemaVersion": 1,
|
|
4
|
-
"generatedAt": "2026-10-
|
|
5
|
-
"instarVersion": "1.3.
|
|
4
|
+
"generatedAt": "2026-10-07T02:21:47.208Z",
|
|
5
|
+
"instarVersion": "1.3.1322",
|
|
6
6
|
"entryCount": 203,
|
|
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": "5df4ce7d6ceed28d82a6b096cd952d263178ed7246ff03e9d371928a0060b4b0",
|
|
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": "5df4ce7d6ceed28d82a6b096cd952d263178ed7246ff03e9d371928a0060b4b0",
|
|
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": "5df4ce7d6ceed28d82a6b096cd952d263178ed7246ff03e9d371928a0060b4b0",
|
|
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": "5df4ce7d6ceed28d82a6b096cd952d263178ed7246ff03e9d371928a0060b4b0",
|
|
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": "5df4ce7d6ceed28d82a6b096cd952d263178ed7246ff03e9d371928a0060b4b0",
|
|
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": "5df4ce7d6ceed28d82a6b096cd952d263178ed7246ff03e9d371928a0060b4b0",
|
|
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": "5df4ce7d6ceed28d82a6b096cd952d263178ed7246ff03e9d371928a0060b4b0",
|
|
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": "5df4ce7d6ceed28d82a6b096cd952d263178ed7246ff03e9d371928a0060b4b0",
|
|
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": "5df4ce7d6ceed28d82a6b096cd952d263178ed7246ff03e9d371928a0060b4b0",
|
|
87
87
|
"since": "2025-01-01"
|
|
88
88
|
},
|
|
89
89
|
"hook:telegram-origin-guard": {
|
|
@@ -101,7 +101,7 @@
|
|
|
101
101
|
"domain": "coherence",
|
|
102
102
|
"sourcePath": "src/core/PostUpdateMigrator.ts",
|
|
103
103
|
"installedPath": ".instar/hooks/instar/scope-coherence-collector.js",
|
|
104
|
-
"contentHash": "
|
|
104
|
+
"contentHash": "5df4ce7d6ceed28d82a6b096cd952d263178ed7246ff03e9d371928a0060b4b0",
|
|
105
105
|
"since": "2025-01-01"
|
|
106
106
|
},
|
|
107
107
|
"hook:scope-coherence-checkpoint": {
|
|
@@ -110,7 +110,7 @@
|
|
|
110
110
|
"domain": "coherence",
|
|
111
111
|
"sourcePath": "src/core/PostUpdateMigrator.ts",
|
|
112
112
|
"installedPath": ".instar/hooks/instar/scope-coherence-checkpoint.js",
|
|
113
|
-
"contentHash": "
|
|
113
|
+
"contentHash": "5df4ce7d6ceed28d82a6b096cd952d263178ed7246ff03e9d371928a0060b4b0",
|
|
114
114
|
"since": "2025-01-01"
|
|
115
115
|
},
|
|
116
116
|
"hook:free-text-guard": {
|
|
@@ -119,7 +119,7 @@
|
|
|
119
119
|
"domain": "safety",
|
|
120
120
|
"sourcePath": "src/core/PostUpdateMigrator.ts",
|
|
121
121
|
"installedPath": ".instar/hooks/instar/free-text-guard.sh",
|
|
122
|
-
"contentHash": "
|
|
122
|
+
"contentHash": "5df4ce7d6ceed28d82a6b096cd952d263178ed7246ff03e9d371928a0060b4b0",
|
|
123
123
|
"since": "2025-01-01"
|
|
124
124
|
},
|
|
125
125
|
"hook:claim-intercept": {
|
|
@@ -128,7 +128,7 @@
|
|
|
128
128
|
"domain": "coherence",
|
|
129
129
|
"sourcePath": "src/core/PostUpdateMigrator.ts",
|
|
130
130
|
"installedPath": ".instar/hooks/instar/claim-intercept.js",
|
|
131
|
-
"contentHash": "
|
|
131
|
+
"contentHash": "5df4ce7d6ceed28d82a6b096cd952d263178ed7246ff03e9d371928a0060b4b0",
|
|
132
132
|
"since": "2025-01-01"
|
|
133
133
|
},
|
|
134
134
|
"hook:claim-intercept-response": {
|
|
@@ -137,7 +137,7 @@
|
|
|
137
137
|
"domain": "coherence",
|
|
138
138
|
"sourcePath": "src/core/PostUpdateMigrator.ts",
|
|
139
139
|
"installedPath": ".instar/hooks/instar/claim-intercept-response.js",
|
|
140
|
-
"contentHash": "
|
|
140
|
+
"contentHash": "5df4ce7d6ceed28d82a6b096cd952d263178ed7246ff03e9d371928a0060b4b0",
|
|
141
141
|
"since": "2025-01-01"
|
|
142
142
|
},
|
|
143
143
|
"hook:stop-gate-router": {
|
|
@@ -146,7 +146,7 @@
|
|
|
146
146
|
"domain": "safety",
|
|
147
147
|
"sourcePath": "src/core/PostUpdateMigrator.ts",
|
|
148
148
|
"installedPath": ".instar/hooks/instar/stop-gate-router.js",
|
|
149
|
-
"contentHash": "
|
|
149
|
+
"contentHash": "5df4ce7d6ceed28d82a6b096cd952d263178ed7246ff03e9d371928a0060b4b0",
|
|
150
150
|
"since": "2025-01-01"
|
|
151
151
|
},
|
|
152
152
|
"hook:auto-approve-permissions": {
|
|
@@ -155,7 +155,7 @@
|
|
|
155
155
|
"domain": "safety",
|
|
156
156
|
"sourcePath": "src/core/PostUpdateMigrator.ts",
|
|
157
157
|
"installedPath": ".instar/hooks/instar/auto-approve-permissions.js",
|
|
158
|
-
"contentHash": "
|
|
158
|
+
"contentHash": "5df4ce7d6ceed28d82a6b096cd952d263178ed7246ff03e9d371928a0060b4b0",
|
|
159
159
|
"since": "2025-01-01"
|
|
160
160
|
},
|
|
161
161
|
"job:health-check": {
|
|
@@ -1571,7 +1571,7 @@
|
|
|
1571
1571
|
"type": "subsystem",
|
|
1572
1572
|
"domain": "updates",
|
|
1573
1573
|
"sourcePath": "src/core/PostUpdateMigrator.ts",
|
|
1574
|
-
"contentHash": "
|
|
1574
|
+
"contentHash": "5df4ce7d6ceed28d82a6b096cd952d263178ed7246ff03e9d371928a0060b4b0",
|
|
1575
1575
|
"since": "2025-01-01"
|
|
1576
1576
|
},
|
|
1577
1577
|
"subsystem:scheduler": {
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"schemaVersion": 1,
|
|
3
3
|
"generatedFrom": "source-tree",
|
|
4
4
|
"registrySha256": "35448db940d659661ebdfb09761439033f93a15157540ee2f6eecf825488e1e6",
|
|
5
|
-
"packageVersion": "1.3.
|
|
5
|
+
"packageVersion": "1.3.1322",
|
|
6
6
|
"guards": [
|
|
7
7
|
{
|
|
8
8
|
"ref": "docs/audits/phase-b/f10-triage.md",
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"sha256": "
|
|
2
|
+
"sha256": "88254d7c0e3148acfb13b7fd93df3e8229c19f4d4d74591749e814eb5fdd2df9",
|
|
3
3
|
"registrySha256": "35448db940d659661ebdfb09761439033f93a15157540ee2f6eecf825488e1e6",
|
|
4
|
-
"packageVersion": "1.3.
|
|
4
|
+
"packageVersion": "1.3.1322"
|
|
5
5
|
}
|
|
@@ -2002,6 +2002,10 @@ Agent-to-agent delivery is tracked durably so a message can't silently die out.
|
|
|
2002
2002
|
- One peer: \`curl http://localhost:${port}/threadline/peers/<fingerprint>/health\`
|
|
2003
2003
|
- \`stale: true\` (or a non-zero \`staleCount\`) means a message has been awaiting acknowledgement past the threshold — the peer may be dark or unreachable; check the relay and the peer's address before assuming they're ignoring me. **Proactive trigger:** when a peer "goes quiet" or before relying on a peer having received something, read this instead of guessing. Read-only — never gates a send.
|
|
2004
2004
|
|
|
2005
|
+
### Is my own relay connection up? (displaced vs retrying)
|
|
2006
|
+
|
|
2007
|
+
Before blaming a quiet peer, check MY side: \`curl http://localhost:${port}/threadline/health\` → \`relay.state\`. \`connected\` is healthy; \`disconnected\` with \`recoverable: true\` is retrying on its own; \`displaced\` means another connection using my identity (usually my own other machine) took the relay. A displaced machine raises a \`Threadline.relay\` degradation and reclaims the connection after a 15-minute pause; a standby (\`multiMachine.telegramPolling: false\`) never connects at all. A send that says "submitted to relay; acceptance unconfirmed" while my relay is down did NOT leave. **Proactive trigger:** a peer hasn't replied and \`/threadline/peers/<fp>/health\` shows a pending message → read my own relay state first.
|
|
2008
|
+
|
|
2005
2009
|
### Threadline Single-Negotiator Lock (one voice per conversation)
|
|
2006
2010
|
|
|
2007
2011
|
Threadline has a per-conversation **negotiator lease**: at most ONE of my sessions owns a conversation's outbound voice at a time. A warm/keep-alive/side session can read, but the most it can SEND is a fixed structural "owner will respond" holding notice — it can never speak content or bind me to anything. The lease is the ONLY blocking authority and it keys on WHO speaks (a structural ownership check), never on what a message means (Signal-vs-Authority).
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# Upgrade Guide — vNEXT
|
|
2
|
+
|
|
3
|
+
<!-- assembled-by: assemble-next-md -->
|
|
4
|
+
<!-- bump: patch -->
|
|
5
|
+
|
|
6
|
+
## What Changed
|
|
7
|
+
|
|
8
|
+
When a second connection using the same identity (usually the agent's own other machine) joined the Threadline relay, the first connection was displaced and stopped retrying for the life of the process. The relay's follow-up 4001 close then emitted a plain `disconnected`, so `/threadline/health` reported `disconnected, recoverable: true` for an agent that would never reconnect. Luna's (sagemind) laptop sat in that state for 40 hours on 2026-10-05/06, unreachable by every peer.
|
|
9
|
+
|
|
10
|
+
- `RelayClient`: a `displaced` frame now sets the state to `disconnected` at once, so the 4001 close no longer emits a masking `disconnected`. An `auth_error` frame now closes the socket, so the close handler schedules the retry instead of waiting on an open unauthenticated socket.
|
|
11
|
+
- `relayConnectionObserver`: a terminal `displaced` is no longer overwritten by a later plain disconnect; a successful `connected` clears it.
|
|
12
|
+
- `ThreadlineBootstrap`: on displacement the server reports a `Threadline.relay` degradation and, after `relayRearmAfterDisplacedMs` (default 15 min, 0 disables), reclaims the connection. Only the configured relay owner holds a relay client (a standby never connects), so reclaiming is the correct outcome. A failed first connect no longer drops the client: it keeps retrying with backoff instead of leaving the agent local-only until restart.
|
|
13
|
+
- `ThreadlineClient.reconnectRelay()` re-arms the existing relay client with its listeners intact.
|
|
14
|
+
- CLAUDE.md template + migration: "Is my own relay connection up? (displaced vs retrying)".
|
|
15
|
+
|
|
16
|
+
## What to Tell Your User
|
|
17
|
+
|
|
18
|
+
If another copy of me on one of your machines briefly takes my connection to other agents, I now say so and take it back on my own after a short pause, instead of going silent to other agents until someone restarts me.
|
|
19
|
+
|
|
20
|
+
## Summary of New Capabilities
|
|
21
|
+
|
|
22
|
+
- Displaced relay connections are reported as a degradation and reclaimed after a pause.
|
|
23
|
+
- `/threadline/health` reports `displaced` (not "recoverable") when that is the true state.
|
|
24
|
+
|
|
25
|
+
## Evidence
|
|
26
|
+
|
|
27
|
+
- `tests/e2e/threadline/RelayE2E.test.ts`: against a real relay, a displaced client reports `disconnected` at once and emits no follow-up plain disconnect, and `connect()` reclaims the connection (both fail without the fix).
|
|
28
|
+
- `tests/e2e/threadline/relay-displacement-reclaim.test.ts`: the production bootstrap path is displaced, reports the degradation, then reclaims the relay and the intruder is displaced in turn.
|
|
29
|
+
- `tests/unit/relay-connection-observer.test.ts`: a plain disconnect after a displacement does not mask it; a reconnect clears it.
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# A machine bumped off the agent relay takes it back (ELI16)
|
|
2
|
+
|
|
3
|
+
Agents talk to each other through a shared relay, and the relay allows one connection per agent identity. When a second connection with the same identity arrives, the first one is kicked off ("displaced").
|
|
4
|
+
|
|
5
|
+
Before this change, a displaced connection gave up for good, and its health report still said it would recover. That is what happened to Luna: her Studio briefly connected with her identity, her laptop was kicked off, and for 40 hours no agent could reach her, with nothing raising an alarm.
|
|
6
|
+
|
|
7
|
+
Now:
|
|
8
|
+
- The health report says "displaced" honestly instead of "will recover".
|
|
9
|
+
- The server raises a degradation alert, so the problem shows up.
|
|
10
|
+
- After a 15-minute pause, the machine takes its connection back. Only the machine that is supposed to own the relay ever holds a connection (a standby never connects), so taking it back is the right outcome. The pause keeps two misconfigured machines from fighting over it every few seconds.
|
|
11
|
+
- Two other ways a connection could stall forever are closed: a rejected login that left the socket hanging, and a failed first connection that the server stopped tracking.
|
|
12
|
+
- Agents learn, through their instructions, to check their own relay before assuming a quiet peer is ignoring them.
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# Side-effects review: relay-displaced-reclaim
|
|
2
|
+
|
|
3
|
+
## Change
|
|
4
|
+
RelayClient displaced/auth_error state handling; observer keeps terminal events; ThreadlineBootstrap reports a degradation on displacement and reclaims the relay after a pause (default 15 min); a failed first connect keeps the client retrying; ThreadlineClient.reconnectRelay(); CLAUDE.md template + idempotent migration section.
|
|
5
|
+
|
|
6
|
+
## Over-block / under-block
|
|
7
|
+
No gate added. The reclaim can only reconnect a machine that already held a relay client, i.e. a configured relay owner (relayEnabled and not relayStandby, and no listener daemon owning the relay).
|
|
8
|
+
|
|
9
|
+
## Self-action bound
|
|
10
|
+
Reclaim is a self-triggered reconnect. Bounded: at most one pending timer per process, one reclaim per displacement, minimum spacing of the configured pause (15 min default). If two machines are both misconfigured as owners they trade the connection at most once per pause each, and every displacement raises a degradation, so the misconfiguration is visible rather than silent. `relayRearmAfterDisplacedMs: 0` restores the pre-fix behaviour.
|
|
11
|
+
|
|
12
|
+
## Interactions
|
|
13
|
+
- Standby (`relayStandby`) machines never create a relay client, so they never reclaim (unchanged, instar#2122).
|
|
14
|
+
- Listener-daemon mode: the server does not hold the relay client, so no reclaim (unchanged).
|
|
15
|
+
- Keeping the client after a failed first connect: routes that check `relayClient` now see a client in `disconnected` state instead of undefined; sends while disconnected fail visibly as before, and the client reconnects when the relay returns.
|
|
16
|
+
|
|
17
|
+
## Signal vs authority
|
|
18
|
+
The degradation report is a signal only. The reclaim reconnects this agent's own connection; it takes no action on peers.
|
|
19
|
+
|
|
20
|
+
## External surfaces
|
|
21
|
+
`/threadline/health` relay.state reports `displaced` accurately. Agent CLAUDE.md gains one section (template + migration, content-sniffed).
|
|
22
|
+
|
|
23
|
+
## Rollback
|
|
24
|
+
Revert the commit, or set `relayRearmAfterDisplacedMs: 0` to disable the reclaim only.
|