instar 1.0.13 → 1.1.0

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 (57) hide show
  1. package/README.md +1 -1
  2. package/dist/cli.js +52 -2
  3. package/dist/cli.js.map +1 -1
  4. package/dist/commands/init.d.ts +17 -0
  5. package/dist/commands/init.d.ts.map +1 -1
  6. package/dist/commands/init.js +156 -64
  7. package/dist/commands/init.js.map +1 -1
  8. package/dist/commands/server.d.ts.map +1 -1
  9. package/dist/commands/server.js +68 -4
  10. package/dist/commands/server.js.map +1 -1
  11. package/dist/commands/setup.d.ts +3 -1
  12. package/dist/commands/setup.d.ts.map +1 -1
  13. package/dist/commands/setup.js +67 -28
  14. package/dist/commands/setup.js.map +1 -1
  15. package/dist/commands/worktree.d.ts +17 -4
  16. package/dist/commands/worktree.d.ts.map +1 -1
  17. package/dist/commands/worktree.js +28 -4
  18. package/dist/commands/worktree.js.map +1 -1
  19. package/dist/core/AgentWorktreeDetector.d.ts +63 -0
  20. package/dist/core/AgentWorktreeDetector.d.ts.map +1 -0
  21. package/dist/core/AgentWorktreeDetector.js +329 -0
  22. package/dist/core/AgentWorktreeDetector.js.map +1 -0
  23. package/dist/core/InstarWorktreeManager.d.ts +99 -0
  24. package/dist/core/InstarWorktreeManager.d.ts.map +1 -0
  25. package/dist/core/InstarWorktreeManager.js +447 -0
  26. package/dist/core/InstarWorktreeManager.js.map +1 -0
  27. package/dist/core/MachineIdentity.d.ts.map +1 -1
  28. package/dist/core/MachineIdentity.js +2 -0
  29. package/dist/core/MachineIdentity.js.map +1 -1
  30. package/dist/core/PostUpdateMigrator.d.ts +25 -0
  31. package/dist/core/PostUpdateMigrator.d.ts.map +1 -1
  32. package/dist/core/PostUpdateMigrator.js +258 -0
  33. package/dist/core/PostUpdateMigrator.js.map +1 -1
  34. package/dist/monitoring/PromptGate.d.ts +12 -0
  35. package/dist/monitoring/PromptGate.d.ts.map +1 -1
  36. package/dist/monitoring/PromptGate.js +44 -0
  37. package/dist/monitoring/PromptGate.js.map +1 -1
  38. package/dist/scaffold/templates.d.ts.map +1 -1
  39. package/dist/scaffold/templates.js +17 -0
  40. package/dist/scaffold/templates.js.map +1 -1
  41. package/package.json +1 -1
  42. package/scripts/lint-no-direct-destructive.js +7 -0
  43. package/scripts/resolve-release-tier.mjs +192 -0
  44. package/src/data/builtin-manifest.json +56 -48
  45. package/src/scaffold/templates.ts +17 -0
  46. package/src/templates/scripts/instar-watchdog.sh +169 -6
  47. package/src/templates/scripts/instar-worktree-create.sh +79 -0
  48. package/upgrades/1.1.0.md +320 -0
  49. package/upgrades/side-effects/agent-worktree-convention-layer-1-2-5.md +280 -0
  50. package/upgrades/side-effects/agent-worktree-convention-layer-3-4.md +285 -0
  51. package/upgrades/side-effects/feat-fix-parent-framework-intercept.md +59 -0
  52. package/upgrades/side-effects/feat-install-claude-gating.md +67 -0
  53. package/upgrades/side-effects/feat-install-framework-flag.md +65 -0
  54. package/upgrades/side-effects/feat-portability-shadow-capabilities.md +63 -0
  55. package/upgrades/side-effects/feat-setup-framework-flag.md +65 -0
  56. package/upgrades/side-effects/lockdown-layer-2.md +123 -0
  57. package/upgrades/side-effects/watchdog-bind-failure-probe.md +174 -0
@@ -0,0 +1,79 @@
1
+ #!/usr/bin/env bash
2
+ # instar-worktree-create — wrapper that delegates to `instar worktree create`
3
+ # when available, with an inline fallback for hosts that don't have the CLI
4
+ # on PATH yet.
5
+ #
6
+ # Background: Claude Code's sandbox scopes filesystem access to the agent's
7
+ # primary working directory. Worktrees outside that directory are subject
8
+ # to mid-session EPERM revocation. The `instar worktree create` subcommand
9
+ # (Layer 1 of the agent worktree convention, src/core/InstarWorktreeManager.ts)
10
+ # places the worktree in the sandbox-safe area and refuses any other
11
+ # destination. This wrapper guarantees agents always reach that path
12
+ # regardless of how `instar` is installed on the host.
13
+ #
14
+ # Spec: docs/specs/AGENT-WORKTREE-CONVENTION-SPEC.md §Sequencing.
15
+ #
16
+ # Usage:
17
+ # instar-worktree-create.sh <branch>
18
+ # instar-worktree-create.sh <branch> <slug>
19
+
20
+ set -euo pipefail
21
+
22
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
23
+ # Layer 1's resolveAgentHome() prefers INSTAR_AGENT_HOME; this wrapper sets
24
+ # it from the script's own location so resolution is deterministic regardless
25
+ # of CWD or how the user invoked us.
26
+ export INSTAR_AGENT_HOME="$(dirname "$SCRIPT_DIR")"
27
+
28
+ # Honor explicit override first.
29
+ if [[ -n "${INSTAR_BIN:-}" && -x "$INSTAR_BIN" ]]; then
30
+ exec "$INSTAR_BIN" worktree create "$@"
31
+ fi
32
+
33
+ # Resolve to an absolute path — shell aliases (like `instar` → `npx instar`)
34
+ # are not honored by `exec`, so we must verify a real binary path.
35
+ INSTAR_RESOLVED="$(command -v instar 2>/dev/null || true)"
36
+ if [[ -n "$INSTAR_RESOLVED" && "$INSTAR_RESOLVED" == /* ]]; then
37
+ exec "$INSTAR_RESOLVED" worktree create "$@"
38
+ fi
39
+
40
+ # Fall back to npx when instar is not on PATH as a binary. Most installs
41
+ # reach the CLI via `npx instar` rather than a globally-linked binary.
42
+ if command -v npx >/dev/null 2>&1; then
43
+ exec npx --no-install instar worktree create "$@"
44
+ fi
45
+
46
+ # Last-resort inline fallback: hosts with neither `instar` on PATH nor `npx`.
47
+ # Mirrors the original hand-rolled helper that predates the CLI subcommand.
48
+ # This path is intentionally minimal — anyone who hits it should install
49
+ # `npx` or get instar on PATH so they pick up future Layer 1 hardening.
50
+ BRANCH="${1:-}"
51
+ SLUG="${2:-}"
52
+ if [[ -z "$BRANCH" ]]; then
53
+ echo "usage: instar-worktree-create.sh <branch> [<slug>]" >&2
54
+ exit 1
55
+ fi
56
+ if [[ -z "$SLUG" ]]; then SLUG="${BRANCH//\//-}"; fi
57
+ WORKTREES_ROOT="$INSTAR_AGENT_HOME/.worktrees"
58
+ WORKTREE_PATH="$WORKTREES_ROOT/$SLUG"
59
+ INSTAR_REPO="${INSTAR_REPO:-$HOME/Documents/Projects/instar}"
60
+ if [[ ! -d "$INSTAR_REPO" ]]; then
61
+ echo "error: instar repo not found at $INSTAR_REPO" >&2
62
+ exit 1
63
+ fi
64
+ if [[ -e "$WORKTREE_PATH" ]]; then
65
+ echo "error: $WORKTREE_PATH already exists" >&2
66
+ exit 1
67
+ fi
68
+ mkdir -p "$WORKTREES_ROOT"
69
+ chmod 0700 "$WORKTREES_ROOT"
70
+ cd "$INSTAR_REPO"
71
+ if git rev-parse --verify --quiet "$BRANCH" >/dev/null; then
72
+ git worktree add "$WORKTREE_PATH" "$BRANCH"
73
+ else
74
+ git worktree add -b "$BRANCH" "$WORKTREE_PATH" main
75
+ fi
76
+ if [[ -d "$INSTAR_REPO/node_modules" && ! -e "$WORKTREE_PATH/node_modules" ]]; then
77
+ ln -s "$INSTAR_REPO/node_modules" "$WORKTREE_PATH/node_modules"
78
+ fi
79
+ echo "worktree ready at: $WORKTREE_PATH"
@@ -0,0 +1,320 @@
1
+ # Upgrade Guide — v1.1.0 (framework-choice install arc + agent worktree convention + deployment lockdown layer 2)
2
+
3
+ <!-- bump: minor -->
4
+
5
+ ## What Changed
6
+
7
+ Seven changes ship together as v1.1.0 — completes the install/wizard
8
+ framework-choice arc Justin asked for (including a hotfix for the
9
+ parent-option interception that caused the smoke test to fail on the
10
+ v1.0.17 build), plus the v1.0.14-v1.0.16 content that has been queued
11
+ behind the npm auth issue.
12
+
13
+ **Hotfix on v1.0.17. Parent --framework option intercepted subcommand flag.**
14
+ The bareword command (`npx instar` with no subcommand) had its own
15
+ `--framework` option defined alongside the same flag on `init` and
16
+ `setup`. Commander treats program-level options as global, so an
17
+ invocation like `instar init --framework codex-cli` had its flag consumed
18
+ by the parent parser before the init subcommand saw it — the flag silently
19
+ fell back to `claude-code`. Smoke-test caught this; the parent-level
20
+ option is removed. To pick a framework from the bareword path, use
21
+ `instar setup --framework codex-cli` explicitly.
22
+
23
+ **A. `instar setup --framework codex-cli` runs end-to-end on a Codex-only host (portability install PRs 3+4 of 4).**
24
+ The `setup` and bareword (`npx instar`) commands now accept a `--framework
25
+ <claude-code|codex-cli>` flag. Detection no longer hard-exits on missing
26
+ Claude when the operator asked for Codex; it calls `checkFrameworkPrerequisite`
27
+ against whichever framework was selected and surfaces the install URL for
28
+ the missing one. The wizard launch and the secret-setup micro-session now
29
+ spawn the chosen runtime: Claude users get the historical
30
+ `claude --dangerously-skip-permissions /setup-wizard ...` invocation;
31
+ Codex users get `codex exec --dangerously-bypass-approvals-and-sandbox`
32
+ with a prompt that reads the same SKILL.md content (the wizard skill itself
33
+ lives in one place; both runtimes are pointed at it). The Playwright
34
+ Telegram-setup flow is untouched and remains portable — the entry to it
35
+ now works for Codex.
36
+
37
+ **0. Codex-only init produces zero `.claude/` files (portability install PR 2 of 4).**
38
+ With v1.0.15 the `--framework` flag became expressible; this release makes
39
+ it actually mean something at install time. When `instar init` is run with
40
+ `--framework codex-cli` (or with `enabledFrameworks: ['codex-cli']` in a
41
+ pre-existing config), every `.claude/`-targeting installer is skipped:
42
+ `.claude/settings.json`, `.claude/scripts/health-watchdog.sh`,
43
+ `.claude/scripts/smart-fetch.py`, `.claude/scripts/git-sync-gate.sh`,
44
+ `.claude/skills/`, and the rich CLAUDE.md instruction document. Codex
45
+ agents continue to receive the canonical `.instar/AGENT.md`, the AGENTS.md
46
+ shadow, framework-neutral hooks under `.instar/hooks/instar/`, and the
47
+ serendipity-capture script (which already lives under `.instar/scripts/`).
48
+ Claude-only and dual-framework installs are byte-for-byte unchanged.
49
+
50
+ **1. `instar init --framework <name>` — choose your runtime at install time.**
51
+ A new flag on the `init` command lets a user pick which AI runtime the agent
52
+ should target: `claude-code` (default — historical behavior), `codex-cli`
53
+ (Codex-only install), or `both` (dual-runtime). The choice is written to
54
+ `.instar/config.json` as `enabledFrameworks`, which the migrator, sentinel,
55
+ and runtime spawn paths already read (added in v1.0.11). This is the first of
56
+ four PRs in the install/wizard portability upgrade — subsequent PRs gate the
57
+ `.claude/` writes on this choice, add the same flag to `setup`, and route the
58
+ wizard through the chosen runtime.
59
+
60
+ **2. Shadow capability mirror (closes the v1.0.0 portability audit).**
61
+ The migrator now mirrors capability-instruction sections from the just-patched
62
+ CLAUDE.md into AGENTS.md and GEMINI.md when those shadows exist. Codex/Gemini
63
+ agents had their canonical identity from v1.0.9 but were missing the
64
+ "here's what you can do" sections; this closes that gap. Section bodies are
65
+ sliced literally from CLAUDE.md — never duplicated in source — so the two
66
+ cannot drift. Claude-only installs are byte-for-byte unchanged.
67
+
68
+ (Note: the shadow capability mirror originally bumped to v1.0.14, but the
69
+ publish step hit an unrelated npm auth issue and did not actually reach the
70
+ registry. Both changes ship together as v1.0.15 once the auth side is
71
+ resolved.)
72
+
73
+ **5. Agent worktree convention — migrator + lifeline detector (Layers 3 + 4).**
74
+ Completes the agent worktree convention spec. On every agent update tick,
75
+ a new `migrateWorktreeConvention` step installs/refreshes
76
+ `<agent_home>/.bin/instar-worktree-create.sh` (a wrapper that `exec`s
77
+ into `instar worktree create` when available, with an inline fallback
78
+ for hosts that don't have the CLI on PATH yet), adds `.worktrees/` to
79
+ `<agent_home>/.gitignore` (defense-in-depth on top of the seed change),
80
+ and ensures `<agent_home>/.worktrees/` exists with mode `0700`. The
81
+ migrator silently skips agents whose home doesn't match the
82
+ `<instarHome>/agents/<name>/` shape (project-bound agents with bespoke
83
+ layouts are unaffected) and refuses to write when `<agent_home>/.bin`
84
+ is a symlink (defeats the /usr/local/bin clobber adversarial surface).
85
+ The Migration Parity Standard backfill for the seed CLAUDE.md
86
+ "Worktree Convention" section also runs here, so existing agents pick
87
+ up the convention documentation on update; the section is mirrored
88
+ through to AGENTS.md/GEMINI.md for Codex/Gemini agents via the
89
+ shadow-capability mirror. On every agent server boot, a new
90
+ `AgentWorktreeDetector` runs once: it resolves the canonical instar
91
+ repo deterministically (config `worktree.repoPath` or the default
92
+ fallback chain — never `INSTAR_REPO` env, because that can differ
93
+ between lifeline boot and interactive sessions), runs
94
+ `git worktree list --porcelain` with a 2-second timeout, skips the
95
+ main checkout and bare entries, and emits an AttentionItem-shaped
96
+ record for every misplaced worktree. Signal-only — never blocks, never
97
+ moves, never deletes. Dedupe is path-hash-based with the documented
98
+ `worktree-misplaced:sha256(path)` key. When no Telegram adapter is
99
+ configured the detector falls back to a JSONL append at
100
+ `<stateDir>/audit/worktree-detector.jsonl` (O_NOFOLLOW + fstat
101
+ owner/mode gate, 24h rolling-window dedupe).
102
+ Side-effects review:
103
+ `upgrades/side-effects/agent-worktree-convention-layer-3-4.md`.
104
+
105
+ **4. Agent worktree convention — `instar worktree create <branch>` (Layers 1 + 2 + 5).**
106
+ A new CLI subcommand creates a sandbox-safe git worktree of the shared instar
107
+ repo inside the agent's own home directory
108
+ (`~/.instar/agents/<agent>/.worktrees/<slug>/`). This is the one location the
109
+ macOS sandbox cannot revoke mid-session — agents who land worktrees in the
110
+ shared checkout (the historical default of `git worktree add`) have been
111
+ stranded mid-implementation multiple times this month with no in-session
112
+ recovery path. The new command refuses any other destination, validates the
113
+ target instar repo against a `remote.origin.url` allowlist, sets per-worktree
114
+ git identity (`Instar Agent (<name>)` / `<name>@instar.local` — signing
115
+ configuration deliberately untouched), and appends a JSONL audit ledger plus
116
+ a durable mirror under `<stateDir>/audit/worktree-ops.jsonl`. New agents
117
+ created with `instar init` get the convention in their seed CLAUDE.md,
118
+ MEMORY.md, and `.gitignore` (`.worktrees/` excluded so it never enters
119
+ git-sync). Existing agents inherit the convention through Layer 3 — the
120
+ `PostUpdateMigrator` step shipping in the next release. The lifeline
121
+ detector (Layer 4) ships in the same follow-up release. Spec:
122
+ `docs/specs/AGENT-WORKTREE-CONVENTION-SPEC.md` (approved 2026-05-17).
123
+ Side-effects review:
124
+ `upgrades/side-effects/agent-worktree-convention-layer-1-2-5.md`.
125
+
126
+ **6. Prompt Gate — auto-dismiss Claude Code's optional session-feedback survey, and reset detector state after every Telegram response.**
127
+ Two related fixes to the Prompt Gate detector and relay path, both
128
+ reported live in Echo's Telegram topic 9029 on 2026-05-20 with screenshots
129
+ showing the same survey re-relayed every 25–50 minutes across multiple
130
+ hours. (a) Claude Code's optional "How is Claude doing this session?"
131
+ widget is non-blocking — the session continues working whether or not
132
+ the operator answers — but the LLM-based detector was classifying it as
133
+ a `selection` prompt and re-relaying to Telegram on every 5-minute LLM
134
+ cooldown expiry. A new structural pattern in `PROMPT_PATTERNS` matches
135
+ the survey by both its question text and its canonical option row
136
+ (`1: Bad / 0: Dismiss`), tags the prompt with a new `autoDismissKey`
137
+ directive on `DetectedPrompt`, and the detected-prompt handler in
138
+ `server.ts` honours the directive: sends the dismiss key, resets
139
+ detector state, skips the classify/relay pipeline entirely. A second
140
+ pre-filter in `llmDetect()` short-circuits the survey before any LLM
141
+ tokens are spent. (b) When a user clicked a Telegram button,
142
+ `telegram.onPromptResponse` called `sessionManager.sendKey()` but did
143
+ not call `InputDetector.onInputSent()`, so the per-session 5-minute
144
+ LLM relay cooldown could silently swallow the next prompt in a
145
+ multi-question form. `onInputSent` now also clears
146
+ `llmRelayTimestamps`, and both `onPromptResponse` and
147
+ `onPromptTextResponse` invoke it after a successful send.
148
+
149
+ **3. Fleet-watchdog bind-failure probe.**
150
+ The watchdog now catches the failure mode where a lifeline reports healthy
151
+ to launchd but its server is locked out of its configured port (typically a
152
+ port collision with another agent). The probe issues an authenticated GET
153
+ /health for each loaded agent, compares the response's project field against
154
+ the agent's launchd-label-derived expected name, and routes any mismatch
155
+ through the existing crash-loop heal + peer-escalation pipeline from PR #245.
156
+ After 3 consecutive cycles (~15 min), the user gets a conflict-aware Telegram
157
+ alert naming both parties — closes the AI-Guy-stuck-behind-codex-server-smoke
158
+ class of failure that took 2 days to surface this week.
159
+
160
+ **4. Deployment lockdown — Layer 2 (release-tier gate).**
161
+ The publish workflow now consults `.instar/release-tier.json` before any
162
+ side-effectful step. The committed tier declares the active release line:
163
+ `patch` (routine maintenance, current default), `minor` (only publish when
164
+ package.json declares a minor leap over npm), `major` (Layer 5
165
+ multi-signature required; blocks until Layer 5 ships), or `hold` (all
166
+ publishes disabled). This closes the second of seven lockdown layers
167
+ designed after the 2026-05-19 v1.0.0 misalignment. Layer 1 (package.json
168
+ as version-truth) shipped in v1.0.8 and is what made every subsequent
169
+ 1.0.x release ship at its declared version; Layer 2 is the operator's
170
+ authoritative "no deploy" signal, expressed in a single committed file
171
+ the workflow physically honors. Resolution logic lives in
172
+ `scripts/resolve-release-tier.mjs` and is exercised by 20 unit tests
173
+ including the regression case that reproduces the 2026-05-19 incident
174
+ under `tier: hold`. The initial committed value is `tier: hold` — this
175
+ release itself does not auto-publish; flip to `patch` to resume routine
176
+ maintenance, or leave on hold during major-version work.
177
+
178
+ ## Evidence
179
+
180
+ Install-framework-choice reproduction prior: `instar init` had no way to
181
+ express "Codex-only." Even with all the v1.0.9–v1.0.13 portability plumbing,
182
+ the user had no UI for the choice; install always wrote Claude-Code-shaped
183
+ defaults.
184
+
185
+ Install-framework-choice after: `instar init my-agent --framework codex-cli`
186
+ writes `enabledFrameworks: ['codex-cli']` to config. Verified by five unit
187
+ tests pinning the resolver: default unflagged is `['claude-code']`, explicit
188
+ `claude-code` matches the default, `codex-cli` returns `['codex-cli']`, `both`
189
+ returns `['claude-code', 'codex-cli']`, and successive calls return fresh
190
+ arrays (no shared mutable state). Backward compatible: users who do not pass
191
+ the flag get identical behavior to today.
192
+
193
+ Shadow capability mirror reproduction prior: a Codex agent's AGENTS.md
194
+ contained identity but none of the capability instructions Claude's CLAUDE.md
195
+ has. Shadow capability mirror after: AGENTS.md and GEMINI.md gain the same
196
+ sections, sliced directly from CLAUDE.md so the content is identical.
197
+ Verified by six unit tests covering append, idempotent re-run, both shadows,
198
+ no-shadow no-op, no-CLAUDE.md no-op, identity preservation.
199
+
200
+ Prompt Gate survey-spam reproduction prior: Telegram topic 9029
201
+ screenshots dated 6:23 AM through 8:31 AM (2026-05-20, single tmux
202
+ session) show identical "Your agent needs you to choose" relay messages
203
+ re-posted at 6:23, 6:51, 7:16, 7:38, 8:31 — the cadence matches the
204
+ 5-minute LLM relay cooldown re-firing on the persistent survey text.
205
+ The relayed `summary` strings ("Framework is asking for user feedback
206
+ rating on Claude's performance this session", "System feedback question:
207
+ How is Claude doing this session?", "Claude Code feedback prompt asking
208
+ for session quality rating", "Claude Code is asking for session quality
209
+ feedback with options to rate or dismiss", "Session quality feedback
210
+ prompt asking user to rate how the agent is performing") all paraphrase
211
+ the same underlying Claude Code prompt and all carry the same
212
+ `1: Bad / 2: Fine / 3: Good` options — confirming the LLM-detection
213
+ path was the entry point and the fingerprint kept rotating because
214
+ surrounding terminal context (task counts, elapsed time) shifted between
215
+ captures. Prompt Gate survey-spam evidence after: new unit test
216
+ `InputDetector.pattern.sessionFeedbackSurvey` in
217
+ `tests/unit/PromptGate.test.ts` pins all three behaviours: (1) the
218
+ canonical survey block emits a `selection` prompt with
219
+ `autoDismissKey: '0'`; (2) the question text alone (without the
220
+ canonical option row) is NOT misclassified as a survey; (3) unrelated
221
+ numbered prompts are not labelled as the survey. A second unit test
222
+ `InputDetector.onInputSent` pins the `llmRelayTimestamps` clear-on-response
223
+ behaviour. Live verification cannot be exercised in dev because the
224
+ survey is fired by Claude Code itself on an opaque internal cadence;
225
+ post-deploy on Echo's host, the Telegram relay history for topic 9029
226
+ should show zero "Claude Code session-feedback survey" relays even as
227
+ agent sessions cross multi-hour durations.
228
+
229
+ Bind-failure probe evidence: today's AI Guy outage
230
+ (`~/Documents/Projects/ai-guy/.instar/logs/lifeline-launchd.log` records
231
+ "Suppressing duplicate server down notification (4163 suppressed this
232
+ outage)" — 2 days of suppressed alerts). After this PR, the same
233
+ configuration produces a BIND-FAIL log line on the first watchdog cycle and
234
+ a Telegram alert by cycle 3. `tests/unit/watchdog-bind-probe.test.ts`
235
+ (18 tests) + `tests/integration/watchdog-bind-fail-escalation.test.ts`
236
+ (2 tests) cover the probe's behaviour and the full bind-fail →
237
+ peer-escalation pipeline.
238
+
239
+ Lockdown Layer 2 evidence: reproduction of the 2026-05-19 incident
240
+ class — a no-deploy session with `package.json: 1.0.13` while npm is on
241
+ `0.28.121` would, under v1.0.8 alone, still publish (Layer 1 honors
242
+ package.json but has no concept of "hold"). Under Layer 2 with
243
+ `tier: hold` committed, the workflow's gate step writes the skip reason
244
+ to `$GITHUB_STEP_SUMMARY` and every downstream step (version bump,
245
+ NEXT.md rename, npm publish, version-bump commit) short-circuits. The
246
+ 20-test unit suite `tests/unit/resolve-release-tier.test.ts` covers each
247
+ of the four tiers across both passing and blocking version configurations
248
+ plus an explicit regression case mirroring the 2026-05-19 incident input
249
+ under `tier: hold`. The committed tier in this release is `hold`, so
250
+ this PR's own merge does not auto-publish — exactly the headline
251
+ guarantee the spec promises.
252
+
253
+ ## What to Tell Your User
254
+
255
+ - "You can now pick which AI runtime to use when you set up an Instar agent. Pass the framework flag to instar init for a Codex-only install. Default behavior is unchanged for everyone else. The framework flag is the first piece of a four-part install upgrade — the next three pieces add the same choice to setup, gate Claude-Code-only files behind the choice, and route the setup wizard through whichever runtime you pick."
256
+ - "Codex and Gemini agents now also get the same capability instructions Claude agents have — discover, private views, coherence gate, agent network. This closes the v1.0 cross-framework portability arc."
257
+ - "If two instar agents end up configured for the same port (configuration drift, leftover smoke-test fixtures, etc.), you'll now get a clear Telegram alert within about 15 minutes naming both agents involved. Previously the lifeline could spin silently for days while the supervisor suppressed its own server-down notifications as duplicates."
258
+ - "Prompt Gate is quieter now. It used to keep pinging you about Claude's optional session-feedback survey every twenty-something minutes — I just dismiss that one for you since it doesn't actually block anything. And when you answer a real Telegram prompt, the next prompt in a multi-step form will reach you immediately instead of getting swallowed by a five-minute cooldown."
259
+ - "Your instar agents have a new way to create git worktrees that the macOS sandbox can't kick them out of mid-session. There's a new instar worktree create command that places the worktree inside the agent's own home directory — the only place the sandbox can't revoke access to. Agents you create from now on will know about this convention out of the box. Agents already on your machine pick it up via the next update tick — the wrapper script is installed automatically, the worktree-convention section is backfilled into their CLAUDE.md, and the worktrees-directory is created with secure permissions, no operator action needed. On every agent startup, a lightweight detector also checks the shared instar repo for any worktrees that ended up in unsafe locations (created via raw git commands before this convention existed, for example) and surfaces them as a low-priority attention item so you can decide whether to relocate them with git worktree move."
260
+ - "I have a new way to physically pause all auto-publishing to npm — a small file at the top of the instar repo that says what release line we're on. If we're working on a major feature, I can set it to hold and the publisher will refuse to ship anything until we deliberately flip it back. This release ships with that switch already in the hold position, so no further auto-publishes happen until we choose to resume. This is the second of seven locks designed after the v1.0.0 deployment misalignment in May."
261
+
262
+ ## Summary of New Capabilities
263
+
264
+ | Capability | How to Use |
265
+ |-----------|-----------|
266
+ | `instar init --framework <name>` | Pass `claude-code` (default), `codex-cli`, or `both`. The choice is persisted to config and read by every downstream step. |
267
+ | Shadow capability mirror | Automatic on update. The migrator copies capability sections from CLAUDE.md into AGENTS.md and GEMINI.md when those shadows exist. |
268
+ | No-duplication source | The section bodies live in exactly one place (CLAUDE.md) and are sliced into shadows at migration time; Claude and non-Claude cannot drift. |
269
+ | Fleet watchdog bind-failure probe | Automatic. Catches port-collision / server-unreachable agents whose lifelines look healthy to launchd. Escalates via peer agent's `/attention` endpoint after 3 cycles. |
270
+ | Conflict-aware Telegram alerts | When the probe identifies the wrong-project case, the escalation summary names both contested parties. |
271
+ | `instar worktree create <branch>` | New CLI subcommand. Places the worktree at `~/.instar/agents/<agent>/.worktrees/<slug>/` — the only location the macOS sandbox cannot revoke mid-session. Resolves agent home from `INSTAR_AGENT_HOME` or CWD walk-up; validates the instar repo against `worktree.repoUrlAllowlist` in `~/.instar/config.json`; sets per-worktree git identity without touching signing config; symlinks `node_modules` by default (`--no-share-node-modules` opts out). |
272
+ | Sandbox-safe worktrees for new agents | `instar init` now seeds the convention into CLAUDE.md (top-level "Worktree Convention" section), MEMORY.md (Project Patterns entry), and `.gitignore` (`.worktrees/` excluded from git-sync). Existing agents pick this up via Layer 3 migrator in the next release. |
273
+ | Authoritative reference doc | `docs/self-knowledge/worktrees.md` — the "how do I create a worktree?" answer any future agent gets pointed at via the seed CLAUDE.md mention. |
274
+ | Existing agents pick up the worktree convention on update | Automatic on next `instar` update tick. `PostUpdateMigrator.migrateWorktreeConvention` installs `<agent_home>/.bin/instar-worktree-create.sh` (wrapper that `exec`s into `instar worktree create`), ensures the `.gitignore` entry, creates `<agent_home>/.worktrees/` with mode `0700`. Idempotent. Refuses if `<agent_home>/.bin` is a symlink. Silently skips agents whose home isn't under `~/.instar/agents/<name>/`. |
275
+ | Existing agents pick up the Worktree Convention CLAUDE.md section on update | Automatic on next update tick (Migration Parity Standard backfill in `migrateClaudeMd`). Section is mirrored through to AGENTS.md / GEMINI.md for Codex/Gemini agents via the shadow-capability mirror. |
276
+ | Auto-dismiss Claude Code's optional session-feedback survey | Automatic. The Prompt Gate recognises the survey by its canonical option row and sends `0` (Dismiss) without relaying. |
277
+ | Detector state reset after every Telegram prompt response | Automatic. `onPromptResponse`/`onPromptTextResponse` now invoke `InputDetector.onInputSent()`, which clears `emittedPrompts`, `stableCount`, `lastOutput`, `lastEmissionTime`, `llmRelayTimestamps`, and the `noPromptCache` (with a generation bump). |
278
+ | Lifeline detector for misplaced worktrees | Automatic on every agent server boot. Resolves the canonical instar repo deterministically (`worktree.repoPath` config or default fallback chain), runs `git worktree list --porcelain` with a 2-second timeout, skips the main checkout and bare entries, and emits an attention-queue-shaped record (or JSONL fallback at `<stateDir>/audit/worktree-detector.jsonl` when no Telegram adapter) for every misplaced worktree. Signal-only — never blocks, never moves, never deletes. Dedupe via `worktree-misplaced:sha256(path)`. |
279
+ | `.instar/release-tier.json` | Committed file. Set `tier` to `patch`, `minor`, `major`, or `hold` to declare the active release line. The publish workflow honors the tier before any side-effectful step. |
280
+ | Tier `hold` engaged on release | Initial value committed as `hold`. To resume routine maintenance, edit `tier` to `patch`. |
281
+ | Workflow gate (Layer 2) | Automatic. Reads `release-tier.json`, runs `scripts/resolve-release-tier.mjs`, short-circuits all publish steps on skip with a structured `$GITHUB_STEP_SUMMARY` entry. |
282
+
283
+ ## Deferred (Tracked Follow-ups)
284
+
285
+ - The install/wizard portability series is complete — Codex-only
286
+ `instar setup --framework codex-cli` runs end-to-end on this release.
287
+ Follow-up work tracked separately: a full smoke test of a fresh Codex-only
288
+ install on a clean machine, and any narrative-prose tweaks the wizard
289
+ skill should adopt to surface framework-specific paths in user-facing
290
+ output.
291
+ - Per-agent "muted" flag for the bind-probe (legitimate maintenance
292
+ windows) is deferred to the v3 Remediator's policy layer.
293
+ - Layers 3 + 4 of the agent worktree convention now ship in this release
294
+ alongside Layers 1+2+5. Earlier note about deferral was for the
295
+ previous PR boundary; both PRs land under v1.1.0. Wrapper refresh of
296
+ echo + bob `.bin/` (agent-home file edit, no instar source change) is
297
+ the remaining manual step.
298
+ - Detector first-run output: ~30 pre-existing worktrees outside agent
299
+ homes on echo's machine will surface as a one-time burst of low-priority
300
+ attention items on first agent restart after this release. Each is
301
+ individually deduped for 24h. Operator decides whether to drain them
302
+ or move them with `git -C <instar_repo> worktree move <old> <new>`.
303
+ - AttentionQueue wireup for the detector (currently it falls back to
304
+ JSONL because TelegramAdapter initializes later in startServer than
305
+ the detector runs) is tracked as a follow-up. The JSONL fallback is
306
+ the durable trail for v1; promoting to Telegram attention items just
307
+ changes the surfacing channel.
308
+ - (Earlier deferred text follows for historical context:) Layers 3 + 4 of the agent worktree convention will
309
+ ship in the next release. Until then, existing agents continue to use
310
+ the hand-rolled `instar-worktree-create.sh` already in their `.bin/`.
311
+ - The two-line wrapper refresh in echo + bob `.bin/` that wires the
312
+ existing bash helper to `exec` into `instar worktree create` is an
313
+ agent-home edit (no instar source change, no gate) and lands together
314
+ with the v1.1.0 push.
315
+ - Layers 3–7 of the deployment lockdown spec — branch isolation as a
316
+ workflow trigger restriction, NEXT.md `hold: true` frontmatter,
317
+ multi-signature for major bumps, loud-refusal hardening with PR
318
+ comments and Telegram mirror, and session-start memory injection —
319
+ ship as separate PRs after Layer 2 lands. Spec:
320
+ `docs/specs/deployment-lockdown.md` (to land alongside Layer 3 PR).