Problem
/codecarto-publish passes the local working directory straight through as the entry's provenance:
const slug = deriveSlug(ctx.cwd); // extensions/codecarto/index.ts:745
...
source_repo: ctx.cwd, // :766
docs/library-format.md:216 describes that field as "Where the analyzed code lives. Local paths permitted but discouraged for shared libraries." Pi does the discouraged thing by default, and a library shared across machines or people ends up carrying absolute paths that mean nothing outside the machine that published them.
It also concentrates the collision that #123 reported. Because slug and source_repo derive from the same string, two checkouts named the same under different parents (~/work/tool and ~/scratch/tool) produce one slug and two provenances — exactly the case the #127 guard now has to refuse. Using the git remote would make the slug stable across clones and let the guard compare something meaningful.
There is a second-order effect worth noting: normalizeSourceRepo cannot fold case on absolute POSIX paths (they are case-sensitive), so path-shaped values are compared more strictly than URL-shaped ones. That is correct behavior, but it means Pi's default value is also the value the comparison can do least normalization work on.
Proposed solution
Read the git remote of ctx.cwd when there is one — origin's fetch URL, or the upstream of the current branch — and fall back to ctx.cwd when the directory is not a git repository or has no remote. Derive slug from the same resolved value so the two stay consistent.
The publish preview already prints Source: ${ctx.cwd} (:757); it should show whatever is actually going to be recorded.
Worth deciding as part of this: whether a resolved remote should also be normalized before it is stored, or stored verbatim and normalized only at comparison time. #127 does the latter, and keeping the recorded value human-readable seems right.
Alternatives considered
- Prompt for it. Accurate, but a question on every publish for something derivable in the common case.
- Keep
ctx.cwd and document it harder. Does not help a shared library, and leaves the slug unstable across clones of one repository.
- Derive slug from the remote but keep
source_repo as ctx.cwd. Fixes slug stability, but records provenance that is still machine-local, and splits the two values that today at least agree with each other.
Scope
Additional context
Follows #127, which fixes #123. Sibling: the missing override on the Pi surface. MCP is unaffected — codecarto_publish requires source_repo from the caller.
Problem
/codecarto-publishpasses the local working directory straight through as the entry's provenance:docs/library-format.md:216describes that field as "Where the analyzed code lives. Local paths permitted but discouraged for shared libraries." Pi does the discouraged thing by default, and a library shared across machines or people ends up carrying absolute paths that mean nothing outside the machine that published them.It also concentrates the collision that #123 reported. Because
slugandsource_repoderive from the same string, two checkouts named the same under different parents (~/work/tooland~/scratch/tool) produce one slug and two provenances — exactly the case the #127 guard now has to refuse. Using the git remote would make the slug stable across clones and let the guard compare something meaningful.There is a second-order effect worth noting:
normalizeSourceRepocannot fold case on absolute POSIX paths (they are case-sensitive), so path-shaped values are compared more strictly than URL-shaped ones. That is correct behavior, but it means Pi's default value is also the value the comparison can do least normalization work on.Proposed solution
Read the git remote of
ctx.cwdwhen there is one —origin's fetch URL, or the upstream of the current branch — and fall back toctx.cwdwhen the directory is not a git repository or has no remote. Deriveslugfrom the same resolved value so the two stay consistent.The publish preview already prints
Source: ${ctx.cwd}(:757); it should show whatever is actually going to be recorded.Worth deciding as part of this: whether a resolved remote should also be normalized before it is stored, or stored verbatim and normalized only at comparison time. #127 does the latter, and keeping the recorded value human-readable seems right.
Alternatives considered
ctx.cwdand document it harder. Does not help a shared library, and leaves the slug unstable across clones of one repository.source_repoasctx.cwd. Fixes slug stability, but records provenance that is still machine-local, and splits the two values that today at least agree with each other.Scope
.codecarto/)core/)Additional context
Follows #127, which fixes #123. Sibling: the missing override on the Pi surface. MCP is unaffected —
codecarto_publishrequiressource_repofrom the caller.