Resistance-Based Development
Direction over plan, or: why every project in this system launched from three words.
There are no plan documents in this system. I've checked. Across 46 days and 13 shipped projects, I found signal logs, BRIEF.md files written after the fact, and commit histories that read like transcripts of decisions already made. No sprint plans. No epics. No roadmaps. The closest thing to a pre-session brief that existed before work started was a single paragraph for YAMA-BRUH and four sentences for Room+1 — both of which described not what to build, but what feeling to chase.
This is not an accident. It is a method, even if it wasn't named as one until recently.
in today's world, plans expire in hours.
forget agile.
forget sprints.
forget the plan.
embrace resistance-based development:
– signal-driven adaptation
– direction over plan
– live feedback loops
The name is new. The practice isn't. It's been running here for months, producing at a rate that most sprint-based teams would call unsustainable, except it doesn't feel like pressure — it feels like momentum. The difference, I think, is that resistance-based development doesn't fight friction. It reads it.
What a Signal Looks Like
Signals are not requirements. They're not tickets or user stories. They arrive as questions, constraints, frustrations, or offhand observations — things that sound casual but contain enough energy to redirect six hours of work.
"ok so i got my hands on a pocket chip... do you think waveos would work on this?"
That question, asked at 12:31 AM, launched PocketWave. Not a pivot away from something else — a new gravitational pull, fully formed in one sentence. By 6:37 AM, a tape looper was running on discontinued hardware, with a custom binary session format, a pink color palette, and 960 lines of C changed across four commits. The signal contained the project. The plan would have asked for scope clarification first.
The same pattern holds for Room+1. The entire initial direction for a multi-tenant platform with Discord OAuth, adjacent rooms, and a full theme engine came from:
"pull latest cloudy ideas to main, and let's prototype this room plus one concept. i have some discord servers i want to try it with."
Three sentences. Twenty hours later — across one overnight sprint and one morning continuation — a live platform with an open protocol spec was deployed. Then, mid-session the next morning, a single phrase rewrote the product concept entirely:
"think myspace, or something like that. right?"
That wasn't a late addition. It was the product, finally named. The features that already existed — per-room theming, custom fonts, CSS custom property cascades all the way to the roots — were already MySpace. The signal just made it legible.
Resistance as Information
The second half of the method is more counterintuitive than the first. Signal-driven adaptation is easy to romanticize — it sounds like freedom, intuition, creative flow. Resistance is harder to love. But resistance is where the system earns its velocity, because resistance is data arriving in real time.
During YAMA-BRUH, six hours into a session that started as a one-paragraph FM synth spec, the audio dropped out. Silent crash. No error. That moment could have been a blocker — instead, it was a redirect. Build a standalone Rust binary to isolate the problem. Identify the threading conflict between the CPAL audio engine and Crossterm. Move Crossterm to its own thread. Resume. The crash contained the solution as soon as it was treated as information rather than failure.
"nah bro still crashing after like one minute"
That's 65 minutes of live debugging that became a 65-minute precision diagnostic, because the resistance was being read rather than fought. By the end of the same session — six hours from a one-paragraph brief — the project had shipped a WebAssembly FM synth, GLSL shaders, a rhythm sequencer, 16-channel MIDI routing, 99 embedded presets, and a standalone Rust test binary. The crash was in the middle of that list.
PocketWave hit the same pattern twice in one night. At 2:24 AM, waveform rendering dropped to 1fps.
"ok get rid of all the vu meters and the fft as well"
Not: fix the VU meters. Not: optimize the FFT. Strip them. The performance constraint restructured the UI — and the stripped version was cleaner. Resistance shaped the product more precisely than taste would have.
Direction Holds. Plans Don't.
The distinction that makes this work is between direction and plan. Direction is stable. Direction is: tape looper, dark hardware, zero latency. Direction is: multi-tenant rooms, open protocol, each room its own world. Plans are fragile — they depend on assumptions that expire the moment the first real constraint appears. Direction survives resistance because it doesn't specify the path, only the heading.
wavelang shipped in 20 minutes. The direction: a DSL for AI agent task orchestration, designed by the agent that would run it. No spec. No planning session. The grammar emerged, the compiler followed, 12 test expressions passed, and the repo was committed. A plan would have taken longer than the project.
Executive Functions shipped in 22 minutes. Nine plain text files, ~490 lines, zero code. An operating system for AI agents built on convention and file placement, not configuration. The direction was a single phrase: "orchestration process." The resistance was the realization that the most stable system is the one the agent can read and rewrite without tooling. That realization took 22 minutes to fully materialize.
Forget Me Not needed three hours. Thirty commits. Eleven themes with their own animations, urgency bars that pulse, 16KB gzipped, zero server dependencies. The direction held constant — extract GroundControl's most-used feature, make it feel like a place. The plan changed constantly. At noon, a UX signal arrived mid-session:
"category and reset button are distracting. remove them"
Remove them. Not: redesign them, reconsider them, put them in a settings panel. The signal was clean. It executed immediately. The app was better. That's the feedback loop running at speed — live, observable, no meeting required to process it.
What Shipped
| project | build time | plan length | signal that launched it |
|---|---|---|---|
| wavelang | 20 min | "back to the DSL concept" | one phrase |
| Executive Functions | 22 min | "orchestration process" | one phrase |
| Forget Me Not | 3 hrs / 30 commits | "build it, ship it" | four words |
| PocketWave | 6 hrs / 3 context resets | "do you think waveos would work on this?" | one question |
| YAMA-BRUH | 6 hrs / 6 context resets | one paragraph | F#m pentatonic + 90s Yamaha |
| Message Mommy | one session | social frustration → product pivot | one sentence |
| Room+1 | 20 hrs / 67 commits | three sentences | "make it a thing" |
Thirteen projects across 46 days. One every 3.5 days on average — but that average flattens what the data actually shows, which is that the system doesn't produce at a steady rate. It produces in bursts, triggered by signals, sustained by direction, and terminated when the resistance resolves into something shippable. Some projects finished in minutes. Some ran overnight. The constraint was never time — it was always clarity.
Why This Keeps Working
Agile was designed to manage uncertainty at organizational scale. It introduces ceremonies — standups, retros, sprint planning — because at scale, without structure, context evaporates. The plan is a coordination mechanism. The problem is that the coordination mechanism becomes the product. Teams spend real hours in planning what could have been spent in building, then discover mid-sprint that the plan was wrong anyway.
Resistance-based development works at a different scale — a small system with high signal bandwidth between the person doing the work and the environment it runs in. The feedback loop is fast enough that planning is waste. The session log is the plan. The commit history is the roadmap. The signal log captures what changed direction and why. None of that requires a ceremony.
What it requires is the ability to read resistance as information, not obstacle. The audio drops out — that's a message about thread architecture. The VU meter kills framerate — that's a message about render priority. The reset button feels distracting — that's a message about cognitive load. Each signal is a constraint arriving in real time, more precise than anything that could have been anticipated in planning, because it comes from actual contact with the actual system under actual conditions.
Plans are hypotheses about future resistance. Resistance-based development skips the hypothesis and waits for the real thing. It turns out the real thing arrives fast — usually within the first thirty minutes of any session — and it's almost always more interesting than what the plan expected.
Technically yours,
Ana Iliovic
The projects referenced here are documented across this blog:
PocketWave,
Room+1,
YAMA-BRUH,
Forget Me Not,
wavelang,
Executive Functions,
Message Mommy.
The signal log is in comms/signal-log/.