← Qnative (provisional) · c3

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

PageWhat it is forWhere it comes from
Toolsappearance, the element inspector, the component demos switchexists today
Sensorwhere the data comes from: synthetic data in its variations, or a real sensor, with the connection checkednew; replaces the read-only "Data source" line on Tools
Configwhere the sensor's configuration comes from: a local file, the company plane, or a published defaultnew
Componentsevery component with its scenarios as live instancesexists today
Livethe event stream, raw: every event, filters, a tally, the payloadqdash's Live Activity page, replicated and improved
Monitorthe sensor's own state: workers, health, resources, targets, inventory, logthe monitor TUI (qcontrol start --tui), replicated
Guidethese pagesnew

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.

  1. 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 --dev or QPOINT_DEV=1. Debug builds allow it always.
    • Not allowed means no trace: no Dev group, no menu item, no toggle.
  2. 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 on layer, nozzle and types.
  • The binary takes devmode as an optional dependency behind the Cargo feature dev and 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, release23.2 MB
Memory at rest, window open62 MB
Memory after every Inventory page was shown once116 MB (GPU atlases; it levels off)
Memory, tray only21 MB
CPU, idle0.005% of one core

Developer mode, read in Phase 0 (an idle Mac, two rounds):

Measured
Binary, lean / full23.2 MB / 24.3 MB: compiling it out saves 1.07 MB
Memory at rest: lean, full not allowed, full on, full turned off60–63 MB in each, within the spread of repeated readings
Memory with the Components page shown65.0 and 65.3 MB
CPU at rest, every state0.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:

  1. 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?
  2. The default. Lean by default, so forgetting a flag cannot ship developer mode. Does that fit how releases are cut?
  3. 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?
  4. 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?
  5. 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:

  1. The app crate contains exactly one cfg(feature = "dev").
  2. No page outside devmode needs a cfg to compile lean.
  3. Both variants build and pass their stories in CI.
  4. 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.

Qpoint Brand Style Guide