carson 4.3.4 → 4.4.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 +4 -4
- data/RELEASE.md +28 -7
- data/VERSION +1 -1
- data/lib/carson/warehouse/workbench.rb +3 -6
- data/lib/carson/worktree.rb +5 -14
- data/lib/cli.rb +9 -9
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: b22cfd5f4976a5367d0a815fac4f360049673aaa585a3783c7296f155be896a9
|
|
4
|
+
data.tar.gz: bdc3f70b4b74dcb489b8dde16ca0244846b4082fc6697713ce83490cb64319c4
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: a77aa24657d4863d5de2a06e14b14e0f339cd9b9ac709933f2b2ec084de721a101781867a7b3a4bb0557623968247ca4333cf5821660778ce0ddd70c20f780ba
|
|
7
|
+
data.tar.gz: 5113678e26302f1eb7b9a5c93e59f4a357434ddade3ec9b4eec00f412c1af8b77888b132ab5f849594e04621d0af57e8e9969f3e0292b23b18bb215894a1dac9
|
data/RELEASE.md
CHANGED
|
@@ -7,25 +7,36 @@ Release-note scope rule:
|
|
|
7
7
|
|
|
8
8
|
## Unreleased
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
## 4.4.0
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
### New
|
|
13
|
+
|
|
14
|
+
- **Auto-chdir on checkout from inside worktree.** `carson checkout` no longer blocks when the current working directory is inside the worktree being removed. Carson `Dir.chdir`s to the main worktree root and completes the removal automatically. Both the warehouse (`assess_removal`) and legacy (`remove_check`) paths are fixed.
|
|
15
|
+
- **Parent shell excluded from held-by-other-process check.** `held_by_other_process?` now excludes `Process.ppid` (the user's shell that launched Carson) in addition to `Process.pid`. Prevents false blocks when the user runs `carson checkout` from inside the worktree.
|
|
13
16
|
|
|
14
17
|
### Why
|
|
15
18
|
|
|
16
|
-
|
|
19
|
+
Running `carson checkout` from inside the target worktree is the most natural invocation — agents and users are already there. Blocking and printing a recovery command added friction for no safety benefit, since Carson can move its own process out.
|
|
17
20
|
|
|
18
|
-
## 4.3.
|
|
21
|
+
## 4.3.5
|
|
19
22
|
|
|
20
23
|
### Fixed
|
|
21
24
|
|
|
22
|
-
-
|
|
25
|
+
- **Story language purged from CLI output.** `checkin`/`checkout` (#509) shipped after the story-language purge (#458) and used "workbench" in every user-facing string — help text, status messages, error messages. All 9 output strings now use technical language ("worktree"). Source-code names unchanged.
|
|
26
|
+
|
|
27
|
+
### New
|
|
28
|
+
|
|
29
|
+
- **Story-language guard test.** `test/story_language_guard_test.rb` scans all output-producing lines in `lib/` for forbidden story-language terms (workbench, warehouse, parcel, courier, bureau, waybill, vault). Strips `#{}` interpolation before checking. Catches future leaks mechanically — the purge is now a permanent rule, not a one-time pass.
|
|
30
|
+
|
|
31
|
+
### Removed
|
|
32
|
+
|
|
33
|
+
- **`carson audit` dissolved.** The audit command and its pre-commit gate have been removed entirely. Three of its seven checks were already enforced by the commands that need them (sealed workbench by `pack!`, working tree by Courier, main sync by `sync!`). The remaining four (PR status, CI baseline, hooks health, outsider fingerprints) were either unproven at commit time or already called by individual commands. Bare `carson` now defaults to `status` instead of `audit`. The pre-commit hook is now a no-op reserved for future use.
|
|
23
34
|
|
|
24
35
|
### Why
|
|
25
36
|
|
|
26
|
-
|
|
37
|
+
Story language in output has no mechanical enforcement — conventions fail on new code. The guard test closes that gap. Audit dissolution: audit was a remote-centred pre-commit gate; in local-centred mode it was dead weight.
|
|
27
38
|
|
|
28
|
-
## 4.3.
|
|
39
|
+
## 4.3.4
|
|
29
40
|
|
|
30
41
|
### New
|
|
31
42
|
|
|
@@ -35,6 +46,16 @@ Local-centred mode means local main is the source of truth. Fetching from GitHub
|
|
|
35
46
|
|
|
36
47
|
An agent edited four files in a worktree, ran `carson deliver` without committing, and lost all work. Carson merged a branch with zero commits ahead of main — a valid fast-forward, technically a no-op. The edits existed only in the working directory and were destroyed on workbench cleanup. The agent then wrote a confident delivery summary describing changes that did not exist on main.
|
|
37
48
|
|
|
49
|
+
## 4.3.3
|
|
50
|
+
|
|
51
|
+
### Fixed
|
|
52
|
+
|
|
53
|
+
- **`carson checkin` is 13× faster.** Removed two redundant `git fetch` calls that hit GitHub on every checkin. `checkin` now branches from local main — zero network, 0.7s instead of 9.4s. Local main is the standard; GitHub is a backup, not a gating dependency.
|
|
54
|
+
|
|
55
|
+
### Why
|
|
56
|
+
|
|
57
|
+
Local-centred mode means local main is the source of truth. Fetching from GitHub on every checkin was a remote-centred assumption baked into the command. The two sequential network round-trips accounted for 90% of the wall time.
|
|
58
|
+
|
|
38
59
|
## 4.3.2
|
|
39
60
|
|
|
40
61
|
### Fixed
|
data/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
4.
|
|
1
|
+
4.4.0
|
|
@@ -166,7 +166,7 @@ module Carson
|
|
|
166
166
|
tracking = seal_check.sealed_tracking_number || "unknown"
|
|
167
167
|
return { command: "checkout", status: "block",
|
|
168
168
|
name: File.basename( workbench.path ), branch: workbench.branch,
|
|
169
|
-
error: "
|
|
169
|
+
error: "worktree is sealed — PR ##{tracking} is still in flight",
|
|
170
170
|
recovery: "wait for CI checks to complete, or run carson deliver to check status" }
|
|
171
171
|
end
|
|
172
172
|
end
|
|
@@ -232,11 +232,8 @@ module Carson
|
|
|
232
232
|
return { status: :ok, missing: true }
|
|
233
233
|
end
|
|
234
234
|
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
error: "current working directory is inside this worktree",
|
|
238
|
-
recovery: "cd #{main_worktree_root} && carson checkout #{File.basename( workbench.path )}" }
|
|
239
|
-
end
|
|
235
|
+
# Auto-chdir out so removal can proceed.
|
|
236
|
+
Dir.chdir( main_worktree_root ) if workbench.holds_cwd?
|
|
240
237
|
|
|
241
238
|
if workbench.held_by_other_process?
|
|
242
239
|
return { status: :block, result_status: "block",
|
data/lib/carson/worktree.rb
CHANGED
|
@@ -270,18 +270,8 @@ module Carson
|
|
|
270
270
|
entry = find( path: resolved_path, runtime: runtime )
|
|
271
271
|
branch = entry&.branch
|
|
272
272
|
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
return {
|
|
276
|
-
status: :block,
|
|
277
|
-
result_status: "block",
|
|
278
|
-
exit_code: Runtime::EXIT_BLOCK,
|
|
279
|
-
resolved_path: resolved_path,
|
|
280
|
-
branch: branch,
|
|
281
|
-
error: "current working directory is inside this worktree",
|
|
282
|
-
recovery: "cd #{safe_root} && carson checkout #{File.basename( resolved_path )}"
|
|
283
|
-
}
|
|
284
|
-
end
|
|
273
|
+
# Auto-chdir out so removal can proceed.
|
|
274
|
+
Dir.chdir( runtime.main_worktree_root ) if entry&.holds_cwd?
|
|
285
275
|
|
|
286
276
|
if entry&.held_by_other_process?
|
|
287
277
|
return {
|
|
@@ -388,11 +378,12 @@ module Carson
|
|
|
388
378
|
return false if stdout.nil? || stdout.empty?
|
|
389
379
|
|
|
390
380
|
normalised = File.join( canonical, "" )
|
|
391
|
-
|
|
381
|
+
# Exclude this process and its parent (the user's shell that launched Carson).
|
|
382
|
+
excluded_pids = [ Process.pid, Process.ppid ].to_set
|
|
392
383
|
stdout.lines.drop( 1 ).any? do |line|
|
|
393
384
|
fields = line.strip.split( /\s+/ )
|
|
394
385
|
next false unless fields.length >= 9
|
|
395
|
-
next false if fields[ 1 ].to_i
|
|
386
|
+
next false if excluded_pids.include?( fields[ 1 ].to_i )
|
|
396
387
|
name = fields[ 8.. ].join( " " )
|
|
397
388
|
name == canonical || name.start_with?( normalised )
|
|
398
389
|
end
|
data/lib/cli.rb
CHANGED
|
@@ -134,7 +134,7 @@ module Carson
|
|
|
134
134
|
parser.separator "Keep agents from breaking main. Keep agents from breaking each other."
|
|
135
135
|
parser.separator ""
|
|
136
136
|
parser.separator "Agent workflow:"
|
|
137
|
-
parser.separator " checkin Get a fresh
|
|
137
|
+
parser.separator " checkin Get a fresh worktree"
|
|
138
138
|
parser.separator " deliver Accept into main and back up to remote"
|
|
139
139
|
parser.separator ""
|
|
140
140
|
parser.separator "Portfolio:"
|
|
@@ -528,15 +528,15 @@ module Carson
|
|
|
528
528
|
checkin_parser = OptionParser.new do |parser|
|
|
529
529
|
parser.banner = "Usage: carson checkin <name> [--json]"
|
|
530
530
|
parser.separator ""
|
|
531
|
-
parser.separator "Prepare a fresh
|
|
532
|
-
parser.separator "The
|
|
531
|
+
parser.separator "Prepare a fresh worktree from the latest main."
|
|
532
|
+
parser.separator "The name becomes the branch."
|
|
533
533
|
parser.separator ""
|
|
534
534
|
parser.separator "Options:"
|
|
535
535
|
parser.on( "--json", "Machine-readable JSON output" ) { options[ :json ] = true }
|
|
536
536
|
parser.separator ""
|
|
537
537
|
parser.separator "Examples:"
|
|
538
538
|
parser.separator " carson checkin feature-auth"
|
|
539
|
-
parser.separator " carson checkin oo/refactor-
|
|
539
|
+
parser.separator " carson checkin oo/refactor-auth"
|
|
540
540
|
end
|
|
541
541
|
checkin_parser.parse!( arguments )
|
|
542
542
|
name = arguments.shift.to_s.strip
|
|
@@ -560,7 +560,7 @@ module Carson
|
|
|
560
560
|
checkout_parser = OptionParser.new do |parser|
|
|
561
561
|
parser.banner = "Usage: carson checkout <name> [--json] [--force]"
|
|
562
562
|
parser.separator ""
|
|
563
|
-
parser.separator "Release a
|
|
563
|
+
parser.separator "Release a worktree when safe."
|
|
564
564
|
parser.separator "Removes the directory and local branch."
|
|
565
565
|
parser.separator ""
|
|
566
566
|
parser.separator "Options:"
|
|
@@ -569,7 +569,7 @@ module Carson
|
|
|
569
569
|
parser.separator ""
|
|
570
570
|
parser.separator "Examples:"
|
|
571
571
|
parser.separator " carson checkout feature-auth"
|
|
572
|
-
parser.separator " carson checkout oo/refactor-
|
|
572
|
+
parser.separator " carson checkout oo/refactor-auth --force"
|
|
573
573
|
end
|
|
574
574
|
checkout_parser.parse!( arguments )
|
|
575
575
|
name = arguments.shift.to_s.strip
|
|
@@ -1036,7 +1036,7 @@ module Carson
|
|
|
1036
1036
|
name = parsed.fetch( :workbench_name )
|
|
1037
1037
|
result = { command: "checkout", status: "error",
|
|
1038
1038
|
name: name,
|
|
1039
|
-
error: "#{name} is not a registered
|
|
1039
|
+
error: "#{name} is not a registered worktree",
|
|
1040
1040
|
recovery: "carson worktree list" }
|
|
1041
1041
|
return report_workbench( result: result, json: parsed.fetch( :json, false ), output: runtime.output )
|
|
1042
1042
|
end
|
|
@@ -1155,11 +1155,11 @@ module Carson
|
|
|
1155
1155
|
when "ok"
|
|
1156
1156
|
case result[ :command ]
|
|
1157
1157
|
when "checkin"
|
|
1158
|
-
output.puts "#{BADGE}
|
|
1158
|
+
output.puts "#{BADGE} Worktree ready: #{result[ :name ]}"
|
|
1159
1159
|
output.puts " path: #{result[ :path ]}"
|
|
1160
1160
|
output.puts " branch: #{result[ :branch ]}"
|
|
1161
1161
|
when "checkout"
|
|
1162
|
-
output.puts "#{BADGE}
|
|
1162
|
+
output.puts "#{BADGE} Worktree released: #{result[ :name ]}"
|
|
1163
1163
|
end
|
|
1164
1164
|
when "error"
|
|
1165
1165
|
output.puts "#{BADGE} #{result[ :error ]}"
|