{
  "generatedAt": "2026-11-03T04:22:40.191Z",
  "commit": "251b04bd7703452a0a5fc3220bda0ef13a91ff15",
  "source": {
    "roadmap": "docs/ROADMAP.md",
    "github": "mark1russell7/headroom"
  },
  "items": [
    {
      "id": "H0",
      "title": "The repository, the plan and the tracker",
      "status": "done",
      "statusClass": "done",
      "section": "The items",
      "line": 43,
      "links": []
    },
    {
      "id": "H1",
      "title": "The sampler: the memory counters, the owner of each process tree, the history in SQLite",
      "status": "done (v0)",
      "statusClass": "done",
      "section": "The items",
      "line": 44,
      "links": []
    },
    {
      "id": "H2",
      "title": "The leases: the pools, the admission rule, the queue, the release on process exit",
      "status": "done (v0)",
      "statusClass": "done",
      "section": "The items",
      "line": 45,
      "links": []
    },
    {
      "id": "H3",
      "title": "The daemon: the `resources.*` procedures on `runProcedureHost` over HTTP, and the `headroom` CLI",
      "status": "done (v0)",
      "statusClass": "done",
      "section": "The items",
      "line": 46,
      "links": []
    },
    {
      "id": "H4",
      "title": "The MCP face: the tools, and a long wait as an MCP task (after client CLI-11 and CLI-35)",
      "status": "later",
      "statusClass": "later",
      "section": "The items",
      "line": 47,
      "links": []
    },
    {
      "id": "H5",
      "title": "The hub: the organizer writes the state of headroom into the `resources` collection of the Fleet Hub",
      "status": "later",
      "statusClass": "later",
      "section": "The items",
      "line": 48,
      "links": []
    },
    {
      "id": "H6",
      "title": "Enforce on Windows: a job object with a memory limit, and a stop when the job closes",
      "status": "done: the job object, `--limit` and `--keep`",
      "statusClass": "done",
      "section": "The items",
      "line": 49,
      "links": []
    },
    {
      "id": "H7",
      "title": "Enforce on Linux and WSL: a cgroup with `MemoryMax`",
      "status": "later",
      "statusClass": "later",
      "section": "The items",
      "line": 50,
      "links": []
    },
    {
      "id": "H8",
      "title": "A Claude Code hook that sends each heavy command through `headroom run`",
      "status": "done: the hook fix is merged. Mark installs the plugin.",
      "statusClass": "done",
      "section": "The items",
      "line": 51,
      "links": []
    },
    {
      "id": "H9",
      "title": "Alerts: kernel pool growth and a commit charge near its limit, sent with `notify.send`",
      "status": "done: the alerts, and the pool tags with their drivers",
      "statusClass": "done",
      "section": "The items",
      "line": 52,
      "links": []
    },
    {
      "id": "H10",
      "title": "More resource kinds: Docker, the npm publish quota, GitHub Actions minutes",
      "status": "in progress: the slot `browser` for browser tests, by itself. Each other slot works with `--slot`.",
      "statusClass": "progress",
      "section": "The items",
      "line": 53,
      "links": []
    },
    {
      "id": "H11",
      "title": "The MCP gateway: one copy of each local MCP server for all the sessions, over HTTP",
      "status": "in progress: the gateway works, the rollout waits for the owners",
      "statusClass": "progress",
      "section": "The items",
      "line": 54,
      "links": []
    },
    {
      "id": "H12",
      "title": "Start the daemon at login, and start it again after a crash: `headroom service install`",
      "status": "done",
      "statusClass": "done",
      "section": "The items",
      "line": 55,
      "links": []
    },
    {
      "id": "H13",
      "title": "The resume plan: the command of each live session, for a reboot",
      "status": "done: `headroom resume-plan` also writes `~/.headroom/resume-plan.md`, and a drain writes it again (H34)",
      "statusClass": "done",
      "section": "The items",
      "line": 56,
      "links": []
    },
    {
      "id": "H14",
      "title": "Runaway alerts: a process above 4 GB that has no lease, or a process whose parent stopped. headroom reports to the organizer. It does not stop the process.",
      "status": "done",
      "statusClass": "done",
      "section": "The items",
      "line": 57,
      "links": []
    },
    {
      "id": "H15",
      "title": "The dashboard: a page of the daemon at `http://127.0.0.1:4730/`, and `headroom dashboard`",
      "status": "done",
      "statusClass": "done",
      "section": "The items",
      "line": 58,
      "links": []
    },
    {
      "id": "H16",
      "title": "The Dev Drive: the code and the package caches on a ReFS volume. `docs/DEV-DRIVE.md` gives the plan.",
      "status": "done: the move is done, the lessons are in `docs/DEV-DRIVE.md`",
      "statusClass": "done",
      "section": "The items",
      "line": 59,
      "links": []
    },
    {
      "id": "H18",
      "title": "Disk space: alerts for low free space, and headroom run waits on a full disk",
      "status": "done",
      "statusClass": "done",
      "section": "The items",
      "line": 60,
      "links": []
    },
    {
      "id": "H19",
      "title": "Disk: each job gets its own `TEMP` and `TMP` folder on the Dev Drive `D:`. The release removes it.",
      "status": "done: `headroom config job-temp`, a temp folder for each lease, `--keep-temp`, and the sweep of the daemon every 10 minutes",
      "statusClass": "done",
      "section": "The items",
      "line": 61,
      "links": []
    },
    {
      "id": "H20",
      "title": "Disk: who writes. The bytes that each session, MCP server and job writes, from the I/O counters of its processes.",
      "status": "done: one counter tracker gives the writes and the cores of each owner. `Status.writes`, the owners of each instance in `Status.resources`, the disk alert and `headroom status` name the owners. The store keeps the writes of each owner each minute.",
      "statusClass": "done",
      "section": "The items",
      "line": 62,
      "links": []
    },
    {
      "id": "H21",
      "title": "Disk: a report of what uses the space, and a safe cleanup. It removes only data that is disposable by definition. All other data goes to Mark first. The `*.before-devdrive` copies stay.",
      "status": "done: `headroom disk report [--drive] [--deep] [--json]` in the process of the command (a fixed list of places, a walk that follows no link or junction, a budget of 30 seconds or 3 minutes with partial sizes), the saved report and its dashboard card. `headroom disk clean [--apply]` deletes only the temp folders of ended leases, old trace files and, behind a gate, `pnpm store prune`. Each other large place goes to the list \"Ask Mark\". The disk alerts end with a hint to the report.",
      "statusClass": "done",
      "section": "The items",
      "line": 63,
      "links": []
    },
    {
      "id": "H22",
      "title": "One resource model: memory, disk, then CPU and more. Each resource has the same five parts: measure, attribute, alert, admit and enforce.",
      "status": "done: memory, disk, CPU, network and services are on the model. The design is `docs/RESOURCES.md`. Steps 1 to 4 shipped in #29, #30 and #31: the types, the broker on two admit modes, `Status.resources` and the alert rules. Step 5 makes disk a lease resource (`--disk 5g`, `--disk D:=5g`). Step 6 is H19. Step 7 is H20. Step 8 has its own item, H21.",
      "statusClass": "done",
      "section": "The items",
      "line": 64,
      "links": []
    },
    {
      "id": "H23",
      "title": "CPU on the resource model: the processors get the five parts of the model",
      "status": "done: the `cpu` alert (85% and 95% of the cores for 5 minutes), the runaway alert for a process tree above 4 cores for 10 minutes, `headroom config cpu-reserve` (2 cores for Mark), the hard cap of `--cpu N --limit` and the weight of each other job object, `--cpu auto` and the peak cores of each lease",
      "statusClass": "done",
      "section": "The items",
      "line": 65,
      "links": []
    },
    {
      "id": "H24",
      "title": "The network on the resource model: the throughput of the adapters, the dynamic TCP ports and the listening ports",
      "status": "done: `net:in` and `net:out` in MB/s, `ports:tcp` with the connections of each owner, the `ports` alert, `headroom ports` and `resources.ports`",
      "statusClass": "done",
      "section": "The items",
      "line": 66,
      "links": []
    },
    {
      "id": "H25",
      "title": "The dashboard: one panel for each resource, from the model",
      "status": "done",
      "statusClass": "done",
      "section": "The items",
      "line": 67,
      "links": []
    },
    {
      "id": "H26",
      "title": "The state of a job: `headroom job <name|id>`, for the fleet's typed wait `job:<name>`",
      "status": "done",
      "statusClass": "done",
      "section": "The items",
      "line": 68,
      "links": []
    },
    {
      "id": "H27",
      "title": "Service health: Docker, the MCP servers of the gateway, the fleet site",
      "status": "done",
      "statusClass": "done",
      "section": "The items",
      "line": 69,
      "links": []
    },
    {
      "id": "H28",
      "title": "UX round 1: the dashboard and the tracker. The dashboard shows what uses the computer, opens each panel to its history and shows the jobs on a timeline.",
      "status": "done",
      "statusClass": "done",
      "section": "The items",
      "line": 70,
      "links": []
    },
    {
      "id": "H29",
      "title": "Process starts by owner. Each new process leaks kernel memory in the AMD display driver until Mark updates it (hub ask `amd-driver`).",
      "status": "done: the resource `procs` in starts each minute, an exact total of the computer from the sequence numbers of Windows, exact counts of the leased jobs from their job objects, a lower bound for each owner with its jobs and its own commands, the alert `churn`, the line of `headroom status`, `processes` in `headroom job`. A parent counts only when it started at or before its child.",
      "statusClass": "done",
      "section": "The items",
      "line": 71,
      "links": []
    },
    {
      "id": "H30",
      "title": "Battery and power: the battery becomes a resource of the model. On battery, heavy jobs wait or run in the efficiency mode of Windows.",
      "status": "done: the resources `battery` (Wh) and `power` (W, the owners as an estimate), the power events of Windows, the sleep gaps in the leases, the rates and the charts, the alerts `battery`, EcoQoS for the jobs of `headroom run` on battery (`--no-eco`), a power request on AC power while a lease is granted, and the line `Power` of `headroom status`. The wait rules come with H31.",
      "statusClass": "done",
      "section": "The items",
      "line": 72,
      "links": []
    },
    {
      "id": "H31",
      "title": "Conditions for a job: plugged in, Mark away, no metered network, a cool CPU. A job waits for a condition, not only for an amount: `headroom run --when ac,away`.",
      "status": "done: the registry of the conditions with `ac`, `battery>=N` and `usage<N` (the usage window of the fleet, fail closed), `--when`, `--timing` (waits for AC power), the battery floor for heavy jobs (`headroom config battery-floor`, `--battery-ok`), the admission at the tick of a power event, and the record of a job that runs without its condition. The planned names point to H33 (`away`), H35 (`cool`), H39 (`unmetered`) and H42 (`night`).",
      "statusClass": "done",
      "section": "The items",
      "line": 73,
      "links": []
    },
    {
      "id": "H32",
      "title": "A forecast for each resource: the time to a limit, from its history. The fleet acts before the limit, not at it.",
      "status": "done: a Theil–Sen fit of the last hour with Kendall's tau as its confidence, the targets from the alert limits, the time left of Windows for the battery, `forecast` in `Status.resources`, the alert `forecast` (a drive at its critical level within 24 hours, a pool at its alert level within 2 hours, the commit charge at 90% within 30 minutes), `headroom forecast`, the line of `headroom status` and a line on each card of the dashboard",
      "statusClass": "done",
      "section": "The items",
      "line": 74,
      "links": []
    },
    {
      "id": "H33",
      "title": "Keep room for Mark: while Mark works or is on a call, heavy jobs wait or run slower. When Mark steps away, they run.",
      "status": "done: the state `present`, `busy` or `away` from the session events, the last input, the notification state and the camera and the microphone (no app names), the condition `away`, the busy wait of heavy jobs (`headroom config busy-wait`, `--ignore-presence`), EcoQoS for heavy jobs and a larger CPU reserve while Mark is at the laptop, no reserve while Mark is away, `headroom config presence off`, the line `You` of `headroom status`, `headroom presence` and the chip of the dashboard",
      "statusClass": "done",
      "section": "The items",
      "line": 75,
      "links": []
    },
    {
      "id": "H34",
      "title": "The reboot budget and a planned drain. headroom forecasts when the kernel leak of the AMD driver needs a reboot, and offers a reboot window. The resume plan (H13) brings the fleet back.",
      "status": "done: `headroom reboot-plan` and `Status.reboot` (the pools, their growth and forecast, a waiting Windows update, the uptime and a recommendation), `headroom drain --at --until --cancel` with the alerts `drain` and `drain:ready`, `--during-drain`, the drain in the settings, the resume plan file, a line of `headroom status` and of the dashboard",
      "statusClass": "done",
      "section": "The items",
      "line": 76,
      "links": []
    },
    {
      "id": "H35",
      "title": "Heat and throttling: when heat or a power limit slows the CPU, timing tests and benchmarks wait, because their numbers are wrong.",
      "status": "done: the speed limit, the speed, the frequency and the thermal zones from the PDH query of the Energy Meter, the resource `thermal` (%), the throttle rule (a limit over 10% or a passive limit, for 30 seconds), the alert `heat` with the owners and their leased jobs, the condition `cool` (`--timing` waits for it), `headroom thermal`, a status line and a dashboard chip",
      "statusClass": "done",
      "section": "The items",
      "line": 77,
      "links": []
    },
    {
      "id": "H36",
      "title": "GPU for each process: the GPU uses the main memory, so GPU memory counts against memory, and each session sees its share.",
      "status": "done: the resource `gpu:<n>` for each adapter (the GPU memory from 5 wildcard counters of PDH in the query of the Energy Meter, the limits from DXGI one time), the GPU memory and the engine use of each owner and of each leased job, the peak GPU memory of a lease, the alert `gpu` (above 90% for 2 minutes), the line `GPU` of `headroom status`, `headroom gpu` and a dashboard panel for each adapter. Windows already counts the shared GPU memory in the available memory, so `memory` does not subtract it.",
      "statusClass": "done",
      "section": "The items",
      "line": 78,
      "links": []
    },
    {
      "id": "H37",
      "title": "Disk speed, SSD wear and disk limits for jobs. A cap on the disk rate of a job keeps the computer fast for the other jobs.",
      "status": "later",
      "statusClass": "later",
      "section": "The items",
      "line": 79,
      "links": []
    },
    {
      "id": "H38",
      "title": "Docker inside: the memory, CPU and disk of each container, by session. The Docker VM shows as one big process, so headroom asks the Docker engine.",
      "status": "done: a Docker client in the daemon (GET requests on the pipe of the engine from the tick, no process), the containers every 30 seconds and `GET /system/df` every 10 minutes, the owner of each container from the folder or the name of its compose project and the fleet roles, the split of the owner `docker` into the owners of the containers and `docker (VM)`, the memory of `vmmemWSL` from `SystemProcessInformation`, `Status.docker`, the alert `docker` (build cache above 20 GB, images with no container above 10 GB), the line `Docker` of `headroom status`, `headroom docker` and a dashboard card.",
      "statusClass": "done",
      "section": "The items",
      "line": 80,
      "links": []
    },
    {
      "id": "H39",
      "title": "Network cost: on a metered network, big downloads wait. While the network is offline, the jobs that need it wait and do not fail.",
      "status": "later",
      "statusClass": "later",
      "section": "The items",
      "line": 81,
      "links": []
    },
    {
      "id": "H40",
      "title": "Budgets outside this computer: the GitHub API quota that all sessions share. A job can wait for room in it. Claude usage stays with the usage meter of the organizer.",
      "status": "later",
      "statusClass": "later",
      "section": "The items",
      "line": 82,
      "links": []
    },
    {
      "id": "H41",
      "title": "Things that expire: certificates, the npm trust, tokens and keys. headroom shows the time left and alerts before each one ends.",
      "status": "later",
      "statusClass": "later",
      "section": "The items",
      "line": 83,
      "links": []
    },
    {
      "id": "H42",
      "title": "Quiet hours and the overnight window: a CPU cap at night for quiet fans, or big test suites that wait for the night. Mark picks the hours.",
      "status": "later",
      "statusClass": "later",
      "section": "The items",
      "line": 84,
      "links": []
    },
    {
      "id": "H43",
      "title": "Clean-grid timing: jobs that can wait run when the New England grid is cleanest. The effect is small, so this item is last.",
      "status": "later",
      "statusClass": "later",
      "section": "The items",
      "line": 85,
      "links": []
    },
    {
      "id": "H44",
      "title": "Fix: the Angular completion in `~/.bashrc` starts node in each login shell, 13 times a minute, only from two sessions that run with no shell snapshot. A restart of those sessions stops it.",
      "status": "waits for Mark",
      "statusClass": "waiting",
      "section": "The items",
      "line": 86,
      "links": []
    },
    {
      "id": "H45",
      "title": "Fix: VS Code polls Docker every 2 seconds. Mark closes the Containers view of VS Code when it is not in use. If the poll continues, Mark turns off the extension in the workspaces that do not use Docker.",
      "status": "waits for Mark",
      "statusClass": "waiting",
      "section": "The items",
      "line": 87,
      "links": []
    },
    {
      "id": "H46",
      "title": "The peer of a local connection: `resources.peer` gives the process, the nearest `claude.exe`, the session and the fleet role at the other end of a loopback TCP connection. The fleet site uses it for its MCP face (server-stack fp-mcp). Also `headroom peer`.",
      "status": "done",
      "statusClass": "done",
      "section": "The items",
      "line": 88,
      "links": []
    },
    {
      "id": "H47",
      "title": "Jobs that start many processes do not run beside browser tests. The lease keeps its peak starts in one minute. A job name whose past runs are above 600 a minute is spawn-heavy, and a first run becomes spawn-heavy when it goes above the limit. A spawn-heavy lease and a browser test wait for each other, in the queue order. Also `--spawn-heavy`, `--no-spawn-heavy` and `headroom config spawn-heavy`.",
      "status": "done",
      "statusClass": "done",
      "section": "The items",
      "line": 89,
      "links": []
    },
    {
      "id": "H48",
      "title": "Runaway handles and the owners of orphans. On 2026-10-25, an orphan `find.exe` of a session held 1.3 million handles, the paged pool grew 593 MB an hour, and headroom named no owner. The alert `handles` (`runaway:handles:<pid>`) warns above 100,000 handles or a gain of 20,000 in 5 minutes, and is critical above 500,000. The daemon records the owner and the command line of each process at its first read, and the table `process_owners` keeps them over a restart. An orphan shows as `<owner> (orphan)` in the owners lists and the CPU runaway alert. `headroom status` gives the sum of the handles.",
      "status": "done",
      "statusClass": "done",
      "section": "The items",
      "line": 90,
      "links": []
    },
    {
      "id": "H49",
      "title": "The memory of the processes that headroom cannot open. On 2026-10-25, the protected services and the minimal processes counted as 0, approximately 7.5 GB. One read of `SystemProcessInformation` gives the private memory and the private working set of each process, with no open. The minimal processes have their own owners (`system:memory compression`, `system:registry`, `system:secure system`), and the VM stays in `docker (VM)` one time. Three new kernel owners give the locked pages, the PFN database and the page tables. The row `unattributed` of `headroom status`, the top bar and the memory card of the dashboard give the memory in use that no owner holds: 4.0 GB, mostly the shared pages. `headroom docker` gives the local clock.",
      "status": "done",
      "statusClass": "done",
      "section": "The items",
      "line": 91,
      "links": []
    },
    {
      "id": "H50",
      "title": "The system file cache. On 2026-10-25, the cache grew to 10.1 GB two times, the available memory stayed near 1 GB for 22 minutes, and the reaper of Claude Code stopped jobs. Windows Search read 350 MB each second from the files of the sessions. The owners `system:search` and `system:defender` show the indexer and the scanner. The engine counts the reads of each owner. The alert `cache` warns when the cache holds 4 GB or more and less than 6 GB is available, and names the top readers and writers. headroom does not trim the cache: the daemon has no privilege for it. Mark removes `D:` from the scope of Windows Search.",
      "status": "in progress",
      "statusClass": "progress",
      "section": "The items",
      "line": 92,
      "links": []
    },
    {
      "id": "H51",
      "title": "The alert names the driver of each pool tag that grows. On 2026-10-29 the alert named no driver for the ReFS tags (`MSb+`, `MSpa`, `MSde`): `driversOf` did not search `System32\\drivers`, because Windows refuses its subfolder `DriverData` (fixed: `sysFiles` skips that subfolder). Next: give one line for each growing tag in the alert, with its driver and the advice of docs/DEV-DRIVE.md, \"The pool tags and their drivers\".",
      "status": "next",
      "statusClass": "open",
      "section": "The items",
      "line": 93,
      "links": []
    },
    {
      "id": "H53",
      "title": "The growth of each pool tag since the start of Windows. On 2026-11-02, after 107 hours, the paged pool was 4.17 GB and the non-paged pool 3.76 GB, and headroom could not tell which tags grew since the start: the store keeps the tag snapshots for 2 hours only, and `pool-tags` gives the largest tags of the non-paged pool only. The store keeps the first snapshot after each start of Windows and one snapshot each hour for 7 days. `headroom pool-tags --since boot` (or `--hours <n>`) gives the largest tags and their growth in both pools, with their drivers. The dashboard shows a chart of the top tags since the start. The data of 2026-11-02 before the restart is in `docs/data/pool-before-reboot-2026-11-02.txt`.",
      "status": "next",
      "statusClass": "open",
      "section": "The items",
      "line": 94,
      "links": []
    },
    {
      "id": "H54",
      "title": "Move `packages/daemon/src/service.ts` onto `./host` of `@mark1russell7/service` 0.6.3 (install, status, instance lock, discovery, stop by pid). Optional.",
      "status": "later",
      "statusClass": "later",
      "section": "The items",
      "line": 95,
      "links": []
    }
  ],
  "pullRequests": [
    {
      "number": 130,
      "title": "chore(deps): update pnpm to v12.16.1",
      "url": "https://github.com/mark1russell7/headroom/pull/130",
      "author": "renovate",
      "branch": "renovate/pnpm-12.x",
      "draft": false,
      "createdAt": "2026-11-02T07:57:33Z",
      "updatedAt": "2026-11-03T02:05:26Z",
      "labels": [
        "dependencies"
      ],
      "checks": "success"
    }
  ],
  "issues": [
    {
      "number": 3,
      "title": "Dependency Dashboard",
      "url": "https://github.com/mark1russell7/headroom/issues/3",
      "author": "renovate",
      "createdAt": "2026-10-19T23:38:37Z",
      "updatedAt": "2026-11-03T04:22:14Z",
      "labels": []
    }
  ],
  "github": {
    "available": true,
    "totals": {
      "pullRequests": 1,
      "issues": 1
    }
  }
}
