instar 1.3.264 → 1.3.266
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.map +1 -1
- package/dist/commands/server.js +26 -9
- package/dist/commands/server.js.map +1 -1
- package/dist/core/PostUpdateMigrator.d.ts.map +1 -1
- package/dist/core/PostUpdateMigrator.js +10 -0
- package/dist/core/PostUpdateMigrator.js.map +1 -1
- package/dist/core/SecretSync.d.ts +7 -2
- package/dist/core/SecretSync.d.ts.map +1 -1
- package/dist/core/SecretSync.js.map +1 -1
- package/dist/core/SessionManager.d.ts.map +1 -1
- package/dist/core/SessionManager.js +9 -1
- package/dist/core/SessionManager.js.map +1 -1
- package/dist/core/types.d.ts +6 -0
- package/dist/core/types.d.ts.map +1 -1
- package/dist/core/types.js.map +1 -1
- package/dist/scaffold/templates.d.ts.map +1 -1
- package/dist/scaffold/templates.js +1 -0
- package/dist/scaffold/templates.js.map +1 -1
- package/dist/server/routes.d.ts.map +1 -1
- package/dist/server/routes.js +11 -0
- package/dist/server/routes.js.map +1 -1
- package/package.json +1 -1
- package/src/data/builtin-manifest.json +64 -64
- package/src/scaffold/templates.ts +1 -0
- package/upgrades/1.3.266.md +45 -0
- package/upgrades/side-effects/gemini-stuck-input-prompt-detection.md +41 -0
- package/upgrades/side-effects/secret-sync-push-guard.md +91 -0
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# Side-Effects Review — isMarkerStuckAtPrompt recognizes Gemini's "│ *" input box
|
|
2
|
+
|
|
3
|
+
**Version / slug:** `gemini-stuck-input-prompt-detection`
|
|
4
|
+
**Date:** `2026-06-04`
|
|
5
|
+
**Author:** `echo`
|
|
6
|
+
**Second-pass reviewer:** `not required (Tier-1; one-line detector widening with marker gate; sibling of the merged codex `›` fix)`
|
|
7
|
+
|
|
8
|
+
## Summary of the change
|
|
9
|
+
|
|
10
|
+
`SessionManager.isMarkerStuckAtPrompt()` decided whether an injected Telegram message is still sitting unsubmitted at the input prompt by checking the line for `❯` (Claude) or `›` (codex). Gemini CLI has neither — its input is a `│ * <text>` box line — so a stuck Gemini message was never detected and `verifyInjection`'s Enter-recovery never fired for Gemini (the recurring mentee-layer auto-submit friction; it bit the loop live this session). The fix adds `│ *` (via `/│\s+\*/`) to the prompt-indicator set.
|
|
11
|
+
|
|
12
|
+
## Decision-point inventory
|
|
13
|
+
|
|
14
|
+
1. `const hasPromptChar = line.includes('❯') || line.includes('›') || /│\s+\*/.test(line);` — one regex added.
|
|
15
|
+
2. The downstream gate is UNCHANGED: a line only counts as stuck if it ALSO contains the injected marker (`line.includes(marker)` or the next line includes the 30-char short marker).
|
|
16
|
+
|
|
17
|
+
## 1. Over-fire / false-positive risk
|
|
18
|
+
|
|
19
|
+
Bounded by the marker gate. `│ *` alone never trips it — it must co-occur with the EXACT injected marker (first ~40 chars of the message we typed). A normal agent output line (even a bulleted `│ *` table/list row) cannot contain our injected marker, so it cannot false-fire (test: "does not false-fire on a │ * line that lacks the injected marker"). Gemini's empty-box placeholder ("Type your message…") is not the injected marker either, so an idle empty box is never seen as stuck (test: "placeholder immunity") — the same property the codex `›` fix relies on.
|
|
20
|
+
|
|
21
|
+
## 2. Regression risk (Claude / codex)
|
|
22
|
+
|
|
23
|
+
None. `❯` and `›` are still checked first; the `│ *` branch only adds coverage. Test: "still matches Claude ❯ and codex › (no regression)" — both pass.
|
|
24
|
+
|
|
25
|
+
## 3. Worst case if `│ *` is imperfect
|
|
26
|
+
|
|
27
|
+
If Gemini's box-bullet differs in some build, the detector simply fails to match (no recovery — i.e. today's behavior, no worse). The recovery action itself (`fireStuckInputRecovery`) is Enter/C-m and is already once-per-session-guarded, so even a spurious match costs at most one extra Enter on a line that genuinely holds our injected marker.
|
|
28
|
+
|
|
29
|
+
## 4. Reversibility
|
|
30
|
+
|
|
31
|
+
Fully reversible: revert the one-line `||` term + drop the Gemini test block. No state, config, or migration.
|
|
32
|
+
|
|
33
|
+
## 5. Blast radius
|
|
34
|
+
|
|
35
|
+
One expression in `src/core/SessionManager.ts:isMarkerStuckAtPrompt` + 4 unit tests (added to the existing codex-stranded-draft-recovery suite). No route/config/persistence change. Affects only stuck-input detection for Gemini sessions.
|
|
36
|
+
|
|
37
|
+
## Evidence pointers
|
|
38
|
+
|
|
39
|
+
- `vitest run tests/unit/codex-stranded-draft-recovery.test.ts tests/unit/session-multishot-recovery.test.ts` → 27/27 green.
|
|
40
|
+
- `tsc --noEmit` clean.
|
|
41
|
+
- Fixture mirrors a real Gemini idle pane captured live this session (`│ * [telegram:1] [Long message saved to …]`).
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
# Side-Effects Review — Secret-Sync push opt-in (receive-only default)
|
|
2
|
+
|
|
3
|
+
**Version / slug:** `secret-sync-push-guard`
|
|
4
|
+
**Date:** `2026-06-04`
|
|
5
|
+
**Author:** `echo`
|
|
6
|
+
**Second-pass reviewer:** `not required` (Tier 2; single-author, safety-tightening change)
|
|
7
|
+
|
|
8
|
+
## Summary of the change
|
|
9
|
+
|
|
10
|
+
Adds an anti-clobber safety guard to cross-machine secret-sync (PR #771 / v1.3.258). Previously
|
|
11
|
+
`multiMachine.secretSync.enabled` activated BOTH receive and push, and a boot best-effort
|
|
12
|
+
push fired unconditionally — so a machine whose local secret store is stale/divergent would
|
|
13
|
+
auto-push its stale set to peers and overwrite their good secrets. This change splits push out
|
|
14
|
+
behind `multiMachine.secretSync.pushEnabled` (default **false**): `enabled` alone is now
|
|
15
|
+
RECEIVE-ONLY; outbound (boot push + `POST /secrets/sync-now`) requires `pushEnabled: true`,
|
|
16
|
+
set only on the machine whose store is authoritative. Files: `src/commands/server.ts` (gate +
|
|
17
|
+
handle field + boot-push guard), `src/core/SecretSync.ts` (`SecretSyncHandle.pushEnabled`),
|
|
18
|
+
`src/core/types.ts` (config field), `src/server/routes.ts` (sync-status reports `mode`;
|
|
19
|
+
sync-now 409s when receive-only), `src/scaffold/templates.ts` + `PostUpdateMigrator.ts`
|
|
20
|
+
(agent awareness, incl. a migration for agents that already have the section).
|
|
21
|
+
|
|
22
|
+
Earned live: 2026-06-04 the mini's store drifted (keychain↔file master-key); enabling the
|
|
23
|
+
original (push-on) secret-sync there would have clobbered the laptop's authoritative secrets.
|
|
24
|
+
|
|
25
|
+
## Decision-point inventory
|
|
26
|
+
|
|
27
|
+
- `multiMachine.secretSync.pushEnabled` gate (server.ts) — **add** — splits outbound from inbound.
|
|
28
|
+
- Boot best-effort `provisionAll()` (server.ts) — **modify** — now gated on pushEnabled.
|
|
29
|
+
- `POST /secrets/sync-now` (routes.ts) — **modify** — returns 409 when receive-only.
|
|
30
|
+
- `GET /secrets/sync-status` (routes.ts) — **modify** — now reports `pushEnabled` + `mode`.
|
|
31
|
+
|
|
32
|
+
## 1. Over-block
|
|
33
|
+
|
|
34
|
+
The guard "blocks" outbound push when `pushEnabled` is false — that is the intended behavior, not
|
|
35
|
+
over-block. A user who genuinely wants push must set `pushEnabled: true` (one config line). No
|
|
36
|
+
legitimate RECEIVE is blocked. The 409 response names the exact remedy.
|
|
37
|
+
|
|
38
|
+
## 2. Under-block
|
|
39
|
+
|
|
40
|
+
The guard does not validate that the push-enabled machine's store is ACTUALLY authoritative — it
|
|
41
|
+
trusts the operator's `pushEnabled: true`. A misconfiguration (pushEnabled on a stale machine)
|
|
42
|
+
could still clobber. Mitigated by: default-off (you must deliberately opt in) + the doc guidance
|
|
43
|
+
("set only on the machine whose store is authoritative"). A value-hash reconciliation (only push
|
|
44
|
+
keys the peer is missing/older) is a sound follow-up but out of scope here.
|
|
45
|
+
|
|
46
|
+
## 3. Level-of-abstraction fit
|
|
47
|
+
|
|
48
|
+
Right layer: a config flag + a wiring gate, consistent with the rest of secret-sync. It reuses the
|
|
49
|
+
existing provisioner/handle; no new primitive. The default-off posture matches the project's
|
|
50
|
+
"dark by default" rollout discipline for risky features.
|
|
51
|
+
|
|
52
|
+
## 4. Signal vs authority compliance
|
|
53
|
+
|
|
54
|
+
- [x] No — this change has no block/allow surface over user messages. (It gates an internal
|
|
55
|
+
outbound sync action behind an explicit config flag — deterministic, not a heuristic gate.)
|
|
56
|
+
|
|
57
|
+
## 5. Interactions
|
|
58
|
+
|
|
59
|
+
- **Shadowing:** none — `pushEnabled` only narrows when the existing push path runs.
|
|
60
|
+
- **Double-fire:** reduces it — the boot push no longer fires on receive-only machines.
|
|
61
|
+
- **Races:** unchanged — same SecretStore read-modify-write as before; receive path untouched.
|
|
62
|
+
- **Feedback loops:** none. A receive-only machine that gets corrected by an authoritative push
|
|
63
|
+
does NOT re-push (it can't), so no ping-pong.
|
|
64
|
+
|
|
65
|
+
## 6. External surfaces
|
|
66
|
+
|
|
67
|
+
- **Peers:** strictly safer — a receive-only machine no longer sends to peers at all.
|
|
68
|
+
- **Config:** new optional field `multiMachine.secretSync.pushEnabled` (absent ⇒ false ⇒ no push).
|
|
69
|
+
No migrateConfig default needed (absence = safe default).
|
|
70
|
+
- **API:** `/secrets/sync-status` gains `pushEnabled` + `mode` fields (additive); `/secrets/sync-now`
|
|
71
|
+
can now return 409 (receive-only) in addition to its prior 200/503/500.
|
|
72
|
+
- **Persistent state:** none changed.
|
|
73
|
+
|
|
74
|
+
## 7. Rollback cost
|
|
75
|
+
|
|
76
|
+
Pure code change. Revert = secret-sync returns to push-on-enable (the less-safe prior behavior).
|
|
77
|
+
No persistent state to unwind. Because push was never enabled on any real machine between #771 and
|
|
78
|
+
this change (the mini incident is exactly why), there is no in-the-wild push to reconcile.
|
|
79
|
+
|
|
80
|
+
## Conclusion
|
|
81
|
+
|
|
82
|
+
A small, safety-tightening change with a default-off posture; it closes the divergent-store clobber
|
|
83
|
+
risk that the 2026-06-04 mini incident exposed and makes laptop→mini the safe reconciliation
|
|
84
|
+
direction for the live verification. The one residual (operator opts pushEnabled on a non-authoritative
|
|
85
|
+
machine) is documented and a value-hash reconciliation is the natural follow-up. Clear to ship.
|
|
86
|
+
|
|
87
|
+
## Evidence pointers
|
|
88
|
+
|
|
89
|
+
16 tests green: 8 unit, 5 integration (incl. the new receive-only guard test: sync-now 409s + peer
|
|
90
|
+
vault untouched), 3 e2e. tsc + lint clean. Spec updated (Guarantees → "Push is opt-in"). Related: the
|
|
91
|
+
SecretStore keychain-drift repair that surfaced this (re-key file→keychain).
|