# Portable collector evidence handoff

Review an OPC UA export before deciding whether its measurements and commands can
be aligned for an offline model review. Keep the data on your own machine.
This standard-library tool opens no network connection. It uses the reviewed
collector and alignment cores without modifying them.

## Review your export

Keep the exact original profile, CSV and collector JSON from the pinned collector.
Write an explicit mapping using an example as a guide, then run from this kit's root:

```sh
python -S -m forge_lab.collection_handoff --profile profile.json --capture capture.csv --collection collection.json --mapping mapping.json --output-dir review
python -S -m forge_lab.collection_handoff --verify review
```

Open `review/handoff.html`. The bundle retains all four original files, the full
collection metadata, the alignment review and every aligned record. Creation
exit 2 means review is needed; exit 1 refuses inconsistent inputs. Verification
exit 0 means every file regenerated exactly using this trusted release.
It does not qualify a model, a physical source or a control action.

## What the checks establish

- The complete original audit reproduces, including every row and finding.
- Original CSV bytes match the collector report's hash.
- Every metadata record binds to its CSV row in collector encounter order.
- Integer wire DateTime fields reproduce the exact CSV timestamp text.
- Raw and effective picosecond fields, absent fields and complete unit declarations remain visible.
- A missing channel stays missing. State measurements do not become held commands.
- Verification regenerates the complete bundle, including the rendered HTML. Updating a tampered file's manifest hash cannot validate its conclusion.

The retained connection declaration is not independent authentication. Collector
indexes are not device sequence numbers. Unit properties were read separately
from values. Clock uncertainty, source sample time and held-command semantics
must be entered explicitly; a successful encrypted read does not establish them.
The collected-data route never unlocks the existing synthetic numerical model.

OPC UA DateTime uses 100-ns ticks. Picosecond fields carry additional offsets in
10-ps intervals; the decoder caps values of 10000 or greater to 9999. The frozen
collector retains those fields without adding them to CSV timestamps. Nonzero
offsets therefore remain a visible limitation of this CSV grid review. See
[Part 6 DataValue](https://reference.opcfoundation.org/specs/OPC-10000-6/5.2.2.17)
and [DateTime](https://reference.opcfoundation.org/specs/OPC-10000-6/5.2.2.5).

## Included controlled exports

Eight example inputs are actual collector exports with invented loopback values.
Seven fresh three-channel cases cover nominal data, uncertain pressure, a wrong
unit label, a missing unit property, repeated source time, finer timestamp fields,
and recent server confirmation without established sample time. Their independent
fixture logs bind CSV values, status and source times, and record 15 value reads
requesting both timestamps with zero writes or calls per case. The earlier
two-channel precision export retains absent pump B, measured speed, plateaued
source time and unknown clock assumptions.

These are captured test-server signals. No process dynamics, sensor calibration,
independent physical clock or plant adoption is demonstrated. The nominal case
passes mechanical checks under entered declarations; its model admission is false.

Run all frozen exports without installed packages:

```sh
python -S run-examples.py --output-dir replay
```

For new invented encrypted captures, `collector-handoff/run-controlled-captures.py`
requires asyncua 2.0.1 and node-opcua 2.186.13. It binds loopback only, provisions a
read role, executes the unchanged collector from the included original audit ZIP,
and compares the cases with `capture-contract-v1.json`. Its output includes private
keys and logs: publish only the reviewed `exports/`, never the private fixture
directory. Cross-host comparisons distinguish frozen-input byte replay from fresh
capture invariants because acquisition times, ports, UUIDs and certificates differ.

## Input limits and trust

Profile and mapping: 256000 bytes each. CSV and original collection report: 16 MiB
each. The pinned collector supports up to 1000 groups and 64 tags, while the
alignment review supports at most 5001 encountered groups. JSON duplicate keys,
nonfinite values, booleans in integer fields, unsupported schemas and unbound
metadata are refused. Regular input files and exact bundle contents are required.
The HTML previews 250 rows; complete JSON files retain every row and integer.
Use a parser that retains signed 64-bit integers rather than JavaScript numbers.

Hashes establish byte identity relative to a trusted release. Someone who replaces
the executable can replace its conclusions. This artifact grants no control
permission; actual site integration and adoption remain unverified.
