Commit 08c4cb7
fix(csharp): verify --codegen never saw the template-spec, so it convicted gen's own output
The C# half of the same defect fixed for Python in the previous commit. SP-1 §4 specified
"--template-spec <path>, with a conventional default the port auto-discovers and the flag
overriding", and that BOTH gen and verify read it. Only the flag on `gen` was built:
VerifyCommand.RunCodegenDrift resolved its own list via GeneratorRegistry.Resolve and never
looked for a spec, so a project that had just run `dotnet meta gen` failed its own drift
gate — every spec-emitted file reported as "committed but a fresh regen would not emit it".
The printed remedy loops. Regenerating cannot produce files the regen does not know about,
and `verify` takes no --template-spec flag to be told about them. It lands on one of the two
ports where the declarative spec is the ONLY consumer authoring path (the generator registry
is closed), so an adopter doing the one thing their port supports fails their own gate.
THE FIX is a shared resolver, not a second flag. GenCommand gains TemplateSpecPathFor +
TemplateSpecGenerators; Run and RunCodegenDrift both go through them. The explicit flag wins
and is used verbatim (a flag naming a missing file stays a hard error — silently ignoring a
path the user typed would be worse); otherwise <projectRoot>/template-spec.json is used if
present. `verify` has no flag, so discovery is the whole mechanism there — which is the
point: a flag on verify would have to be repeated at every CI call site, and one that is
forgotten reproduces the bug exactly.
projectRoot is ProjectRootFor(metadataDir) — the metadata dir's parent. Not a new rule: it
is already where the .gen-state manifest is anchored, and it is what the Python port uses.
Both ports now agree on the filename AND the anchor, which is what makes one spec file work
unchanged on either.
The catch around generator construction widens from ArgumentException to the same set
GenCommand.Run already handles (IOException / UnauthorizedAccessException / JsonException),
since verify can now hit the spec-reading paths that throw them — a malformed spec must come
back as `verify --codegen: <message>`, not an unhandled throw.
TWO DIFFERENCES FROM THE PYTHON PORT, both verified rather than assumed:
- C# does NOT have Python's second defect. Its CodegenDrift.ListFiles already enumerates
"*", so non-.cs template output was always compared. Python's globbed "*.py", which made
a deleted AND a corrupted template file report "in sync".
- C# has NO jurisdiction guard on its `inCommitted && !inFresh` branch, so it convicts
files it never wrote — the pre-0.24.3 TypeScript behaviour. That is a real and separate
defect, it is NOT introduced here, and fixing it changes verify's verdict for every
existing C# adopter, so it is reported rather than folded in.
The discriminating test is the one that matters: the lazy fix for a gate that convicts its
own output is to make it ignore what it does not recognise, which fixes the symptom by
blinding the gate. So deleting a spec-generated file, and separately editing one, must both
still fail. Plus: discovery works, the flag REPLACES discovery rather than adding to it, no
spec file leaves behaviour unchanged, and a malformed discovered spec fails loudly (silently
skipping it would put gen and verify back out of agreement, which is the whole defect).
Proven by breaking: reverting both files (file copy, not stash) fails 4 of the 7; restoring
passes 7. Full C# suite green across all four test projects — Cli 72, Render 291,
Conformance 994, Codegen 374 (+1 skipped), and the project count on disk was checked against
the count that reported, since `dotnet test` prints Passed! for a project that never built.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HSCgs7z19w8aGXGiceCohC1 parent 5fbe5b1 commit 08c4cb7
3 files changed
Lines changed: 221 additions & 9 deletions
File tree
- server/csharp
- MetaObjects.Cli.Tests
- MetaObjects.Cli
Lines changed: 154 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
| 146 | + | |
| 147 | + | |
| 148 | + | |
| 149 | + | |
| 150 | + | |
| 151 | + | |
| 152 | + | |
| 153 | + | |
| 154 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
83 | 83 | | |
84 | 84 | | |
85 | 85 | | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
86 | 136 | | |
87 | 137 | | |
88 | 138 | | |
| |||
109 | 159 | | |
110 | 160 | | |
111 | 161 | | |
112 | | - | |
113 | | - | |
114 | | - | |
115 | | - | |
116 | | - | |
117 | | - | |
118 | | - | |
| 162 | + | |
| 163 | + | |
| 164 | + | |
119 | 165 | | |
120 | 166 | | |
121 | 167 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
14 | 14 | | |
15 | 15 | | |
16 | 16 | | |
| 17 | + | |
17 | 18 | | |
18 | 19 | | |
19 | 20 | | |
| |||
238 | 239 | | |
239 | 240 | | |
240 | 241 | | |
241 | | - | |
| 242 | + | |
| 243 | + | |
| 244 | + | |
| 245 | + | |
| 246 | + | |
| 247 | + | |
| 248 | + | |
| 249 | + | |
| 250 | + | |
| 251 | + | |
| 252 | + | |
242 | 253 | | |
243 | | - | |
| 254 | + | |
| 255 | + | |
244 | 256 | | |
245 | 257 | | |
246 | 258 | | |
| |||
0 commit comments