Running and Controlling
Verifying a run: what the checker proves and what it cannot
A twin that builds and runs has proven nothing about connectivity. The fabric server exits 0 on a run where every consumer read zero for 100 steps (that happened here, first Wildfire run, 147 flat links). The checker exists so that "it ran" and "what the producer sent arrived where the interface definition says it should" are two different statements.
What a glued component writes
Every glued component appends one row per simulation step to COMPONENT_trace.csv:
step, time_ns, one column per signal the component carries, and for each consumed
signal a SIGNAL_changes column counting how often the received value changed. Producers
write the value they sent; consumers write the value they last received. Files are opened
and closed per row, so they are complete even if the run is killed.
The three checks
Run from the innexis-vsi folder:
python twin_glue\check_traces.py TWIN_DIR --traces TRACE_DIR
TWIN_DIR must hold the glue_wiring.json that the glue wrote for that build. For a kept
run, point both arguments at the runs\... folder.
- Link check, one line per consumed signal. At every step the consumer's value must equal
the producer's value at some step in the window from
step minus lagtostep(default lag 3, modulo 256), and the consumer must have changed at leaststeps divided by the producer's period, minus lagtimes. Lag 0 is a real delivery order: the fabric delivers within a step to any component scheduled after the producer, so the window includes the current step. Output:okorFAILwith the number of steps off and the change count. - Producer-rate check. Each producer column must change exactly
(steps minus 1) divided by periodtimes over the run. That is what proves the declared per-bus period landed in the build; the link check alone would pass a producer at the wrong rate because consumers follow it anyway. Output:rate_okandrate_badcounts and aRATEline per offender. - Presence. A consumer without a trace file or column is
MISSING, never a pass. Components with nothing consumed (the Ethernet-only ones) are counted asnothing, so a twin cannot pass by having no consumers.
The RESULT line is PASS only with zero FAIL, zero MISSING and zero rate_bad. Exit code 1
otherwise, so it can gate a script.
Prove the checker before trusting it
python twin_glue\check_traces.py TWIN_DIR --selftest
Four parts, all must report as follows: the C++ produce() formula and the checker's Python
copy agree over 12,000 values across five periods; a run fabricated from the wiring at the
declared periods passes (177 links, 18 producers on Wildfire); one consumer column frozen at
zero is detected; one producer forced to period 1 against a declared 12 is detected as a
rate failure. A checker that has not been shown to fail on bad input is not a checker.
Reading the verdict on a real twin
The Wildfire run of 2026-09-08 20:41 (runs\20260908-2042-wildfire-perbus-177pass):
RESULT: {'pass': 177, 'fail': 0, 'missing': 0, 'nothing': 25, 'rate_ok': 18, 'rate_bad': 0}
177 consumed signals verified; 25 Ethernet-only components with nothing to check; 18
producers each at its declared rate. The mixed C++ and Python twin and the SysML-driven
twin read the same way with their own counts (runs\README.md lists them).
What a failure pattern usually means (EXERCISED)
| pattern | cause seen here |
|---|---|
| all consumers of one CAN frame flat at 0, producer fine | consumers were transmitting the frame too, with zero payload; mute them (glue does this) |
| a producer's consumers all flat, other links fine | that producer's sends were skipped; check its "Before sending" region and the generated send calls |
| 1 to 3 links off by 97 steps but with 99 changes | correct values at lag 0 and a checker window that excluded lag 0 (fixed) |
| every trace missing | the run never started; check the fabric log for Waiting for client connections and the fixed-port and firewall notes in getting-started |
| Python component traces missing while C++ ones exist | the Python client's working directory is the twin root; the glue's trace writer redirects into vsi.sim\_logs when it can see it |
What the checker cannot tell you
It verifies that the stimulus reached the right consumers at a bounded lag and rate. It does
not verify behaviour, timing against a real system, or anything on an Ethernet socket,
because no signal-level data crosses those sockets in twins built from Teamcenter. The MSP-2
twins carry a scripted scenario instead (chassis state machine, watchdog, time lock) and are
judged by reading their traces against that scenario; see msp2_glue\README.md.
Source: innexis-vsi/twin_glue/check_traces.py and README.md; runs/20260908-2042-wildfire-perbus-177pass (EXERCISED 2026-09-08) · retrieved Tue Sep 08 2026 00:00:00 GMT+0000 (Coordinated Universal Time)