Skip to content

aitools: parse experimental_skills manifest section#5243

Open
jamesbroadhead wants to merge 6 commits into
mainfrom
aitools-experimental-skills
Open

aitools: parse experimental_skills manifest section#5243
jamesbroadhead wants to merge 6 commits into
mainfrom
aitools-experimental-skills

Conversation

@jamesbroadhead
Copy link
Copy Markdown

@jamesbroadhead jamesbroadhead commented May 12, 2026

Summary

The skills manifest in databricks/databricks-agent-skills is gaining a new top-level experimental_skills map alongside the existing skills map (see paired d-a-s PR #73, which imports the ai-dev-kit skill catalog into experimental/).

This wires the parsing through the aitools installer:

  • Manifest.ExperimentalSkills is flattened into Manifest.Skills during FetchManifest, with Experimental=true and RepoDir set so the rest of the installer treats them uniformly.
  • fetchSkillFile now takes the repo subdirectory (skills/ vs experimental/) per skill, so experimental skills are downloaded from their actual location upstream.
  • The existing --experimental flag (already wired in cmd/skills.go) now has experimental skills to install; without it, resolveSkills filters them out as before.
  • Name collisions between stable and experimental are resolved by renaming the experimental copy with a -experimental suffix (stable wins).

UX

# default — only stable skills
databricks experimental aitools skills install

# all experimental skills, plus stable
databricks experimental aitools skills install --experimental

# one experimental skill by name (--experimental still required by resolveSkills)
databricks experimental aitools skills install databricks-iceberg --experimental

TODOs / caveats for iteration

  1. DATABRICKS_SKILLS_REF pin. Partially resolved. The default ref is still the latest stable release tag (sourced from experimental/aitools/lib/installer/SKILLS_VERSION); the experimental manifest section won't exist there until d-a-s cuts a release with PR #73 merged. The default ref bump is a follow-up automated by the SKILLS_VERSION file. UX fix shipped in this PR: if --experimental is passed but the manifest at the resolved ref has no experimental skills, a warning is logged pointing users at DATABRICKS_SKILLS_REF=main.

  2. Collision handling is naive. Resolved. Every experimental skill now gets a -experimental suffix unconditionally (not just on collision). The manifest key + install dir both carry the suffix; new SourceName field on SkillMeta preserves the upstream repo dir name for fetch URLs. Users see at a glance which installed skills are experimental.

    Also handled in the same commit: experimental↔stable transitions. If a skill flips its experimental status upstream (the same logical skill changes manifest key), install removes the stale variant on disk + state before installing the new one, and uninstall accepts either variant name (and removes both if both are present). Helper: alternateVariantKey(). Covered by new tests TestInstallReplacesAlternateVariant, TestUninstallByEitherVariantRemovesBoth, TestUninstallByAlternateNameWhenOnlyOneVariantInstalled.

  3. list UX. Resolved. aitools skills list already shows experimental skills with an [experimental] tag in the NAME column. Combined with the TODO Bump gopkg.in/ini.v1 from 1.66.4 to 1.66.5 #2 resolution (-experimental suffix in the manifest key), every experimental row reads e.g. databricks-iceberg-experimental [experimental] — slightly redundant but a clear visual anchor. Hide-by-default was considered but rejected: users running list are usually looking for what's available, and silently omitting experimental skills makes them un-discoverable.

  4. State tracking. Resolved — kept additive semantics. InstallState.IncludeExperimental records what was last requested but is not used to drive retroactive removal. Running install without --experimental leaves previously-installed experimental skills in place. Rationale: (a) users running install are typically adding/updating, not declaring set membership; (b) silently uninstalling things the user previously asked for is surprising; (c) the transition cleanup shipped under TODO Bump gopkg.in/ini.v1 from 1.66.4 to 1.66.5 #2 handles the actual drift case (skill's experimental status flipping upstream). Removal is what uninstall is for.

  5. No acceptance test yet. Resolved. Added an acceptance test at acceptance/experimental/aitools/skills/install/ covering the install flow against a mocked manifest server:

    • Stable-only install (no flag) → 1 skill installed
    • --experimental install adds the experimental skill (with -experimental suffix per the install-path model) → 2 skills total
    • Re-running --experimental is idempotent

    To make the test reachable, exposed a new env-var override DATABRICKS_SKILLS_BASE_URL that overrides the hard-coded raw.githubusercontent.com base URL used by GitHubManifestSource.FetchManifest and fetchSkillFile. Defaults to the canonical URL when unset, so no production behavior change. Updated Taskfile.yml's test-exp-aitools task to include acceptance/experimental/aitools/**.

    Variants left as follow-up acceptance tests (the structure is now in place):

    • Variant transition cleanup (stable → experimental, experimental → stable)
    • Uninstall flow (with both variants installed)
    • Specific-skill install (install <name> --experimental)
    • Error cases (skill not found, --experimental with empty manifest)
  6. --experimental flag scope. Resolved — kept current scope. Each command has internally consistent behavior:

    • install --experimental → explicit opt-in (required to install experimental skills).
    • update → state-driven (honors InstallState.IncludeExperimental from the last install). If you opted in once, future updates refresh experimentals; otherwise they're skipped (see update.go line 125).
    • list → shows all skills with an [experimental] tag (no filtering — discovery first, opt-in to install).

    Adding --experimental / --no-experimental to update for one-off overrides was considered but rejected: the natural workflow is to re-run install --experimental (or just install), which already sets the desired state. Follow-up if real users hit a use case for the override.

Test plan

  • `go build ./...` passes.
  • `go test ./experimental/aitools/...` passes (added `source_test.go` covering flatten/collision/empty cases).
  • Run `./task lint` and `./task fmt` before merge.
  • Manual: against a d-a-s ref containing experimental_skills, verify the four UX cases above behave correctly.

This pull request and its description were written by Claude.

The skills manifest in databricks/databricks-agent-skills now exposes a
new top-level experimental_skills map alongside the existing skills map
(see databricks-agent-skills PR for the imported ai-dev-kit content).

This wires the parsing through:
- Manifest.ExperimentalSkills is flattened into Manifest.Skills during
  FetchManifest, with Experimental=true and RepoDir set so the rest of
  the installer can stay uniform.
- fetchSkillFile takes the repo subdirectory (skills/ vs experimental/)
  per skill, so experimental skills are downloaded from their actual
  location in the upstream repo.
- The existing --experimental flag (already wired in cmd/skills.go) now
  has experimental skills to install; without it, resolveSkills filters
  them out as before.
- Name collisions between stable and experimental are resolved by
  renaming the experimental copy with a -experimental suffix (stable
  wins).

Co-authored-by: Isaac
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 12, 2026

Approval status: pending

/experimental/aitools/ - needs approval

8 files changed
Suggested: @arsenyinfo
Also eligible: @pkosiec, @fjakobs, @Shridhad, @atilafassina, @keugenek, @igrekun, @MarioCadenas, @pffigueiredo, @ditadi, @calvarjorge, @lennartkats-db

General files (require maintainer)

13 files changed
Based on git history:

  • @simonfaltum -- recent work in experimental/aitools/lib/installer/

Any maintainer (@andrewnester, @anton-107, @denik, @pietern, @shreyas-goenka, @simonfaltum, @renaudhartert-db) can approve all areas.
See OWNERS for ownership rules.

Previously, only experimental skills that collided with a stable skill
of the same name got the -experimental suffix on the manifest key (and
therefore the install dir). The non-colliding ones installed under
their unmarked upstream name, making it hard to tell at a glance which
skills in ~/.claude/skills/ are stable vs experimental.

Now every experimental skill gets the suffix unconditionally. The
manifest key carries the suffix; SourceName (new SkillMeta field)
preserves the upstream repo directory name so fetch URLs still work.

So:
  ~/.claude/skills/databricks-iceberg-experimental/  ← was databricks-iceberg
  ~/.claude/skills/databricks-jobs-experimental/     ← unchanged (was already a collision)

flattenManifest, installSkillToDir, and the mock used by tests are
updated. New source_test.go cases cover non-colliding, colliding, and
empty-stable-skills variants.

Co-authored-by: Isaac
jamesbroadhead added a commit to databricks/databricks-agent-skills that referenced this pull request May 12, 2026
- experimental/README.md: install examples now use the -experimental
  suffix on the skill name + the --experimental flag (matching the
  install-path behaviour landed in databricks/cli#5243). Adds a short
  note explaining why the in-repo dir name and the install dir name
  differ.
- experimental/README.md: drop databricks-model-serving from the
  collision example (it was removed from this PR earlier).
- experimental/README.md: update the (also available as stable skill)
  note for databricks-jobs to point at the open TODO #1a.
- Root README: clarify the suffixed install name in the by-name install
  example.

Co-authored-by: Isaac
When a skill flips its experimental status upstream, the manifest key
changes (gains or loses the -experimental suffix). Without explicit
handling, install would leave the stale variant on disk and in state,
and uninstall would fail to find a skill that the user typed under
its other variant name.

- Install: before installing a skill, check if the alternate variant
  is in state and remove it (delete install dir, agent symlinks, and
  state entry). Logs "Replaced previous variant X with Y".
- Uninstall: accept either variant when the user uninstalls by name;
  if both are installed, remove both (the "old version" of the same
  logical skill is stale by definition).

New `alternateVariantKey()` helper centralizes the suffix toggle.
Tests cover: install replacing stale variant, uninstall by either
variant when one is installed, uninstall removing both when both are
installed.

Co-authored-by: Isaac
The default DATABRICKS_SKILLS_REF pin is a release tag that pre-dates
the experimental_skills manifest section (see
databricks/databricks-agent-skills#73). Users who pass --experimental
against that ref today silently get no experimental skills installed.

Log a Warnf at install time pointing them at the env var override
(=main, or a future release that includes the section).

Helper: manifestHasExperimental(), unit-tested in source_test.go.

Co-authored-by: Isaac
Adds an acceptance test under acceptance/experimental/aitools/skills/
that covers the install flow against a mocked manifest server.

To make the test reachable, exposes DATABRICKS_SKILLS_BASE_URL as an
env-var override on top of the hard-coded raw.githubusercontent.com
URL used by GitHubManifestSource.FetchManifest and fetchSkillFile.
Defaults to the canonical URL when unset, so no behaviour change in
production.

The test covers:
- Stable-only install (no --experimental) → 1 skill installed.
- --experimental adds the experimental skill (with -experimental
  suffix per the install-path model) → 2 skills total.
- Re-running --experimental is idempotent.

Taskfile's test-exp-aitools run now picks up tests under
acceptance/experimental/aitools/** in addition to acceptance/apps/**.

Co-authored-by: Isaac
Three additional acceptance tests under acceptance/experimental/aitools/skills/:

- install-specific: --skills flag picks one stable skill; --skills with
  -experimental suffix + --experimental flag installs the experimental
  variant; asking for an experimental skill without --experimental fails
  with the expected error.
- install-experimental-empty: when --experimental is set but the manifest
  exposes no experimental skills, a warning points at
  DATABRICKS_SKILLS_REF=main. Exercises the manifestHasExperimental nudge
  introduced in an earlier commit.

(uninstall-both-variants was prototyped but was flaky under the framework's
parallel-test env handling; that path is already covered by the unit tests
TestUninstallByEitherVariantRemovesBoth and
TestUninstallByAlternateNameWhenOnlyOneVariantInstalled.)

Co-authored-by: Isaac
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