fix(board): align the rev2 board profile with the frozen hardware design - #19
Merged
Conversation
…ware Spec, plan, research, data model, contract and tasks for closing the gap between the frozen rev2 schematic (2026-08-12) and the firmware board profile. Spec was rewritten same-day after a codebase survey showed the reservoir-pump divergence was already fixed in feature 006; the real remaining scope is the phantom buttons (BTN_CONFIG polled on EXP_SCK/IO18 at boot), three missing power signals, and stale SYNC1 markers. Analyze pass: 100% coverage, no critical findings; quickstart build commands corrected to CI's canonical forms. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The rev2 profile defined BTN_MANUAL=5 and BTN_CONFIG=18, and the boot path configured IO18 as an input and read it to decide whether to force WiFi provisioning. The frozen rev2 board has neither button (only BOOT/RESET and the status LED), and IO18 is EXP_SCK on the expansion header J7 — so on real hardware expansion-bus traffic could be misread as a held config button, and core firmware claimed a pin the design reserves. - board.h: BOARD_HAS_BTN_MANUAL / BOARD_HAS_BTN_CONFIG on both boards (rev1 = 1 with pins 5/18 unchanged, rev2 = 0 with the pin macros deliberately undefined — the RS485-DE / reservoir-pump enforcement pattern, so unguarded references fail the build). - board.h sanity: flag<->pin consistency pairs for both button flags, the button distinctness check guarded by the flags, and a rev2-ONLY expansion-reservation check erroring if any defined pin lands on IO18/19/23/4/27 (rev1 legitimately uses 18 and 27 — the reservation is a property of the rev2 board, not of the firmware). - app_main: the config-button read, its poll loop and LED feedback compile only under BOARD_HAS_BTN_CONFIG; buttonless boards fall back to the credentials-absent provisioning path (feature 007), unchanged. The pump boot fail-safe is untouched. - Contract TUs pin both sides: rev1 buttons present with frozen values (FR-002 regression guard), rev2 buttons absent plus expansion disjointness for every core pin. Spec: specs/012-rev2-pin-map (US1, FR-001..004, FR-007) Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The frozen rev2 design provides three signals the board profile did not mention, forcing the next developer back to the schematic (project rule: pin tables live only in components/board/). - BOARD_HAS_VBAT_SENSE / BOARD_PIN_VBAT_SENSE 34 — battery divider on an input-only ADC1 pin (ADC2 is unusable with WiFi up); readings compress above ~2.45 V at the pin, FW-1. - BOARD_HAS_PWR_PG / BOARD_PIN_PWR_PG 35 — buck power-good, input-only, open-drain with an external pull-up; IO34-39 have no internal pulls, FW-6. - BOARD_HAS_SENS_PWR_EN / BOARD_PIN_SENS_PWR_EN 25 — switched 12 V sensor domain. The rail is OFF by HARDWARE default (R61 holds the gate off while the GPIO is hi-Z), so this feature deliberately does not drive the pin; rail sequencing and the FW-3 settle are PR-14 scope. All three carry the flag<->pin consistency pattern: rev1 defines the flags at 0 with the pin macros absent, so an unguarded PR-14 reference fails the rev1 build. Contract TUs pin both sides, and the new pins join the rev2 expansion-disjointness checks. Spec: specs/012-rev2-pin-map (US2, FR-005, FR-007) Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
SYNC 1 has happened (2026-08-12: all sheets drawn, ERC clean, components ordered) and every rev2 value in the profile matches the frozen contract, so the 11 TODO(SYNC1) markers and the "GPIO numbers provisionally mirror rev 1" header were actively misleading — they invite edits to values that are now fixed by hardware. - Each rev2 pin group cites hardware/rev2/design-notes/02-mcu.md §2.2 SYNC 1 map (frozen 2026-08-12) once, at group level. - I2C address map corrected: 0x41 is the solar INA226, POPULATED on this node per the 2026-08-12 decision (it was documented as a DNP footprint); driver support is PR-14. BME280 is 0x77 (SDO -> VDDIO, rev1 parity), and the note now says BOARD_INA226_ADDR names the pump monitor. - The rev2 contract TU's copy of the old DNP claim is corrected too. No macro values change in this commit. Spec: specs/012-rev2-pin-map (US3, FR-006, SC-004) Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…ty flags
firmware/CLAUDE.md still told agents that rev2 pins were provisional behind
TODO(SYNC1) markers, and its capability-flag list predated feature 012.
- Board-revision section: rev2 pins are FROZEN and cite the SYNC 1 map;
rev2 has no buttons and reserves IO18/19/23/4/27 for J7 (a rev2-only
invariant — rev1 legitimately uses IO18/IO27).
- Capability-flag list extended with the five new flags, and the
enforcement-pattern sentence now names which pin macros are undefined on
which board. The rev2-only power/rail signals are noted as declared but
consumer-less until PR-14.
- WiFi section: the boot config-button read is compiled out where
BOARD_HAS_BTN_CONFIG == 0.
Verification notes for this feature (all in the pinned v6.0.1 container):
host suite 316 tests / 0 failures; both board targets build with the right
CONFIG_BOARD_* in sdkconfig and all five artifacts present; the rev1 image
is byte-size identical to the pre-feature baseline (0x103df0), which is the
practical evidence for the rev1 no-op requirement (FR-002). Negative proof
(quickstart §4): an unguarded BOARD_PIN_BTN_CONFIG reference added to the
rev2 contract TU fails the build ("was not declared in this scope") and was
reverted — the enforcement pattern bites.
Spec: specs/012-rev2-pin-map (polish, plan D4)
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
… gaps, correct citations Hardening pass over the feature 012 review findings. The rev2 profile itself was confirmed correct; these changes make its guarantees enforceable and its provenance accurate. No pin VALUE changes: board.h gains only #if/#error guards and comments. - Pin the frozen macro VALUES in both contract TUs (FR-002's durable guard): rev1 I2C 21/22, RS485 16/17, DE 25, UART2, pump 26, LED 2; the mirror set for rev2. Previously only the values feature 012 touched were asserted, so a stray edit to a pre-existing pin passed the host suite. - Extend the pin-distinctness net to the three new rev2 power/rail pins (VBAT_SENSE, PWR_PG, SENS_PWR_EN) against every core function pin and each other, under their capability flags. Mutation-proven: SENS_PWR_EN == 26 (the pump gate) compiled silently before this. - Require every capability flag to be DEFINED, not merely 0/1 — an undefined macro evaluates to 0 in #if with no diagnostic, silently deleting the behavior it gates and disabling the flag-guarded checks above. - Add a maintenance sentinel to the rev2 section: the preprocessor cannot enumerate macros, so a new BOARD_PIN_* must be added by hand to the expansion-reservation check and to the rev2 contract TU. - Correct the I2C address-map citation to 07-i2c-env.md §7.3 (§7.4 is open items), and the solar INA226 provenance to the 01-power.md §1.5 decision of 2026-06-20 with the populate gate cleared 2026-08-10 (2026-08-12 is the schematic freeze, a different event). - De-pair the expansion comment: SCK=IO18, MISO=IO19, MOSI=IO23, CS=IO4, IRQ=IO27 per 08-expansion.md §8.3 — "SCK/MOSI/MISO on IO18/19/23" read pairwise implied MOSI=IO19, which is wrong. Verification: host suite 316 tests / 0 failures; both board targets build green with CONFIG_BOARD_REV1_DEVKIT=y and CONFIG_BOARD_REV2=y respectively. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…ntinel Follow-up to 176be1e, from the verification re-review. board.h only; still zero #define additions or removals. - Move the capability-flag definedness check to the TOP of the sanity section, ahead of every flag-guarded check rather than after them. Those checks are gated on the very flags it validates, so an undefined flag could previously switch OFF the collision checks it was meant to enable and still reach the definedness error only afterwards. Ordering makes that structurally impossible. Placed above the reservoir-pump and RS485-DE guards too, not just the power/rail block — they have the same dependency. - Add the latent SENS_PWR_EN vs RS485_DE cross-check, matching the existing double-guard pattern. Unreachable on both boards today (no board has both signals), but a future board combining them would put both on IO25 and collide silently. Verified to fire by synthetically granting rev1 a sensor rail on 25. - Complete the maintenance sentinel: it listed only the two hand-maintained lists that predated it and omitted the third one the previous commit introduced — the eight-flag definedness check. Now covers new BOARD_HAS_* flags as well as new BOARD_PIN_*. - Sentinel wording: "disjointness/frozen-value asserts" overstated the rev2 TU, which asserts frozen values and expansion-set membership, not general pairwise disjointness. Corrected. Verification: host suite 316 tests / 0 failures; rev2 target builds green with CONFIG_BOARD_REV2=y. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Spec-kit feature 012 (
specs/012-rev2-pin-map/). The rev2 schematic froze 2026-08-12; this brings the firmware board profile into line with it:BTN_MANUAL/BTN_CONFIG(IO5/IO18) — neither exists on the board, and IO18 isEXP_SCK, the expansion header's SPI clock, whichapp_mainpolled at every boot to decide provisioning entry. Expansion-bus activity could drop the node into provisioning mode. Buttons are now capability-flagged (BOARD_HAS_BTN_*: rev1 = 1 unchanged, rev2 = 0 with the pin macros deleted — unguarded references fail the build, same pattern as the reservoir pump).VBAT_SENSE(IO34, ADC1, input-only),PWR_PG(IO35, input-only, externally pulled up),SENS_PWR_EN(IO25, output; rail is OFF by hardware default — sequencing is PR-14 scope).TODO(SYNC1)markers and the "provisionally mirrors rev 1" header replaced with citations of the frozen SYNC 1 map; solar INA226 comment corrected (populated, decision 2026-06-20 / gate cleared 2026-08-10).SENS_PWR_ENon the pump gate now fails the build); all eight capability flags definedness-checked ahead of the checks they gate; rev2-only expansion-set reservation (IO18/19/23/4/27); latent IO25 cross-check; maintenance sentinel.Safety
Constitution principle I verified by review:
pumps_force_off()and its call site are byte-identical — the diff touches nothing in the pump boot-safety path. The credentials-absent provisioning path is unchanged on both boards; on rev2 it is now the sole provisioning trigger (the board has no config button — accepted at CP2, a BOOT-button trigger is a possible PR-14+ feature).Verification
espressif/idf:v6.0.1container;CONFIG_BOARD_*verified in sdkconfig.clang++ -dM) before/after shows rev1 gained ONLY the five newBOARD_HAS_*flags — zero values changed; the rev1 image is byte-size identical to the pre-feature baseline. Byte-identity (sha256) cannot be demonstrated becauseCONFIG_APP_REPRODUCIBLE_BUILDis off (ESP-IDF embeds build date/time in the app descriptor); the durable FR-002 guard is the frozen-value static_asserts added to both contract TUs.Merge order
Depends on #18 (merged):
board.hciteshardware/rev2/design-notes/02-mcu.md §2.2, introduced there.Review trail
Full workflow in
specs/012-rev2-pin-map/(spec → plan → tasks → analyze). Three review agents (code/tests/comments) + fixer + verification re-review (APPROVE); checkpoint docs CP2/CP3 signed off by Paul 2026-08-12. No HIL required — compile-time facts for a board that does not exist yet plus a provably unchanged rev1; bench verification of the new signals lands with PR-14 bring-up.🤖 Generated with Claude Code