carson 3.23.2 → 3.24.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/API.md +1 -1
- data/MANUAL.md +4 -2
- data/README.md +3 -3
- data/RELEASE.md +17 -0
- data/VERSION +1 -1
- data/lib/carson/cli.rb +14 -5
- data/lib/carson/runtime/deliver.rb +119 -1
- data/lib/carson/runtime/govern.rb +9 -5
- data/lib/carson/runtime/review/gate_support.rb +1 -1
- data/lib/carson/runtime/status.rb +1 -1
- data/lib/carson/runtime.rb +4 -1
- 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: 92803422cb09be4d2f4b31cf6c0b0f98796373c2a6a403af55c0e09361d0e951
|
|
4
|
+
data.tar.gz: 36f06f845aca0878e2d18de009e661c662baf08675ce3b3331e08f4f2907cc58
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 356bdf1b684829c5d506d00d303db0473f1cacdfd70d7831c21db201d465dd51fd3c03aa7a63f1cebc5658f6fe98321d6cc2bbc99c6f049753325f8898bb7479
|
|
7
|
+
data.tar.gz: ecad319106eb238264d3155740c36960521a70448183946c1ed1646d8b1b5291345d7eef8c0463a68e5cc55b0efe5d7687574d1ac2d869eeaaac08b73bafed81
|
data/API.md
CHANGED
|
@@ -25,7 +25,7 @@ carson <command> [subcommand] [arguments]
|
|
|
25
25
|
| Command | Purpose |
|
|
26
26
|
|---|---|
|
|
27
27
|
| `carson audit` | Evaluate governance status and generate report output. |
|
|
28
|
-
| `carson deliver` | Start autonomous branch delivery for the current checkout
|
|
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. |
|
|
29
29
|
| `carson sync` | Fast-forward local `main` from configured remote when tree is clean. |
|
|
30
30
|
| `carson prune` | Remove stale local branches whose upstream refs no longer exist. |
|
|
31
31
|
| `carson template check` | Detect drift between managed templates and host `.github/*` files. |
|
data/MANUAL.md
CHANGED
|
@@ -152,12 +152,14 @@ carson worktree create my-feature
|
|
|
152
152
|
cd /path/to/.claude/worktrees/my-feature
|
|
153
153
|
```
|
|
154
154
|
|
|
155
|
-
**2. Work** — make changes,
|
|
155
|
+
**2. Work** — make changes, test them, and either commit normally or let Carson create the delivery commit.
|
|
156
156
|
|
|
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. Managed template drift is corrected
|
|
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.
|
|
158
158
|
|
|
159
159
|
```bash
|
|
160
160
|
carson deliver
|
|
161
|
+
# or, if the worktree is still dirty:
|
|
162
|
+
carson deliver --commit "fix: describe this delivery"
|
|
161
163
|
# Output: PR #N, Delivery: queued|gated
|
|
162
164
|
# Next: carson status
|
|
163
165
|
```
|
data/README.md
CHANGED
|
@@ -60,15 +60,15 @@ carson onboard your/repo/path
|
|
|
60
60
|
carson worktree create your-worktree
|
|
61
61
|
cd your/repo/path/.claude/worktrees/your-worktree
|
|
62
62
|
|
|
63
|
-
# work
|
|
64
|
-
carson deliver
|
|
63
|
+
# work and test, then either commit yourself or let Carson create the delivery commit
|
|
64
|
+
carson deliver --commit "fix: describe this delivery"
|
|
65
65
|
carson status
|
|
66
66
|
|
|
67
67
|
# keep govern running to advance queued deliveries
|
|
68
68
|
carson govern --loop 300
|
|
69
69
|
```
|
|
70
70
|
|
|
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. `carson status` shows the active branch deliveries, and `carson govern` advances queued work across the governed portfolio.
|
|
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.
|
|
72
72
|
|
|
73
73
|
## Portfolio Layer
|
|
74
74
|
|
data/RELEASE.md
CHANGED
|
@@ -5,6 +5,23 @@ 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.24.0
|
|
9
|
+
|
|
10
|
+
### What changed
|
|
11
|
+
|
|
12
|
+
- **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.
|
|
13
|
+
- **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.
|
|
14
|
+
|
|
15
|
+
### No migration required
|
|
16
|
+
|
|
17
|
+
## 3.23.3
|
|
18
|
+
|
|
19
|
+
### What changed
|
|
20
|
+
|
|
21
|
+
- **Fix: review gate failed with "accepts at most 1 arg(s), received 3"** — `current_pull_request_for_branch` placed `--json` after the `--` end-of-options separator, causing `gh pr view` to treat it as a positional argument instead of a flag. Flags now precede `--`.
|
|
22
|
+
|
|
23
|
+
### No migration required
|
|
24
|
+
|
|
8
25
|
## 3.23.2
|
|
9
26
|
|
|
10
27
|
### What changed
|
data/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
3.
|
|
1
|
+
3.24.0
|
data/lib/carson/cli.rb
CHANGED
|
@@ -550,22 +550,29 @@ module Carson
|
|
|
550
550
|
return { command: :invalid }
|
|
551
551
|
end
|
|
552
552
|
|
|
553
|
-
options = { json: false, title: nil, body_file: nil }
|
|
553
|
+
options = { json: false, title: nil, body_file: nil, commit_message: nil }
|
|
554
554
|
deliver_parser = OptionParser.new do |parser|
|
|
555
|
-
parser.banner = "Usage: carson deliver [--json] [--title TITLE] [--body-file PATH]"
|
|
555
|
+
parser.banner = "Usage: carson deliver [--json] [--title TITLE] [--body-file PATH] [--commit MESSAGE]"
|
|
556
556
|
parser.separator ""
|
|
557
557
|
parser.separator "Push the current branch, create or refresh the pull request, and hand the branch to Carson."
|
|
558
|
-
parser.separator "
|
|
558
|
+
parser.separator "Use --commit to create one all-dirty delivery commit before Carson pushes and opens the PR."
|
|
559
559
|
parser.separator ""
|
|
560
560
|
parser.separator "Options:"
|
|
561
561
|
parser.on( "--json", "Machine-readable JSON output" ) { options[ :json ] = true }
|
|
562
562
|
parser.on( "--title TITLE", "PR title (defaults to branch name)" ) { |value| options[ :title ] = value }
|
|
563
563
|
parser.on( "--body-file PATH", "File containing PR body text" ) { |value| options[ :body_file ] = value }
|
|
564
|
+
parser.on( "--commit MESSAGE", "Commit all dirty user changes before delivery" ) { |value| options[ :commit_message ] = value }
|
|
564
565
|
parser.separator ""
|
|
565
566
|
parser.separator "Examples:"
|
|
566
|
-
parser.separator " carson deliver
|
|
567
|
+
parser.separator " carson deliver Deliver existing commits"
|
|
568
|
+
parser.separator " carson deliver --commit \"fix: harden flow\" Commit dirty changes, then deliver"
|
|
567
569
|
end
|
|
568
570
|
deliver_parser.parse!( arguments )
|
|
571
|
+
if options.fetch( :commit_message, nil ).to_s.strip.empty? && !options.fetch( :commit_message, nil ).nil?
|
|
572
|
+
error.puts "#{BADGE} --commit requires a non-empty message"
|
|
573
|
+
error.puts deliver_parser
|
|
574
|
+
return { command: :invalid }
|
|
575
|
+
end
|
|
569
576
|
unless arguments.empty?
|
|
570
577
|
error.puts "#{BADGE} Unexpected arguments for deliver: #{arguments.join( ' ' )}"
|
|
571
578
|
error.puts deliver_parser
|
|
@@ -575,7 +582,8 @@ module Carson
|
|
|
575
582
|
command: "deliver",
|
|
576
583
|
json: options.fetch( :json ),
|
|
577
584
|
title: options[ :title ],
|
|
578
|
-
body_file: options[ :body_file ]
|
|
585
|
+
body_file: options[ :body_file ],
|
|
586
|
+
commit_message: options[ :commit_message ]
|
|
579
587
|
}
|
|
580
588
|
rescue OptionParser::ParseError => exception
|
|
581
589
|
error.puts "#{BADGE} #{exception.message}"
|
|
@@ -763,6 +771,7 @@ module Carson
|
|
|
763
771
|
runtime.deliver!(
|
|
764
772
|
title: parsed.fetch( :title, nil ),
|
|
765
773
|
body_file: parsed.fetch( :body_file, nil ),
|
|
774
|
+
commit_message: parsed.fetch( :commit_message, nil ),
|
|
766
775
|
json_output: parsed.fetch( :json, false )
|
|
767
776
|
)
|
|
768
777
|
when "review:gate"
|
|
@@ -5,7 +5,8 @@ module Carson
|
|
|
5
5
|
module Deliver
|
|
6
6
|
# Entry point for `carson deliver`.
|
|
7
7
|
# Pushes the current branch, ensures a PR exists, records delivery state, and returns.
|
|
8
|
-
|
|
8
|
+
# When --commit is supplied, Carson creates one all-dirty agent-authored commit first.
|
|
9
|
+
def deliver!( title: nil, body_file: nil, commit_message: nil, json_output: false )
|
|
9
10
|
branch_name = current_branch
|
|
10
11
|
main_branch = config.main_branch
|
|
11
12
|
remote_name = config.git_remote
|
|
@@ -17,11 +18,38 @@ module Carson
|
|
|
17
18
|
return deliver_finish( result: result, exit_code: EXIT_BLOCK, json_output: json_output )
|
|
18
19
|
end
|
|
19
20
|
|
|
21
|
+
initial_dirty = working_tree_dirty?
|
|
22
|
+
if initial_dirty && commit_message.to_s.strip.empty?
|
|
23
|
+
result[ :error ] = "working tree is dirty"
|
|
24
|
+
result[ :recovery ] = "carson deliver --commit \"describe this delivery\""
|
|
25
|
+
return deliver_finish( result: result, exit_code: EXIT_BLOCK, json_output: json_output )
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
if !initial_dirty && !commit_message.to_s.strip.empty?
|
|
29
|
+
result[ :commit ] = blocked_commit_payload(
|
|
30
|
+
message: commit_message,
|
|
31
|
+
summary: "blocked — working tree is already clean"
|
|
32
|
+
)
|
|
33
|
+
result[ :error ] = "working tree is already clean"
|
|
34
|
+
result[ :recovery ] = "carson deliver"
|
|
35
|
+
return deliver_finish( result: result, exit_code: EXIT_BLOCK, json_output: json_output )
|
|
36
|
+
end
|
|
37
|
+
|
|
20
38
|
sync_exit, sync_diagnostics = deliver_template_sync
|
|
21
39
|
if sync_exit == EXIT_ERROR
|
|
22
40
|
result[ :error ] = sync_diagnostics.to_s.strip.empty? ? "template sync failed" : sync_diagnostics.strip
|
|
23
41
|
return deliver_finish( result: result, exit_code: sync_exit, json_output: json_output )
|
|
24
42
|
end
|
|
43
|
+
template_sync_committed = sync_exit == EXIT_BLOCK
|
|
44
|
+
|
|
45
|
+
unless commit_message.to_s.strip.empty?
|
|
46
|
+
commit_exit = prepare_delivery_commit!(
|
|
47
|
+
commit_message: commit_message,
|
|
48
|
+
template_sync_committed: template_sync_committed,
|
|
49
|
+
result: result
|
|
50
|
+
)
|
|
51
|
+
return deliver_finish( result: result, exit_code: commit_exit, json_output: json_output ) unless commit_exit == EXIT_OK
|
|
52
|
+
end
|
|
25
53
|
|
|
26
54
|
push_exit = push_branch!( branch: branch_name, remote: remote_name, result: result )
|
|
27
55
|
return deliver_finish( result: result, exit_code: push_exit, json_output: json_output ) unless push_exit == EXIT_OK
|
|
@@ -61,6 +89,93 @@ module Carson
|
|
|
61
89
|
|
|
62
90
|
private
|
|
63
91
|
|
|
92
|
+
def prepare_delivery_commit!( commit_message:, template_sync_committed:, result: )
|
|
93
|
+
if working_tree_dirty?
|
|
94
|
+
return create_delivery_commit!( commit_message: commit_message, result: result )
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
if template_sync_committed
|
|
98
|
+
result[ :commit ] = skipped_commit_payload(
|
|
99
|
+
message: commit_message,
|
|
100
|
+
summary: "skipped — template sync committed all pending changes"
|
|
101
|
+
)
|
|
102
|
+
return EXIT_OK
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
# The caller blocks the ordinary clean-tree case before template sync.
|
|
106
|
+
# Keep this branch as a post-sync safety net so future sequencing changes
|
|
107
|
+
# do not silently turn a clean tree into a successful no-op commit request.
|
|
108
|
+
result[ :commit ] = blocked_commit_payload(
|
|
109
|
+
message: commit_message,
|
|
110
|
+
summary: "blocked — working tree is already clean"
|
|
111
|
+
)
|
|
112
|
+
result[ :error ] = "working tree is already clean"
|
|
113
|
+
result[ :recovery ] = "carson deliver"
|
|
114
|
+
EXIT_BLOCK
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
def create_delivery_commit!( commit_message:, result: )
|
|
118
|
+
_, add_stderr, add_success, = git_run( "add", "-A" )
|
|
119
|
+
unless add_success
|
|
120
|
+
error_text = add_stderr.to_s.strip
|
|
121
|
+
error_text = "git add failed" if error_text.empty?
|
|
122
|
+
result[ :commit ] = blocked_commit_payload(
|
|
123
|
+
message: commit_message,
|
|
124
|
+
summary: "blocked — #{error_text}"
|
|
125
|
+
)
|
|
126
|
+
result[ :error ] = error_text
|
|
127
|
+
result[ :recovery ] = "git status"
|
|
128
|
+
return EXIT_ERROR
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
commit_stdout, commit_stderr, commit_success, = git_run( "commit", "-m", commit_message )
|
|
132
|
+
unless commit_success
|
|
133
|
+
error_text = [ commit_stderr.to_s.strip, commit_stdout.to_s.strip ].reject( &:empty? ).join( " | " )
|
|
134
|
+
error_text = "git commit failed" if error_text.empty?
|
|
135
|
+
result[ :commit ] = blocked_commit_payload(
|
|
136
|
+
message: commit_message,
|
|
137
|
+
summary: "blocked — #{error_text}"
|
|
138
|
+
)
|
|
139
|
+
result[ :error ] = error_text
|
|
140
|
+
result[ :recovery ] = "git status"
|
|
141
|
+
return EXIT_ERROR
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
result[ :commit ] = created_commit_payload(
|
|
145
|
+
message: commit_message,
|
|
146
|
+
head: current_head,
|
|
147
|
+
summary: "created agent-authored commit"
|
|
148
|
+
)
|
|
149
|
+
EXIT_OK
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
def created_commit_payload( message:, head:, summary: )
|
|
153
|
+
{
|
|
154
|
+
status: "created",
|
|
155
|
+
message: message,
|
|
156
|
+
head: head,
|
|
157
|
+
summary: summary
|
|
158
|
+
}
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
def skipped_commit_payload( message:, summary: )
|
|
162
|
+
{
|
|
163
|
+
status: "skipped",
|
|
164
|
+
message: message,
|
|
165
|
+
head: nil,
|
|
166
|
+
summary: summary
|
|
167
|
+
}
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
def blocked_commit_payload( message:, summary: )
|
|
171
|
+
{
|
|
172
|
+
status: "blocked",
|
|
173
|
+
message: message,
|
|
174
|
+
head: nil,
|
|
175
|
+
summary: summary
|
|
176
|
+
}
|
|
177
|
+
end
|
|
178
|
+
|
|
64
179
|
def deliver_template_sync
|
|
65
180
|
saved_output, saved_error = @output, @error
|
|
66
181
|
captured_out = StringIO.new
|
|
@@ -135,6 +250,9 @@ module Carson
|
|
|
135
250
|
return
|
|
136
251
|
end
|
|
137
252
|
|
|
253
|
+
if result[ :commit ]
|
|
254
|
+
puts_line "Commit: #{result.dig( :commit, :summary )}"
|
|
255
|
+
end
|
|
138
256
|
puts_line "PR: ##{result[ :pr_number ]} #{result[ :pr_url ]}" if result[ :pr_number ]
|
|
139
257
|
if result[ :delivery ]
|
|
140
258
|
puts_line "Delivery: #{result.dig( :delivery, :status )}"
|
|
@@ -18,7 +18,7 @@ module Carson
|
|
|
18
18
|
def govern_cycle!( dry_run:, json_output: )
|
|
19
19
|
print_header "Carson Govern"
|
|
20
20
|
repositories = governed_repo_paths
|
|
21
|
-
repositories = [
|
|
21
|
+
repositories = [ repository_record.path ] if repositories.empty?
|
|
22
22
|
puts_line "governing #{repositories.length} repo#{plural_suffix( count: repositories.length )}"
|
|
23
23
|
|
|
24
24
|
report = {
|
|
@@ -64,7 +64,7 @@ module Carson
|
|
|
64
64
|
end
|
|
65
65
|
|
|
66
66
|
def govern_repo!( repo_path:, dry_run: )
|
|
67
|
-
scoped_runtime =
|
|
67
|
+
scoped_runtime = repo_runtime_for( repo_path: repo_path )
|
|
68
68
|
repository = Repository.new( path: repo_path, authority: scoped_runtime.config.govern_authority, runtime: scoped_runtime )
|
|
69
69
|
deliveries = scoped_runtime.ledger.active_deliveries( repo_path: repo_path )
|
|
70
70
|
|
|
@@ -108,7 +108,7 @@ module Carson
|
|
|
108
108
|
end
|
|
109
109
|
|
|
110
110
|
def reconcile_delivery!( delivery: )
|
|
111
|
-
branch =
|
|
111
|
+
branch = repository_record.branch( delivery.branch ).reload
|
|
112
112
|
if branch.head && branch.head != delivery.head
|
|
113
113
|
return ledger.update_delivery(
|
|
114
114
|
delivery: delivery,
|
|
@@ -288,7 +288,7 @@ module Carson
|
|
|
288
288
|
end
|
|
289
289
|
|
|
290
290
|
def housekeep_repo!( repo_path: )
|
|
291
|
-
scoped_runtime =
|
|
291
|
+
scoped_runtime = repo_runtime_for( repo_path: repo_path )
|
|
292
292
|
sync_status = scoped_runtime.sync!
|
|
293
293
|
scoped_runtime.prune! if sync_status == EXIT_OK
|
|
294
294
|
end
|
|
@@ -373,7 +373,7 @@ module Carson
|
|
|
373
373
|
end
|
|
374
374
|
|
|
375
375
|
def review_evidence( delivery:, repo_path: )
|
|
376
|
-
repo_runtime =
|
|
376
|
+
repo_runtime = repo_runtime_for( repo_path: repo_path )
|
|
377
377
|
owner, repo = repo_runtime.send( :repository_coordinates )
|
|
378
378
|
details = repo_runtime.send( :pull_request_details, owner: owner, repo: repo, pr_number: delivery.pull_request_number )
|
|
379
379
|
pr_author = details.dig( :author, :login ).to_s
|
|
@@ -399,6 +399,10 @@ module Carson
|
|
|
399
399
|
{ summary: revision.summary.to_s, dispatched_at: revision.started_at.to_s }
|
|
400
400
|
end
|
|
401
401
|
|
|
402
|
+
def repo_runtime_for( repo_path: )
|
|
403
|
+
realpath_safe( repo_path ) == realpath_safe( repo_root ) ? self : build_scoped_runtime( repo_path: repo_path )
|
|
404
|
+
end
|
|
405
|
+
|
|
402
406
|
def thread_body( details:, url: )
|
|
403
407
|
Array( details[ :review_threads ] ).each do |thread|
|
|
404
408
|
thread[ :comments ].each do |comment|
|
|
@@ -121,7 +121,7 @@ module Carson
|
|
|
121
121
|
|
|
122
122
|
# Pull request selected by current branch; nil is returned when no PR exists.
|
|
123
123
|
def current_pull_request_for_branch( branch_name: )
|
|
124
|
-
stdout_text, stderr_text, success, = gh_run( "pr", "view", "--
|
|
124
|
+
stdout_text, stderr_text, success, = gh_run( "pr", "view", "--json", "number,title,url,state", "--", branch_name )
|
|
125
125
|
unless success
|
|
126
126
|
error_text = gh_error_text( stdout_text: stdout_text, stderr_text: stderr_text, fallback: "unable to read PR for branch #{branch_name}" )
|
|
127
127
|
return nil if error_text.downcase.include?( "no pull requests found" )
|
|
@@ -54,7 +54,7 @@ module Carson
|
|
|
54
54
|
def gather_status
|
|
55
55
|
repository = repository_record
|
|
56
56
|
branch = branch_record
|
|
57
|
-
deliveries = ledger.active_deliveries( repo_path:
|
|
57
|
+
deliveries = ledger.active_deliveries( repo_path: repository.path )
|
|
58
58
|
|
|
59
59
|
{
|
|
60
60
|
version: Carson::VERSION,
|
data/lib/carson/runtime.rb
CHANGED
|
@@ -87,8 +87,11 @@ module Carson
|
|
|
87
87
|
end
|
|
88
88
|
|
|
89
89
|
# Passive repository record for the current runtime context.
|
|
90
|
+
# Uses main_worktree_root so the repo_path stored in the ledger is always the
|
|
91
|
+
# canonical main tree path, regardless of which worktree the command runs from.
|
|
92
|
+
# This ensures govern (which looks up by main tree path) finds worktree deliveries.
|
|
90
93
|
def repository_record
|
|
91
|
-
Repository.new( path:
|
|
94
|
+
Repository.new( path: main_worktree_root, authority: config.govern_authority, runtime: self )
|
|
92
95
|
end
|
|
93
96
|
|
|
94
97
|
# Passive branch record for the current checkout.
|