carson 4.3.0 → 4.3.2

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: 5d25d50d20c3cc3244b3ab246ca7f5b661e097146993fee1cc5b8dd66f978938
4
- data.tar.gz: 1d2f6a26fc79dc62688c409557f2b74328f593f2e582af17c4a6fa020bb1b75b
3
+ metadata.gz: cef1919871b9d457a8b1ad95b2faa127cbb1a740fa211bf48e1b18110141be5a
4
+ data.tar.gz: bd4f1107862848b8a60d5ef794f43127a6b8f14146ed781bfe72d841220f4190
5
5
  SHA512:
6
- metadata.gz: 234de9b2d4bad297af4b7bf24bd396629690bde5925fa743d9438316dcbb146f88e444b0aed61a72c022de32e34ba09aeedfb078afc4711973437eb5a38e6279
7
- data.tar.gz: 2d3438c23a8146367289413e28d756eee5cb303c58c5820273f471482a83f351d0fc379a3db01a6edbbcdd5f13afbce508b8f999344d0e295dfb6fd74c816f88
6
+ metadata.gz: c4047e729026abc15be0601316a3521249cdc392c60b24b6ebf61bf5454746d48d649f16f2cda705e5a01ed2c9cce91ac2b407fd8d10ad670453fd2d0742d243
7
+ data.tar.gz: 9dee7343ec14dbf351fce53e0da6b406e52fe64bb71e736bb70ad23dc22c2e82013d34705d901d7b304d79b6cb40ef1cb8cc0c3412da9796ab6d853e81648156
@@ -62,10 +62,6 @@ jobs:
62
62
  working-directory: host
63
63
  run: carson refresh
64
64
 
65
- - name: Carson audit
66
- working-directory: host
67
- run: carson audit
68
-
69
65
  - name: Carson review gate
70
66
  working-directory: host
71
67
  env:
data/API.md CHANGED
@@ -21,7 +21,7 @@ Repo-scoped commands: `carson <repo> <command>` or `carson <command>` when CWD i
21
21
  |---|---|
22
22
  | `carson setup` | Interactive quiz to configure remote, main branch, workflow, and canonical lint-policy path. Writes `~/.carson/config.json`. |
23
23
  | `carson onboard <repo_path>` | Apply one-command baseline setup for a target git repository. Auto-triggers `setup` on first run. Installs or refreshes Carson-managed global hooks. |
24
- | `carson refresh` | Re-apply hooks, templates, and audit across all governed repos after upgrading Carson. Auto-propagates template updates to the remote via worktree (branch workflow: PR on `carson/template-sync`; trunk workflow: push to main). Skips repos with active worktrees or uncommitted changes. |
24
+ | `carson refresh` | Re-apply hooks and templates across all governed repos after upgrading Carson. Auto-propagates template updates to the remote via worktree (branch workflow: PR on `carson/template-sync`; trunk workflow: push to main). Skips repos with active worktrees or uncommitted changes. |
25
25
  | `carson offboard <repo_path>` | Remove Carson-managed host artefacts, detach Carson hooks path, and deregister from `govern.repos`. |
26
26
  | `carson list [--json]` | List all governed repositories. |
27
27
 
@@ -29,9 +29,8 @@ Repo-scoped commands: `carson <repo> <command>` or `carson <command>` when CWD i
29
29
 
30
30
  | Command | Purpose |
31
31
  |---|---|
32
- | `carson audit` | Evaluate governance status and generate report output. |
33
32
  | `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. Before push, Carson verifies the branch is fresh against the configured remote `main`; behind or unknown freshness blocks delivery without creating or refreshing a PR. If freshness is good, Carson pushes, creates or refreshes the PR, watches the delivery for a bounded settle window, merges when clear, syncs local `main`, and reports merge proof for the delivered branch. Non-integrated exits report `Merge deferred` or `Merge blocked` with explicit handoff commands. |
34
- | `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. |
33
+ | `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, and merges through the recovery path. |
35
34
  | `carson sync` | Fast-forward local `main` from configured remote when tree is clean. |
36
35
  | `carson prune` | Remove stale local branches whose upstream refs no longer exist. |
37
36
  | `carson housekeep [--json] [--dry-run]` | Attempt to sync the current repo, then reap worktrees with strong abandonment evidence, reconcile integrated delivery worktree records from the ledger, and prune stale branches. Safe cleanup still runs when sync is blocked. |
data/MANUAL.md CHANGED
@@ -40,7 +40,7 @@ On first run (no `~/.carson/config.json` exists), `onboard` launches `carson set
40
40
  - Repository `core.hooksPath` alignment to Carson global hooks.
41
41
  - Commit-time governance gate via managed `pre-commit` hook.
42
42
  - Canonical `.github/*` template synchronisation (when `lint.canonical` is configured).
43
- - Initial governance audit.
43
+ - Initial governance status check.
44
44
 
45
45
  ### Reconfigure later
46
46
 
@@ -78,7 +78,7 @@ jobs:
78
78
  Notes:
79
79
  - When upgrading Carson, update both `carson_ref` and `carson_version` together.
80
80
  - `CARSON_READ_TOKEN` must have read access to your policy source repository.
81
- - The reusable workflow installs a pinned RuboCop gem before `carson audit`; mirror the same pin in host governance workflows for deterministic checks.
81
+ - The reusable workflow installs a pinned RuboCop gem before lint checks; mirror the same pin in host governance workflows for deterministic checks.
82
82
 
83
83
  ### Canonical Templates
84
84
 
@@ -112,7 +112,7 @@ Carson discovers files in this directory and syncs them to governed repos. Root
112
112
 
113
113
  ## Operating Strategies
114
114
 
115
- These strategies are the audit lens for Carson. If behaviour departs from them, either the product model or the implementation needs attention.
115
+ These strategies are the design lens for Carson. If behaviour departs from them, either the product model or the implementation needs attention.
116
116
 
117
117
  ### Git Strategist
118
118
 
@@ -181,7 +181,7 @@ When a governance-owned required check is already red on the default branch, the
181
181
  carson recover --check "Carson governance"
182
182
  ```
183
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.
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 recovery event before reporting success.
185
185
 
186
186
  If Carson refuses recovery, the message explains the exact missing proof or remaining gate and tells you what to do next.
187
187
 
@@ -255,13 +255,13 @@ The two tools serve different layers. EnterWorktree owns the session (CWD switch
255
255
 
256
256
  ```bash
257
257
  carson sync # fast-forward local main
258
- carson audit # full governance check
258
+ carson status # check repository state
259
259
  ```
260
260
 
261
261
  **Before push or PR update:**
262
262
 
263
263
  ```bash
264
- carson audit
264
+ carson status
265
265
  carson template check
266
266
  ```
267
267
 
@@ -287,7 +287,7 @@ carson list --json # machine-readable output
287
287
  **Portfolio maintenance:**
288
288
 
289
289
  ```bash
290
- carson refresh # re-apply hooks, templates, audit across all repos
290
+ carson refresh # re-apply hooks and templates across all repos
291
291
  carson list # list all governed repositories
292
292
  ```
293
293
 
@@ -411,7 +411,7 @@ Change: `CARSON_REVIEW_DISPOSITION`.
411
411
 
412
412
  How much Carson prints.
413
413
 
414
- - Default: **concise**. A healthy audit prints one line. Problems print actionable summaries with cause and fix.
414
+ - Default: **concise**. A healthy run prints one line. Problems print actionable summaries with cause and fix.
415
415
  - `--verbose` restores full diagnostic key-value output for debugging.
416
416
 
417
417
  ## Configuration
data/README.md CHANGED
@@ -66,7 +66,7 @@ carson housekeep
66
66
 
67
67
  `carson deliver` runs Carson-owned branch delivery. Before any push, Carson verifies that the branch is fresh against the configured remote `main` using local git. If freshness is behind or unknown, delivery stops with an explicit block and no PR side effect. After a PR exists, Carson delegates merge eligibility to GitHub's `mergeStateStatus` — if GitHub reports `CLEAN`, Carson proceeds regardless of local ancestor status. Plain `deliver` transports existing commits only; `carson deliver --commit "..."` creates one all-dirty delivery commit first, then continues the same flow. If the branch is fresh, Carson pushes it, creates or refreshes the PR, watches the delivery for a bounded settle window, merges when clear, and syncs local `main`. If the settle window expires without integration, Carson exits with an explicit `Merge deferred` or `Merge blocked` handoff instead of leaving the PR mysteriously open. Deferred and blocked exits say whether Carson attempted merge and list the next commands in order.
68
68
 
69
- 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.
69
+ 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 a recovery event, and never teaches operators to step outside Carson first.
70
70
 
71
71
  `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. Content matching `main` is diagnostic, not standalone proof that a worktree is abandoned. `carson housekeep` is the main cleanup pass: sync main, reap worktrees with strong abandonment evidence (for example a missing directory, merged PR, or closed abandoned PR), and prune stale branches. 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
72
 
data/RELEASE.md CHANGED
@@ -7,6 +7,37 @@ Release-note scope rule:
7
7
 
8
8
  ## Unreleased
9
9
 
10
+ ### Removed
11
+
12
+ - **`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.
13
+
14
+ ### Why
15
+
16
+ Audit was a remote-centred pre-commit gate — it blocked commits based on delivery-time concerns (PR checks, CI baseline) that don't belong at commit time. In local-centred mode it was purely dead weight. Rather than relocate it to bureau, we verified that none of its unique checks had proven value at any gate, and dissolved the whole thing. Scars, not speculation.
17
+
18
+ ## 4.3.2
19
+
20
+ ### Fixed
21
+
22
+ - **Vault gives correct recovery when main worktree is dirty.** `vault_blocked` now inspects stderr from `git merge --ff-only` to distinguish dirty-tree conflicts from diverged-history blocks. Previously, both cases got the generic "rebase" advice — misleading when the branch was already a valid fast-forward descendant and the real problem was uncommitted files in the main worktree.
23
+
24
+ ### Why
25
+
26
+ An agent rebased three times on an already-correct branch because Carson misdiagnosed a dirty-tree block as divergence. The fix: read stderr, give the right advice. Scars, not speculation.
27
+
28
+ ## 4.3.1
29
+
30
+ ### Changed
31
+
32
+ - **Bureau is an enhancement, not a mode.** Config simplified from `workstyle: local/remote` to `bureau: true/false` (default: false). Local delivery is always the foundation. Bureau adds PR + CI on top.
33
+ - **Pre-push hook simplified to no-op.** Pushes to main are always legitimate — local delivery is the base. The hook no longer needs workstyle detection or push guards.
34
+ - **Parcel-on-main guard added.** `carson deliver` blocks when run from main itself — agents must work on a workbench.
35
+ - **Output: "Synced to remote"** replaces "Pushed to remote". Sync is objective.
36
+
37
+ ### Why
38
+
39
+ The key insight: remote-centred is not a different path — it's local delivery with Bureau enhancement bolted on. One path, optional layer. `workstyle` dissolved into a single `bureau` toggle. 72 insertions, 166 deletions.
40
+
10
41
  ## 4.3.0
11
42
 
12
43
  ### New
data/VERSION CHANGED
@@ -1 +1 @@
1
- 4.3.0
1
+ 4.3.2
@@ -1,19 +1,4 @@
1
1
  #!/usr/bin/env bash
2
2
  set -euo pipefail
3
-
4
- if [[ -n "${CARSON_BIN:-}" ]]; then
5
- carson_command=( "$CARSON_BIN" )
6
- elif command -v carson >/dev/null 2>&1; then
7
- carson_command=( "carson" )
8
- else
9
- echo "Carson policy: 'carson' command is required for pre-commit governance checks." >&2
10
- echo "Install Carson and rerun 'carson prepare'." >&2
11
- exit 1
12
- fi
13
-
14
- if ! "${carson_command[@]}" audit; then
15
- echo "Carson policy: commit blocked by governance audit." >&2
16
- echo "Resolve reported policy blocks before committing." >&2
17
- echo "If lint policy files are missing, run: carson lint policy --source <path-or-git-url>" >&2
18
- exit 1
19
- fi
3
+ # Pre-commit hook — reserved for future use.
4
+ exit 0
@@ -1,60 +1,14 @@
1
1
  #!/usr/bin/env bash
2
- # Carson pre-push hook — enforces push policy in governed repositories.
2
+ # Carson pre-push hook.
3
3
  #
4
- # Guards:
5
- # 1. Blocks direct push to main/master refs.
6
- # 2. Blocks raw git push in governed repos agents must use `carson deliver`.
7
- # Carson bypasses via --no-verify internally. No env-var signal to spoof.
4
+ # Local delivery is always the base — pushes to main are legitimate.
5
+ # When bureau enhancement is enabled, the Bureau path runs through
6
+ # Runtime.deliver!, not through raw git push. So the hook has nothing
7
+ # to enforce in either case.
8
8
  #
9
- # Bypass: git push --no-verify
9
+ # The hook remains installed for future use (e.g. bureau-specific guards).
10
+ # For now: consume stdin and exit.
10
11
  set -euo pipefail
11
12
 
12
- hooks_dir="$(cd "$(dirname "$0")" && pwd)"
13
- style="$(cat "$hooks_dir/workflow_style" 2>/dev/null || echo "branch")"
14
- [ "$style" = "trunk" ] && exit 0
15
-
16
- # --- Guard 1: block pushes to main/master refs ---
17
-
18
- remote_name="${1:-unknown}"
19
- remote_url="${2:-unknown}"
20
- has_commit_push=false
21
- while read -r local_ref local_sha remote_ref remote_sha; do
22
- case "$remote_ref" in
23
- refs/heads/main|refs/heads/master)
24
- echo "Pushes to ${remote_ref#refs/heads/} go through PRs, not direct push." >&2
25
- echo "Use \`carson deliver\` instead — it handles push, PR, and merge with safety guards." >&2
26
- echo "Bypass: git push --no-verify" >&2
27
- exit 1
28
- ;;
29
- esac
30
- [[ "$local_sha" != "0000000000000000000000000000000000000000" ]] && has_commit_push=true
31
- done
32
-
33
- # --- Guard 2: block raw git push in governed repos ---
34
- # All pushes in governed repos are blocked unconditionally.
35
- # Carson bypasses this hook via --no-verify when pushing internally.
36
- # No env-var bypass — cannot be spoofed.
37
-
38
- config_file="${HOME}/.carson/config.json"
39
- if [[ -f "$config_file" ]]; then
40
- repo_root="$(git rev-parse --show-toplevel 2>/dev/null || echo "")"
41
- if [[ -n "$repo_root" ]]; then
42
- normalised="$(cd "$repo_root" && pwd -P)"
43
- if grep -qF "\"$normalised\"" "$config_file" 2>/dev/null; then
44
- echo "This repo is Carson-governed — use \`carson deliver\` instead of raw \`git push\`." >&2
45
- echo "Use \`carson deliver\` instead — it handles push, PR, and merge with safety guards." >&2
46
- echo "Bypass: git push --no-verify" >&2
47
- exit 1
48
- fi
49
- fi
50
- fi
51
-
52
- # --- Template sync on push ---
53
-
54
- if $has_commit_push; then
55
- if [[ -n "${CARSON_BIN:-}" ]]; then
56
- ruby "$CARSON_BIN" template apply --push-prep || exit 1
57
- else
58
- carson template apply --push-prep || exit 1
59
- fi
60
- fi
13
+ cat > /dev/null
14
+ exit 0
@@ -3,7 +3,7 @@ module Carson
3
3
  module Adapters
4
4
  module Agent
5
5
  WorkOrder = Struct.new( :repo, :branch, :pr_number, :objective, :context, :acceptance_checks, keyword_init: true )
6
- # objective: "fix_ci" | "address_review" | "fix_audit"
6
+ # objective: "fix_ci" | "address_review"
7
7
  # context: String (legacy — PR title) or Hash with structured evidence:
8
8
  # fix_ci: { title:, ci_logs:, ci_run_url:, prior_attempt: { summary:, dispatched_at: } }
9
9
  # address_review: { title:, review_findings: [{ kind:, url:, body: }], prior_attempt: ... }
data/lib/carson/config.rb CHANGED
@@ -28,13 +28,12 @@ module Carson
28
28
  :review_wait_seconds, :review_poll_seconds, :review_max_polls, :review_sweep_window_days,
29
29
  :review_sweep_states, :review_disposition, :review_risk_keywords,
30
30
  :review_tracking_issue_title, :review_tracking_issue_label, :review_bot_usernames,
31
- :audit_advisory_check_names,
32
31
  :workflow_style,
33
32
  :govern_repos, :govern_merge_method,
34
33
  :govern_agent_provider, :govern_state_path,
35
34
  :govern_check_wait,
36
35
  :poll_interval_at_bureau,
37
- :workstyle
36
+ :bureau
38
37
 
39
38
  def self.load( repo_root: )
40
39
  base_data = default_data
@@ -80,13 +79,10 @@ module Carson
80
79
  "label" => "carson-review-sweep"
81
80
  }
82
81
  },
83
- "audit" => {
84
- "advisory_check_names" => [ "Scheduled review sweep", "Carson governance", "Tag, release, publish" ]
85
- },
86
82
  "deliver" => {
87
83
  "poll_interval_at_bureau" => 30
88
84
  },
89
- "workstyle" => "local",
85
+ "bureau" => false,
90
86
  "govern" => {
91
87
  "repos" => [],
92
88
  "merge" => {
@@ -170,9 +166,6 @@ module Carson
170
166
  sweep[ "states" ] = states unless states.empty?
171
167
  bot_usernames = env_string_array( key: "CARSON_REVIEW_BOT_USERNAMES" )
172
168
  review[ "bot_usernames" ] = bot_usernames unless bot_usernames.empty?
173
- audit = fetch_hash_section( data: copy, key: "audit" )
174
- advisory_names = env_string_array( key: "CARSON_AUDIT_ADVISORY_CHECK_NAMES" )
175
- audit[ "advisory_check_names" ] = advisory_names unless advisory_names.empty?
176
169
  deliver = fetch_hash_section( data: copy, key: "deliver" )
177
170
  deliver[ "poll_interval_at_bureau" ] = env_integer( key: "CARSON_POLL_INTERVAL_AT_BUREAU", fallback: deliver.fetch( "poll_interval_at_bureau" ) )
178
171
  govern = fetch_hash_section( data: copy, key: "govern" )
@@ -243,14 +236,10 @@ module Carson
243
236
  @review_tracking_issue_title = fetch_string( hash: tracking_issue_hash, key: "title" )
244
237
  @review_tracking_issue_label = fetch_string( hash: tracking_issue_hash, key: "label" )
245
238
  @review_bot_usernames = fetch_optional_string_array( hash: review_hash, key: "bot_usernames" )
246
- audit_hash = fetch_hash( hash: data, key: "audit" )
247
- @audit_advisory_check_names = fetch_optional_string_array( hash: audit_hash, key: "advisory_check_names" )
248
-
249
239
  deliver_hash = fetch_hash( hash: data, key: "deliver" )
250
240
  @poll_interval_at_bureau = fetch_non_negative_integer( hash: deliver_hash, key: "poll_interval_at_bureau" )
251
241
 
252
- workstyle_raw = data.fetch( "workstyle", "local" ).to_s.downcase
253
- @workstyle = [ "local", "remote" ].include?( workstyle_raw ) ? workstyle_raw.to_sym : :local
242
+ @bureau = !!data.fetch( "bureau", false )
254
243
 
255
244
  govern_hash = fetch_hash( hash: data, key: "govern" )
256
245
  @govern_repos = fetch_optional_string_array( hash: govern_hash, key: "repos" ).map { |path| safe_expand_path( path ) }
@@ -64,11 +64,10 @@ module Carson
64
64
  # == Workstyle
65
65
  #
66
66
  # The courier's gesture depends on the workstyle:
67
- # - :local push main to backup vault (simple, no PR, no waiting)
68
- # - :remote ship waybill → bureau acceptance (complex Bureau trip)
69
- #
70
- # The courier doesn't know whether it's doing "backup" or "primary" —
71
- # it just delivers to wherever the workstyle dictates.
67
+ # The courier delivers parcels. The default gesture is local: sync the
68
+ # vault to the remote. When bureau enhancement is enabled, the courier
69
+ # also files a PR and waits for Bureau checks — but that path runs
70
+ # through Runtime.deliver!, not through this default gesture.
72
71
  class Courier
73
72
  # Exit codes — shared contract between Carson employees and the CLI.
74
73
  OK = 0
@@ -80,9 +79,9 @@ module Carson
80
79
  # The courier checks the bureau up to 6 times before leaving.
81
80
  MAX_CHECKS_AT_BUREAU = 6
82
81
 
83
- def initialize( warehouse, workstyle: :local, ledger: nil, merge_method: "rebase", poll_interval_at_bureau: 30, output: $stdout )
82
+ def initialize( warehouse, bureau: false, ledger: nil, merge_method: "rebase", poll_interval_at_bureau: 30, output: $stdout )
84
83
  @warehouse = warehouse
85
- @workstyle = workstyle
84
+ @bureau = bureau
86
85
  @ledger = ledger
87
86
  @merge_method = merge_method
88
87
  @poll_interval_at_bureau = poll_interval_at_bureau
@@ -90,10 +89,10 @@ module Carson
90
89
  end
91
90
 
92
91
  # Deliver a parcel.
93
- # Local gesture: push main to backup vault.
94
- # Remote gesture: ship to Bureau, file waybill, poll, register.
92
+ # Default: sync the vault to the remote.
93
+ # Bureau enhancement: also file waybill, poll, register.
95
94
  def deliver( parcel, title: nil, body_file: nil, commit_message: nil )
96
- return deliver_locally( parcel ) if @workstyle == :local
95
+ return deliver_locally( parcel ) unless @bureau
97
96
 
98
97
  result = {
99
98
  command: "deliver",
@@ -255,9 +254,9 @@ module Carson
255
254
  result[ :diagnostic ] = waybill.ci_diagnostic
256
255
  end
257
256
 
258
- # Local gesture: push main to the backup vault.
257
+ # Local gesture: sync the vault to the remote.
259
258
  # The parcel is already in the vault (accepted by the Warehouse).
260
- # The courier's job is to push the vault state to the remote backup.
259
+ # The courier's job is to push the vault state to the remote.
261
260
  def deliver_locally( parcel )
262
261
  result = {
263
262
  command: "deliver",
@@ -269,11 +268,9 @@ module Carson
269
268
  main = @warehouse.main_label
270
269
  root = @warehouse.main_worktree_root
271
270
 
272
- # --no-verify bypasses the pre-push hook that blocks direct pushes
273
- # to main in governed repos. This IS Carson's delivery — the vault
274
- # accepted the parcel, now the courier backs it up.
271
+ # The pre-push hook understands local workstyle — no bypass needed.
275
272
  _, stderr, status = Open3.capture3(
276
- "git", "-C", root, "push", "--no-verify", remote, main
273
+ "git", "-C", root, "push", remote, main
277
274
  )
278
275
 
279
276
  if status.success?
@@ -284,7 +281,7 @@ module Carson
284
281
  result[ :exit ] = OK
285
282
  result[ :outcome ] = "delivered"
286
283
  result[ :synced ] = false
287
- result[ :backup_error ] = stderr.strip
284
+ result[ :sync_error ] = stderr.strip
288
285
  end
289
286
 
290
287
  result
@@ -20,7 +20,7 @@ module Carson
20
20
  head: current_head
21
21
  )
22
22
  courier = Courier.new( warehouse,
23
- workstyle: :remote,
23
+ bureau: true,
24
24
  ledger: ledger,
25
25
  merge_method: config.govern_merge_method,
26
26
  poll_interval_at_bureau: config.poll_interval_at_bureau,
@@ -1,12 +1,12 @@
1
1
  # Repository onboarding and refresh lifecycle.
2
- # Onboard: detect remote, install hooks, apply templates, run initial audit.
2
+ # Onboard: detect remote, install hooks, apply templates.
3
3
  # Refresh: re-apply hooks and templates after Carson upgrade.
4
4
  # Refresh all: batch refresh across governed portfolio with safety checks.
5
5
  module Carson
6
6
  class Runtime
7
7
  module Local
8
8
  # One-command onboarding for new repositories: detect remote, install hooks,
9
- # apply templates, and run initial audit.
9
+ # and apply templates.
10
10
  def onboard!
11
11
  fingerprint_status = block_if_outsider_fingerprints!
12
12
  return fingerprint_status unless fingerprint_status.nil?
@@ -32,7 +32,7 @@ module Carson
32
32
  onboard_apply!
33
33
  end
34
34
 
35
- # Re-applies hooks, templates, and audit after upgrading Carson.
35
+ # Re-applies hooks and templates after upgrading Carson.
36
36
  def refresh!
37
37
  fingerprint_status = block_if_outsider_fingerprints!
38
38
  return fingerprint_status unless fingerprint_status.nil?
@@ -55,13 +55,8 @@ module Carson
55
55
 
56
56
  @template_sync_result = template_propagate!( drift_count: drift_count + stale_count )
57
57
 
58
- audit_status = audit!
59
- if audit_status == EXIT_OK
60
- puts_line "OK: Carson refresh completed for #{repo_root}."
61
- elsif audit_status == EXIT_BLOCK
62
- puts_line "Refresh complete — some checks need attention. Run carson audit for details."
63
- end
64
- return audit_status
58
+ puts_line "OK: Carson refresh completed for #{repo_root}."
59
+ return EXIT_OK
65
60
  end
66
61
 
67
62
  puts_line "Refresh"
@@ -82,12 +77,11 @@ module Carson
82
77
 
83
78
  @template_sync_result = template_propagate!( drift_count: total_drift )
84
79
 
85
- audit_status = audit!
86
80
  puts_line "Refresh complete."
87
- audit_status
81
+ EXIT_OK
88
82
  end
89
83
 
90
- # Re-applies hooks, templates, and audit across all governed repositories.
84
+ # Re-applies hooks and templates across all governed repositories.
91
85
  # Checks each repo for safety (active worktrees, uncommitted changes) and
92
86
  # marks unsafe repos as pending to avoid disrupting active work.
93
87
  def refresh_all!
@@ -202,7 +196,7 @@ module Carson
202
196
 
203
197
  private
204
198
 
205
- # Concise onboard orchestration: hooks, templates, remote, audit, guidance.
199
+ # Concise onboard orchestration: hooks, templates, remote, guidance.
206
200
  def onboard_apply!
207
201
  hook_status = with_captured_output { prepare! }
208
202
  return hook_status unless hook_status == EXIT_OK
@@ -218,7 +212,6 @@ module Carson
218
212
  end
219
213
 
220
214
  onboard_report_remote!
221
- audit_status = onboard_run_audit!
222
215
 
223
216
  puts_line ""
224
217
  puts_line "Carson at your service."
@@ -235,7 +228,7 @@ module Carson
235
228
  puts_line ""
236
229
  puts_line "To adjust any setting: carson setup"
237
230
 
238
- audit_status
231
+ EXIT_OK
239
232
  end
240
233
 
241
234
  # Friendly remote status for onboard output.
@@ -247,33 +240,6 @@ module Carson
247
240
  end
248
241
  end
249
242
 
250
- # Runs audit with captured output; reports summary instead of full detail.
251
- def onboard_run_audit!
252
- audit_error = nil
253
- audit_status = with_captured_output { audit! }
254
- rescue StandardError => exception
255
- audit_error = exception
256
- audit_status = EXIT_OK
257
- ensure
258
- return onboard_print_audit_result( status: audit_status, error: audit_error )
259
- end
260
-
261
- def onboard_print_audit_result( status:, error: )
262
- if error
263
- if error.message.to_s.match?( /HEAD|rev-parse/ )
264
- puts_line "No commits yet — run carson audit after your first commit."
265
- else
266
- puts_line "Audit skipped — run carson audit for details."
267
- end
268
- return EXIT_OK
269
- end
270
-
271
- if status == EXIT_BLOCK
272
- puts_line "Some checks need attention — run carson audit for details."
273
- end
274
- status
275
- end
276
-
277
243
  # Verifies configured remote exists and logs status without mutating remotes.
278
244
  def report_detected_remote!
279
245
  if git_remote_exists?( remote_name: config.git_remote )
@@ -365,7 +365,7 @@ module Carson
365
365
  case cause
366
366
  when "ci" then "fix_ci"
367
367
  when "review" then "address_review"
368
- else "fix_audit"
368
+ else "fix_ci"
369
369
  end
370
370
  end
371
371
 
@@ -84,14 +84,14 @@ module Carson
84
84
  }
85
85
  if baseline.fetch( :status ) == "skipped"
86
86
  result[ :error ] = "unable to verify the default-branch baseline: #{baseline.fetch( :skip_reason )}"
87
- result[ :recovery ] = "run carson audit after fixing GitHub access"
87
+ result[ :recovery ] = "run carson status after fixing GitHub access"
88
88
  return recover_finish( result: result, exit_code: EXIT_ERROR, json_output: json_output )
89
89
  end
90
90
 
91
91
  baseline_entry = recovery_baseline_entry( baseline: baseline, check_name: check_name )
92
92
  if baseline_entry.nil?
93
93
  result[ :error ] = "#{check_name} is not red on #{baseline.fetch( :default_branch, config.main_branch )}"
94
- result[ :recovery ] = "run carson audit to confirm the baseline check state"
94
+ result[ :recovery ] = "run carson status to confirm the baseline check state"
95
95
  return recover_finish( result: result, exit_code: EXIT_BLOCK, json_output: json_output )
96
96
  end
97
97
 
@@ -408,7 +408,7 @@ module Carson
408
408
  elsif result[ :synced ]
409
409
  puts_line "Synced local #{result.fetch( :main_branch )}."
410
410
  end
411
- puts_line "Recorded recovery audit for #{result.fetch( :check )}."
411
+ puts_line "Recorded recovery for #{result.fetch( :check )}."
412
412
  puts_line "Check back with #{result.fetch( :next_step )}" if result[ :next_step ]
413
413
  end
414
414
  end
@@ -163,7 +163,7 @@ module Carson
163
163
  }
164
164
  end
165
165
 
166
- # When sweep is clear, close prior tracking issue and add one clear audit comment.
166
+ # When sweep is clear, close prior tracking issue and add a clear comment.
167
167
  def close_review_sweep_issue_if_open( repo_slug:, issue: )
168
168
  return { action: "none", issue: nil } if issue.nil?
169
169
  return { action: "none", issue: issue } unless issue.fetch( :state ) == "OPEN"
@@ -14,8 +14,6 @@ module Carson
14
14
  EXIT_ERROR = 1
15
15
  EXIT_BLOCK = 2
16
16
 
17
- REPORT_MD = "pr_report_latest.md".freeze
18
- REPORT_JSON = "pr_report_latest.json".freeze
19
17
  REVIEW_GATE_REPORT_MD = "review_gate_latest.md".freeze
20
18
  REVIEW_GATE_REPORT_JSON = "review_gate_latest.json".freeze
21
19
  REVIEW_SWEEP_REPORT_MD = "review_sweep_latest.md".freeze
@@ -43,7 +41,7 @@ module Carson
43
41
  attr_reader :template_sync_result
44
42
 
45
43
  # Lazy ledger: only constructed when a command actually needs delivery state.
46
- # Read-only commands (worktree list, audit, prune, sync) never touch the
44
+ # Read-only commands (worktree list, prune, sync) never touch the
47
45
  # govern state lock file.
48
46
  def ledger
49
47
  @ledger ||= Ledger.new( path: @config.govern_state_path )
@@ -115,7 +113,7 @@ module Carson
115
113
  success
116
114
  end
117
115
 
118
- # Human-readable plural suffix helper for audit messaging.
116
+ # Human-readable plural suffix helper.
119
117
  def plural_suffix( count: )
120
118
  count.to_i == 1 ? "" : "s"
121
119
  end
@@ -366,7 +364,6 @@ module Carson
366
364
  end
367
365
 
368
366
  require_relative "runtime/local"
369
- require_relative "runtime/audit"
370
367
  require_relative "runtime/loop_runner"
371
368
  require_relative "runtime/housekeep"
372
369
  require_relative "runtime/list"
@@ -63,12 +63,22 @@ module Carson
63
63
  end
64
64
 
65
65
  # Build the blocked/error result when vault acceptance fails.
66
+ # Distinguishes dirty-tree conflicts from diverged-history blocks
67
+ # so the agent gets the correct recovery advice.
66
68
  def vault_blocked( parcel, stderr )
67
- {
68
- status: "block",
69
- error: "#{parcel.label} cannot be fast-forwarded into #{@main_label}.",
70
- recovery: "Rebase onto #{@main_label} and deliver again."
71
- }
69
+ if stderr.to_s.include?( "would be overwritten" )
70
+ {
71
+ status: "block",
72
+ error: "Main worktree has uncommitted changes that conflict with #{parcel.label}.",
73
+ recovery: "Commit or discard the dirty files in the main worktree, then deliver again."
74
+ }
75
+ else
76
+ {
77
+ status: "block",
78
+ error: "#{parcel.label} cannot be fast-forwarded into #{@main_label}.",
79
+ recovery: "Rebase onto #{@main_label} and deliver again."
80
+ }
81
+ end
72
82
  end
73
83
 
74
84
  end