The P3 dispatcher's default seams shell out to gh/git, but the R720 box has
no gh and a read-only PAT with no Actions scope — so dispatch_apply_verify
returned no run_id and every task parked at verify ("dispatch unresolved").
Add a GitHub-App auth path: the box mints short-lived (~1h) installation
access tokens from the App private key and uses them for the three dispatch
seams, removing the gh dependency.
- agent_team/github_app.py (new): mint_installation_token (RS256 App JWT,
iss=app_id, iat backdated 60s, exp 9 min; POST /access_tokens) + a lazy
TokenProvider that caches and re-mints near expiry. Secret-safe: the JWT
and token are never logged, never in an exception message, never persisted.
- dispatcher.py: app_branch_pusher / app_workflow_dispatcher / app_run_locator
(additive; gh/git _default_* left untouched). Push auth rides a host-scoped
http.extraHeader via GIT_CONFIG_* env (token never in argv/ps); the REST
run locator maps id->databaseId / created_at->createdAt into select_run_id
and surfaces 4xx promptly instead of silently exhausting the poll window.
- coordinator.py: default_dispatch_node_factory binds the App seams when
AGENT_TEAM_GH_APP_ID / _INSTALLATION_ID / _PRIVATE_KEY are all set; partial
or unreadable config logs one warning and falls back to gh-default (never
raises at serve-start).
- requirements.txt: pin PyJWT, cryptography, requests (App seams + CI fetcher).
- DEPLOY-R720.md / README.md: App dispatch config, permission/scope audit,
env-precedence check, key rotation/revocation + incident response.
Tests: +18 (test_github_app.py new; dispatcher/coordinator additions) covering
JWT claims, cache/re-mint, token-scrub-on-error, REST field mapping + run-name
correlation, and the partial-env inert fallback. Full suite 1523 passing.
|
||
|---|---|---|
| .. | ||
| db | ||
| nodes | ||
| transport | ||
| __init__.py | ||
| api.py | ||
| billing.py | ||
| ci_fetcher.py | ||
| ci_gate.py | ||
| ci_watcher.py | ||
| coordinator.py | ||
| dashboard.py | ||
| deadline_timer.py | ||
| decisions.py | ||
| dispatcher.py | ||
| draft_pr_monitor.py | ||
| github_app.py | ||
| graph.py | ||
| invoker.py | ||
| invoker_multi.py | ||
| ledger.py | ||
| operator_cli.py | ||
| recovery.py | ||
| responder.py | ||
| resume_worker.py | ||
| state_store.py | ||
| status_page.py | ||
| task_model.py | ||
| topology.py | ||