carson 3.23.3 → 3.27.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 25b3eaecbcb43c5438f2e39e64b834ff0a9941b6d02694bfa616e039ada44013
4
- data.tar.gz: c8f3c8632d7f8b46215c163d712ea7470e611f2aed519ffa83e675d96dcccbc8
3
+ metadata.gz: e71c18b520bc6869f6f22cff8593d59b7e4d38a58b7c9f7648d75252fdd8691c
4
+ data.tar.gz: 468b1b132620b3844ccd5df01907c149ddce5bf987bf2aa4fee6a17f3301cea7
5
5
  SHA512:
6
- metadata.gz: 0536db61fa21a38624a40f7385ebb9e488870dd7f855308cef550213aeddc99e388d746be0b8d9d4392f383a171ddecfbc11728bd92ccd4efec15d58cad9b088
7
- data.tar.gz: 1787a26c1aaf8c548ca0c8d31fbc5c6a8da8a7d0ec86b2064b4dd8cb43e3b430384b0fb0b3b06418e73733ea03fce78a0a5462366da345c53aa99d986791114f
6
+ metadata.gz: 6a3842a3fdb48ede44c4def41b1533ae43f68b5267a8d1280f1cdf7685b161406f58365002e20b34bb4dfa5a9fc2e788a970cf6c406dd877087844197114148d
7
+ data.tar.gz: 8ee70fb5f5f06bfc417ae39634f9277a07ca5aaa867a57b14960987a12cbe66a44ea193fc167831645025cd573d599f8cf385e8849c2a40d94ff0c6c43eb5967
data/API.md CHANGED
@@ -25,13 +25,17 @@ carson <command> [subcommand] [arguments]
25
25
  | Command | Purpose |
26
26
  |---|---|
27
27
  | `carson audit` | Evaluate governance status and generate report output. |
28
- | `carson deliver [--commit MESSAGE]` | Start autonomous branch delivery for the current checkout. Plain `deliver` transports existing commits only; `--commit` creates one all-dirty delivery commit first, then pushes, creates or refreshes the PR, records delivery state, and returns immediately. |
28
+ | `carson deliver [--commit MESSAGE]` | Run Carson-owned branch delivery for the current checkout. Plain `deliver` transports existing commits only; `--commit` creates one all-dirty delivery commit first, then Carson pushes, creates or refreshes the PR, waits for merge readiness, merges when clear, and syncs local `main`. |
29
+ | `carson recover --check NAME [--json]` | Run the exceptional governed recovery path when one governance-owned required check is already red on the default branch. Carson proves the named baseline failure, keeps every other gate intact, merges through the recovery path, and records a machine-readable audit event. |
29
30
  | `carson sync` | Fast-forward local `main` from configured remote when tree is clean. |
30
31
  | `carson prune` | Remove stale local branches whose upstream refs no longer exist. |
32
+ | `carson housekeep [--json] [--dry-run]` | Attempt to sync the current repo, then reap dead worktrees, reconcile integrated delivery worktree records from the ledger, and prune stale branches. Safe cleanup still runs when sync is blocked. |
31
33
  | `carson template check` | Detect drift between managed templates and host `.github/*` files. |
32
34
  | `carson template apply` | Write canonical managed template content into host `.github/*` files. |
33
- | `carson status [--json]` | Show repository delivery state. Default output is Markdown/text; `--json` is the explicit machine contract. |
35
+ | `carson status [--json]` | Show repository delivery state, including the next queued delivery and blocked-delivery summaries. Default output is Markdown/text; `--json` is the explicit machine contract. |
36
+ | `carson abandon <pr_number\|pr_url\|branch> [--json]` | Close abandoned delivery work and clean up its PR, worktree, and branch when safe. |
34
37
  | `carson worktree create <name>` | Create an isolated worktree and branch for a new stream of work. |
38
+ | `carson worktree list [--json]` | Show every registered worktree with PR state and Carson's cleanup recommendation. |
35
39
  | `carson worktree remove <path_or_name>` | Remove a worktree safely and clean up its branch when allowed. |
36
40
 
37
41
  ### Batch commands (Layer 2)
@@ -46,7 +50,9 @@ All batch commands operate across every governed repository registered in `gover
46
50
  | `carson prune --all` | Remove stale branches across all governed repos. |
47
51
  | `carson status --all [--json]` | Portfolio-wide delivery overview per governed repository. |
48
52
  | `carson template check --all` | Read-only template drift detection across all governed repos. |
49
- | `carson housekeep --all` | Sync, reap dead worktrees, and prune across all governed repos. |
53
+ | `carson housekeep --all [--loop SECONDS]` | Attempt sync, then reap dead worktrees, reconcile integrated delivery worktree records from the ledger, and prune across all governed repos. Safe cleanup still runs when sync is blocked. |
54
+
55
+ `--loop SECONDS` runs the housekeep cycle continuously, sleeping SECONDS between cycles. It requires `--all`, accepts only positive integers, and exits cleanly on `Ctrl-C` with a cycle count summary.
50
56
 
51
57
  ### Govern commands
52
58
 
@@ -58,6 +64,12 @@ All batch commands operate across every governed repository registered in `gover
58
64
 
59
65
  Governed integration is fixed to `squash`. Non-squash `govern.merge.method` values are rejected by config validation.
60
66
 
67
+ After a live integration attempt, govern reports the actual outcome. Failed merges stay held at gate instead of being reported as integrated.
68
+
69
+ After CI and review pass, Carson still checks GitHub mergeability. Conflicting PRs stay held at gate with an explicit merge-conflict summary, while `BEHIND` PRs remain eligible under Carson's current squash policy.
70
+
71
+ After a successful govern merge, Carson runs the same cleanup path as `housekeep`: sync, reap safe worktrees, then prune.
72
+
61
73
  ### Review commands
62
74
 
63
75
  | Command | Purpose |
@@ -79,6 +91,15 @@ Governed integration is fixed to `squash`. Non-squash `govern.merge.method` valu
79
91
 
80
92
  Automation and CI integrations should treat exit `2` as an expected policy failure signal.
81
93
 
94
+ ## Governance guard contract
95
+
96
+ In a Carson-governed repository:
97
+ - Raw `git worktree add` and `git worktree remove` are blocked. Use `carson worktree create` and `carson worktree remove`.
98
+ - Raw `git pull --rebase` is blocked. Use `carson sync`.
99
+ - Raw `gh pr create` and `gh pr merge` are blocked. Use `carson deliver`.
100
+ - Bootstrap repair for a baseline-red governance check uses `carson recover --check NAME`, not raw `gh api`.
101
+ - On the governed main working tree, raw `git add` and `git commit` are blocked until a Carson worktree exists for the task.
102
+
82
103
  ## Repository boundary contract
83
104
 
84
105
  Blocked Carson artefacts in host repositories:
@@ -107,7 +128,6 @@ Environment overrides:
107
128
  - `CARSON_REVIEW_SWEEP_STATES`
108
129
  - `CARSON_WORKFLOW_STYLE`
109
130
  - `CARSON_GOVERN_REPOS`
110
- - `CARSON_GOVERN_AUTHORITY`
111
131
  - `CARSON_GOVERN_AGENT_PROVIDER`
112
132
  - `CARSON_GOVERN_CHECK_WAIT`
113
133
 
@@ -117,7 +137,6 @@ Environment overrides:
117
137
  {
118
138
  "govern": {
119
139
  "repos": ["~/Dev/project-a", "~/Dev/project-b"],
120
- "authority": "remote",
121
140
  "agent": {
122
141
  "provider": "auto",
123
142
  "codex": {},
@@ -127,19 +146,18 @@ Environment overrides:
127
146
  "merge": {
128
147
  "method": "squash"
129
148
  },
130
- "state_path": "~/.carson/state.sqlite3"
149
+ "state_path": "~/.carson/state.json"
131
150
  }
132
151
  }
133
152
  ```
134
153
 
135
154
  `govern` semantics:
136
155
  - `repos`: list of local repo paths to govern (empty = current repo only).
137
- - `authority`: `"remote"` (default) or `"local"`.
138
156
  - `agent.provider`: `"auto"`, `"codex"`, or `"claude"`.
139
157
  - `agent.codex` / `agent.claude`: provider-specific options (reserved).
140
158
  - `check_wait`: seconds to wait for CI checks before classifying (default: `30`).
141
159
  - `merge.method`: `"squash"` only in governed mode.
142
- - `state_path`: SQLite ledger path for active deliveries and revisions.
160
+ - `state_path`: JSON file path for active deliveries and revisions.
143
161
 
144
162
  `template` schema:
145
163
 
data/MANUAL.md CHANGED
@@ -117,8 +117,8 @@ These strategies are the audit lens for Carson. If behaviour departs from them,
117
117
  ### Git Strategist
118
118
 
119
119
  - **Worktree-first discipline** — substantive work happens in worktrees, never on the main working tree. This keeps concurrent agent work isolated and makes cleanup explicit.
120
- - **Deterministic base selection** — new work starts from the repo's chosen integration authority, not from whatever branch state happens to be lying around.
121
- - **Single landing path per authority** — in `remote`, completed work rejoins through remote `main`; in `local`, completed work rejoins through local `main` and then pushes `main` as backup.
120
+ - **Deterministic base selection** — new work starts from a synced remote baseline, not from whatever branch state happens to be lying around.
121
+ - **Single landing path** — completed work rejoins through remote `main` via PR-based delivery.
122
122
  - **Content-aware merge detection** — Carson proves whether a branch's content is already on `main` without relying on commit SHAs, so squash and rebase merges are handled correctly.
123
123
  - **Worktree-aware delivery** — Carson lands work without assuming `main` can be checked out in the active worktree, and cleanup is deferred to the correct context.
124
124
  - **Exact post-merge guidance** — after a successful landing, Carson tells the caller the next clean-up command instead of leaving the lifecycle half-finished.
@@ -127,7 +127,8 @@ These strategies are the audit lens for Carson. If behaviour departs from them,
127
127
 
128
128
  - **Outsider boundary** — Carson governs repositories without writing Carson-specific config, scripts, or runtime payloads into them.
129
129
  - **Command ownership** — in governed repositories, Carson owns worktree and delivery operations so agents do not mix raw git flows with governed ones.
130
- - **Authority enforcement** — every governed repo has one integration authority at a time. That authority determines how work starts and how it returns to shared truth.
130
+ - **Main-tree protection** — on the governed main working tree, Carson blocks `git add` and `git commit` until the agent creates a Carson worktree for the task.
131
+ - **Governed delivery** — completed work returns to shared truth through remote `main` via PR-based delivery. Carson owns the landing path.
131
132
  - **Active review gating** — when the repo uses PR-based delivery, review findings must be acknowledged before merge. Feedback is never silently buried.
132
133
  - **Portfolio triage** — `carson govern` applies the same discipline across multiple repositories: classify, merge, dispatch, or escalate.
133
134
  - **Template propagation** — Carson treats canonical policy files as managed infrastructure and keeps them consistent across repos.
@@ -145,47 +146,76 @@ These strategies are the audit lens for Carson. If behaviour departs from them,
145
146
 
146
147
  The core workflow for coding agents using Carson. One command per step, full lifecycle.
147
148
 
148
- **1. Create a worktree** — Carson starts new work from the repo's chosen integration authority rather than from the caller's current HEAD. When that authority requires sync, Carson checks it before branching:
149
+ **1. Create a worktree** — Carson syncs remote `main` and starts new work from that baseline rather than from the caller's current HEAD:
149
150
 
150
151
  ```bash
151
152
  carson worktree create my-feature
152
153
  cd /path/to/.claude/worktrees/my-feature
153
154
  ```
154
155
 
156
+ On the governed main working tree, Carson blocks raw `git add` / `git commit` and blocks raw `git worktree add/remove`, raw `git pull --rebase`, and raw `gh pr create/merge`. Use `carson worktree create`, `carson sync`, and `carson deliver` instead.
157
+
155
158
  **2. Work** — make changes, test them, and either commit normally or let Carson create the delivery commit.
156
159
 
157
- **3. Hand the branch to Carson** — `deliver` is the asynchronous branch handoff. In remote authority Carson pushes the branch, creates or refreshes the PR, records delivery state, and returns immediately. Plain `carson deliver` transports existing commits and blocks if the worktree is dirty. `carson deliver --commit "..."` creates one all-dirty agent-authored commit first, then continues the same delivery flow. Managed template drift is still corrected in a separate Carson-managed commit before push.
160
+ **3. Hand the branch to Carson** — `deliver` is the synchronous happy path. Carson pushes the branch, creates or refreshes the PR, waits for the CI and review signals it can observe, merges when the path is clear, and syncs local `main`. Plain `carson deliver` transports existing commits and blocks if the worktree is dirty. `carson deliver --commit "..."` creates one all-dirty agent-authored commit first, then continues the same delivery flow. Managed template drift is still corrected in a separate Carson-managed commit before push.
158
161
 
159
162
  ```bash
160
163
  carson deliver
161
164
  # or, if the worktree is still dirty:
162
165
  carson deliver --commit "fix: describe this delivery"
163
- # Output: PR #N, Delivery: queued|gated
164
- # Next: carson status
166
+ # Output: merged into main, or held at gate with the next command
165
167
  ```
166
168
 
167
- **4. Monitor and advance** — `status` is the delivery surface. It shows the current branch plus active deliveries for the repository. Keep `govern` running to advance queued deliveries and revisions across governed repositories:
169
+ **4. Inspect or wait when needed** — when `deliver` cannot merge immediately, `status` shows the current branch, the next queued delivery, and any blocked-delivery summaries for the repository. Keep `govern` running when you want unattended portfolio reassessment and revision dispatch across governed repositories:
168
170
 
169
171
  ```bash
170
172
  carson status
171
173
  carson govern --loop 300
172
174
  ```
173
175
 
174
- **5. Clean up landed work** — once the delivery is integrated, use Carson cleanup commands from the main worktree:
176
+ ### Recover a baseline-red governance check
177
+
178
+ When a governance-owned required check is already red on the default branch, the PR that repairs it can deadlock behind that same gate. Use the explicit recovery path instead of reaching for raw `gh api`:
179
+
180
+ ```bash
181
+ carson recover --check "Carson governance"
182
+ ```
183
+
184
+ Recovery is narrow. Carson proves that the named check is red on the default branch, verifies that the current branch is repairing the governance surface, requires every other required check and the review gate to pass, then records a machine-readable audit event before reporting success.
185
+
186
+ If Carson refuses recovery, the message explains the exact missing proof or remaining gate and tells you what to do next.
187
+
188
+ **5. Clean up landed work** — once the delivery is integrated, use Carson cleanup commands from the main worktree. `worktree list` shows every registered worktree with PR state, absorbed-into-main detection, and Carson's cleanup recommendation:
175
189
 
176
190
  ```bash
177
191
  cd /path/to/repo
178
- carson worktree remove my-feature
179
- carson prune
192
+ carson worktree list
193
+ carson housekeep
180
194
  ```
181
195
 
196
+ `housekeep` still performs safe reaping and branch pruning when `sync` cannot complete. A blocked sync no longer prevents cleanup work that has its own safety evidence.
197
+
198
+ `housekeep` also reconciles integrated delivery worktree records from the ledger. If the recorded worktree is already gone, Carson clears the stale ledger path. If the worktree still points at the integrated head and is safe to remove, Carson reaps it and clears the ledger path in the same pass.
199
+
200
+ When you need to abandon a stale branch or PR instead of landing it:
201
+
202
+ ```bash
203
+ carson abandon 291
204
+ # or:
205
+ carson abandon https://github.com/owner/repo/pull/291
206
+ # or:
207
+ carson abandon feature/stale-work
208
+ ```
209
+
210
+ `abandon` closes the PR when it is still open, removes the matching worktree when safe, deletes the local and remote branch refs when allowed, and marks the delivery as failed in Carson's ledger.
211
+
182
212
  **Safety guards** — `worktree remove` blocks when:
183
213
  - Shell CWD is inside the worktree (prevents session crash).
184
214
  - Branch has unpushed commits with content that differs from main (prevents data loss).
185
215
 
186
216
  After squash or rebase merge, the content matches main — removal proceeds without `--force`.
187
217
 
188
- **Stale worktree recovery** — if a worktree directory is destroyed externally (for example by a raw GitHub merge/delete flow), `worktree remove` and `prune` handle the stale entry gracefully: they clean up the git registration and delete the branch without error. Use Carson's `deliver` + `govern` flow instead of raw `gh pr merge --delete-branch` so the worktree directory stays intact for orderly cleanup.
218
+ **Stale worktree recovery** — if a worktree directory is destroyed externally (for example by a raw GitHub merge/delete flow), `worktree remove`, `worktree list`, `housekeep`, and `prune` handle the stale entry gracefully: they clean up the git registration and delete the branch without error when Carson has enough evidence. Use Carson's delivery and cleanup commands instead of raw `gh pr merge --delete-branch` so the worktree directory stays intact for orderly cleanup.
189
219
 
190
220
  ### Carson vs Claude Code EnterWorktree
191
221
 
@@ -264,10 +294,13 @@ carson audit --all # governance audit across all repos
264
294
  carson prune --all # remove stale branches across all repos
265
295
  carson template check --all # detect template drift across all repos
266
296
  carson housekeep --all # full maintenance cycle across all repos
297
+ carson housekeep --all --loop 300 # housekeep every 5 minutes
267
298
  ```
268
299
 
269
300
  `refresh --all` checks each repo for safety before operating: repos with active worktrees or uncommitted changes are skipped with clear reasons. Other batch commands attempt each repo and report failures without stopping.
270
301
 
302
+ `housekeep --all --loop SECONDS` runs the full housekeep cycle continuously, sleeping SECONDS between passes. It requires `--all`, accepts only positive integers, and exits cleanly on `Ctrl-C` with a cycle count summary.
303
+
271
304
  **Periodic maintenance:**
272
305
 
273
306
  ```bash
@@ -292,6 +325,12 @@ Each cycle runs independently: if one cycle fails (network error, GitHub API tim
292
325
 
293
326
  `carson govern` dispatches coding agents (Codex or Claude) when an active delivery is blocked by CI, review, or policy feedback. The agent receives the failure context and attempts a revision. If the agent succeeds, the delivery re-enters the governance pipeline. If it fails repeatedly or times out, the delivery is escalated for human attention.
294
327
 
328
+ After a live merge attempt, govern reports the actual outcome. Failed merges stay held at gate instead of being reported as integrated.
329
+
330
+ After CI and review pass, Carson still checks GitHub mergeability. Conflicting PRs stay held at gate with an explicit merge-conflict summary, while `BEHIND` PRs remain eligible under Carson's current squash policy.
331
+
332
+ After a successful govern merge, Carson runs the same cleanup path as `carson housekeep`: sync, reap safe worktrees, then prune.
333
+
295
334
  The agent provider is configurable via `govern.agent.provider` (`auto`, `codex`, or `claude`). In `auto` mode, Carson selects the first available provider.
296
335
 
297
336
  ## Governed Integration Policy
@@ -375,15 +414,6 @@ Whether reviewer findings require acknowledgement.
375
414
 
376
415
  Change: `CARSON_REVIEW_DISPOSITION`.
377
416
 
378
- #### Delivery authority
379
-
380
- Where completed work rejoins shared truth.
381
-
382
- - **`remote`** (default) — the PR lands on remote `main`.
383
- - **`local`** — Carson integrates through local `main`, then pushes `main` as backup.
384
-
385
- Change: `govern.authority` in config.
386
-
387
417
  #### Output verbosity
388
418
 
389
419
  How much Carson prints.
@@ -411,7 +441,6 @@ Common environment overrides:
411
441
  | `CARSON_REVIEW_SWEEP_WINDOW_DAYS` | Lookback window for review sweep. |
412
442
  | `CARSON_REVIEW_SWEEP_STATES` | PR states to include in sweep. |
413
443
  | `CARSON_REVIEW_BOT_USERNAMES` | Comma-separated bot usernames to ignore in review gate and sweep. |
414
- | `CARSON_GOVERN_AUTHORITY` | Override delivery authority (`remote` or `local`). |
415
444
  | `CARSON_WORKFLOW_STYLE` | Workflow style override (`branch` or `trunk`). |
416
445
  | `CARSON_RUBY_INDENTATION` | Ruby indentation policy (`tabs`, `spaces`, or `either`). |
417
446
 
data/README.md CHANGED
@@ -32,20 +32,10 @@ Carson lives on your workstation and in CI, never inside the repositories it gov
32
32
 
33
33
  The outsider boundary still matters: Carson governs repositories without becoming a runtime dependency inside them.
34
34
 
35
- ## Two Authorities
36
-
37
- Each governed repo chooses one integration authority.
38
-
39
- **Remote** — remote `main` is the integration authority. Agents still work in local worktrees, but completed work rejoins through remote `main`.
40
-
41
- **Local** — local `main` is the integration authority. Agents still work in local worktrees, but completed work rejoins through local `main`, then `main` is pushed to the remote as backup.
42
-
43
- This is about where completed work rejoins shared truth, not about team size. Both authorities use worktrees. The authority changes how work lands, not whether Carson is needed.
44
-
45
35
  ## Principles
46
36
 
47
37
  - **Worktree-first** — substantive work happens in worktrees, not on `main`.
48
- - **Carson-owned operations** — Carson owns worktree and delivery operations in governed repositories.
38
+ - **Carson-owned operations** — Carson owns worktree and delivery operations in governed repositories. Raw `git worktree add/remove`, raw `git pull --rebase`, and raw `gh pr create/merge` are blocked, and `git add` / `git commit` are blocked on the main working tree until you create a Carson worktree.
49
39
  - **Self-diagnosing output** — every block should say what happened and the exact next command.
50
40
  - **Outsider boundary** — Carson governs repositories without becoming a host-repository runtime dependency.
51
41
 
@@ -62,13 +52,16 @@ cd your/repo/path/.claude/worktrees/your-worktree
62
52
 
63
53
  # work and test, then either commit yourself or let Carson create the delivery commit
64
54
  carson deliver --commit "fix: describe this delivery"
65
- carson status
66
55
 
67
- # keep govern running to advance queued deliveries
68
- carson govern --loop 300
56
+ # inspect cleanup recommendations once the work is landed
57
+ carson worktree list
69
58
  ```
70
59
 
71
- By default, repositories onboard as `remote`. `carson deliver` is the branch handoff: it pushes the branch, creates or refreshes the PR, records delivery state, and returns immediately. Use plain `carson deliver` when the branch is already committed. Use `carson deliver --commit "..."` when the worktree is dirty and Carson should create one all-dirty delivery commit first. `carson status` shows the active branch deliveries, and `carson govern` advances queued work across the governed portfolio.
60
+ `carson deliver` owns the normal branch-delivery path: it pushes the branch, creates or refreshes the PR, waits for the review and CI gates Carson can observe, merges when clear, and syncs local `main`. If CI or review is still pending after Carson's configured wait windows, `deliver` returns a gated state instead of merging. Use plain `carson deliver` when the branch is already committed. Use `carson deliver --commit "..."` when the worktree is dirty and Carson should create one all-dirty delivery commit first.
61
+
62
+ When one Carson-governed required check is already red on the default branch and the current PR is the repair, use `carson recover --check "..."`. Recovery is the explicit exceptional path: Carson proves the baseline failure, keeps every other gate intact, records an audit event, and never teaches operators to step outside Carson first.
63
+
64
+ `carson worktree list` is the visibility surface for cleanup: it shows every registered worktree, the branch, PR state, whether the content is already on `main`, and Carson's keep or reap recommendation. When work needs to be abandoned instead of landed, use `carson abandon <pr-number|pr-url|branch>` to close the PR and clean up the branch/worktree safely.
72
65
 
73
66
  ## Portfolio Layer
74
67
 
@@ -80,7 +73,7 @@ carson refresh --all
80
73
  carson govern --dry-run
81
74
  ```
82
75
 
83
- `carson govern` is the portfolio layer. It advances queued deliveries, dispatches revision work for blocked branches, and surfaces what needs human judgement. Governed integration is squash-only and happens one repository at a time.
76
+ `carson govern` is the portfolio layer. It reassesses active deliveries across governed repositories, dispatches revision work for blocked branches, and surfaces what needs human judgement. Governed integration is squash-only and happens one repository at a time.
84
77
 
85
78
  ## Where to Read Next
86
79
 
data/RELEASE.md CHANGED
@@ -5,6 +5,30 @@ Release-note scope rule:
5
5
  - `RELEASE.md` records only version deltas, breaking changes, and migration actions.
6
6
  - Operational usage guides live in `MANUAL.md` and `API.md`.
7
7
 
8
+ ## 3.27.0
9
+
10
+ ### What changed
11
+
12
+ - **3.25.0 — Value objects simplified** — `Delivery` gains `repo_path`, `key` (composite `repo_path:branch:head`), and an embedded `revisions` array. `revision_count` is now derived from `revisions.length`. `Revision` drops `id` and `delivery_id`. Numeric delivery IDs are removed from the model entirely.
13
+ - **3.25.1 — Config defaults updated** — `govern.state_path` default changed from `~/.carson/state.sqlite3` to `~/.carson/state.json`. Fallback leaf follows suit.
14
+ - **3.26.0 — Ledger rewritten from SQLite to JSON** — The delivery ledger is now a plain JSON file (`~/.carson/state.json`) with file-lock protection and atomic writes. Revisions are embedded in their parent delivery. No migration — a missing `state.json` starts with an empty ledger; legacy `state.sqlite3` files are left untouched.
15
+ - **3.26.1 — Consumers use natural keys** — `govern.rb` and `deliver.rb` reference `delivery.key` instead of `delivery.id`. `revisions_for_delivery` uses the delivery object directly. `revision_count:` arguments removed from `update_delivery` calls (count is derived). Human output shows `Delivery: branch → main` instead of `Delivery #id`.
16
+ - **3.27.0 — sqlite3 dependency removed** — `spec.add_dependency "sqlite3"` removed from `carson.gemspec`. Carson has zero native extension dependencies.
17
+
18
+ ### Migration
19
+
20
+ - If you have an existing `~/.carson/state.sqlite3`, Carson will not read it. Active deliveries start fresh. The old file is not deleted.
21
+ - Any automation referencing `govern.state_path` with `.sqlite3` should update to `.json`.
22
+
23
+ ## 3.24.0
24
+
25
+ ### What changed
26
+
27
+ - **Govern now finds worktree-created deliveries** — `repository_record` stored the worktree CWD as `repo_path` in the ledger, but `govern` looked up deliveries by the main tree path from config. The SQL query never matched, so `carson govern` always reported "no active deliveries" for worktree-created PRs. Now `repository_record` uses `main_worktree_root` so the ledger key is always the canonical main tree path. Also fixed the govern fallback path, `reconcile_delivery!`, `housekeep_repo!`, and `review_evidence` for the same mismatch.
28
+ - **Status shows canonical repository name** — `carson status` from a worktree displayed the worktree folder name (e.g. `feature-branch`) as `Repository:` instead of the actual repository name. Now correctly shows the canonical name.
29
+
30
+ ### No migration required
31
+
8
32
  ## 3.23.3
9
33
 
10
34
  ### What changed
@@ -38,7 +62,7 @@ Release-note scope rule:
38
62
 
39
63
  ### What changed
40
64
 
41
- - **Single-actor branch delivery redesign** — Carson is now the sole actor. Repository and branch state are recorded in a SQLite delivery ledger, `carson deliver` becomes the asynchronous branch handoff, and `carson govern` advances queued deliveries and revision cycles without blocking the caller process.
65
+ - **Single-actor branch delivery redesign** — Carson is now the sole actor. Repository and branch state are recorded in a JSON delivery ledger, `carson deliver` becomes the asynchronous branch handoff, and `carson govern` advances queued deliveries and revision cycles without blocking the caller process.
42
66
  - **Status redesigned around deliveries** — `carson status` now reports repository authority, the current branch, active deliveries, and stale-branch counts. `--json` exposes the same delivery-centred model explicitly for software consumers.
43
67
  - **Governed integration is squash-only** — Carson now enforces a single governed integration policy. Repository settings must allow squash merge, and Carson rejects governed configs that specify any other merge method.
44
68
  - **Setup and help contract simplified** — `carson setup` no longer offers merge-method choice for governed repositories, and `carson deliver --merge` is removed in favour of the single autonomous `carson deliver` path.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 3.23.3
1
+ 3.27.0
data/carson.gemspec CHANGED
@@ -28,7 +28,6 @@ Gem::Specification.new do |spec|
28
28
  spec.bindir = "exe"
29
29
  spec.executables = [ "carson" ]
30
30
  spec.require_paths = [ "lib" ]
31
- spec.add_dependency "sqlite3", ">= 1.3", "< 3"
32
31
  spec.files = Dir.glob( "{lib,exe,templates,hooks}/**/*", File::FNM_DOTMATCH ).select { |path| File.file?( path ) } + [
33
32
  ".github/workflows/carson_policy.yml",
34
33
  "README.md",
data/hooks/command-guard CHANGED
@@ -1,8 +1,9 @@
1
1
  #!/usr/bin/env bash
2
2
  # Carson command guard — Claude Code PreToolUse hook.
3
3
  #
4
- # Blocks raw `gh pr create` and `gh pr merge` in Carson-governed repositories.
5
- # Agents should use `carson deliver` instead.
4
+ # Blocks raw worktree and delivery commands in Carson-governed repositories,
5
+ # plus `git add` / `git commit` on the main working tree.
6
+ # Agents should use Carson's governed path instead.
6
7
  #
7
8
  # Claude Code sends JSON on stdin: {"tool_name": "Bash", "tool_input": {"command": "..."}}
8
9
  # To block: print reason to stderr, exit 2.
@@ -22,6 +23,14 @@
22
23
  # ]
23
24
  set -euo pipefail
24
25
 
26
+ block_command() {
27
+ local summary="$1"
28
+ local recovery="$2"
29
+ echo "$summary" >&2
30
+ echo "$recovery" >&2
31
+ exit 2
32
+ }
33
+
25
34
  # Read the tool call JSON from stdin.
26
35
  input="$(cat)"
27
36
 
@@ -32,14 +41,6 @@ tool_name="$(echo "$input" | jq -r '.tool_name // empty' 2>/dev/null)"
32
41
  command_text="$(echo "$input" | jq -r '.tool_input.command // empty' 2>/dev/null)"
33
42
  [ -n "$command_text" ] || exit 0
34
43
 
35
- # Check for gh pr commands that Carson replaces.
36
- # Match only at command position: start of line, or after a shell operator (&&, ||, ;, |).
37
- # This avoids false positives from gh pr references inside commit messages or string arguments.
38
- guarded_pattern='(^|&&|\|\||;|\|)\s*gh\s+pr\s+(create|merge)'
39
- if ! echo "$command_text" | grep -qE "$guarded_pattern"; then
40
- exit 0
41
- fi
42
-
43
44
  # Check if the current directory is inside a governed repository.
44
45
  config_file="${HOME}/.carson/config.json"
45
46
  [ -f "$config_file" ] || exit 0
@@ -47,12 +48,55 @@ config_file="${HOME}/.carson/config.json"
47
48
  repo_root="$(git rev-parse --show-toplevel 2>/dev/null || echo "")"
48
49
  [ -n "$repo_root" ] || exit 0
49
50
 
50
- normalised="$(cd "$repo_root" && pwd -P)"
51
- if ! grep -qF "\"$normalised\"" "$config_file" 2>/dev/null; then
51
+ current_root="$(cd "$repo_root" && pwd -P)"
52
+ common_dir="$(git rev-parse --path-format=absolute --git-common-dir 2>/dev/null || echo "")"
53
+ if [ -n "$common_dir" ]; then
54
+ governed_root="$(cd "$(dirname "$common_dir")" && pwd -P)"
55
+ else
56
+ governed_root="$current_root"
57
+ fi
58
+
59
+ if ! grep -qF "\"$governed_root\"" "$config_file" 2>/dev/null; then
52
60
  exit 0
53
61
  fi
54
62
 
55
- # This is a raw gh pr command in a governed repo — block it.
56
- echo "This repo is Carson-governed use \`carson deliver\` instead of raw \`gh pr\`." >&2
57
- echo "Use \`carson deliver\` instead it handles push, PR, and merge with safety guards." >&2
58
- exit 2
63
+ main_branch="$(jq -r '.git.main_branch // "main"' "$config_file" 2>/dev/null || echo "main")"
64
+ [ -n "$main_branch" ] || main_branch="main"
65
+ current_branch="$(git rev-parse --abbrev-ref HEAD 2>/dev/null || echo "")"
66
+ on_main_worktree=false
67
+ on_main_branch=false
68
+ [ "$current_root" = "$governed_root" ] && on_main_worktree=true
69
+ [ "$current_branch" = "$main_branch" ] && on_main_branch=true
70
+
71
+ # Match only at command position: start of line, or after a shell operator (&&, ||, ;, |).
72
+ # This avoids false positives from mentions inside commit messages or string arguments.
73
+ delivery_pattern='(^|&&|\|\||;|\|)\s*gh\s+pr\s+(create|merge)\b'
74
+ worktree_pattern='(^|&&|\|\||;|\|)\s*git\s+worktree\s+(add|remove)\b'
75
+ pull_rebase_pattern='(^|&&|\|\||;|\|)\s*git\s+pull([^;&|]|\\\|)*--rebase\b'
76
+ main_mutation_pattern='(^|&&|\|\||;|\|)\s*git\s+(add|commit)\b'
77
+
78
+ if grep -qE "$delivery_pattern" <<<"$command_text"; then
79
+ block_command \
80
+ "This repo is Carson-governed — use \`carson deliver\` instead of raw \`gh pr\`." \
81
+ "Use \`carson deliver\` instead — it handles push, PR, and merge with safety guards."
82
+ fi
83
+
84
+ if grep -qE "$worktree_pattern" <<<"$command_text"; then
85
+ block_command \
86
+ "This repo is Carson-governed — use \`carson worktree\` instead of raw \`git worktree\`." \
87
+ "Use \`carson worktree create <name>\` or \`carson worktree remove <name>\` instead."
88
+ fi
89
+
90
+ if grep -qE "$pull_rebase_pattern" <<<"$command_text"; then
91
+ block_command \
92
+ "This repo is Carson-governed — use \`carson sync\` instead of raw \`git pull --rebase\`." \
93
+ "Use \`carson sync\` instead — it owns main-branch alignment in governed repos."
94
+ fi
95
+
96
+ if [ "$on_main_worktree" = true ] && [ "$on_main_branch" = true ] && grep -qE "$main_mutation_pattern" <<<"$command_text"; then
97
+ block_command \
98
+ "Main working tree is read-only in this Carson-governed repo." \
99
+ "Use \`carson worktree create <name>\` first, then run \`git add\` or \`git commit\` inside that worktree."
100
+ fi
101
+
102
+ exit 0