Skip to content

Phase 6d: github runner port - #62

Closed
grubmeshi wants to merge 1 commit into
refactor/single-go-binary/phase-6c-azdevopsfrom
refactor/single-go-binary/phase-6d-github
Closed

Phase 6d: github runner port#62
grubmeshi wants to merge 1 commit into
refactor/single-go-binary/phase-6c-azdevopsfrom
refactor/single-go-binary/phase-6d-github

Conversation

@grubmeshi

Copy link
Copy Markdown
Collaborator

Phase 6d — github runner port

Fourth of the four stacked Kotlin→Go port PRs. Base: phase-6c-azdevops.

Ports the GitHub Actions workflow_dispatch runner to Go (internal/github, cmd/github, cmd/bbrunner github, container): App JWT (stdlib RS256 + tolerant PKCS#1, no external JWT lib) → installation token → dispatch → async handover / sync poll. internal/github new at 91.3% (gate 90). Build, race tests, lint (0 issues), coverage gate all pass on the full stacked tree (all 11 gates PASS).

Consolidation notes

  • Registers personaGithub in cmd/bbrunner; a personaGithub registration assertion was added to cmd/bbrunner/main_test.go (missing in the original slice) so all four phase-6 personas are pinned.
  • PLAN_DETAIL_06D_github.md copied in from the plan branch (was absent) so the §4.6 Template fit-check subsection lives with the sub-plan, matching 06B/06C.

Fit-check reconciliation (flagged)

PLAN_DETAIL_06D §4.6 assumed github would consume a shared meshapi.DecryptInputs and a shared ExternalCallError. In the landed stack neither is consumed by github, and this is consistent rather than divergent:

  • ExternalCallError is package-local in ALL three ports (06B put it in internal/gitlab, not meshapi) — each persona classifies its own external-call failures, so there is no shared type to consume.
  • github's Mode A/B input handling decodes into its own []runInput, which neither the byte-based meshapi.DecryptInputs nor the typed meshapi.DecryptInputSpecs can express, so it keeps a package-local decode+decrypt path plus a package-local Decryptor twin — the same choice internal/tf already makes. Details in CROSS_REPO_TODO.md (phase-6d).

Sanctioned deltas / deferrals

  • JVM endgame (delete github-block-runner/, block-runner-core/, Gradle machinery; flip CI) deferred to the acceptance-gated flip PR.
  • Preserved designed deltas: dropped stray dispatch Content-Type (§16.2), deterministic sorted permission-map rendering (§16.5), unified Clock for JWT+poll (§16.9), single-run exit tightening (G-P11).
  • Kotlin pin tests not added (gradle not runnable); the Go scenario suite is the surviving pin.

🤖 Generated with Claude Code

Port PLAN_DETAIL_06D_github.md: the GITHUB_WORKFLOW persona in Go.

- App-JWT auth chain, stdlib RS256 (crypto/rsa SignPKCS1v15 + x509.ParsePKCS1PrivateKey),
  no JWT dependency (§4.2/§16.13); whitespace-tolerant PKCS#1 parsing matching Kotlin (G-P2).
- githubClient: 5 REST calls, frozen headers, actions=write permission gate, 422
  unsupported-input heuristic (pure classify fn), validated run/job status enums.
- Dual input modes: Mode A base64-JSON run object (impl stripped to {type}, G-P10 leak
  hygiene, json.Number fidelity D8), Mode B url+token+conditional-endpoint table.
- In-handler sync poller: heuristic find-window (5 newest, -30s, 12x10s), 30m poll budget,
  job-step batches (trigger step in first batch, completed-job re-report quirk G-P4),
  terminal update from conclusion; ctx-cancel reports terminal ABORTED (never SUCCEEDED).
- Config compat (blockrunner: block, private-key order, SPRING_PROFILES_ACTIVE alias),
  cert/NoOp decryptor, event-driven reporter seam, R12 single-run exit (G-P11 tightening).
- Persona wiring: cmd/github (+ bbrunner github subcommand), mgmt on 8102, per-app
  Dockerfile + runner-config.yml (baked dev key, umbrella §10.5).
- Gate: thresholds += internal/github 90 (91.3%, no exclusions), depguard github group.

Template fit-check (§4.6) passed unchanged. Because 06B is not landed in this base
(phase-6a-manual), the ExternalCallError/DecryptInputs shapes it promised are implemented
package-locally for now and should be reconciled to the shared meshapi twins at
consolidation. JVM teardown (steps 10-11) and CI flips are deferred to consolidation to
keep this slice disjoint from the parallel 6b/6c siblings.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@grubmeshi

Copy link
Copy Markdown
Collaborator Author

Superseded by #65, which consolidates the plan + all phases 0→7 + the phase-3/5 remediation into a single reviewable PR (with all plan/run artifacts and a code-verified FOLLOW_UP.md). Closing in favor of #65.

@grubmeshi grubmeshi closed this Jul 13, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant