instar 1.3.213 → 1.3.214

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,65 @@
1
+ # Upgrade Guide — vNEXT
2
+
3
+ <!-- assembled-by: assemble-next-md -->
4
+ <!-- bump: patch -->
5
+
6
+ ## What Changed
7
+
8
+ Secret Drop's stored-submission lifetime was reworked so a submitted secret can no
9
+ longer be deleted out from under an active consumer.
10
+
11
+ - **Server (`SecretDrop.ts`)** — the post-submission store now uses a **sliding idle
12
+ window** instead of a fixed 5-minute timer. The cleanup timer re-arms on every
13
+ `peekReceived`, so a secret that is actively being retrieved never expires. The idle
14
+ window is 15 minutes (was 5) and a new per-token `receivedDeadline` enforces a hard
15
+ **30-minute absolute cap** (`armReceivedCleanup` clamps each re-arm with
16
+ `Math.min(idle, deadline − now)`), so even a continuously-polled secret is purged.
17
+ `consumeReceived`/`shutdown` clear the new deadline map; the stuck-consumer event's
18
+ `minutesUntilCleanup` is derived from the deadline.
19
+ - **Consumer (`secret-drop-retrieve.mjs`)** — new `--run -- <cmd>` mode performs an
20
+ **atomic use-and-consume**: it pipes the field value to the command's stdin and
21
+ consumes the submission only if the command exits 0. A failed or launch-error
22
+ handoff never destroys the secret, making consume-on-failure structurally impossible.
23
+ - **Awareness/migration** — the CLAUDE.md scaffold documents `--run` for new agents;
24
+ an idempotent `PostUpdateMigrator` block adds the guidance to existing agents that
25
+ already have the hardened helper. The helper script itself ships via the existing
26
+ always-overwrite relay-script refresh.
27
+
28
+ ## What to Tell Your User
29
+
30
+ - **Secret Drop is now sturdier**: "If you hand me a password or key through a secure
31
+ link, it won't quietly expire while I'm in the middle of using it anymore — so you
32
+ shouldn't have to send the same thing twice. And if a step fails, I keep what you
33
+ sent so we can retry, instead of throwing it away." (Note: a secret still lives only
34
+ in memory, so a server restart still clears anything not yet used — that's the
35
+ security trade-off, unchanged.)
36
+
37
+ ## Summary of New Capabilities
38
+
39
+ | Capability | How to Use |
40
+ |-----------|-----------|
41
+ | Sliding retrieval window + 30-min cap | automatic |
42
+ | Atomic use-and-consume | `secret-drop-retrieve.mjs TOKEN field --run -- <cmd>` |
43
+
44
+ ## Evidence
45
+
46
+ **Reproduction (observed live, 2026-06-02):** during a multi-step credential handoff
47
+ (Bitwarden login, then a GitHub token) the operator had to resubmit the same secret
48
+ roughly six times. Each time, the submission sat in the store while a multi-step
49
+ retrieval ran; the fixed 5-minute timer deleted it mid-flow regardless of the active
50
+ retrievals, and a standalone consume fired after a step that had not yet succeeded —
51
+ destroying the secret with no recovery but resubmission.
52
+
53
+ **Before/after (deterministic, fake-timer unit tests in
54
+ `tests/unit/SecretDrop.test.ts`):**
55
+ - Before this change, a submission was unconditionally deleted 5 minutes after
56
+ submit. After it: a submission peeked at 14 min and again at 28 min is still present
57
+ (the window slid on each read); an untouched submission is still cleaned up after the
58
+ idle window; and a submission polled every 10 min is nonetheless purged once past the
59
+ 30-min absolute cap.
60
+ - `--run` mode: consume is invoked only on child exit 0; on non-zero exit or a launch
61
+ error the submission is left intact (verified by inspecting the spawnSync branch and
62
+ the documented `gh auth login --with-token` example).
63
+
64
+ Suites: SecretDrop 37/37, migration 15/15 green; `tsc --noEmit` clean. An independent
65
+ second-pass reviewer concurred with the side-effects review.
@@ -0,0 +1,83 @@
1
+ # Side-effects review — Secret Drop Sliding Window + Atomic Use-and-Consume
2
+
3
+ **Spec:** `docs/specs/secret-drop-sliding-window.md`
4
+ **Files:** `src/server/SecretDrop.ts`, `src/templates/scripts/secret-drop-retrieve.mjs`, `tests/unit/SecretDrop.test.ts`, `tests/unit/PostUpdateMigrator-secretDropHardenedRetrieve.test.ts`, `src/core/PostUpdateMigrator.ts`, `src/scaffold/templates.ts`
5
+
6
+ ## 1. Over-block — what legitimate inputs does this reject that it shouldn't?
7
+
8
+ Nothing new is rejected. Submission validation (CSRF, required fields, R1a signature)
9
+ is unchanged. The sliding window only affects how long an accepted submission is
10
+ *retained*; it never rejects a submission or a retrieve. `--run` adds a code path but
11
+ the default retrieve/`--names`/`--consume` behaviors are byte-for-byte unchanged.
12
+
13
+ ## 2. Under-block — what failure modes does this still miss?
14
+
15
+ - **Server restart loses an unconsumed secret.** Explicitly out of scope (in-memory by
16
+ design); contract documented in the spec; encrypted-at-rest tracked as follow-up
17
+ (`fb-391a4a30-de9`).
18
+ - **An agent that uses the destructive `consumeReceived`/`--consume` mid-flow can still
19
+ drop a secret.** The `--run` mode + CLAUDE.md guidance steer away from this, but the
20
+ standalone `--consume` is retained for back-compat and is still misusable. Mitigated,
21
+ not eliminated. Accepted: removing `--consume` outright would be a breaking change to
22
+ any caller already using it.
23
+
24
+ ## 3. Level-of-abstraction fit
25
+
26
+ Correct layer. Lifetime management belongs in `SecretDrop` (it owns the store and the
27
+ timers). The atomic use-and-consume belongs in the consumer helper (it owns the
28
+ hand-off to the command). No higher/lower layer is a better owner, and no smarter gate
29
+ exists that this should feed instead.
30
+
31
+ ## 4. Signal vs authority compliance
32
+
33
+ Compliant. This adds no decision point that gates information flow or blocks actions.
34
+ The `--run` "consume only on exit 0" is a success gate on a local subprocess, not an
35
+ authority over agent behavior. No brittle-check-with-blocking-authority is introduced.
36
+ (Ref: `docs/signal-vs-authority.md`.)
37
+
38
+ ## 5. Interactions
39
+
40
+ - **Stuck-consumer timer:** still fires at 60s; `minutesUntilCleanup` now derives from
41
+ `receivedDeadline` (true purge time) — more accurate, not less. The stuck timer is
42
+ NOT re-armed on peek (deliberate: it's a "nobody has consumed this yet" nudge, and
43
+ the absolute deadline it reports is fixed at submit). No double-fire, no race.
44
+ - **Cleanup timer:** centralized in `armReceivedCleanup`; each re-arm clears the prior
45
+ timer first (no timer leak). `consumeReceived`/`shutdown` clear the timer, the stuck
46
+ timer, AND the new `receivedDeadline` map (no map leak).
47
+ - **`--consume` flag and `--run`:** mutually independent; `--run` consumes via the same
48
+ `?consume=true` endpoint after success. No shadowing.
49
+
50
+ ## 6. External surfaces
51
+
52
+ - **Other agents:** the helper template change reaches every agent via the
53
+ always-overwrite relay-script refresh; the server change ships via npm. CLAUDE.md
54
+ awareness reaches new agents (scaffold) and existing agents (idempotent migrator
55
+ block, tested). No external API shape change — `/secrets/retrieve/:token` and
56
+ `?consume=true` are unchanged.
57
+ - **Timing/runtime dependence:** the window is wall-clock based (setTimeout); fake-timer
58
+ tests cover the boundaries deterministically. No dependence on conversation state.
59
+
60
+ ## 7. Rollback cost
61
+
62
+ Pure code revert — no data migration, no agent-state repair. Reverting restores the
63
+ fixed 5-min window and removes `--run`; the standalone `--consume` path is untouched
64
+ throughout, so nothing depends on the new behavior to function. The migrator block is
65
+ idempotent and additive (a revert simply stops adding the bullet; already-migrated
66
+ CLAUDE.md files keep a harmless accurate bullet).
67
+
68
+ ## Tier
69
+
70
+ **Tier 2.** Risk floor 2 (safety-invariant proximity: SecretDrop / never-on-disk).
71
+ Declared at the floor — not below it. Full ceremony: converged + approved spec, ELI16,
72
+ this artifact, second-pass review, trace.
73
+
74
+ ## Second-pass review (independent)
75
+
76
+ An independent reviewer audited this artifact against the code and verified each
77
+ claim: (1) no timer/`receivedDeadline` map leak — every add has a matching clear on
78
+ consume/shutdown/re-arm; (2) the sliding window cannot exceed the 30-min cap (the
79
+ `Math.min(IDLE, deadline−now)` clamp enforces it); (3) `--run` consumes only on exit
80
+ 0, never on launch error or non-zero exit, and the value reaches the subprocess via
81
+ stdin only — never stdout/argv; (4) signal-vs-authority compliant (no brittle gate
82
+ with blocking authority); (5) the stuck-consumer timer is correctly NOT re-armed on
83
+ peek. **Verdict: "Concur with the review."**