Files

7.4 KiB

Typed port core milestone handoff

Implemented in D:/CodexWorktrees/Capella2-typed-ports, branch codex/typed-port-contracts, based on c20a207. This is the core portion of the adopted port contract. It must be integrated with the migration/source worker's companion changes; desktop/native acceptance remains the root task's work.

Delivered behavior

  • Schema 3 persists PortContract::{FunctionInput, FunctionOutput, Component, Legacy}, preserved LegacyPortContract, Standard/Flow component kind and separate orientation, mandatory FE port UUIDs, BoundaryExchange.oriented, and identified PortAllocation relations. Legacy association data is preserved through typed resolution and remains reference-aware without becoming an invented provided/required declaration.
  • Typed function/component ownership, direct item declarations, empty-contract handling, actual work allocation, endpoint direction, same-layer references, unique PortAllocation pairs, explicit interface roles, and exchange/port allocation correspondence are validated in ports.rs through the normal candidate validator. Standard-to-Flow component exchanges are structural errors, reflecting the root's later native observation. Legacy compatibility remains explicitly warned.
  • Public plan_functional_exchange, plan_component_exchange, plan_legacy_port_resolution, and plan_legacy_work_port_split implement the contract request types and return concrete existing commands. Public plan_function_port_items supplies explicit item synchronization. Planners validate complete candidate batches; intermediate generation does not modify the original project.
  • FE creation reuses exactly one compatible typed endpoint or creates deterministic new endpoints. Explicit incompatible reuse fails; ambiguous Auto creates a fresh port. Component generation creates/reuses both component ports, two PortAllocations, the boundary exchange, and ExchangeAllocation together. It requires actual work allocations and never invents interfaces or provider/requirement roles. Repeated generation with an existing boundary reuses facts and identities.
  • Split preserves the original legacy record, primary UUID/alias/prose, artifacts, constraints, and traces; it creates one opposite typed port and rewires source/target FE references. Resolution retains original interface metadata and legacy role identities. API/source can represent preserved legacy roles on resolved ports, with clear warnings; normal typed function ports use item contracts.
  • Reidentify visits typed item declarations, required FE endpoints, legacy interface associations, and allocation relations. Deleting a function port cascades incident FEs; deleting an FE retains independent ports. Deleting a work Allocation cascades dependent PortAllocations, and deleting a required PortAllocation cascades its dependent ExchangeAllocation. Interface deletion clears the preserved optional association and removes role relations while retaining items/ports.
  • OA-to-SA Interaction creation creates typed SA endpoints through the FE builder. SA-to-OA FE mapping remains portless, and Required scope does not copy even Legacy SA endpoint ports solely because an FE used them. Typed SA ports, boundary implementation, and dependent role/allocation records have explicit omission warnings. Original SA objects remain intact. Existing counterpart updates retain their endpoint identities.
  • The demo now uses typed ports, explicit function/component port allocations, and port-level interface roles. Projection anchors derive from visible owners without requiring port placements; orientation is independent of anchor side and actual exchange endpoint IDs are retained.

Integration APIs and changed rendering fields

All port helpers and request types are re-exported through oa_core::*; the bounded implementation module is oa_core::ports.

  • make_port(project, id, owner, name, contract) -> Result<Element, ModelError> builds an explicit port element for a caller's transaction. It does not adopt a model or independently validate unrelated candidate state.
  • ElementBody::new(Kind::Port, ..) now returns None: contextual authoring must choose a typed contract and owner. Do not restore a generic InOut default to make old forms compile.
  • RelationBody::new(FunctionalExchange, ..) is an explicitly unbound draft with nil endpoint IDs; it cannot pass candidate validation. Normal GUI/API authoring should use the public planner or a concrete complete Batch. Command::Connect(FunctionalExchange, ..) and Project::relate(FunctionalExchange, ..) now create/reuse real endpoint ports. The latter remains the existing unchecked Project builder; Session validates its resulting transaction.
  • ProjectedPort.direction is replaced by side: PortAnchorSide::{Left, Right, Bottom}. projection::port_anchor_side(&Element) is public. Glyph semantics must inspect the element's actual PortContract; Standard/Unset and InOut Flow are not interchangeable.
  • ProjectedEdge adds oriented: bool; BoundaryExchange uses its persisted value and other edges use true. The root's newer main-only summary: bool, routing, and layout changes must be merged alongside this field, not overwritten by this older checkpoint's projection body.
  • item_satisfies is identity equality until R6 specialization lands. items_satisfy, actual_performer, component_allows, has_port_allocation, and port_contract provide the small shared validation/authoring seams.

Preview binding to the current revision/fingerprint and UI display of non-FE references during split belong to the existing desktop preview/usage surface. Port planners return concrete commands; they do not introduce a second preview transaction engine. The UI must present preserved legacy associations distinctly and expose source/form/connection paths using these helpers.

Verification

Build output is isolated at D:/CodexBuilds/Capella2-typed-ports-core.

  • cargo test -p oa-core: all 124 tests passed after core/source/migration integration, including unchanged legacy admission/location tests. One additional directed-legacy-resolution regression was then added to the focused port suite.
  • cargo test -p oa-core --test release_ports: all 9 focused tests passed, covering atomic creation/reuse/collisions, actual allocation/generation, provider/requirement independence, Standard/Flow rejection, Legacy split and resolution, preserved attachments and references, deletion/remap/undo, portless transitions, and contract-aware geometry.
  • cargo clippy -p oa-core --all-targets -- -D warnings: passed after the final core/test changes.
  • Existing scenario14, diagram3, and workflow28 suites pass, including remapping/deleting every demo identity and checking the remaining candidate. Source/migration tests and server checks are owned/reported by the companion worker.

No CUA, desktop/native acceptance, deployment, future R6 item specialization, or R3 semantic baseline engine is claimed. Current R3 name/description-only drift remains the separately documented release seam; this milestone does not disguise it as completed semantic review.

Owned commit scope

Core: model.rs, ports.rs, lib.rs, validation.rs, references.rs, session.rs, transitions.rs, demo.rs, projection.rs.

Tests: new release_ports.rs; typed fixture adaptations in workflows.rs and release_scenarios.rs.

Handoff: this file only. Migration/source/server/documentation files and their tests belong to the companion worker and are intentionally excluded from the core commit.