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

Nothing Fires on Its Own

~12 min · scheduler, automation, agency, unattended-jobs

Level 0Cold Workshop
0 XP0/35 lessons0/12 achievements
0/100 XP to next level100 XP to go0% complete

The Two Refusals That Do the Real Work

The last lesson listed four refusals. Two of them — no server, no port — are ordinary engineering restraint. The other two are stranger and more interesting: no scheduler and no brain. They are what stop this tool from quietly becoming a content factory, and they are the ones most likely to be argued away.

Here is the argument that would win in most projects. The tool takes an identifier and produces a video. Videos should be published regularly. Therefore: put it on a timer, feed it whatever is queued, and let it run overnight. Every piece of that reasoning is technically sound, and the design rejects it outright.

Why a Timer Was Rejected

The stated reason is not that unattended jobs are unreliable. It is a claim about what the tool is: a person runs the job; the workshop is a tool. A scheduler inverts that. Once a timer fires the pipeline, the tool is the actor and the human is a reviewer of output that already exists — and the entire quality doctrine of this repo depends on the human being upstream of production, not downstream of it.

There is a second reason, and it is the one that generalizes past this project. A schedule creates demand that the material may not be able to meet. If the tool must produce something every week, then in a week with nothing worth saying it will produce something anyway, because that is what the schedule asks for. The design answers this by making the queue itself the cadence: three requests in a week means three videos; zero requests means zero, and zero is a legitimate outcome that requires no explanation.

No Brain: Where the Judgment Comes From

The other refusal is subtler. Beacon holds no model and runs no autonomous judgment loop. It has plenty of decisions in it — what to render, how to phrase a line, which of four generated images is usable — but none of those live in the tool. They arrive from outside on each run, from whoever is driving it. The tool contributes determinism: the same inputs render the same frames, the same encode profile, the same measured checks.

That split is worth naming precisely, because it is the difference between a tool and an agent. A tool makes the same thing happen every time you pull the lever. An agent decides when to pull. Keeping the lever and the deciding in different places means you can always answer the question "why does this exist?" with a person and a moment, rather than with a configuration nobody remembers writing.

Code

Two ways to arrange the same components·text
REJECTED — the tool is the actor

  timer ──▶ pick from queue ──▶ render ──▶ publish
                                             │
                                        human reviews
                                        (downstream, after the spend)


CHOSEN — the person is the actor

  human decides ──▶ request ──▶ human picks it up ──▶ render
                                       │
                                  human gates the script
                                  (upstream, before the spend)

# same boxes, opposite causality.
# the second one cannot produce a video nobody wanted.
The shape a tool has when it holds no judgment·python
# Every stage is a pure-ish function of its inputs plus a cache.
# Nothing here decides WHETHER to run - only HOW, given that it was asked.

STAGES = {
    "check":     stage_check,      # hard rules: fail loudly, decide nothing
    "tts":       stage_tts,        # synthesize exactly the segments given
    "plates":    stage_plates,     # render exactly the scenes declared
    "clips":     stage_clips,
    "assemble":  stage_assemble,
    "validate":  stage_validate,   # measure; report; refuse to bless
}

def main(stage: str, force: bool = False) -> None:
    # No scheduler imports here. No 'if it's been a week' branch.
    # The only way this runs is that somebody typed it.
    STAGES[stage](episode_dir, force=force)

External links

Exercise

Find an automated job in your own systems that runs on a timer and produces something a person is expected to read — a report, a digest, a summary. Ask what happens on a period when there is genuinely nothing to say. Does it emit an empty artifact, a padded one, or nothing at all? Then redesign the trigger so that the interesting case (nothing happened) is representable without producing noise.
Hint
Watch for the artifact that is technically correct and completely uninformative — the weekly report where every field reads "no change." That is a schedule producing output because the schedule exists, and the fix is almost always to make the trigger an event rather than a clock.

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.