Skip to content

Spec: generalize GitHub write path for issue/milestone creation off flat-PAT onto installation-token/Orb-broker #7425

Description

@JSONbored

Problem

contributor-issue-draft.ts's createGitHubContributorIssue and ruleset.ts's fileUpstreamDriftIssues both write GitHub issues via a flat operator PAT (LOOPOVER_CONTRIBUTOR_ISSUE_TOKEN ?? LOOPOVER_DRIFT_ISSUE_TOKEN ?? GITHUB_PUBLIC_TOKEN) through a raw fetch, bypassing makeInstallationOctokit/createInstallationToken (src/github/app.ts, src/github/client.ts) and the Orb broker (src/orb/broker-client.ts) that every other GitHub write in this codebase (labels, comments, collaborator-permission checks) already goes through. That PAT must itself hold write access to whichever repo is targeted — it does not automatically follow "wherever this selfhoster's App/Orb-installation is installed" the way every other write path does. A selfhoster-facing issue/milestone-planning tool built on this pattern would require every selfhoster to separately mint and manage a write-capable PAT just for this one feature, defeating the point of the Orb broker existing.

Area

src/github/app.ts, src/github/client.ts, src/orb/broker-client.ts, src/services/contributor-issue-draft.ts, src/upstream/ruleset.ts.

Proposal (open questions a design pass needs to answer)

  • A shared resolver, given a target repo, should return a write-capable Octokit client by trying (1) the selfhoster's own GitHub App installation token via makeInstallationOctokit, then (2) the Orb broker path (fetchBrokeredInstallationToken) if no local App key is configured. The flat-PAT fallback should not be offered to the new selfhoster-facing tool at all.
  • Decide whether contributor-issue-draft.ts and ruleset.ts's existing PAT-based writers get migrated onto the same resolver (for consistency) or are left as-is with the divergence documented (they only ever target loopover's own repo, a narrower risk surface than an arbitrary selfhosted repo) — this is a maintainer call, not purely mechanical.
  • Confirm the resolver's error behavior when neither an App key nor a broker enrollment is configured: the new tool must fail closed with a clear "not configured" message, never silently fall back to an unscoped token.

Deliverables

  • Shared repo-write-client resolver (App-key branch, broker branch, explicit no-fallback-to-PAT for new callers).
  • Decision + implementation on whether existing PAT-based writers (contributor-issue-draft.ts, ruleset.ts) migrate onto it.
  • Test coverage for both the App-key and broker branches, and the fail-closed unconfigured case.

Resources

  • src/github/app.ts (makeInstallationOctokit, createInstallationToken)
  • src/github/client.ts
  • src/orb/broker-client.ts (isOrbBrokerMode, fetchBrokeredInstallationToken)
  • src/services/contributor-issue-draft.ts:555 (createGitHubContributorIssue, the PAT-based pattern being replaced for new callers)
  • src/upstream/ruleset.ts:325 (fileUpstreamDriftIssues, same PAT pattern)

Boundaries

  • maintainer-only. This blocks the rest of the epic — the planning MCP tool (sub-issue 2) must not ship until this resolver exists, since it must not offer selfhosters a new PAT-based path.
  • Must not weaken the Orb broker's existing "never trust the caller's installation_id, always bind server-side to the registered install" guarantee (src/orb/broker.ts).
  • Not scoped to change how labels/comments/collaborator-checks already resolve their client — those are unaffected; this is specifically about closing the gap for issue/milestone-writing code.

Metadata

Metadata

Assignees

Labels

maintainer-onlyOwner-only work — yields no Gittensor points.orbGittensory Orb related - maintainer self-hosting analytics.roadmapOn the Wave-2 agent-layer roadmap board (project 9)

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions