Music Lab
A four-unit music program: note reading drills, ear training, composition prompts, listening reflection. Program-led walkthrough.
The setup
Your kid takes piano lessons once a week. The teacher gives them a piece to practice. You want the in-between days to do more than rote practice: note reading drills, ear training prompts, little composition sparks, listening reflection. You want a coherent lab structure, not a pile of one-off tasks.
By the end of this walkthrough, you'll have a four-unit Music Lab program assigned to your kid, with each unit pulling from a different Build pattern (canvas, conversational, listen-and-tell). The program is the spine; the patterns are the limbs.
This walkthrough leans on the Program pattern, which is Soon on the kid surface. The MCP tools exist; we'll use them and call out what's still landing.
Patterns we'll chain
- Program: the four-unit Music Lab template, assigned per kid.
- Interactive canvas: tap-the-key drills for note reading.
- Conversational task: composition prompts and listening reflection.
- Reports and briefs: weekly digest of which units moved forward.
- Autonomous loop: a nudge that picks one unit per session.
The arc
1. Define the template
The Music Lab has four units, each with one or two leaf tasks. Each leaf task points to a skill that knows how to deliver it (the canvas to render, or the conversation to run). Tasks without a taskRef are placeholders the parent fills in later.
program.create({
name: "Music Lab",
description: "Pick-and-choose music adventure that complements piano lessons. Note reading, ear training, composition, and listening.",
type: "template",
units: [
{
name: "Note Reading",
emoji: "๐ผ",
description: "Read notes on the staff.",
children: [
{ name: "Treble Clef Notes", emoji: "๐ต",
description: "See a note, hear it, tap C/D/E.",
taskRef: { skillId: "<treble-clef-canvas-skillId>" }
}
]
},
{
name: "Pitch Ear",
emoji: "๐",
description: "Hear pitch and identify it. Needs a grown-up and piano.",
children: [
{ name: "High or Low?", emoji: "๐ถ",
description: "Grown-up plays two notes. You say which is higher.",
taskRef: { skillId: "<high-or-low-conversation-skillId>" }
}
]
},
{
name: "Compose & Create",
emoji: "โจ",
description: "Make up songs at the real piano; reflect with Sprout.",
children: [
{ name: "Make Up a Song", emoji: "๐ผ",
description: "Make up a little song. Then tell me about it.",
taskRef: { skillId: "<compose-reflect-conversation-skillId>" }
},
{ name: "Song with a Feeling", emoji: "๐",
description: "Make a happy song and a sleepy song. What changed?",
taskRef: { skillId: "<feeling-song-conversation-skillId>" }
}
]
},
{
name: "Listen",
emoji: "๐ง",
description: "Build the music brain by listening and reflecting.",
children: [
{ name: "What Did You Hear?", emoji: "๐",
description: "Tell me about music you heard or played today.",
taskRef: { skillId: "<listen-reflect-conversation-skillId>" }
}
]
}
],
inputVariables: [
{ name: "kid_name", description: "First name, used in prompts." },
{ name: "weekly_cadence", description: "e.g. 'Mon/Wed/Fri after dinner'." }
]
})
# Returns { programId: "<templateId>" }The skills referenced under each taskRef are skills you've already built using the other Build patterns. Treble Clef Notes wraps an Interactive canvas with a staff renderer and tap targets. The composition and listening prompts wrap Conversational tasks with the right guidance for each goal.
2. Assign to your kid
program.assign({
templateId: "<templateId>",
childId: "<kidId>",
slots: { kid_name: "Alex", weekly_cadence: "Mon/Wed/Fri after dinner" }
})
# Tasks for the first unit get authored automatically as the kid progresses.3. Cadence with an Autonomous loop
The program is pick-and-choose by design, but kids do better with a nudge. A daily heartbeat at 5pm checks the program state and queues one unit task for the kid to choose from. Follows the Autonomous loop pattern.
heartbeat.create({
name: "Music Lab nudge",
cron: "0 17 * * 1,3,5", // Mon/Wed/Fri 5pm
tz: "America/New_York",
runSkillId: "<music-lab-nudge-skillId>",
skillInput: { kid_id: "<kidId>", program_id: "<programId>" }
})The nudge skill: read program progress, pick the unit that hasn't moved in the longest, surface that unit's leaf task as the suggestion.
4. Weekly digest
Sunday night, a Reports and briefs skill summarizes the week per unit: how many sessions, which leaf tasks moved, what the kid said about their songs. Card in the family inbox. Pairs nicely with a heartbeat firing 0 20 * * 0.
The result
Your kid opens Sprout and sees a Music Lab section with four units. They can pick where to go. The nudge points them gently when they haven't been on the piano in a few days. Each session, Sprout asks about what they played, listens to their reflection, scores a tap drill if they want one. Sunday night you get the digest. The piano teacher sees more engaged practice without you turning into a drill sergeant.
Variations
- Different instrument. Swap "piano" for "guitar" / "violin" / "drums". The unit shapes (read, ear, compose, listen) translate; the task content changes.
- Different domain. The same four-unit shape works for sports drills (technique, conditioning, scrimmage reflection, watching tape), language practice (vocab, listening, speaking, reading), or art (sketching, color theory, composition, art history).
- No nudge. Skip the heartbeat; let the kid drive entirely. Programs work either way.
- Two kids, same template. Call
program.assigntwice with differentslots. The template is shared; the assigned instances are independent.
Notes on current state
The MCP program tools (program.create, program.assign, program.update) are live and the schema accepts the shape above. The kid-facing Music Lab section in the app is Soon: today the assigned tasks land as regular tasks in the kid's task list; the explicit "program with units" surface is coming. The walkthrough is fully buildable as MCP plumbing now; the visual structure lands with the kid surface.