From cf04ff144219ceebfafce29c1611dddf21ab69a1 Mon Sep 17 00:00:00 2001 From: "sorokin.oleg.edu" Date: Sun, 6 Sep 2026 07:48:14 +0300 Subject: [PATCH] Document hosted desktop workflows and local save behavior --- README.md | 12 ++++++---- crates/oa-desktop/src/guide.rs | 40 ++++++++++++++++++++++++++-------- docs/scope.md | 8 +++---- docs/server.md | 36 ++++++++++++++++++++++++++++-- 4 files changed, 77 insertions(+), 19 deletions(-) diff --git a/README.md b/README.md index 58b5837e..51265d2c 100644 --- a/README.md +++ b/README.md @@ -102,7 +102,7 @@ Reparenting a nested element through Properties moves its declaration, descendan ## Save and reopen -Ctrl+S saves, Ctrl+Shift+S saves as, and Ctrl+O opens. An `.arcadia` suffix selects text; other suffixes select JSON. Opening detects content rather than relying on the filename. Windows uses native dialogs; Linux uses a path-entry dialog with overwrite confirmation and no portal requirement. +Ctrl+S saves to the current local or hosted destination, Ctrl+Shift+S opens Save as, and Ctrl+O opens a local file. An `.arcadia` suffix selects text; other suffixes select JSON. Opening detects content rather than relying on the filename. Windows uses native dialogs; Linux uses a path-entry dialog with overwrite confirmation and no portal requirement. **Save all** validates a snapshot and saves the source bundle, comparing previously read dependency bytes to reject detected external changes. Each file is replaced atomically; a staged transaction journal allows explicit recovery of interrupted multi-file saves. This is not an atomic multi-file filesystem operation or distributed locking. If recovery is needed, **Recover interrupted save** appears in Textual model. Dirty New/Open/Close operations offer save/discard/cancel. There is no periodic autosave of unsaved edits. Share or commit the entry file and all included source files together. @@ -118,14 +118,18 @@ The default is `127.0.0.1:8787`, with a platform-local data directory. `--data-d The API queries and edits complete models, canonical source, multi-file source projects, elements, relationships, artifacts and traces. Transactions and transition previews use the same core validation and source writer as the desktop. Writes require the returned ETag in `If-Match`. One revision protects the accepted model and source bundle together, including comment-only edits. The server retains the current revision only. -Desktop files and hosted resources transfer explicitly; the desktop has no direct server connection. Use **Save as** to export `system.json`, import it, then edit using the API. The model interchange endpoint accepts a complete JSON model or standalone canonical source: +Use **Hosted models...** in the desktop top bar to connect, **Publish as new** to upload the current authored source project, or select a catalog entry and choose **Open selected**. Diagrams, properties and text share the same local editing history. **Save to server** / Ctrl+S explicitly sends valid changes; invalid drafts and failed writes retain your work. A revision conflict preserves local work and checks the server for review, with read-only source files and an explicit, undoable **Reload server version**. **Save as local...** switches back to a local destination after successfully saving an `.arcadia` source project; JSON export keeps the hosted destination. See the [hosted desktop walkthrough](docs/server.md#edit-hosted-models-in-the-desktop) for conflict recovery and connection setup. + +The desktop keeps bearer credentials in memory and accepts HTTPS, with HTTP allowed only on localhost/loopback. Hosted editing does not require a cloud account and does not provide automatic synchronization or merges. + +Scripts can also import a complete JSON model or standalone canonical source through the model interchange endpoint: ```sh curl --fail-with-body -X POST http://127.0.0.1:8787/api/v1/projects/import \ -H 'Content-Type: application/json' --data-binary @system.json ``` -The response supplies the service `resource_id` and ETag. After API changes, export `/api/v1/projects//source` to a new `.arcadia` file and open it in the desktop. This preserves model UUIDs, aliases, diagrams, traces and artifact metadata. Importing creates a separate hosted resource. Artifact URIs and revisions are opaque references for code, CAD, schematics, documents and other evidence; the application does not fetch or execute them. +The response supplies the service `resource_id` and ETag. Refresh the desktop catalog to open that resource; after API changes to an open model, use **Check server** to review them. Alternatively, export `/api/v1/projects//source` to a new `.arcadia` file for local interchange. This preserves model UUIDs, aliases, diagrams, traces and artifact metadata. Importing creates a separate hosted resource. Artifact URIs and revisions are opaque references for code, CAD, schematics, documents and other evidence; the application does not fetch or execute them. To preserve authored files and comments, use `POST /api/v1/projects/import-source-project` with a JSON bundle containing `entry` and a `files` map of relative paths to source strings. `GET` and conditional `PUT /api/v1/projects//source-project` exchange that complete accepted bundle. Include resolution uses only the submitted files; the server never opens the client's disk paths. See the [REST contract](docs/api.rst) for payloads, located diagnostics and admission limits. @@ -142,4 +146,4 @@ cargo build --release --workspace --locked - `crates/oa-desktop`: Iced state/drafts, typed forms, architecture/behavior views, source highlighting and file workflows. - `crates/oa-server`: REST transport, conditional writes, bounded queries and atomic local store. -The [architecture guide](docs/architecture.md) explains extension boundaries. Windows/Linux CI is configured; remote CI was not run in this environment. LA/PA, simulation, native Capella interchange, complete SysML/Capella conformance, direct hosted editing, semantic merge tooling and production-scale collaboration remain outside this prototype. +The [architecture guide](docs/architecture.md) explains extension boundaries. Windows/Linux CI is configured; remote CI was not run in this environment. LA/PA, simulation, native Capella interchange, complete SysML/Capella conformance, semantic merge tooling and production-scale collaboration remain outside this prototype. diff --git a/crates/oa-desktop/src/guide.rs b/crates/oa-desktop/src/guide.rs index 78c0bbb2..1d277b07 100644 --- a/crates/oa-desktop/src/guide.rs +++ b/crates/oa-desktop/src/guide.rs @@ -102,7 +102,7 @@ impl Topic { Self::Source => "Textual editing & Git", Self::Recovery => "Checks & error recovery", Self::Files => "Files & keyboard shortcuts", - Self::Server => "REST API & automation", + Self::Server => "Hosted models & REST API", } } @@ -751,16 +751,42 @@ fn article(topic: Topic) -> Article { Topic::Server => { const { Article { - summary: "The Rust REST service gives scripts and engineering-tool plugins access to the same model, commands, validation and source representation.", + summary: "Use optional hosted storage from the desktop, scripts and engineering-tool plugins. All clients work with the same model, validation and authored source.", keywords: "server rest api automation ai plugin curl http etag if-match revision resource_id deploy hosted cad scripting openapi token", sections: &[ example( "Start a local service", - "Run the separate arcadia-server binary from a terminal. Its default address is loopback 127.0.0.1:8787. docs/server.md describes storage, authentication and Linux deployment.", - "arcadia-server --data-dir ./arcadia-models\n\nGET http://127.0.0.1:8787/health\nGET http://127.0.0.1:8787/api/v1/openapi.json", + "From the repository root, run the command below in a terminal and leave it running. The default address is loopback 127.0.0.1:8787, with platform-local storage. docs/server.md also covers installed executables, authentication and Linux deployment.", + "cargo run --locked -p oa-server --bin arcadia-server\n\nGET http://127.0.0.1:8787/health\nGET http://127.0.0.1:8787/api/v1/openapi.json", ), walkthrough( - "Build a safe editing client", + "Open or publish a hosted model", + &[ + "Choose Hosted models... in the top bar. Enter the service root, such as http://127.0.0.1:8787, without /api/v1. Enter the configured bearer token if required, then Connect / refresh.", + "Choose Publish as new to upload the current source project, including its files and comments, as a separate hosted resource. Its acknowledgement switches the current Save destination to that resource.", + "To open an existing resource, search the Hosted model catalog, select a model and choose Open selected. More models loads another page. Unsaved work uses the normal save/discard/cancel prompt.", + "Edit diagrams, properties or Textual model, then choose Save to server or press Ctrl+S. Valid drafts are applied; invalid drafts remain available to correct or revert. Edits and Undo stay local until Save.", + ], + ), + walkthrough( + "Review another client's changes", + &[ + "Check server reads the current revision without replacing local content. A stale Save returns 412 and automatically checks the server for review; local work is retained.", + "Review the changed file list. View server text opens a read-only file; Back to review returns to the list. There is no automatic merge.", + "Reload server version adopts the reviewed source project as one undoable local change after checking unapplied drafts. Undo restores the previous accepted local version without changing the server. Reconcile your intended changes before saving again.", + "After an unknown write outcome, use Check previous write when offered. If publication may already have succeeded, inspect the refreshed catalog before publishing another copy.", + ], + ), + explain( + "Return to a local file", + "Choose Save as local... or Ctrl+Shift+S, then save an .arcadia entry to retain included files and comments. A successful source-project save makes that file the current destination and leaves the hosted resource unchanged. JSON exports the model only and retains the hosted destination and unsaved state. Canceling or a failed save also retains the hosted destination. Forget connection becomes available after leaving the hosted session.", + ), + explain( + "Connection credentials", + "The desktop keeps credentials in memory only. Use HTTPS remotely; HTTP is allowed only for localhost or a loopback IP. Put the token in its own field, never the service URL. URLs with credentials, queries or fragments are rejected, and redirects are not followed. To update a token, enter it and Connect / refresh for the same service, then retry the check or Save.", + ), + walkthrough( + "Automate model edits", &[ "Create or import a project using /api/v1/projects or /api/v1/projects/import. Keep the returned service resource_id; it is distinct from the editable model UUID.", "Read the project's envelope, source or model. Preserve its exact ETag as the precondition for your edit.", @@ -769,10 +795,6 @@ fn article(topic: Topic) -> Article { "Query /artifact-links and /traces to connect domain-tool artifacts to model records. The server stores these references; the integration is responsible for resolving its external artifacts.", ], ), - explain( - "Desktop files and hosted models", - "The desktop currently edits local model files. To exchange with the service, export its /source or /model response and open that file; upload a reviewed candidate through the API with its original revision precondition. The desktop does not maintain a live hosted editing session.", - ), explain( "Deployment and persistence", "Non-loopback binding requires a configured bearer token. Use the documented local-disk storage and deployment configuration. The service keeps the current revision and serializes accepted updates; it does not provide retained revision history or server-side undo. Stop the service cleanly before copying its committed store for backup.", diff --git a/docs/scope.md b/docs/scope.md index 78812937..8a1fbd04 100644 --- a/docs/scope.md +++ b/docs/scope.md @@ -14,7 +14,7 @@ Arcadia Studio implements a systems-engineering workbench spanning Operational A | Perspectives and evidence | Bidirectional counterpart creation/linking, reviewed name/description updates, many-to-many typed/manual traces, arbitrary artifact URI/revision/fragment references | | Views and editing | Independent diagrams, decomposition/allocation nesting, collapse, pan/zoom/Fit/Arrange, editable connection routes and labels, four-side port positioning, direct interaction/functional/boundary exchange tools, contextual menus, SVG export, model explorer and typed properties | | Text and storage | `arcadia 4` source projects with relative includes and nested declarations, stable aliases/UUIDs, a source-file tree, per-file drafts and diagnostics, comment-preserving graphical updates, exact model/source Undo/Redo, legacy migration, atomic saves and interrupted source-save recovery | -| Automation | Rust REST service for project/source-bundle/query/validation/transaction/transition/artifact workflows, ETag preconditions, bounded requests and atomic current-revision storage | +| Automation and hosted editing | Rust REST service for project/source-bundle/query/validation/transaction/transition/artifact workflows; optional desktop catalog/open/publish, explicit conditional Save, server review and local Save as; ETag preconditions, bounded requests and atomic current-revision storage | Graphical and textual parity applies to the persistent fields of this profile. Diagram placements are model data; camera, selection, source cursor and undo history are session state. Canvas gestures need not match textual operations one for one: typed inspectors and explicit commands expose precise semantics. Full source replacement must repair dependencies in its candidate, while graphical delete/reidentify commands maintain references automatically. @@ -41,18 +41,18 @@ These are concrete design responses, not claims that every Capella user experien | Hard-to-review model files | Modular typed source, stable aliases/UUIDs, preserved comments/formatting and source-aware history | Semantic merges, completion and an LSP are absent | | Hidden mutation effects | Validated atomic commands, dependency cleanup, identity maintenance, previewed counterpart changes and undo | No distributed editing or automatic structural reconciliation | | Platform/plugin overhead | Native Rust/Iced desktop and independent headless service | WGPU has substantial dependencies and needs a working graphics adapter | -| UI-coupled automation | Renderer-independent core and documented REST commands/queries | Desktop-hosted model editing is absent; transfer uses import/export | +| UI-coupled automation | Renderer-independent core, documented REST commands/queries and optional hosted desktop editing | Save and server review are explicit; there is no automatic synchronization or merge | ## Required first-release work -Direct scenario/process canvas authoring, semantic-content drift and reviewed counterpart reconciliation, native acceptance of expanded data contracts, persistent coverage/filter views, Home/recent-project and unsaved-work recovery, hosted desktop editing, guidance and final acceptance remain in the [release plan](../harness/PLAN.md). These are unfinished requirements, not exclusions from the release. Direct state editing has scoped Windows/Linux acceptance recorded in [state evidence](../harness/release-state-editing.md). Interrupted source-save recovery restores a save transaction; it does not checkpoint unsaved models or drafts. +Direct scenario/process canvas authoring, semantic-content drift and reviewed counterpart reconciliation, native acceptance of expanded data contracts, persistent coverage/filter views, Home/recent-project and unsaved-work recovery, guidance and final acceptance remain in the [release plan](../harness/PLAN.md). These are unfinished requirements, not exclusions from the release. Hosted desktop editing is implemented; its remaining native acceptance is tracked in the release plan and current state. Direct state editing has scoped Windows/Linux acceptance recorded in [state evidence](../harness/release-state-editing.md). Interrupted source-save recovery restores a save transaction; it does not checkpoint unsaved models or drafts. ## Remaining boundaries - Logical and Physical Architecture, deployment semantics, executable behavior, complete SysML or Capella metamodel support, and native `.capella`/`.aird` import/export. - Complete Capella communication/scenario variants beyond the specified Studio profile. - Semantic merge, completion and language-server tooling. Local external-file checks do not provide a cross-process transaction lock. -- Collaborative editing, server undo/history, retry receipts, multiple service replicas and network-synchronized data directories. The service stores current models under explicit capacity limits; the current desktop transfers hosted data through explicit import/export until the planned client is implemented. +- Collaborative editing, server undo/history, retry receipts, multiple service replicas and network-synchronized data directories. The service stores current models under explicit capacity limits. Desktop edits and Undo remain local until Save; revision conflicts require explicit review, and Reload is an undoable local operation. Credentials stay in memory and remote desktop connections require HTTPS. - Production-scale performance guarantees, full screen-reader/keyboard diagram support, high-contrast/localized experiences and signed installers. - Runtime plugin loading or an extension ABI. External tools can use the REST API; additional in-process infrastructure needs a concrete use case. diff --git a/docs/server.md b/docs/server.md index 1b6bde70..ee2b9027 100644 --- a/docs/server.md +++ b/docs/server.md @@ -85,9 +85,41 @@ For a native Linux installation, create an `arcadia` service account, install th Ctrl+C/SIGTERM stops admission and drains HTTP requests. Already-started blocking tasks run to their completion boundary. The systemd example permits 45 seconds before a supervisor kill; an interrupted process recovers by loading the last installed envelopes. `/health/ready` means the initial store validation succeeded and the process can respond; it is not an ongoing disk-free-space or integrity probe. -## Desktop and automation integration +## Edit hosted models in the desktop -A desktop or automation client can query current JSON/source, edit with shared typed commands, validate/dry-run, and commit using the original ETag. For hosted editing, keep the user's draft until the service acknowledges the new revision. On `412`, preserve the draft and reload server state for review; a blind replacement retry would discard another client's work. +Start a local service from the repository root, then leave it running while using the desktop: + +```sh +cargo run --locked -p oa-server --bin arcadia-server +``` + +The same command works in PowerShell and a Linux shell and uses the platform-local data directory described above. For a custom store, append `-- --data-dir PATH`; choose a local directory outside a synchronized folder. For an installed release, run `.\arcadia-server.exe --data-dir PATH` on Windows or `./arcadia-server --data-dir PATH` on Linux. + +1. In the desktop top bar, choose **Hosted models...**. Enter `http://127.0.0.1:8787` as **Service address**, or your deployed service's HTTPS address. Use the service root, without `/api/v1`; a reverse-proxy path prefix is supported. +2. Enter the configured secret in **Bearer token** if required, then choose **Connect / refresh**. Tokens stay in application memory; they are not saved in model/source files. Leave the token empty for an unauthenticated loopback service. +3. To share the current local model, choose **Publish as new**. This uploads the complete authored source project, including its entry file, included files and comments, and creates a separate service resource. After acknowledgement, the current project's Save destination becomes that hosted resource; an existing local file is not overwritten. +4. To work on an existing resource, search the **Hosted model catalog**, select a model, and choose **Open selected**. **More models** loads another catalog page. Unsaved local work uses the normal save/discard/cancel prompt before opening. +5. Edit through diagrams, properties or **Textual model**. Choose **Save to server**, or press Ctrl+S, to validate/apply drafts and send the complete source project. The header shows the last acknowledged hosted revision and whether local changes remain. Edits and Undo/Redo stay local until an explicit Save. + +An invalid source or property draft prevents publication/save and remains available to correct or revert. A rejected server write or failed connection retains the local model and source history. The application does not silently publish the last valid model while dropping an invalid draft. Detached source drafts must be reattached or reverted before hosted Save. + +### Review a newer server version + +An API client or another desktop can edit the same resource. Each Save includes the exact ETag of the desktop's last acknowledged revision. If the server has changed, it rejects that stale Save with `412 revision_conflict`; the desktop retains local work and checks the latest server version for review. Choose **Check server** to perform the same read explicitly, or retry the check after restoring a failed connection. + +The review lists changed, added and removed source files. **View server text** opens a read-only file; **Back to review** returns to the list. Reading the server does not replace local content. **Reload server version** adopts the reviewed bundle as one undoable local change after checking unapplied drafts. Undo can restore the previous accepted local version, but it does not undo the server's revision. There is no automatic merge: inspect and reconcile the intended edits before saving again. + +For a connection failure with an unknown write outcome, use **Check previous write** when offered before another Save. If the server holds exactly the submitted bundle, the desktop acknowledges that save. If it differs, review it. An uncertain publication may already have created a resource; refresh and inspect the catalog before choosing **Publish another copy**. + +### Save locally and manage the connection + +Choose **Save as local...** in Hosted models, or Ctrl+Shift+S, and select an `.arcadia` entry file to retain included files and comments. A successful source-project save switches future Ctrl+S operations to that local destination and leaves the hosted resource unchanged. Choosing JSON exports the model only and keeps the hosted Save destination and unsaved state. Canceling or failing the local save also keeps the hosted destination. **Forget connection** is available after leaving the hosted session and clears the remembered connection/token in memory. + +The desktop accepts HTTPS service URLs and HTTP only for `localhost` or a loopback IP address. Credentials, query parameters and fragments in the URL are rejected; put the bearer token in its own field. Redirects are not followed. For remote access, configure a TLS reverse proxy as described above; the server itself does not provide TLS. To replace an expired token, enter the new value and choose **Connect / refresh** for the same service, then retry the check or Save. Connection settings and tokens are not persisted across application restarts. + +## Automation integration + +Automation clients use the same typed model, validation, authored source and revision preconditions as the desktop. Preserve the submitted draft and original ETag until a write is acknowledged; on `412`, read and reconcile the current version instead of blindly replacing it. Use `POST /api/v1/projects/import-source-project` to import `{"entry":"model.arcadia","files":{"model.arcadia":"..."}}`. Use `GET` and conditional `PUT /api/v1/projects/{id}/source-project` to export or edit that complete authored workspace. These routes preserve comments, line endings, entry names and module layout. Missing declaration IDs are inserted once; keep the accepted bundle returned by PUT or subsequent GET. Candidate validation accepts `{"format":"source-project","source_project":{...}}` and reports diagnostics without adoption.