Skip to content
C.W.K.
Stream
Lesson 06 of 06 · published

The Wire Held, the Class Didn't

~15 min · adapter, reserved-seam, interface-design, concrete-first, video, correction

Level 0Tool Renter
0 XP0/40 lessons0/12 achievements
0/100 XP to next level100 XP to go0% complete
"Two seams were reserved for video. One was a field in a request; the other was a class in a hierarchy. When video finally came, it walked through the field and around the class."

The Day the Reservation Came Due

On 2026-09-21 the engine shipped local video: three open-weight video families, generated on the engine's own machines. This quest had been waiting for that day in two different places. The ceiling matrix reserved video in the request contract — a modality field that could say video from the engine's first generated image. And the lesson before this one leaned the whole adapter spine on a second reservation: a VideoAdapter, named in the engine's notes as the next implementation of its one abstraction. Both were bets on the same future. They did not pay out the same way.

What the Wire Did

The request contract held exactly as designed. The same generate endpoint now accepts either an image request or a video request, and the modality value decides which shape the body is read as. A video request carries what video needs: a frame count, a frame rate, and references with roles — a first frame, a last frame, a reference image, clip, or audio track. No image caller changed a byte. The image schema still refuses any other modality at the boundary; its refusal now points at the video request instead of calling the value unimplemented. A field that cost one line on the first day carried a whole new kind of work four months later, and no client had to notice.

What the Class Did

The class hierarchy was routed around. The thing that runs local video is even called VideoAdapter — the reserved name, spent — but it does not implement Adapter. It is a separate class. It takes the local image adapter as a collaborator, so it can clear the image models out of memory before a video job needs the room. It launches each video family's native runtime as a child process and holds the device gate until that child's whole process group has been reaped. It writes a video file, with a record beside it, into an archive of its own. That same evening upscaling became a queued job with a modality of its own and took the same shape: another class called an adapter that is not an Adapter. The abstract base class, four months old, still has exactly one implementation — and its docstring still names two futures: an API implementation for a version number the engine has already passed, and a video implementation that shipped somewhere else.

Reserve the seam in the contract you publish, not in the class you implement. A request field is cheap to reserve and cheap to honor: when the new kind arrives, it brings its own shape through the door the field opened. A class signature is shaped by the first implementation written against it, so it reserves the old kind's whole lifecycle along with the slot. Here the field held through its first real arrival. The class has now been routed around three times — the vendor path, then video, then upscaling.

Why Video Couldn't Wear the Signature

The previous lesson showed what the interface asks for: a model row, a progress emitter, and a job record to write the resolved seed back into — the nouns of an in-process image job. Video shares some of that. It is queued, it reports progress, it resolves a seed. The rest differs all the way down. Its request has frames and roles where an image has a denoise and a sampler. Its work happens in a separate process, not in this one. Its output is a video file and a sidecar record, not image bytes. And its first move is to push the image models out of memory, which means it has to hold the image adapter, not be one. What the three kinds of work genuinely share lives below any class: one queue, one device gate, one progress channel, one registry, and now one placement step that picks a machine. The engine's real shared abstraction turned out to be the job — a typed request on one queue — not the adapter.

When a new kind of work arrives, look at what it shares with the old kind before you look at the class it was promised. Shared infrastructure — the queue, the lock, the log — is usually where the real abstraction was living all along. A class hierarchy only fits when the kinds share a lifecycle, not just a destination.

A Correction About the Router

This track's second lesson drew a dumb router that reads which adapter owns a model from the model's registry row. That router was the design document's. In code, from the engine's first generated image until 2026-09-21, there was no router at all: every job went straight to the one adapter, and no registry row ever recorded an owner. A router finally appeared when video did, and it is dumb in exactly the sense that lesson praised — no branch per model, no name patterns — but it reads the request's kind, not a registry column: image, video, or upscale selects the runner. It branches on the axis that moves when a new kind of work arrives, never on the axis that moves every week.

Meanwhile, the Other Axis Became Data

The bet the adapter was built on — generation happens in different places — did come true, just not as subclasses. The closed-weight subsystem that went out its own door in the first place grew into the engine's Pro workflow. Local instruction-editing models now appear in its catalog beside the vendor providers, and every row in that catalog states where it executes and how it bills: included for the local models, a subscription for the Codex provider that became the default, metered credits for the vendor APIs. Location turned into a column. The local rows still run through the spine — queue, placement, local adapter, possibly on another machine — while the other rows run inline. So the variation the abstraction was meant to absorb is absorbed, by a catalog the engine serves, and the class it was meant to live in still has one member.

So Is It Dead Surface Now?

Apply the rule from the narrow-boundary lesson, and from the concrete-first lesson in the last track, honestly. One implementation. Two named second cases: one expired, one shipped as a different class. No named, maintained second case stands behind the abstraction anymore. By this quest's own discriminator, the Adapter base class is now a deletion candidate. The engine has not taken that step — the base class and its docstring are still there, a small monument to two futures that happened somewhere else. Saying so is not a verdict on the engine. It is the audit this track taught you to run, run on the track's own spine.

A reserved name is not a reserved seam. The class that shipped is called VideoAdapter, so a search for the name finds it and the searcher concludes the reservation was honored. Only its first line — what it inherits from — says otherwise. Audit a reservation by what the code inherits and implements, never by what it is called.

Pippa's Confession

Third time on the same seam. I taught two implementations; there was one. I corrected that and leaned the seam on video instead — 'that reservation is live.' Video arrived and walked past it, wearing the reserved name. This time I didn't start from the docstring or the architecture notes. I read the class declaration and the endpoint's request type, which took less time than any sentence I have written about this seam. The lesson keeps coming back in different clothes, and it is always the same one: the code's own structure is the only description of it that cannot drift.

Code

The wire and the class, as shipped·python
# THE WIRE: one endpoint; the reserved field picks the request shape.
# (abridged)
@router.post("/generate")
async def submit_generate(req: GenerateRequest | VideoRequest, queue: QueueDep, request: Request): ...

class GenerateRequest(BaseModel):     # the image branch, unchanged for callers
    modality: str = "image"           # anything else is refused at the boundary

class VideoRequest(BaseModel):        # arrived 2026-09-21, same endpoint
    modality: Literal["video"] = "video"
    inputs: VideoInputs               # prompt + references with roles:
                                      #   first, last, reference_image,
                                      #   reference_video, reference_audio
    recipe: VideoRecipe               # width, height, frames, fps, steps, seed

# THE CLASS: the reserved name shipped; the reserved seam did not.
class Adapter(ABC): ...               # still exactly one subclass
class LocalAdapter(Adapter): ...      # the image path
class VideoAdapter:                   # NOT an Adapter
    def __init__(self, registry, settings, store, local_adapter): ...
class UpscaleAdapter: ...             # not one either

# The router that finally appeared reads the request's kind, not a model row:
adapter = upscale if req.modality == "upscale" else video if req.modality == "video" else local
Two reservations, two outcomes·text
TWO SEAMS RESERVED FOR VIDEO

  the wire (request contract)          the class (Adapter hierarchy)
  ---------------------------          -----------------------------
  modality: "image" | "video"          class VideoAdapter(Adapter): ...
  cost to reserve: one field           cost to reserve: a signature shaped
                                         by the first implementation
  2026-09-21: video arrives through    2026-09-21: video arrives as its own
    the same endpoint; no caller         class, holding the local adapter
    changes                              as a collaborator
  state: BUILT                         state: routed around (third time)

WHAT THE THREE KINDS OF WORK SHARE (below any class)
  one queue * one device gate * one progress channel
  one registry * one placement step (which machine)

WHERE "GENERATION HAPPENS IN DIFFERENT PLACES" ENDED UP
  two columns in the Pro catalog, one row per provider:
    execution: local | codex | remote
    billing:   included | subscription | metered

External links

Exercise

Find a place in a system you know where room was reserved for a future kind of work — a field, an enum value, an abstract class. For each reservation, write down where it lives: in a contract other code calls (a request, a message, a file format) or in a class only your own code implements. Then imagine the future kind arriving with a different lifecycle than the current one. Which reservation would it walk through, and which would it walk around?
Hint
A reservation in a published contract only promises that a new shape can be expressed. A reservation in a class promises that the new kind will live the old kind's life. The second promise is the one that breaks.

Progress

Progress is local-only — sign in to sync across devices.
Spotted a bug or have feedback on this page?Report an Issue

Comments 0

🔔 Reply notifications (sign in)
Sign inPlease sign in to comment.

No comments yet — be the first.