Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
5e9a5ee
docs(roadmap): v3.0.0 becomes a full rewrite ported from c-RCP, not P…
SoundMatt Aug 21, 2026
d99ccf9
ci: run CI/DCO on the rewrite/v3-from-c-rcp branch too
SoundMatt Aug 21, 2026
1edc870
rewrite(phase1): port acf.hpp/avtp.hpp from c-RCP's RC5-conformant re…
SoundMatt Aug 21, 2026
79261c4
rewrite(phase1): add fragment/respqueue, convert loan to fixed-capaci…
SoundMatt Aug 21, 2026
e56fd7a
rewrite(phase1): port request/sequencer/scheduler from c-RCP's RC5-co…
SoundMatt Aug 21, 2026
2d976af
rewrite(phase2): port watchdog + build allocation fault-injection sea…
SoundMatt Aug 21, 2026
692f017
rewrite(phase2): port e2e/lifecycle from c-RCP, correct HARA.md's ove…
SoundMatt Aug 21, 2026
8821de9
rewrite(phase3): port iseled/i2c from c-RCP; fix ROADMAP.md's Phase 1…
SoundMatt Aug 21, 2026
2eba2ac
rewrite(phase3): port can/lin from c-RCP, wire CAN XL fragmentation v…
SoundMatt Aug 21, 2026
7c24c41
rewrite(phase3): port adc/gpio from c-RCP, fix a critical ADC averagi…
SoundMatt Aug 21, 2026
22bea34
rewrite(phase3): port mdio from c-RCP, revert an earlier session's ow…
SoundMatt Aug 21, 2026
04c0fc5
rewrite(phase3): port pwm and wakeup from c-RCP, fix PWM_OUT Subtract…
SoundMatt Aug 21, 2026
417de59
rewrite(phase3): port spi and uart from c-RCP, RC5 nr_cs/deassert_cs_…
SoundMatt Aug 21, 2026
efbab1a
rewrite(phase4): port regmap batch A from c-RCP — general map, EP0, g…
SoundMatt Aug 21, 2026
479e04e
rewrite(phase4): port server.c admission/scheduling into new server.h…
SoundMatt Aug 21, 2026
ddb9b76
rewrite(phase4): port regmap batch B from c-RCP — HW pins, streams, E…
SoundMatt Aug 22, 2026
4f59113
rewrite(phase4): port discovery from c-RCP, fix claim-release and val…
SoundMatt Aug 22, 2026
ac93355
rewrite(phase4): fix adapt.hpp's missing read_size_or_segment_num fie…
SoundMatt Aug 22, 2026
ce7884c
rewrite(phase4): mock.hpp batch A — wire server::Endpoint admission (…
SoundMatt Aug 22, 2026
a7a1244
rewrite(phase4): mock.hpp batch B — Table 24 response suppression + r…
SoundMatt Aug 22, 2026
5200d6b
rewrite(phase4): mock.hpp batch C — wire RxSequenceGuard, StreamFault…
SoundMatt Aug 22, 2026
d02cd34
rewrite(phase4): mock.hpp batch D1 — wire fragment.hpp/respqueue.hpp …
SoundMatt Aug 22, 2026
73fc51e
rewrite(phase4): mock.hpp batch D2 — AVTPDU frame-level dispatch, clo…
SoundMatt Aug 22, 2026
3cc4947
rewrite(phase5): udp.hpp — wire Server::Handler to Phase 4 frame-leve…
SoundMatt Aug 22, 2026
aa5d99b
rewrite(phase5): l2.hpp — add FrameHandler wired to Phase 4 frame-lev…
SoundMatt Aug 22, 2026
017051b
rewrite(phase5): shmem.hpp — rebuild Channel around a real bounded by…
SoundMatt Aug 22, 2026
4db668c
rewrite(phase5): admin.hpp — fixed-capacity subscriber/counter bounds…
SoundMatt Aug 22, 2026
2d933e2
rewrite(phase6): batch 1 — ACF/AVTP/WIREERR catalog re-derivation (#155)
SoundMatt Aug 22, 2026
f8399bb
rewrite(phase6): batch 2 — FRAG/RESPQUEUE-slice/LOAN catalog re-deriv…
SoundMatt Aug 22, 2026
a642804
rewrite(phase6): batch 3 — conditional-request cluster catalog re-der…
SoundMatt Aug 22, 2026
a05ab56
rewrite(phase6): batch 5 — watchdog: one traceability gap found, no c…
SoundMatt Aug 22, 2026
15f962b
rewrite(phase6): batch 6 — E2E/LIFECYCLE catalog re-derivation (#159)
SoundMatt Aug 22, 2026
6ebeb85
rewrite(phase6): batch 7 — CANEP/LINEP/ISELED catalog re-derivation (…
SoundMatt Aug 22, 2026
4a08cff
rewrite(phase6): batch 8 — I2C/ADC/GPIO catalog re-derivation (#161)
SoundMatt Aug 22, 2026
950b5a5
rewrite(phase6): batch 9 — MDIO/PWM catalog re-derivation (#162)
SoundMatt Aug 22, 2026
ba76dde
rewrite(phase6): batch 10 — SPI/UART/WAKEUP catalog re-derivation (#163)
SoundMatt Aug 22, 2026
92e4b2c
rewrite(phase6): batch 11 — REQ-REGMAP-*→REQ-RMAP-* rename + RMAP/SRV…
SoundMatt Aug 22, 2026
231ff90
rewrite(phase6): batch 12 — DISC/RELAY catalog re-derivation (#165)
SoundMatt Aug 22, 2026
f013d5a
rewrite(phase6): batch 13 — MOCK/PWRMODE catalog re-derivation (Phase…
SoundMatt Aug 22, 2026
f093f7d
rewrite(phase7): batch 1 — port LifecycleStateMachine/E2ESafePoint TL…
SoundMatt Aug 22, 2026
6c06089
rewrite(phase7): batch 2 — add real MC/DC coverage ratchet gate (LLVM…
SoundMatt Aug 22, 2026
b1dcf40
rewrite(phase7): batch 3 — release-pipeline hardening, dispositions, …
SoundMatt Aug 22, 2026
0d49e85
rewrite(phase8): batch B — content-parity audit (tsn/powerstate/fault…
SoundMatt Aug 22, 2026
3650496
rewrite(phase8): batch A — content-parity audit (record/observe/confi…
SoundMatt Aug 22, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .fusa-dispositions.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"dispositions": []
}
1,975 changes: 1,974 additions & 1 deletion .fusa-reqs-pending.json

Large diffs are not rendered by default.

8,569 changes: 8,520 additions & 49 deletions .fusa-reqs.json

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions .fusa.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
"version": "1",
"project": {
"name": "cpp-RCP",
"version": "2.26.0",
"module": "github.com/SoundMatt/cpp-RCP",
"standard": "iso26262",
"asil": "ASIL-B"
Expand Down
378 changes: 358 additions & 20 deletions .github/workflows/ci.yml

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion .github/workflows/dco.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name: DCO

on:
pull_request:
branches: [main]
branches: [main, rewrite/v3-from-c-rcp]

jobs:
dco:
Expand Down
59 changes: 59 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,16 @@ jobs:
--dal DAL-B \
--output do178-gap-report.json || true

# .fusa-iec62443.json (target_sl/component_type/incident_resp_doc) is
# the hand-authored input `cpfusa iec62443` reads; already a required
# artifact per ci.yml's cpfusa-check job. Same non-gating rationale as
# the ISO 26262/IEC 61508/DO-178C gap reports above.
- name: Regenerate IEC 62443 gap report (SL-2, artifact only — non-gating)
run: |
/tmp/cpfusa/build/cpfusa iec62443 \
--sl SL-2 \
--output iec62443-gap-report.json || true

- name: Regenerate structural coverage report (DO-178C, artifact only — non-gating)
run: |
/tmp/cpfusa/build/cpfusa coverage \
Expand All @@ -148,6 +158,53 @@ jobs:
/tmp/cpfusa/build/cpfusa report --format json --output report.json || true
/tmp/cpfusa/build/cpfusa report --format html --output report.html || true

# Release-gate check (mirrors c-RCP's own "Verify shipped artifacts
# declare the version being released" step), adapted to what cpp-FuSa
# v0.18.0's actual output carries for this project. c-RCP's tool
# stamps its generated sbom.json/provenance.json module field as
# "c-RCP@<version>", so its check reads that field directly. cpp-FuSa
# v0.18.0 does not do the equivalent for cpp-RCP: `cpfusa release`'s
# sbom.json/provenance.json/artifact-manifest.json and `cpfusa
# qualify`'s qualify-report.json all hardcode
# "module": "github.com/SoundMatt/cpp-FuSa" regardless of target
# project (verified directly against a local build of the pinned
# v0.18.0 binary) — a real limitation of that pinned tool release, not
# something this repo's own files can fix. report.html is the one
# artifact `cpfusa report` actually generates that renders the target
# project's own name+version ("<b>Project:</b> cpp-RCP v<version>"),
# sourced from .fusa.json's project.version — so it is what this check
# verifies instead, alongside re-confirming .fusa.json itself agrees
# with version.hpp. This re-checks what ci.yml's version-sources-agree
# job already checks on every push, because that job's trigger
# (push to main/rewrite branches) does not fire on a tag push, so nothing
# else guarantees the three sources still agreed at the exact ref this
# release job checked out.
- name: Verify shipped artifacts declare the version being released
run: |
header_version=$(grep -m1 -oE 'kVersion[[:space:]]*=[[:space:]]*"[0-9]+\.[0-9]+\.[0-9]+"' include/rcp/version.hpp | grep -oE '[0-9]+\.[0-9]+\.[0-9]+')
if [ -z "$header_version" ]; then
echo "::error file=include/rcp/version.hpp::Could not parse kVersion"
exit 1
fi

fail=0

fusa_version=$(grep -m1 -oE '"version": *"[0-9]+\.[0-9]+\.[0-9]+"' .fusa.json | grep -oE '[0-9]+\.[0-9]+\.[0-9]+')
if [ "$fusa_version" != "$header_version" ]; then
echo "::error file=.fusa.json::.fusa.json's project.version is '$fusa_version', but include/rcp/version.hpp says '$header_version' -- every artifact cpfusa generates from .fusa.json (report.html included) is stamped from the stale value."
fail=1
fi

if [ ! -f report.html ]; then
echo "::error::Expected report.html to have been generated by the previous step"
fail=1
elif ! grep -qE "cpp-RCP v${header_version}[[:space:]&<]" report.html; then
echo "::error file=report.html::Does not declare 'cpp-RCP v${header_version}' -- expected this release's compliance report to carry the version being released."
fail=1
fi

[ "$fail" -eq 0 ] || exit 1

- name: Tool qualification evidence
run: /tmp/cpfusa/build/cpfusa qualify

Expand Down Expand Up @@ -179,6 +236,7 @@ jobs:
iso26262-gap-report.json \
iec61508-gap-report.json \
do178-gap-report.json \
iec62443-gap-report.json \
coverage-report.json \
sas.json sas.md \
sci.json \
Expand Down Expand Up @@ -242,6 +300,7 @@ jobs:
iso26262-gap-report.json
iec61508-gap-report.json
do178-gap-report.json
iec62443-gap-report.json
coverage-report.json
audit-pack.zip
fusa-badge.svg
Expand Down
18 changes: 18 additions & 0 deletions AUDIT_PACK.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,23 @@ itself was written to correct.
Required threshold: 80% branch coverage. MC/DC coverage target of 80% is
tracked as an open item for an ASIL-C upgrade path.

Real MC/DC (condition/decision) evidence, distinct from the `cpfusa
coverage --mcdc`/`--dal DAL-B` branch-coverage fallback above, is now
measured in CI by `.github/workflows/ci.yml`'s `mcdc` job (Phase 7 batch
2 / cpp-RCP #129): LLVM's own `-fcoverage-mcdc` instrumentation, built
and run against the full `ctest` suite, exported via `llvm-cov export`
(not `cpfusa coverage --mcdc-file`, whose parser expects JSON keys real
`llvm-cov export` output does not produce — see the job's own header
comment; filed upstream as SoundMatt/cpp-FuSa#64-class). Freshly measured
immediately before this PR (Homebrew LLVM 18.1.8, matching the CI job's
own clang-18, on `include/rcp/*.hpp`): 313/466 = 67.17% real MC/DC
condition-pair coverage (corroborated by a second local run on LLVM
22.1.8: 426/629 = 67.73%, close agreement across a 4-major-version
toolchain gap). The `mcdc` job ratchet-gates a 60% floor — real margin
below that measurement, not a 100% or 80% claim — so this stays
open-item/informational for the 80% ASIL-C target above while still
catching a real regression today.

---

## 4. DO-178C (DAL-C) Applicability
Expand Down Expand Up @@ -101,6 +118,7 @@ All of the following gates must pass for a tagged release:
| IEC 61508 report | `cpfusa iec61508` | Gap report generated (advisory) |
| DO-178C report | `cpfusa do178` | Gap report generated (advisory) |
| Coverage | `cpfusa coverage` | ≥ 80% branch |
| MC/DC (real, LLVM) | `ci.yml`'s `mcdc` job (`llvm-cov export`) | Ratchet floor: ≥ 60% (not 100%; see §3) |
| SCI (Software Change Impact) | `cpfusa sci` | No unmitigated impacts |
| Audit pack | `cpfusa audit-pack` | Generated |
| Release badge | `cpfusa badge` | Green |
Expand Down
113 changes: 113 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
# Changelog

All notable changes to cpp-RCP are documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/).

This changelog starts from the ground-up rewrite tracked on
`rewrite/v3-from-c-rcp` (cpp-RCP issue #129, ROADMAP.md Phase 17) and does not
attempt to reconstruct the project's full pre-rewrite history — see git log
for that. Entries below are one line per merged PR/batch, in the order
merged.

## [Unreleased] — v3.0.0 rewrite (`rewrite/v3-from-c-rcp`)

### Phase 7 — release hardening, formal verification, coverage

- Release-pipeline hardening: `version-sources-agree` CI job, real `cpfusa
analyze`/`cpfusa cyber` gating, `.fusa-dispositions.json`, IEC 62443 release
gap report, shipped-artifact version verification (batch 3)
- rewrite(phase7): batch 2 — add real MC/DC coverage ratchet gate (LLVM) (#168)
- rewrite(phase7): batch 1 — port LifecycleStateMachine/E2ESafePoint TLA+
specs, add TLC CI job (#167)

### Phase 6 — requirement catalog re-derivation (complete)

- rewrite(phase6): batch 13 — MOCK/PWRMODE catalog re-derivation (Phase 6
complete) (#166)
- rewrite(phase6): batch 12 — DISC/RELAY catalog re-derivation (#165)
- rewrite(phase6): batch 11 — REQ-REGMAP-\*→REQ-RMAP-\* rename + RMAP/SRV
catalog (#164)
- rewrite(phase6): batch 10 — SPI/UART/WAKEUP catalog re-derivation (#163)
- rewrite(phase6): batch 9 — MDIO/PWM catalog re-derivation (#162)
- rewrite(phase6): batch 8 — I2C/ADC/GPIO catalog re-derivation (#161)
- rewrite(phase6): batch 7 — CANEP/LINEP/ISELED catalog re-derivation (#160)
- rewrite(phase6): batch 6 — E2E/LIFECYCLE catalog re-derivation (#159)
- rewrite(phase6): batch 5 — watchdog: one traceability gap found, no catalog
change (#158)
- rewrite(phase6): batch 3 — conditional-request cluster catalog
re-derivation (#157)
- rewrite(phase6): batch 2 — FRAG/RESPQUEUE-slice/LOAN catalog re-derivation
(#156)
- rewrite(phase6): batch 1 — ACF/AVTP/WIREERR catalog re-derivation (#155)

### Phase 5 — admin/shmem and transport dispatch wiring

- rewrite(phase5): admin.hpp — fixed-capacity subscriber/counter bounds, port
deadlock fix (#154)
- rewrite(phase5): shmem.hpp — rebuild Channel around a real bounded
byte-level buffer (#153)
- rewrite(phase5): l2.hpp — add FrameHandler wired to Phase 4 frame-level
dispatch (#152)
- rewrite(phase5): udp.hpp — wire Server::Handler to Phase 4 frame-level
dispatch (#151)

### Phase 4 — mock dispatch, discovery, register map, server admission

- rewrite(phase4): mock.hpp batch D2 — AVTPDU frame-level dispatch, closes
out Phase 4 (#150)
- rewrite(phase4): mock.hpp batch D1 — wire fragment.hpp/respqueue.hpp for
E2E fragmented dispatch (#149)
- rewrite(phase4): mock.hpp batch C — wire RxSequenceGuard,
StreamFaultTracker, RxWatchdog (#148)
- rewrite(phase4): mock.hpp batch B — Table 24 response suppression +
regmap/discovery wiring (#147)
- rewrite(phase4): mock.hpp batch A — wire server::Endpoint admission (#146)
- rewrite(phase4): fix adapt.hpp's missing read_size_or_segment_num field,
add test_adapt.cpp (#145)
- rewrite(phase4): port discovery from c-RCP, fix claim-release and
validation gaps (#144)
- rewrite(phase4): port regmap batch B from c-RCP — HW pins, streams, EP-ID
map, optional subsystems (#143)
- rewrite(phase4): port server.c admission/scheduling into new server.hpp
(#141)
- rewrite(phase4): port regmap batch A from c-RCP — general map, EP0,
generic/functional split (#142)

### Phase 3 — remaining endpoint types

- rewrite(phase3): port spi and uart from c-RCP, RC5 nr_cs/deassert_cs_pause
fix (#139)
- rewrite(phase3): port pwm and wakeup from c-RCP, fix PWM_OUT Subtract
operand order (#140)
- rewrite(phase3): port mdio from c-RCP, revert an earlier session's own
regression (#138)
- rewrite(phase3): port adc/gpio from c-RCP, fix a critical ADC averaging
regression (#137)
- rewrite(phase3): port can/lin from c-RCP, wire CAN XL fragmentation via
fragment.hpp (#136)
- rewrite(phase3): port iseled/i2c from c-RCP; fix ROADMAP.md's Phase 17
missing i2c entry (#135)

### Phase 2 — E2E/lifecycle/watchdog

- rewrite(phase2): port e2e/lifecycle from c-RCP, correct HARA.md's
overstated H-004 claim (#134)
- rewrite(phase2): port watchdog + build allocation fault-injection seam,
ported from c-RCP (#133)

### Phase 1 — core wire format foundation

- rewrite(phase1): port request/sequencer/scheduler from c-RCP's
RC5-conformant reference (#132)
- rewrite(phase1): add fragment/respqueue, convert loan to fixed-capacity,
ported from c-RCP (#131)
- rewrite(phase1): port acf.hpp/avtp.hpp from c-RCP's RC5-conformant
reference (#130)

### Rewrite kickoff

- ci: run CI/DCO on the rewrite/v3-from-c-rcp branch too
- docs(roadmap): v3.0.0 becomes a full rewrite ported from c-RCP, not Phase
16's organic conclusion
36 changes: 36 additions & 0 deletions FORMAL_VERIFICATION.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,42 @@ accepted. Unlike the pre-replacement sliding-window bitmap this spec
supersedes, there is no window to exhaust — acceptance is a single
comparison against the high-water mark.

**STATUS CORRECTED 2026-08-21 (cpp-RCP issue #129 / RELAY Phase 17 Phase 2
pass) — two distinct corrections, both documentation-only:**

1. **Wiring gap, not algorithm gap.** This section previously implied
`RxSequenceGuard` — and by extension the SP1/SP2 properties verified
here — functions as a real, active mitigation for H-004. It does not:
`RxSequenceGuard` is **never instantiated anywhere outside its own unit
test** — not in `mock::Server`'s dispatch, and not in any transport
`Server`. SP1/SP2 are correctly verified properties of the
`RxSequenceGuard` *primitive itself*, but a formally-verified primitive
that nothing in this codebase calls provides no actual protection
against H-004 today. See `HARA.md`'s own corrected H-004 section for
the full account (mirroring c-RCP's own resolution of the identical
ambiguity, issues #601/#606). Wiring `RxSequenceGuard` into
`rcp/mock.hpp`'s dispatch is explicitly out of scope for this pass
(Phase 4/server-dispatch work) — this correction only makes this
section stop overstating what already-verified fact it establishes.
2. **This spec models the pre-Phase-2-pass algorithm.** The same Phase 2
pass that produced this correction also content-corrected
`e2e::RxSequenceGuard`'s actual comparison rule against c-RCP's
`rcp_e2e_seq_evaluate()`: acceptance is now an RFC 1982 forward-window
comparison over the 8-bit AVTPDU `sequence_num` space (forward distance
in `[1, 127]`), not the plain non-wrapping `n > last_seq` this file's
`tla/RxSequenceGuard.tla` still models (its own `Accept(n)` action). A
non-wrapping model is a real behavioral divergence from the corrected
C++ implementation, not merely an abstraction choice the "Assumptions
and Abstractions" section below already accounts for (that section's
"unsigned 32-bit wrap-around... is not modelled directly" note predates
and does not cover this). Re-deriving `RxSequenceGuard.tla` (and its
`.cfg`) against the RFC 1982 rule — including the independent
`rx_seq_safestate_enable`-gated discontinuity signal this pass also
added — is **not undertaken in this pass** (a distinct formal-modeling
task, not a documentation fix); tracked as a follow-up. Until then,
SP1/SP2 as stated here should be read as verified properties of the
*prior* algorithm, not the current one.

**ASIL tracing**: H-004 (request replay/out-of-order delivery), SG-004,
REQ-E2E-007.

Expand Down
Loading
Loading