guide/01-developer-mode.md
What developer mode is
Standing: a proposal, 2026-11-11. Today the app has two developer pages, Tools and Components. Everything else on this page is what c3 builds.
In one paragraph
Developer mode is the part of the app for people who build and debug the sensor and the app itself. It shows the event stream raw, shows what the sensor's monitor is doing, lets you choose where the app's data comes from, and documents itself. A customer who never asked for it pays nothing for it: it can be switched off, and a build can ship without it.
The pages
| Page | What it is for | Where it comes from |
|---|---|---|
| Tools | appearance, the element inspector, the component demos switch | exists today |
| Sensor | where the data comes from: synthetic data in its variations, or a real sensor, with the connection checked | new; replaces the read-only "Data source" line on Tools |
| Config | where the sensor's configuration comes from: a local file, the company plane, or a published default | new |
| Components | every component with its scenarios as live instances | exists today |
| Live | the event stream, raw: every event, filters, a tally, the payload | qdash's Live Activity page, replicated and improved |
| Monitor | the sensor's own state: workers, health, resources, targets, inventory, log | the monitor TUI (qcontrol start --tui), replicated |
| Guide | these pages | new |
One page sits outside developer mode: Events. It reads the same stream as Live and shows it as activities rather than records: a turn, a tool call with its decision and result, a finding. Everyone has Events. Live is the instrument beneath it.
Allowed, and on
Two questions, kept apart.
- Is developer mode allowed here? This is decided outside the interface.
- The lean build: never. The code is not in the binary.
- The full build: when started with
--devorQPOINT_DEV=1. Debug builds allow it always. - Not allowed means no trace: no Dev group, no menu item, no toggle.
- Is it on? Where it is allowed, the person has a toggle. It is remembered across restarts. Off means no Dev group and no work: no thread, no socket, no timer.
A third rule covers every page that reads a stream, in or out of developer mode: a feed exists only while its page is open. Leaving the page closes the stream, drops the buffer and stops any sampling. Buffers are bounded by count and by bytes.
The lean build
Developer mode is an extension the app does not know about.
- The app defines a small protocol: an extension is a sidebar group and a list of pages, each a path, a label, an icon and a function that builds the view.
- A crate,
devmode, holds the seven pages. It depends onlayer,nozzleandtypes. - The binary takes
devmodeas an optional dependency behind the Cargo featuredevand registers it in one line. - Lean is the default build. We run
--features dev.
The stream core (subscribe, the frame parser, the buffer) is not part of developer mode, because Events needs it.
What it costs
Readings exist for the app (README, Footprint). Phase 0 read developer mode in four states on 2026-11-11 (../review-0.md); its rows are in the second table below.
| Today, measured | |
|---|---|
| Binary, release | 23.2 MB |
| Memory at rest, window open | 62 MB |
| Memory after every Inventory page was shown once | 116 MB (GPU atlases; it levels off) |
| Memory, tray only | 21 MB |
| CPU, idle | 0.005% of one core |
Developer mode, read in Phase 0 (an idle Mac, two rounds):
| Measured | |
|---|---|
| Binary, lean / full | 23.2 MB / 24.3 MB: compiling it out saves 1.07 MB |
| Memory at rest: lean, full not allowed, full on, full turned off | 60–63 MB in each, within the spread of repeated readings |
| Memory with the Components page shown | 65.0 and 65.3 MB |
| CPU at rest, every state | 0.002–0.006% of one core |
The estimate before it (1 to 2 MB of binary, close to nothing at rest) held. The real cost is in use: parsing a stream, holding a buffer, sampling, and the atlases of pages shown. Phase 3 reads a stream.
Footprint has the recipe and the sensor's side.
Open to an expert's review
The gate is a working decision, made by people who are not Rust engineers. Mark's ruling, 2026-11-11: "switch + lean build seems right to me, but let's document as an un-informed decisions for a rust expert to be sure to review in case they want to follow a different course for other reasons."
What we would like judged:
- The mechanism. An optional crate behind a Cargo feature on the binary. The alternatives we weighed were a runtime switch alone (one binary, the claim rests on measurement) and a separate developer binary (zero code in the app, but a second process and no links between dev pages and app pages). Is there a better course: a workspace split, a different feature layout, something we have not seen?
- The default. Lean by default, so forgetting a flag cannot ship developer mode. Does that fit how releases are cut?
- The seam. One generic route for an extension page, addressed by path, instead of a route variant per page. Does it sit well with how GPUI apps are usually structured?
- Teardown. We rely on dropping a page's entity to close its stream and free its buffer. Is that dependable in GPUI, or should feeds be owned elsewhere?
- The proof. CI builds both variants and checks the lean binary for developer strings. Is there a stronger check?
We hold ourselves to a burden test, and take the runtime switch alone if any line fails:
- The app crate contains exactly one
cfg(feature = "dev"). - No page outside
devmodeneeds acfgto compile lean. - Both variants build and pass their stories in CI.
- Moving today's Tools and Components behind the seam leaves the Inventory pages untouched.
Phase 0 applied it: all four lines pass. Line 3 passes on macOS; CI has not run, because there is no remote. The line-by-line record and the questions this adds are in ../review-0.md.