instar 1.3.373 → 1.3.375
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 +6 -0
- package/dist/commands/server.d.ts.map +1 -1
- package/dist/commands/server.js +42 -4
- package/dist/commands/server.js.map +1 -1
- package/dist/server/AgentServer.d.ts +9 -0
- package/dist/server/AgentServer.d.ts.map +1 -1
- package/dist/server/AgentServer.js +10 -0
- package/dist/server/AgentServer.js.map +1 -1
- package/dist/server/routes.d.ts.map +1 -1
- package/dist/server/routes.js +69 -0
- package/dist/server/routes.js.map +1 -1
- package/dist/users/TopicOperatorStore.d.ts.map +1 -1
- package/dist/users/TopicOperatorStore.js +8 -0
- package/dist/users/TopicOperatorStore.js.map +1 -1
- package/package.json +1 -1
- package/src/data/builtin-manifest.json +47 -47
- package/upgrades/1.3.375.md +88 -0
- package/upgrades/side-effects/topic-operator-polling-bind-inc2e.md +62 -0
- package/upgrades/side-effects/transfer-place-half-journal.md +74 -0
- package/upgrades/topic-operator-polling-bind-inc2e.eli16.md +56 -0
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
# Side-Effects Review — Transfer PLACE-half journaling (coherence finding #5)
|
|
2
|
+
|
|
3
|
+
**Version / slug:** `transfer-place-half-journal`
|
|
4
|
+
**Date:** `2026-06-06`
|
|
5
|
+
**Author:** `echo`
|
|
6
|
+
**Second-pass reviewer:** `not required`
|
|
7
|
+
|
|
8
|
+
## Summary of the change
|
|
9
|
+
|
|
10
|
+
`POST /pool/transfer` now lands the PLACE half of a deliberate move: for a quiet
|
|
11
|
+
topic (never-seen or released ownership record) it CASes `place→claim` for the
|
|
12
|
+
target as one synchronous pair and journals the placement (`reason: 'user-move'`,
|
|
13
|
+
real epoch) so the entry replicates to the pinned-to machine — closing the
|
|
14
|
+
"no machine ever produced the evidence the #926/#930 read-side fallbacks read"
|
|
15
|
+
gap proven live (the working-set reflex answered `not-owner` after a transfer
|
|
16
|
+
even on v1.3.371+). A resting `placing` record naming the target is repaired via
|
|
17
|
+
claim (the bug-#11 shape). Response gains `placedOwnership`.
|
|
18
|
+
|
|
19
|
+
## Decision-point inventory
|
|
20
|
+
|
|
21
|
+
One: which ownership-record shapes the block may mutate. Active-with-target →
|
|
22
|
+
skip (no-op). Never-seen/released → place+claim. Resting placing-with-target →
|
|
23
|
+
claim repair. Everything else (active other-machine, placing other-machine,
|
|
24
|
+
transferring) → strictly untouched.
|
|
25
|
+
|
|
26
|
+
## 1. Over-block
|
|
27
|
+
|
|
28
|
+
Nothing new is rejected; the route's accept/reject surface is unchanged. The
|
|
29
|
+
block only ever ADDS ownership evidence; on any CAS refusal the transfer still
|
|
30
|
+
succeeds exactly as before (`placedOwnership:false`).
|
|
31
|
+
|
|
32
|
+
## 2. Under-block
|
|
33
|
+
|
|
34
|
+
A topic actively owned by a third machine still journals nothing on transfer
|
|
35
|
+
(deliberate — never steal a live session; the pin drives re-placement on real
|
|
36
|
+
traffic, which CASes and journals through the existing router chokepoint). A
|
|
37
|
+
`placing` record naming a different machine is also left alone — repairing
|
|
38
|
+
someone else's in-flight placement is not this handler's call.
|
|
39
|
+
|
|
40
|
+
## 3. Level-of-abstraction fit
|
|
41
|
+
|
|
42
|
+
Right layer: the same handler that already owns the RELEASE half (and its
|
|
43
|
+
journaling) now owns the PLACE half — the two halves of one move live at one
|
|
44
|
+
chokepoint. The state machine itself is untouched; the handler composes the
|
|
45
|
+
existing legal transitions (place, claim) exactly as the router's confirmClaim
|
|
46
|
+
precedent does.
|
|
47
|
+
|
|
48
|
+
## 4. Signal vs authority compliance
|
|
49
|
+
|
|
50
|
+
**Required reference:** [docs/signal-vs-authority.md](../../docs/signal-vs-authority.md)
|
|
51
|
+
|
|
52
|
+
No blocking authority added. Both CAS failures and journal failures are
|
|
53
|
+
best-effort (`@silent-fallback-ok` / observability-never-endangers-the-observed):
|
|
54
|
+
the transfer response never fails because of this block, and the journal entry
|
|
55
|
+
is evidence, not actuation.
|
|
56
|
+
|
|
57
|
+
## 5. Interactions
|
|
58
|
+
|
|
59
|
+
- **SessionRouter**: claim immediately follows place so the record never RESTS at
|
|
60
|
+
`placing` — the shape that queues every later message as ownership-contention
|
|
61
|
+
(bug #11). A real message for the topic now finds `active(target)` and forwards.
|
|
62
|
+
- **Working-set reflex (#926/#930)**: the journaled entry replicates and the
|
|
63
|
+
target's wsOwnerOf journal-placement fallback finally has something to read.
|
|
64
|
+
- **Post-transfer closeout**: unchanged — it keys on ownership moving away, which
|
|
65
|
+
this block makes MORE accurate (the registry now reflects the deliberate move).
|
|
66
|
+
- **Ownership nonces**: fresh `tplace`/`tclaim` nonces per call; no replay overlap
|
|
67
|
+
with router (`:c:`/`:cl:`) or release (`:rel:`) nonce families.
|
|
68
|
+
|
|
69
|
+
## 6. External surfaces
|
|
70
|
+
|
|
71
|
+
One additive JSON response field (`placedOwnership`). No new routes, no config,
|
|
72
|
+
no notifications, no Telegram. Journal entries use the existing topic-placement
|
|
73
|
+
kind/op-key contract (`${topic}:${epoch}` — real epochs, so no dedupe collision
|
|
74
|
+
with router-emitted entries).
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# ELI16 — Remembering the boss on the simpler phone line too
|
|
2
|
+
|
|
3
|
+
## The one-sentence version
|
|
4
|
+
The agent now writes down "this is the verified boss of this chat" no matter
|
|
5
|
+
which of its two message pipes the boss's message arrived through — before, one
|
|
6
|
+
pipe did this and the other forgot.
|
|
7
|
+
|
|
8
|
+
## The backstory
|
|
9
|
+
We've been closing a real security hole: an agent on a shared computer slowly
|
|
10
|
+
started treating a *different real person* (call her Caroline) as its boss. The
|
|
11
|
+
fix was a filing cabinet that records, per chat, who the verified boss is —
|
|
12
|
+
decided ONLY by the verified ID of whoever actually sent the message, never by a
|
|
13
|
+
name typed in a document. The last step (increment 2d) made the cabinet fill in
|
|
14
|
+
automatically — but only on the agent's MAIN message pipe (the relay most of the
|
|
15
|
+
fleet uses). A simpler setup, where the agent talks to Telegram directly without
|
|
16
|
+
the relay, still never filled in the cabinet. That was safe (an empty cabinet
|
|
17
|
+
just means "I don't know," never a wrong answer), but it meant some agents never
|
|
18
|
+
learned who their boss was.
|
|
19
|
+
|
|
20
|
+
## What this change adds
|
|
21
|
+
Both pipes eventually flow through one shared doorway in the code (the
|
|
22
|
+
`onTopicMessage` seam). This change puts the "write down the boss" step at that
|
|
23
|
+
doorway, so it runs no matter which pipe delivered the message. Two careful
|
|
24
|
+
details:
|
|
25
|
+
|
|
26
|
+
1. **The doorway still checks the allowed list.** The main pipe lets messages
|
|
27
|
+
from non-allowed people *through the doorway* (it just refuses to bind them
|
|
28
|
+
earlier) — so the doorway check is load-bearing. Without it, an outsider in
|
|
29
|
+
the group could seat themselves as boss — the exact Caroline bug. We test
|
|
30
|
+
this with a literal unauthorized "Caroline" message and prove nobody gets
|
|
31
|
+
written down.
|
|
32
|
+
2. **One cabinet, not two.** The cabinet keeps a copy of its contents in memory.
|
|
33
|
+
If the doorway opened its OWN second cabinet on the same file, the two copies
|
|
34
|
+
could silently overwrite each other's entries. So the doorway asks the server
|
|
35
|
+
for its existing cabinet (resolved late, because the server is built after
|
|
36
|
+
the doorway is wired) — same instance, no lost entries. A test proves an
|
|
37
|
+
entry written one way survives an entry written the other way.
|
|
38
|
+
|
|
39
|
+
## A small bonus fix
|
|
40
|
+
Since both pipes now re-write the boss on every message, the cabinet learned to
|
|
41
|
+
notice "this is exactly what I already have" and skip the disk write — a
|
|
42
|
+
re-delivered or repeated message is now a pure read instead of a pointless file
|
|
43
|
+
rewrite.
|
|
44
|
+
|
|
45
|
+
## Why it's safe
|
|
46
|
+
- Wrapped so any failure is logged and swallowed — recording the boss can never
|
|
47
|
+
break message handling.
|
|
48
|
+
- Before the server finishes booting, the doorway just skips the step (no
|
|
49
|
+
cabinet yet = nothing written = fail-safe).
|
|
50
|
+
- On the main pipe both the old write (increment 2d) and the new doorway write
|
|
51
|
+
run — same cabinet, same record, harmless.
|
|
52
|
+
|
|
53
|
+
## What's deliberately left for next time
|
|
54
|
+
Nothing in this family — the operator-binding loop is now closed on every
|
|
55
|
+
ingress path. The remaining Know Your Principal work is elsewhere (per-agent
|
|
56
|
+
credential isolation, Phase 3).
|