diff --git a/library/skills/asset-strategy/SKILL.md b/library/skills/asset-strategy/SKILL.md index 703657b..4be7ce8 100644 --- a/library/skills/asset-strategy/SKILL.md +++ b/library/skills/asset-strategy/SKILL.md @@ -12,6 +12,22 @@ allowed-tools: Read Grep Skill summer_search_assets summer_list_my_assets summer Classify the user's request, ask at most one clarifying question, then dispatch to the right specialist via the `Skill` tool. Don't generate anything yourself — every media-type/asset-class combination has a dedicated specialist that owns the prompt patterns, polycount targets, gates, and fallbacks. Your job is the routing decision, not the work. +## Studio-only media boundary + +All new project media — images, sprites, textures, 3D meshes, music, SFX, voice, +video, and motion — must be created through Summer Engine Studio tools +(`summer_generate_*` or their Summer chat equivalents). Never use Python, +GDScript, shell scripts, SVG/canvas, oscillators or MIDI, agent-native image +generation, chat documents/artifacts, or an external generator as a substitute. +Code may wire/import/play Studio media and perform deterministic +post-processing; it may not author the requested media itself. Preserve the +returned Summer asset id and import through Summer tools. A temporary chat +preview is not an importable project asset. + +If the routed specialist or Summer generation tool is unavailable, do not +improvise another generation path. Refresh/install the Summer skill or hand the +exact prompt to the Summer Studio dashboard, then stop. + ## Step 1 — Classify by media type | Signal in user request | Continue at | @@ -131,4 +147,7 @@ VFX is **code, not generative** — recipes are shader + GDScript + node setup, ## Fallback (no MCP) -The router still works without MCP — classification is text-only. It hands off to the specialist, which surfaces its own no-MCP fallback (typically: run the equivalent generation via the Summer dashboard / Meshy / nano-banana web, then `summer_import_from_url` once MCP is back). +The router still works without MCP — classification is text-only. It hands off +to the specialist, which must use the Summer Studio dashboard as its only +generation fallback. Do not route to a provider website or agent-native media +generator. Import the durable Summer asset when MCP is available again. diff --git a/library/skills/music-track/SKILL.md b/library/skills/music-track/SKILL.md index dc953a3..80f97d3 100644 --- a/library/skills/music-track/SKILL.md +++ b/library/skills/music-track/SKILL.md @@ -17,6 +17,16 @@ ElevenLabs Music renders a track from a prompt. Summer clamps the requested leng This skill produces one track aligned with the audio bible's music style and dynamic music plan, then wires it as an `AudioStreamPlayer` on the `Music` bus with a marked loop point if it's a loop, or as a linear cinematic stream if it's a one-shot. +## Studio-only generation boundary + +Create the music only with Summer Engine Studio's `summer_generate_audio` +music capability. Never synthesize or encode the track with Python, GDScript, +shell tools, oscillators, MIDI, a chat artifact, or an external generator. Code +may import, configure, loop, crossfade, and play the Studio-generated track; it +must not author the music itself. Preserve the returned Summer asset id and +import it through Summer tools. If Studio generation is unavailable, provide +the exact Summer Studio dashboard prompt and stop instead of switching methods. + ## When to use - Looped track for a level, biome, menu, or game state (calm / tension / combat). @@ -241,6 +251,8 @@ Cutscene (cinematic): varies tempo, D minor, 4/4, solo piano opens, ## Anti-patterns - **Genre adjectives only.** `epic`, `chill`, `hype` — meaningless. +- **Synthesizing the track in code.** Python, GDScript, shell audio tools, + oscillators, and MIDI are not substitutes for Studio music generation. - **Naming a game or composer.** Model won't replicate; use ingredients. - **Loop shorter than 30s.** Recognized as repetition fast. - **Music on `Master` bus at 0 dB.** Buries SFX. Use `Music` bus at `-8 dB`. diff --git a/library/skills/using-summer/SKILL.md b/library/skills/using-summer/SKILL.md index fe9c495..97d9244 100644 --- a/library/skills/using-summer/SKILL.md +++ b/library/skills/using-summer/SKILL.md @@ -38,6 +38,24 @@ Two layers: - **Skills** — discipline guides that fire on specific situations: brainstorming a game, designing a mechanic, building an FPS controller, debugging a crash, shipping a build. Each one is a SKILL.md you load via the Skill tool. - **MCP tools** — `summer_*` tools that talk to the running Summer Engine on `localhost:6550`. Scene mutation (`summer_add_node`, `summer_set_prop`), inspection (`summer_get_scene_tree`, `summer_inspect_node`), play/diagnostics (`summer_play`, `summer_get_diagnostics`), asset import/generation (`summer_import_from_url`, `summer_generate_3d`), and 30+ more. +## Media Generation Boundary + +For project deliverables such as images, sprites, textures, 3D meshes, music, +sound effects, voice, video, and motion, create the media only through Summer +Engine Studio generation tools (`summer_generate_*` or their Summer chat +equivalents). Never substitute Python, GDScript, shell scripts, SVG/canvas, +oscillators or MIDI, an agent-native image generator, a chat document/artifact, +or an external generation service. A temporary chat preview is not a project +asset. + +Code may import, wire, play, or deterministically post-process media returned by +Studio. It may also implement an explicitly requested procedural engine effect; +it must not synthesize authored media as a fallback. Preserve the returned +Summer asset id and import through Summer tools, preferring +`summer_import_asset_by_id` when the tool supports the asset type. If the Summer +generation route is unavailable, give the exact Summer Studio dashboard handoff +and stop instead of silently switching generators. + **Scripting language:** The user is making a Summer game with the Summer SDK. GDScript is the default creator language. Summer currently uses the 4.6.1 upstream technical base, plans to adopt 4.7.1 next, and follows upstream diff --git a/registry/generated/index.json b/registry/generated/index.json index 72b06d1..c85bda9 100644 --- a/registry/generated/index.json +++ b/registry/generated/index.json @@ -532,7 +532,7 @@ "id": "skill/asset-strategy", "kind": "skill", "version": "1.0.2", - "content_hash": "f7a5adea3d1a289b2ea2cd7e1ba947dae295ea54b95f77f081693fff945eb3c7", + "content_hash": "1cd28ac3961eebec6997a9c9c035bb72afae1c6fbf0342e6c279ffbc5a1674cc", "summary": "Route any 'I need a [thing]' asset request to the right specialist skill — disambiguates 2D / 3D / audio / video / VFX / animation pipelines.", "use_when": [ "planning asset creation, picking an asset pipeline, or routing an 'I need a [thing]' request to the right specialist skill", @@ -1910,7 +1910,7 @@ "id": "skill/music-track", "kind": "skill", "version": "1.0.2", - "content_hash": "549f169cf06ad03bf5a8ef5d056854a833453b4d8b715cdb603b291530c5c4ca", + "content_hash": "b1b94347d4eba5d1bf1b012b17a08c89982318622faf2d0bb713a929c16ef492", "summary": "Generate a looped or cinematic music track — loops authored at >=30s with a marked loop point, cinematic tracks at >=60s linear.", "use_when": [ "generating a looped or cinematic music track — main theme, boss music, title screen, exploration loop, combat track", @@ -3178,7 +3178,7 @@ "id": "skill/using-summer", "kind": "skill", "version": "1.0.4", - "content_hash": "27980a37339ff2b75dd53ebf0fe39561a48ae3103f82b3aa7b96ce53ec45bfe9", + "content_hash": "0de4390a44596664c72febe6bbe5cf24ec901937839ec5c20ba7f0115258d4c8", "summary": "Session bootstrap for Summer projects — establishes how to find and use Summer skills and the summer-engine MCP before any response.", "use_when": [ "starting any conversation in a Summer Engine project", diff --git a/src/core/capabilities/agent-playbook.ts b/src/core/capabilities/agent-playbook.ts index e654ad6..26b8a4e 100644 --- a/src/core/capabilities/agent-playbook.ts +++ b/src/core/capabilities/agent-playbook.ts @@ -176,6 +176,7 @@ export function buildAgentPlaybook( "Use summer_replace_text for existing project text and summer_write_file with create_only:true for new files; overwrites require the sha256 from summer_read_file.", "For live scene hierarchy and inspector changes, prefer scene tools. Guarded text writes support .tscn/.tres, and the engine schedules editor reloads after they land.", "Write GDScript by default; use C# only if the project already uses it.", + "Create project media (images, sprites, textures, 3D meshes, music, SFX, voice, video, and motion) only through Summer Engine Studio generation tools. Never substitute Python/GDScript/shell synthesis, SVG/canvas, oscillators/MIDI, agent-native image generation, chat documents/artifacts, or an external generator. Code may import, wire, play, or deterministically post-process Studio media, but must not author the requested media itself. A chat preview is not a project asset; preserve the Summer asset id and import through Summer tools. If Studio generation is unavailable, provide the exact Summer Studio dashboard handoff and stop.", "Never remove multiple top-level nodes unless the user explicitly requests destructive edits.", "Never change priority: locked .summer memory, voice IDs, canon, or provider bindings without explicit user confirmation.", ], diff --git a/src/mcp/tools/project-tools.test.ts b/src/mcp/tools/project-tools.test.ts index 9479919..5a923af 100644 --- a/src/mcp/tools/project-tools.test.ts +++ b/src/mcp/tools/project-tools.test.ts @@ -342,6 +342,20 @@ priority: locked expect(JSON.stringify(body)).toContain("priority: locked"); }); + it("routes project media generation exclusively through Summer Studio", async () => { + const { server, tools } = createFakeServer(); + registerProjectTools(server as never); + + const playbookTool = getTool(tools, "summer_get_agent_playbook"); + const body = parseToolResult(await playbookTool.handler({})); + const playbook = JSON.stringify(body); + + expect(playbook).toContain("only through Summer Engine Studio generation tools"); + expect(playbook).toContain("Never substitute Python/GDScript/shell synthesis"); + expect(playbook).toContain("A chat preview is not a project asset"); + expect(playbook).toContain("dashboard handoff and stop"); + }); + it("structures the playbook on the observe-first / routing / invariants skeleton", () => { const playbook = buildAgentPlaybook(); const text = JSON.stringify(playbook);