Repository navigation
Adds Statifier.check_accepts for a chart's declared events - #24
Merged
Merged
Conversation
A host that declares the events it will send can now ask which declared names the chart can never select on (unreachable) and which descriptors the chart listens for that the declaration leaves out (undeclared). The lists and their order follow the reference's Statifier.Chart.check_accepts/2 at v2.16.0: the vocabulary is every descriptor on a transition of a state some path can enter, in transition index order, matched with the selection's own event-name matcher, and a declared name is never read as a pattern. The conformance runner now reads declared_events and expect_accepts as the reference's harness reads them: both or neither, the two lists compared exactly before the chart starts. The statifier suite's accepts case passes and joins the registry. Refs: srb-7is
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.
Refs: srb-7is
What this adds
Statifier.check_accepts(machine, declared_events): a host that declares the event names a chart accepts asks which of them the chart can never select on, and which event descriptors the chart listens for that the declaration leaves out. It answers a frozenStatifier::AcceptsCheckwith two lists:unreachable: each declared name no descriptor in the chart's vocabulary matches, in the declaration's order, without duplicates.undeclared: each descriptor in the vocabulary that matches no declared name, in transition index order (a state's own transitions before its children's), each descriptor once.nil(no declaration) answers two empty lists;[]answers the whole vocabulary asundeclared. A machine of the wrong kind, a declaration that is neither an Array nor nil, or a declared name that is not a String raisesTypeError, as the other public calls raise for arguments of the wrong kind.The semantics, and where they come from
The reference is statifier-ex at
v2.16.0, the tag the vendored corpus names:Statifier.Chart.check_accepts/2inlib/statifier/chart.ex. A declared entry is a name, not a descriptor, so a*in it is an ordinary token.Statifier.Chart.events/1and its private entry walkentered_states/1in the same file. "Can be active" is a static rule over the chart's structure that reads nocond: the root by its default, then every state a transition, aninitial, a parallel's regions or a history's default enters, with its ancestors and a parallel ancestor's untargeted regions. History pseudo-states contribute no descriptor. Descriptors are sorted by transition index and deduplicated as strings.Statifier.Interpreter.NameMatch.name_match?/2andtokenize/1. This package already has that matcher (Statifier::Interpreter::NameMatch, which transition selection uses), and the check reuses it; there is no second matcher.accepts/2inlib/mix/statifier/corpus/host_case.ex. Both keys or neither; either alone is a disagreement naming the one present; the check's two lists must equalexpect_acceptsexactly, order included, before the session starts.statifier-ts's
checkAccepts(src/accepts.ts) has the same shape: a plain value with the same two members.Return shape
check_acceptsreturns itsAcceptsCheckdirectly, not aStatifier::Result. The reference and statifier-ts both return a plain value, and the check refuses nothing, so aResultwould always have a nilerror. TheStatifiermodule doc and the README say that the other nine calls answer aResultand this one does not. The method name is statifier-ts'scheckAcceptsin snake case, decided by the conductor under a standing consent, 2026-10-23.The runner and the registry
test/conformance/runner.rbnow readsdeclared_eventsandexpect_accepts(Drive::HONOURED_HOST_KEYS). The comparison lives inConformance::Accepts(test/conformance/accepts.rb): it compiles the case and compares the check before the drive starts the chart. The statifier suite's accepts case,statifier/accepts/loan_declares_an_unreachable_event, now passes, andrake "ratchet[statifier]"added it toconformance/registry.json. The registry's claims are unchanged (scion,statifier,w3c-mandatory,w3c-optional). The README's conformance table now reads statifier 22 of 36 and 295 entries in all (119 + 22 + 152 + 2). The gate's registry stage prints295 entries pass today, and its gap list names 14 unclaimed statifier cases: the ten diff cases and the four that state an exported position.Tests
test/accepts/check_accepts_test.rbcovers the public method: transition order with a chart whose walk enters a later state first; the matcher on token boundaries with prefixes, a trailing dot and wildcards; a*in a declared name; each entry rule (an ancestor's transition, a parallel's untargeted region, a history's default target, and a state no path enters); duplicates;niland[]; a deeply frozen answer with the host's strings left unfrozen; and theTypeErrors.test/conformance/accepts_test.rbcovers the runner: an exact comparison including order; the check compared before the chart is driven; either key without the other failing the case and naming the key that is present.test/conformance/statifier_suite_test.rbnow expects the suite's accepts group to pass.test/conformance/drive_test.rbtests the not-honoured refusal with a key the runner still does not read.Every new test that asserts behaviour has a sabotage note: the code was broken, the named test failed on an assertion, and the file was restored byte for byte.
Gate
mise exec -- bundle exec rakeis green on this head: rubocop clean on 197 files,corpus:checkagrees,registry: 295 entries pass today, 614 runs with 0 failures, line coverage 99.81% (3164 / 3170), branch coverage 96.46% (1008 / 1045). The commit's tree is byte-identical to the tree that run checked.Provenance
test/conformance/accepts.rbholds the runner's comparison because adding it toConformance::Drivepushed that module over the lint's module-length limit.test/conformance/drive_test.rbchanged because its not-honoured test useddeclared_eventsas its example of a key the runner does not read.changelog.d/srb-7is.md(Added).