Resolve caller default branch throughout gated sync

Merged
UN
7d ago
+256-21

Closes #128.

Scheduled callers without repository metadata previously stopped before checkout because the guard compared against refs/heads/. A caller whose default branch was trunk passed the guard but later checked out, rebuilt from, and targeted main.

The first step now resolves the caller default branch with authenticated gh api repos/$GITHUB_REPOSITORY, falling back to event metadata only when present. It validates the branch and fails closed with a clear diagnostic if resolution fails or the caller ref differs. Checkout, sync preparation from origin/<default>, PR lookup/create bases, permanent tracker links, and PR text all use the result. No main literal remains in the reusable workflow. Other workflow operations, package pins, and gate thresholds remain unchanged; README and the caller example describe the behavior and repinning requirement. This follows GitHub's caller-context contract and repository metadata API.

Acceptance tests execute the actual workflow Bash with a schedule payload lacking repository, dispatch metadata, rejected refs, API precedence/fallback, and resolution failure. Tests inject the gh executable through PATH, preserving the unchanged attestation policy. A real Git fixture with no main branch checks the trunk guard result, checkout binding, preparation, PR bases, links, and body.

Behavioral revert proofs recorded in the tracker:

  • Reverting API resolution to payload-only initialization makes the schedule-without-repository test fail: 0 passed, 1 failed; exit 1 instead of 0, comparing against refs/heads/.
  • Reverting only preparation to origin/main makes the contract and real trunk fixture fail: 0 passed, 2 failed; Git exits 128 with an invalid reference. Restoring the fixes passes.

Validation used isolated HOME and Git configuration, at unchanged thresholds:

  • npm run release:check: 681/681 passed; zero failures, skips, cancellations, or todos.
  • bun run release:check: 681/681 passed with the same zero counts, in a separate copy verified to have identical tracked content and independent coverage files.
  • Both coverage receipts: 13 authored modules at exact 100/100/100/100; 10,040/10,040 lines and statements, 255/255 functions, 2,832/2,832 branches, no skipped source. Static checks, privacy, zero duplication, production audit, pack, changelog, and attestation passed.
  • node_modules/.bin/pm test pm-github-q4uz --run --progress --timeout 600: 7/7 passed. Focused attestation tests passed 8/8.
  • Post-commit privacy audited 4,519 objects with approved identities and no secret or host-path matches; changelog check passed. Committed source/config/docs match the tested content; later tracker changes record the results and claim release.

Tracker: pm-github-q4uz, with review evidence at this commit. Claim released; item remains in progress for orchestrator verification. Callers still need to repin; live caller schedules were not run.