@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
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
# First-party review gate
|
|
2
|
+
|
|
3
|
+
This is an opt-in model judgement of an immutable task snapshot. It is **not Git-host bot approval**, proof that every defect was found, or authority to merge, deploy, release or advance a chain. Checks, the completion gate, trusted feedback and the existing human merge boundary still apply. The [qualification record](audit/first-party-review.md) currently records an unavailable native boundary and unmeasured live quality; do not change defaults on the strength of deterministic fixtures.
|
|
4
|
+
|
|
5
|
+
## Select a policy
|
|
6
|
+
|
|
7
|
+
New tasks snapshot one version-1 policy:
|
|
8
|
+
|
|
9
|
+
| Mode | Required evidence |
|
|
10
|
+
| --- | --- |
|
|
11
|
+
| `external-required` | Configured external actor's clear verdict for the exact head |
|
|
12
|
+
| `first-party-required` | Coordinator-owned first-party clear for the exact input |
|
|
13
|
+
| `both-required` | Both, without unresolved disagreement |
|
|
14
|
+
|
|
15
|
+
A configured external reviewer retains `external-required` by default. There is no bot-installation detection. A repository with `reviewer: null` must opt into a qualified route, or explicitly choose the legacy exception below. Missing, slow, failed and rate-limited required reviewers never count as clear and never select another policy.
|
|
16
|
+
|
|
17
|
+
For new tasks without a remote reviewer, set these keys in the operator configuration:
|
|
18
|
+
|
|
19
|
+
```json
|
|
20
|
+
{
|
|
21
|
+
"reviewer": null,
|
|
22
|
+
"review": {
|
|
23
|
+
"mode": "first-party-required",
|
|
24
|
+
"route": "codex",
|
|
25
|
+
"specialist": null,
|
|
26
|
+
"timeout_ms": 3600000,
|
|
27
|
+
"max_jobs": 2048,
|
|
28
|
+
"retries": 2,
|
|
29
|
+
"budget_usd": 100,
|
|
30
|
+
"max_input_bytes": 100000,
|
|
31
|
+
"zero_checks": false
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
`review` can also be set on a `repos` object. Defaults allow 2,048 total reviewer jobs per task, including fresh-head rereviews and final synthesis, a $100 accounting allowance, two known pre-dispatch retries and 60 minutes per job. Each source piece, reduction and whole-PR synthesis has its own deadline; the limit is not a deadline for the entire PR review. Operators can select up to 8,192 jobs, $10,000 and one hour per job; explicit smaller limits remain enforced. Raising defaults does not silently rewrite saved task policies. The external actor remains the configured `reviewer` object and is copied into each task. `specialist` is either `null`, `security`, or `regression`; general correctness always applies. These are short rubrics, with no policy or requirements authority.
|
|
37
|
+
|
|
38
|
+
`zero_checks: true` is an explicit operator CI policy for a repository with no required checks. An empty Git-host response alone never establishes that policy for new version-1 tasks. Missing CI stops as `missing-ci`; a missing/disabled completion gate stops separately as `completion-gate-skipped`.
|
|
39
|
+
|
|
40
|
+
Legacy records are snapshotted as version 0 on reconciliation using their last configured external requirement. An absent reviewer is explicitly displayed as **legacy no-review**, never clearance. Existing runs do not inherit new config policy choices. For an intentional new legacy run, set both `reviewer: null` and `review: { "legacy_no_review": true }`. This grants no review evidence. Back up state before upgrading: historical configurations that were never recorded cannot be recovered from PR prose, so restore the original reviewer configuration before the first reconciliation of old records.
|
|
41
|
+
|
|
42
|
+
## Qualification and diagnostics
|
|
43
|
+
|
|
44
|
+
The selected Git host must provide the complete review-evidence operation through
|
|
45
|
+
the shared host registry. An unsupported host or missing operation stops
|
|
46
|
+
qualification before native preparation, including when a saved clear exists.
|
|
47
|
+
GitHub retains `owner/repo` identities. Bitbucket uses
|
|
48
|
+
`bitbucket.org/workspace/repository`; its evidence adapter is implemented, but its
|
|
49
|
+
live private/public review matrix remains a separate qualification requirement.
|
|
50
|
+
No other Git host is supported by this review path.
|
|
51
|
+
|
|
52
|
+
Use the exact executable in `harness.codex.bin`. Only its restricted preparation profile is implemented as a reviewer route; other coding adapters are unqualified. The review service supplies text in a fresh isolated workspace, disables tools, MCP/plugins, hooks, skills, memories, delegation, telemetry and user/project instructions, denies escalation and network access from model tools, and verifies the effective native configuration including managed requirements. Provider authentication is confined to the native inference connection. The coding session and its context mounts are never reused.
|
|
53
|
+
|
|
54
|
+
```sh
|
|
55
|
+
gallivant review qualify --repo owner/repo
|
|
56
|
+
gallivant review qualify --repo owner/repo --run --wait
|
|
57
|
+
gallivant review qualify --repo bitbucket.org/workspace/repository
|
|
58
|
+
gallivant review qualify --repo bitbucket.org/workspace/repository --run --wait
|
|
59
|
+
gallivant review status <task-handle>
|
|
60
|
+
gallivant doctor
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
The run page shows a live reviewer activity feed with the current phase, job
|
|
64
|
+
progress, findings count and handoff state. It is separate from the coding
|
|
65
|
+
agent's log and updates while the page is open; it does not expose reviewer
|
|
66
|
+
prompts, raw output or captured source. Its visible history starts when the
|
|
67
|
+
page opens. The entries dashboard's last-activity time tracks a run, review or
|
|
68
|
+
recorded event, rather than routine coordinator writes.
|
|
69
|
+
|
|
70
|
+
The first command only reads qualification. `--run` explicitly authorizes a separate bounded live challenge. It returns a running record; repeating the command reconciles that same keyed execution. A failed qualification is retained, not silently retried as a new paid session. Repair the observed provider/native-policy failure before requalification; changed native configuration yields a different qualification identity. A credential/configuration/binary change invalidates qualification. Setup diagnostics and start preflight require qualification and recheck the effective native boundary before author launch. A version/sign-in result alone cannot qualify a route.
|
|
71
|
+
|
|
72
|
+
For recognized ChatGPT OAuth profiles, routine token refresh retains the same
|
|
73
|
+
qualification only when the selected account, owner, issuer, client and subject
|
|
74
|
+
remain consistent across the locally stored ID and access token claims. A
|
|
75
|
+
changed principal or provider invalidates qualification. The provider still
|
|
76
|
+
validates the actual credentials; unknown formats and API keys use the full
|
|
77
|
+
credential digest and fail closed on changes.
|
|
78
|
+
Unrelated absolute project trust records outside the review root do not change
|
|
79
|
+
the review identity. Records covering the review root and all other effective
|
|
80
|
+
configuration and managed policies remain bound.
|
|
81
|
+
|
|
82
|
+
`npm run test:first-party-review:live` is the opt-in disposable-repository probe. It requires `REVIEW_LIVE=1`, the normal operator configuration, and an explicit review allowance; ordinary tests never call a model. Do not run it to work around an administrator or guardrail refusal.
|
|
83
|
+
|
|
84
|
+
Codex does not expose a native USD hard cap or reliable cost receipt here. The coordinator reserves `budget_usd / max_jobs` before each review launch and consumes the reservation even when actual cost is unknown. `max_input_bytes` remains a hard per-job prompt cap (at most 100,000 bytes); it is never raised for a large PR. `max_jobs`, the reserved budget and the per-job timeout bound the complete aggregate. Job count, wall time and known pre-dispatch retries are independently bounded. This is an accounting allowance, **not a guaranteed provider billing cap**. Cost qualification and live spend measurement remain outstanding; configure a provider-side limit before relying on a monetary ceiling. Provider failure requires a person; it never spends a coding fix round by itself.
|
|
85
|
+
|
|
86
|
+
## Evidence, fixes and migration
|
|
87
|
+
|
|
88
|
+
The GitHub and Bitbucket adapters capture exact head/base/merge-base IDs, a complete diff, full before/after content for added, modified, removed and renamed files, the immutable PRD and every criterion, checks and the full completion receipt. Bitbucket additionally binds the repository UUID and PR number, consumes every diffstat page, compares that inventory to the raw commit comparison, reads source metadata/content at the merge base and head, and rechecks the PR after capture. Oversized evidence, unsupported binaries or submodule content, omitted patches, duplicate or truncated pages, unreadable snapshots and concurrent PR changes produce incomplete review. API credentials stay in the host adapter; reviewer jobs receive neither host nor Git credentials, and redirects outside the bound API repository are refused.
|
|
89
|
+
|
|
90
|
+
The coordinator requests PNG and JPEG evidence and plans one restricted visual job per changed side alongside text slices. Captures are limited to 32 image sides, 5 MiB per side and 16 MiB total, with dimensions at most 8192 by 8192 and 16 million pixels. Corrupt, unsupported, oversized or incomplete images fail closed. Text qualification alone does not qualify image attachment, model vision or isolation. Each visual job receives a coordinator-created copy, and its exact image identity is checked again at execution; image text and metadata are untrusted data. A [disposable live screenshot review](audit/bitbucket-review-qualification.md#live-image-qualification-and-disposable-review-2026-11-03) reached a clear whole-PR verdict after recovering its owned outputs; the resend PR remains unverified. Preserve screenshots and an incomplete status when qualification or evidence is missing.
|
|
91
|
+
|
|
92
|
+
The coordinator requests link-object capture from both host adapters. Bounded UTF-8 target bytes are reviewed as untrusted Git object data at each revision; targets are never resolved or followed. Unsupported targets, ambiguous type transitions, incomplete inventories or mismatched hashes and revisions fail closed. Host and reviewer qualification still applies.
|
|
93
|
+
|
|
94
|
+
Image qualification is recorded independently for the configured executable bytes,
|
|
95
|
+
model and reviewer configuration. `review qualify --repo OWNER/REPO --capability image`
|
|
96
|
+
reads its status; adding `--run` explicitly starts one bounded image challenge and
|
|
97
|
+
consumes the review allowance. The challenge verifies a coordinator-created copy
|
|
98
|
+
at the execution boundary. It is not an end-to-end PR review or host qualification.
|
|
99
|
+
All image sides, text slices and the whole-PR synthesis must complete under the
|
|
100
|
+
same bounded allowance; missing or mismatched results cannot clear the review.
|
|
101
|
+
An image inspection judges its own image, while a text-only requirement may be
|
|
102
|
+
deferred to synthesis. The coordinator records criteria omitted by an image job
|
|
103
|
+
and carries its unresolved concerns through reductions. The final reviewer must
|
|
104
|
+
evaluate those concerns and all criteria against the combined evidence; an
|
|
105
|
+
unresolved need for visual evidence still blocks clearance. A previously owned
|
|
106
|
+
image output rejected solely for local scope can be revalidated against its
|
|
107
|
+
original input and qualification without launching the image job again.
|
|
108
|
+
|
|
109
|
+
When the full serialized evidence does not fit one job, the shared service creates immutable byte-bounded source and patch slices. Every piece repeats the same task, repository, PR, head, base, merge base, brief, criteria, checks, receipt, policy and aggregate digest. Long single lines and large lockfiles are sliced with absolute line/column offsets rather than omitted. Every changed path and every criterion must appear in the aggregate, every piece must return a valid matching identity, and all pieces must finish before clearance. A finding in any piece, a timeout, malformed output, missing piece, conflicting finding identity, exhausted job/budget bound or unresolved scope blocks readiness. If the configured aggregate cannot hold the evidence, the result says `review-incomplete`/`REVIEW_INCOMPLETE` with the required and configured job counts; it does not review a prefix.
|
|
110
|
+
|
|
111
|
+
Split review has two stages. Each local inspection judges only supplied slices,
|
|
112
|
+
records concrete defects and supplies bounded, source-quoted observations for
|
|
113
|
+
the final reviewer. Missing other pieces is expected and does not establish a
|
|
114
|
+
missing implementation. Local clear verdicts cannot clear the PR. If every local
|
|
115
|
+
inspection finishes without findings, a separate restricted whole-PR reviewer
|
|
116
|
+
receives the complete criteria, receipt and checks plus reports or validated
|
|
117
|
+
reductions covering every source piece. It
|
|
118
|
+
must resolve cross-file questions and return its own clear verdict. Empty reports,
|
|
119
|
+
unsupported quotes, unresolved scope and oversized synthesis never clear. Each
|
|
120
|
+
observation is verified against its captured source; final findings must also be
|
|
121
|
+
grounded in a supplied report. An incorrect line number is resolved only when the
|
|
122
|
+
exact single-line quote occurs at one unique line in the supplied file, side and
|
|
123
|
+
slice (or, for synthesis, a supplied report). The original and corrected line
|
|
124
|
+
and a quote digest are retained in the review ledger. Ambiguous, absent or
|
|
125
|
+
multiline quotes never gain clearance from this correction.
|
|
126
|
+
When execution sanitization masks a secret-looking value in a quote, the
|
|
127
|
+
coordinator compares it with the same sanitized form of the captured source
|
|
128
|
+
line. The review result retains the masked quote; matching still requires the
|
|
129
|
+
specified file, side and line or a unique source location.
|
|
130
|
+
|
|
131
|
+
Malformed output or an unverifiable citation receives up to the configured
|
|
132
|
+
`retries` fresh, tools-disabled reviewer attempts, using the same job, spend and
|
|
133
|
+
time limits. Previous attempts stay in the ledger; an ambiguous launch, tool
|
|
134
|
+
attempt or provider failure is never silently retried as a format error. A local
|
|
135
|
+
scope concern is retained in the ledger and carried through any reductions to
|
|
136
|
+
the final whole-PR reviewer; it is never accepted as clearance. Whole-PR
|
|
137
|
+
unresolved scope remains blocking. Older outputs rejected for citation numbering
|
|
138
|
+
or local-slice scope are revalidated once against the exact original input and
|
|
139
|
+
owned execution.
|
|
140
|
+
A confirmed, terminal Codex model-capacity response receives bounded retries
|
|
141
|
+
after one and five minutes, within the same reviewer job and spend allowances.
|
|
142
|
+
The saved evidence and completed pieces are retained. Authentication, quota,
|
|
143
|
+
policy denials, ambiguous ownership and unrecognized provider errors still stop
|
|
144
|
+
for inspection; no model or provider is switched automatically.
|
|
145
|
+
A new protocol identity retains old failed jobs
|
|
146
|
+
for audit without reusing their incomplete verdicts.
|
|
147
|
+
|
|
148
|
+
A local-scope inspection still requires final synthesis when partitioning happens
|
|
149
|
+
to produce only one piece; only an actual unsplit whole-PR review may clear
|
|
150
|
+
directly. If the combined reports exceed the prompt cap, the same restricted
|
|
151
|
+
review service reduces them in bounded groups over as many levels as needed.
|
|
152
|
+
Each node binds its child reports and a contiguous coverage range to the original
|
|
153
|
+
aggregate. Missing, duplicate or out-of-order coverage is refused, and the root
|
|
154
|
+
must cover every original piece. All original reports and intermediate jobs stay
|
|
155
|
+
in the durable ledger. Each reduction preserves source-grounded observations;
|
|
156
|
+
any concrete finding blocks instead of being summarized away. A reduction's
|
|
157
|
+
local clear verdict never replaces the final whole-PR verdict. Reduction and
|
|
158
|
+
final jobs consume the same task job, spend and timeout allowances, and restart
|
|
159
|
+
reuses their exact saved inputs and executions.
|
|
160
|
+
|
|
161
|
+
Source capture remains bounded to 16 MiB overall, independently of the higher
|
|
162
|
+
job allowance. The per-job input remains 100,000 bytes; synthesis must fit the
|
|
163
|
+
same bound. These are evidence and context limits, not spending defaults. Explicit
|
|
164
|
+
task/provider authorizations remain pinned. The intake planner has separate,
|
|
165
|
+
explicitly funded settings: up to 12 calls, 100,000 input and 16,000 output
|
|
166
|
+
tokens per call, $10 and a five-minute request timeout. Those higher ceilings
|
|
167
|
+
do not enlarge a saved task's approved allowance.
|
|
168
|
+
|
|
169
|
+
The model receives this material as untrusted JSON. The final output must cover all criteria, identify the route/head/input digest, leave no unresolved scope, and report either `clear` or actionable findings grounded in captured source or an exact image identity. Local concerns are carried to that final review. Invalid, partial, timed-out, failed or tool-attempting output cannot clear. The coordinator owns the ledger under `reviews/` and the separate execution namespace under `runs/review__...`. Public comments and agent-authored approval text are never an alternative source of internal clearance.
|
|
170
|
+
|
|
171
|
+
Polling reuses captured source only when the repository, head and base still match, and rechecks the live PR binding before using it. Changed head, base, checks, receipt, policy or brief invalidates the whole aggregate, not only one piece. Piece keys make restart and repeated host pages idempotent; an old-head or partial aggregate cannot clear. A delayed poll accepts a valid result whose recorded execution completion time met the deadline; missing completion times, late results and executions still running past the deadline cannot clear.
|
|
172
|
+
|
|
173
|
+
The registry caches validated reads only while the underlying file identity and
|
|
174
|
+
timestamps are unchanged. Returned records remain detached, and another
|
|
175
|
+
process's atomic write invalidates the cache. This avoids repeatedly parsing a
|
|
176
|
+
large registry during review polling without changing write ownership or gates.
|
|
177
|
+
Each review advancement also reuses immutable completed jobs from one ledger
|
|
178
|
+
read, while retaining the same policy, input, binding and reviewer checks.
|
|
179
|
+
|
|
180
|
+
Between host polls, the coordinator advances an already captured review on its
|
|
181
|
+
local progress cadence. It does not refetch the PR for every piece. Terminal
|
|
182
|
+
local results wake the host lane, which must reread the current binding before
|
|
183
|
+
readiness or author dispatch. An explicit recheck or policy change also wakes
|
|
184
|
+
that lane immediately instead of waiting for the old polling deadline.
|
|
185
|
+
|
|
186
|
+
Findings use the existing fix dispatch and round counter. Their disposition is recorded. A subsequent push needs fresh evidence. Repeated findings on the same input, required-reviewer disagreement and exhausted fix rounds stop for a person. `review dispute <handle> --finding <id> --reason "..."` records a pending dispute and removes readiness; it has no self-accept operation. A person must resolve the defect or deliberately change policy and re-evaluate it.
|
|
187
|
+
|
|
188
|
+
Findings remain `pending` during confirmed provider-health waits or a busy local runner. `dispatch-intent` is saved immediately before launch and becomes `dispatched` with the accepted run ID. A confirmed unsent refusal returns the findings to pending but still requires the existing explicit resume; an ambiguous launch retains its intent and requires a person before any retry. Waiting alone consumes no fix round.
|
|
189
|
+
|
|
190
|
+
Historical review records are stored in the private `reviews/history/` directory
|
|
191
|
+
under the Gallivant home. The registry retains compact references and dispatch
|
|
192
|
+
dispositions; `gallivant review status <handle>` verifies and displays the full
|
|
193
|
+
history. Existing inline history migrates on the next registry write. Back up and
|
|
194
|
+
restore the registry and the review directory together. Missing or changed archive
|
|
195
|
+
files are reported as errors rather than treated as review clearance. Migration
|
|
196
|
+
upgrades the registry format: older releases refuse it rather than changing
|
|
197
|
+
references they do not understand. Stop older coordinators before upgrading.
|
|
198
|
+
|
|
199
|
+
Transient Bitbucket read timeouts, rate limits and server errors during evidence
|
|
200
|
+
capture are retried through the bounded coordinator retry path. Authentication,
|
|
201
|
+
identity, incomplete evidence and uncertain write failures remain blocking; each
|
|
202
|
+
attempt still captures and verifies the current PR before review or readiness.
|
|
203
|
+
|
|
204
|
+
Changing head, base, checks, receipt or policy invalidates readiness. Configured external findings and trusted human feedback still enter the shared fix path, including feedback arriving after internal clearance on the same head. The external reviewer must answer again when its previously reviewed input changes. The completion gate remains independent of model opinion.
|
|
205
|
+
|
|
206
|
+
A newly observed head retains the push-based review window, so a timely exact-head approval that arrived between polls still counts. The same rule applies when an author run settles and advances the feedback cursor. Changes to base, receipt or checks on the same head start a new review window when observed and require a later external answer.
|
|
207
|
+
|
|
208
|
+
Config edits affect future tasks. For a stopped/settled existing task, use:
|
|
209
|
+
|
|
210
|
+
```sh
|
|
211
|
+
gallivant review policy <handle> --mode both-required --reason "Require both reviews for this task"
|
|
212
|
+
gallivant review policy <handle> --mode first-party-required --reason "Enable the qualified independent local reviewer"
|
|
213
|
+
gallivant recheck <handle>
|
|
214
|
+
gallivant review retry <handle> --reason "Retry the rejected citation with exact single-line source quotes"
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
`review retry` explicitly authorizes fresh reviewer executions for incomplete
|
|
218
|
+
output whose previous process exited successfully. It retains completed pieces,
|
|
219
|
+
original attempts, reservations and an operator-reason audit. New attempts use
|
|
220
|
+
the same job/spend/timeout limits and strict validation; recheck alone reuses the
|
|
221
|
+
old terminal record. It also accepts a reviewer cancelled by the coordinator
|
|
222
|
+
after a provider error only after confirming its identity, stopped process tree,
|
|
223
|
+
recorded cancellation reason and absence of tool attempts or denials. Ambiguous
|
|
224
|
+
launches, active reviewers, other provider failures, tool/boundary failures and
|
|
225
|
+
unresolved cancellation cannot use this shortcut.
|
|
226
|
+
The normal host lane rechecks the live binding before review can authorize
|
|
227
|
+
readiness. No author session, PR or chain merge gate is reset.
|
|
228
|
+
|
|
229
|
+
The command first proves that the selected route is qualified, then records the prior policy and reason, revokes readiness, and re-evaluates the current head. For an existing Bitbucket legacy run, this is the only path that removes `legacy_no_review`; direct config edits do not change its snapshot. The original PRD snapshot, task/run identity, PR, checkout and implementation session are retained. A failed preflight changes none of them and starts no paid review. No command here merges or advances a chain before its existing merge gate.
|
|
230
|
+
|
|
231
|
+
Policy changes and disputes share per-task process exclusion with review decisions,
|
|
232
|
+
including label publication and notification. If a decision is already in flight,
|
|
233
|
+
the command refuses without changing the policy; retry after that operation
|
|
234
|
+
finishes. A failed label removal leaves a durable obligation for later ticks to
|
|
235
|
+
retry, even while the task is stopped. Clearance stays revoked during that wait.
|
|
236
|
+
|
|
237
|
+
### Waiting for qualification and explicitly retrying a stopped probe
|
|
238
|
+
|
|
239
|
+
Use `gallivant review qualify --repo OWNER/REPO --run --wait` to keep the CLI
|
|
240
|
+
alive until its bounded challenge settles. This retains the process exit
|
|
241
|
+
callback; a short-lived launcher can otherwise lose the precise exit time and
|
|
242
|
+
later reject an on-time response as a late observed completion. Normal daemon
|
|
243
|
+
review continues to use its existing lifecycle.
|
|
244
|
+
|
|
245
|
+
Captured local reviews advance alongside provider and Git-host polling. They
|
|
246
|
+
wait for their own task's decision lock, not unrelated provider reconciliation.
|
|
247
|
+
This progress does not clear readiness: the coordinator still fetches the
|
|
248
|
+
current PR head and evaluates the complete review and acceptance gates.
|
|
249
|
+
|
|
250
|
+
After inspecting a failed qualification, use
|
|
251
|
+
`gallivant review qualify --repo OWNER/REPO --run --wait --retry --reason "explanation"`
|
|
252
|
+
to authorize a fresh bounded attempt. Only a recorded timeout/provider failure
|
|
253
|
+
with matching ownership, confirmed process cessation and no recorded tool
|
|
254
|
+
attempt or policy denial qualifies for this operation. A legacy dispatch-ID
|
|
255
|
+
conflict rejected before launch can also recover after confirming its archived
|
|
256
|
+
process has stopped. Each retry uses a distinct execution identity and preserves earlier attempts and costs,
|
|
257
|
+
reserves another configured qualification allowance, and requires a new native
|
|
258
|
+
challenge to pass. It never turns failed output into clearance. Unknown or
|
|
259
|
+
active processes, missing completion records and boundary failures remain
|
|
260
|
+
blocked. The default without `--wait` still returns the running record promptly.
|
|
261
|
+
|
|
262
|
+
## Persistence and polling
|
|
263
|
+
|
|
264
|
+
The coordinator saves changed task and reviewer records immediately. Unchanged progress polls do not rewrite the registry or refresh the task’s change timestamp. Native process liveness and output are still checked each tick; unchanged live execution observations are persisted at most once per minute, and settled executions need no heartbeat. Provider health checks, remote-provider cursors, launch/stop intents, result collection and readiness gates retain their existing persistence and polling.
|
|
265
|
+
|
|
266
|
+
Historical review evidence is kept in the private, content-addressed archive described above. Reusing an identical archived record verifies the existing file without writing another copy. No review evidence or logs are deleted by these optimizations.
|
|
@@ -0,0 +1,294 @@
|
|
|
1
|
+
# Git host boundary
|
|
2
|
+
|
|
3
|
+
For a GitHub review mirror that delivers through Bitbucket, see the [explicit branch promotion workflow](bitbucket-promotion.md). It preserves reviewed commits and uses the existing host/review services.
|
|
4
|
+
|
|
5
|
+
`github.com` supports task dispatch. Bitbucket's explicit no-reviewer path
|
|
6
|
+
completed live local Codex tasks through PR publication and receipt acceptance
|
|
7
|
+
on disposable public and private repositories, but its coding session could
|
|
8
|
+
read the selected merge-capable token file. General Bitbucket dispatch remains
|
|
9
|
+
unqualified while credential isolation is repaired. Independent Bitbucket
|
|
10
|
+
review and clean Linux installation also remain unvalidated. Other hosts remain
|
|
11
|
+
unsupported. The synthetic adapter in
|
|
12
|
+
`test/git-host.test.mjs` is an offline contract fixture, not a supported host.
|
|
13
|
+
|
|
14
|
+
`lib/host_definitions.mjs` owns the static host catalogue. `lib/hosts.mjs` binds
|
|
15
|
+
its declarations to Node transport implementations. Portable views and task
|
|
16
|
+
profiles read the same declarations without importing Node or credential code. It is independent of both the harness
|
|
17
|
+
registry and execution transports. Shared code obtains `hostApi(context)` and
|
|
18
|
+
selects a repository for dispatch through `context.hosts.select(...)`. Setup and
|
|
19
|
+
transport tools use `inspect(...)` or `inspectRemote(...)`; these do not qualify
|
|
20
|
+
the host for dispatch. The old `context.gh`
|
|
21
|
+
property is retained as an integration/test compatibility seam. New lifecycle
|
|
22
|
+
code must not use it. GitHub CLI commands, wire normalization, prompt commands,
|
|
23
|
+
learning endpoints and rulesets belong to `lib/gh.mjs`, `lib/hosts/github.mjs`
|
|
24
|
+
and the GitHub diagnostics feature module.
|
|
25
|
+
|
|
26
|
+
## Identity and compatibility
|
|
27
|
+
|
|
28
|
+
`repository.mjs` parses HTTPS, HTTP (historical GitHub input, upgraded before use),
|
|
29
|
+
scp-style SSH and `ssh://` input. It rejects ambiguous authorities, ports,
|
|
30
|
+
queries, fragments, encoded path characters, traversal and unsupported schemes.
|
|
31
|
+
It never embeds rejected input in errors. HTTPS userinfo is discarded; it is
|
|
32
|
+
never a credential source. Canonical records contain `host`, `path`,
|
|
33
|
+
`remoteIdentity` (`host/owner/repository`) and `key`.
|
|
34
|
+
|
|
35
|
+
The historical GitHub key remains `owner/repository`; another qualified host's
|
|
36
|
+
key is `host/owner/repository`. Entry IDs, worktree paths and run folder names
|
|
37
|
+
include that key. Existing GitHub IDs, branch prefixes, cursors, receipt hashes,
|
|
38
|
+
PR metadata and chain ownership tokens are read without rewriting them.
|
|
39
|
+
Review/inline/comment IDs keep their old cursor keys, such as `review:42`.
|
|
40
|
+
A short handle still works when it identifies exactly one entry. Ambiguity
|
|
41
|
+
requires `host/owner/repository#number`. Contradictory saved identities and duplicate
|
|
42
|
+
PR ownership stop with a backup/reconciliation instruction; no automatic
|
|
43
|
+
migration, cursor reset or redispatch repairs them.
|
|
44
|
+
|
|
45
|
+
## Adapter declaration
|
|
46
|
+
|
|
47
|
+
Each registry declaration supplies:
|
|
48
|
+
|
|
49
|
+
| Field | Contract |
|
|
50
|
+
| --- | --- |
|
|
51
|
+
| `host`, `id` | Canonical authority and stable completion-evidence adapter ID |
|
|
52
|
+
| `capabilities` | Required evidence and optional decoration, separately declared |
|
|
53
|
+
| `credential(config, repository)` | Resolve current API/HTTPS authorization for the bound host; never cache at daemon boot |
|
|
54
|
+
| `remote(repository)` | Verified clone URL, protocol, host and repository path |
|
|
55
|
+
| `create(options)` | Repository/API operations with injected transport and credentials |
|
|
56
|
+
| `parsePr(url)`, `prUrl(repository, number)` | Strict PR routing and canonical UI links |
|
|
57
|
+
| `prompts` | Host-specific create, inspect, CI-log and receipt-edit instructions |
|
|
58
|
+
| `dataContract` | `host-records-v1` |
|
|
59
|
+
|
|
60
|
+
Required capabilities are `pullRequests`, `reviews`, `comments`, `checks`,
|
|
61
|
+
`diff`, `mergeProof` and `recovery`. Missing required capabilities fail closed.
|
|
62
|
+
`labels` is optional: an adapter without labels does not block readiness.
|
|
63
|
+
GitHub retains its existing retry semantics for label writes. Learning and
|
|
64
|
+
ruleset operations are GitHub features, not mandatory adapter methods.
|
|
65
|
+
|
|
66
|
+
Repository operations cover branch/default-branch and permission reads, exact
|
|
67
|
+
ref/ancestry proof, file reads, PR view/list/diff, review/comment pages, comments,
|
|
68
|
+
body/title/recovery writes, ready-for-review and idempotent publication.
|
|
69
|
+
`fileAtStrict` distinguishes a missing file from inaccessible or incomplete
|
|
70
|
+
content. The shared chain engine requires the exact merge commit to be an
|
|
71
|
+
ancestor of the intended base; a closed PR never authorizes a successor.
|
|
72
|
+
|
|
73
|
+
First-party review additionally requires `reviewEvidence(repo, pr, head, base,
|
|
74
|
+
maxBytes)`: complete diff and before/after changed-file content, including
|
|
75
|
+
deletions, bound to exact head, base and merge-base IDs. Qualification and
|
|
76
|
+
reconciliation refuse adapters without this operation before launching a
|
|
77
|
+
first-party reviewer or reusing its clearance. External-only and explicit
|
|
78
|
+
no-reviewer policies do not require this method. Evidence reads and policy/dispute label writes
|
|
79
|
+
use the same repository registry and credential binding as other lifecycle
|
|
80
|
+
operations. Review jobs and verdicts remain coordinator-owned.
|
|
81
|
+
|
|
82
|
+
## Domain records and completeness
|
|
83
|
+
|
|
84
|
+
Every normalized record carries `source` (host and adapter), `actor` (login and
|
|
85
|
+
bot flag), `eventId`, `headSha`, `createdAt` and `updatedAt`. Unknown optional
|
|
86
|
+
values are explicit nulls. Review/comment records also carry `at`, `reviewId`
|
|
87
|
+
and `replyTo`. Their original numeric `id` remains stable for saved cursors.
|
|
88
|
+
CI records expose `outcome: passed | failed | pending`, name, URL and optional
|
|
89
|
+
run ID. Wire-specific CI classification exists only in the adapter.
|
|
90
|
+
|
|
91
|
+
PRs retain the established domain field names (`headRefOid`, `headRefName`,
|
|
92
|
+
`baseRefName`, `state`, `mergeCommit`, `mergedAt`, `statusCheckRollup`, body,
|
|
93
|
+
author and URL). These are contract fields, not permission to import a host
|
|
94
|
+
client. The GitHub adapter keeps legacy event aliases for existing consumers;
|
|
95
|
+
the review engine accepts the canonical actor, head and timestamp fields too.
|
|
96
|
+
|
|
97
|
+
A list is either a complete array or `{ items, complete: true }`. Incomplete
|
|
98
|
+
pages, absent CI, rate limits, authentication failures and unreadable diffs
|
|
99
|
+
throw before a readiness decision. GitHub pagination uses bounded subprocess
|
|
100
|
+
output; PR list/check limits are refused at their cap. Shared retries preserve
|
|
101
|
+
cursors, dispatch ownership and the last known decision. Optional decorations
|
|
102
|
+
never supply review, CI or merge evidence. The shared loop has one reviewer
|
|
103
|
+
verdict and one CI outcome predicate for every qualified host.
|
|
104
|
+
|
|
105
|
+
## Transport and provider binding
|
|
106
|
+
|
|
107
|
+
The shared Git layer clones with native `git clone --filter=blob:none`. The
|
|
108
|
+
GitHub policy converts accepted GitHub SSH/HTTP inputs to verified HTTPS; no
|
|
109
|
+
shared Git method constructs a GitHub URL. Existing fetch, base selection,
|
|
110
|
+
operator commit identity, isolated configuration and push behavior remain.
|
|
111
|
+
Origin and push destinations are checked against the repository identity before
|
|
112
|
+
credentialed network operations.
|
|
113
|
+
|
|
114
|
+
The HTTPS helper reads Git's requested protocol, host and repository path before
|
|
115
|
+
returning the bound token. It resets repository credential helpers, refuses
|
|
116
|
+
redirects and receives secrets only through environment variables. Clone URLs,
|
|
117
|
+
argv, committed files and public diagnostics contain no token. A run clears
|
|
118
|
+
inherited API tokens and SSH channels. Bitbucket supports an explicitly selected
|
|
119
|
+
SSH key for coordinator Git operations; an SSH key alone cannot authorize the PR
|
|
120
|
+
API. The coordinator may clone and push over selected SSH or HTTPS. The coding
|
|
121
|
+
session receives neither the repository API token nor the SSH key. Its bounded
|
|
122
|
+
checkout mailbox requests validated push and PR operations from the coordinator.
|
|
123
|
+
Coordinator Git disables checkout hooks before using a privileged credential.
|
|
124
|
+
Setup never grants a sandbox extra key paths.
|
|
125
|
+
GitHub resolution order remains configured token file, daemon environment,
|
|
126
|
+
then `gh auth token`, with explicit-file failure refusing fallback. Resolution
|
|
127
|
+
happens for each operation so reauthentication works without restarting.
|
|
128
|
+
|
|
129
|
+
Providers declare `repositoryAccess`: `local-worktree`, `snapshot`, or
|
|
130
|
+
`bound-host` with allowed authorities. The shared pre-dispatch check enforces it
|
|
131
|
+
before clone or paid preparation. A local-worktree provider needs no adapter
|
|
132
|
+
change to use another qualified host. No host-by-harness switch table exists.
|
|
133
|
+
|
|
134
|
+
## Regression evidence
|
|
135
|
+
|
|
136
|
+
`test/git-host.test.mjs` exercises canonical identity, saved state, collisions,
|
|
137
|
+
normalized feedback, provider access, native clone, token isolation, failure
|
|
138
|
+
preservation and a synthetic host through readiness and chain merge proof.
|
|
139
|
+
`test/git-host-architecture.test.mjs` rejects direct host CLI/API imports or
|
|
140
|
+
prompt commands and a second host-specific review/CI branch in shared modules.
|
|
141
|
+
The existing review, recovery, receipt, chain and execution suites retain
|
|
142
|
+
coverage for bounded retries and idempotent writes. All these tests are offline
|
|
143
|
+
and make no model calls.
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
## Bitbucket Cloud setup
|
|
147
|
+
|
|
148
|
+
Configure credentials explicitly in `git_hosts["bitbucket.org"]`. Existing
|
|
149
|
+
`github_token_file` resolution is unchanged and is never tried for Bitbucket.
|
|
150
|
+
No `gh` installation or GitHub sign-in is required for a Bitbucket-only config.
|
|
151
|
+
Use an Atlassian account API token; repository access tokens are not required.
|
|
152
|
+
Request `read:repository:bitbucket`, `write:repository:bitbucket`,
|
|
153
|
+
`read:pullrequest:bitbucket` and `write:pullrequest:bitbucket`, limited to the
|
|
154
|
+
selected workspace where available. Reads do not prove write scopes: diagnostics
|
|
155
|
+
report them as unknown until the corresponding write, which surfaces permission
|
|
156
|
+
errors and never silently switches credentials.
|
|
157
|
+
|
|
158
|
+
```json
|
|
159
|
+
{
|
|
160
|
+
"git_hosts": {
|
|
161
|
+
"bitbucket.org": {
|
|
162
|
+
"api": {
|
|
163
|
+
"email": "operator@example.com",
|
|
164
|
+
"token_file": "~/.config/repository-access/bitbucket-api-token"
|
|
165
|
+
},
|
|
166
|
+
"git": { "transport": "https" }
|
|
167
|
+
}
|
|
168
|
+
},
|
|
169
|
+
"repos": [{ "repo": "bitbucket.org/workspace/repository", "base": "release/v2" }]
|
|
170
|
+
}
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
Keep the existing harness, operator identity, worktrees and other config settings.
|
|
174
|
+
Token files must be private (`chmod 600`). HTTPS Git uses the selected API token
|
|
175
|
+
unless `git.token_file` explicitly selects a separate private token file. Git's
|
|
176
|
+
helper returns the token only for HTTPS on `bitbucket.org` and the exact repository;
|
|
177
|
+
it uses the account-token Git username `x-bitbucket-api-token-auth`. API requests
|
|
178
|
+
use account email plus token over HTTPS to `api.bitbucket.org`, with redirects
|
|
179
|
+
refused. API and Git authorization may differ, but the base commit observed through
|
|
180
|
+
Git must match the API repository and base.
|
|
181
|
+
|
|
182
|
+
For SSH, use this `git` block instead:
|
|
183
|
+
|
|
184
|
+
```json
|
|
185
|
+
{
|
|
186
|
+
"transport": "ssh",
|
|
187
|
+
"ssh_key": "~/.config/repository-access/bitbucket-key",
|
|
188
|
+
"known_hosts": "~/.config/repository-access/bitbucket-known-hosts"
|
|
189
|
+
}
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
Select an unencrypted dedicated key that the coordinator can read, with mode 600.
|
|
193
|
+
No SSH agent or global SSH configuration is used. The dedicated known-hosts file
|
|
194
|
+
must contain only `ssh.bitbucket.org` entries matching Atlassian's published
|
|
195
|
+
SHA256 fingerprints. Get candidate public keys from `https://bitbucket.org/site/ssh`,
|
|
196
|
+
select the `ssh.bitbucket.org` lines and independently check their fingerprints
|
|
197
|
+
against [Atlassian's SSH host-key documentation](https://support.atlassian.com/bitbucket-cloud/docs/configure-ssh-and-two-step-verification/).
|
|
198
|
+
Do not accept an unverified `ssh-keyscan` result. A host-key rotation stops access
|
|
199
|
+
until the published pins and selected file are reviewed. Strict verification is
|
|
200
|
+
always enabled. Existing `git@bitbucket.org:workspace/repo.git` origins and the
|
|
201
|
+
new `git@ssh.bitbucket.org:workspace/repo.git` origins resolve to one Cloud identity;
|
|
202
|
+
clones use the new endpoint described in [Atlassian's SSH migration notice](https://developer.atlassian.com/cloud/bitbucket/changelog/).
|
|
203
|
+
Self-hosted servers, custom SSH aliases and alternate ports are unsupported.
|
|
204
|
+
|
|
205
|
+
Run `init` from the checkout to bind the API repository UUID and workspace UUID
|
|
206
|
+
under the host's `repositories` map, or run `doctor` for read-only diagnostics.
|
|
207
|
+
Setup checks repository access, the selected base, effective account push role,
|
|
208
|
+
PR reads, comments when a PR exists, branch restrictions where visible, and native
|
|
209
|
+
Git access to the same base. The account role comes from the
|
|
210
|
+
[authenticated user's repository permissions](https://developer.atlassian.com/cloud/bitbucket/rest/api-group-repositories/#api-user-workspaces-workspace-permissions-repositories-get),
|
|
211
|
+
filtered by repository UUID, using repository read scope without workspace-admin access.
|
|
212
|
+
An archive flag, if supplied, is enforced; the Cloud
|
|
213
|
+
repository schema does not currently expose that flag consistently, so absence
|
|
214
|
+
is reported as unknown. A missing API credential reports missing PR/comment
|
|
215
|
+
capability even when an SSH key is configured. A successful transport check is
|
|
216
|
+
followed by an explicit failed dispatch check. No paid model probe is needed for
|
|
217
|
+
this milestone, and `init` does not recommend starting a task on an unqualified host.
|
|
218
|
+
|
|
219
|
+
API credentials are reread for every operation. A changed email, account UUID on
|
|
220
|
+
successive permission reads, repository UUID,
|
|
221
|
+
workspace UUID, canonical slug or API clone target stops access. Restore the
|
|
222
|
+
previous binding, or inspect the new identity and explicitly edit the binding;
|
|
223
|
+
setup never silently migrates a renamed or transferred repository.
|
|
224
|
+
|
|
225
|
+
## Bitbucket evidence and publication bounds
|
|
226
|
+
|
|
227
|
+
`lib/hosts/bitbucket.mjs` owns API shape and pagination differences. PR snapshots
|
|
228
|
+
include source/destination UUIDs, branches and commits, draft state, host state
|
|
229
|
+
(`OPEN`, `MERGED`, `DECLINED` or `SUPERSEDED`), title/description, diff, comments,
|
|
230
|
+
reviewer participants, tasks and statuses tied to the current head. Declined and
|
|
231
|
+
superseded PRs normalize to `CLOSED`, preserving `hostState`. UUID-based actor
|
|
232
|
+
identity avoids nickname ambiguity. These observations do not qualify reviewer
|
|
233
|
+
trust, CI policy, recovery or merge proof for dispatch.
|
|
234
|
+
Build statuses use the [documented commit link](https://developer.atlassian.com/cloud/bitbucket/rest/api-group-commit-statuses/#api-repositories-workspace-repo-slug-commit-commit-statuses-get)
|
|
235
|
+
to confirm the queried repository and head; missing or mismatched links stop the snapshot.
|
|
236
|
+
PR list responses omit reviewer and participant collections. Bounded list results
|
|
237
|
+
are expanded through repository-scoped PR detail reads before normalization;
|
|
238
|
+
preflight also reads the selected PR's details before checking comment access.
|
|
239
|
+
Missing or inaccessible detail records stop the operation, and a failed read after
|
|
240
|
+
publication preserves the unresolved write until reconciliation succeeds.
|
|
241
|
+
|
|
242
|
+
Reads are bounded to 100 pages and 10,000 items per collection, 4 MiB per JSON
|
|
243
|
+
response, a diff smaller than 16 MiB, and 20 seconds per request. Missing fields,
|
|
244
|
+
cycles, changed filters, size inconsistencies, rate limits, foreign pagination,
|
|
245
|
+
redirects and changed PR identity/head during a snapshot produce explicit errors.
|
|
246
|
+
The documented diff redirect is allowed only into the same repository's diff
|
|
247
|
+
endpoint. Failures never become empty reviews or successful checks.
|
|
248
|
+
|
|
249
|
+
Publication uses the existing public-text validator, exact repository UUIDs and
|
|
250
|
+
source/base names. It checks PRs in all states before every publication, updates one matching open PR,
|
|
251
|
+
and refuses forks, closed predecessors, conflicting bases or duplicate ownership.
|
|
252
|
+
Writes address immutable workspace/repository UUIDs so a concurrent slug change
|
|
253
|
+
cannot redirect a write into a replacement repository. Every write is
|
|
254
|
+
followed by reconciliation, including timeouts after acceptance. An unresolved
|
|
255
|
+
create remains blocked in that adapter instance until a matching PR is observed;
|
|
256
|
+
a restart still reads before any write. Concurrent publication in one instance
|
|
257
|
+
is refused. There is no fork creation, merge, force push or repository-settings API.
|
|
258
|
+
Comments are never automatically retried after an uncertain write.
|
|
259
|
+
|
|
260
|
+
Offline coverage: `test/bitbucket.test.mjs`, `test/bitbucket-fixture.mjs` and
|
|
261
|
+
`test/host-transport-contract.test.mjs`. The shared contract assertions run against
|
|
262
|
+
both production adapters with injected wire responses. No fixture test calls a
|
|
263
|
+
model or writes to a live repository. Live review-loop qualification remains a
|
|
264
|
+
separate milestone.
|
|
265
|
+
|
|
266
|
+
API references: [repositories](https://developer.atlassian.com/cloud/bitbucket/rest/api-group-repositories/),
|
|
267
|
+
[pull requests](https://developer.atlassian.com/cloud/bitbucket/rest/api-group-pullrequests/),
|
|
268
|
+
and [account-token authentication](https://support.atlassian.com/bitbucket-cloud/docs/using-api-tokens/).
|
|
269
|
+
|
|
270
|
+
## Review-loop implementation and ship gate
|
|
271
|
+
|
|
272
|
+
The [Bitbucket review guide](bitbucket-review.md) supersedes transport-only setup
|
|
273
|
+
examples for reviewer/trust/check policy. `init --host-config <json> --base <branch>`
|
|
274
|
+
can bootstrap an empty config, with an explicit reviewer (or `null`) and stable
|
|
275
|
+
trusted UUIDs. The adapter now implements review normalization, required task
|
|
276
|
+
blockers, recovery operations and merge ancestry. The explicit no-reviewer
|
|
277
|
+
dispatch path has [disposable live observations](audit/bitbucket-review-qualification.md),
|
|
278
|
+
but credential isolation failed; independent review and clean Linux installation
|
|
279
|
+
remain unvalidated. Do not enable general dispatch from these observations.
|
|
280
|
+
|
|
281
|
+
`prView` may include `feedback: { complete: true, headSha, reviews, inline, comments }`.
|
|
282
|
+
The shared loop consumes this one coherent snapshot; adapters without it retain
|
|
283
|
+
the previous collection methods. Strict records declare `headBinding: "exact"`
|
|
284
|
+
and an explicit `verdict`; PR-wide required tasks declare `required: true` and
|
|
285
|
+
`headBinding: "pull-request"`. Stable `sequence` values disambiguate verdicts that
|
|
286
|
+
share a timestamp. `strictIdentity` requests recorded branch/base/head and terminal
|
|
287
|
+
merge checks. These are domain contract fields, not host-name branches in the
|
|
288
|
+
scheduler. GitHub's historical event keys and review interpretation are retained.
|
|
289
|
+
|
|
290
|
+
A future GitLab adapter must implement the same complete records, explicit policy,
|
|
291
|
+
strict URL/credential binding, publication, file reads, and merge proof. Add its
|
|
292
|
+
static definition/implementation and shared-contract tests, then qualify it live
|
|
293
|
+
with a compatible provider. Until then GitLab and unregistered hosts fail before
|
|
294
|
+
dispatch. Host, harness and inference provider remain separate configuration axes.
|
package/docs/guardrails.md
CHANGED
|
@@ -309,3 +309,59 @@ that a tool call was denied. The historical findings are linked below.
|
|
|
309
309
|
## Follow-ups filed against APort
|
|
310
310
|
|
|
311
311
|
The historical [decision record](https://github.com/uchibeke/gallivant/blob/main/docs/audit/DECISIONS.md) lists: multi-file `apply_patch` in the Codex hook, `git push` refspec parsing, control-plane paths blocked by default, a non-interactive local passport install, and a Repository Guard slice that blocks pushes rather than reporting merges.
|
|
312
|
+
|
|
313
|
+
## Reviewer authority
|
|
314
|
+
|
|
315
|
+
The opt-in first-party reviewer uses the restricted native preparation boundary in a fresh session with supplied evidence only. Image jobs additionally require their own capability qualification and a verified coordinator-created copy. Its profile denies tools, escalation, delegation and tool network access; setup/start verify effective native policy and require a live qualification record. A private HOME or a prompt alone is not sufficient. The model cannot write task policy, state, files, Git refs, PRs or approvals. The coordinator validates exact-input structured output; public agent text is never an independent host actor. Unknown or partial output fails closed. See [review isolation, evidence and monetary limitations](first-party-review.md) and [unmet live qualification](audit/first-party-review.md). Review grants no merge or deployment authority.
|
|
316
|
+
|
|
317
|
+
Repository identity, credential transport and PR evidence are defined by the
|
|
318
|
+
[Git host contract](git-hosts.md). GitHub and Bitbucket Cloud can dispatch;
|
|
319
|
+
Bitbucket's live no-reviewer path has been qualified on a disposable public
|
|
320
|
+
repository. Independent Bitbucket review remains unvalidated. Existing IDs and
|
|
321
|
+
chain ownership are retained without a state migration.
|
|
322
|
+
|
|
323
|
+
## Independent Bitbucket reviewer credentials
|
|
324
|
+
|
|
325
|
+
Coding sessions receive only their repository-bound coding credential. Reviewer
|
|
326
|
+
credentials belong on an isolated reviewer machine, OS account, or container.
|
|
327
|
+
The independent publisher accepts only the configured stable actor and prepared
|
|
328
|
+
exact head; a successful Pipeline without a posted verdict is silence.
|
|
329
|
+
See [reviewer isolation and publication](bitbucket-review.md#independent-local-codex-reviewer).
|
|
330
|
+
Setup never installs a pipeline, creates a token, or authorizes inference.
|
|
331
|
+
|
|
332
|
+
## Keep working artifacts out of pull requests
|
|
333
|
+
|
|
334
|
+
Every local harness receives the same publication policy and generated `commit-msg` hook. The hook examines the
|
|
335
|
+
NUL-delimited staged file list and rejects task scratch directories, conventional work logs, audit/evidence notes,
|
|
336
|
+
and carried task inputs. Removing those files is allowed; preserve any carried files locally because the brief and
|
|
337
|
+
snapshot checks still need them. The hook is refreshed at start and on every resumed/fix run. Hosted file results
|
|
338
|
+
are checked before writing them, and the coordinator checks the complete remote PR diff before expensive first-party review and before readiness, even when the optional output-content scan is disabled. An unreadable or malformed diff is retried and
|
|
339
|
+
never treated as clean. A prohibited file schedules a normal corrective round with its exact path.
|
|
340
|
+
|
|
341
|
+
Requested audit reports, screenshots and other evidence are still valid deliverables. The operator names exact
|
|
342
|
+
paths in the approved brief's [`publish_files`](prd.md) list. The coordinator uses its saved snapshot, never a
|
|
343
|
+
session-edited whitelist. Before upgrading or restarting the daemon for existing runs, review retained deliverables in reserved directories.
|
|
344
|
+
The operator must name their exact paths in `publish_files` and accept the updated saved brief through the usual
|
|
345
|
+
`resume --resnapshot` flow at a safe resume boundary. Do not edit a running session's snapshot or grandfather all
|
|
346
|
+
existing files. Without those prior approved exceptions, the new guard will request cleanup instead of readiness.
|
|
347
|
+
|
|
348
|
+
Use a temporary directory outside the repository for scratch files. Runner command/session logs remain in task
|
|
349
|
+
storage; concise verification results belong in the PR receipt. Keep durable release/rollback instructions in the
|
|
350
|
+
project docs without appending a running execution diary. This policy does not inspect arbitrary prose or provide
|
|
351
|
+
an isolation boundary: an agent with Git credentials can bypass local hooks and push, but reserved work-artifact
|
|
352
|
+
paths will not pass the coordinator's readiness check. A clean check is cached only for its exact head, base and approved policy, so review polls do not repeatedly fetch
|
|
353
|
+
the diff. Normal rechecks also inspect legacy ready entries; no PR is automatically rewritten.
|
|
354
|
+
|
|
355
|
+
First-party reviewers receive carried text inputs from the coordinator's immutable `readSource` snapshots, with
|
|
356
|
+
content digests in their private evidence. They do not fetch those files from remote HEAD or the mutable session
|
|
357
|
+
checkout. These inputs follow the existing capture, per-job input and review-job caps; missing or oversized input
|
|
358
|
+
is reported explicitly, never silently omitted. Keep source context concise: it accompanies each source/visual
|
|
359
|
+
review piece and the final synthesis. The complete brief plus private source context and review metadata must fit the
|
|
360
|
+
configured per-job input cap (at most 100,000 serialized UTF-8 bytes). Larger private sources must be narrowed or
|
|
361
|
+
split into separately approved tasks; do not commit them as a workaround. Required image evidence remains in Git at its approved output paths.
|
|
362
|
+
|
|
363
|
+
`openai-agents` transports all approved inputs privately with their original hashes, but only explicit output overlays
|
|
364
|
+
are forced into a result. Verification permits private inputs to remain untracked or unstaged only while their bytes
|
|
365
|
+
and modes exactly match the coordinator snapshots. Editing, staging, deleting or substituting them fails publication.
|
|
366
|
+
Codex Cloud's Git-only input transport cannot provide this privacy for new/changed inputs and refuses before commit
|
|
367
|
+
or push; its dispatch is separately unavailable until repository binding is qualified. See [codex-cloud.md](codex-cloud.md).
|