Skip to content

P3-A1: canonical binary SV device-profile envelope - #146

Merged
masarray merged 6 commits into
mainfrom
hardening/smv-p1-3-device-profile-binary
Oct 7, 2026
Merged

masarray merged 6 commits into
mainfrom
hardening/smv-p1-3-device-profile-binary

Conversation

@masarray

@masarray masarray commented Oct 7, 2026 •

Copy link
Copy Markdown
Owner

Tracks #36 and #33. Stacked on #145 / #144.

Current base: main@bdd895ae8641dbf3d9c5c6509e3eb94f78802b8d (includes accepted #145 and #148)
Current head: ba131a2481f8fe70f318488a4234fe2a21525cd1

Purpose

Close the remaining P3-A1 software integrity gap without creating a second SV semantic model.

The host already owns SvPublisherProfile; the ESP already has deterministic STOPPED staging/atomic commit and a prebuilt WirePlan. This PR introduces the canonical host -> device binary envelope between them.

Architecture

  • no C++ struct memcpy / ABI-dependent wire format;
  • explicit big-endian byte serialization;
  • fixed-capacity allocation-free decoded representation;
  • magic + schema version + header length + total length + payload length;
  • CRC-32 over the complete canonical record with the CRC field logically zeroed;
  • ordered wire-leaf descriptors;
  • bounded svID/DataSet strings;
  • resolved timing/counter/SmvOpts values only.

The existing BRCB checkpoint CRC-32 implementation is promoted to a shared integrity primitive rather than introducing a second checksum algorithm.

Host compiler gate

compile_esp32p4_device_profile() only succeeds when the existing device capability classifier says the profile is currently deployable.

Therefore:

  • a resolved generic/legacy Class-A 4I+4V profile may compile;
  • IEC 61869-9 may remain fully valid at the host standards layer while the current ESP32-P4 device compiler rejects it as unsupported capability.

No standard-valid profile is relabeled invalid merely because V1 device firmware cannot deploy it.

Binary V1 invariants

  • canonical wire-type code + canonical width for every leaf;
  • Quality/Timestamp flags must agree with the wire type;
  • payload length equals the exact sum of ordered leaf widths;
  • APPID/MAC/VLAN invariants revalidated defensively;
  • no hidden VLAN state;
  • SmvOpts child flags cannot exist when the element is absent;
  • no embedded-NUL identifier smuggling;
  • exact record length required;
  • unknown flags/types/version rejected;
  • CRC mismatch rejected.

Regression

  • shared CRC-32 known-answer vector (123456789 -> 0xCBF43926);
  • byte-for-byte golden device-profile vector;
  • encode/decode equality;
  • short buffer;
  • CRC corruption;
  • wrong magic/version/length;
  • noncanonical leaf width;
  • embedded NUL;
  • inconsistent SmvOpts;
  • SCL 4800 Class-A -> compiled binary profile;
  • host-valid IEC 61869-9 -> current ESP device compiler rejection.

Non-goals in this stacked tranche

  • no embedded decoder/activation wiring yet;
  • no serial transport change yet;
  • no ESP runtime layout expansion;
  • no physical timing/conformance claim.

Next within #36 after this portable contract is accepted: bounded embedded decoder -> temporary RuntimePublisherProfile -> atomic commit, then bridge transport migration.

Merge discipline

#145 and #148 have merged. Current branch has both as ancestors and is ahead of current main (behind 0). Require full fresh exact-head CI on ba131a... and repeat head/merge-base verification before merge.

2026-10-07 integration / decoder hardening

Extract the existing BRCB checkpoint CRC-32 semantics into a small portable core header so the upcoming compiled SV device-profile envelope can reuse one integrity algorithm instead of introducing a second checksum authority. No checkpoint wire-format change. Tracks #36.
Add an allocation-free fixed-capacity device-profile model, explicit big-endian binary codec with magic/version/length/CRC-32, ordered wire-leaf descriptors, and an ESP32-P4 host compiler that only accepts currently deployable Class-A profiles. Golden/corruption tests lock the binary contract and prove host-valid IEC 61869-9 remains outside the current device capability. Tracks #36.
Reject hidden VLAN/SmvOpts state, embedded-NUL identifier smuggling, noncanonical leaf widths, and descriptor flag/type mismatches before binary encoding. Keep the envelope canonical so a future embedded decoder cannot reinterpret malformed but checksummed records. Tracks #36.
Add the standard CRC-32 known-answer vector so the shared integrity primitive cannot drift independently between BRCB checkpoint storage and compiled SV device-profile records. Tracks #36.

masarray commented Oct 7, 2026

Copy link
Copy Markdown
Owner Author

Scoped pre-merge review for P3-A1 binary contract (no competing implementation): prior exact-head CI on deda183bfb5ffa97bbc5bb009004bfc3d7904f98 is 14/14 green, but branch is still stacked on the pre-#145 base. Current main@0a08767... has the same tree as P1.2 head 2a524f9..., so retargeting should be feasible; after P1.3 #148 is accepted, re-evaluate the complete diff and require fresh exact-head merge validation.

One fail-closed contract review item for a future bounded follow-up (not a blocker claim without a regression): valid_profile_shape() currently rejects profile_family == unspecified and sampling_basis == unknown, but not unrecognized cast enum values; encode_profile_family() / encode_sampling_basis() then write code 0. Similarly any enum value other than multicast currently passes the unicast shape branch, and encode_into() serializes unicast code 2. Consider exhaustive enum-value validation with negative fixture(s), so manually constructed CompiledSvDeviceProfile cannot be silently canonicalized to a different transport mode. Preserve all existing supported values and golden vector.

No code changes made to your branch; #36 remains the owner of the binary device-profile authority.

@masarray
masarray changed the base branch from hardening/smv-p1-2-iec61869-profile to main October 7, 2026 00:53

masarray commented Oct 7, 2026

Copy link
Copy Markdown
Owner Author

P3-A1 next gate — retarget completed, hold for fresh validation (2026-10-07)

P1.3 PR #148 merged safely into main@bdd895ae8641dbf3d9c5c6509e3eb94f78802b8d after 15/15 exact-head workflows succeeded; issue #147 closed.

PR #146 is now retargeted to that exact main, with unchanged head@deda183bfb5ffa97bbc5bb009004bfc3d7904f98. GitHub reports mergeable/clean, with the existing seven-file binary-profile diff; no new PR or competing authority was created.

Important: the prior 14/14 successes for #146 were run at 2026-10-07 00:15Z, before this retarget. Although GitHub's workflow metadata now displays the current base ref, those are not fresh post-P1.3 merge-tree CI runs. Keep #146 Draft / NOT MERGED until an integration head based on current main is validated and the binary codec edge-case review above is addressed or dispositioned. Do not reuse stale green runs as current-merge acceptance.

Bounded next step for #36: integrate current main via a non-destructive, lease-protected branch update, preserve P1.3 SCL negative tests plus #146 binary golden vectors, and run exact-head C++/Studio/embedded/security and package gates on the combined tree. Host binary acceptance is not embedded decoding/activation or physical timing acceptance.

Integrate main@bdd895ae8641dbf3d9c5c6509e3eb94f78802b8d and retain nofASDU / compiled-device-profile regression coverage. Reject unknown transport/family/mode enum encodings and return a decoded profile only after all validation gates. No realtime hot-path modifications. Tracks #36 #139.

masarray commented Oct 7, 2026

Copy link
Copy Markdown
Owner Author

2026-10-07 P3-A1 integration + decoder hardening checkpoint

  • Current main exact base: bdd895ae8641dbf3d9c5c6509e3eb94f78802b8d (merged P3-H P1.3: fail-closed SCL nofASDU provenance #148 P1.3).
  • Existing P3-A1: canonical binary SV device-profile envelope #146 branch updated by fast-forward with expected-head lease, no force push: hardening/smv-p1-3-device-profile-binary@483bd90e64891a62d474e94729b1a6a1b7c5f5a2. Merge commit parents: old P3-A1: canonical binary SV device-profile envelope #146 head deda183... and accepted main bdd895...; ahead 5 / behind 0; 7 original scoped files relative to main.
  • Retains both P1.3 invalid-explicit-nofASDU negative regression and P3-A1: canonical binary SV device-profile envelope #146 compiled-device-profile/golden-byte regression within combined tests/test_scl.cpp.
  • Hardened existing V1 codec, not a second decoder: reject unknown profile family, sampling mode, and transport enums on encode (no unknown→unicast alias); transactional binary decode uses a bounded temporary and publishes output only after final validation.
  • Negative regressions include 3 unknown enums and a CRC-valid malformed late leaf descriptor proving decoded output remains empty; existing golden vector unchanged by design.
  • No embedded runtime hot-path change, no firmware-side binary transfer claim, no physical test claim. Embedded mapping is future bounded P3-A1: compiled SV device profile and deterministic ESP32-P4 activation #36 tranche (binary decode → supported-capability check → STOPPED-only existing runtime_profile_commit).
  • Fresh exact-head pull-request CI is running, do not merge based on older deda183... CI. Keep Draft until full acceptance.

masarray commented Oct 7, 2026

Copy link
Copy Markdown
Owner Author

CI failure triage + fixed head — 2026-10-07

Fresh integration head 483bd90e64891a62d474e94729b1a6a1b7c5f5a2 passed Linux/GCC and Linux/Clang compilation/regression but C++ CI Windows/MSVC failed in test_sampled_values.cpp (log job 112579052019; C4244 promoted to C2220). Root cause: the new late-invalid-descriptor regression used std::fill(..., 0U), where MSVC warns on narrowing the literal unsigned int into a uint8_t byte. This was a test harness literal, not a binary codec or firmware runtime defect.

Fixed narrowly on existing PR #146 branch: commit ba131a2481f8fe70f318488a4234fe2a21525cd1 uses std::uint8_t{0U} with the same wire bytes and CRC calculation. No source/runtime behavior changed. New exact-head CI started; discard previous-head green results and do not merge before this head is fully accepted.

@masarray
masarray marked this pull request as ready for review October 7, 2026 02:40
@masarray
masarray merged commit 879f84b into main Oct 7, 2026
32 checks passed
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 7, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-07T02:41:23.493318Z ba131a2 Draft marked ready
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

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.

1 participant