Repository navigation
Cell literals refuse unspaced arithmetic and read 0i as MATLAB does; VariantBank and VariantConfigurations follow MATLAB in every spelling - #151
Merged
Conversation
A cell member typed without spaces, such as {1+2}, {a+b}, {2i+3i}, {2*3}
or {-a}, was held as one char member ('1+2', '-a'). MATLAB computes each
of them ({3}, a sum, {0+5i}, {6}, a negated name), so the char was a value
MATLAB never makes, while the spaced {1 + 2} and {- a} were already
refused. Under the group G ruling (accept the sign and i + 1 forms, keep
refusing arithmetic), a bare member that holds + - * / \ or ^ and is not
one literal is now refused, and the edit leaves the value as it was.
A bare word such as {abc} or {a_b, c1} is still held as text, and a sign
that belongs to one literal is still read: {-2}, {1e+3}, {1e-3}, {1+2i},
{-2i}, {i+1}, {2i-3}.
probe_cell_sign_literals.m gains the unspaced rows, and the refusal table
in cellSignMember.test.ts quotes what MATLAB R2027a (27.1.0.3409468) made
of each. The edit-path test now types {1+2}, {a+b}, {-a} and {2i+3i} into
a text and a binary dictionary and expects the refusal.
…TLAB makes
A cell member typed with a zero imaginary part, such as {0i}, {1 + 0i},
{1+0i} or {0i + 1}, was held as a complex member (0+0i, 1+0i) and saved
as one. MATLAB R2027a holds each as a real double: its arithmetic drops an
imaginary part that is all zero, and a lone 0i is real too. Under the
group G ruling (accept these forms as MATLAB does) and theme 2 (follow
MATLAB, measured first), such a member is now that double, with its real
part as MATLAB sums it, -0 included: {-0 + 0i} is 0, {-0 - 0i} and {-0i}
are -0, and {-0i + 0} is 0. A nested cell's member is read the same way.
Only a cell's member changes. The top level is what an element of a complex
array takes, which must stay complex, so 0i and 1 + 0i typed as a whole
value are read as before, although MATLAB makes doubles of them too. An
array literal such as {[0i 1]} holds no complex element in this parser and
is still refused.
probe_cell_sign_literals.m gains 68 rows (the zero forms in a cell, nested,
in an array and at the top level), and cellSignMember.test.ts quotes what
MATLAB made of each. The new tests drive the parser and the edit path into
a text and a binary dictionary, and a save and reopen in both formats.
… {- 2}
A VariantConditions edit of {i+1}, {i + 1} or {- 2} is refused with
MATLAB's message for a member that is not text ("Conditions defined in
'VariantConditions' property must be a scalar string."), because the
parser reads each as the one number MATLAB makes of it (1+1i, 1+1i, -2),
as for {1,2}. No VariantBank test held that: with the imaginary-first
form or the spaced unary sign dropped from a cell member, the edit was
refused as "must be a cell array" instead, and those tests stayed green.
Test only. The three cases join the refusal list in
variantBankFields.test.ts, run against a text and a binary dictionary.
The two i + 1 cases fail with the imaginary-first form dropped, and
{- 2} with the spaced sign dropped; all pass on the code as it is.
… one A text dictionary R2026b wrote holds a Simulink.VariantBank as plain properties, with no saveobj envelope, as it holds a coder info. The bank was read out of the envelope alone, so there its Bank Name, Variant Conditions and coder info cells showed their defaults, the file's values showed only as Other rows, and every edit was refused as having nowhere to be saved. Under C-168 (follow MATLAB) with the fix shape C-169B gave the coder info, the bank now reads its fields from, and writes an edit into, the plain properties when there is no envelope, and invents no envelope. What R2027a reads of that spelling was measured first, on synthetic files made from the R2027a text fixture with its banks and coder infos respelled so and hand-edited one field at a time. MATLAB reads the bag property by property, through the setters, with no warning: a value a setter refuses is read as that property's default alone, not the whole bank as from an envelope; a char VariantConditions is read as no conditions; BankCoderInfo is read independently of the two coder infos; and a missing field is read as its default. MATLAB read core's own saves of such a bank back as written. Under theme 1 a hand-edited bank so spelled is shown and saved as read, and its warning says what MATLAB does there. A field the bag does not have still takes no edit. The Variant Bank rows also claim their plain keys, so Other no longer repeats them; the Hidden BankCoderInfo, which has no row, is listed under Other. The probe (variantbank_plain.mjs and probe_variantbank_plain.m) and its truth are committed, and variantBankFields.test.ts grades core's reading of every case against what MATLAB read. A condition past int32, which neither spelling warns of, is recorded and left for a follow-up.
…aken MATLAB R2027a's setter takes a DefinitionFile of 302 characters (300 a's and .c), while it refuses a HeaderFile longer than 255 characters in a part: the length rule is the header file's alone. The editor takes that edit, but no test held it. With the length check moved out of the header file branch, so a DefinitionFile got the 255 rule too, the whole suite stayed green, and the edit was refused as "Check specified header file name ... invalid file name length". Test only. The 302-character name joins the coder info edit table in variantBankFields.test.ts, run against a text and a binary dictionary. Both cases fail with that change and pass on the code as it is.
An earlier version of this package wrote a saveobj envelope back as <P Name="undefined" Class="struct"> in place of MATLAB's <P Source="saveobj" PropertyType="any" Class="struct">, and a binary dictionary saved so still holds a coder info that way. The node reads its five properties from the envelope or from R2026b's plain properties, found neither, and showed the coder info blank, its state only as an Other.undefined row, with no warning. What R2027a does with it was measured first, on synthetic files made from the R2027a fixtures. In a binary dictionary MATLAB cannot make the coder info at all: the dictionary and its other entries open, but that entry's value fails with "Data dictionary unable to create an object of class 'Simulink.VariantBankCoderInfo'." A text dictionary's plain bag holding only that struct is read as every default, and one holding the five properties too is read from them, the 'undefined' ignored. MATLAB warned of none of them. Under theme 1 such a coder info is still shown and saved as read, and the dictionary's warnings now carry one part-unreadable for it that names 'undefined' and says what MATLAB does with it in that format. A bag with the five beside its 'undefined' is not reported, and an edit of one of the five still has nowhere to be saved. The probe (coderinfo_undefined.mjs and probe_coderinfo_undefined.m) and its truth are committed, and variantBankFields.test.ts grades core's reading of each case against what MATLAB read.
…LAB's class does not have
MATLAB R2027a has no Value property on Simulink.VariantConfigurations.
Under either name an entry of this kind goes by,
Simulink.VariantConfigurationData or Simulink.VariantConfigurations, the
object built is a Simulink.VariantConfigurations, isprop(..., 'Value') is
0, none of the ten properties its metaclass lists (seven hidden) is a
Value, and setting one fails with "Unrecognized property 'Value' for class
'Simulink.VariantConfigurations'." The probe opens no file:
test/parity/matlab/probe_variantconfigurations_value.m, with what it
measured in variantconfigurations_value.truth.json.
The node had a Value anyway. setProperty('Value', ...) fell through to the
generic tail, which took the text and marked the entry Modified, and both
save paths wrote it beside the saveobj envelope. An entry held as plain
properties, with no envelope, also gained Value '' on every save, an
unedited one included.
The node now does what VariantBank and VariantBankCoderInfo do (C-168,
C-169). A Value edit is refused ("'<name>' is a
Simulink.VariantConfigurations, which has no Value, so none can be set on
it.") and leaves the entry unmodified, and _serializedOverrides is empty,
so no save writes a Value. A Value key a file already carries is written
back as read.
test/variantConfigurationsNoValue.test.ts covers a new entry in both
formats, a Value already in the file, and an entry held as plain
properties. Three existing tests pinned the removed behaviour and change:
variantLeafNodes.test.ts now lists the class among those that refuse an
edit of their one property, and objectArrayElementClass.test.ts no longer
exempts it from the untouched-save check. In newEntryEnvelopeBothFormats,
C-199's undeclared-field case rode on this Value. It now rides on a
custom-saving class defined in the test, written and read by the real
writers and readers.
The unspaced-arithmetic refusal (d4975c3) checks one bare member for an operator. Nothing held it to that member: checking the whole row instead passed the full suite, and under that change {abc, -2}, {abc, 1e-3}, {abc, 'x-y'}, {abc, [1 -2]} and {-2, abc} were all refused, where main and this branch read them as ['abc', -2] and so on. The "keeps a bare word" test in cellSignMember.test.ts now parses each of them and expects the word as text beside the member read as before. Under the row-wide check each comes back null, so the test fails.
The 'undefined' warning (269f897) is for a coder info with no envelope, an own 'undefined' property and none of the five. Two parts of that test were not held by any test: dropping the 'undefined' check, or the envelope check, passed the full suite. Without the first, a plain bag with none of the five, such as {} or {Foo: 'x'}, was warned of as held in a property named 'undefined', which it does not have. Without the second, an envelope with an 'undefined' beside it was warned of too. What R2027a (27.1.0.3409468) makes of each was measured first, in the same probe run as the damaged cases, on files made from the R2027a fixtures. The envelope with an 'undefined' struct of other values beside it is read from the envelope in both formats, the 'undefined' ignored. A text dictionary's plain bag with no property, or with only Foo, is read as every default. MATLAB warned of none of them, so none is reported here. coderinfo_undefined.mjs makes the four control files, and the truth now holds them (the five earlier rows are as before). variantBankFields.test.ts grades each against what MATLAB read: no warning, shown and listed as read, and saved as read. Under either change above two of the four fail, each with the 'undefined' warning MATLAB does not give. The comment above heldUnderUndefined and the coder info doc name the controls.
…of the five The 'undefined' warning (269f897) is for a coder info whose plain bag holds an 'undefined' and none of the five properties. Which of the five it looks for was not held by any test: checking that all five are there (every in place of some), or checking HeaderFile alone, passed the full suite. Under either, a text dictionary's plain bag with an 'undefined' beside only some of the five was warned of as one MATLAB reads with every property at its default. What R2027a (27.1.0.3409468) makes of two such bags was measured first, on files made from the R2027a text fixture: ciA's HeaderFile alone beside an 'undefined' struct of other values, and ciA's DefinitionFile and Qualifier beside one. MATLAB reads each from the properties it holds, every other at its default, ignores the 'undefined', and gives no warning. Core already does the same, so the only src change is the comment above heldUnderUndefined. coderinfo_undefined.mjs makes the two files, and the truth now holds them (its nine earlier rows are as before). variantBankFields.test.ts grades both as controls: no warning, shown and listed as read, and saved as read. The two bags hold no field in common, so a check of any one field alone fails at least one of them: every in place of some fails both, HeaderFile alone fails the second, DefinitionFile or Qualifier alone the first, and PreStatement or PostStatement alone both. The coder info doc, the probe header and the README row name the new controls.
…e five alone A check of only some of the five properties still passed every test: the two partial controls, HeaderFile alone and DefinitionFile with Qualifier, left a check that skipped DefinitionFile, Qualifier, PreStatement or PostStatement, or read only HeaderFile and DefinitionFile, unseen. Such a check warns falsely of a bag that holds only a field it skips. coderinfo_undefined.mjs now also writes a text bag of DefinitionFile, Qualifier, PreStatement or PostStatement alone, each beside an 'undefined' struct of other values. MATLAB R2027a (27.1.0.3409468) reads each from that one field, every other at its default, with no warning, and so does core. The four are added to the controls, so each of the five is held alone by one, and any check that leaves a field out warns of that one. The 11 earlier rows of the truth are unchanged. No behaviour changes: src gains only comments, and dist only those comments and its maps.
This was referenced Oct 19, 2026
Merged
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.
Seven items from group H, one commit each, on main 38c20de. Three fix rounds added four commits, and round 3 merged main 17b610c in. Each
srccommit carries its regenerateddist. MATLAB is R2027a 27.1.0.3409468. Every probe opens only repo fixtures copied to /tmp, or files it generates under /tmp. Each probe is committed undertest/parity/matlab/with its truth file and a test.B-01 (d4975c3): refuse unspaced arithmetic in a cell literal
i + 1forms as MATLAB does, and keep refusing arithmetic."{1+2},{a+b},{2i+3i},{-a}and{2*3}were each held as one char member, andeditProperty(..., 'Value', '{1+2}')was accepted. MATLAB computes these values. Core already refused the spaced form{1 + 2}.tokenizeCellElementsfallback (MatlabValueParser.ts), a bare span that no literal parser could read fell through toelements.push(span).+ - * / \ ^, the same way a joined span is. A bare word ({abc}) stays text. A sign that belongs to one literal is still read:{-2} {1e+3} {1e-3} {1+2i} {-2i} {i+1}.probe_cell_sign_literals.mgains 24 rows. Their output is quoted intest/cellSignMember.test.ts, and a script checked every quoted line against the log.{-}and{+}. The realeditPropertypath on cellarr_text/binary.sldd now types{1+2},{a+b},{-a}and{2i+3i}. Before the fix, 21 tests failed (expected { type: 'cell', value: ['1+2'] } to be null;expected true to match { error: true, ... }). The controls passed before and after. No existing assertion changed. Fix round 1 pinned that the check runs on the member, not the whole row (50896dd).{1:3},{a==b},{f(x)}) are still text, as cellElementShape.test.ts pins on purpose. Changing that needs its own call.+ - * / \ ^is refused, some bare members that used to be accepted are refused:{V==-1}and{V>-2}were written as'V == -1'and'V > -2'. They are now refused as "must be a cell array".{V+1==2}was refused before too, but by the condition check.{@(x)x+1},{1:-1:0},{-int8(1)},{-0x1F},{e-3}.{V==1}and{1:3}are still text, and the quoted{'V==-1'}is still taken.B-02 (df73f30): a cell member whose imaginary part is zero is a real double
{0i}was held as complex0+0i, and{1 + 0i},{1+0i}and{0i + 1}as1+0i. MATLAB makes each of these a real double.tokenizeCellElementskept the complex bag fromparseComplex/parseImaginaryFirsteven when its imaginary part was 0.zeroImaginaryAsReal(span)returns MATLAB's real part, with IEEE signed zeros ({-0 - 0i}and{-0i}give -0,{0i - 0}gives 0). This applies to cell members only, so nested cells follow. The top level, complex-array elements and_setConstrainedValueare untouched.editPropertyon both fixtures. There is also a nested-cell test and a save/reopen in both formats: binary writesClass="double"1.0 / -0.0, and text writes a bare 1. Before the fix, 174 failed (expected [ { re: 1, im: +0 } ] to deeply equal [ 1 ]) and the controls passed. No existing assertion changed.0i/1 + 0ireal. Changing that would break "an element of a complex array stays complex", so it needs its own call.{1+0i, 5}. If you change only the 5, the save now writes that member as a real1, where before this PR it stayed complex.1+0i:complexbecomes1:double.{1+0i, 6}. But the top level stays complex for exactly this round-trip reason, and_literalRoundTripsdoes not catch it for a cell member._literalRoundTripscould return false for such a member, so the element is edited instead.B-03 (25ffd3f): pin the VariantBank refusal of
{i+1},{i + 1},{- 2}{i+1}is now refused, matching MATLAB, but unpinned".variantBankFields.test.tsexpect MATLAB's measured "must be a scalar string." message, in both formats.parseImaginaryFirstfrom the cell path fails the{i+1}and{i + 1}rows (4 failures). Disabling the unary-sign normalization fails{- 2}(2 failures).cellSignMember.test.tsalready killed both mutants (121 and 84 failures); what no test held before was the VariantBank-level message. No existing test changed, and dist is unchanged.B-06 (ab2880a): read and edit a VariantBank held as plain properties
Otherrows, and every edit was refused with "nowhere to be saved".VariantBankNodeconstructor read fields only throughreadSaveobjField, and edits wrote only into the envelope.fieldOfreads the envelope, or else the plain property, as VariantBankCoderInfoNode does. It is used by the constructor, by the "nowhere to be saved" check and byunreadFields. In a plain bag,_mergePropswrites into the plain property and does not invent an envelope. Warnings for a plain bag name MATLAB's per-property reading. The four bank props gain their plain source keys, and the docs gain a section on R2026b's spelling.variantbank_plain.mjsrespells the repo's R2027a fixture into 30 hand cases and 4 core saves, all under /tmp.probe_variantbank_plain.mwritesvariantbank_plain.truth.json. MATLAB reads such a bag property by property, with no warning. A value a setter refuses becomes that property's default alone. All 4 core saves were read back as written.variantBankFields.test.tscovers display, edit and undo, grades 28 hand cases against the truth, and checks the 4 save cases. The fixture text is pinned by sha256. Before the fix, 35 failed (cells showed defaults, and edits were refused as "nowhere to be saved"). Three mutants gave 10, 5 and 1 failures. No existing test changed.B-07 (99f6d9f): pin that a 302-character DefinitionFile is taken
'a'.repeat(300) + '.c', in both formats.B-08 (269f897): warn of a VariantBankCoderInfo held under a property named
undefined<P Name="undefined">showed five blank cells, plus anOther.undefinedrow, with no warning.fieldOfreads only named fields, and nothing reported the bag it could not read.heldUnderUndefined(props)covers the case with no envelope, an ownundefinedkey and none of the five fields. In that caseunreadFieldsadds onepart-unreadableclause, worded per format. Display, save-as-read and the edit refusal are unchanged, and are now pinned.coderinfo_undefined.mjsbuilds 15 /tmp files from the repo fixtures (5 at first; the controls were added in the fix rounds), andprobe_coderinfo_undefined.mwrites the truth. In binary, the dictionary opens, but that entry's getValue fails ("unable to create an object of class 'Simulink.VariantBankCoderInfo'"). In text, MATLAB reads every default. When some of the five properties sit besideundefined, MATLAB reads those and ignores theundefined. MATLAB gave no warning in any case.expected [] to deeply equal [['ciA','part-unreadable']]). The controls and the "beside" case pass by design: MATLAB warns of none of them, and neither does core. The mutants of the check are listed under the fix rounds; at head every one is killed. No existing test changed.undefinedstill gets no warning; it needs its own measurement. A repair action would be a new design decision.heldUnderUndefineddoes not depend on the format, so a binary coder info with no envelope, anundefinedand some of the five is not measured, and is not warned of. MATLAB does not write a binary plain bag, and the old package wroteundefinedwith none of the five beside it, so that case is hypothetical. A follow-up could measure it.B-19 (03abbc2): VariantConfigurations has no Value
Valueto''and accepted a Value edit. Both save paths wrote that Value beside the envelope, and an unedited plain-bag save added"Value": "".probe_variantconfigurations_value.mopens no file. Under both class names, the object built isSimulink.VariantConfigurationsandisprop(...,'Value')is 0. Its metaclass lists 10 properties and none is Value. Setting one fails: "Unrecognized property 'Value' ..."._serializedOverrides()returns{}. A Value key a file already carries is written back as read.test/variantConfigurationsNoValue.test.tshas 7 tests, and 6 of the 7 failed against main's node. The MATLAB-truth pluscreateDefaultfields test passes on main by design. The 7th failure in the before-run was the changedobjectArrayElementClasspin.variantLeafNodes.test.ts: the class joinsREAD_ONLY, because its "writes an edit back" case was the removed Value edit.objectArrayElementClass.test.ts: the exemption forconfigurations("its node writes a Value") is removed.newEntryEnvelopeBothFormats.test.ts(C-199): thedeclared:falserow and the "undeclared field" test used VCD's Value as their vehicle. They move to a test-local custom saver,Test.UndeclaredSibling, which still goes through the real writers and readers. A mutant that dropsdelete stored[key]inDataNode._mergePropsfails all 3 of its tests.displayValuestays'').Gates at 03abbc2 (before the fix rounds)
Gates at the current head are under Fix round 3.
rm -rf dist && npm run buildleaves the tree clean.npm run verify: exit 0. 296 test files passed and 1 skipped; 10435 tests passed and 27 skipped. The smoke, pack, leak and browser checks are OK.DEX_READBACKS_CORPUS=... npx vitest run test/parity/readbacks.truth.test.ts test/parity/m9MergedSaves.truth.test.ts: 45 of 45 passed.DEX_MATLAB_CMDtests were not run. None of them reaches these paths: the writeback/fidelity live tests type scalars, arrays and a char, and none covers VariantBank or VariantConfigurations.variable.fidelity's{1, 2}cell edit reaches no changed branch either: it is refused before and after.Fix round 1
Two new commits on top of 03abbc2. No force-push, and no earlier commit was changed. main was 31b8ac3; #150 changes no src or dist. The branch merged into it with no conflict, so main was not merged in.
cellSignMember.test.tsnow also parses{abc, -2},{abc, 1e-3},{abc, 'x-y'},{abc, [1 -2]}and{-2, abc}. It expects the word to stay text and the other member to be read as before. Main and this branch both give that. If the operator check runs on the whole row (.test(rowStr)) instead of on the member (.test(span)), every one of these comes backnull, and the test fails (expected null to deeply equal { type: 'cell', … }). No other test changed, and dist is unchanged.undefinedstruct holding other values beside the envelope MATLAB wrote, in binary (b_ciA_envelope_beside) and in text (t_ciA_envelope_beside). MATLAB reads the envelope and ignores theundefined.t_ciA_empty_bag), and one holding onlyFoo: 'x'(t_ciA_other_bag). MATLAB reads every default.variantBankFields.test.tsgrades each control against the truth: no warning, shown as read, itsOther.rows listed, and saved as read.own(UNDEFINED_KEY)is dropped, the two bag controls fail. If!(SAVEOBJ_KEY in props)is dropped, the two envelope controls fail. Each failure is the'undefined'warning that MATLAB does not give.heldUnderUndefined, and dist was regenerated. The coder info doc, the probe header and the README row name the controls.rm -rf dist && npm run buildleaves the tree clean.npm run verify: exit 0. 296 files passed and 1 skipped; 10439 tests passed and 27 skipped (4 more than before).Fix round 2
One new commit on top of 4fed791. There was no force-push, and no earlier commit changed. main was still 31b8ac3, and the trial merge was clean, so main was not merged in.
heldUnderUndefined, the part!FIELDS.some(own)was not held by any test. Two mutants passed the full suite:.everyin place of.some, and a check ofHeaderFilealone. Under either, a text plain bag with anundefinedbeside only some of the five properties got a falsepart-unreadablewarning, saying that MATLAB reads the coder info with every property at its default.What MATLAB does (R2027a 27.1.0.3409468, on /tmp files made from
test/fixtures/variantbank_r2027a_text.sldd): two new control cases.t_ciA_partial_headeris ciA'sHeaderFilealone, beside anundefinedstruct of other values. MATLAB readsh.h, with every other property at its default.t_ciA_partial_definitionis ciA'sDefinitionFileandQualifier, beside the same struct. MATLAB readsd.candConst, with every other property at its default.undefinedand gives no warning. Core already did the same, so there is no behaviour change. The measurement is text only (see B-08, Left out).coderinfo_undefined.mjsmakes the two files. The truth gains the two cases and their rows. The 9 earlier rows are byte-identical, and so is the header (date 2026-10-19).variantBankFields.test.tsgrades both cases as controls: no warning, shown and listed (Other.undefined) as read, and saved as read.The two bags hold no field in common, so every single-field form of the check is killed:
.every!own('HeaderFile')t_ciA_partial_definition!own('DefinitionFile')t_ciA_partial_header!own('Qualifier')t_ciA_partial_header!own('PreStatement')!own('PostStatement')Each failure is
expected [ { code: 'part-unreadable', … } ] to be undefined. A check of a larger subset of the five could still pass; round 3 closes that.The only src change is the comment above
heldUnderUndefined("any of the five", and what was measured). dist was regenerated, and differs in that comment and its maps only. The coder info doc, the probe header and the README row name the new controls.No existing test changed. The controls were added to B-08's own
CONTROLSlist, which this PR added.rm -rf dist && npm run buildleaves the tree clean.npm run verify: exit 0. 296 files passed and 1 skipped. 10441 tests passed and 27 skipped (2 more than at 4fed791). Smoke, pack (659 files), leak and browser checks are OK.npm pack: verify 3539/3539, integration 275 passing and 1 pending.Fix round 3
Main had moved to 17b610c, so this round merged it in, then closed the last gap in B-08's controls and checked B-01's side effect on files. There was no force-push, rebase or amend, and no earlier commit changed.
test/parity/matlab/README.md: both sides added probe rows at the same place in the table. Both sides' rows are kept.rm -rf dist && npm run build), and it equals the dist git merged.npm run verifyexit 0, 301 files passed and 1 skipped, 10750 tests passed and 27 skipped. DEX_READBACKS_CORPUS readbacks plus m9MergedSaves: 45/45.!FIELDS.some(own)were!FIELDS.filter((f) => f !== X).some(own)for X = DefinitionFile, Qualifier, PreStatement or PostStatement, and!own('HeaderFile') && !own('DefinitionFile')(the same as!FIELDS.slice(0, 2).some(own)). Under any of them, a bag that holds only a field the check skips gets a falsepart-unreadablewarning. Display and save are unchanged.What MATLAB does (R2027a 27.1.0.3409468, re-running the committed probe on the /tmp files the committed generator makes from
test/fixtures/variantbank_r2027a_text.sldd): four new control cases.t_ciA_partial_definition_alone,t_ciA_partial_qualifier,t_ciA_partial_preandt_ciA_partial_posteach hold one ofDefinitionFile,Qualifier,PreStatementorPostStatementalone, beside anundefinedstruct of other values. MATLAB reads each from that one field (d.c,Const,pre,post), with every other property at its default, ignores theundefined, and gives no warning. Core already did the same, so there is no behaviour change.The truth gains the four cases and their rows. The 11 earlier cases and rows are unchanged, and so is the header (date 2026-10-19).
variantBankFields.test.tsgrades the four as controls, as before: no warning, shown and listed (Other.undefined) as read, and saved as read. Witht_ciA_partial_header, each of the five is now held alone by one control. A check that leaves out any field therefore warns of that control, and no subset of the five can pass.Each mutant was applied to src,
variantBankFields.test.ts(611 tests) was run, and the file was restored byte for byte. None was committed.!FIELDS.some(own)!FIELDS.filter((f) => f !== 'HeaderFile').some(own)t_ciA_partial_header!FIELDS.filter((f) => f !== 'DefinitionFile').some(own)t_ciA_partial_definition_alone!FIELDS.filter((f) => f !== 'Qualifier').some(own)t_ciA_partial_qualifier!FIELDS.filter((f) => f !== 'PreStatement').some(own)t_ciA_partial_pre!FIELDS.filter((f) => f !== 'PostStatement').some(own)t_ciA_partial_post!own('HeaderFile') && !own('DefinitionFile')t_ciA_partial_qualifier,t_ciA_partial_pre,t_ciA_partial_post!FIELDS.every(own)Each failure is
expected [ { code: 'part-unreadable', … } ] to be undefined.src gains only comments: the comment above
heldUnderUndefinednames what was measured, and so does the coder info doc. dist differs in that comment and its maps only. The generator, the probe header and the README row name the new controls.No existing test changed. The controls were added to B-08's own
CONTROLSlist.V==-1,V>-2,@(x)x+1,1:-1:0,-int8(1),-0x1Fore-3is a char member.{…};{…};{'V == 1','V==-1'},{'@(x)x+1'}). Every other entry is shown as it is without the edit, and the file is saved byte-identical. Typing the shown text back unchanged is taken as no change, as on main.{}. That difference is the B-06 fix.{V==-1}and{V>-2}, and refused the other five through the condition check. It is refused with "Invalid MATLAB expression" in a plain variable's cell, where main held each one as a char. It is also refused with "Invalid MATLAB expression" in a Parameter's Value, where main refused it as a cell Value.rm -rf dist && npm run buildleaves the tree clean.npm run verify: exit 0. 301 files passed and 1 skipped. 10754 tests passed and 27 skipped (4 more than on the merge). Smoke, pack (659 files), leak and browser checks are OK.Mutants re-checked by the orchestrator at 1e08fca
In a fresh clone, each applied alone to
src, run againstvariantBankFields.test.tsandcellSignMember.test.ts, then restored:.everyfails 6; dropping any one of HeaderFile, DefinitionFile, Qualifier, PreStatement or PostStatement from the check fails 1 each (its own partial control);!own('HeaderFile') && !own('DefinitionFile')fails 3; droppingown(UNDEFINED_KEY)fails 2 (the empty and the other-field bags); dropping!(SAVEOBJ_KEY in props)fails 2 (the envelope beside, binary and text); B-01's operator check on the whole row (rowStr) instead of the member fails 1 (the bare-word control).Noted for later (not changed)
VariantConfigurationDataNode.setProperty, the Value edit is still refused if_refuseEncodedEditor_refuseInlineBagEditis dropped. Only the reason changes, to the generic "has no Value". Neither reason is pinned yet. Nothing is written in either case.Simulink.VariantBankCoderInfo.md(lines 129-132, from before this PR) names two corpus paths. This PR edits that file but not those lines. A separate follow-up should remove them, as B-06 did forSimulink.VariantBank.md.Implements the maintainer's rulings, as audited in group H (2026-10-19).