Files
aquacom-gateway-suite/docs/product/codex-implementation-specification.md
T
2026-10-05 20:32:13 +02:00

56 KiB
Raw Blame History

\# Codex Implementation Specification

\## AquaCom Integration Gateway

\*\*Document type:\*\* Implementation specification

\*\*Target implementation agent:\*\* Codex

\*\*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 Codex 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;

\- Codex 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. Codex implementation principles

Codex shall follow these principles throughout development.

\## 3.1 Do not invent AquaCom protocol details

Codex 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 Codex to the authoritative project documentation rather than attempt to contain the complete project specification.

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

Complex implementation work shall use an execution plan maintained in the repository. OpenAI's current Codex guidance explicitly 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 shall contain approximately the following instructions.




\\# AquaCom Integration Gateway







Read ARCHITECTURE.md and the relevant documents under docs/ before



changing implementation behavior.







For substantial features, protocol changes, persistence changes, or



cross-module refactors, create or update an ExecPlan under



docs/exec-plans/active/.







\\## Non-negotiable architecture rules







1\\. AquaCom protocol parsing belongs only in src/aquacom.



2\\. OPC UA must never parse AquaCom telegrams.



3\\. Storage adapters consume canonical historical records only.



4\\. Historical samples must never be replayed as current process values.



5\\. Preserve source timestamps separately from gateway receipt timestamps.



6\\. Stable point IDs and OPC UA NodeIds must survive restart and renaming.



7\\. Do not invent undocumented AquaCom protocol behavior.



8\\. Every protocol implementation requires automated test vectors.



9\\. Every bug fix requires a regression test where practical.



10\\. Live acquisition takes priority over historical backfill.







\\## AquaCom protocol evidence







Protocol behavior may only be implemented using documented or validated



evidence stored or referenced from docs/protocol/.







If information is insufficient, document the gap in



docs/protocol/protocol-gaps.md instead of guessing.







\\## Testing







Run applicable unit, integration and acceptance tests before considering



a task complete.







Do not weaken or remove tests merely to make a change pass.







\\## Security







Never commit secrets, private keys, production certificates, passwords



or production network addresses.







OPC UA insecure modes must not become the production default.







\\## Documentation







Update relevant architecture or configuration documentation whenever



observable behavior changes.



Nested AGENTS.md files may later be added where a specific module requires additional constraints.

Codex supports 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.

\---

\# 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.



Codex shall not close a protocol gap without evidence.

\---

\# 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.

\---

\# 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



Recommended default:




REJECT\\\_CONFLICT



where conflicting values are stored diagnostically rather than silently overwritten.

\---

\# 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



\&#x20;       =



same NodeId



across:

\- restart;

\- upgrade;

\- rename;

\- transport address change.

\---

\# 35. OPC UA current-value mapping

For each configured live point:




CurrentValue.Value



\&#x20;   → OPC UA Value







CurrentValue.SourceTimestamp



\&#x20;   → OPC UA SourceTimestamp







gateway processing time



\&#x20;   → OPC UA ServerTimestamp







CurrentValue.Quality



\&#x20;   → 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



\&#x20;       │



\&#x20;       ▼



AquaCom WGH request



\&#x20;       │



\&#x20;       ▼



wait for RTU



Correct behavior:




AquaCom synchronization



\&#x20;       │



\&#x20;       ▼



Repository







OPC UA HistoryRead



\&#x20;       │



\&#x20;       ▼



Repository



\---

\# 37. OPC UA historical continuation

The implementation shall support bounded historical reads.

Configuration:




maximumValuesPerHistoryRead



If more values exist than can be returned:




HistoryRead



\&#x20;  │



\&#x20;  ▼



batch 1 + continuation token



\&#x20;  │



\&#x20;  ▼



HistoryRead continuation



\&#x20;  │



\&#x20;  ▼



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:



\&#x20; id: aquacom-gateway-01



\&#x20; site: central-ot



\&#x20; timezone: Europe/Stockholm



\---

\# 41. Station configuration

Conceptual configuration:




station:



\&#x20; id: PS001



\&#x20; enabled: true







\&#x20; transport:



\&#x20;   type: tcp



\&#x20;   ...







\&#x20; aquacom:



\&#x20;   address: ...



\&#x20;   profile: ...







\&#x20; acquisition:



\&#x20;   live:



\&#x20;     enabled: true



\&#x20;     interval: ...







\&#x20;   history:



\&#x20;     enabled: true



\&#x20;     synchronization: ...







\&#x20; points:



\&#x20;   source: ...



Exact syntax shall be selected during technology selection.

\---

\# 42. Point configuration

Conceptual:




point:



\&#x20; id: LEVEL



\&#x20; name: Wet well level







\&#x20; source:



\&#x20;   aquacomReference: ...







\&#x20; datatype: float



\&#x20; engineeringUnit: m







\&#x20; live:



\&#x20;   enabled: true







\&#x20; history:



\&#x20;   enabled: true







\&#x20; opcua:



\&#x20;   enabled: true



\&#x20;   historizing: true







\&#x20; storage:



\&#x20;   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



\&#x20;     │



\&#x20;     ├── send request



\&#x20;     ├── receive response



\&#x20;     ├── decode



\&#x20;     ├── update values



\&#x20;     └── 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:




\&#x20;                Acceptance



\&#x20;                   /\\\\



\&#x20;                  /  \\\\



\&#x20;             Integration



\&#x20;               /      \\\\



\&#x20;              /        \\\\



\&#x20;            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

Codex 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



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

\---

\# 59. ExecPlan requirement

Codex 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



\&#x20;       ↓



decoder



\&#x20;       ↓



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



\&#x20;     ↓



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



\&#x20;      │



\&#x20;      ├── Repository A



\&#x20;      └── 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. Codex 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. Codex rule for incomplete requirements

When Codex 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



\&#x20;       ↓



stop scheduling new acquisition



\&#x20;       ↓



complete/cancel active AquaCom transactions



\&#x20;       ↓



persist watermarks



\&#x20;       ↓



flush durable state



\&#x20;       ↓



stop OPC UA



\&#x20;       ↓



close storage



\&#x20;       ↓



terminate



\---

\# 73. Crash recovery

Following unclean shutdown:




load persistent state



\&#x20;       ↓



validate spool



\&#x20;       ↓



recover pending deliveries



\&#x20;       ↓



restore synchronization watermarks



\&#x20;       ↓



reconnect stations



\&#x20;       ↓



resume live operation



\&#x20;       ↓



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



\&#x20;  │



\&#x20;  ▼



authorization



\&#x20;  │



\&#x20;  ▼



command validation



\&#x20;  │



\&#x20;  ▼



command service



\&#x20;  │



\&#x20;  ▼



AquaCom control operation



\&#x20;  │



\&#x20;  ▼



confirmation/readback



\&#x20;  │



\&#x20;  ▼



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:




\&#x20;                        AquaCom



\&#x20;                           │



\&#x20;                           ▼



\&#x20;               ┌───────────────────────┐



\&#x20;               │  AquaCom Gateway      │



\&#x20;               │                       │



\&#x20;               │ Protocol              │



\&#x20;               │ Acquisition           │



\&#x20;               │ State                 │



\&#x20;               │ History recovery      │



\&#x20;               │ Normalization         │



\&#x20;               │ Diagnostics           │



\&#x20;               └───────┬───────┬───────┘



\&#x20;                       │       │



\&#x20;              LIVE     │       │ HISTORY



\&#x20;                       │       │



\&#x20;                       ▼       ▼



\&#x20;                    OPC UA   Historical pipeline



\&#x20;                       │       │



\&#x20;                       │       ├─────────► Repository



\&#x20;                       │       ├─────────► Historian



\&#x20;                       │       ├─────────► Database



\&#x20;                       │       └─────────► Archive



\&#x20;                       │



\&#x20;                       └───────────────► 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 Codex execution sequence

The recommended first Codex 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 Codex

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.