Fix the red eval gate, and the form-clone defect the stale row was hiding - #168
Merged
Merged
Conversation
…164) The `eval` CI job has been red since #167 merged: `eval coverage --check` reported COVERAGE_DRIFT because #167 added the `form-clone` capability without regenerating eval/COVERAGE.md. (#165's red build-test and knowledge-audit were an Actions outage — "Failed to resolve action download info" — not code, and are already green on main.) Writing the missing eval case surfaced a real defect in the capability the stale row was hiding. `--rebind` renamed the datasource and repointed the control-level <DataSource> nodes, but left the design's own <DataSource> and <TitleDataSource> naming the datasource the clone no longer has — a form that compiles and fails at runtime. The cause is that those two are first-level children of <Design>, so they are written as <DataSource xmlns="">, and the pattern was anchored on the bare "<DataSource>"; the control-level ones nest under <Controls xmlns="">, inherit the namespace, appear bare, and so were the only ones matched. <JoinSource> was not handled at all, so a joined datasource kept pointing at its parent's old name. The element list is grounded on the live installation rather than guessed: across 300 shipped ApplicationSuite forms, DataSource, TitleDataSource, WorkflowDataSource, PresenceDataSource and JoinSource are the only elements whose value is a datasource name — the rest of the *DataSource* family is either a container or holds something else ( DataSourceChangeGroupMode is an enum, DataSourceRelation names a relation). Matching now tolerates attributes and backreferences the closing tag, so it cannot bleed from DataSource into DataSourceLinks. The unit fixture's <Design> went straight to <AxFormControl> and so never had the nodes that break — it now carries the design properties and a joined datasource, which is what makes the four new tests fail before the fix. L2-form-clone-basic clones the two-datasource details-transaction form: 19 KB in, and the clone differs on exactly the root <Name> and the class declaration and is byte-identical everywhere else, which is the guarantee worth locking for string surgery over a document this code does not own. It is a plain clone rather than a rebind because MiniAot has only FmVehicle and FmVehicleLine: rebinding the simple form onto FmVehicleLine binds a <DataField>Make</DataField> that table does not have, and the richer form already uses both, so either golden would enshrine a form nobody should ship. The rebind path is covered by the unit tests instead. A fixture table would let it graduate to an eval case; left as follow-up. Verified locally against all four CI jobs: build clean, 1178 tests pass, knowledge audit clean, 52/52 eval cases with `coverage --check` green, and no skills drift. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SuTvn5ymx3HAUtGjsxBuaA
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.
Why CI is red
evalhas been failing onmainsince #167 merged. All 51 cases passed — the failure is the job's second step:#167 added the
form-clonecapability without regeneratingeval/COVERAGE.md.#165's red
build-test (ubuntu)andknowledge-auditwere not code. Both died before checkout on an Actions outage (Failed to resolve action download info. Error: Service Unavailable); macOS and Windows passed in the same run and both jobs are already green onmain. Nothing to fix there.The defect behind the stale row
Regenerating
COVERAGE.mdalone would have turned CI green while leavingform-cloneat--T— shipped, untaught, unproven. Writing the missing eval case surfaced a real bug.--rebindrenamed the datasource and repointed the control-level<DataSource>nodes, but left the design's own<DataSource>and<TitleDataSource>naming a datasource the clone no longer has:A form that compiles and fails at runtime.
Cause. Those two are first-level children of
<Design>, so they are written as<DataSource xmlns="">. The pattern was anchored on the bare"<DataSource>". The control-level ones nest under<Controls xmlns="">, inherit the namespace, appear bare — so they matched and the design ones did not.<JoinSource>was not handled at all, leaving a joined datasource pointing at its parent's old name.The fix
The element list is grounded on the live installation rather than guessed. Across 300 shipped
ApplicationSuiteforms, these are the only elements whose value is a datasource name:DataSourceTitleDataSourceWorkflowDataSourcePresenceDataSourceJoinSourceThe rest of the
*DataSource*family is either a container (DataSources,DataSourceLinks,ReferencedDataSources) or holds something else —DataSourceChangeGroupModeis an enum,DataSourceRelationnames a relation. Names reached through a nested<Name>(root links, referenced/derived datasources) were already covered by the existing<Name>rewrite.Matching now tolerates attributes and backreferences the closing tag, so it cannot bleed from
DataSourceintoDataSourceLinks— there is a negative test for exactly that.Why the tests missed it
The unit fixture's
<Design>went straight to<AxFormControl>, so it never contained the nodes that break. It now carries the design properties and a joined datasource — which is what makes the four new tests fail before the fix and pass after.The eval case
L2-form-clone-basicclones the two-datasource details-transaction form: 19 KB in, and the clone differs on exactly the root<Name>and the class declaration, byte-identical everywhere else. That is the guarantee worth locking for string surgery over a document this code does not own.It is a plain clone rather than a rebind deliberately. MiniAot has only
FmVehicleandFmVehicleLine: rebinding the simple form ontoFmVehicleLinebinds a<DataField>Make</DataField>that table does not have, and the richer form already uses both, so either golden would enshrine a form nobody should ship. The rebind path is covered by unit tests, which assert it more precisely anyway. Adding a third fixture table would let it graduate to an eval case — left as follow-up, sinceMiniAotEndToEndTestsasserts the fixture's table count.form-clonenow reads-E TinCOVERAGE.md, matching itscontrol-method/datasource-methodsiblings.Verification
All four CI jobs run locally:
coverage --checkgreen🤖 Generated with Claude Code