feat: GitHub identity via config-dir profiles#101
Draft
levifig wants to merge 4 commits into
Draft
Conversation
Successor to the parked PATH shim (PR #100): per-identity gh config profiles selected by GH_CONFIG_DIR β a path, not a secret β wired per-project through harness-native env (Claude Code settings.local.json first), with the github-account hook retreating to pure-read verification wherever a profile mapping exists and convergence surviving only as fallback. Maintainer-endorsed mechanism (cli/cli#12145); the native --account selector was closed unmerged upstream. Spikes gate the build: keyring isolation per config dir and credential-helper env inheritance. The shim's rejection is recorded in Cut with grounds β mechanism nature, not correctness β seeding the rejection-KB pattern.
β¦ange A community report of GH_CONFIG_DIR being honored by gh but not by git push credential resolution lands as a deliberately disconfirming Source Input: both U1 spikes sharpen (keychain by-host lookup is the suspected mechanism), the HTTPS matrix row's spike must reproduce the failure before deciding ships/ships-with-caveats/residual, and core scope is explicitly insulated from a failed spike.
β¦ofiles change Two more #12145 inputs adjudicated: the maintainer's session-wide GH_TOKEN export is concurrency-safe (env is per-process, zero disk mutation β verified in the parked change's spike) but rejected as the wired mechanism, since it puts a live secret in every subprocess env and cannot be statically wired into harness config; kept as the zero-setup terminal recipe. The field-proven conditional credential helper (per-tree or repo-local git config resolving a named token inline) becomes the likely shipped answer for the HTTPS matrix row β the one surface gh's own mechanisms miss β and a U2 wiring candidate. The U1 spike now adjudicates three candidate mechanisms for HTTPS.
Both gate spikes pass with corrections. Keyring isolation is real at the pointer layer only: profiles scope the active account, but credentials live once machine-wide in the OS keychain, and --user/GH_TOKEN bypass profile scoping entirely β profile health checks now probe the active account without --user. Discussion #188559 did not reproduce here but its mechanism is real (config-merge helper ordering), so GH_CONFIG_DIR inheritance is documented as unreliable and the repo-local conditional credential helper ships as the HTTPS mechanism, spike-verified to pin identity against an adversarial pointer. New residual: a stale osxkeychain internet-password for github.com found on this machine β status/doctor will warn on the class. Transcripts in research/.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Change
docs/changes/20260708-gh-config-dir-profiles/ β shaped, validated (
loaf change check: zero violations, executable). Draft = spikes pending: Decision 5 gates all building on two empirical spikes, and one of them now has a documented counterexample to reproduce first.What & Why
Successor to the parked PATH shim (PR #100 β rejected after implementation on mechanism nature, not correctness). Same invariant β per-invocation GitHub identity, agents type bare
gh, repo names the account while the machine picks the mechanism β achieved through gh's own maintainer-endorsed mechanism:GH_CONFIG_DIRprofiles (cli/cli#12145). One config dir per identity, each with a single-accounthosts.yml, selected by an env var that is a path, not a secret, wired per-project through harness-native env config (Claude Codesettings.local.jsonfirst). No PATH edits, no symlink, no binary dispatch, no token material in environments.The tier vocabulary simplifies: tier 1 convergence (merged in #99 β default, zero footprint, disclosed pointer-collision cost) and tier 2 profiles (recommended opt-in). The hook retreats to pure-read verification wherever a profile mapping exists; convergence survives only as the fallback beneath it.
Review focus
git pushHTTPS inheriting the profile env. GitHub Community Discussion #188559 reports the second one failing (gh honors the profile;git pushreverts to the previously-logged-in account). Both spikes run before anything is built; the fog register carries the counterexample and the ships/ships-with-caveats/residual decision tree.gh authexemption β wired-and-matching pure-read pass β wired-but-mismatched block (never converge someone's explicit profile choice) β unwired convergence fallback.GH_TOKENinjection superseded; no auto-wiring ever.GH_CONFIG_DIRpaths live in machine-local files (settings.local.json). The untrusted-repo residual strictly improves over the shim β nothing maps accountβprofile unless the user wired it.Verification
Shaping-stage:
loaf change check docs/changes/20260708-gh-config-dir-profilesβ zero violations, executable. U1 spike evidence (V2) will land in this folder'sresearch/as command-reproducible transcripts before U2βU5 build. H3 inherits the parked Change's DoD: this repo wired as the first production use, the 2026-07-07 account race rerun and won.Migration / breaking changes
None at this stage. When implemented: strictly opt-in per machine and per project; tier-1 behavior unchanged for everyone else.
Deferred