Skip to content

P0 consolidate: firmware-truth PTP lifecycle, firm SV START and native clipboard tests - #268

Open
masarray wants to merge 15 commits into
fix/p0-ptp-copy-diagnostics-verified-start-20261021from
fix/p0-ptp-sv-lifecycle-consolidated-20261021
Open

masarray wants to merge 15 commits into
fix/p0-ptp-copy-diagnostics-verified-start-20261021from
fix/p0-ptp-sv-lifecycle-consolidated-20261021

Conversation

@masarray

@masarray masarray commented Oct 20, 2026 •

Copy link
Copy Markdown
Owner

Baseline and scope

Stacks on #267 (24fddc945da1cd0379d9b269955d061e00ebfc2b), which stacks on #265; selectively ports native clipboard/CMake/Qt CI from divergent #266 (799b66481f77abdcbdb50a6f1cab5fe165ade006). Does NOT merge/cherry-pick both histories and does NOT touch main.

Physical capture 20 Oct

395,424 SV frames over 98.858 s at observed ~3999.895 fps, 0 sample count loss/reorder/duplicate, 366 PTP Announce/Sync/Follow_Up, smpSynch 0→1→0; internal cause PHASE_OR_MAC_GATE_LOST at phase 4 us uncertainty 6 us. Firmware capture build 799b66481f77abdc (#266) and PTP SOURCE UNLOCKED; these do not prove physical clock lock or final branch hardware behavior. SV stopped after capture segment; cause of stop not established by wire alone.

Changes

  • DeviceController.scenarioApplying is the only authority for Studio START-in-progress. Removes the QML 8s watchdog and onLastErrorChanged cancellation: unrelated PTP/serial error cannot bounce the injection button or cancel perceived START.
  • Preserve P0 Studio: verified PTP preflight and working Timing Copy Diagnostics #267's bounded PTP SHOW preflight before role mutation, explicit STOP ACK/readback, no uncontrolled recovery STOP. Adopt already-running same SOURCE/RECEIVER role only after matching fresh PTP2 role evidence and PTP RUNNING readback; no redundant disruptive restart.
  • The exact firmware PTPROLE rejected: stop PTP before changing operating role is positive evidence of ACTIVE runtime; keep PTP ON/STOP actionable, preserve reason, never fabricate OFF or auto-stop unowned transmitter.
  • Port P0 physical PTP stale-role recovery + verified Time Sync clipboard #266's native Qt clipboard harness + CMake + Windows/Linux studio CI and Windows preview verification alongside P0 Studio: verified PTP preflight and working Timing Copy Diagnostics #267's GUI singleton import, readback, and selectable in-Studio fallback.
  • Add deterministic positive/negative PTP adoption/role-reject regressions; update structural GUI regression to enforce SSOT UI state.

Gates / not claimed

Await exact-head Windows Qt, embedded ESP32-P4, Windows Native Preview/Inno installer + bundled firmware tests, full CI. Physical START/STOP, PTP/SV LOCK, relay IEC 61850-9-3 Pdelay acceptance and 120s/1h hardware capture remain unverified until Studio-only bench. NO main merge or release.

21 Oct forensic addendum: FALSE-OFF ROOT CAUSE / firmware correction

Capture host-clock timeline: SV last observed ~22:01:35.404Z; Studio observed SV STOP at 22:01:37.467Z, PTP OFF at 22:01:38.510Z while L2 PTP Announce/Sync/Follow_Up continued through 22:02:01.346Z. This proves telemetry-vs-wire disagreement, not a true PTP STOP. Root in ptp_mode_facade.cpp: status.is_running was driven by source_has_fresh_evidence(), which loses qualification transiently even while ar_ptp_source_runtime_active() owns EMAC and continues transmitting. Firmware now reports physical SOURCE runtime for PTP status=RUNNING, while canonical clock usability/generation still require fresh timing evidence. Thus GUI toggle no longer flips OFF on temporary clock uncertainty; physical PTP source RUNNING does not certify SV/PTP LOCK. Added portable canonical timing negative test and structural guard against conflating the two domains. Exact SHA and firmware bundle must be rebuilt from this revised head; earlier green checks/artifacts belong to earlier SHA and do not satisfy this revision.

@masarray
masarray marked this pull request as ready for review October 20, 2026 22:26
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 20, 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-20T22:28:52.522712Z af25366 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.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: af25366adf

ℹ️ 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".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +1449 to +1454
if (ptpRuntimeRoleSeen_) {
const QString existingRole = pendingPtpRole_;
resetPtpStartup();
ptpStatus_ = QStringLiteral("PTP %1 already active on board; external sync unqualified").arg(existingRole);
emit ptpStateChanged();
return; // No redundant role/config/start, no surprise STOP.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Verify the active configuration before adopting it

When reconnecting to an already-running board whose role matches the requested role but whose domain, transportSpecific, VLAN, or cadence differs, this branch resets the startup transaction and reports the runtime as adopted without ever comparing pendingPtpConfig_ with the PTP config readback that follows the status line. The configured-start request therefore silently leaves the board transmitting with settings different from those selected in the expert panel; wait for and validate the configuration readback, or reject the adoption and require a verified stop.

AGENTS.md reference: AGENTS.md:L11-L18

Useful? React with 👍 / 👎.

Comment on lines 23 to +24
function onRunningChanged() {
if (ribbon.device.running) {
ribbon.startQueued = false
startWatchdog.stop()
controller.pendingApply = false
}
}
function onLastErrorChanged() {
if (!ribbon.startQueued) return
ribbon.startQueued = false
startWatchdog.stop()
controller.pendingApply = true
if (ribbon.device.running) controller.pendingApply = false

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Restore the pending marker after a failed START transaction

When pendingApply is already false after a previous successful run, a subsequent CFG commit/readback/START rejection or timeout now only clears scenarioApplying; because the broad error handler was removed and this connection only handles successful RUNNING evidence, pendingApply remains false. After such a failure the status strip incorrectly says the setpoints are applied even when the transaction failed before commit, so the authoritative transaction failure path needs to mark the draft pending without reacting to unrelated device errors.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Owner Author

CI / artifact checkpoint — exact HEAD verified

  • Consolidated head: 6c97195e80c0058f675ad2bf6f4be053687453dc (PR P0 consolidate: firmware-truth PTP lifecycle, firm SV START and native clipboard tests #268, base P0 Studio: verified PTP preflight and working Timing Copy Diagnostics #267, NOT main).
  • ALL 11 top-level workflows PASS at this exact SHA: CI Routing Policy, Product Naming Guard, RC2 Acceptance Policy, Embedded Profile CI, ESP32-P4 SMV Injector, ESP32-P4 PTP Lab Profile, ARStack Studio Qt (Windows native clipboard harness + Qt build), ARStack Studio Windows Lifecycle, Security and Evidence, ARStack Studio Native Preview (firmware+Windows setup), C++ CI.
  • One Studio physical-test bundle (ZIP containing Windows native Inno Setup exe, portable, SHA256SUMS): https://github.com/masarray/arstack61850/actions/runs/39509540847/artifacts/12305446667
  • Preview bundle workflow verified firmware manifest.sourceCommit equals exact PR HEAD, phaseSyncPreview ON, servo ON, MAC TX evidence ON, mirror OFF; bundled fresh firmware is from same SHA, pinned public baseline provides flasher only. Installed Windows GUI checks include firmware contract, P0 policy, native clipboard readback, application lifecycle; Inno clean install/upgrade/uninstall and legacy NSIS->Inno migration all PASS.
  • Physical qualification still NOT accepted: no device bench run yet for updated firmware, no relay/IEC 61850-9-3 Pdelay interop proof, no stable AUTO SV LOCK proof. Do not merge/release main before operator-driven Studio physical acceptance.

Copy link
Copy Markdown
Owner Author

21 Oct — post-install physical PCAP checkpoint (operator capture 2026-10-20 23:05:09–23:07:14 UTC)

Independently inspected the raw 69 MB .pcap, 499,988-row samples.csv, seconds.csv, events.csv and telemetry report.json for ARStack_SV_20261020_230509_486. The board's reported build ID 6c97195e80c0058f matches exact #268 HEAD 6c97195e80c0058f675ad2bf6f4be053687453dc (report snapshot only; bootloader attestation is not available).

Strong positive local steady-state evidence: 125.000357 s of capture, 499,988 canonical SV frames, observed 3999.884576 fps, all VLAN PCP4/VID0, APPID 0x4000, svID ARSTACK_SV01, source E8:F6:0A:E0:C5:3F. All 8 channels present; 0 malformed frames, 0 smpCnt discontinuities/duplicates/reorders/missing, 0 nonzero channel-quality flags, 125 smpCnt=0 epochs. 3 Windows host arrival gaps of 1184/1550/1877 us did not interrupt smpCnt. PTP on wire: exactly 125 Announce, 125 Sync, 125 matching Follow_Up (seq 41..165), domain 0, two-step Sync, same MAC and same sourcePortIdentity, no missing PTP sequence IDs, ~1s intervals. PTP+SV continued for entire capture; all 126 Studio snapshots show SV RUNNING, PTP SOURCE RUNNING, firmware missed=0/txFailures=0, boot/profile/signal generation unchanged.

Measured local sync: initial smpSynch=0 for 79,074 SV frames; one PCAP change 0→1 at 23:05:29.329067Z (19.769 s after capture start; smpCnt=1001), then 420,914 consecutive frames (105.23 s) with smpSynch=1, zero reversions. Studio syncFlight reports exactly one ACQUIRED (phase=0 us, uncertainty=2 us, MACpairs=2, clean=10); this is firmware diagnostic and not an independent hardware phase capture. SOURCE discipline remains UNLOCKED and source NONE throughout, expected for an untraceable local SOURCE, not evidence of external GM LOCK. Wire PTP GM class 248, timeAccuracy 0xFE, timeSource 0xA0; Follow_Up seconds 40..164 are a free-running local epoch, not demonstrated UTC/TAI absolute time. Host-relative cross-correlation of smpCnt=0 to two-step Sync estimated PTP second boundary: median ~+52.7 us, p95 ~+109.3 us (PC capture RX delay/jitter; never hardware SV egress/clock phase certification). No Pdelay request/response in this isolated capture.

Outstanding acceptance: report.physical_acceptance=false remains correct. LOCAL stability for ~105s is a promising partial pass, but ~19.77s observed 0→1 from capture start does not establish near-immediate START acquisition (START command precedes capture; exact click-to-lock not recorded). This single steady-state capture cannot prove START/STOP button tactile responsiveness, no spontaneous stopping beyond 125s, toggle behavior across transitions, clipboard native readback, 1h longevity, external IED/IEC 61850-9-3 Pdelay and end-to-end traceable synchronization. Re-test via Studio GUI with START timestamp, explicit STOP/START cycles, 1h capture and relay evidence before main merge/release.

Waveform note: wire-fit fundamental phases: IA -28.089°, IB -148.049°, IC +91.956°, UA -0.053°, UB -120.049°, UC +119.953°. Current three phases have roughly +1.95° relative to the prior engineering example of -30/-150/+90; because this capture lacks the actual operator setpoint/CFG SHOW snapshot, this is a test hypothesis, NOT a confirmed phase bug. Keep phase/RMS equivalence unaccepted until same-run UI setpoints + firmware readback + PCAP match.

Decision: #268 still open/unmerged. Do not treat physical acceptance as green or alter safety gates merely to reduce acquisition delay.

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