---
name: measuring-a-process-env-vs-shipping-a-probe
description: "2026-08-21 flynn correction — reading a target process's environment block answers \"does this process carry X\" cold, with no release and no traffic; ship an in-process probe only for ephemeral targets or standing regression signal."
metadata: 
  node_type: memory
  type: feedback
  originSessionId: d4b9ffe5-c44f-4d39-898f-a3399266fa85
  modified: 2026-08-22T00:26:57.999Z
---

Settling **"does the process that shells `spt send` carry `OWL_SESSION_ID`?"** (claude-spt #10), I
shipped a release (v0.28.2) whose only content was a log line at the dispatch site. It worked — both
legs read `owl=empty`, and the fix followed in v0.28.3.

⭐ **flynn answered the same class of question with no code, no release, and no send at all**: read the
target process's **PEB environment block** directly. It cannot be confounded by the very send path
under measurement, and it costs nothing to try first. His safety rules, which are the method:

- Take the pid from the **spawn's own reported output** (`spt shell spawn` prints `pid=NNNNN`), never
  by picking a process out of the table — on a multi-owner node they are indistinguishable, and
  reading another owner's process env would expose their tokens.
- Only read a process **you spawned**.

**The methods are COMPLEMENTARY, not ranked** — flynn bounded his own claim once I named the gap:

| target | instrument |
|---|---|
| durable pid (resident service, live shell) | PEB read — answers cold, no release, nothing to confound |
| ephemeral (a CC hook child) | in-process probe — the only thing that CAN observe it |

**When an in-process probe still earns its keep:**
- the target is **ephemeral** — a CC hook child is spawned per event and lives milliseconds, so there
  is no pid to catch by hand;
- you want a **standing regression signal** rather than one reading — our probe still logs
  `inherited=` on every dispatching turn, so a harness that starts or stops providing the var shows
  up instead of being silent.

**Structural point I got wrong and he corrected:** "pass the session id at the send site" does NOT
generalize to a broker-spawned resident. It has no session ancestor (spawned at boot, service
identity), so there is nothing to pass — and passing one would stamp one owner's session onto another
owner's traffic on a shared daemon. Whether a session-shaped stamping predicate needs a
service-identity path is spt-core design, doyle's to rule.

Label discipline both sides kept: the env **absence** is measured; "therefore `sender_proven` is
None" is **deduced** from the recorded predicate — neither of us re-read spt-core source
(public-surface-only). Related: [[list-vs-predicate-assertions]], [[signature-match-is-not-root-cause]].
