📝 Documenation
This commit is contained in:
+110
@@ -0,0 +1,110 @@
|
|||||||
|
# Changelog
|
||||||
|
|
||||||
|
All notable changes to the **AquaCom Integration Gateway** project are documented in this file.
|
||||||
|
|
||||||
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to
|
||||||
|
[Semantic Versioning](https://semver.org/spec/v2.0.0.html). Until the first implementation release, changes are
|
||||||
|
grouped per working session; version numbers begin with the first production-capable release (roadmap G14, see
|
||||||
|
[ExecPlan 001](docs/exec-plans/active/001-implementation-roadmap.md)).
|
||||||
|
|
||||||
|
## [Unreleased]
|
||||||
|
|
||||||
|
### 2026-10-06 — Project surface
|
||||||
|
|
||||||
|
#### Added
|
||||||
|
|
||||||
|
- `README.md` — project overview: capabilities, architecture summary (Mermaid), documentation map with
|
||||||
|
precedence, protocol-evidence policy, current repository layout, status checklist, third-party copyright
|
||||||
|
notice for the vendor protocol document, license placeholder.
|
||||||
|
- `CHANGELOG.md` — this file.
|
||||||
|
- `docs/exec-plans/active/001-implementation-roadmap.md` — **ExecPlan 001, the umbrella implementation
|
||||||
|
roadmap**: verified current-state snapshot; open decisions D-001 (technology selection — blocking) through
|
||||||
|
D-006; phase/gate table for Phases 0–14 (G0–G14) with exit criteria and gap dependencies; §79 task mapping
|
||||||
|
(T001–T020); protocol-gap consumption schedule; failure-handling, testing and compatibility commitments;
|
||||||
|
progress log; decisions log (DR-001…DR-011); acceptance-evidence plan for the §77 DoD.
|
||||||
|
|
||||||
|
### 2026-10-05 — Protocol evidence layer
|
||||||
|
|
||||||
|
#### Added
|
||||||
|
|
||||||
|
- `docs/protocol/AquaCom_RTU_1_6_eng.pdf` — authoritative AquaCom protocol source: *Technical description –
|
||||||
|
AquaCom – RTU level*, Rev 1.6, ITT Flygt AB, July 2004 (evidence class: SPECIFICATION).
|
||||||
|
- `docs/protocol/AquaCom_RTU_1_6_eng_markdown/` — markdown conversion of the source (lossy at specific
|
||||||
|
tables; PDF is authoritative — see gap registry AQ-GAP-001).
|
||||||
|
- `docs/protocol/known-operations.md` — operations registry: OPS-001…OPS-012 (session ops OK/BRK/EBR/caller-ID;
|
||||||
|
live WGS; alarms WCA/ALR/ALN/ALO; history WGH; reports WGD; configuration MCC/MAS/MAT/SLT; fixed answers
|
||||||
|
SCO/SCE/NDA/Wait), each with evidence sections, scope status (control/setpoint writes OUT-OF-SCOPE) and an
|
||||||
|
evidence-complete implementation order.
|
||||||
|
- `docs/protocol/protocol-gaps.md` — gap registry with 10 entries (AQ-GAP-001…010) in the mandated entry format,
|
||||||
|
including working hypotheses for WGS `alp` semantics and WGH block value counts.
|
||||||
|
- `docs/protocol/test-vectors.md` — test-vector catalogue: **35 source checksum vectors verified by
|
||||||
|
recomputation** against the §2.4 algorithm (including the §3.6.4 Wait-byte pair), framing/session vectors,
|
||||||
|
WGS/WGH/WGD decode scenarios, simulator scenario requirements, and 4 synthetic vectors covering the 16-bit
|
||||||
|
wraparound branches (values computed and verified).
|
||||||
|
|
||||||
|
#### Verified
|
||||||
|
|
||||||
|
- Checksum algorithm (§2.4): exact match on all 35 single-line source examples — confirms summed range
|
||||||
|
(after SOH/STX, excluding `#`), space inclusion around `#`, and Wait-byte (DC3) exclusion.
|
||||||
|
- §3.6.4 Wait-byte pair: both forms sum to 2925 — proves in-telegram Wait bytes must be stripped and are
|
||||||
|
excluded from the checksum.
|
||||||
|
|
||||||
|
#### Found (in the 2004 source document)
|
||||||
|
|
||||||
|
- MAT fetch request prints checksum 557; recomputes to 540 (557 is the SLT fetch checksum — copy-paste error).
|
||||||
|
The MAT fetch answer verifies exactly (353).
|
||||||
|
- Narrative/destination mismatches in examples (§2.2.3.1 "plant number 89" vs telegram dest 86; §3.4.10.2
|
||||||
|
fixed-line dest given as plant number).
|
||||||
|
- WCA hour range typo (0–24 vs ALR's 0–23).
|
||||||
|
- All findings recorded in the gap registry with handling instructions; none block implementation.
|
||||||
|
|
||||||
|
### 2026-10-05 — Documentation baseline (commit `08d44ba`, "Update documents")
|
||||||
|
|
||||||
|
#### Fixed
|
||||||
|
|
||||||
|
- **Markdown formatting restored in all five guidance documents** — the files had been JSON-escaped
|
||||||
|
(`\#`, `\*\*`, ` ` entities, `# `-prefixed lines in `ARCHITECTURE.md`, double-escaping in the
|
||||||
|
implementation specification). Approximately 25,500 lines of escaped text normalized to clean Markdown;
|
||||||
|
verified zero residual artifacts.
|
||||||
|
|
||||||
|
#### Changed
|
||||||
|
|
||||||
|
- `AGENTS.md` reduced from a 35-section duplicate specification (1,403 lines) to the short entry-point form
|
||||||
|
(≈70 lines) its own specification mandates (§4/§6): document table with roles, non-negotiable rules,
|
||||||
|
evidence rules, testing/security/uncertainty guidance.
|
||||||
|
- `ARCHITECTURE.md` §1 now defines **document roles and precedence** (software-spec = requirements;
|
||||||
|
ARCHITECTURE = structure; implementation-spec = process; configuration-reference = config semantics;
|
||||||
|
`AGENTS.md` never overrides).
|
||||||
|
- Watermark semantics defined precisely (§21): advances on **durable spool commit**, not final delivery —
|
||||||
|
new invariants INV-013…INV-016 added (out-of-order arrival, watermark scope, dedup across restart,
|
||||||
|
timestamp quarantine).
|
||||||
|
- `software-specification.md`: RFC 2119 keyword definitions added (§2); `REJECT_CONFLICT` made the default
|
||||||
|
duplicate strategy (§13); missing-timestamp records **quarantined with diagnostics** (§10); shared/multi-drop
|
||||||
|
transport requirement with arbitration (§5.1); repository interface naming aligned to `ARCHITECTURE.md` §25.
|
||||||
|
- Implementation specification made agent-neutral ("the implementation agent"); config-key naming aligned
|
||||||
|
(`maxValuesPerRead`); conflict-policy mapping documented; **evidence-acquisition plan** added (§17) —
|
||||||
|
resolved the next day by the arrival of the Rev 1.6 source.
|
||||||
|
- `configuration-reference.md`: default storage routing made deterministic (§60); overflow policies that
|
||||||
|
discard data must emit diagnostics (§27.5); administrative channel defined as config-file mechanism until
|
||||||
|
a real interface is specified (§81).
|
||||||
|
|
||||||
|
#### Added
|
||||||
|
|
||||||
|
- `missing_docs.md` — registry of planned documents that do not exist yet, with references and priorities;
|
||||||
|
updated as items are created.
|
||||||
|
|
||||||
|
### 2026-10-05 — Initial documentation set (commit `fbec27f`, "Initial commit")
|
||||||
|
|
||||||
|
#### Added
|
||||||
|
|
||||||
|
- `ARCHITECTURE.md` — system structure, boundaries, canonical model, timestamp discipline, historical
|
||||||
|
pipeline, OPC UA architecture, invariants INV-001…INV-012.
|
||||||
|
- `docs/product/software-specification.md` — functional requirements with design objectives and the
|
||||||
|
requirement summary table (AQG-001…AQG-030).
|
||||||
|
- `docs/product/codex-implementation-specification.md` — implementation process: phases 0–14, task sizing,
|
||||||
|
test pyramid, completion criteria, ExecPlan requirements.
|
||||||
|
- `docs/configuration/configuration-reference.md` — full configuration model with field-by-field
|
||||||
|
semantics, validation rules and examples.
|
||||||
|
- `AGENTS.md` (original, long form — replaced in the 2026-10-05 documentation-baseline session above).
|
||||||
|
|
||||||
|
[Unreleased]: https://example.invalid/aquacom-gateway/compare/initial-commit...HEAD
|
||||||
@@ -0,0 +1,126 @@
|
|||||||
|
# AquaCom Integration Gateway
|
||||||
|
|
||||||
|
The **AquaCom Integration Gateway** connects AquaCom-compatible field equipment (legacy MacTec-standard RTUs used in pump stations and similar water-utility installations) to modern OT/IT systems.
|
||||||
|
|
||||||
|
The gateway:
|
||||||
|
|
||||||
|
- communicates with AquaCom stations over TCP or serial transports;
|
||||||
|
- acquires **current (live) process values**;
|
||||||
|
- retrieves **historical process values** recorded in the field equipment;
|
||||||
|
- normalizes everything into a protocol-independent canonical data model;
|
||||||
|
- exposes current values through **OPC UA Data Access**;
|
||||||
|
- exposes historical values through **OPC UA Historical Access**;
|
||||||
|
- delivers history to one or more **independent, configurable storage destinations**;
|
||||||
|
- recovers historical data automatically after communication interruptions (watermark-based backfill with store-and-forward buffering);
|
||||||
|
- provides operational and protocol **diagnostics**.
|
||||||
|
|
||||||
|
It is deliberately an *integration gateway*, not merely an OPC UA server: the long-term asset is the normalized information layer and the historical recovery mechanism, so OPC UA, the storage technology, and the AquaCom equipment can each evolve or be replaced independently.
|
||||||
|
|
||||||
|
> **Status: specification & planning phase.**
|
||||||
|
> This repository currently contains the complete documentation set, the verified protocol evidence, and the implementation roadmap. Runtime code does not exist yet — implementation begins with Phase 0 of the [implementation roadmap](docs/exec-plans/active/001-implementation-roadmap.md).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Architecture
|
||||||
|
|
||||||
|
```mermaid
|
||||||
|
graph TB
|
||||||
|
RTU[AquaCom stations / RTUs] --> TR[AquaCom Transport]
|
||||||
|
TR --> PE[AquaCom Protocol Engine]
|
||||||
|
PE --> SM[Station / Session Manager]
|
||||||
|
SM --> CM[Canonical data model]
|
||||||
|
|
||||||
|
CM --> CS[Current-State Service]
|
||||||
|
CM --> HAM[Historical Acquisition Manager]
|
||||||
|
HAM --> HP[Historical pipeline: validate → deduplicate → durable spool]
|
||||||
|
HP --> REPO[(History repository)]
|
||||||
|
HP --> SINKS[(Storage sinks A…N)]
|
||||||
|
|
||||||
|
CS --> SRV[OPC UA server: Data Access + Historical Access + diagnostics]
|
||||||
|
REPO --> SRV
|
||||||
|
SRV --> CLIENTS[SCADA / historian / analytics clients]
|
||||||
|
```
|
||||||
|
|
||||||
|
Core architectural rules (normative in [`ARCHITECTURE.md`](ARCHITECTURE.md)):
|
||||||
|
|
||||||
|
- AquaCom protocol parsing lives only in the AquaCom modules; no OPC UA, history or storage code touches a telegram.
|
||||||
|
- Data crosses subsystem boundaries only through the canonical model.
|
||||||
|
- A historical sample describes the process **at its SourceTimestamp** — it never becomes a current value merely because it was recently received.
|
||||||
|
- OPC UA Historical Access queries the gateway's history repository; a client `HistoryRead` never triggers AquaCom traffic.
|
||||||
|
- `StationId`, `PointId` and OPC UA NodeIds remain stable across restart, upgrade, renaming and transport-address changes.
|
||||||
|
- Live acquisition takes priority over bulk historical backfill.
|
||||||
|
|
||||||
|
## Documentation
|
||||||
|
|
||||||
|
| Document | Role |
|
||||||
|
|---|---|
|
||||||
|
| [`AGENTS.md`](AGENTS.md) | Entry point for coding agents and contributors — pointers and non-negotiable rules |
|
||||||
|
| [`ARCHITECTURE.md`](ARCHITECTURE.md) | System structure, boundaries, interfaces, invariants — also defines document precedence (§1) |
|
||||||
|
| [`docs/product/software-specification.md`](docs/product/software-specification.md) | Functional requirements — what the gateway shall do |
|
||||||
|
| [`docs/product/codex-implementation-specification.md`](docs/product/codex-implementation-specification.md) | Implementation process: phases, task sizing, testing strategy, completion criteria |
|
||||||
|
| [`docs/configuration/configuration-reference.md`](docs/configuration/configuration-reference.md) | Configuration model, fields, defaults, validation rules |
|
||||||
|
| [`docs/protocol/`](docs/protocol) | AquaCom protocol knowledge: evidence, operation registry, gap registry, test vectors |
|
||||||
|
| [`docs/exec-plans/active/001-implementation-roadmap.md`](docs/exec-plans/active/001-implementation-roadmap.md) | Implementation roadmap (ExecPlan 001): phases 0–14, gates, decisions |
|
||||||
|
| [`missing_docs.md`](missing_docs.md) | Planned documents that do not exist yet |
|
||||||
|
|
||||||
|
When documents overlap, the precedence defined in `ARCHITECTURE.md` §1 applies: the software specification for *requirements*, `ARCHITECTURE.md` for *structure*, the implementation specification for *process*, the configuration reference for *configuration semantics*. No other document overrides them.
|
||||||
|
|
||||||
|
## Protocol evidence
|
||||||
|
|
||||||
|
The AquaCom implementation is strictly **evidence-based**: telegram framing, checksums, operations, addressing, timestamp encoding and historical-data semantics may only be implemented from verified evidence (the authoritative vendor protocol description, validated traffic captures, or known-good implementations). Unknown protocol behavior is recorded in the [gap registry](docs/protocol/protocol-gaps.md) — never guessed.
|
||||||
|
|
||||||
|
| Document | Content |
|
||||||
|
|---|---|
|
||||||
|
| [`docs/protocol/AquaCom_RTU_1_6_eng.pdf`](docs/protocol/AquaCom_RTU_1_6_eng.pdf) | Authoritative source: *Technical description – AquaCom – RTU level*, Rev 1.6, ITT Flygt AB, July 2004 |
|
||||||
|
| [`docs/protocol/known-operations.md`](docs/protocol/known-operations.md) | Registry of implementable operations, each with evidence and scope status |
|
||||||
|
| [`docs/protocol/protocol-gaps.md`](docs/protocol/protocol-gaps.md) | Open protocol questions with working hypotheses and workarounds |
|
||||||
|
| [`docs/protocol/test-vectors.md`](docs/protocol/test-vectors.md) | Checksum-verified test vectors for the codec (35 source vectors recomputed and confirmed) |
|
||||||
|
|
||||||
|
## Repository layout
|
||||||
|
|
||||||
|
```text
|
||||||
|
.
|
||||||
|
├── AGENTS.md # entry point for agents / contributors
|
||||||
|
├── ARCHITECTURE.md # system structure, boundaries, invariants
|
||||||
|
├── README.md # this file
|
||||||
|
├── missing_docs.md # planned documents not yet created
|
||||||
|
└── docs/
|
||||||
|
├── architecture/ # detailed subsystem architecture (planned)
|
||||||
|
├── configuration/
|
||||||
|
│ └── configuration-reference.md
|
||||||
|
├── exec-plans/
|
||||||
|
│ └── active/
|
||||||
|
│ └── 001-implementation-roadmap.md
|
||||||
|
├── product/
|
||||||
|
│ ├── software-specification.md
|
||||||
|
│ └── codex-implementation-specification.md
|
||||||
|
└── protocol/
|
||||||
|
├── AquaCom_RTU_1_6_eng.pdf # authoritative protocol source
|
||||||
|
├── AquaCom_RTU_1_6_eng_markdown/ # markdown conversion (lossy — see gap registry)
|
||||||
|
├── known-operations.md
|
||||||
|
├── protocol-gaps.md
|
||||||
|
└── test-vectors.md
|
||||||
|
```
|
||||||
|
|
||||||
|
## Current status and next steps
|
||||||
|
|
||||||
|
- [x] Complete, consistent specification and architecture documentation
|
||||||
|
- [x] Protocol evidence acquired and catalogued; 35 checksum vectors verified by recomputation
|
||||||
|
- [x] Implementation roadmap (ExecPlan 001) with phase gates and decision log
|
||||||
|
- [ ] **Technology selection** (decision D-001): implementation language + OPC UA server stack — server-side Historical Access support is the make-or-break capability to verify per candidate
|
||||||
|
- [ ] Phase 0: repository skeleton, CI, configuration schema
|
||||||
|
- [ ] Phases 1–14 per the [roadmap](docs/exec-plans/active/001-implementation-roadmap.md)
|
||||||
|
|
||||||
|
## Getting started
|
||||||
|
|
||||||
|
**Reading the project** (suggested order): this file → [`ARCHITECTURE.md`](ARCHITECTURE.md) → [`docs/product/software-specification.md`](docs/product/software-specification.md) → the [roadmap](docs/exec-plans/active/001-implementation-roadmap.md).
|
||||||
|
|
||||||
|
**Contributing / implementing**: read [`AGENTS.md`](AGENTS.md) first — it defines the evidence rules, architectural boundaries, testing requirements and the ExecPlan process that all substantial work must follow.
|
||||||
|
|
||||||
|
## Third-party material
|
||||||
|
|
||||||
|
The AquaCom protocol description under `docs/protocol/` is a third-party copyrighted document (© 2004 ITT Flygt AB). It is kept in this repository for internal engineering reference; do not redistribute it outside your organization without the copyright holder's permission.
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
Not yet chosen. Licensing will be decided before the first public release of implementation code.
|
||||||
@@ -0,0 +1,189 @@
|
|||||||
|
# ExecPlan 001 — Implementation Roadmap: AquaCom Integration Gateway
|
||||||
|
|
||||||
|
**Document type:** ExecPlan (umbrella roadmap)
|
||||||
|
**Status:** Active
|
||||||
|
**Created:** 2026-10-06
|
||||||
|
**Scope:** Phases 0–14 (implementation specification §60) through the initial production release
|
||||||
|
**Authoritative references:** `ARCHITECTURE.md` · `docs/product/software-specification.md` · `docs/product/codex-implementation-specification.md` · `docs/configuration/configuration-reference.md` · `docs/protocol/` (gap registry, operations registry, test vectors)
|
||||||
|
|
||||||
|
> This is the **umbrella plan**: it sequences the whole implementation and records cross-phase decisions. Substantial individual features may spawn focused child ExecPlans in this directory (implementation specification §59); this roadmap remains the index. Per `ARCHITECTURE.md` §1, role-authoritative documents win over any restatement here.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 1. Purpose
|
||||||
|
|
||||||
|
Provide a single, gated execution path from the current documentation-complete, evidence-prepared repository state to the initial production release defined by `software-specification.md` §47 / implementation specification §74, such that:
|
||||||
|
|
||||||
|
- every implemented AquaCom behavior traces to verified evidence (`AGENTS.md`, `known-operations.md`);
|
||||||
|
- each phase ends in a working, testable repository state (implementation specification §79);
|
||||||
|
- the one open blocking decision (technology selection) is resolved explicitly and recorded before code begins;
|
||||||
|
- protocol gaps are consumed at the phase that needs them, with documented workarounds where possible.
|
||||||
|
|
||||||
|
## 2. Current state (2026-10-06)
|
||||||
|
|
||||||
|
**Exists and verified:**
|
||||||
|
|
||||||
|
- Complete, consistent documentation set: short-form `AGENTS.md` entry point; `ARCHITECTURE.md` with document precedence (§1) and invariants INV-001…INV-016; `software-specification.md` with requirement IDs AQG-001…AQG-030 and RFC-2119 keywords; agent-neutral implementation specification; `configuration-reference.md`.
|
||||||
|
- Protocol evidence: authoritative source (*AquaCom – RTU level, Rev 1.6, ITT Flygt AB, 2004*) as PDF + markdown conversion in `docs/protocol/`.
|
||||||
|
- `docs/protocol/protocol-gaps.md` — 10 entries (1 `VERIFY`, 9 `OPEN`), each with working hypotheses where applicable.
|
||||||
|
- `docs/protocol/known-operations.md` — OPS-001…OPS-012 registered with evidence sections, scope status, and an evidence-complete implementation order.
|
||||||
|
- `docs/protocol/test-vectors.md` — **35 source checksum vectors verified by recomputation** against the §2.4 algorithm (including the §3.6.4 Wait-byte pair), framing/session vectors, 4 synthetic wraparound vectors, WGS/WGH/WGD decode scenarios, simulator scenario requirements.
|
||||||
|
|
||||||
|
**Does not exist yet:** `src/`, `tests/`, `simulator/`, `schemas/`, `config/`, CI, `README.md`, `CHANGELOG.md`, any implementation.
|
||||||
|
|
||||||
|
**Open:** technology selection (decision D-001 below) — the only blocking item.
|
||||||
|
|
||||||
|
## 3. Desired state
|
||||||
|
|
||||||
|
The initial production scope (implementation specification §74): verified live and historical AquaCom acquisition for multiple stations; canonical data model; live cache; historical pipeline with deduplication and durable spool; ≥1 queryable history repository; ≥2 independently configurable storage destinations; OPC UA Data Access + Historical Access with stable NodeIds and security on by default; diagnostics and structured logging; simulator; automated tests including restart recovery; configuration validation. Explicitly excluded: process control, setpoint writes, OPC UA HistoryUpdate, HA clustering (implementation specification §75).
|
||||||
|
|
||||||
|
## 4. Constraints
|
||||||
|
|
||||||
|
Hard rules that bind every phase (traceability in parentheses):
|
||||||
|
|
||||||
|
1. Never invent AquaCom protocol behavior; evidence classes only (`AGENTS.md`; implementation specification §3.1).
|
||||||
|
2. AquaCom logic only in `src/aquacom`; OPC UA and storage never parse telegrams (INV-001/002/003).
|
||||||
|
3. Historical samples never update current state (INV-004); SourceTimestamp preserved (INV-005).
|
||||||
|
4. OPC UA HistoryRead queries a repository, never the RTU (INV-006).
|
||||||
|
5. Storage failure never stops live acquisition (INV-007).
|
||||||
|
6. Stable StationId/PointId/NodeIds across restart, upgrade, rename, transport change (INV-008/009).
|
||||||
|
7. Watermark advances on durable spool commit (INV-014); dedup correct across restart (INV-015).
|
||||||
|
8. Out-of-order historical arrival supported (INV-013); missing-timestamp records quarantined (INV-016).
|
||||||
|
9. Live acquisition priority over backfill (AQG-028); every queue bounded (ARCHITECTURE §51).
|
||||||
|
10. Secure defaults; no secrets in the repo (`AGENTS.md` Security).
|
||||||
|
|
||||||
|
## 5. Open decisions
|
||||||
|
|
||||||
|
| ID | Decision | Blocks | Recommendation / resolution path |
|
||||||
|
|---|---|---|---|
|
||||||
|
| **D-001** | Implementation language + OPC UA server stack | **Phase 1 (all code)** | The hard constraint is **server-side Historical Access** (Part 11) — far less commonly supported than Data Access. Run a HistoryRead smoke test per candidate before committing. Candidates in priority order: C#/.NET (OPC Foundation .NET Standard stack — reference HA implementation), Java/Milo (HA supported), Python/asyncua (fast development; **verify HA server completeness first**). |
|
||||||
|
| D-002 | Configuration format | Phase 0 (schema skeleton) | YAML — all examples in `configuration-reference.md` are already YAML. Low risk. |
|
||||||
|
| D-003 | First history repository technology | Phase 8 | Behind the `HistoryRepository` interface (ARCHITECTURE §25), so replaceable. Embedded (e.g. SQLite) minimizes external dependencies for the first release; external (PostgreSQL/TimescaleDB) remains a valid Phase 12+ sink. Decide at Phase 8 entry. |
|
||||||
|
| D-004 | Second storage sink technology | Phase 12 | NDJSON file archive is the lowest-risk second destination (config examples already use it). Decide at Phase 12 entry. |
|
||||||
|
| D-005 | CI platform | Phase 0 | Whatever the repository host provides; must run format/lint/static/unit/integration + schema validation without network access (implementation specification §57). |
|
||||||
|
| D-006 | Configuration schema technology | Phase 0 | JSON Schema if D-002 = YAML (standard YAML-schema validation path). |
|
||||||
|
|
||||||
|
**Pre-implementation checklist (project owner, in order):**
|
||||||
|
|
||||||
|
1. **Resolve D-001.** I can build and run the HA smoke test for each candidate stack on request — a ~50-line HistoryRead server+client per candidate settles it empirically.
|
||||||
|
2. **PDF spot-checks** (~30 min, recommended before Phase 3/6; non-blocking for Phases 0–2): confirm AQ-GAP-001(a) MCC type table, (b) WGS answer `mp1–mp128` byte ranges, (e) whether §3.7 truly ends mid-telegram; AQ-GAP-002 whether the PDF defines `alp` more explicitly; AQ-GAP-006 whether the MAT request really prints 557.
|
||||||
|
3. **Confirm deployment target**: OS/host, and whether field contact is TCP via terminal server (serial-over-IP) or direct serial — determines which Phase 2 transports to implement first.
|
||||||
|
|
||||||
|
**What does *not* block starting:** real RTU hardware or captures (the simulator drives Phases 0–13; every gap that would need a live capture has a documented workaround), `aquacom.md` consolidation, operations documentation (Phase 14).
|
||||||
|
|
||||||
|
## 6. Implementation sequence
|
||||||
|
|
||||||
|
### 6.1 Phase/gate overview
|
||||||
|
|
||||||
|
| Phase | Scope (§60) | Gate — exit criteria | Key gap dependency |
|
||||||
|
|---|---|---|---|
|
||||||
|
| **0** | Repository skeleton, CI, README/CHANGELOG, config schema skeleton | **G0:** CI green on placeholder test; schema validates the §72 minimal config; tree matches implementation specification §5 | — |
|
||||||
|
| **1** | Canonical core: StationId, PointId, CurrentValue, HistoricalSample, DataQuality, AcquisitionSource, config domain | **G1:** domain unit tests + serialization round-trips pass; identifier-stability rule enforced (rename ≠ new PointId); `core` has zero aquacom/opcua/storage imports | — |
|
||||||
|
| **2** | Transport abstraction + mock transport; TCP first (serial-over-IP per deployment answer) | **G2:** connect/send/receive/timeout/reconnect tests pass; supports shared-medium arbitration (software-specification §5.1) | — |
|
||||||
|
| **3** | Codec framework: framing, checksum, Wait-byte stripping, validation, fixture framework | **G3:** **100 % of approved vectors green** (AQ-CK-001…035, S1–S4, framing vectors AQ-FR-001…005); invalid telegrams rejected with diagnostics | AQ-GAP-001 (`VERIFY` items against PDF) |
|
||||||
|
| **4** | AquaCom simulator | **G4:** scripted WGS success/timeout/malformed/checksum-error/configurable values; **no shared codec code** (self-validation ban, §49) | — |
|
||||||
|
| **5** | Station/session manager | **G5:** multiple simulated stations; one failing station does not affect others; state machine per §18; configurable thresholds | — |
|
||||||
|
| **6** | Live acquisition: WGS decode → point mapping → scaling → CurrentValue | **G6:** simulator → CurrentValue with correct value, quality, timestamps (Source vs Received distinguished); scaling formula applied; alarm/point split via `Nal` | AQ-GAP-002 (workaround: decode via `Nal`, `alp` diagnostic-only) |
|
||||||
|
| **7** | OPC UA live interface: DA, subscriptions, stable NodeIds, security | **G7:** OPC UA test client browses/reads/subscribes; NodeIds stable across restart; security `None` disabled | — |
|
||||||
|
| **8** | Local historical repository (first queryable store) | **G8:** store / query interval / bounds / restart persistence behind the §25 interface | — |
|
||||||
|
| **9** | Historical pipeline: validation → dedup → durable spool → distribution | **G9:** duplicate submissions produce no duplicate records (idempotent across restart, INV-015); spool survives restart; out-of-order writes accepted (INV-013) | — |
|
||||||
|
| **10** | AquaCom historical acquisition: WGH retrieval, watermark, backfill state machine, throttling | **G10:** simulator's missing interval recovered after reconnect; watermark resumes from persistent state; backfill throttled so live polling stays responsive | AQ-GAP-003 (hypothesis: block value count from station CFG — validate against simulator) |
|
||||||
|
| **11** | OPC UA Historical Access: HistoryRead raw values, continuation | **G11:** HA client reads both originally stored and recovered values; continuation works; **INV-006 test: HistoryRead never triggers AquaCom traffic** | — |
|
||||||
|
| **12** | Second storage destination (sink abstraction) | **G12:** one HistoricalSample → repository + sink B; failure of B does not stop A | — |
|
||||||
|
| **13** | Store-and-forward resilience | **G13:** destination offline → history accumulates → delivered on restore; restart during backlog loses no acknowledged data (§53) | — |
|
||||||
|
| **14** | Production hardening: security, resource limits, performance validation, ops documentation | **G14:** §77 DoD reviewed item-by-item; §69 performance validation with capacity targets recorded | — |
|
||||||
|
| **O-1** (optional, after 10) | WGD periodical reports (`AQUACOM_REPORT`) | report day retrieved, scaled per point, `NDA` handled as missing-not-failed | AQ-GAP-009 (documented defaults) |
|
||||||
|
|
||||||
|
### 6.2 Task mapping (implementation specification §79)
|
||||||
|
|
||||||
|
T001→P0 · T002→P1 · T003→P0/P1 (config model + schema validation) · T004→P2 · T005+T006→P3 · T007→P4 · T008→P6 (WGS, first verified live operation) · T009→P5/P6 · T010→P6 (current-state service) · T011→P7 · T012→P8 · T013→P9 · T014→P9/P13 (durable spool) · T015+T016→P10 (WGH + backfill state machine) · T017→P11 · T018→P12 · T019→P13 (full reconnect/backfill acceptance) · T020→P14.
|
||||||
|
|
||||||
|
Each task ends in a working repository state. Recommended task granularity: one §79-sized task per working session, each with the Goal / Files / Behavior / Constraints / Tests / Acceptance structure (§61).
|
||||||
|
|
||||||
|
### 6.3 Gap consumption schedule
|
||||||
|
|
||||||
|
| Gap | Consumed at | Handling |
|
||||||
|
|---|---|---|
|
||||||
|
| AQ-GAP-001 | before Phase 3 table implementations | `VERIFY` against PDF; 35 approved vectors already cover framing/checksum |
|
||||||
|
| AQ-GAP-002 | Phase 6 | workaround documented (decode via `Nal`); hypothesis strengthened by all four examples |
|
||||||
|
| AQ-GAP-003 | Phase 10 | hypothesis wired to station CFG; simulator validation; close on first real capture |
|
||||||
|
| AQ-GAP-004 | text points (none in initial scope) | deferred |
|
||||||
|
| AQ-GAP-005 | any time PDF text is available | transcribe long examples → recompute → approve as wraparound fixtures (synthetics cover the branch meanwhile) |
|
||||||
|
| AQ-GAP-006 | Phase 3 fixture import | use 540 once PDF-confirmed; verified answer vector approvable independently |
|
||||||
|
| AQ-GAP-007 | SCE handling (Phase 3/6) | payload treated as optional diagnostic, never parse-critical |
|
||||||
|
| AQ-GAP-008/009/010 | dialled lines / WGD / alarms | extension scope; not in initial release |
|
||||||
|
|
||||||
|
## 7. Files/components affected
|
||||||
|
|
||||||
|
`src/{core,aquacom,history,storage,opcua,diagnostics,host}/` per `ARCHITECTURE.md` §6 and dependency direction §7 · `tests/{unit,integration,protocol,opcua,history,acceptance}/` · `simulator/` · `fixtures/` (imported from `docs/protocol/test-vectors.md`) · `schemas/` · `config/examples/` · `README.md`, `CHANGELOG.md` · CI definition · documentation updates in `docs/` as behavior lands (never after).
|
||||||
|
|
||||||
|
## 8. Data model changes
|
||||||
|
|
||||||
|
None yet — the canonical contracts are frozen in `ARCHITECTURE.md` §13–§14 and implementation specification §10–§13. Any contract change requires: update the role-authoritative document first, update dependents, update tests, record the decision here. The core module must compile without AquaCom/OPC UA/storage imports (enforced in CI from Phase 1).
|
||||||
|
|
||||||
|
## 9. Failure handling
|
||||||
|
|
||||||
|
The failure matrix of `software-specification.md` §35 / `ARCHITECTURE.md` §55 is normative: station failure isolates; storage failure isolates and buffers; OPC UA failure never stops acquisition; malformed telegrams are rejected with diagnostics; restart loses no acknowledged history. Each phase's tests must cover the failure modes it introduces (implementation specification §56 fault injection); every new failure mode gets a diagnostic (AGENTS.md Task completion).
|
||||||
|
|
||||||
|
## 10. Testing
|
||||||
|
|
||||||
|
- Pyramid per §50: deterministic unit/component tests dominate; integration via simulator; acceptance scenario at the top.
|
||||||
|
- Fixtures: imported **only** from `docs/protocol/test-vectors.md`; approved fixtures immutable; new vectors require evidence and registry update (never delete).
|
||||||
|
- Protocol tests run without external network (§57); simulator must not share codec code (§49).
|
||||||
|
- Restart-recovery tests at every phase that adds persistent state (§53).
|
||||||
|
- Bug fixes carry regression tests (AGENTS.md).
|
||||||
|
|
||||||
|
## 11. Migration/compatibility
|
||||||
|
|
||||||
|
Storage schemas versioned with explicit migrations; startup never silently destroys incompatible data; destructive migration requires administrative action (implementation specification §65). `configVersion` gating with explicit migration tooling (§66). OPC UA NodeId stability across releases (§68); configuration schema changes never force namespace changes (`configuration-reference.md` §71).
|
||||||
|
|
||||||
|
## 12. Progress
|
||||||
|
|
||||||
|
| Date | Entry |
|
||||||
|
|---|---|
|
||||||
|
| 2026-10-05 | Documentation set completed and made consistent; protocol evidence acquired (Rev 1.6 source); gap registry (10 entries), operations registry (OPS-001…012), and test-vector catalogue (35 verified vectors) created. Phase 0 documentation deliverables done. |
|
||||||
|
| 2026-10-06 | This roadmap created. Awaiting D-001 (technology selection) before Phase 0 code tasks. |
|
||||||
|
| 2026-10-06 | `README.md` and `CHANGELOG.md` created — the §5 repository-structure documentation items for Phase 0 are complete. Remaining Phase 0 deliverables: technology selection (D-001), code skeleton, CI, configuration schema. |
|
||||||
|
|
||||||
|
_Update this log at every phase gate; spawn child ExecPlans for §59-triggering work and link them here._
|
||||||
|
|
||||||
|
## 13. Decisions log
|
||||||
|
|
||||||
|
| ID | Date | Decision | Reference |
|
||||||
|
|---|---|---|---|
|
||||||
|
| DR-001 | 2026-10-05 | Documentation unescaped, de-duplicated; single-source-of-truth precedence defined | `ARCHITECTURE.md` §1 |
|
||||||
|
| DR-002 | 2026-10-05 | `AGENTS.md` reduced to short entry-point form per its own spec §4/§6 | `AGENTS.md` |
|
||||||
|
| DR-003 | 2026-10-05 | Watermark advances on **durable spool commit**, not final delivery | `ARCHITECTURE.md` §21, INV-014 |
|
||||||
|
| DR-004 | 2026-10-05 | Duplicate-conflict default **REJECT_CONFLICT** | software-spec §13 |
|
||||||
|
| DR-005 | 2026-10-05 | Deduplication correct across restart (persisted state or idempotent storage) | INV-015 |
|
||||||
|
| DR-006 | 2026-10-05 | Pipeline accepts out-of-order historical arrival; queries order by SourceTimestamp | INV-013 |
|
||||||
|
| DR-007 | 2026-10-05 | Records without usable SourceTimestamp quarantined with diagnostics | INV-016 |
|
||||||
|
| DR-008 | 2026-10-05 | Control/setpoint writes OUT-OF-SCOPE for initial release; read-only integration first | known-operations OPS-005/006/009/010 |
|
||||||
|
| DR-009 | 2026-10-05 | WGS decode via `Nal`; `alp` diagnostic-only until AQ-GAP-002 closes | AQ-GAP-002 hypothesis |
|
||||||
|
| DR-010 | 2026-10-05 | WGH block value count derived from station CFG | AQ-GAP-003 hypothesis |
|
||||||
|
| DR-011 | 2026-10-06 | Umbrella roadmap established; D-001 recorded as the blocking decision | this document |
|
||||||
|
|
||||||
|
## 14. Unexpected findings
|
||||||
|
|
||||||
|
- Source document contains checksum/typo defects: MAT fetch request prints 557 (recomputes 540; 557 = SLT fetch checksum — copy-paste error), narrative destination mismatches (§2.2.3.1 "plant 89" vs telegram dest 86; §3.4.10.2 fixed-line dest given as plant number) — recorded in AQ-GAP-005/006.
|
||||||
|
- The PDF→markdown conversion is lossy at specific tables and truncates §3.7; byte-exact recomputation of long examples from the conversion is impossible (AQ-GAP-001/005). The PDF is authoritative.
|
||||||
|
- The §2.4 checksum algorithm verified exactly against all 35 single-line examples — including the subtle rules that spaces around `#` are summed and Wait bytes are excluded.
|
||||||
|
|
||||||
|
## 15. Acceptance evidence
|
||||||
|
|
||||||
|
Production evaluation requires all of (implementation specification §77), evidenced by:
|
||||||
|
|
||||||
|
1. **Mandatory end-to-end scenario** (§54 T0–T8; `software-specification.md` §46): recorded as an automated acceptance test (T019); passing run attached to the Phase 14 gate.
|
||||||
|
2. **Protocol traceability audit:** every implemented operation maps to an `known-operations.md` entry with evidence; remaining gaps explicitly listed (§77 items 2, 15) — the gap registry *is* the evidence.
|
||||||
|
3. **Vector suite green:** all approved vectors passing in CI (§77 item 12).
|
||||||
|
4. **Restart/data-integrity tests** (§53): no acknowledged history lost across restart, outage, backlog (items 7–9).
|
||||||
|
5. **Security tests** (§55): untrusted certs rejected, None disabled in production config, no secrets logged.
|
||||||
|
6. **DoD checklist review:** the 15 items of §77 walked item-by-item at G14, each with its artifact.
|
||||||
|
7. Items 13 (validated against real equipment/traffic) and operational documentation remain **post-simulator** milestones dependent on field access — explicitly tracked, not silently dropped.
|
||||||
|
|
||||||
|
## 16. Plan maintenance
|
||||||
|
|
||||||
|
- Update §12 (Progress) at every phase gate; record new decisions in §13 immediately.
|
||||||
|
- Spawn a child ExecPlan (same structure, §59) for: any new AquaCom operation, storage/persistence architecture, OPC UA namespace redesign, security changes, cross-module refactors, data migration. Link children from §12.
|
||||||
|
- Move this plan to `docs/exec-plans/completed/` when G14 and §15 are satisfied.
|
||||||
|
- This plan never overrides the role-authoritative documents (`ARCHITECTURE.md` §1).
|
||||||
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
Binary file not shown.
|
After Width: | Height: | Size: 2.8 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 181 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 3.6 KiB |
@@ -0,0 +1,165 @@
|
|||||||
|
# AquaCom known operations registry
|
||||||
|
|
||||||
|
**Source of all evidence:** *Technical description – AquaCom – RTU level*, Rev 1.6, ITT Flygt AB, July 2004 (`AquaCom_RTU_1_6_eng.pdf`; markdown conversion in this folder). Section references below are to that document.
|
||||||
|
|
||||||
|
**Purpose.** Registers every AquaCom operation the gateway may implement, with its evidence and implementation status. An operation enters this registry *before* implementation begins; adding an operation with status beyond `REGISTERED` requires its evidence to be complete and its gaps resolved or scoped. Open questions live in `protocol-gaps.md` — this registry never invents behavior not stated in the source.
|
||||||
|
|
||||||
|
**Status values:** `REGISTERED` (evidence located, not yet implemented) · `PARTIAL` (framework-level support only) · `IMPLEMENTED` (codec + tests + traceability) · `OUT-OF-SCOPE` (deliberately not implemented in the initial release; evidence retained for future phases).
|
||||||
|
|
||||||
|
**Framing note (applies to every operation):** CS→RTU telegrams are `SOH + SPACE + DEST + SPACE + TYPE + SPACE + DATA… + SPACE + '#' + SPACE + CHK + CR`; RTU→CS telegrams are `STX + SPACE + DATA… + SPACE + '#' + SPACE + CHK + CR` (§2.3.2). Checksum per §2.4; `Wait` (DC3) bytes are stripped before parsing and excluded from the checksum (§3.6.4).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Session / control operations
|
||||||
|
|
||||||
|
### OPS-001 — Connection message (`OK`)
|
||||||
|
|
||||||
|
| Field | Content |
|
||||||
|
|---|---|
|
||||||
|
| Direction | RTU→CS (CS dialled) · CS→RTU (RTU dialled in alarm) |
|
||||||
|
| Purpose | Dialled-line connection answer; the answering side sends OK before conversation begins. The answering phase is "6×OK with 2.5s delay between each, aborted as soon as a telegram arrives"; some RTUs send 2×OK ≈4s apart instead (§2.2.3, §3.3.1). |
|
||||||
|
| Evidence | §2.2.3, §3.3.1, examples §3.4.1.2, §3.4.5.3, §3.4.7.2, §3.4.9.2, §3.4.10.3, §3.4.11.3, §3.4.12.2 |
|
||||||
|
| Gaps | — |
|
||||||
|
| Status | REGISTERED (dialled lines only; not applicable to fixed/TCP operation) |
|
||||||
|
|
||||||
|
### OPS-002 — Break (`BRK`)
|
||||||
|
|
||||||
|
| Field | Content |
|
||||||
|
|---|---|
|
||||||
|
| Direction | CS→RTU |
|
||||||
|
| Purpose | End communication. No answer is returned. Send 3× in a row before hanging up. Mandatory after a WGS containing a control command — some RTUs stay "remote controlled" until BRK (§3.4.13). |
|
||||||
|
| Evidence | §3.4.13 |
|
||||||
|
| Gaps | — |
|
||||||
|
| Status | REGISTERED (required for session teardown; harmless on fixed lines) |
|
||||||
|
|
||||||
|
### OPS-003 — Break with acknowledge (`EBR`)
|
||||||
|
|
||||||
|
| Field | Content |
|
||||||
|
|---|---|
|
||||||
|
| Direction | CS→RTU |
|
||||||
|
| Purpose | BRK variant expecting a `SCO` answer; retransmit up to 6 times on timeout or wrong answer. Not supported in Forth RTUs (§3.5.4, §3.2 summary table). |
|
||||||
|
| Evidence | §3.5.4 |
|
||||||
|
| Gaps | — |
|
||||||
|
| Status | REGISTERED (Basic RTUs only) |
|
||||||
|
|
||||||
|
### OPS-004 — Caller identification (dialled lines)
|
||||||
|
|
||||||
|
| Field | Content |
|
||||||
|
|---|---|
|
||||||
|
| Direction | RTU→CS |
|
||||||
|
| Purpose | Identifies the calling RTU (`STX DEST ACT # CHK CR`); capability-dependent (§2.2.3.2). |
|
||||||
|
| Evidence | §2.2.3.2–3 |
|
||||||
|
| Gaps | AQ-GAP-008 (ACT values unknown) |
|
||||||
|
| Status | REGISTERED — blocked by AQ-GAP-008 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Live-data operations
|
||||||
|
|
||||||
|
### OPS-005 — Status request (`WGS`)
|
||||||
|
|
||||||
|
| Field | Content |
|
||||||
|
|---|---|
|
||||||
|
| Direction | CS→RTU, answer RTU→CS |
|
||||||
|
| Purpose | Live-values polling. Answer: `ver, prod, Nal, alp, rem, r1–r4, mp1–mpN` (measuring points for the requested picture), followed by `Nal` alarm codes (§3.4.10). This is the protocol's primary live-acquisition operation. |
|
||||||
|
| Evidence | §3.4.10, examples §3.4.10.2–3, §2.2.3.1, §3.6.4; CFG picture/command sections §3.4.10.4–5 |
|
||||||
|
| Gaps | AQ-GAP-002 (alp semantics; hypothesis `mp count = alp−1` consistent with all four examples), AQ-GAP-005 (long-example checksums pending PDF transcription) |
|
||||||
|
| Status | REGISTERED (live acquisition is core scope; see `software-specification.md` §11) |
|
||||||
|
|
||||||
|
The `dir` field (F/B/N/M/!) is machine **control** — excluded from the initial release (`software-specification.md` §3.2); the decoder shall tolerate its syntax, and the gateway shall always transmit `!` (ignore).
|
||||||
|
|
||||||
|
### OPS-006 — Alarm request (`WCA`) and answers `ALR`/`ALN`/`ALO`
|
||||||
|
|
||||||
|
| Field | Content |
|
||||||
|
|---|---|
|
||||||
|
| Direction | CS→RTU (`WCA`, `ALO`), RTU→CS (`ALR`, `ALN`) |
|
||||||
|
| Purpose | Alarm polling/acknowledgement; `set=2` sets the RTU clock from the request's date/time (§3.4.1). Alarm retrieval is extension scope but the evidence now exists. |
|
||||||
|
| Evidence | §3.4.1, §2.2.3.3, §3.5.1.1 (Basic ALR variant) |
|
||||||
|
| Gaps | AQ-GAP-010 |
|
||||||
|
| Status | REGISTERED — alarm retrieval is OUT-OF-SCOPE for the initial release; clock setting (`set=2`) also OUT-OF-SCOPE (audit + confirmation architecture required first, cf. implementation specification §76) |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Historical-data operations
|
||||||
|
|
||||||
|
### OPS-007 — Historical trend (`WGH`)
|
||||||
|
|
||||||
|
| Field | Content |
|
||||||
|
|---|---|
|
||||||
|
| Direction | CS→RTU, answer RTU→CS (data or `NDA`) |
|
||||||
|
| Purpose | 5-minute-block historical trend retrieval. Request carries the timestamp of the last stored block; the answer continues from there, up to max 6 hours / 4000 chars; `NDA` ends the stream. This is the backfill/watermark operation the Historical Acquisition Manager is built around (§3.4.12). |
|
||||||
|
| Evidence | §3.4.12 incl. full multi-answer example §3.4.12.2 and CFG scaling §3.4.12.3; wire-level example §3.7 |
|
||||||
|
| Gaps | AQ-GAP-003 (block value count), AQ-GAP-001(e/g) |
|
||||||
|
| Status | REGISTERED (core scope; requires `protocol-gaps.md` AQ-GAP-003 working hypothesis wired to station point configuration) |
|
||||||
|
|
||||||
|
Semantics confirmed by example: a day's final block is timestamped `00:00` of the *next* day (§3.4.12.2 comment); requests use the last received block's timestamp to resume — the exact pattern the gateway's synchronization watermark must reproduce.
|
||||||
|
|
||||||
|
### OPS-008 — Periodical report (`WGD`)
|
||||||
|
|
||||||
|
| Field | Content |
|
||||||
|
|---|---|
|
||||||
|
| Direction | CS→RTU, answer RTU→CS (data or `NDA`) |
|
||||||
|
| Purpose | Per-day segmented aggregates (default 00-06 / 06-09 / 09-16 / 16-00 + sum) per reporting point (§3.4.11). Maps to canonical `AcquisitionSource = AQUACOM_REPORT`. Request also sets the RTU clock (same caveat as WCA). |
|
||||||
|
| Evidence | §3.4.11 incl. CFG section and scaling formula |
|
||||||
|
| Gaps | AQ-GAP-009, AQ-GAP-010(b) |
|
||||||
|
| Status | REGISTERED (implemented after WGH; report points configured separately from trend points per §3.4.11.4) |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Configuration / definition operations
|
||||||
|
|
||||||
|
### OPS-009 — Function channels (`MCC`, `MPA`, `MPB`, `MPC`, `MPD`, `MPL`)
|
||||||
|
|
||||||
|
| Field | Content |
|
||||||
|
|---|---|
|
||||||
|
| Direction | CS→RTU (set) and RTU→CS (fetch) |
|
||||||
|
| Purpose | Setpoint/config channel write & fetch. **Fetch limitation (Forth):** the RTU echoes only the *last sent* telegram — you must send what you want to receive; a cold-started RTU cannot be fetched from (§3.4.2–3, §3.4.3 "Important 2"). Types: `A`/`D` integer, `T` text (quoted, `_` = empty/space-as-underscore), `0–4` float decimals (§3.4.2.2; Basic variant §3.5.2). |
|
||||||
|
| Evidence | §3.4.2–3, §3.4.2.3 CFG/AquaView examples |
|
||||||
|
| Gaps | AQ-GAP-001(a), AQ-GAP-004 |
|
||||||
|
| Status | REGISTERED (used for station configuration; **writes to setpoints are control operations — OUT-OF-SCOPE initially**; read-back of a previously sent telegram is acceptable) |
|
||||||
|
|
||||||
|
### OPS-010 — Analogue channels (`MAS`)
|
||||||
|
|
||||||
|
| Field | Content |
|
||||||
|
|---|---|
|
||||||
|
| Direction | CS→RTU (set) and RTU→CS (fetch) |
|
||||||
|
| Purpose | Analogue input config (signal type, alarm levels, hysteresis, decimals; `htr` trend flag on Basic RTUs). Fetch requires a prior send, as with MCC (§3.4.4–5, §3.5.3). |
|
||||||
|
| Evidence | §3.4.4–5, §3.5.3, CFG examples |
|
||||||
|
| Gaps | AQ-GAP-003 (htr vs. Forth CFG trend section) |
|
||||||
|
| Status | REGISTERED (definitions source; writes OUT-OF-SCOPE initially, as OPS-009) |
|
||||||
|
|
||||||
|
### OPS-011 — Alarm code filter (`MAT`) and priorities (`SLT`)
|
||||||
|
|
||||||
|
| Field | Content |
|
||||||
|
|---|---|
|
||||||
|
| Direction | CS→RTU (set) and RTU→CS (fetch, capability-dependent per ATF controller-type digits) |
|
||||||
|
| Purpose | Alarm code remapping and A–Z priorities. The document itself states MAT "is not necessary to implement" (§3.4.6.3). |
|
||||||
|
| Evidence | §3.4.6–9 |
|
||||||
|
| Gaps | AQ-GAP-006 |
|
||||||
|
| Status | OUT-OF-SCOPE (alarm system extension; revisit when alarm retrieval is scheduled) |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Answer telegrams (all operations)
|
||||||
|
|
||||||
|
### OPS-012 — Fixed answers `SCO` / `SCE` / `NDA` / `!!` (Wait)
|
||||||
|
|
||||||
|
| Field | Content |
|
||||||
|
|---|---|
|
||||||
|
| Direction | RTU→CS |
|
||||||
|
| Purpose | `SCO` = telegram OK; `SCE` = error in telegram (optional rejected-channel payload, AQ-GAP-007); `NDA` = requested data not available (normal WGH/WGD stream terminator — **not** an error); `!!` = single DC3 (13H) byte, may be embedded *inside* another telegram, must be stripped before parsing, excluded from checksum, and resets the CS receive timeout (§3.6). |
|
||||||
|
| Evidence | §3.6, §3.6.4 checksum-identical pair of examples (both verified: 2925), §3.7 |
|
||||||
|
| Gaps | AQ-GAP-007 (SCE payload) |
|
||||||
|
| Status | REGISTERED (the `!!` handling is a hard requirement for any long-answer operation: WGH, WGD, WGS, MCC fetch) |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Implementation order (evidence-complete subset)
|
||||||
|
|
||||||
|
1. Framing + checksum + `!!` stripping (OPS-012 + framing note) — fully evidenced, unblocked.
|
||||||
|
2. OPS-005 `WGS` (live) — blocked only by AQ-GAP-002, which has a documented workaround (decode via `Nal`, cross-check `alp` diagnostically).
|
||||||
|
3. OPS-007 `WGH` (history) — blocked by AQ-GAP-003 working-hypothesis wiring (station configuration drives block layout).
|
||||||
|
4. OPS-008 `WGD` (reports) — after WGH; AQ-GAP-009 defaults.
|
||||||
|
5. Session ops OPS-001/002 as transports require (BRK for fixed-line WGS sessions).
|
||||||
|
|
||||||
|
This order matches the implementation phases (Phase 3 codec → Phase 6 live → Phase 10 historical) and honors live-over-history scheduling.
|
||||||
@@ -0,0 +1,163 @@
|
|||||||
|
# AquaCom protocol gap registry
|
||||||
|
|
||||||
|
**Source:** *Technical description – AquaCom – RTU level*, Rev 1.6, ITT Flygt AB, July 2004 — present in this folder as `AquaCom_RTU_1_6_eng.pdf` (markdown conversion: `AquaCom_RTU_1_6_eng_markdown/AquaCom_RTU_1_6_eng.md`). The PDF is authoritative wherever the conversion is ambiguous.
|
||||||
|
|
||||||
|
**Policy.** AquaCom protocol behavior may only be implemented from verified evidence (`AGENTS.md`; implementation specification §3.1). Unresolved protocol questions are recorded here instead of guessed (implementation specification §62, case C). An entry is closed only when the missing evidence exists; closing requires citing the evidence, adding a resolution note, and changing the status. Entries are never deleted.
|
||||||
|
|
||||||
|
**Entry format** (implementation specification §17): Gap ID, Description, Affected operation, Evidence available, Evidence missing, Impact, Implementation status.
|
||||||
|
|
||||||
|
**Status values:**
|
||||||
|
|
||||||
|
- `OPEN` — evidence missing; implement only what is documented, never the undocumented part.
|
||||||
|
- `VERIFY` — evidence exists in the PDF; the markdown conversion is unreliable at the cited places; check the PDF before implementing.
|
||||||
|
- `CLOSED` — resolved; cite evidence and date in a resolution note.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## AQ-GAP-001 — Fidelity of the markdown conversion
|
||||||
|
|
||||||
|
| Field | Content |
|
||||||
|
|---|---|
|
||||||
|
| Gap ID | AQ-GAP-001 |
|
||||||
|
| Description | The PDF→markdown conversion is lossy at several places. Confirmed instances: (a) §3.4.2.2 MCC DATA type table is mangled — the type rows are merged ("A = D = Integer (0-32767) … Analogue (0-200)"); (b) §3.4.10.1 WGS status-answer table merges the `mp1–mp128` byte-range cell into the description text (recoverable reading: 1–12 bytes each, measuring points 1–128); (c) §2.2.3.2 caller-ID field table formatting is broken; (d) §3.4.2.3.3 controller-type example prints `101 001` while the surrounding text refers to `(010)` (the parallel sections print `101 010` and `101 100` consistently); (e) the §3.7 detailed example is truncated mid-telegram ("…_0_1_1" followed by the document footer), so the answer's checksum is never reached; (f) WGS request examples print `0!` for the `mash`/`dir` fields — checksum verification proves the wire form is `0 !` (two space-separated fields), so this instance is resolved, but the PDF rendering should be confirmed for the record; (g) §3.4.12.1 states the WGH block `YY` is 2 bytes, but checksum-verified examples transmit single-digit years (e.g. `1 4 30 23 35`) — all block date fields shall be accepted as 1–2 digits. |
|
||||||
|
| Affected operation | all telegram parsing |
|
||||||
|
| Evidence available | authoritative PDF in this folder |
|
||||||
|
| Evidence missing | none — each affected table must be checked against the PDF before implementation |
|
||||||
|
| Impact | wrong field layouts if implemented from the markdown conversion alone |
|
||||||
|
| Status | `VERIFY` |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## AQ-GAP-002 — WGS status answer: `alp` semantics and measuring-point/alarm boundary
|
||||||
|
|
||||||
|
| Field | Content |
|
||||||
|
|---|---|
|
||||||
|
| Gap ID | AQ-GAP-002 |
|
||||||
|
| Description | `Nal` ("number of alarms following last measuring point") is unambiguous and consistent with all examples: alarm codes are appended after the measuring points, `Nal` of them. `alp` ("position where the first alarm is to be found") does not define its reference frame in the document. Arithmetic across **all four** printed examples is consistent with `alp` = the 1-based position, within the measuring-point sequence, of the first alarm, i.e. `measuring-point count = alp − 1`: §2.2.3.1 (alp=48, Nal=3), §3.4.10.2 (alp=22, Nal=1), §3.4.10.3 (alp=64, Nal=1), §3.6.4 (alp=11, Nal=1, 10 measuring points explicit). The earlier note that §2.2.3.1 "does not reconcile" was an analysis error (a mis-split field list), now retracted. What remains missing is an explicit definition, and a capture from a real station (the four examples agree but are all from the same vendor document). |
|
||||||
|
| Affected operation | WGS status answer decoding |
|
||||||
|
| Evidence available | §3.4.10.1 field definitions; arithmetic of examples §2.2.3.1, §3.4.10.2–3, §3.6.4 |
|
||||||
|
| Evidence missing | an explicit definition, or a validated capture from a station whose measuring-point count is independently known |
|
||||||
|
| Impact | the boundary between measuring points and trailing alarm codes; a misparse shifts every subsequent value |
|
||||||
|
| Status | `OPEN` — hypothesis strengthened but still vendor-document-internal; do not treat `alp` as confirmed |
|
||||||
|
|
||||||
|
**Working hypothesis (not confirmed — do not rely on it):** `alp` is the 1-based position, within the measuring-point sequence, of the first alarm; measuring points number `alp − 1`. An initial implementation may split measuring points from alarms using `Nal` alone (documented unambiguously), cross-check against `alp − 1` diagnostically, and shall not reject telegrams on an `alp` mismatch until this gap is closed.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## AQ-GAP-003 — WGH: number of values per block and trend-point membership
|
||||||
|
|
||||||
|
| Field | Content |
|
||||||
|
|---|---|
|
||||||
|
| Gap ID | AQ-GAP-003 |
|
||||||
|
| Description | Historical trend blocks contain `v1…v32`; "the actual numbers is depending of the type of RTU and version". The count is not signaled in the telegram. Examples: §3.4.12.2 has 7 values per block; §3.7 has 6. On Forth RTUs the station CFG contains a dedicated historical-trend section ("; ##3 / Number of points for Historical trend", with per-point wagon mapping) which presumably governs both membership and count; on Basic RTUs the MAS `htr` flag marks trend participation instead (§3.5.3.2). The document never explicitly states that the decoder must derive the per-block value count from station configuration. |
|
||||||
|
| Affected operation | WGH historical trend data decoding |
|
||||||
|
| Evidence available | §3.4.12.1 block format; examples §3.4.12.2 and §3.7; CFG sections §3.4.12.3 and §3.5.3.2 |
|
||||||
|
| Evidence missing | an explicit statement, or a validated capture from a station whose CFG is known |
|
||||||
|
| Impact | block splitting is ambiguous: values are numeric and cannot be distinguished from the following block's date fields by form alone |
|
||||||
|
| Status | `OPEN` |
|
||||||
|
|
||||||
|
**Working hypothesis (not confirmed):** the expected value count comes from the station's point configuration (CFG historical-trend section); the decoder validates each block's structure against it. Values are wagon-mapped and scaled per point (`Scaled = Raw*(Max−Min)/Max_input + Min`, §3.4.12.3).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## AQ-GAP-004 — Character encoding of text values
|
||||||
|
|
||||||
|
| Field | Content |
|
||||||
|
|---|---|
|
||||||
|
| Gap ID | AQ-GAP-004 |
|
||||||
|
| Description | Telegrams are "an ASCII-string with support of IBM extended codes. E.g. codes 01H to FFH is supported" — the code page for IBM extended codes (e.g. Å/Ä/Ö in Swedish station names) is not defined. Some RTUs support UTF-8 in the MCC data part, capability-dependent (ATF controller-type position 3). The checksum is byte-based and unaffected. |
|
||||||
|
| Affected operation | MCC T-type values (station names, telephone numbers), any text-bearing points |
|
||||||
|
| Evidence available | §2.3.1; §3.4.2.3.3 Note 4 |
|
||||||
|
| Evidence missing | a code-page definition, or a capture containing non-ASCII text |
|
||||||
|
| Impact | garbled text values; incorrect string comparisons |
|
||||||
|
| Status | `OPEN` (low priority until text points are used) |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## AQ-GAP-005 — Example checksum integrity in the source document
|
||||||
|
|
||||||
|
| Field | Content |
|
||||||
|
|---|---|
|
||||||
|
| Gap ID | AQ-GAP-005 |
|
||||||
|
| Description | **35 single-line examples** from the document were recomputed against the §2.4 algorithm and verify exactly (see `test-vectors.md` §1), confirming the algorithm itself, including the Wait-exclusion rule (§3.6.4 pair: both forms sum to 2925). However: (a) the long multi-line examples (WGS answers 7679/3633/6967/6968, WGH answers 6922/6479/4220, WGD answers 4984/5632, MCC 24268/28910, SLT 14331/15425/15061) **cannot be byte-exactly recomputed from the markdown conversion** — blockquote `>` prefixes, `\#` escapes and line-wrap artifacts (e.g. `1\n4 30` splitting a block, `- 16384` splitting a value) survive in the conversion and change byte sums; manual cleanup attempts give near-miss values (e.g. SLT 14331 → 14330/14295 depending on artifact handling), proving the artifacts, not the algorithm, are the problem; (b) example narratives contain destination mismatches (§2.2.3.1 says plant number 89 but the telegram uses dest 86; §3.4.10.2 gives a fixed-line dest as "plant number 901" although fixed-line dest should be the Node ID). |
|
||||||
|
| Affected operation | approved test vectors only — the checksum algorithm is confirmed for all short vectors |
|
||||||
|
| Evidence available | 35 verified recomputations in `test-vectors.md`; authoritative PDF |
|
||||||
|
| Evidence missing | PDF text extraction (or manual transcription) of the long examples free of conversion artifacts |
|
||||||
|
| Impact | the long examples cannot be approved fixtures until transcribed from the PDF; they are the only candidates exercising 16-bit wraparound (sums > 65535), so synthetic vectors cover that branch in the meantime |
|
||||||
|
| Status | `OPEN` |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## AQ-GAP-006 — MAT fetch request checksum
|
||||||
|
|
||||||
|
| Field | Content |
|
||||||
|
|---|---|
|
||||||
|
| Gap ID | AQ-GAP-006 |
|
||||||
|
| Description | The MAT fetch **request** `9 MAT 0 1 # 557` (§3.4.7.2) recomputes to **540**. 557 is exactly the checksum of the structurally identical SLT fetch request `9 SLT 0 1` (§3.4.9.2, verified), indicating a copy-paste error in the source document. The MAT fetch **answer** `7 9001 # 353` verifies exactly (353), so the answer side is sound. |
|
||||||
|
| Affected operation | MAT fetch request vector |
|
||||||
|
| Evidence available | §3.4.7.2 examples; recomputation (request: 540; answer: 353 verified) |
|
||||||
|
| Evidence missing | PDF confirmation of which checksum the printed request should carry |
|
||||||
|
| Impact | minor — use 540 for the request vector once PDF-confirmed; the verified answer vector may be approved independently |
|
||||||
|
| Status | `OPEN` |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## AQ-GAP-007 — SCE payload semantics
|
||||||
|
|
||||||
|
| Field | Content |
|
||||||
|
|---|---|
|
||||||
|
| Gap ID | AQ-GAP-007 |
|
||||||
|
| Description | "A SCE answer for a MCC telegram might contain the channel number the RTU rejected. Example: SCE 48 # 423." Whether and when the payload field is present is unspecified ("might"). |
|
||||||
|
| Affected operation | SCE (error in telegram) handling |
|
||||||
|
| Evidence available | §3.4.2.3 example (checksum verifies) |
|
||||||
|
| Evidence missing | a rule for payload presence |
|
||||||
|
| Impact | low — treat any payload as optional diagnostic data, never as parse-critical |
|
||||||
|
| Status | `OPEN` (low) |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## AQ-GAP-008 — Caller-ID telegram `ACT` field contents
|
||||||
|
|
||||||
|
| Field | Content |
|
||||||
|
|---|---|
|
||||||
|
| Gap ID | AQ-GAP-008 |
|
||||||
|
| Description | §2.2.3.2 defines the dialled-line caller-ID telegram (`STX DEST ACT # CHK CR`) with `ACT` = "Type of message, 3 bytes", but lists no valid `ACT` values. The §2.2.3.3 example transmits the literal string `ACT`, and its checksum (369) is consistent with that literal — suggesting an unexpanded placeholder rather than real traffic. |
|
||||||
|
| Affected operation | dialled-line caller identification |
|
||||||
|
| Evidence available | §2.2.3.2–3 |
|
||||||
|
| Evidence missing | valid `ACT` values, or a capture of a real caller-ID telegram |
|
||||||
|
| Impact | low for fixed-line/TCP-first deployments (feature is dialled-only and capability-dependent) |
|
||||||
|
| Status | `OPEN` (low) |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## AQ-GAP-009 — WGD segment boundaries configurability
|
||||||
|
|
||||||
|
| Field | Content |
|
||||||
|
|---|---|
|
||||||
|
| Gap ID | AQ-GAP-009 |
|
||||||
|
| Description | WGD answer segments are documented as "default 00-06 / 06-09 / 09-16 / 16-00". The word "default" implies configurability, but no mechanism is documented in this document. |
|
||||||
|
| Affected operation | WGD periodical data interpretation |
|
||||||
|
| Evidence available | §3.4.11.1 |
|
||||||
|
| Evidence missing | the configuration mechanism (possibly an AquaView/CFG setting outside this document) |
|
||||||
|
| Impact | low — use the documented defaults; record deviation diagnostically |
|
||||||
|
| Status | `OPEN` (low) |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## AQ-GAP-010 — Minor source-document inconsistencies in alarm telegrams
|
||||||
|
|
||||||
|
| Field | Content |
|
||||||
|
|---|---|
|
||||||
|
| Gap ID | AQ-GAP-010 |
|
||||||
|
| Description | (a) The WCA field table gives the hour range as 0–24 (§3.4.1) while ALR gives 0–23 (§3.4.1.6); 24 is likely a source typo — validate as 0–23 unless the PDF shows otherwise. (b) The semantics of the WCA date/time fields when `set=0` (poll mode) are not stated; the examples always carry the CS's current time, but the document does not say what the RTU does with it when `set=0`. |
|
||||||
|
| Affected operation | WCA request encoding; alarm polling |
|
||||||
|
| Evidence available | §3.4.1, §2.2.3.3, §3.4.1.2–3 examples |
|
||||||
|
| Evidence missing | PDF confirmation; a statement of `set=0` time semantics |
|
||||||
|
| Impact | low — alarms are extension scope; do not implement clock setting or rely on `set=0` time semantics until resolved |
|
||||||
|
| Status | `OPEN` (low) |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Closed gaps
|
||||||
|
|
||||||
|
None yet. When closing an entry: keep the original text, append a **Resolution** note citing the evidence and date, and set the status to `CLOSED`.
|
||||||
@@ -0,0 +1,114 @@
|
|||||||
|
# AquaCom approved test vectors
|
||||||
|
|
||||||
|
**Fixture source policy:** all vectors below are derived from *Technical description – AquaCom – RTU level*, Rev 1.6, ITT Flygt AB, July 2004 (`AquaCom_RTU_1_6_eng.pdf`) — evidence class **SPECIFICATION** (examples printed in the authoritative document). Vectors marked *(synthetic)* are constructed by the project to exercise edge cases the document's examples do not cover; they are labeled **SYNTHETIC_FROM_SPECIFICATION** and are subordinate to the source examples in authority. Each fixture becomes an automated test on implementation; fixtures are immutable once approved (implementation specification §64).
|
||||||
|
|
||||||
|
**Notation.** `<SOH>`=01H, `<STX>`=02H, `<CR>`=0DH, `_`=space (20H), `!W` = Wait byte (DC3, 13H). Checksums are per §2.4: sum of all bytes after SOH/STX up to (excluding) `#`, excluding Wait bytes, in a 16-bit signed integer; the transmitted value is the absolute value. The separator space between `#` and the checksum, and the trailing space before `CR`, **are included** in the summed range.
|
||||||
|
|
||||||
|
**Checksum convention reminder (verified by the examples below):** the summed range starts *after* SOH/STX — i.e. at the space that follows the start byte — and ends at the space immediately before the checksum digits. `32+83+67+79+32=293` for `SCO` (§2.4) confirms this: leading space 32, `SCO` 83+67+79, trailing space 32.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 1. Checksum algorithm vectors
|
||||||
|
|
||||||
|
| ID | Telegram | Documented checksum | Verified | Source |
|
||||||
|
|---|---|---|---|---|
|
||||||
|
| AQ-CK-001 | `<STX> SCO _ # _ 293 <CR>` | 293 | yes | §2.4 |
|
||||||
|
| AQ-CK-002 | `<SOH> 9 BRK _ # _ 376 <CR>` | 376 | yes | §3.4.1.2 |
|
||||||
|
| AQ-CK-003 | `<SOH> 0 ALO _ # _ 364 <CR>` | 364 | yes | §2.2.3.3 |
|
||||||
|
| AQ-CK-004 | `<STX> NDA _ # _ 275 <CR>` | 275 | yes | §3.4.12.2 |
|
||||||
|
| AQ-CK-005 | `<STX> SCO _ # _ 293 <CR>` (RTU→CS OK answer) | 293 | yes | §3.4.2.3 |
|
||||||
|
| AQ-CK-006 | `<STX> SCE 48 _ # _ 423 <CR>` | 423 | yes | §3.4.2.3 |
|
||||||
|
| AQ-CK-007 | `<SOH> 9 WCA 0 3 6 17 13 59 _ # _ 1031 <CR>` | 1031 | yes | §2.2.3.3 |
|
||||||
|
| AQ-CK-008 | `<SOH> 9 WCA 0 3 6 17 14 0 _ # _ 970 <CR>` | 970 | yes | §2.2.3.3 |
|
||||||
|
| AQ-CK-009 | `<STX> ALN T 0 0 0 0 _ # _ 719 <CR>` | 719 | yes | §2.2.3.3 |
|
||||||
|
| AQ-CK-010 | `<STX> OK _ # _ 218 <CR>` | 218 | yes | §2.2.3.1, §3.4.1.2 |
|
||||||
|
| AQ-CK-011 | `<SOH> 5 WCA 0 1 4 27 10 13 _ # _ 1011 <CR>` | 1011 | yes | §3.4.1.3 |
|
||||||
|
| AQ-CK-012 | `<STX> ALR 111 11 1 4 27 10 13 A T 0 0 0 0 B 31 _ # _ 1922 <CR>` | 1922 | yes | §3.4.1.3 |
|
||||||
|
| AQ-CK-013 | `<SOH> 5 ALO _ # _ 369 <CR>` | 369 | yes | §3.4.1.3 |
|
||||||
|
| AQ-CK-014 | `<SOH> 9 MCC 0 1 _ # _ 525 <CR>` | 525 | yes | §3.4.3.2 |
|
||||||
|
| AQ-CK-015 | `<SOH> 9 SLT 0 1 _ # _ 557 <CR>` | 557 | yes | §3.4.9.2 |
|
||||||
|
| AQ-CK-016 | `<SOH> 2 MAS 0 1 _ # _ 532 <CR>` | 532 | yes | §3.4.5.3 |
|
||||||
|
| AQ-CK-017 | `<SOH> 2 MAT 7 7 81 81 82 9003 _ # _ 1194 <CR>` | 1194 | yes | §3.4.6.1 |
|
||||||
|
| AQ-CK-018 | `<SOH> 9 MAT 7 9001 _ # _ 700 <CR>` | 700 | yes | §3.4.6.2 |
|
||||||
|
| AQ-CK-019 | `<SOH> 9 WGD 01 05 02 13 38 01 05 01 _ # _ 1433 <CR>` | 1433 | yes | §3.4.11.3 |
|
||||||
|
| AQ-CK-020 | `<SOH> 5 WGD 01 05 02 13 10 01 05 01 _ # _ 1419 <CR>` | 1419 | yes | §3.4.11.2 |
|
||||||
|
| AQ-CK-021 | `<SOH> 9 WGH 01 04 30 23 30 _ # _ 1039 <CR>` | 1039 | yes | §3.4.12.2 |
|
||||||
|
| AQ-CK-022 | `<SOH> 9 WGH 01 05 01 03 50 _ # _ 1038 <CR>` | 1038 | yes | §3.4.12.2 |
|
||||||
|
| AQ-CK-023 | `<SOH> 9 WGH 01 05 01 08 10 _ # _ 1039 <CR>` | 1039 | yes | §3.4.12.2 |
|
||||||
|
| AQ-CK-024 | `<SOH> 9 WGH 01 05 01 08 20 _ # _ 1040 <CR>` | 1040 | yes | §3.4.12.2 |
|
||||||
|
| AQ-CK-025 | `<SOH> 500 WGH 99 12 31 21 40 _ # _ 1147 <CR>` | 1147 | yes | §3.7 |
|
||||||
|
| AQ-CK-026 | `<STX> 9_ACT_#_369_<CR>` (caller-ID, literal ACT) | 369 | yes | §2.2.3.3 |
|
||||||
|
| AQ-CK-027 | `<STX> ALR 9 12 3 6 17 13 58 P T 0 0 0 0 A 27 _ # _ 1867 <CR>` | 1867 | yes | §2.2.3.3 |
|
||||||
|
| AQ-CK-028 | `<STX> ALR 9 12 1 4 27 10 26 P T 0 0 0 0 A 27 _ # _ 1856 <CR>` | 1856 | yes | §3.4.1.2 |
|
||||||
|
| AQ-CK-029 | `<SOH> 9 WCA 0 1 4 27 10 27 _ # _ 1020 <CR>` | 1020 | yes | §3.4.1.2 |
|
||||||
|
| AQ-CK-030 | `<SOH> 86 WGS P 0 ! 1 _ # _ 785 <CR>` | 785 | yes | §2.2.3.1 — confirms the `0 !` two-field form |
|
||||||
|
| AQ-CK-031 | `<SOH> 901 WGS P 0 ! 11 _ # _ 878 <CR>` | 878 | yes | §3.4.10.2 |
|
||||||
|
| AQ-CK-032 | `<SOH> 9 WGS P 2 F 1 _ # _ 771 <CR>` | 771 | yes | §3.4.10.3 |
|
||||||
|
| AQ-CK-033 | `<STX> 32000 654321 03 11 0 0 0 0 0 1 2 3 4 5 6 7 8 9 10 8050 8531 8532 _ # _ 2925 <CR>` | 2925 | yes | §3.6.4 (Wait-free form of the WGS-answer pair) |
|
||||||
|
| AQ-CK-034 | `<STX> 32000 65!W4321 03 11!W 0 0 0 0 0!W 1 2 3 4 5!W 6 7 8 9 1!W0 8050 853!W1 8532 _ # _ 2925 <CR>` | 2925 | yes | §3.6.4 (Wait-laden form; identical checksum — proves Wait exclusion) |
|
||||||
|
| AQ-CK-035 | `<STX> 7 9001 _ # _ 353 <CR>` | 353 | yes | §3.4.7.2 (MAT fetch answer) |
|
||||||
|
|
||||||
|
**Discrepant vector (documented checksum fails recomputation; see `protocol-gaps.md` AQ-GAP-006):**
|
||||||
|
|
||||||
|
| ID | Telegram | Documented | Recomputed | Source | Note |
|
||||||
|
|---|---|---|---|---|---|
|
||||||
|
| AQ-CK-E1 | `<SOH> 9 MAT 0 1 _ # _ 557 <CR>` | 557 | 540 | §3.4.7.2 | fetch **request**; 557 is exactly the SLT fetch checksum (copy-paste error); not approved until PDF-confirmed |
|
||||||
|
|
||||||
|
The long multi-line examples (WGS answers 7679 / 3633 / 6967 / 6968; WGH answers 6922 / 6479 / 4220; WGD answers 4984 / 5632; MCC 24268 / 28910; SLT 14331 / 15425 / 15061) are candidates for wraparound coverage (sums > 65535) but **cannot be recomputed from the markdown conversion** — blockquote markers, `\#` escapes and line-wrap artifacts survive in the conversion and alter byte sums (AQ-GAP-005). They must be transcribed from the authoritative PDF before approval; until then they are **not approved fixtures**, and the synthetic vectors below cover the wraparound branches.
|
||||||
|
|
||||||
|
**Synthetic algorithm-branch vectors (values computed and verified against the §2.4 algorithm):**
|
||||||
|
|
||||||
|
| ID | Constructed telegram | Raw sum | Expected checksum | Why |
|
||||||
|
|---|---|---|---|---|
|
||||||
|
| AQ-CK-S1 | `<STX>` + 200 × `A` + ` _ # _` | 13064 | 13064 | no wraparound — round-trip baseline *(synthetic)* |
|
||||||
|
| AQ-CK-S2 | `<STX>` + 806 × `z` + ` _ # _` | 98396 | 32676 | sum > 65535 (16-bit wraparound **and** the ≥32768 absolute-value branch: 98396 mod 65536 = 32860 → 65536−32860 = 32676) *(synthetic)* |
|
||||||
|
| AQ-CK-S3 | `<STX>` + 550 × `z` + ` _ # _` | 67164 | 1628 | wraparound **without** the absolute-value branch (67164 mod 65536 = 1628 < 32768) — isolates the mod-65536 step *(synthetic)* |
|
||||||
|
| AQ-CK-S4 | `<STX> SCO !W !W _ # _ 293 <CR>` | — | 293 | Wait bytes excluded from the sum *(synthetic; superseded by source vector AQ-CK-033/034, retained as an algorithm-level unit test)* |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2. Framing / session vectors
|
||||||
|
|
||||||
|
| ID | Scenario | Expectation | Source |
|
||||||
|
|---|---|---|---|
|
||||||
|
| AQ-FR-001 | CS dialled, RTU answers 6×OK 2.5 s apart; CS transmits request after first OK detected | conversation proceeds; the OK sequence is aborted by the incoming request | §2.2.3 |
|
||||||
|
| AQ-FR-002 | Answer arrives with Wait bytes embedded mid-token (`…65!!4321…`) | strip `!W` before tokenization; checksum unchanged; parser output equals the Wait-free form | §3.6.4 |
|
||||||
|
| AQ-FR-003 | BRK sent 3×, then hang-up | no answer expected; transport closes cleanly | §3.4.13 |
|
||||||
|
| AQ-FR-004 | Inter-character gap of 1 s inside a telegram | accepted (RTU-side limit is exactly 1 s; the gateway as CS uses 4–20 s whole-telegram timeout — §2.5) | §2.5 |
|
||||||
|
| AQ-FR-005 | Telegram data length > 4000 chars | rejected by framer; diagnostic generated (protocol max) | §2.3.2 |
|
||||||
|
|
||||||
|
## 3. Live data vectors (WGS)
|
||||||
|
|
||||||
|
| ID | Scenario | Expected decode | Source |
|
||||||
|
|---|---|---|---|
|
||||||
|
| AQ-WGS-001 | Fixed, request `901 WGS P 0 ! 11` → answer `23400 13885 01 22 0 0 0 0 0 3 0 3 3 4800 … 7 8111` | `ver=23400`, `prod=13885`, `Nal=1`, `alp=22`, `rem=0`, 21 measuring points (alp−1, hypothesis — AQ-GAP-002), then 1 alarm code (8111). Decode via `Nal`; cross-check `alp−1` diagnostically only | §3.4.10.2 (checksum not yet approvable — AQ-GAP-005 long example) |
|
||||||
|
| AQ-WGS-002 | Request with control command then BRK | command suppressed by gateway (control OUT-OF-SCOPE); BRK still required after command-bearing WGS per §3.4.13 | §3.4.10, §3.4.13 |
|
||||||
|
| AQ-WGS-003 | Request with `dir`=`!` (ignore) | no command dispatched; normal status answer | §3.4.10 |
|
||||||
|
|
||||||
|
## 4. Historical vectors (WGH)
|
||||||
|
|
||||||
|
| ID | Scenario | Expected decode | Source |
|
||||||
|
|---|---|---|---|
|
||||||
|
| AQ-WGH-001 | Request `9 WGH 01 04 30 23 30` → first answer of §3.4.12.2 (36 blocks, checksum 6922) | 36 blocks; first `1 4 30 23 35`, last `1 5 1 3 50`; 7 values per block; `!` separators; **requires AQ-GAP-003 hypothesis wiring** | §3.4.12.2 |
|
||||||
|
| AQ-WGH-002 | Continuation: request with last received block timestamp `9 WGH 01 05 01 03 50` → next answer | stream resumes at `1 5 1 3 55`; proves the watermark-resume protocol | §3.4.12.2 |
|
||||||
|
| AQ-WGH-003 | Final continuation `9 WGH 01 05 01 08 20` → `NDA` | `NDA` = normal end-of-stream, not an error; synchronization interval complete | §3.4.12.2 |
|
||||||
|
| AQ-WGH-004 | Day rollover: block `1 4 30 0 0` follows block `1 4 30 23 55` | the `00:00` block belongs to the *next* day (comment: "the last block for a day is the one with time stamp 00:00") — **no date-field jump; the date increments**; single-digit year/month/day accepted (1–2 byte fields) | §3.4.12.2 |
|
||||||
|
| AQ-WGH-005 | Answer with embedded Wait bytes (§3.7 form) | parse identical to Wait-free form; checksum identical (§3.6.4 pair) | §3.7, §3.6.4 |
|
||||||
|
| AQ-WGH-006 | Request whose span exceeds 6 hours or 4000 chars | RTU truncates per §3.4.12.1 limits; gateway detects truncated stream by receiving fewer blocks than the requested interval and re-requests from the last block timestamp (at-least-once; dedup by §13/§23 rules) | §3.4.12.1 *(synthetic scenario, specification-derived limit)* |
|
||||||
|
| AQ-WGH-007 | Scaling: CFG point `Max=0.01, Min=0, Max_input=10`, raw 64786 | `Scaled = Raw×(Max−Min)/Max_input + Min` → 64.786 — every vector decode must apply wagon scaling per station CFG, not raw values | §3.4.12.3 *(synthetic combination of documented formula + example raw value)* |
|
||||||
|
|
||||||
|
## 5. Report vectors (WGD)
|
||||||
|
|
||||||
|
| ID | Scenario | Expected decode | Source |
|
||||||
|
|---|---|---|---|
|
||||||
|
| AQ-WGD-001 | Request `5 WGD 01 05 02 13 10 01 05 01` → answer `0 0 0 501 501 0 0 0 1506 1506 …` | per point: seg1..seg4 + sum; 10 reporting points per §3.4.11.4 CFG; scaling formula per point | §3.4.11.2, §3.4.11.4 |
|
||||||
|
| AQ-WGD-002 | Empty report day → all-zero answer (§3.4.11.3) | 64 zero values decoded as valid (not NDA); zero is a legitimate report value | §3.4.11.3 |
|
||||||
|
| AQ-WGD-003 | `NDA` answer | report data for that day does not exist; mark interval missing, do not treat as failure | §3.4.11 |
|
||||||
|
|
||||||
|
## 6. Simulator scenario requirements (traceability targets)
|
||||||
|
|
||||||
|
The simulator (implementation specification §49) shall be able to replay every vector above plus inject: bad checksum (failing AQ-CK verification), truncated telegram (no `#`/`CR`), over-long telegram, inter-character stall of 1.5 s (RTU-side timeout breach), mid-telegram Wait flooding, duplicate WGH blocks across two answers (dedup regression per `ARCHITECTURE.md` §23), conflicting block re-transmission (REJECT_CONFLICT path per §13), and station clock set to a future date (timestamp-validation diagnostics per `software-specification.md` §26). The simulator must not share parsing code with the production decoder (§49).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Approval state:** section 1 verified rows (AQ-CK-001–035) and section 2 approved as fixtures; AQ-CK-E1 pending AQ-GAP-006 (PDF confirmation); long examples pending AQ-GAP-005 (PDF transcription); sections 3–4 blocked by AQ-GAP-002/003 for full decode assertions (framing-level assertions may proceed; `Nal`-based decoding is documented and unblocked). Synthetic vectors subordinate to source vectors. Update this file's approval state when gaps close — never delete vectors.
|
||||||
+7
-9
@@ -6,10 +6,7 @@ Referenced from: `AGENTS.md`, `ARCHITECTURE.md`, `docs/product/codex-implementat
|
|||||||
|
|
||||||
## Root
|
## Root
|
||||||
|
|
||||||
| Document | Referenced for | Source of reference |
|
**Status 2026-10-06:** all root documents exist (`README.md`, `CHANGELOG.md`). No root documents are missing.
|
||||||
|---|---|---|
|
|
||||||
| `README.md` | Repository overview; required by the repository structure (§5) | codex-implementation-specification.md §5 |
|
|
||||||
| `CHANGELOG.md` | Version history; required by the repository structure (§5) | codex-implementation-specification.md §5 |
|
|
||||||
|
|
||||||
## docs/architecture/
|
## docs/architecture/
|
||||||
|
|
||||||
@@ -29,12 +26,11 @@ Referenced by `ARCHITECTURE.md` (§1) and the repository structure (§5).
|
|||||||
|
|
||||||
Referenced by `AGENTS.md` (protocol-evidence and uncertainty rules), `ARCHITECTURE.md` (§54), `software-specification.md` (§5.1), and the repository structure (§5).
|
Referenced by `AGENTS.md` (protocol-evidence and uncertainty rules), `ARCHITECTURE.md` (§54), `software-specification.md` (§5.1), and the repository structure (§5).
|
||||||
|
|
||||||
|
**Status 2026-10-05:** The authoritative source is present (`AquaCom_RTU_1_6_eng.pdf` + markdown conversion), and the gap registry (`protocol-gaps.md`), operations registry (`known-operations.md`), and test-vector catalogue (`test-vectors.md`) have been created from it. Only the curated knowledge base remains:
|
||||||
|
|
||||||
| Document | Referenced for | Priority |
|
| Document | Referenced for | Priority |
|
||||||
|---|---|---|
|
|---|---|---|
|
||||||
| `docs/protocol/aquacom.md` | Authoritative AquaCom protocol knowledge base | High — blocks Phase 3+ implementation |
|
| `docs/protocol/aquacom.md` | Curated AquaCom protocol knowledge base — to be derived from `AquaCom_RTU_1_6_eng.md` (framing, checksum, timeout, transport and encoding rules currently live in the other three files and the source document) | Medium — consolidation work, no longer an evidence blocker |
|
||||||
| `docs/protocol/known-operations.md` | Registry of verified AquaCom operations | High |
|
|
||||||
| `docs/protocol/protocol-gaps.md` | **Protocol-gap registry.** Every unresolved AquaCom protocol question shall be recorded here; the evidence rules in `AGENTS.md` and the implementation spec are not executable without it. | **Highest — create first** |
|
|
||||||
| `docs/protocol/test-vectors.md` | Approved protocol test vectors for implemented telegram types | High — required by every implemented telegram type |
|
|
||||||
|
|
||||||
## docs/operations/
|
## docs/operations/
|
||||||
|
|
||||||
@@ -56,6 +52,8 @@ Referenced by `AGENTS.md` and codex-implementation-specification.md §59.
|
|||||||
| `docs/exec-plans/active/` | Active ExecPlans for substantial work |
|
| `docs/exec-plans/active/` | Active ExecPlans for substantial work |
|
||||||
| `docs/exec-plans/completed/` | Completed ExecPlans |
|
| `docs/exec-plans/completed/` | Completed ExecPlans |
|
||||||
|
|
||||||
|
**Status 2026-10-06:** `docs/exec-plans/active/001-implementation-roadmap.md` exists (umbrella roadmap: phases 0–14, gates, gap-consumption schedule, decisions log). Child ExecPlans are spawned from it per §59 as substantial work begins; `completed/` is created when the first plan finishes.
|
||||||
|
|
||||||
## Schemas
|
## Schemas
|
||||||
|
|
||||||
Referenced by `configuration-reference.md` §1 and the repository structure (§5). Extensions depend on the configuration format chosen during technology selection.
|
Referenced by `configuration-reference.md` §1 and the repository structure (§5). Extensions depend on the configuration format chosen during technology selection.
|
||||||
@@ -72,5 +70,5 @@ Referenced by `configuration-reference.md` §1 and the repository structure (§5
|
|||||||
## Notes
|
## Notes
|
||||||
|
|
||||||
- The directories `docs/architecture/` and `docs/protocol/` already exist but are empty; `docs/operations/`, `docs/exec-plans/` and `schemas/` do not exist yet.
|
- The directories `docs/architecture/` and `docs/protocol/` already exist but are empty; `docs/operations/`, `docs/exec-plans/` and `schemas/` do not exist yet.
|
||||||
- `protocol-gaps.md` deserves priority: the architecture's evidence rules direct unresolved protocol questions into it, so its absence would leave the first such question with nowhere to go. Creating an empty registry with the entry template from codex-implementation-specification.md §17 is sufficient to start.
|
- `protocol-gaps.md` now exists and is seeded (10 entries: 1 conversion-fidelity `VERIFY`, 9 `OPEN`). Unresolved AquaCom protocol questions continue to be recorded there; closing an entry requires evidence and a dated resolution note.
|
||||||
- ExecPlan directory contents are created on demand as substantial work begins; an empty directory is the normal state.
|
- ExecPlan directory contents are created on demand as substantial work begins; an empty directory is the normal state.
|
||||||
Reference in New Issue
Block a user