6b56ba17

By: Lucien Huber <im@lcnbr.ch>

order inferred numerator interface ports canonically

NumeratorInterface::admit took the port order of a tensor without
declared metadata from SymbolicTensor::infer. That order follows
Symbolica's term order, which depends on symbol registration, and the
aggregate fragment product concatenated it. Export emits num_interface
whenever re-admission disagrees, so whether a diagram's JSON and DOT
carried num_interface, and in which order, changed between processes.
Validation also rejected an aggregate whose ports were a permutation of
the fragment product's, so such artifacts failed to import in another
process.

Admission now orders explicit ports by their source notation, and the
fragment product uses the same order. Label transport keeps a canonical
order, declared or inferred, canonical for the new labels; any other
order, which only a declaration produces, moves positionally. Tensors
with open ports keep their order. A per-thread cache keeps the
source-notation keys cheap. Validation accepts the exact zero that
subtraction leaves for permuted ports, so artifacts that declare another
port order still import.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>