Skip to content

S11.11: Make MISRA suppressions honest + close E11 #414

Description

@DavidCozens

Parent epic: #29

Context

S11.10 (#413) closes the last per-class migration — every stateful _Create /
_Destroy class in the library, including the SolidSyslog core itself, now
lives on SolidSyslogPoolAllocator. The E11 mechanism work is complete.

What remains is an audit. Over the sweep stories, misra_suppressions.txt
shrank class by class as storage-cast deviations evaporated. But the trim has
been opportunistic — each sweep deleted its own class's lines, line numbers
drifted as the files were rewritten, and nobody has verified that every
remaining line still fires a finding if removed
. Per
feedback_cppcheck_misra_invariant, the suppressions file's job is to assert
"no new findings vs main" — a stale entry quietly defeats that, because the
line will never fire whether the suppression is there or not, and the file's
honesty erodes.

This story makes the suppressions file honest, compacts the D.002 deviation
document, sweeps docs for residual <Class>Storage mentions, and closes the
epic.

Decisions locked in pre-raise

1. Suppressions honesty sweep — bulk-delete + restore-only-what-fires.

The mechanism:

a. Snapshot misra_suppressions.txt at the commit immediately before S11.01
landed
(#394's parent). Record the file's line count and per-rule
breakdown — this is the "pre-E11" baseline.
b. Record the current (post-S11.10) line count and per-rule breakdown — this
is the "post-E11 pre-honesty" baseline.
c. Delete the suppressions file entirely (keep the header comment only).
d. Clear the cppcheck-misra CTU cache.
e. Run cmake --preset cppcheck && cmake --build --preset cppcheck fresh.
f. For each finding in the run, add a suppression entry — grouped by the
deviation that authorises it, with the same # D.NNN — … header layout
as today.
g. Re-run cppcheck-misra. CI-clean.
h. Record the post-honesty line count.
i. DEVLOG records pre-E11 / post-E11-pre-honesty / post-honesty all three.

This guarantees that every line in the final file corresponds to a current
finding. Anything that was stale is gone permanently. Per
feedback_cppcheck_misra_invariant, this is the right invariant to assert,
not a count target.

2. Compact D.002. Rewrite the body of docs/misra-deviations.md D.002 so
the scope is explicit and accurate post-E11:

  • (a) Vtable downcastsstatic inline ... *SelfFromBase(...) in every
    pool class. Rule 11.3, structural OO-in-C interface→implementation cast.
  • (b) SolidSyslogAddress — Strict-tier opaque value type across three
    platforms (FreeRtos / Posix / Windows). Caller-supplied-storage shape via
    SolidSyslogAddressStorage + SOLIDSYSLOG_ADDRESS_SIZE. Out of E11 scope
    (utility on a struct, no Create lifecycle).
  • (c) SolidSyslogFormatter — transient stack-built builder. Out of E11
    scope per the epic body.

One heading, one set of suppressions covering all three. No split into D.013.
The rationale subsection is updated to reflect that the historical
caller-supplied-storage shape evaporated for every pool-allocated class under
E11 and now applies only to Address and Formatter.

3. CLAUDE.md audience-table sweep. Walk every row in the public-header
audience table and strip residual <Class>Storage typedef and
SOLIDSYSLOG_<*>_SIZE mentions for classes that have migrated. Per-class
sweep PRs have updated their own rows, but cross-class references in shared
rows may have been missed.

4. SKILL.md sweep. Walk SKILL.md for any reference to the
caller-supplied-storage pattern, the SOLIDSYSLOG_<*>_STORAGE_SIZE family, or
the historical _Create(Storage*) shape. Update where stale.

5. Strip feedback_storage_pattern memory entry. Marked "obsoleted per
class as each migrates" in S11.09's memory pointers; the migration is now
complete. Remove the entry from MEMORY.md and delete its file.

6. E11 retrospective DEVLOG. A single DEVLOG entry summarising the epic:
classes migrated, suppressions delta (pre-E11 → post-E11 honest), public API
changes shipped, breaking changes (S11.10's handle API), tunables added,
deferred follow-ups (Dynamic-allocation future epic, S21.03's FF_MAX_SS
override now simpler post-S11.09).

7. Close E11 epic when this PR merges. All sub-issues will be CLOSED by
this point; closing the epic itself is the final step.

Sequencing on the work branch

Recommended commit shape on refactor/s11-11-final-sweep:

  1. chore: S11.11 rebuild misra_suppressions.txt from fresh cppcheck-misra run
  2. docs: S11.11 compact D.002 deviation to vtable + Address + Formatter scope
  3. docs: S11.11 sweep CLAUDE.md audience table for residual Storage mentions
  4. docs: S11.11 update SKILL.md
  5. chore: S11.11 remove feedback_storage_pattern memory entry
  6. docs: S11.11 E11 retrospective DEVLOG

Squash-merge title: chore: S11.11 honest MISRA suppressions + E11 close-out.

Acceptance criteria

  1. misra_suppressions.txt rebuilt from a fresh cppcheck-misra run (CTU
    cache cleared). Every entry corresponds to a finding that fires today.
  2. DEVLOG records three line-count baselines: pre-E11 (immediately before
    S11.01), post-E11-pre-honesty (current main + S11.10), post-honesty (this
    story).
  3. docs/misra-deviations.md D.002 rewritten — one heading, three explicit
    scope items (vtable downcasts in every pool class; Address; Formatter).
    Rationale subsection updated.
  4. CLAUDE.md audience table — no residual <Class>Storage typedef or
    SOLIDSYSLOG_<*>_SIZE mentions on migrated classes.
  5. SKILL.md — any storage-pattern references updated.
  6. feedback_storage_pattern memory entry removed from MEMORY.md; file
    deleted.
  7. E11 retrospective DEVLOG entry on the work branch.
  8. All host gates green from the gcc devcontainer: debug, sanitize, coverage,
    analyze-tidy, analyze-cppcheck, analyze-format. Clang-debug + IWYU via the
    clang container.
  9. cppcheck-misra CI-clean — the rebuilt suppressions file produces no
    findings on the configured rule subset.
  10. E11 epic (E11: Static-Allocation Variant #29) closed when this PR merges. All sub-issues are CLOSED
    on merge.

Out of scope

  • Removing the surviving D.002 scope items (Address, Formatter, vtable
    downcasts) — all three are structural and out of E11's scope.
  • Other deviations (D.001, D.003 – D.012) — E11 didn't touch these; no
    honesty audit needed unless the suppressions-rebuild reveals stale entries
    in those sections, in which case they get trimmed naturally.
  • SOLIDSYSLOG_ALLOCATION_STRATEGY=dynamic — explicit future epic.
  • Any per-class logic change.

Memory pointers for the next session

  • CLAUDE.md + SKILL.md.
  • MEMORY.md, especially:
    • feedback_cppcheck_misra_invariant — the assertion this story enforces.
    • feedback_storage_pattern — removed by this story.
    • project_e11_static_pool_design
    • project_pool_allocator_helper
    • feedback_devlog_in_pr
    • feedback_pr_template
    • feedback_no_git_commit_dash_s
    • feedback_no_merge
    • feedback_iwyu_local_invocation
  • E11 epic body (E11: Static-Allocation Variant #29).
  • All S11.01 – S11.10 DEVLOG entries (the body of work being closed out).

Open questions for the next session

  • Pre-E11 baseline commit identifier — the parent of feat: S11.01 CircularBuffer pool migration (E11 pilot) #394's merge commit.
    Confirm the SHA at the start of the work; if S11.01 commits were rebased
    during PR review, the parent SHA may differ from what's logged.
  • D.002 rationale wording — the historical table comparing alternatives
    (malloc / public concrete types / pass-by-value) is still accurate but now
    applies only to Address and Formatter. Decide whether to keep the
    comparison or trim to a single sentence.

Metadata

Metadata

Assignees

No one assigned

    Labels

    storyStory issue

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions