Task · OPN-0123

Tolerate transitional CARP and NDP response shapes seen during a firewall upgrade

Description

During the 2026-10-12 production upgrade to 26.7.6 the box answered api/diagnostics/interface/get_vip_status with {“total”:0,“rowCount”:0,“current”:1,“rows”:[],“carp”:[]} - carp as an empty array where the decoder expects an object (carpInfo in opnsense/carp.go), failing the whole fetch with an unmarshal error - and answered api/diagnostics/interface/get_ndp with HTTP 200 and an empty body (unexpected end of JSON input). Each happened once mid-upgrade, but both recur on any reboot or service restart window.

Acceptance Criteria

Definition of Done

Implementation Plan

Implement transitional CARP/NDP decoding within owned files; fail reproductions before fixes; staged candidate after local gate for root security review, CodeRabbit and publication.

Implementation Notes

loop10: pre-mutation ownership gap, 0 implementation attempts. Empty HTTP200 NDP classification must precede shared client observer/cache. Root amended ownership for an endpoint-specific client.go check and serializes this lane after firmware landing to avoid shared-file ownership. Observer behavior tests remain in ndp_test.go.

loop10: 4 implementation cycles, final permitted candidate passed full gate. CARP restart [] decodes disabled/no-info while ordinary objects retain behavior; empty successful NDP body returns a transient failure before request-result observation/cache/publication, with actual failed-observer/no-cache proof. Named CARP object descent preserves introspection. Guarded review caught and closed a major false-pass from unnecessary Heterogeneous; strict canonical object schema already tolerates PHP empty arrays and retains invalid-container and new-key checks. New registered-validator regression failed before correction then passed. Final security PASS and completed CodeRabbit zero findings across all six final paths. Root integration, exact-SHA CI and auto-deploy readback remain pending; not Done yet.

loop10: 4 implementation cycles, completed at ceiling without extra attempts. Published source passed exact integrated gate and CI; auto-deployed build observed, CARP/NDP success both 1 after deploy. Raw index metadata changed during composed gate but exact tracked tree/cached diff unchanged and independently verified. No test/baseline weakened; major canary false-pass corrected before landing.

Final Summary

Tolerates observed CARP empty-array restart body and classifies empty successful NDP responses as counted transient failures before cache/publication. Named schema descent retains strict container/field drift and unknown-key discovery; actual-validator red/green proof closes the major review finding. Guarded reviews, CodeRabbit and exact source/composed/CI checks passed; live build and collector health observed.

View the source file on GitHub