Files
aquacom-gateway-suite/docs/product/codex-implementation-specification.md
2026-10-05 21:27:47 +02:00

48 KiB
Raw Permalink Blame History

Implementation Specification

AquaCom Integration Gateway

Document type: Implementation specification

Target implementation agent: any AI coding agent (Codex, Copilot, or equivalent)

System: AquaCom Integration Gateway

Primary southbound interface: AquaCom

Primary northbound interface: OPC UA

Additional capability: Pluggable historical storage

Programming language: To be selected during implementation planning

Version: 0.1

Status: Draft


1. Purpose

This document defines how the implementation agent shall implement the AquaCom Integration Gateway.

The gateway shall:

  • communicate with AquaCom-compatible devices;

  • acquire current process information;

  • acquire historical process information;

  • maintain a protocol-independent internal data model;

  • expose current values through OPC UA;

  • expose historical values through OPC UA Historical Access;

  • persist historical information through one or several configurable storage providers;

  • recover historical data after communication interruptions where AquaCom equipment supports this;

  • maintain diagnostic information;

  • provide a simulation environment for development and automated testing.

This document describes:

  • repository organization;

  • architectural boundaries;

  • required modules;

  • internal interfaces;

  • data contracts;

  • state machines;

  • configuration;

  • persistence;

  • testing;

  • milestones;

  • implementation-agent working rules;

  • acceptance criteria.

It does not prescribe the implementation programming language.


2. Fundamental implementation rule

The implementation shall be based on the following processing architecture:


AquaCom

    │

    ▼

Transport

    │

    ▼

AquaCom protocol engine

    │

    ▼

Station/session manager

    │

    ▼

Canonical data model

    │

    ├──────────────► Current-state service

    │                       │

    │                       ▼

    │                   OPC UA DA

    │

    └──────────────► Historical pipeline

                            │

                 ┌──────────┼──────────────┐

                 │          │              │

                 ▼          ▼              ▼

             Repository  Storage A      Storage B

                 │

                 ▼

             OPC UA HA

No component above the AquaCom protocol layer shall parse or construct AquaCom telegrams.

No AquaCom component shall depend upon OPC UA.

No AquaCom component shall depend upon a particular database.

No storage adapter shall depend upon AquaCom telegram structure.


3. Implementation agent principles

The implementation agent shall follow these principles throughout development.

3.1 Do not invent AquaCom protocol details

The implementation agent shall never invent:

  • byte positions;

  • telegram structure;

  • field identifiers;

  • checksums;

  • addressing rules;

  • commands;

  • response codes;

  • scaling;

  • timestamp encoding;

  • historical-data behavior.

Protocol behavior may only be implemented when supported by at least one of:

  1. authoritative AquaCom documentation;

  2. validated packet/serial captures;

  3. existing known-good implementation behavior;

  4. approved test vectors.

Unknown protocol details shall be represented as:


NOT_IMPLEMENTED

or documented protocol gaps.

A compilation-successful guess is not an acceptable implementation.


4. Repository documentation strategy

The repository shall contain a short root AGENTS.md.

Detailed requirements shall live under docs/.

AGENTS.md shall primarily direct the implementation agent to the authoritative project documentation rather than attempt to contain the complete project specification.

This follows current agent guidance favoring concise repository instructions with deeper documentation maintained separately.

Complex implementation work shall use an execution plan maintained in the repository. Current agent guidance recommends plan documents for significant features or refactors.


5. Repository structure

The initial repository shall use the following logical organization:


/

├── AGENTS.md

├── README.md

├── ARCHITECTURE.md

├── CHANGELOG.md

├── LICENSE

│

├── docs/

│   ├── product/

│   │   └── software-specification.md

│   │

│   ├── architecture/

│   │   ├── overview.md

│   │   ├── data-flow.md

│   │   ├── live-data.md

│   │   ├── historical-data.md

│   │   ├── opcua.md

│   │   ├── storage.md

│   │   └── security.md

│   │

│   ├── protocol/

│   │   ├── aquacom.md

│   │   ├── known-operations.md

│   │   ├── protocol-gaps.md

│   │   └── test-vectors.md

│   │

│   ├── configuration/

│   │   └── configuration-reference.md

│   │

│   ├── operations/

│   │   ├── deployment.md

│   │   ├── diagnostics.md

│   │   ├── backup-recovery.md

│   │   └── troubleshooting.md

│   │

│   └── exec-plans/

│       ├── active/

│       └── completed/

│

├── schemas/

│   ├── gateway-config.schema.*

│   ├── station-config.schema.*

│   └── point-config.schema.*

│

├── config/

│   └── examples/

│

├── src/

│   ├── core/

│   ├── aquacom/

│   ├── history/

│   ├── storage/

│   ├── opcua/

│   ├── diagnostics/

│   └── host/

│

├── tests/

│   ├── unit/

│   ├── integration/

│   ├── protocol/

│   ├── opcua/

│   ├── history/

│   └── acceptance/

│

├── simulator/

│

├── fixtures/

│   ├── aquacom/

│   ├── history/

│   └── configuration/

│

├── tools/

│

└── deployment/

File extensions shall be selected once the implementation language and configuration formats are chosen.


6. Root AGENTS.md

The root AGENTS.md implements this strategy: it is the short entry point that directs the implementation agent to the authoritative documents, lists the non-negotiable architecture and evidence rules, and never restates full specifications. The current root AGENTS.md in this repository is the reference implementation of that form and takes precedence over any example restated here.

Nested AGENTS.md files may later be added where a specific module requires additional constraints. Current coding agents support hierarchical AGENTS.md instructions scoped to directory trees, making this suitable for stricter protocol or storage-specific rules if the repository grows.


7. Architecture document

ARCHITECTURE.md shall act as the primary architecture map.

It shall contain:

  • system purpose;

  • module diagram;

  • dependency direction;

  • canonical data model;

  • live-data flow;

  • historical-data flow;

  • security boundaries;

  • links to detailed documents.

The following dependency direction is mandatory:


             ┌──────────────┐

             │     host     │

             └──────┬───────┘

                    │

       ┌────────────┼────────────┐

       ▼            ▼            ▼

    OPC UA       history      diagnostics

       │            │

       │         storage

       │            │

       └──────┬─────┘

              ▼

             core

              ▲

              │

           aquacom

core shall contain no dependencies on AquaCom, OPC UA or a particular storage implementation.


8. Core domain module

The core module shall contain protocol-neutral data models.

Required logical entities include:


StationId

PointId

CurrentValue

HistoricalSample

DataQuality

AcquisitionSource

StationState

CommunicationState

HistorySynchronizationState


9. Stable identifiers

9.1 StationId

StationId shall be an immutable logical gateway identifier.

It shall not depend solely upon:

  • IP address;

  • hostname;

  • serial port;

  • display name.

Example:


station:PS001


9.2 PointId

PointId shall be an immutable logical identifier.

Example:


station:PS001/point:LEVEL

Changing:


Wet well level

to:


Inlet sump level

shall not change PointId.


10. CurrentValue contract

The canonical current-value model shall conceptually contain:


CurrentValue

StationId

PointId

Value

DataType

Quality

SourceTimestamp?

ReceivedTimestamp

UpdatedTimestamp

AcquisitionSource

SourceTimestamp may be absent when AquaCom provides no trustworthy source timestamp.

ReceivedTimestamp shall always be gateway-generated.


11. HistoricalSample contract

Historical samples shall contain:


HistoricalSample

StationId

PointId

Value

DataType

Quality

SourceTimestamp

ReceivedTimestamp

AcquisitionSource

AcquisitionId?

Metadata?

SourceTimestamp is mandatory for normal process history.

A record without a reliable historical timestamp shall not silently be interpreted as historical process data. Such a record shall be quarantined with diagnostics: rejected from normal history, recorded distinctly for investigation, and never stored with a fabricated or gateway-generated timestamp (see software-specification.md §10).


12. DataQuality

Internal quality shall be independent of OPC UA.

At minimum:


GOOD

UNCERTAIN

BAD

UNKNOWN

Optional reason/substatus shall support values equivalent to:


COMMUNICATION_FAILURE

STALE

INVALID_VALUE

INVALID_TIMESTAMP

CONFIGURATION_ERROR

CONVERSION_ERROR

SOURCE_UNCERTAIN

HISTORY_GAP

The OPC UA module shall map this model to OPC UA StatusCodes.


13. AcquisitionSource

Historical and current information shall identify origin.

Examples:


LIVE

AQUACOM_HISTORY

AQUACOM_REPORT

RECOVERY

IMPORT

SIMULATOR

Implementation shall permit additional values.


14. AquaCom transport interface

The AquaCom transport abstraction shall provide functions equivalent to:


open()

close()

send(bytes)

receive()

isConnected()

getDiagnostics()

The interface shall not interpret AquaCom fields.

Potential transport implementations may include:

  • TCP;

  • serial;

  • modem abstraction;

  • serial-over-IP.

The initial implementation only needs transports required by the target environment.


15. AquaCom protocol codec

The protocol codec shall provide deterministic transformation between:


raw transport bytes

and:


AquaComMessage

Logical interfaces:


encode(request) -> bytes

decode(bytes) -> message

validate(bytes) -> validation_result

The codec shall have no network dependency.

This is required so protocol behavior can be exhaustively unit tested.


16. Protocol test vectors

Every implemented AquaCom telegram type shall have test fixtures.

Fixture format shall contain conceptually:


name

source

direction

raw-data

decoded-operation

decoded-fields

expected-validation

notes

Example source classifications:


SPECIFICATION

CAPTURE

KNOWN_GOOD_IMPLEMENTATION

SYNTHETIC_FROM_SPECIFICATION

The test suite shall prove both:


raw → decoded

and where applicable:


object → encoded raw


17. Protocol gap registry

docs/protocol/protocol-gaps.md shall maintain unresolved protocol issues.

Each entry shall contain:


Gap ID

Description

Affected operation

Evidence available

Evidence missing

Impact

Implementation status

Example:


AQ-GAP-007

Exact encoding of history timestamp field for controller type X

is not yet verified.

Impact:

History retrieval cannot be enabled for this controller type.

Required evidence:

Protocol specification or validated capture.

The implementation agent shall not close a protocol gap without evidence.

Evidence acquisition plan

Protocol evidence does not currently exist in this repository. The evidence rule above is therefore not executable until evidence is acquired. Until then, Phase 3 (codec framework) may proceed with the framework, fixture and simulation scaffolding, but no telegram behavior may be implemented.

Evidence shall be acquired through at least one of:

  1. obtaining the authoritative AquaCom protocol specification from the equipment vendor or system owner;
  2. capturing traffic from a known-good AquaCom deployment (sanitized per §64 before committing);
  3. deriving behavior from an existing known-good integration.

The responsible party for obtaining the authoritative documentation shall be identified before Phase 3 starts, and the acquisition status shall be tracked in docs/protocol/protocol-gaps.md until resolved. Implementation milestones that depend on specific operations (live polling, history retrieval) are blocked by missing evidence for those operations and shall be sequenced after the evidence exists.


18. AquaCom session manager

Each configured station shall use an independent session/state abstraction.

Conceptual states:


DISABLED

INITIALIZING

CONNECTING

ONLINE

DEGRADED

OFFLINE

RECOVERING

Basic transition:


             successful communication

OFFLINE ──────────────────────────────► ONLINE

ONLINE

  │

  │ repeated communication failures

  ▼

DEGRADED

  │

  │ threshold exceeded

  ▼

OFFLINE

  │

  │ transport available

  ▼

RECOVERING

  │

  │ successful synchronization

  ▼

ONLINE

Thresholds shall be configurable.


19. Live acquisition scheduler

The live acquisition scheduler shall:

  • schedule AquaCom live requests;

  • apply per-station polling configuration;

  • prevent overlapping invalid station transactions;

  • prioritize live communication over history backfill;

  • implement retry policy;

  • update communication diagnostics.

The scheduler shall not write directly to OPC UA.

It shall publish canonical CurrentValue updates.


20. Current-state service

The Current-State Service shall maintain the latest accepted current value for each PointId.

Interface equivalent:


update(CurrentValue)

get(PointId)

getAll(StationId)

subscribe(PointId)

The service shall reject obsolete updates where appropriate.

A recovered historical sample shall not invoke:


CurrentState.update()

unless it has independently been determined to represent current state.


21. Historical acquisition manager

The Historical Acquisition Manager shall manage history retrieval from AquaCom stations.

Responsibilities:

  • determine retrieval windows;

  • initiate historical requests;

  • maintain synchronization watermark;

  • process partial responses;

  • resume interrupted synchronization;

  • throttle retrieval;

  • deduplicate;

  • send canonical historical samples to the historical pipeline.

Conceptual interface:


synchronize(station)

synchronize(station, start, end)

getSynchronizationState(station)

pause(station)

resume(station)


22. Synchronization watermark

Each station shall maintain persistent history synchronization state.

Example:


StationId

HistoryStreamId

LastCompleteTimestamp

LastAttemptTimestamp

LastSuccessfulTimestamp

SynchronizationState

The watermark shall only advance when the implementation has sufficient evidence that the interval has been processed successfully. The precise advancement condition — durably spooled, not finally delivered — is defined in ARCHITECTURE.md §21; final delivery is tracked independently through per-destination spool acknowledgements.


23. Historical recovery state machine

Conceptual history states:


IDLE

CHECK_REQUIRED_RANGE

REQUESTING

RECEIVING

PERSISTING

VERIFYING

COMPLETE

RETRY_WAIT

FAILED

Typical sequence:


IDLE

  │

  ▼

CHECK_REQUIRED_RANGE

  │

  ▼

REQUESTING

  │

  ▼

RECEIVING

  │

  ▼

PERSISTING

  │

  ▼

VERIFYING

  │

  ├── incomplete ──► REQUESTING

  │

  └── complete ───► COMPLETE

A restart during synchronization shall resume from persistent state without requiring complete duplication of the historical interval.


24. Historical pipeline

The historical pipeline shall receive:


HistoricalSample

and perform:


validation

    ↓

normalization

    ↓

deduplication

    ↓

durable enqueue

    ↓

distribution

Conceptually:


HistoricalSample

       │

       ▼

Validator

       │

       ▼

Deduplicator

       │

       ▼

Durable spool

       │

 ┌─────┼─────────┐

 ▼     ▼         ▼

Repo  Store A   Store B


25. Deduplication key

Default logical identity:


StationId

+

PointId

+

SourceTimestamp

If AquaCom supplies a stronger identity such as a sequence number, the implementation may include it.

The deduplication algorithm shall be deterministic.

Collision behavior shall be configurable:


KEEP_FIRST

KEEP_LAST

REJECT_CONFLICT

VERSION_CONFLICT

The configuration reference (docs/configuration/configuration-reference.md §24.2) names these policies keep-first, keep-last, reject, and version; the semantic mapping between the two namings shall be kept in the configuration model so the same policy cannot drift apart between documents.

Recommended default:


REJECT_CONFLICT

where conflicting values are stored diagnostically rather than silently overwritten.

Deduplication state shall remain correct across restart (see ARCHITECTURE.md §23): a restart during synchronization shall not introduce duplicate records, either through persisted deduplication state or through idempotent storage.

The deduplication window shall be bounded.


26. History repository interface

A History Repository is a queryable source used by OPC UA Historical Access.

Required logical interface:


store(sample)

storeBatch(samples)

readRaw(

    pointId,

    startTime,

    endTime,

    limit,

    continuation

)

readAtTime(

    pointId,

    timestamps

)

getBounds(pointId)

health()

The repository may be:

  • local;

  • external;

  • relational;

  • time-series;

  • industrial historian.

OPC UA shall interact only through this abstraction.


27. Storage sink interface

A storage sink is an independent history destination.

Required interface:


initialize()

write(sample)

writeBatch(samples)

flush()

health()

shutdown()

A storage sink does not need to support queries.

Examples:


SQL sink

time-series sink

industrial historian sink

file/archive sink

message-stream sink


28. Repository versus sink

These concepts shall remain distinct.


Repository

    = historical data can be queried

Sink

    = historical data can be delivered

A component may implement both interfaces.

Example:


Local historian:

    Repository = yes

    Sink       = yes

Archive file:

    Repository = no

    Sink       = yes


29. Durable spool

Historical delivery shall pass through persistent buffering.

Conceptual record:


SpoolRecord

RecordId

HistoricalSample

CreatedTimestamp

Destinations[]

Acknowledgements[]

RetryState

Example:


record 123

StorageLocal       ACK

CentralHistorian   PENDING

Archive            ACK

Record 123 shall remain available until required delivery policy has been fulfilled.


30. Delivery policy

Configuration shall define whether a destination is:


REQUIRED

OPTIONAL

Example:


LocalHistory:

    REQUIRED

CentralHistorian:

    REQUIRED

ArchiveExport:

    OPTIONAL

A failed optional destination shall generate diagnostics but shall not indefinitely block spool cleanup.


31. Storage failure handling

Each storage destination shall implement independent retry.

Recommended conceptual retry progression:


immediate

short delay

increasing delay

maximum delay

periodic retry

Exact timing shall be configurable.

Retries shall not block live acquisition.


32. OPC UA module

The OPC UA module shall contain:


Server lifecycle

Namespace manager

Node mapping

Current-value provider

Historical provider

StatusCode mapper

Security configuration

Diagnostics exposure

It shall depend upon:


core

current-state service

history repository

diagnostics

It shall not depend directly upon AquaCom transport or AquaCom codec.


33. OPC UA namespace mapping

Default structure:


AquaCom

│

├── Gateway

│   ├── Status

│   ├── Version

│   ├── StartTime

│   ├── ConfigurationVersion

│   ├── HistoricalQueueDepth

│   └── Storage

│

└── Stations

    │

    ├── PS001

    │   ├── Process

    │   │   ├── Level

    │   │   ├── Pump01Running

    │   │   └── Pump02Running

    │   │

    │   └── Diagnostics

    │       ├── CommunicationState

    │       ├── LastCommunication

    │       ├── HistoryState

    │       └── HistoryWatermark

    │

    └── PS002

Namespace generation shall be deterministic.


34. OPC UA NodeId generation

OPC UA NodeIds shall derive from stable internal identifiers.

Example:


ns=<gateway namespace>;s=station/PS001/point/LEVEL

The exact syntax may differ.

The critical requirement is:


same logical point

        =

same NodeId

across:

  • restart;

  • upgrade;

  • rename;

  • transport address change.


35. OPC UA current-value mapping

For each configured live point:


CurrentValue.Value

    → OPC UA Value

CurrentValue.SourceTimestamp

    → OPC UA SourceTimestamp

gateway processing time

    → OPC UA ServerTimestamp

CurrentValue.Quality

    → OPC UA StatusCode

If communication fails, the node shall transition to a suitable non-Good status according to configuration.


36. OPC UA history provider

When an OPC UA client sends:


HistoryRead

the OPC UA layer shall call:


HistoryRepository.readRaw()

It shall never directly cause:


AquaCom history request

The following is prohibited:


OPC UA HistoryRead

        │

        ▼

AquaCom WGH request

        │

        ▼

wait for RTU

Correct behavior:


AquaCom synchronization

        │

        ▼

Repository

OPC UA HistoryRead

        │

        ▼

Repository


37. OPC UA historical continuation

The implementation shall support bounded historical reads.

Configuration:


opcua.historicalAccess.maxValuesPerRead

(This is the field defined in docs/configuration/configuration-reference.md §19.3. Earlier revisions of this document called it maximumValuesPerHistoryRead; the configuration-reference name is authoritative.)

If more values exist than can be returned:


HistoryRead

   │

   ▼

batch 1 + continuation token

   │

   ▼

HistoryRead continuation

   │

   ▼

batch 2

Continuation state shall be resource-limited.


38. Time handling

Internal canonical timestamps shall be timezone-unambiguous.

Preferred internal representation:


UTC timestamp

Station configuration shall define AquaCom timezone interpretation where required.

Configuration fields shall include concepts equivalent to:


timezone

timestampSource

maximumFutureDeviation

maximumPastDeviation

dstPolicy

The raw source timestamp may optionally also be retained for diagnostics.


39. Configuration model

A gateway configuration shall contain approximately:


gateway

logging

opcua

history

storage

stations

security

diagnostics


40. Gateway configuration

Conceptual example:


gateway:

  id: aquacom-gateway-01

  site: central-ot

  timezone: Europe/Stockholm


41. Station configuration

Conceptual configuration:


station:

  id: PS001

  enabled: true

  transport:

    type: tcp

    ...

  aquacom:

    address: ...

    profile: ...

  acquisition:

    live:

      enabled: true

      interval: ...

    history:

      enabled: true

      synchronization: ...

  points:

    source: ...

Exact syntax shall be selected during technology selection.


42. Point configuration

Conceptual:


point:

  id: LEVEL

  name: Wet well level

  source:

    aquacomReference: ...

  datatype: float

  engineeringUnit: m

  live:

    enabled: true

  history:

    enabled: true

  opcua:

    enabled: true

    historizing: true

  storage:

    enabled: true


43. Configuration schema validation

Machine-readable schemas shall validate configuration before startup.

Validation shall detect:

  • duplicate station IDs;

  • duplicate point IDs;

  • invalid references;

  • impossible polling intervals;

  • unsupported transports;

  • missing required storage;

  • invalid timezone;

  • duplicate OPC UA NodeIds;

  • invalid security configuration.

Invalid configuration shall fail safely.


44. Secrets

Secrets shall be supplied through an external secret mechanism appropriate to the selected deployment environment.

The repository shall never contain production:


passwords

private keys

API tokens

certificate private keys

database credentials

Example files shall use placeholders.


45. Diagnostics model

Gateway-level diagnostics:


GatewayState

Version

ConfigurationVersion

StartTime

Uptime

StationCount

OnlineStationCount

HistoricalQueueDepth

SpoolDiskUsage

OPCUAState

Per-station:


CommunicationState

LastRequest

LastResponse

LastSuccessfulCommunication

ConsecutiveFailures

ProtocolErrors

HistorySynchronizationState

HistoryWatermark

HistoricalBacklog

Per-storage destination:


State

LastSuccessfulWrite

LastFailure

PendingRecords

Retries

Latency


46. Logging requirements

Structured logging shall be preferred.

Every log record should support context equivalent to:


timestamp

severity

component

stationId?

pointId?

operation?

correlationId?

message

error?

Raw telegram logging shall be a separate debug facility.

Production default shall not log every telegram.


47. Correlation IDs

AquaCom transactions shall have a transaction/correlation identifier.

Example flow:


AQ transaction 81245

      │

      ├── send request

      ├── receive response

      ├── decode

      ├── update values

      └── diagnostics

This ID should be propagated through relevant diagnostics.


48. Metrics

The implementation shall expose or internally maintain metrics equivalent to:


aquacom_requests_total

aquacom_errors_total

aquacom_request_duration

station_online

live_values_processed

history_samples_received

history_samples_deduplicated

history_samples_pending

storage_writes_total

storage_write_errors

opcua_clients_connected

opcua_history_reads

spool_bytes

Specific metrics technology shall not be prescribed.


49. Simulator

A simulator shall be treated as a first-class component.

It shall support scripted station behavior.

Required simulation scenarios:


normal live operation

communication timeout

connection loss

malformed response

bad checksum

delayed response

historical values

historical gap

duplicate history

conflicting duplicate

station clock error

reconnect and backfill

The simulator shall not share parsing code with the production AquaCom decoder in ways that make protocol tests self-validating.


50. Test pyramid

The project shall implement:


                 Acceptance

                    /\

                   /  \

              Integration

                /      \

               /        \

             Unit tests

The majority of tests should be deterministic unit and component tests.


51. Required unit tests

AquaCom codec


framing

checksum

address encoding

telegram decoding

invalid telegram rejection

unexpected field handling

Canonical model


quality mapping

timestamp validation

stable identifier handling

History


deduplication

watermark progression

gap handling

conflict handling

spool acknowledgement

OPC UA


NodeId mapping

quality mapping

timestamp mapping

history result conversion


52. Required integration tests

At minimum:


Simulator → AquaCom engine

AquaCom engine → Current State

AquaCom history → Historical pipeline

Historical pipeline → Repository

Historical pipeline → multiple sinks

Repository → OPC UA HistoryRead

Current state → OPC UA subscription


53. Restart recovery tests

Automated tests shall cover gateway restart during:


normal operation

history retrieval

database outage

spool backlog

partial delivery

reconnect recovery

Expected result:

No acknowledged historical data is silently lost.


54. End-to-end mandatory acceptance test

Scenario:


T0:

Station online.

Gateway receives live level values.

OPC UA client receives current values.

Values are persisted historically.

T1:

Station communication is interrupted.

Gateway marks communication degraded/bad.

Current OPC UA value is not falsely reported as newly valid.

T2:

Station continues local historical recording.

T3:

Communication returns.

Live acquisition resumes promptly.

T4:

Gateway identifies missing historical interval.

Gateway retrieves historical records.

T5:

Historical records retain their original timestamps.

They are delivered to all required storage destinations.

T6:

OPC UA current value remains the actual current process value.

T7:

OPC UA HistoryRead for T1–T4 returns recovered historical values.

T8:

Same historical interval is retrieved again.

No unintended duplicate historical records are created.

The system shall not be considered production-capable until this test passes.


55. Security tests

Tests shall verify:


untrusted OPC UA client certificate rejected

trusted client accepted

insecure OPC UA endpoint disabled by production configuration

invalid credentials rejected where user authentication is enabled

private keys not logged

unauthorized HistoryUpdate rejected

configuration containing secret placeholders validated appropriately


56. Fault injection

Integration testing shall permit fault injection including:


network disconnect

packet loss

delayed responses

storage timeout

storage exception

disk-full simulation

OPC UA client disconnect

process restart

corrupted local spool entry


57. CI requirements

Every change shall run:


format/lint checks

static validation

unit tests

integration tests suitable for CI

configuration schema validation

dependency/security checks where available

Protocol fixtures shall be testable without external network access.


58. Pull request completion criteria

The implementation agent shall consider a development task complete only when:


implementation exists

tests exist

tests pass

relevant documentation is updated

configuration examples are updated if required

no known architectural boundary has been violated

new protocol behavior has supporting evidence

new failure modes have diagnostics

no production secrets have been introduced

Implementation-agent task prompts work best when scoped similarly to concrete issues or PRs with explicit files and expected outcomes.


59. ExecPlan requirement

The implementation agent shall create an ExecPlan for work involving:

  • new AquaCom operations;

  • history synchronization;

  • storage architecture;

  • OPC UA namespace redesign;

  • security changes;

  • cross-module refactoring;

  • persistent-data migration;

  • changes affecting more than one architectural boundary.

ExecPlan structure:


Title

Purpose

Current state

Desired state

Constraints

Files/components affected

Implementation sequence

Data model changes

Failure handling

Testing

Migration/compatibility

Progress

Decisions

Unexpected findings

Acceptance evidence

The plan shall remain updated while implementation proceeds.


60. Development phases

Implementation shall proceed in controlled phases.


Phase 0 – Repository and architecture

Deliver:


AGENTS.md

README.md

ARCHITECTURE.md

docs structure

CI skeleton

configuration skeleton

No AquaCom protocol implementation required.

Acceptance:

  • repository builds;

  • automated test runner works;

  • architecture dependencies documented.


Phase 1 – Canonical core

Implement:


StationId

PointId

CurrentValue

HistoricalSample

DataQuality

AcquisitionSource

configuration domain

Acceptance:

  • unit tests;

  • serialization tests where applicable;

  • stable identifier behavior defined.


Phase 2 – AquaCom transport abstraction

Implement:


transport interface

connection lifecycle

timeouts

retry primitives

diagnostics

Implement only required initial transport.

Acceptance:

  • mock transport tests;

  • connection-loss testing;

  • reconnect testing.


Phase 3 – AquaCom codec framework

Implement:


frame abstraction

message abstraction

codec interfaces

validation framework

fixture framework

Only protocol elements with evidence may be implemented.

Acceptance:


captured/documented telegram

        ↓

decoder

        ↓

expected structured representation


Phase 4 – AquaCom simulator

Implement simulator before depending on field equipment for normal development.

Acceptance:

  • successful transaction;

  • timeout;

  • malformed telegram;

  • configurable process values.


Phase 5 – Station/session manager

Implement:


station lifecycle

communication state

poll scheduling

retry policy

diagnostics

Acceptance:

  • multiple simulated stations;

  • one station failing does not affect others.


Phase 6 – Live acquisition

Implement:


live AquaCom operation

point mapping

scaling

canonical CurrentValue

current-state cache

Acceptance:


simulated AquaCom

      ↓

CurrentValue

with correct value, quality and timestamps.


Phase 7 – OPC UA live interface

Implement:


server

namespace

stable NodeIds

current reads

subscriptions

quality

timestamps

security

Acceptance:

An OPC UA test client can browse and subscribe to simulated AquaCom values.


Phase 8 – Local historical repository

Implement the first queryable history repository.

The selected technology may be embedded or external, but shall implement the defined repository abstraction.

Acceptance:


store

query interval

query bounds

restart persistence


Phase 9 – Historical pipeline

Implement:


validation

deduplication

durable spool

delivery

repository integration

Acceptance:

Multiple submissions of the same sample do not produce unintended duplicate records.


Phase 10 – AquaCom historical acquisition

Implement only after sufficient protocol evidence is available.

Deliver:


history retrieval

watermark

reconnect synchronization

backfill

throttling

partial recovery

Acceptance:

The simulator's missing time interval is recovered after reconnection.


Phase 11 – OPC UA Historical Access

Implement:


HistoryRead

raw values

timestamps

quality

continuation

Acceptance:

An OPC UA HA client can retrieve both originally stored and recovered historical values.


Phase 12 – Multiple storage destinations

Implement storage sink abstraction plus second sink implementation.

Acceptance:


one HistoricalSample

       │

       ├── Repository A

       └── Storage B

and failure of Storage B does not stop Repository A.


Phase 13 – Store-and-forward resilience

Implement:


persistent spool

destination acknowledgements

retry

backpressure

disk limits

Acceptance:

A storage destination may be offline while history accumulates and receive the backlog when restored.


Phase 14 – Production hardening

Implement and validate:


security

resource limits

performance

operations documentation

backup/recovery

deployment

certificate handling

structured diagnostics

long-duration tests


61. Implementation agent task sizing

Implementation phases shall be divided into bounded tasks rather than requesting the complete gateway in one prompt.

Preferred task structure:


Goal

Relevant files

Required behavior

Constraints

Tests

Acceptance criteria

Example:


Implement the HistoricalSample deduplication service.

Relevant:

src/history

docs/architecture/historical-data.md

Requirements:

- identity based on StationId + PointId + SourceTimestamp

- conflicting value must be detected

- default conflict policy REJECT_CONFLICT

Do not:

- introduce database-specific logic

- modify AquaCom codec

- modify OPC UA

Add unit tests covering:

- first sample

- exact duplicate

- conflicting duplicate

- different point

- different timestamp


62. Rule for incomplete requirements

When the implementation agent encounters an implementation ambiguity, it shall classify it as:


A. Local implementation detail

B. Architectural decision

C. AquaCom protocol uncertainty

D. Safety/security uncertainty

For A:

Choose the simplest implementation consistent with architecture.

For B:

Record the decision in the current ExecPlan.

For C:

Do not guess. Add a protocol gap.

For D:

Choose the safer behavior and document the decision.


63. AquaCom source traceability

Every implemented protocol operation shall have traceability metadata in documentation.

Example:


Operation: HistoricalRead-X

Evidence:

AquaCom specification section 8.3

Capture fixture AQ-HIST-004

Validated against ControllerType-A

Implemented:

yes

Tests:

protocol/history_read_004

This traceability shall make it possible to audit why the implementation behaves as it does.


64. Protocol capture handling

Production captures used as test fixtures shall be:

  • sanitized;

  • stripped of unnecessary network identifiers;

  • documented;

  • immutable once used as reference fixtures.

Fixture modification requires justification.

Raw captures shall not automatically be committed if they contain sensitive operational information.


65. Storage migration rule

Storage schemas shall be versioned.

Schema changes shall have explicit migrations.

Application startup shall not silently destroy incompatible historical data.

Destructive migration requires explicit administrative action.


66. Configuration versioning

The configuration model shall include a schema version.

Example:


configVersion: 1

Future incompatible configuration changes shall provide validation and, where reasonable, migration tooling.


67. Software version exposure

Gateway software version shall be available through:

  • startup logs;

  • diagnostics;

  • OPC UA diagnostics namespace.

Build metadata should include where possible:


version

build identifier

source revision

configuration schema version


68. Compatibility strategy

The gateway shall distinguish:


protocol compatibility

configuration compatibility

storage compatibility

OPC UA namespace compatibility

Changes to any of these shall be considered independently.

Stable OPC UA NodeIds are particularly important and shall not change unnecessarily between releases.


69. Performance validation

Before production acceptance, test:


expected station count

expected point count

normal polling interval

normal historical rate

large backfill

simultaneous OPC UA subscriptions

large HistoryRead

storage unavailable

maximum expected spool backlog

The purpose is to establish capacity limits rather than merely demonstrate successful execution.


70. Live-priority scheduling

AquaCom scheduling shall conceptually prioritize:


1. connection/health-critical transactions

2. current/live acquisition

3. alarm/event retrieval when implemented

4. requested configuration operations

5. historical recovery

6. low-priority maintenance

Historical recovery shall be throttled if required to maintain live acquisition responsiveness.


71. Memory and queue limits

Every queue shall be bounded.

No component may create an unbounded:


message queue

history list

retry list

client response

log buffer

Queue-full behavior shall be explicitly defined.


72. Graceful shutdown

The application shall support controlled shutdown.

Order:


stop accepting administration changes

        ↓

stop scheduling new acquisition

        ↓

complete/cancel active AquaCom transactions

        ↓

persist watermarks

        ↓

flush durable state

        ↓

stop OPC UA

        ↓

close storage

        ↓

terminate


73. Crash recovery

Following unclean shutdown:


load persistent state

        ↓

validate spool

        ↓

recover pending deliveries

        ↓

restore synchronization watermarks

        ↓

reconnect stations

        ↓

resume live operation

        ↓

continue required historical synchronization

Live communication shall normally resume before large backfill jobs.


74. Initial production scope

The first production release shall include:


AquaCom transport

AquaCom protocol framework

verified live-value acquisition

verified historical acquisition

multiple stations

canonical data model

live cache

historical pipeline

deduplication

durable spool

at least one history repository

storage adapter framework

at least two independently configurable storage targets

OPC UA Data Access

OPC UA Historical Access

OPC UA security

stable NodeIds

diagnostics

structured logging

simulator

automated tests

restart recovery

configuration validation


75. Explicitly excluded from first production release

Unless separately approved:


AquaCom remote pump control

AquaCom setpoint write

OPC UA control writes

OPC UA Methods for process control

OPC UA HistoryUpdate

automatic historian correction

clustered high availability

automatic protocol discovery

Read-only process integration shall be established before remote-control functionality is introduced.


76. Future process-control architecture

If control is later implemented, it shall use a separate command pipeline:


OPC UA

   │

   ▼

authorization

   │

   ▼

command validation

   │

   ▼

command service

   │

   ▼

AquaCom control operation

   │

   ▼

confirmation/readback

   │

   ▼

audit

Direct mapping:


OPC UA write → raw AquaCom telegram

shall not be permitted.


77. Definition of Done

The gateway implementation is complete for production evaluation when:

  1. All mandatory Phase 0–14 features are implemented.

  2. No implemented AquaCom operation depends on undocumented guessed protocol behavior.

  3. Current data is available through OPC UA.

  4. Historical data is available through OPC UA Historical Access.

  5. AquaCom history backfill does not alter current values.

  6. Historical source timestamps are preserved.

  7. Gateway restart does not lose acknowledged history.

  8. Temporary storage outage does not immediately cause historical loss.

  9. Multiple storage destinations operate independently.

  10. OPC UA NodeIds are stable.

  11. OPC UA security is enabled by default.

  12. Simulator-based end-to-end acceptance tests pass.

  13. Tests against real AquaCom equipment or validated traffic have passed.

  14. Operational deployment and recovery documentation exists.

  15. Remaining protocol gaps are explicitly documented.


78. Implementation objective

The resulting software shall behave as an integration platform:


                         AquaCom

                            │

                            ▼

                ┌───────────────────────┐

                │  AquaCom Gateway      │

                │                       │

                │ Protocol              │

                │ Acquisition           │

                │ State                 │

                │ History recovery      │

                │ Normalization         │

                │ Diagnostics           │

                └───────┬───────┬───────┘

                        │       │

               LIVE     │       │ HISTORY

                        │       │

                        ▼       ▼

                     OPC UA   Historical pipeline

                        │       │

                        │       ├─────────► Repository

                        │       ├─────────► Historian

                        │       ├─────────► Database

                        │       └─────────► Archive

                        │

                        └───────────────► OPC UA HA

The implementation shall remain usable even if:

  • the SCADA platform changes;

  • the historical database changes;

  • additional storage destinations are introduced;

  • AquaCom equipment is gradually replaced;

  • additional northbound interfaces are introduced.

The gateway's permanent value shall therefore be the normalized information and integration boundary, not merely its OPC UA endpoint.


79. First implementation execution sequence

The recommended first implementation tasks are:


Task 001

Create repository skeleton and architecture documents.

Task 002

Create core domain models and stable identifier rules.

Task 003

Create configuration model and schema validation.

Task 004

Create AquaCom transport abstraction and mock transport.

Task 005

Create AquaCom protocol codec framework without inventing protocol fields.

Task 006

Create protocol fixture/test-vector framework.

Task 007

Create AquaCom simulator architecture.

Task 008

Implement first documented live AquaCom operation.

Task 009

Implement Station Manager and live acquisition.

Task 010

Implement current-state service.

Task 011

Implement OPC UA live-value interface.

Task 012

Implement historical repository abstraction.

Task 013

Implement historical pipeline and deduplication.

Task 014

Implement durable spool.

Task 015

Implement first verified AquaCom historical operation.

Task 016

Implement backfill state machine.

Task 017

Implement OPC UA Historical Access.

Task 018

Implement second storage destination.

Task 019

Implement full reconnect/backfill acceptance test.

Task 020

Production hardening.

Each task shall result in a working repository state rather than leaving the main branch intentionally uncompilable or untestable.


80. Primary instruction to the implementation agent

When implementing this system, prioritize correctness, traceability and recoverability over speed of implementation.

In particular:

Never compensate for missing AquaCom documentation by inventing plausible protocol behavior.

Build the architecture around the unknown portions first.

Add real AquaCom behavior only as verified protocol knowledge becomes available.

Every protocol feature shall be backed by evidence and automated tests.

Every architectural component shall be replaceable behind its documented interface.

Every historical sample shall retain its original process timestamp.

And no recovered historical value shall ever masquerade as a new live process value.