Daily harness signal

Inventory is not visibility

August 17, 2026 · JST One fresh finding Skills · routing · installation
A model-visible skill list is a routing surface, not an installation inventory. Treat hidden manual skills as installed-but-unadvertised, or setup workflows can silently omit required configuration.
01 · Fresh · source date 2026-08-07

Separate installed inventory from the routing catalog

Use when: a setup, router, migration, or dependency check asks whether another skill or command is installed. Claude Code removes skills with disable-model-invocation: true from model context; the Matt Pocock plugin nevertheless declares triage in plugin.json. Current setup logic checks a sibling folder or “available skills,” so plugin installs can return a false negative and skip triage-labels.md.

Action: split discovery into three explicit snapshots: installed_inventory from the attested package manifest and resolved install root; model_catalog for names the model may invoke; and user_catalog for manual commands. Give every entry a stable package-plus-component ID and invocation mode. Installation checks must query installed_inventory, never model_catalog. In the affected plugin, treat triage as installed whenever the active manifest contains ./skills/engineering/triage; for selective standalone installs, resolve the exact skill directory. Emit inventory_source, component_id, present, model_visible, and reason in the setup trace. Fail closed with a warning if inventory cannot be read; do not silently skip dependent configuration.

Acceptance check: create two fixtures. A bundled fixture lists triage in plugin.json and sets disable-model-invocation: true; a standalone fixture omits it. Run setup in fresh repositories. Pass only if the bundled run writes docs/agents/triage-labels.md and ### Triage labels while the trace says present=true, model_visible=false; the standalone run must omit both and say present=false. Add a mutation control that removes the manifest entry but leaves a stale cached folder; the result must remain absent.

Evidence: official Claude docs say disable-model-invocation removes a skill from context while user invocation remains. The current manifest includes triage; the current skill has that flag; and setup source still uses the visible-list test. Issue #812 observed the exact omission in four repositories, while #740 reports the same false inference in a router.

Caveat: these are open field reports, without a maintainer-confirmed fix or controlled independent replay. A manifest is authoritative only for its attested package and version. Other harnesses expose different catalogs, so copy the three-plane invariant, not Claude-specific paths. A clean fixture that preserves the labels despite the hidden skill would falsify the failure claim.

Compact source notes

  1. mattpocock/skills issue #812 (created 2026-08-07; updated 2026-08-08). Open, versioned v1.2.2 reproduction with outputs from four repositories and an explicit plugin-versus-standalone contrast.
  2. Current setup skill, triage skill, and plugin manifest (retrieved 2026-08-17). Inspectable upstream artifacts show the predicate, hidden flag, and declared package membership still coexist.
  3. Claude Code skills reference (retrieved 2026-08-17). Official semantics: disable-model-invocation: true removes the description from model context but preserves manual invocation.
  4. mattpocock/skills issue #740 (2026-08-04). Independent workflow symptom from the same repository: a router interpreted five hidden manual skills as uninstalled.
  5. Method: anchor lens—current source, official visibility semantics, and observable fixture outputs; unity lens—installed inventory, model routing, and manual invocation are separate capability planes joined by stable identity. Confidence: Likely.