instar 1.3.257 → 1.3.259

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.
@@ -0,0 +1,46 @@
1
+ # Upgrade Guide — vNEXT
2
+
3
+ <!-- assembled-by: assemble-next-md -->
4
+ <!-- bump: minor -->
5
+
6
+ ## What Changed
7
+
8
+ Finishes Phase 4 of the multi-machine arc: cross-machine secret sync. A secret given to the
9
+ agent on one machine can now be distributed, encrypted, to its other machines — so the same
10
+ agent can use it everywhere without the user re-entering it per machine.
11
+
12
+ - **`SecretSync` module** — `SecretProvisioner` (sender side: encrypts the secret set per
13
+ recipient to that machine's X25519 key and pushes a signed `secret-share` over the mesh) +
14
+ `SecretShareHandler` (receiver side: decrypts with this machine's own key and stores into
15
+ the local encrypted vault) + `secretKeyPaths` (names-only flattening for status).
16
+ - **Reuses the existing forward-secret crypto** (`encryptForSync`/`decryptFromSync`,
17
+ ephemeral-key-per-payload X25519 → AES-GCM); the mesh already enforces TLS, Ed25519
18
+ signing, and the registered-peer gate, so this adds application-layer confidentiality.
19
+ - **Two routes** (both behind auth): `GET /secrets/sync-status` reports which secret key
20
+ NAMES this machine holds plus the peers it would sync to (never a value); `POST
21
+ /secrets/sync-now` is the deterministic push lever (encrypts per online peer and pushes).
22
+ - **Config flag** `multiMachine.secretSync.enabled` — ships dark; defaults on only for the
23
+ development agent. A single-machine agent is a no-op.
24
+
25
+ ## What to Tell Your User
26
+
27
+ - **A secret you give me on one machine can become usable on your other machines** — a bot
28
+ token, an API key, a login — without you setting it up again on each computer. It travels
29
+ encrypted to each of your machines and is never written down in plain text along the way.
30
+ - This is an early capability and ships turned off by default. When it is on, if you ever
31
+ start re-entering something you already gave me elsewhere, I can tell you it already synced.
32
+
33
+ ## Summary of New Capabilities
34
+
35
+ - Cross-machine secret distribution: drop a secret once, use it on every paired machine.
36
+ - A read-only status view of which secrets a machine holds (names only, never values).
37
+ - A deterministic push lever to sync secrets on demand.
38
+
39
+ ## Evidence
40
+
41
+ 15 tests across all three tiers: 8 unit (real-crypto round-trip, per-recipient sealing,
42
+ wrong-key-fails confidentiality, best-effort fan-out, names-only flattening), 4 integration
43
+ (real SecretStore + real crypto encrypt→ship→decrypt through the HTTP routes, asserting no
44
+ secret value ever appears in a response, plus the 503-when-disabled paths), and 3 e2e (the
45
+ routes alive through the real AgentServer with a genuine round-trip into a peer vault, behind
46
+ auth). Spec: docs/specs/cross-machine-secret-sync-spec.md (approved).
@@ -0,0 +1,32 @@
1
+ # Upgrade Guide — vNEXT
2
+
3
+ <!-- assembled-by: assemble-next-md -->
4
+ <!-- bump: patch -->
5
+
6
+ ## What Changed
7
+
8
+ Added a CI gate (`.github/workflows/eli16-pr-gate.yml` + the pure check
9
+ `scripts/eli16-pr-description-check.mjs`) that requires every PR's DESCRIPTION to carry a
10
+ plain-English ELI16 overview, and FAILS the PR when it is missing. Per Justin's standard
11
+ (2026-06-05): the PR description is what a reviewer reads and approves on the link, and the PRs "had
12
+ different formats." The ELI16 *file* (docs/specs/<slug>.eli16.md) is unchanged and still enforced at
13
+ commit time; this closes the PR-body half. Re-runs on `edited` (self-clears on a description fix);
14
+ exempts bot authors + the automated release-cut PR.
15
+
16
+ ## What to Tell Your User
17
+
18
+ None — internal change (no user-facing surface).
19
+
20
+ ## Summary of New Capabilities
21
+
22
+ None — internal change (no user-facing surface).
23
+
24
+ ## Evidence
25
+
26
+ - The decision is a PURE function (`checkPrDescriptionEli16`) with 10 unit tests covering both
27
+ sides (has-overview → pass; missing / too-short / next-heading-boundary / comment-stripped → fail)
28
+ and every exemption (bot, release-cut, title-mentions-release non-exemption, null inputs).
29
+ - `node --check scripts/eli16-pr-description-check.mjs` clean. New additive workflow — cannot affect
30
+ existing checks/builds/releases; a failing PR is visible + self-clears on a description edit.
31
+ - This PR's own description carries an ELI16 overview (dogfoods the gate). scripts + workflow + test
32
+ only, no `src/` (internal-only lane).
@@ -0,0 +1,112 @@
1
+ # Side-Effects Review — Cross-Machine Secret Sync
2
+
3
+ **Version / slug:** `cross-machine-secret-sync`
4
+ **Date:** `2026-06-04`
5
+ **Author:** `echo`
6
+ **Second-pass reviewer:** `not required` (Tier 2; single-author under Justin's explicit signoff)
7
+
8
+ ## Summary of the change
9
+
10
+ Implements Phase 4 of the multi-machine arc: a secret given to the agent on one machine is
11
+ distributed, encrypted per-recipient, to its other registered machines so the same agent can
12
+ use it everywhere without re-entry. New `src/core/SecretSync.ts` holds a `SecretProvisioner`
13
+ (sender: encrypt the secret set to each online peer's X25519 key, push a signed `secret-share`
14
+ over the mesh), a `SecretShareHandler` (receiver: decrypt with this machine's own key, store
15
+ into the local encrypted vault), and `secretKeyPaths` (names-only flattening for status). The
16
+ inbound dispatcher handler was already wired in `src/commands/server.ts`; this change adds the
17
+ OUTBOUND provisioner (constructed after the MeshRpcClient), a route-facing `_secretSyncHandle`,
18
+ two routes in `src/server/routes.ts` (`GET /secrets/sync-status`, `POST /secrets/sync-now`)
19
+ plumbed through `AgentServer` + `RouteContext`, the `multiMachine.secretSync` config type, and
20
+ agent-awareness (CLAUDE.md template + `PostUpdateMigrator` section). Crypto is reused, not new
21
+ (`encryptForSync`/`decryptFromSync`, forward-secret ephemeral-key X25519→AES-GCM).
22
+
23
+ ## Decision-point inventory
24
+
25
+ - `multiMachine.secretSync.enabled` gate (server.ts) — **add** — enables inbound handler +
26
+ outbound provisioner; resolves to `config.multiMachine.secretSync.enabled ?? !!developmentAgent`
27
+ (dark for normal agents, on for the dev agent).
28
+ - `SecretProvisioner.listPeers` online filter — **add** — only online, registered peers with a
29
+ resolvable encryption key receive a push.
30
+ - `secret-share` mesh acceptance — **pass-through** — authenticity, signing, registered-peer
31
+ gate, and nonce replay are already enforced by the existing MeshRpcDispatcher verify/RBAC
32
+ layer; this change adds only application-layer confidentiality on top.
33
+
34
+ ## 1. Over-block
35
+
36
+ No block/allow surface — over-block not applicable. The two routes 503 only when the feature
37
+ is disabled or the handle is absent; they never reject a legitimate request when enabled.
38
+
39
+ ## 2. Under-block
40
+
41
+ No block/allow surface — under-block not applicable. (Security property of note instead: a
42
+ `secret-share` payload sealed to machine A cannot be decrypted by machine B — GCM auth fails —
43
+ covered by the "wrong key fails" unit test.)
44
+
45
+ ## 3. Level-of-abstraction fit
46
+
47
+ Right layer. The transport-level guarantees (TLS, Ed25519 signing, registered-peer gate, nonce
48
+ replay) live in the mesh and are reused, not re-implemented. This change is purely the
49
+ application-layer secret-distribution logic over that transport, plus thin route/handle wiring.
50
+ It USES the existing `encryptForSync`/`decryptFromSync` primitive rather than rolling new crypto,
51
+ and USES `SecretStore.read()`/`set()` rather than re-implementing vault access. No higher-level
52
+ gate is duplicated.
53
+
54
+ ## 4. Signal vs authority compliance
55
+
56
+ - [x] No — this change has no block/allow surface.
57
+
58
+ The routes are read (status) and an explicit push lever; neither holds block authority over any
59
+ message or operation. The mesh acceptance layer (the existing smart authority) owns
60
+ accept/reject for `secret-share`.
61
+
62
+ ## 5. Interactions
63
+
64
+ - **Shadowing:** none. The two new routes are new paths (`/secrets/sync-status`,
65
+ `/secrets/sync-now`) that don't sit before/after any existing check.
66
+ - **Double-fire:** the inbound `secret-share` handler is idempotent at the vault level — a
67
+ re-delivered share just re-writes the same decrypted value (rotate=overwrite, per spec).
68
+ Boot best-effort push + the deterministic route can both push the same set; the receiver
69
+ storing the same value twice is harmless.
70
+ - **Races:** `SecretStore.read`/`set` is read-modify-write to one encrypted file via an atomic
71
+ temp-file rename. Concurrent shares writing different key-paths could interleave a read with a
72
+ write; v1 syncs the whole set on provision and overwrites, so a lost interleaved write is
73
+ re-converged by the next push. Flagged as a known v1 limitation, not a correctness break for
74
+ the single-writer-at-a-time provision pattern.
75
+ - **Feedback loops:** none. A received share does not itself trigger a re-push (no boot/provision
76
+ event fires on inbound store), so shares don't ping-pong between machines.
77
+
78
+ ## 6. External surfaces
79
+
80
+ - **Other agents on the same machine:** none — keyed to this agent's own mesh + vault.
81
+ - **Install base:** ships DARK; a normal agent and a single-machine agent are no-ops.
82
+ - **External systems:** none new. Uses the existing mesh transport between the user's own paired
83
+ machines; no third-party service involved.
84
+ - **Persistent state:** writes decrypted secrets into the RECEIVING machine's existing encrypted
85
+ vault (`config.secrets.enc`) — the same store Secret Drop / SecretMigrator already write. No
86
+ new on-disk plaintext; the wire payload is forward-secret encrypted.
87
+ - **Timing:** boot best-effort push is fire-and-forget and never blocks startup.
88
+
89
+ ## 7. Rollback cost
90
+
91
+ Pure code change behind a dark flag — revert and ship a patch; no user-visible regression during
92
+ the rollback window (the feature is off for everyone except the dev agent). The only persistent
93
+ side effect is that secrets already pushed to a peer remain in that peer's vault after rollback —
94
+ which is the intended end-state (the user wanted them there) and requires no cleanup. No schema
95
+ or migration to unwind.
96
+
97
+ ## Conclusion
98
+
99
+ The review surfaced one honest v1 limitation (whole-set overwrite means an interleaved partial
100
+ write is re-converged on the next push rather than merged) which is acceptable for the
101
+ push-on-provision model and is documented. No design changes were required. Crypto is reused, the
102
+ transport gate is reused, the feature ships dark, and rollback is a clean revert. Clear to ship
103
+ through the ceremony, with live-verification on the real laptop+mini pair as the final gate
104
+ before enabling it beyond the dev agent.
105
+
106
+ ## Evidence pointers
107
+
108
+ - 15 tests green: `tests/unit/secret-sync.test.ts` (8), `tests/integration/secret-sync-routes.test.ts`
109
+ (4, real crypto round-trip through HTTP + no-value-leak asserts), `tests/e2e/secret-sync-alive.test.ts`
110
+ (3, real AgentServer alive + round-trip into a peer vault + auth).
111
+ - `tsc --noEmit` clean; `npm run lint` clean.
112
+ - Spec: `docs/specs/cross-machine-secret-sync-spec.md` (approved).
@@ -0,0 +1,48 @@
1
+ # Side-Effects Review — ELI16-on-every-PR gate (PR description)
2
+
3
+ **Version / slug:** `eli16-pr-description-gate`
4
+ **Date:** `2026-06-05`
5
+ **Author:** `echo`
6
+ **Second-pass reviewer:** `required (a new gate that blocks EVERY PR)`
7
+
8
+ ## Summary
9
+
10
+ Justin's standard (2026-06-05): every PR's DESCRIPTION must carry a plain-English ELI16 overview,
11
+ because the description is what a reviewer reads and approves when they open the PR link — and the
12
+ current PRs "have different formats." This adds a CI gate (`.github/workflows/eli16-pr-gate.yml`)
13
+ that runs a pure check (`scripts/eli16-pr-description-check.mjs`) on every PR body and FAILS the PR
14
+ when no ELI16 overview is present. The ELI16 *file* (`docs/specs/<slug>.eli16.md`) is unchanged and
15
+ still enforced at commit time by the instar-dev gate; this is the missing PR-body half.
16
+
17
+ ## Decision-point inventory
18
+
19
+ One decision: does the PR body contain an ELI16 overview? PASS when (a) the author is a Bot, or
20
+ (b) the title is a `chore: release` cut, or (c) the body has a heading whose text contains
21
+ `ELI16`/`ELI-16`/`ELI 16` followed by >= 200 chars of (comment-stripped) content. Otherwise FAIL.
22
+
23
+ ## 1. Over-block (what it blocks)
24
+
25
+ A human/agent PR whose description lacks a real ELI16 overview is blocked — that's the point. The
26
+ check re-runs on `edited`, so adding the overview to the description clears it WITHOUT a new push.
27
+ The failure message is actionable (tells you exactly what to add + that the file is a good source).
28
+
29
+ ## 2. Under-block (what it lets through)
30
+
31
+ Bot PRs and the automated `chore: release` PR (which has no human reviewer reading an ELI16). A PR
32
+ that has a real ELI16 heading + >= 200 chars passes. The check measures content only up to the next
33
+ heading, so a one-line ELI16 followed by a long "What Changed" does NOT slip through (tested).
34
+
35
+ ## 3. Blast radius — CRITICAL
36
+
37
+ This gate blocks EVERY non-exempt PR, so a false-fail would block the whole fleet's PRs. Mitigations:
38
+ the decision is a PURE function with 10 unit tests covering both sides AND every exemption (bot,
39
+ release-cut, the "title mentions release" non-exemption, null/empty inputs, the next-heading
40
+ boundary, comment-stripping). The gate is a NEW, additive workflow — it cannot affect existing
41
+ checks, builds, or releases; a failing PR is VISIBLE and self-clears on a description edit (not a
42
+ silent jam like the manifest/publish class). No `src/` runtime change.
43
+
44
+ ## 4. Reversibility
45
+
46
+ Fully reversible: delete the workflow + script + test. No state, no migration. Verified: the check
47
+ script parses (`node --check`); 10/10 unit tests pass. This PR's own description carries an ELI16
48
+ overview (dogfoods the gate).