Skip to content

Self-referential skill invocations do not render per harness #907

Description

@williamthorsen

Problem

A skill or subagent that names its own invocation in prose — e.g. capture-feedback's "Invoke /capture-feedback whenever the user gives feedback" — is written as a literal /slug. That renders correctly only on Claude, whose skill sigil is /; on a harness with a different sigil (Rovo's !) it stays /slug, which is wrong. These references can't adopt the {skill:} invocation token today because a self-targeting token makes the resolver treat the artifact as its own dependency and trips the cycle check.

The same literal-/slug spelling was also used for references naming a different skill. Those need reclassifying, not the same fix.

Context

#879 tokenized genuine cross-artifact invocations and left every literal-/slug reference alone, because a self-token forms a resolver cycle. The refined treatment splits the untokenized references three ways: a self-reference renders but must not depend on itself; a reference naming a runnable command in another artifact should ship that command (a genuine edge, not a render-only reference); and a reference pointing backward up an existing dependency — a depended-upon skill naming its depender — is not a dependency at all and would cycle if tokenized.

Proposed solution

Let an artifact render its own invocation per harness without contributing a dependency edge: the resolver drops a direct self-edge arising from a body invocation token, instead of throwing the cycle error. Genuine transitive cycles (A→B→A) and frontmatter-declared self-dependencies still error — only the direct body-token self-edge is dropped. (Drop the self-edge; do not add a separate render-only token.)

Apply the correct treatment to every literal-/slug reference across the library:

  • Self-reference{skill:self} / {subagent:self} body token: renders per harness, self-edge dropped, no dependency.
  • Non-invoking cross-reference{skill:other} token: a genuine dependency edge, so the named command ships with the referring artifact.
  • Backward reference — a depended-upon skill naming its depender (capture-event → capture-feedback, create-devlog → wrap-up) → reword to plain prose; not a dependency, must not render as a command.

Acceptance criteria

Must have

  • A body invocation token targeting its own artifact renders per harness and contributes no dependency edge.
  • A genuine dependency cycle (A→B→A) and a frontmatter-declared self-dependency still raise the cycle error.
  • Every literal-/slug self-reference in the library is converted to a self-token and renders per harness.
  • Every literal-/slug cross-reference either becomes a dependency edge or, where it points backward, is reworded to non-command prose.
  • New and modified behavior is covered by tests.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions