Range the replay-safety guard over the substrates the factory can build - #776
Merged
Conversation
The guard that was supposed to keep the classifier in lockstep with the deciders had no independent side. It asserted a hand-written set of four refs against the classifier's own hand-written sets, so it agreed by construction, and it never looked at an adapter at all. It therefore reported nothing while the llm substrate shipped a model_ref of `provider:model`, a value no literal set could ever contain. Asking is_replay_safe about an LLM-steered run raises rather than answering. No production caller consults it yet, so the defect is dormant, but the module's own docstring claimed a coverage it did not have. Key the classification by DecideSubstrate instead. That Literal is the independent side: decide_port_config maintains it so its factory knows what it can build, a substrate missing from it cannot be constructed, and whoever adds an adapter must edit it for reasons that have nothing to do with replay. The test now asserts set equality in both directions, so a seventh substrate fails CI until classified and a deleted one fails until its classification goes too. Two substrates do not record their own name, and the classifier now says so rather than pretending otherwise. staged returns its child's advice unchanged, so its own name on an iteration means the composite grew a ref it should not have, and that input raises. llm records provider:model, an open set rather than a constant, recognised by shape. Verified by mutation: adding an unclassified substrate to the Literal, misclassifying llm, disabling the llm route, and removing the composite refusal each fail exactly their own tests and nothing else. One test was dropped along the way for failing that check, having compared a result against the same map it came from. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Coverage reportClick to see where and how coverage changed
This report was generated by python-coverage-comment-action |
||||||||||||||||||||||||
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 was wrong
The guard meant to keep
decider_replayabilityin lockstep with the deciders had no independent side. It asserted a hand-written set of four refs against the classifier's own hand-written sets, so it agreed by construction, and it never looked at an adapter at all.It therefore reported nothing while the
llmsubstrate shipped amodel_refofprovider:model, a value no literal set could ever contain. Askingis_replay_safeabout an LLM-steered run raises rather than answering. No production caller consults it yet, so the defect is dormant, but the module docstring claimed a coverage it did not have.The fix
Key the classification by
DecideSubstrateinstead. ThatLiteralis the independent side:decide_port_configmaintains it so its factory knows what it can build, a substrate missing from it cannot be constructed, and whoever adds an adapter must edit it for reasons that have nothing to do with replay. The test now asserts set equality in both directions, so a seventh substrate fails CI until classified and a deleted one fails until its classification goes too.Two substrates do not record their own name, and the classifier now says so rather than pretending otherwise:
stagedreturns its child's advice unchanged, so its own name on an iteration means the composite grew a ref it should not have. That input raises.llmrecordsprovider:model, an open set rather than a constant, recognised by shape.Verification
Verified by mutation: adding an unclassified substrate to the
Literal, misclassifyingllm, disabling the llm route, and removing the composite refusal each fail exactly their own tests and nothing else. One test was dropped along the way for failing that check, having compared a result against the same map it came from.14,934 unit / 37,424 architecture passing, full-repo pyright clean.
Naming
Replayability/SUBSTRATE_REPLAYABILITY/replayability_of, asStrEnum. The naming reviewer overturned an earlierReplayClass: there are zero pre-existing*Classenums, and 114 of 116 enums in the tree areStrEnum.🤖 Generated with Claude Code