@bookedsolid/rea 0.6.0 → 0.6.1

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.
@@ -15,6 +15,39 @@ set -uo pipefail
15
15
  # ── 1. Read ALL stdin immediately ─────────────────────────────────────────────
16
16
  INPUT=$(cat)
17
17
 
18
+ # ── 1a. Cross-repo guard (must come FIRST — before any rea-scoped check) ──────
19
+ # Mirror of push-review-gate.sh. When CLAUDE_PROJECT_DIR points to rea but
20
+ # the current git checkout is a DIFFERENT repository (distinct object DB),
21
+ # exit 0 — rea's gate does not own that commit.
22
+ #
23
+ # Identity via `--git-common-dir` so linked worktrees of rea
24
+ # (`git worktree add`, `.claude/worktrees/*`) are correctly recognized as
25
+ # the SAME repo and kept under the gate — they share object DB, refs, and
26
+ # HEAD history with rea's main checkout. Path-prefix fallback fires
27
+ # when either side is not a git checkout. Must run BEFORE the jq and HALT
28
+ # checks: a missing-jq or HALT-frozen rea must not block commits in other
29
+ # repos that merely share a Claude Code session with rea. Fixed in 0.6.1.
30
+ REA_ROOT="${CLAUDE_PROJECT_DIR:-$(pwd)}"
31
+ if [[ -n "${CLAUDE_PROJECT_DIR:-}" ]]; then
32
+ CWD_REAL=$(pwd -P 2>/dev/null || pwd)
33
+ if REA_REAL=$(cd "$REA_ROOT" 2>/dev/null && pwd -P 2>/dev/null); then
34
+ CWD_COMMON=$(git -C "$CWD_REAL" rev-parse --path-format=absolute --git-common-dir 2>/dev/null || true)
35
+ REA_COMMON=$(git -C "$REA_REAL" rev-parse --path-format=absolute --git-common-dir 2>/dev/null || true)
36
+ if [[ -n "$CWD_COMMON" && -n "$REA_COMMON" ]]; then
37
+ CWD_COMMON_REAL=$(cd "$CWD_COMMON" 2>/dev/null && pwd -P 2>/dev/null || echo "$CWD_COMMON")
38
+ REA_COMMON_REAL=$(cd "$REA_COMMON" 2>/dev/null && pwd -P 2>/dev/null || echo "$REA_COMMON")
39
+ if [[ "$CWD_COMMON_REAL" != "$REA_COMMON_REAL" ]]; then
40
+ exit 0
41
+ fi
42
+ else
43
+ case "$CWD_REAL/" in
44
+ "$REA_REAL"/*|"$REA_REAL"/) : ;; # inside rea — run the gate
45
+ *) exit 0 ;; # outside rea — not our gate
46
+ esac
47
+ fi
48
+ fi
49
+ fi
50
+
18
51
  # ── 2. Dependency check ──────────────────────────────────────────────────────
19
52
  if ! command -v jq >/dev/null 2>&1; then
20
53
  printf 'REA ERROR: jq is required but not installed.\n' >&2
@@ -23,7 +56,6 @@ if ! command -v jq >/dev/null 2>&1; then
23
56
  fi
24
57
 
25
58
  # ── 3. HALT check ────────────────────────────────────────────────────────────
26
- REA_ROOT="${CLAUDE_PROJECT_DIR:-$(pwd)}"
27
59
  HALT_FILE="${REA_ROOT}/.rea/HALT"
28
60
  if [ -f "$HALT_FILE" ]; then
29
61
  printf 'REA HALT: %s\nAll agent operations suspended. Run: rea unfreeze\n' \
@@ -37,6 +37,63 @@ set -uo pipefail
37
37
  # ── 1. Read ALL stdin immediately ─────────────────────────────────────────────
38
38
  INPUT=$(cat)
39
39
 
40
+ # ── 1a. Cross-repo guard (must come FIRST — before any rea-scoped check) ──────
41
+ # When CLAUDE_PROJECT_DIR points to the rea repo (the Claude Code session's
42
+ # project directory) but the current working directory is a DIFFERENT
43
+ # repository, this hook is firing for someone else's push. rea's gate only
44
+ # owns pushes from within rea itself — exit 0 so the foreign repo's
45
+ # `git push` proceeds unblocked.
46
+ #
47
+ # MUST run before the jq check and HALT check. Those are rea-scoped concerns:
48
+ # a missing-jq or HALT-frozen state in rea must not block pushes in OTHER
49
+ # repos that merely share a Claude Code session with rea. Fixing that
50
+ # governance-scope leak is half the point of this guard.
51
+ #
52
+ # Also: without this guard, ref-resolution inside `resolve_argv_refspecs`
53
+ # runs `git rev-parse` inside REA_ROOT for refs that only exist in the
54
+ # foreign repo, which hard-fails with "could not resolve source ref". That
55
+ # failure lands BEFORE REA_SKIP_PUSH_REVIEW / REA_SKIP_CODEX_REVIEW can be
56
+ # checked, so consumers are left with no documented way out. Discovered
57
+ # during the 0.6.0 cross-repo consumer upgrade; fixed in 0.6.1.
58
+ #
59
+ # Repo-identity comparison via shared `--git-common-dir`, NOT path-prefix or
60
+ # `--show-toplevel`. Why common-dir: a linked worktree created by
61
+ # `git worktree add` has a different toplevel (different checkout path) but
62
+ # the SAME repository — shared object DB, shared refs, shared HEAD history.
63
+ # Any `.claude/worktrees/*` checkout of rea IS rea and must run the gate.
64
+ # `--show-toplevel` would falsely flag those worktrees as "foreign" and
65
+ # bypass HALT plus every other gate (Codex R3 finding, 0.6.1).
66
+ #
67
+ # `--path-format=absolute` (Git ≥ 2.31, March 2021) normalizes the common
68
+ # dir so the same repo's common-dir is equal regardless of which worktree
69
+ # asked. Engines pin Node ≥20 which ships with a recent-enough Git for dev.
70
+ #
71
+ # Falls back to path-prefix when either cwd or REA_ROOT is not a git
72
+ # checkout (the rea 0.5.1 non-git escape-hatch scenario).
73
+ REA_ROOT="${CLAUDE_PROJECT_DIR:-$(pwd)}"
74
+ if [[ -n "${CLAUDE_PROJECT_DIR:-}" ]]; then
75
+ CWD_REAL=$(pwd -P 2>/dev/null || pwd)
76
+ if REA_REAL=$(cd "$REA_ROOT" 2>/dev/null && pwd -P 2>/dev/null); then
77
+ CWD_COMMON=$(git -C "$CWD_REAL" rev-parse --path-format=absolute --git-common-dir 2>/dev/null || true)
78
+ REA_COMMON=$(git -C "$REA_REAL" rev-parse --path-format=absolute --git-common-dir 2>/dev/null || true)
79
+ if [[ -n "$CWD_COMMON" && -n "$REA_COMMON" ]]; then
80
+ # Both sides are git checkouts. Realpath'd common-dirs match IFF they
81
+ # point at the same underlying repository (main or linked worktree).
82
+ CWD_COMMON_REAL=$(cd "$CWD_COMMON" 2>/dev/null && pwd -P 2>/dev/null || echo "$CWD_COMMON")
83
+ REA_COMMON_REAL=$(cd "$REA_COMMON" 2>/dev/null && pwd -P 2>/dev/null || echo "$REA_COMMON")
84
+ if [[ "$CWD_COMMON_REAL" != "$REA_COMMON_REAL" ]]; then
85
+ exit 0
86
+ fi
87
+ else
88
+ # Non-git-repo path: literal quoted expansions — no glob expansion.
89
+ case "$CWD_REAL/" in
90
+ "$REA_REAL"/*|"$REA_REAL"/) : ;; # inside rea — run the gate
91
+ *) exit 0 ;; # outside rea — not our gate
92
+ esac
93
+ fi
94
+ fi
95
+ fi
96
+
40
97
  # ── 2. Dependency check ──────────────────────────────────────────────────────
41
98
  if ! command -v jq >/dev/null 2>&1; then
42
99
  printf 'REA ERROR: jq is required but not installed.\n' >&2
@@ -45,7 +102,6 @@ if ! command -v jq >/dev/null 2>&1; then
45
102
  fi
46
103
 
47
104
  # ── 3. HALT check ────────────────────────────────────────────────────────────
48
- REA_ROOT="${CLAUDE_PROJECT_DIR:-$(pwd)}"
49
105
  HALT_FILE="${REA_ROOT}/.rea/HALT"
50
106
  if [ -f "$HALT_FILE" ]; then
51
107
  printf 'REA HALT: %s\nAll agent operations suspended. Run: rea unfreeze\n' \
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bookedsolid/rea",
3
- "version": "0.6.0",
3
+ "version": "0.6.1",
4
4
  "description": "Agentic governance layer for Claude Code — policy enforcement, hook-based safety gates, audit logging, and Codex-integrated adversarial review for AI-assisted projects",
5
5
  "license": "MIT",
6
6
  "author": "Booked Solid Technology <oss@bookedsolid.tech> (https://bookedsolid.tech)",