Skip to content

fix(og): adopt a differently-cased project instead of duplicating it - #18

Merged
jmvbambico merged 1 commit into
mainfrom
fix/og-project-case-insensitive
Oct 9, 2026
Merged

jmvbambico merged 1 commit into
mainfrom
fix/og-project-case-insensitive

Conversation

@jmvbambico

Copy link
Copy Markdown
Owner

Why

ensure_project() looked the Omnigent project up by exact name:

proj = next((p for p in projects if p.get("name") == name), None)

name is ${OG_PROJECT:-$AGENT_NAME}. On a machine where a project named
Hivemind already existed and agent_name was hivemind, that lookup missed
and og POSTed a second project. Both then rendered in the Omnigent
sidebar as near-identical folders, and neither side ever cleaned up the other —
observed in the wild for ~2 weeks, with sessions accumulating in both. og
kept re-pinning the lowercase one while anything started from the sidebar
landed in the other.

What

Case-insensitive lookup, then adopt rather than duplicate:

  • Match on casefold(); prefer the exact-case project, else the lowest id
    so a rerun adopts the same one regardless of server response order.
  • When the adopted project's name differs only in case, rename it to the
    canonical name via PATCH /v1/projects/{id}. That route 409s when another
    of the caller's projects already holds the name — swallow only 409 and keep
    the adopted project's existing name.
  • POST a new project only when there is no case-insensitive match.
  • stdout now prints the name the project actually ends up with, not the
    requested one. The caller builds OG_PUBLIC_URL=".../?project=$proj" from
    it, so printing a name the server does not have would silently break the
    composer deep-link.

bin/og only, +28/-3. The agent/workspace/host pinning block and its
re-pin-every-start behaviour are untouched.

Verification

  • bash -n bin/og — pass
  • extracted heredoc Python py_compile — pass (bash -n cannot catch Python
    syntax inside the heredoc)
  • python3 -m pytest tests/ -q — 293 passed
  • The implementer exercised the lookup/adopt logic standalone against a fake
    project list: exact match, case-only difference, no match, multiple matches,
    the rename-409 sub-case, non-409 propagation, and a rerun for idempotency.

The sandboxed installer gate in AGENTS.md does not apply — no installer/ or
template files are touched. No automated test covers ensure_project(); it is
Python embedded in a bash heredoc, which this repo's pytest suite does not
reach.

Review

cross-vendor-review: passed

Implemented by a deepseek-pinned worker, reviewed independently by an
OpenAI-pinned reviewer with no blocking findings. The reviewer traced the
original bug case, the 409 path, every post-rename use of the stale in-memory
proj dict, the tie-break, the two sequential PATCHes, and idempotency on
rerun. Two unreachable edges it raised and I am recording rather than fixing:
identical project ids would make the min() tie-break fall back to server
response order, and a null stored name would be reported as "" without
reconciliation — neither is a state this API produces.

🤖 Generated with Claude Code

ensure_project looked the project up by exact name, so a project named
"Hivemind" was missed by an agent named "hivemind" and og POSTed a second
one, leaving two identical-looking folders in the sidebar. Match
case-insensitively and adopt the existing project, renaming it to the
canonical name when the case differs. A 409 on that rename (another
project already holds the canonical name) keeps the adopted project's own
name rather than failing; the printed name is whatever the project ended
up called, so the composer URL still points at a real project.

Co-authored-by: CommandCodeBot <noreply@commandcode.ai>
@jmvbambico
jmvbambico merged commit 309b049 into main Oct 9, 2026
3 checks passed
@jmvbambico
jmvbambico deleted the fix/og-project-case-insensitive branch October 9, 2026 03:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant