@uchibeke/gallivant 0.2.0 → 0.3.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.
Files changed (133) hide show
  1. package/README.md +120 -60
  2. package/SECURITY.md +9 -0
  3. package/bin/gallivant.mjs +41 -14
  4. package/bin/promote-bitbucket.mjs +40 -0
  5. package/bin/task-pr.mjs +9 -0
  6. package/bin/task-review.mjs +15 -0
  7. package/docs/README.md +6 -2
  8. package/docs/agent-setup.md +55 -41
  9. package/docs/architecture.md +11 -3
  10. package/docs/bitbucket-promotion.md +69 -0
  11. package/docs/bitbucket-review.md +330 -0
  12. package/docs/chains.md +30 -1
  13. package/docs/codex-cloud.md +7 -0
  14. package/docs/codex-review.md +50 -0
  15. package/docs/commands.md +103 -14
  16. package/docs/config.md +45 -13
  17. package/docs/execution.md +1 -1
  18. package/docs/first-party-review.md +266 -0
  19. package/docs/git-hosts.md +294 -0
  20. package/docs/guardrails.md +56 -0
  21. package/docs/install.md +137 -67
  22. package/docs/launch.md +7 -4
  23. package/docs/network-recovery.md +9 -0
  24. package/docs/openai-agents.md +3 -2
  25. package/docs/prd.md +23 -2
  26. package/docs/preparation.md +2 -2
  27. package/docs/release-qualification.md +1 -1
  28. package/docs/releasing.md +46 -22
  29. package/docs/task-delivery.md +5 -5
  30. package/docs/task-profiles.md +537 -0
  31. package/docs/tasks.md +59 -197
  32. package/lib/attribution.mjs +7 -3
  33. package/lib/block.mjs +10 -1
  34. package/lib/chains.mjs +101 -30
  35. package/lib/codex_cloud.mjs +2 -1
  36. package/lib/codex_cloud_input.mjs +15 -6
  37. package/lib/codex_cloud_result.mjs +1 -1
  38. package/lib/commands/doctor.mjs +22 -453
  39. package/lib/commands/init.mjs +281 -28
  40. package/lib/commands/register.mjs +81 -13
  41. package/lib/commands/resume.mjs +5 -1
  42. package/lib/commands/review.mjs +66 -0
  43. package/lib/commands/serve.mjs +8 -0
  44. package/lib/commands/start.mjs +30 -11
  45. package/lib/commands/status.mjs +18 -2
  46. package/lib/commands/task.mjs +9 -1
  47. package/lib/commands/up.mjs +19 -11
  48. package/lib/commands/why.mjs +7 -3
  49. package/lib/config.mjs +42 -9
  50. package/lib/context.mjs +28 -21
  51. package/lib/control.mjs +21 -6
  52. package/lib/credential.mjs +20 -14
  53. package/lib/deliverable.mjs +2 -0
  54. package/lib/events.mjs +96 -53
  55. package/lib/execution.mjs +132 -11
  56. package/lib/execution_preparation.mjs +16 -1
  57. package/lib/execution_result.mjs +26 -5
  58. package/lib/first_party_review.mjs +618 -0
  59. package/lib/fs.mjs +10 -3
  60. package/lib/gh.mjs +144 -56
  61. package/lib/git.mjs +133 -32
  62. package/lib/git_diff.mjs +121 -0
  63. package/lib/harness.mjs +14 -10
  64. package/lib/host_contract.mjs +71 -0
  65. package/lib/host_definitions.mjs +22 -0
  66. package/lib/hosts/bitbucket.mjs +553 -0
  67. package/lib/hosts/bitbucket_contract.mjs +57 -0
  68. package/lib/hosts/bitbucket_credential.mjs +62 -0
  69. package/lib/hosts/bitbucket_review.mjs +44 -0
  70. package/lib/hosts/bitbucket_review_producer.mjs +50 -0
  71. package/lib/hosts/github.mjs +57 -0
  72. package/lib/hosts/github_contract.mjs +27 -0
  73. package/lib/hosts/github_doctor.mjs +482 -0
  74. package/lib/hosts/github_review_summary.mjs +38 -0
  75. package/lib/hosts/transport_doctor.mjs +35 -0
  76. package/lib/hosts.mjs +130 -0
  77. package/lib/learning_qualification.mjs +1 -1
  78. package/lib/notify.mjs +1 -1
  79. package/lib/openai_agents_input.mjs +7 -2
  80. package/lib/openai_agents_sources.mjs +16 -8
  81. package/lib/plugin_package.mjs +13 -1
  82. package/lib/pr_operation.mjs +41 -0
  83. package/lib/prd.mjs +18 -3
  84. package/lib/preparation_codex.mjs +6 -1
  85. package/lib/probe.mjs +6 -4
  86. package/lib/process.mjs +24 -0
  87. package/lib/promotion.mjs +132 -0
  88. package/lib/promotion_git.mjs +63 -0
  89. package/lib/prompt.mjs +16 -13
  90. package/lib/provider_health.mjs +14 -3
  91. package/lib/repository.mjs +68 -0
  92. package/lib/repository_preflight.mjs +11 -0
  93. package/lib/review_evaluation.mjs +25 -0
  94. package/lib/review_evidence.mjs +500 -0
  95. package/lib/review_history.mjs +73 -0
  96. package/lib/review_image.mjs +145 -0
  97. package/lib/review_link.mjs +12 -0
  98. package/lib/review_policy.mjs +132 -0
  99. package/lib/review_policy_contract.mjs +18 -0
  100. package/lib/review_state.mjs +13 -0
  101. package/lib/review_visual.mjs +94 -0
  102. package/lib/runtime-environment.mjs +6 -0
  103. package/lib/runtime_node.mjs +3 -2
  104. package/lib/runtime_state.mjs +39 -5
  105. package/lib/sources/prd.mjs +6 -3
  106. package/lib/state.mjs +137 -24
  107. package/lib/task_completion.mjs +7 -3
  108. package/lib/task_contract.mjs +201 -27
  109. package/lib/task_delivery.mjs +9 -2
  110. package/lib/task_delivery_contract.mjs +13 -9
  111. package/lib/task_delivery_view.mjs +18 -2
  112. package/lib/task_environment.mjs +13 -1
  113. package/lib/task_limits.mjs +13 -0
  114. package/lib/task_model_config.mjs +99 -0
  115. package/lib/task_model_route.mjs +243 -0
  116. package/lib/task_prepare.mjs +21 -8
  117. package/lib/task_profile.mjs +1875 -0
  118. package/lib/task_repository_context.mjs +65 -0
  119. package/lib/tasks.mjs +252 -51
  120. package/lib/tick.mjs +373 -98
  121. package/lib/time.mjs +1 -0
  122. package/lib/tracker/pages.mjs +19 -5
  123. package/lib/tracker/review.mjs +21 -0
  124. package/lib/tracker_process.mjs +8 -1
  125. package/lib/verification_sandbox.mjs +2 -1
  126. package/lib/work_artifacts.mjs +79 -0
  127. package/npm-shrinkwrap.json +12 -3
  128. package/package.json +9 -3
  129. package/templates/plugin/task-delivery.SKILL.md +17 -10
  130. package/templates/plugin/task-intake-contract.json +18 -0
  131. package/templates/plugin/task-profile-requests.mjs +1448 -0
  132. package/templates/tracker/tracker.css +3 -0
  133. package/templates/tracker/tracker.js +38 -0
package/docs/chains.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # PRD chains
2
2
 
3
- **Gallivant automates delivery; humans approve integration.** A chain starts its next PRD only after GitHub confirms
3
+ **Gallivant automates delivery; humans approve integration.** A chain starts its next PRD only after the Git host confirms
4
4
  that the preceding PR was merged into the planned base branch. Gallivant never merges PRs. Passing tests, an accepted
5
5
  receipt, `ready-for-human`, and a finished agent session are progress toward that decision; none starts the next task.
6
6
 
@@ -38,6 +38,29 @@ the chain; closing any milestone's PR without merging stops it.
38
38
  The scope is deliberately linear: one repository, one base, one active milestone per chain. There is no dependency
39
39
  graph, stacked-PR mode or automatic merge. Unrelated tasks and other chains can run independently.
40
40
 
41
+ ## Continue after an existing PR
42
+
43
+ If the first task already has a registered PR, keep its current run and queue only the new work:
44
+
45
+ ```sh
46
+ gallivant chain launch --after https://github.com/your-org/your-repo/pull/123 docs/prds/launch.md
47
+ # A registered handle also works:
48
+ gallivant chain integration --after your-org/your-repo#123 docs/prds/integration.md docs/prds/next.md
49
+ ```
50
+
51
+ `--after` accepts a PR URL from a supported Git host or a registered run handle. Register the PR first if it is not
52
+ already tracked. At least one **new** ready PRD is required, in the same repository and approved base as the PR.
53
+ The predecessor is a dependency, not a newly started milestone: its session, review policy, counters and any existing
54
+ chain ownership stay unchanged. The usual `say`, `recheck` and `resume` commands still manage that run.
55
+
56
+ The chain records the exact registered PR, repository, branch and base. It waits for the author process to finish
57
+ and the host to confirm a merge, then checks that merge commit in both the remote base and the successor's clone.
58
+ An open PR marked ready does not release the dependency. A removed or retargeted registration, a closed unmerged PR,
59
+ or missing merge ancestry stops dispatch. Retry and resnapshot cannot replace the predecessor; cancel and create a
60
+ new chain to change it. Progress counts only the newly queued milestones and displays the predecessor separately.
61
+ Keep the predecessor registered until the chain finishes. Run a version supporting `--after` on every coordinator
62
+ using this home; do not downgrade while these chains remain active.
63
+
41
64
  ## Inspect progress
42
65
 
43
66
  ```sh
@@ -100,3 +123,9 @@ the ordinary review loop. It does not cancel or undo work that has already start
100
123
 
101
124
  Chain approval and unstarted milestones live in local `state.json`; unlike an open PR's identity, they cannot be
102
125
  reconstructed from GitHub. Preserve your Gallivant home when moving the daemon to another machine.
126
+
127
+ Repository identity, credential transport and PR evidence are defined by the
128
+ [Git host contract](git-hosts.md). GitHub and Bitbucket Cloud can dispatch;
129
+ Bitbucket's live no-reviewer path has been qualified on a disposable public
130
+ repository. Independent Bitbucket review remains unvalidated. Existing IDs and
131
+ chain ownership are retained without a state migration.
@@ -17,6 +17,13 @@ tasks remain available. Its implementation is offline tested; live qualification
17
17
  is **unverified**. Local Codex and `openai-agents` retain their existing defaults
18
18
  and continuation behavior.
19
19
 
20
+ The Git-based Cloud input transport cannot privately deliver new or changed carried
21
+ source files. It refuses before committing or pushing them; use a local harness or
22
+ `openai-agents` for those tasks. Existing repository files with unchanged bytes are
23
+ usable inputs. `publish_files` is only for output documents the operator explicitly
24
+ wants in the PR, never a workaround for publishing private task context. This remains
25
+ a separate limitation from the repository-binding requirement that currently disables dispatch.
26
+
20
27
  ## Trusted worker setup
21
28
 
22
29
  Use a trusted operator or self-hosted Node 22+ worker with persistent private
@@ -0,0 +1,50 @@
1
+ # Requesting and verifying Codex reviews
2
+
3
+ A Git push updates the pull-request head and can start CI. It does **not** by
4
+ itself request a new Codex review. In this repository's observed setup, automatic
5
+ review covers a newly opened pull request; a later head needs an explicit
6
+ `@codex review` comment. Security review is a separate request using
7
+ `@codex security review`. A quiet thread after a push is therefore not a clean
8
+ review result.
9
+
10
+ Gallivant's background review loop posts the configured
11
+ `reviewer.rereview_comment` after a fix run it dispatched. A manual push, a PR
12
+ outside that loop, or a branch reset does not inherit that behavior. Do not infer
13
+ that the daemon requested a review unless its comment is present on the PR.
14
+
15
+ ## Verify a review against the exact head
16
+
17
+ For every final push:
18
+
19
+ 1. Read the current PR head SHA from GitHub after the push.
20
+ 2. Post `@codex review`; also post `@codex security review` when the change
21
+ affects authorization, parsing, credentials, execution, or other security
22
+ boundaries.
23
+ 3. Wait for a Codex review receipt created after the request. Compare its
24
+ `commit_id` (and any `Reviewed commit` in the body) with the current GitHub
25
+ head SHA. For inline findings, compare each comment's `commit_id` too.
26
+ 4. Fix each finding or reply with a reproducible test showing why it does not
27
+ apply. After another push, request and verify both reviews again.
28
+
29
+ Example read-only checks:
30
+
31
+ ```bash
32
+ git rev-parse HEAD
33
+ gh pr view NUMBER --json headRefOid
34
+ gh api repos/OWNER/REPO/pulls/NUMBER/reviews \
35
+ --jq '.[] | {commit_id, submitted_at, state, body}'
36
+ gh api repos/OWNER/REPO/pulls/NUMBER/comments \
37
+ --jq '.[] | {commit_id, created_at, path, line, body}'
38
+ ```
39
+
40
+ An old inline thread can stay visible after later commits, and GitHub can retain
41
+ review records when a branch is reset to a previously seen SHA. Treat a record
42
+ as current only when its commit matches the live head and its timestamp follows
43
+ the current review request. A clean `reviewDecision`, an empty inline-comment
44
+ list, or a successful push is not a substitute for that receipt. A review with
45
+ no findings may have a summary and no inline threads, so verify the review record
46
+ as well as comments.
47
+
48
+ This procedure reflects the repository's observed Codex integration, not a
49
+ general guarantee about future GitHub or Codex behavior. If the trigger changes,
50
+ update this guide after verifying it with a new exact-head review.
package/docs/commands.md CHANGED
@@ -9,7 +9,7 @@ Use `gallivant --help` (or `gallivant help`) for the installed CLI's syntax and
9
9
 
10
10
  | Intent | Command | Notes |
11
11
  |---|---|---|
12
- | Create config | `gallivant init` | Selected Codex or Claude installation; preserves existing config. |
12
+ | Set up the current repository | `gallivant init` | Private config, this repository in `repos`, then the `doctor` report; safe to repeat. |
13
13
  | Check setup/connectivity | `gallivant doctor` | `--network` tests DNS/HTTPS; `--probe` is a real Claude run. |
14
14
  | Prepare a task | `gallivant task "request"` | Uses inference; implementation requires `--run` authorization. |
15
15
  | Inspect/continue a prepared task | `gallivant task list`, `inspect`, `answer`, `resume`, `validate`, `start` | Task IDs and exact revisions; see [task operations](#task-operations). |
@@ -25,6 +25,7 @@ Use `gallivant --help` (or `gallivant help`) for the installed CLI's syntax and
25
25
  | Diagnose a stop | `gallivant why HANDLE` | Shows state, failure and pending controls. |
26
26
  | Continue stopped execution | `gallivant resume HANDLE` | Preserves the session; explicit changed-brief acceptance uses `--resnapshot`. |
27
27
  | Re-evaluate PR gates | `gallivant recheck HANDLE` | No budget reset, no CI rerun, no replacement for execution recovery. |
28
+ | Qualify or change review policy | `gallivant review qualify|status|policy|dispute` | Qualification is separate and may be paid only with `--run`; policy changes preserve the task and session. |
28
29
  | Send a correction | `gallivant say HANDLE --note "..."` | Queues same-session delivery; supported local runs can use `--interrupt`. |
29
30
  | Stop future dispatch | `gallivant cancel HANDLE` | Requests cancellation; inspect confirmation before assuming the process stopped. |
30
31
  | Forget tracking | `gallivant remove HANDLE` | Leaves the PR, branch, labels and checkout in place. |
@@ -46,12 +47,39 @@ select the configured harness in the PRD or task preparation.
46
47
 
47
48
  ## `gallivant init [--harness codex|claude] [--worktrees <directory>]`
48
49
 
49
- Create a private config from your authenticated GitHub login and the selected
50
- installed harness (Codex by default). Creates a separate checkouts directory,
51
- disables optional notifications initially, and prints the packaged template paths.
52
- Existing configs are refused, never replaced. Does not change credentials, global
53
- harness settings, reviewer installation or repository rules. Follow `doctor` and
54
- [installation](install.md) next. `--version` prints the installed package version.
50
+ Set up the Git checkout you run it in. Published form:
51
+ `npx --yes @uchibeke/gallivant init --harness codex`.
52
+
53
+ Before writing anything it checks, in this order, that the directory is a Git
54
+ checkout whose `origin` is a github.com repository, that `gh` is signed in, that
55
+ the selected harness is installed at a supported version and signed in, and that
56
+ the resolved run credential can push to the repository. A failed check stops the
57
+ command with the exact fix (`gh auth login`, `codex login`, `claude auth login`,
58
+ or the remote or permission to correct) and leaves no state behind.
59
+ Classic credentials also need `public_repo` or `repo` scope; the account's push
60
+ role alone does not grant that scope. If the scope lookup fails, setup asks you
61
+ to retry before writing state. Fine-grained tokens have no OAuth scope header
62
+ and still require the repository permission check.
63
+
64
+ It then creates a private config from your authenticated GitHub login and the
65
+ selected installed harness (Codex by default for a new config), creates a
66
+ separate checkouts directory, disables optional notifications, records the
67
+ repository in `repos` once, and prints the `doctor` report plus the packaged
68
+ template paths. Its exit status is doctor's: `0` when every check passes, `1`
69
+ while checks remain.
70
+
71
+ Repeating it is safe. An existing config keeps every key as written; the only
72
+ change is the one `repos` entry for the current repository, never duplicated.
73
+ `--harness` adds a second supported harness without touching the first;
74
+ when both Codex and Claude are configured, pass `--harness` to choose one.
75
+ Concurrent updates use the same mutation lock as other CLI writes; if settings
76
+ change during the prerequisite checks, setup rechecks them before writing.
77
+ `--worktrees` is refused when it differs from the configured directory. `init`
78
+ does not sign in, change credentials, global harness settings, reviewer
79
+ installation or repository rules, and does not start a task. When run through
80
+ `npx` it says that nothing was installed globally and prints both the next `npx`
81
+ command and the optional `npm install -g @uchibeke/gallivant`. See
82
+ [installation](install.md). `--version` prints the installed package version.
55
83
 
56
84
  ## `gallivant doctor [--send] [--probe]`
57
85
 
@@ -88,6 +116,11 @@ Requests can produce code, documentation, research or other repository artifacts
88
116
  A natural-language task still becomes an explicit, validated delivery contract;
89
117
  it does not require the user to write a PRD first.
90
118
  See [task operations](tasks.md) for examples, source delivery and stopping rules.
119
+ `--delivery pull_request` selects the typed delivery profile that alone authorizes
120
+ external actions for new tasks, `--completion-target` sets its completion
121
+ condition, and `--route harness|model` chooses the planner route. The result's
122
+ `review` object is the revision-pinned view an owner approves with `task start
123
+ --run`. See [typed delivery profiles](task-profiles.md).
91
124
 
92
125
 
93
126
  ### Task operations
@@ -115,8 +148,9 @@ Preparation accepts `--repo`, `--base`, repeated `--context` files and `--verify
115
148
  commands, and a retry-safe `--request-id`. Answers may also add explicit context
116
149
  and verification commands. `--completion-target delivery_ready|integrated` selects
117
150
  whether the task tracks readiness or confirmed integration; neither grants merge
118
- permission. `--run` on initial preparation authorizes dispatch after readiness and
119
- any required answers. `--no-daemon` leaves monitoring startup to an existing host
151
+ permission. Initial preparation returns the draft or questions for review even
152
+ when `--run` is present; approve the visible revision separately with `task start
153
+ --revision N --run`. `--no-daemon` leaves monitoring startup to an existing host
120
154
  or explicit coordinator. See [task operations](tasks.md) for revision conflicts,
121
155
  uncertain dispatch, evidence and authorization rules.
122
156
 
@@ -161,7 +195,30 @@ Local task submission:
161
195
  8. Copies those snapshots into the checkout at their original repository paths, creating directories as needed. The PRD is usually only in your own checkout; this copy lets the session commit it with the implementation. Copies in the session's checkout are writable and are never read back for a decision.
162
196
  9. Starts the session detached with the PRD as its prompt, records the session id, and remembers the repo for recovery.
163
197
 
164
- The entry is `running` until the daemon sees the run end. Then either a PR exists on the branch and the entry enters `pr-open`, or it stops with `no-pr`.
198
+ The entry is `running` until the daemon sees the run end. Then either a PR exists on the branch and the entry enters `pr-open`, or a successful worker that did not open one stops with `no-pr`. A failed or incomplete worker without a PR stops with `harness-error`; inspect its run log. Recognized terminal connection failures use the bounded [network recovery](network-recovery.md) path instead.
199
+
200
+ Workers must collect verification results before returning. Claude launches disable
201
+ native background shell/subagent execution and disallow `Monitor`, which otherwise
202
+ remains available despite that setting. This applies to both new and resumed
203
+ implementation/review runs, without changing the operator's global settings,
204
+ sandbox, APort hooks or task allowances. Temporary development servers may still
205
+ be used within a run, with their tests collected and processes cleaned up before
206
+ returning. Shell checks need explicit timeouts sufficient for the check and within
207
+ the approved limits; a timed-out check is not a pass. Tool-free preparation keeps
208
+ its existing deny-all boundary. These native controls are described in Claude's
209
+ [environment reference](https://code.claude.com/docs/en/env-vars) and
210
+ [Monitor documentation](https://code.claude.com/docs/en/tools-reference#monitor-tool).
211
+
212
+ A background-task notification's result cannot settle the main task or hide its
213
+ failure. Gallivant owns durable wakeups and review polling. It does not blindly
214
+ restart every `no-pr` or missing-result failure, which could repeat external
215
+ effects or run unchanged blocked work indefinitely. After upgrading, explicitly
216
+ resume an already stopped run once; future launches receive the lifecycle policy.
217
+ An interrupted pre-PR session becomes resumable only after its owned process tree
218
+ has stopped. Late results stay quarantined; the coordinator still discovers any
219
+ PR already opened before delivering the queued correction to the same session.
220
+ An older failed interrupt is repaired to a stopped state, preserving its message
221
+ for an explicit retry instead of replaying that failed request automatically.
165
222
 
166
223
  It also brings the daemon up in the background if one is not already running, and waits until the daemon reports
167
224
  itself before returning. That is not a convenience: `start` opens a session that will open a pull request, and the
@@ -185,11 +242,13 @@ with exit code 1. Retry `gallivant start` without a PRD, not the original submis
185
242
  processes continue; restart monitoring with `gallivant start`. Embedded trackers
186
243
  are owned by their host and are not stopped by this command.
187
244
 
188
- ## `gallivant chain [<name> [<first.md> <next.md> ...]] [--base <branch>]`
245
+ ## `gallivant chain [<name> [<first.md> <next.md> ...]] [--base <branch>] [--after <pr-url|handle>]`
189
246
 
190
247
  Queue at least two ready PRDs in order. All must be new tasks in one checkout of the same repository and on the same
191
248
  resolved base. `--base` selects the base for a new chain; otherwise the repository config or default branch applies.
192
- The daemon starts the first task and starts each successor only after GitHub confirms the preceding PR was merged
249
+ With `--after`, queue one or more new PRDs behind an already registered PR in that same repository and base.
250
+ The existing run is preserved; its exact PR, branch and base are pinned, and its merge must precede all queued tasks.
251
+ The daemon starts the first task and starts each successor only after the Git host confirms the preceding PR was merged
193
252
  into that base. The final merge completes the chain. `ready-for-human`, a completed agent process and a local `done`
194
253
  entry never satisfy the dependency; closing without merging stops the chain. Gallivant never merges for you.
195
254
 
@@ -199,6 +258,7 @@ brings the existing daemon up if needed. Independent runs continue alongside it.
199
258
  | Command | Effect |
200
259
  |---|---|
201
260
  | `gallivant chain launch first.md next.md` | Approve the order and current brief/source fingerprints, then queue dispatch. |
261
+ | `gallivant chain launch --after your-org/repo#123 next.md` | Wait for the registered predecessor's verified merge, then start the new task. |
202
262
  | `gallivant chain launch --retry` | Recheck a stopped chain after its cause is resolved. |
203
263
  | `gallivant chain launch --retry --resnapshot` | Explicitly accept updated briefs and carried sources for unstarted tasks. |
204
264
  | `gallivant chain launch --cancel` | Stop future dispatch; preserve already started work and its review loop. |
@@ -217,8 +277,10 @@ Puts a PR into the loop that Gallivant did not open, or resets one that stopped.
217
277
  - A `--worktree` you pass is resolved to an absolute path first, so `.` means the directory you typed it in and not whatever directory the daemon happens to run in later. It is then checked before it is accepted: its `origin` must be the PR's repository and it must already be on the PR's head branch. A path that fails either check is an error, since the harness edits and pushes from that directory. It is never relocated or re-cloned for you, because a resumed session is keyed to the directory it ran in.
218
278
  - On an entry that already exists: reason cleared, iteration reset to zero, a marked reset comment posted on the PR (so a count rebuilt from GitHub starts from zero too), cursor set to now, watching again. This is how you restart a `needs-human` PR after you fixed the conflict or answered the question. A fresh registration instead looks at the PR's whole history, so feedback already on it gets addressed.
219
279
  - That reset comment is the reset boundary, so posting it is a precondition of the reset and not a best-effort extra. A count rebuilt from GitHub finds its marker and counts only the round comments after it; with the comment missing and `state.json` later lost, recovery reconstructs the rounds this command had just zeroed, and an entry restored at `max_iterations` stops with `iterations` on its next event having done no work in the round. If it cannot be posted, `register` refuses and changes nothing: the entry keeps its iteration, its state and its cursor, and running the same command again once GitHub answers does the whole reset in one go.
220
- - A reset with a new `--harness` or `--session` makes two durable writes to GitHub, and they are ordered so a failure between them cannot leave GitHub and the registry disagreeing about which harness or session this PR belongs to. The reset comment goes first because it is safely repeatable: a count rebuilt from GitHub takes the LAST reset marker, so a second one counts as one. The identity block goes last, because that write is what a recovery reads the harness and the session out of. So a failed block write leaves a reset comment on the PR, the registry untouched, and both sides still naming the old identity; the same command run again completes the reset.
221
- - Changing `--harness` without giving a new `--session` drops the inherited session and starts a fresh one on the next fix round. This also applies when both harnesses use UUIDs: a Claude session does not belong to Codex. An explicit `--session` must have the chosen harness's format and is used as supplied.
280
+ - A reset with a new `--harness` or `--session` makes two durable writes to GitHub. The reset comment goes first because it is safely repeatable: a count rebuilt from GitHub takes the LAST reset marker, so a second one counts as one. The identity block goes last, because that write is what a recovery reads the harness and the session out of. If a same-harness block write fails, the registry keeps its prior identity. For a cross-harness reset, the old entry is first fenced against dispatch; if the block write or ledger reservation is ambiguous, the fence remains and rerunning the same `register` command finishes the handoff after inspecting the last run. A failure before the identity write restores the prior entry.
281
+ - Changing `--harness` on an existing entry drops the inherited session and starts a fresh one on the next fix round. This also applies when both harnesses use UUIDs: a Claude session does not belong to Codex. An explicit `--session` can attach only without a harness change, and must have the chosen harness's format.
282
+
283
+ For a stopped PR whose local provider is exhausted, inspect `gallivant why widget#142` and confirm its last run has settled. Stop the coordinator with `gallivant down`, then run `gallivant register https://github.com/owner/widget/pull/142 --harness codex` and restart it with `gallivant up`. A cross-harness reset requires the coordinator's exclusive lock; it refuses while the daemon is running, so an old-provider dispatch cannot race the reset. The registration does not send a model request. The old execution ledger, result and run log remain under the same run tree. A new ledger is reserved for Codex before the registry changes, and recovery after `state.json` loss selects the latest ledger. A recorded handoff whose ledger is missing refuses dispatch until its matching backup is restored. The first fix prompt tells the new session to read the approved brief, local checkout, unpushed commits, PR and review threads, including after registry recovery. The former Claude conversation cannot be transferred. A reset starts the round count and feedback cursor from now, so earlier review comments do not trigger the new session. Post a **new** trusted PR comment beginning `/fix` with the work to continue; `@codex review` alone requests a reviewer, and `recheck` only reevaluates readiness. Do not repeat a successful `register`: each success posts another reset marker and restarts that cursor and count. A change between local harnesses refuses an unsettled run or any explicit `--session`: an ID's format cannot prove that the new provider owns that conversation. A PR with a saved brief keeps its original snapshot and acceptance criteria; the explicit register command records the new execution route separately from its original `harness:` field.
222
284
 
223
285
  When the block names a PRD that exists on the PR's branch, the daemon's own snapshot of it is taken, exactly as recovery does, because the completion gate reads that snapshot and nothing else: without it the gate is skipped and the PR can be marked ready with no acceptance criterion evaluated. A snapshot already on disk is kept rather than replaced with the copy the session could have edited, and a PRD the branch does not carry is logged and the PR watched without a gate.
224
286
 
@@ -618,3 +680,30 @@ Harnesses still invoke their own GitHub tools directly. A prompt and a later dae
618
680
  incorrect draft or branded phrase never appears briefly before correction. This implementation enforces daemon
619
681
  writes and readiness, not an exclusive network publication boundary. The encoded recovery record is also not secret:
620
682
  it can be decoded to inspect the precise existing branch/session identity.
683
+
684
+ ## Bitbucket setup and PR commands
685
+
686
+ For an explicitly mapped GitHub review mirror, `npm run promote:bitbucket -- --github-pr URL --bitbucket-repo bitbucket.org/WORKSPACE/REPO --bitbucket-pr N` previews a commit-preserving handoff from a source checkout. It requires exact accepted source readiness, then refreshes the shared review/check policy. Apply requires the inspected plan digest. See [GitHub-to-Bitbucket promotion](bitbucket-promotion.md) for retained post-merge plans, idempotent PR updates and race handling. It never merges or deploys.
687
+
688
+ Bitbucket Cloud dispatch is available with explicit repository credentials and review policy. Its complete first-party evidence adapter and the shared bounded review service are implemented; the private/public live reviewer matrix and clean Linux installation remain separate qualifications. A prior public disposable run proved PR publication and receipt acceptance in legacy no-reviewer mode only. See the [setup, review and troubleshooting guide](bitbucket-review.md) for prerequisites and limits. Bitbucket-only setup needs no GitHub sign-in; it does not install a pipeline or alter repository settings.
689
+
690
+ `init` accepts `--host-config <json>` and `--base <branch>`. The installed `task-pr` command supports bound PR create/view/diff/edit/comment operations; `task-review` prepares and publishes independent reviewer results. These commands do not qualify a harness or authorize a model invocation.
691
+
692
+ For the independent local reviewer, configure `review.mode: "first-party-required"` and `review.route: "codex"`, then run `gallivant review qualify --repo bitbucket.org/workspace/repository --run`. Run the same command without `--run` to inspect its durable result. A new task preflight refuses before author dispatch unless this exact executable/provider fingerprint qualified. To migrate a settled existing task, use `gallivant review policy HANDLE --mode first-party-required --reason "Enable the qualified independent local reviewer"`, then `gallivant recheck HANDLE`. That audited command preserves the task, PRD snapshot, PR and implementation session; editing config alone cannot remove its legacy policy.
693
+
694
+ Review prompts remain at or below 100,000 bytes. Large changes are divided across at most `review.max_jobs` fresh restricted jobs and the reserved `review.budget_usd`; every path and criterion must be covered. A single large file is sliced or the aggregate stops explicitly as incomplete. Zero CI checks still require `review.zero_checks: true` and are never inferred from reviewer clearance.
695
+
696
+ The default review allowance is 2,048 jobs and $100 in accounting reservations,
697
+ with 60 minutes per job. Split inspections provide source-grounded reports;
698
+ a separate whole-PR synthesis must clear before readiness. Coding fix rounds
699
+ default to 60 with a $50 per-run allowance. Reviewer jobs and Git commits are
700
+ not coding rounds: the displayed round advances when a corrective coding run
701
+ settles, including a changed completion receipt. Existing task review limits
702
+ remain pinned until an explicit `review policy` command and recheck.
703
+
704
+ Reviewer qualification can use `review qualify --repo OWNER/REPO --run --wait`
705
+ to keep the launch process alive until settlement. An explicitly inspected,
706
+ owned stopped timeout/provider failure can be retried with `--retry --reason
707
+ "explanation"` on that same command. This preserves its history and reserves a
708
+ new bounded allowance; it never accepts a failed result or bypasses review.
709
+ See [first-party review](first-party-review.md#waiting-for-qualification-and-explicitly-retrying-a-stopped-probe).
package/docs/config.md CHANGED
@@ -9,19 +9,20 @@ while apply and key setup refuse before activation. Key paths are separate expli
9
9
  operator paths, and OpenSSH is pinned outside worker writes. See [learning](learning.md)
10
10
  for the CLI, bounds, separate extraction allowance and backup/rotation limitations.
11
11
 
12
- `~/.gallivant/config.json`, mode 600. `gallivant init` creates a local Codex or
13
- Claude configuration; `gallivant doctor` prints a suggested configuration when
14
- none exists. Set `GALLIVANT_HOME` to use another directory. Hosted providers need
12
+ `~/.gallivant/config.json`, mode 600. `gallivant init`, run inside a checkout,
13
+ creates a local Codex or Claude configuration, records that repository in `repos`
14
+ and prints the `doctor` report; repeated runs preserve every key you have edited.
15
+ `gallivant doctor` prints a suggested configuration when none exists. Set `GALLIVANT_HOME` to use another directory. Hosted providers need
15
16
  explicit configuration; they are not discovered from local executable paths.
16
17
  See [installation](install.md) for the first-run sequence.
17
18
 
18
19
  | Key | Default | Meaning |
19
20
  |---|---|---|
20
21
  | `poll_seconds` | 120 | GitHub review and chain-check cadence. Minimum 30. Provider progress and readiness use the separate `execution.progressMs` cadence; the daemon may tick more frequently. |
21
- | `max_iterations` | 30 | Automatic fix-round allowance per PR. A pushed fix or changed completion receipt consumes a round. At the cap, further automatic work stops with `needs-human`. Explicit operator resumes can exceed the cap; their progress still counts. |
22
+ | `max_iterations` | 60 | Automatic fix-round allowance per PR. A pushed fix or changed completion receipt consumes a round. At the cap, further automatic work stops with `needs-human`. Explicit operator resumes can exceed the cap; their progress still counts. |
22
23
  | `checks_grace_minutes` | 5 | A head younger than this with no checks reported is not green yet; GitHub shows an empty check list for the first seconds after a push. A head older than this with no checks at all counts as green. |
23
24
  | `run_timeout_minutes` | 720 | Local runs exceeding this time are killed; remote execution uses provider cancellation/reconciliation where supported and preserves unknown ownership. It is a runtime allowance, not a provider billing cap. Overridable per repository; see below and [execution](execution.md). |
24
- | `max_budget_usd` | 5 | Passed to Claude as `--max-budget-usd` and used in task preparation/authorization accounting. Other local harnesses have no equivalent enforced dollar cap. Hosted dispatch also requires its explicit provider allowance; reservations are not a billing hard cap. |
25
+ | `max_budget_usd` | 50 | Passed to Claude as `--max-budget-usd` and used in task preparation/authorization accounting. Other local harnesses have no equivalent enforced dollar cap. Hosted dispatch also requires its explicit provider allowance; reservations are not a billing hard cap. |
25
26
  | `rereview_minutes` | 6 | If the reviewer has not reviewed this long after a request, the request is posted once more. |
26
27
  | `stall_hours` | 6 | If the reviewer still has not reviewed, the PR stops with `reviewer-silent`. |
27
28
  | `trusted_authors` | required | GitHub logins whose reviews and comments may start a run. Everyone else is ignored. Your own login belongs here. |
@@ -40,9 +41,10 @@ See [installation](install.md) for the first-run sequence.
40
41
  | `harness.openai-agents` | absent | Explicit account, organization, project, model, API credential, hosted environment, network policy and allowance. See [Agents setup](openai-agents.md). |
41
42
  | `harness.codex-cloud` | absent | Recognized for configuration/recovery, but new dispatch is unavailable. See [Cloud blocker](codex-cloud.md). |
42
43
  | `execution` | bounded defaults | Transport/probe deadlines, progress cadence, concurrency, backoff and event limits. See [execution scheduling](execution.md#scheduling-and-limits). |
44
+ | `intake_model` | absent | The explicitly funded planner route for natural-language intake: `{ adapter, model, endpoint, credential_env, budget, timeout_ms }`. The key is read from the named environment variable at call time. Configurable ceilings are 12 calls, 100,000 input and 16,000 output tokens per call and a $10 allowance; configuration can lower them. Timeout defaults to two minutes, configurable up to five. Existing approved route/task budgets remain pinned. See [typed delivery profiles](task-profiles.md#configuring-the-model-route). |
43
45
  | `repos` | [] | The repositories Gallivant watches, appended by `start` and `register` and read by `up` to recover from GitHub. Each entry is either `"owner/name"` or an object: `{ "repo": "owner/name", "base": "staging", "run_timeout_minutes": 90 }`. Both object keys are optional. See below. |
44
46
 
45
- The default allows 30 rounds as an upper allowance for unattended review. It is not a target or a promise of completion:
47
+ The default allows 60 rounds as an upper allowance for unattended review. It is not a target or a promise of completion:
46
48
  large tasks can exhaust it, while missing external prerequisites cannot be solved by more rounds. Reaching the cap
47
49
  requires an operator decision, and it never increases itself.
48
50
  Existing explicit `max_iterations` settings keep their value. More rounds allow more time and model spend; they do
@@ -82,6 +84,12 @@ an awake machine or a continuously running Node host.
82
84
  qualify its event stream and unattended permissions; it is not a supported choice.
83
85
  Provider/model selection for local harnesses remains in each harness's own
84
86
  configuration; Gallivant does not add a general per-task local model router.
87
+ Changing the native model configuration for the same local harness does not
88
+ change Gallivant's recorded harness or session ID. A later `gallivant resume`
89
+ still asks that CLI to resume its exact session, but whether the CLI applies the
90
+ new model to that conversation is native provider behavior, not a Gallivant
91
+ continuity guarantee. Gallivant does not pass a per-run `--model` flag or route
92
+ around an exhausted provider account.
85
93
 
86
94
  ## The base branch
87
95
 
@@ -266,6 +274,11 @@ Gallivant was first driven against, and it is only a default:
266
274
  - `rereview_comment` is the entire text Gallivant posts to ask for another look. It is posted after every push that came from a fix run, and again as a nudge if the reviewer says nothing for `rereview_minutes`. Gallivant never inspects the string, so a bot mention, a slash command or a plain sentence all work.
267
275
  - `blocking_pattern` is a regex tested against each inline comment of the reviewer's newest review since the last request. A match, or a `CHANGES_REQUESTED` state, keeps the PR out of `ready-for-human`.
268
276
 
277
+ Pushing a commit does not automatically request Codex review for a manually
278
+ updated PR. Follow [the exact-head review procedure](codex-review.md) after each
279
+ final push; the background loop only posts its configured request after runs it
280
+ dispatches itself.
281
+
269
282
  ### Pointing it at a different reviewer
270
283
 
271
284
  Nothing beyond these three fields needs to change. Two worked examples.
@@ -296,12 +309,11 @@ account is what distinguishes a review tool from the trusted humans in `trusted_
296
309
  dispatches a fix run against rather than waiting on. So a human login in `reviewer.login` never matches, the verdict
297
310
  stays `waiting`, and the PR waits out `stall_hours` and then stops with `reviewer-silent` for a person to look at.
298
311
  That is a reasonable way to run a repo where a human gates every merge, but it is a wait, not a verdict. If you want
299
- the human's findings to drive fix rounds instead, put them in `trusted_authors` and set `reviewer` to null.
312
+ the human's findings to drive fix rounds, put them in `trusted_authors`. New tasks without an external actor also need a qualified first-party policy or the explicit legacy no-review exception.
300
313
 
301
314
  ### No automated reviewer
302
315
 
303
- `"reviewer": null` means there is no review tool: only humans and CI drive the loop, and a PR is ready as soon as
304
- checks are green. Gallivant asks nobody for a re-review, so there is no nudge and no `reviewer-silent` stop. It still
316
+ `"reviewer": null` means no external review tool is configured. For new tasks, select a qualified first-party route or set `review.legacy_no_review: true` explicitly. Legacy no-review readiness rests on checks and the configured completion gate and is labelled as absence of review, never clearance. No external re-review or nudge is requested. It still
305
317
  comments after a push, because the round comment is also how a recovery rebuilds the round count off the PR, but the
306
318
  comment says `Pushed a fix.` and mentions no one.
307
319
 
@@ -338,7 +350,9 @@ tree. That is the same rule the brief follows: the daemon judges what it recorde
338
350
  given by editing a document it was handed. Editing one in your own tree afterwards is reported by `gallivant why` the
339
351
  same way an edited brief is, and the list itself is part of the contract, so adding or removing a file is a contract
340
352
  change even though no criterion moved. Changes to either the manifest or file bytes block readiness and resume until
341
- accepted with `resume --resnapshot`; accepted snapshots are also restored when a checkout is recreated.
353
+ accepted with `resume --resnapshot`; accepted snapshots are also restored when a checkout is recreated. Carried inputs
354
+ remain local and untracked unless explicitly requested as output in the approved brief's [`publish_files`](prd.md) list.
355
+ Keep those local copies when removing accidental commits; the task still reads them.
342
356
 
343
357
  `sources` and `context_paths` answer different questions and neither replaces the other. `sources` puts named files
344
358
  INSIDE the checkout, so it works on every harness because it needs no flag at all. `context_paths` grants a session read
@@ -412,14 +426,16 @@ Every run gets the resolved credential as `GH_TOKEN`, the git settings below, an
412
426
 
413
427
  ### Git settings for a run
414
428
 
415
- No file. Git's own `GIT_CONFIG_COUNT` with numbered `GIT_CONFIG_KEY_n`/`GIT_CONFIG_VALUE_n` pairs carries four settings:
429
+ No file. Git's own `GIT_CONFIG_COUNT` with numbered `GIT_CONFIG_KEY_n`/`GIT_CONFIG_VALUE_n` pairs carries the following settings:
416
430
 
417
431
  | Key | Value |
418
432
  |---|---|
419
433
  | `user.name` | Your Git-configured name, resolved by the coordinator for each run |
420
434
  | `user.email` | Your Git-configured email, resolved by the coordinator for each run |
421
435
  | `push.default` | `current` |
422
- | `credential.helper` | a shell snippet that prints `GH_TOKEN` as the password, and prints nothing when there is no `GH_TOKEN` |
436
+ | `credential.helper` | an empty entry resets inherited helpers, followed by a helper that answers only for the bound HTTPS host and repository |
437
+ | `credential.useHttpPath` | `true` |
438
+ | `http.followRedirects` | `false` |
423
439
 
424
440
  Plus `GIT_CONFIG_NOSYSTEM=1` and `GIT_CONFIG_GLOBAL=/dev/null`.
425
441
 
@@ -427,4 +443,20 @@ Nothing in that list is a path outside the worktree, and that is the point. Unti
427
443
 
428
444
  Both isolating variables are load-bearing, and `GIT_CONFIG_NOSYSTEM` is not decoration. `GIT_CONFIG_GLOBAL` replaces only git's global file; the system one still applies, and on a Mac with the Xcode command line tools `/Library/Developer/CommandLineTools/usr/share/git-core/gitconfig` sets `credential.helper = osxkeychain`. Without `GIT_CONFIG_NOSYSTEM` a run had a path to your keychain whatever else was set. With it, `git config --get-all credential.helper` in a run's environment returns nothing but the snippet above.
429
445
 
430
- What this does not bound, said plainly because it is easy to mistake for new: a run's own `.git/config` is still read, `credential.helper` is multi-valued, and a repo-local helper is consulted before this one. That was equally true when the helper lived in a global file, since local config always won there too. A run owns its worktree, so it can always add a helper. What bounds a run is the token's scope and the branch ruleset, not how the config travels.
446
+ The helper resets repository-local credential helpers and refuses other hosts, repository paths and redirects. Runs clear inherited API tokens and SSH transport settings. A run can read its own environment, so token scope and repository rulesets remain essential. See the [Git host contract](git-hosts.md) for identity, compatibility and provider binding.
447
+
448
+ ## Bitbucket repository policy
449
+
450
+ Set `reviewer` (or explicit `null`), stable UUID `trusted_authors`, and
451
+ `required_checks` under `git_hosts["bitbucket.org"]`. A host repository entry can
452
+ override these settings, and a `repos` object takes precedence over both.
453
+ GitHub's top-level reviewer defaults are never inherited by Bitbucket.
454
+ See [configuration examples and credential scope](bitbucket-review.md).
455
+ For a deliberate no-reviewer task, set `reviewer: null` and
456
+ `review.legacy_no_review: true` on the repository entry. Readiness then reports
457
+ that no independent review was performed; it still requires configured checks
458
+ and the completion receipt.
459
+
460
+ ## Versioned review policy
461
+
462
+ `review.mode` selects `external-required`, `first-party-required`, or `both-required` for new tasks. `review.route: "codex"` requires a successful isolated live qualification. `review.specialist` allows at most one of `security` or `regression`. Defaults and bounds, per-repository settings, separate review allowances, explicit zero-check CI policy and the `legacy_no_review` exception are documented in [First-party review](first-party-review.md). A config edit cannot change an existing task policy; use `review policy <handle> --mode <mode> --reason "..."` to revoke readiness and explicitly re-evaluate. `reviewer: null` alone no longer authorizes an unattended new start.
package/docs/execution.md CHANGED
@@ -785,7 +785,7 @@ is live or its gates have passed. Check the linked PR and the consumer's current
785
785
  release evidence before an installation:
786
786
 
787
787
  The connected execution successor is
788
- [`aporthq/agent-passport#417`](https://github.com/aporthq/agent-passport/pull/417),
788
+ [`aporthq/agent-passport#417`](https://github.com/aporthq/agent-passport/pull/417) (not publicly readable),
789
789
  with canonical PRD `docs/prds/aport-task-delivery-workflow-integration.md` and job
790
790
  identity `aporthq/agent-passport/aport-task-delivery-workflow-integration`. It
791
791
  preserves the original T0–T9 requirements; the recorded plan requires the actual