Repository navigation
Refuses unresolved providers at start_child_at - #273
Merged
Merged
Conversation
Driver.start_child_at/6 now checks the driver's function_providers:
list first, before the parent's record is read, any child is created
or anything is written, and answers {:refused, {:function_providers,
reason}} within its existing {:refused, reason} shape. Without it, a
driver whose list does not resolve could start a fan-out child whose
automatic answer the parent's door then refused, and that refusal is
discarded on the automatic path, so the invocation never settled.
The check is the one the driver's other doors use. The typespec names
the reason, the docs and README say so, ADR-0004's proposed Amendment
gains the door in its table by a dated edit, and a changelog fragment
carries the host-facing line. Ruled by the operator, 2026-10-13.
Refs: sp-8ktk
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
StatifierPersistence.Driver.start_child_at/6refuses a driver whosefunction_providers:list does not resolve, at its entry, answering{:refused, {:function_providers, reason}}within its existing{:refused, reason}return shape. Thatstart_child_at/6refuses within its existing shape was ruled by the operator, 2026-10-13;resolve_and_answer_parent/3is unchanged.Before this, a driver whose list did not resolve could create and drive a fan-out child through this door. The child's automatic answer then reached
answer_parent/3, which refuses such a list before it settles anything, and on the automatic path that refusal is discarded, so the invocation never settled and nothing told the host.How
check_function_providers/2inStatifierPersistence.Driver, over the driver's own list), first: before the parent's record is read, before any child is created and before anything is written. A thin wrapper (check_start_providers/1) turns that check's{:error, reason}into this door's{:refused, reason}; the reason term is the same.{:refused, {:function_providers, Executions.function_providers_reason()} | term()}; the reason was already inside the openterm(), so no caller's contract narrows or widens. The function's docs andDriver.new/3's option docs name the refusal, and the README'sfunction_providers:paragraph says the fan-out door answers in its own shape.[:statifier_persistence, :child, :refused], as the door's:execution_not_foundemits none: that event'sreasonis ADR-0008 decision 4's refusal set (docs/telemetry.md), and widening it is not this change.git diff origin/main -- docs/adr/removes no line.changelog.d/sp-8ktk.md: one Added line, the host-facing sentence (only a driver with a list that does not resolve sees a change).Tests
Two new tests in
test/statifier_persistence/function_providers_test.exs, under "Driver.start_child_at/6"::execution_not_found); no serialization exclusion asked for, the parent's record unchanged, no child execution at either index.The existing fan-out test files are unchanged.
Sabotage, each run against the new tests, the copy restored byte-equal after each:
start_child_at/6: the refusal test went red on its assertion (the door answered:okand created the child);Gate
Full
mix qualitygreen locally on this tree (format, compile with warnings as errors, credo, docs, doc links, dependencies, dialyzer, tests at 96.0% coverage), against a local Postgres server on 5432.Provenance
Driver.new/3option docs are not named in the bead; both listed the doors that refuse and would otherwise have read as complete without this one.