From bb5ab14efaea43127483bb541d2595307ebc5a34 Mon Sep 17 00:00:00 2001 From: rongo Date: Tue, 15 Sep 2026 12:40:26 +0300 Subject: [PATCH 1/2] Enforce unconditional governance filtering and install disambiguation for AI Catalog skills Match the Cursor plugin's jfrog-ai-catalog behavior: always pass --allowed-only on --list-skills/--list-skill-versions with no bypass path, refuse requests to see blocked/disallowed results, and never default to latest or the first repo when installing. Resolve version then repo from a single --list-skill-versions call, using the native picker UI when available. Co-Authored-By: Claude Sonnet 5 --- plugin/skills/jfrog-ai-catalog/SKILL.md | 10 ++- .../references/discovering-skills.md | 34 +++++++-- .../references/installing-skills.md | 73 +++++++++++++++---- 3 files changed, 94 insertions(+), 23 deletions(-) diff --git a/plugin/skills/jfrog-ai-catalog/SKILL.md b/plugin/skills/jfrog-ai-catalog/SKILL.md index fc94f85..57acc3f 100644 --- a/plugin/skills/jfrog-ai-catalog/SKILL.md +++ b/plugin/skills/jfrog-ai-catalog/SKILL.md @@ -26,7 +26,7 @@ Pick the row matching the user's intent and read that reference file. | Intent | Read | |--------|------| | "What skills are available?" / browse the catalog / list versions / search by name | [references/discovering-skills.md](references/discovering-skills.md) | -| Install or update a skill (latest or a pinned version), or a download is blocked | [references/installing-skills.md](references/installing-skills.md) | +| Install a skill with an explicitly resolved version and repo, update a skill, or handle a blocked download | [references/installing-skills.md](references/installing-skills.md) | | "What's installed?" / remove an installed skill | [references/managing-installed-skills.md](references/managing-installed-skills.md) | | Publish / upload / release a skill to the catalog | [references/publishing-skills.md](references/publishing-skills.md) | | "What plugins are available?" / browse the plugin catalog / list plugin versions / search plugins | [references/discovering-plugins.md](references/discovering-plugins.md) | @@ -97,7 +97,7 @@ flowchart TD B -->|No| C[Ask user to install jf CLI, then continue] B -->|Yes| D{Intent} C --> D - D -->|List all skills / versions| E[npx @jfrog/agent-guard --list-skills] + D -->|List all skills / versions| E[npx @jfrog/agent-guard --list-skills --allowed-only] D -->|Install / update skill| F[Resolve slug + version, then jf skills install/update] D -->|List installed skills / remove| G[jf skills list / rm -rf install dir] D -->|Publish skill| H[Resolve/provision repo, validate bundle, jf skills publish] @@ -121,7 +121,11 @@ the reference files above. the next agent session start, so tell the user to restart. - **Don't leak the plumbing**: present skills/versions/repos to the user, never the `npx`/Agent Guard commands, `--registry`, flags, or cursors. Run follow-ups - yourself. + yourself. Discuss catalog filtering only when the user asks about missing or + blocked results; follow the refusal in `discovering-skills.md`. +- **Skill discovery is always policy-scoped**: every skill and skill-version + listing must follow `discovering-skills.md`. Never weaken that listing path, + including for audit, blocked-content, or named-repository requests. - **Use the response templates verbatim**: where a reference file gives a "reply using this exact template" block, fill the placeholders and send exactly that, with the same wording every time and no extra preamble or commentary. diff --git a/plugin/skills/jfrog-ai-catalog/references/discovering-skills.md b/plugin/skills/jfrog-ai-catalog/references/discovering-skills.md index 60d2f82..25e8186 100644 --- a/plugin/skills/jfrog-ai-catalog/references/discovering-skills.md +++ b/plugin/skills/jfrog-ai-catalog/references/discovering-skills.md @@ -1,22 +1,24 @@ # Discovering skills -List-all and versions go through the **Agent Guard**. +List-all and versions go through the **Agent Guard** and are always limited to +skills allowed by the project's governance policy. This has no exceptions. ## List skills (page through the catalog) ```bash npx --yes --registry @jfrog/agent-guard \ - --list-skills --project "" [--name ] [--server ""] [--page-size ] [--cursor ] [--format json] + --list-skills --project "" --allowed-only [--name ] [--server ""] [--page-size ] [--cursor ] --format json ``` | Flag | Required | Purpose | |------|----------|---------| | `--project ` | **Yes** | AI Catalog project to list. | +| `--allowed-only` | **Yes** | Limit results to skills allowed by project policy. Never omit it. | | `--name ` | No | Find skills by name: server-side, case-insensitive substring, scoped to the project. | | `--server ` | No | jf CLI config entry to authenticate with (defaults to the resolved single server). | | `--page-size ` | No | Results per page. Pass `50` to stay bounded. The Agent Guard defaults to 500 if omitted. | | `--cursor ` | No | Continuation cursor from a previous page's JSON, to fetch the next page. | -| `--format json` | No | Raw page JSON instead of the default compact TSV (name + last-updated). | +| `--format json` | **Yes** | Raw page JSON used to render the result. | Request a bounded page with `--page-size 50 --format json`, present those skills, then read `exhausted` and `cursor` from the response. If `exhausted` is `false` @@ -37,6 +39,20 @@ For a `--name` search with no matches, reply with one line instead: To offer a follow-up (a skill's versions or repos), ask in plain language ("want the versions for one of these?") and run the command yourself. +## Requests for blocked or missing results + +Never omit `--allowed-only`, even when the user asks to see everything, blocked +skills, disallowed skills, or the contents of a repo absent from the results. +Never run another command to infer or expose what filtering removed. + +Only when the user asks about blocked or missing results, reply: + +> The listing is always governance-filtered. For access to a missing or blocked +> skill or repository, contact your project's governance policy owner. + +Otherwise, present the results simply as the list. Do not mention filtering, the +flag, or its mechanism. + ## List a repo's skills To see what is published in one specific skills repository (for example, to check @@ -50,6 +66,9 @@ jf skills list --repo "" --server-id "" --format json Never run a bare `jf skills list` (it errors): always pass `--repo ` here, or `--harness ` for installed skills (see `managing-installed-skills.md`). +Use this repo-scoped command only for a repo already returned by an allowed +catalog response or explicitly resolved/provisioned during publishing. Never use +it to inspect a missing repo or work around the governed catalog listing. **Presenting results (use this exact format).** Render the skills as this table, sorted by name, and nothing else (no commands, URLs, or flags): @@ -70,10 +89,12 @@ line instead: ```bash npx --yes --registry @jfrog/agent-guard \ - --list-skill-versions --project "" --skill "" [--server ""] [--page-size ] [--cursor ] [--format json] -# JSON: versions[].version, versions[].locations[].repoKey (page through with cursor like above) + --list-skill-versions --project "" --skill "" --allowed-only [--server ""] --format json +# JSON: versions[].version, versions[].locations[].repoKey ``` +Treat this one response as complete. Do not page or repeat the call. + **Presenting versions (use this exact format).** Newest version first: Versions of ``: @@ -81,3 +102,6 @@ Versions of ``: | Version | Hosted in | |---------|-----------| | `` | ``[, ``…] | + +Every returned location is already allowed by project policy. Do not annotate +repositories with "(allowed)" or similar labels. diff --git a/plugin/skills/jfrog-ai-catalog/references/installing-skills.md b/plugin/skills/jfrog-ai-catalog/references/installing-skills.md index 8c105ec..8ff9554 100644 --- a/plugin/skills/jfrog-ai-catalog/references/installing-skills.md +++ b/plugin/skills/jfrog-ai-catalog/references/installing-skills.md @@ -6,13 +6,15 @@ verify-landed check. ## Contents +- Choice UI - When evidence verification fails - Handling a blocked download (403 / Xray-gated) - Verify the install landed - Update an installed skill -Install by **slug** (the registry `slug`/`name`, never a display name). Latest -version is used by default, and the user may pass an explicit version. +Install by **slug** (the registry `slug`/`name`, never a display name). Always +resolve and pass a concrete version and repository. Never install with +`--version "latest"` and never choose the first repository as a default. **The `jf skills install` command takes no project.** Resolving which repo hosts the slug uses `--list-skill-versions` (below), which does require `--project`, so use `` resolved at session start (see SKILL.md Prerequisites). @@ -20,7 +22,7 @@ use `` resolved at session start (see SKILL.md Prerequisites). ```bash jf skills install "" \ --server-id "" \ - --version "latest" \ + --version "" \ --repo "" \ --harness "" \ --quiet @@ -69,15 +71,15 @@ Choose exactly one install target (these are mutually exclusive): | `--project-dir ` | Project root combined with the agent's project path. | | `--path ` | Direct: files go under `/`. | -**Always resolve and pass `--repo`.** When the platform has more than one skills -repository (the common case), `jf skills install` errors with `multiple skills -repositories found … specify --repo` if you omit it, even when the skill lives -in only one repo. So **the first install step is always** to look up where the -slug is hosted with the Agent Guard: +**Always resolve and pass a concrete `--version` and `--repo`.** When the platform +has more than one skills repository (the common case), `jf skills install` +errors with `multiple skills repositories found … specify --repo` if you omit +it, even when the skill lives in only one repo. Resolve both values from exactly +one Agent Guard call: ```bash npx --yes --registry @jfrog/agent-guard \ - --list-skill-versions --project "" --skill "" [--server ""] --format json + --list-skill-versions --project "" --skill "" --allowed-only [--server ""] --format json # read versions[].version and versions[].locations[].repoKey ``` @@ -85,12 +87,53 @@ npx --yes --registry @jfrog/agent-guard \ listing (`--list-skills`, even with `--name`) returns just names, not repos or versions, so use the versions call above to pick the repo, never a name listing. -- **One repo hosts the slug.** Use it as `--repo ` directly. Don't ask. -- **Multiple repos host the slug.** Do not pick silently. Naming a project is not - a repo choice, so ask even when one repo is project-scoped. List the repos (and - the version each holds), ask the user which to install from, then pass - `--repo `. The newest version may only exist in one of them, so - surface that to avoid giving the user a stale version. +Resolve choices in this order: + +1. **Version first.** + - If the user named a version, verify that exact value exists in + `versions[].version`. If absent, stop and offer the returned versions with + the picker described below. Do not make another catalog call. + - If the user did not name a version and exactly one version exists, use that + concrete version without asking. + - If the user did not name a version and more than one exists, ask which + version to install. Present versions newest first. Never assume the newest, + `"latest"`, or the first response entry. + - If no versions exist, report that the skill is unavailable for the project + and stop. + +2. **Repository second.** After settling the version, use only that version + object's `locations[]`; discard locations attached to every other version. + Do not make another catalog call. + - If the user named a repo, verify it is among the selected version's + locations. If absent, say that repo is not governance-allowed for the + project and stop. Never retry without the policy filter or inspect the repo + directly. + - If exactly one repo hosts the selected version, use its `repoKey` without + asking. + - If more than one repo hosts the selected version, ask which repo to use. + Never pick the first or the most recently updated-looking repo: equal + slug+version values in different repos can contain different skills. + - If the selected version has no returned locations, report it unavailable + for the project and stop. + +## Choice UI + +Use the agent surface's native interactive single-choice picker (an arrow-key +selectable menu, such as VS Code's Quick Pick UI) whenever a version or repo +choice is required. Do not print a table and wait for a typed reply when a +picker is available. + +- Version picker: label each option with only the version string, newest first. + Do not include repo keys before the version is settled. +- Repo picker: label each option with only its `repoKey`. Put + `@` in that option's description or subtitle, not its label. +- Do not append "(allowed)" to repo labels. Every returned location is already + allowed. +- Only when no interactive picker exists in the current context, fall back to a + Markdown table followed by a plain-language question. Use one **Version** + column (newest first) for versions or one **Repository** column (`repoKey` + only) for repos, and name `@` in the repo question. Never add + an "(allowed)" annotation. ## When evidence verification fails From 32729964e61f51c72562f986ed22c44a3f41eb13 Mon Sep 17 00:00:00 2001 From: rongo Date: Thu, 17 Sep 2026 10:43:48 +0300 Subject: [PATCH 2/2] Correct Choice UI: Copilot Chat has no native picker, always use table fallback how-to-ask-user.md's harness table never listed VS Code/Copilot Chat as having a native single-choice prompt tool -- skills here are chat-turn instructions with no access to VS Code's showQuickPick API. Remove the unverified 'VS Code's Quick Pick UI' claim. Co-Authored-By: Claude Sonnet 5 --- .../references/installing-skills.md | 20 +++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/plugin/skills/jfrog-ai-catalog/references/installing-skills.md b/plugin/skills/jfrog-ai-catalog/references/installing-skills.md index 8ff9554..bb4b43a 100644 --- a/plugin/skills/jfrog-ai-catalog/references/installing-skills.md +++ b/plugin/skills/jfrog-ai-catalog/references/installing-skills.md @@ -119,9 +119,14 @@ Resolve choices in this order: ## Choice UI Use the agent surface's native interactive single-choice picker (an arrow-key -selectable menu, such as VS Code's Quick Pick UI) whenever a version or repo -choice is required. Do not print a table and wait for a typed reply when a -picker is available. +selectable menu) whenever a version or repo choice is required and such a +picker is available to the skill. Do not print a table and wait for a typed +reply when a picker is available. + +**GitHub Copilot Chat (this harness) has no such picker.** Skills here run as +chat-turn instructions with no programmatic access to VS Code's native +`showQuickPick` UI, so always use the Markdown table fallback below for +version and repo choices — never claim or imply an arrow-key picker exists. - Version picker: label each option with only the version string, newest first. Do not include repo keys before the version is settled. @@ -129,11 +134,10 @@ picker is available. `@` in that option's description or subtitle, not its label. - Do not append "(allowed)" to repo labels. Every returned location is already allowed. -- Only when no interactive picker exists in the current context, fall back to a - Markdown table followed by a plain-language question. Use one **Version** - column (newest first) for versions or one **Repository** column (`repoKey` - only) for repos, and name `@` in the repo question. Never add - an "(allowed)" annotation. +- Fall back to a Markdown table followed by a plain-language question. Use one + **Version** column (newest first) for versions or one **Repository** column + (`repoKey` only) for repos, and name `@` in the repo + question. Never add an "(allowed)" annotation. ## When evidence verification fails