akuko — story to film, one reviewed stage at a time
This file is a router. Each action lives in its own file under actions/; load it on demand and follow it. Do not inline action behaviour here. Shared rules live in lib/:
lib/state.md— the project file, stages, status transitions, decision folding. Read it before anything that writes.lib/hosts.md— host detection, what each host can do, the host adapter.lib/spend.md— the spend gate and cost ledger (WP-03).lib/providers.md— providers (WP-03).
The project format is schema/akuko-project.ts (akuko.json, JSON Schema in schema/akuko-project.schema.json).
Every action starts the same way
- Detect the host (
lib/hosts.md§Detection): A claude-artifact · B local · C ikenga. Runnode --experimental-strip-types hosts/detect.ts --tools <your FULL tool list — every loaded and deferred tool name>. If the output has awarning, or you are in any doubt, treat the host as A (artifact DB) and never create a project folder. Record the result inakuko.json.host. - Read the project through the host adapter (
readState()); if there is none, route tointake(orsetupif the person wants to configure first). - Fold decisions people made since the last run (
readDecisions()→lib/state.md§Decision folding) before doing anything else. - Load the action file and follow it. Write the project only through
writeState(); store files only throughstoreAsset().
Routing
| If the user says… | Load this | Owner |
|---|---|---|
| "set up akuko", "configure", "set a budget", "add my keys" | actions/setup.md | WP-08 |
| "check my setup", "what's missing", "doctor" | actions/doctor.md | WP-08 |
| "make a film from this story / script", "start a project", "intake" | actions/intake.md | WP-04 |
| "break it down", "shot list", "breakdown", "import a shot list" | actions/breakdown.md | WP-04 |
| "characters", "locations", "look / style", "bible" | actions/bible.md | WP-05 |
| "storyboard", "sketch board", "beat board", "board" | actions/board.md | WP-21 |
| "key frames", "final panels", "keyframes", "continuity check" | actions/keyframes.md | WP-22 |
| "animate", "make the clips", "motion", "treatment", "camera moves" | actions/motion.md | WP-10 · WP-11 · WP-27 |
| "lip-sync", "make them say the line", "lipsync" | actions/lipsync.md | WP-28b |
| "voice-over", "music", "sound effects", "sound" | actions/sound.md | WP-12 |
| "animatic", "preview the film", "let me watch it", "rough cut", "assemble" | actions/assemble.md | B-11 (preview built) · WP-13 (rough cut, picture lock: stub) |
| "export", "send to Resolve", "give me a timeline" | actions/export.md | WP-23 (Resolve handoff) |
| "I reviewed it", "apply my notes", "review" | actions/review.md | WP-07a |
| "show me …", "open the board", "view" | actions/view.md | WP-07c |
| "where are we", "what's next", "status", "how much will it cost", "estimate" | actions/status.md | WP-30 (whole-film estimate) |
Export hands the approved film to DaVinci Resolve as a timeline plus media. MP4 masters, cutdowns and a Canva deck are parked (plan Round 7): if asked for an MP4, say so and offer the handoff.
If nothing matches, run status and offer the next action it suggests. If an action file (or the route asked for) still says Stub (WP-02), tell the person it is not built yet and stop — do not improvise it. An animatic is not improvised either: assemble preview is the built, free route for one (approved key frames timed to the shots, never a review unit, never saved to the project).
Stages
intake → breakdown → sketch → bible → keyframes → motion → sound → assemble → export (0–8, schema/akuko-project.ts#STAGES; the film profile is profiles/film/profile.json). A stage opens only when the stages before it are approved (lib/state.md §Stages).
Review rules
These hold on every host and in every action and view:
- Only a person approves. Actions move units to
pending-review; only a person's decision moves a unit toapproved. No action or view auto-approves, pre-ticks or batch-approves. - Never auto-advance past review. Each stage ends at a review gate (Atelier
ux_mode: approve): run, then pause on what was produced. - One unit at a time inside a stage: produce, show, wait — don't regenerate the whole stage because one shot was sent back.
- Decisions go through the decision format (
Decisionin the schema), written by a review surface to the host's store. A view never editsakuko.jsonand never callswriteState(). - Requested changes are honoured, then marked: revise the unit, add a "Revised: …" comment, return it to
pending-review.
Spend rules
- No paid call without an OK. Every paid job (image, video, TTS) goes through the spend gate (
lib/spend.md): show the estimate, the cap, what is spent and what is left if you approve, then wait for an explicit approval of that job. - No cap, no spend. If
akuko.json.budgetis null, refuse paid jobs and point tosetup. - Never exceed the cap or a job's
approved_max; stop and ask instead. - Money is never hidden or rounded. Every paid call is recorded in
ledger[], success or failure. - Keys stay in the environment (or the host's secret store) — never in
akuko.json, a view, the artifact database, the ledger or a file the board can read, and never repeated back. On claude.ai (host A) a key is pasted per chat, and only when a paid direct call is about to run: probe the network first (scripts/probe.ts), tell the person the key will be visible in this chat's history, is used for this chat only and is never written anywhere, get "use my key for this chat", then set it only on that command's environment, reserve, save to the board, send (lib/spend.md§Host A, R-11). - House rules come before money. When the project has
rules, every job is checked against them before the spend gate, and a breach is refused (rules-breach), naming the rule and the offending text or file. Report it and stop; never reword, drop a reference or edit the rules to get past it. Runrules/cli.ts checkfor a free preflight (lib/state.md§"Rules guard (WP-26)"). - A plan allowance is spend too. A connected tool that uses the person's own plan allowance instead of money (Canva's monthly AI limit on claude.ai) gets an OK of every wave: the count, the service, that akuko can't see what is left, and the exact reply
approve <n> <service> generations. Each generation goes in the ledger with zero money and a units count (lib/spend.md§Allowance).
Hosts in one line each
- A — claude-artifact (claude.ai): Node and files only in a remote workspace that lasts one chat, so no durable project folder. The project lives in the board artifact's database; the agent reads and writes it with tool calls and runs the stage commands on a working copy. Generation through connected MCPs (e.g. Canva), manual prompt packages, and paid direct APIs with a key pasted for that chat (R-11, after a network probe); MP4 renders locally.
- B — local (Claude Code):
akuko.jsonon disk, files in the project folder, all providers via env keys, HyperFrames + FFmpeg. - C — ikenga: B plus the Ikenga bridge (and Studio when its MCP is connected); Studio owns render state.
Details and the capability evidence: lib/hosts.md.
Files
SKILL.md this router
actions/*.md one file per action (Atelier frontmatter)
lib/state.md project file rules, stages, transitions, decision folding
lib/hosts.md host detection, capabilities, manual host check
hosts/types.ts HostAdapter contract (G-HOST)
hosts/{claude-artifact,local,ikenga}.ts one adapter per host
profiles/film/ the film profile
schema/ akuko.json format (G-SCHEMA)