pub fn claude_session_id(stdout: &str) -> Option<String>Expand description
Read the top-level session_id string from a Claude JSON result envelope
(--output-format json). Returns None for plain-text stdout, a
non-JSON-object envelope, an envelope with no session_id key, or a
session_id of a non-string JSON type — never panics.
D-04 / T-28-04 (this plan’s <threat_model>): deliberately reads ONLY the
envelope’s TOP-LEVEL session_id key via a direct serde_json::Value::get,
never the module’s [json_find_key]/[json_scan] traversal helpers. Those
helpers descend into nested objects, and the agent-authored DEVFLOW_RESULT
marker payload — embedded inside this same envelope’s result text and
deserialized by [parse_marker_lines] directly into AgentResult — is
reachable that way. A top-level get makes it true BY CONSTRUCTION that an
agent cannot redirect the session DevFlow later resumes into by planting a
different session_id key inside its own self-authored marker JSON.
Regression test: session_id_in_devflow_result_marker_is_not_returned.
Deliberate deviation from RESEARCH.md § “Discretion Resolutions” item 5,
which suggested adding a session_id field directly to AgentResult.
NOT done: parse_marker_lines deserializes the agent’s own
DEVFLOW_RESULT JSON straight into AgentResult via serde_json::from_str,
so a #[serde(default)] field there would be agent-settable — the agent
could name the session DevFlow resumes into (T-28-04). A standalone reader
over the top-level envelope key carries no such surface and is equally
available to every caller; D-04’s persistence target (State::session_id)
is unchanged, only the carrier differs.