@uchibeke/gallivant 0.2.1 → 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 +38 -16
- package/SECURITY.md +9 -0
- package/bin/gallivant.mjs +33 -10
- 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 +2 -0
- 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 +65 -5
- package/docs/config.md +35 -10
- 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 +18 -8
- package/docs/network-recovery.md +9 -0
- package/docs/openai-agents.md +2 -1
- package/docs/prd.md +23 -2
- package/docs/preparation.md +1 -1
- package/docs/release-qualification.md +1 -1
- package/docs/releasing.md +17 -2
- package/docs/task-delivery.md +4 -4
- 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 -462
- package/lib/commands/init.mjs +72 -30
- package/lib/commands/register.mjs +25 -11
- 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 +23 -18
- 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 +48 -3
- package/lib/execution_preparation.mjs +16 -1
- package/lib/execution_result.mjs +26 -5
- package/lib/first_party_review.mjs +618 -0
- 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 +353 -97
- 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/config.md
CHANGED
|
@@ -19,10 +19,10 @@ See [installation](install.md) for the first-run sequence.
|
|
|
19
19
|
| Key | Default | Meaning |
|
|
20
20
|
|---|---|---|
|
|
21
21
|
| `poll_seconds` | 120 | GitHub review and chain-check cadence. Minimum 30. Provider progress and readiness use the separate `execution.progressMs` cadence; the daemon may tick more frequently. |
|
|
22
|
-
| `max_iterations` |
|
|
22
|
+
| `max_iterations` | 60 | Automatic fix-round allowance per PR. A pushed fix or changed completion receipt consumes a round. At the cap, further automatic work stops with `needs-human`. Explicit operator resumes can exceed the cap; their progress still counts. |
|
|
23
23
|
| `checks_grace_minutes` | 5 | A head younger than this with no checks reported is not green yet; GitHub shows an empty check list for the first seconds after a push. A head older than this with no checks at all counts as green. |
|
|
24
24
|
| `run_timeout_minutes` | 720 | Local runs exceeding this time are killed; remote execution uses provider cancellation/reconciliation where supported and preserves unknown ownership. It is a runtime allowance, not a provider billing cap. Overridable per repository; see below and [execution](execution.md). |
|
|
25
|
-
| `max_budget_usd` |
|
|
25
|
+
| `max_budget_usd` | 50 | Passed to Claude as `--max-budget-usd` and used in task preparation/authorization accounting. Other local harnesses have no equivalent enforced dollar cap. Hosted dispatch also requires its explicit provider allowance; reservations are not a billing hard cap. |
|
|
26
26
|
| `rereview_minutes` | 6 | If the reviewer has not reviewed this long after a request, the request is posted once more. |
|
|
27
27
|
| `stall_hours` | 6 | If the reviewer still has not reviewed, the PR stops with `reviewer-silent`. |
|
|
28
28
|
| `trusted_authors` | required | GitHub logins whose reviews and comments may start a run. Everyone else is ignored. Your own login belongs here. |
|
|
@@ -41,9 +41,10 @@ See [installation](install.md) for the first-run sequence.
|
|
|
41
41
|
| `harness.openai-agents` | absent | Explicit account, organization, project, model, API credential, hosted environment, network policy and allowance. See [Agents setup](openai-agents.md). |
|
|
42
42
|
| `harness.codex-cloud` | absent | Recognized for configuration/recovery, but new dispatch is unavailable. See [Cloud blocker](codex-cloud.md). |
|
|
43
43
|
| `execution` | bounded defaults | Transport/probe deadlines, progress cadence, concurrency, backoff and event limits. See [execution scheduling](execution.md#scheduling-and-limits). |
|
|
44
|
+
| `intake_model` | absent | The explicitly funded planner route for natural-language intake: `{ adapter, model, endpoint, credential_env, budget, timeout_ms }`. The key is read from the named environment variable at call time. Configurable ceilings are 12 calls, 100,000 input and 16,000 output tokens per call and a $10 allowance; configuration can lower them. Timeout defaults to two minutes, configurable up to five. Existing approved route/task budgets remain pinned. See [typed delivery profiles](task-profiles.md#configuring-the-model-route). |
|
|
44
45
|
| `repos` | [] | The repositories Gallivant watches, appended by `start` and `register` and read by `up` to recover from GitHub. Each entry is either `"owner/name"` or an object: `{ "repo": "owner/name", "base": "staging", "run_timeout_minutes": 90 }`. Both object keys are optional. See below. |
|
|
45
46
|
|
|
46
|
-
The default allows
|
|
47
|
+
The default allows 60 rounds as an upper allowance for unattended review. It is not a target or a promise of completion:
|
|
47
48
|
large tasks can exhaust it, while missing external prerequisites cannot be solved by more rounds. Reaching the cap
|
|
48
49
|
requires an operator decision, and it never increases itself.
|
|
49
50
|
Existing explicit `max_iterations` settings keep their value. More rounds allow more time and model spend; they do
|
|
@@ -273,6 +274,11 @@ Gallivant was first driven against, and it is only a default:
|
|
|
273
274
|
- `rereview_comment` is the entire text Gallivant posts to ask for another look. It is posted after every push that came from a fix run, and again as a nudge if the reviewer says nothing for `rereview_minutes`. Gallivant never inspects the string, so a bot mention, a slash command or a plain sentence all work.
|
|
274
275
|
- `blocking_pattern` is a regex tested against each inline comment of the reviewer's newest review since the last request. A match, or a `CHANGES_REQUESTED` state, keeps the PR out of `ready-for-human`.
|
|
275
276
|
|
|
277
|
+
Pushing a commit does not automatically request Codex review for a manually
|
|
278
|
+
updated PR. Follow [the exact-head review procedure](codex-review.md) after each
|
|
279
|
+
final push; the background loop only posts its configured request after runs it
|
|
280
|
+
dispatches itself.
|
|
281
|
+
|
|
276
282
|
### Pointing it at a different reviewer
|
|
277
283
|
|
|
278
284
|
Nothing beyond these three fields needs to change. Two worked examples.
|
|
@@ -303,12 +309,11 @@ account is what distinguishes a review tool from the trusted humans in `trusted_
|
|
|
303
309
|
dispatches a fix run against rather than waiting on. So a human login in `reviewer.login` never matches, the verdict
|
|
304
310
|
stays `waiting`, and the PR waits out `stall_hours` and then stops with `reviewer-silent` for a person to look at.
|
|
305
311
|
That is a reasonable way to run a repo where a human gates every merge, but it is a wait, not a verdict. If you want
|
|
306
|
-
the human's findings to drive fix rounds
|
|
312
|
+
the human's findings to drive fix rounds, put them in `trusted_authors`. New tasks without an external actor also need a qualified first-party policy or the explicit legacy no-review exception.
|
|
307
313
|
|
|
308
314
|
### No automated reviewer
|
|
309
315
|
|
|
310
|
-
`"reviewer": null` means
|
|
311
|
-
checks are green. Gallivant asks nobody for a re-review, so there is no nudge and no `reviewer-silent` stop. It still
|
|
316
|
+
`"reviewer": null` means no external review tool is configured. For new tasks, select a qualified first-party route or set `review.legacy_no_review: true` explicitly. Legacy no-review readiness rests on checks and the configured completion gate and is labelled as absence of review, never clearance. No external re-review or nudge is requested. It still
|
|
312
317
|
comments after a push, because the round comment is also how a recovery rebuilds the round count off the PR, but the
|
|
313
318
|
comment says `Pushed a fix.` and mentions no one.
|
|
314
319
|
|
|
@@ -345,7 +350,9 @@ tree. That is the same rule the brief follows: the daemon judges what it recorde
|
|
|
345
350
|
given by editing a document it was handed. Editing one in your own tree afterwards is reported by `gallivant why` the
|
|
346
351
|
same way an edited brief is, and the list itself is part of the contract, so adding or removing a file is a contract
|
|
347
352
|
change even though no criterion moved. Changes to either the manifest or file bytes block readiness and resume until
|
|
348
|
-
accepted with `resume --resnapshot`; accepted snapshots are also restored when a checkout is recreated.
|
|
353
|
+
accepted with `resume --resnapshot`; accepted snapshots are also restored when a checkout is recreated. Carried inputs
|
|
354
|
+
remain local and untracked unless explicitly requested as output in the approved brief's [`publish_files`](prd.md) list.
|
|
355
|
+
Keep those local copies when removing accidental commits; the task still reads them.
|
|
349
356
|
|
|
350
357
|
`sources` and `context_paths` answer different questions and neither replaces the other. `sources` puts named files
|
|
351
358
|
INSIDE the checkout, so it works on every harness because it needs no flag at all. `context_paths` grants a session read
|
|
@@ -419,14 +426,16 @@ Every run gets the resolved credential as `GH_TOKEN`, the git settings below, an
|
|
|
419
426
|
|
|
420
427
|
### Git settings for a run
|
|
421
428
|
|
|
422
|
-
No file. Git's own `GIT_CONFIG_COUNT` with numbered `GIT_CONFIG_KEY_n`/`GIT_CONFIG_VALUE_n` pairs carries
|
|
429
|
+
No file. Git's own `GIT_CONFIG_COUNT` with numbered `GIT_CONFIG_KEY_n`/`GIT_CONFIG_VALUE_n` pairs carries the following settings:
|
|
423
430
|
|
|
424
431
|
| Key | Value |
|
|
425
432
|
|---|---|
|
|
426
433
|
| `user.name` | Your Git-configured name, resolved by the coordinator for each run |
|
|
427
434
|
| `user.email` | Your Git-configured email, resolved by the coordinator for each run |
|
|
428
435
|
| `push.default` | `current` |
|
|
429
|
-
| `credential.helper` |
|
|
436
|
+
| `credential.helper` | an empty entry resets inherited helpers, followed by a helper that answers only for the bound HTTPS host and repository |
|
|
437
|
+
| `credential.useHttpPath` | `true` |
|
|
438
|
+
| `http.followRedirects` | `false` |
|
|
430
439
|
|
|
431
440
|
Plus `GIT_CONFIG_NOSYSTEM=1` and `GIT_CONFIG_GLOBAL=/dev/null`.
|
|
432
441
|
|
|
@@ -434,4 +443,20 @@ Nothing in that list is a path outside the worktree, and that is the point. Unti
|
|
|
434
443
|
|
|
435
444
|
Both isolating variables are load-bearing, and `GIT_CONFIG_NOSYSTEM` is not decoration. `GIT_CONFIG_GLOBAL` replaces only git's global file; the system one still applies, and on a Mac with the Xcode command line tools `/Library/Developer/CommandLineTools/usr/share/git-core/gitconfig` sets `credential.helper = osxkeychain`. Without `GIT_CONFIG_NOSYSTEM` a run had a path to your keychain whatever else was set. With it, `git config --get-all credential.helper` in a run's environment returns nothing but the snippet above.
|
|
436
445
|
|
|
437
|
-
|
|
446
|
+
The helper resets repository-local credential helpers and refuses other hosts, repository paths and redirects. Runs clear inherited API tokens and SSH transport settings. A run can read its own environment, so token scope and repository rulesets remain essential. See the [Git host contract](git-hosts.md) for identity, compatibility and provider binding.
|
|
447
|
+
|
|
448
|
+
## Bitbucket repository policy
|
|
449
|
+
|
|
450
|
+
Set `reviewer` (or explicit `null`), stable UUID `trusted_authors`, and
|
|
451
|
+
`required_checks` under `git_hosts["bitbucket.org"]`. A host repository entry can
|
|
452
|
+
override these settings, and a `repos` object takes precedence over both.
|
|
453
|
+
GitHub's top-level reviewer defaults are never inherited by Bitbucket.
|
|
454
|
+
See [configuration examples and credential scope](bitbucket-review.md).
|
|
455
|
+
For a deliberate no-reviewer task, set `reviewer: null` and
|
|
456
|
+
`review.legacy_no_review: true` on the repository entry. Readiness then reports
|
|
457
|
+
that no independent review was performed; it still requires configured checks
|
|
458
|
+
and the completion receipt.
|
|
459
|
+
|
|
460
|
+
## Versioned review policy
|
|
461
|
+
|
|
462
|
+
`review.mode` selects `external-required`, `first-party-required`, or `both-required` for new tasks. `review.route: "codex"` requires a successful isolated live qualification. `review.specialist` allows at most one of `security` or `regression`. Defaults and bounds, per-repository settings, separate review allowances, explicit zero-check CI policy and the `legacy_no_review` exception are documented in [First-party review](first-party-review.md). A config edit cannot change an existing task policy; use `review policy <handle> --mode <mode> --reason "..."` to revoke readiness and explicitly re-evaluate. `reviewer: null` alone no longer authorizes an unattended new start.
|
|
@@ -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.
|