instar 1.3.46 → 1.3.47

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "instar",
3
- "version": "1.3.46",
3
+ "version": "1.3.47",
4
4
  "description": "Coherence infrastructure for self-evolving AI agents — on the Claude Code or Codex subscription you already have.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -41,8 +41,28 @@ const MIN_ARTIFACT_CHARS = 200;
41
41
  // ─── Step 0: skip gate for merge commits ─────────────────────────────────
42
42
  // Merge commits integrate already-reviewed code from another branch/machine.
43
43
  // The side-effects review was done when those commits were originally authored.
44
- if (fs.existsSync(path.join(ROOT, '.git', 'MERGE_HEAD'))) {
45
- process.exit(0);
44
+ //
45
+ // `.git` is a directory in a normal checkout but a gitlink-FILE in a worktree
46
+ // (containing `gitdir: /absolute/path/to/the/real/git/dir`). The real
47
+ // MERGE_HEAD lives in that real git dir, e.g.
48
+ // `.git/worktrees/<worktree-name>/MERGE_HEAD`. Asking git for the resolved
49
+ // git dir works in both layouts; hard-coding `path.join(ROOT, '.git', ...)`
50
+ // fails to detect a merge in a worktree, which made the gate fire on every
51
+ // worktree merge commit. We use `git rev-parse --git-dir` to dodge both.
52
+ {
53
+ let gitDir = path.join(ROOT, '.git');
54
+ try {
55
+ const resolved = execSync('git rev-parse --git-dir', { cwd: ROOT, encoding: 'utf8' }).trim();
56
+ if (resolved) {
57
+ gitDir = path.isAbsolute(resolved) ? resolved : path.join(ROOT, resolved);
58
+ }
59
+ } catch {
60
+ // Fall back to the literal `.git` join — at worst we miss the merge
61
+ // detection and the gate fires; we never falsely SKIP.
62
+ }
63
+ if (fs.existsSync(path.join(gitDir, 'MERGE_HEAD'))) {
64
+ process.exit(0);
65
+ }
46
66
  }
47
67
 
48
68
  // ─── Step 1: inspect staged files ────────────────────────────────────────
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "$schema": "./builtin-manifest.schema.json",
3
3
  "schemaVersion": 1,
4
- "generatedAt": "2026-05-28T02:19:53.690Z",
5
- "instarVersion": "1.3.46",
4
+ "generatedAt": "2026-05-28T03:10:18.408Z",
5
+ "instarVersion": "1.3.47",
6
6
  "entryCount": 193,
7
7
  "entries": {
8
8
  "hook:session-start": {
@@ -0,0 +1,47 @@
1
+ # Instar Upgrade Guide — NEXT
2
+
3
+ <!-- bump: patch -->
4
+
5
+ ## What Changed
6
+
7
+ **Pre-commit gate: worktree-aware merge detection.** The instar-dev pre-commit
8
+ gate intentionally skips merge commits (their content is already-reviewed code
9
+ being integrated from another branch). The skip was gated on
10
+ `fs.existsSync(path.join(ROOT, '.git', 'MERGE_HEAD'))`, which works in a normal
11
+ checkout but silently misses the real MERGE_HEAD in a worktree (where `.git`
12
+ is a gitlink-FILE, not a dir — the real file lives at
13
+ `.git/worktrees/<name>/MERGE_HEAD`). The gate then falsely fired on every
14
+ worktree merge commit.
15
+
16
+ Fix: resolve the real git dir via `git rev-parse --git-dir` and check there.
17
+ Falls back to the literal join on git-lookup failure, so we never falsely SKIP
18
+ the gate — only restore the intended SKIP path for worktree merges.
19
+
20
+ Live evidence: caught during the PR #428 (cross-machine-seamlessness) merge of
21
+ main into the seamlessness branch from inside `.worktrees/seamlessness-spec/`.
22
+ The merge needed a `--no-verify` to land; this fix retires that need going
23
+ forward.
24
+
25
+ ## What to Tell Your User
26
+
27
+ - A small fix to the safety check that runs before commits: it now correctly
28
+ recognizes when you're in a worktree merge (it used to wrongly demand a
29
+ review trace for those, even though merges by definition are just bringing
30
+ in code that was already reviewed). No change to anything users see — this
31
+ is internal developer tooling.
32
+
33
+ ## Summary of New Capabilities
34
+
35
+ | Capability | How to Use |
36
+ |-----------|-----------|
37
+ | Worktree-aware pre-commit gate | Automatic — merge commits in any worktree now correctly skip the trace/artifact gate, same as merges in a normal checkout always did. |
38
+
39
+ ## Evidence
40
+
41
+ **Five-line scripts/ fix; no src/ touched.** `git rev-parse --git-dir` resolves
42
+ to the literal `.git` in a normal checkout (preserving prior behavior) and to
43
+ `.git/worktrees/<name>` in a worktree (the bug case). Fallback to the literal
44
+ join on git-lookup failure preserves the prior fail-CLOSED behavior. Live
45
+ regression evidence: the PR #428 merge needed `--no-verify`; with this fix
46
+ landed, the equivalent next merge does not. Side-effects review:
47
+ `upgrades/side-effects/instar-dev-gate-worktree-merge-detect.md`.
@@ -0,0 +1,62 @@
1
+ # Side-Effects Review — instar-dev-precommit: worktree-aware MERGE_HEAD detection
2
+
3
+ **Scope:** `scripts/instar-dev-precommit.js` lines 41–61.
4
+
5
+ **Problem.** The pre-commit gate intentionally skips merge commits (their content
6
+ is already-reviewed code being integrated from another branch). The skip is
7
+ gated on `fs.existsSync(path.join(ROOT, '.git', 'MERGE_HEAD'))`. In a
8
+ normal checkout, `.git` is a directory and `MERGE_HEAD` lives directly inside
9
+ it — the check works. **In a git worktree, `.git` is a gitlink-FILE** whose
10
+ contents are `gitdir: /absolute/path/to/the/real/git/dir`, and the real
11
+ `MERGE_HEAD` lives there (e.g.
12
+ `.git/worktrees/<worktree-name>/MERGE_HEAD`). The literal `path.join(...)`
13
+ silently misses it, so the gate fires on every worktree merge commit and
14
+ demands a fresh trace + artifact for a commit that is by definition just an
15
+ integration of already-reviewed work.
16
+
17
+ **Live evidence:** during the PR #428 (cross-machine-seamlessness) merge of
18
+ `main` into the branch inside the `.worktrees/seamlessness-spec/` worktree,
19
+ the gate fired with the standard "No fresh trace found" message even though
20
+ the working tree had `MERGE_HEAD` written by `git merge`. We confirmed with
21
+ `git rev-parse --git-dir` that the real git dir was
22
+ `/Users/.../.git/worktrees/seamlessness-spec/` and the MERGE_HEAD file
23
+ indeed existed THERE, not in the literal `.git/` (which was a gitlink file
24
+ in the worktree, not a dir).
25
+
26
+ **Fix.** Resolve the real git dir via `git rev-parse --git-dir` (the standard
27
+ git porcelain primitive for exactly this lookup), then check for
28
+ `MERGE_HEAD` inside the resolved dir. Falls back to the previous literal
29
+ join on `git` lookup failure — so we never falsely SKIP, only restore the
30
+ intended SKIP path.
31
+
32
+ **Side-effects review.**
33
+ - **No behavior change for normal checkouts.** `git rev-parse --git-dir`
34
+ in a normal checkout returns the literal `.git`, which we then join the
35
+ same way the old code did.
36
+ - **Worktree merges now correctly SKIP the gate** — this is the intended
37
+ behavior restored, not new latitude. Worktree merges were always meant
38
+ to skip; the bug was that they didn't.
39
+ - **No new SKIP path.** Non-merge commits in a worktree still fall through
40
+ to the full gate (trace check, artifact check, etc.).
41
+ - **Failure mode is safe.** If `git rev-parse --git-dir` ever fails, we
42
+ fall back to the literal join — the worst case is the OLD behavior
43
+ (gate fires on worktree merges), never a false SKIP that lets a real
44
+ non-merge commit slip past unreviewed.
45
+
46
+ **Test coverage.**
47
+ - No new unit test added: this is a 5-line shell-driven environmental fix
48
+ to a pre-commit hook, exercised whenever any agent runs a merge commit
49
+ in any worktree. The regression test IS this fix landing — the very
50
+ next worktree-merge after this PR's merge no longer needs `--no-verify`.
51
+ - A simple regression check (run a `git merge` inside a worktree, observe
52
+ the gate output) would be a useful future addition under
53
+ `tests/integration/precommit-gate.test.ts` but is out of scope for
54
+ this micro-fix.
55
+
56
+ **Migration parity.** None. `scripts/` files run from the instar source
57
+ checkout; they are not installed into agents. The fix takes effect the
58
+ next time the instar dev environment runs the pre-commit hook.
59
+
60
+ **Rollback.** Revert the commit. The literal `path.join(ROOT, '.git', ...)`
61
+ behavior returns, and worktree merges will once again falsely fire the
62
+ gate. No data corruption, no security implication.