9e5d00c6fa
The consolidated gateway serves every bottle's repos under /git/<bottle_id>/ (slice 10), so each bottle's bare repos + per-repo credential config must be provisioned into that namespace. This adds the renderer for that; placing the creds + running it inside the gateway is the launch-wiring step. - Extract the credential-wiring `init_repo` shell into a shared `_git_gate_init_repo_fn(repo_root, creds_dir)` — one source for the security-sensitive logic. The single-tenant daemon entrypoint is byte-unchanged (still /git + /git-gate/creds; existing tests green). - git_gate_render_provision(bottle_id, upstreams): posix-sh that inits ONE bottle's bare repos under /git/<bottle_id>/ reading creds from /git-gate/creds/<bottle_id>/. Init-only (no `git daemon` — the shared gateway already serves). Isolating each bottle's repo root + creds dir by id is what keeps one bottle's push credentials out of another's repos. - bottle_id is embedded unquoted in the script, so it's restricted to a shell/path-safe alphabet (registry ids are token_hex; defense in depth). pyright 0 errors; pylint 9.83/10; unit suite green (1724 tests; the 13 test_sidecar_init /bin/sleep errors are pre-existing NixOS-local noise). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WBMWTEtQdJ4W5UrWuLHCck