instar 1.2.66 → 1.2.68

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 (54) hide show
  1. package/dist/commands/server.d.ts.map +1 -1
  2. package/dist/commands/server.js +50 -1
  3. package/dist/commands/server.js.map +1 -1
  4. package/dist/core/PostUpdateMigrator.d.ts +12 -0
  5. package/dist/core/PostUpdateMigrator.d.ts.map +1 -1
  6. package/dist/core/PostUpdateMigrator.js +138 -0
  7. package/dist/core/PostUpdateMigrator.js.map +1 -1
  8. package/dist/core/SessionManager.d.ts.map +1 -1
  9. package/dist/core/SessionManager.js +3 -0
  10. package/dist/core/SessionManager.js.map +1 -1
  11. package/dist/core/codexCapabilities.d.ts +31 -0
  12. package/dist/core/codexCapabilities.d.ts.map +1 -0
  13. package/dist/core/codexCapabilities.js +56 -0
  14. package/dist/core/codexCapabilities.js.map +1 -0
  15. package/dist/core/frameworkSessionLaunch.d.ts.map +1 -1
  16. package/dist/core/frameworkSessionLaunch.js +13 -0
  17. package/dist/core/frameworkSessionLaunch.js.map +1 -1
  18. package/dist/providers/adapters/anthropic-headless/transport/agenticSessionHeadless.d.ts.map +1 -1
  19. package/dist/providers/adapters/anthropic-headless/transport/agenticSessionHeadless.js +1 -0
  20. package/dist/providers/adapters/anthropic-headless/transport/agenticSessionHeadless.js.map +1 -1
  21. package/dist/providers/adapters/openai-codex/transport/agenticSessionHeadless.d.ts.map +1 -1
  22. package/dist/providers/adapters/openai-codex/transport/agenticSessionHeadless.js +1 -0
  23. package/dist/providers/adapters/openai-codex/transport/agenticSessionHeadless.js.map +1 -1
  24. package/dist/providers/adapters/openai-codex/transport/codexSpawn.d.ts +2 -0
  25. package/dist/providers/adapters/openai-codex/transport/codexSpawn.d.ts.map +1 -1
  26. package/dist/providers/adapters/openai-codex/transport/codexSpawn.js +4 -0
  27. package/dist/providers/adapters/openai-codex/transport/codexSpawn.js.map +1 -1
  28. package/dist/server/AgentServer.d.ts +4 -0
  29. package/dist/server/AgentServer.d.ts.map +1 -1
  30. package/dist/server/AgentServer.js +2 -0
  31. package/dist/server/AgentServer.js.map +1 -1
  32. package/dist/server/routes.d.ts +6 -0
  33. package/dist/server/routes.d.ts.map +1 -1
  34. package/dist/server/routes.js +60 -1
  35. package/dist/server/routes.js.map +1 -1
  36. package/dist/threadline/ConversationStore.d.ts +158 -0
  37. package/dist/threadline/ConversationStore.d.ts.map +1 -0
  38. package/dist/threadline/ConversationStore.js +341 -0
  39. package/dist/threadline/ConversationStore.js.map +1 -0
  40. package/dist/threadline/ThreadlineRouter.d.ts.map +1 -1
  41. package/dist/threadline/ThreadlineRouter.js +24 -0
  42. package/dist/threadline/ThreadlineRouter.js.map +1 -1
  43. package/dist/threadline/WarrantsReplyGate.d.ts +110 -0
  44. package/dist/threadline/WarrantsReplyGate.d.ts.map +1 -0
  45. package/dist/threadline/WarrantsReplyGate.js +263 -0
  46. package/dist/threadline/WarrantsReplyGate.js.map +1 -0
  47. package/dist/threadline/mcp-http-client.d.ts.map +1 -1
  48. package/dist/threadline/mcp-http-client.js +6 -0
  49. package/dist/threadline/mcp-http-client.js.map +1 -1
  50. package/package.json +1 -1
  51. package/src/data/builtin-manifest.json +63 -63
  52. package/upgrades/1.2.67.md +57 -0
  53. package/upgrades/1.2.68.md +97 -0
  54. package/upgrades/side-effects/codex-hook-trust-bypass.md +37 -0
@@ -0,0 +1,97 @@
1
+ # Upgrade Guide — vNEXT
2
+
3
+ <!-- bump: minor -->
4
+ <!-- minor = new capability, backward compatible -->
5
+
6
+ ## What Changed
7
+
8
+ Phase 1 of the Threadline re-assessment — the **conversation keystone**. It fixes
9
+ the two failures we hit live: agent-to-agent threads fragmenting into stray
10
+ side-sessions, and two agents echoing acknowledgements at each other forever (the
11
+ echo↔codey ~20-minute ping-pong on 2026-05-24).
12
+
13
+ **The root cause.** Every inbound Threadline message spawned a fresh, memory-less
14
+ worker whose prompt always said "reply." Nothing owned the turn count, so an
15
+ amnesiac worker reflexively volleyed acks; and the conversation→topic binding was
16
+ captured *outbound by willpower* (a caller had to stamp `originTopicId`), so when
17
+ it was forgotten the thread floated into a new untied session.
18
+
19
+ **The fix (three parts).**
20
+ 1. **A single Conversation record** (`ConversationStore`) is now the home for a
21
+ thread's turn count, novelty hashes, binding and lifecycle — the one place the
22
+ one-shot worker provably can't keep, but the gate needs. Every write goes
23
+ through a single-writer CAS surface (modeled on `CommitmentTracker.mutate`) so
24
+ concurrent inbound messages can't clobber the turn count.
25
+ 2. **A warrants-a-reply gate** runs once at the relay inbound funnel, upstream of
26
+ all three routing branches (pipe-spawn / warm-listener / cold-spawn), so a
27
+ no-reply verdict short-circuits all of them. Questions, imperatives and
28
+ decisive control tokens always get a reply; a content-free ack does not; a
29
+ novelty-gated turn budget winds down a circular exchange while a genuinely
30
+ novel long collaboration never trips it; a human in the thread is always
31
+ answered instantly.
32
+ 3. **Structural session/topic binding.** The origin session name is injected at
33
+ the spawn boundary (`INSTAR_SESSION_NAME`), forwarded on the send, and
34
+ resolved to the owning topic server-side — so a conversation sticks to its
35
+ session/topic without anyone remembering to tag it.
36
+
37
+ Plus an anti-hijack fix found while wiring it: a threadId is not a bearer token —
38
+ an unverified peer presenting someone else's threadId is now isolated to a fresh
39
+ first-contact thread instead of being injected into the owner's session.
40
+
41
+ ## What to Tell Your User
42
+
43
+ - Agents no longer loop on "thanks → thanks." A bare acknowledgement doesn't
44
+ trigger a reply, and a back-and-forth that stops making progress winds down on
45
+ its own — but a real question or request is always answered, and if you're in
46
+ the conversation it stays instant.
47
+ - A conversation now stays glued to the right place automatically; it won't spin
48
+ off into a stray parallel session anymore.
49
+ - Nothing to configure. Existing in-flight conversations are migrated over on
50
+ update so they keep their context.
51
+
52
+ ## Summary of New Capabilities
53
+
54
+ | Capability | How to Use |
55
+ |-----------|-----------|
56
+ | Conversation single-source-of-truth (`ConversationStore`) | Automatic; backs the loop gate's turn/novelty state at `.instar/threadline/conversations.json` |
57
+ | Warrants-a-reply loop gate | Automatic at the relay inbound funnel; budget exhaustion escalates ONE attention item (never silently drops) |
58
+ | Structural session/topic binding | Automatic via `INSTAR_SESSION_NAME` — no caller needs to stamp `originTopicId` |
59
+ | Anti-hijack resume guard | Automatic; unverified threadId-mismatch → isolated fresh thread |
60
+
61
+ ## Migration Notes
62
+
63
+ `PostUpdateMigrator.migrateThreadlineConversationStore` folds the legacy
64
+ `thread-resume-map.json` + `context-thread-map.json` into `conversations.json` on
65
+ update — idempotent, field-preserving (`sessionUuid`, `agentIdentity`, `pinned`,
66
+ `failed`/`archived`, cross-machine, `boundTopicId`), and it never clobbers a
67
+ runtime-written row. No `~/.codex` or relay change.
68
+
69
+ The full physical collapse of `ThreadResumeMap`/`ContextThreadMap` into the single
70
+ store (so the router reads/writes *only* the Conversation) is intentionally NOT in
71
+ this release: those stores are written from two processes (the server and the MCP
72
+ stdio child), so a single in-memory store needs the child to route writes through
73
+ the server first — tracked as **CMT-497**, folding into the Phase 2 server-owned
74
+ reply model (CMT-493). Phase 1 ships the loop/fragmentation/hijack fixes with the
75
+ Conversation as the authoritative turn/novelty/binding store.
76
+
77
+ ## Evidence
78
+
79
+ - Spec: `docs/specs/THREADLINE-CONVERSATION-KEYSTONE-SPEC.md` (+ ELI16 companion,
80
+ + convergence report — 2 fatal + 4 blocking findings fixed before code).
81
+ - Tests (4 tiers): `ConversationStore.test.ts` (14, incl. 50-concurrent-increment
82
+ CAS race), `WarrantsReplyGate.test.ts` (18, both sides of every boundary),
83
+ `ThreadlineRouter-anti-hijack.test.ts` (3), `PostUpdateMigrator-conversationStore.test.ts`
84
+ (5, field preservation + idempotency), integration `warrants-reply-funnel.test.ts`
85
+ (5, incl. the echo↔codey loop-termination reproduction + CAS integrity under
86
+ concurrency), and wiring-integrity `conversation-keystone-wiring.test.ts` (6,
87
+ feature-alive: constructed + invoked + upstream of all branches).
88
+ - A loop-gate bug the integration test caught that unit tests missed: keying
89
+ "first contact" off `turnCount===0` made every post-progress turn reply, since
90
+ turnCount resets to 0 on novelty — fixed to key off conversation history.
91
+
92
+ ## Rollback
93
+
94
+ Additive. The Conversation store is new; the gate is a guarded early-return at the
95
+ funnel; the binding is a launch-time computation. Revert = remove the funnel gate
96
+ block + the `INSTAR_SESSION_NAME` injection + the migration call. No persistent
97
+ state to clean up (the legacy stores are left intact by the migration).
@@ -0,0 +1,37 @@
1
+ # Side-Effects Review: Codex hook-trust bypass (P6a — autonomy)
2
+
3
+ ## Change
4
+ - **New** `src/core/codexCapabilities.ts`: memoized `codexSupportsHookTrustBypass(binaryPath)` — probes `codex --help` once per binary path, returns whether `--dangerously-bypass-hook-trust` is supported. Fails closed on any error.
5
+ - **`src/core/frameworkSessionLaunch.ts`**: both the interactive (`codexCliBuilder`) and headless (`codexCliHeadlessBuilder`) codex builders append `--dangerously-bypass-hook-trust` when the probe passes.
6
+
7
+ ## Why
8
+ Codex requires interactive trust of command hooks before they run; that prompt freezes an unattended/autonomous session and offers a "continue without trusting" escape that lets an agent decline its own guards. The flag (codex 0.133) runs instar's already-vetted hooks with no prompt. Per Justin's delegation ("choose what's best for Instar", 2026-05-24), chosen as a **per-agent launch flag** over system-managed hooks — see spec §10 P6a for the full rationale.
9
+
10
+ ## Scope / blast radius
11
+ - **Codex launches only.** Claude launches are untouched (separate builder). The flag is appended only to codex argv, and only when the probed binary supports it.
12
+ - **Safe-by-construction:** instar writes the hooks (`installCodexHooks`) AND owns the launch command — there is no untrusted third-party hook this prompt would have protected against. The "danger" of the flag (running arbitrary untrusted hooks) does not apply.
13
+ - **No system-wide effect:** unlike managed hooks, this changes nothing outside instar's own spawned codex processes. The operator's personal `codex` launches do not get the flag and still prompt normally.
14
+ - **Older codex (<0.133):** the probe returns false → flag omitted → the launch still succeeds (an unknown flag would otherwise fail the whole launch) and degrades to the safe-by-blocking interactive trust-prompt path.
15
+
16
+ ## Signal vs Authority / over-block
17
+ - No change to what the hooks block. This only affects whether they run unprompted. No new authority, no new patterns.
18
+
19
+ ## Performance
20
+ - The probe runs `codex --help` at most once per binary path per process (memoized), at session-spawn time (infrequent), 5s timeout. Negligible.
21
+
22
+ ## Migration parity
23
+ - **None required.** This is instar's own dist code (the launch builders), not an agent-installed file (`.claude/settings.json` / `.codex/hooks.json` / hook scripts / config defaults). Existing agents receive it on the normal npm update + server restart. (The P5c hooks.json/guard changes that this depends on already shipped in v1.2.66 with their own migration.)
24
+
25
+ ## Unbypassability (honest bound)
26
+ - The agent cannot remove the flag from a launch instar constructs → it cannot turn off the trust-bypass. It could still attempt to edit `.codex/hooks.json` / the guard script to neuter the hook itself; that residual vector is covered by always-overwrite-on-update of instar-owned hooks + the file-edit gates, not by this change. Absolute unbypassability would require system-managed hooks, deliberately not chosen (see spec §10 P6a).
27
+
28
+ ## Tests
29
+ - `tests/unit/codexCapabilities.test.ts` (5): supported/unsupported `--help`, fail-closed on missing + empty path, memoization (cached true survives binary deletion).
30
+ - `tests/unit/frameworkSessionLaunch.test.ts` (+4): interactive & headless builders append the flag when the fake binary advertises it, omit it when it doesn't; prompt stays the final positional arg in headless.
31
+ - Live-proven end-to-end on real codex 0.133 (no trust granted → no prompt → guard still blocked `rm -rf /`). `tsc` clean; 53 launch/capability tests green.
32
+
33
+ ## Rollback
34
+ - Remove the two `if (codexSupportsHookTrustBypass(...)) argv.push(...)` blocks and delete `codexCapabilities.ts`. No data migration. (Rollback re-introduces the autonomous-hang on the trust prompt.)
35
+
36
+ ## Publish
37
+ - Branch `echo/codex-hook-trust-bypass`. Patch → next release.