No test coverage verified the end-to-end Phase 3 source-wiring invariants as a suite:
that every representative targeting node type (Pin, DataPoint, Button, TaskList, Trigger, Cron)
flows through TargetingWiringEditor; that pre-Phase3 wired nodes retain their
sources/executionSource/nodeAction values through withParentSourceDefault and
JSON round-trips; that PARENT_EXECUTE_SUCCESS is absent from the rendered Invoked-By
options while the enum constant survives deserialization; that the multi-host source picker
groups by host and deduplicates correctly; and that deleting a source node leaves
source-wired subscribers structurally intact.
Stages 1–4 (PRs #294–#297) shipped the implementation and partial test coverage in dedicated issue branches. No single closing stage verified all invariants together:
InvokedByOptionsTest — filter + deserialization safety.SourcePickerLogicTest — type-first host-grouped picker logic.SourceDeleteSemanticsTest — D8 non-destructive delete.The TargetingWiringContractTest in composeApp/desktopTest/ closes the remaining gaps:
representative-type interface check, copy-round-trip, D4 targets-field retention, and
pre-Phase3 wiring preservation (both via withParentSourceDefault and fastJson).
TargetingWiringContractTest in composeApp/src/desktopTest/kotlin/krill/zone/app/
covering tasks 5.1 and 5.3 of openspec/changes/universal-source-wiring-ux/tasks.md:
is TargetingNodeMetaData.sources, executionSource, nodeAction survive copy() for each type.targets is retained in the data model across all six types (Phase 4 will delete it).withParentSourceDefault preserves pre-configured executionSource and nodeAction; does
not duplicate sources; adds the new parent when sources were empty.fastJson round-trip for Pin, DataPoint, and TaskList nodes with existing wiring.InvokedByOptionsTest, SourcePickerLogicTest,
SourceDeleteSemanticsTest, NodeMetaDataSourceWiringTest) remain on main from PRs #294–#297.targets is hidden from the editor UI but preserved in all MetaData
types and processors until Phase 4 reworks the 8 targets-reading processors. Any new
editor must NOT expose a targets picker. The TargetingWiringContractTest guards this
by asserting (meta as TargetingNodeMetaData).targets is readable and non-empty when set.TargetingWiringContractTest’s
representative-type assertions so interface compliance and wiring round-trips are gated
from day one.