Skip to content

wot-specs: revise WoT Binding and add registry-first Connectivity 1.1 - #17

Merged
marcschier merged 13 commits into
mainfrom
wot-binding-xregistry
Jul 27, 2026
Merged

wot-specs: revise WoT Binding and add registry-first Connectivity 1.1#17
marcschier merged 13 commits into
mainfrom
wot-binding-xregistry

Conversation

@marcschier

@marcschier marcschier commented Jul 21, 2026

Copy link
Copy Markdown
Owner

What this PR changes or proposes

Adds a dedicated top-level wot-specs/ area with two complete, standalone specification drafts:

  • OPC UA — WoT Binding supersedes OPC 10101 v1.00, retains its uav protocol/security vocabulary, adds collision-safe model/platform terms, defines event mapping, and specifies bidirectional NodeSet2 ↔ WoT conversion. The semantic/readable mapping is primary; the complete uav:nodes projection is added only for source facts not yet expressible by the vocabulary, and uav:nodeSet is reserved for explicit byte archival or a demonstrated final fallback.
  • OPC UA — WoT Connectivity 1.1 additively revises OPC 10100-1 in the existing http://opcfoundation.org/UA/WoT-Con/ namespace. It incorporates the complete published 1.02 model with every numeric NodeId and signature retained, marks the superseded management/upload surface as deprecated, and adds an xRegistry-backed TD/TM registry under Server. Thing Models materialize as types, Thing Descriptions as instances, and forms compile into injectable binder plans with dependency-closure Refresh, validation/load/binding events, model/semantic-change behavior, registry-scoped federation and selectable graceful/immediate retirement.

The existing OPC 10100-1 v1.02 namespace, NodeIds, methods and workflows remain directly present and callable in the combined 1.1 model.

The PR also adds:

  • JSON-LD context and extension/conversion schema;
  • worked TD/TM, type/reference, native projection and archival examples;
  • generated combined WoT-Con 1.1 NodeSet2/NodeIds/Annex (283 XML nodes, all 172 legacy CSV rows preserved, plus additive 64000+ registry nodes);
  • deterministic generators and standard-library validators;
  • root README navigation for the new wot-specs/ structure.

The review follow-ups also:

  • correct all standard InputArguments, OutputArguments, and EnumStrings BrowseNames to namespace 0 and fix the canonical placeholder ModellingRule NodeIds;
  • add uav:eventType, portable nsu= ExpandedNodeIds, and exact HasComponent subtype preservation;
  • make native uav:nodes conversion the default and require completeness tests to forbid the envelope;
  • define digest-protected RFC 6901 residue entries for unmapped JSON-LD members, including stable link selectors;
  • clarify that observable / observeproperty advertises binding support rather than defining OPC UA Variable monitorability.
  • add NamespaceUri-qualified compact model names for ReferenceTypes and types while keeping ExpandedNodeIds definitive for instances and runtime type mapping; typed References now use the ReferenceType model name directly in rel with uav:refId as identifier. The non-published uav:typedReference draft term was removed.
  • rename the ReferenceType identifier fallback to uav:refId; prefer @context-qualified BrowseNames/paths while retaining OPC 10000-6 URI-qualified QualifiedNames as an alternative; clarify that mapToNodeId is instance mapping while mapToType is definitive DataType mapping accompanied by mapToTypeName; retain and explain WoT actionGroups.
  • remove the Connectivity What/Where/Why/How labels; restrict document resolution to the local registry or configured xRegistry federation; make TD endpoint/security metadata client- or binder-informative rather than registry trust policy; require SignAndEncrypt for registry mutations while permitting deployment-selected insecure reads; and allow either graceful retirement or immediate BadNodeIdUnknown invalidation.

Why

OPC 10101 currently describes an OPC UA endpoint in WoT but does not provide an exact, generic two-way NodeSet representation or the model vocabulary needed to retain type composition, references, modelling rules and external semantics.

OPC 10100-1 v1.02 stores uploaded TDs behind a fixed flat asset-management surface. WoT Connectivity 1.1 retains that API for compatibility while adding a preferred registry model that can represent authored Thing Models, generated type definitions, arbitrary TD hierarchy/references, versioned documents and dynamic protocol code-behind.

The registry-first design makes TD/TM documents the versioned source of truth and the AddressSpace a derived projection, while preserving every current 1.02 scenario in the same namespace and model.

Type

  • Feedback / annotation only (no spec authored — maintainers will draft the change)
  • Concrete spec / prose change
  • Model change (NodeSet / CSV / generated artifacts, via the tooling)
  • Tooling / examples
  • Docs

Validation

  • WoT Binding validator: 7 JSON artifacts, 57 documented uav terms, model-name, native-profile and archival digest/XML checks — OK
  • WoT Connectivity validator: 283 XML nodes / 307 CSV rows / all published 1.02 IDs and classes / xRegistry references / deprecation markers / embedded Annex — 0 errors, 0 warnings
  • Internal links: OK
  • JSON/YAML parsing: OK
  • all WoT specification Mermaid diagrams: compiled
  • Markdown lint scoped to wot-specs/: 0 errors
  • Self-contained repository extension validation: OK
  • git diff --check: clean

Stack proof

The dependent draft implementation is available at OPCFoundation/UA-.NETStandard#4093. It depends on OPCFoundation/UA-.NETStandard#4094 (the upstream-owned successor to #4015) and proves conversion, source generation, selectable live retirement, registry materialization, legacy compatibility and protocol binders.

Checklist

  • I edited the source (spec document, descriptor, or generator) — not generated NodeSets / CSV / Annex tables by hand
  • For a generated-spec change, I regenerated and ran validation (python core-specs/extras/validate_all.py and/or the extension's validate_local.py)
  • I opened this from a topic branch and am ready to discuss

- WoT Connectivity generator: mark InputArguments, OutputArguments, and
  EnumStrings as namespace-0 BrowseNames using the existing _ns0bn
  mechanism, covering both type declarations and well-known instance
  methods. Regenerated NodeSet2.xml accordingly (no NodeId churn).
- Strengthen wot-specs/WoT-Connectivity/tools/validate_local.py to
  reject well-known Properties (InputArguments/OutputArguments/
  EnumStrings) that carry a namespace-2 BrowseName instead of ns=0.
- Correct the WoT Binding spec's normative modelling-rule NodeIds:
  MandatoryPlaceholder i=11510, OptionalPlaceholder i=11508 (previously
  swapped/incorrect). Add a validator assertion in
  wot-specs/WoT-Binding/tools/validate_local.py to prevent regression.
Comment thread wot-specs/WoT-Binding/OPC-UA-WoT-Binding.md Outdated
Comment thread wot-specs/WoT-Binding/OPC-UA-WoT-Binding.md Outdated
Comment thread wot-specs/WoT-Binding/OPC-UA-WoT-Binding.md Outdated
Comment thread wot-specs/WoT-Binding/OPC-UA-WoT-Binding.md Outdated
Comment thread wot-specs/WoT-Binding/OPC-UA-WoT-Binding.md
Comment thread wot-specs/WoT-Connectivity/OPC-UA-WoT-Connectivity.md Outdated
Comment thread wot-specs/WoT-Connectivity/OPC-UA-WoT-Connectivity.md Outdated
Comment thread wot-specs/WoT-Connectivity/OPC-UA-WoT-Connectivity.md Outdated
Comment thread wot-specs/WoT-Connectivity/OPC-UA-WoT-Connectivity.md Outdated
Comment thread wot-specs/WoT-Connectivity/OPC-UA-WoT-Connectivity.md Outdated
marcschier and others added 2 commits July 22, 2026 10:59
…1.02) + WoT Binding revisions

Resolves all 14 unresolved review threads on PR #17.

WoT Binding (OPC-UA-WoT-Binding.md):
- Remove the ADR-informed paragraph; add "1.1 Differences from OPC 10101 v1.00"
  (preserved terms, event mapping, model/platform vocabulary, exact NodeSet
  roundtrip/preservation, implementer guidance). [thread 1]
- Address-space example: add a left-to-right figure (WoT sample -> OPC UA
  nodes/references) with explanation. [thread 2]
- Move the ADR->uav crosswalk out of the spec into
  wot-specs/extras/WoT-Binding/adr-to-uav-crosswalk.md; link only from
  extras/README and the WoT-Binding README. [thread 3]
- Expand every S6 vocabulary subsection: concept, when/why it is an OPC UA
  model fact, normative usage, a short JSON example, and its explanation. [thread 4]
- Add "Annex D — Implementer walkthrough": TM->types, TD->instances, and the
  reverse AddressSpace/NodeSet->TM/TD, using concise snippets. [thread 5]
- Allow rel: uav:componentOf as a parent link (S6.2 + validation table +
  direction rule); demonstrate it in examples/01. [thread 10, Binding side]

WoT Connectivity (OPC-UA-WoT-Connectivity.md):
- Use the companion-spec header (title, Release, Namespace, publication date,
  WG-draft status, hr, numbered clauses); state intended submission to the OPC
  Foundation WoT WG. [thread 6]
- Stop using "V2": additive revision 1.1 in the existing namespace
  http://opcfoundation.org/UA/WoT-Con/; incorporate the full OPC 10100-1 v1.02
  model into one combined NodeSet preserving every published NodeId (1..172),
  type, method signature and the well-known WoTAssetConnectionManagement;
  add registry nodes in 64000+; mark the legacy surface Deprecated (OPC 11030);
  rename artifacts to Opc.Ua.WoTCon.*; drop separate-namespace/dual-profile
  claims. [thread 7]
- Replace remaining V2 architecture prose with contextual language. [thread 8]
- Expand S6 concepts into what/where/why/how subsections, each type linked to
  its Annex anchor, with short examples. [thread 9]
- No-flat-root: remove the "A server MAY ..." convenience-folder paragraph;
  define parent selection via WoT links (rel: uav:componentOf), the link
  direction and how the materializer resolves the parent and creates the
  HasComponent Reference. [thread 10]
- Add the explicit link to the WoT Binding spec in S7.2 projection mapping. [thread 11]
- Expand S7.4-7.8 into implementer-ready normative shall/should/may prose
  (dependency graph + errors, closure atomicity, invalid desired versions,
  shadow prepare/switch/drain/retire state diagram, refresh/idempotence,
  version switch/unload/delete/federation) with examples. [thread 12]
- Expand S9 Refresh (purpose/use cases, caller workflow, validate/plan/apply
  algorithm, concurrency/generation, outcomes/errors, implementer
  responsibilities) with a Mermaid sequence diagram. [thread 13]
- Replace S12's link-only example list with shown, discussed snippets from the
  TM, TD, invalid TD and refresh-results files. [thread 14]

Model / generator:
- Pin the OPC 10100-1 v1.02 sources under legacy/ (WotConnection.xml/.csv) as a
  parsed source input (not hand-copied); build_model.py deterministically emits
  one combined NodeSet: ns order Core 0, xRegistry 1, own 2; legacy nodes remap
  ns=1 -> ns=2 with numeric ids unchanged; new nodes stay 64000+ (no churn).
- NamespaceMetadata carries the 1.1 version at stable NodeIds; deprecation is
  machine-readable via ReleaseStatus="Deprecated".
- validate_local.py proves legacy id/class preservation vs the pinned CSV, no
  duplicate ids, single namespace at model version 1.1.0, xRegistry references,
  deprecation markers, callable well-known WoTAssetConnectionManagement, and
  Annex A embedding, plus all previous structural checks.

Validation: xRegistry + both WoT validators 0 errors/0 warnings; internal links
OK; JSON parses; 5 Mermaid diagrams compile; markdownlint scoped to wot-specs
0 errors; git diff --check clean.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Comment thread wot-specs/WoT-Binding/OPC-UA-WoT-Binding.md
Comment thread wot-specs/WoT-Binding/OPC-UA-WoT-Binding.md Outdated
Comment thread wot-specs/WoT-Binding/OPC-UA-WoT-Binding.md Outdated
@marcschier marcschier changed the title wot-specs: revise WoT Binding and add registry-first Connectivity V2 wot-specs: revise WoT Binding and add registry-first Connectivity 1.1 Jul 22, 2026
…deId identity, HasComponent subtypes

WoT Binding revisions responding to three review threads on OPC-UA-WoT-Binding.md:

- uav:eventType (thread PRRT_kwDOTKTzys6S4F6O): add an explicit @type
  annotation for WoT event affordances / Thing Models that project OPC UA
  EventTypes (BaseEventType subtypes). Define its domain, the mapping, its
  relation to the uav:isEvent flag, and reverse conversion. Update the JSON-LD
  context, JSON Schema (eventType/@type vs uav:isEvent consistency), pump event
  examples (Binding + Connectivity), Section 5.2/6.1/8/9.1/1.1 tables and the
  Annex D walkthrough, and validator term coverage.

- Portable identity (thread PRRT_kwDOTKTzys6S4IHC): make ExpandedNodeId
  normative. uav:id, uav:hasComponent, uav:componentOf, uav:mapToNodeId,
  uav:mapToType and any NodeId-valued uav:refType shall use the OPC 10000-6
  nsu=<NamespaceUri>;... form (or namespace-0 canonical i=...), never the
  session-local ns=<index> form, so documents survive namespace-table
  reordering. Add Section 5.1.1, update URI/base/href rules (preserving
  percent-encoding), fix example hrefs, tighten the schema, and add validator
  checks that reject ns= in portable fields and validate ExpandedNodeId syntax.
  Wording explicitly excludes the qualified BrowseName form and the NodeSet2
  preservation envelope so it does not contradict the exact roundtrip.

- Component subtypes (thread PRRT_kwDOTKTzys6S4JsF): clarify that
  uav:hasComponent/uav:componentOf cover HasComponent and all subtypes for
  parent-child discovery, and that exact subtype semantics (e.g.
  HasOrderedComponent) are pinned by a uav:typedReference link (refType =
  ReferenceType ExpandedNodeId, plus uav:refName); reverse conversion recreates
  the subtype, otherwise plain HasComponent is used. Add a HasOrderedComponent
  example (i=49) and cover it in the walkthrough.

Validated: WoT Binding + WoT Connectivity local validators, internal links,
JSON/YAML well-formedness, scoped markdownlint, and git diff --check all clean.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Comment thread wot-specs/WoT-Binding/OPC-UA-WoT-Binding.md Outdated
Comment thread wot-specs/WoT-Binding/OPC-UA-WoT-Binding.md Outdated
Comment thread wot-specs/WoT-Binding/OPC-UA-WoT-Binding.md Outdated
Comment thread wot-specs/WoT-Binding/OPC-UA-WoT-Binding.md Outdated
Comment thread wot-specs/WoT-Binding/OPC-UA-WoT-Binding.md Outdated
Comment thread wot-specs/WoT-Binding/OPC-UA-WoT-Binding.md Outdated
Comment thread wot-specs/WoT-Binding/OPC-UA-WoT-Binding.md Outdated
Comment thread wot-specs/WoT-Binding/OPC-UA-WoT-Binding.md Outdated
Comment thread wot-specs/WoT-Binding/OPC-UA-WoT-Binding.md Outdated
Comment thread wot-specs/WoT-Binding/OPC-UA-WoT-Binding.md Outdated
Comment thread wot-specs/WoT-Binding/OPC-UA-WoT-Binding.md Outdated
Comment thread wot-specs/WoT-Binding/OPC-UA-WoT-Binding.md Outdated
Comment thread wot-specs/WoT-Binding/OPC-UA-WoT-Binding.md Outdated
Comment thread wot-specs/WoT-Binding/OPC-UA-WoT-Binding.md Outdated
Comment thread wot-specs/WoT-Binding/OPC-UA-WoT-Binding.md
Comment thread wot-specs/WoT-Binding/OPC-UA-WoT-Binding.md
Comment thread wot-specs/WoT-Binding/OPC-UA-WoT-Binding.md Outdated
Comment thread wot-specs/WoT-Binding/examples/01-opcua-td-pump.jsonld Outdated
Comment thread wot-specs/WoT-Binding/OPC-UA-WoT-Binding.md Outdated
Comment thread wot-specs/WoT-Binding/OPC-UA-WoT-Binding.md Outdated
Comment thread wot-specs/WoT-Binding/OPC-UA-WoT-Binding.md Outdated
Comment thread wot-specs/WoT-Binding/OPC-UA-WoT-Binding.md Outdated
Comment thread wot-specs/WoT-Binding/OPC-UA-WoT-Binding.md
Comment thread wot-specs/WoT-Binding/OPC-UA-WoT-Binding.md
Comment thread wot-specs/WoT-Binding/OPC-UA-WoT-Binding.md Outdated
Comment thread wot-specs/WoT-Binding/tools/validate_local.py
Comment thread wot-specs/WoT-Binding/OPC-UA-WoT-Binding.md Outdated
Comment thread wot-specs/WoT-Connectivity/OPC-UA-WoT-Connectivity.md Outdated
Comment thread wot-specs/WoT-Connectivity/OPC-UA-WoT-Connectivity.md Outdated
Comment thread wot-specs/WoT-Connectivity/OPC-UA-WoT-Connectivity.md Outdated
Comment thread wot-specs/WoT-Connectivity/OPC-UA-WoT-Connectivity.md Outdated
@marcschier
marcschier requested a review from koepalex July 25, 2026 10:38
@marcschier
marcschier merged commit bbb1c46 into main Jul 27, 2026
6 checks passed
@marcschier
marcschier deleted the wot-binding-xregistry branch July 27, 2026 06:16
marcschier added a commit that referenced this pull request Jul 27, 2026
…atrix validation, per-DataSet SchemaId (#20)

* Avro spec: encoder derives schema from type model; clarify publish/version lifecycle

Correct the encoder/decoder/schema roles and the schema-change publish
protocol in the Avro DataEncoding, its Part 14 mapping, and the Schema
Registry PubSub profile:

- Encoding PRODUCES a schema from the OPC UA type model; the encoder is
  never handed one. The schema's CRC-64-AVRO fingerprint is the SchemaId.
  The decoder needs the schema (registry/announcement or AddressSpace
  re-derivation). Fixes 5.1, 6 intro, 6.1, 7, and the ExtensionObject
  known-struct wording (5.9) so branch order is derived from the type
  model's subtype hierarchy, not consulted from an external registry.
- S1: on a schema change the publisher shall PUBLISH to subscribers by
  BOTH registering the new schema in the Schema Registry AND announcing it
  (6.4 step 4, 8.4.5 encoder change tracking, SReg Annex C.2).
- S2: a publisher shall advance ConfigurationVersion when the produced
  schema changes (MinorVersion append / MajorVersion reset); decoders stay
  SchemaId-authoritative and still decode if a publisher misbehaves (8.4.8).

Applies to standalone OPC-UA-Avro-Encoding.md and the errata Part 6/Part 14
plus the Schema Registry. Arrow parallel pass tracked separately.

* Reflect implementation learnings into Avro/Arrow specs

Capture two normative rules discovered while implementing, so another
implementer makes the right decisions:

- Matrix dimension validation (finding #17): a matrix has at least two
  dimensions and the product of dimensions equals the element count; a
  decoder shall reject a violating matrix with Bad_DecodingError. Removes
  the contradictory 'empty dimensions vector' claim in Avro 5.5 (the
  implementation requires >=2 dimensions). Applied to Avro Part 6 5.5 and
  Arrow Part 6 matrix, standalone + errata.
- Per-DataSet SchemaId (finding #20): the SchemaId identifies a single
  DataSet's schema; a NetworkMessage-level SchemaId is valid only when all
  its DataSetMessages share one schema, otherwise each DataSetMessage
  carries its own SchemaId. A producer computes/tracks the SchemaId and
  advances the DataSet ConfigurationVersion per DataSet, not per
  NetworkMessage. Applied to Avro Part 14 framing and Arrow Part 14 5.2.1,
  standalone + errata.

markdownlint clean; check_links OK.

* Avro spec: address PR #20 feedback (schema-gen inputs, decoder resolution, fixed NM envelope)

Applies the three PR #20 review threads to the standalone Avro spec and mirrors
the normative changes to the Part 6 / Part 14 errata specs:

- T1 (schema-gen inputs): a grown schema also takes the previous schema of the
  lineage as an input (append new Variant body form / ExtObj concrete type as an
  additional union branch, existing branch indices preserved); no previous schema
  supplied = reset = new MajorVersion. Softened "never handed one".
- T2 (decoder resolution): primary use case is a subscriber/downstream consumer
  that does NOT have the OPC UA type model at decode time, so it obtains the
  shared schema by SchemaId; "computed" -> "are using".
- T3 (NetworkMessage envelope): the NM is a fixed, specification-defined envelope
  whose schema never changes; payload is an array of { schemaId, dataSetMessage:bytes }
  entries carrying each DataSetMessage opaquely, decoded via its per-DataSet schema.
  Added single-DataSet and un-enveloped-batch models; updated carrier table and
  common-header SchemaId identification.

markdownlint (target files) + check_links (514) clean.

* Avro spec: address PR #20 round-2 feedback (schema-gen wording, style, NetworkMessage schema artifacts)

Standalone Avro spec + Part 6/14 errata:
- T1 (§5.1): reconcile "encoder is not handed a schema" with §6.1 - the encoder GROWS its own
  previous schema (appending a Variant/ExtObj branch) when a form evolves, and creates a new
  schema from scratch (a new MajorVersion) only when no previous schema exists. Removed the
  unexplained "Neither side may substitute alternate branches" sentence.
- T2 (§5.8/§5.9 and §8.1): broke the dense Variant/ExtensionObject paragraphs into logical
  paragraphs of full sentences; removed semicolon-joined clauses.
- T3 (§7): "does not have" -> "likely does not have" the type model at consumption time.
- T4 (§8.1): the fixed NetworkMessage envelope is now a published artifact - generated
  AvroNetworkMessage.avsc + AvroDataSetPayloadEntry.avsc (via message_types.py), linked from
  §8.1 and reproduced in Annex B.
- T5 (§8.1): the un-enveloped batch schema AvroDataSetMessageBatch.avsc likewise generated,
  linked and added to Annex B.
- T6: mirrored T1/T2/T3 into Part 6 and the NetworkMessage envelope/batch artifact links into
  Part 14.

markdownlint (target files: only pre-existing MD011 false positives in generated annex blocks)
and check_links (514) clean.

* Arrow specs: parity with the Avro PR #20 model (encoder role, S1/S2, columnar envelope rationale)

Brings the Arrow standalone spec and the Part 6/14 Arrow errata up to the model applied to
Avro in PR #20. The Arrow specs already carried the per-DataSet SchemaId and the
advance-MinorVersion lifecycle; this fills the remaining gaps:

- Encoder role (Part 6 §5.6.9): the encoder is not handed a foreign schema - it PRODUCES the
  Arrow Schema from the type model and GROWS its own previous schema (appending a dense-union
  child, existing children and type codes unchanged); no previous schema = new MajorVersion.
- Decoder framing (§5.6.10): the primary consumer LIKELY does not have the type model at
  consumption time, so it obtains the schema by SchemaId; only an AddressSpace-holding decoder
  re-derives.
- S1 (§6.9.2.5 / Part 14 §5.2.5): publishing a changed schema is ONE rule with two channels -
  register in the Schema Registry AND announce (announce-only when no registry is reachable).
- S2 (§5.6.12 step 4, §6.9.2.7 / Part 14 §5.2.7): the publisher SHALL advance the DataSet
  ConfigurationVersion on schema growth; decoders stay SchemaId-authoritative.
- Columnar envelope rationale (§6.9.2.1 / Part 14 §5.2.1) - reflecting the reference
  implementation: an Arrow NetworkMessage is one homogeneous RecordBatch whose schema IS the
  DataSet schema, so the per-DataSet SchemaId is inherent and Arrow deliberately does NOT adopt
  Avro's fixed envelope with opaque per-DataSet entries. Implementers shall not add one.
- Style: broke the dense semicolon paragraphs into full sentences; linked the generated
  struct-ArrowSchemaAnnouncement / struct-ArrowSchemaRequest artifacts.

markdownlint clean on the Arrow specs; check_links OK (514).

* Drafts cleanup: retire dead pubsub-binding NodeSet references and stop destructive regeneration

The pubsub-binding NodeSet was renamed to scenario-binding and then rewritten as
observability-export, but five tool/doc references still pointed at the deleted path:

- avro/arrow tools/build_schemas.py + xregistry-catalog/tools/build_catalog.py: repoint the
  default source NodeSet to the current successor,
  core-specs/observability-export/Opc.Ua.ObservabilityExport.NodeSet2.xml (it still defines
  BoundItemDataType/BoundItemKindEnum and the model's successor DataTypes).
- extras/validate_all.py + avro-encoding/README.md: fix the stale example/default path.

Also fixes a destructive failure mode in the Avro generator: it used to shutil.rmtree() the
committed schema directory and only THEN fail on the missing NodeSet, leaving the artifacts
deleted (hit for real while generating the PR #20 NetworkMessage schemas). It now validates the
NodeSet path first and exits 2 with a usage hint, leaving the output directory untouched.
Verified: missing NodeSet -> clear error, exit 2, all 31 artifacts intact.

Generated artifacts are intentionally NOT regenerated here. The committed schemas still derive
from the old scenario-binding model, so regenerating would churn schema files, schemaids and the
Annex type-reference tables; that refresh is a separate, deliberate change (it is why
avro/arrow validate_local still report type-reference drift, a pre-existing staleness).

check_links OK (514).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants