Files
claude-foundations/claude/source-control.md
Paul O'Reilly 091fae73e8 Pre-flight: check ssh-add -l before asking user to load a key
Keys are often pre-loaded. Added explicit check-first guidance and
a note to use grep -i (case-insensitive) — a case-sensitive grep
will silently miss keys whose comments use different capitalisation.
2026-07-18 11:00:52 +12:00

2.9 KiB

Source Control

Hosts and orgs

  • All projects on Gitea (gitea.oreillyit.nz) as primary remote — prefer this hostname over gitea.homelab.internal (same instance, the public name enables external access)
  • Migrate existing remotes from gitea.homelab.internal to gitea.oreillyit.nz when convenient
  • skynet org: AI-focused projects. Owned by ai_enablement.
  • homelab org: infrastructure projects (cluster-bootstrap, etc.). Owned by cluster-administrator.
  • oreillyit org: non-AI internal O'Reilly IT tools. Owned by ai_enablement.
  • Optionally push-mirror to GitHub for public visibility.

SSH aliases

Pattern: gitea.oreillyit.nz-<username>.

  • gitea.oreillyit.nz-homelab → authenticates as cluster-administrator (key: ~/.ssh/gitea-cluster-admin)
  • gitea.oreillyit.nz-ai-enablement → authenticates as ai_enablement (key: ~/.ssh/gitea.ai-enablement)
  • gitea.oreillyit.nz-accelerators → (key: ~/.ssh/gitea.accelerators.2026)

Git remote URL format: git@gitea.oreillyit.nz-<user>:<org>/<repo>.git

  • Example: git@gitea.oreillyit.nz-ai-enablement:skynet/custom-claude-skills.git

SSH agent pre-flight

Before the first push of a session:

  1. Derive the alias: git remote get-url origin — the host segment is the SSH alias.
  2. Run ssh-add -l and read the full output. Keys are often pre-loaded — check before asking. Use grep -i <keyname> (case-insensitive) to find the relevant entry; a case-sensitive grep will miss keys whose comments use different capitalisation.
  3. If the key is present, proceed. Only ask the user to ssh-add ~/.ssh/<keyfile> if it is genuinely absent. Claude cannot answer a passphrase prompt.
  4. Confirm auth: ssh -T git@<alias> — expect a Gitea welcome message.

In non-interactive contexts (CI, container agents, unattended loops), use GIT_SSH_COMMAND='ssh -o BatchMode=yes' git push so a missing credential fails fast instead of hanging on a passphrase prompt.

Push failure recovery

Symptom Likely cause
Permission denied (publickey) Key not loaded, or wrong alias in remote URL
Push hangs silently Passphrase prompt in non-interactive context — use BatchMode=yes
403 after API-created repo SSH user not added as collaborator — add via Gitea UI or API

Commit locally first, surface the failure explicitly, and never end a session with finished work unpushed and unmentioned. Record the recovery step in CONTEXT.md.

Working rules

  • Always pull before planning work — run git pull --ff-only when entering a project. Work may have been pushed from another machine or by container agents. If the pull fails (diverged history, uncommitted changes), warn the user before proceeding.
  • Meaningful commit messages; prefer small, focused commits over large batches.
  • Enable pre-commit hooks where appropriate (secret detection, linting, formatting).
  • Never commit secrets in plaintext — use SOPS + age or equivalent encryption.