{
  "summary": "## Finding\n\n**Highest-confidence source of the residual v0.37 brain CPU bursts is the registry pump’s local re-advertisement pass, specifically repeated project-ID derivation from every endpoint session-ledger row.** This is not the already-fixed executable self-hash and does not require a poisoned connection to occur.\n\n### Cadence and field correlation\n\n- `crates/spt-daemon/src/config.rs:35-42` defines the peer-pump cadences; registry defaults to **30 s**.\n- The deployed `C:/Users/decid/AppData/Local/spt-core/daemon.json` confirms `registry_pump_period_ms: 30000` and `peer_pump: true`.\n- `crates/spt-daemon/src/pump/mod.rs:95-103` gives the scheduler a 200 ms tick, while `:587-591` initializes every worker’s last-run value to `None`, so all four pump legs run immediately after a brain refresh.\n- `crates/spt-daemon/src/pump/mod.rs:728-729` stamps the worker **after the entire round**, not when work begins. Therefore the registry burst is not on a rigid 30 s wall-clock grid: the next registry pass begins 30 s after the previous round finishes. With the current dead-peer 10 s dial waits, burst starts can be roughly 56 s apart rather than 30 s apart.\n- The current log provides a useful natural experiment:\n  - `C:/Users/decid/AppData/Local/spt-core/logs/daemon.stderr.log:1016-1019`: refreshed brain’s dispatcher/pump starts at `wall_ms=1784292560815`.\n  - `:1254-1255`: the prime-all round reaches its paired 10 s dial timeouts at `1784292586908/9`.\n  - `:1424-1425`: the next **15 s notif-only** round reaches the same 10 s timeout at `1784292611960/1`. From the prior round’s completion, `15 s cadence + 10 s timeout` predicts approximately `1784292611909`; the observed extra local work is only about **51 ms**.\n  - `:1610-1611`: the next **30 s registry** round reaches timeout at `1784292643383`. From the initial round completion, `30 s cadence + 10 s timeout` accounts for 40 s; the remaining approximately **16.47 s** is recurring local work before the dials are drained. This isolates registry-round preparation from the cheap notif round without requiring speculative CPU attribution.\n- Two approximately 16 s registry clusters in a 90 s window can occupy about 32 one-second buckets; the observed **27/90 samples at least 10%**, with dense clusters and a low 3.1% median, is the expected shape after sampling/phase boundaries. It is not the shape of the dispatcher’s 100 ms polling baseline.\n\n### Work performed on each registry round\n\n1. `crates/spt-daemon/src/pump/registry.rs:141-162` runs eviction/rotation work and then unconditionally calls `RegistryHost::advertise_local` in `pre_round`, before connecting to any peer. Thus it runs even when no peer is reachable.\n2. `crates/spt-daemon/src/registryhost.rs:579-620` enumerates every bound top-level perch and calls `recent_projects_for` once per perch.\n3. `crates/spt-daemon/src/registryhost.rs:981-1009` reads the full bounded `sessions.log`, walks newest-to-oldest, excludes owlery-internal paths, and only stops after finding eight **unique** project IDs. Deduplication occurs **after** project-ID derivation.\n4. `crates/spt-store/src/sessions.rs:27-30,99-102` shows each ledger is a rolling file capped at 64 rows and `read_all` reads/parses the file each call.\n5. `crates/spt-store/src/project.rs:21-24,55-64,95-137` derives each row’s project by spawning `git -C <cwd> remote get-url origin`, then—if that does not return a usable remote—spawns `git -C <cwd> rev-parse --show-toplevel`. Each eligible ledger row therefore costs **one or two subprocess launches with 10 s budgets**, even when many rows repeat the same cwd/project.\n6. A census of the current 12 bound-perch ledgers found **200 eligible non-owlery cwd rows**. No perch reaches the cap of eight unique projects, so all 200 rows are derived each registry pass: **at least 200 and at most 400 sequential `git.exe` launches per pass**. Repeated cwd values are not cached.\n7. `crates/spt-daemon/src/registryhost.rs:584-632,701-728` also advances the epoch once for every perch/subnet row and once per subnet node-label row. The current `identity/subnet.json` has two active subnets and there are 12 bound perches, yielding **26 epoch advances per round**. `crates/spt-store/src/epoch.rs:63-75` shows every advance is an atomic file write. `RegistryHost::advertise_local` then rewrites registry snapshots at `registryhost.rs:729-733`.\n\nComplexity is therefore approximately $O(L \\times G + P \\times S + R)$ per registry pass, where $L$ is eligible ledger rows, $G$ is one/two external Git processes per row, $P$ is bound perches, $S$ is subnets, and $R$ is in-memory registry rows scanned/serialized. The subprocess term dominates on this Windows host.\n\n### Candidate discrimination\n\n- **Notif pump, 15 s:** source cadence is `config.rs:40`; the log’s isolated notif round adds only about 51 ms before the fixed 10 s timeout. It cannot explain a recurring 16 s CPU cluster.\n- **Dispatcher, 100 ms:** `dispatch.rs:500-544,665-679` performs `brain.net_streams()` every poll and spawns only for newly eligible rows. It can explain a low steady baseline or stream-event spikes, but not the log-isolated 30 s registry preparation delay. Current post-refresh log has no poison/failure evidence supplied by this path.\n- **Live-host reconciliation, 5 s:** `livehost.rs:49-51,1015-1017,1106-1111` queries live sessions and scans endpoint records every 5 s. It does not run Git per historical ledger row; a 5 s phase-locked signal would look materially different.\n- **Project-index full backstop, 300 s:** `projwriter.rs:55-64,590-690` can be expensive but can contribute at most one scheduled pass in a 90 s sample. Current `project-index-stats.json` also reports the latest cycle at 549 ms, not a dense multi-second cluster.\n\n### Falsifiable field measurement\n\nCapture at least 120 s of ETW/WPR CPU sampling plus process-start events, or Procmon process events, filtered to the current brain PID and its descendants. Also record write events for `identity/epoch` and `identity/registry/{BIGNET,SPT_DEV}.json`.\n\nThe registry explanation predicts:\n\n1. CPU clusters are on the brain’s `spt-peer-pump` thread.\n2. Each cluster contains approximately **200–400 `git.exe` child starts**, concentrated over approximately 16 s.\n3. The registry/epoch writes finish near the end of that cluster.\n4. For the currently unreachable peers, `PUMP_PEER_FAIL ... exceeded the 10s bound` follows approximately 10 s later.\n5. The intervening 15 s notif round has no comparable Git-child cluster.\n\nZero clustered Git starts, CPU attribution to another brain thread, or 5 s rather than registry-round phase locking falsifies this explanation and elevates livehost/dispatcher as the next candidates.\n\n### Field-gate disposition\n\n**CPU field gate: HOLD / NO-GO. Registry-lifecycle correctness gate: PASS on the available zero-poison evidence.**\n\nThis is **expected steady-state behavior of the current source**, not a recurrence of REGISTRY-LIFECYCLE poison and not evidence that the self-hash fix failed—the read-rate collapse from 63.91 MiB/s to 0.29 MiB/s corroborates that fix. It is also not a v0.37 lifecycle regression in the narrow causal sense: it is a pre-existing/latent periodic workload now exposed after removing the continuous hash load. Nevertheless, 90 s mean brain CPU of 8.39% of one core, p95 28.1%, and approximately 16 s hot clusters do not satisfy v0.37’s release claim that idle-node steady background CPU has ended. The mean improved versus v0.36’s 15.5%, but the residual is real scheduled work rather than measurement noise; the overall performance field gate should remain held until the process-start discriminator confirms or rejects it and the accepted idle threshold is met.",
  "files": [
    {
      "path": "crates/spt-daemon/src/pump/registry.rs",
      "description": "Lines 141-162 perform all node-local registry eviction/rotation/re-advertisement work in `pre_round`; line 162 calls `advertise_local` before peer fan-out."
    },
    {
      "path": "crates/spt-daemon/src/registryhost.rs",
      "description": "Lines 579-632 derive recent projects for every bound perch and author a row for each subnet; lines 701-733 add node-label epochs and rewrite snapshots; lines 981-1009 scan ledgers and invoke project derivation before deduplication."
    },
    {
      "path": "crates/spt-store/src/project.rs",
      "description": "Lines 21-24 define a 10 s Git budget; lines 55-64 expose project-ID derivation; lines 95-137 show sequential `git remote get-url` and fallback `git rev-parse` subprocesses for every cwd."
    },
    {
      "path": "crates/spt-store/src/sessions.rs",
      "description": "Lines 27-30 define the 64-row rolling ledger cap; lines 99-102 show `read_all` reads/parses the ledger file."
    },
    {
      "path": "crates/spt-store/src/epoch.rs",
      "description": "Lines 63-75 show every registry epoch increment is persisted with an atomic write."
    },
    {
      "path": "crates/spt-daemon/src/pump/mod.rs",
      "description": "Lines 95-103 define the 200 ms scheduler tick; lines 516-518 state ordering; lines 587-591 prime all workers after refresh; lines 728-729 timestamp cadence after the completed round."
    },
    {
      "path": "crates/spt-daemon/src/config.rs",
      "description": "Lines 35-42 define 30 s registry, 15 s notif, 60 s sync, and 3600 s update pump cadences."
    },
    {
      "path": "crates/spt-daemon/src/dispatch.rs",
      "description": "Lines 500-544 and 665-679 show the 100 ms-style polling dispatcher enumeration and end-of-loop sleep, a steady-baseline comparator rather than the isolated 30 s local delay."
    },
    {
      "path": "crates/spt-daemon/src/livehost.rs",
      "description": "Lines 49-51 and 1015-1111 define the 5 s reconciliation comparator and its sliced sleep."
    },
    {
      "path": "crates/spt-daemon/src/projwriter.rs",
      "description": "Lines 55-64 and 590-690 define the 300 s project-index backstop comparator."
    },
    {
      "path": "C:/Users/decid/AppData/Local/spt-core/daemon.json",
      "description": "Deployed configuration confirms peer pump enabled and registry/notif/sync periods of 30000/15000/60000 ms."
    },
    {
      "path": "C:/Users/decid/AppData/Local/spt-core/identity/subnet.json",
      "description": "Current field state has two active subnets, SPT_DEV and BIGNET, determining the per-round epoch/write multiplier."
    },
    {
      "path": "C:/Users/decid/AppData/Local/spt-core/logs/daemon.stderr.log",
      "description": "Lines 1016-1019, 1254-1255, 1424-1425, and 1610-1611 provide the refresh start and three timeout anchors that isolate approximately 16.47 s of recurring registry-local preparation versus approximately 51 ms for notif."
    },
    {
      "path": "C:/Users/decid/AppData/Local/spt-core/index/project-index-stats.json",
      "description": "Current index state reports 12 endpoints, five projects, and latest periodic cycle duration 549 ms, excluding project-index reconciliation as the dense 90 s burst source."
    }
  ],
  "architecture": "`run_brain` starts the brain-owned network consumers → `run_peer_pump` schedules four worker legs → every registry-due round calls `RegistryWorker::pre_round` → `RegistryHost::advertise_local` enumerates 12 bound perches → `recent_projects_for` parses each perch’s rolling session ledger → every eligible historical cwd synchronously calls `project_id_for_dir` → one/two `git.exe` processes run before project deduplication → each perch/subnet advertisement advances an atomically persisted epoch → registry snapshots are rewritten → only then does peer dial/fan-out begin. Because worker cadence is marked after the entire round, approximately 16.5 s local registry preparation plus current 10 s peer waits stretches nominal 30 s registry scheduling into approximately 56.5 s burst-start spacing. That architecture predicts low CPU between dense clusters and directly matches the observed median/mean/p95 split."
}