Each record captures one decision, the situation that forced it, and what it costs. Format is Michael Nygard's: context, decision, consequences.
| # | Decision |
|---|---|
| 0001 | Target .NET 10 and current C# |
| 0002 | Split the engine from the UI shell |
| 0003 | Render on the CPU, leave a GPU backend possible (user-directed) |
| 0004 | Author patches in a visual node editor (user-directed) |
| 0065 | A text language, which parses to a patch (user-directed; the pipe rule amended by 0144, the panel added by 0145, loops by 0208) |
| 0067 | A module keeps its name, and its memory, across a rebuild (user-directed) |
| 0068 | The file that was opened decides who owns the patch (user-directed) |
| 0119 | The website shows a module by photographing one (user-directed) |
| 0123 | A third program plays a patch and writes nothing (user-directed) |
| 0144 | A pipe lands where the text says (user-directed) |
| 0145 | The panel is written in the text (user-directed) |
| 0208 | The text has loops, unrolled as it is built (user-directed) |
| 0160 | A patch plays in a browser on the engine compiled to WebAssembly (user-directed) |
| 0162 | The editor runs in a browser, with the picture on a canvas of its own (user-directed; a few settings given back by 0182) |
| 0163 | A build draws every preset's still once, for every program to show (user-directed) |
| 0166 | flyback-cli shot draws the editor's window with no screen (user-directed) |
| 0183 | The binder is one walk, and what it asks for is handed nothing back (user-directed) |
| 0187 | The plate scrolls with the reading and folds into a pinned header (user-directed; supersedes 0122's pinned plate and right-hand name) |
| 0184 | The editor runs on Android, with its plugins linked in (user-directed) |
| 0211 | The editor builds for iOS as it does for Android (user-directed; its simulator run made daily by 0212) |
| 0189 | The architecture is a C4 model in Structurizr DSL (user-directed; superseded by 0204) |
| 0204 | The C4 views are Mermaid flowcharts (user-directed) |
| # | Decision |
|---|---|
| 0005 | Compile patches to a flat register machine |
| 0006 | Scalar interpreter parallelised over rows, not SIMD |
| 0007 | Values are register slots; scalars broadcast to colors |
| 0008 | Modules are data in a single catalogue |
| 0009 | Every input port carries an editable default (color ports and Output's left exempted by 0084; values moved to the tooltip on compact modules by 0149) |
| 0010 | Any-typed ports make maths modules polymorphic |
| 0011 | Compile backwards from the Output node (unread ops inside a reached module swept by 0096) |
| 0012 | Feedback is an explicit module, not a graph cycle (cycles superseded by 0075) |
| 0013 | Guard arithmetic instead of propagating NaN |
| 0014 | Coordinate and value conventions |
| 0021 | Recompile the whole patch on every edit |
| 0031 | A sequencer is eight inputs and no memory (user-directed) |
| 0032 | The registers are double precision |
| 0035 | A GLSL backend for the video path (time carried in two floats by 0137; Windows moved off ANGLE by 0155; export moved to the GPU by 0157) |
| 0137 | The clock reaches the GPU in two floats (user-directed) |
| 0155 | Windows draws through native OpenGL (user-directed) |
| 0157 | flyback-cli render draws on the GPU (user-directed) |
| 0214 | The picture draws through Metal on Apple's machines (user-directed) |
| 0215 | A picture is smoothed fast live and best on export (user-directed) |
| 0216 | A Mac's installed plugins live outside the bundle |
| 0167 | The shader reads a table as a float texture (user-directed) |
| 0040 | A probe is a second compile root, not a second machine (user-directed; what a sweep shares amended by 0143) |
| 0043 | A Scan is a Probe read backwards (user-directed; its Output knob superseded by 0077) |
| 0056 | A patch can be played, and what plays it is one opcode (user-directed) |
| 0048 | Time is seconds, and nothing else (user-directed) |
| 0050 | Normalled sockets carry a signal with no wire (user-directed) |
| 0051 | A quantiser's scale is a set on the node (user-directed) |
| 0052 | A patch names its samples rather than carrying them (user-directed; a built preset carries its own by 0151; drawn on the GPU by 0167) |
| 0059 | A picture comes in as a texture (user-directed) |
| 0053 | A Scope records what the speakers played (user-directed) |
| 0058 | The picture is told how loud the sound is (user-directed) |
| 0073 | An Analyzer is a Scope filled with a spectrum (user-directed) |
| 0203 | A Plot draws a pitch function as a curve in the picture (user-directed) |
| 0213 | A Raymarch is its scene written out once a step (user-directed) |
| 0181 | A Beam draws two taps against each other on phosphor (user-directed) |
| 0185 | A drawing is played by a plugin as three tables gone round once a cycle (user-directed) |
| 0054 | What a module carries is a part, not a subtype (user-directed) |
| 0055 | A plugin's extra declares its editor (user-directed; a fourth shape, text, added by 0104 and given several lines by 0105) |
| 0061 | What a module carries is kept in one store (user-directed) |
| 0062 | MIDI input is polyphonic through indexed voices (user-directed; a voice can belong to one channel, and a busy voice keeps what it held, by amendment) |
| 0099 | The computer keyboard can be laid out by scale, and the patch says how (user-directed) |
| 0086 | Panel knobs are read as live values, and a MIDI controller turns a knob rather than a socket (user-directed; a learn walks the panel and keeps a drum machine's channel by amendment) |
| 0170 | The knob panel randomizes, and a held knob sits it out (user-directed) |
| 0209 | A module rolls its own knobs, as an undo step (user-directed) |
| 0205 | A panel knob can be played as a switch or a button (user-directed) |
| 0139 | A patch keeps to an instrument's clock (user-directed) |
| 0179 | A MIDI file plays as tables read by the clock (user-directed) |
| 0140 | An instrument is known by a profile file (user-directed) |
| 0057 | A shape is a distance, and one module inks it (user-directed) |
| 0105 | Text is a shape, baked into a picture (user-directed) |
| 0095 | A module may be a handful of others, if it is exactly them (user-directed; the Bell it left out counted again and added by 0097; its "the engine's own presets may not need a plugin" reused for six primitives by 0128) |
| 0097 | A wrapping module carries a setting where what it wraps differed (user-directed) |
| 0130 | An Auto remap reads its ranges off its wires (user-directed) |
| 0104 | A formula is one block, and exactly the modules it names (user-directed) |
| 0106 | A sum in the text is one Expression (user-directed; its printing of every Expression as a call replaced by 0107) |
| 0107 | An Expression is printed as the sum it is (user-directed; a sum with a pipeline for an operand made a call by 0108) |
| 0108 | A preset arrives with its arithmetic folded into Expressions (user-directed; what it leaves alone narrowed by 0109) |
| 0109 | The Expression stands for the small Maths modules (user-directed) |
| 0064 | A pixel runs only what a pixel changes |
| 0074 | A cell is a plane on the video path (user-directed) |
| 0075 | A cycle carries its own delay (user-directed) |
| 0126 | A bus is a wire with no cable (user-directed) |
| 0174 | A polyphonic wire is lowered once per voice (user-directed) |
| 0076 | The processor runs a program as IL once it is built (user-directed) |
| 0096 | An op nothing reads is left out (user-directed) |
| 0143 | A module a sweep reads is lowered once wherever it reads the same |
| 0077 | The picture is heard only through a Scan (user-directed; its aspect table's shell-export row retired by 0078; its Live-engine row amended by 0083) |
| 0083 | The live engine's aspect follows the preview (user-directed) |
| 0084 | A socket with nothing to dial gets no knob (user-directed) |
| # | Decision |
|---|---|
| 0015 | Avalonia for the UI shell |
| 0016 | Build the UI in C#, without XAML |
| 0017 | Draw the node editor in one custom control |
| 0018 | Never render frames on the UI thread |
| 0039 | One window class, across a file per region (superseded by 0148) |
| 0044 | Lay patches out in layers, not with springs (user-directed; what becomes of a drawing too large for the canvas settled by 0092; runnable over a selection by 0110) |
| 0045 | What is copied is a patch file (user-directed) |
| 0046 | The module list is a gesture, not a panel (user-directed; a left-drag pan offered as a setting by 0182) |
| 0182 | Drag to pan is a setting that trades the left and right buttons (user-directed) |
| 0070 | A preset declares no coordinates (user-directed) |
| 0071 | Two undo stacks, and which one a press lands on |
| 0078 | Export leaves the shell for the CLI that already writes it (user-directed; its Output-panel Record… row moved to the toolbar by 0080; playing without the editor is 0123) |
| 0080 | Record moves to the toolbar, with a glyph and Ctrl+R (user-directed; its Output-panel Rewind row moved to the toolbar by 0081; its press given a count-in by 0090) |
| 0081 | Rewind moves to the toolbar, beside Record (user-directed; every take does it first by 0090) |
| 0164 | Volume is on the toolbar too (user-directed) |
| 0082 | The Output settings move to the settings window, and are kept (user-directed; its next-launch latency made immediate by 0085; kept in one file with every other setting by 0171) |
| 0171 | Every setting is kept in one file (user-directed) |
| 0087 | The assistant moves to a column, beside the patch (user-directed) |
| 0090 | A take is counted in, and starts at zero (user-directed; its fixed three seconds and unconditional rewind made settings by 0091) |
| 0091 | How a take begins is two settings (user-directed) |
| 0092 | A drawing too wide for the canvas shuts a box, and one that cannot fit moves nothing (user-directed) |
| 0110 | The layout can be given the selection instead of the patch (user-directed) |
| 0093 | A startup preset is a Graphics setting (user-directed; its row moved to Files by an amendment) |
| 0103 | Unsaved work outlives a crash (user-directed) |
| 0111 | The panel's actions are a row of glyphs (user-directed) |
| 0116 | A module is drawn as its category, and a standout as itself (user-directed) |
| 0117 | A module switched off is a wire (user-directed) |
| 0118 | A plugin paints its own module's background (user-directed) |
| 0121 | The window is left as it was left (user-directed) |
| 0129 | Full screen on another monitor is a window of its own (user-directed) |
| 0122 | The panel wears the block it is about (user-directed; the face it borrows is 0116) |
| 0124 | What two shells draw with is a project of its own (user-directed) |
| 0147 | A socket says what it is for, in words the panel and the assistant share (user-directed) |
| 0148 | The window is its hubs and the regions around them (user-directed; the layout and the keys handed to EditorView by 0162) |
| 0150 | The editor and the viewer are each composed in a container (user-directed) |
| 0194 | The editor's folders stand on a footing that names no feature (user-directed) |
| 0149 | Compact modules share rows and put their values in the tooltip (user-directed) |
| # | Decision |
|---|---|
| 0022 | Audio and video are two sinks over one patch |
| 0023 | Oversample the audio path rather than band-limiting modules (2× and a setting by 0168) |
| 0168 | The sound is oversampled 2× by default, and the factor is a setting (user-directed) |
| 0024 | Sample generation in the engine, the audio device in the shell |
| 0178 | A Line In hears the microphone while the sound plays (user-directed) |
| 0027 | Delay lines give the audio path a memory (user-directed) |
| 0029 | Linux sound through ALSA, on a thread of our own |
| 0190 | Linux sound goes through jackd when one is running |
| 0191 | The Sound tab picks the backend where more than one can play |
| 0192 | Windows sound plays through ASIO when it is picked (user-directed) |
| 0030 | Oscillators accumulate their phase on the audio path |
| 0036 | Export video as Motion JPEG in an AVI (user-directed; demoted to the fallback by 0089) |
| 0089 | ffmpeg encodes what it can, and the AVI is the fallback (user-directed) |
| 0154 | An MP3 sample is read by ffmpeg (user-directed) |
| 0049 | Record the GPU frame, not the interpreter (user-directed) |
| 0038 | A sequencer's notes are a list on the node (user-directed) |
| 0153 | An Arrangement is a grid of parts on the node (user-directed) |
| 0037 | One Output block, which every patch has (user-directed; its gain socket renamed volume by 0079; its picture settings moved to the settings window by 0082) |
| 0041 | A plugin can hold state without a new opcode (user-directed; the filter itself, and five more like it, moved into the engine by 0128) |
| 0042 | The clock and the memory flag belong to the emitter |
| 0079 | The gain knob becomes Volume, and nought is off (user-directed) |
| 0100 | Mastering is a plugin of stateful primitives (user-directed) |
| 0101 | A one-knob maximizer is a module of its own (user-directed) |
| 0125 | A Duck is a sidechain with the depth on a knob (user-directed) |
| 0128 | Filter, Random, Slew, Drive, Delay and Reverb are the engine's own (user-directed) |
| 0142 | Figures is three modules that are each a picture and a sound (user-directed) |
| 0146 | Fractals is three modules about one point c (user-directed) |
| 0152 | Easy is a synth and a drum that cannot be set wrong (user-directed) |
| # | Decision |
|---|---|
| 0019 | No third-party dependencies in the engine (read as being about dependencies rather than about programs by 0089) |
| 0020 | JSON patch files keyed by string type IDs |
| 0060 | A bundle is a patch and what it names (user-directed) |
| 0131 | Shared presets live on a site that only reads its media (user-directed) |
| 0136 | A letter goes to the author through the preset site (user-directed) |
| 0138 | The preset site starts with presets kept as files (user-directed) |
| 0151 | A built preset carries its files in its assembly (user-directed) |
| 0141 | The preset site starts with a plugin its build packs and the release key signs (user-directed) |
| 0175 | The preset site is a Worker, and GitHub reads what is submitted (user-directed) |
| 0176 | The preset site lives at flybackmodular.app alone (user-directed) |
| 0177 | The .NET site is gone (user-directed) |
| 0025 | Platform I/O behind plugins loaded at run time |
| 0026 | Modules may come from plugins, and the file records which (user-directed) |
| 0028 | Publish one platform at a time, with only that platform's plugins |
| 0063 | One plugin per platform, carrying its sound and its MIDI (user-directed) |
| 0102 | A plugin is compiled against a contract with a version of its own (user-directed) |
| 0132 | A plugin package says what it is, and installs only when asked (user-directed) |
| 0134 | A plugin declares its modules, and is refused for one it did not (user-directed) |
| 0133 | A shared plugin is unpublished until the admin publishes it (user-directed) |
| 0135 | A patch that names a plugin you do not have offers it (user-directed) |
| 0158 | A plugin loads only once somebody said yes, and never holds a key (user-directed) |
| 0033 | Patches may be authored by an agent, behind the plugin boundary (user-directed; its all-or-nothing prose budget replaced by 0098) |
| 0034 | Settings in a file, the key in the operating system's store (user-directed; the file made the one every setting shares by 0171) |
| 0088 | A release installs itself at the next start, if its signature says it is ours (user-directed) |
| 0127 | The person chooses what opens a Flyback file (user-directed) |
| 0120 | Every change passes the gate a release passes |
| 0193 | The pages are checked in a headless Chromium the gate carries |
| 0195 | CI runs on GitHub's runners on every OS; the self-hosted ones are by hand (user-directed; superseded by 0212) |
| 0198 | A release ships the Android editor as an APK signed with the release key (user-directed) |
| 0197 | Dependabot's updates arrive as one pull request and merge when Build passes (user-directed) |
| 0199 | The Microsoft Store gets an MSIX the Store signs and updates (user-directed) |
| 0200 | macOS runs by hand and before a release, not on every push (user-directed; superseded by 0212) |
| 0212 | macOS runs on every push; the device runs and the measuring run daily; no self-hosted runners (user-directed) |
| 0196 | A tutorial step is a patch the editor checks against |
| 0094 | A run says what it played, and nothing about who played it (user-directed; two more events and a wait at the end added by 0103) |
| 0103 | A run says how it ended, in bands (user-directed; the modules picked and more of the editor added 2026-09-28) |
| 0047 | The agent gets an ear, which is a second model (user-directed) |
| 0066 | A second wire format, so one model can hear what it built (user-directed) |
| 0069 | An assistant declares its own settings (user-directed; its field vocabulary shared with every plugin by 0085) |
| 0085 | A sound backend declares its own settings (user-directed; the backend itself picked by 0191) |
| 0072 | A conversation is saved with the patch it is about (user-directed) |
| 0098 | The briefing has a budget, and a list that outranks it (user-directed; its default raised to 100,000 by 0101) |
| 0113 | The workbench does not limit how large a patch is (user-directed) |
| 0115 | The assistant may read the presets (user-directed) |
| 0156 | A conversation follows its patch while the modules and wires hold (user-directed) |
| 0159 | A turn pays only for what is new (user-directed) |
| 0180 | A conversation is bounded by how large it has grown (user-directed) |
| 0161 | A turn is the host's, and a provider writes only its format (user-directed) |
| 0169 | The host's side of a conversation is a project of its own (user-directed) |
| 0172 | Claude Code is an assistant by running the program the person signed in (user-directed; superseded by 0201) |
| 0173 | Codex is an assistant the same way, and Gemini is not (user-directed) |
| 0201 | Claude Code is not an assistant until Anthropic says it may be (user-directed) |
| 0202 | A coding assistant the person runs edits the open patch over MCP (user-directed; its tools changed by 0210) |
| 0210 | The assistant edits the patch's text (user-directed) |
| 0186 | A decision model answers typed questions behind the plugin boundary (user-directed) |
| 0188 | What every host reads is a project of its own (user-directed) |
| 0206 | The gate has a ten-minute time budget (user-directed) |
| 0207 | Mutation testing plants bugs in each commit's diff (user-directed) |