Files
github--spec-kit/docs/reference
Manfred Riem fa3a5c5ce7 Clarify extension catalog trust model in docs, help, and messaging (#4177)
* Clarify extension catalog trust model in docs, help, and messaging (#4176)

Extension catalog management gave no explanation of why the community
catalog is discovery-only, and the install-error text nudged users to
flip a discovery catalog to install_allowed — exactly the wrong move.

- Docs: add a "discovery-only vs. install sources" trust-model section,
  document `add --from <url>` as the lightweight vetted-install path, and
  stop implying you should make community installable.
- Help: expand the `catalog` app and `--install-allowed` help to state the
  vetting intent instead of bare mechanics.
- Messaging: rewrite the not-installable errors in `add`, `search`, and
  `info` to point at `--from` and self-curated catalogs, and to say
  explicitly not to flip a discovery-only catalog to install_allowed.
- `catalog list` now prints trust-model guidance when a discovery-only
  catalog is active.
- Tests cover the new list guidance (present/absent).

Deliberately does not add a verb to toggle install_allowed on an existing
catalog: discovery-only is a security boundary, not an inconvenience.

Assisted-by: GitHub Copilot (model: Claude Opus 4.8, supervised)

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: a86c498e-f129-4422-9983-d1a33513fd4d

* Address PR review: copy-pasteable install hint and accurate --from warning (#4176)

- The discovery-only "install directly" hint used the user-typed argument,
  which can be a display name with spaces (resolved via search) and would
  break when copied as a shell command. Emit the resolved catalog ID
  (ext_info['id']) instead. Added a regression test.
- The `--from` untrusted-source warning claimed the URL was "not listed in
  any of your configured extension catalogs", which is false for a URL
  copied from a discovery-only catalog — the exact flow this PR documents.
  Reword it to state the install is bypassing trusted (install-allowed)
  catalogs, which is accurate regardless of discovery-catalog membership.

Assisted-by: GitHub Copilot (model: Claude Opus 4.8, supervised)

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: a86c498e-f129-4422-9983-d1a33513fd4d

* Harden install hints against catalog-controlled IDs; expose archive URL (#4176)

Second review round on #4177.

Shell-safety: catalog entry IDs (especially from discovery-only catalogs)
are not validated during catalog merge, and rich.markup.escape only
neutralizes Rich markup, not shell metacharacters. A malicious ID like
`foo; rm -rf ~` was interpolated into the `specify extension add ... --from`
command we encourage the user to copy. Add `_command_safe_id`, which only
emits an ID matching the manifest rule `^[a-z0-9-]+$` (via
VALID_EXTENSION_ARTIFACT_NAME_PATTERN) and otherwise falls back to a literal
`<extension-id>` placeholder. Applied to every suggested command in `add`,
`search`, and `info`.

Discoverability: the documented `--from <archive-url>` flow gave no CLI path
to obtain the URL. `extension info` now prints the candidate `download_url`
for a discovery-only entry (clearly flagged as needing vetting), and the docs
show `extension info <name>` as the way to get the archive URL.

Tests cover the resolved-ID hint, the unsafe-ID neutralization, and pass the
full extensions + CLI suites (635).

Assisted-by: GitHub Copilot (model: Claude Opus 4.8, supervised)

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: a86c498e-f129-4422-9983-d1a33513fd4d

* Reject leading-hyphen catalog IDs; test info archive-URL branch (#4176)

Third review round on #4177.

_command_safe_id: an ID like `--force` satisfies the manifest character rule
`^[a-z0-9-]+$` but Typer parses a leading hyphen as an option rather than the
positional extension argument, so an untrusted catalog could still yield a
non-copyable or option-altering suggested command. Reject a leading hyphen and
fall back to the `<extension-id>` placeholder.

Tests: cover the new `extension info` discovery-only branch that surfaces the
candidate `download_url` (plus the no-URL fallback), and the leading-hyphen
rejection. Full extensions suite green (528).

Assisted-by: GitHub Copilot (model: Claude Opus 4.8, supervised)

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: a86c498e-f129-4422-9983-d1a33513fd4d

---------

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: a86c498e-f129-4422-9983-d1a33513fd4d
2026-08-17 15:48:59 -05:00
..