Repository navigation
ARD P0–P3: Unified Protocol SSOT — deep COT/quality flags across Frame Trace, Events, Values and Reports #39
Description
CURRENT TRACE/PROPERTIES/AUTO-SCROLL UX CHECKPOINT — 2026-10-29
**Verified master: 5584abb53f623677644902ddef38fbc9ff1c4d73 — merged PR #54. Reconcile this with future PRs; all previous snapshots below are historical.
Merged user-visible corrections (UX-01)
- Trace every frame now shows explicit host-local
HH:mm:ss.fffnear TX/RX direction, not a misleading second-only time. Original full IEC-101 narrative remains available for copied/exported evidence; Trace header removes its redundant timestamp and uses user-specified solid 24px up/down TX/RX icons, not faint Unicode glyphs. Host adapter time is not true physical wire-edge time. - Frame Interpreter is now a stable Frame Properties table; thin zebra stripes, readable two-column responsive grid, selected-only typed Link address/function, TI + type name, VSQ, COT/flags, CA/IOA, Quality bits, value, RTU time, command, integrity and bounded per-object details. Old mouse-hover protocol-group mutation is no longer attached to the visible inspector. Don't revert to hover flicker or restore noisy HEX chips.
- Primary tab navigation font raised to 14 WPF px and 42px-high targets, Trace detail+HEX font enlarged.
- Trace: mouse wheel pauses auto-follow without consuming the wheel event; explicit header toggle binds to existing rail Follow/Hold state. Frame selection and continued bounded raw buffer remain independent.
- Events: separate header auto-scroll toggle with user-supplied down/lines icon; mouse wheel disables follow, leaves visible SOE rows stable while new evidence still enters bounded authoritative ring; explicit resume refreshes latest rows once. This does not disable capture/polling.
- Source changes remain WPF/ViewModels and styling only. IEC-101/103/104 decoders, passive RX-only, FCB/FCV, serial polling, .ariec SHA/byte capture and command-RTU proof unchanged.
Evidence and gates
Windows CI #40870239635 passed Release build, 19/19 protocol smoke, 250/250 xUnit, and portable win-x64 package. CodeQL, dependencies and hygiene passed on exact PR HEAD ebad333b302ebef59be636b4ad30295b957b57a0. Windows CI artifact ID 12896170809; inner portable ZIP SHA256 c41aa391b2764e6869f2ea0a3536af9ffc44eb24a099c1d39a817bba77e5f7c2, checksum matched SHA256SUMS.txt; ZIP CRC validated; contains ARIEC60870.Desktop.exe and START_HERE_MONITOR.md.
- Known debt: formatter continues reporting 166
WHITESPACElog lines withcontinue-on-error; it is not a clean mandatory formatting gate. Do not misstate formatter green. - FAT not done: native Windows 100/125/150% DPI visual inspection, in-situ hover stability, actual wheel/selection scroll under traffic, physical 2/4-COM passive/active timing and sustained long-run resource measurements. CI is not proof of hardware UX.
- Contract:
docs/RESPONSIVE_LAYOUT_POLICY.mdsection "2026-10-29 Trace/Events observation usability (UX-01)". Keep public repo vendor-neutral.
SUPERSEDED PRIOR CHECKPOINTS (retained below for continuity)
LIVE MONITOR / RIGHT-CLICK CLIPBOARD RELEASE CHECKPOINT — 2026-10-29
Verified master 552d8bce66e3193aa64867dc2682fa1689932348 (merged PR #50, after #49). Refresh master before subsequent work.
Operator behavior now confirmed by source + CI:
- Live IEC-101 passive Start Monitor never records automatically. Full raw journaling remains explicit opt-in in Setup; RX-only 2/4-COM parser/Trace/Values/Events continue to run.
- Right-click any Frame Trace row → Copy Selected Frame: if right-clicked row was not selected, copy only that frame; if right-clicked row belongs to the Ctrl/Shift multi-selection, preserve every selected row (do not focus another ListBoxItem) and copy the entire selection in frame sequence order. Windows clipboard contains human/AI-readable text with original raw HEX, COT, quality and source context; paste directly with Ctrl+V; no file or network upload. Evidence Ledger has same menu. Optional Save Selected Frames (.ariec) produces a reopenable structured ZIP with verified frames.jsonl + analysis.md.
- Windows win-x64 portable bundle now contains START_HERE_MONITOR.md (current workflow) rather than old record-first P0 guide. Verified inner GUI ZIP contains
ARIEC60870.Desktop.exe, current guide and example profile; CRC pass, SHA25652c570369e78c1a7dd9cad819c5e8621197cf358810c7a6fbeff91a9e933ab12. - CI exact PR HEAD
5a856822a6327bc89ebcb6eb0215a76f9829be7a: Windows CI 40844634419 SUCCESS (Release, protocol smoke, xUnit including 2-frame clipboard ordering, Windows packaging), CodeQL, Hygiene, Dependency review SUCCESS. Physical COM FAT has not been performed. - Maintain vendor-neutral public language. Never regress monitor to record-first, nor equate bounded visible Trace excerpts with full-session lossless capture.
dotnet formatremains a preexisting non-gating maintenance debt.
PREVIOUS CHECKPOINTS (historical only; preserve for traceability)
LIVE-FIRST MONITOR & SHAREABLE TRACE CHECKPOINT — 2026-10-29
Current verified master: 260383b24d1ca4df1982406467520b1cf03bc1b3 (merged PR #49). This supersedes previous "record by default" UX; refresh master before modifying. PR #49 contains no automatic recording in normal passive monitoring.
Implemented and CI-verified
- Main connection action is Start Monitor / Stop Monitor (not Record RX). Passive IEC-101 monitor opens 2/4 RX-only COM taps, streams into existing Trace, Values, Events and Findings, and creates no files or capture folders by default. This is true at the engine level, not just the button label. UI clearly shows "Live only · no disk recording". An optional Setup checkbox Record entire raw session to disk, default OFF, activates the pre-existing fully verified binary journal, indexes and manifest. Lock the option while monitoring; do not allow retroactive claims.
- Multi-select Trace frames with Ctrl/Shift, Save Selected Frames (.ariec) or right-click Copy Selected Frames for AI / Sharing. Selected bundle still reopens via Open Capture with verified
frames.jsonlSHA-256 and raw field-width profile. Additionalanalysis.mdprovides human/AI-friendly original raw HEX, direction, COT/flags, quality bits, command/reply, per-object source details and timestamp caveats;README.mddescribes its scope. No automatic cloud transmission or hidden bulk capture. - Full raw journaling remains explicitly opt-in and compatible with original 2/4-RX passive replay and legacy archives. Selected visible trace is a bounded excerpt, never a claim of full session completeness.
- New synthetic engine tests verify no directory created while both COM sources produce complete FT1.2 frames, RX-only closure, explicit optional journal. Desktop share formatter and GUI smoke regressions test source, COT, quality and default OFF.
- CI exact PR head
e74459b88f61a4a9ec68f43daf6b381cf373e3e6: Windows CI 40843020872 PASS (Release + 19/19 protocol smoke + 218/218 xUnit + GUI packaging). CodeQL, Dependency Review, Repository Hygiene PASS. Windows artifact ID12883358281; inner package SHA256331d9037f559cd450d17315eca7e00b1518fa3b253376604331577c72f83b1c3, verified against CI SHA256SUMS with intact ZIP CRC. Build is still pending real physical serial FAT. - Formatting caveat persists:
dotnet format --verify-no-changesemitted pre-existing and/or current whitespace issues (155 log lines) but iscontinue-on-error: truein CI. Therefore CI green is NOT evidence that the formatting check is clean. Address in targeted maintenance rather than masking. - Operator/engineering guide:
docs/IEC101_LIVE_MONITOR_SELECTIVE_CAPTURE_20261029.md.
Non-negotiable future behavior
Do not change Start Monitor into automatic Record; do not create files under the hood in live-only mode. Never infer a full capture from bounded live UI data. Preserve SHA/provenance and original unmodified raw bytes; AI-facing Markdown remains derived, not source authority. Protect RX-only transport and field hardware; no TX. Retain one decoder/one evidence model, good performance, current command/RTU forensics and compact Quality/COT grid badges. Public material remains vendor-neutral with no named commercial comparison tools. No physical FAT claim before hardware tests.
HISTORICAL PREVIOUS CHECKPOINT (retained for traceability)
CURRENT VERIFIED CHECKPOINT — 2026-10-29 15:00 WIB
Latest verified master: 55928bcb7eec26f0b87e95c5a34ecfe626e2c515 from merged PR #48. Refresh master and all open PRs before future modifications; older snapshots below are historical.
- Merged feat(forensics): typed Quality/COT badges and vendor-neutral public documentation (#39) #45: compact typed Quality/COT badges in existing grid cells and public vendor-neutral text.
- Merged fix(commands): typed and source-scoped RTU verdicts without false physical proof (#39) #46: typed, source-aware command phase/RTU reply verdict without inferring physical actuation.
- Merged feat(capture): verified .ariec integrity and typed IEC101/104 offline field replay (#39) #47: verified capture hash and typed selected-frame archive/replay; older V1 raw remains without guessed semantics.
- Merged fix(commands): block ambiguous or bad-quality RTU verdicts (#39) #48: reject RX warning replies as proof; feedback needs healthy typed quality (reject unknown/IV/BL/SB/NT/OV/CY/CA); overlapping command requests marked ambiguous, source-matched ACTTERM without ACTCON stays incomplete; echoed S/E mismatch flagged across relevant phases. All source data retained.
- Build evidence: PR #48 CI 40838991800 Release build, protocol smoke, full xUnit suite and Windows GUI package PASS; CodeQL 40838991692, dependency review and hygiene PASS. Verified GUI ZIP SHA-256:
ab0762568a62cafba9a6de97911fa895e0c38b9e65ca42600db62c5c53794bde. GitHub Actions portable asset ID12881519677. - Not yet certified: IEC103/104 full byte-span Inspector parity, durable multi-stage transaction evidence across Active/Passive/replay, complete all-object Event/Values/report/export parity, enforced formatting gate, measured CPU/latency/memory and physical FAT. CI success is not a field interoperability certificate. Do not claim total professional parity until field acceptance is complete.
- Public release discipline: continue vendor-neutral text only, no customer captures/IDs, no commercial benchmark brand references in new public files, comments, PRs or issue updates. Do not rewrite historical commits.
HISTORICAL PREVIOUS CHECKPOINT (for traceability; superseded by live status above)
CURRENT VERIFIED RELEASE-CANDIDATE CHECKPOINT — 2026-10-29
Latest verified master: 2cf5c0265dd7e63e446bfe7f103bfd2a4bec4b73 (PR #47). Use this as audit snapshot only; refresh master before editing.
| PR | Status | Verified impact |
|---|---|---|
| #45 | Merged · d26168fb |
Small typed Quality/COT badges in existing columns; source-backed flags and public vendor-neutral documentation |
| #46 | Merged · fe3eb25a |
Typed source-scoped command response phase and safe RTU feedback verdict: ACTCON != physical operation |
| #47 | Merged · 2cf5c026 |
Verified .ariec SHA-256 manifest; recorded Link/COT/CA/IOA widths; trusted IEC101/104 raw re-decode and source/stream/object provenance; legacy capture compatibility |
Windows CI for PR #47 (run 40837634055) passed Release build, protocol smoke, all xUnit and Windows portable GUI packaging. CodeQL (run 40837634060), dependencies and hygiene also passed. GitHub Actions default merge checkout was verified at synthetic commit b57be45: PR #47 merged with PR #46 changes, so the packaged PR #47 GUI includes both workstreams. The portable ZIP includes ARIEC60870.Desktop.exe, tested as ZIP intact with SHA-256 a398fd9b06389fe87099113bd6bada3f18b25a953edb2c8df9853ecd7cb2dea8.
Open acceptance gates — do not claim full product parity
- IEC103/104 complete byte-span Inspector parity; IEC101 byte map already in master.
- Full transaction evidence including ambiguous/unmatched RTU replies and state-target feedback verification, plus durable derived transaction records across Passive/Active/offline.
- Complete multi-object Event/Values/report/PDF/export replay parity, not just selected Trace
.ariecbyte-map restoration. - Enforced formatting gate, measured UI/CPU/allocations and physical FAT (serial links, redundant A/B, 100/125/150% Windows DPI).
- Packaging from a reproducible Windows CI workflow is proven; independent physical interoperability superiority or certification is not proven.
Public text rule: do not include competitor/vendor product names in source, docs, issues, PR metadata or new public files. No private capture records in public tests.
HISTORICAL CHECKPOINTS (superseded by CURRENT VERIFIED above)
ACTIVE BUILD CHECKPOINT — 2026-10-29
- Merged PR #45
d26168fb: compact typed Quality chips and COT NEG/TEST chips in existing grids; seven Desktop tests; updated vendor-neutral public documentation. Windows CI, CodeQL, dependency/hygiene all green. Portable GUI binary artifact built and verified. - PR #46
d07b77c8: typed COT/P-N command verdict, source-aware protocol/circuit/CA/IOA/Type matching, SELECT/EXECUTE phase separation, feedback observed-vs-physically-proven honesty. Six synthetic Master tests. CI under review until verified and merged. - Public-repository privacy: do not introduce names, trademarks, links, identifiers or product-specific advertising for the commercial comparison instrument in repository files, docs, PR titles and new issues. Preserve clean-room IEC-standard implementation. Historical immutable Git commit messages cannot be rewritten without destructive history changes.
- Remaining for true product completeness: full raw source identity persisted into
.ariecwith offline re-decode, IEC-103/104 byte-true Inspector parity, multi-stage transaction finding navigation, structured report consistency, field hardware FAT, performance baselines and enforced non-optional formatting gate. No unsupported claim of physical interoperability equivalence.
LIVE RECONCILIATION / HANDOFF — 2026-10-29 (Asia/Jakarta)
Verified current master: baf537ae12ab8e9b0ecb4c03f44c33dfe9f4849a (merge PR #44, 2026-10-29 05:14 WIB). This is the latest verified baseline at audit time, not a pin for future work; refresh master, open PRs, and CI before implementing anything. No protocol feature PR is open at this snapshot; unrelated dependency PR #12 remains open.
Current merged progress: do not restart or overwrite
| Area | Verified implementation | Merge | Scope warning |
|---|---|---|---|
| Passive IEC-101 2/4 RX, verified journal, replay, transaction correlation, GI lifecycle, outage timeline, anomaly navigator | P0-P4A previous baseline, PRs #24–#38 | #38 0bf7b41 |
Preserve passive RX-only and original raw offsets; correlation is link/request-response, not full application command lifecycle |
| M1 typed forensic command/quality | IEC-10x raw COT/P-N/TEST/OA, C_SC/C_DC/C_RC/C_SE/C_BO command qualifier meaning, selected RTU application response ACTCON/negative/ACTTERM, DIQ/SIQ/QDS/BCR quality and element source offsets, Master/Passive/dual-link evidence | #40 668836385 |
Merged, not draft. No claim of full cross-grid SSOT or physical command action |
| M2 checkpoint Values & SOE | Protocol + physical channel + CA + IOA value identity, strict user mapping/GI logical source isolation; preserve first/repeat spontaneous observations vs known state changes; evidence source/offset/object references | #41 aa9f00937 |
Not full M2; no complete persistent Frame/ASDU/Object graph or command lifecycle |
| Trace first paint | Reset stale Hold on new session; immediate first render; bounded 1200 row ring and 75ms batched UI; structured IEC101 narrator, backpressure still visible | #42 f1b13c57a |
Real 1200-bps COM initial-paint FAT not yet proven |
| independent IEC-101 reference multiline Trace | One physical telegram = arrow/time title + Data Link + ASDU object list (as applicable) + original HEX; no duplicate raw for secondary object rows | #43 9ef09e674 |
Avoid regressing exact telegram format to generic one-line narrative |
| Readable / byte-true IEC101 Inspector | ClearType/Ideal font metrics and dark ink; selection-only pure Iec101FrameByteInspector with linked exact raw byte field groups including multiple IOAs; fallback for IEC103/104 |
#44 baf537ae1 |
IEC103/104 Inspector NOT yet equivalent; actual DPI screen/readability FAT outstanding |
Current master CI run 40778401892 reports SUCCESS: Release build; 19/19 protocol smoke; 185/185 xUnit (Core 12, Master 68, Monitor 62, Reporting 5, Desktop 23, Repository 15); Windows GUI package built. Master CodeQL 40778401780 also succeeded. Nuance / quality debt: .github/workflows/ci.yml explicitly has continue-on-error: true for dotnet format --verify-no-changes, which emitted error WHITESPACE and process exit code 1 on this very run. Thus green workflow does not mean formatting clean; do not silently certify format gate until fixed and enforced. Avoid broad unrelated mass-format in a feature PR.
Public stable release latest verified v3.6.7 (2026-06-20) does not yet represent the October changes. CI artifact != stable real-hardware FAT/release.
Accepted product requirements — do not lose
- ONE reliable typed SSOT, not a set of WPF/English-string interpreters. Immutable/on-wire Frame→Link/APCI→ASDU→Object graph, byte spans, decode profile/version, source journal/ref, typed COT/flags/time/quality/command fields, provenance and explicit unknown/absent/N/A/invalid/false states. Master, Passive, Active IEC101/103/104 (correct protocol-specific decoder), redundant link A/B, offline replay,
.ariec, report and UI must render the same decoded facts. Never invent validity or semantic class. - Full command AND RTU reply forensic interpretation is essential, not optional: C_SC, C_DC, C_RC, C_SE normalized/scaled/float, C_BO, QOI GI, QCC counter GI RQT/FRZ, read, CP56 clock sync, test/reset; qualifier raw bits SCO/DCO/RCO/QOS, SELECT vs EXECUTE, Type/CA/IOA, COT with negative/TEST/OA; application COT7/9/10/44–47 and RTU echoes, returned process status, IEC101 link FC/FCB/FCV/ACD/DFC or IEC104 I/S/U N(S)/N(R), timestamps, exact hex bytes. Link ACK != ACTCON != physical operation.
- Real source-backed command lifecycle: SELECT→RTU ACTCON→EXECUTE→RTU ACTCON→ACTTERM→optional measured/digital feedback, matching by protocol/source/channel/CA/IOA/Type/transaction context; negative, unknown, ambiguous, duplicate, unmatched, timeout and missing ACTTERM must be explicit. Passive host timing cannot be misrepresented as true wire/RTU processing time.
- ONE compact Quality column with premium lightweight badges, NEVER flag-per-column. Only actionable active states as tiny inline badges: QDS OVF, IV INVALID, BLK, SUB, NT; BCR CARRY and ADJ; 2–3 visible max and +N for extra, unobtrusive Good if demonstrably valid, dash/Unknown otherwise. SIQ/DIQ including Type31 OV=N/A (do not display OVF); BCR carry is not OV. Exact all-bit status 0/1/N/A/unknown and byte offset in inspector. COT remains ONE column with cause code/name, tiny NEG/TEST chips as needed. Quality-only changes update snapshot. No animations/heavy WPF cell trees.
- Grid completeness without noise: Trace stays exact 4-part physical telegram, multi-object ASDU loop, no silent omission by verbosity; Events show real event COT, typed flags, SOE/source/relay timestamp; Values show latest per physical source+CA+IOA; Messages show link/application response; Findings reference exact evidence; PDF/HTML/CSV/.ariec retain full typed flags/provenance, not copies of truncated display strings. Event row must link to exact FrameId/ObjectIndex/raw bytes.
- Field reliability and cost: passive zero-TX; protect FCB/polling, dual redundant A/B, full binary journal; bounded UI rings, batch flush and virtualized rows with no per-frame WPF/IO churn. Fix root causes with synthetic golden vectors and measured CPU/memory/latency; no naive patch chain. Never publish private SICAM/SCADA captures or identifiers to public repo.
Verified remaining work / next implementation sequence
- P0-A — Canonical evidence persistence: frame/ASDU/object IDs, exact raw ranges for 101/104 and protocol-specific 103, immutable typed references across all source adapters, parsed profile/version; repair selected
.ariecopen path (currentEvidenceRow(CaptureFrameSnapshot)still assigns VSQ and ObjectCount-;CaptureFrameSnapshotstores display strings instead of reconstructable parsed model). Preserve backwards compatibility with older.ariecand verified passive binary journals. - P0-B — Application command transaction correlator across active Master and Passive, with SELECT/EXECUTE/ACTCON/ACTTERM/NEG/feedback and source-aware matching, ambiguous/unmatched statuses. Reuse existing link-level passive correlator, don't duplicate it. Add Type45–64, COT, SQ/QOS and negative response/timeout golden vectors. Do not conflate link acknowledgment with process success.
- P0-C — Premium compact Quality/COT UX in Events, Values, Messages and relevant Trace entries, with typed flags (never regex parsing), one Quality cell, no additional per-flag columns; keyboard/tooltip/Inspector full 0/1/N/A support and badge rendering-performance tests. As of this audit
MainWindow.xamlstill hasDataGridTextColumn Header="Quality", andRelayEventRow/ValueRowexpose textualQuality; this work is NOT done. - P1-D — Whole-grid parity, reports, replay and provenance navigation: event click→raw Frame+Object, IEC104/103 Inspector parity, structured report/export, JSON/.ariec schema and offline re-decode from original raw+profile; preserve COT P/N/TEST/OA and quality/counters. Do not treat old
docs/UNIFIED_PROTOCOL_COMMAND_FORENSICS_M1.mdremaining checklists as all still undone: PR41/44 completed sub-parts. - P1-E — Hardening and FAT: correct
dotnet formatnon-gating status or pay down formatting debt through isolated justified change; Windows UI smoke, true first paint, crisp text at scaling 100/125/150%, 1200 bps IEC101 SICAM A8000/independent IEC-101 reference comparison, four COM A/B stress, large multi-object replay, command failure scenarios; measured CPU/allocation/RAM plateau/Stop latency. CI/portable artifacts alone do not prove physical hardware. - Keep PRs small enough to review but cross-layer correct; branch only from newly refreshed master and reconcile concurrent merges, prohibit stale PR feat(iec10x): M1 typed command/RTU response forensics and quality SSOT (#39) #40 branch reuse; minimize redundant CI runs (one coherent change batch per PR). Do not change active Master or passive transport for UI-only fixes.
Acceptance gate for claiming complete SSOT
Exact same synthetic source bytes/profile produce identical typed Type/VSQ/COT(flags)/CA/IOA/all Objects/quality/raw offsets through Active, Passive, and verified Replay; command and RTU responses display complete phase/outcome and true source bytes; Events and Values inherit same information without fabricated Good/OV; selected .ariec restores the same evidence; reports preserve it; GUI remains responsive at sustained field load. Explicitly record which assertions require physical hardware FAT.
HISTORICAL ORIGINAL ISSUE (retained verbatim after this line)
The following sections describe original pre-merge planning and are preserved for traceability. Their phrases "planning only", "draft PR #40", and unfinished M1/M2 bullet points are historical, not the current state. Refer to LIVE RECONCILIATION above first.
Unified Protocol SSOT — engineering ARD / implementation contract
Basis: audited master at 0bf7b41c53267b67c98535c849855a91c76a9860 (2026-10-28). Preserve already merged passive P0–P4A, four-RX A/B, verified raw journals/replay, Active Master IEC-101/103/104. This issue is planning only; code/CI/hardware are not implemented or claimed.
Implementation started
- Draft PR #40 — M1 typed IEC-10x command/RTU response forensics
- Branch
feat/unified-ssot-command-forensics-m1-20261028from protected baseline0bf7b41c; nomastermerge. - Typed COT/P-N/TEST/OA, command qualifier SELECT/EXECUTE and RTU outcome, SIQ/DIQ/QDS/BCR, exact ASDU information-element offsets, passive compact-HEX parser fix, IEC101 FC9 counter fix. 9 synthetic tests added.
- Status: implementation under CI review, NOT full SSOT/UI parity. Quality badge WPF templates, full command lifecycle correlation and complete report/replay/Event Log semantics remain subsequent milestones. No real-device validation claimed.
Field-driven deficiencies found in current code
Master/Iec101MasterSessionformats spaced raw HEX butDesktop/MainWindow.PassiveMonitor.csuses unspacedConvert.ToHexString(raw);FrameInspector.SplitHexBytes()depends on whitespace. Selected Monitor frame therefore loses byte-accurate FT1.2 field grouping.- Passive
DataClassis assigned only when FC10/FC11 are observed; FC8/FC9 replies lose their matched request-class context in the view. Keep requested polling class distinct from actual RTU queue class (unknown unless configured evidence). Iec10xAsduDecoderalready parses COT P/N, TEST, OA and some quality fields, butIec103MasterEvidenceEvent,RelayEventRow,ValueRow, reports and .ariec snapshots flatten/omit structured flags, source-byte spans and objects.UpdateValueAndEventViewscan drop first-observed or repeated spontaneous digital events in Active Master if no known state transition. Preserve received spontaneous event as an event fact; classify state change separately.UpdateLiveCounterscounts NO DATA by searching textNO DATA; FC9 decoder text isNo requested data available. Count typed FC=9, not English strings.- Current
.ariecsnapshot reload initializes some fields such as VSQ/object count to-even though original raw HEX is available.
Non-negotiable architecture
- One immutable on-wire raw source record per captured frame: session/source/circuit/direction, raw offset, sequence, bytes, host receipt timestamp + timing caveat, decode profile + version, integrity.
- Shared pure protocol decoder in Core for IEC-101/104 10x ASDUs, with protocol-specific IEC-103 model and FT1.2/APCI handling; no second decoder in WPF. Migrate with narrow compatibility facades rather than rewriting runtime state machines.
- Typed
FrameRecord -> AsduRecord -> ObjectRecord[]with exact field spans (offset+length), numeric COT + TEST/P-N/OA, VSQ SQ/count, object value/raw quality/time, parse status (unknown/invalid/not applicable preserved). - Derived
TransactionRecord,ObservedEventRecord,ValueSnapshot,FindingRecordonly reference source IDs and object index. No raw HEX copies per object. Source-derived flags and inference provenance distinguished. - IEC-101/104 COT: cause raw byte & 0x3F; P/N bit 6; TEST bit 7; OA from second COT byte if configured (show OA=0). Retain raw bytes and legal/unknown causes.
- Correct quality by Type ID: SIQ SPI+BL/SB/NT/IV (OV N/A); DIQ DPI+BL/SB/NT/IV (OV N/A, including Type31); QDS OV+BL/SB/NT/IV; BCR SQ/CY/CA/IV (do not label CY as QDS OV). Timestamp CP24/CP56 flags and invalidity; no silent PC-time substitution.
Unknown,False,NotApplicable,Absent,Invalidare distinct statuses. An unknown decode is notGood.- Every grid, report and export reads one model: Trace: full field tree+clickable true byte spans; Events: COT code/name/P-N/TEST/OA, correct quality bit flags (OV/CY when applicable), all observed spontaneous event objects and state-change classification; Values: latest per IOA snapshot + last COT/quality/source; Messages: request/reply transaction, FCB/FCV/ACD/DFC; Findings: typed rule, exact frame/object proof; Report/.ariec: versioned source + re-decode parity.
- Active Master must retain its transport and polling semantics; Passive Monitor must remain zero-TX; source capture can be full journal while WPF ring/window remains bounded. Never claim a complete capture if queues/disk lose data. Preserve source coverage labels.
- Performance: parse once, lazily materialize detailed inspector, batch WPF UI, preserve virtualization and bounded rings; no per-frame synchronous disk I/O, no regex-as-semantics, no naive duplicate object model copies. Measure relevant CPU/allocations/latency vs baseline, investigate >10% regressions per Master guardrails.
UX decision — compact premium flag badges, NOT separate flag columns (user clarification 2026-10-28)
- No individual OV/IV/BL/SB/NT/CY/CA/TEST/P-N/ACD/DFC columns in default or advanced Events/Values/Trace grids. Keep one compact Quality cell; flags are inline tiny semantic chips within that cell. COT remains ONE
COTcolumn:3 Spontaneousplus compactNEGorTESTinline chip only when active. Link/transaction statuses likewise remain grouped within their relevant existing cells. - Show only actionable/active flags as badges: e.g. QDS OV=1 ->
OVFamber; IV=1 ->INVALIDred; NT=1 ->NTamber; BL=1 ->BLKmuted; SB=1 ->SUBneutral; BCR CY=1 ->CARRYamber, CA=1 ->ADJmuted. When fully decoded and all applicable bad-quality flags are clear show unobtrusiveGood(or minimal dot + Good); unknown/unsupported/missing quality ->Unknown/—, never falseGood. - For DIQ/SIQ (e.g. Type31) OV does not apply: no
OVFbadge for either zero or N/A, but full inspector must explicitly show OV=Not applicable. For BCR useCARRY, not QDSOVF. Zero flags are not individually badged in the grid. - Sort flag severity and limit visible chips (e.g. 2–3) with a final compact
+Noverflow-indicator for hidden badge count only; never confuse UI+Nwith protocol OV bit. Hover/click opens tooltip/popover with all active flags and raw bits; selected row inspector always shows all flags including 0, absent, unknown, invalid, N/A, bit index and source byte offset. - Badges are small, calm, crisp, visually aligned in a single Quality column; no oversized cards, no enlarged row heights or per-row animated decorations. Use restrained semantic palette, text + color (not color alone), accessible tooltip and keyboard selection; virtualized/recycled cells and cached value converters.
- If a flag state changes without the value changing, update Values Quality cell and keep event evidence according to event COT; flag-only variations must not be discarded. All UI chips derive from typed quality/status records, never by parsing strings.
- Filtering by flag (OVF/IV/BL/NT/CY etc.) is allowed via a compact filter menu, WITHOUT making individual columns. Exports/reports must retain fully structured flags independent of compact grid display.
- Test explicit UX: normal QDS
Good; QDS OV1 =>[OVF]; QDS OV1/IV1 =>[INVALID] [OVF]; Type31 DIQ healthy =>Good(never OVF); BCR CY1 =>[CARRY]; COT TEST/NEG chips only when those bits actually set.
Mandatory command + RTU response forensic contract (added 2026-10-28)
Every command and every RTU reply must be decoded to the same engineering depth as measurement/events. This applies to IEC-101/104 and protocol-specific IEC-103 commands where defined, in Active Master, Passive Monitor and offline replay.
- Display typed command identity: Type ID/mnemonic; raw COT byte, numeric cause and name, P/N negative, TEST, OA even when OA=0; CA, all IOAs; full qualifier byte and bit meaning; raw control / APCI/FT1.2 flags.
- IEC-10x command object details by type: C_SC SCO state/S-E/QU; C_DC DCS/S-E/QU; C_RC RCS/S-E/QU; C_SE normalized/scaled/float setpoint and QOS qualifier/S-E; C_BO bitstring; GI QOI; counter GI RQT/FRZ; read IOA; clock sync CP56 + validity; test/reset raw qualifier and meaning. Preserve unknown fields without guessing.
- RTU answer must show reply phase and outcome from on-wire COT: activation confirmation COT7, negative confirmation P/N=1, deactivation confirmation COT9, activation termination COT10, unknown Type/COT/CA/IOA errors (44..47); include command echo/qualifier if present, Type/IOA, timestamps, APDU N(S)/N(R) or IEC101 FC/ACD/DFC and pending request context.
- Never treat a link-layer ACK as application-level command success. A valid COT7 means activation confirmed, not proven physical process operation; COT10/return status and value feedback must be shown separately. Timing from passive USB host receives is approximate, not true device processing latency.
- Correlation is evidence-backed: match command request/response using protocol, connection/circuit, CA, IOA, Type ID and sequence/context where possible; show matched, unmatched, ambiguous, timed out, negative, or confirmation-without-termination without inventing causality. Select-before-operate should show SELECT/EXECUTE phases with individual responses.
- No new flag columns: Quality contains compact actionable badges; COT one column with short phase and optional NEG/TEST chips; selection opens full inspector with bit-by-bit and original byte offsets.
- Acceptance fixtures: positive C_SC select COT6→COT7→execute COT6→COT7→COT10; negative P/N COT7; wrong IOA COT47; C_SE QOS SELECT; C_DC DCS; C_RC; C_IC QOI; C_CI QCC; IEC101 FC0/E5 ACK without application acceptance; IEC104 I-frame sequence; unmatched response and replay parity.
Meaningful milestone plan
M1 / P0 — Canonical typed field model + correct byte spans. Fix HEX mismatch, COT/quality/flag types, FC9 counter, E5 contextual behavior, FT1.2 0/1/2 byte addressing, Type/VSQ/IOA arrays and per-object raw offset. Test independent pure decoder first.
M2 / P0-P1 — Master/Passive/Offline parity. Source adapters feed same record model; pair request→reply without inventing data queue class; preserve received spontaneous events even first/repeated; Value snapshot updates for every information object and quality-only change; legacy .ariec re-decode.
M3 / P1 — Complete compact UX + report parity. Trace right-side expandable byte/bit map; Events/Values use ONE Quality column with conditional tiny badges for important active flags, ONE COT column with conditional NEG/TEST chips, never a column per flag; full bit tree only in inspector; double click event → exact frame object + raw bytes; Findings and PDF/HTML/CSV use identical typed record semantics.
M4 / P2 — Regression/performance/hardware release gate. Golden synthetic vectors, field-excerpt-specific tests, WPF Windows smoke exact selected-field assertions; 2/4-RX replay; memory plateau, UI responsiveness and stop/start; release only after reproducible Windows build/CI/artifact. Physical SICAM/ETERA FAT remains separate/unproven until performed.
Public acceptance vectors (sanitized; field capture stays private)
- Build synthetic, independently authored IEC-101 fixtures reflecting Class2 FC11 request followed by secondary FC8 Type31 response with COT3, DIQ and CP56Time2a, plus FC9 examples.
- Test P/N=0, TEST=0, OA=0, DIQ DPI=OFF, BL/SB/NT/IV flags, OV=N/A, ACD/DFC and exact field offsets; distinguish requested Class2 from unknown RTU queue assignment.
- Use synthetic counter fixtures including three FC9 replies to verify NO DATA counting from numeric FC, not human-readable text.
- Test VSQ SQ0/SQ1 multi-object identities and all per-object quality flags.
- Privately supplied SICAM field evidence is for local validation only. Do not upload original capture, on-wire HEX, timing, addresses or station identifiers into this public issue or public test fixture without explicit approval.
- Compare identical synthetic bytes/profile through Master, Passive, offline capture and verified replay: same typed field tree and raw spans; source and inferred correlation metadata may differ.
Repository guardrails
Read AGENTS.md, src/ARIEC60870.Core/AGENTS.md, src/ARIEC60870.Master/AGENTS.md, docs/EVENT_LOG_POLICY.md, docs/OUTPUT_AND_PERFORMANCE_POLICY.md before implementing; update policy/docs and golden tests. No proprietary IEC/vendor code copying. Protect newer commits and concurrent PRs; no blind merge.
Activity
feat(iec10x): add typed COT, quality and command response semantics (#39
feat(iec10x): preserve command COT, typed quality and ASDU offsets in…
feat(iec10x): preserve command COT, typed quality and ASDU offsets in…
feat(iec10x): project typed command/response evidence from Master and…
feat(iec10x): project typed command/response evidence from Master and…
feat(iec10x): project typed command/response evidence from Master and…
feat(iec10x): project typed command/response evidence from Master and…
feat(trace): typed command response and COT detail, normalize HEX acr…
fix(iec101): count secondary FC9 directly instead of NO DATA text (#39)
test(iec10x): synthetic command ACTCON/negative, COT flags, quality, …
test(iec10x): use explicit nullable comparisons for qualifier/quality…
docs: record M1 command evidence contract, limitations and next gates (…
feat(iec10x): include bitstring command Type51/64 and time-tagged res…
feat(iec10x): include bitstring command Type51/64 and time-tagged res…
refactor(iec10x): remove superseded duplicate textual quality decoder (…
17 remaining items
feat(wpf): bind typed quality badges and COT phase/NEG/TEST in Value …
feat(wpf): compact colorful Quality and COT flags in existing Values/…
test(wpf): QDS OVF/IV, DIQ N/A, BCR CARRY, COT NEG/TEST and grid pari…
feat(forensics): typed Quality/COT premium badges and vendor-neutral …
fix(commands): source-scoped typed RTU verdicts without false physica…
feat(capture): verified .ariec integrity and typed IEC101/104 offline…
fix(capture): retain original arrival/source/stream/object provenance…
feat(capture): typed verified archive replay with source provenance (#47
fix(commands): require trusted quality and valid RTU evidence before …
fix(commands): flag command overlaps, unpaired termination and respon…
test(commands): cover quality gating, malformed RTU replies and out-o…
fix(commands): reject untrusted and ambiguous RTU command verdicts (#48)
masarray commentedon Oct 29, 2026
LIVE UX HANDOFF — merged PR #55, 2026-10-29
Latest verified
master:4168316fe12998d08a0ac16eb32de7af034c81ba. This supersedes the PR #54 checkpoint at the top of the issue; recheckmasterbefore coding.Shipped: embedded verified official SIL-OFL Inter across GUI (raw HEX remains mono); smaller TX/RX and follow icons; same-size Inter TX/time; soft mist/slate surfaces; resume-only Follow controls (hidden when active); Events one novice-readable Value
Single Point ON/OFF,Double Point ON/OFF, original before/after retained; missing RTU timestamp shown as dash. Root autoscroll defect fixed: Events was reverse-ordered newest-first while auto-follow jumped to last/oldest. Now chronological newest-bottom and incremental WPF row reconciliation, independently holding visible Events while the bounded source ring continues. Routine duplicate COT/Type detail in Inspector removed, full semantic bits preserved.Evidence: PR #55 ; exact CI https://github.com/masarray/ARIEC60870/actions/runs/40899210395 passed 19/19 smoke and 259/259 xUnit, packaged WPF GUI and smoke. CodeQL https://github.com/masarray/ARIEC60870/actions/runs/40899210517, dependency review and hygiene passed. Portable ZIP checksum
559573a77dc831076e52f490a533fc5f8b32c3bb9738b421ce3a6ae6c028488b, artifact ID12908563158.Open quality gates: Windows physical GUI scroll/FAT at 100/125/150% DPI; quantified long-running performance/hardware interoperability. Existing 166 nonblocking formatter whitespace diagnostics remain. All public material vendor-neutral and no private captures committed.
masarray commentedon Oct 29, 2026
M5 DONE — Typed IEC-10x Command Casebook (2026-10-29)
Master
156e4e243b0d1f1c8fe725713e59c2ffcf721eff— merged PR #56. This comment supersedes earlier incomplete CMD-01 planning; refresh HEAD before writing any next thread.Functional milestone: M5 adds a bounded typed Command Casebook in Master (not another ASDU decoder, no TX), explicitly keyed to protocol, physical source, 101 link, CA, IOA, Type, OA. Exposes read-only Controls workspace with stage table, selected case interpretation, Copy Case for Analysis (host time, evidence refs, original HEX), and Open Source Frame (exact physical source + frame sequence). Verified offline
.ariecreopens and regenerates observed cases, marking an incomplete excerpt Observed incomplete rather than a hardware timeout. Report PDF metadata and Markdown evidence include case summary/negative/ambiguous findings.Reliable acceptance: SELECT → ACTCON → EXECUTE → ACTCON → feedback/ACTTERM in either order; P/N negative and COT44–47; overlapping repeated requests ambiguous (no last-wins); A/B source isolation; bad-quality/wrong-target/unmapped digital feedback never accepted; link ACK and ACTCON/ACTTERM alone not physical proof. Old duplicated WPF command ledger and arbitrary fixed 8-second timeout removed. UI preview bounded; passive monitor RX-only remains.
Gates exact PR head
1a818c1f5540ad0a97e4c52511d8aefbdb84742f: CI #40905175119 PASS, 19/19 protocol smoke, 274/274 xUnit, Windows Release/WPF GUI smoke, CodeQL, Dependency Review, Repository Hygiene PASS. Artifact ID12911971001; user Windows inner ZIP SHA256d138eff79e748d662f01bbd9fd9327ebb8042f779f61ccd21f33355092aa26f7, matched CISHA256SUMS.txt, outer+inner CRC clean.Honest limitations: formatting stage remains nonblocking (192 WHITESPACE logs, continue-on-error); no physical serial FAT or real Windows DPI/long-run signoff. IEC103 native controls, cross-reconnect 104 session identity, multiday signed canonical IDs, per-stage PDF appendix and all-vendor lab interop remain future work. Keep GUI premium/quiet and no commercial comparison tool names in public repo.
Next BIG milestone (not cosmetic): canonical raw Frame → ASDU → Object identity and archive replay/report equivalence + full physical IEC101/104 controlled command FAT, separating observed protocol confirmation from actual target switchgear feedback. Read
docs/M5_COMMAND_CASEBOOK_20261029.mdand canonical interoperability ARD/PRD.masarray commentedon Oct 29, 2026
LIVE ENGINEERING HANDOFF — R2-A merged 2026-10-30
Current verified master:
0e36328d1892e074c63dd917c43c260015229b4f(merged PR #57). Previous issue-body checkpoints are historical. PR #56 already delivered M5 source-qualified Control Casebook; do NOT duplicate the command transaction correlator.R2-A delivered (not only documentation):
Iec10xInteroperabilityProfileinMaster/Model, schema-v1 strict JSON import/export, explicit generic vs historical NUC101/NUC104 reference, protocol/edition/widths/mode/GI policy and stable fingerprint; malformed, unsupported, forged national-convention claim and unknown settings rejected.BuildSettingsFromUiinvokesValidateActivebefore active transport startup; enforce IEC104 fixed ASDU widths/TCP, IEC101 supported unbalanced master/addresses, IEC103 fixed supported field widths, profile-protocol consistency. Clear error instead of unsafe TX. Legacy passive monitor RX-only, replay and verified original archive untouched.9b509dba52a80946e7e230c61da3fbc4117792c3.12932572590; standalone inner ZIP SHA256f77b141e0972a6643783d6966190fc91d5b2d8736da5b32813c474d0348af220, CRC verified and matches CI SHA256SUMS. Formatting check still non-blocking with 206 whitespace diagnostics; do not report it clean.Next meaningful milestone R2-B: validated custom-project profile import/export in GUI with explicit diff/preview, field-width/version persistence in capture replay, typed reinterpretation parity across Trace/Events/Values/Report without changing raw hashes; no silent profile upgrades. Follow with R3 physical serial 2/4-COM FAT, DPI/perf and evidence of interoperability. Reconcile master before opening new branch; public repo remains neutral and free of private field captures.