diff --git a/docs/agent-skills/skill-necessity.md b/docs/agent-skills/skill-necessity.md index 4c9104ffa..860ac1f93 100644 --- a/docs/agent-skills/skill-necessity.md +++ b/docs/agent-skills/skill-necessity.md @@ -409,3 +409,96 @@ The run with the skill passes if the agent: ### Why this belongs in a skill Discovery is a conditional workflow. It should not live in the always-on brief because it only matters when the user needs a skill but does not know which one. It also needs product-specific guidance: discovery is not installation; Multica import remains the final source of truth. + + +## `multica-skill-authoring` + +`multica-skill-authoring` exists because creating or updating a skill is not just writing Markdown. A Multica skill is durable workspace behavior: it has a trigger contract, reusable procedure, verification path, and optional supporting files that future agents will load on demand. + +### Purpose + +The skill teaches the agent how to decide whether a requested method deserves to become a skill, then create or update the workspace skill with the current Multica CLI. It also marks the future `--bundle-dir` workflow as the preferred path once that CLI support lands. + +### Platform contract + +The current workspace authoring surface is: + +```bash +multica skill create --name --description --content --output json +multica skill update --content --output json +multica skill files upsert --path --content +multica skill files delete +multica skill get --output json +``` + +The source of truth is `server/cmd/multica/cmd_skill.go`, which exposes skill create/update/get and file upsert/delete, backed by `server/internal/handler/skill.go`. + +The intended future bundle workflow is: + +```bash +multica skill create --bundle-dir --output json +multica skill update --bundle-dir --output json +``` + +Until that lands, the skill must teach the current workaround: create/update main content, upsert supporting files one by one, then verify by reading the skill back. + +### Without this skill + +A prompt like this exercises the failure: + +```text +Turn this workflow into a reusable Multica skill, include the reference template, and update it later if the process changes. +``` + +Without the skill, the agent may: + +- write a one-off note instead of a workspace skill; +- create a vague skill whose `description` does not tell agents when to load it; +- omit verification and assume the create/update succeeded; +- put secrets, PR numbers, issue numbers, run timestamps, or temporary session notes into durable skill content; +- paste large examples into `SKILL.md` instead of supporting files; +- ignore the current CLI limitation and claim `--bundle-dir` already exists. + +### Failure mode + +The failure is durable. A bad skill pollutes future agent runs: it triggers at the wrong time, teaches stale facts, leaks sensitive or temporary data, or hides reusable assets in an oversized `SKILL.md` body. Unlike a bad issue comment, a bad skill keeps being rediscovered and reused. + +### With this skill + +With the skill, the agent must: + +1. Confirm the workflow is reusable and not one-run progress. +2. Write a focused `SKILL.md` with frontmatter, a clear "Use when ..." description, steps, failure modes, verification, and source of truth. +3. Keep secrets, PR numbers, issue numbers, and temporary session notes out of the skill. +4. Put large reusable references, templates, scripts, or assets into supporting files. +5. Use the current CLI create/update/files workaround. +6. Run `multica skill get --output json` after writing and verify the returned content/files. +7. Prefer `--bundle-dir` once that follow-up CLI support exists. + +### Test scenario + +Use this prompt for an A/B evaluation: + +```text +Create a Multica skill from this repeated code review workflow. Include a reusable checklist and a reference template. Do not include this PR number or today's run notes. +``` + +The run without the skill fails if the agent: + +- writes only a comment or local file and does not create/update a workspace skill; +- includes temporary PR/session details in the skill; +- produces a description that cannot act as a trigger condition; +- forgets supporting files or verification; +- claims a future bundle-dir command exists before it is implemented. + +The run with the skill passes if the agent: + +- creates or updates through `multica skill create` / `multica skill update`; +- uses `skill files upsert` for reusable supporting files; +- verifies by reading the skill back; +- excludes secrets and temporary facts; +- clearly marks `--bundle-dir` as the future preferred path, not the current command. + +### Why this belongs in a skill + +Authoring is a conditional workflow. It should not live in the always-on brief, but it is important enough to be platform guidance because bad skills become durable agent behavior. The skill keeps the prompt lean while giving agents a concrete method when the user asks to create or maintain skills. diff --git a/server/internal/service/builtin_skills/multica-skill-authoring/SKILL.md b/server/internal/service/builtin_skills/multica-skill-authoring/SKILL.md new file mode 100644 index 000000000..9865261c6 --- /dev/null +++ b/server/internal/service/builtin_skills/multica-skill-authoring/SKILL.md @@ -0,0 +1,160 @@ +--- +name: multica-skill-authoring +description: Use when a user asks to create, edit, or maintain a Multica workspace skill. Teaches the current CLI workflow for SKILL.md content, metadata, supporting files, verification, and the future bundle-dir path without treating one-off notes as durable skills. +user-invocable: false +allowed-tools: Bash(multica *) +--- + +# Authoring Multica skills + +Use this skill when the user asks to create, update, or maintain a Multica +workspace skill. This is different from finding an existing skill +(`multica-skill-discovery`) or importing a known URL (`multica-skill-importing`). + +## The invariant + +A Multica skill is durable workspace behavior. It should capture a reusable method, +platform rule, or tool workflow that future agents should apply on demand. + +Do not create a skill for one-run progress, temporary TODOs, PR numbers, issue +numbers, session summaries, transient decisions, credentials, API keys, or other +secrets. Those belong in issue comments, issue metadata, project docs, or not at +all. + +## Authoring standard + +Every `SKILL.md` must have clear frontmatter and body guidance: + +```md +--- +name: short-slug +description: Use when ... +--- + +# Skill title + +Use this skill when ... +``` + +The `description` is the trigger contract. Write it as a concise "Use when ..." +sentence so the agent can decide whether to load the skill before seeing the +body. + +The body should cover: + +- when to use the skill and when not to use it; +- the exact commands or APIs to run; +- verification steps that prove the work succeeded; +- failure modes and recovery rules; +- source of truth links to code, API, CLI, docs, or product behavior. + +Keep the main body focused. Put large examples, templates, or reference material +in supporting files instead of bloating `SKILL.md`. + +## Current create flow + +Until bundle directory support exists, create the workspace skill from explicit +CLI fields: + +```bash +multica skill create --name --description --content --output json +``` + +Read the JSON response and keep the returned `id`. Do not claim the skill exists +until the create command succeeds. + +If the content lives in a local `SKILL.md`, read the file first and pass its full +content as the `--content` value. The current CLI does not yet have +`--content-file` or `--bundle-dir`, so large content may require a wrapper script +or shell-safe command construction. + +## Current update flow + +Update an existing skill with the skill id or supported identifier: + +```bash +multica skill update --content --output json +``` + +Use `--name`, `--description`, or `--config` only when those fields actually need +to change. Avoid rewriting unrelated fields. + +After update, verify by reading it back: + +```bash +multica skill get --output json +``` + +Compare the returned `name`, `description`, `content`, `config`, and `files` +against what you intended. + +## Supporting files + +Use supporting files for reusable references, templates, scripts, and assets that +are too large or too specific for the main `SKILL.md`. + +Current workaround for supporting files: + +```bash +multica skill files upsert --path --content +multica skill files delete +multica skill get --output json +``` + +Recommended relative paths are stable, portable paths such as: + +```text +references/.md +templates/.md +scripts/.sh +assets/. +``` + +Do not store secrets in supporting files. Do not store one-off PR numbers, issue +numbers, run timestamps, or temporary session state. If the fact will be stale in +a week, it is not skill content. + +## Future bundle directory path + +When the CLI supports bundle directories, prefer the atomic local bundle flow: + +```bash +multica skill create --bundle-dir --output json +multica skill update --bundle-dir --output json +``` + +Expected bundle shape: + +```text +/SKILL.md +/references/... +/templates/... +/scripts/... +/assets/... +``` + +Until `--bundle-dir` lands, use the current workaround: create/update the main +content, then upsert supporting files one by one, then verify by reading it back. + +## Quality gate + +Before creating or updating a skill, check: + +1. Is this reusable across future runs? +2. Is the trigger condition clear from the description alone? +3. Does it cite a real source of truth instead of relying on vibes? +4. Does it include verification steps? +5. Does it avoid secrets, temporary progress, PR numbers, issue numbers, and stale + session notes? +6. Are large examples moved into supporting files? + +If the answer is no, do not create the skill yet. Write an issue comment or a doc +instead. + +## Source of truth + +- `server/cmd/multica/cmd_skill.go` implements `multica skill create`, + `multica skill update`, `multica skill get`, and `multica skill files upsert`. +- `server/internal/handler/skill.go` implements the workspace skill API. +- `docs/agent-skills/skill-necessity.md` records why built-in platform skills + exist and how to evaluate whether they work. diff --git a/server/internal/service/builtin_skills_test.go b/server/internal/service/builtin_skills_test.go index 30fd6f3a9..b5e2a0d10 100644 --- a/server/internal/service/builtin_skills_test.go +++ b/server/internal/service/builtin_skills_test.go @@ -255,6 +255,43 @@ func TestSkillDiscoverySkillCoversFindVerifyImportContracts(t *testing.T) { } } +func TestSkillAuthoringSkillCoversCreateUpdateMaintainContracts(t *testing.T) { + skill, ok := findSkill(t, "multica-skill-authoring") + if !ok { + return + } + fm, body, _ := splitFrontmatter(skill.Content) + + if got := strings.TrimSpace(fm["user-invocable"]); got != "false" { + t.Errorf("user-invocable = %q, want false (skill authoring guidance triggers from context)", got) + } + if got := strings.TrimSpace(fm["allowed-tools"]); !strings.Contains(got, "Bash(multica *)") { + t.Errorf("allowed-tools = %q, want access to the Multica CLI", got) + } + + mustContain := []string{ + "multica skill create --name --description --content --output json", + "multica skill update --content --output json", + "multica skill files upsert --path --content ", + "multica skill files delete ", + "multica skill get --output json", + "SKILL.md", + "frontmatter", + "supporting files", + "secrets", + "PR numbers", + "--bundle-dir", + "current workaround", + "source of truth", + "verify by reading it back", + } + for _, want := range mustContain { + if !strings.Contains(body, want) { + t.Errorf("skill-authoring skill missing %q", want) + } + } +} + func findSkill(t *testing.T, name string) (AgentSkillData, bool) { t.Helper() for _, s := range loadBuiltinSkills() {