Skip to content

rewrite(phase8): batch A — content-parity audit (record/observe/config/cli + dyndata/redundancy/sim re-verify) - #171

Merged
SoundMatt merged 2 commits into
rewrite/v3-from-c-rcpfrom
phase8/batch-a-core
Aug 22, 2026
Merged

rewrite(phase8): batch A — content-parity audit (record/observe/config/cli + dyndata/redundancy/sim re-verify)#171
SoundMatt merged 2 commits into
rewrite/v3-from-c-rcpfrom
phase8/batch-a-core

Conversation

@SoundMatt

Copy link
Copy Markdown
Owner

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

  • 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

…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>
@SoundMatt
SoundMatt merged commit 3650496 into rewrite/v3-from-c-rcp Aug 22, 2026
25 checks passed
@SoundMatt
SoundMatt deleted the phase8/batch-a-core branch August 22, 2026 21:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant