galata. GitHub ↗

Experimental project files and worker commands

The project preview stores editable continuous block models, presentation and simulation settings alongside immutable run evidence. It implements the bounded M2 project/worker increment under ADR-0012, plus the typed linear import in ADR-0013 and retained revision recovery in ADR-0014. These experimental formats do not freeze a public project API or change the product version from 0.3.0.

The project commands support the macOS/Linux POSIX worker boundary. Current verification claims are listed in the implementation record; hosted Linux and macOS verification remain pending. Linux and macOS are now the only supported platforms for the study CLI and numerical library as well, but each keeps its own evidence scope.

Commands

After building the CLI, create and run the synthetic feedback starter:

./build/dev/src/cli/galata project create build/feedback.galata
./build/dev/src/cli/galata project inspect build/feedback.galata
./build/dev/src/cli/galata project run build/feedback.galata

Import the local NT-33A plant/controller graph into a new project:

./build/dev/src/cli/galata project import-linear build/nt33a.galata examples/nt33a-graph-design/study.yaml
./build/dev/src/cli/galata project inspect build/nt33a.galata
./build/dev/src/cli/galata project run build/nt33a.galata

Import runs the study into project-owned storage and adopts its exported model and simulation settings. It requires exactly one model.linear_graph stage and exactly one directly connected sim.model stage. Reference sim.linear stages and reports are allowed. The study may contain at most 64 stages; its retained origin accepts at most 128 input records and 128 artifact records, including the manifest. A failed or cancelled import does not publish a project head; incomplete import outputs remain for investigation. Retry uses another new or empty destination. There is no automatic cleanup or import resume.

The .galata suffix is a directory naming convention, not an archive format. Create and import require a new or empty directory. Inspect returns a single JSON document with the current revision, model, presentation, simulation settings and run history. Run executes synchronously in its own CLI process and returns a run record with execution status and artifact paths. A desktop caller launches this same command as a child process.

Save a draft using the exact revision returned by the inspect operation that supplied the editor's working copy. In this syntax, replace the angle-bracketed arguments with the draft file and observed revision:

galata project save <directory> <draft.json> --expected-revision <64-hex-revision>

For example, the directory may be build/feedback.galata. A stale revision is refused, leaving the newer head in place. Create, import, inspect and save return schema galata.project-view.v1; the view includes revision, draft_schema and runs in addition to the three draft content objects. Imported projects also return origin_sha256 and a verified origin view. Successful commands exit zero. Refused, failed and cancelled commands exit nonzero with a diagnostic.

Review and restore saved work

List retained drafts, inspect a selected draft, then restore it using the head observed by the editor:

galata project revisions <directory>
galata project revision <directory> <64-hex-revision>
galata project restore <directory> <64-hex-revision> --expected-revision <observed-head>

The list returns galata.project-history.v1, with current_revision, current_status, an optional current_diagnostic, ordering and revisions. The ordering is revision_filename_ascending; content hashes and filesystem timestamps do not establish chronology or ancestry. Each entry reports its retained filename, revision stem, is_current and status. A valid entry also includes model_profile, block_count, simulation and, for an imported draft, origin_relation. An invalid entry includes a diagnostic. A damaged, malformed or symlinked entry remains visible alongside other valid entries. A missing current file produces an invalid current status without adding a synthetic retained entry. A malformed project pointer refuses the listing.

Selected inspection returns galata.project-revision.v1, containing revision, the complete validated draft and optional origin_relation. These are saved bytes interpreted through the draft contract; valid history can still contain unfinished wiring. Neither inspection publishes a head or starts execution. Both hold the existing project lock while obtaining their view.

Restore checks the expected head and both drafts under the same lock. It requires an unchanged draft schema and origin attachment identity, then atomically points the head at the exact selected revision and returns galata.project-view.v1. It does not create another revision or change any retained draft bytes. Restoring the current revision is an idempotent success. A stale editor, missing or invalid target, incompatible schema or different origin is refused. The current head and draft must also be valid; this command does not repair a damaged storage pointer or reconstruct a missing origin.

All newer revisions and runs remain available. A worker already executing continues with its submitted revision. A later restore can select any compatible retained draft again. The history view validates each entry's own content and origin; restore additionally checks its compatibility with the current project.

Draft versus executable model

A save input is a closed JSON object with these required fields:

Field Contract
schema galata.project-draft.v1 for ordinary projects; galata.project-draft.v2 for imported projects
model A model object using the continuous scalar or linear model vocabulary
presentation galata.presentation.v1 for block positions, or galata.presentation.v2 for positions and manual wire routes; see the contract below
simulation initial_time_s, positive step_s, nonnegative integer steps, and positive integer sample_stride
origin_sha256 Required only in draft v2: the immutable SHA-256 of the retained source-origin attachment

An inspect response is a view rather than a save input: construct the draft from its model, presentation and simulation, and use the view's draft_schema as the draft schema. For v2 retain origin_sha256 exactly. Retain the view's revision separately for the expected-revision argument. Save refuses changing the draft schema, removing the origin or replacing its digest. The source attachment is not an editable property of a project.

The model keeps the M1 Constant, Gain, signed ordered Sum, Integrator and Output block kinds; the explicit continuous-linear.v1 profile adds ordered typed linear_combination rows. Save checks supported versions, closed keys, finite numeric values, identifiers and resource limits. It can preserve unfinished wiring, incompatible connected types and algebraic loops so that an engineer can save work in progress. Run applies the complete compiler checks and records refusal as a failed job before numerical execution. Existing strict executable-model parsing and direct C++ compilation keep their validation contracts.

Numeric JSON strings and Boolean values are not numeric parameters. Binary64 values, including signed zero and representable subnormals, retain the model format's conversion semantics. Integer input-port indexes must survive saving without conversion through binary64; an exact index outside the block's ports remains an execution error. Stable IDs such as true and false are strings.

Presentation fields cannot introduce executable behavior. A layout edit changes the project revision while preserving the executable semantic digest. Solver settings also belong to the project/run request rather than the equations: changing a step size preserves model identity but changes the submitted run. An ordinary semantic edit changes the model's semantic identity.

The imported origin view has schema galata.project-origin-view.v1, the original model_semantic_sha256, parsed adapter and manifest objects, the retained manifest path and a relation field. matches_imported_model means the current compiled graph has the imported semantic digest. modified_from_import means it has a different digest; uncompiled_draft means the current draft cannot compile. These labels describe identity, not numerical or engineering approval. Inspected runs also report their revision's relation to the same origin.

Presentation and manual wire routes

Presentation is a closed object independent of the project-draft version. Both ordinary draft v1 and imported draft v2 accept either presentation schema:

Presentation schema Required fields
galata.presentation.v1 schema, positions
galata.presentation.v2 schema, positions, routes

positions is a map with at most 1,024 entries. Each key names an existing block; each value is a closed { "x": number, "y": number } object. Coordinates must be finite and in [-100,000, 100,000]. A block may omit its stored position. Presentation v1 rejects a routes field. Presentation v2 requires a routes array, which may be empty and contains at most 256 entries.

Each route is a closed object with these required fields:

Field Contract
source Source block ID from an existing model connection
target Target block ID from that same connection
input That connection's exact input index: an unquoted, nonnegative decimal integer representable by std::size_t
points An ordered array of 2 through 64 closed { "x": number, "y": number } objects

At most one route may name each (source, target, input) tuple. Every route coordinate is finite and in [-100,000, 100,000]. Each consecutive pair must change exactly one coordinate: segments are nonzero and horizontal or vertical. Unknown fields, nonexistent connections, duplicate route identities, malformed coordinates and oversized routes are refused. Route coordinates are logical canvas positions; view zoom, scrolling and display offsets are not stored.

The worker validates this bounded presentation syntax and connection identity. It does not derive card dimensions, enforce port attachment or assess a route's visual clearance. The native preview separately checks that custom routes leave and enter ports rightward, attach to their current positions and avoid card interiors. When a retained route fails those display checks, the preview shows an automatic path with a diagnostic while retaining the custom route until the user reshapes or resets it. Rendering limits still apply.

Existing presentation v1 drafts remain accepted. Opening a project does not upgrade its presentation. The native preview switches to presentation v2 when a custom shape is applied to the draft; Save retains it. Resetting the last custom route returns the draft to presentation v1. Moving a block removes the custom routes attached to it; Arrange removes all custom routes. These edits support Undo/Redo. Neither the project-draft schema nor the imported origin identity changes with presentation edits.

Older workers that support only presentation v1 refuse presentation v2 drafts; they do not silently discard saved routes. Use the updated worker with custom routes, or explicitly reset all routes and save before opening with an older one.

Manual route edits change the project revision, but they do not change the connection graph, executable semantic digest or numerical execution. The compiler's model validation and the separation of execution evidence from accuracy, physical validity and engineering acceptance remain unchanged.

Storage and identity

The following names illustrate files generated inside a project:

project.json
revisions/<revision-sha256>.json
origins/<origin-sha256>.json
imports/<import-id>/model.yaml
imports/<import-id>/adapter.json
imports/<import-id>/run-<manifest-sha256>.json
runs/<run-id>/request.json
runs/<run-id>/model.yaml
runs/<run-id>/origin.json
runs/<run-id>/study.yaml
runs/<run-id>/result.json
runs/<run-id>/output/response.csv
runs/<run-id>/output/evidence.json
runs/<run-id>/output/run-<manifest-sha256>.json

The project head has schema galata.project.v1 and names the SHA-256 of the stored draft revision. Revisions are immutable; a successful save writes a new revision and publishes the head under an exclusive project lock. Previous revisions and runs remain retained. An interrupted save may leave an unreferenced revision, which does not replace the accepted head. Explicit restore only moves this pointer back to a compatible retained draft; history discovery also includes valid unreferenced drafts from an interrupted save. No save order or reachability graph is inferred from directory contents.

Imported projects retain all study outputs under imports/<import-id>/ and a bounded galata.project-origin.v1 attachment under the origins directory. The attachment contains the original model semantic digest, exact exported model_yaml, adapter_json and manifest_json strings, project-relative manifest_path, and artifacts records with project-relative paths and SHA-256 values. This binds original matrix/channel/controller evidence and full source linearization diagnostics to the imported files and source snapshots. Inspect and run verify these bindings before presenting an imported project's source context.

A submitted request binds one saved revision. The worker snapshots the model and generated study in its own run directory before execution. Imported revisions also snapshot the exact attachment as origin.json; their generated study supplies it through model.compile.context_path. The new run manifest retains that file as a consumed input. Saving later edits does not mutate that request or its inputs. Project locking covers the snapshot transaction rather than the full simulation, so working edits can be saved while an earlier request runs.

Stored artifact paths are project-relative. Paths emitted to the current caller are absolute and resolve inside the owned run. Moving the project directory preserves those bindings; original absolute source locations remain provenance. Malformed revision digests, traversal and symlinked owned files fail closed. There is no automatic external model lookup or network resolution.

Run status and review

Status in an inspected view Interpretation
running The request exists and its worker owns the OS run lock
completed The terminal record, manifest, consumed source and required output/evidence bindings verify
failed The worker retained a parsing, compilation, execution or publication failure
cancelled The worker observed cooperative cancellation and recorded it
interrupted The worker no longer owns its lock and no terminal record was committed
invalid Retained schema or integrity checks fail; the record cannot support completed status

SIGTERM requests cooperative cancellation. The pipeline checks between stages and before completed-manifest publication; the continuous simulator also checks at step boundaries. A native callback or long stage can still delay a response. Hard termination releases the worker's OS lock, and a later inspect identifies the interrupted request. Process ownership does not rely on a potentially reused PID. No manual stale-lock deletion is required after a process exits.

The terminal record uses schema galata.project-result.v1 and retains its revision, ID, status and diagnostic. A completed record binds trajectory, model-evidence and pipeline-manifest paths and digests. Review verifies those bindings and the exact consumed source bytes against the submitted snapshot. Rehashing a manifest that names a different source does not establish that it belongs to this request. If a retained output is changed, inspect reports an invalid result and preserves the original terminal record for investigation.

Completion remains execution evidence. Numerical accuracy, model validity and engineering acceptance stay separate and not_assessed for both continuous profiles. The model evidence retains semantic identity, solver options, ordered state/output/schedule IDs and a trajectory digest. The ordinary pipeline manifest retains input snapshots and build/runtime identity. A plot or partial CSV cannot replace these records or turn an interrupted run into a completed study.

The imported manifest's original Jacobian and CARE diagnostics remain visible as source evidence. Project reruns do not inherit those diagnostics as an assessment of edited model rows. Even an unchanged graph requires separate accuracy, physical-validity and engineering-acceptance evidence. Retaining the origin supplies traceability; it does not establish a newly validated aircraft model or controller.

Limits and compatibility

Model source is limited to 1 MiB; a project draft to 2 MiB; source-origin attachments to 8 MiB; and retained runs and revisions to 1,024 each. The M1 compiler/runtime limits on blocks, connections, steps, stored scalars and scheduled evaluations continue to apply. Unknown schemas, duplicate keys, malformed and oversized documents are refused. Canvas coordinates are bounded to [-100,000, 100,000]. Initial time is bounded to [-10^12, 10^12] seconds; step size is between the smallest normal binary64 value and 10^12 seconds. Step count is at most 1,000,000 and sample stride is in [1, 1,000,000]. The runtime additionally checks representable time arithmetic and execution/storage budgets. Artifact review reads at most 128 MiB per file.

This preview has no automatic migration, autosave, checkpoint resume, compiled cache, shared-drive editing or long-term compatibility guarantee. OS locks and atomic publication are a local process-recovery contract, not proof of every filesystem's power-loss durability. The worker is a separate process without an operating-system sandbox or accepted hard wall-time/resource budget. The linear adapter reconstructs a local perturbation plant/controller graph; it adds no nonlinear aircraft block, sampled/hybrid behavior or validity assessment.

For native macOS build and interaction instructions, see the M2 implementation record and desktop preview guide.