Flush queued IDE writes and restart validation after host revision changes

This commit is contained in:
2026-11-13 20:53:22 +01:00
parent 8be0aec287
commit 1856f69637
11 changed files with 284 additions and 2 deletions
+4
View File
@@ -58,3 +58,7 @@ Evidence logs are `/tmp/generated-vm-bootstrap.log`, `/tmp/generated-vm-processo
The first registered IntelliJ run passed the classpath workflow but stopped in module-path mode at the previously recorded immediate exact-save assertion, before generation checks. An unchanged module-path retry timed out at initial canvas rendering (`WorkflowProbe` line 438), also before generation checks. No assertion was weakened. Existing startup/persistence/preview-gate reliability work remains open; this slice does not claim to fix those intermittent failures.
The final unchanged module-path retry hit the same initial-render timeout. Consequently, **registered IntelliJ module-path whole-host qualification remains open** for this slice. Registered IntelliJ classpath passed generated-registry discovery, full shared editing/history/diagnostic checks, exclusive JavaFX 26 native verification and worker shutdown. Standalone and real target-process module-path checks passed, including generated classes and registry behavior; these do not substitute for the missing registered IDE pass. Follow up on initial rendering and save synchronization before declaring that host gate complete.
## Save/startup gate follow-up
The previously open module-path host gate is closed by the [IntelliJ save/startup reliability follow-up](ide-host-reliability.md): deterministic regressions reproduced and corrected queued VFS persistence and stale validation state, followed by three consecutive passing registered module-path workflows with the generated registry checks included. The failed attempts above remain historical evidence.
+43
View File
@@ -0,0 +1,43 @@
# IntelliJ save completion and canvas startup
This follow-up addresses the save and initial-render failures recorded during [generated ViewModel qualification](generated-viewmodels.md). The unchanged initial module-path baseline passed once; that did not close the intermittent gate. Controlled scheduling regressions then reproduced both failures without manual input.
## Causes and fixes
**Save completion:** IntelliJ's `FileDocumentManager` is an asynchronous VFS write requestor. It can mark a Document clean before its bytes reach the filesystem. Our adapter completed its save future and read the old bytes through NIO. That also left a stale external-change baseline after a native autosave. The adapter now flushes pending updates for the affected file when establishing the initial disk baseline, before clean-disk comparisons and before completing an explicit save. Native save notifications record the accepted Document version. Actual external edits still fail with the draft retained; no competing file writer or undo store was introduced.
**Canvas startup:** the document-change render debounce and the host revision poll are independent. Validation can start against the old host revision, followed by loading a newer revision with identical text (edit/revert or native reload). Its reply is correctly rejected by revision, but the old in-flight marker previously remained. Later rendering joined that dead validation request indefinitely. Loading a new revision now invalidates obsolete validation state, and loading a usable projection schedules rendering again after synchronization. Stale replies remain rejected, including after a replacement validation starts.
Broader document-event filtering was considered but was not needed to reproduce or correct these failures. The fixes preserve the existing captured-draft and preview invalidation policy.
## Deterministic regressions
`IntellijDocumentsTest.testSaveWaitsForQueuedVfsWrites` runs against the real IntelliJ Document and asynchronous local VFS. Its test-only scheduling control holds the VFS executor queue; the real per-file flush must execute queued writes. Before the fix, the completed save returned clean while NIO read `before` instead of `after`. It additionally checks a queued native save followed by another edit/save, with no false external conflict. Opening a second designer adapter while the native save was queued reproduced `External change; draft retained` before the initial-baseline flush was added. The existing real external-conflict and draft-preservation tests remain required. Reflection into the executor is limited to this test and pinned to the qualified SDK; no host implementation depends on that internal field.
```sh
JAVA_HOME="$JAVA_HOME" designer-intellij/gradlew -p designer-intellij --no-daemon \
-PideaHome="$IDEA_HOME" test --tests '*IntellijDocumentsTest'
```
`ProjectionHostChecks.renderRevisionRace` pauses only the test's document-poll and render timers, performs an edit/revert through the real host document service, starts target validation and delivers the real poll callback before its reply. It requires fresh target pixels on the newer revision without another user action and verifies unchanged source. Before the fix it failed with `Host revision stranded target validation/rendering`. This scenario runs in both standalone and registered IntelliJ workflows. A narrow native standalone entry point runs the same scenario against a real module-path application:
```sh
python3 scripts/check-render-race.py --java-home "$JAVA_HOME" \
--target-java-home "$TARGET_JAVA_HOME"
```
Build/install the modules and run the bootstrap once to prepare its test classpath. The narrow script creates a disposable fixture and closes the host and workers. It does not replace whole-host qualification.
## Whole-host qualification
The real IDE runner now accepts `--mode classpath|modulepath|all` and `--repeat N`. Every repetition starts a fresh isolated IDE/project; it retains per-run evidence under `target/ide-workflow/runs-*/<mode>-run-<N>`. Existing exact-source save, history, diagnostics, generated discovery, exclusive JavaFX 26 natives and worker-shutdown assertions and timeouts remain intact.
```sh
python3 scripts/check-ide-host.py --java-home "$JAVA_HOME" \
--target-java-home "$TARGET_JAVA_HOME" --idea-home "$IDEA_HOME" \
--mode modulepath --repeat 3
```
Qualification on 2026-11-13: the full bootstrap passed 141 Maven tests, target linkage/bytecode/packaging checks, 38 target processes with 548 checks, both standalone native workflows, 48 lifecycle cycles and abrupt owner death. After extending the initial-baseline regression, all 11 IntelliJ unit/adapter tests and the plugin rebuild passed again (152 unit/adapter tests overall, zero failures/errors/skips). Three consecutive fresh registered IntelliJ module-path sessions and a final fresh classpath session passed with the final plugin, without retrying a failed run. Each includes the forced revision race, source-preserving edits and exact save assertions, Undo/Redo, native diagnostics/fixes, generated registry discovery, exclusive JavaFX 26 natives and worker shutdown.
The previous failures remain historical evidence. Red/green logs: `/tmp/ide-save-red.log`, `/tmp/ide-save-late-open.log`, `/tmp/ide-save-final.log`, `/tmp/render-race-red.log` and `/tmp/render-race-green.log`. Whole-suite evidence: `/tmp/ide-reliability-bootstrap.log`, `/tmp/ide-reliability-modulepath.log` `/tmp/ide-reliability-classpath.log`, `target/ide-workflow/runs-ip2002jp` (module-path) and `target/ide-workflow/runs-4_sojrex` (classpath). These are disposable local evidence, not published artifacts. This closes the bounded IntelliJ module-path save/startup gate on the pinned macOS/IDE/JavaFX setup; other platforms and IDE SDKs remain outside that qualification. No manual testing is part of this follow-up; previously skipped human tests remain skipped.
+4
View File
@@ -155,3 +155,7 @@ The [generated Model metadata slice](generated-model-metadata.md) adds an opt-in
The [ViewModel generation slice](generated-viewmodels.md) extends the metadata processor with typed replaceable Java sources, checked-in Maven settings and declarative registry services. NeitzelLib supplies stored-property lookup and compatible shared identity/default selection. Both hosts discover generated/custom defaults through target workers and keep existing authoring/history behavior. Clean consumer builds, Lombok, generated inheritance/nesting and rejection cases have automated coverage. Dedicated configuration selection UI, broader cross-module/generic mappings and reviewed FXML form generation remain later work.
Qualification: automated standalone and registered IntelliJ classpath workflows pass. Real module-path consumer/runtime tests pass, but registered IntelliJ module-path remains open after the existing save assertion and initial-render timeouts; see the qualification record above. No manual testing was requested or substituted.
## IntelliJ save/startup reliability gate
The [reliability follow-up](ide-host-reliability.md) closes the generated-ViewModel slice's remaining IntelliJ module-path gate. Explicit saves now await per-file VFS persistence, native saves update the accepted baseline, and opening/refreshing a document accounts for queued writes. Host revision synchronization clears obsolete validation and schedules current rendering. Controlled red/green regressions and three consecutive fresh registered module-path runs pass without changing source/history assertions or timeouts. Previously skipped human checks remain skipped.