Repository navigation
Every witness reads back its effect, and the mutation audit covers grants and lists its gaps.
3 added, 3 changed, 10 fixed.
Changed
- Format
ess/34: a compensating refusal (compensates: truebesideexternal:) may delete its addressed row withdeletes:andinstance:; the interpreted target removes the row and answers the error, and its scenario requires the error, no event and the row absent from every immediate view. Belowess/34the delete keeps itsrefusal_mutated_state, now namingess/34; fromess/34themissing_declarationof a compensation declaring no change namesdeletes:in its message and hint. Fromess/34a namedwhen:orwhen_related:refusal of a command addressing an existing row snapshots that row completely and requires it unchanged; below it suites keep their bytes. At every format, a further witness of a deleting branch (a conjunct of a compound guard's complement) requires the deleted row absent instead of present (#581, #585, #587; story:every-witness-reads-back-its-outcome-effect). ess verify conform mutatelists each site a selected class excluded or left without a live mutant, with its reason, underunmutated_sitesin the report (ess-mutation-report/8) and the manifest (ess-mutation-manifest/7), and asunmutated <id> (<reason>): …lines beside the stillborn mutants. The summary line gives; S of N site(s) scored.transition-totakes the first other state the model admits, or lists the transition asno_admissible_state.sets-retargetretargets a creating orOptionalwrite that has no sibling input of its type to a literal, or lists it asunobserved_fieldwhere nothing in the model reads the field, so no target could tell the literal apart. Where the selected classes find only unmutated sites, theESS-MUTATE-003refusal prints each one.--fail-on-unmutatedmakes such a site, or a stillborn mutant, block exit 0. The default exit status is unchanged, and a report or manifest that lists no such site keeps its format and bytes (story:the-mutation-audit-reports-the-sites-it-could-not-mutate).ess verify conform mutateaudits actor grants with two new classes,grant-drop(one command removed from one actor'smay:) andgrant-add(one served command added to an actor that lacks it). Where either is selected, which the default selection does, the baseline and every mutant's suite keep their<command>/grant/deniedscenarios, agrant-dropmutant's refusal is sent as the actor that lost the grant, and agrant-addmutant's suite sends the command as the actor that gained it, also where an actor carrying attributes holds it. A grant of the system actor (system_actor) or of a command nothing serves (command_not_served), and agrant-addno scenario can be sent for (attributed_holder), is listed as an unmutated site. A grant mutant takesess-mutation-manifest/7andess-mutation-report/8. A selection without a grant class keeps its baseline, its bytes and its ids (story:the-mutation-audit-covers-actor-grants).- The precedence section of
docs/design/cross-record-and-stored-field-guards.mdstates how an input refusal and anunknown_instance:orexists: falsebranch are ordered in each format: the input refusal answers first fromess/27,ess/29refuses either declared above it naming both and the order, and belowess/29either order validates. No behaviour changes. Validation and the interpreter already agreed, and so did both explorers on theunknown_instance:pair; they leave awhen_related:command out. Tests now pin it (story:unknown-instance-and-input-guard-agree-on-order). - The scenario of a non-refusing
unknown_instance:branch reads every immediate view of the addressed entity afterwards and requires no row with the identity it sent, so a no-op that stores a row fails; where no such view exists a note names the scenario and the entity. ESS-COMMAND-005 for aninstance:without an effect now namesdeletesamong the effects, and its hint namesdeletes:andunknown_instance: true, refuses: false(story:a-delete-may-have-a-no-op-branch-that-emits-nothing). - CI: the test archives are built with their symbol tables stripped, about a quarter smaller, and each archive download attempt may take 40 minutes instead of 30, so a shard on a slow runner gets its archive.
- The generated explorer (Go and TypeScript) no longer expects an arranged
external:branch where a branch the stored row selects (its held state, or a predicate over its fields) holds. The interpreter answers the held state first, as the precedence order does, so a target in that order failed exploration naming the external branch (story:explorer-and-interpreter-agree-on-external-cause-for-stored-record). - 9 more in the changelog.
Every change: CHANGELOG.md § 0.85.0