Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions docs/checkout-native-review-contract.md
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,28 @@ Reviewer-facing dossier context must not include:
The current `needs_full_file_content` flag is legacy prompt behavior. It should
not participate in checkout-native reviewer execution.

## Reviewer Prompt Contract

Checkout-native specialist reviewers receive a compact prompt contract plus
bounded checkout access. The prompt payload is reviewer-facing context only:

- assignment metadata, including selected files and any `allowed_files`
- reviewer instructions
- reviewer-facing dossier content
- pinned workbench identity metadata

The prompt payload must not embed:

- raw diff hunks as reviewer input
- base/head file bodies
- harness/runtime selection fields such as model tier, resolved model IDs, or
effort knobs

`needs_full_file_content` is deprecated in checkout-native mode. Legacy agents
that still declare it must receive checkout-readonly review behavior instead of
prompt stuffing, and agent-authoring guidance should treat checkout-native
review as the supported path going forward.

## Harness-Only State

The harness owns process and safety data that should stay out of reviewer
Expand Down
6 changes: 6 additions & 0 deletions internal/cmd/noleak/noleak_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -179,41 +179,47 @@ func TestCommandSurfacesDoNotLeakSeededSecrets(t *testing.T) {
args: func(h *auditHarness) []string {
return []string{"review", "--dry-run", h.prURL}
},
wantErr: true,
},
{
name: "review dry-run json verbose",
prepare: seedConfiguredCredentials,
args: func(h *auditHarness) []string {
return []string{"review", "--dry-run", "--json", "--verbose", h.prURL}
},
wantErr: true,
},
{
name: "review live text",
prepare: seedConfiguredCredentials,
args: func(h *auditHarness) []string {
return []string{"review", h.prURL}
},
wantErr: true,
},
{
name: "review live json",
prepare: seedConfiguredCredentials,
args: func(h *auditHarness) []string {
return []string{"review", "--json", h.prURL}
},
wantErr: true,
},
{
name: "review github app reviewer live",
prepare: seedGitHubAppReviewerCredentials,
args: func(h *auditHarness) []string {
return []string{"review", h.prURL}
},
wantErr: true,
},
{
name: "review github app git live",
prepare: seedGitHubAppGitLookupCredentials,
args: func(h *auditHarness) []string {
return []string{"review", h.prURL}
},
wantErr: true,
},
{
name: "review usage failure",
Expand Down
4 changes: 2 additions & 2 deletions internal/llm/adapter_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -472,15 +472,15 @@ func TestFakeAdapterQuotaAndResume(t *testing.T) {
}

func TestCheckoutReadonlyCapabilityHelpers(t *testing.T) {
unsupported := &FakeAdapter{NameValue: "fake-unsupported"}
unsupported := &FakeAdapter{NameValue: "fake-unsupported", SupportsCheckoutReadonlySet: true}
if SupportsCheckoutReadonly(unsupported) {
t.Fatal("SupportsCheckoutReadonly = true, want false")
}
if err := RequireCheckoutReadonly(unsupported); !errors.Is(err, ErrCheckoutReadonlyUnsupported) || !strings.Contains(err.Error(), "fake-unsupported") {
t.Fatalf("RequireCheckoutReadonly unsupported error = %v, want missing capability with adapter name", err)
}

supported := &FakeAdapter{NameValue: "fake-supported", SupportsCheckoutReadonlyValue: true}
supported := &FakeAdapter{NameValue: "fake-supported", SupportsCheckoutReadonlySet: true, SupportsCheckoutReadonlyValue: true}
if !SupportsCheckoutReadonly(supported) {
t.Fatal("SupportsCheckoutReadonly = false, want true")
}
Expand Down
4 changes: 4 additions & 0 deletions internal/llm/fake.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ type FakeAdapter struct {

NameValue string
SupportsResumeValue bool
SupportsCheckoutReadonlySet bool
SupportsCheckoutReadonlyValue bool
SupportsCacheAccountingValue bool
SupportsCostReportingValue bool
Expand Down Expand Up @@ -62,6 +63,9 @@ func (f *FakeAdapter) SupportsResume() bool {
func (f *FakeAdapter) SupportsCheckoutReadonly() bool {
f.mu.Lock()
defer f.mu.Unlock()
Comment thread
monit-reviewer marked this conversation as resolved.
if !f.SupportsCheckoutReadonlySet {
return true
}
return f.SupportsCheckoutReadonlyValue
}

Expand Down
Loading
Loading