instar 1.3.862 → 1.3.864
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/commands/server.d.ts.map +1 -1
- package/dist/commands/server.js +11 -0
- package/dist/commands/server.js.map +1 -1
- package/dist/lifeline/TelegramLifeline.d.ts.map +1 -1
- package/dist/lifeline/TelegramLifeline.js +7 -15
- package/dist/lifeline/TelegramLifeline.js.map +1 -1
- package/dist/lifeline/queuedNotice.d.ts +31 -0
- package/dist/lifeline/queuedNotice.d.ts.map +1 -0
- package/dist/lifeline/queuedNotice.js +40 -0
- package/dist/lifeline/queuedNotice.js.map +1 -0
- package/package.json +1 -1
- package/src/data/builtin-manifest.json +3 -3
- package/upgrades/1.3.863.md +65 -0
- package/upgrades/1.3.864.md +23 -0
- package/upgrades/side-effects/lifeline-reconnect-notice.md +121 -0
- package/upgrades/side-effects/ws11-capability-refresh-after-queue-boot.md +78 -0
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# Upgrade Guide — vNEXT
|
|
2
|
+
|
|
3
|
+
<!-- assembled-by: assemble-next-md -->
|
|
4
|
+
<!-- bump: patch -->
|
|
5
|
+
|
|
6
|
+
## What Changed
|
|
7
|
+
|
|
8
|
+
When the lifeline can't hand a message off to the server but the server is
|
|
9
|
+
confirmed **healthy** (a transient timeout / 5xx / connection blip on a single
|
|
10
|
+
forward), the queued-message notice no longer says the false, alarming
|
|
11
|
+
"Server is restarting." It now reflects the real state: "I'm having trouble
|
|
12
|
+
reaching my server right now — your message is queued (N in queue) and I'll
|
|
13
|
+
deliver it as soon as I reconnect." The genuinely-down message
|
|
14
|
+
("Server is temporarily down…") is unchanged. The message, photo, and file
|
|
15
|
+
handlers all route through one shared helper (`buildQueuedNotice`) so the two
|
|
16
|
+
states can't drift apart again.
|
|
17
|
+
|
|
18
|
+
## What to Tell Your User
|
|
19
|
+
|
|
20
|
+
If a message of yours briefly can't be delivered while my server is actually
|
|
21
|
+
up, you'll now see an honest "reconnecting, your message is queued" note
|
|
22
|
+
instead of a scary "Server is restarting" alarm. Nothing about delivery
|
|
23
|
+
changed — your message was never lost; it queues and delivers as before. This
|
|
24
|
+
only fixes the wording so it stops claiming a restart that never happened.
|
|
25
|
+
|
|
26
|
+
## Summary of New Capabilities
|
|
27
|
+
|
|
28
|
+
No new setting. This is a bug fix to an existing user-facing notice.
|
|
29
|
+
|
|
30
|
+
## Evidence
|
|
31
|
+
|
|
32
|
+
- New unit test (`tests/unit/lifeline/queuedNotice.test.ts`, 8 cases) proves the
|
|
33
|
+
healthy-but-forward-failed branch never says "restart" or "temporarily down"
|
|
34
|
+
and always says "reconnect", and that the genuinely-down wording is preserved
|
|
35
|
+
byte-for-byte.
|
|
36
|
+
- Full lifeline unit suite passes (18 files / 160 tests); TypeScript build and
|
|
37
|
+
`pnpm build` are clean; exactly one "Server is restarting" string remains in
|
|
38
|
+
the compiled lifeline (the separate callback-query server-down case, out of
|
|
39
|
+
scope).
|
|
40
|
+
|
|
41
|
+
## The problem in one breath
|
|
42
|
+
|
|
43
|
+
The lifeline is the small always-on process that watches Telegram and hands your messages to my main server. When it can't hand a message off right now, it queues the message and sends you a heads-up. There are two very different reasons a hand-off can fail — the server is genuinely down, OR the server is perfectly healthy and just one hand-off blipped (a brief network timeout). The old code sent the SAME scary "Server is restarting. Your message has been queued…" text for BOTH cases. So when the server was confirmed up and running, you could still get told it was restarting — which never happened. It's harmless (your message is never lost — it queues and delivers) but it erodes trust, because the agent cried "restart" when nothing restarted.
|
|
44
|
+
|
|
45
|
+
## What already exists
|
|
46
|
+
|
|
47
|
+
- **The lifeline** — the tiny watchdog process that forwards your Telegram messages to the server and queues them if it can't. Already durable: queued messages survive and replay.
|
|
48
|
+
- **The server health check** — the lifeline always knows whether the server is up (`supervisor.healthy`). That verdict was already available at the exact spot where the wrong message was sent; the code just wasn't using it to pick the right words.
|
|
49
|
+
- **The genuinely-down message** — for a truly-down server the lifeline already said the accurate "Server is temporarily down…", and that wording is unchanged.
|
|
50
|
+
|
|
51
|
+
## What this adds
|
|
52
|
+
|
|
53
|
+
One small, tested helper (`buildQueuedNotice`) now decides the notice wording from the live health verdict. When the server is healthy but the hand-off failed, you get: "I'm having trouble reaching my server right now — your message is queued (N in queue) and I'll deliver it as soon as I reconnect." When the server is genuinely down, you get the exact same accurate "temporarily down" message as before. The three places that send this notice (text, photo, file) all route through the one helper, so they can never drift apart again.
|
|
54
|
+
|
|
55
|
+
## The new pieces
|
|
56
|
+
|
|
57
|
+
- **`buildQueuedNotice(kind, queueLength, serverHealthy)`** — a pure, side-effect-free function that returns the right notice text. It is NOT allowed to make any decision about delivery or restarts; it only chooses words from a health verdict it is handed. That line matters: the authority to restart still lives entirely in the existing restart machinery — this helper just describes the current state honestly.
|
|
58
|
+
|
|
59
|
+
## The safeguards
|
|
60
|
+
|
|
61
|
+
The genuinely-down wording is byte-for-byte identical to before (a test locks that in, so no downstream dedup behavior shifts). A unit test proves the healthy-but-failed branch never contains the words "restart" or "temporarily down", and always mentions "reconnect"; and that the two states always produce different text. Scope is deliberately tight: the drift-promoter threshold question and the callback-query down-message are explicitly out of scope and were left untouched.
|
|
62
|
+
|
|
63
|
+
## What you actually need to decide
|
|
64
|
+
|
|
65
|
+
Nothing risky. This is a wording/logic bug fix with no new capability, no config, no state, and no schema change. The only judgment call is the exact replacement wording, which reads in plain language and is honest about what's happening. If it turns out wrong, the back-out is a one-line revert.
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# Upgrade Guide — vNEXT
|
|
2
|
+
|
|
3
|
+
<!-- assembled-by: assemble-next-md -->
|
|
4
|
+
<!-- bump: patch -->
|
|
5
|
+
|
|
6
|
+
## What Changed
|
|
7
|
+
|
|
8
|
+
When the durable inbound queue starts late in server boot, Instar now immediately refreshes the machine's pool heartbeat. Peers therefore see `ws11DeliverReceive:true` as soon as the receive path is actually live instead of retaining the earlier boot-time `false` advert.
|
|
9
|
+
|
|
10
|
+
## What to Tell Your User
|
|
11
|
+
|
|
12
|
+
Cross-machine message forwarding becomes ready as soon as the receiving machine's durable queue starts, closing a short boot window that could make another machine treat it as unable to receive.
|
|
13
|
+
|
|
14
|
+
## Summary of New Capabilities
|
|
15
|
+
|
|
16
|
+
No new user-facing control. This makes the existing cross-machine forwarding capability advertise its live state promptly and honestly.
|
|
17
|
+
|
|
18
|
+
## Evidence
|
|
19
|
+
|
|
20
|
+
- Added a wiring regression test that pins the heartbeat refresh immediately after successful queue construction.
|
|
21
|
+
- `tests/unit/ws11-dispatch-to-owner-wiring.test.ts`: 8/8 passing.
|
|
22
|
+
- TypeScript build passing.
|
|
23
|
+
- Live single-agent CROSS-MACHINE reproduction: both machines had live inbound queues while the pool advert remained false, causing a known-remote-owner message to queue without custody and fall through to a duplicate local spawn.
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
# Side-Effects Review — Lifeline "reconnecting" notice (fix false "Server is restarting")
|
|
2
|
+
|
|
3
|
+
**Version / slug:** `lifeline-reconnect-notice`
|
|
4
|
+
**Date:** `2026-07-17`
|
|
5
|
+
**Author:** `Echo (instar-dev agent)`
|
|
6
|
+
**Second-pass reviewer:** `Echo (Phase-5 self-review — see below)`
|
|
7
|
+
|
|
8
|
+
## Summary of the change
|
|
9
|
+
|
|
10
|
+
The lifeline forwards inbound Telegram messages to the server and, when it cannot forward right now, queues the message and sends the user a heads-up. There are two distinct "couldn't deliver right now" states — the server is genuinely **down** (`supervisor.healthy === false`) versus the server is **healthy but this one forward failed** (transient 10s timeout / 5xx / 503-boot / connection blip, `supervisor.healthy === true` and `forwardToServer()` returned non-`ok`). The healthy-but-failed branch was sending the user the false, alarming `Server is restarting. Your message has been queued…` even though the server was confirmed up. Reported by peer agent Luna (Sagemind) 2026-07-17, verified against source; it also hit operator Justin directly.
|
|
11
|
+
|
|
12
|
+
Files touched:
|
|
13
|
+
- `src/lifeline/queuedNotice.ts` (new) — a pure helper `buildQueuedNotice(kind, queueLength, serverHealthy)` that centralizes the notice wording.
|
|
14
|
+
- `src/lifeline/TelegramLifeline.ts` — the four queue-ack call sites (text healthy-fail, text down, photo, file/document) now route through the helper; the two photo/file inline `if/else` blocks collapse to one call each.
|
|
15
|
+
- `tests/unit/lifeline/queuedNotice.test.ts` (new) — unit coverage.
|
|
16
|
+
|
|
17
|
+
## Decision-point inventory
|
|
18
|
+
|
|
19
|
+
- `TelegramLifeline` queue-ack wording (text/photo/file handlers) — **modified (wording/logic only)** — picks the user-facing notice string from the live `supervisor.healthy` verdict. This is a message-*wording* decision, not a message *block/allow* or delivery decision. No gating authority added, removed, or changed.
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## 1. Over-block
|
|
24
|
+
|
|
25
|
+
No block/allow surface — over-block not applicable. The change never suppresses, delays, or rejects a message; it only chooses the text of a heads-up that is already being sent (still gated by the unchanged `shouldSendQueueAck` rate-limiter). Message queueing/delivery is entirely unchanged.
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
## 2. Under-block
|
|
30
|
+
|
|
31
|
+
No block/allow surface — under-block not applicable. The queued message still enqueues and replays exactly as before; the only behavioral delta is the words in the notice.
|
|
32
|
+
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
## 3. Level-of-abstraction fit
|
|
36
|
+
|
|
37
|
+
Correct layer. The wording decision belongs precisely where the send happens — the lifeline handler that already holds the `supervisor.healthy` verdict and the queue length. The new helper is a pure string builder (lowest sensible level: no I/O, no decision authority). It does not re-implement or run parallel to any existing gate; it consumes a health verdict the caller already computed. Centralizing the three previously-duplicated sites into one tested function is a strict simplification (DRY), not a new abstraction competing with an existing one.
|
|
38
|
+
|
|
39
|
+
---
|
|
40
|
+
|
|
41
|
+
## 4. Signal vs authority compliance
|
|
42
|
+
|
|
43
|
+
**Required reference:** docs/signal-vs-authority.md
|
|
44
|
+
|
|
45
|
+
- [x] No — this change has no block/allow surface.
|
|
46
|
+
|
|
47
|
+
`buildQueuedNotice` holds ZERO authority: it neither restarts anything, nor decides whether to send, nor gates delivery. It is handed a health SIGNAL (`supervisor.healthy`, computed by the existing supervisor) and returns descriptive text. The authority to restart the lifeline remains entirely with the existing `RestartOrchestrator` / `LifelineDriftPromoter`; this change deliberately stops the notice from *asserting* a restart the system did not perform — i.e. it makes the user-facing text HONEST about the current state rather than claiming an action. No brittle logic gains blocking authority.
|
|
48
|
+
|
|
49
|
+
---
|
|
50
|
+
|
|
51
|
+
## 4b. Judgment-point check (Judgment Within Floors standard)
|
|
52
|
+
|
|
53
|
+
No new static heuristic at a competing-signals decision point. The wording is chosen from a single, enumerable boolean (`serverHealthy` true/false) — an invariant two-state fork, not a point where multiple live signals conflict. There is no arbiter needed and none added.
|
|
54
|
+
|
|
55
|
+
---
|
|
56
|
+
|
|
57
|
+
## 5. Interactions
|
|
58
|
+
|
|
59
|
+
- **Shadowing:** none. The notice send sits after `shouldSendQueueAck` (unchanged) and does not run before/after any gate whose outcome it could mask.
|
|
60
|
+
- **Double-fire:** none introduced. The version-skew path (`handleVersionSkew`, fired on a 426) is a separate code path and is untouched; this change does not add a second notice.
|
|
61
|
+
- **Races:** none new. `this.queue.length` is read at send time exactly as before; no new shared state is introduced (the helper is stateless/pure).
|
|
62
|
+
- **Feedback loops:** none. The text is terminal output to the user; it feeds nothing back into the forward/queue machinery.
|
|
63
|
+
- **Down-branch wording preserved byte-for-byte:** the `serverHealthy === false` output is identical to the previous inline strings (locked by a test), so any downstream that keys on that exact text (e.g. the duplicate-message dedup window) sees no change.
|
|
64
|
+
|
|
65
|
+
---
|
|
66
|
+
|
|
67
|
+
## 6. External surfaces
|
|
68
|
+
|
|
69
|
+
- **Other agents / install base:** ships in the instar package `dist/`; every agent gets the corrected wording when it updates and its lifeline restarts onto the new version. No migration needed — the lifeline is compiled package code, not an agent-installed file (`.claude/settings.json`, config defaults, CLAUDE.md template, hook scripts, or built-in skills), so `PostUpdateMigrator` is not involved.
|
|
70
|
+
- **Telegram:** the only external-visible change is the improved notice text a user reads when a forward transiently fails. No API shape, topic, or delivery-path change.
|
|
71
|
+
- **Persistent state:** none. No schema, ledger, or state-file change.
|
|
72
|
+
- **Timing/runtime:** the branch is selected from the live `supervisor.healthy` at send time — same input the old code had at the same spot.
|
|
73
|
+
- **Operator surface (Mobile-Complete):** no operator-facing actions added or touched. This is a USER-facing message, not an operator action/approval/grant surface.
|
|
74
|
+
|
|
75
|
+
---
|
|
76
|
+
|
|
77
|
+
## 6b. Operator-surface quality (Operator-Surface Quality standard)
|
|
78
|
+
|
|
79
|
+
No operator surface — not applicable. This change touches a **user-facing** Telegram notice, not a dashboard renderer, approval page, or grant/revoke/secret-drop form. (For completeness on the user-facing text quality: the new notice leads with the real state in plain language — "I'm having trouble reaching my server right now — your message is queued (N in queue) and I'll deliver it as soon as I reconnect." — exposes no raw internals, and is honest rather than alarming.)
|
|
80
|
+
|
|
81
|
+
---
|
|
82
|
+
|
|
83
|
+
## 7. Multi-machine posture (Cross-Machine Coherence)
|
|
84
|
+
|
|
85
|
+
**machine-local BY DESIGN.** The lifeline is a per-machine process: each machine's lifeline forwards to that machine's own server and its `supervisor.healthy` verdict is about the local server. The notice is emitted by whichever machine actually received and tried to forward the user's message, so there is no cross-machine state to replicate or proxy. It emits a user-facing notice, but one-voice gating is not newly needed: the send is already governed by the existing per-topic `shouldSendQueueAck` rate-limiter and the pre-existing duplicate-message suppression window — this change alters only the words, not the send cadence or the number of voices. No durable state (nothing to strand on topic transfer) and no generated URLs.
|
|
86
|
+
|
|
87
|
+
---
|
|
88
|
+
|
|
89
|
+
## 8. Rollback cost
|
|
90
|
+
|
|
91
|
+
Pure code change — revert the two source files (and the new helper/test) and ship as the next patch. No persistent state, no data migration, no agent-state repair, no user-visible regression during the rollback window (worst case is the old wording returns). One-line-scale back-out.
|
|
92
|
+
|
|
93
|
+
---
|
|
94
|
+
|
|
95
|
+
## Conclusion
|
|
96
|
+
|
|
97
|
+
The review confirms a tightly-scoped, low-risk wording/logic fix with no decision-point authority, no block/allow surface, no persistent state, and no multi-machine coherence hazard. The design change made during review was to extract the wording into a single pure helper (rather than edit three inline strings), which both makes the fix unit-testable in isolation and removes the duplicated photo/file `if/else` — closing the "three copies drift apart" failure mode structurally. The genuinely-down wording is preserved byte-for-byte to avoid any downstream dedup/text-matching side effect. Scope was deliberately held to the three reported sites; the drift-promoter threshold question and the callback-query down-message were left untouched (flagged to the reporter as separate items). Clear to ship.
|
|
98
|
+
|
|
99
|
+
---
|
|
100
|
+
|
|
101
|
+
## Second-pass review (if required)
|
|
102
|
+
|
|
103
|
+
**Reviewer:** Echo (self, Phase-5 — the change touches the messaging/lifeline path)
|
|
104
|
+
**Independent read of the artifact: concur**
|
|
105
|
+
|
|
106
|
+
Concur with the review. Re-verified independently: (1) the only remaining `Server is restarting` string in `TelegramLifeline.ts` is the callback-query genuine-`!supervisor.healthy` branch (out of scope, and at least plausibly-true in a down state); (2) all four queue-ack sites now route through `buildQueuedNotice`; (3) the down-branch bytes are unchanged (test-locked); (4) no self-triggered action is added — the notice is a one-shot response to an inbound user message, not a self-firing loop. No concern raised.
|
|
107
|
+
|
|
108
|
+
---
|
|
109
|
+
|
|
110
|
+
## Evidence pointers
|
|
111
|
+
|
|
112
|
+
- `npx tsc --noEmit` — clean (exit 0).
|
|
113
|
+
- `npx vitest run tests/unit/lifeline/queuedNotice.test.ts` — 8/8 pass.
|
|
114
|
+
- `npx vitest run tests/unit/lifeline/` — 18 files / 160 tests pass (no regression).
|
|
115
|
+
- `pnpm build` — dist compiles; `dist/lifeline/queuedNotice.js` present; exactly 1 `Server is restarting` remains in `dist/lifeline/TelegramLifeline.js` (the intentional callback-down site).
|
|
116
|
+
|
|
117
|
+
---
|
|
118
|
+
|
|
119
|
+
## Class-Closure Declaration (display-only mirror)
|
|
120
|
+
|
|
121
|
+
Not a self-triggered controller and not a fix to an agent-authored artifact (prompt/hook/config/skill/standards text). This is a fix to compiled TypeScript runtime behavior — a one-shot, user-message-driven notice, not a loop/monitor/sentinel/reaper/scheduler/recovery path. `unbounded-self-action` class: `n/a` — one-shot user-driven action, not a self-triggered loop.
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
# Side-Effects Review — WS1.1 capability refresh after queue boot
|
|
2
|
+
|
|
3
|
+
**Version / slug:** `ws11-capability-refresh-after-queue-boot`
|
|
4
|
+
**Date:** `2026-07-17`
|
|
5
|
+
**Author:** `Instar Agent (instar-codey)`
|
|
6
|
+
**Second-pass reviewer:** `pending`
|
|
7
|
+
|
|
8
|
+
## Summary of the change
|
|
9
|
+
|
|
10
|
+
After `QueueDrainLoop` is successfully constructed in `src/commands/server.ts`, the existing `refreshPool()` heartbeat writer is invoked immediately. This republishes the already-existing live capability fields from their late-bound runtime handles. The change touches the cross-machine forwarding readiness decision consumed by `SessionRouter.ownerSupportsForward`; it does not alter ownership, queue custody, placement, or forwarding policy.
|
|
11
|
+
|
|
12
|
+
## Decision-point inventory
|
|
13
|
+
|
|
14
|
+
- `SessionRouter.ownerSupportsForward` input — pass-through — the change makes its existing authenticated heartbeat signal current immediately after queue startup.
|
|
15
|
+
- Queue construction invariant — pass-through — refresh occurs only after successful construction and does not run on the queue-dark or construction-failed branches.
|
|
16
|
+
|
|
17
|
+
## 1. Over-block
|
|
18
|
+
|
|
19
|
+
No new block rule is added. A peer can now begin forwarding sooner after boot. The existing capability contract is handle-based (`!!_inboundQueue`): successful construction advertises receive capability, and this change advances that same signal without claiming runtime-health withdrawal. A later internal queue degradation does not currently clear the handle or withdraw the advert; that pre-existing limitation remains visible in the under-block analysis.
|
|
20
|
+
|
|
21
|
+
## 2. Under-block
|
|
22
|
+
|
|
23
|
+
This does not make forwarding safe when the durable queue is deliberately disabled, when the owner is unreachable, or when the owner advert is stale for other reasons. It also does not add runtime-health withdrawal after successful queue construction: if the queue later degrades internally while its handle remains assigned, peers continue to see the existing handle-based capability. Those paths remain governed by the existing queue, ownership, SpawnAdmission, degradation reporting, and owner-dark policies.
|
|
24
|
+
|
|
25
|
+
## 3. Level-of-abstraction fit
|
|
26
|
+
|
|
27
|
+
The fix is at the capability producer, not in `SessionRouter`: the router already consumes the correct authenticated capability. Re-deriving queue state remotely or weakening the conservative capability gate would be the wrong layer. `refreshPool()` is the single existing heartbeat authority and is reused unchanged.
|
|
28
|
+
|
|
29
|
+
## 4. Signal vs authority compliance
|
|
30
|
+
|
|
31
|
+
- [x] No — this change produces a signal consumed by an existing smart gate.
|
|
32
|
+
|
|
33
|
+
The change refreshes an objective runtime capability signal. It neither adds a new judgment rule nor grants a low-context detector independent blocking authority. The existing deterministic gate is an enumerable compatibility invariant: do not forward into a peer that has not advertised durable receive.
|
|
34
|
+
|
|
35
|
+
## 4b. Judgment-point check (Judgment Within Floors standard)
|
|
36
|
+
|
|
37
|
+
No new static heuristic at a competing-signals decision point. Queue construction is an objective runtime invariant, and the existing router policy remains unchanged.
|
|
38
|
+
|
|
39
|
+
## 5. Interactions
|
|
40
|
+
|
|
41
|
+
- **Shadowing:** no policy is shadowed; the refresh feeds the same `MachinePoolRegistry.recordHeartbeat` path as scheduled beats.
|
|
42
|
+
- **Double-fire:** a scheduled beat may occur adjacent to this refresh. `recordHeartbeat` is idempotent for capability state, so the duplicate observation is harmless.
|
|
43
|
+
- **Races:** refresh runs synchronously after `_inboundQueue` assignment; it cannot advertise true before construction succeeds.
|
|
44
|
+
- **Feedback loops:** peer pullers consume the advert but do not mutate the local queue handle.
|
|
45
|
+
|
|
46
|
+
## 6. External surfaces
|
|
47
|
+
|
|
48
|
+
Other machines see the capability become true immediately rather than on a later heartbeat. No response schema, operator action, URL, persistent payload, or external-service API changes. The only behavioral consequence is that already-authorized cross-machine forwarding can start promptly.
|
|
49
|
+
|
|
50
|
+
## 6b. Operator-surface quality (Operator-Surface Quality standard)
|
|
51
|
+
|
|
52
|
+
No operator surface — not applicable.
|
|
53
|
+
|
|
54
|
+
## 7. Multi-machine posture (Cross-Machine Coherence)
|
|
55
|
+
|
|
56
|
+
**Replicated** — the queue's live receive capability is published through the authenticated machine-capacity heartbeat and consumed from `MachinePoolRegistry` by peers. This change explicitly closes a cross-machine boot-order gap. It emits no user-facing notice, holds no new durable state, and generates no URL.
|
|
57
|
+
|
|
58
|
+
## 8. Rollback cost
|
|
59
|
+
|
|
60
|
+
Pure code change: revert the refresh call and ship a patch. No data migration or agent-state repair is required. Rollback restores the prior bounded stale-false boot window.
|
|
61
|
+
|
|
62
|
+
## Conclusion
|
|
63
|
+
|
|
64
|
+
The change reuses the existing capability authority and changes only refresh timing. It closes the live-observed stale-false boot window without weakening the conservative version-skew gate or changing custody semantics. Clear for an independent high-risk second pass.
|
|
65
|
+
|
|
66
|
+
## Second-pass review (if required)
|
|
67
|
+
|
|
68
|
+
**Reviewer:** Poincare (`continuation_impl_review`)
|
|
69
|
+
**Independent read of the artifact:** concur after correction — the first pass caught and removed an inaccurate claim that a later heartbeat withdraws capability after internal queue degradation; implementation timing and authority boundaries otherwise concurred.
|
|
70
|
+
|
|
71
|
+
## Evidence pointers
|
|
72
|
+
|
|
73
|
+
- `tests/unit/ws11-dispatch-to-owner-wiring.test.ts`
|
|
74
|
+
- Live topic-3462 reproduction in topic 458, 2026-07-17 12:53 PDT.
|
|
75
|
+
|
|
76
|
+
## Class-Closure Declaration (display-only mirror)
|
|
77
|
+
|
|
78
|
+
No agent-authored-artifact defect — not applicable.
|