Generation needs durable state
An image button is easy to demo and difficult to operate. Real generation can take time, return several outputs, fail after a provider accepts the request, or finish after the user has moved to another page. Credits must be deducted and refunded consistently. Collaborators need to find the result later.
Laper models those realities with two durable concepts:
- an AI generation task records what was requested and moves through a state machine;
- an asset records each successful output that belongs to the project.
The distinction allows one task to produce multiple assets without pretending that a UI loading spinner is the source of truth.
The backend owns the transaction
The browser starts a task with project and entity context. The Go backend validates the user and project, accounts for credits, dispatches work, and owns the terminal state. The separate generation service performs the model call and uploads media, but it does not authenticate users or write application tables.
On success, the backend can atomically finalize the task and persist assets. On a terminal failure, it can apply the corresponding refund policy. A user notification may arrive through the private AI-task channel, but durable HTTP data remains the reconciliation path.
This boundary is intentional:
| Responsibility | Owner |
|---|---|
| User and project authorization | API backend |
| Credit deduction and refund | API backend |
| Task lifecycle and retry state | API backend |
| Model execution and media upload | Generation worker |
| Durable output record | assets data owned by backend |
| Screenplay and entity document state | Loro CRDT through normal editor/entity writes |
Supabase Realtime never takes over CRDT. It can tell the current user that a task changed state; it does not decide what the screenplay contains and does not replay assets into the document.
Context comes from the entity that requested the work
Visual generation is more useful when it has a stable subject. Laper's project views provide that subject:
- a character can request a portrait or casting reference from its profile;
- a location can request a visual reference from location data;
- a prop can request a design reference;
- a scene can request a scene still from its screenplay scope and characters;
- a storyboard shot can request a frame using the scene text and explicit shot settings.
The output becomes a project asset. When the workflow calls for a selected image on an entity, the application routes the result back through the entity's normal write path. AI does not get a separate hidden document model.
For the shot-specific rules, including previous-frame continuity and explicit camera settings, see AI storyboarding from scene context. For the people layer, see characters, casting, and relationships.
The Assets view is an audit surface
Laper's Assets module is not the universal “generate” button. Generation starts where the context lives—on a character, scene, location, prop, shot, or tool panel. Assets then aggregates the results and task history for the project.
The module has two perspectives:
- a generation canvas for browsing project outputs spatially;
- a task list for status, history, and active-task counts.
The task list loads durable project task pages over HTTP. A member can inspect the team's project tasks, while the private task notification channel is scoped to the current user's task updates. Asset records are also loaded durably rather than pretending every collaborator's history can be reconstructed from ephemeral events.
Failure is part of the product
Generation systems should explain failure without losing money or state. A terminal task can carry a meaningful failure reason; the backend can determine whether credits need to be returned; the browser can reconcile after refresh. This is why the task exists independently from the media output.
The product does not promise that every request succeeds, that a provider is never congested, or that visual continuity is automatic. It provides a state machine in which success, failure, retry, and refund have explicit owners.
That operational honesty is part of the wider AI screenwriting software design: AI output becomes accountable project data instead of a transient result trapped in a chat bubble.