diff --git a/.fusa-reqs-pending.json b/.fusa-reqs-pending.json index 51aa546..f89971a 100644 --- a/.fusa-reqs-pending.json +++ b/.fusa-reqs-pending.json @@ -188,6 +188,16 @@ "asil": "ASIL-B", "tc18": "§11.2, TC18.txt L1182; §11.2.1, TC18.txt L1204", "gap": "Confirmed absent (2026-08-22): shares REQ-TIMED-012's exact root cause and evidence — rcp/acf.hpp's encode_acf_abb() and rcp/l2.hpp's/udp.hpp's TSCF framing already provide the wire-encoding half of this pair (a caller can build a TSCF-headed ACF_ABB frame today), but the decode/admission half (a dispatch entry point that decodes a real TSCF-wrapped ACF_ABB frame and threads its avtp_timestamp into timed_admit()/timed_due() the way REQ-TIMED-012 describes) does not exist anywhere in cpp-RCP. See REQ-TIMED-012's gap text for the full detail; both ids share one missing piece (a TSCF-aware dispatch/admission entry point) and would likely be closed together." + }, + { + "id": "REQ-WDG-010", + "title": "The per-stream watchdog is kicked by every request received on that stream", + "text": "The RC Server's request-reception path shall call rcp::watchdog::Manager::on_request_received() (StreamWatchdog::kick_from_request()) for a request stream's stream_key on every request successfully received on that stream, so the per-stream watchdog measures the gap between consecutive requests from that RC Client.", + "standard": "iso26262", + "level": "ASIL-B", + "asil": "ASIL-B", + "tc18": "§12.7.7, TC18.txt L2936-L2938", + "gap": "NOT a behavioral gap -- a traceability-tag gap (2026-08-22, cpp-RCP Phase 6 batch 5, watchdog module): the behavior itself is genuinely, robustly implemented and tested. rcp/mock.hpp's dispatch_e2e_core() (the reference RC Server's actual request-reception path) calls rx_watchdog_kick(stream_id, ...) unconditionally, before any admission/validation check, at both of its call sites (mock.hpp:1147 inside dispatch_e2e_core, and mock.hpp:1343 inside dispatch_frame_e2e's per-member loop) -- rx_watchdog_kick() itself (mock.hpp:2097) forwards straight to rcp::watchdog::Manager::on_request_received(). tests/test_mock.cpp has a dedicated test, \"dispatch_e2e kicks the per-stream RxWatchdog (REQ-WDG-010) on every call...\" (test_mock.cpp:1739-1742+), that exercises exactly this behavior end-to-end (kick before an overflow, elapsed-time overflow after). rcp/sim.hpp's Simulator::dispatch/register_stream (sim.hpp:86-153) independently wires the same rcp::watchdog::Manager hook for the simulation harness. The blocker is purely mechanical: cpp-FuSa's trace tool (src/trace/trace.cpp) only counts a requirement as traced/tested when a literal `// fusa:req REQ-WDG-010` / `// fusa:test REQ-WDG-010` comment line exists somewhere in the tree (regex `//\\s*fusa:req\\s+`/`//\\s*fusa:test\\s+` followed by a REQ-\\S+ token) -- the existing `REQ-WDG-010:` prose mentions in mock.hpp's plain comments and the `[REQ-WDG-010]` Catch2 tag string in test_mock.cpp do NOT match that regex, so this id currently has ZERO formal annotations anywhere in the repo. CI hard-gates on this: .github/workflows/ci.yml's cpfusa-trace job runs `cpfusa trace --req-coverage 100` (fails outright, no `|| true`) and a second step that requires testedRequirements == totalRequirements (also a hard `exit 1` gate) -- adding this id to .fusa-reqs.json today, with no real tag anywhere, would fail CI. Fixing this requires adding the two formal tags to include/rcp/mock.hpp and tests/test_mock.cpp, both out of this batch's file-scope (batch 5 is restricted to .fusa-reqs.json/.fusa-reqs-pending.json/include/rcp/watchdog.hpp/tests/test_watchdog.cpp only) -- filed here so a future mock.hpp-scoped batch can add those two tags and migrate this entry into .fusa-reqs.json in the same change." } ] } \ No newline at end of file diff --git a/include/rcp/watchdog.hpp b/include/rcp/watchdog.hpp index a5dd527..8820cf4 100644 --- a/include/rcp/watchdog.hpp +++ b/include/rcp/watchdog.hpp @@ -60,9 +60,27 @@ // - c-RCP REQ-WDG-010 (the RC Server's request-reception path shall call // kick() on every request received) is a cross-cutting dispatch-layer // integration requirement, not watchdog-module behavior; this file's -// kick_from_request()/Manager::on_request_received() are the hook, and -// rcp/sim.hpp's Simulator::dispatch already wires it in exactly this -// shape (see sim.hpp's own header comment). +// kick_from_request()/Manager::on_request_received() are the hook. +// [Phase 6 batch 5, cpp-RCP issue #129, 2026-08-22] Re-verified against +// real code, not just this comment's own prior claim: rcp/sim.hpp's +// Simulator::dispatch already wires it in exactly this shape (see +// sim.hpp's own header comment), and separately rcp/mock.hpp's +// dispatch_e2e_core() (the reference RC Server's actual +// request-reception path) calls rx_watchdog_kick() -- which forwards +// straight to Manager::on_request_received() -- unconditionally before +// any admission check, at both of its call sites, with a dedicated +// tests/test_mock.cpp TEST_CASE exercising it end-to-end. Genuinely +// implemented and tested, but NOT added as a REQ-WDG-010 entry in this +// project's own .fusa-reqs.json here: neither mock.hpp nor +// test_mock.cpp carries cpp-FuSa's required literal `// fusa:req`/ +// `// fusa:test` tag for it (only informal comment mentions and a +// Catch2 tag string, which cpp-FuSa's trace tool does not recognize), +// and adding the catalog entry without that tag existing somewhere +// would fail CI's hard 100%-traced/100%-tested trace gates +// (.github/workflows/ci.yml's cpfusa-trace job). Filed to +// .fusa-reqs-pending.json instead, with the full citation, for a +// future mock.hpp/test_mock.cpp-scoped batch (out of this batch's +// watchdog.hpp/test_watchdog.cpp-only file-scope) to tag and migrate. // - c-RCP REQ-WDG-012 (destroy(k) is a null-safe no-op, otherwise closes // then frees) does not transfer: no manual destroy exists here — // StreamWatchdog/Manager are plain value types with ordinary C++