@twinsearth/w2m-dsh-plugin 1.1.15 → 1.1.17

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.
@@ -5,14 +5,14 @@
5
5
  },
6
6
  "metadata": {
7
7
  "description": "The w2m fleet plugins: one account, many machines, any of Windows, macOS or Linux.",
8
- "version": "1.1.15"
8
+ "version": "1.1.17"
9
9
  },
10
10
  "plugins": [
11
11
  {
12
12
  "name": "w2m-fleet",
13
13
  "source": "./",
14
14
  "description": "Read fleet state and dispatch commands across the machines registered to one account. Read-only MCP surface: the five exposed tools cannot change anything.",
15
- "version": "1.1.15",
15
+ "version": "1.1.17",
16
16
  "author": {
17
17
  "name": "TwinsEarth"
18
18
  },
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "w2m-fleet",
3
3
  "description": "Drive the same project on online Windows, macOS and Linux machines from one account: read fleet state, dispatch commands and read results. The MCP surface is deliberately read-only.",
4
- "version": "1.1.15",
4
+ "version": "1.1.17",
5
5
  "author": {
6
6
  "name": "TwinsEarth"
7
7
  },
package/CHANGELOG.md CHANGED
@@ -2,6 +2,118 @@
2
2
 
3
3
  All notable changes to this project are documented here.
4
4
 
5
+ ## [1.1.17] — 2026-10-18
6
+
7
+ **Fleet chat: messages live in a session, are refused by a byte budget rather than silently dropped, are stored
8
+ encrypted and split across the fleet's own machines, and reach the agent as a tool.**
9
+
10
+ ### The store, and the rule it refuses to break
11
+
12
+ `src/relay/fleet-messages.mjs` keeps messages per **session** -- the operator's scope: deleting the session deletes the
13
+ history, and a machine joining or leaving changes who reads the flow, never what was said.
14
+
15
+ The budget is the operator's formula, not a round number:
16
+
17
+ limit = min(200 MB, max(100 MB, used-in-7-days))
18
+
19
+ A message over it is **refused** with the current usage attached (`FLEET_QUOTA_EXCEEDED`); nothing is silently dropped
20
+ and nobody else's words are evicted to make room. Text only: non-strings, control characters and messages over 4 KiB are
21
+ refused by name. Every timestamp comes from the relay's clock, because client clocks in this fleet disagree by tens of
22
+ seconds.
23
+
24
+ ### Encrypted sharding with the three rules that keep it from losing data
25
+
26
+ `src/relay/message-shards.mjs` seals a day's messages with AES-256-GCM under a key derived from the fleet key (domain
27
+ separated, no new long-lived secret) and splits the result across the fleet:
28
+
29
+ - **rebuildable** -- the metadata says which machine holds which part, so a reader never guesses;
30
+ - **offline tolerated** -- every part gets **two replicas on two different machines**; one machine being down is the
31
+ normal case;
32
+ - **integrity** -- each shard carries sha256 of its own bytes. A corrupt shard fails as `SHARD_CORRUPT` naming the part
33
+ and machine; a missing one fails as `MISSING_SHARDS` naming **which** parts; a wrong key fails as `AUTH_FAILED`
34
+ without returning partial plaintext.
35
+
36
+ ### HTTP and the notification that carries no text
37
+
38
+ `POST /v1/fleet/messages` and `GET /v1/fleet/messages` sit behind the device gate: the author is the token holder, never
39
+ a body field. Every read returns the fleet's current usage so a client can warn before a write is refused.
40
+ `GET /v1/fleet/messages/stream` is SSE and emits **only** `{session_id, message_id, machine_id, at_ms}` -- the text is
41
+ always fetched through the authenticated read, because a broadcast carrying text would send every message to every
42
+ listener and make the membership check decorative.
43
+
44
+ ### The twelfth tool: `w2m_chat`
45
+
46
+ `w2m_chat` (`send` / `list`) exposes the above to the agent. It is an ordinary MCP tool available on every transport;
47
+ `w2m_run` remains the only host-only one.
48
+
49
+ ### The cost of adding a tool: seven count pins
50
+
51
+ Adding a twelfth tool is not one edit. The count is pinned in **eight** places -- `README` (both languages), four test
52
+ suites (`tools`, `p2p-plugin`, `loader-entry`, `tool-cards`), `scripts/verify-installed.mjs`'s expected list, and
53
+ `test/claims.test.mjs`'s assertion. The first attempt fixed the ones that came to mind and left three red; the gate caught
54
+ each. `docs/PLATFORMS.md` gained a section stating that `w2m_chat` is available over MCP.
55
+
56
+ ### Not verified
57
+
58
+ - no client UI panel beyond the generic tool card;
59
+ - the SSE route has module-level notification tests, not a live end-to-end stream assertion;
60
+ - shards are produced and reassembled but **not yet transported** to machines -- that is the relay's next step, and the
61
+ tests say so rather than implying distribution works.
62
+
63
+ ### Verified
64
+
65
+ Gate GREEN twice, 15 of 15. tools 120, claims 48, p2p 32, loader 10, fleet-messages 7, message-shards 9, chat-http 3,
66
+ message-notify 3.
67
+
68
+ ## [1.1.16] — 2026-10-18
69
+
70
+ **A machine waiting to be admitted now appears where you already answer questions -- and the README leads with how to
71
+ install it.**
72
+
73
+ ### Admission in `w2m_approvals`
74
+
75
+ `w2m_approvals` merges `GET /v1/fleet/admission/pending` into its list as `kind:'fleet_admission'` rows, so a machine
76
+ asking to join shows up beside the permission requests already there. Settling an `adm-` id goes to the **relay's**
77
+ decide endpoint, not the local permission index: admission is not an authority escalation, and pushing it through
78
+ `approvalRequestFor` -- whose shape requires a needs-approval verdict and a capability -- would record a lie in the
79
+ audit trail. The list is shared; the stores are not.
80
+
81
+ The countdown is derived from the **relay's clock** (`rabbit_time`), never this machine's: three machines in this fleet
82
+ disagree by tens of seconds, and a local countdown would fire the automatic approval early on a fast machine. The relay
83
+ still owns the decision and still refuses to auto-approve with no member online.
84
+
85
+ ### Two defects the tests caught
86
+
87
+ - the merged request omitted `rabbitUrl` and the device token, so it threw into the surrounding catch and the rows were
88
+ **silently missing** -- a probe showed the fetch was never called at all (`calls: []`);
89
+ - the refusal code was read from `json.code`, but protocol errors arrive at `json.error.code`, so `reason_code` was always
90
+ null and a late `ALREADY_DECIDED` decision looked like a success path.
91
+
92
+ Five assertions now cover that seam: rows and their fields, relay-clock countdown, an unreachable relay still showing the
93
+ local queue, `adm-` routing reaching the relay, and a late decision reported rather than thrown.
94
+
95
+ ### README rewritten around installation
96
+
97
+ Five routes, easiest first: DSH plugin (zero configuration), npm/MCP for any client, Claude Code marketplace, Codex, and
98
+ the verified release tarball. Then quick start, the 11 tools registered, the `W2M_*` environment a dispatched command
99
+ receives, the fleet model, the security posture, and an explicit **verified / not verified** table that names the approval
100
+ popup, the four-machine `W2M_INDEX` run, the unimplemented chat channel and the macOS P2P downgrade instead of implying
101
+ they work.
102
+
103
+ Two claim checks rejected the first draft and were right: a `SHA256SUMS` release-download URL does not name a
104
+ `<name>-<version>.tgz` asset, and "eleven tools" had to be the measured number.
105
+
106
+ ### Not in this release
107
+
108
+ The approval **popup** (a dedicated 10-second countdown control) is not implemented -- the rules are enforced by the
109
+ relay and this tool lists and settles the requests. The fleet chat channel remains designed (FLEET-CHAT-DESIGN.md) and
110
+ not built. No four-machine `W2M_INDEX` run yet.
111
+
112
+ ### Verified
113
+
114
+ Gate GREEN (final pass, 15 of 15). 2458 tests in 102 files, 2444 pass, 0 fail, 14 skip. tools 120, tool-cards 8,
115
+ claims 47.
116
+
5
117
  ## [1.1.15] — 2026-10-17
6
118
 
7
119
  **A machine that cannot join the old way now proves its account, asks to join, and waits for an answer -- and the