Repository navigation
ai pull request scan
GitHub released REST endpoints for AI Scan for pull requests in public preview on 2026-09-10 (changelog). AI Scan is GitHub's AI-powered security detection for pull requests and covers languages and frameworks CodeQL does not support, such as PHP, shell, Terraform, and Dockerfiles. Issue #35 adds security.aiPullRequestScan so the setting is handled by plan, apply, import, and import --into.
Implemented in PR #36, awaiting review. The design is recorded in docs/design.md and docs/adr.md records 8 and 9.
Two changes were added after the plan below was written, both found while verifying against an empty private repository without Advanced Security:
-
ADR record 9. A 403 from the CodeQL default setup or AI Scan read now means the feature is unavailable: blocked, or manual when
optional: true, andapplyskips the write. Without it, an optional declaration reported an update forever andplan --cinever exited0on such a repository.importalso reports a CodeQL default setup 403 as a diagnostic instead of failing. -
PR review. A failed optional CodeQL default setup write in the same
applyrun leaves the AI Scan dependency unsatisfied.
Verification on that repository: plan reports both features as manual, apply --yes exits 0, plan --ci exits 0, import succeeds with diagnostics, and import --into proposes no changes. Seeding an existing empty repository fails with 409 for an unrelated, pre-existing reason and is tracked in Issue #37.
| Type | Issue |
|---|---|
| Parent | Issue #35 |
The endpoints are served under API version 2026-03-10, the version the client already pins (REST reference).
| Use | Method and path | Body and response |
|---|---|---|
| Read | GET /repos/{owner}/{repo}/code-scanning/ai-scan |
{"pr_scan": "enabled" | "disabled"}; 403 when Advanced Security is not enabled, 404 |
| Write | PATCH /repos/{owner}/{repo}/code-scanning/ai-scan |
body {"pr_scan": ...}; 403 when archived or Advanced Security is not enabled, 422 |
| Organization (not managed) |
GET/PATCH /orgs/{org}/code-scanning/ai-scan
|
a disabled organization prevents repositories from enabling AI Scan |
AI Scan also requires GitHub Advanced Security, a Copilot license, CodeQL default setup, and enablement by the enterprise and organization. Usage consumes AI credits.
-
Shape.
security.aiPullRequestScan: { enabled, optional }, reusingFeatureSetting.schemaVersionstays1; binaries older than this change reject the key as an unknown field. - Repository scope only. The organization endpoint is not managed, consistent with organization policy being reported as manual work. A write GitHub rejects because of the organization setting fails like any other write.
-
CodeQL dependency. Only
enabled: truedepends on CodeQL default setup being effectively enabled after the run: a declaredcodeqlDefaultSetuptakes precedence, otherwise the live state. An unsatisfied dependency isblocked, ormanualwhenoptional: true. This is evaluated the same way asdependabotSecurityUpdatesondependabotAlerts, and re-checked at apply time. -
Order. Applied in
StageSecurityimmediately aftercodeqlDefaultSetup; no new stage. -
Unreadable state. In
plan, a failed read is unknown and reports an update. Inimport, a 403 or 404 is reported as a diagnostic and the key is omitted rather than written asenabled: false(ADR record 1); other errors fail the import. -
Preview. No opt-in flag or separate header. The documentation states the API is a public preview and recommends
optional: true, because the prerequisites cannot be checked before writing.
- Schema and config:
schema/repospec.schema.json,internal/config/config.go - API client:
AIScanSetting,GetAIScan,UpdateAIScanininternal/githubapi - Planner:
appendSecurityChanges,applyRemainingSecurity, and a CodeQL effective-state helper ininternal/planner/planner.go - Import and refresh:
internal/importer/security.go,internal/refresh/plan.go,internal/refresh/jsonapply.go - Documentation:
docs/design.md,docs/adr.mdrecord 8,docs/examples/bootstrap.yaml,README.md, and their_jatwins
Unit tests cover the API client (path, method, body, and API version header), the planner (noop convergence, unknown state, blocked and manual dependency outcomes, enabled: false never blocked, and apply order codeql < AI Scan < rulesets), the importer (enabled, disabled, 403 and 404 diagnostics, other errors), and refresh for both YAML and JSON. scripts/verify.sh / scripts/verify.ps1 run the full test suite, vet, and the build. A test repository then confirms plan → apply → plan --ci exits 0 and that import --into proposes no difference.
The organization-level AI Scan setting and any change to the Advanced Security or Copilot licensing of a repository are out of scope.