[Perl] DAQ system for the FAPG.
chore migrate AGENTS directives to Kiro steering files
Move all project rules from AGENTS.org to .kiro/steering/: - project-context.md: architecture, users, messaging - code-conventions.md: Perl/Bash style, repo structure - testing.md: Test2::V0, prove, dashboard test guidelines - version-control.md: conventional commits, AI author fields - deployment-safety.md: operational code protections Remove AGENTS.org and AGENTS.override.md.
Changed files
.kiro/steering/code-conventions.md
@@ -0,0 +1,39 @@
1
Added:
# Code Conventions
2
Added:
3
Added:
## Repository Map
4
Added:
5
Added:
- `README.org` — overall architecture
6
Added:
- `lib/FAPG/DAQ/` — shared Perl modules
7
Added:
- `roles/daq-node/` — probe reader script and node service (Pi Zeros)
8
Added:
- `roles/daq-hub/` — MQTT broker configuration (Pi 5)
9
Added:
- `roles/daq-recorder/` — MQTT-to-database recorder (VPS)
10
Added:
- `roles/dashboard/` — Mojolicious dashboard (VPS)
11
Added:
- `roles/vpn/` — WireGuard notes and host configs
12
Added:
- `t/` — end-to-end smoke tests and multi-role tests
13
Added:
- `CAD/` — enclosure design files
14
Added:
15
Added:
## Structure Rules
16
Added:
17
Added:
- Shared DAQ behavior goes under `lib/FAPG/DAQ/` when used by more than one role.
18
Added:
- Role-local code stays under that role's `lib`, `bin`, `etc`, or `t` tree.
19
Added:
20
Added:
## Perl
21
Added:
22
Added:
- Target Perl v5.32.1.
23
Added:
- Use strict/warnings.
24
Added:
- STDOUT and STDERR should provide useful diagnostics for the Systemd journal.
25
Added:
- After modifying Perl code:
26
Added:
- Lint with Perl-Critic as severely as possible.
27
Added:
- Reformat with Perl-Tidy using the `.perltidyrc` at the project root.
28
Added:
- Use `JSON::PP` for structured JSON parsing and generation.
29
Added:
30
Added:
## Shell
31
Added:
32
Added:
- Shell scripts use Bash.
33
Added:
- Follow Google's Bash shell style guide.
34
Added:
- Check with shellcheck for critical warnings after modifications.
35
Added:
36
Added:
## General
37
Added:
38
Added:
- All scripts begin with an appropriate shebang line.
39
Added:
- Executable bits on scripts must be preserved.
.kiro/steering/deployment-safety.md
@@ -0,0 +1,21 @@
1
Added:
# Deployment and Host Safety
2
Added:
3
Added:
## Operational Code
4
Added:
5
Added:
Files under `roles/*/etc`, `roles/*/deploy`, `roles/vpn`, and `configure-sd-card` are operational code. Treat with care.
6
Added:
7
Added:
## Prohibited Changes (unless explicitly requested)
8
Added:
9
Added:
- Do NOT rotate credentials, hostnames, usernames, IP addresses, WireGuard keys, MQTT ACLs, or systemd unit names.
10
Added:
- Keep service names stable unless all dependent deployment scripts and docs are updated together.
11
Added:
12
Added:
## Dashboard Notes
13
Added:
14
Added:
- The dashboard is a Mojolicious app under `roles/dashboard`.
15
Added:
- API responses are not stable. Frontend JS must be updated following backend API modifications.
16
Added:
- Database path can be overridden with `FAPG_DAQ_DB` env var.
17
Added:
18
Added:
## Documentation
19
Added:
20
Added:
- Use Org Mode (`.org` files) for project documentation.
21
Added:
- Update architecture docs when MQTT topics, payload schema, host roles, or data flow change.
.kiro/steering/project-context.md
@@ -0,0 +1,40 @@
1
Added:
# Project Context
2
Added:
3
Added:
This project implements a data acquisition (DAQ) system for an aquaponic farm: the *Ferme Aquaponique du Pays de Gex*, located in the Pays de Gex, France.
4
Added:
5
Added:
Website: https://www.lafermeaquaponique.com/
6
Added:
7
Added:
## Users
8
Added:
9
Added:
- Customers are aquaponic farmers.
10
Added:
- Assume no higher IT sophistication than the average person.
11
Added:
- Assume deep expertise in aquaponic farm design and operation.
12
Added:
13
Added:
## Architecture
14
Added:
15
Added:
All hosts are on the same farm LAN.
16
Added:
17
Added:
- 4 DAQ nodes: Raspberry Pi 2W units, each with 1 Atlas Scientific USB EZO carrier board + 1 probe
18
Added:
- 1 DAQ hub: Raspberry Pi 5 (MQTT broker)
19
Added:
- 1 DAQ recorder: remote VPS (persists MQTT messages to SQLite)
20
Added:
- 1 Dashboard: same VPS (Mojolicious web app)
21
Added:
22
Added:
Probes: pH, EC, Dissolved Oxygen, ORP (all Atlas Scientific).
23
Added:
24
Added:
## Messaging
25
Added:
26
Added:
- DAQ nodes publish readings over MQTT.
27
Added:
- DAQ hub acts as MQTT broker.
28
Added:
- DAQ recorder persists all MQTT messages to a relational database.
29
Added:
- Topics: `fapg/daq/<probe>/<node>/reading`
30
Added:
- Schema: `fapg.daq.reading.v1`
31
Added:
- Probe keys are always lowercase: `ph`, `do`, `orp`, `ec`.
32
Added:
33
Added:
## OS Versions
34
Added:
35
Added:
| Host | OS | Version |
36
Added:
|--------------|----------------------|----------|
37
Added:
| DAQ nodes | Raspberry Pi OS Lite | Trixie |
38
Added:
| DAQ hub | Raspberry Pi OS Lite | Trixie |
39
Added:
| DAQ recorder | Debian 11 | Bullseye |
40
Added:
| Dev machine | Gentoo | latest |
.kiro/steering/testing.md
@@ -0,0 +1,22 @@
1
Added:
# Testing
2
Added:
3
Added:
## Framework
4
Added:
5
Added:
- Use TAP tests with the `Test2::V0` package.
6
Added:
- Run tests with `prove`.
7
Added:
- Run all tests in a directory after modifying files in that directory.
8
Added:
9
Added:
## Test Layouts
10
Added:
11
Added:
- `t/` — end-to-end smoke tests and multi-role tests
12
Added:
- `roles/*/t/` — role-specific tests
13
Added:
14
Added:
## Dashboard Page Tests
15
Added:
16
Added:
- Focus on: route health, page identity, core user-facing content, essential accessibility semantics, and `data-*` hooks for JS.
17
Added:
- Test shared layout behavior on one representative page, not every page.
18
Added:
- Cover all probe keys using compact, data-driven assertions.
19
Added:
- Limit negative assertions to meaningful boundaries (unknown routes, deprecated routes, regressions).
20
Added:
- Do NOT assert incidental wrappers, styling-only classes, or unrelated elements.
21
Added:
- Keep page-rendering and endpoint-behavior tests separate when a page exposes non-HTML responses.
22
Added:
- Max 50 assertions per rendered page.
.kiro/steering/version-control.md
@@ -0,0 +1,25 @@
1
Added:
# Version Control
2
Added:
3
Added:
## Git
4
Added:
5
Added:
- Use Git as the version control system.
6
Added:
- Public repo: https://git.mlnp.fr/FAPG/fapg-daq
7
Added:
8
Added:
## AI Agent Commits
9
Added:
10
Added:
- Commits created by an AI agent must indicate so in `user.name` and `user.email`:
11
Added:
- `user.name`: concatenate agent model name and current agent effort
12
Added:
- `user.email`: a generic email clearly identifying the company that developed the agent
13
Added:
- AI commits must follow the Conventional Commits specification (https://www.conventionalcommits.org/en/v1.0.0/).
14
Added:
- AI commits should include the list of changes in the commit body.
15
Added:
16
Added:
## Conventional Commits
17
Added:
18
Added:
Format: `type(scope): description`
19
Added:
20
Added:
Types used in this project:
21
Added:
- `feat(dashboard):` — new feature
22
Added:
- `fix(dashboard):` — bug fix
23
Added:
- `refactor(dashboard):` — code restructuring
24
Added:
- `test(dashboard):` — test additions/changes
25
Added:
- `chore:` — maintenance tasks
AGENTS.org
@@ -1,238 +0,0 @@
1
Removed:
#+TITLE: Agent Guildance
2
Removed:
#+AUTHOR: Marius Peter
3
Removed:
#+DATE: <2026-07-07 Tue>
4
Removed:
5
Removed:
* Normative language
6
Removed:
7
Removed:
- SHALL :: mandatory.
8
Removed:
- SHOULD :: expected unless there is a documented reason not to.
9
Removed:
- MAY :: optional.
10
Removed:
- MUST NOT :: prohibited.
11
Removed:
12
Removed:
13
Removed:
* Context
14
Removed:
15
Removed:
16
Removed:
** Scope
17
Removed:
18
Removed:
- This project SHALL implement a data acquisition (DAQ) system for an
19
Removed:
aquaponic farm.
20
Removed:
- The farm is the /Ferme Aquaponique du Pays de Gex/, located in the
21
Removed:
/Pays de Gex/ in France.
22
Removed:
23
Removed:
[[https://www.lafermeaquaponique.com/]]
24
Removed:
25
Removed:
26
Removed:
** Users
27
Removed:
28
Removed:
- This project's customers are aquaponic farmers.
29
Removed:
- The project SHALL be designed so as to be most useful to them.
30
Removed:
- Their level of IT sophistication SHALL be assumed to be no higher
31
Removed:
than the average person.
32
Removed:
- Their level of aquaponic farm design and operation expertise SHALL
33
Removed:
be assumed to correspond to deep expertise.
34
Removed:
35
Removed:
36
Removed:
* Architecture
37
Removed:
38
Removed:
39
Removed:
** Hosts and roles
40
Removed:
41
Removed:
All hosts are on the same farm LAN.
42
Removed:
43
Removed:
- 4 DAQ nodes :: 4 Raspberry Pi 2W units, each featuring:
44
Removed:
- 1 [[https://atlas-scientific.com/carrier-boards/electrically-isolated-usb-ezo-carrier-board/][Atlas Scientific USB EZO carrier board]]
45
Removed:
- 1 probe provided by Atlas Scientific
46
Removed:
- 1 DAQ hub :: 1 Raspberry Pi 5 unit
47
Removed:
- 1 DAQ recorder :: 1 remote VPS
48
Removed:
49
Removed:
50
Removed:
** OS versions
51
Removed:
52
Removed:
| Host | OS | Version |
53
Removed:
|--------------+----------------------+----------|
54
Removed:
| DAQ nodes | Raspberry Pi OS Lite | Trixie |
55
Removed:
| DAQ hub | Raspberry Pi OS Lite | Trixie |
56
Removed:
| DAQ recorder | Debian 11 | Bullseye |
57
Removed:
| Dev machine | Gentoo | <latest> |
58
Removed:
59
Removed:
60
Removed:
** Sensor nodes
61
Removed:
62
Removed:
The sensor nodes feature Atlas Scientific probe circuits for:
63
Removed:
64
Removed:
- [[https://atlas-scientific.com/embedded-solutions/ezo-ph-circuit/][pH]],
65
Removed:
- [[https://atlas-scientific.com/embedded-solutions/ezo-conductivity-circuit/][EC]],
66
Removed:
- [[https://atlas-scientific.com/embedded-solutions/ezo-dissolved-oxygen-circuit/][Dissolved Oxygen]],
67
Removed:
- and [[https://atlas-scientific.com/embedded-solutions/ezo-orp-circuit/][ORP]].
68
Removed:
69
Removed:
70
Removed:
** DAQ messaging
71
Removed:
72
Removed:
- The DAQ nodes SHALL publish readings over MQTT.
73
Removed:
- The DAQ hub SHALL act as the MQTT broker.
74
Removed:
- The DAQ recorder SHALL persist all MQTT messages to a relational
75
Removed:
database.
76
Removed:
77
Removed:
78
Removed:
* Repository map
79
Removed:
80
Removed:
- =README.org= :: describes the overall architecture.
81
Removed:
- =lib/FAPG/DAQ/= :: contains shared Perl modules.
82
Removed:
- =roles/daq-node/= :: contains the probe reader script and node
83
Removed:
service file. The Pi Zeros handle this role.
84
Removed:
- =roles/daq-hub/= :: contains MQTT broker configuration. The Pi 5
85
Removed:
handles this role.
86
Removed:
- =roles/daq-recorder/= :: contains the MQTT-to-database recorder.
87
Removed:
The VPS handles this role.
88
Removed:
- =roles/dashboard/= :: contains the Mojolicious dashboard. The VPS
89
Removed:
handles this role.
90
Removed:
- =roles/vpn/= :: contains WireGuard notes and host configs. The VPN
91
Removed:
is instantiated between the Pi 5 and the VPS, so that the VPS may
92
Removed:
subscribe to MQTT messages as if it were on the farm LAN.
93
Removed:
- =t/= :: contains end-to-end smoke tests, and tests involving
94
Removed:
multiple roles.
95
Removed:
- =CAD/= :: contains enclosure design files.
96
Removed:
97
Removed:
98
Removed:
* Code
99
Removed:
100
Removed:
The public code repo is hosted at [[https://git.mlnp.fr/FAPG/fapg-daq]].
101
Removed:
102
Removed:
103
Removed:
** Versions
104
Removed:
105
Removed:
- The project SHALL target Perl v5.32.1.
106
Removed:
- The project SHALL implement tests based on the Test2::V0 Perl
107
Removed:
module.
108
Removed:
109
Removed:
110
Removed:
** Structure
111
Removed:
112
Removed:
- Shared DAQ behavior SHALL appear under =lib/FAPG/DAQ/= when it
113
Removed:
is used by more than one role.
114
Removed:
- Role-local code SHALL stay under that role's =lib=, =bin=,
115
Removed:
=etc=, or =t= tree.
116
Removed:
117
Removed:
118
Removed:
** Perl
119
Removed:
120
Removed:
- Perl code SHALL use strict/warnings.
121
Removed:
- Perl script STDOUT and STDERR SHALL provide useful diagnostics in
122
Removed:
the Systemd journal.
123
Removed:
- After modifying Perl code:
124
Removed:
- Perl scripts SHALL be linted against Perl-Critic, as severely as
125
Removed:
possible.
126
Removed:
- Perl scripts SHALL be reformatted with Perl-Tidy using the
127
Removed:
=.perltidyrc= config file at the root of the project.
128
Removed:
129
Removed:
130
Removed:
** Shell
131
Removed:
132
Removed:
- Shell scripts SHALL be written in Bash.
133
Removed:
- Shell scripts SHALL adhere to Google's Bash shell style guide
134
Removed:
([[https://google.github.io/styleguide/shellguide.html]]).
135
Removed:
- After modifying Bash code:
136
Removed:
- Bash scripts SHOULD be checked with ~shellcheck~ for critical
137
Removed:
warnings.
138
Removed:
139
Removed:
140
Removed:
** Conventions
141
Removed:
142
Removed:
- All scripts SHALL begin with an appropriate shebang line.
143
Removed:
- MQTT readings SHALL use the =fapg.daq.reading.v1= schema and topics
144
Removed:
shaped like:
145
Removed:
146
Removed:
#+begin_src text
147
Removed:
fapg/daq/<probe>/<node>/reading
148
Removed:
#+end_src
149
Removed:
150
Removed:
- Probe keys SHALL be in lowercase in payloads and topics: =ph=, =do=,
151
Removed:
=orp=, and =ec=.
152
Removed:
- Structured JSON parsing and generation SHALL be handled through
153
Removed:
=JSON::PP=.
154
Removed:
155
Removed:
156
Removed:
** Tests
157
Removed:
158
Removed:
159
Removed:
*** Basic requirements
160
Removed:
161
Removed:
- The project SHALL implement TAP tests using the =Test2::V0= package.
162
Removed:
- Tests SHALL be ran using the =prove= command.
163
Removed:
- All tests in a given directory SHALL be ran after modifying one or
164
Removed:
more files in that directory. In case of modifications spanning
165
Removed:
multiple directories, tests in each of those directories SHALL be
166
Removed:
ran.
167
Removed:
168
Removed:
169
Removed:
*** Test layouts
170
Removed:
171
Removed:
- =t/= :: end-to-end smoke tests, and tests involving more than one
172
Removed:
role.
173
Removed:
- =roles/*/t/= :: role-specific tests.
174
Removed:
175
Removed:
176
Removed:
*** Dashboard page tests
177
Removed:
178
Removed:
- Page-rendering tests SHOULD focus on route health, page identity,
179
Removed:
core user-facing content and actions, essential accessibility
180
Removed:
semantics, and =data-*= hooks required by JavaScript behavior.
181
Removed:
- Shared layout behavior SHALL be tested on one representative page
182
Removed:
rather than repeated on every page.
183
Removed:
- Collections of configured probes SHOULD cover every probe key using
184
Removed:
compact, data-driven assertions.
185
Removed:
- Negative page assertions SHOULD be limited to meaningful boundaries,
186
Removed:
such as unknown routes, deprecated routes, cross-probe content
187
Removed:
isolation, or a documented regression.
188
Removed:
- Incidental wrappers, styling-only classes, and the presence or
189
Removed:
absence of every unrelated page element SHOULD NOT be asserted.
190
Removed:
- Page-rendering tests and endpoint behavior tests SHOULD be kept
191
Removed:
separate when a page also exposes downloads or another non-HTML
192
Removed:
response.
193
Removed:
- A page-rendering test SHOULD use no more than 50 assertions per
194
Removed:
rendered page.
195
Removed:
196
Removed:
197
Removed:
** Version control system
198
Removed:
199
Removed:
- The project SHALL use Git as its version control system.
200
Removed:
- Commits created by an AI agent SHALL indicate so in the =user.name=
201
Removed:
and =user.email= fields.
202
Removed:
- The =user.name= field shall be constructed by concatenating agent
203
Removed:
model name and current agent effort.
204
Removed:
- The =user.email= field shall be filled with a generic e-mail
205
Removed:
address clearly identifying the company which developed the agent.
206
Removed:
- Commits generated by agents SHALL follow the [[https://www.conventionalcommits.org/en/v1.0.0/#specification][Conventional Commits]]
207
Removed:
specification.
208
Removed:
- Commits generated by agents SHOULD include the list of changes
209
Removed:
included in the commit in the commit body.
210
Removed:
211
Removed:
212
Removed:
* Deployment and host safety
213
Removed:
214
Removed:
- Files under =roles/*/etc=, =roles/*/deploy=, =roles/vpn=, and
215
Removed:
=configure-sd-card= SHALL be treated as operational code.
216
Removed:
- Credentials, hostnames, usernames, IP addresses, WireGuard keys,
217
Removed:
MQTT ACLs, and systemd unit names MUST NOT be rotated, unless the
218
Removed:
task explicitly asks for it.
219
Removed:
- Service names SHOULD be kept stable, unless all dependent deployment
220
Removed:
scripts and docs are updated together.
221
Removed:
- Executable bits on scripts SHOULD be preserved.
222
Removed:
223
Removed:
224
Removed:
* Dashboard notes
225
Removed:
226
Removed:
- The dashboard is a Mojolicious app under =roles/dashboard=.
227
Removed:
- API responses SHALL not be stable for now. Code in
228
Removed:
=roles/dashboard/public/js= SHALL be updated following backend API
229
Removed:
modifications.
230
Removed:
- The dashboard database path MAY be overridden with =FAPG_DAQ_DB=.
231
Removed:
232
Removed:
233
Removed:
* Documentation
234
Removed:
235
Removed:
- This repository SHALL use Org Mode for project documentation. New
236
Removed:
project docs SHALL use =.org= files.
237
Removed:
- Architecture docs SHALL be updated when MQTT topics, payload schema,
238
Removed:
host roles, or data flow change.
AGENTS.override.md
@@ -1,3 +0,0 @@
1
Removed:
# AGENTS.override.md
2
Removed:
3
Removed:
Use the AGENTS.org file.