Skip to content

feat(spec,tck): support bundled agent skills in mixins - #80

Merged
cdupuis merged 8 commits into
mainfrom
feat/bundled-agent-skills
Sep 29, 2026
Merged

cdupuis merged 8 commits into
mainfrom
feat/bundled-agent-skills

Conversation

@cdupuis

@cdupuis cdupuis commented Sep 29, 2026 •

Copy link
Copy Markdown
Collaborator

Add native discovery for skills supplied by Kit image layers. A skill mixin declares com.docker.sandbox/agent-skill@1 with an in-image config.path; its basename becomes the skill-store directory name unless config.name overrides it. Agent workloads and mixins declare discovery destinations with com.docker.sandbox/agent-skills-directory@1. Every selected destination receives every selected bundled skill before workload launch. Filesystem assembly remains the runtime's responsibility.

Closes #79.

The new types include Go config readers, strict validation, JSON Schemas, composition rules, artifact checks, and runtime conformance fixtures with fake-adapter mutations. Identical source/name requests collapse, different sources claiming the same effective name fail composition, and existing image or host-store entries cannot be overwritten. Required skills without a destination fail; optional ones are skipped and recorded. Source paths must be literal after publication so the artifact can be checked, while discovery names may use create-time arguments. Registration preserves supporting files and executable permissions and does not execute bundled scripts.

The review-skill example demonstrates a name override and relative reference file. Existing agent examples declare optional discovery directories, and the repository's authoring/migration skills request native registration optionally while retaining their context fallback. Authoring and migration guidance explain the new contracts.

This is additive under RELEASES.md: it introduces new capability types, changes no existing fields or capability versions, and leaves agent-skills@1 host-sharing semantics and schemaVersion: "3" intact. An older runtime refuses a required new capability and skips an optional one under the existing extension rules. Runtimes must implement the new contracts to provide native discovery; this repository supplies the specification, library, publishing validation, and conformance suite.

The Go skill reader exposes the entry label as DisplayName, keeping the embedded skill config's Name unshadowed. The YAML example shows both names and the basename fallback. The existing SPEC-v3 §7/name-display-only statement now explicitly says capability-entry names; its contract and existing coverage are unchanged. Reader tests check that labels do not supply a missing skill-name override.

Normative accounting (all new anchors are covered; no new waivers):

  • agent-skill@1/name-valid and agent-skill@1/source-literal: descriptor-valid artifact check through Go validation, with schema, expansion, and group tests.
  • agent-skill@1/content-present: agent-skill-content artifact check, including optional groups and missing/non-file content.
  • agent-skill@1/exposed: runtime probes for basename naming, explicit override, multiple destinations, content, relative references, and executable permissions; mutations remove, rename, truncate, or corrupt those results, including trailing-newline-only changes to both skill files and supporting content.
  • agent-skill@1/before-launch: workload-entrypoint snapshot and a late-exposure mutation.
  • agent-skill@1/no-execution: script side-effect marker and an execution mutation.
  • agent-skill@1/unavailable: required refusal, optional skip records, and mutations accepting, refusing, or dropping records incorrectly.
  • agent-skill@1/existing-conflict: image-content collision check plus agent-skill@1/host-conflict, each with an overwrite mutation.
  • agent-skills-directory@1/destination: bundled and host-shared skills coexist at both discovery paths; a mutation drops the second destination. Host-sharing-off exposure is covered separately by agent-skill@1/exposed.

Validation: task validate, task lint, task test, task test:e2e, and task kit:dev KIT=review-skill / task kit:dev KIT=skills. Runtime behavior is verified against the fake adapter; the Docker Sandboxes runtime suite was not run. Validation at 4a77b65: task validate, task lint, task test:unit, and task test:tck all passed. Mutation tests run their asserted checks through the same runner setup, claim gating, and cleanup, while the conforming baseline still runs every check. This removes repeated unrelated checks that caused the CI ten-minute timeout; the local sandbox suite completed in 29 seconds with all mutation assertions retained. The unclaimed-skill refusal probe now supplies a discovery destination and explicitly skips that branch when destination support is not claimed; a regression verifies the skill-specific refusal independently of other types.

Release note

Kits can declare bundled agent skills with an optional discovery-name override and expose them through agent-declared skill directories.

Declare bundled skill sources separately from agent discovery directories so skills can compose across agents without requesting host-store access. Default discovery names to source basenames and allow an explicit override, while keeping content validation and collision outcomes testable across publishers and runtimes.

Signed-off-by: Christian Dupuis <cd@docker.com>
@cdupuis
cdupuis requested a review from a team as a code owner September 29, 2026 16:22
Copilot AI balanced review requested due to automatic review settings September 29, 2026 16:22
Reconcile the fixture inventory and mutation maps with environment expansion. Keep bundled source paths literal at publication while allowing final-container environment values to choose discovery names and directories.

Signed-off-by: Christian Dupuis <cd@docker.com>

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟡 Changes recommended

The fake adapter modifies the host skill store, and its exposure probe does not verify the complete bundled directory.

Review effort: Balanced
Findings: 1 Medium severity

Open (1)
What changed in this PR

Adds native bundled agent-skill discovery across the specification, implementation, examples, and conformance suites.

Changes:

  • Defines and validates bundled-skill source and destination capabilities.
  • Adds artifact/runtime conformance checks and mutation fixtures.
  • Updates agent examples and authoring guidance.
File Description
tck/​sandbox/​testdata/​fixtures/​bundled-skill/​review.skill Adds primary skill fixture.
tck/​sandbox/​testdata/​fixtures/​bundled-skill/​renamed.skill Adds renamed skill fixture.
tck/​sandbox/​testdata/​fixtures/​bundled-skill/​register.sh Adds execution sentinel.
tck/​sandbox/​testdata/​fixtures/​bundled-skill/​reference.txt Adds supporting content.
tck/​sandbox/​testdata/​fixtures/​bundled-skill/​read.sh Adds relative-reference probe.
tck/​sandbox/​testdata/​fixtures/​bundled-skill/​bundled-skill.yaml Declares bundled skills.
tck/​sandbox/​testdata/​fixtures/​bundled-skill/​bundled-skill.dockerfile Packages skill content.
tck/​sandbox/​testdata/​fixtures/​bundled-reader/​probe Probes exposed skills.
tck/​sandbox/​testdata/​fixtures/​bundled-reader/​entrypoint Captures launch-time state.
tck/​sandbox/​testdata/​fixtures/​bundled-reader/​bundled-reader.yaml Declares discovery destinations.
tck/​sandbox/​testdata/​fixtures/​bundled-reader/​bundled-reader.dockerfile Builds reader workload.
tck/​sandbox/​testdata/​fixtures/​bundled-optional/​review.skill Adds optional skill content.
tck/​sandbox/​testdata/​fixtures/​bundled-optional/​renamed.skill Adds optional fixture data.
tck/​sandbox/​testdata/​fixtures/​bundled-optional/​register.sh Adds optional script sentinel.
tck/​sandbox/​testdata/​fixtures/​bundled-optional/​reference.txt Adds optional reference content.
tck/​sandbox/​testdata/​fixtures/​bundled-optional/​read.sh Adds optional reference reader.
tck/​sandbox/​testdata/​fixtures/​bundled-optional/​bundled-optional.yaml Declares optional skill.
tck/​sandbox/​testdata/​fixtures/​bundled-optional/​bundled-optional.dockerfile Packages optional skill.
tck/​sandbox/​testdata/​fixtures/​bundled-host-conflict/​conflict.skill Adds host-conflict content.
tck/​sandbox/​testdata/​fixtures/​bundled-host-conflict/​bundled-host-conflict.yaml Declares conflicting name.
tck/​sandbox/​testdata/​fixtures/​bundled-host-conflict/​bundled-host-conflict.dockerfile Packages conflict fixture.
tck/​sandbox/​testdata/​fixtures/​bundled-existing/​existing.skill Adds existing destination entry.
tck/​sandbox/​testdata/​fixtures/​bundled-existing/​bundled-existing.yaml Defines existing-content mixin.
tck/​sandbox/​testdata/​fixtures/​bundled-existing/​bundled-existing.dockerfile Seeds destination collision.
tck/​sandbox/​testdata/​fake-adapter Models skill registration mutations.
tck/​sandbox/​sandbox_test.go Registers bundled-skill mutations.
tck/​sandbox/​fixtures_test.go Updates fixture count.
tck/​sandbox/​coverage_test.go Accounts for new requirements.
tck/​sandbox/​checks.go Adds capability fixtures.
tck/​sandbox/​agent_skill.go Implements runtime checks.
tck/​sandbox/​agent_skill_test.go Tests checks and mutations.
tck/​kit/​kit.go Registers artifact check.
tck/​kit/​agent_skill.go Validates published skill content.
tck/​kit/​agent_skill_test.go Tests artifact validation.
Taskfile.yaml Adds the example Kit.
spec/​validate.go Validates skill declarations.
spec/​types.go Defines capability constants.
spec/​surface.go Classifies permission surface.
spec/​schema_test.go Includes new schema types.
spec/​merge.go Adds composition keys and conflicts.
spec/​groups.go Registers known capabilities.
spec/​agent_skill.go Adds configs, readers, and validation.
spec/​agent_skill_test.go Tests validation and composition.
skills/​skills.yaml Requests native skill registration.
skills/​migrate-kit-to-v3/​FIELD-MAPPING.md Documents migration behavior.
skills/​create-kit-v3/​SKILL.md Documents authoring behavior.
schema/​kit.schema.json Connects capability schemas.
schema/​capabilities/​com.docker.sandbox/​agent-skills-directory@1.schema.json Defines destination schema.
schema/​capabilities/​com.docker.sandbox/​agent-skill@1.schema.json Defines bundled-skill schema.
examples/​review-skill/​review-skill.yaml Adds example descriptor.
examples/​review-skill/​review-skill.dockerfile Packages example content.
examples/​review-skill/​content/​SKILL.md Adds example skill.
examples/​review-skill/​content/​references/​checklist.md Adds example reference.
examples/​opencode/​opencode.yaml Declares OpenCode destination.
examples/​opencode-mixin/​opencode-mixin.yaml Declares OpenCode mixin destination.
examples/​devin/​devin.yaml Declares Devin destination.
examples/​devin-mixin/​devin-mixin.yaml Declares Devin mixin destination.
examples/​cursor/​cursor.yaml Declares Cursor destination.
examples/​cursor-mixin/​cursor-mixin.yaml Declares Cursor mixin destination.
examples/​codex/​codex.yaml Declares Codex destination.
examples/​codex-mixin/​codex-mixin.yaml Declares Codex mixin destination.
examples/​claude/​claude.yaml Declares Claude destination.
examples/​claude-mixin/​claude-mixin.yaml Declares Claude mixin destination.
docs/​spec/​SPEC-v3.md Registers capability shapes.
docs/​spec/​capabilities/​com.docker.sandbox/​agent-skills-directory@1.md Specifies discovery destinations.
docs/​spec/​capabilities/​com.docker.sandbox/​agent-skill@1.md Specifies bundled skills.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread tck/sandbox/testdata/fixtures/bundled-reader/probe
Copilot AI review requested due to automatic review settings September 29, 2026 16:28

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟡 Changes recommended

Published validation can miss invalid literal skill source paths when the discovery name is parameterized.

Review effort: Balanced
Findings: 2 Medium severity

Open (2)

Comment thread spec/validate.go
A create-time discovery name must not hide a malformed source path from authored or published validation. Check the literal source shape before deferring parameterized values, including declarations in optional groups.

Signed-off-by: Christian Dupuis <cd@docker.com>
Check the sentinel script as content at both discovery destinations without executing it. Mutations for missing, corrupted, and non-executable copies prove the exposure check rejects incomplete skill trees.

Signed-off-by: Christian Dupuis <cd@docker.com>
Copilot AI review requested due to automatic review settings September 29, 2026 16:43

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🔵 Needs a closer look

The public reader API ambiguously shadows the skill’s configured name with its display label.

Review effort: Balanced
Findings: None

Resolved since last review (2)
Previously missed (1)

In code that hasn't changed since last review

Medium severity Avoid shadowing AgentSkill.Name with display label

spec/​agent_skill.go:27

AgentSkillCapability.Name shadows the embedded AgentSkill.Name, so request.Name returns the display label rather than the effective-name override. This makes the new public reader API easy to consume incorrectly despite embedding the config type; expose the entry label as DisplayName (or store the config under a named field) so the two meanings have distinct selectors.

Signed-off-by: Christian Dupuis <cd@docker.com>
Copilot AI review requested due to automatic review settings September 29, 2026 16:55

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🔵 Needs a closer look

The conformance probe can miss byte-level changes to skill and reference files.

Review effort: Balanced
Findings: None

Previously missed (1)

In code that hasn't changed since last review

Medium severity Compare SKILL.md byte-for-byte instead of command substitution

tck/​sandbox/​testdata/​fixtures/​bundled-reader/​probe:10

Command substitution strips trailing newlines from both files, so a runtime can truncate or add trailing newlines in either SKILL.md and still pass the exact-content requirement. Compare the files byte-for-byte, as the probe already does for register.sh.

This issue also appears on line 17 of the same file.

@cdupuis

cdupuis commented Sep 29, 2026

Copy link
Copy Markdown
Collaborator Author

Addressed the latest review summary’s name-shadowing concern in 7ea326a. The two names have distinct roles: entry name is a human-readable capability label; config.name overrides the skill directory basename and participates in skill identity.

The Go reader now exposes the entry label as request.DisplayName, so request.Name is the unshadowed skill config override. AgentSkillName(request.AgentSkill) computes the effective directory name, including the basename fallback. Tests cover an override and an omitted override with a display label present. The capability example now shows both YAML names and the resulting destination path, and SPEC-v3 explicitly scopes its display-only rule to capability-entry names. No descriptor fields or runtime semantics changed.

Validation: task validate, task lint, all unit packages, and focused skill, bundled-skill mutation, and normative-accounting tests passed. The full task test rerun hit the 10-minute sandbox-suite timeout while other suites were active on the host; this is recorded in the PR description. The concern was posted only in the review summary, so there is no new inline thread to resolve; both existing threads remain resolved.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟡 Changes recommended

The unclaimed agent-skill@1 probe is inherently unsatisfiable and cannot verify the intended refusal behavior.

Review effort: Balanced
Findings: 1 Medium severity

Open (1)

Comment thread tck/sandbox/checks.go
Signed-off-by: Christian Dupuis <cd@docker.com>
Signed-off-by: Christian Dupuis <cd@docker.com>
Copilot AI balanced review requested due to automatic review settings September 29, 2026 17:20
@cdupuis

cdupuis commented Sep 29, 2026 •

Copy link
Copy Markdown
Collaborator Author

Addressed the review-summary comment about command substitution in 425881a. The exposure probe now uses byte-for-byte comparisons for both SKILL.md files, the reference file, and read.sh, alongside the existing register.sh comparison. The execution check for relative references remains. Added four fake-adapter mutations that append a trailing newline, one per file; all four escaped detection before the fix and are now caught.

Validation at 425881a: task validate, task lint, and the full task test all passed, including the sandbox conformance suite and every fake-adapter mutation. The unclaimed-skill regression also passed, and its inline review thread is resolved.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🔵 Needs a closer look

It introduces broad normative and runtime-conformance contracts, while the real runtime suite was not executed.

Review effort: Balanced
Findings: None

Resolved since last review (1)

Each fake-adapter mutation reran the entire conformance suite even though it only asserted failures for its listed requirements. The extra bundled-skill cases pushed the CI job past the default ten-minute Go test timeout. Run each mutation against those checks through the same claim gating, sentinel environment, and cleanup path, and keep the complete conforming baseline and partial-runtime tests.

Signed-off-by: Christian Dupuis <cd@docker.com>
Copilot AI balanced review requested due to automatic review settings September 29, 2026 17:39

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🔵 Needs a closer look

It introduces a broad normative runtime contract whose real Docker Sandboxes conformance suite was not run.

Review effort: Balanced
Findings: None

@cdupuis
cdupuis merged commit a0d94ca into main Sep 29, 2026
8 checks passed
@cdupuis
cdupuis deleted the feat/bundled-agent-skills branch September 29, 2026 17:48
@cdupuis

cdupuis commented Sep 29, 2026

Copy link
Copy Markdown
Collaborator Author

Fixed the CI timeout in 4a77b65. Each mutation had been rerunning the entire conformance suite while asserting only its listed requirements. Mutation runs now select those checks through the same runner setup, claim gating, sentinel environment, and cleanup; the full conforming baseline and all mutation assertions remain. No timeout increase was needed.

Local validation, lint, unit tests, and sandbox conformance tests passed; the sandbox suite took 29 seconds. CI is now green: https://github.com/docker/sandbox-kit-spec/actions/runs/36606556312 (sandbox job: 1m5s, including setup).

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.

feat(spec): support bundled agent skills in mixins

2 participants