Skip to content

omind guard locked on new repos with no remotes because pulls / fetches are not possible #149

Description

@CryptoJones

Summary

Inside a brand-new repo with no remote (a freshly git init'd directory — e.g. the first steps of scaffolding a new project), omind guard locks the agent out of its own repo. The same-turn freshness gate (repo-work-fresh-base) demands a git fetch / git pull before any review/edit/test/commit — but a repo with no remote has nothing to fetch, so the demanded remediation is impossible:

  • git fetchfatal: No remote repository specified.
  • git pull --ff-onlyThere is no tracking information for the current branch.

Only the exact string git fetch --all --prune happens to exit 0 (it iterates over zero remotes as a no-op), so the block is technically escapable via one specific incantation — but the two commands the block message actually suggests both fail, which reads as a hard deadlock.

Reproduce

mkdir /tmp/newrepo && git -C /tmp/newrepo init
cd /tmp/newrepo
# consult the git-rules note this turn (satisfies repo-work-read-git-rules), then:
#   → any Write/Edit/pytest/commit is blocked with rule_id=repo-work-fresh-base
git pull --ff-only          # fatal: There is no tracking information for the current branch.
git fetch                   # fatal: No remote repository specified.

Driving the decision engine directly:

from omind import guard
sess = "demo"
guard.record_consult(sess, kind="read", target=guard.GIT_RULES_NOTE, relevant=True)
v = guard.decide({"tool": "Write", "file_path": "/tmp/newrepo/hello.py", "session": sess})
# BEFORE: v.allow is False, v.rule_id == "repo-work-fresh-base"

Root cause

guard.decide() demands freshness for any repo-sensitive action whenever _repo_root_for_action(...) resolves a repo (i.e. a .git exists) and the per-turn freshness marker isn't set. It never checks whether the repo actually has a remote. A repo with zero configured remotes has no upstream to be stale against, so the freshness check is vacuous there — yet it's enforced, and can't be satisfied by the remediation the block message recommends.

Proposed fix

Waive the freshness demand when the repo has no configured remote (repo-work-fresh-base no longer fires); keep it exactly as-is for any repo that has a remote. The rules-note consult (repo-work-read-git-rules) still applies — this only touches freshness.

Detection must be subprocess-free (this runs on the PreToolUse hot path) and conservative: read <repo>/.git/config for a [remote "…"] stanza, and treat any doubt — a .git pointer file (linked worktree / submodule, whose remotes live in the shared config), an unreadable config, or any resolution error — as has a remote. That way freshness is only ever waived when we positively confirm zero remotes, and a repo that has a remote can never be loosened.

Scope / non-goals

  • Not a loosening for real repos: a repo with a remote still requires a same-turn fetch.
  • Does not touch the git pull bare-vs---ff-only rule, the rules-note consult, or the destructive hard-blocks.
  • A directory that is not a git repo at all already isn't freshness-gated (no .git → no repo → freshness branch skipped); it only ever hits the ordinary consult-gate.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions