instar 1.3.279 → 1.3.281

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 (33) hide show
  1. package/dist/commands/server.d.ts.map +1 -1
  2. package/dist/commands/server.js +16 -1
  3. package/dist/commands/server.js.map +1 -1
  4. package/dist/core/Config.d.ts.map +1 -1
  5. package/dist/core/Config.js +71 -3
  6. package/dist/core/Config.js.map +1 -1
  7. package/dist/core/GlobalSecretStore.d.ts +6 -1
  8. package/dist/core/GlobalSecretStore.d.ts.map +1 -1
  9. package/dist/core/GlobalSecretStore.js +26 -10
  10. package/dist/core/GlobalSecretStore.js.map +1 -1
  11. package/dist/core/PostUpdateMigrator.d.ts.map +1 -1
  12. package/dist/core/PostUpdateMigrator.js +7 -3
  13. package/dist/core/PostUpdateMigrator.js.map +1 -1
  14. package/dist/core/SecretManager.d.ts +4 -0
  15. package/dist/core/SecretManager.d.ts.map +1 -1
  16. package/dist/core/SecretManager.js +23 -7
  17. package/dist/core/SecretManager.js.map +1 -1
  18. package/dist/core/SecretMigrator.d.ts.map +1 -1
  19. package/dist/core/SecretMigrator.js +6 -1
  20. package/dist/core/SecretMigrator.js.map +1 -1
  21. package/dist/monitoring/PromptGate.d.ts +9 -0
  22. package/dist/monitoring/PromptGate.d.ts.map +1 -1
  23. package/dist/monitoring/PromptGate.js +52 -0
  24. package/dist/monitoring/PromptGate.js.map +1 -1
  25. package/package.json +1 -1
  26. package/src/data/builtin-manifest.json +20 -20
  27. package/src/templates/hooks/grounding-before-messaging.sh +8 -3
  28. package/upgrades/{1.3.279.md → 1.3.280.md} +49 -0
  29. package/upgrades/1.3.281.md +20 -0
  30. package/upgrades/keychain-per-agent-master-key.eli16.md +3 -0
  31. package/upgrades/side-effects/gemini-modal-safe-reject.md +86 -0
  32. package/upgrades/side-effects/hook-block-stderr.md +33 -0
  33. package/upgrades/side-effects/keychain-per-agent-master-key.md +50 -0
@@ -5,6 +5,24 @@
5
5
 
6
6
  ## What Changed
7
7
 
8
+ Prompt Gate now recognizes the exact Gemini CLI package-runner install prompt
9
+ that blocked the live mentorship cycle: an `instar` package version followed by
10
+ `Ok to proceed? (y)`. That narrow prompt is answered with the highlighted
11
+ default, so the agent can continue through its own Instar CLI command without a
12
+ manual Enter press. Arbitrary package installs are not auto-answered.
13
+
14
+ Prompt Gate also recognizes Gemini CLI execution-approval modals, but with the
15
+ opposite policy. Execution approvals ask whether model-proposed command text may
16
+ run. This change adds no approval path. When the known modal shape includes the
17
+ reject option, Prompt Gate chooses that reject option and records the rejected
18
+ command text in the server log plus an observable Prompt Gate event.
19
+
20
+ Fixed an invisible-verdict bug in the pre-send message-quality gate. When the gate
21
+ blocked an outbound message, it wrote its reasons to the wrong output channel, so
22
+ the agent saw a generic "hook error" instead of the actual findings — and would
23
+ retry blind. The reasons now land on the channel the runtime actually shows, so a
24
+ blocked message comes back with the specific quality findings to fix.
25
+
8
26
  Added a Mandates tab to the dashboard — the operator's surface for the coordination
9
27
  permission slips. It lists every issued mandate with live authorship verification and
10
28
  state, provides PIN-gated forms to issue a new mandate or revoke an existing one, and
@@ -24,6 +42,16 @@ written to the server log, even if the caller's connection already timed out.
24
42
 
25
43
  ## What to Tell Your User
26
44
 
45
+ Gemini can now get past the specific Instar package install prompt that was
46
+ blocking mentor cycles. If Gemini asks to run an arbitrary command, Instar will
47
+ not approve it automatically. It rejects the known approval prompt and leaves a
48
+ visible record of the command it refused, so the mentor can see why the task
49
+ changed course.
50
+
51
+ Your agent's pre-send quality check now explains itself. If it holds a message
52
+ back, the agent sees exactly why and revises, instead of appearing to hit a
53
+ mysterious error.
54
+
27
55
  Your dashboard now has a Mandates tab where you manage the permission slips for
28
56
  autonomous agent-to-agent work: see every slip and whether its authorship still
29
57
  verifies, issue a new one with your PIN, tear one up with your PIN, and read the
@@ -36,6 +64,16 @@ results always show up in the logs.
36
64
 
37
65
  ## Summary of New Capabilities
38
66
 
67
+ - Auto-answer the narrow Gemini package-runner install confirmation for Instar
68
+ package versions.
69
+ - Auto-reject Gemini execution-approval modals with an explicit reject option.
70
+ - Record execution auto-rejects visibly so mentor diagnosis does not depend on
71
+ guessing from a stalled terminal.
72
+
73
+ - Blocked outbound messages surface their quality findings to the agent instead
74
+ of an opaque hook error.
75
+ - Maturity: stable; the gate's judgments are unchanged — only their visibility.
76
+
39
77
  - See all coordination mandates with live authorship-verification badges and
40
78
  active/revoked/expired state at a glance.
41
79
  - Issue a mandate from a form (pre-filled with the standard two-authority shape) —
@@ -51,3 +89,14 @@ results always show up in the logs.
51
89
  - Comparison outcomes are always logged server-side, even when the requester's
52
90
  connection timed out first.
53
91
  - Maturity: stable; no other route's timing changes.
92
+
93
+ ## Evidence
94
+
95
+ Not reproducible in a live dev shell without driving Gemini into the exact
96
+ interactive modal, but covered by deterministic unit fixtures from the captured
97
+ terminal shapes:
98
+
99
+ - package-runner install prompt for `instar@1.3.270` auto-dismisses with Enter;
100
+ - arbitrary package-runner install prompt does not auto-dismiss;
101
+ - execution-approval modal with highlighted Allow once still auto-rejects;
102
+ - rejected execution command text is carried in the detected prompt metadata.
@@ -0,0 +1,20 @@
1
+ # Upgrade Guide — vNEXT
2
+
3
+ <!-- assembled-by: assemble-next-md -->
4
+ <!-- bump: patch -->
5
+
6
+ ## What Changed
7
+
8
+ `Config.loadConfig` (loud merge failure + critical-placeholder boot guard `assertNoCriticalSecretPlaceholders`), `GlobalSecretStore.initWithKeychain` (generation guard, injectable exec), `SecretManager` (reported degradations), `SecretMigrator` (drops `forceFileKey`). Complements #810 (vault-key-coherence — per-agent keychain slots, keyId header, dual-key reads), which owns the SecretStore layer. Spec: `docs/specs/keychain-per-agent-master-key.md`.
9
+
10
+ ## What to Tell Your User
11
+
12
+ Nothing user-visible in normal operation. The remaining layers of the 2026-06-05 secrets incident are closed: an undecryptable secret store now stops the boot immediately with a precise, actionable error (instead of a confusing crash-loop minutes later), and the shared secret vault can no longer orphan existing data by generating a fresh key over it.
13
+
14
+ ## Summary of New Capabilities
15
+
16
+ - Boot fails fast with an actionable message when secrets cannot be resolved for boot-critical fields (enabled messaging adapters' tokens; authToken when binding non-loopback) — never a placeholder-driven type-error crash minutes later.
17
+ - `mergeConfigWithSecrets` failures are reported through DegradationReporter instead of an empty catch.
18
+ - The user-global secret store refuses to generate a new key over existing encrypted data it would orphan; it reports and stays locked instead.
19
+ - Local secret-store failures in SecretManager are reported instead of silently returning empty results.
20
+ - `migrateSecrets` writes with the same key resolution the boot read path uses (no manufactured key divergence).
@@ -0,0 +1,3 @@
1
+ # Secrets boot guard + orphan-proof stores
2
+
3
+ When an agent's encrypted secrets can't be decrypted, the old behavior was to silently swallow the failure and let placeholder objects leak into the running config — the server then crash-looped minutes later on an unrelated-looking type error (the 2026-06-05 incident). Now the boot fails fast with a message naming the exact affected fields, the shared cross-agent secret vault refuses to generate a fresh key over existing data it would orphan, and secret-store failures are loudly reported instead of looking like "no secrets stored." Complements PR #810, which fixed the key storage layer itself.
@@ -0,0 +1,86 @@
1
+ # Side-effects Review: Gemini Modal Safe Rejects
2
+
3
+ ## Change
4
+
5
+ This Tier-1 change extends the existing Prompt Gate deterministic modal path.
6
+ It does not introduce a new policy engine or a new execution surface.
7
+
8
+ Touched surfaces:
9
+
10
+ - `src/monitoring/PromptGate.ts`: adds narrow Gemini CLI matchers for the
11
+ observed `npx instar@... Ok to proceed? (y)` install prompt and for Gemini
12
+ execution-approval modals with an explicit reject option.
13
+ - `src/commands/server.ts`: logs execution auto-rejects before sending the
14
+ reject key, and reports them through `DegradationReporter`.
15
+ - `tests/unit/PromptGate.test.ts`: covers the install-confirm match and
16
+ near-miss, plus the execution-approval reject boundary.
17
+
18
+ ## Overreach / Underreach
19
+
20
+ The install matcher is deliberately under-broad. It accepts only the captured
21
+ package-runner shape for `instar@x.y.z`, because the live miss was `instar`
22
+ itself. It does not auto-answer unrelated package installs such as `left-pad`.
23
+
24
+ The execution matcher is also narrow. It only auto-rejects when the terminal
25
+ shows the known `Allow execution of:` modal and a reject option. If the UI shape
26
+ changes or the reject option is missing, normal relay/classification remains the
27
+ fallback. There is no auto-approve path.
28
+
29
+ ## Safety Boundary
30
+
31
+ Install confirmations and execution approvals are not the same class.
32
+
33
+ An `npx instar@... Ok to proceed? (y)` prompt confirms the package runner's
34
+ default for an Instar command the agent already invoked. Accepting it unblocks
35
+ the intended tool path.
36
+
37
+ An execution-approval prompt asks whether arbitrary command text may run. The
38
+ command can be malformed, unrelated to the task, or unsafe. The live Gemini
39
+ cycle proved this with a shell-comment command. Auto-approving that class would
40
+ turn model output into code execution. This change therefore only supports
41
+ safe-reject for execution approvals.
42
+
43
+ ## Observability
44
+
45
+ Auto-rejects are intentionally visible. Before sending the reject key, the
46
+ server writes a `[PromptGate] Auto-rejected execution approval...` warning with
47
+ the rejected command text and emits a `PromptGate.executionApprovalAutoReject`
48
+ DegradationReporter event.
49
+
50
+ This is not just debugging convenience. It is part of the safety design: when a
51
+ mentee appears to stall or pivot, the mentor can see that the framework rejected
52
+ an execution prompt and why.
53
+
54
+ ## Signal vs Authority
55
+
56
+ The new matchers are deterministic authority only for two tightly-scoped UI
57
+ shapes:
58
+
59
+ - safe-default for `instar@...` package-runner install confirmation;
60
+ - safe-reject for Gemini execution approval with an explicit reject option.
61
+
62
+ Everything else remains signal for the existing Prompt Gate relay/classifier
63
+ flow. The change does not add an LLM prompt filter, does not broaden yes/no
64
+ auto-approval, and does not treat generic `Ok to proceed?` text as authority.
65
+
66
+ ## Adjacent Systems
67
+
68
+ - Telegram/Slack prompt relay: unchanged for prompts that do not match the new
69
+ exact shapes.
70
+ - AutoApprover: unchanged. Execution safe-reject uses the pre-classifier
71
+ auto-dismiss path, not the auto-approve path.
72
+ - DegradationReporter: receives one observable event per execution auto-reject.
73
+ The event is intentional and mentor-facing; it should not be treated as a
74
+ failure of Prompt Gate.
75
+
76
+ ## Rollback
77
+
78
+ Revert the three code/test changes and remove these upgrade artifacts. Runtime
79
+ state does not need migration. Existing agents would return to relaying or
80
+ waiting on these Gemini prompts.
81
+
82
+ ## Verification
83
+
84
+ - `npm test -- --run tests/unit/PromptGate.test.ts` passed, 57 tests.
85
+ - `npx tsc --noEmit` passed.
86
+
@@ -0,0 +1,33 @@
1
+ # Side-effects review — grounding hook block-output → STDERR
2
+
3
+ Live incident (2026-06-05): the message-quality gate (convergence check inside the
4
+ grounding-before-messaging PreToolUse hook) correctly BLOCKED several outbound
5
+ messages — but wrote the findings + block banner to STDOUT. On a PreToolUse exit-2
6
+ block, Claude Code surfaces ONLY STDERR, so every block rendered to the agent as
7
+ "hook error ... No stderr output": a malfunction instead of a verdict. The agent
8
+ (me) retried blind several times before diagnosing via direct hook invocation.
9
+
10
+ ## 1. The change
11
+
12
+ Both copies of the hook source (the `src/templates/hooks/` init-time file AND the
13
+ inline `PostUpdateMigrator.getGroundingBeforeMessaging()` that migrateHooks
14
+ always-overwrites onto every agent) now route the block findings + banner to
15
+ STDERR. The pass path (GROUNDED on stdout, exit 0) is unchanged.
16
+
17
+ ## 2. Migration parity
18
+
19
+ Built-in hooks in `.instar/hooks/instar/` are ALWAYS overwritten on every
20
+ migration run — the fix reaches every deployed agent automatically on the next
21
+ update; no new migration code needed.
22
+
23
+ ## 3. Blast radius
24
+
25
+ Two-line behavioral change inside an existing block branch. The gate's
26
+ DECISIONS are untouched — only where the explanation lands. No config, routes,
27
+ or schema.
28
+
29
+ ## 4. Test coverage
30
+
31
+ 6 tests (3 × both template copies via describe.each): block → exit 2 + findings
32
+ on STDERR with stdout clean; pass → exit 0 + GROUNDED on stdout; non-messaging
33
+ input untouched. Run against the REAL hook sources with a stubbed quality check.
@@ -0,0 +1,50 @@
1
+ # Side-Effects Review — Secrets boot guard + orphan-proof stores
2
+
3
+ **Version / slug:** `keychain-per-agent-master-key`
4
+ **Date:** `2026-06-05`
5
+ **Author:** `echo`
6
+ **Second-pass reviewer:** `codex gpt-5.5 adversarial spec review (SHIP-WITH-CHANGES, all 8 required changes applied); re-scoped after PR #810 landed the SecretStore layer in parallel — surviving sections were part of the converged design`
7
+
8
+ ## Summary of the change
9
+
10
+ Closes the remaining layers of the 2026-06-05 keychain master-key poisoning incident (Echo boot crash-loop, ~25 min Telegram mute) that PR #810 (vault-key-coherence) did not cover: `loadConfig` reports merge failures via DegradationReporter and fails the boot fast when `{secret:true}` placeholders survive in boot-critical fields; `GlobalSecretStore.initWithKeychain` refuses to generate over existing ciphertext; `SecretManager` local-store catches report instead of silently returning null/{}; `migrateSecrets` drops the `forceFileKey` write/read asymmetry.
11
+
12
+ ## Decision-point inventory
13
+
14
+ - `Config.loadConfig` — modified — merge catch reports via DegradationReporter; `assertNoCriticalSecretPlaceholders` fails boot on surviving placeholders in ENABLED adapters' required secret fields (telegram token/chatId, slack botToken/appToken) or authToken when binding non-loopback.
15
+ - `GlobalSecretStore.initWithKeychain` — modified — generation guard over existing ciphertext (report + stay locked, never orphan); injectable exec for hermetic tests.
16
+ - `SecretManager.get/set/getAllFromLocal` — modified — failures reported via `reportLocalStoreFailure`, behavior (degrade) unchanged.
17
+ - `SecretMigrator.migrateSecrets` — modified — drops `forceFileKey: true` (writes resolve through the same key resolution as reads).
18
+
19
+ ## 1. Over-block
20
+
21
+ The boot guard could block a boot that previously "worked" in a degraded state (placeholders present but the adapter happened to be broken anyway). That is intentional: the previous behavior was a 2-minute zombie boot ending in `tokenHash(Object)`. Scope is narrowed to enabled adapters' required fields + conditional authToken; disabled adapters and unknown fields never block (codex review changes #5/#6). Verified by integration tests on both sides of each boundary.
22
+
23
+ ## 2. Over-permit
24
+
25
+ None added. The generation guard strictly REMOVES a permissive path (fresh key over existing ciphertext). The boot guard never relaxes any existing check.
26
+
27
+ ## 3. Interplay with the parallel fixes (#810, #802, #789)
28
+
29
+ - **#810 (vault-key-coherence)** owns SecretStore: per-agent accounts (`master-key:<stateDir>`), keyId header, dual-key fallback, convergence-on-write. Its named wrong-key error flows verbatim into this PR's actionable boot failure — the two compose: #810 makes most key divergence self-heal; when nothing decrypts, this PR makes the failure fast and precise instead of a placeholder leak.
30
+ - **#802** guards the CONSUMER side (TelegramAdapter string-shape checks). This PR guards the PRODUCER side (config load). #802's PR body names this spec as the owner of the config layer.
31
+ - **#789/#810's VITEST guard** keeps test runs file-key-only; this PR's tests never touch the real keychain (GlobalSecretStore tests use the injectable exec / password-mode seeding; the real-keychain generation test is darwin-scoped `skipIf`).
32
+
33
+ ## 4. Failure modes
34
+
35
+ - No key decrypts a store → #810 throws its named error → merge catch reports → boot guard throws the actionable message naming fields (never silent placeholders).
36
+ - Secrets genuinely absent (fresh agent, no migration) → no placeholders in config → guard never fires → zero change.
37
+ - GlobalSecretStore keychain entry vanishes with data present → store stays LOCKED with a report instead of silently orphaning data behind a fresh key.
38
+ - Loopback-only agent with an authToken placeholder → degrade-with-report (boot proceeds) — matches the existing non-loopback-only criticality condition.
39
+
40
+ ## 5. Migration parity
41
+
42
+ No installed-file/config-shape changes — `PostUpdateMigrator` untouched by design. The boot guard activates purely from existing on-disk state.
43
+
44
+ ## 6. Token/cost impact
45
+
46
+ None. No LLM calls; one config-tree scan at boot (microseconds).
47
+
48
+ ## 7. Rollback
49
+
50
+ Revert the commit. All four changes are behavior-narrowing or report-only; no data format changes, nothing re-encrypted. Old behavior (silent catch, generate-on-miss) returns exactly as before.