Background
include/rcp/errors.h defines rcp_wire_error_t, the 17 numbered wire error codes assigned by TC18's own Table 27 (the values an RC Server places in an Acknowledge/Response frame's err field to tell an RC Client what went wrong). REQ-WIREERR-001 covers the enum itself.
The header's own comment is already honest about the gap:
"This header intentionally does not attempt to wire every internal rcp_errc_t/rcp_<mod>_errc_t value in the codebase onto one of these seventeen codes... rcp_e2e_wire_error() below is the one concrete mapping this milestone adds... Additional mappings (e.g. sequencer.h's REQUEST_NOT_FOUND-shaped failures, authz.h's UNAUTHORIZED_ACCESS-shaped failures) are real future work, not modeled here."
Confirmed by grep (2026-08-07): only errors.c/errors.h reference the 17 RCP_ERROR_* constants anywhere in the codebase. No endpoint module, server.c, authz.c, sequencer.c, or any request_*.c actually populates a real error response's err field with the correct numbered code for most failure conditions. Only 1 of 17 codes is wired to a real path today: RCP_ERROR_POCI_FAILURE via rcp_e2e_wire_error() (CRC32/E2E mismatch).
This is safety-relevant: an RC Client's ability to correctly diagnose why a request failed depends on the RC Server returning the right numbered code, not a generic/wrong one or none at all.
The 16 unmapped codes and their TC18 meaning
RCP_ERROR_UNSUPPORTED_CMD = 1, // the addressed operation/endpoint doesn't support the requested command
RCP_ERROR_SEQUENCER_NOT_KNOWN = 2, // the referenced sequencer index isn't configured
RCP_ERROR_UNAUTHORIZED_ACCESS = 3, // the caller isn't permitted to perform this request
RCP_ERROR_LOCKED_MEM_ACCESS = 4, // the addressed register/memory is locked against this access
RCP_ERROR_REQUEST_CANCELED = 5, // the request was canceled before it completed
RCP_ERROR_REQUEST_NOT_FOUND = 6, // the referenced request (e.g. to cancel) is not known
RCP_ERROR_EP_ERROR = 7, // the addressed endpoint reported an internal fault
RCP_ERROR_EP_NOT_FOUND = 8, // the addressed endpoint (byte_bus_id) does not exist
RCP_ERROR_PWM_IN_NO_SIGNAL = 9, // a PWM input endpoint has no signal to report
RCP_ERROR_REQUEST_STORAGE_OVERFLOW = 10, // the request-storage capacity is exhausted
RCP_ERROR_REQUEST_REJECTED = 11, // the request was well-formed but rejected on other grounds
// 12 (POCI_FAILURE) already wired
RCP_ERROR_PRESENTATION_TIME_TOO_FAR = 13, // a timed request's presentation_time is outside the acceptable window
RCP_ERROR_GPTP_FAIL = 14, // gPTP time sync is unavailable or has failed
RCP_ERROR_INVALID_PARAMETER = 15, // a request field's value is out of range or otherwise invalid
RCP_ERROR_CHAIN_ABORTED = 16, // a chained request sequence was aborted before completion
RCP_ERROR_CHAIN_ERROR = 17, // a chained request sequence failed internally
What needs to happen (for the agent picking this up)
- Scope first, don't just start wiring. For each of the 16 codes, find every internal failure condition in the codebase that semantically matches it. Candidate locations, not exhaustive:
server.c (routing/dispatch — EP_NOT_FOUND, UNSUPPORTED_CMD), authz.c (UNAUTHORIZED_ACCESS, LOCKED_MEM_ACCESS), sequencer.c/request_compound.c (SEQUENCER_NOT_KNOWN, REQUEST_STORAGE_OVERFLOW), request_cancel.c (REQUEST_CANCELED, REQUEST_NOT_FOUND), request_chained.c (CHAIN_ABORTED, CHAIN_ERROR), request_timed.c (PRESENTATION_TIME_TOO_FAR, GPTP_FAIL), every ep_*.c (EP_ERROR, PWM_IN_NO_SIGNAL in ep_pwm.c specifically), and general request validation (INVALID_PARAMETER).
- Verify against TC18 text directly which specific conditions each code is meant to cover — don't guess from the enum's one-line paraphrase alone.
errors.h's own comment says the numeric values are "the protocol's on-wire contract" reproduced exactly, but the enumerator names/descriptions are this implementation's own paraphrase, not the spec's wording — go back to the primary source (OA_TC18_specification_v_0.5.1_RC.pdf, Table 27 and the surrounding per-request-type error prose) for each mapping.
- Wire each mapping into the real response-construction path — likely a per-module
rcp_<x>_wire_error() function mirroring rcp_e2e_wire_error()'s existing shape, called wherever that failure is actually detected and a response is being constructed.
- Test each mapping — a real request that triggers the failure condition and asserts the response's
err field carries the correct code, not just that an error occurred.
- Add/update
.fusa-reqs.json entries with real tc18 citations to TC18's Table 27 and the specific per-request-type error-condition prose, following this repo's per-function //cfusa:req tagging convention.
- Verify with a freshly-built, CI-pinned
cfusa (check the exact tag in .github/workflows/ci.yml, never trust a cached binary) — check 0 errors, trace --req-coverage 100 --sec-tested 100.
- Given the size (potentially touching every module), consider whether this should ship as several smaller PRs (e.g. grouped by which module owns the mapping) rather than one large one — this repo's established pattern favors small, fully-verified PRs over big-bang changes.
Not in scope for this issue
- Codes 1 and 12 already have real mappings (
UNSUPPORTED_CMD is presumably already used somewhere for command rejection — verify this as part of scoping rather than assuming; POCI_FAILURE is confirmed wired via rcp_e2e_wire_error()).
- This issue is about wiring existing internal failures to the right wire code — it is not about inventing new failure detection that doesn't exist today (e.g. if nothing in the codebase currently detects "gPTP sync unavailable" at all, that's a separate, larger feature gap worth its own issue, not silently folded into this one).
Background
include/rcp/errors.hdefinesrcp_wire_error_t, the 17 numbered wire error codes assigned by TC18's own Table 27 (the values an RC Server places in an Acknowledge/Response frame'serrfield to tell an RC Client what went wrong).REQ-WIREERR-001covers the enum itself.The header's own comment is already honest about the gap:
Confirmed by grep (2026-08-07): only
errors.c/errors.hreference the 17RCP_ERROR_*constants anywhere in the codebase. No endpoint module,server.c,authz.c,sequencer.c, or anyrequest_*.cactually populates a real error response'serrfield with the correct numbered code for most failure conditions. Only 1 of 17 codes is wired to a real path today:RCP_ERROR_POCI_FAILUREviarcp_e2e_wire_error()(CRC32/E2E mismatch).This is safety-relevant: an RC Client's ability to correctly diagnose why a request failed depends on the RC Server returning the right numbered code, not a generic/wrong one or none at all.
The 16 unmapped codes and their TC18 meaning
What needs to happen (for the agent picking this up)
server.c(routing/dispatch —EP_NOT_FOUND,UNSUPPORTED_CMD),authz.c(UNAUTHORIZED_ACCESS,LOCKED_MEM_ACCESS),sequencer.c/request_compound.c(SEQUENCER_NOT_KNOWN,REQUEST_STORAGE_OVERFLOW),request_cancel.c(REQUEST_CANCELED,REQUEST_NOT_FOUND),request_chained.c(CHAIN_ABORTED,CHAIN_ERROR),request_timed.c(PRESENTATION_TIME_TOO_FAR,GPTP_FAIL), everyep_*.c(EP_ERROR,PWM_IN_NO_SIGNALinep_pwm.cspecifically), and general request validation (INVALID_PARAMETER).errors.h's own comment says the numeric values are "the protocol's on-wire contract" reproduced exactly, but the enumerator names/descriptions are this implementation's own paraphrase, not the spec's wording — go back to the primary source (OA_TC18_specification_v_0.5.1_RC.pdf, Table 27 and the surrounding per-request-type error prose) for each mapping.rcp_<x>_wire_error()function mirroringrcp_e2e_wire_error()'s existing shape, called wherever that failure is actually detected and a response is being constructed.errfield carries the correct code, not just that an error occurred..fusa-reqs.jsonentries with realtc18citations to TC18's Table 27 and the specific per-request-type error-condition prose, following this repo's per-function//cfusa:reqtagging convention.cfusa(check the exact tag in.github/workflows/ci.yml, never trust a cached binary) —check0 errors,trace --req-coverage 100 --sec-tested 100.Not in scope for this issue
UNSUPPORTED_CMDis presumably already used somewhere for command rejection — verify this as part of scoping rather than assuming;POCI_FAILUREis confirmed wired viarcp_e2e_wire_error()).