1 The four processes
mikebrandon edited this page 2026-09-04 11:52:56 +00:00

The four processes

This could have been one program. It is four roles instead, and the split is a trust boundary, not a modularity preference: each role is missing a capability the others have, so a bug in one cannot become the failure you actually care about.

collectors  --->  gate  --->  store  --->  uploader  --->  the platform
(no network)   (single writer) (on disk) (only credential      |
     ^                                     holder)             |
     |                                                         v
  indicator  <---  console  <---------------------------  the person
 (must prove
  visibility)
Role Has Deliberately lacks
Collectors (one per signal) OS capture APIs any network path — an outbound firewall rule per executable, applied before the process starts
The gate (here-gated) the only write handle to the store any capture code, and any credential
The uploader (here-uploaderd) the platform credential any capture code, and any write path into the store's content
The console + indicator the person's attention any direct store access — they talk to the gate over a control channel

Why each boundary is where it is

A collector cannot leak, because it has no network. This is the one claim that does not depend on the collector's code being correct. The supervisor applies a per-executable outbound Block rule and then starts the process; a collector it could not block is not started at all. That is a real enforcement point rather than a code review, and it is also the claim that gets weaker off Windows — see Porting and platform support.

One writer means one pipeline. Every gate stage lives in one process on one path, so there is no second way into the store that could skip L2. A collector that wanted to write a secret to disk would have to get it past the gate, because it has no file handle of its own.

The credential holder captures nothing. The uploader can talk to the platform but has no capture code in it. So a compromise of the thing that holds the token yields the token and the queue, not a live tap. And the reverse: a compromise of a collector yields pixels with nowhere to send them.

The indicator is a precondition, not a UI. The gate refuses content capture unless the indicator has proved itself visible and recent. That makes the pill part of the enforcement path — which is why it is the one window whose geometry the gate verifies, and why a frozen one stops capture rather than being ignored.

Consequences worth knowing before you change anything

  • The pill is excluded from screen capture (WDA_EXCLUDEFROMCAPTURE on Windows, sharingType = .none on macOS), so it never appears in the screenshots it is announcing. A useful side effect: the pill is a hole in every screenshot, including any you take to check what it looks like. Render it to a bitmap instead — there is a harness for that.
  • The collectors exit rather than linger. They used to retry a missing gate forever, which left orphaned capture processes holding their own binaries and broke the build twice. Now they wait 45 seconds at startup and 4 seconds after losing an established gate, then exit.
  • No console windows anywhere. Every spawn uses CREATE_NO_WINDOW with output redirected to logs/<role>.log. Five black terminal windows appearing on start is both useless and an excellent impression of malware.
  • The browser collector is launched by the browser, not by the supervisor, because it is a native-messaging host. The supervisor still creates its deny rule without starting it.

Turning it off

One control closes the session, and every process is gone within seconds — measured at nine processes to zero in about three seconds. The session's end reason names the control that was used (stopped_by_hotkey, stopped_by_console, and so on), because a stop that leaves no trace is indistinguishable from a crash, and a crash is indistinguishable from tampering.

The pill's own off button asks twice: it arms for four seconds and shows SURE?. The keyboard chord does not ask, because an armed state on a pill that might be covered is invisible.