neosourceDocs
Search docs

Re-run the git-lfs closure scan for a GitHub-linked repository

POST/api/repos/{owner}/{repo}/github-lfs/recheck

recheckGithubLfs

Walks everything the repository's **current** refs make reachable and reports whether any of it is a git-lfs pointer file, then stores the verdict and updates `write_health`. The scan's object universe is STORAGE, not any incoming pack: an object that is stored but currently unreachable — a pointer force-pushed away that a branch could resurrect — is found the moment a ref would reach it. It is the same computation the push gate runs, so a `clean` here and an admitted push are one answer. Three results. `clean` means every object in the closure was read and none is a pointer. `pointers_detected` names the first one found. `unverified` means the scan could not answer — a read failure, a missing object, or a closure past the walk ceiling — and it is the **fail-closed** value, not an error: a GitHub-managed repository's pushes are refused on it exactly as they are on `pointers_detected`. `ref_set_digest` binds the verdict to the exact refs it was computed over, and `scanner_version` to the grammar that computed it; a stored verdict that matches neither is treated as `unverified` rather than trusted. Available on any repository with a GitHub relationship, mirror included — a mirror has to be able to clear `lfs_blocked` before it can be promoted to `github_managed`. `404` when the repository has no relationship at all. Requires repository **admin**: the scan walks the full closure.

Requires authentication using a bearer token or a session cookie — see tokens and scopes.

curl

curl -X POST 'https://neosource.dev/api/repos/OWNER/REPO/github-lfs/recheck' \
  -H 'Authorization: Bearer $NEOSOURCE_TOKEN'

fetch

fetch("https://neosource.dev/api/repos/OWNER/REPO/github-lfs/recheck", {
  method: "POST",
  headers: {
    Authorization: "Bearer $NEOSOURCE_TOKEN",
  },
});

Path parameters

ownerrequired

Repository owner or organization slug.

string

reporequired

Repository name.

string

Responses

200The verdict of this scan

application/json

GithubLfsVerificationResponse

object

Response of `POST /api/repos/{owner}/{repo}/github-lfs/recheck` — one prospective-closure git-lfs scan over the repository's CURRENT refs (ADR 0115 **D9**). Distinct from `GithubRelationshipResponse::write_health`, which reports the *stored* posture and nothing about what it was computed from. This response is the scan itself, and it carries the two fields that make a verdict re-checkable rather than merely reported: * `ref_set_digest` — the exact ref set the verdict is bound to. A `clean` that describes a repository which has since moved is not a `clean`, which is why the digest travels with the result rather than beside it. * `scanner_version` — the grammar and walk that produced it. Compared for EQUALITY, so a rollback to an older binary refuses a newer scanner's row just as firmly as a stale one. `checked_at` is millis since the Unix epoch, matching every other timestamp on this surface.

checked_atrequired

integerint64

Millis since the Unix epoch.

ref_set_digestrequired

string

Lowercase hex of the 32-byte fingerprint of the ref set scanned.

resultrequired

LfsVerificationResult

string

Verdict of one prospective-closure LFS scan (`github_lfs_verifications.result`). Mirrors the Phase 0b CHECK constraint exactly — `clean` | `pointers_detected` | `unverified`. A new variant needs a migration. **`Unverified` is the fail-closed value, not an error value.** Every way a scan can fail to reach an answer — a read failure, a missing object, a walk over the ceiling, a stored row bound to a different ref set or a different scanner — resolves to this variant. Nothing may collapse it to `Clean`. It reaches the wire as of the `POST …/github-lfs/recheck` route (`GithubLfsVerificationResponse`), so the serde `rename_all` must agree with [`Self::as_str`] — pinned by `lfs_verification_result_wire_consistency` in `neosource-api-types/tests/enum_wire_consistency.rs`, which is the entry this derive owes.

"clean""pointers_detected""unverified"

scanner_versionrequired

string

The scanner that produced `result`.

write_healthrequired

GithubWriteHealth

string

Whether a GitHub-authoritative repository is currently safe to write through — the `github_repo_sync.write_health` column. Closed vocabulary; the tokens are the CHECK list at `migrations/20260901120000_github_relationship_expand.sql`. The default for a fresh relationship is [`Self::LfsUnverified`], not `Healthy`: a repo whose LFS posture nobody has looked at yet is not known-good, and the fail-closed direction is the one that does not push objects at an upstream that will reject or mangle them.

"healthy""lfs_unverified""lfs_blocked""paused""error"

Standard errors

Bodies documented once for the whole API — see standard errors.

  • 400Bad Request — one of: invalid_input
  • 401Authentication required
  • 403Forbidden — one of: forbidden
  • 404Not Found — one of: not_found
  • 409Conflict — one of: already_exists, conflict, non_fast_forward
  • 423Locked — one of: busy
  • 429Rate limited — retry after the `Retry-After` header
  • 500Internal server error
  • 503Service temporarily unavailable / at capacity — retry after the `Retry-After` header
  • 504Gateway timeout — the request exceeded the server's handling budget