Files
NeitzelFXDesigner/docs/initial-project-contract.md
T

137 lines
15 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# NeitzelFXDesigner initial project contract
Status: accepted architecture consolidated from decision rounds Q1–Q15 on 2026-11-12. Module names and configuration 1.0 fields are implemented by bootstrap work packages 3–4. Public preview Java signatures remain provisional; the draft wire codec and limits now have regression coverage. This document refines roadmap stage 1, not the complete product specification.
Decision provenance: [accepted workspace decisions](provenance.md). Execution order: [repository bootstrap plan](repository-bootstrap-plan.md). Existing authoring, preview, binding, generation and host requirements remain in the [broader roadmap context](provenance.md#broader-roadmap).
## Project and scope
- Repository: **NeitzelFXDesigner**; application name: **Neitzel FX Designer**.
- Remote: `ssh://git@gitea.neitzel.de:2222/konrad/NeitzelFXDesigner.git`.
- Canonical independent checkout: `/Volumes/PlanckSSD/KI/java/NeitzelFXDesigner`, alongside NeitzelLib in the canonical Java workspace. The research worktree is not its permanent checkout.
- Initial default branch: `main`. The initial repository bootstrap establishes this branch; the earlier consolidation found no advertised remote refs.
- The Component builder fix belongs to NeitzelLib. Designer/tooling code belongs to NeitzelFXDesigner. Application fixtures depend on library artifacts, never copied NeitzelLib sources.
- First milestone: one real Component and sample Model through Build and Refresh, successful-build capture, metadata discovery and target-runtime rendering in both minimal hosts. Include classpath and module-path fixtures and failure diagnostics.
- Full binding/generation UI, general projection editing, production handoff, packaging and wider qualification retain their later roadmap gates. Minimal hosts are not feature-complete releases.
## Modules and dependency direction
The artifact names below are established by work package 3. See [implemented boundaries and baselines](module-host-boundaries.md); the broader responsibilities remain the target architecture.
| Module/directory | Responsibility | Boundary |
| --- | --- | --- |
| `designer-contracts` | Configuration types/schema, wire envelopes, metadata DTOs and capability definitions | No Kit, IntelliJ or application classes; schema/protocol versions are independently tracked |
| `designer-core` | Application contexts, build/snapshot orchestration, validation, document edit intents and worker sessions | Depends on contracts; obtains host services through interfaces, not host implementations |
| `designer-kit-ui` | Shared canvas, hierarchy, inspector and later binding/generation panels | Depends on core and pinned Kit/JavaFX; no IntelliJ API |
| `designer-standalone` | Native application entry point, documents/undo, menus, navigation and lifecycle | Adapts core/UI to standalone services |
| `designer-intellij` | FXML editor, IDE Documents/commands, project/build/navigation integration and focus | Adapts the same core/UI; qualify build and packaging against the selected IDE SDK |
| `designer-preview-api` | Typed example descriptors and fresh preview-session lifecycle | Small project-facing artifact; no Kit or IntelliJ dependency |
| `designer-target-tools` | Discovery and NeitzelLib loading/rendering adapter in the application runtime | Uses contracts/preview API and target-compatible library dependencies; never execute application classes in a host |
| `designer-maven-plugin` | Effective project/dependency/runtime capture in the selected Maven build JVM | No Kit/IntelliJ or target application runtime dependency |
| `integration-fixtures/` | Real classpath and module-path Maven applications, examples and failure cases | Same scenarios consumed by both hosts; normal artifact dependencies |
Shared contracts may be Java artifacts without implying identical JDK/JavaFX versions in hosts and workers. Select bytecode/API baselines per module from the supported target fixtures; verify that application-facing artifacts load on the oldest initial target before publishing them. The IntelliJ packaging toolchain must be pinned and tested; a Maven reactor for shared artifacts does not assume that ordinary Maven JAR packaging produces a supported plugin.
```mermaid
flowchart LR
S[Standalone adapter] --> U[Shared Kit UI]
I[IntelliJ adapter] --> U
U --> C[Shared designer core]
S --> C
I --> C
C --> K[Configuration / protocol / metadata contracts]
C -->|Dedicated local IPC| W[Target-runtime tooling]
W --> K
W --> P[Preview API]
A[Application examples] --> P
W --> N[NeitzelLib and application runtime]
```
Each host owns its own engine/UI instances. The authoritative document and undo history belong to the active host. Kit remains a projection. This diagram describes dependencies and process boundaries, not shared mutable state across hosts.
## Shared application configuration
`neitzel-fx-designer.json` lives at the application's Maven reactor root. It contains a schema version and named application contexts. A context selects an application module, Maven profiles, classpath/module-path launch mode, preview sources/module and examples. Relative paths resolve from the configuration location, never the process working directory. Validate modules and paths against the selected reactor. Obtain dependency graphs and ordinary source/resource roots from Maven rather than maintaining competing lists.
Configuration 1.0 is now executable; see the [schemas and validation contract](configuration-and-protocol.md). The following example is valid input, with Java requirements defaulting to 21:
```json
{
"schemaVersion": "1.0",
"contexts": {
"desktop": {
"applicationModule": "app",
"mavenProfiles": ["designer-preview"],
"launchMode": "classpath",
"buildRuntime": "build-java",
"targetRuntime": "application-java",
"preview": {
"sourceSet": "module",
"module": "preview",
"provider": "example.preview.PersonExamples",
"defaultExample": "person.standard"
}
}
}
}
```
The schema covers `test` preview sources in the application module, module-path entry/access settings and runtime requirements. Example IDs belong to provider descriptors; configuration selects a default and may select/filter descriptors rather than duplicating their metadata. A provider class name identifies a typed implementation, not an arbitrary reflective factory method. Provider registration/descriptor extraction must be validated against the library before the public API is frozen.
Select the context automatically when exactly one matches. Otherwise ask, show the active context and remember the choice locally. Opening a Component from a parent inherits that context. Shared source documents retain one host-owned draft even when usable in multiple contexts.
Local settings hold installed JDK mappings, absolute machine paths and remembered context/UI preferences. Shared runtime names refer to required build and target runtimes; resolve, display and validate those roles separately. Application JavaFX comes from Maven. A missing/incompatible target requests setup; never silently substitute the designer's or IDE's JVM. No automatic configuration migration. Unsupported schema/capabilities disable the affected tool with diagnostics while ordinary source editing remains available.
## Build and snapshot contract
Work package 5 now implements the shared [Build and Refresh workflow](build-and-refresh.md), including its validation and explicitly bounded input closure. Worker activation and UI wiring are implemented in the [first connected workflow](first-connected-workflow.md).
1. Resolve the selected context and required reactor dependencies, including configured preview sources. Prefer the Maven wrapper; expose the plan, command/output and cancellation. Avoid unrelated applications unless dependency resolution requires them.
2. Identify known unsaved Java, Maven and designer-configuration inputs affecting the build. Offer **Save affected files and build** or **Cancel**, listing the affected files. Do not implicitly build older disk versions. Account for IDE autosave; another process's unsaved buffers are not observable.
3. Capture the relevant input identity/revision manifest and execute the build with the selected build runtime. FXML-only draft edits have separate revisions and need not trigger Java compilation.
4. After success, stage a consistent snapshot of compiled outputs, generated metadata, resources and resolved dependency content/identities into an ignored designer cache. Do not hand workers mutable `target` paths or mutable dependency outputs. Copy or content-address artifacts; a snapshot must not change if later builds overwrite their inputs.
5. Verify inputs/output capture remained consistent throughout the operation. A fingerprint at only one instant is insufficient. Detected changes, capture failures, cancellation or failed builds prevent activation. Publish a complete manifest/snapshot atomically, never a partially populated directory.
6. Activate the successful snapshot, refresh discovery and restart affected preview sessions. A manifest identifies context, build inputs, artifacts/digests, runtime requirements and tool contracts. Discovery and rendering use the same build identity.
7. Retain the last usable successful snapshot after failure, mark retained derived results outdated, and require explicit **Preview with last successful build**. An outdated build is not silently promoted to current.
Cache contents are local, ignored and reconstructible. Active workers retain their snapshots until stopped; eviction must not remove in-use artifacts. Numerical retention limits are operational defaults, not a new authoring decision.
FXML previews overlay the owning host's current parent and open Component drafts onto the selected build snapshot. Document revisions and snapshot identity remain distinct; source edits must not silently change a worker's captured input. Reject obsolete results using host-owned revision ordering, not numeric assumptions about IDE modification stamps. Resources outside the supported draft-overlay mechanism remain part of explicit resource/build freshness validation.
## Discovery and preview API
Work package 6 now qualifies the [development API and target adapter](preview-target-fixtures.md) against real classpath/module-path fixtures. Session cleanup is cooperative; a fresh target JVM is required to release NeitzelLib process-wide Model/ViewModel state.
Metadata listing must not construct Models or invoke Controller methods. Separate example descriptors (stable IDs, display labels, compatible Model/View information and declared capabilities) from runtime construction. Generated descriptor metadata or equivalent non-constructing discovery must be tested; calling arbitrary provider initialization merely to list examples does not satisfy this boundary.
Selecting an example creates a fresh owned preview session with its Model graph and explicitly configured services. Provide readiness and cleanup hooks. Ordinary examples become ready after load/CSS/layout; asynchronous examples signal readiness subject to cancellation/timeout. Construction, services, Controller actions and cleanup execute only in the target JVM. Verify the adapter against NeitzelLib's actual injection/loading lifecycle before publishing Java signatures.
A parent rendering snapshot shares its Model graph across embedded Components; standalone Component preview selects its own example. Interactive preview has its own JVM/session. Bounded graceful cleanup precedes forced worker termination when necessary; cleanup callbacks cannot be guaranteed after process death, so host-side lifecycle ownership remains required.
## Versions and communication
Track configuration schema, wire/metadata contracts and preview API compatibility independently from product releases. Major changes represent breaking contracts; additive features use declared optional capabilities. Equal product versions alone are not proof of compatibility. Verify discovery and rendering independently so one unavailable capability does not unnecessarily disable the other.
Use a dedicated loopback-only socket with a per-launch random token and version/capability handshake for worker messages. Standard output/error remain captured application logs and cannot carry protocol framing. Do not log tokens. Bind the session to the launched worker and reject messages before authentication/negotiation. Use explicit bounded framing, validate lengths and resource limits before allocation, correlate requests/replies and define cancellation/error outcomes. Encoding, limits and negotiation are now defined by the [executable draft wire contract](configuration-and-protocol.md#draft-wire-protocol-10); transport integration is implemented in the first connected workflow.
Every applicable request/result identifies its worker session, request, context and build snapshot; rendering also identifies document revisions and requested size. Obsolete results cannot mutate current document/UI state. Diagnostics identify operation and available source origin while preserving editing.
Keep the proven reserved owner-lifetime channel for worker cleanup independent of FX responsiveness. The independently owning standalone editor must survive IDE death; it does not use the preview-worker death rule. Production host-to-host handoff remains a separate protocol/gate; choosing a worker socket does not silently choose its production transport.
## Library prerequisite and acceptance
Integrate and test the Component builder fix separately in NeitzelLib, preserve unrelated work, and establish the first released artifact containing it. Declare the resulting supported minimum/capability in designer metadata. Older unsupported versions receive diagnostics, not a hidden adapter. Until release, development fixtures may pin a clearly identified installed snapshot; a SNAPSHOT name alone does not establish fix provenance. The corrected source on main declares `de.neitzel.lib:fx:1.0-SNAPSHOT` with Java 21 / JavaFX 21.0.7. The fix and tested local artifact identity are recorded in [runtime provenance](runtime/neitzellib-baseline.md). No corrected minimum released version is asserted.
Accept the first milestone only when both minimal hosts use the same core/UI/fixtures and demonstrate:
- Constructor-only Components accept custom/inherited FXML attributes after initialization; invalid values fail; Model identity/write-back survive without an adapter.
- Classpath and module-path applications build, discover and render through their selected runtimes; missing module access is diagnosed rather than repaired with silent broad opens.
- Build scope and explicit save choices are observable; failed/cancelled/stale builds preserve documents and do not publish a current snapshot.
- Subsequent builds cannot mutate a running worker's snapshot; active snapshot cleanup is safe.
- FXML draft updates render without Java recompilation and stale responses are ignored.
- Missing/incompatible runtime/schema/protocol/capability failures are actionable and limited to affected tools.
- Listing examples performs no Model/Controller construction; selecting an example produces fresh state and honors readiness/cleanup.
- Console output cannot corrupt worker messages; owner death, cancellation and timeout terminate workers.
These acceptance requirements are covered by the combined work-package suites; the [connected-workflow report](first-connected-workflow.md) records the qualified platforms and bounded UI scope. Broader product behavior remains governed by the existing roadmap.