VSIKnowledge

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.

  1. 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 lag to step (default lag 3, modulo 256), and the consumer must have changed at least steps divided by the producer's period, minus lag times. 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: ok or FAIL with the number of steps off and the change count.
  2. Producer-rate check. Each producer column must change exactly (steps minus 1) divided by period times 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_ok and rate_bad counts and a RATE line per offender.
  3. Presence. A consumer without a trace file or column is MISSING, never a pass. Components with nothing consumed (the Ethernet-only ones) are counted as nothing, 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)