v0.7.4 — Deterministic parent-session attribution
What's New
Deterministic parent-session attribution (session-parent-link)
Fixes an edge case where sub-agent cost rollup could silently drop spend when the harness header lacked a parentSession field at session_start time.
Changes
activateSession()late-binding: first non-undefined parent wins; never overwrites a setparentSessionIdsetParentIfAbsent(): private helper encapsulates the immutable-parent rule (unit-testable in isolation)resolveParentFromHeader(): wrapsgetHeader()?.parentSessionwith error handling — never throws- Header-first resolution at
session_startandsession_branch - Fallback path in
turn_start: when header has no parent, falls back to the previously-active session ID - Disagreement detection: logs
[model-router] parent attribution disagreementwhen header and fallback differ; prefers header - Debug logging: attribution source tagged as
header|fallback|noneper scope, idempotent viaparentAttributionLoggedset
Tests
9 new tests in test/session-parent-link.test.ts covering all attribution paths, error resilience, late-binding, and finalizeChildSession rollup integration.
Diagnosing missing rollup
Enable debug: true in ~/.omp/agent/model-router.json and look for:
[model-router] parent attribution: child=<id> source=<header|fallback|none> parent=<id>
If you see source=none for a session you expected to be a child, the harness header has no parentSession for that session — the issue is upstream, not in the router.