rewrite(phase8): batch A — content-parity audit (record/observe/config/cli + dyndata/redundancy/sim re-verify) - #171
Merged
Conversation
…g/cli + dyndata/redundancy/sim re-verify) Part of the v3.0.0 ground-up rewrite (cpp-RCP #129, ROADMAP.md Phase 17), branch rewrite/v3-from-c-rcp. Phase 8 (remaining modules), batch A of 2: record, observe, config, cli -- all already implemented+tested from an earlier untracked pass; audited against c-RCP for genuine capability gaps. Plus dyndata/redundancy/sim (no c-RCP equivalent) re-verified for integration/staleness against the now much more mature Phase 5-7 core. ## record.hpp vs c-RCP recorder.c/recorder.h No functional gaps -- both sides deliberately diverge to different capture granularities (c-RCP: raw ACF/AVTPDU frames; cpp-RCP: RC-Client request/response pairs), already documented on both sides. Closed 5 real test gaps instead: write_binary()/read_binary() failure paths, mutation-immunity of stored entries, Playback::run_all()'s actual-sleep branch (previously only exercised at speed_factor=0.0), PlaybackConfig{} default. ## observe.hpp: genuine gaps ported - New standalone observe::record() free function (mirrors c-RCP's rcp_observe_record()) -- lets a caller record a span/counters directly without an ObservingClient wrapper; ObservingClient::request() now delegates to it. - Span::stream_key added (previously byte_bus_id only, unlike c-RCP's full addr). - Metric/MetricsSink::record_counter gained byte_bus_id (previously stream_key only, losing per-endpoint attribution within a stream). 7 new tests added. ## config.hpp: largest gap, includes a real latent bug fix c-RCP's config.c had a later rework (server/hw_pin_map schema feeding mock.c) cpp-RCP never picked up. Ported the two pieces reachable without touching mock.hpp (out of scope): ServerManifest + apply_to_mock() with c-RCP's exact merge semantics (magic overwritten only if nonzero, options OR'd not overwritten), HwPinManifestEntry + capacity-checked application to RegisterMap::hw_pin_map, load_to_mock() combinator. NOT ported (documented, deliberate): c-RCP's dynamic endpoints/streams sections -- mock::Server has no dynamic endpoint-registration API, fixed at compile time. Real bug fixed: the endpoint-entry parser only routed an object to parse_endpoint_entry if BOTH stream_key and byte_bus_id keys were present in the raw scan -- an entry with only one was silently DROPPED rather than rejected. The same bug class c-RCP's own config.c independently found and fixed (per its own 2026-08-13/#338 comment). Fixed by routing on EITHER key, with parse_endpoint_entry itself now the one place that validates both are genuinely present (throwing ParseError if not) -- a malformed entry is now loudly rejected, not silently dropped. 15 new tests added. ## cli.hpp: genuine gaps ported - capabilities_json()'s features array now reports the 5 REQ-RMAP-030 option names (time_sync/enhanced_cancel/trigger/chained/ compound_bundles) -- cpp-RCP has real underlying implementations for all 5 but never advertised them. - transports now includes "tsn" (a real, non-stub wrapper), matching c-RCP's own equivalent module. 5 new tests added (previously-untested help/--help/-h dispatch, dangling --format value, status default text, new capabilities fields). ## dyndata.hpp / redundancy.hpp / sim.hpp (no c-RCP equivalent) Confirmed clean, no changes: every call site verified to match current lifecycle.hpp/e2e.hpp/regmap.hpp/watchdog.hpp/adapt.hpp/mock.hpp shapes exactly; test coverage confirmed real (genuine construction, real state-transition assertions, meaningful concurrency stress, real mock::Server/Adapt() integration), not vestigial. ## Catalog flags, correctly left untouched (Phase 6 is closed) - REQ-REC-006/007, REQ-OBS-009..022, REQ-CFG-007..020, REQ-CLI-005/006: various no-cpp-counterpart or cross-language content-mismatch ids. - REQ-RED-001/002/003: catalog titles still say "RedundantController" (the retired class name) though text/code/tests correctly say RedundantRequestFn -- a catalog-only staleness artifact. ## Verification Independently re-verified: confirmed the config.hpp routing fix directly against source -- the "else if" now reads `obj.find("stream_key") != npos || obj.find("byte_bus_id") != npos` (was implicitly AND-gated before), and parse_endpoint_entry itself throws ParseError if byte_bus_id is missing -- exactly the claimed fix. Confirmed the REQ-RED-* title-staleness claim directly against .fusa-reqs.json (titles say "RedundantController", code/tests say "RedundantRequestFn" 12/13 times respectively). Full tree rebuilt from scratch: 0 errors, 0 warnings, 58/58 ctest suites pass (100%). include/rcp/cli.hpp: +28 (619->647). include/rcp/config.hpp: +267 (172->439). include/rcp/observe.hpp: +43 (168->211). include/rcp/ record.hpp, dyndata.hpp, redundancy.hpp, sim.hpp: unchanged. tests/test_cli.cpp: +37. tests/test_config.cpp: +156. tests/test_observe.cpp: +144. tests/test_record.cpp: +85. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Signed-off-by: Matt <47545907+SoundMatt@users.noreply.github.com>
PR #171's windows-2022/msvc/C++17 job failed: a braced-init-list {3, 1, 4, 1, 5} deduces std::initializer_list<int>, and binding each element to a range-for variable of avtp::ByteBusId (uint16_t) is a narrowing conversion MSVC's /W4 /WX flags as error C4244 (clang/gcc did not flag this, or flagged it differently, so it wasn't caught locally on macOS/Linux toolchains). Fixed by making each list element's type explicit (avtp::ByteBusId{3} etc.), eliminating the narrowing. Verified: rebuilt test_observe standalone locally, 54/54 assertions pass. Full tree rebuilt from scratch: 0 errors, 0 warnings, 58/58 ctest suites pass (100%). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Signed-off-by: Matt <47545907+SoundMatt@users.noreply.github.com>
10 tasks
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.
rewrite(phase8): batch A — content-parity audit (record/observe/config/cli + dyndata/redundancy/sim re-verify)
Part of the v3.0.0 ground-up rewrite (cpp-RCP #129, ROADMAP.md Phase 17),
branch rewrite/v3-from-c-rcp. Phase 8 (remaining modules), batch A of 2:
record, observe, config, cli -- all already implemented+tested from an
earlier untracked pass; audited against c-RCP for genuine capability
gaps. Plus dyndata/redundancy/sim (no c-RCP equivalent) re-verified for
integration/staleness against the now much more mature Phase 5-7 core.
record.hpp vs c-RCP recorder.c/recorder.h
No functional gaps -- both sides deliberately diverge to different
capture granularities (c-RCP: raw ACF/AVTPDU frames; cpp-RCP: RC-Client
request/response pairs), already documented on both sides. Closed 5
real test gaps instead: write_binary()/read_binary() failure paths,
mutation-immunity of stored entries, Playback::run_all()'s actual-sleep
branch (previously only exercised at speed_factor=0.0), PlaybackConfig{}
default.
observe.hpp: genuine gaps ported
rcp_observe_record()) -- lets a caller record a span/counters
directly without an ObservingClient wrapper; ObservingClient::request()
now delegates to it.
full addr).
stream_key only, losing per-endpoint attribution within a stream).
7 new tests added.
config.hpp: largest gap, includes a real latent bug fix
c-RCP's config.c had a later rework (server/hw_pin_map schema feeding
mock.c) cpp-RCP never picked up. Ported the two pieces reachable
without touching mock.hpp (out of scope): ServerManifest +
apply_to_mock() with c-RCP's exact merge semantics (magic overwritten
only if nonzero, options OR'd not overwritten), HwPinManifestEntry +
capacity-checked application to RegisterMap::hw_pin_map, load_to_mock()
combinator. NOT ported (documented, deliberate): c-RCP's dynamic
endpoints/streams sections -- mock::Server has no dynamic
endpoint-registration API, fixed at compile time.
Real bug fixed: the endpoint-entry parser only routed an object to
parse_endpoint_entry if BOTH stream_key and byte_bus_id keys were
present in the raw scan -- an entry with only one was silently
DROPPED rather than rejected. The same bug class c-RCP's own config.c
independently found and fixed (per its own 2026-08-13/#338 comment).
Fixed by routing on EITHER key, with parse_endpoint_entry itself now
the one place that validates both are genuinely present (throwing
ParseError if not) -- a malformed entry is now loudly rejected, not
silently dropped. 15 new tests added.
cli.hpp: genuine gaps ported
option names (time_sync/enhanced_cancel/trigger/chained/
compound_bundles) -- cpp-RCP has real underlying implementations for
all 5 but never advertised them.
c-RCP's own equivalent module.
5 new tests added (previously-untested help/--help/-h dispatch, dangling
--format value, status default text, new capabilities fields).
dyndata.hpp / redundancy.hpp / sim.hpp (no c-RCP equivalent)
Confirmed clean, no changes: every call site verified to match current
lifecycle.hpp/e2e.hpp/regmap.hpp/watchdog.hpp/adapt.hpp/mock.hpp shapes
exactly; test coverage confirmed real (genuine construction, real
state-transition assertions, meaningful concurrency stress, real
mock::Server/Adapt() integration), not vestigial.
Catalog flags, correctly left untouched (Phase 6 is closed)
various no-cpp-counterpart or cross-language content-mismatch ids.
(the retired class name) though text/code/tests correctly say
RedundantRequestFn -- a catalog-only staleness artifact.
Verification
Independently re-verified: confirmed the config.hpp routing fix
directly against source -- the "else if" now reads
obj.find("stream_key") != npos || obj.find("byte_bus_id") != npos(was implicitly AND-gated before), and parse_endpoint_entry itself
throws ParseError if byte_bus_id is missing -- exactly the claimed
fix. Confirmed the REQ-RED-* title-staleness claim directly against
.fusa-reqs.json (titles say "RedundantController", code/tests say
"RedundantRequestFn" 12/13 times respectively). Full tree rebuilt from
scratch: 0 errors, 0 warnings, 58/58 ctest suites pass (100%).
include/rcp/cli.hpp: +28 (619->647). include/rcp/config.hpp: +267
(172->439). include/rcp/observe.hpp: +43 (168->211). include/rcp/
record.hpp, dyndata.hpp, redundancy.hpp, sim.hpp: unchanged.
tests/test_cli.cpp: +37. tests/test_config.cpp: +156.
tests/test_observe.cpp: +144. tests/test_record.cpp: +85.
Co-Authored-By: Claude Sonnet 5 noreply@anthropic.com