Skip to content

fix(catalog): stop double-prefixing praxis-* skills; teach the namespace rule - #67

Draft
anshulsao wants to merge 2 commits into
mainfrom
fix/skill-double-prefix
Draft

fix(catalog): stop double-prefixing praxis-* skills; teach the namespace rule#67
anshulsao wants to merge 2 commits into
mainfrom
fix/skill-double-prefix

Conversation

@anshulsao

@anshulsao anshulsao commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

Two related defects in how catalog skills get named on disk.


1. Double prefix

PrefixedName() unconditionally concatenated praxis- onto the catalog name. Two agent-factory seed skills are authored as praxis-dag / praxis-dag-runner, so they installed as:

~/.claude/skills/praxis-praxis-dag/
~/.claude/skills/praxis-praxis-dag-runner/

User-visible, not cosmetic: the Praxis UI generates pickup prompts saying "Use the praxis-dag skill" (ui/src/components/dag/pickupPrompt.ts, DagRunsPage.tsx) — a name that never existed on disk. Of the nine seeds in anthropic_agents/seeds/skills/, these two are the only prefixed ones.

Fix: collapse when the name already carries the prefix, in both skillcatalog and agentcatalog (identical concatenation in each). Only an exact prefix match collapses — my-praxis-dag and praxisdag are untouched.

Why safe: the existing test asserted the double-prefix deliberately, reasoning it "keeps the rule 'if it starts with praxis-, the CLI installed it' mechanical." Collapsing preserves that invariant — the folder still lives in the namespace. Also verified: no TrimPrefix anywhere reverse-maps a folder name back to a catalog name, and praxis-praxis-dag is receipt-tracked and not a meta-skill, so wipePrevProfileSkills removes it before the corrected name installs. New TestPrefixedName_AlwaysInReservedNamespace pins the invariant so it can't silently regress.

Upgrade path: no manual cleanup. Both praxis login and praxis refresh-skills run runPostAuthSetup, which wipes praxis-* and reinstalls — either heals an existing install.


2. Cross-references between skills never resolve

Catalog skills are installed as praxis-<name> but their bodies reference each other by the bare name. 17 such references across 5 installed skills, none of which resolve:

skill broken refs
praxis-build-facets-module /design-facets-module ×5, /modules-repo-workflow ×3
praxis-design-facets-module /build-facets-module ×3, /modules-repo-workflow ×1
praxis-facets-module-testing /modules-repo-workflow ×1
praxis-modules-repo-workflow /build-facets-module ×1, /facets-module-testing ×1
praxis-memory /memory ×2

Load-bearing, not incidental — praxis-build-facets-module opens with "STOP — Have you completed the /design-facets-module skill?" and praxis-design-facets-module ends with "Proceed to /build-facets-module". The design → build → test → publish handoff chain dead-ends at every hop. praxis-memory hits it too, so this reaches binary-embedded content — fixing only the server-side seeds wouldn't have covered it.

Fix: rather than rewriting every reference at render time (which would have to run over content the CLI doesn't own, and would rot as new skills add new cross-refs), state the resolution rule once in the meta-skill the host loads first: the prefix is provenance, skills name each other bare, resolve /Xpraxis-X.


Testing

  • go build ./..., go vet ./..., gofmt -l . clean
  • Full go test ./... green
  • Both new tests fail on the pre-fix code (reproduced praxis-praxis-dag, praxis-praxis-, and the missing namespace guidance) and pass after
  • Rendered the new meta-skill section and eyeballed the markdown

Not exercised against a live control plane — no end-to-end praxis login round-trip was run.

🤖 Generated with Claude Code

https://claude.ai/code/session_01LpVxm5k6cuVWnz5pKsFUdT

@coderabbitai

coderabbitai Bot commented Aug 3, 2026

Copy link
Copy Markdown

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 421a0eda-4e3c-45a6-a0c6-c61d044b39a6

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Comment @coderabbitai help to get the list of available commands.

PrefixedName() unconditionally concatenated "praxis-" onto the catalog
name. Two agent-factory seed skills are authored as "praxis-dag" and
"praxis-dag-runner", so they landed on disk as praxis-praxis-dag and
praxis-praxis-dag-runner.

That is user-visible, not just cosmetic: the Praxis UI generates pickup
prompts that say "Use the praxis-dag skill" (ui/src/components/dag/
pickupPrompt.ts), so the name it hands the user never matched the folder
the CLI installed.

Collapse when the catalog name already carries the prefix. This is safe:

  - the reserved-namespace invariant the cleanup globs rely on is only
    that an installed folder LIVES IN the praxis- namespace, which holds
    either way (asserted by a new test);
  - nothing reverse-maps a folder name back to its catalog name by
    stripping exactly one prefix (verified: no TrimPrefix on the prefix
    constants anywhere in the tree);
  - praxis-praxis-dag is receipt-tracked and is not a meta-skill, so the
    wipe-and-reinstall in runPostAuthSetup removes the stale dir before
    the corrected name is installed. Both `praxis login` and
    `praxis refresh-skills` go through that path, so either heals an
    existing install — no manual cleanup needed.

Only an exact prefix match collapses — "my-praxis-dag" and "praxisdag"
are still prefixed. Applied to agentcatalog too, which had the identical
concatenation.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LpVxm5k6cuVWnz5pKsFUdT
@anshulsao
anshulsao force-pushed the fix/skill-double-prefix branch from a4fd72c to 5094579 Compare August 4, 2026 04:51
Catalog skills are installed as praxis-<name>, but their bodies
cross-reference each other by the BARE name. 17 such references exist
across 5 installed skills, and none of them resolve:

  praxis-build-facets-module    → /design-facets-module ×5, /modules-repo-workflow ×3
  praxis-design-facets-module   → /build-facets-module ×3, /modules-repo-workflow ×1
  praxis-facets-module-testing  → /modules-repo-workflow ×1
  praxis-modules-repo-workflow  → /build-facets-module ×1, /facets-module-testing ×1
  praxis-memory                 → /memory ×2

These are load-bearing, not incidental. praxis-build-facets-module opens
with "STOP — Have you completed the /design-facets-module skill?" and
praxis-design-facets-module ends with "Proceed to /build-facets-module",
so the design → build → test → publish handoff chain dead-ends at every
hop. praxis-memory shows the same bug reaches binary-embedded content, so
fixing only the server-side seeds would not have covered it.

Rather than rewriting every reference at render time — which would have to
re-run on content the CLI does not own and would silently rot as new
skills add new cross-refs — state the resolution rule once in the
meta-skill the host loads first: the prefix is provenance, skills name
each other bare, resolve /X to praxis-X.

Guarded by TestPraxisMetaSkill_TeachesPrefixResolutionRule.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LpVxm5k6cuVWnz5pKsFUdT
@anshulsao anshulsao changed the title fix(catalog): don't double-prefix skills/agents already named praxis-* fix(catalog): stop double-prefixing praxis-* skills; teach the namespace rule Aug 4, 2026
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