Skip to content

Pi: the source_repo collision guard has no escape hatch on the primary surface #146

Description

@TheAmericanMaker

Problem

#127 makes publishEntry refuse a publish whose source_repo differs from the one recorded on the entry's newest version, with allowSourceRepoChange (allow_source_repo_change on codecarto_publish) as the opt-out for a repository that genuinely moved.

That opt-out is MCP-only. /codecarto-publish is registered with handler: async (_args, ctx) (extensions/codecarto/index.ts:718) and takes no arguments, so a Pi user who trips the guard after a rename, org transfer, or host change cannot publish at all. The error surfaces through ctx.ui.notify(\Unable to publish: ${message}`, "error") (:781`) and the run ends there.

Pi is also where the guard is most likely to fire. slug and source_repo both derive from ctx.cwd (:745, :766), so two same-named directories under different parents collide by construction — see the sibling issue on using the git remote instead.

CLAUDE.md puts Pi first in surface priority ("New features land here first"). This one landed on MCP only. #127 flagged the inversion deliberately rather than riding it along in a bug fix, which is why this is filed separately.

As landed in #127, the refusal message no longer prescribes an action the caller may not expose — it names where each remedy lives instead. That keeps the message honest; it does not give Pi the remedy.

Proposed solution

Pi already calls ctx.ui.confirm for the publish preview (:760). The conflict looks like it belongs in the same place: catch the refusal, present the recorded vs. incoming source_repo, and offer the override as a second confirm rather than a flag the user has to know about.

A flag would also work and is closer to existing precedent — /codecarto-library-init already parses args.trim().split(/\s+/) for --namespace — but a blind --allow-source-repo-change on a command that otherwise takes no arguments is harder to discover at the moment it is needed.

Alternatives considered

  • Leave it. A dead-end is still strictly better than the silent cross-project append it replaced, and the workaround (publish through MCP once) exists. It is a bad failure mode on the recommended surface, though.
  • Auto-suffix the slug (-2, -3). docs/library-format.md promised this and it was never implemented; fix: refuse a publish that would append to another project's history #127 removed the promise rather than building it, on the grounds that silent suffixing is its own surprise for an agent-driven tool. Not revisiting that here.

Scope

  • Template (.codecarto/)
  • Pipeline definition / variant
  • Pi extension
  • MCP server
  • Core (core/)
  • Documentation
  • CI / release

Additional context

Follows #127, which fixes #123. Sibling: the ctx.cwd-as-source_repo default.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions