Skip to content

Runtime Invariant Coverage

This document maps runtime invariants to concrete CI tests. Add a row here whenever a runtime semantic invariant is added, moved, or intentionally deferred.

# Invariant Coverage
1 GraphContext::publish() never directly calls downstream components. tests/test_runtime.cpp: Runtime.PublishStagesWithoutRecursiveDownstreamExecute.
2 immediate edges in a DAG are visible in the same epoch. Runtime.ImmediateFeedForwardIsVisibleInSameEpochAndMetricsMatch; Runtime.RunModeExecutesEventRuntimeAndRoutesChannels.
3 delay edges are visible only at the next epoch. Runtime.DelayEdgeCommitsAtNextEpochBoundary; Graph.DelayEdgeBreaksImmediateCycle.
4 state readers see the old snapshot in the current epoch and the new snapshot next epoch. Runtime.StateAndAsyncEdgesCommitAfterCurrentEpoch; Graph.StateEdgesRejectMultipleWritersToSameTarget.
5 async edges do not participate in immediate SCCs and are visible as deferred events; max_inflight bounds pending deferred completions and discarded CompositeLoop async outputs release accounting. Runtime.StateAndAsyncEdgesCommitAfterCurrentEpoch; Runtime.AsyncTaskReadyTriggersDownstreamOnLaterEpoch; Runtime.AsyncMaxInflightDropsOldestBeforeChannelCapacity; Runtime.AsyncMaxInflightRejectPoliciesDoNotCommitRejectedCompletions; Runtime.CompositeLoopDiscardedAsyncOutputsReleaseInflightAccounting; Graph.NonImmediateFeedbackEdgesDoNotCreateImmediateSccs.
6 Undeclared immediate SCCs reject. Graph.ImmediateCycleRequiresCompositeLoop; Graph.FixedSeedImmediateCyclesRejectAndAcceptExactCompositeLoop.
7 CompositeLoop declarations must exact-match the immediate SCC. Graph.PartialCompositeLoopDeclarationIsRejected; Graph.OverlappingImmediateCyclesCollapseIntoOneCompositeLoopRegion; Graph.ComponentCannotHaveMultipleCompositeLoopOwners.
8 CompositeLoop external outputs commit only after loop success or an explicit partial-success policy. Runtime.CompositeLoopRegionOwnsInternalFixedPointIterations; Runtime.CompositeLoopConvergenceStopsBeforeMaxIterations; Runtime.CompositeLoopSolverIterationDiscardsPartialOutputsByDefault; Runtime.CompositeLoopSolverIterationCanCommitPartialOutputsWhenPolicyAllows; Runtime.CompositeLoopSolverIterationCanFailOnPartialSuccessPolicy; Runtime.CompositeLoopBudgetOverrunStopsLoopAndReportsMetric.
9 Latest overwrite does not create an unbounded backlog. tests/test_channel.cpp: Channel.LatestChannelDeliversOnlyNewestPayload; app smoke app_overload_latest_vs_queue_runs.
10 Queue capacity handles full channels by overflow policy; previous-tick values notify waiters exactly once when they become visible at epoch advance. Channel.QueueDropsOldestWhenFull; Channel.QueueDropNewestRejectsIncomingPayloadWhenFull; Channel.QueueBlockReturnsWouldBlockWithoutDroppingExistingPayload; Channel.QueueFailFastReturnsCapacityError; Channel.PreviousTickNotifiesWaitersExactlyOnceWhenPendingValueBecomesVisible.
11 move_only + multi-reader is invalid. Graph.MoveOnlyPolicyRequiresSingleReader.
12 Multiple state writers are invalid unless a future merge policy exists. Graph.StateEdgesRejectMultipleWritersToSameTarget.
13 batch, time_sync, and all_inputs trigger consumption order is deterministic. Runtime.AllInputsWaitsForEveryRequiredPort; Runtime.TimeSyncWaitsForInputsAndUsesTimeSyncTriggerKind; Runtime.TimeSyncDropsOldestOutOfSlopSampleUntilInputsAlign; Runtime.BatchTriggerPreservesPartialBatchUntilThreshold; Runtime.BatchTriggerFlushesPartialBatchAfterWindowExpires.
13a Trigger v2 preview policies are declarative, keep suppressed pending queues bounded, and explain suppression/drop reasons without arbitrary code execution. Runtime.WatermarkTriggerDropsLateSamplesAndReportsMetrics; Runtime.ConditionTriggerWaitsForDeclarativeReadinessWithoutScripting; Runtime.ConditionTimestampTriggerDropsMissingTimestampHeadItem; Runtime.DebounceTriggerCoalescesPendingEventsWithoutCoalesceFlag; Runtime.RateLimitTriggerSuppressesRepeatedReadyChecksWithReasonMetric; Runtime.RateLimitTriggerBoundsSuppressedPendingMessages; Graph.TriggerV2PoliciesValidateDeclarativeFields.
14 Stop token is observed between scheduler iterations. Runtime.StopTokenStopsBeforeExecutingComponentsAndCleansUp.
15 Worker lanes do not break compiled region boundaries. Runtime.ThreadPoolLaneExecutesReentrantInvocationsConcurrently; Runtime.ThreadPoolLaneSerializesNonReentrantInvocations; graph region-order tests in tests/test_graph.cpp.
16 Non-reentrant components do not overlap. Runtime.ThreadPoolLaneSerializesNonReentrantInvocations.
17 Reentrant components can overlap but do not exceed lane max_threads. Runtime.ThreadPoolLaneExecutesReentrantInvocationsConcurrently.
18 Metrics match actual behavior. Runtime.ImmediateFeedForwardIsVisibleInSameEpochAndMetricsMatch; async max-inflight tests; cli_golden_outputs metrics golden.
19 Trace events are emitted with legal durations and stable semantic fields. Runtime.RunModeExecutesEventRuntimeAndRoutesChannels; cli_golden_outputs trace golden and Chrome trace smoke.
20 Schema unknown fields reject. Graph.RejectsUnknownRootFields; cli_reject_invalid_unknown_field; schema_v1_contract_smoke.
21 Component config transactions validate before apply, commit at epoch boundaries, and roll back to the old committed snapshot on invalid or failed apply. tests/test_state.cpp: ConfigSnapshotStore.ComponentConfigUpdatesRespectEpochBoundary, ConfigSnapshotStore.PendingConfigUpdatesCanRollbackWithoutChangingActiveSnapshot; tests/test_runtime.cpp: Runtime.ComponentConfigUpdatesApplyOnEpochBoundary, Runtime.InvalidComponentConfigTransactionIsRejectedBeforeApply, Runtime.ComponentConfigApplyFailureRollsBackAppliedComponents; app smoke app_robot_cell_pilot_runs.
22 Runtime observer failures and bounded observer drops are observable and non-fatal to runtime semantics. Runtime.ObserverFailureIsRecordedButDoesNotChangeRuntimeSemantics; Runtime.InMemoryObserverDropsBoundedRecordsAndReportsDrops; AdapterSdk.ObserverFailureIsNonFatalRuntimeEvidence.
23 Runtime metric samples obey the descriptor schema and avoid default high-cardinality labels. Metrics.RuntimeMetricDescriptorRegistryIsStableAndUnique; Metrics.RuntimeMetricSchemaRejectsHighCardinalityDefaultTags; Metrics.ExportedRuntimeMetricsMatchDescriptorSchema; cli_golden_outputs metrics JSON.
24 Defensive graph input limits reject malformed, oversized, invalid-UTF-8, and over-nested inputs before runtime execution. GraphInputLimits.RejectsOverlongNonConfigStrings; GraphInputLimits.RejectsDeepConfigSnapshots; cli_validate_input_limit_override_fails_safely; fuzz_graph_input_smoke; tests/cli/check_parser_limits.py; tests/fuzz/fuzz_graph_inputs.py.
25 Core/runtime/YAML/CLI/adapter boundaries do not leak private or deferred dependencies into stable embedding surfaces. policy_no_core_adapter_deps; policy_architecture_self_test; tests/policy/check_no_adapter_deps.py; package/runtime-only CMake smokes; cmake_otel_adapter_options_smoke; cmake_prometheus_adapter_options_smoke; cmake_ros2_adapter_options_smoke.
26 Release preparation is reproducible and non-publishing unless a human performs the tag/push step. release_prepare_smoke; tests/release/check_release_prepare.py; scripts/release_prepare.sh --skip-gates artifact rehearsal evidence.
27 The real-world pilot composes current runtime semantics without adapter dependencies or hardware claims. app_robot_cell_pilot_runs; docs/11-user-guide/case-study-robot-cell.md; examples/apps/robot_cell_pilot/README.md.
28 Hierarchical subgraph organization expands before validation and cannot hide cycles or metric paths. Graph.SubgraphExpandsToNamespacedComponentsEdgesAndPlanHierarchy; Graph.SubgraphExpansionDoesNotHideImmediateCycles; Graph.SubgraphCompositeLoopOwnsExpandedCycle; Runtime.HierarchicalGraphMetricsPreserveExpandedComponentPath.
29 Graph templates expand deterministically through strict parameter substitution and leave runtime unaware of templates. Graph.TemplateInstanceExpandsDeterministicallyAndValidates; Graph.TemplateInstanceRejectsMissingOrUnknownParameter; Graph.TemplateInstanceRejectsUnknownPlaceholder; cli_validate_template_source_transform_sink; cli_run_template_source_transform_sink.
30 Adapter exporter previews consume observer/result records without affecting runtime semantics or metric cardinality. OtelAdapter.MapsMetricDescriptorsToPreviewMetricRecords; OtelAdapter.ObservesRuntimeRunnerWithoutChangingSemantics; PrometheusAdapter.MapsCountersAndGaugesWithBoundedLabels; PrometheusAdapter.ObservesRuntimeRunnerWithoutChangingSemantics; adapter option smokes.
31 Adapter boundary previews map external transport concepts at graph boundaries without adding transport fields to schema v1. Ros2Adapter.ValidatesBoundaryMappingAndKeepsQosExternal; Ros2Adapter.InjectsSubscriptionMessageThroughFakeBoundaryBridge; Ros2Adapter.PublishesBoundaryOutputThroughFakePublisherBridge; cmake_ros2_adapter_options_smoke.
32 FFI preview uses opaque handles and explicit ownership without freezing ABI or importing language runtimes into core. CApiPreview.RunsNoopGraphAndIteratesMetrics; CApiPreview.ReportsBuilderErrorsWithoutExceptions; cmake_c_api_options_smoke; policy_no_core_adapter_deps.
33 Python automation preview stays CLI-backed, default-off, and outside core/runtime native bindings. python_preview_smoke; cmake_python_preview_options_smoke; policy_no_core_adapter_deps.
34 Dynamic plugin loading is optional, explicit, trusted-native only, and does not become a runtime/core dependency. test_plugin_loader; cmake_plugin_loader_options_smoke; policy_no_core_adapter_deps; policy_architecture_self_test.
35 Schema v2 remains a design boundary until a reviewed v2 loader exists; schema v1 stays strict and rejects schema_version: 2. schema_v1_contract_smoke; docs_command_smoke; docs/33-specs-rfcs/schema-v2-notes.md.
36 Editor/schema UX uses installed schema discovery and diagnostic JSON without adding a runtime editor/LSP dependency. editor_schema_ux_smoke; cmake_package_runtime_smoke; docs_command_smoke; docs/41-development-tools/editor-schema.md.
37 Community contribution surfaces keep unsafe semantic/API/schema/adapter changes behind explicit proposal, review, and validation lanes. community_readiness_smoke; docs/44-coding-standards/contributing.md; .github/PULL_REQUEST_TEMPLATE.md; .github/ISSUE_TEMPLATE/*.
38 Live observe is an output-only validation surface: disabled by default, bounded and non-blocking when enabled, lossy on observer overflow, and unable to change runtime semantics or existing metrics/trace/health contracts. LiveObserve.DisabledSessionProducesNoEvents; Runtime.LiveObserveDisabledByDefaultProducesNoEvents; Runtime.LiveObserveEnabledEmitsLifecycleAndRuntimeEventsWithoutChangingSemantics; Runtime.LiveObserveOverflowReportsDropSummaryWithoutChangingRuntimeResult; cli_observe_ndjson_minimal; live_assertions_smoke; live_record_artifact_smoke; live_replay_smoke; live_dashboard_smoke; ./scripts/goal_check.sh live; ./scripts/goal_check.sh live-perf.

Maintenance rule

If a runtime change modifies any invariant above, update the named tests or add a new focused test in the same commit. ./scripts/agent_check.sh is the gate that keeps this mapping executable.