Skip to main content

1. Understand the application architecture

Start by separating the work your application owns from the work Skulk™ owns. Studio is a useful example because it is substantial enough to need persistence, a UI and several workflows, but it still calls ordinary public model APIs.

Follow one user action​

An operator writes a shot description and clicks Plan. Studio reads the model catalog and live placement, resolves the shot and returns a plan. The operator then starts a render. Studio records a durable operation, submits a Skulk™ video job and follows it until the finished clip is downloaded into Studio's own storage.

The UI, application process and inference model need not run on the same machine.

Browser ── scoped HTTP ──┐
├── Studio child ── HTTP ── Skulk API ── model runner
Fabric caller ── host ──┘ │
├── SDK operation journal
└── application media library

The host supervises the child; the child tracks jobs; Skulk™ places and runs inference.

BoundaryInputOutputOwner
Browser → StudioApplication HTTP requests under the surface URLPlans, operation records and mediaStudio
Fabric caller → childNegotiated capability call through Skulk™ and the managed hostOne typed resultSkulk™ routing + Studio behavior
Child → Skulk™ APICatalog/state reads, video jobs, chat completionsModel facts, job references and resultsSkulk™ inference
Child → durable storageOperation intent, logs, files and retention marksRestartable application stateStudio + SDK persistence helpers

The browser does not speak the managed child's socket protocol. The child does not import a model runner. These boundaries let you change the UI or switch the application workflow without rewriting Skulk™'s inference machinery.

The source map​

The Python application lives under src/foxlight_video_studio/.

FileRead it for
contracts.pyTyped requests, results, settings, descriptors and the signed manifest.
child.pyStartup, SDK wiring, dispatch, health, background workers and shutdown.
planning.pyResolving model cards, reference modes, geometry, engine settings and plan digests.
skulk_api.pyBounded HTTP requests and decoding Skulk™ replies.
render.pyThe SDK job adapter: submit, observe, collect and cancel.
refine.py / guides.pyPrompt rewriting with a placed chat model and model-specific guidance.
assets.py / media.pyImports, content identity, media validation and reference lookup.
takes.py / history.pyRetention marks and migration of earlier operation history.
server.py / webapp.pyApplication HTTP routes and packed browser assets.
speed.py / thumbnails.pyLocal timing observations and thumbnail backfill.
packaging.pyChecking that the signed manifest matches the packaged code.

The web application lives in web/. Its API client is separate from its state stores and components. schemas/ is generated from the application contracts; tools/ contains schema and packaging utilities; tests/ and integration/ exercise increasingly complete boundaries.

What Studio uses from the SDK​

SDK moduleStudio's useWhat you still implement
contractsStartup, Hello, Health, Invoke, Result, typed contracts and manifestsYour application schemas and dispatch behavior.
wireRead/write bounded messages to the managed hostThe child loop and owned cleanup.
storageProtected directories, startup reads and atomic writesMedia validation, naming and retention.
operationsJournals, services, runners, logs and operation descriptorsThe backend adapter and meaningful plan.
databaseUsed by SDK operation persistenceApplication-specific stores and migrations where needed.
servingHost-selected addresses and caller admission helpersHTTP routes, UI authentication and surface readiness.
streamsNot used by Studio's six descriptors at this revisionStreaming handlers if your own workflow needs them.

Studio uses unary calls to start and inspect durable work. A render's duration is not a reason to declare a streaming capability. Choose streaming when you actually exchange incremental output or caller media during a call. See choosing a contract.

Keep these identities separate​

IdentityExample / sourcePurpose
Bundle idfoxlight.video-studioWhich installed application package this is.
Installed node idHost-provided Startup.node_idWhich installation owns this child and its durable scope.
Capability id + versionvideo.render@1.0.0Which operation a caller requests.
Descriptor revisionDerived from the descriptor contractWhether caller and provider agree on the exact contract.
Operation idCaller-retained application idDeduplicating and observing application work.
Backend referenceSkulk™ video job idFollowing the external inference job.
Plan digestDigest of resolved workDetecting changes between review and execution.

Do not substitute a job id for an operation id, or a plan digest for authorization. Each answers a different question.

Check your understanding​

If the Studio tab closes during a render, the application operation can continue. If the Studio child restarts, its journal remains and the stored video job can be reconciled. If the model host fails, Studio cannot manufacture a successful model job. You should be able to point to the owner of each failure before writing recovery code.

Next: define the contracts.