instar 1.3.672 → 1.3.674

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 (36) hide show
  1. package/dist/commands/server.d.ts.map +1 -1
  2. package/dist/commands/server.js +113 -11
  3. package/dist/commands/server.js.map +1 -1
  4. package/dist/core/inboundLossRouting.d.ts +30 -0
  5. package/dist/core/inboundLossRouting.d.ts.map +1 -0
  6. package/dist/core/inboundLossRouting.js +35 -0
  7. package/dist/core/inboundLossRouting.js.map +1 -0
  8. package/dist/monitoring/EnforcedTerminationWatchdog.d.ts +91 -0
  9. package/dist/monitoring/EnforcedTerminationWatchdog.d.ts.map +1 -0
  10. package/dist/monitoring/EnforcedTerminationWatchdog.js +172 -0
  11. package/dist/monitoring/EnforcedTerminationWatchdog.js.map +1 -0
  12. package/dist/monitoring/enforcedTermination.d.ts +105 -0
  13. package/dist/monitoring/enforcedTermination.d.ts.map +1 -0
  14. package/dist/monitoring/enforcedTermination.js +105 -0
  15. package/dist/monitoring/enforcedTermination.js.map +1 -0
  16. package/dist/monitoring/enforcedTerminationWiring.d.ts +18 -0
  17. package/dist/monitoring/enforcedTerminationWiring.d.ts.map +1 -0
  18. package/dist/monitoring/enforcedTerminationWiring.js +80 -0
  19. package/dist/monitoring/enforcedTerminationWiring.js.map +1 -0
  20. package/dist/monitoring/guardManifest.d.ts.map +1 -1
  21. package/dist/monitoring/guardManifest.js +10 -0
  22. package/dist/monitoring/guardManifest.js.map +1 -1
  23. package/dist/server/AgentServer.d.ts +3 -0
  24. package/dist/server/AgentServer.d.ts.map +1 -1
  25. package/dist/server/AgentServer.js +1 -0
  26. package/dist/server/AgentServer.js.map +1 -1
  27. package/dist/server/routes.d.ts +3 -0
  28. package/dist/server/routes.d.ts.map +1 -1
  29. package/dist/server/routes.js +8 -0
  30. package/dist/server/routes.js.map +1 -1
  31. package/package.json +1 -1
  32. package/src/data/builtin-manifest.json +47 -47
  33. package/upgrades/1.3.673.md +50 -0
  34. package/upgrades/1.3.674.md +43 -0
  35. package/upgrades/side-effects/enforced-termination-watchdog.md +95 -0
  36. package/upgrades/side-effects/inbound-delivery-sacred.md +62 -0
@@ -0,0 +1,62 @@
1
+ # Side-Effects Review — Inbound Delivery Is Sacred (Postmortem F3)
2
+
3
+ **Version / slug:** `inbound-delivery-sacred`
4
+ **Date:** `2026-06-26`
5
+ **Author:** `Echo (instar-dev agent)`
6
+ **Second-pass reviewer:** `not-required — Phase 5 triggers on a block/allow DECISION on inbound messaging; this makes no block/allow decision (it is loss-notice delivery ROUTING, no authority added), runs only while the queue is dark, and is backed by a pure unit-tested router. Rigor is the 6-case unit suite + this review.`
7
+
8
+ ## Summary
9
+
10
+ Routes inbound-queue loss notices to the ORIGINATING topic (each loss item's
11
+ `sessionKey` is the topic id) instead of the single `agent-attention-topic` that
12
+ `notify()` silently drops when unset. A loss with no resolvable topic and no
13
+ attention topic surfaces LOUDLY (`console.error`) instead of vanishing. New pure
14
+ function `planInboundLossNotices` (`src/core/inboundLossRouting.ts`) + a thin
15
+ `notifyInboundLoss` helper in server.ts, applied to all 5 inbound-queue loss sites.
16
+
17
+ ## The 8 questions
18
+
19
+ 1. **Over-block** — N/A. This is not a gate; it adds no block/reject. It only
20
+ changes WHERE a loss notice is delivered. It cannot reject a legitimate message.
21
+ 2. **Under-block** — N/A (no blocking). The failure mode it closes is *under-notice*
22
+ (a silent drop), which is exactly what it fixes.
23
+ 3. **Level-of-abstraction fit** — Correct layer. The loss is detected in
24
+ `QueueDrainLoop` (already complete); the DELIVERY of the notice is a server-bootstrap
25
+ concern (where `notify` + the attention-topic state live). The grouping logic is
26
+ extracted to a pure, testable core (`inboundLossRouting.ts`); server.ts only does
27
+ the side-effecting notify/console.error. Right split.
28
+ 4. **Signal vs authority** — Pure signal-delivery. No blocking authority added. The
29
+ pure router holds no authority; the helper only emits notices. Complies with
30
+ `docs/signal-vs-authority.md`.
31
+ 5. **Interactions** — Reuses the existing `notify()` funnel (batcher, attention
32
+ topic, Slack mirror) — does not bypass it, only passes a `topicId` so it lands in
33
+ the originating topic. The `stuck-recovery` notice already routed per-topic and is
34
+ UNCHANGED. No double-fire: each loss item is counted once, per topic.
35
+ 6. **External surfaces** — Changes the destination + wording of a user-facing loss
36
+ notice (now per-topic, drops the redundant "topics:" list). It depends on the loss
37
+ item's `sessionKey` being the topic id (verified — that is how the queue keys
38
+ custody). No new external dependency.
39
+ 7. **Multi-machine posture** — Machine-local BY DESIGN. Each machine reports the loss
40
+ of the messages IT held; the notice goes to the originating topic on that machine's
41
+ Telegram path. No replication needed (a loss is a local custody event). The
42
+ attention-topic fallback + loud `console.error` are also machine-local.
43
+ 8. **Rollback cost** — Trivial. The change is inert while the inbound queue is dark
44
+ (default). Revert is a code-only back-out (no migration, no state). The queue's
45
+ loss-DETECTION is unchanged; only the notice routing differs.
46
+
47
+ ## What it does NOT do
48
+
49
+ - Does not change the queue's loss-detection, retry, or expiry logic (all already
50
+ complete). It only hardens the notice *channel*.
51
+ - Does not touch the fail-OPEN direct-inject fallback (already comprehensive).
52
+ - Does not run while the queue is dark (default) — zero behavior change on the fleet.
53
+
54
+ ## Rollback
55
+
56
+ Revert the commit. No persisted state, no migration. Inert while `inboundQueueConfig`
57
+ ships `enabled:false`.
58
+
59
+ ## Second-pass reviewer verdict
60
+
61
+ Not required — see the header rationale (no block/allow decision; delivery-routing only;
62
+ dark; pure-function-backed). The decision boundary is covered by the 6-case unit suite.