|
| 1 | +# Migration Verification Ledger |
| 2 | + |
| 3 | +Tracks the byte-by-byte / faithfulness verification status of every Xtend→Java migrated file. |
| 4 | +Local working doc — **never commit** (lives under untracked `.claude/`). Last updated 2026-06-25. |
| 5 | + |
| 6 | +## Why two kinds of "vetted" |
| 7 | +These migrations include **code generators** whose emitted text becomes committed `src-gen`; for those, output must be **byte-identical** to what the Xtend compiler produced (`xtend-gen`) — CI cannot catch generator drift (no regen in the build). Non-generator files (tests, plain logic) emit no generated text, so byte-vetting is N/A; they need only **behavioural faithfulness**. |
| 8 | + |
| 9 | +## Verification tiers (strongest → weakest) |
| 10 | +- **HARNESS** — executable `StringConcatenation` byte-equality harness vs `xtend-gen` (gold standard; `.claude/coalesce-verify/*.java`) |
| 11 | +- **APPEND-DIFF** — append-for-append comparison of migrated `.java` vs `xtend-gen` (authoritative for emitted bytes) |
| 12 | +- **FAITHFULNESS** — behavioural read of logic/test files (emit no generated text → byte-vet N/A) |
| 13 | +- **SWEEP** — 51-agent ultracode faithfulness review (the merged batch, read-based) |
| 14 | +- **NONE** — not yet vetted |
| 15 | + |
| 16 | +--- |
| 17 | + |
| 18 | +## A. Generators (emit committed text) — BYTE-VETTED |
| 19 | + |
| 20 | +| File | PR | Tier | Result | |
| 21 | +|------|----|------|--------| |
| 22 | +| `LspBuilderIntegrationFragment2` | #1430 | HARNESS (`Probe`) | IDENTICAL | |
| 23 | +| `StandaloneBuilderIntegrationFragment2` | #1430 | HARNESS (`SB`) | IDENTICAL | |
| 24 | +| `FormatterFragment2` | #1430 | HARNESS (`FF`) | IDENTICAL | |
| 25 | +| `LanguageConstantsFragment2` | #1430 | HARNESS (`LC`) | IDENTICAL | |
| 26 | +| `AnnotationAwareContentAssistFragment2` | #1430 | HARNESS (`AACA`) | **DRIFT found → fixed in #1446** | |
| 27 | +| `ResourceFactoryFragment2` | #1430 | APPEND-DIFF | IDENTICAL | |
| 28 | +| `BuilderIntegrationFragment2` | #1430 | APPEND-DIFF (per-pair) | IDENTICAL | |
| 29 | +| `BundleVersionStripperFragment`, `DefaultFragmentWithOverride`, `ProjectConfig`, `ModelInferenceFragment2`, `CompareFragment2` | #1430 | APPEND-DIFF / per-pair read | IDENTICAL | |
| 30 | +| `FormatGenerator` | #1428 | APPEND-DIFF (Phase 2) | IDENTICAL | |
| 31 | +| `FormatJvmModelInferrer` | #1428 | APPEND-DIFF + deep-dive | `getDirectiveName` Group0 bug → fixed via A0/#1443; `List.of`→`Arrays.asList` → #1446 | |
| 32 | +| `FormatFragment2` (format.generator) | #1428-era | APPEND-DIFF (Phase 2) | IDENTICAL | |
| 33 | +| `CheckQuickfixProviderFragment2` (check.generator) | merged | APPEND-DIFF (Phase 2) | IDENTICAL | |
| 34 | +| `CheckCfgGenerator` (checkcfg.core) | merged | APPEND-DIFF (Phase 2) | IDENTICAL | |
| 35 | +| `AbstractAnnotationAwareAntlrGrammarGenerator` | #1429 | APPEND-DIFF (manual) | IDENTICAL | |
| 36 | +| `AnnotationAwareAntlrGrammarGenerator` | #1429 | HARNESS (`AAGG1`/`AAGG2`) | IDENTICAL | |
| 37 | +| `AnnotationAwareAntlrContentAssistGrammarGenerator` | #1429 | HARNESS (`CA1`) + APPEND-DIFF (agent, empirical StringConcatenation) | IDENTICAL (incl. uncommitted batch-1) | |
| 38 | +| `AnnotationAwareXtextAntlrGeneratorFragment2` | #1429 | APPEND-DIFF (agent) | IDENTICAL | |
| 39 | + |
| 40 | +**Every byte-output generator across the campaign is byte-vetted.** The only confirmed generator drift (`AnnotationAware`) is fixed in #1446; the only generator behavioural defect (`getDirectiveName`) was split out and merged as #1443. |
| 41 | + |
| 42 | +## B. Logic / test files — FAITHFULNESS-VETTED (byte-vet N/A) |
| 43 | + |
| 44 | +- **#1429**: `GrammarRuleAnnotations`, `PredicatesNaming` — workflow agents, logic faithful. |
| 45 | +- **#1427 check.core.test (11)**: per-pair read by me — all OK (1 nit, §D). |
| 46 | +- **Merged batch (~31)** — checkcfg.core(.test), sample.helloworld, xtext.ui, xtext.scope/export generators, format.ide/ui, check.test.runtime, check/format .test, xtext.check.generator — **SWEEP** (51-agent ultracode), all CLEAR (1 nit, §D). Generators within this batch were additionally APPEND-DIFF'd (§A). |
| 47 | + |
| 48 | +## C. Pure deletions — N/A (no `.java` counterpart, not migrations) |
| 49 | +- `AbstractResourceDescriptionManagerTest.xtend` (dead JUnit4 infra, `d920b3bad`) |
| 50 | +- `CheckNewProject.xtend`, `CheckQuickfixProvider.xtend` (wizard removal, `06de65661`) |
| 51 | + |
| 52 | +## D. Known divergences (all fixed or benign) |
| 53 | +| File | Divergence | Status | |
| 54 | +|------|-----------|--------| |
| 55 | +| `AnnotationAwareContentAssistFragment2` | multi-line `Alternatives` continuation-indent drift | **fixed in #1446** | |
| 56 | +| `FormatJvmModelInferrer.getDirectiveName` | `Group0` varargs-trap bug | **fixed, merged #1443** | |
| 57 | +| `FormatJvmModelInferrer` dispatcher throws | `List.of` null-intolerant; empty-`[]` noise | **fixed in #1446** (9 → `Arrays.asList`, 3 empty simplified) | |
| 58 | +| `CheckModelUtil.modelWithContexts` (#1427) | trailing `"\n "` vs Xtend | **deferred** — only caller is `@Disabled`; near-zero impact | |
| 59 | +| `CheckCfgScopeProviderTest` (checkcfg.core.test) | `NPE`→`IllegalStateException` (same msg/outcome) | **kept** — intentional quality improvement, documented | |
| 60 | + |
| 61 | +## E. Not yet byte-vetted |
| 62 | +- **No generator remains unvetted.** Non-generator merged files have FAITHFULNESS/SWEEP coverage only (byte-vet N/A — they emit no generated text). |
| 63 | +- **#1429 is the last open migration** — all 6 of its files are now byte-/faithfulness-vetted (§A/§B); pending: Ruben re-review of the remaining "multi-line string" comments + the `:90` decision. |
| 64 | + |
| 65 | +--- |
| 66 | + |
| 67 | +## F. Verification machinery — how to (re)trigger |
| 68 | + |
| 69 | +### Ground truth: `xtend-gen` |
| 70 | +The authoritative byte target is **`xtend-gen/`** — the Xtend compiler's own `.java` output. After a `.xtend` is migrated (deleted), its `xtend-gen` is gone from that branch, but **sibling worktrees on older commits still have it**: |
| 71 | +- locate: `find /Users/joao/Git/Avaloq/dsl-devkit* -path '*xtend-gen*<ClassName>.java'` |
| 72 | +- original `.xtend`: `git show <migration-commit>^:<path>` (or `upstream/master:<path>` while the PR is open) |
| 73 | +- **validity gates (always check):** (a) the worktree's `.xtend` is byte-identical to the migrated original (`diff`), and (b) `xtend-gen` mtime ≥ `.xtend` mtime (fresh, i.e. built from that source). |
| 74 | + |
| 75 | +### Method 1 — executable HARNESS (gold standard) — `.claude/coalesce-verify/*.java` |
| 76 | +Lift BOTH the original append sequence (a real `new StringConcatenation("\n")`, dynamic values as params) and the candidate (text block `.formatted(...)`) into a tiny Java program; assert `old.toString().equals(neu)` over an input battery (empty / multi-line / single-line / quotes / `%` / unicode / stub-vs-non-stub / options-vs-single). Compile/run: |
| 77 | +``` |
| 78 | +JAR=~/.m2/repository/org/eclipse/xtext/org.eclipse.xtext.xbase.lib/2.43.0/org.eclipse.xtext.xbase.lib-2.43.0.jar |
| 79 | +javac -cp "$JAR" -d . X.java && java -cp "$JAR:." X |
| 80 | +``` |
| 81 | +Existing harnesses: `Probe, SB, FF, LC, AACA, AAGG1, AAGG2, CA1`. Use real `StringConcatenation`/`StringConcatenationClient` (not a re-implementation) so two-arg `append(v,indent)` re-indent + `newLineIfNotEmpty` semantics are exact. `AACA` is the template that caught the only real drift (two-arg→single-arg on a multi-line value). |
| 82 | + |
| 83 | +### Method 2 — ULTRACODE Opus workflow (scale) — `Workflow({scriptPath})` |
| 84 | +Parallel Opus agents, one per file, each comparing migrated `.java` vs `xtend-gen` **append-for-append**, then an adversarial **refute-by-default** pass; schema-validated structured output; `pipeline(review → refute)`; `model: 'opus'`; **FIND-ONLY (read-only, no side effects).** |
| 85 | +- `.claude/wf-sweep.js` — the 51-file merged-migration sweep (CFG `.claude/sweep-cfg.json`, built from `git log --diff-filter=D --name-only -- '*.xtend'`). |
| 86 | +- `.claude/wf-p1429.js` — the 4 remaining #1429 generators/logic. |
| 87 | +- re-run/iterate: `Workflow({scriptPath, resumeFromRunId})` (completed agents return cached results). |
| 88 | + |
| 89 | +**The drift checklist baked into the agent prompt (and what to look for manually):** |
| 90 | +1. **two-arg `append(value,indent)` vs single-arg** — single-arg drops re-indentation of *continuation lines* of a MULTI-LINE value (the `AnnotationAware` bug). For every two-arg in `xtend-gen`, confirm migrated matches (or value is provably single-line). |
| 91 | +2. trailing whitespace from loop bodies (`«FOR»` strips last-element trailing; a `for` appending `"\n "` does not — the `modelWithContexts` bug). |
| 92 | +3. `newLine()` vs `newLineIfNotEmpty()` (differ on empty/whitespace-only lines). |
| 93 | +4. `StringBuilder "\n"` vs `StringConcatenation` default delimiter. |
| 94 | +5. Java text-block stripping (min indent incl. closing delim + trailing ws) vs Xtend rich-string min-content-indent stripping. |
| 95 | +6. import-managed `append(TypeReference/Class)` folded into a `%s` text block (output/import drift). |
| 96 | +7. `List.of` (null-intolerant) vs `Arrays.asList` (xtend-gen). |
| 97 | +**Benign — NOT findings:** `xtend-gen` splits `append(" ")+append("x")` vs migrated combined `append(" x")`; `_xxx` temp vars vs inlined calls; source-style/whitespace that doesn't change emitted bytes. |
| 98 | + |
| 99 | +### Adjudication rule |
| 100 | +Agent CLEAR is not final for generators — the only proofs that *caught* drift were the executable harness + append-for-append. Treat agent verdicts as triage; **harness-confirm any non-trivial generator** (esp. multi-line two-arg cases) before trusting CLEAR. |
| 101 | + |
| 102 | +--- |
| 103 | + |
| 104 | +## G. Complete file inventory (all 69 deleted `.xtend`, every file recorded) |
| 105 | + |
| 106 | +*Auto-derived 2026-06-25 from `git log --diff-filter=D` on master + the open #1429 branch. 66 migrated + 3 deletions.* |
| 107 | +Tier totals: APPEND-DIFF=14, DELETION (not a migration)=3, FAITHFULNESS (binding-only, no text)=3, FAITHFULNESS (per-pair)=11, FAITHFULNESS (workflow)=2, HARNESS=7, SWEEP=29 |
| 108 | + |
| 109 | + |
| 110 | +**com.avaloq.tools.ddk.check.core.test** (11) |
| 111 | +- `IssueCodeValueTest.xtend` — FAITHFULNESS (per-pair) |
| 112 | +- `BasicModelTest.xtend` — FAITHFULNESS (per-pair) |
| 113 | +- `BugAig830.xtend` — FAITHFULNESS (per-pair) |
| 114 | +- `CheckScopingTest.xtend` — FAITHFULNESS (per-pair) |
| 115 | +- `IssueCodeToLabelMapGenerationTest.xtend` — FAITHFULNESS (per-pair) |
| 116 | +- `ProjectBasedTests.xtend` — FAITHFULNESS (per-pair) |
| 117 | +- `CheckModelUtil.xtend` — FAITHFULNESS (per-pair) |
| 118 | +- `CheckTestUtil.xtend` — FAITHFULNESS (per-pair) |
| 119 | +- `CheckFormattingTest.xtend` — FAITHFULNESS (per-pair) |
| 120 | +- `CheckApiAccessValidationsTest.xtend` — FAITHFULNESS (per-pair) |
| 121 | +- `CheckValidationTest.xtend` — FAITHFULNESS (per-pair) |
| 122 | + |
| 123 | +**com.avaloq.tools.ddk.check.test.runtime** (1) |
| 124 | +- `TestLanguageGenerator.xtend` — SWEEP |
| 125 | + |
| 126 | +**com.avaloq.tools.ddk.check.test.runtime.tests** (3) |
| 127 | +- `CheckConfigurationIsAppliedTest.xtend` — SWEEP |
| 128 | +- `CheckExecutionEnvironmentProjectTest.xtend` — SWEEP |
| 129 | +- `IssueLabelTest.xtend` — SWEEP |
| 130 | + |
| 131 | +**com.avaloq.tools.ddk.check.ui** (2) |
| 132 | +- `CheckNewProject.xtend` — DELETION (not a migration) |
| 133 | +- `CheckQuickfixProvider.xtend` — DELETION (not a migration) |
| 134 | + |
| 135 | +**com.avaloq.tools.ddk.check.ui.test** (1) |
| 136 | +- `CheckQuickfixTest.xtend` — SWEEP |
| 137 | + |
| 138 | +**com.avaloq.tools.ddk.checkcfg.core** (4) |
| 139 | +- `CheckCfgGenerator.xtend` — APPEND-DIFF |
| 140 | +- `CheckCfgJvmModelInferrer.xtend` — SWEEP |
| 141 | +- `PropertiesInferenceHelper.xtend` — SWEEP |
| 142 | +- `ConfiguredParameterChecks.xtend` — SWEEP |
| 143 | + |
| 144 | +**com.avaloq.tools.ddk.checkcfg.core.test** (7) |
| 145 | +- `CheckCfgContentAssistTest.xtend` — SWEEP |
| 146 | +- `CheckCfgScopeProviderTest.xtend` — SWEEP |
| 147 | +- `CheckCfgSyntaxTest.xtend` — SWEEP |
| 148 | +- `CheckCfgModelUtil.xtend` — SWEEP |
| 149 | +- `CheckCfgTestUtil.xtend` — SWEEP |
| 150 | +- `CheckCfgConfiguredParameterValidationsTest.xtend` — SWEEP |
| 151 | +- `CheckCfgTest.xtend` — SWEEP |
| 152 | + |
| 153 | +**com.avaloq.tools.ddk.sample.helloworld.ui.test** (3) |
| 154 | +- `CheckConfigurationIsAppliedTest.xtend` — SWEEP |
| 155 | +- `CheckExecutionEnvironmentProjectTest.xtend` — SWEEP |
| 156 | +- `IssueLabelTest.xtend` — SWEEP |
| 157 | + |
| 158 | +**com.avaloq.tools.ddk.xtext.check.generator** (2) |
| 159 | +- `CheckValidatorFragment2.xtend` — FAITHFULNESS (binding-only, no text) |
| 160 | +- `CheckQuickfixProviderFragment2.xtend` — APPEND-DIFF |
| 161 | + |
| 162 | +**com.avaloq.tools.ddk.xtext.export.generator** (1) |
| 163 | +- `ExportFragment2.xtend` — FAITHFULNESS (binding-only, no text) |
| 164 | + |
| 165 | +**com.avaloq.tools.ddk.xtext.format** (6) |
| 166 | +- `FormatRuntimeModule.xtend` — SWEEP |
| 167 | +- `FormatStandaloneSetup.xtend` — SWEEP |
| 168 | +- `FormatGenerator.xtend` — APPEND-DIFF |
| 169 | +- `FormatJvmModelInferrer.xtend` — APPEND-DIFF |
| 170 | +- `FormatScopeProvider.xtend` — SWEEP |
| 171 | +- `FormatValidator.xtend` — SWEEP |
| 172 | + |
| 173 | +**com.avaloq.tools.ddk.xtext.format.generator** (1) |
| 174 | +- `FormatFragment2.xtend` — APPEND-DIFF |
| 175 | + |
| 176 | +**com.avaloq.tools.ddk.xtext.format.ide** (2) |
| 177 | +- `FormatIdeModule.xtend` — SWEEP |
| 178 | +- `FormatIdeSetup.xtend` — SWEEP |
| 179 | + |
| 180 | +**com.avaloq.tools.ddk.xtext.format.test** (1) |
| 181 | +- `FormatParsingTest.xtend` — SWEEP |
| 182 | + |
| 183 | +**com.avaloq.tools.ddk.xtext.format.ui** (1) |
| 184 | +- `FormatUiModule.xtend` — SWEEP |
| 185 | + |
| 186 | +**com.avaloq.tools.ddk.xtext.generator** (18) |
| 187 | +- `BundleVersionStripperFragment.xtend` — APPEND-DIFF |
| 188 | +- `DefaultFragmentWithOverride.xtend` — APPEND-DIFF |
| 189 | +- `BuilderIntegrationFragment2.xtend` — APPEND-DIFF |
| 190 | +- `LspBuilderIntegrationFragment2.xtend` — HARNESS |
| 191 | +- `StandaloneBuilderIntegrationFragment2.xtend` — HARNESS |
| 192 | +- `FormatterFragment2.xtend` — HARNESS |
| 193 | +- `LanguageConstantsFragment2.xtend` — HARNESS |
| 194 | +- `ProjectConfig.xtend` — APPEND-DIFF |
| 195 | +- `ModelInferenceFragment2.xtend` — APPEND-DIFF |
| 196 | +- `AbstractAnnotationAwareAntlrGrammarGenerator.xtend` — APPEND-DIFF |
| 197 | +- `AnnotationAwareAntlrContentAssistGrammarGenerator.xtend` — HARNESS |
| 198 | +- `AnnotationAwareAntlrGrammarGenerator.xtend` — HARNESS |
| 199 | +- `AnnotationAwareXtextAntlrGeneratorFragment2.xtend` — APPEND-DIFF |
| 200 | +- `GrammarRuleAnnotations.xtend` — FAITHFULNESS (workflow) |
| 201 | +- `PredicatesNaming.xtend` — FAITHFULNESS (workflow) |
| 202 | +- `ResourceFactoryFragment2.xtend` — APPEND-DIFF |
| 203 | +- `CompareFragment2.xtend` — APPEND-DIFF |
| 204 | +- `AnnotationAwareContentAssistFragment2.xtend` — HARNESS |
| 205 | + |
| 206 | +**com.avaloq.tools.ddk.xtext.generator.test** (1) |
| 207 | +- `XbaseGeneratorFragmentTest.xtend` — SWEEP |
| 208 | + |
| 209 | +**com.avaloq.tools.ddk.xtext.scope.generator** (1) |
| 210 | +- `ScopingFragment2.xtend` — FAITHFULNESS (binding-only, no text) |
| 211 | + |
| 212 | +**com.avaloq.tools.ddk.xtext.test.core** (1) |
| 213 | +- `AbstractResourceDescriptionManagerTest.xtend` — DELETION (not a migration) |
| 214 | + |
| 215 | +**com.avaloq.tools.ddk.xtext.ui** (1) |
| 216 | +- `TemplateProposalProviderHelper.xtend` — SWEEP |
| 217 | + |
| 218 | +**com.avaloq.tools.ddk.xtext.ui.test** (1) |
| 219 | +- `TemplateProposalProviderHelperTest.xtend` — SWEEP |
| 220 | + |
0 commit comments