@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.
- package/README.md +120 -60
- package/SECURITY.md +9 -0
- package/bin/gallivant.mjs +41 -14
- package/bin/promote-bitbucket.mjs +40 -0
- package/bin/task-pr.mjs +9 -0
- package/bin/task-review.mjs +15 -0
- package/docs/README.md +6 -2
- package/docs/agent-setup.md +55 -41
- package/docs/architecture.md +11 -3
- package/docs/bitbucket-promotion.md +69 -0
- package/docs/bitbucket-review.md +330 -0
- package/docs/chains.md +30 -1
- package/docs/codex-cloud.md +7 -0
- package/docs/codex-review.md +50 -0
- package/docs/commands.md +103 -14
- package/docs/config.md +45 -13
- package/docs/execution.md +1 -1
- package/docs/first-party-review.md +266 -0
- package/docs/git-hosts.md +294 -0
- package/docs/guardrails.md +56 -0
- package/docs/install.md +137 -67
- package/docs/launch.md +7 -4
- package/docs/network-recovery.md +9 -0
- package/docs/openai-agents.md +3 -2
- package/docs/prd.md +23 -2
- package/docs/preparation.md +2 -2
- package/docs/release-qualification.md +1 -1
- package/docs/releasing.md +46 -22
- package/docs/task-delivery.md +5 -5
- package/docs/task-profiles.md +537 -0
- package/docs/tasks.md +59 -197
- package/lib/attribution.mjs +7 -3
- package/lib/block.mjs +10 -1
- package/lib/chains.mjs +101 -30
- package/lib/codex_cloud.mjs +2 -1
- package/lib/codex_cloud_input.mjs +15 -6
- package/lib/codex_cloud_result.mjs +1 -1
- package/lib/commands/doctor.mjs +22 -453
- package/lib/commands/init.mjs +281 -28
- package/lib/commands/register.mjs +81 -13
- package/lib/commands/resume.mjs +5 -1
- package/lib/commands/review.mjs +66 -0
- package/lib/commands/serve.mjs +8 -0
- package/lib/commands/start.mjs +30 -11
- package/lib/commands/status.mjs +18 -2
- package/lib/commands/task.mjs +9 -1
- package/lib/commands/up.mjs +19 -11
- package/lib/commands/why.mjs +7 -3
- package/lib/config.mjs +42 -9
- package/lib/context.mjs +28 -21
- package/lib/control.mjs +21 -6
- package/lib/credential.mjs +20 -14
- package/lib/deliverable.mjs +2 -0
- package/lib/events.mjs +96 -53
- package/lib/execution.mjs +132 -11
- package/lib/execution_preparation.mjs +16 -1
- package/lib/execution_result.mjs +26 -5
- package/lib/first_party_review.mjs +618 -0
- package/lib/fs.mjs +10 -3
- package/lib/gh.mjs +144 -56
- package/lib/git.mjs +133 -32
- package/lib/git_diff.mjs +121 -0
- package/lib/harness.mjs +14 -10
- package/lib/host_contract.mjs +71 -0
- package/lib/host_definitions.mjs +22 -0
- package/lib/hosts/bitbucket.mjs +553 -0
- package/lib/hosts/bitbucket_contract.mjs +57 -0
- package/lib/hosts/bitbucket_credential.mjs +62 -0
- package/lib/hosts/bitbucket_review.mjs +44 -0
- package/lib/hosts/bitbucket_review_producer.mjs +50 -0
- package/lib/hosts/github.mjs +57 -0
- package/lib/hosts/github_contract.mjs +27 -0
- package/lib/hosts/github_doctor.mjs +482 -0
- package/lib/hosts/github_review_summary.mjs +38 -0
- package/lib/hosts/transport_doctor.mjs +35 -0
- package/lib/hosts.mjs +130 -0
- package/lib/learning_qualification.mjs +1 -1
- package/lib/notify.mjs +1 -1
- package/lib/openai_agents_input.mjs +7 -2
- package/lib/openai_agents_sources.mjs +16 -8
- package/lib/plugin_package.mjs +13 -1
- package/lib/pr_operation.mjs +41 -0
- package/lib/prd.mjs +18 -3
- package/lib/preparation_codex.mjs +6 -1
- package/lib/probe.mjs +6 -4
- package/lib/process.mjs +24 -0
- package/lib/promotion.mjs +132 -0
- package/lib/promotion_git.mjs +63 -0
- package/lib/prompt.mjs +16 -13
- package/lib/provider_health.mjs +14 -3
- package/lib/repository.mjs +68 -0
- package/lib/repository_preflight.mjs +11 -0
- package/lib/review_evaluation.mjs +25 -0
- package/lib/review_evidence.mjs +500 -0
- package/lib/review_history.mjs +73 -0
- package/lib/review_image.mjs +145 -0
- package/lib/review_link.mjs +12 -0
- package/lib/review_policy.mjs +132 -0
- package/lib/review_policy_contract.mjs +18 -0
- package/lib/review_state.mjs +13 -0
- package/lib/review_visual.mjs +94 -0
- package/lib/runtime-environment.mjs +6 -0
- package/lib/runtime_node.mjs +3 -2
- package/lib/runtime_state.mjs +39 -5
- package/lib/sources/prd.mjs +6 -3
- package/lib/state.mjs +137 -24
- package/lib/task_completion.mjs +7 -3
- package/lib/task_contract.mjs +201 -27
- package/lib/task_delivery.mjs +9 -2
- package/lib/task_delivery_contract.mjs +13 -9
- package/lib/task_delivery_view.mjs +18 -2
- package/lib/task_environment.mjs +13 -1
- package/lib/task_limits.mjs +13 -0
- package/lib/task_model_config.mjs +99 -0
- package/lib/task_model_route.mjs +243 -0
- package/lib/task_prepare.mjs +21 -8
- package/lib/task_profile.mjs +1875 -0
- package/lib/task_repository_context.mjs +65 -0
- package/lib/tasks.mjs +252 -51
- package/lib/tick.mjs +373 -98
- package/lib/time.mjs +1 -0
- package/lib/tracker/pages.mjs +19 -5
- package/lib/tracker/review.mjs +21 -0
- package/lib/tracker_process.mjs +8 -1
- package/lib/verification_sandbox.mjs +2 -1
- package/lib/work_artifacts.mjs +79 -0
- package/npm-shrinkwrap.json +12 -3
- package/package.json +9 -3
- package/templates/plugin/task-delivery.SKILL.md +17 -10
- package/templates/plugin/task-intake-contract.json +18 -0
- package/templates/plugin/task-profile-requests.mjs +1448 -0
- package/templates/tracker/tracker.css +3 -0
- package/templates/tracker/tracker.js +38 -0
package/docs/agent-setup.md
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
# Let an agent set up Gallivant
|
|
2
2
|
|
|
3
|
-
Give the prompt below to your coding agent. It can inspect prerequisites,
|
|
4
|
-
the
|
|
5
|
-
login and any required trust prompts. Setup does not need
|
|
6
|
-
repository, and
|
|
3
|
+
Give the prompt below to your coding agent. It can inspect prerequisites, run
|
|
4
|
+
the published setup command, read the resulting report and validate a first task.
|
|
5
|
+
You handle account login and any required trust prompts. Setup does not need
|
|
6
|
+
access to every private repository, and running the setup command does not start
|
|
7
|
+
a paid session.
|
|
7
8
|
|
|
8
9
|
Start with **Codex or Claude and one repository**. Those are the harnesses supported
|
|
9
10
|
by `gallivant init`. [Hosted Agents API](openai-agents.md) uses an explicit config
|
|
@@ -24,12 +25,15 @@ CLI --help and the docs matching the installed version. Prefer an already workin
|
|
|
24
25
|
Codex or Claude setup. Preserve existing credentials, settings, running jobs,
|
|
25
26
|
worktrees and uncommitted changes. Report proposed config changes without secrets.
|
|
26
27
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
28
|
+
From inside the target checkout, run the published setup command:
|
|
29
|
+
npx --yes @uchibeke/gallivant init --harness codex (or --harness claude), then
|
|
30
|
+
read its report. Do not clone the Gallivant repository or install it globally
|
|
31
|
+
unless I ask. If the command stops because gh or the harness is signed out, tell
|
|
32
|
+
me the exact login command it printed and wait; do not sign in for me. Do not
|
|
33
|
+
overwrite an existing config, weaken security settings, install hooks, change
|
|
34
|
+
repository protections or elevate privileges without my authorization. Never ask
|
|
35
|
+
me to paste API keys or tokens into this conversation. Use the provider's login
|
|
36
|
+
flow or a private credential file instead.
|
|
33
37
|
|
|
34
38
|
Ask only for missing decisions: target repository and checkout, approved base
|
|
35
39
|
branch, preferred available harness, first task scope, and allowed spending.
|
|
@@ -88,38 +92,45 @@ automatically commit, or switch a dirty checkout. Confirm which GitHub repositor
|
|
|
88
92
|
and base branch the task should use; the current branch is not necessarily the
|
|
89
93
|
approved PR target. Account login and Git identity belong to the user.
|
|
90
94
|
|
|
91
|
-
## 2.
|
|
95
|
+
## 2. Run the setup command
|
|
92
96
|
|
|
93
|
-
Use the [current installation instructions](install.md#
|
|
94
|
-
|
|
95
|
-
an option after the package is published. Avoid `sudo npm install`; use a
|
|
96
|
-
user-owned Node installation or prefix when global installation is not writable.
|
|
97
|
-
Do not silently replace a different installed version while its daemon is running.
|
|
98
|
-
|
|
99
|
-
After GitHub and the selected harness are signed in:
|
|
97
|
+
Use the [current installation instructions](install.md#2-the-command). After
|
|
98
|
+
GitHub and the selected harness are signed in, from inside the target checkout:
|
|
100
99
|
|
|
101
100
|
```sh
|
|
102
|
-
gallivant --
|
|
103
|
-
gallivant --help
|
|
104
|
-
gallivant init --harness codex
|
|
105
|
-
gallivant doctor
|
|
101
|
+
npx --yes @uchibeke/gallivant init --harness codex # or: --harness claude
|
|
106
102
|
```
|
|
107
103
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
104
|
+
`npx` runs the published package on demand; it installs nothing globally and
|
|
105
|
+
does not clone this repository. `init` is noninteractive. It refuses, writing
|
|
106
|
+
nothing, when the directory is not a GitHub checkout, `gh` or the harness is
|
|
107
|
+
signed out, or the login cannot push to the repository; report the printed
|
|
108
|
+
command to the user instead of working around it. Otherwise it creates
|
|
109
|
+
`~/.gallivant/config.json` (mode 600) when none exists, records the current
|
|
110
|
+
repository in `repos` once, creates the worktrees directory and prints the
|
|
111
|
+
`doctor` report. Exit status `1` means checks remain, not that setup failed.
|
|
112
|
+
|
|
113
|
+
With an existing config, `init` keeps every key as written and adds only the
|
|
114
|
+
current repository. Do not edit unrelated keys. The normal path is
|
|
115
|
+
`~/.gallivant/config.json`; use `$GALLIVANT_HOME/config.json` if that variable is
|
|
116
|
+
already set. Pass `--worktrees /absolute/path` only on first creation; later
|
|
117
|
+
runs refuse a different directory.
|
|
118
|
+
|
|
119
|
+
If the user prefers a persistent command, `npm install -g @uchibeke/gallivant`
|
|
120
|
+
is the documented option; ask before installing globally. Avoid `sudo npm
|
|
121
|
+
install`; use a user-owned Node installation or prefix. Do not silently replace
|
|
122
|
+
a different installed version while its daemon is running.
|
|
123
|
+
|
|
124
|
+
Before a real run, finish the [harness guardrail setup](install.md#7-aport-on-claude-code)
|
|
116
125
|
for the selected harness. Some steps require human interaction: for example,
|
|
117
126
|
Codex's initial `/hooks` trust prompt cannot be automated. Report such a blocker
|
|
118
127
|
instead of changing the enforcement level or bypassing it.
|
|
119
128
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
129
|
+
`init` records the repository without a base branch; its pull requests target
|
|
130
|
+
the default branch unless the user chooses otherwise with `start --base` or a
|
|
131
|
+
`{ "repo", "base" }` entry, following [configuration](config.md#the-base-branch).
|
|
132
|
+
Review the config diff without printing credentials. Confirm these decisions
|
|
133
|
+
before dispatch:
|
|
123
134
|
|
|
124
135
|
| Decision | What must be established |
|
|
125
136
|
|---|---|
|
|
@@ -129,8 +140,9 @@ printing credentials. Confirm these decisions before dispatch:
|
|
|
129
140
|
| Completion evaluator | Default APort hosted confirmation needs network access. A local evaluator is an explicit user choice, not an automatic workaround for a failure. |
|
|
130
141
|
| Cost | Confirm `max_iterations`, provider budget controls and allowed spend. `max_budget_usd` is a native per-run dollar cap for Claude; other local harnesses have no equivalent enforced dollar cap. |
|
|
131
142
|
|
|
132
|
-
Run `gallivant doctor`
|
|
133
|
-
(API unchecked)” as proof of
|
|
143
|
+
Run `gallivant doctor` (or `npx --yes @uchibeke/gallivant doctor`) again and
|
|
144
|
+
report every failure. Do not treat “signed in (API unchecked)” as proof of
|
|
145
|
+
inference access. `doctor` without extra flags checks
|
|
134
146
|
configuration, credentials and repository access without launching a model run.
|
|
135
147
|
`doctor --probe` launches a real Claude sandbox test when Claude is configured;
|
|
136
148
|
`doctor --send` sends a real notification. Use those only when authorized.
|
|
@@ -206,9 +218,11 @@ review and merge.
|
|
|
206
218
|
|
|
207
219
|
## What setup verification proves
|
|
208
220
|
|
|
209
|
-
The package's `npm run test:install`
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
221
|
+
The package's `npm run test:install` check packs the tarball and runs the
|
|
222
|
+
README's `npx` setup command against it from a disposable repository, with
|
|
223
|
+
fixture `gh` and `codex` commands and a throwaway home. It proves which binary
|
|
224
|
+
ran, the config and directory permissions, repository registration, repeat
|
|
225
|
+
safety and the printed next steps. It does not use a real account, invoke a
|
|
226
|
+
model or certify a provider's current availability. A first authorized
|
|
227
|
+
end-to-end task is still needed to verify the user's actual repository
|
|
228
|
+
permissions, provider entitlement, sandbox, CI and review integration.
|
package/docs/architecture.md
CHANGED
|
@@ -38,6 +38,10 @@ lib/events.mjs pure rules: what counts as an event, trust, reviewer ve
|
|
|
38
38
|
lib/prompt.mjs start, register and fix prompts; quoting and caps
|
|
39
39
|
lib/harness.mjs capability registry plus local argv, session, outcome and sign-in adapters
|
|
40
40
|
lib/tasks.mjs natural-language intake, revisions, validation, readiness and explicit execution consent
|
|
41
|
+
lib/task_profile.mjs portable typed delivery profile, deterministic delivery screen and planner tag coverage (vendored by Agent Passport)
|
|
42
|
+
lib/task_model_route.mjs bounded text-only model route for drafting; pre-call allowance checks, usage-derived cost
|
|
43
|
+
lib/task_model_config.mjs operator configuration and absolute ceilings for that route
|
|
44
|
+
lib/task_repository_context.mjs read-only, bounded repository snapshot pinned to the prepared revision
|
|
41
45
|
lib/task_delivery.mjs authenticated host operation boundary; delegates to the same task service
|
|
42
46
|
lib/execution.mjs durable local/remote dispatch, ownership, observations and recovery
|
|
43
47
|
lib/execution_result.mjs owned hosted artifact verification and coordinator publication
|
|
@@ -72,10 +76,10 @@ templates/ passport, Claude sandbox settings, PRD, tracker/{tracke
|
|
|
72
76
|
|
|
73
77
|
## Design rules
|
|
74
78
|
|
|
75
|
-
|
|
79
|
+
Legacy review policies on intake tasks targeting `delivery_ready` stop automatic observation and fixing
|
|
76
80
|
at the qualified saved handoff. Explicit queued recheck/resume/message controls
|
|
77
81
|
reopen the workflow. `integrated` targets and legacy written-PRD runs retain
|
|
78
|
-
monitoring. `completionStopsAutomation` and the exported `coordinatorEntryActive`
|
|
82
|
+
monitoring. Version-1 review policies keep ready deliveries monitored so late trusted feedback and changed input can revoke readiness. `completionStopsAutomation` and the exported `coordinatorEntryActive`
|
|
79
83
|
keep core and host schedulers aligned. The review transitions below apply while
|
|
80
84
|
an entry is monitored; malformed or incomplete delivery proof cannot mark it
|
|
81
85
|
finished or suppress work.
|
|
@@ -215,7 +219,7 @@ For each registry entry that is not `done`:
|
|
|
215
219
|
6. **Dispatch.** Past the cap, stop with `iterations`. Otherwise recreate the checkout if it is gone, merge the base branch into the work branch, build the fix prompt, resume the session (or start one for a registered PR), move the cursor to the newest event and record the ids dispatched at that instant, record the run.
|
|
216
220
|
|
|
217
221
|
The merge is where a round of work starts from the current base rather than from wherever the base was when the branch was cut, and it is a merge rather than a rebase for three reasons that all live in this codebase. A rebase of a pushed branch can only move with a force-push, which the rules every session is given forbid. `reviewerVerdict` clears a head only when the commit the reviewer named is that head, so a rewrite makes every prior clearance describe a commit that no longer exists, and the reviewer's inline comments are anchored to those same commits. And step 7 reads a head the loop did not put there as a person's push, so a daemon force-push would look to the daemon itself like a stranger pushing. A merge moves the head forward, keeps every reviewed commit an ancestor, and needs no `--force`. An outstanding review therefore does not hold it up, which is the point: a rebase would have had to wait for the review, and that is a deadlock where the reviewer waits for a fix and the fix waits for the reviewer. The merge commit stays local until the session pushes, so nothing on GitHub moves, the reviewer clock is not reset and the round is still counted from the session's own push. It is recorded the moment it succeeds rather than by the save at the end of this step, because four things after it can return early and a merge nobody recorded is a change to a checkout with nothing to explain it. A conflict is aborted and the entry stops with `base-conflict` naming the base, because a half-merged checkout handed to a session as if it were clean is the worst thing this step could leave, and a conflict does not resolve on its own so retrying every tick would loop forever. Four things that would refuse identically on every poll stop the entry instead of looping: a checkout that cannot be recreated (`no-worktree`, with the cause as the event), a harness that refuses the configured `context_paths` (`context-paths`), no GitHub credential (`no-credential`) and no git identity on the machine (`no-identity`, whose event is the two `git config --global` commands that fix it). None of them resolves on its own, and the entry would otherwise redispatch the same feedback every poll with nothing notified. One invariant orders the rest of this step: **a spawned run must be recorded before anything else can fail.** Everything that can throw, the checkout and the ready-label removal included, happens before the spawn, and the registry write that owns the run comes immediately after it with no `await` in between. A process the registry does not know about is the worst state the dispatch can leave, because the settle step reads it as an unrelated leftover and the feedback that caused it is still new, so the same feedback spawns a second fixer when the first one exits. The label removal is the one write that can therefore hold a dispatch back, and holding it back is bounded: five consecutive failures stop the entry with `stuck`. `gh.removeLabel` throws by default and swallows only gh's own "label not found", which is what makes that bound reachable at all: the lenient behaviour was once the default, one of the two callers omitted the flag, and a GitHub that refused the write resolved as though the label had merely been absent.
|
|
218
|
-
7. **Ready.** First, a head nobody told the loop about. Both watching states go through the same check, in one place: `fixed_sha` follows the head, the reviewer clock resets to the push and the nudge becomes available again, because the reviewer has not seen this commit. A `ready` entry also leaves ready with the label off, since its verdict, its green checks and its accepted receipt all describe a commit that is not the head any more. Handling it for `ready` alone used to leave a `pr-open` entry judging the new head with the old head's age, so the same tick that noticed the push could stop it as `reviewer-silent` on a wait that expired before the commit existed, and the nudge already spent on the old head was never reissued. Then, for a `pr-open` entry: no events, no run, not a draft,
|
|
222
|
+
7. **Ready.** First, a head nobody told the loop about. Both watching states go through the same check, in one place: `fixed_sha` follows the head, the reviewer clock resets to the push and the nudge becomes available again, because the reviewer has not seen this commit. A `ready` entry also leaves ready with the label off, since its verdict, its green checks and its accepted receipt all describe a commit that is not the head any more. Handling it for `ready` alone used to leave a `pr-open` entry judging the new head with the old head's age, so the same tick that noticed the push could stop it as `reviewer-silent` on a wait that expired before the commit existed, and the nudge already spent on the old head was never reissued. Then, for a `pr-open` entry: no events, no run, not a draft, checks settled and the pinned review policy satisfied. Version-1 policies require explicit zero-check CI authorization for an empty check response; legacy no-review is disclosed as absence of review. Then the brief, compared with the operator's own copy: this is the only place the daemon reads their working tree, and it is here because this is where the contract is about to be used to certify something. A contract that moved stops the entry with `prd-changed` and the difference named, before the gate runs and without setting `gate_skipped`, which describes the other thing entirely (a PR that reached READY with the gate unrun, where this entry is not reaching ready at all). An edit outside the contract re-takes the snapshot, notifies nobody and carries on. Then the completion gate (`deliverable.mjs`): the PR body's receipt must attest every acceptance criterion of the PRD with evidence; a deny starts a receipt round. A receipt whose shape is wrong is one of those denies, not an exception. The output scan needs the whole diff, so a diff that cannot be read or reaches the 16 MiB scan cap is no decision at all. Large hosted payloads are sent in overlapping pieces within the API request limit, with full criteria and attestations on each; every piece must allow. Unreadable diffs and unavailable evaluators use the same bounded `entry.retry` mechanism as writes, with the cause visible in `status` and `why`; five consecutive failures stop as `needs-human`, without a fixer run or iteration. The label goes on before the registry says ready, so a label write that fails leaves the entry in `pr-open` to be retried rather than a ready PR carrying no label, and those retries are counted on the same `entry.retry` as every other declining write: a token that cannot write labels at all used to repeat the readiness judgement, the completion gate included, on every poll forever, while `status` said the entry was waiting on a reviewer who had already answered. Only then notify, once.
|
|
219
223
|
8. **Silence.** Reviewer configured and quiet since the last request: nudge once after `rereview_minutes`, stop with `reviewer-silent` after `stall_hours`. Draft conversion in step 3 starts a fresh reviewer window, so time spent as a draft does not count as reviewer silence.
|
|
220
224
|
|
|
221
225
|
The reviewer clock (`rereview.at`) is when the reviewer was last asked about the current head, and all three of those timers measure from it. Its best available value is the head commit's committer date, which is when the commit was made and not when it arrived on the branch, so it is floored at `rereview_minutes` ago: a commit made on Monday and pushed on Thursday must not stop the PR for a silence the reviewer was never given a chance to break. The rule is `reviewerClock` in `events.mjs`, pure and in one place because the tick is not its only writer: `reconcile` sets the same field on a recovered entry and goes through the same function, so a PR whose last round comment is older than `stall_hours` is not stopped `reviewer-silent` on the first tick after a crash recovery for silence that accrued while no daemon was running to ask.
|
|
@@ -263,3 +267,7 @@ a successful version probe alone cannot establish unattended support.
|
|
|
263
267
|
## Adding a reviewer
|
|
264
268
|
|
|
265
269
|
No code. Set `reviewer.login`, `reviewer.rereview_comment` and `reviewer.blocking_pattern` in config.
|
|
270
|
+
|
|
271
|
+
## Coordinator-owned first-party review
|
|
272
|
+
|
|
273
|
+
`review_policy.mjs` owns versioned task policy and input bindings; `review_evidence.mjs` captures complete snapshots and validates structured judgement. `first_party_review.mjs` advances keyed review jobs through the existing execution registry, in a separate session and allowance. The shared tick handles readiness, trusted external feedback and fix rounds. Review jobs do not create a second scheduler or publish independent approvals. Host adapters provide the same normalized evidence contract; only the existing GitHub boundary is implemented here. See [policy and recovery behavior](first-party-review.md), including native qualification and measured rollout limitations.
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# Review on GitHub, deliver through Bitbucket
|
|
2
|
+
|
|
3
|
+
`npm run promote:bitbucket` transfers an accepted GitHub PR's **original commits** to Bitbucket Cloud and creates or updates its Bitbucket PR. It uses Git transport, the existing host adapters and the same review/check policy as the coordinator. It does not copy files, create commits, force-push, merge, enable CI or deploy.
|
|
4
|
+
|
|
5
|
+
This is an operator command from a Gallivant source checkout. Install dependencies with `npm ci`. Configure both hosts using the [Git host guide](git-hosts.md); Git push access and Bitbucket API repository/PR access are both required. The command uses the existing scoped credentials, including a configured Bitbucket SSH key. Never put a token in a repository URL or a plan file.
|
|
6
|
+
|
|
7
|
+
## Before promotion
|
|
8
|
+
|
|
9
|
+
- Register and finish the GitHub run. It must retain an exact accepted completion and review binding under an explicit review policy. A label, green CI or the PR author's statement alone is insufficient.
|
|
10
|
+
- Stopped dispatch and queued/applying operator controls block promotion. Cancellation, messages, resume and recheck requests must be reconciled before accepted work can be delivered. These controls are checked again after plan validation and after a push; a cancellation during an already-running push can leave the branch updated, but prevents subsequent PR publication when observed.
|
|
11
|
+
- Only the exact remotely reviewed commit is transferred. Local checkout edits, untracked carried research inputs, environment files and session logs are neither read nor included. The transfer uses its own disposable bare Git repository, so an operator checkout may remain dirty or may already have been removed after merge.
|
|
12
|
+
- Specify the destination repository explicitly. No organization or repository mapping is inferred.
|
|
13
|
+
- For an existing Bitbucket PR, supply its number. This updates that PR rather than creating a duplicate.
|
|
14
|
+
- The Bitbucket base must have the same Git tree as the reviewed GitHub base. Its commit hash may differ because the two hosts merged earlier changes separately. Promote dependent work in order, after the preceding Bitbucket change has merged. Reconcile differing trees on GitHub and obtain review again.
|
|
15
|
+
- An existing destination branch must be an ancestor of the reviewed source head. Divergence is not resolved automatically.
|
|
16
|
+
|
|
17
|
+
GitHub Actions may remain disabled for a review-only mirror. Zero CI checks are accepted **only** when the source run's operator-approved review policy explicitly allows zero checks. Configured required checks still must exist and pass. Local test results and production release requirements are not replaced by that setting. Missing required external or first-party review blocks promotion.
|
|
18
|
+
|
|
19
|
+
## Preview, approve and apply
|
|
20
|
+
|
|
21
|
+
For an existing mapped PR:
|
|
22
|
+
|
|
23
|
+
```sh
|
|
24
|
+
npm run promote:bitbucket -- \
|
|
25
|
+
--github-pr https://github.com/example/app/pull/1 \
|
|
26
|
+
--bitbucket-repo bitbucket.org/example/app \
|
|
27
|
+
--bitbucket-pr 93 \
|
|
28
|
+
--out accepted-promotion.json
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
The default is a remote read-only dry run. It fetches into a disposable temporary Git repository and prints the source and destination heads, bases, exact title/body, review policy, check count and a SHA-256 `digest`. `--out` saves that plan locally with mode 600 and refuses to overwrite an existing file. Keep private plans outside your repository; they contain private PR prose and the previous destination PR text, which may include its task metadata. Transport credentials are never added to the plan.
|
|
32
|
+
|
|
33
|
+
Inspect the complete plan, then rerun the same mapping with its digest:
|
|
34
|
+
|
|
35
|
+
```sh
|
|
36
|
+
npm run promote:bitbucket -- \
|
|
37
|
+
--github-pr https://github.com/example/app/pull/1 \
|
|
38
|
+
--bitbucket-repo bitbucket.org/example/app \
|
|
39
|
+
--bitbucket-pr 93 \
|
|
40
|
+
--apply --expected-plan DIGEST_FROM_THE_DRY_RUN
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
The digest is an exact human approval pin, not a substitute for fresh review evidence. Changed source code, review, checks, public text, destination branch, base or existing PR text requires another dry run. The command reads accepted state and operator controls from the run registry; it never writes that registry or starts another agent.
|
|
44
|
+
|
|
45
|
+
For a new PR, omit `--bitbucket-pr`. The default destination branch is `work/github-OWNER-REPO-pr-N`; `--branch` and `--base` select explicit alternatives. Subsequent runs reuse an existing PR only when its repository, branch/base and source-review provenance match. Otherwise supply an explicit PR mapping. Closed, cross-repository or duplicate targets are rejected.
|
|
46
|
+
|
|
47
|
+
The Bitbucket title and human-readable body come from the GitHub PR, with a source-review link and original commit SHA appended. Source task receipts and recovery/session metadata are removed because they do not authorize a new host/task. The source GitHub PR retains the complete evidence.
|
|
48
|
+
|
|
49
|
+
## After merging on GitHub
|
|
50
|
+
|
|
51
|
+
Run the same dry-run command after merge. When GitHub still supplies the original reviewed base, the coordinator's retained acceptance hash is checked directly against the original head, base, body, checks and policy. No pre-merge plan file is required. The accepted local record and fresh clear reviewer/check evidence remain mandatory; merging a PR before it was accepted does not manufacture that authority.
|
|
52
|
+
|
|
53
|
+
Optionally save `--out accepted-promotion.json` while the PR is accepted and still open. If GitHub later reports a different base, that archived plan can reconstruct the original base using:
|
|
54
|
+
|
|
55
|
+
```sh
|
|
56
|
+
--accepted-plan /absolute/path/to/accepted-promotion.json
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
Use the new printed digest for `--apply --expected-plan ...`, keeping `--accepted-plan` on that command too when using the fallback. The reconstructed binding must exactly match the coordinator's retained acceptance hash. The plan cannot replace a missing local acceptance record or authorize changed code, body, checks or policy.
|
|
60
|
+
|
|
61
|
+
The transferred head is the original reviewed PR head even when GitHub used squash or merge commits. The GitHub merge/squash commit is never described as reviewed or silently substituted. Squash merges can make subsequent branch histories diverge between hosts; prefer history-preserving merges for this bridge. A future branch that is not a fast-forward of its mapped Bitbucket branch must be reconciled and reviewed, not force-pushed.
|
|
62
|
+
|
|
63
|
+
## Races and retries
|
|
64
|
+
|
|
65
|
+
Apply rechecks the plan before pushing. A native pre-push guard checks the server-advertised old branch SHA; Git's ordinary fast-forward update then compares that SHA on the server. No force or force-with-lease option is used.
|
|
66
|
+
|
|
67
|
+
There is no atomic transaction across GitHub and Bitbucket. The command rechecks evidence and destination after the push, before publishing the PR, and verifies the returned PR head/base. The publication adapter's final reconciliation read also enforces the approved PR absence or exact existing number and previous title/body. An observed concurrent creation or text edit stops publication. This adapter has no atomic conditional-update contract with Bitbucket: an edit between that final read and the write can still be overwritten without detection, so avoid concurrent PR editing during apply. If an operation fails, including a lost push response, the branch or PR may already have been updated; the error states that possibility. Inspect the target and rerun a dry run. Never respond with a force push. Bitbucket merge and deployment remain separate operator decisions and retain their normal release controls.
|
|
68
|
+
|
|
69
|
+
This bridge supports GitHub to Bitbucket Cloud only. It does not automatically schedule promotion, accept unregistered PRs, establish live production readiness, or migrate CI/secrets/deployment configuration.
|
|
@@ -0,0 +1,330 @@
|
|
|
1
|
+
# Bitbucket Cloud review setup and qualification
|
|
2
|
+
|
|
3
|
+
Bitbucket Cloud dispatch and complete first-party evidence capture are implemented.
|
|
4
|
+
The independent local review route is still **live-unqualified** until the public
|
|
5
|
+
and private disposable repository matrix records a genuine blocking verdict,
|
|
6
|
+
same-session correction and fresh exact-head clearance. Earlier disposable runs
|
|
7
|
+
proved regular PR publication and receipt acceptance with **no reviewer
|
|
8
|
+
configured**; they are not review evidence. The private coding session could also
|
|
9
|
+
read the coordinator's merge-capable API-token file by path, so that historical
|
|
10
|
+
coding-credential hold remains separate from reviewer credential isolation. Do
|
|
11
|
+
not migrate an existing legacy run or start unattended work on the strength of
|
|
12
|
+
offline fixtures. See the [qualification record](audit/bitbucket-review-qualification.md).
|
|
13
|
+
|
|
14
|
+
## First setup, including a checkout with no existing configuration
|
|
15
|
+
|
|
16
|
+
Use Node 22 or later, Git, and an explicitly selected installed local Codex or
|
|
17
|
+
Claude executable. Bitbucket setup does not require `gh` or GitHub sign-in.
|
|
18
|
+
Version/sign-in diagnostics do not prove model access. Existing GitHub defaults
|
|
19
|
+
and runs retain their previous review semantics.
|
|
20
|
+
|
|
21
|
+
1. Obtain an Atlassian **account API token** scoped to the intended workspace,
|
|
22
|
+
with `read:repository:bitbucket`, `write:repository:bitbucket`,
|
|
23
|
+
`read:pullrequest:bitbucket`, and `write:pullrequest:bitbucket`. Save it in a
|
|
24
|
+
private file (`chmod 600`). Supply the account email separately. An account
|
|
25
|
+
API token can be used with a free-plan repository; this does not require a
|
|
26
|
+
workspace/repository access-token subscription or Agentic Pipelines.
|
|
27
|
+
2. For HTTPS Git, the coordinator uses the selected token as
|
|
28
|
+
`x-bitbucket-api-token-auth`; the API uses account email/token Basic auth.
|
|
29
|
+
For SSH Git, keep the API token and select the explicit SSH key/verified
|
|
30
|
+
known-hosts file described in [Git host setup](git-hosts.md). SSH authentication
|
|
31
|
+
alone cannot read or write PRs. The coding session receives neither token nor
|
|
32
|
+
SSH key through environment variables: its bounded PR mailbox asks the
|
|
33
|
+
coordinator to push and publish. A same-user coding process can still read
|
|
34
|
+
the configured private files unless a separate boundary denies those reads.
|
|
35
|
+
HTTPS and Cloud SSH checkout origins identify
|
|
36
|
+
the same repository; self-hosted servers and SSH aliases remain unsupported.
|
|
37
|
+
3. Write a host settings file outside the coding checkout. Example:
|
|
38
|
+
|
|
39
|
+
```json
|
|
40
|
+
{
|
|
41
|
+
"api": {
|
|
42
|
+
"email": "operator@example.com",
|
|
43
|
+
"token_file": "~/.config/repository-access/bitbucket-api-token"
|
|
44
|
+
},
|
|
45
|
+
"git": { "transport": "https" },
|
|
46
|
+
"trusted_authors": ["{11111111-1111-1111-1111-111111111111}"],
|
|
47
|
+
"reviewer": null,
|
|
48
|
+
"required_checks": ["Tests"]
|
|
49
|
+
}
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
Replace the example UUID with the operator's stable Bitbucket UUID, not a nickname.
|
|
53
|
+
Select `reviewer: null` deliberately; the local first-party path needs no separate
|
|
54
|
+
Bitbucket reviewer account. After `init`, configure the repository entry for a
|
|
55
|
+
new reviewed run:
|
|
56
|
+
|
|
57
|
+
```json
|
|
58
|
+
{
|
|
59
|
+
"repo": "bitbucket.org/workspace/repository",
|
|
60
|
+
"reviewer": null,
|
|
61
|
+
"review": {
|
|
62
|
+
"mode": "first-party-required",
|
|
63
|
+
"route": "codex",
|
|
64
|
+
"max_input_bytes": 100000,
|
|
65
|
+
"max_jobs": 2048,
|
|
66
|
+
"budget_usd": 100,
|
|
67
|
+
"zero_checks": false
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
Keep `review.legacy_no_review: true` only for a deliberately unreviewed legacy
|
|
73
|
+
run while live qualification is unavailable. That mode still enforces configured
|
|
74
|
+
CI, trusted commands, unresolved required feedback and the completion receipt,
|
|
75
|
+
but its readiness record says `none`; it is never independently reviewed. The
|
|
76
|
+
example check name must exactly match the repository's build status name. An
|
|
77
|
+
empty `required_checks` list does not waive CI for a version-1 policy: a repository
|
|
78
|
+
with no checks must explicitly set `review.zero_checks: true`. Missing/partial
|
|
79
|
+
responses, rate limits, outages and pending checks never pass.
|
|
80
|
+
|
|
81
|
+
From the intended checkout:
|
|
82
|
+
|
|
83
|
+
```sh
|
|
84
|
+
gallivant init --harness codex --host-config /absolute/path/bitbucket-host.json --base release/v2
|
|
85
|
+
gallivant doctor
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
`--host-config` imports settings for the verified checkout's host. It creates a
|
|
89
|
+
new config, or accepts unchanged settings while preserving UUID bindings added
|
|
90
|
+
by setup. JSON member order does not matter; changed or omitted policy and
|
|
91
|
+
conflicting identity bindings are refused. `--base` is validated and saved on the repository entry.
|
|
92
|
+
`init` binds repository/workspace UUIDs, reads the selected base and account push
|
|
93
|
+
role, and verifies Git's base SHA against the API. `doctor` distinguishes unknown
|
|
94
|
+
write scopes from observed read access. Only an actual write can prove Git push,
|
|
95
|
+
PR creation and comment write permission. Setup never installs a pipeline,
|
|
96
|
+
creates a credential, changes repository protection, or makes a paid model call.
|
|
97
|
+
It reports dispatch availability separately from transport access.
|
|
98
|
+
|
|
99
|
+
Host settings live under `git_hosts["bitbucket.org"]`. `repositories["workspace/repo"]`
|
|
100
|
+
may override `api`, `git`, `reviewer`, `trusted_authors`, and `required_checks`,
|
|
101
|
+
alongside the UUID binding. Each override replaces that setting, not another
|
|
102
|
+
host's credentials. A `repos` object may override reviewer/trust/check policy;
|
|
103
|
+
precedence is repository entry, host repository binding, host settings. Historical
|
|
104
|
+
top-level reviewer/trust defaults apply only to GitHub. Reviewer objects for
|
|
105
|
+
Bitbucket must supply every required field; the GitHub mention is rejected.
|
|
106
|
+
|
|
107
|
+
## Independent local Codex reviewer
|
|
108
|
+
|
|
109
|
+
The host adapter binds the repository UUID, PR number, full head and base object
|
|
110
|
+
IDs, and merge base. It paginates `diffstat/<head>..<base>?topic=true`, compares
|
|
111
|
+
that changed-path inventory to the complete raw comparison, and reads regular
|
|
112
|
+
UTF-8 source at the merge base and head through `src/{commit}/{path}`. Added,
|
|
113
|
+
modified, removed and renamed files all carry before/after text as applicable.
|
|
114
|
+
Unsupported binary, subrepository, missing-patch, duplicate, truncated, stale,
|
|
115
|
+
rate-limited, redirected and oversized evidence is refused. The coordinator
|
|
116
|
+
captures bounded symlink target data as untrusted Git objects without following
|
|
117
|
+
the link. Unsupported targets or ambiguous type transitions block review.
|
|
118
|
+
The PR binding is read again after capture. The API token stays behind the host boundary and is not
|
|
119
|
+
part of the reviewer prompt or environment.
|
|
120
|
+
|
|
121
|
+
The coordinator requests bounded PNG and JPEG sides at the exact revisions and
|
|
122
|
+
requires a separate image-capability qualification before launching visual jobs.
|
|
123
|
+
It combines their validated reports with text review and whole-PR synthesis.
|
|
124
|
+
The image qualification does not itself qualify the host or complete a PR review;
|
|
125
|
+
the [disposable live screenshot review](audit/bitbucket-review-qualification.md#live-image-qualification-and-disposable-review-2026-11-03)
|
|
126
|
+
reached a clear verdict after its owned outputs were recovered; the resend PR
|
|
127
|
+
has not been rechecked. Preserve the original files and incomplete state when any
|
|
128
|
+
capability or evidence is unavailable.
|
|
129
|
+
|
|
130
|
+
Qualify the exact configured executable/provider route only after authorizing its
|
|
131
|
+
separate paid challenge:
|
|
132
|
+
|
|
133
|
+
```sh
|
|
134
|
+
gallivant review qualify --repo bitbucket.org/workspace/repository
|
|
135
|
+
gallivant review qualify --repo bitbucket.org/workspace/repository --run --wait
|
|
136
|
+
gallivant review qualify --repo bitbucket.org/workspace/repository
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
The first and last commands are read-only. `--run` starts at most the one durable
|
|
140
|
+
qualification job for that fingerprint; CLI version and sign-in checks alone do
|
|
141
|
+
not prove selected-model access. Start refuses before author dispatch if the route
|
|
142
|
+
cannot qualify.
|
|
143
|
+
|
|
144
|
+
Qualification fingerprints use the adapter's selected provider environment,
|
|
145
|
+
configuration, credentials and executable. Parent-agent session and tool-call
|
|
146
|
+
IDs do not invalidate an existing qualification. The private Codex profile drops
|
|
147
|
+
the desktop-only `daybreak` flag for CLI compatibility; strict inspection of
|
|
148
|
+
effective permissions and managed policy remains required.
|
|
149
|
+
|
|
150
|
+
For a settled existing run that still has the explicit legacy snapshot, use the
|
|
151
|
+
audited transition and then recheck the same PR:
|
|
152
|
+
|
|
153
|
+
```sh
|
|
154
|
+
gallivant review policy HANDLE --mode first-party-required \
|
|
155
|
+
--reason "Enable the qualified independent local reviewer"
|
|
156
|
+
gallivant recheck HANDLE
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
This is the only path that removes the saved legacy policy. It retains the task
|
|
160
|
+
identity, original PRD snapshot, PR, checkout and implementation session. A
|
|
161
|
+
failed route preflight changes nothing and launches no review. Do not edit an
|
|
162
|
+
active WebBabyShower brief or local policy as an implementation test.
|
|
163
|
+
|
|
164
|
+
Each reviewer job is a fresh restricted Codex execution with no implementation
|
|
165
|
+
session, context mounts, tools, network, host/Git credential or publication
|
|
166
|
+
authority. The 100,000-byte input cap applies to every job. Large evidence is
|
|
167
|
+
split into immutable source/patch slices, including a single large lockfile or
|
|
168
|
+
line; every slice repeats the aggregate identities and all acceptance criteria.
|
|
169
|
+
Clearance requires every piece to complete and match. `max_jobs`, `budget_usd`
|
|
170
|
+
and per-job timeout bound the aggregate. If the full change does not fit those
|
|
171
|
+
bounds, the run stops with `review-incomplete`; no path or suffix is omitted.
|
|
172
|
+
|
|
173
|
+
## External Bitbucket reviewer account
|
|
174
|
+
|
|
175
|
+
This is an alternative external-review setup, not required by the local path.
|
|
176
|
+
Use a separate Bitbucket account for the automated reviewer. Configure its stable
|
|
177
|
+
UUID, never its display name, nickname, the coding account, or a Pipeline label:
|
|
178
|
+
|
|
179
|
+
```json
|
|
180
|
+
{
|
|
181
|
+
"reviewer": {
|
|
182
|
+
"actor_id": "{22222222-2222-2222-2222-222222222222}",
|
|
183
|
+
"rereview_comment": "Review the current commit and post a work-review verdict.",
|
|
184
|
+
"blocking_pattern": "\\bP[01]\\b"
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
This fragment belongs in the coding coordinator's host/repository policy. The
|
|
190
|
+
reviewer token does **not** belong there. On a separate operator-controlled
|
|
191
|
+
reviewer machine, OS account, or isolated container, store another private config
|
|
192
|
+
with the same policy and the **reviewer** account email/token in `api`. Its token
|
|
193
|
+
needs repository read and PR read/write. The coding agent must have no filesystem,
|
|
194
|
+
environment, secret-store or container access to that credential. A private file
|
|
195
|
+
in a directory readable by the coding identity is not isolation. The review model
|
|
196
|
+
needs only the prepared input and a read-only checkout, never publication secrets.
|
|
197
|
+
Codex requires its own supported sign-in or provider credentials and actual model
|
|
198
|
+
access; CLI installation/sign-in alone cannot qualify it.
|
|
199
|
+
|
|
200
|
+
The installed `task-review` tool separates preparation and publication from
|
|
201
|
+
inference. It never invokes a model, changes model/provider settings, or posts a
|
|
202
|
+
review request. These review transport steps are covered by offline tests; the
|
|
203
|
+
intervening Codex execution and end-to-end publication are still unqualified:
|
|
204
|
+
|
|
205
|
+
```sh
|
|
206
|
+
task-review prepare --config /private/reviewer-config.json \
|
|
207
|
+
--url https://bitbucket.org/workspace/repo/pull-requests/7 > review-input.json
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
In the isolated reviewer checkout, use the operator-selected Codex executable
|
|
211
|
+
under the existing read-only review permissions to inspect the input's exact
|
|
212
|
+
head and diff. Follow `review-input.json.instructions`. Save its actual response
|
|
213
|
+
as `review-result.json`, containing only this JSON shape:
|
|
214
|
+
|
|
215
|
+
```json
|
|
216
|
+
{
|
|
217
|
+
"head_sha": "0123456789012345678901234567890123456789",
|
|
218
|
+
"verdict": "blocking",
|
|
219
|
+
"summary": "Concrete findings from reviewing this exact commit."
|
|
220
|
+
}
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
A successful model execution is not a verdict. Outside the model process, publish
|
|
224
|
+
its response with the separate reviewer credential:
|
|
225
|
+
|
|
226
|
+
```sh
|
|
227
|
+
task-review publish --config /private/reviewer-config.json \
|
|
228
|
+
--url https://bitbucket.org/workspace/repo/pull-requests/7 \
|
|
229
|
+
--input review-input.json --result review-result.json
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
Publication verifies the authenticated actor differs from the coding author and
|
|
233
|
+
matches `reviewer.actor_id`. It rechecks repository UUIDs, PR number, branches,
|
|
234
|
+
base, full head SHA and diff hash against the prepared input. An explicit retry
|
|
235
|
+
reuses an identical verdict only while it remains the reviewer's latest decision.
|
|
236
|
+
A superseded match causes a new publication, so blocking/clear/blocking decisions
|
|
237
|
+
take effect even on the same head. Uncertain comment writes are not silently
|
|
238
|
+
retried. Keep the real model transcript/run ID with qualification
|
|
239
|
+
artifacts: a manually authored fixture result cannot prove a Codex review.
|
|
240
|
+
An ordinary Pipeline can orchestrate these steps when an operator explicitly
|
|
241
|
+
installs it, enables Pipelines, and configures provider and reviewer secrets in an
|
|
242
|
+
isolated trusted job. Do not expose those secrets to arbitrary PR code or the
|
|
243
|
+
coding step. No paid Agentic Pipelines capability is assumed or installed.
|
|
244
|
+
|
|
245
|
+
The posted comment contains a `work-review` fenced JSON block. Only the configured
|
|
246
|
+
actor and a complete exact current SHA can clear readiness. Abbreviations, old-head
|
|
247
|
+
approvals, prose claiming a successful Pipeline, or a run with no posted verdict
|
|
248
|
+
are silence. Native Bitbucket approvals do not identify a reviewed commit and
|
|
249
|
+
cannot clear an automated-review gate. Native change requests and unresolved tasks
|
|
250
|
+
remain blockers until their authors remove/resolve them, including after one fix
|
|
251
|
+
round has consumed their events.
|
|
252
|
+
|
|
253
|
+
Trusted humans can post `/fix ...`. Inline findings use a verified code link to
|
|
254
|
+
the full source SHA or a standalone `Reviewed commit: <40-character-sha>` line.
|
|
255
|
+
Unknown inline heads stop readiness with the source link rather than silently
|
|
256
|
+
approving or dispatching a guessed head. A command explicitly naming an older head
|
|
257
|
+
is ignored. Replies authored by the coding account do not become new fix requests.
|
|
258
|
+
|
|
259
|
+
## Session PR operations and recovery
|
|
260
|
+
|
|
261
|
+
`task-pr` is the bounded PR CLI used by Bitbucket start/fix/resume prompts. In a
|
|
262
|
+
task session it writes a bounded request to the checkout's mailbox; the daemon
|
|
263
|
+
verifies the saved repository, branch, base and PR identity, then uses its own
|
|
264
|
+
Git and API credentials. `push`, `create`, `edit` and `comment` push committed
|
|
265
|
+
HEAD through the coordinator before publication. `view` and `diff` are read
|
|
266
|
+
operations. The agent receives no Git or PR token and no SSH key in its
|
|
267
|
+
environment. Its observed ability to read the token file remains a dispatch
|
|
268
|
+
blocker. The
|
|
269
|
+
coordinator disables checkout hooks when running Git, so an agent-written
|
|
270
|
+
pre-push hook cannot run with coordinator authority. The mailbox has no merge,
|
|
271
|
+
deployment or repository-settings operation. Direct `task-pr` use outside an
|
|
272
|
+
agent session still requires an explicitly bound API credential.
|
|
273
|
+
The PR CLI created and reconciled a disposable private PR, read its exact head,
|
|
274
|
+
posted a comment and updated its body. A separate live public task also used it
|
|
275
|
+
to open and update a regular PR. See the [qualification record](audit/bitbucket-review-qualification.md).
|
|
276
|
+
|
|
277
|
+
After the credential boundary is qualified, local PRD commands use the verified
|
|
278
|
+
checkout, and `register` uses the exact PR
|
|
279
|
+
URL. Host-qualified state/worktree keys
|
|
280
|
+
prevent a same-named GitHub repository controlling a Bitbucket PR. Base overrides
|
|
281
|
+
flow through clone, PR publication and later base updates. Use `gallivant doctor`
|
|
282
|
+
to confirm access and policy before `gallivant start <prd> --base <branch>`.
|
|
283
|
+
Hosted providers with a GitHub-bound environment are incompatible. A snapshot
|
|
284
|
+
provider must pass the same publication and qualification checks as a local one.
|
|
285
|
+
|
|
286
|
+
Bitbucket snapshots supply one coherent set of paginated comments, participants,
|
|
287
|
+
required tasks and statuses for the head. The shared event cursor, bounded fix
|
|
288
|
+
round, session continuation, completion gate and chain engine consume those
|
|
289
|
+
records. Unreadable snapshots preserve cursors. A changed PR branch/base or a
|
|
290
|
+
replacement repository stops with `pr-identity`. Declined/superseded PRs cannot
|
|
291
|
+
become done. A merged PR must match the recorded head and its merge commit must
|
|
292
|
+
be an ancestor of the intended base before completion or chain advancement.
|
|
293
|
+
No command merges the PR, force-pushes, deploys or alters protections.
|
|
294
|
+
|
|
295
|
+
## Troubleshooting
|
|
296
|
+
|
|
297
|
+
- `NO_CREDENTIAL`: select the account email and private API-token file under the
|
|
298
|
+
correct host/repository. An SSH key, GitHub token or token file without an email
|
|
299
|
+
is insufficient. Restore scopes before retrying; do not broaden another host.
|
|
300
|
+
- `reviewer.actor_id` / explicit reviewer errors: use the actual UUID and producer
|
|
301
|
+
configuration, or explicitly choose no-reviewer mode. Do not use `@codex review`.
|
|
302
|
+
- `BB_INCOMPLETE`, `BB_STALE`, HTTP 429/5xx: restore API access or wait for the read
|
|
303
|
+
retry. Never clear a cursor or turn missing evidence into an empty collection.
|
|
304
|
+
- `REVIEW_UNQUALIFIED`: confirm the exact `harness.codex.bin`, selected model and
|
|
305
|
+
provider access, then explicitly run `review qualify --repo ... --run`. Do not
|
|
306
|
+
substitute `--version`, sign-in status or an offline fixture.
|
|
307
|
+
- `review-incomplete` / `REVIEW_INCOMPLETE`: inspect the named missing identity,
|
|
308
|
+
path, patch or required job count. For a large complete text change, raise
|
|
309
|
+
`max_jobs` and `budget_usd` only within an operator-approved bound, then select
|
|
310
|
+
the new policy explicitly. Unsupported binary, subrepository, malformed link, rate-limited,
|
|
311
|
+
redirected or stale evidence must be corrected; increasing a byte cap is not a
|
|
312
|
+
workaround.
|
|
313
|
+
- Screenshot evidence: check `review qualify --repo ... --capability image` for
|
|
314
|
+
the exact route. Repair the reported native or provider issue before a separately
|
|
315
|
+
authorized `--run`; do not repeat an unchanged failed launch. PNG/JPEG limits
|
|
316
|
+
and all image sides still apply. Unsupported formats remain incomplete.
|
|
317
|
+
- `pr-identity`: inspect source/base/repository/head and restore the recorded
|
|
318
|
+
identity. A decline or unproven merge needs operator reconciliation, not a new
|
|
319
|
+
paid run or an automatic chain advance.
|
|
320
|
+
- Access probe fails: check the selected coordinator SSH key or HTTPS token and
|
|
321
|
+
the account API token for PR operations. The coding session receives neither.
|
|
322
|
+
Re-run `doctor`, then resume the existing task rather than starting a duplicate.
|
|
323
|
+
- PR mailbox timeout: confirm the daemon is running and can read the selected
|
|
324
|
+
repository; retry the same `task-pr` operation. Do not give the coding session
|
|
325
|
+
a token to work around the mailbox.
|
|
326
|
+
|
|
327
|
+
API semantics are based on Atlassian's [PR APIs](https://developer.atlassian.com/cloud/bitbucket/rest/api-group-pullrequests/),
|
|
328
|
+
[commit ancestry API](https://developer.atlassian.com/cloud/bitbucket/rest/api-group-commits/),
|
|
329
|
+
[source metadata](https://developer.atlassian.com/cloud/bitbucket/rest/api-group-source/),
|
|
330
|
+
and [account API-token guidance](https://support.atlassian.com/bitbucket-cloud/docs/using-api-tokens/).
|