@twinsearth/w2m-dsh-plugin 0.27.0 → 0.28.0

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/CHANGELOG.md CHANGED
@@ -4,6 +4,77 @@ All notable changes to this project are documented here. The format follows
4
4
  [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project
5
5
  adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6
6
 
7
+ ## [0.28.0] — 2026-10-15
8
+
9
+ **First real-machine verification of the recent work, and a tool that packs four answers into one exit code.**
10
+
11
+ ### The measurement
12
+
13
+ The MacMini's checkout was updated to 0.27.0 and its own suites run there, with **the exit code produced by
14
+ that machine** as the evidence:
15
+
16
+ | Suite on MacMini | Result |
17
+ |---|---|
18
+ | `permission.test.mjs` | pass |
19
+ | `fleet-scale.test.mjs` | pass |
20
+ | `fleet-state.test.mjs` | pass |
21
+ | `crypto-blake2s.test.mjs` | pass |
22
+
23
+ Those four cover the code written in this span — the permission gate, the fleet arithmetic, the endpoint
24
+ reconciliation, and the crypto capability report. This is the goal's "verify on the real machine with exit
25
+ codes and artifacts" satisfied for that body of work, rather than inferred.
26
+
27
+ ### `scripts/machine-test-packet.mjs`
28
+
29
+ A dispatch carries **one** exit code, so running four suites in one `node --test` answers only "did anything
30
+ fail". This packs **two bits per file** into a single byte: `10` passed, `01` failed, `00` absent, `11`
31
+ not measured. **`00` is distinguished from `01` on purpose** — "the file is not on this machine" is a
32
+ deployment finding, "the file ran and failed" is a code finding.
33
+
34
+ **Four dispatches were spent on this channel before the tool existed, two of them on my own misreadings:**
35
+
36
+ * a TAP parser matching `^ok ` that counted **nothing**, because Node indents its subtests. It returned
37
+ `pass 0 fail 0` and I nearly read that as "no tests ran".
38
+ * a summary regex that matched nothing, so the exit code described **my parser** rather than the code under
39
+ test.
40
+
41
+ Both were the same mistake in different clothes, and it is the mistake this project keeps making: **assuming
42
+ the shape of output instead of reading it.**
43
+
44
+ ### Three defects in the tool itself, all caught by its own suite
45
+
46
+ * **The docstring claimed "zero is the all-clear", and that is false.** One passing file is `2`, four are
47
+ `170`. **Zero means every file was ABSENT** — a total deployment failure the old claim would have had a
48
+ reader take as a clean run. `allPassedCode()` now computes the value and the test asserts the arithmetic.
49
+ * **The guard against emitting `126`/`127` was never reached** by the inputs I guessed. Enumerating the whole
50
+ two-bit space found the only two combinations that land on a shell-owned value
51
+ (`[PASSED, WAITED, WAITED, FAILED]` and `[WAITED, WAITED, WAITED, FAILED]`).
52
+ * **The reassuring message was unreachable**, because it tested `code === 0` rather than the outcomes.
53
+ `packOutcomes([])` returns `0`, so the one code that reads as success was attached to the one input that
54
+ measured nothing.
55
+
56
+ ### The budget, and the fifth time I hit the same ceiling
57
+
58
+ The first version took a 40-second timeout **per file** and ran four files: a 160-second worst case against
59
+ this fleet's **~50-second lease ceiling** (`heartbeatIntervalMs 10s × missedHeartbeats 2 + leaseGraceMs 30s`).
60
+ It **expired** on the real machine, and an expired lease carries **no exit code at all** — so the measurement
61
+ was lost rather than reported negative. That is the fifth time in this project that a dispatch was built
62
+ without respect for the ceiling.
63
+
64
+ The fix is a **total budget** (`DEFAULT_BUDGET_MS`, 30s) with a per-file cap, and files that miss their turn
65
+ are named `WAITED` rather than dropped — a packet that quietly omitted the last file would look like a clean
66
+ run of the ones it managed. A per-file timeout answers "is this file hung"; only a total budget answers "will
67
+ the answer survive the trip".
68
+
69
+ ### What the real machine refused, which is a finding and not a bug
70
+
71
+ `node scripts/machine-test-packet.mjs ...` came back **`COMMAND_NOT_ALLOWED`**. The MacMini's allow-list
72
+ admits `node -e` and `node --test`; it does not admit an arbitrary script path, and the packet **spawns
73
+ `node --test` internally**, so it would be refused a second time. The tool is correct and tested; it needs an
74
+ allow-list entry to run there, and **that is a change nobody has made.**
75
+
76
+ **11 tests, 0 failures.**
77
+
7
78
  ## [0.27.0] — 2026-10-15
8
79
 
9
80
  **A blocked fleet reports itself. The approval count is in `w2m_status`, and it arrives as a note.**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@twinsearth/w2m-dsh-plugin",
3
- "version": "0.27.0",
3
+ "version": "0.28.0",
4
4
  "description": "DSH: Windows2MacOS — drive the same project on online Windows and macOS machines from one DeepSeek account, across networks and regions. P2P hole punching is the default path (relay + shared server as rendezvous, ledger and fallback), with a bundled STUN responder, Tailscale/public-VPS/tunnel shapes, Rabbit relay + per-machine Localside + eight DSH tools (replicate / split), nine aggregate verdicts and signed requests.",
5
5
  "type": "module",
6
6
  "main": "lib/index.js",
@@ -113,13 +113,13 @@
113
113
  }
114
114
  },
115
115
  "scripts": {
116
- "test": "node --test --test-force-exit test/relay.test.mjs test/broadcast.test.mjs test/agent.test.mjs test/authority.test.mjs test/blocks.test.mjs test/approval-index.test.mjs test/fleet-sync.test.mjs test/health.test.mjs test/storage.test.mjs test/exit-channel.test.mjs test/council.test.mjs test/log-bounds.test.mjs test/test-report.test.mjs test/fleet-scale.test.mjs test/fleet-state.test.mjs test/crypto-blake2s.test.mjs test/installed-version.test.mjs test/permission.test.mjs test/layer-model.test.mjs test/memory.test.mjs test/tools.test.mjs test/claims.test.mjs test/fleet-target.test.mjs test/client-bundle.test.mjs test/schedule.test.mjs test/auto-update.test.mjs test/update-source.test.mjs test/update-install.test.mjs test/update-wiring.test.mjs test/signing.test.mjs test/stress.test.mjs test/shared-config.test.mjs test/metrics.test.mjs test/metrics-route.test.mjs test/tool-cards.test.mjs test/p2p-stun.test.mjs test/p2p-transport.test.mjs test/p2p-signaling.test.mjs test/p2p-node.test.mjs test/p2p-transport-fields.test.mjs test/p2p-plugin.test.mjs test/p2p-crypto.test.mjs test/stun-server.test.mjs test/loader-entry.test.mjs test/mdns-wire.test.mjs test/mdns-discover.test.mjs test/chatops-approval.test.mjs test/chatops-policy.test.mjs test/chatops-file-safety.test.mjs test/chatops-outbound-queue.test.mjs test/chatops-commands.test.mjs test/chatops-bridge.test.mjs test/chatops-config-route.test.mjs test/chatops-apply.test.mjs test/chatops-ilink-contract.test.mjs test/chatops-fleet.test.mjs test/chatops-account.test.mjs test/chatops-auth.test.mjs test/chatops-fleet-scope.test.mjs test/chatops-handoff.test.mjs test/chatops-fleet-wiring.test.mjs test/chatops-fleet-live.test.mjs test/chatops-takeover.test.mjs test/chatops-device-signing.test.mjs test/chatops-relay-verify.test.mjs test/chatops-durability.test.mjs test/chatops-run-command.test.mjs test/secrets-guard.test.mjs test/chatops-ilink-fleet-bridge.test.mjs test/chatops-fleet-join.test.mjs",
116
+ "test": "node --test --test-force-exit test/relay.test.mjs test/broadcast.test.mjs test/agent.test.mjs test/authority.test.mjs test/blocks.test.mjs test/approval-index.test.mjs test/fleet-sync.test.mjs test/health.test.mjs test/storage.test.mjs test/exit-channel.test.mjs test/council.test.mjs test/log-bounds.test.mjs test/test-report.test.mjs test/fleet-scale.test.mjs test/fleet-state.test.mjs test/crypto-blake2s.test.mjs test/installed-version.test.mjs test/permission.test.mjs test/machine-test-packet.test.mjs test/layer-model.test.mjs test/memory.test.mjs test/tools.test.mjs test/claims.test.mjs test/fleet-target.test.mjs test/client-bundle.test.mjs test/schedule.test.mjs test/auto-update.test.mjs test/update-source.test.mjs test/update-install.test.mjs test/update-wiring.test.mjs test/signing.test.mjs test/stress.test.mjs test/shared-config.test.mjs test/metrics.test.mjs test/metrics-route.test.mjs test/tool-cards.test.mjs test/p2p-stun.test.mjs test/p2p-transport.test.mjs test/p2p-signaling.test.mjs test/p2p-node.test.mjs test/p2p-transport-fields.test.mjs test/p2p-plugin.test.mjs test/p2p-crypto.test.mjs test/stun-server.test.mjs test/loader-entry.test.mjs test/mdns-wire.test.mjs test/mdns-discover.test.mjs test/chatops-approval.test.mjs test/chatops-policy.test.mjs test/chatops-file-safety.test.mjs test/chatops-outbound-queue.test.mjs test/chatops-commands.test.mjs test/chatops-bridge.test.mjs test/chatops-config-route.test.mjs test/chatops-apply.test.mjs test/chatops-ilink-contract.test.mjs test/chatops-fleet.test.mjs test/chatops-account.test.mjs test/chatops-auth.test.mjs test/chatops-fleet-scope.test.mjs test/chatops-handoff.test.mjs test/chatops-fleet-wiring.test.mjs test/chatops-fleet-live.test.mjs test/chatops-takeover.test.mjs test/chatops-device-signing.test.mjs test/chatops-relay-verify.test.mjs test/chatops-durability.test.mjs test/chatops-run-command.test.mjs test/secrets-guard.test.mjs test/chatops-ilink-fleet-bridge.test.mjs test/chatops-fleet-join.test.mjs",
117
117
  "test:e2e": "node --test --test-force-exit test/e2e.test.mjs test/crossnetwork.test.mjs test/signing-e2e.test.mjs test/outbound-only.test.mjs test/recovery.test.mjs test/pipeline-e2e.test.mjs test/p2p-agent.test.mjs",
118
118
  "test:relay": "node --test --test-force-exit test/relay.test.mjs",
119
119
  "test:agent": "node --test --test-force-exit test/agent.test.mjs test/memory.test.mjs",
120
120
  "test:tools": "node --test --test-force-exit test/tools.test.mjs",
121
121
  "test:crossnetwork": "node --test --test-force-exit test/crossnetwork.test.mjs",
122
- "test:all": "node --test --test-force-exit test/relay.test.mjs test/broadcast.test.mjs test/agent.test.mjs test/authority.test.mjs test/blocks.test.mjs test/approval-index.test.mjs test/fleet-sync.test.mjs test/health.test.mjs test/storage.test.mjs test/exit-channel.test.mjs test/council.test.mjs test/log-bounds.test.mjs test/test-report.test.mjs test/fleet-scale.test.mjs test/fleet-state.test.mjs test/crypto-blake2s.test.mjs test/installed-version.test.mjs test/permission.test.mjs test/layer-model.test.mjs test/memory.test.mjs test/tools.test.mjs test/claims.test.mjs test/fleet-target.test.mjs test/client-bundle.test.mjs test/schedule.test.mjs test/auto-update.test.mjs test/update-source.test.mjs test/update-install.test.mjs test/update-wiring.test.mjs test/signing.test.mjs test/stress.test.mjs test/e2e.test.mjs test/crossnetwork.test.mjs test/signing-e2e.test.mjs test/outbound-only.test.mjs test/recovery.test.mjs test/pipeline-e2e.test.mjs test/shared-config.test.mjs test/metrics.test.mjs test/metrics-route.test.mjs test/tool-cards.test.mjs test/p2p-stun.test.mjs test/p2p-transport.test.mjs test/p2p-signaling.test.mjs test/p2p-node.test.mjs test/p2p-transport-fields.test.mjs test/p2p-plugin.test.mjs test/p2p-agent.test.mjs test/stun-server.test.mjs test/loader-entry.test.mjs test/mdns-wire.test.mjs test/mdns-discover.test.mjs test/p2p-crypto.test.mjs test/chatops-approval.test.mjs test/chatops-policy.test.mjs test/chatops-file-safety.test.mjs test/chatops-outbound-queue.test.mjs test/chatops-commands.test.mjs test/chatops-bridge.test.mjs test/chatops-config-route.test.mjs test/chatops-apply.test.mjs test/chatops-ilink-contract.test.mjs test/chatops-fleet.test.mjs test/chatops-account.test.mjs test/chatops-auth.test.mjs test/chatops-fleet-scope.test.mjs test/chatops-handoff.test.mjs test/chatops-fleet-wiring.test.mjs test/chatops-fleet-live.test.mjs test/chatops-takeover.test.mjs test/chatops-device-signing.test.mjs test/chatops-relay-verify.test.mjs test/chatops-durability.test.mjs test/chatops-run-command.test.mjs test/secrets-guard.test.mjs test/chatops-ilink-fleet-bridge.test.mjs test/chatops-fleet-join.test.mjs",
122
+ "test:all": "node --test --test-force-exit test/relay.test.mjs test/broadcast.test.mjs test/agent.test.mjs test/authority.test.mjs test/blocks.test.mjs test/approval-index.test.mjs test/fleet-sync.test.mjs test/health.test.mjs test/storage.test.mjs test/exit-channel.test.mjs test/council.test.mjs test/log-bounds.test.mjs test/test-report.test.mjs test/fleet-scale.test.mjs test/fleet-state.test.mjs test/crypto-blake2s.test.mjs test/installed-version.test.mjs test/permission.test.mjs test/machine-test-packet.test.mjs test/layer-model.test.mjs test/memory.test.mjs test/tools.test.mjs test/claims.test.mjs test/fleet-target.test.mjs test/client-bundle.test.mjs test/schedule.test.mjs test/auto-update.test.mjs test/update-source.test.mjs test/update-install.test.mjs test/update-wiring.test.mjs test/signing.test.mjs test/stress.test.mjs test/e2e.test.mjs test/crossnetwork.test.mjs test/signing-e2e.test.mjs test/outbound-only.test.mjs test/recovery.test.mjs test/pipeline-e2e.test.mjs test/shared-config.test.mjs test/metrics.test.mjs test/metrics-route.test.mjs test/tool-cards.test.mjs test/p2p-stun.test.mjs test/p2p-transport.test.mjs test/p2p-signaling.test.mjs test/p2p-node.test.mjs test/p2p-transport-fields.test.mjs test/p2p-plugin.test.mjs test/p2p-agent.test.mjs test/stun-server.test.mjs test/loader-entry.test.mjs test/mdns-wire.test.mjs test/mdns-discover.test.mjs test/p2p-crypto.test.mjs test/chatops-approval.test.mjs test/chatops-policy.test.mjs test/chatops-file-safety.test.mjs test/chatops-outbound-queue.test.mjs test/chatops-commands.test.mjs test/chatops-bridge.test.mjs test/chatops-config-route.test.mjs test/chatops-apply.test.mjs test/chatops-ilink-contract.test.mjs test/chatops-fleet.test.mjs test/chatops-account.test.mjs test/chatops-auth.test.mjs test/chatops-fleet-scope.test.mjs test/chatops-handoff.test.mjs test/chatops-fleet-wiring.test.mjs test/chatops-fleet-live.test.mjs test/chatops-takeover.test.mjs test/chatops-device-signing.test.mjs test/chatops-relay-verify.test.mjs test/chatops-durability.test.mjs test/chatops-run-command.test.mjs test/secrets-guard.test.mjs test/chatops-ilink-fleet-bridge.test.mjs test/chatops-fleet-join.test.mjs",
123
123
  "pack": "node scripts/pack.mjs",
124
124
  "verify:join": "node scripts/verify-join.mjs",
125
125
  "lint": "eslint .",
@@ -145,7 +145,8 @@
145
145
  "test:fleet-state": "node --test --test-force-exit test/fleet-state.test.mjs",
146
146
  "test:crypto-blake2s": "node --test --test-force-exit test/crypto-blake2s.test.mjs",
147
147
  "test:installed-version": "node --test --test-force-exit test/installed-version.test.mjs",
148
- "test:permission": "node --test --test-force-exit test/permission.test.mjs"
148
+ "test:permission": "node --test --test-force-exit test/permission.test.mjs",
149
+ "test:packet": "node --test --test-force-exit test/machine-test-packet.test.mjs"
149
150
  },
150
151
  "keywords": [
151
152
  "dsh-bundle",
@@ -193,7 +193,7 @@ const MAX_STAGES = 16;
193
193
  * `package.json` during `scripts/pack.mjs` rather than hand-maintained, and `W2M_PLUGIN_VERSION`
194
194
  * overrides it at runtime for tests and packagers.
195
195
  */
196
- const PLUGIN_VERSION = '0.27.0';
196
+ const PLUGIN_VERSION = '0.28.0';
197
197
 
198
198
  /** How long any single HTTP call may take before it is aborted, in milliseconds. */
199
199
  const DEFAULT_REQUEST_TIMEOUT_MS = 15_000;