Skip to content

comments: state the constraint, drop the history — include/morph and src, plus the AGENTS.md rule that says so - #792

Merged
Yaraslaut merged 5 commits into
masterfrom
comments/no-history-include-src
Sep 23, 2026
Merged

Yaraslaut merged 5 commits into
masterfrom
comments/no-history-include-src

Conversation

@Yaraslaut

Copy link
Copy Markdown
Member

Comments in include/morph/** and src/** now state what the code does and
why, and nothing else. This also carries the AGENTS.md section that says so:
PR #790 merged the filing-bar half of that branch but not "Comments and
documentation"
, so the rule this change implements is not yet on master. The
first commit here adds it.

The rule

A comment, and a page under docs/, states what the code does now and
why
. Nothing else.

  • No history. Not what the code used to do, not what was tried and
    abandoned, not what a change replaced.
  • No issue numbers, no commit hashes. If a ticket's reasoning is worth
    keeping, keep the reasoning, in the reader's own words, where it applies.
  • Reasoning stays, and is the point.

The test applied to every sentence: does this describe the code as it is now,
or how it got here?
Now stays. How it got here goes.

What this is not

It is not a line-count exercise. There was no target percentage, and the
reduction is a consequence of removing history rather than a goal. Several
blocks are longer-feeling after the pass because the argument they were
making had to be restated in the present tense rather than gestured at with a
ticket number.

Three representative cases, in the report to the dispatcher, cover a block that
lost its history and kept its reasoning, one that collapsed to two lines, and
one that stayed thirty lines long because all thirty were live constraint.

Scope

tree before after
include/morph (excl. util/rational.hpp) 320 refs 0
src 114 refs 0

include/morph/util/rational.hpp is untouched — a fork PR holds it, and its 4
remaining refs are the only ones left under include/.

One commit hash was also removed (core/async.hpp cited master @ c6f6d953
beside its compile-time measurements; the measurements stay, the hash goes).

Two ticket numbers appeared in assert message strings rather than comments
(core/registry.hpp, core/bridge.hpp). Those are text a user reads on an
assertion failure, so they now point at docs/spec/core/registry.md. That is
the only place anything but a comment changed.

Deliberately left alone, because they are identifiers rather than comments and
renaming them would be a code change: Catch2 tags in tests/ ([morph497] and
friends) and one QML test function name. UAX #44 in render/locale_format.hpp
and DynamicForm.qml survives a naive citation grep and is a Unicode standard
reference, not a tracker link.

Not reached

examples/, tests/, scripts/, cmake/, .github/ and docs/ still carry
roughly 1,500 morph# references between them. They are untouched here.

Gates

Measured on this branch, rebased onto e053d5c5:

  • clang-format 22.1.8 — all 45 changed C++ files clean under
    --dry-run -Werror.
  • ctest — 1586/1586 passed, 71.7 s. Comment-only, so this is the check that
    nothing moved.
  • Doxygen --target doc — exit 0, zero warnings. Verified rather than
    assumed: the generated Doxyfile.doc carries WARN_AS_ERROR = FAIL_ON_WARNINGS and WARN_IF_UNDOCUMENTED = YES, so the gate can fail.
    Every public symbol keeps its complete @param/@tparam/@return.
  • clang-tidy-diff — 44 files analysed (non-zero, confirmed), zero warnings
    and zero errors on changed lines. The only errors in the log are
    'QCoreApplication' file not found for the two src/qt/*.cpp, because this
    local build has Qt off; CI configures it.
  • Citation grep — grep -rnE "morph#[0-9]|#[0-9]{3,4}" over
    include/morph and src returns only util/rational.hpp (excluded) and
    UAX #44.
  • NOLINT integrity — no NOLINT line is added or removed by this diff, all
    NOLINTBEGIN/NOLINTEND pairs balance, and all 78 NOLINTNEXTLINE
    directives in changed files still sit immediately above code rather than above
    a comment. This was checked explicitly because several rewrites sit next to
    suppressions.

🤖 Generated with Claude Code

https://claude.ai/code/session_01VptDWG2fKr2vBnLSJcgzgW

Yaraslaut and others added 5 commits September 23, 2026 18:42
…story

The codebase had drifted to 52% comment lines in `include/morph` -- 18,581 of
35,732 -- with single unbroken blocks running to 145, 124, 92 and 88 lines, and
1,946 issue references spread across code and `docs/`.

A large part of that is history written into the wrong medium. A comment saying
what the code used to do, or naming the ticket that changed it, duplicates
something `git blame` already holds exactly and permanently -- except the copy
rots at the next edit, and it sends the reader out of the file to a tracker to
understand the line in front of them.

So the rule is now explicit: a comment, and a page under `docs/`, states what
the code does now and why. Reasoning stays and is the point -- "why this and not
the obvious alternative" is a current fact about a current constraint, not
history. What goes is the narrative of how the code arrived here.

Public API documentation is exempt from brevity and not from the rule: Doxygen
runs with WARN_AS_ERROR, so every public symbol keeps complete
@param/@tparam/@return -- written fully, and without a ticket number in them.

Length is left to follow from the rules rather than being capped. Once the
history and the citations are gone, most long blocks are short, and a limit
would only invite padding up to it or truncating reasoning that earns its space.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VptDWG2fKr2vBnLSJcgzgW
…istory

Comments in these four subsystems carried the story of how they got here
alongside what they do: ticket citations, "before this ...", "exactly as
before", "(today's behavior)" on every default, and in one case a whole
`@par` devoted to what an earlier version of that same paragraph had said.

Every sentence was tested against "does this describe the code as it is
now, or how it got here?". What it describes now stays, including the long
blocks -- `locale_format.hpp`'s measured Unicode locale facts, the UTF-8
strictness argument in `decodeUtf8`, `qt_executor.hpp`'s teardown hazard --
because all of that is live constraint rather than narrative. What was left
is the reasoning, in place, with no reader sent to a tracker.

No code changed; this is comment text only.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VptDWG2fKr2vBnLSJcgzgW
`core` carried the densest history in the tree: 77 ticket citations in
`bridge.hpp` alone, a commit hash in `backend.hpp`'s allocation note, and
several blocks written as the story of a refactor -- a before/after
allocation table, "what had to be preserved, and where it now lives", "what
morph#593 established", "the four `*Async` twins morph#571 removed".

What those blocks were protecting is the reasoning, and it stays: the four
invariants `BridgeSink`'s settle path holds, why `notify`-style liveness
checks are two steps and what closes the window, why `_attachMtx` is not
held across a dispatch, why the gate advances over a contiguous run of
released tickets rather than jumping, why an out-of-order release is
recorded rather than applied. Those are current facts about current
constraints and several of them are still twenty lines long.

What went is the narrative around them, and the tracker round trip. The
three clang-tidy suppression stamps keep their verification status -- what
was re-checked, at which pinned version, and what would change the verdict
-- without naming the tickets that deleted the scripts that used to check.

Assert message strings in `registry.hpp` and `bridge.hpp` also named a
ticket; those are text a user reads, so they now point at
`docs/spec/core/registry.md` instead. No other code changed.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VptDWG2fKr2vBnLSJcgzgW
…of the library

Same test per sentence as the two commits before it. The blocks that
needed the most care here were the ones whose history *was* the argument:

- `forms.hpp`'s nested-aggregate note enumerated two abandoned designs by
  ticket. The comparison is the reason the current design is right, so it
  stays -- as a statement about what an ancestor type list and a depth
  counter each cost, not about what was tried when.
- `file_offline_queue.hpp`'s constructor explained a `repairTornTail()`
  call that is deliberately absent. Rewritten as the three current reasons
  it would be wrong to add one, which is what a reader needs.
- `replay_ledger.hpp`'s profile of two `std::string` constructions keeps
  every measured figure and the condition that reopens it ("the moment a
  per-request caller of this class appears"). Only the citations and the
  revision the numbers were taken on went.

`include/morph/util/rational.hpp` is untouched: a fork PR holds it.

Gates on this tree: clang-format 22.1.8 clean; 1586/1586 ctest; Doxygen
`--target doc` exit 0 with `WARN_AS_ERROR = FAIL_ON_WARNINGS` and
`WARN_IF_UNDOCUMENTED = YES` both confirmed set in the generated Doxyfile,
and zero warnings in the log.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VptDWG2fKr2vBnLSJcgzgW
`DynamicForm.qml` carried 30 citations, most of them attached to a sentence
in the past tense about what the renderer once did with a schema shape.
Every one of those is better as the present-tense statement of what the
branch is for -- "a renderer that collapses the `oneOf` to its first
non-null branch draws a plain TextField over a three-value set" says the
same thing to someone reading the branch, and stays true.

The locale block keeps every measured figure: 77 of 711 locales with a
non-ASCII negative sign, 76 with a non-ASCII zeroDigit, 0 with a
multi-unit separator against 54 for each sign. Those are the facts that
make the code's shape correct and they are why that comment is long.

`tst_i18n.qml`'s section headers were ticket numbers; they are now what
the section is about. Catch2 tags in `tests/` (`[morph497]` and friends)
are identifiers rather than comments and are left alone, as is the one
`test_a_nullable_ref_member_keeps_morph189s_numeric_encoding` function
name -- renaming either is a code change, not a comment change.

"UAX #44" survives the citation grep and is a Unicode standard reference,
not a tracker link.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VptDWG2fKr2vBnLSJcgzgW
@Yaraslaut
Yaraslaut force-pushed the comments/no-history-include-src branch from 0b5d88e to 8c81cb7 Compare September 23, 2026 16:51
@Yaraslaut
Yaraslaut merged commit f017603 into master Sep 23, 2026
26 of 27 checks passed
Yaraslaut added a commit that referenced this pull request Sep 24, 2026
…s, .github, cmake and tests (refs #792) (#797)

* docs/spec: state the constraint, drop the citation

327 tracker references across 24 spec files — 279 `morph#NNN` and 48 of the
`issue #NNN` / bare `#NNN` forms the first pass's grep did not see — replaced
by the reasoning they stood in for, per AGENTS.md "Comments and documentation".

Most of the diff is rewriting, not deleting. A paragraph whose only support was
a ticket number has the support restated: "the same check-then-call shape,
elsewhere in `Bridge` — issue #489" becomes the four dispositions and why each
site can or cannot take the lifetime gate; backend.md's "What was wrong with
the old shape" becomes "Why one bind virtual and not four", which argues the
alternative's two costs in the present tense instead of narrating its removal.

Every measured block stays whole: executor.md's strand-recycling allocation
table, security.md's `gai_strerror` mapping evidence, testing_strategy.md's
302x polling-step swing, registry.md's transparent-key census, backend.md's
`ActionCall` round-trip figures. Past-tense narration around them is recast as
the condition the number belongs to, and the revisions the measurements were
taken on come out with the ticket numbers.

backend.md's "Migration status" table — seven landed pull requests — is gone;
what it carried that is still true (default `bindModel` routes to the
synchronous verb, the `parkIfInFrame` arm is measured-unreachable and kept
anyway, the `inlineExecutor()` choice) is restated as current behaviour.

`UAX #44` in forms.md is a Unicode standard, not a tracker, and stays.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VptDWG2fKr2vBnLSJcgzgW

* examples: delete the forge annex, which the ladder no longer has a slot for

`examples/forge/` held one tracked file, a rung-8 design annex. It is not in
`examples/rungs.txt` — which that file calls "the single authority" for
rungs — and has no `CMakeLists.txt`, the only directory under `examples/`
with neither. Its own header gates it on a decision that has passed:
"building the product phases is a post-rung-4 decision", and kanban is rung 4
and shipped.

Its four referrers in `examples/LADDER.md` are repaired rather than left
dangling: the rung-8 table row goes, the annex range becomes 5-7, and the two
sentences that named forge in prose are rewritten so they read correctly
without it. `examples/kanban/README.md`'s deferral note loses a cross-reference
to "forge phase 2" and states the reason directly, and
`examples/IMPLEMENTATION.md`'s FTS5 escapee is described by what it is rather
than by which rung would have needed it.

No other link into that directory remains.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VptDWG2fKr2vBnLSJcgzgW

* examples: delete FINDINGS.md, which now duplicates four live homes

Every section of `examples/FINDINGS.md` has somewhere else to live, so keeping
it is duplication that drifts: what gets recorded is AGENTS.md's filing bar,
the promotion rule is AGENTS.md's "same example defect in a second place",
triage dispositions are the `triage-issue` skill's verdict labels, and
identity and citation are GitHub issues. It also directed readers to
`docs/findings/`, which does not exist.

Its one live fact was the "Promoted findings" record: five rungs had
accumulated seven near-identical copies of the same idempotency
check-then-set table, which is why `morph::offline::IReplayLedger` exists.
`docs/spec/offline/offline.md` already carried that argument — the rung count,
the call-site count, why storage stays app-side, and the conformance suite —
so rather than duplicate it, that paragraph gains the five rung names and the
history is dropped.

Referrers under `examples/` are rewritten rather than unlinked, since most are
instructions to a reader: `IMPLEMENTATION.md` and `LADDER.md` point at
AGENTS.md's filing bar; `kanban/README.md`, `pastebin/README.md`,
`common/wasm_spike/README.md`, `crm/README.md` and `crm`'s `lead_dto.hpp`
state the rule they were citing instead of citing it. The pastebin section
explaining why a flat finding sequence was abandoned keeps the argument — a
number that outlives its target resolves to the wrong thing — and drops the
account of the migration.

The `docs/superpowers/` references are left alone: those are plan and spec
documents recording work as it was done, and a passing mention of the
pipeline in a record of the past is not an instruction to anyone.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VptDWG2fKr2vBnLSJcgzgW

* scripts+.github+cmake: gate comments that state what the gate measures, not which ticket asked for it

356 tracker references across the gate configuration — ci.yml's 132 the
largest share — replaced by the constraint each one stood for. The pattern
throughout is the same: a comment saying "this exists because morph#NNN" is
rewritten to say what goes wrong without the line, which is what a reader
editing it needs and what survives the ticket being closed.

Every measured block is kept intact and in the present tense: ci.yml's
302x polling-step swing and its parallel-ctest timings, cmake/tsan.supp's
second_deadlock_stack line counts and its 0.275s/0.273s cost, the allowlist's
five-run branch censuses, compiler_options.cmake's UBSan-recovers
demonstration. Past-tense narration around them is recast as the condition the
number belongs to.

**User-visible strings changed** — text a person reads on a failure, which
AGENTS.md's rule covers as much as a comment:

- `.github/workflows/ci.yml` — the clang-tidy filter's "findings in your code
  (morph#753)" warning.
- `cmake/DepCache.cmake` — `morph_declare_dep`'s FATAL_ERROR, and the
  `FETCHCONTENT_SOURCE_DIR_*` cache docstring.
- `cmake/morph_add_rung.cmake` — the semicolon-in-journey-name FATAL_ERROR.
- `cmake/compiler_options.cmake` — the warning-sentinel FATAL_ERROR, three
  coverage cache-sharing messages, and the coverage-manifest FATAL_ERROR.
- `scripts/check_branch_coverage.py` — the "contributes no branch records"
  failure.
- `scripts/check_install_export.sh`, `scripts/check_ctest_name_collisions.sh`,
  `scripts/check_coverage_objects.sh`, `scripts/check_coverage_roots.sh`,
  `scripts/check_catch2_pin.sh` — one message each.
- `scripts/test_check_sanitizer_instrumentation.sh` — two failure strings.

Two of those are asserted on by a self-test. `check_branch_coverage.py`'s own
`--self-test` keyed two cases on the literal `morph#403` appearing in the
message it was checking; both now key on `contributes no branch records`, and
the self-test passes. That is the failure mode this kind of edit has: a message
is a contract with whatever reads it.

`scripts/branch_partial_allowlist.json`: every measured figure and every
"what would retire this entry" clause stays. What goes is the provenance —
CI job ids, branch names, commit SHAs — and the account of one entry being
deleted and restored, which is rewritten as what it actually teaches: without
`-fprofile-update=atomic` a coverage run can report that disjunct as taken and
fail the gate, and the entry is right anyway.

Left alone deliberately: the ctest `-E "OomInjector|morph#108"` filter in
ci.yml, which selects by test name, and `morph690_fixture_marker` in a
sanitizer test fixture. Both are code that contains a ticket-shaped token;
renaming them is a behaviour change, not a comment change. The `net audit
finding #10` labels in the allowlist are that audit's own vocabulary, not
tracker references, and sit beside `#6`, `#7`, `ST1` and `BK2`.

Verified: all four workflows parse as YAML; all 14 distinct `scripts/...`
paths they name resolve; `branch_partial_allowlist.json` and
`scenario/coverage_allowlist.json` parse as JSON; the three edited Python
modules parse; and the self-tests of check_branch_coverage,
check_sanitizer_instrumentation, check_coverage_profiles, check_coverage_objects,
check_ctest_name_collisions, check_coverage_roots, check_automoc_includes and
check_tidy_suppression_scope all pass, as does `check_catch2_pin.sh .`.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VptDWG2fKr2vBnLSJcgzgW

* tests: comments that say what the case proves, not which ticket asked for it

457 tracker references across 97 files under `tests/` — 364 `morph#NNN` and
93 of the `issue #NNN` / bare `#NNN` forms — replaced by the constraint each
case exists to pin. A test comment that reads "regression coverage for
morph#NNN" tells a reader nothing about what breaks if the case is deleted;
each is rewritten to say that instead, in the present tense.

Measured blocks stay: `bench_dispatch_allocations.cpp`'s 8.06-per-call figure
and its 84-process spread, `bench_dispatch_latency.cpp`'s 302x polling swing
and its injected-delay table, `test_bridge_lifetime.cpp`'s 0/200-under-ASan
against 26/200 unsanitized, `test_quantity.cpp`'s render timings,
`tests/CMakeLists.txt`'s load-average sweeps, `.clang-tidy`'s 751-entry
database measurement.

**User-visible strings changed**, which is the part to review closely:

- **21 `TEST_CASE` names** lost a trailing ` (morph#NNN)` — these are ctest
  entry names as well as text a person reads in a failure report. Nothing in
  the repository filters on any of them.
- One exception, deliberately kept: `attachHandlerAsync's out-of-frame success
  callback ... (morph#108)` in `test_async_registration.cpp`. `ci.yml`'s
  clang-asan/clang-tsan legs exclude tests by name with
  `-E "OomInjector|morph#108"`, so that token is a selector. Renaming it
  without editing the workflow would silently stop excluding the case and turn
  both legs red. `tests/oom_injector.cpp`'s comment now says so explicitly.
- `test_strand_race.cpp`'s watchdog line, printed to `stderr` from a second
  thread, no longer prefixes itself with a ticket number.
- `tests/compile_checks/forms_dag_budget.cmake` and
  `demote_interface_includes_selftest.cmake` — three `FATAL_ERROR` messages.
- `tests/net/test_socket_server.cpp` — one `FAIL(...)`.

Left as they are, and why: Catch2 tags (`[issue26]`, `[morph583]`, …) are
identifiers, not prose; the net audit's own `finding #6`/`#7`/`#8`/`#10`/`#11`
labels are that audit's vocabulary rather than tracker references, and appear
beside `ST1`/`BK2`/`S3` in the same files; and `test_tcp_socket.cpp` quotes a
real ctest line verbatim (`Test #1696: ...`) as evidence, not as a citation.

clang-format (22.1.8) re-wrapped the lines these edits reflowed; the whole
changed set is clean under `--dry-run -Werror`.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VptDWG2fKr2vBnLSJcgzgW

* coverage: repoint seven allowlist line hints the comment cleanup moved

Removing comment lines from include/morph shifted the branches the partial-
coverage allowlist pins, and the gate resolves each entry by line first. Seven
of twenty-one entries no longer landed on their recorded source text, so the
coverage leg failed on master and on every branch cut from it -- including two
pull requests that change nothing near these files.

    core/backend.hpp        1302 -> 1294
    core/remote.hpp         1416 -> 1413
    core/remote.hpp         1494 -> 1491
    core/bridge.hpp         2041 -> 2012
    net/socket_backend.hpp   146 -> 145
    net/socket_backend.hpp   158 -> 157
    net/socket_backend.hpp   826 -> 823

Only the hints move. Every entry still resolves to the identical source text it
recorded, each match is unique in its file, and no disposition, reason or
measurement is touched -- the gate's complaint was about where to look, not
about what it found there.

Worth noting for whoever next edits comments in a header the allowlist pins:
this is a line-numbered index into files nothing stops anyone reformatting, and
it drifts silently until a coverage run resolves it. The text match is what
makes the repair mechanical rather than a re-audit.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VptDWG2fKr2vBnLSJcgzgW

---------

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Yaraslaut added a commit that referenced this pull request Sep 24, 2026
…t tree (refs #792) (#799)

* comments(examples): state the tidy suppressions' constraints, drop the citations

Every `.clang-tidy` under `examples/` -- the shared testkit one, seven rung
`tests/` copies and eight rung `include/` copies. The suppressions' arguments,
probe tables and measured counts all stay; what goes is the ticket numbers, the
narration of what a paragraph used to claim, and the description of gates that
no longer exist. Where a removed gate was the only thing holding a placement
rule, the rule is now stated as one to keep by hand, which is what is true.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VptDWG2fKr2vBnLSJcgzgW

* comments(examples/common): state the constraint, drop the citation

The shared testkit, its GUI helpers and examples/common/CMakeLists.txt. The
measured blocks stay whole -- the 165 TSan warnings behind deadline.hpp's
Qt-free rule, the 0.9^60 sampling argument in test_action_driver.cpp, the
seed sweep that found 314/779/2522, the clang-tidy reach argument in
test_db_fixture.cpp. What goes is the ticket numbers, the dates of gates that
have since been removed, and the paragraphs written as "this used to ..." --
each restated as the constraint that is true now.

One user-visible string changed: `PoolTransactionAudit`'s leak diagnostic
opened with `morph#740:` and now opens with `PoolTransactionAudit:`. Its only
reader is the audit's own self-test, whose `contains("morph#740")` moves to
`contains("PoolTransactionAudit")` in the same commit; the rest of the message,
including the `SQL_ATTR_AUTOCOMMIT still OFF` phrase that test also asserts on,
is untouched.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VptDWG2fKr2vBnLSJcgzgW

* comments(examples/bank): state the constraint, drop the citation

bank's CMakeLists, the GUI controllers and its three test suites. The
measurements stay: the 21-of-21 `disk I/O error (10)` under `ctest -j` behind
unique_test_database.hpp, `parseMinor`'s 0.49999999999999994 + 0.5 == 1.0
table, and the pool-hand-off count that makes test_pool_scope.cpp's zero
evidence rather than an unwired counter. What goes is the ticket numbers and
the "before the fix it did X" framing, each restated as the constraint the
code holds now.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VptDWG2fKr2vBnLSJcgzgW

* comments(examples/ledger): state the constraint, drop the citation

The largest rung tree: README, SYNC-BENCHMARK.md, the DTO and model headers,
book_access.hpp's ownership/scope argument, and eleven test suites.

Kept whole, because each is a live constraint rather than a story: the
rollback-journal vs. WAL contention contrast on `ReadTxnGuard` (with the
`DataMapperPool::Return` consequence and the 60s `busy_timeout` that follows
from it), `requireCategoryInBook`'s argument for a write-side-only guard and
why the refusal is `NotFound` and not `ValidationError`, the report-job
scope comparison's worked failure (`Done` is terminal, so the correct body
can never be computed afterwards), and SYNC-BENCHMARK.md's +50.00 balance
that the per-currency zero-sum invariant cannot see.

Rewritten rather than deleted: everywhere a paragraph argued from when a
thing changed. "Until morph#373 this was accepted" becomes what accepting it
would cost; "morph#183 replaced the hand-written traits" becomes what a
hand-written trait has to do that the macro does not.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VptDWG2fKr2vBnLSJcgzgW

* comments(examples/kanban): state the constraint, drop the citation

README, the two schema-driven QML views, board_model.{hpp,cpp} and ten test
suites. `gui/qml/BoardView.qml` and `tests/test_board_layout.cpp` are left
alone -- an open PR holds them.

Kept whole: the post-commit-tail argument in board_model.cpp (why the
four re-reads moved inside the transaction rather than being shielded, and
why a re-read failing after the commit leaves nothing truthful to return),
the 165 ThreadSanitizer warnings behind test_kanban_stress.cpp's Qt-free
rule and why a prebuilt Qt makes them unusable either way, and the
`WaitBudget`/`WaitStep` argument against a NOLINT.

The README's "Findings" section was a list of tracker links. It now records
what each finding *is*, and says the tracker holds their state -- which is
the part a reader of this file cannot get from the link anyway.

Catch2 tags (`[kanban][board][morph#751]` and friends) are left as they are:
renaming a tag is a code change, not a comment one.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VptDWG2fKr2vBnLSJcgzgW

* comments(examples/crm): state the constraint, drop the citation

crm's README, the offline outbox header and four test suites. The GCC 16
`-Warray-bounds` false-positive block in test_pipeline.cpp keeps every part
that is evidence -- the diagnostic text, the devirtualization GCC performs to
reach it, the measured 112 vs. 136 byte holder sizes, and the `== 16` bound
that makes the suppression lapse rather than accumulate; only the ticket
number left.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VptDWG2fKr2vBnLSJcgzgW

* comments(examples/lims): state the constraint, drop the citation

The rung with the longest README in the tree. Its "Findings raised by this
rung" section was ten tracker links; each entry keeps its whole body -- the
`ModelKey`/`WrappedModelKey` rule-of-three argument, the
`x-versionDecimalPlaces` two-keys-for-one-concept reasoning, the semicolon
in a TEST_CASE name that made `ctest -L ladder-lims` report 85 against the
binary's 87 -- and loses the link and the issue number.

§3 decision 7's retag-vs-round argument and §7's "a lab reading replayed
with no identified author is disqualifying" both stay in full: they are the
reason this rung is stricter than the framework, not a record of a request.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VptDWG2fKr2vBnLSJcgzgW

* comments(examples): state the constraint, drop the citation — polls, pastebin and bookmarks

The three remaining rungs. Kept: pastebin's sqliteodbc
`RETURNING`/`SQLFetch` finding (the upstream Lightweight issue stays -- it is
a third-party defect record, not this tracker) and the 1-in-1,640 exhaustion
arithmetic behind `paste_id_source.hpp`'s seam; polls's `messagesPerSecond`
correction, restated as what a silently dropped frame would cost rather than
as what changed.

Three user-visible strings changed, all of the same shape: the
`fromRowId` refusals in `polls::OptionId`, `polls::PollEventId` and
`kanban::BoardEventId` ended `... sentinel (morph#NNN)` and now end
`... sentinel`. Nothing reads them -- grepped for the message text and for
`unrepresentable` across the tree; the only assertions on these paths are
`CHECK_THROWS_AS` on the exception type.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VptDWG2fKr2vBnLSJcgzgW

* comments(examples): state the constraint, drop the citation — the ladder's own docs

IMPLEMENTATION.md, TESTING.md, LADDER.md, rungs.txt, examples/CMakeLists.txt
and the three non-rung trees (forms, concepts, qt_tls_client).

TESTING.md keeps every measurement it rests on -- the 165 TSan warnings that
make a Qt-linked rung unsanitisable, the 95.85% `examples/common` baseline and
the four-file split that accounts for the drop since, the `ctest -L
ladder-lims` 85-vs-87 count. What goes is the tickets and the "was documented
long before anything enforced it" framing: a path filter that matches nothing
succeeds as loudly as one with nothing to do whether or not that has happened
yet, and that is the sentence worth keeping.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VptDWG2fKr2vBnLSJcgzgW

* comments(examples): reflow the paragraphs the citation removals left ragged

Whitespace only, and confined to comment paragraphs the earlier commits in
this branch already touched: dropping a parenthetical citation mid-sentence
leaves one short line, and this pulls the following words up so the paragraph
reads at its usual width again. No wording changes, no code.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VptDWG2fKr2vBnLSJcgzgW

---------

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant