Blocks v0.17.0. Own PR — three related gaps in the same repair path, all found reviewing #277.
_synthesize_call_site_wrapper_spans opens a dispatch span from a provider or tool event. Those events carry lineage but not subgraph_identities, and may carry no caller_invocation_metadata. The repair for that is a backfill from the first inner node event — which never arrives if the wrapper short-circuits.
1. Subgraph identity is not repaired when no node event follows
Fan-out node declared with subgraph_identity="leaf_identity" and an instance_middleware that issues a provider call then returns a partial without calling next_call (the FailureIsolation / early-exit shape). No inner node event is emitted, _sync_subgraph_spans never runs for that prefix, and the backfill never executes. The instance dispatch span keeps openarmature.subgraph.name='' despite the declared identity.
2. Caller metadata is never backfilled at all
A dispatch span synthesized from a provider event may lack the §5.6 cross-cutting openarmature.user.* entirely. The event's caller_invocation_metadata is read defensively (so it no longer crashes), but nothing repairs it later. Same short-circuit shape makes it permanent.
3. The detached arms are not mirrored
_synthesize_call_site_wrapper_spans mirrors only the two non-detached arms of _sync_subgraph_spans. For a fan-out registered in detached_fan_outs, the orphan's parent is still decided by drain scheduling — and now differs in trace id, not just parent, which is a larger divergence than the one #277 set out to close.
Direction
(1) and (2) want the same thing: the synthesis path should source what it can from the invocation rather than only from the event, and the backfill should not be the sole repair. (3) is either mirroring the two detached arms or an explicit, tested carve-out — but not silence.
Each needs a test with the wrapper short-circuiting, since every existing test lets the inner node run.
Blocks v0.17.0. Own PR — three related gaps in the same repair path, all found reviewing #277.
_synthesize_call_site_wrapper_spansopens a dispatch span from a provider or tool event. Those events carry lineage but notsubgraph_identities, and may carry nocaller_invocation_metadata. The repair for that is a backfill from the first inner node event — which never arrives if the wrapper short-circuits.1. Subgraph identity is not repaired when no node event follows
Fan-out node declared with
subgraph_identity="leaf_identity"and aninstance_middlewarethat issues a provider call then returns a partial without callingnext_call(the FailureIsolation / early-exit shape). No inner node event is emitted,_sync_subgraph_spansnever runs for that prefix, and the backfill never executes. The instance dispatch span keepsopenarmature.subgraph.name=''despite the declared identity.2. Caller metadata is never backfilled at all
A dispatch span synthesized from a provider event may lack the §5.6 cross-cutting
openarmature.user.*entirely. The event'scaller_invocation_metadatais read defensively (so it no longer crashes), but nothing repairs it later. Same short-circuit shape makes it permanent.3. The detached arms are not mirrored
_synthesize_call_site_wrapper_spansmirrors only the two non-detached arms of_sync_subgraph_spans. For a fan-out registered indetached_fan_outs, the orphan's parent is still decided by drain scheduling — and now differs in trace id, not just parent, which is a larger divergence than the one #277 set out to close.Direction
(1) and (2) want the same thing: the synthesis path should source what it can from the invocation rather than only from the event, and the backfill should not be the sole repair. (3) is either mirroring the two detached arms or an explicit, tested carve-out — but not silence.
Each needs a test with the wrapper short-circuiting, since every existing test lets the inner node run.