Fork Routing
repos.upstream_urlis the parent repository used for PR base routing;repos.fork_urlis an optional GitHub fork push target.no-mistakes init --fork-url <url>expectsoriginto point at the GitHub parent repository and<url>at the contributor fork; plainno-mistakes initpreserves an existing fork URL on idempotent refresh.- Push code must resolve the push URL via
resolvePushURL(internal/pipeline/steps/common_git.go) so configured forks still receive branch updates, including after a CI repair restarts validation; the non-fork path recovers the credentialled upstream from the worktree'soriginremote at run time because the DBupstream_urlis stored redacted (see Credential Redaction below).Repo.PushURL()remains correct only for fork-only callers (e.g.rebase.go), since fork URLs carry no embedded credentials. - GitHub PR code must keep
--repopointed at the parent and use--head <fork_owner>:<branch>whenfork_urlis set; existing-PR lookup must list by the bare branch and filter head-owner fields, never pass<owner>:<branch>togh pr list --head. - Non-GitHub fork MR/PR routing is intentionally out of scope until implemented end to end; if a legacy row has
fork_urlfor another provider, PR creation must skip instead of opening a self PR. - Every new run best-effort refreshes registered upstream/fork URLs from the working clone through
gate.RefreshRepoURLs: origin is the upstream authority, an existing fork requires one uniquely matching clone remote, both DB fields replace atomically, and every discovery/validation/write failure logs only a bounded reason and continues with the exact old registration. The refresh never rewrites clone or gate remotes;Repo.URLsVerifiedis run-scoped evidence that trusted fetch/push may use the refreshed DB URL instead of an inherited stale gate origin.
Repository Forge Identity (internal/forgecontext)
- Optional global
forge_profilesmap raw remote host tokens/SSH aliases to one isolatedghorglabconfig directory, plus an optionalexpected_loginpin. The resolver owns profile selection, validation, parent/fork ambiguity, provider-specific fail-closed activation, and the immutable run environment; do not add ambient account switching or per-step routing. Profile identity for the parent/fork same-profile check is the config directory AND the pin, so conflicting pins fail as ambiguous instead of silently picking one account (sameProfile/expectLoginown the rationale). - A resolved context must reach built-in provider commands, configured shell commands, native agents, managed agent servers, and recovered approval reconciliation. Never mutate the daemon environment or persist credentials/profile selection in the DB; recovery re-resolves from current global config.
- No configured profiles means exact legacy ambient behavior. Online auth failures keep provider steps' existing skip behavior; deterministic config/routing errors fail before the pipeline. The public contract lives in
docs/src/content/docs/reference/global-config.md.
Credential Redaction in Stored URLs and Errors (security)
gate.InitWithForkruns the upstream URL throughsafeurl.Redactbefore every DB persist (UpdateRepoMetadata*,InsertRepoWithIDAndFork) and the "gate initialized" log line; the bare gate'soriginremote still carries the full credentialled URL (viaprovisionGate) so carved worktrees authenticate. Because the DB copy is redacted, push and branch-sync code must recover the credential from the worktree'soriginremote at run time (resolvePushURL/resolveUpstreamURL), never fromRepo.UpstreamURL/Repo.PushURL().- Step-failure errors (
executor.goFailStep/log/IPC emit) and the Bitbucket resolve-repo error are redacted viasafeurl.RedactText/safeurl.Redactso a credentialled URL wrapped into an error can never reach a step log orruns.error. Reuseinternal/safeurlfor new redaction sites rather than adding a git-local helper; it is already wired intogit.Run/step git-run error formatting. - Regressions:
TestInitRedactsCredentialURL,TestResolveUpstreamURL_PreservesCredential,TestResolveUpstreamURL_FallsBackToRecordedURL,TestResolvePushURL_ForkWinsOverCredential.