Repo Allowlist and Scoping
Repository enablement, branch and policy gates, manual-command authority, and token-scoping limits.
Admission differs between the Node service and the native Cloudflare runtime. Do not treat GILF_REPOS as a security allowlist or assume every declared repository setting is enforced by both paths.
R/ means son-of-anton-review (feat/cloudflare-native). P/ means son-of-anton-operator-parity (feat/greptile-operator-parity), a separate unmerged branch containing the operator Worker API.
Node: GILF_REPOS seeds configuration
export GILF_REPOS=owner/repo-a,owner/repo-bR/server.mjs:64-74 reads this comma-separated list at startup and calls setRepoConfig for each name with environment-derived validation settings. It also supplies the list to the Node dashboard. It does not reject signed deliveries for all other repositories.
ReviewService merges an absent repo record over defaults (R/src/review-service.js:1295-1310). Those defaults enable review, automatic review and the exact base branches main and dev. Limit GitHub App installation access deliberately; do not rely on absence from this seed list.
For automatic Node PR events, shouldAutoReview checks enabled, review.auto, the PR base branch and review.onDraft. A failed check is returned as auto_review_disabled (R/src/config.js:86-97; R/src/review-service.js:716-717).
Native Cloudflare: stored enablement plus pinned policy
Native ingress is a superset event filter, not the final authorization decision. The container hydrates a run from D1 and pins review policy. It does not read GILF_REPOS.
| Repository state at first policy snapshot | Native enabled state |
|---|---|
| Stored repo config | Merged config.enabled |
| No config, previously reviewed | Enabled |
| No config, no previous review | autoEnableNewRepos, default false |
The reviewed-repo exception refers to analysis/publication statuses, not merely a PR head or a queued/skipped run. evaluateRuntimeAdmission refuses repositoryEnabled === false with repository_disabled before evaluating manual or automatic policy.
Native branch-filter limitation: the native entrypoint seeds and runs the review directly. Its hydration path reads repo enablement and manual authorization, but does not call Node's shouldAutoReview. Do not assume branches.include, review.auto or review.onDraft provide the same gate on this path. Use the pinned policy's branch filters, autoReviewNewCommits and reviewDrafts for native admission, and verify the resulting decision.
Sources: R/cloudflare-native/src/ingress.js:54-77; R/cloudflare-native/src/d1-store-adapter.js:153-172; R/cloudflare-native/container/entrypoint.mjs:82-95,135-148; R/src/scm-store.js:24-28; R/src/review-policy-runtime.js:26-43.
Stored repository configuration
DEFAULT_REPO_CONFIG and mergeRepoConfig define this shape. The following are code defaults, not evidence of a particular workspace's saved policy:
{
enabled: true,
mode: 'comment',
branches: { include: ['main', 'dev'] },
review: {
auto: true,
onDraft: false,
inlineComments: 'high_confidence_only',
lenses: ['security', 'correctness', 'tests', 'contracts'],
},
validation: { provider: 'crabbox', codeChangesOnly: true },
manual: {
enabled: true,
commands: ['@anton review', '@anton rerun', '@anton status', '@anton help',
'@gilf review', '@gilf rerun', '@gilf status', '@gilf help'],
allowAssociations: ['OWNER', 'MEMBER', 'COLLABORATOR'],
allowUsers: [],
},
competitor: { autoAudit: true, users: ['greptile-apps[bot]', 'greptile-apps'] },
publishing: { checkRun: true, review: true, stickyStatusComment: true },
}Source: R/src/config.js:1-97. Nested Crabbox/E2B configuration is documented in Validation executors.
Important limits:
- Node
branches.includeuses exact equality, not globs. Its predicate does not readbranches.exclude. inlineCommentsis declared configuration, not implemented per-line publication. The publisher sends review bodies, checks and issue comments, without inline positions (R/src/github-publisher.js:22-79).- The parser recognizes its fixed four verbs; the declared
manual.commandslist is not a configurable parser grammar (R/src/commands.js:1-26). - A stored key is not proof of a runtime consumer. In particular, the parity repo API accepts model fields and branch exclusions that must not be advertised as working native model/branch overrides.
Workspace review policy
For automatic runs, policy checks paused author, commit-trigger setting, draft setting, file count and filters. Missing metadata can defer a decision until hydration; it does not mean the PR matched.
| Setting | Default | Denial reason |
|---|---|---|
pausedAuthors | [] | author_paused |
autoReviewNewCommits | true | new_commits_disabled on synchronize |
reviewDrafts | false | draft_review_disabled |
fileChangeLimit | 500 | file_change_limit |
filters | [] | filters_not_matched |
An authorized manual review bypasses the automatic checks inside evaluateReviewPolicy after paused-author handling. It does not bypass native repository disablement, authorization or the monthly model-budget gate. Unknown author metadata can still defer a manual request when authors are paused.
Sources: R/src/operator-review-policy.js:154-180; R/src/review-policy-runtime.js:39-53; R/src/codex-review-runner.js:2376-2392.
Filter grammar
A PR matches if any rule matches; each rule requires all its conditions. Empty rule lists match. Maximum 50 rules, 1 to 20 conditions per rule, up to 50 values per condition.
| Field | Operators | Value kind |
|---|---|---|
label, author, repository | is, is_not | Strings; repository uses owner/repo |
targetBranch, sourceBranch, path | is, is_not | Safe globs; ** must be a whole segment |
title, keyword | contains, not_contains | Case-insensitive substring |
draft | is, is_not | Empty values list |
filesChanged | at_most, more_than | One integer string from 0 to 100000 |
Example native target-branch policy:
{
"filters": [{
"conditions": [{ "field": "targetBranch", "operator": "is", "values": ["main", "release/*"] }]
}]
}This is a policy fragment, not the complete PATCH body. See Dashboard settings for revision and authentication requirements. Source: R/src/operator-review-policy.js:46-108,110-176.
Manual-command authority
isAuthorizedCommenter first permits a case-insensitive manual.allowUsers login match, otherwise checks the uppercased GitHub author association. Defaults permit OWNER, MEMBER and COLLABORATOR. manual.enabled: false disables manual commands.
The Node service also requires a known PR head, ignores non-command comments and deduplicates command ids. Native authorization uses the HMAC-authenticated comment in the delivered payload, not a caller-supplied actor string. Repeating an existing webhook is not the same as posting a new @anton rerun comment.
Sources: R/src/commands.js:9-39; R/src/review-service.js:736-834; R/cloudflare-native/src/d1-store-adapter.js:162-172; R/cloudflare-native/src/ingress.js:80-114.
Editing repository config on the parity API
This endpoint belongs to P/cloudflare/, not the native Worker's public ingress. Example for an operator who already has the admin token securely available:
curl -sS -X PATCH "$ANTON_OPERATOR/operator/api/repos/owner%2Frepo" \
-H "authorization: Bearer $SON_OF_ANTON_OPERATOR_ADMIN_TOKEN" \
-H 'content-type: application/json' \
-d '{"enabled":true,"branches":{"include":["main","dev"]},"reason":"enable main and dev"}'ANTON_OPERATOR is an example shell variable holding your parity Worker origin, not product configuration. The Worker accepts canonical SON_OF_ANTON_OPERATOR_ADMIN_TOKEN or legacy GILF_OPERATOR_ADMIN_TOKEN configuration. Generated anton_ machine keys do not grant repo-write authority.
Accepted patch fields: enabled; branches.include / exclude; validation.provider (local, crabbox, e2b, shadow) and codeChangesOnly; model.provider, model.model, model.fallbackProvider, model.fallbackModel, model.reasoningEffort; alerts; and reason. These are the patch validator's accepted fields, not proof every setting is consumed by the native engine. Writes record repo-config-update; enabling a repository whose synced GitHub access was removed returns 409.
GET /operator/api/repos exposes repository rows. The original anton-ui Settings view is read-only; anton-ui-trace-parity adds actual per-repository toggles and disables enablement when access is removed.
Sources: P/cloudflare/src/review-state-api.js:254-304,520-541; P/cloudflare/src/worker.js:65-80,115-135; anton-ui/src/views/Settings.tsx:190-305; anton-ui-trace-parity/src/views/Settings.tsx:209-218,253-264.
Token scope is caller-specific
The native broker holds the App private key, while review clone and publish calls request scoped installation tokens. Publisher calls pass the target repository and narrow checks/pull-request permissions (R/src/github-publisher.js:13-103); clone requests ask for contents/metadata read access (R/cloudflare-native/container/entrypoint.mjs:110-118).
The broker helper itself does not require a nonempty repository list: shapeTokenRequest omits repositories when none are supplied. Do not describe it as a universal guarantee against installation-wide tokens (R/cloudflare-native/src/key-broker-core.js:15-35).
Operator-side risk policy is separate
loadReviewPolicy reads config/review-risk.yaml and its scoring helper processes risk_signals, negative_signals and hard_blocks. This is distinct from the workspace admission policy above; a risk-policy design or file is not an extra native admission gate. Repository context files can contribute review guidance, not credentials or a replacement for operator authority. Sources: R/src/review-policy.js:43-87; R/src/codex-review-runner.js:1499-1526.