Files
ARCADIA-Studio/harness/release-libraries-semantics-design-20260910.md
T

50 KiB

Reusable libraries: candidate semantics and falsifiers

Codex-956atf /root/libraries_design, 2026-09-10. This is a bounded foundational proposal for root synthesis and independent criticism. No candidate in this report is a ratified decision or implemented capability. Sole owned file: this report. No production edits, Cargo invocation, native application operation, or new passing test result. Initial source checkpoint was 8547b85; later root changes through aa40345 do not change the inspected library/reference architecture.

Read the complete updated PROJECT_GOAL.md, the requirements delta, Gitea issue #1 through comment #92, the open PR list (empty), and shared Wiki Home. Ownership is recorded in comments #86 and #93. Coordinated definition interfaces with the separate analysis/quantity designer. Codex-9e8r6t's independent criticism in #90 is incorporated below; that host's scenario/layout/creation/platform work is outside this task. Wiki Home contains older checkpoint evidence, not current release acceptance.

Proposed outcome and decision boundary

An engineer can publish a reusable library from ordinary modeled content, use its definitions in multiple projects, instantiate an OA/SA pattern more than once with explicit contextual bindings, and selectively update an instance without losing local work. The saved project carries the exact required library content and reopens offline. GUI, textual source and REST expose the same imports, bindings, instance identities and update choices.

The leading candidate is immutable content-pinned definition imports plus editable, materialized pattern instances with explicit origin maps and three-way update. It fits the current architecture better than making every architectural object a virtual instance of an external definition. It also provides maintained reuse that source copying alone cannot provide.

The most consequential remaining choice is how existing layer-owned data/interface definitions participate. This report prefers an explicit immutable local mount adapter for those existing records, while new layer-neutral quantity/calculation definitions use a qualified DefRef. That is a compatibility boundary requiring criticism and tests, not permission to create two inconsistent library systems. If the adapter cannot satisfy the common identity, source and update rules below, it loses to the more invasive uniform definition-reference alternative.

Local package publication and explicit server upload are sufficient to prove maintained cross-project reuse. A registry, automatic discovery, remote writeback from an instance, arbitrary executable plugins and full SysML/KerML instantiation are separate capabilities; none is assumed to exist under this proposal. This is a proposed bounded implementation strategy for the user's requirement, not a reduction of the acceptance obligations.

Evidence that constrains the design

Verified repository fact Consequence
model.rs:13 has only Layer::Oa and Layer::Sa; Project at :1621 has local element/relation/diagram/artifact/trace maps. identities() at :1727 builds one UUID/alias namespace. A package cannot be another Project merged into the maps without an explicit identity translation and ownership policy. A third neutral layer must not be invented just to store units.
SharedBody at model.rs:593 includes DataType, DataField, ExchangeItem and Interface; TypeRef::Named(Id) at :347 and ordinary semantic references use local UUIDs. validation.rs:126 expects an existing compatible element in the owner's layer. Neutral library references are not currently accepted by these paths. Making data definitions neutral requires a deliberate metamodel/refactoring decision.
parent_permits at validation.rs:92 distinguishes semantic containment. Processes/scenarios are layer roots; occurrences, lifelines, ports, data fields and state regions have specific owner kinds. SA admits at most one System of Interest (language.rst:31). Instantiation cannot place every selected object under an arbitrary container or clone another System of Interest. Binding and graphical placement are different operations.
OccurrenceBody contains ordered branches, sequence references, ScenarioUse lifeline bindings, reply identities, operation allocations and message-field paths (model.rs:550). ContextualLink endpoints have occurrence-reference paths. A pattern is a graph of typed records and references, not a collection of named boxes. Repeated uses, paths and order must retain their distinctions.
references.rs:5,11 enumerates typed live element/relation references; :206 also remaps views, placements, artifacts, traces and explicitly typed semantic-history references. Deletion at :270 can cascade into other records. Reuse these authoritative classifications where applicable, but do not run one UUID replacement over package metadata, text or historical origins. A library update must preview cross-instance deletion impact.
semantic/historical.rs:305 deliberately distinguishes historical UUID remapping from deletion; historical facts need not refer to currently live objects. OA/SA review has its own baseline and transition semantics. A package source member, an old local snapshot identity and a live local reference are different categories. OA/SA counterpart review is not a library merge engine.
SourceBundle is an explicit UTF-8 file map (source_project.rs:17). The compiler reads no filesystem/network. Includes share the project's global namespace (language.rst:1692). Imports need separate syntax and explicit supplied content. Neither relative include paths nor an ambient cache establish library identity.
prepare_command at session.rs:170 validates a private candidate and returns exact identity correspondence. update_bundle_with_identity_map at source_project.rs:780 checks the old index, preserves authored bytes and recompiles. Server admission at store.rs:144 uses that boundary. Library operations must extend this preparation/admission path. An adapter may not accept a model before package resolution and the corresponding source update both succeed.
Session stores Project history; desktop/source and server add document-level responsibilities. Command::Replace and nested Batch are available (session.rs:375). Read-only widgets are insufficient for immutability. Replace, source Apply, REST writes, nested batches, deletion, identity changes, migration and recovery all need the same semantic guards.

Capella's official feature page describes reusable collections/replicas packaged in libraries and shared between projects. Its official comparison explains why architectural functions/components are usually treated as distinct usages and why replication/synchronization supports that workflow. These observations support both shared definitions and distinguishable editable architectural occurrences. They do not specify the content-addressing, offline, merge or API rules proposed here. Capella features, Capella instance and definition rationale

Materially different candidates

Criteria come from the requested engineering workflow: maintained reuse, separate instances, exact offline reproducibility, complete source/API parity, understandable local editing, and a tractable extension of current semantics. Scores below are qualitative design judgments, not measured performance.

Candidate Maintained reuse / local editing Identity and offline behavior Existing-core impact Main falsifier
A. Copy source or model fragments; record a URL in an artifact link Local editing is simple; comparison/update is manual and correspondence is not authoritative. Fresh IDs can be generated, but provenance, exact dependency versions and subsequent merge are unspecified. Small. Cannot reliably update two differently edited instances of the same pattern. Fails as the final library implementation.
B. Compose immutable external model namespaces; all uses remain qualified references Excellent shared definitions; architectural local edits require a separate override or specialization model. Qualified identities and pinned packages can be exact. Every local lookup, containment/reference validator, query, diagram, transition and command must understand an external model environment. A supposedly simple rename or deletion of one architecture occurrence modifies the shared definition or requires an unexplained override language.
C. Virtual template instances plus an override log; expand effective models on demand Strong separation of template and instance; updates can replay or rebase overrides. Instance identity must remain stable as template shape changes; overridden lists/deletions need their own algebra. Adds an effective-model layer below nearly all current commands, validation, projection, source and API queries. Current explicit source records cease to be the editable authoritative model, or effective expansion yields different IDs after reopen.
D. Pinned shared definitions plus materialized editable patterns and explicit three-way update Ordinary local modeling remains available; origin maps make later comparison possible. Exact package closure and local maps survive reopen/history; updates are explicit. New package/document subsystem, reference adapter and merge planner; ordinary architectural records remain local. Immutability or provenance can be bypassed through Replace/source/REST, or local edits are silently lost during update. Leading candidate if these are disproved.

D wins over A because it maintains correspondence and update semantics. It wins over B/C for the first release because the existing ordinary local graph remains the engineering workspace, while shared definitions still have their proper distinct role. B is the stronger fallback if uniform qualified references prove simpler than maintaining the proposed legacy-definition mount boundary. C is not selected merely because template expansion is convenient for implementation; its override language would itself need a substantial specification and user workflow.

Common package, identity and resolution contract

The following rules apply to every export category and both representations of imported definitions.

  1. Logical identity: a library author allocates one PackageId UUID and preserves it across revisions. Each exported item, prototype record, neutral definition and external role has a persistent UUID. Renaming does not change identity. The publisher must create a new identity when a record changes semantic record class. Names and source aliases never establish correspondence.
  2. Revision identity: a PackagePin contains package_id, an exact nonempty version label, a package-format version and a SHA-256 digest. The label is human-facing and is not an implicit compatibility range. No ordering or automatic upgrade follows from a label. A changed digest is a different immutable revision even if all names are unchanged. Two contents claiming the same package ID/version with different digests produce a conflict when compared or brought into the same import graph; there is no last-writer-wins choice.
  3. Sealing: a package contains a manifest and one prototype SourceBundle. The prototype is an ordinary admitted Project in its own private namespace, including any local neutral definition catalog introduced by the analysis design. The manifest identifies the source entry, exports, member selection, roles and exact dependencies. All package record IDs must already be explicit. Importing sealed content must never insert missing IDs or migrate/reformat bytes silently; an older package requiring migration is republished as a new revision.
  4. Digest preimage: define a portable framed byte stream rather than hashing ZIP metadata. Proposal: ASCII ARCADIA-LIBRARY-1 followed by a NUL; then the manifest UTF-8 byte length as unsigned 64-bit big-endian and its exact bytes; then the entry-path length/bytes; then the file count; then each canonical logical path and source text, each separately length-prefixed, in ascending UTF-8 path-byte order. Counts/lengths are unsigned 64-bit big-endian. The manifest has no self-digest field; it includes dependency pins. Hash exact source bytes, including comments and line endings. The lowercase 64-hex-character digest identifies those bytes. This rule is a Studio proposal, not a claim of conformance to another package format.
  5. Dependencies: every package dependency names another exact pin, never a URL to resolve during compilation. The complete transitive graph must be supplied and acyclic. Prototype imports must agree with the manifest's declared dependencies; hidden prototype dependencies are errors. Within one root import closure, each PackageId resolves to exactly one pin. A diamond with two different revisions of the same PackageId is an explicit conflict, even if the author expects them to be compatible. An identical repeated dependency is deduplicated by digest. Report the two requiring paths.
  6. Concurrent versions: two separate named imports in one project may have distinct closures and pin different versions of the same package. This permits one instance to advance while another remains pinned. Aliases qualify lookup; they do not make the definitions equal. Identical digest/member/dependency identity reached through two aliases denotes the same imported definition; changed digest is not automatic type equivalence. This matches the analysis designer's proposed exact type identity.
  7. Import immutability: once referenced, an ImportId's root pin and closure cannot change. Updating creates a new import and explicitly rebinds selected uses/instances. Renaming the import alias changes source spelling only. Removing an import is refused while a live definition use, mount or managed instance still requires it. Old package bytes remain available to history and recovery even when the current document no longer uses them.
  8. Resolution: a pure VerifiedPackageStore is derived from explicitly supplied package bytes by digest checking, manifest parsing, bounded graph resolution and prototype validation. No deserialized boolean such as verified: true is trusted. Missing content, unknown export/member, forbidden private member, duplicate manifest key/UUID, dependency cycle, wrong digest, unsupported package format and source/admission limit failures return located diagnostics and no candidate. They never substitute a cached different version or an empty definition.
  9. Budgets: apply total document/package limits to the deduplicated closure, not fresh limits per package. Initial benchmark candidates are 64 packages, graph depth 16, 256 dependency edges, and 64 MiB combined project/package source, in addition to existing record/parse budgets. These numeric choices require realistic-library measurements before becoming normative; finite configurable refusal is mandatory. A rejected import retains the raw draft and accepted document unchanged.

Digest verification establishes exact content identity; publisher identity or compatibility promises are separate metadata. Registry access, if later added, only supplies bytes to this same admission boundary.

Export categories and the definition-reference tradeoff

The proposed manifest has three explicit export categories. An engineer sees their purpose, not Rust variant names.

Export category Consumer semantics Layer policy
Definition An immutable reusable quantity kind, unit, calculation or other neutral catalog definition. DefRef::Imported { import, package, member } resolves through the supplied closure. Only stable formal parameter IDs and other definitions may be captured; no particular project's property/case/participant identity. Neutral. Applicability of an analysis property/case remains OA/SA-owned and is checked by the analysis model.
LayeredDefinition An immutable data/interface contract graph mounted once into a consuming project, with an explicit source-member-to-local-ID map. Many local uses point to that one mounted graph. Initial allowed records: DataType, DataField, ExchangeItem, Interface and their data-association/interface-item-allocation closure. Exactly the layer declared in the prototype export. Mounting does not translate OA to SA or relax same-layer references. A package may publish separate OA/SA exports.
Pattern A set of ordinary OA/SA semantic records materialized with fresh local identities and explicit external bindings. The resulting architectural records are editable, with instance provenance maintained separately. Original layer of each member is preserved. An export may deliberately span OA/SA and carry explicit mapped traces. An independent layer-transition command remains a different operation.

The layered-definition adapter preserves current TypeRef::Named(Id) and same-layer validators. Mounted records are semantically read-only; they are not editable pattern instances. Their payload must exactly equal the admitted export transformed only by the stored identity/alias map. The mount's revision and member identity/alias map are immutable once created; editing that map in source is not a bypass for renaming/reidentifying an imported payload. The outer import alias remains local spelling. A user can fork/detach definitions explicitly. A new package revision creates a new mount with new local IDs; selected referencing uses are rebound in one reviewed transaction. The old mount can coexist for unchanged uses. A layered definition has no project-specific roles: its complete data/interface dependency graph is included or resolved through other explicitly mounted exact definition exports.

This avoids silently neutralizing current data semantics or converting all architectural references into external references. Its cost is real: local mounted IDs and qualified neutral definition references have different storage shapes. The common resolver must expose one origin descriptor (pin, export, member), one import lifecycle and one read-only/error policy to UI/API clients. The origin descriptor must be discoverable from a mounted local ID and from a DefRef. An API must never report the mounted record as ordinary editable content merely because its model field is a UUID.

The competing uniform alternative introduces qualified references for all reusable data/interface/member positions and a neutral definition catalog for those records. It removes materialized mounts, but touches DataField ownership, inherited field lookup, port/interface contracts, operation allocation identities, message field paths, diagrams, transitions and semantic-history source forms. It should win if a focused prototype shows fewer special cases or if the intended engineering workflow requires one exact data identity to span OA and SA. That requirement is not inferred by redefining the existing same-layer rule. Root should resolve this adapter choice before implementing the catalog/reference migration.

Pattern publication, closure and binding

Use an admitted prototype Project as the authoring context, rather than allowing arbitrary ill-typed placeholder JSON. An export selects prototype members and declares the prototype identities at its boundary as named roles. Those prototype role records demonstrate a valid context, but are not cloned into consumers.

An export's closure is explicitly reviewable and then sealed:

  • Start from selected semantic roots. Include all semantically owned descendants required by those roots: ordered occurrences/branches, lifelines, ports, fields, machine regions/states and newly modeled analysis records where their declared subject is included.
  • Include internally owned relation records, not only relations whose endpoint names happen to match. This includes sequence/contextual links, state transitions/actions, interface-item allocations and other relations needed for the selected behavior/contracts. An omitted essential relation is an export error; an intentionally partial external relation requires a declared boundary role.
  • Classify every typed reference as another exported member, an imported definition with an exact pin, or a declared external role. No dangling package-private UUID may escape. Forward references are valid; unresolved references are not converted to None to make the export succeed. Existing deliberately incomplete optional fields may remain incomplete and retain their engineering warnings.
  • Give each role a stable ID, label, required reference category, allowed kinds/layer, and context predicates inferred from all its use sites. Parent roles must satisfy parent_permits. Scenario roles must respect viewpoint/represented-source rules; operation/port bindings must satisfy their existing ownership contracts. The final materialized candidate still passes complete core validation, which is stronger than matching a kind label.
  • A required role has exactly one explicit binding; an optional role can be explicitly absent only where every use site permits absence. Two roles may bind the same host identity only when their contracts and all resulting relations remain valid. This is shown in preview. There is no bind-by-name fallback.
  • A package System of Interest is a context role, never a cloned member. An SA pattern may require binding to the host's System or leave that separately optional if its contents permit. The operation never creates a second System, translates it into another kind, or silently creates one to satisfy a binding.
  • A prototype Project ID is not an architectural member. Layer roots stay roots unless their kind permits a chosen semantic parent. Importing into a diagram adds placements only through an explicit presentation choice; the diagram is not their semantic owner.

The package author can publish a whole coherent two-layer pattern; the manifest must state which cross-layer trace links are included. New instances may copy those links when both endpoints are resolved. They do not copy prior semantic-review acknowledgments as though the consumer reviewed the instance. The initial policy clears copied trace baselines and reports that review is pending. Ordinary accepted local baselines on an existing instance are not automatically refreshed during a library update. Explicitly supplied artifact links preserve URI/revision/fragment literals; UUID-shaped strings are never remapped. A relative artifact target must have an explicit package or consumer base policy before it can be exported portably; no silent rebasing against the user's current directory.

Presentation export is an explicit independent option: include a named diagram with its placements/routes/options only when every referenced semantic identity can be mapped or bound. Allocate fresh diagram and placement UUIDs, remap actual typed references, and preserve geometry. Semantic-only instantiation creates no arbitrary default arrangement; the initiating graphical workflow may supply reviewed placement commands. Updating semantic content does not overwrite local layout unless the user selects a separate presentation change set.

Proposed persistent model and document shapes

These are type-level sketches, not production Rust or finalized source grammar. Identity wrapper types should prevent passing a foreign member UUID to a local-ID remapper.

PackagePin { package_id: PackageId, version: String, format: u32, digest: Digest }
PackageArchive { manifest_source: String, prototype_source: SourceBundle }
LibraryImport { id: ImportId, alias: Alias, root: PackagePin }
DefRef = Local(DefinitionId)
       | Imported { import: ImportId, package: PackageId, member: MemberId }

DefinitionMount {
    id: MountId, alias: Alias, import: ImportId, export: ExportId,
    member_map: Map<MemberId, LocalId>, aliases: Map<MemberId, Alias>
}

LibraryInstance {
    id: InstanceId, alias: Alias, name: String,
    base: { import: ImportId, export: ExportId, bindings: RoleBindings,
            materialization_policy: Policy, original_local_map: MemberMap,
            snapshot: TypedInstanceGraph },
    correspondence: Map<MemberId, Live(LocalId) | Deleted(ReservedLocalId)>,
    identity_lineage: ExplicitLocalIdentityCorrespondence,
    proposed_binding_defaults: RoleBindings,
    detached_origins: List<OriginRecord>
}

Project additions: imports, definition_mounts, library_instances,
                   local neutral definitions (owned by the analysis design)

PortableDocument {
    model: Project,
    source: SourceBundle,
    packages: Map<Digest, PackageArchive>
}

The package archive map is authoritative input to pure admission, not an ambient resolver cache. Its parsed model/index can be derived and shared immutably in memory. An implementation may deduplicate immutable bytes between snapshots, but it must not omit them from portable export/recovery or drop a pin required by Undo.

Project includes import/mount/instance intent and local editable records. The document compiler derives/verifies mounted payload against exact package content, checks every origin map and definition reference, and rejects forged mismatches. Public JSON that contains mounted records is checked against the same materialization. No special trust attaches to an API caller's supplied project or plan. A core model-only convenience API can use an empty store for projects without imports; it must return missing_library_content for imported content unless the required store is explicitly supplied.

The baseline records the actual last adopted package, bindings and materialized typed graph, not a regenerated guess from current local data. Its snapshot includes the exact chosen local aliases/names, identity map, copied presentation policy and constructor payloads. Regenerating aliases with fresh_alias against today's project would create a false baseline after unrelated names are added; that is prohibited. Baseline references can be historical and absent, so validate their closed shape, mapping and derivation separately from current live-reference admission. Deleted tracked members retain a reserved local identity so a later import cannot silently reuse that UUID for a different object. The active correspondence is injective, record-class-preserving and disjoint between instances and mounts. Separate instances always allocate separate local members, even with identical bindings and names. Shared immutable definitions can deliberately be common to both.

Explicit local Reidentify must update current correspondence and a typed lineage map used during comparison; it does not rewrite the sealed package or the immutable original snapshot. Deletion marks a mapped member absent instead of forgetting its origin. A subsequent new record with a similar name is a local addition, not the deleted member's replacement. A retained upstream-deleted member can be explicitly detached; a later upstream reintroduction cannot silently adopt that local extension.

Textual source and portable admission

Text must represent the complete library intent. Merely attaching packages to a desktop save dialog would break parity with source Apply and REST.

Proposed source forms illustrate the required information; keyword spelling/version numbers remain subject to grammar review:

library_import controls_v1 id "<import-uuid>" {
    package "<package-uuid>";
    version "1.0.0";
    digest "<sha256>";
}

definition_mount oa_telemetry id "<mount-uuid>" {
    import @controls_v1;
    export "<oa-data-export-uuid>";
    members { "<source-type-uuid>" -> "<local-type-uuid>" alias telemetry; }
}

library_instance left_monitor id "<instance-uuid>" {
    import @controls_v1;
    export "<pattern-export-uuid>";
    bindings { "<operator-role-uuid>" -> @operator_left; }
    members { "<source-activity-uuid>" -> @monitor_left; }
    // Exact baseline/correspondence records are typed source values.
}

For neutral definition use, a readable qualified alias can resolve to the exact imported member (controls_v1::duration); canonical output must retain the stable import/member identity, and alias changes must use the source index rather than text replacement. Existing local alias spelling remains globally unique for local records. Member aliases are scoped inside their package; two packages may both export duration. Missing/ambiguous export lookup is an error, never a first-result match. Avoid widening current reserved words until the actual grammar is selected.

The pure source compiler accepts an explicit portable source envelope consisting of the ordinary SourceBundle plus package archives, resolves imports from that envelope, and returns the entire admitted document. Existing include semantics remain unchanged. Package archives are nested typed source bundles in JSON/REST. A directory export places them at digest-addressed paths and an explicit manifest maps pins to those logical entries; file loading builds the same envelope before calling the compiler. The directory loader may read only those declared bounded paths, just as current includes are explicit. It must never search another open project's cache for a convenient revision.

Canonical source export must offer a self-contained envelope/directory containing every required package, with the invariant compile_source_document(format_source_document(document)) == document.model plus exact package bytes. A single source string that contains imports but lacks the explicit package envelope returns missing-content diagnostics. Existing no-library string APIs continue working. A plain model JSON export that needs imports must likewise use the published portable document representation; it must not masquerade as independently reopenable when its required bytes are absent.

SourceIndex needs locations for imports, mounts, instance mappings, bindings, definition references and lineage fields, with typed classification of local versus foreign IDs. Derived mounted payload does not receive a second ordinary editable declaration: canonical formatting emits its mount directive/map and the supplied package envelope, and compilation reconstructs/verifies it. The source updater must classify derived mounted records explicitly rather than treating a missing ordinary declaration as a reason to append one. Graphical operations update only affected local tokens and metadata; package bytes are immutable. Editable pattern instances, their diagrams and their source declarations remain ordinary authored records. Exact source/history tests must include comments, duplicate display names, non-ASCII text, mixed file ownership and CRLF content.

Command boundary, visitor audit and immutability

The shared core should expose pure prepare operations, with no Iced or HTTP-specific library rules:

inspect_package(archive, supplied_closure, limits) -> PackageInspection
prepare_import(document, archive_closure, import_identity) -> PreparedDocument
prepare_mount(document, import, export, reserved_map) -> PreparedDocument
prepare_instantiate(document, import, export, bindings, presentation, reserved_map)
    -> PreparedDocument
preview_instance_update(document, request) -> LibraryUpdatePlan
prepare_instance_update(document, request, choices, expected_plan_fingerprint)
    -> PreparedDocument
prepare_detach_instance / prepare_fork_definition / prepare_remove_import

Preparation resolves exact bytes, reserves IDs once, validates package/mapping/role rules, builds an ordinary candidate command batch, checks complete model semantics, updates the source envelope, recompiles, and compares the resulting full model and pinned content before adoption. The returned selected identity is optional metadata, not proof of acceptance. A preview exposes its base revision/source/closure fingerprint and reserved IDs. Commit recomputes/checks the request and choices against the current document; it never trusts arbitrary serialized commands supplied in a plan. Stale revision, changed source, changed package bytes, lost binding target, unresolved conflict or source-budget failure rejects the whole operation.

Mandatory reference categories and their behavior:

Category Example Rename/reidentify/delete behavior
Live local semantic reference Parent, endpoint, field path, scenario binding, analysis property subject, local DefRef Existing typed local visitors apply; same-layer/kind rules remain. Include new analysis and library use sites in impact queries.
Live local library bookkeeping Instance current correspondence, current binding defaults, imported/mounted object handles Update through explicit typed library visitors. Reidentify composes actual identity correspondence. Deletion records tombstones or refuses removal of required managed objects as specified.
Qualified definition reference ImportId plus PackageId/MemberId Import alias changes source spelling only. Explicit reference rebinding changes revision. A local element reidentify never changes PackageId or MemberId.
Foreign origin PackageId, export/member/role IDs, dependency IDs and sealed prototype references Never visited as local identity. Never renamed/deleted because an equal UUID bit pattern happens to occur locally.
Historical baseline/original-map reference Last-adopted role bindings and original local map Retain exact stored observations. Use explicit identity-lineage data during comparison rather than rewriting sealed or historical origins. Absence from the current model is allowed. Never include these in deletion cascades.
Existing OA/SA semantic-history reference Typed SemanticBaseline fields Preserve the current explicit-remap policy in semantic/historical.rs; do not broaden it to package history. No generic scan of UUID-shaped strings.
Literal content Artifact URI/revision/fragment, descriptions, expression text, comments Preserve bytes except an explicitly edited literal. A UUID-looking substring is not a reference.

Audit every affected boundary: Project.identities/contains/fresh_alias/layer_of/named, typed reference enumeration/remapping, reserved/tombstone identity checks, deletion impact and finish-deletions, inheritance pruning, kind/reference admission, source normalization/index/update, JSON decoding, migration, semantic baselines and transition preparation, projection/view options, server query/edit endpoints, recovery and both forms of history. An allowlist of editable imported fields in a form is not this audit.

Mounted records reject ordinary Edit/Rename/Reparent/SetAlias/Reidentify/Delete and any transitive command that would mutate their verified payload. If a local deletion would cascade into a mount, the whole operation requires a reviewed rebind/detach/removal instead. Replace and source Apply may propose another valid immutable revision/import/mount, but cannot alter bytes while retaining an old pin or forge a mounted payload that does not match the export. The first implementation should centralize this as before/after document admission, so nested Batch and all adapters are covered.

Three-way update: exact observable rules

For a managed instance, define B as its exact stored last-adopted materialized snapshot, validated against the pinned export and stored policy/bindings; L is the current local graph and N is the proposed new export with explicit proposed bindings and reserved identity/alias map. Match members by stable package member identity, then use the stored correspondence/explicit local identity lineage to compare their local roles. Do not match by name, diagram position or graph similarity, or reconstruct B using current local names/values.

Fresh members in N reserve new local IDs once. Surviving members keep their current local IDs. A kind/class change under the same source member ID is a conflict, not an identity-preserving edit. A package update may not silently convert an Activity into a Function, an element into a relation, or a definition into an occurrence.

For a typed facet with values b, l, n:

  • If l == b, the upstream change to n is an eligible update.
  • If n == b, retain the local change l.
  • If l == n, the edits have converged.
  • Otherwise, require an explicit local/upstream/valid authored resolution.

Equality is typed and includes exact reference identities. Constructor changes and their dependent fields are one coupled decision. In the first coherent slice, ordered member arrays are compared as complete ordered values; simultaneous local reorder and upstream insertion is a conflict requiring an explicit final order. This conservative rule is preferable to silently inventing an insertion anchor. Truly set-valued collections can compare by identity membership where the existing specification says order is irrelevant.

Deletion is not a special case that bypasses review:

Situation Required outcome
Upstream deletes a member; local member is unchanged Eligible deletion only after all external references and current deletion cascades are shown. Any affected object outside the instance requires explicit resolution.
Upstream deletes a locally edited or locally referenced member Conflict: keep as detached local content, or explicitly delete/rebind the full reviewed impact. No hidden cascade.
Local member was deleted; upstream changes it Conflict: preserve local deletion or recreate from upstream using its reserved identity if still admissible. Never resurrect it just because its name appears in the new package.
Upstream and local both delete Converged absence; provenance remains sufficient for the next update.
Local addition is absent from both package revisions Preserve it as local extension. Its relations/containment can still make another proposed change invalid.
Upstream changes or removes a role Review the role/binding facet and all affected use sites. Wrong-layer or missing targets are errors. No fallback to a different same-named participant.

An ordinary local field edit changes the actual model; it does not retroactively change the package baseline. An explicit rebind action records intended role defaults and changes the selected current use sites, with a preview of any divergent local field. Future additions use the proposed bindings shown in update preview. The tool must not imply that every ordinary reference remains a live parameter substitution after materialization.

The plan covers all choices and the complete candidate, including effects outside the instance, before Apply becomes available. Apply is one document/history transaction. On success the base advances to the exact new package/materialization, even when selected local overrides or deletions remain; they remain differences from that new base. A rejected or cancelled preview leaves the old base unchanged. Evaluating a preview and inspecting changes create no history step.

Semantic and presentation updates have separate choices. Existing OA/SA traces stay ordinary local artifacts: neither updating a package nor changing a binding implies the engineer has reviewed OA/SA consistency. The current semantic reviewer can report resulting changes, but its acknowledgment state is not a substitute for the library baseline.

Detach, fork and removal

Detach instance retains the current local semantic records, IDs, relationships, source spelling and local layout. It removes active update management and reservations for absent members, records a non-live origin note with package digest/export/mapping, and clearly states that future package updates will not be offered for those records. Detaching must not detach another instance sharing an immutable definition.

Fork imported definition creates ordinary editable local neutral definitions or a local data graph, with fresh IDs and an explicit reference-rebind selection. It copies the dependency closure needed for the fork or retains explicit pinned references; no dangling private member escapes. The original imported definition and unselected uses remain pinned. This operation is different from changing a package's sealed bytes.

Removing a whole instance uses a reviewed deletion impact and one atomic command. Removing an unused mount/import is explicit; it cannot remove another current use's dependency. Garbage collection may reclaim package bytes only when no current document, history, pending accepted recovery snapshot or retained baseline needs them. Closing the project does not evict information required by its saved portable form.

Concrete two-project example

Publish package ControlPatterns, PackageId P, version 1.0.0, digest D1. It exports neutral Duration/ms/s and a reusable calculation, one OA data contract, and a monitor pattern. The OA pattern contains Activity A, an owned behavior/scenario with two distinct occurrences and a typed link; external participant role R is excluded from cloned membership. A separate SA export can carry Function/port structure and bind the host System. The IDs P/A/R are symbolic stable UUIDs for this example, not name-based resolution.

  1. Project Alpha imports D1 as import I1; Beta independently imports the exact same package. Both persist all required package bytes.
  2. Alpha instantiates the pattern twice. Maps are A -> alpha_left and A -> alpha_right, with distinct UUIDs for every copied occurrence/link/placement. Role R binds to different existing participants. Both can deliberately use the same immutable Duration definition and OA data mount. Beta's map has entirely different local IDs.
  3. Alpha changes the left activity's description and reorders its two occurrences. The right instance stays unchanged. Beta closes its project and its application.
  4. Publish 1.1.0 with digest D2, preserving A and other surviving member IDs. It changes the same description, adds a third occurrence, and removes another referenced member. Alpha imports D2 as I2; I1 is untouched.
  5. Update only Alpha's left instance. Preview shows the description conflict, the complete order conflict, the member addition and outside-reference deletion impact. The engineer keeps the local description, explicitly chooses a valid three-occurrence order and keeps the removed referenced member as detached local content. One Apply advances only this instance to I2; its surviving UUIDs remain stable. The right instance remains on I1.
  6. Undo restores Alpha's exact model/source/import/instance state and prior accepted package references; Redo restores the same reserved IDs and choices. Save and close Alpha, clear only disposable resolver caches, disconnect the network, and reopen Alpha/Beta from their portable files. Alpha has its selected D2 instance plus the pinned D1 instance; Beta still has D1. Their type/evaluation identities and results are derived from those exact bytes.

A variation binds a role to an invalid SA actor for the OA export, supplies two different pins of a shared dependency within one closure, modifies one package source byte without updating its digest, or removes a required archived package. Each variation rejects with a precise diagnostic and preserves the accepted project. A variation uses two package versions under distinct imports; it succeeds without conflating their definitions by alias or stable member ID alone.

REST, migration and release acceptance

Extend the existing published Studio API, not an undocumented desktop-only endpoint. Read/query responses expose imports, origin, definition mutability, instance status and exact pins. Package inspection/upload accepts bounded explicit archives; import/instantiate/rebind/detach/update use the same pure core preparation as the GUI. A read-only preview response includes revision/closure identity and structured changes/conflicts; commit requires the current ETag and complete choices. A stale ETag or changed dependency rejects atomically. Independent clients must not need private Rust enum knowledge beyond the published schemas/examples. This is not a claim to implement the OMG Systems Modeling API.

A deliberate next schema/source version must add the chosen forms. Existing source7 includes remain ordinary project modules. Existing ScenarioUse/SequenceReference remain within-project reuse. Existing annotations, artifact links or filenames that look like library references do not become imports by heuristic. The default migration adds empty library state and preserves all accepted source/comments/IDs; neutral analysis migration is coordinated with its own design. Package-format evolution is independent and explicit: old immutable bytes keep their old digest, and supported readers either interpret that format correctly or request a republished/migrated revision.

The first vertical slice is complete only when it proves the following through core, source, REST and the actual native application. None has been executed in this report.

Acceptance / falsifier Required independent observation
L1. Shared definitions plus distinct architecture Publish a package containing a usable data definition, neutral unit/calculation and OA/SA pattern exports; consume in two fresh projects and instantiate twice in one. Compare complete models, maps, typed references and exact package bytes. Two instances must not alias accidentally.
L2. Real maintained update Execute the description/order/deletion example above. Check local changes and outside references, explicit choices, base advancement, untouched old-version uses and stable surviving IDs. Compare against a separately constructed expected graph, not the planner's own candidate.
L3. Exact history/recovery Save/reopen, Undo/Redo and crash recovery retain exact authored source, all pins/maps, reserved IDs and raw invalid bindings/update drafts. Compare saved snapshots byte-for-byte and full models; semantically similar regenerated IDs fail. Preview/cancel creates no revision/history step.
L4. Offline and missing content Close both applications/projects, discard disposable caches, reopen offline. Exact pinned definitions/results remain available. Remove a required archive and observe a clear unresolved import with no mutation or fallback, then supply the exact bytes and recover.
L5. Dependency and namespace failures Test a diamond with conflicting dependency versions, a dependency cycle, same package/version with different content, duplicate manifest keys and IDs, case-colliding logical paths, unknown/private exports, alias collisions and aggregate-budget exhaustion. Test two legitimate concurrent versions under different imports.
L6. Immutability on every adapter Attempt direct/multi-level-Batch/Replace/source/REST mutations, reidentification and cascaded deletion of mounted/imported content. Every path either rejects unchanged or performs an explicit valid fork/rebind/removal. Changing an origin UUID or digest cannot make forged payload authoritative.
L7. Typed visitor traps Put identical UUID bits in a live local ID, package member, historical original map, artifact URI, description and expression text. Reidentify/delete the local object. Only the specified typed categories change; package bytes/literal content remain exact. Include current OA/SA historical semantics and a deleted managed member.
L8. Domain closure Pattern contains nested ALT/LOOP occurrences, ScenarioUse repeated bindings, operation allocation and message-field paths, contextual links, state machine transitions, OA/SA traces and data inheritance. Instantiate with valid/invalid bindings. Full core admission passes/rejects appropriately; no required relation is dropped to force success.
L9. Layer and singleton fidelity OA cannot bind an SA role; importing an SA pattern never clones a second System of Interest. Explicit parent and graphical placement choices preserve existing containment semantics. New neutral definitions do not bypass architectural layer checks.
L10. Graphical task usability At minimum and wide windows, publish/import, choose an export, bind the intended participant among repeated names, instantiate, inspect origin and resolve update conflicts. Use scope/kind groups, contextual search and a focused detail editor. A package browser or change review must not expand every member into one long homogeneous list. Record an action/time budget before the comparison and observe real task completion.
L11. Independent API/source client A client using the published OpenAPI and reST can supply package bytes, create imports/instances, query origin, preview/apply update, handle stale ETag, detach and export a portable document. Build equivalent accepted models through GUI/source/API and compare them fully.

Highest-value next experiment and reasons to revisit

Before a large implementation, run a small pure-core prototype against one existing DataType/Interface graph and the proposed neutral Duration/calculation definition. Implement only import resolution, one immutable mount, one pattern map and the exact document round-trip in an isolated experiment. Falsify the two-reference-shape bridge with source rename, local Reidentify, deletion, Replace, duplicate UUID bits and concurrent versions. If special cases spread into ordinary projection/command code instead of a confined resolver/admission adapter, switch to the uniform definition-reference design before proceeding.

Then implement the three-way update example with a conservative typed-facet merge. A complete valid candidate plus exact source history is the success criterion; a visually plausible diff is not. Native workflow design can use real inspection data from that prototype, but the package/reference contract must be reviewed before downstream UI/API/schema work.

Reasons to reopen the leading choice include a demonstrated need for virtual instances/overrides, exact shared data identity across layers, registry-driven dependency solving, collaborative package authoring, package signatures as a workflow requirement, or unacceptable measured size/performance of preserved package/history content. These would justify explicit design expansion, not hidden changes to pin or identity semantics.