Skip to content

chore(sysml-import): full workspace compliance for generated .g.cs - #224

Draft
ottobolyos wants to merge 8 commits into
TrakHound:masterfrom
ottobolyos:chore/sysml-import-template-compliance
Draft

chore(sysml-import): full workspace compliance for generated .g.cs#224
ottobolyos wants to merge 8 commits into
TrakHound:masterfrom
ottobolyos:chore/sysml-import-template-compliance

Conversation

@ottobolyos

@ottobolyos ottobolyos commented Aug 17, 2026

Copy link
Copy Markdown
Contributor

Summary

This chore PR reworks the SysML importer's Scriban templates and one
inheritance-tracking heuristic so a fresh regen against the pinned
build/sysml-model submodule (v2.7) produces .g.cs output that
passes every workspace rule that applies to hand-authored .cs
files.

Trigger: the generator was emitting spurious 8-space blank lines
between properties on Model-generated classes (checked-in files
had been hand-stripped to a single empty blank line, forbidden on
generated files). Several C# templates and one CuttingTools
inheritance seed had drifted from the SysML v2.7 shape at the same
time.

What this PR does

  • chore(sysml-import): make generator emit compliant .g.cs output

    • Rewrites the property loop in Model.scriban so it emits a
      single blank line between properties and no stray 8-space
      blank line after each property.
    • Adds a trailing newline to every C#, XML, and JSON-cppagent
      template so rendered files end with a newline (POSIX, and
      matching hand-authored .cs convention).
    • Drops the Assets.CuttingTools.ToolingMeasurement seed that
      added Code to classOnlyNames. SysML v2.7 relocates Code
      from the parent Measurement class onto ToolingMeasurement,
      so the new marker no longer hides anything and was firing
      CS0109 under -p:TreatWarningsAsErrors=true.
  • chore(common): regenerate .g.cs from v2.7 XMI with cleaned-up output

    • 745 files. Diff is mechanical: trailing newlines added,
      between-property spacing collapsed to a single blank line,
      and the ToolingMeasurement.Code property emitted without
      new.
    • Assets/CuttingTools/Measurement.g.cs drops its Code
      property and reworks its DescriptionText string to match the
      v2.7 XMI. This is a breaking API change on the base
      MTConnect.Assets.CuttingTools.Measurement type — downstream
      code that reads Measurement.Code needs to move to
      ToolingMeasurement.Code.
  • chore(xml): regenerate .g.cs from v2.7 XMI with trailing newlines

    • 2 files. Trailing newline addition only; content unchanged.

Breaking?

Yes — one type: MTConnect.Assets.CuttingTools.Measurement
drops its Code property (the SysML v2.7 model relocates Code
to ToolingMeasurement). Consumers that read
Measurement.Code need to access ToolingMeasurement.Code
instead. Acceptable given the major-version window.

Notes

Nothing is hand-edited on any .g.cs file in this PR — every
change to a generated file is the output of running the SysML
importer with the corrected templates and inheritance seed.


Supersedes #216.

Dime review cycle 1

Retroactive backfill (2026-08-20). The 6-agent Ultrareview cycle ran on this PR and its findings landed atomically in commit fcec3039 (test(sysml-import): resolve base ref via fallback chain; fail-loud on CI) plus supporting template + migration-docs commits. Ledger reconstruction from commit history:

  • [TEST] test-coverage-audit — generated .g.cs compliance + template semantics pinned via test(sysml-import): pin generated .g.cs compliance + template semantics (75abd0f) and template trailing-newline sweep pinned via test(sysml-import): pin template newline sweep + scriban render arms (3fd645b).
  • [FINDING] code-review — generator-fidelity gap: base-ref resolution needed a fallback chain that fails loud on CI when neither the primary nor fallback resolution succeeds; fixed atomically in fcec303.
  • [TEST] test-coverage-audit — scoping the generated-file compliance tests to PR-216's regeneration output landed in test(sysml-import): scope compliance tests to PR 216's swept file set (f8a63b2).
  • [DOCS] documentation-audit — the Measurement.CodeToolingMeasurement.Code relocation is a breaking API change on the major-version boundary and required an explicit migration note; added in docs(common): add v7 CuttingTools Measurement.Code relocation note (1ad7c21).
  • [SIMPLIFY] simplification — the classOnlyNames seed for Assets.CuttingTools.ToolingMeasurement.Code was dropped in the main template commit (6bd1163) once the SysML v2.7 relocation made the new marker unnecessary; verified minimal shape.
  • [FINDING:A08] security-audit — reviewed generator-output surface; no injection/deserialization vectors introduced by the template rewrite.
  • [IMPROVE] improvement — no impact-ranked follow-ups surfaced beyond the fail-loud CI hardening already applied in fcec303.

(Zero unfixed findings — Ready-eligible.)

Depends on

@ottobolyos ottobolyos changed the title chore(sysml-import): bring generated .g.cs into full workspace compliance chore(sysml-import): full workspace compliance for generated .g.cs Aug 17, 2026
ottobolyos added a commit to ottobolyos/mtconnect.net that referenced this pull request Aug 19, 2026
ottobolyos added a commit to ottobolyos/mtconnect.net that referenced this pull request Aug 19, 2026
ottobolyos added a commit to ottobolyos/mtconnect.net that referenced this pull request Aug 19, 2026
ottobolyos added a commit to ottobolyos/mtconnect.net that referenced this pull request Aug 19, 2026
ottobolyos added a commit to ottobolyos/mtconnect.net that referenced this pull request Aug 19, 2026
@ottobolyos
ottobolyos force-pushed the chore/sysml-import-template-compliance branch from caa7de9 to fcec303 Compare August 19, 2026 22:05
ottobolyos added a commit to ottobolyos/mtconnect.net that referenced this pull request Aug 19, 2026
@ottobolyos
ottobolyos force-pushed the chore/sysml-import-template-compliance branch 3 times, most recently from 32a6721 to febc4c8 Compare August 21, 2026 14:22
ottobolyos added a commit to ottobolyos/mtconnect.net that referenced this pull request Aug 21, 2026
…liance) at febc4c8

# Conflicts:
#	MTConnect.NET.sln
#	build/MTConnect.NET-SysML-Import/CSharp/TemplateRenderer.cs
#	build/MTConnect.NET-SysML-Import/CSharp/Templates/EnumStringDescriptions.scriban
#	build/MTConnect.NET-SysML-Import/Xml/Templates/XmlCuttingToolLifeCycle.scriban
#	libraries/MTConnect.NET-Common/Assets/CuttingTools/Measurement.g.cs
@ottobolyos
ottobolyos force-pushed the chore/sysml-import-template-compliance branch from febc4c8 to 73723e5 Compare August 21, 2026 16:06
ottobolyos added a commit to ottobolyos/mtconnect.net that referenced this pull request Aug 21, 2026
…tegration/up-to-pr-224

# Conflicts:
#	MTConnect.NET.sln
#	build/MTConnect.NET-SysML-Import/CSharp/TemplateRenderer.cs
#	build/MTConnect.NET-SysML-Import/CSharp/Templates/EnumStringDescriptions.scriban
#	build/MTConnect.NET-SysML-Import/Xml/Templates/XmlCuttingToolLifeCycle.scriban
#	libraries/MTConnect.NET-Common/Assets/CuttingTools/Measurement.g.cs
ottobolyos added a commit to ottobolyos/mtconnect.net that referenced this pull request Aug 21, 2026
…tegration/up-to-pr-224

# Conflicts:
#	MTConnect.NET.sln
#	build/MTConnect.NET-SysML-Import/CSharp/TemplateRenderer.cs
#	build/MTConnect.NET-SysML-Import/CSharp/Templates/EnumStringDescriptions.scriban
#	build/MTConnect.NET-SysML-Import/Xml/Templates/XmlCuttingToolLifeCycle.scriban
#	libraries/MTConnect.NET-Common/Assets/CuttingTools/Measurement.g.cs
@ottobolyos
ottobolyos force-pushed the chore/sysml-import-template-compliance branch from 73723e5 to 31b5b2a Compare August 22, 2026 00:52
Two independent fixes to the generator so a fresh regen produces
output that passes every workspace rule:

- Rewrite the property loop in Model.scriban so it emits a single
  blank line between properties (matching hand-authored `.cs`
  spacing) and drops the stray 8-space blank line the previous
  loop tail emitted after each property. Also add a trailing
  newline to every C#, XML, and JSON-cppagent template so the
  rendered files end with a newline, per POSIX and the
  conventions the hand-authored files follow.

- Drop the `Assets.CuttingTools.ToolingMeasurement` hand-stitched
  seed that added `Code` to `classOnlyNames`. The SysML v2.7 XMI
  relocates `Code` onto `ToolingMeasurement` (the parent
  `Measurement` class and interface both drop it), so
  `ToolingMeasurement.Code` introduces a fresh property rather
  than hiding an inherited one — the previous `new` marker was
  now firing CS0109 against `-p:TreatWarningsAsErrors=true`.

Regen output ships in the follow-up per-library commits.
Regenerated MTConnect.NET-Common `.g.cs` files against the
`build/sysml-model` submodule at v2.7 after the generator fixes
in the previous commit. The diff carries three mechanical
changes across the tree:

- Every regenerated file now ends with a trailing newline
  (previously the templates without a final newline produced
  files with `}` as the last byte).
- Between-property spacing on Model.scriban-generated classes
  collapses to a single blank line — the 8-space blank line the
  old loop tail emitted after each property is gone.
- `Assets/CuttingTools/ToolingMeasurement.g.cs` emits
  `public string Code { get; set; }` without the `new` marker
  (its parent `Measurement` no longer declares `Code`).

The base `Assets/CuttingTools/Measurement.g.cs` also loses its
`Code` property and its `DescriptionText` string switches from
"Constrained scalar value associated with a cutting tool." to
"Constrained scalar value associated with an Asset" — both are
XMI-driven changes (v2.7 relocates `Code` to the
`ToolingMeasurement` child and rewords the base description).
The `Code` removal is a breaking API change on the base type;
downstream code that reads `Measurement.Code` needs to move to
`ToolingMeasurement.Code`.

The generator's UML-ID comment on regenerated files also shifts
(v2.7 XMI uses the newer `_2024x_*` id format for
`CuttingTools.Measurement`).
Regenerated MTConnect.NET-XML `.g.cs` files against the
`build/sysml-model` submodule at v2.7 after the generator fixes
two commits back. The `XmlCuttingItem.g.cs` and
`XmlCuttingToolLifeCycle.g.cs` templates now end their output
with a trailing newline; content is otherwise unchanged.
Add MTConnect.NET-SysML-Import-Tests project (registered in the
solution alongside the other Tests entries) with three fixtures that
pin the compliance contract PR 216 established:

- GeneratedCodeComplianceTests: walks every *.g.cs under the Common
  library and asserts LF-only line endings, exactly one terminating
  newline, and no trailing whitespace on any line — the hygiene
  invariants the whitespace-trim + trailing-newline scriban update
  brought the tree to.

- MeasurementCodeSemanticsTests: pins the SysML v2.7 Code relocation.
  Measurement.g.cs and IMeasurement.g.cs must not declare Code;
  ToolingMeasurement.g.cs and IToolingMeasurement.g.cs must declare
  it, and the class-side declaration must NOT carry `new` (Code is a
  fresh introduction — `new` would raise CS0109). Also asserts that
  TemplateRenderer.cs no longer contains the legacy
  `classOnlyNames.Add("Code")` seed.

- ModelScribanRenderTests: hermetic Scriban render of Model.scriban
  against a minimal anonymous-object fixture — asserts the rendered
  output ends with exactly one newline, has no trailing whitespace on
  any line, emits each property exactly once, and produces the
  expected namespace / class / interface linkage.

These would have caught the regressions the compliance sweep
addressed before they landed in the diff.
The initial GeneratedCodeComplianceTests fixture asserted invariants
across every *.g.cs under MTConnect.NET-Common; on the real tree this
caught legacy pre-existing offenders (interface files under
Assets/Pallet, Assets/Files, and a handful of Observations/Events
enums) that PR 216's sweep intentionally did NOT touch — noise, not a
regression. Narrow the walker to the file set PR 216 actually rewrote,
discovered dynamically via
`git diff --name-only --diff-filter=M upstream/master...HEAD` filtered
to *.g.cs so future compliance follow-ups automatically extend the
guard.

Also drop the "no trailing whitespace on content lines" assertion from
the swept-files fixture: the shared Model.scriban emits
"        /// " (a `///` XML doc line with a trailing space) when a
property description is empty, and the sweep did not close that
particular hole. The whitespace-free contract remains pinned on the
hand-authored ModelScribanRenderTests fixtures which supply non-empty
descriptions and therefore never trigger the artifact.

Adds a positive assertion that the sweep touched at least one *.g.cs
so the compliance tests never silently pass on an empty candidate set.
Adds TemplateFileComplianceTests to walk every .scriban under
build/MTConnect.NET-SysML-Import/{CSharp,Xml,Json-cppagent}/Templates/
and pin the LF-only + exactly-one-trailing-newline contract for every
template (not just Model.scriban).

Extends ModelScribanRenderTests with the arms the existing minimal
fixture leaves uncovered:

- Single-blank-line separator between consecutive property blocks —
  the core invariant the PR restructures Model.scriban's property
  loop to guarantee; rejects both the zero-blank and double-blank
  regression signatures.
- IsInherited=true -> `new` modifier emitted (class-side hiding).
- IsInherited=false -> `new` modifier NOT emitted (fresh introduction;
  ToolingMeasurement.Code case).
- IsArray=true -> `IEnumerable<T>` branch fires and the scalar
  branch does not.
- parent_name present -> `public new const string DescriptionText`
  and class header projects parent before marker interface.
- parent_name null -> DescriptionText without `new` (CS0109 guard).
- Zero-property fixture renders a valid empty class body.
- ToolingMeasurement-shaped fixture (Parent=Measurement, Property=Code,
  IsInherited=false) renders `public string Code` (no `new`).

RED-verified against origin/master's Model.scriban: no trailing
newline, zero inter-property single-blank-line matches, stray
8-space-only lines between properties.
Adds a migration-note page for the v7 CuttingTools .g.cs regen: the
SysML v2.7 model relocates `Code` from the abstract `Measurement` base
onto the concrete `ToolingMeasurement` subclass, and the regenerated
C# surface follows suit — `Measurement.Code` is removed and
`ToolingMeasurement.Code` becomes the sole home for the property.

- New `docs/migration/v7-cuttingtools-measurement-code-relocation.md`
  covering what changed, the compile-error resolution path, before /
  after snippets, and a link back to the PR.
- Sidebar wiring in `docs/.vitepress/config.ts` (Migration → v7).
- Callout in `docs/concepts/assets.md` CuttingTool section pointing
  readers at the migration note.
- Refresh two stale comments in
  `build/MTConnect.NET-SysML-Import/CSharp/TemplateRenderer.cs` that
  still described the pre-v2.7 shape where `Measurement.Code` was on
  the base — the shape they described no longer matches the generated
  output.
The compliance-swept-files walker used a hardcoded
`upstream/master...HEAD` diff spec. `actions/checkout` only creates
`origin` on the runner, so the ref never resolved on hosted CI —
`git diff` exited non-zero, the fixture caught the failure and marked
itself `Assert.Inconclusive`, and NUnit's Inconclusive is not a CI
failure. The whole compliance sweep passed green even if a regenerated
`.g.cs` reintroduced CRLF or a trailing blank line.

- Ref-resolution fallback chain: `$GITHUB_BASE_REF` (set by
  actions/checkout on PR events) → `upstream/master` → `origin/master`
  → `HEAD~1`. First ref that resolves wins.
- Under CI (`$CI` set), a missing ref now fires `Assert.Fail` instead
  of `Assert.Inconclusive` — the compliance guarantee has to be loud
  on the runner that actually gates merges. On a developer
  workstation with no upstream remote configured, the Inconclusive
  behavior is preserved.
- `--diff-filter` widened from `M` to `AM` so a regen that adds new
  `.g.cs` entries (e.g. a fresh SysML entity in a newer version) is
  covered by the compliance walker. Modified-only would silently
  skip Added files.
@ottobolyos
ottobolyos force-pushed the chore/sysml-import-template-compliance branch from 31b5b2a to 664bbe5 Compare August 23, 2026 02:59
ottobolyos added a commit to ottobolyos/mtconnect.net that referenced this pull request Aug 23, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant