Skip to content

S23.22: final documentation and comment quality gate before 0.1.0 #708

Closed

Description

@DavidCozens

Parent epic: #246

A final quality gate over the written material — every .md file and every source
comment — before the first public release.

The audience is embedded engineers evaluating the library during procurement, so at
0.1.0 the documentation is part of the product rather than a support artifact. A
statement that is stale, contradicted elsewhere, or repeated in three places with
three different emphases costs the same as a defect, and is harder to find later
because nothing fails when it is wrong.

Axes

  • Accuracy — does it describe what the code does now? Anything written ahead of
    the implementation, or left behind by it.
  • Duplication — one authoritative home per piece of knowledge. Where the same
    rule is stated twice, one copy becomes a link.
  • Repetition — the same point restated within a page, or a paragraph that adds
    emphasis rather than information.
  • Readability — plain declarative prose. Structure that lets a reader find the
    answer without reading the whole page.

Scope

  • docs/** and the root .md files, including the community-health set.
  • Source comments in Core/ and Platform/, and the @file briefs that generate
    the API reference.
  • CLAUDE.md and SKILL.md — internal, but they are the contract this work is
    judged against, and they are public in a public repo.

Source comments are deliberately in scope here rather than under E24, so the
audit is one ticket to iterate rather than two. E24 should not pick up a parallel
comment-quality story.

Method

Findings are collected as comments on this issue. Because the audit is about
consistency across the documentation set, a fix scoped to one page cannot be judged
against that standard — so work proceeds as commits on a single branch behind a draft
PR, which runs the docs gates continuously without spending a review on a partial
state. The PR is marked ready when the set is coherent, and that is when it is read.
The issue closes when the findings list is empty, not when the first PR merges.

Out of scope

Acceptance

  • Every finding on the list is resolved, or explicitly declined with a recorded
    reason.
  • markdownlint-cli2 clean, and the docs-build and analyze-markdown lanes green.
  • No statement in the audited set contradicts another, and each rule has one
    authoritative home with links pointing at it.

Activity

  1. added this to the 0.1.0 milestone on Aug 5, 2026
  2. DavidCozens commented on Aug 5, 2026

    @DavidCozens
    CollaboratorAuthor

    First findings, from board maintenance after #707 merged.

    CLAUDE.md — Project Board Membership. The board has six enabled project workflows: Auto-add sub-issues to project, Auto-close issue, Item added to project, Item closed, Pull request linked to issue, Pull request merged. Two documented rules look stale against them:

    • "Adding an issue to the repo does not add it to the board — that is a separate step and must be done explicitly." Auto-add sub-issues to project is enabled, so addSubIssue may already do it, making step 3 of the add-to-board recipe redundant.
    • "When a PR merges and closes a story, flip its project Status to Done. Closing the issue does not update the Status field automatically." Item closed and Pull request merged are both enabled, and S32.02: OpenSSF Scorecard workflow + Best Practices badge #644 moved to Done on closing without anyone setting it.

    Both need confirming by observation before the text is rewritten — an automation being enabled is not proof of which field it writes. Worth doing, because the current text prescribes manual steps that may be unnecessary.

    Not a documentation finding, but adjacent. issue.projectItems in GraphQL returns totalCount: 0 for issues on this board, because the project is user-owned (DavidCozens) while the repository is org-owned (cososo-ltd). Enumerating the project's items directly works, and needs pagination — the board holds 277 items, past the 100-item page default. Anything in the docs that suggests checking board membership from the issue side would be unreliable.

  3. 54 remaining items

  4. DavidCozens commented on Aug 12, 2026

    @DavidCozens
    CollaboratorAuthor

    Findings still open — the RFC compliance matrix is done

    The matrix is finished and read end to end. #747, #749, #751 and #752 carry the work;
    #748, #750 and #753 carry what came out of it and belong to 0.2.0. What remains on this
    issue is the rest of the documentation set.

    1. The summary counting rule. RFC 5424's "Total requirements = 40" includes five rows
      that state they carry no requirement of their own — §6.2.3.1, §6.3.5, §6.5, §7.1.4,
      §7.2.5 — which exist so a reader can see those sections were considered rather than
      skipped. Either the column becomes a row count, or those five are excluded and the
      totals recomputed. Maintainer's decision.
    2. The duplication trim across the rest of the set. The principle is settled and was
      applied to the matrix: the parent row carries what is true of the element, each child
      row carries its own parameter, and headers carry the mechanics. §7.2 went from 177
      words to 57, §7.3 from 95 to 49, RFC 5426 §3.2 from 136 to 75, RFC 5425 §4.2 from 34
      to 13.
    3. docs/iec62443.md structural review — everything after Control Implementation.
      Needs scope input: the per-substrate prose grows a block per TLS backend, and
      Deployment Considerations and Architecture for Security now overlap
      security/threat-model.md and ci.md. The old cipher-pinning overstatement is gone.
    4. Null objects beyond the matrix. The matrix preamble now states once that a status
      describes a correctly wired instance, and that a component which could not be built is
      reported through the error handler rather than being a compliance limit. The roles
      pages and the porting guide have not been read for the same pattern.
    5. Files never audited in depth: porting.md, structured-data.md, NAMING.md,
      bdd.md, the integrating-* guides, CLAUDE.md, SKILL.md. build-integration.md is
      parked deliberately. misra-deviations.md is done.
    6. README: no baseline caveat under What it costs — the figures are incremental on
      a device already running FreeRTOS, lwIP, FatFs and Mbed TLS, and read as impossible
      without that; em-dash density 27 in 986 words.
    7. Low priority: four "…is the point" constructions in hardening-path.md.
  5. DavidCozens commented on Aug 12, 2026

    @DavidCozens
    CollaboratorAuthor

    Findings after the compliance-guide session

    Four pull requests carry this round: #757, #759 and #760, alongside #758, which is
    David's fix for a defect this audit turned up. What follows supersedes the
    previous findings comment.

    Closed

    • The summary counting rule. Dropped. The matrix carries a statement covering
      it and the review was satisfied, so the column stays as it is.
    • docs/porting.md, docs/roles/index.md, docs/structured-data.md,
      docs/core/index.md, docs/NAMING.md, docs/bdd.md.
      Audited against the
      code. core/index.md needed no change; its hand-maintained list of Core classes
      is complete today, though nothing asserts it stays so.
    • docs/iec62443.md. Rewritten, 2272 words to 1336. It had opened by arguing
      the standard did not apply to us and then listed gaps in a column headed Gaps.
      Four rows answered the wrong question: CR 6.1 described whether logging blocks
      the caller where the control is about the log being readable, and CR 6.2
      described transport reliability where the control is about monitoring for
      intrusion, attack and fault.
    • docs/security/threat-model.md. Rescoped, 1752 words to 797. In
      threat-modelling terms a library is not a component, and the page asserted four
      trust boundaries, two of which were admissions that no boundary existed. The
      adversary catalogue and the Defended by construction list are gone; the second
      had already drifted into claiming Send never blocks on a full kernel buffer,
      which the Posix page contradicts.
    • Null-object caveats beyond the matrix. Checked. porting.md and
      roles/index.md both present Nulls as the porting mechanism rather than as a
      compliance limitation. No residue to remove.
    • The character sweep. docs: write source comments in characters a UK keyboard types #760, 1005 substitutions across 250 files, applying the
      rule added to CLAUDE.md in docs: S23.22 hold the README, the working agreement and the porting guide to the code #757.

    Declined, with reasons

    • pack as vocabulary. Survives in six documents including docs/NAMING.md,
      where it heads a section. Removing it from CLAUDE.md alone would make things
      worse, and a repo-wide change is not this story's.
    • The CodeRabbit review budget in CLAUDE.md. It shaped decisions this
      session but stays unwritten by the maintainer's decision.
    • The SolidSyslogNullSd naming exception. The StructuredData role's Null
      breaks the SolidSyslogNull<Role> pattern that three documents state. Closed:
      no note, no rename. Do not raise it again.

    Raised and resolved

    Still open

    • Batch 5, the never-audited pages. About 11,100 words: builds.md, ci.md,
      containers.md, local-checks.md, release-process.md, error-severity.md,
      overview.md, docs/README.md, and the security/ siblings. Plus about 2,100
      words of community-health set, CONTRIBUTING.md, CODE_OF_CONDUCT.md,
      SUPPORT.md, SECURITY.md and the PR template, which this issue scopes in and
      no findings comment has mentioned before now.
    • Batch 6, source comments in Core/ and Platform/. 373 files, never
      started. docs: write source comments in characters a UK keyboard types #760 changed characters, not content.
    • References to issues and pull requests. The maintainer wants them out
      generally: they were justified for issues expected in 0.1.0 and that reason is
      expiring. This contradicts the Link the record, not the source rule added to
      CLAUDE.md in docs: S23.22 hold the README, the working agreement and the porting guide to the code #757, so the rule is decided first and the sweep follows.
    • build-integration.md, parked deliberately.

    Recorded nowhere else

  6. DavidCozens commented on Aug 13, 2026

    @DavidCozens
    CollaboratorAuthor

    Batch 5 closed, and Batch 6 deliberately scoped down

    #764 carries this round. It supersedes the "Still open" section of the previous
    comment on Batches 5 and the reference sweep.

    Closed

    • Batch 5, the never-audited pages. builds.md, ci.md, containers.md,
      local-checks.md, release-process.md, error-severity.md, overview.md,
      docs/README.md and the security/ siblings, held to the workflows, the presets
      and the headers they describe. builds.md, overview.md and release-process.md
      needed no change.
    • The community-health set, which this issue scoped in and no findings comment
      had mentioned: CONTRIBUTING.md, CODE_OF_CONDUCT.md, SUPPORT.md, SECURITY.md
      and the pull-request template. All accurate; no change needed.
    • References to issues and pull requests. The rule is settled and written into
      CLAUDE.md: an issue is linked while its work is outstanding, and when it closes
      the prose is read against the code before either is deleted — a fixed divergence
      takes prose and link out together, an issue closed as not planned takes only the
      link. Source comments are held to this more strictly than documentation. Nine
      closed-issue references removed; every reference left in docs/ points at an open
      0.2.0 issue. The MISRA deviation register keeps its provenance links by decision.

    What was wrong

    • error-severity.md named three error categories that are not symbols.
    • SolidSyslog.h documented SERVICE_HALTED against a SolidSyslogDiscardPolicy_Halt
      that does not exist; the enumerator is SOLIDSYSLOG_DISCARD_POLICY_HALT.
    • The site home pointed at the repository README.md, which is not published to the
      site at all.
    • at-rest-cryptography.md tied the two AES-GCM policies to host and embedded targets
      respectively; the choice is which crypto library the build links, and
      integration-linux-mbedtls runs Mbed TLS on Linux.
    • containers.md described the retired hello-world ELF and a behave service that is
      behave-linux; sbom.md said container digests live in containers.md, which holds
      tags by design; local-checks.md counted two IWYU lanes where there are three.
    • Two counts had rotted and are gone rather than corrected: the required-context count
      and a line-of-C figure in ci.md, and a CI wall-clock estimate in local-checks.md.

    Also settled

    Links to published root documents. A page under docs/ names the root file by its
    repo-relative path, and hooks/source_links.py re-aims it at the published page at
    build time instead of rewriting it out to GitHub. The source form works on GitHub and
    in a clone; the site resolves it internally. Ten hand-written site paths, five of them
    predating this work, are now uniform.

    The repository is no longer described as a template. One vestigial line in
    CLAUDE.md told a reader cloning the template to reconfigure branch protection.

    Batch 6 is narrowed, by decision

    Batch 6 was scoped as source comments across Core/ and Platform/ — 373 files. It
    will not be completed exhaustively before 0.1.0. The bar for this release is
    documentation that is accurate, not comments that are word perfect, and docs improve
    continuously after it ships.

    Done already, mechanically, across all 373 files: every SolidSyslog symbol named in a
    comment resolves to a declared symbol (one defect, above), no comment names a file that
    does not exist, and closed-issue references are gone.

    What remains, and is the whole of the intended pass:

    • The failure-mode claims, triaged to those an integrator could act on — a claim that an
      error is silent, unreported, or safely degraded — verified against the functions.
      44 candidates identified; most are internal notes and will be left alone.
    • Comments carrying another class's documentation rather than referring to it. That is
      the duplication that actually rots, and stripping is the fix.

    Explicitly out of scope for 0.1.0: adding the missing implementor halves of the
    SolidSyslog<Role>Definition.h contracts, @file brief length variance, and any
    @param / @return sweep. This is recorded so the narrowing reads as a decision.

    build-integration.md remains parked.

  7. DavidCozens commented on Aug 17, 2026

    @DavidCozens
    CollaboratorAuthor

    Findings list is empty. #772 is the last one.

    Supersedes the "Still open" and "Recorded nowhere else" sections of every previous
    comment.

    Closed

    • Batch 6, source comments. Complete as scoped. The mechanical sweeps over all
      373 files were done before the previous comment; docs: S23.22 style the documentation tables, and stop Core naming a platform #765 carried the duplication
      finding. The 43 failure-mode claims were re-derived and the integrator-facing ones
      verified against the functions: SolidSyslogBuffer.h's silent drop (the
      CircularBuffer write does drop and report nothing), the Mbed TLS HMAC mismatch
      returning false unreported, the Posix message-queue buffer's EAGAIN silence with
      every other errno surfaced, and the UDP sender swallowing an untransmittable record
      as sent. All four accurate. The rest of the 43 are internal notes, left alone by the
      narrowing decision. The cross-class half is machine-guarded:
      scripts/check_platform_docs.py passes.
    • docs/build-integration.md. Read by the maintainer; no change needed. It was
      parked from the start and comes off the list rather than moving to another one.
    • The README baseline caveat and the four "is the point" constructions in
      hardening-path.md. Both done since the last comment.

    Declined, with reasons

    • The two output-parameter conventions in the public API, size_t* bytesRead
      alongside uint8_t* keyOut. Dropped. Parameter names are not ABI and the
      divergence costs a reader nothing.
    • No compile-time sector-size check on Platform/PlusFat/. Investigated and
      declined. FF_MAX_SS is a FatFs macro; FreeRTOS+FAT publishes no compile-time
      sector-size macro at all, taking the sector size as a runtime argument at disk
      init, so S21.04: BlockDevice reports its own block size + single SOLIDSYSLOG_FILE_BLOCK_SIZE tunable #527's acceptance criterion was not expressible for that backend. Closing
      the gap properly would mean a new File vtable operation so the adapter could
      report a runtime sector size to Core, existing only to second-guess a number the
      integrator sets from their own media. Two things came out of the investigation and
      came out of the investigation: the FatFs check covered only the tunable default,
      since SolidSyslogFileBlockDevice_Create takes blockSize as a runtime parameter
      that bypasses it, and the load-bearing floor - one worst-case record - is enforced
      centrally in SolidSyslogTunablesDefaults.h for every backend. So the FatFs check
      was not earning its place either: docs: S23.22 drop the FatFs sector floor and its porting-guide example #772 removes it, along with the porting guide's
      section that used it as the worked example for choosing an #error over a build
      gate. The two FAT adapters end up the same shape, which settles the asymmetry
      rather than explaining it.

    Acceptance

    Every finding resolved or explicitly declined. markdownlint-cli2 clean and the
    docs-build and analyze-markdown lanes green on every PR in the series. The
    documentation set has one authoritative home per fact, asserted by
    check_platform_docs.py, by the strict anchor validation added in #747, and by the
    link resolution settled in #764.

    Batch 6's explicitly deferred items stand as recorded: the missing implementor halves
    of the SolidSyslog<Role>Definition.h contracts, @file brief length variance, and
    any @param / @return sweep. Documentation improves continuously after 0.1.0
    ships; none of those is a release gate.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    documentationImprovements or additions to documentationstoryStory issue

    Type

    No type

    Projects

    No projects

      Milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions