Skip to content

Resolve project identity from canonical repo URL, not directory basename #716

Description

@thekoma

Problem

After #687 made basename(git rev-parse --show-toplevel) the default project key, two failure modes remain:

  1. Basename collisions~/work/utils (github.com/acme/utils) and ~/clients/foo/utils (github.com/foo/utils) both resolve to utils and silently share memory.
  2. Cross-machine fragmentation — a single agentmemory pod serving multiple MCP clients sees the same repo as different projects when contributor checkouts differ in basename. Concrete shape: central pod at /srv/projects/foo, dev box at /home/<user>/src/foo, or simply foo-prod vs foo on a fork. AGENTMEMORY_PROJECT_NAME works around this but requires per-machine config for what is intrinsic to the repo.

Both fall away once the resolver consults remote.origin.url — the same identity src/hooks/post-commit.ts:65 already uses for commit attribution.

Proposal

Insert one step between the env override and the toplevel-basename fallback:

AGENTMEMORY_PROJECT_NAME
→ canonical(git config --get remote.origin.url)
→ basename(git rev-parse --show-toplevel)   ← #687, unchanged
→ basename(cwd)                              ← unchanged

canonical produces host/owner/repo:

Input Output
https://github.com/acme/widgets.git github.com/acme/widgets
git@github.com:Acme/Widgets.git github.com/acme/widgets
ssh://git@host.example:2222/acme/widgets.git host.example/acme/widgets
https://user:token@github.com/acme/widgets github.com/acme/widgets

Lowercased end-to-end (host providers treat owner/repo case-insensitively; preserving path case would re-fragment same-repo clones). Trailing .git stripped, credentials stripped. Unparseable remotes fall through to basename.

Why this and not #530

#530 proposed canonicalization plus multi-key matching across canonical/cwd/worktree-top/main-root/aliases. This issue keeps the single-key partitioning #687 just shipped — the change is where the key comes from, not how it's matched. No migration of existing data; deployments that already set AGENTMEMORY_PROJECT_NAME see no behavior change.

Non-goals

  • Monorepo sub-package partitioning. Every package under github.com/acme/monorepo resolves to the same key by design — partitioning within a monorepo is an orthogonal concern (the project axis isn't the right one for it). Operators who need per-package memory continue to set AGENTMEMORY_PROJECT_NAME per-package.
  • Multi-remote awareness (forks). origin is sufficient for the two failure modes above. AGENTMEMORY_PROJECT_NAME remains the override for fork workflows that need to point at upstream.
  • SSH config aliases, insteadOf rewrites. Resolver consumes the raw URL git emits; if a contributor configures an alias differently across machines, that's the same class of problem as setting different env vars and is solved by the same escape hatch.

Performance

One git config --get remote.origin.url invocation, capped at 500ms (same budget the rest of _project.ts already uses). Same shape as #530's tightened lookup discussed by @rockarxiv on that PR.

Patch shape

~60 LOC in src/hooks/_project.ts, 12 new unit tests, full suite (1303 tests) green. Happy to discuss the approach before opening the PR if there's a different shape you'd prefer; otherwise the PR will follow.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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