← Dev Journal

One list for everything

After chapter one · Part 2 · series ongoing

What do you do when the plan grows while you’re in the middle of it?

Every team I’ve led has had to answer that question, usually more than once a month. A bug shows up that nobody planned for. A stakeholder walks over with a “small” request. Halfway through a task, you find out the task was actually three tasks. There are a lot of names for this: feature creep, scope creep, found work, discovered tasks. My answer to all of them is the same, and it’s not a clever one. They all go on one list, and that list gets prioritized against the work you’ve already committed to.

I’ve been teaching that rule for most of my career. What I didn’t notice, until I went back through the commit history for this post, was that I’d been running it on MoVox too, on a project with exactly one person on it.

The plan was one to two weeks.

At the end of the last post, the feedback on chapter one had given me a new job: a 白话 version, the story told in plain modern Chinese instead of the original classical text. The first episode would be 三顾茅庐, chapters 36 to 38.

The scope was small on purpose. The picture side of the pipeline already existed and worked: the ink paintings, the realistic clips, the editor that puts it all together. Chapters 37 and 38 still had to be drawn and reviewed, but that was running tools I already had, the way I’d done for chapter one, and both versions would share the same pictures. The new work was all text and audio. Rewrite the text, voice the new text, build both versions of each chapter on one set of keyframes and clips, ship both. I expected a week, two at the most.

It took four. Chapter 37 went up on October 28, chapter 38 on October 31. And what shipped was not the thing I planned.

Then the list grew.

Three kinds of things showed up, and they showed up in no particular order.

Feedback. The realistic clips weren’t realistic enough. I told that story in the last post: my wife, who’s also the art director, called them “a human-like photo pasted on top of a cartoonish drawing,” and she was right. So the whole photo step got rebuilt.

A new idea. My wife and kids were watching YouTube one evening and found AI-made music videos where 孙悟空 and 猪八戒, or 刘邦 and 苏轼, were singing modern rock and rap. The kids thought it was cool. We got talking about whether I could do something realistic like that, with our characters actually speaking their lines. I did some research (with Claude’s help) and it turned out to be feasible, on my one card, using only models under the same permissive licenses (Apache 2.0 or MIT) that every model in MoVox has to meet. I explained why that rule exists in the license post. That’s how lip-sync showed up. Nobody had planned it.

Bugs. The new work kept turning up old problems, because 白话 put the pipeline through a path it had never been through before. About a quarter of the dialogue had no voice of its own, because only the bigger characters had ever been given one. Some lines were attributed to the wrong speaker. 张飞’s voice changed pitch from one emotion to the next, and that turned out to be a real limitation in how the voice model makes voices, not a setting. The machine read the 白话 particle 地 as dì (the noun, “ground”) instead of de. A scene cut in the wrong place quietly dropped the scene before it.

Each of these was real. Each one, taken alone, was worth doing. And if you just say yes to all of them as they come in, you get what every team gets: a two-week plan that’s still “almost done” two months later, and people working nights to close the gap.

The rule I’ve taught teams.

Here’s how it works in a scrum sprint, if you haven’t run one. At the start of the sprint, the team commits to a set of work, sized against how much the team can actually do in that time. That’s the capacity. Then the sprint starts, and the world keeps happening. Bugs, requests, discovered work, all of it goes to the product owner (PO, the person who decides what matters most for the product), and the PO prioritizes it against the work already committed.

Anything less urgent than the committed work waits for a later sprint. Anything more urgent gets pulled in, but here’s the part people skip: it doesn’t get added on top. It displaces the same amount of capacity off the current list, and the lowest-priority item gets bumped first. The sprint stays the same size. What’s in it changes.

That’s the whole rule. It’s my best effort at preventing scope creep and constant overtime, and over the years I’ve taught it as a leader at more than one company. It’s not because I’m against change. It’s because the alternative is pretending the team has more hours than it does. Trust me, you don’t want a burnt-out team.

I was the product owner, and I didn’t notice.

On MoVox, there’s no PO meeting. There’s just me. But looking back, every one of those new items went through exactly that filter, in my head.

Lip-sync wasn’t in the plan. But it gives the video a huge amount of value. A conversation between two people where their mouths actually move is a different kind of video from a narrator reading over paintings. And it combined with the photoreal request in a way that made the two of them worth more together than apart, because every lip-sync shot is made from the photo. If I’d built lip-sync on the old photos, I’d have rendered it all again once the photos changed. If I’d fixed the photos first and kept reviewing clips the old way, I’d have reviewed a lot of clips that lip-sync was about to replace.

So the decision on October 18 was: both of them, in sequence. Photo first, lip-sync second, and stop reviewing clips in the old style right away. Every shot would be reviewed exactly once.

And I want to be honest about what was actually expensive there, because it’s not what I first assumed. It’s not the GPU hours. A chapter takes days on the card, and the lip-sync pass on chapter 37 alone was 11.6 GPU-hours, but the card can run overnight while I sleep. It’s not even the hours of my time. I definitely didn’t spend 11 hours reviewing one chapter’s pictures.

The real cost is the loop. I need a block of time where I can sit down and go through the review. I flag something, and it goes off to be redrawn. By the time the redraw is done, I might not be at my desk anymore. So the review waits, and the redraw waits, and sometimes the whole pipeline waits not hours but a day or two until I can come back. Every redraw I could avoid wasn’t saving GPU time so much as saving one of those trips around the loop.

What went out to make room.

If something comes in, something goes out. Here’s what went out.

Everything 文言. The original plan was to ship both versions of chapters 37 and 38. The 文言 lip-sync pass and the 文言 rebuilds were the lowest priority on the list, so they got bumped. The 白话 versions went up alone.

Chapter 36. That was an early call, once the episode was 三顾茅庐. Chapter 36 is mostly unrelated to the visit itself, and once lip-sync needed most of an overnight run per chapter, cutting it saved real time. The episode is chapters 37 and 38.

Redoing chapter one. It stands on its own, and I decided to keep the old video as it is, as a record of where the project was. It’s useful to be able to look back at the work-in-progress versions.

The automatic review console. I designed it, and then decided it was lower priority than finishing the chapters, so it never got pulled in.

The real fix for the voices. 张飞 got a quick stop-gap, cloning every line from his one neutral clip. It’s a lower quality bar than the real fix, but the real fix needs proper planning, and once the stop-gap was in, it stopped being urgent.

None of these were a no. They’re all still on the list. I never officially had a backlog, but the list exists, in the state of the design docs and the issue tracker. When time allows and the need comes up, priorities shift, and something deferred gets bumped up and pulled in. That’s the right way to do agile: everything is fluid and keeps changing, and you welcome that instead of fighting it. The rule doesn’t stop change. It just makes every change cost something you can see.

So why did two weeks take four?

If you’ve been keeping count, you’ve noticed the problem. If something comes in and something goes out, the plan should stay the same size. It didn’t. Two weeks at most turned into four. So did the rule fail?

Partly, and it’s worth being honest about how.

First, my estimate was wrong. The text and audio work, the part that was really new, landed about where I said it would: the 白话 version of chapter 37 was voiced within a week, and the editor was building 白话 videos in about ten days. But the estimate also included reviewing the keyframes for chapters 37 and 38, which had never been drawn before. I knew that review was in there. I didn’t expect it to take as long as it did. That’s not scope creep, that’s a bad estimate, and it’s the most common kind of overrun there is.

Second, what came in was bigger than what went out. The 文言 versions, chapter 36 and the chapter one redo weren’t two weeks of work. Photoreal and lip-sync were more. At some point there’s nothing left on the list that’s lower priority than what’s coming in, and the rule runs out of things to bump.

When that happens, you have three levers left. You can cut more scope. You can move the date. Or you can add hours, which on a team means overtime. At work, the date is usually fixed, because something outside the team depends on it. So once the scope can’t give any more and the high-priority item still has to come in, overtime is the last resort. It happened on my teams more than I’d like, and I’m not going to pretend it didn’t. The rule never promised zero overtime. It promises that overtime is the last lever you pull, and that you pull it on purpose, instead of drifting into it because nobody ever said what would go out.

On MoVox, nobody was waiting on a date. It’s a side project, and the release is paced by my review, not by a launch. So the lever I pulled was the date. Did I also work more hours? Honestly, I can’t tell you. This is evenings after work, and some nights it runs past midnight either way. What I can tell you is that the date moving was a decision I made when lip-sync came in, not something I found out at the end.

The one I pulled in on purpose.

There’s one item that went the other way, and it’s my favorite.

All through chapter 37, every hand fix I made went into one issue: why this keyframe was wrong, what I did about it, grouped by cause. The plan was to sit down and do a retro on it after chapters 37 and 38 were both reviewed. I pulled that retro forward, between the two chapters, because it was paying down tech debt that would make chapter 38 faster. Chapter 37’s review was exactly where my estimate had gone wrong, and I didn’t want to be wrong the same way twice. It was the tooling that turned what I’d been checking by eye into checks the pipeline runs, and that made the review and the decisions in it a lot faster.

And it worked. Chapter 37 took weeks. Chapter 38 took days.

That’s an idea from a training I gave, called “Spend More to Save More.” The short version: spending time that doesn’t look like progress, on tools and process and thinking, often buys you back far more than it costs. And every decision about what to work on is itself an investment, so look at its ROI (return on investment) the same way you would anything else. 磨刀不误砍柴工: sharpening the axe doesn’t slow down the woodcutting.

Light process isn’t no process.

When you’re a small team, or a team of one, the instinct is to drop process. And for a lot of it, that’s right. I don’t need standups with myself, or a sprint board, or a planning meeting. The ceremony is overhead, and on a small project the overhead is a bigger share of the work.

But some of what those habits taught me is worth keeping even when the ceremony is gone. You still have a capacity, even if it’s one person’s evenings and one GPU. You still get discovered work, and it still needs to be weighed against what you already committed to. You still have to decide what’s worth doing next, and why. Drop all of that and you don’t get speed, you get chaos, and the chaos is what makes it slow.

Light process, not no process. The part to keep is the part that makes you ask, every time something new shows up: is this worth more than what it would push out?

The retro is also where the next post starts. It’s about what I learned from being the check by hand for a whole chapter, and why the fix was to write the check instead.