The problem
retained provider execution requires reconciliation before replacement is the settle reason for two situations that call for opposite operator responses:
- We cannot safely determine whether this execution ran. Refusing to replace it is correct. The operator must reconcile before retrying, or risk paying twice for one turn.
- The provider sent something malformed. Nothing needs reconciling. The execution's status is not in doubt; a contract was broken and the right response is to fix or report the provider.
An operator reading a journal cannot tell which one they have. Both produce the same string, and until recently both produced it with no cause at all.
Four exhibits, three days
| # |
Cause carried in the chain |
When |
Record |
| 1 |
ZodError … "path": ["prompt"] … maximum 16384 |
2026-09-11 ~11:00Z |
discovery@master:.agent/reflections/2026-09-11-190000.md |
| 2 |
RetainedRunProviderContractError: <!DOCTYPE html> … tangle.tools | 502: Bad gateway |
2026-09-11 ~23:40Z |
issue #1203, discovery-lab@master:pursuits/mech-interp-foundations-glm2-20260911e |
| 3 |
Error: Tangle session event arrived without a stable id |
2026-09-12 ~01:15Z |
mech-interp-foundations-astra-20260911f:s74, 1 death in 79 children |
| 4 |
none — Sandbox.get(id) not-found for four ids while the same account listed 34 retained sandboxes |
2026-09-09 |
discovery@master:research/r14-provider-reconciliation-20260909.md |
Exhibit 4 is the control, and it is why this is one issue rather than three. There the execution genuinely could not be reconciled: four children journalled infra:true, zero iterations, zero tokens, no output reference, and the provider could not resolve their ids at all. R14 classifies that refusal as correct — "a safety refusal to retry an admitted-but-unobservable execution". Nothing about that should change.
Exhibits 1 through 3 are a different kind: a request-schema violation, a transport error body where JSON was expected, and a provider event violating its own identity contract. In none of them is reconciliation the issue. They wear the refusal's name because they arrive on the same path.
What I think the fix is
Discriminate where the cause is still known, so a contract violation never inherits the reconciliation refusal's reason. Concretely: when the failure is a schema, transport, or identity violation, settle it as that, with the provider and the violated contract named. Reserve the reconciliation reason for the case where the execution's status is genuinely unknown.
Fixing the three exhibits separately would leave the ambiguity intact for the fourth kind that arrives next.
A note on reading the history
All four are visible only because #1188 shipped the cause chain into the settle reason in 0.213.0 at 06:07Z on 2026-09-11. Before that these read as a bare wrapper with no cause. So the apparent absence of this pattern in older journals is an observability artifact, not a frequency claim, and anyone counting occurrences from historical records will undercount.
Scope
Not asking for the refusal behaviour to change. Exhibit 4 shows it doing its job. The ask is that the reason name which of the two things happened.
Exhibits 1, 2 and 4 were assembled by the session tracking the owner/operator handoff; exhibit 3 and the live journals are from the mech-interp lanes. Both citations verified against the files before filing.
The problem
retained provider execution requires reconciliation before replacementis the settle reason for two situations that call for opposite operator responses:An operator reading a journal cannot tell which one they have. Both produce the same string, and until recently both produced it with no cause at all.
Four exhibits, three days
ZodError … "path": ["prompt"] … maximum 16384discovery@master:.agent/reflections/2026-09-11-190000.mdRetainedRunProviderContractError: <!DOCTYPE html> … tangle.tools | 502: Bad gatewaydiscovery-lab@master:pursuits/mech-interp-foundations-glm2-20260911eError: Tangle session event arrived without a stable idmech-interp-foundations-astra-20260911f:s74, 1 death in 79 childrenSandbox.get(id)not-found for four ids while the same account listed 34 retained sandboxesdiscovery@master:research/r14-provider-reconciliation-20260909.mdExhibit 4 is the control, and it is why this is one issue rather than three. There the execution genuinely could not be reconciled: four children journalled
infra:true, zero iterations, zero tokens, no output reference, and the provider could not resolve their ids at all. R14 classifies that refusal as correct — "a safety refusal to retry an admitted-but-unobservable execution". Nothing about that should change.Exhibits 1 through 3 are a different kind: a request-schema violation, a transport error body where JSON was expected, and a provider event violating its own identity contract. In none of them is reconciliation the issue. They wear the refusal's name because they arrive on the same path.
What I think the fix is
Discriminate where the cause is still known, so a contract violation never inherits the reconciliation refusal's reason. Concretely: when the failure is a schema, transport, or identity violation, settle it as that, with the provider and the violated contract named. Reserve the reconciliation reason for the case where the execution's status is genuinely unknown.
Fixing the three exhibits separately would leave the ambiguity intact for the fourth kind that arrives next.
A note on reading the history
All four are visible only because #1188 shipped the cause chain into the settle reason in 0.213.0 at 06:07Z on 2026-09-11. Before that these read as a bare wrapper with no cause. So the apparent absence of this pattern in older journals is an observability artifact, not a frequency claim, and anyone counting occurrences from historical records will undercount.
Scope
Not asking for the refusal behaviour to change. Exhibit 4 shows it doing its job. The ask is that the reason name which of the two things happened.
Exhibits 1, 2 and 4 were assembled by the session tracking the owner/operator handoff; exhibit 3 and the live journals are from the mech-interp lanes. Both citations verified against the files before filing.