instar 1.3.213 → 1.3.215

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.
Files changed (48) hide show
  1. package/dist/commands/route.d.ts.map +1 -1
  2. package/dist/commands/route.js +1 -0
  3. package/dist/commands/route.js.map +1 -1
  4. package/dist/core/GeminiCliIntelligenceProvider.d.ts +3 -0
  5. package/dist/core/GeminiCliIntelligenceProvider.d.ts.map +1 -1
  6. package/dist/core/GeminiCliIntelligenceProvider.js +51 -21
  7. package/dist/core/GeminiCliIntelligenceProvider.js.map +1 -1
  8. package/dist/core/PostUpdateMigrator.d.ts.map +1 -1
  9. package/dist/core/PostUpdateMigrator.js +15 -0
  10. package/dist/core/PostUpdateMigrator.js.map +1 -1
  11. package/dist/core/frameworkSessionLaunch.d.ts.map +1 -1
  12. package/dist/core/frameworkSessionLaunch.js +2 -1
  13. package/dist/core/frameworkSessionLaunch.js.map +1 -1
  14. package/dist/providers/adapters/gemini-cli/config.d.ts +3 -0
  15. package/dist/providers/adapters/gemini-cli/config.d.ts.map +1 -1
  16. package/dist/providers/adapters/gemini-cli/config.js.map +1 -1
  17. package/dist/providers/adapters/gemini-cli/errors.d.ts.map +1 -1
  18. package/dist/providers/adapters/gemini-cli/errors.js +4 -2
  19. package/dist/providers/adapters/gemini-cli/errors.js.map +1 -1
  20. package/dist/providers/adapters/gemini-cli/models.d.ts +7 -4
  21. package/dist/providers/adapters/gemini-cli/models.d.ts.map +1 -1
  22. package/dist/providers/adapters/gemini-cli/models.js +10 -3
  23. package/dist/providers/adapters/gemini-cli/models.js.map +1 -1
  24. package/dist/providers/adapters/gemini-cli/observability/geminiCapacityPolicy.d.ts +54 -0
  25. package/dist/providers/adapters/gemini-cli/observability/geminiCapacityPolicy.d.ts.map +1 -0
  26. package/dist/providers/adapters/gemini-cli/observability/geminiCapacityPolicy.js +111 -0
  27. package/dist/providers/adapters/gemini-cli/observability/geminiCapacityPolicy.js.map +1 -0
  28. package/dist/providers/adapters/gemini-cli/transport/oneShotCompletion.d.ts.map +1 -1
  29. package/dist/providers/adapters/gemini-cli/transport/oneShotCompletion.js +55 -23
  30. package/dist/providers/adapters/gemini-cli/transport/oneShotCompletion.js.map +1 -1
  31. package/dist/scaffold/templates.d.ts.map +1 -1
  32. package/dist/scaffold/templates.js +1 -0
  33. package/dist/scaffold/templates.js.map +1 -1
  34. package/dist/server/SecretDrop.d.ts +19 -6
  35. package/dist/server/SecretDrop.d.ts.map +1 -1
  36. package/dist/server/SecretDrop.js +79 -30
  37. package/dist/server/SecretDrop.js.map +1 -1
  38. package/dist/server/routes.js +1 -1
  39. package/dist/server/routes.js.map +1 -1
  40. package/package.json +1 -1
  41. package/src/data/builtin-manifest.json +64 -64
  42. package/src/scaffold/templates.ts +1 -0
  43. package/src/templates/scripts/secret-drop-retrieve.mjs +65 -2
  44. package/upgrades/1.3.214.md +65 -0
  45. package/upgrades/1.3.215.md +41 -0
  46. package/upgrades/gemini-capacity-policy.eli16.md +21 -0
  47. package/upgrades/side-effects/gemini-capacity-policy.md +139 -0
  48. package/upgrades/side-effects/secret-drop-sliding-window.md +83 -0
@@ -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,41 @@
1
+ # Upgrade Guide — vNEXT
2
+
3
+ <!-- assembled-by: assemble-next-md -->
4
+ <!-- bump: patch -->
5
+
6
+ ## What Changed
7
+
8
+ Gemini CLI one-shot calls now have a provider-specific capacity policy. When
9
+ Gemini reports a 429, `QUOTA_EXHAUSTED`, `resource exhausted`, or a usage/quota
10
+ limit, Instar parses any reset window Gemini provides, retries only short
11
+ capacity windows once, and otherwise records a local defer window so subsequent
12
+ calls fail fast instead of spawning another doomed Gemini process.
13
+
14
+ Explicit caller-supplied raw Gemini model ids continue to pass through to the
15
+ Gemini CLI. Only the automatic `capacityPolicy.fallbackModel` path is
16
+ constrained to the known local Gemini model set. When that fallback is valid,
17
+ both Gemini execution paths rebuild `gemini -m <model>` on retry from the
18
+ policy-selected model, so fallback configuration is not just resolved, it is
19
+ actually applied to the next CLI invocation.
20
+
21
+ ## What to Tell Your User
22
+
23
+ - **Gemini quota handling is calmer:** "When Gemini says its quota is exhausted,
24
+ I now remember the reset window and stop repeatedly poking it. Short capacity
25
+ blips get one bounded retry; longer quota windows are surfaced as a clear
26
+ defer instead of looking like a stalled agent."
27
+
28
+ ## Summary of New Capabilities
29
+
30
+ | Capability | How to Use |
31
+ |-----------|------------|
32
+ | Gemini capacity defer window | Automatic for Gemini CLI one-shot calls |
33
+ | Short Gemini capacity retry | Automatic, one bounded retry for short windows |
34
+ | Known-only Gemini capacity fallback | Automatic; `fallbackModel` swaps only when the fallback is a known Gemini model |
35
+
36
+ ## Evidence
37
+
38
+ - `npx vitest run tests/unit/gemini-cli-adapter.test.ts tests/unit/geminiCapacityPolicy.test.ts tests/unit/frameworkSessionLaunch.test.ts tests/integration/gemini-capacity-policy-integration.test.ts tests/e2e/gemini-capacity-policy-lifecycle.test.ts`
39
+ — 5 files / 80 tests passed, including raw-model pass-through and spawned
40
+ retry argv assertions.
41
+ - `npx tsc --noEmit`
@@ -0,0 +1,21 @@
1
+ # Gemini Capacity Handling — ELI16
2
+
3
+ Viewable private artifact:
4
+ https://codey.dawn-tunnel.dev/view/b5873ea2-17ba-4adf-9d1a-f0e1c48f781e?sig=3e2c7d2f4e0852cf91496f79ce25aeca72ce778c92d3278e101b63bec90400af
5
+
6
+ Gemini sometimes says, "I'm out of capacity right now; try again after this
7
+ reset window." Before this change, Instar treated that too much like an ordinary
8
+ failure. The next Gemini call could try again immediately, hit the same quota
9
+ wall, and make the agent look stuck. One fallback path also guessed an old model
10
+ name, `gemini-2.0-flash`, which Gemini rejected.
11
+
12
+ This change gives Gemini its own capacity rule. If the reset is short, Instar
13
+ waits briefly and tries once. If Gemini gives a longer reset window, Instar
14
+ remembers it and refuses later Gemini calls locally until the window passes.
15
+ That means no repeated doomed Gemini subprocesses and a clearer error for the
16
+ agent/operator.
17
+
18
+ It also limits Gemini model choices to the verified names we know work:
19
+ `gemini-2.5-flash` and `gemini-2.5-pro`. If some code asks for an unknown Gemini
20
+ model, Instar falls back to `gemini-2.5-flash` instead of sending a guessed model
21
+ to Gemini and getting a 404.
@@ -0,0 +1,139 @@
1
+ # Side-Effects Review — Gemini capacity policy
2
+
3
+ **Version / slug:** `gemini-capacity-policy`
4
+ **Date:** `2026-06-03`
5
+ **Author:** `instar-codey`
6
+ **Second-pass reviewer:** `not required`
7
+
8
+ ## Summary of the change
9
+
10
+ This change adds a Gemini-specific capacity policy beside the existing Gemini
11
+ adapter observability code. Gemini one-shot calls now classify quota/rate-limit
12
+ failures, parse reset windows such as `quota will reset after 7h32m28s`, retry
13
+ only short capacity windows once, and record a process-local defer window for
14
+ longer quota exhaustion. While deferred, later calls fail locally with a retry
15
+ hint instead of spawning another Gemini CLI process that would hit the same
16
+ quota wall.
17
+
18
+ Review update: the optional `capacityPolicy.fallbackModel` is now wired into
19
+ the retry loop instead of only being resolved in the policy decision. Both
20
+ Gemini execution paths rebuild `gemini -m <model>` on each retry attempt from
21
+ the current policy-selected model, so a configured fallback actually changes
22
+ the spawned CLI argv. Explicit caller-supplied raw model ids still pass through
23
+ the primary resolver; only automatic capacity fallback is constrained to known
24
+ Gemini models.
25
+
26
+ The change also constrains automatic Gemini fallback selection to verified known
27
+ models: `gemini-2.5-flash` and `gemini-2.5-pro`. Explicit raw Gemini model ids
28
+ continue to pass through to the CLI because they represent caller intent. The
29
+ bad `gemini-2.0-flash` fallback observed during the mentor loop is avoided by
30
+ the known-only fallback helper rather than by rewriting every raw model id.
31
+
32
+ ## Decision-point inventory
33
+
34
+ - `isGeminiCapacityError` — add — classifies Gemini quota/rate-limit/capacity
35
+ error strings.
36
+ - `parseGeminiRetryAfterMs` — add — extracts reset windows from Gemini stderr.
37
+ - `decideGeminiCapacityPolicy` — add — chooses `none`, `retry`, or `defer`.
38
+ - `recordGeminiCapacityDeferral` / `getGeminiCapacityGate` — add — process-local
39
+ defer state for Gemini calls.
40
+ - Gemini fallback resolution — modify — automatic capacity fallback ids must be
41
+ in the known set or the current caller-selected model is kept.
42
+ - `GeminiCliIntelligenceProvider` and adapter one-shot transport — modify — both
43
+ apply the policy before and after spawning Gemini.
44
+ - Retry argv rebuild — modify — short-window retries rebuild the Gemini argv
45
+ from `decision.model`, so `capacityPolicy.fallbackModel` is applied to the
46
+ next spawned process.
47
+
48
+ ---
49
+
50
+ ## 1. Over-block
51
+
52
+ The main over-block risk is a false-positive capacity classification that defers
53
+ Gemini when the failure was not actually quota related. The classifier is
54
+ deliberately narrow: explicit `429`, `QUOTA_EXHAUSTED`, `resource exhausted`,
55
+ `rate limit`, quota, usage-limit, or capacity language. Generic parse errors,
56
+ syntax errors, binary-not-found errors, and ordinary non-zero exits do not defer.
57
+
58
+ The known-model constraint applies only to automatic capacity fallback. Explicit
59
+ caller-selected Gemini model ids still pass through to the CLI, so newly valid
60
+ Gemini ids are not blocked by this policy. If `capacityPolicy.fallbackModel` is
61
+ unknown, the retry keeps the caller's current model instead of swapping to a
62
+ guessed fallback.
63
+
64
+ ## 2. Under-block
65
+
66
+ This policy is process-local. A server restart forgets the defer window and the
67
+ first post-restart Gemini call may probe the provider again. That matches the
68
+ existing LLM circuit-breaker shape and keeps the change small. A future durable
69
+ capacity ledger could persist provider reset windows across restarts if repeated
70
+ restart-probes become noisy.
71
+
72
+ This does not discover the full Gemini model catalog dynamically. It uses the
73
+ currently verified set and keeps the list explicit. Dynamic discovery is a
74
+ separate model-catalog problem, not part of quota handling.
75
+
76
+ ## 3. Level-of-abstraction fit
77
+
78
+ The policy belongs at the Gemini provider boundary, not at each caller. The
79
+ adapter one-shot transport and live `GeminiCliIntelligenceProvider` are the
80
+ places that see Gemini stderr and own whether to spawn Gemini again. Keeping the
81
+ decision there means reviewers, route, setup narrative calls, and future Gemini
82
+ one-shots share the same capacity behavior.
83
+
84
+ Known-model fallback belongs in the capacity-policy fallback helper because that
85
+ is the only automatic model swap path in this change. Primary model resolution
86
+ still maps canonical tiers and otherwise respects explicit raw model ids.
87
+
88
+ ## 4. Signal vs authority compliance
89
+
90
+ **Required reference:** [docs/signal-vs-authority.md](../../docs/signal-vs-authority.md)
91
+
92
+ - [x] Not applicable to conversational/product judgment — this is deterministic
93
+ provider-capacity handling and model-id validation at the transport boundary.
94
+
95
+ The defer gate is not making a semantic judgment about user intent. It acts only
96
+ after Gemini itself reports a quota/capacity condition or while the recorded
97
+ reset window from that provider report is still active.
98
+
99
+ ## 5. Interactions
100
+
101
+ - **Global LLM circuit breaker:** The Gemini provider still throws clear
102
+ quota/rate-limit text, so the existing circuit breaker can continue to observe
103
+ and pause broader LLM-backed work. The Gemini policy additionally prevents
104
+ repeated Gemini subprocesses during a known Gemini reset window.
105
+ - **Setup wizard:** Gemini narrative fallback continues to work; quota failures
106
+ become clearer and do not repeatedly spawn Gemini.
107
+ - **Route override detector:** The known-model list now includes
108
+ `gemini-2.5-flash`, so the verified default is recognized.
109
+ - **Session launch:** Unchanged by the capacity fallback review fix; the
110
+ known-model gate is isolated to automatic provider retry fallback.
111
+
112
+ ## 6. External surfaces
113
+
114
+ Users may see clearer Gemini quota/defer errors instead of a generic Gemini CLI
115
+ failure or a stalled task. Operators can rely on `gemini-2.5-flash` as the safe
116
+ automatic capacity fallback when configured. Explicit caller-supplied model ids
117
+ continue to pass through. No config migration, schema change, or external API
118
+ change is introduced.
119
+
120
+ ## 7. Rollback cost
121
+
122
+ Rollback is a code revert of the Gemini policy module, the two provider wiring
123
+ changes, the fallback known-list change, tests, and these artifacts. No
124
+ data migration is required. A running process that had recorded a defer window
125
+ would forget it on restart.
126
+
127
+ ## Conclusion
128
+
129
+ The change is a narrow sibling to the Codex capacity/model-swap work, scoped to
130
+ Gemini's actual error and model surfaces. It prevents repeated doomed Gemini CLI
131
+ spawns during quota windows, avoids guessed model fallbacks, and pins the
132
+ behavior with unit, integration, and E2E tests.
133
+
134
+ ## Evidence pointers
135
+
136
+ - `tests/unit/geminiCapacityPolicy.test.ts`
137
+ - `tests/integration/gemini-capacity-policy-integration.test.ts`
138
+ - `tests/e2e/gemini-capacity-policy-lifecycle.test.ts`
139
+ - `tests/unit/frameworkSessionLaunch.test.ts`
@@ -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."**