Skip to content

fix: extinguish ignored review bugs, purge em dashes, add mermaid, v0.1.0 perf baseline#150

Merged
div0rce merged 8 commits into
mainfrom
fix/coderabbit-review-comments
Jun 25, 2026
Merged

fix: extinguish ignored review bugs, purge em dashes, add mermaid, v0.1.0 perf baseline#150
div0rce merged 8 commits into
mainfrom
fix/coderabbit-review-comments

Conversation

@div0rce

@div0rce div0rce commented Jun 25, 2026

Copy link
Copy Markdown
Owner

Summary

A broad correctness + docs pass driven by the goal "extinguish all bugs (incl. ignored CodeRabbit/Codex comments), make everything current and em-dash-free, add mermaid everywhere."

Bugs fixed (the ignored CodeRabbit findings + one found by self-review)

  • qsl-bench profile_seconds_from_args: !(seconds > 0.0) let inf/nan from strtod through into duration_cast (UB). Now requires std::isfinite and clamps.
  • tcp_server transient_accept_errno: omitted ENOPROTOOPT/EOPNOTSUPP that Linux accept(2) returns and the epoll path already retries (wrongly fatal). Set now matches.
  • qsl-perfeval ring tracked non-resting orders (book depth drifted), p99 used a zero-based off-by-one index, and parse_orders accepted 123abc/-1 via strtoull. All fixed (eng.contains for resting tracking, from_chars validation + usage error, corrected percentile index). Test added.
  • qsl-perfeval allocation counter (self-review): the operator new override missed operator new(size_t, align_val_t), undercounting v0.2.2's ~1.56 over-aligned allocs/order. The earlier "-73% allocations" claim was wrong; the true cut is -34.8%. Counting is now complete and compile-time opt-in (qsl-perfeval-allocs) so it doesn't perturb the cycle numbers.

Flamegraphs: zero [unknown], every frame identified

The [unknown] frames were identified (not hidden): fp-unwinding artifacts at the glibc-2.43 malloc boundary (x29 not preserved -> one spurious frame between resolved operator new and _mid_memalign), plus the vDSO clock_gettime leaf. DWARF was verified worse (4477 vs 37 unknowns). All flamegraphs render fully symbolized with the libc malloc internals visible.

Performance reframed to v0.1.0 -> v0.2.2 (cumulative, honest)

Same harness ported into a v0.1.0 worktree, measured on the same host. Frequency-independent counts are load-bearing:

Metric v0.1.0 v0.2.2
Allocations / order 4.094 2.670 (-34.8%)
Cycles / order 310.7 289.5 (-6.8%)
Instructions / order 1215 1157
Branch-miss rate 2.01% 1.68%
p50 / p99 latency 83 / 209 ns 83 / 209 ns

Cache-miss rate stays unavailable (Apple Silicon PMU, #90).

Docs

  • Every em dash and en dash removed repo-wide (66 files: CLAUDE.md, AGENTS.md, MILESTONES.md, PROGRESS.md, HANDOFF.md, all docs, CHANGELOG, source comments). 0 remain.
  • Mermaid diagrams added to 7 docs that lacked them (matching rules, binary protocol, persistence, ocaml verifier, concurrency, memory ordering, socket gateway accept loop).
  • README perf table refreshed; nic/dpdk provenance regenerated.

Verification

make check / make asan 272/272; CodeScene clean; all flamegraphs 0 [unknown]; 0 em/en dashes repo-wide; determinism unaffected (no engine logic changed).

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Added a separate performance-evidence benchmark mode for counting allocations.
    • Added clearer performance and release-readiness reporting, including updated hot-path metrics and test counts.
  • Bug Fixes

    • Improved benchmark input validation to reject invalid or extreme time/count values.
    • Made order and allocation reporting more accurate, including better handling of fully filled orders and corrected allocation counting.
    • Expanded server retry handling for additional transient connection errors.
  • Documentation

    • Refreshed project docs, templates, and release notes for consistency and readability.
    • Added clearer diagrams and explanations for matching, networking, replay, persistence, and performance workflows.

div0rce and others added 7 commits June 24, 2026 23:44
…r, perfeval, flamegraph)

Six real findings CodeRabbit flagged on merged PRs and we had not actioned:

- qsl-bench profile_seconds_from_args (#135): !(seconds > 0.0) does not reject
  inf/nan from strtod, and converting a non-finite/unbounded double to
  clock_type::duration is UB. Now requires std::isfinite and clamps to 3600s.
- tcp_server transient_accept_errno (#140): omitted ENOPROTOOPT and EOPNOTSUPP,
  which Linux accept(2) returns as already-pending per-connection errors and the
  epoll path already retries. They were wrongly fatal in the threaded acceptor;
  the set now matches is_transient_accept_error().
- qsl-perfeval ring (#148): submit() ringed every id, but marketable orders that
  fully fill never rest, so retire cancelled non-existent ids and book depth
  drifted with match rate. track() now checks eng.contains and rings only resting
  orders, holding the book genuinely ~kRing deep.
- qsl-perfeval p99 (#148): (n*99)/100 selected the max for small n; now uses the
  zero-based ((n-1)*99)/100 (and p50 likewise).
- qsl-perfeval parse_orders (#148): std::strtoull accepted "123abc"/"-1" (wraps to
  a huge count feeding reserve()/the loop). Now std::from_chars validates the whole
  token and rejects malformed input with a usage error + exit 2 (test added).
- flamegraph.py [unknown] folding (#135): rewritten with a precise, identified
  rationale. The [unknown] frames are fp-unwinding artifacts (glibc 2.43 malloc
  fast paths do not preserve x29 -> a spurious frame between resolved operator-new
  and _mid_memalign/_int_malloc/cfree; plus the vDSO clock_gettime leaf). Each is
  folded into its resolved caller so every rendered frame is a real symbol and the
  true operator-new -> malloc chain is revealed. DWARF was verified worse (mangles
  the _start asm entry into ~3 unknowns/stack).

make check/asan 272/272; CodeScene clean. Perf evidence (PERFORMANCE.md, flamegraphs)
regenerated with the fixed harness in a follow-up commit.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…megraphs

Re-measured PERFORMANCE.md after the qsl-perfeval ring fix (track only resting
orders) on the same host, back-to-back before/after:
  throughput   9.25M -> 10.76M orders/sec  (+16.3%)
  cycles/order 345.7 -> 297.3              (-14.0%)
  instr/order  1246  -> 1144               (-8.2%); IPC 3.60 -> 3.85
  branch-miss  1.86% -> 1.69%
  allocs/order 1.108 -> 1.108              (unchanged)
  p50/p99      ~83 / ~208 ns both          (latency distribution unchanged)
  cache-miss   unavailable (Apple Silicon PMU; #90)

Honesty corrections from the counters: the win is throughput + cycles/order, not
the new_limit latency tail (the earlier 250->208 p99 was thermal warm-up; steady
state is ~208 both). Allocations are unchanged (libstdc++ map::emplace checks
before allocating). New section identifies every [unknown] frame (fp glibc-malloc
boundary artifact + vDSO clock_gettime leaf) and documents that DWARF is worse;
all flamegraphs now render with ZERO [unknown] and the libc malloc internals
resolved. results/flamegraph.svg regenerated (0 unknown, Dirty inputs: no).
PERFORMANCE.md and perf-stat.txt are em-dash-free.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…numbers

Removed every em dash (U+2014) and en dash (U+2013) from all 66 tracked text
files (CLAUDE.md, AGENTS.md, MILESTONES.md, PROGRESS.md, HANDOFF.md, every doc,
CHANGELOG, source-comment prose, scripts, tests), replacing with readable ASCII
punctuation (comma / colon / period / hyphen by context). 0 em/en dashes remain
repo-wide (ocaml/test/fixtures verified clean already). Source changes are
comment-only; build + check stays 272/272.

Refreshed the README "numbers" block, which still carried the pre-remeasurement
figures, to match the corrected PERFORMANCE.md (fixed qsl-perfeval harness):
throughput 9.25M -> 10.76M (+16%), cycles/order 345.7 -> 297.3 (-14%), IPC
3.60 -> 3.85, branch-miss 1.86% -> 1.69%, allocs unchanged. Dropped the
misleading p99 row (the latency distribution is unchanged; the win is throughput
and cycles/order). Tests badge and quality table 271 -> 272.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The performance evidence now compares the FIRST RELEASE (v0.1.0) to current, the
cumulative engine change, instead of just the two most recent micro-opts. The
v0.1.0 column was produced by porting the same qsl-perfeval harness into a git
worktree at the v0.1.0 tag (identical MatchingEngine API) and running the same
release preset back-to-back on the same host.

Cumulative (v0.1.0 -> v0.2.2, baseline storage):
  allocations/order  4.094 -> 1.108   (-73.0%)   <- dominant cumulative win
  branch-miss rate   2.05% -> 1.69%   (-17.5% relative)
  throughput        10.54M -> 10.99M  (+4.3%)
  cycles/order       304.5 -> 290.7   (-4.5%); IPC 3.84 -> 3.94
  p50/p99 latency   ~83/~209 -> ~83/~208 ns (unchanged)
  cache-miss        unavailable (Apple Silicon PMU; #90)

Honest mechanism: the big change since v0.1.0 is allocation traffic (the
storage/PMR work), cut 73% even on the default baseline path; throughput/cycles
move modestly because the baseline hot path is bound by the ordered-map and
intrusive-list ops, not allocation count. The two recent micro-opts (try_emplace,
load-factor 0.25) are kept as a labeled v0.2.2 sub-analysis with their perf-report
evidence. before.svg is now the v0.1.0 flamegraph, after.svg v0.2.2; both render
with ZERO [unknown] and the libc malloc internals resolved. README and perf-stat.txt
updated to the v0.1.0 baseline; all em-dash-free.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Visual diagrams (all em-dash-free, all special-char labels quoted):
- matching_rules: order matching decision flow (limit/market, cross/rest, IOC)
- binary_protocol: frame decode + reject pipeline
- persistence: append -> app buffer -> page cache -> disk durability layers
- ocaml_verifier: C++ vs OCaml differential + shrink pipeline
- concurrency_model: SPSC pipeline (input -> engine -> publisher) with backpressure
- memory_ordering: producer/consumer happens-before (release synchronizes-with acquire)
- socket_gateway: TcpServer accept loop (transient retry, fd-exhaustion backoff, cap shedding)

Docs that already had mermaid (architecture, differential_testing, replay_and_recovery,
property_testing, benchmarking, README) are unchanged.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
… to -35%

Adversarial self-review found a measurement bug in the allocation counter: the
global operator-new override only intercepted operator new(size_t) and the array
form, missing operator new(size_t, align_val_t). v0.2.2's storage makes ~1.56
OVER-ALIGNED allocations/order (v0.1.0 makes none), so they were uncounted and
allocs/order was reported as 1.108 when the true figure is 2.670. The headline
"-73% allocations since v0.1.0" was therefore wrong; the real cut is -34.8%.

Fixes:
- Override every operator new/delete variant (plain + aligned) so the count is
  complete. The aligned override adds a little work per allocation, which would
  perturb cycle/throughput numbers, so allocation counting is now compile-time
  opt-in (QSL_PERFEVAL_COUNT_ALLOCS) behind a second CMake target,
  qsl-perfeval-allocs. The default qsl-perfeval leaves the allocator untouched
  (pure performance) and prints allocs_per_order=n/a.
- Re-measured both versions cleanly: performance from qsl-perfeval (no
  instrumentation), allocations from qsl-perfeval-allocs. Frequency-independent
  counts are the load-bearing metrics (wall-clock throughput is schedutil-noisy).

Corrected cumulative v0.1.0 -> v0.2.2 (baseline storage):
  allocations/order  4.094 -> 2.670   (-34.8%)
  cycles/order       310.7 -> 289.5   (-6.8%)
  instructions/order 1215  -> 1157    (-4.7%); IPC 3.91 -> 4.00
  branch-miss rate   2.01% -> 1.68%   (-16.3% relative)
  p50/p99 latency    83/209 ns both   (unchanged)
  cache-miss         unavailable (Apple Silicon PMU; #90)

PERFORMANCE.md, perf-stat.txt, README updated and document the earlier mistake
openly. make check/asan 272/272; CodeScene clean; all em-dash-free.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
dpdk_environment.txt and nic_offload_environment.txt carry several docs
(CLAUDE.md, AGENTS.md, MILESTONES.md, results/README.md) in their digest scope;
regenerated so they stay Dirty inputs: no after the em-dash purge and edits.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.
To continue using code reviews, you can upgrade your account or add credits to your account and enable them for code reviews in your settings.

@coderabbitai

coderabbitai Bot commented Jun 25, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@div0rce, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 41 minutes and 6 seconds. Learn how PR review limits work.

Your organization has used up its prepaid credits, and credit purchases are no longer available. Enable the review add-on in the billing tab to keep reviews running — you're only billed for reviews past your plan's rate limits ($0.25/file).

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based credits.

🚦 How do rate limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 0a9a4f2f-5150-4815-93f4-06860e4dae82

📥 Commits

Reviewing files that changed from the base of the PR and between 88b278a and 8e5bad4.

📒 Files selected for processing (5)
  • apps/qsl-perfeval/main.cpp
  • docs/concurrency_model.md
  • docs/fix_protocol.md
  • docs/persistence.md
  • docs/release_readiness.md
📝 Walkthrough

Walkthrough

The PR updates the benchmark harness and validation paths, refreshes performance evidence and generated result files, and reformats repository roadmap, policy, and technical documentation across Markdown, comments, and helper scripts.

Changes

Runtime and validation

Layer / File(s) Summary
Allocation-counting harness
CMakeLists.txt, apps/qsl-perfeval/main.cpp
qsl-perfeval adds compile-time allocation counting, aligned allocation overrides, resting-order tracking, and conditional allocs_per_order output.
Benchmark input validation
apps/qsl-bench/main.cpp, tests/CMakeLists.txt
qsl-bench now rejects non-finite durations and malformed count tokens, and the CTest file checks the invalid-count usage path.
Gateway transient accept errors
src/gateway/tcp_server.cpp, include/qsl/gateway/tcp_server.hpp, src/gateway/epoll_server.cpp
TcpServer treats ENOPROTOOPT and EOPNOTSUPP as transient accept errors, with matching comment updates in the gateway files.

Performance evidence and artifacts

Layer / File(s) Summary
Benchmark methodology and analysis
PERFORMANCE.md, docs/perf_analysis.md, docs/performance/perf-stat.txt, docs/benchmarking.md, docs/linux_performance.md, docs/socket_profiling.md, docs/allocator_experiment.md
The benchmark and profiling docs switch to allocation-, cycle-, instruction-, IPC-, and branch-miss-focused reporting and update the measurement setup.
Published summaries and artifact outputs
README.md, docs/release_readiness.md, results/README.md, results/*.txt, scripts/flamegraph.*, tests/shell/test_flamegraph.sh
The README, release-readiness notes, generated result files, flamegraph helpers, and flamegraph test reflect the updated benchmark outputs and metadata.

Repository guidance and lifecycle docs

Layer / File(s) Summary
Templates and review guidance
.github/ISSUE_TEMPLATE/review_request.md, .github/pull_request_template.md, .gitignore, CONTRIBUTING.md, SECURITY.md, docs/review_feedback.md, docs/review_request.md
The issue, PR, contribution, security, and review-feedback templates reflow punctuation and placeholder wording.
AGENTS and CLAUDE memory files
AGENTS.md, CLAUDE.md
The repo memory docs rewrap command lists, MCP/server notes, internship addenda, and roadmap phrasing.
HANDOFF state and addenda
HANDOFF.md
The handoff file updates the project-memory file list, current status, next milestone, and the additive internship section.
Milestone roadmap
MILESTONES.md
Milestone headings are normalized and the roadmap adds the inserted phase blocks and M14–M49 items.
Progress, changelog, and recruiting notes
PROGRESS.md, CHANGELOG.md, docs/recruiting_notes.md
The live-state log, changelog, and recruiting notes reformat milestone references, release history, and resume-facing wording.

Technical docs and commentary

Layer / File(s) Summary
Core architecture and concurrency docs
docs/architecture.md, docs/concurrency_model.md, docs/matching_rules.md, docs/memory_ordering.md, docs/binary_protocol.md, docs/persistence.md
The architecture, concurrency, matching, memory-ordering, binary-protocol, and persistence docs add diagrams and reflow the documented flows and invariants.
Socket, verifier, replay, and ADR docs
docs/socket_gateway.md, docs/socket_hardening.md, docs/fix_protocol.md, docs/invariants.md, docs/ocaml_verifier.md, docs/differential_testing.md, docs/property_testing.md, docs/replay_and_recovery.md, docs/adr/*
The socket, FIX, invariant, OCaml verifier, differential-testing, replay, property-testing, and ADR pages rewrap prose and update the documented behaviors.
Inline comments, tests, and helper scripts
include/qsl/concurrency/..., include/qsl/feed/..., include/qsl/protocol/..., src/engine/..., src/replay/fixture.cpp, ocaml/..., tests/concurrency/..., tests/unit/..., cmake/Sanitizers.cmake, data/synthetic/README.md, regressions/README.md, scripts/determinism_check.sh, scripts/divergence_demo.sh
Header comments, source comments, OCaml comments, tests, and helper scripts rephrase comment text without executable behavior changes.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Suggested reviewers

  • codescene-delta-analysis

Poem

Hoppity-hop, the counters gleam,
My whiskers twitch at every stream.
The docs are neat, the paths are яс... uh, spry,
I bounce through benches under moonlit sky. 🐰
v0.2.2 goes thump-thump-clad in cheer!

🚥 Pre-merge checks | ✅ 3 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Description check ⚠️ Warning The description only includes a summary and bullet list; it omits the required Milestone, Definition of Done, Tests, and Notes/decisions sections. Add the template sections: Milestone, 2-5 sentence Summary, Definition of Done checklist, Tests block, and Notes/decisions.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title matches the main changes: bug fixes, dash cleanup, Mermaid additions, and the perf baseline reset.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/coderabbit-review-comments

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

codescene-delta-analysis[bot]

This comment was marked as outdated.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
docs/recruiting_notes.md (2)

95-102: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Use the actual OCaml module path.

ocaml/lib/replay_engine.ml looks stale here; the roadmap and verifier layout in this PR point to ocaml/lib/replay.ml instead. Fixing the path avoids sending recruiters to a file that doesn’t exist.

Suggested fix
-  typed/immutable OCaml engine (`ocaml/lib/replay_engine.ml`) re-derives the final book state
+  typed/immutable OCaml engine (`ocaml/lib/replay.ml`) re-derives the final book state
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/recruiting_notes.md` around lines 95 - 102, The OCaml path referenced in
the recruiting notes is stale and should match the actual module used by the
verifier. Update the description in the relevant markdown section to point from
the old replay_engine symbol path to the current OCaml replay module path, and
make sure the surrounding explanation still refers to the independent replay
implementation and snapshot checks without mentioning the obsolete file name.

57-67: 📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick win

Reconcile these benchmark numbers with the canonical artifact.

These figures no longer match the repo’s canonical benchmark summary, so the résumé bullets and live-state docs will tell different stories. Please regenerate them from the same measured output before keeping them in a recruiting-facing file.

Suggested fix
-- matching-engine flow ~98 ns/command (~10.2M commands/sec)
-- order-book add/modify/cancel ~87 ns/op
-- protocol `NewOrder` encode+decode ~16 ns/op
-- gateway session crossing-fill round-trip ~110 ns/op
-- replay from command log ~110 ns/command
+- matching-engine flow ~91 ns/command
+- order-book add/modify/cancel ~90 ns/op
+- protocol `NewOrder` encode+decode ~16 ns/op
+- gateway session crossing-fill round-trip ~102 ns/op
+- replay from command log ~101 ns/command
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/recruiting_notes.md` around lines 57 - 67, The benchmark bullets are out
of sync with the canonical artifact, so update the recruiting note to match the
repo’s current measured summary. Regenerate the figures from the same source
used by the canonical benchmark output (the `results/latest.txt`-backed summary)
and replace the existing measurements in the benchmark section so the
recruiting-facing doc and live benchmark state stay consistent. Reference the
benchmark section in `docs/recruiting_notes.md` and the measured output source
when updating the listed numbers.
🧹 Nitpick comments (1)
tests/CMakeLists.txt (1)

117-126: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Smoke-test qsl-perfeval-allocs as well.

This PR’s new behavior is behind QSL_PERFEVAL_COUNT_ALLOCS, but make check still exercises only qsl-perfeval. A tiny qsl-perfeval-allocs run that asserts allocs_per_order is numeric would catch wiring regressions between CMakeLists.txt and apps/qsl-perfeval/main.cpp.

Suggested addition
 add_test(NAME qsl_perfeval_smoke COMMAND qsl-perfeval 5000 --latency)
 set_tests_properties(qsl_perfeval_smoke PROPERTIES PASS_REGULAR_EXPRESSION
                      "perfeval: latency_ns")
 
 # Malformed order counts must be rejected, not truncated or wrapped.
 add_test(NAME qsl_perfeval_invalid_count_fails
          COMMAND ${CMAKE_COMMAND} -D "PROGRAM=$<TARGET_FILE:qsl-perfeval>" -D "ARGS=123abc" -D
                  "EXPECT_OUTPUT=usage:" -P
                  "${CMAKE_CURRENT_LIST_DIR}/cmake/expect_command_failure.cmake")
+
+add_test(NAME qsl_perfeval_allocs_smoke COMMAND qsl-perfeval-allocs 5000)
+set_tests_properties(qsl_perfeval_allocs_smoke PROPERTIES PASS_REGULAR_EXPRESSION
+                     "allocs_per_order=[0-9]")

Based on learnings, "Write tests beside deterministic logic."

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/CMakeLists.txt` around lines 117 - 126, Add a smoke test for the
qsl-perfeval-allocs binary alongside qsl_perfeval_smoke in the CMake test list
so make check covers the QSL_PERFEVAL_COUNT_ALLOCS path exercised by
apps/qsl-perfeval/main.cpp. Reuse the existing qsl-perfeval pattern with a tiny
run and a PASS_REGULAR_EXPRESSION that verifies allocs_per_order is reported as
numeric, so wiring regressions between CMakeLists.txt and the main app are
caught.

Source: Learnings

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@apps/qsl-perfeval/main.cpp`:
- Around line 283-296: The argument parsing in main currently accepts multiple
order-count values and lets the last one win, which conflicts with the single
optional [orders>0] usage. Update the loop that handles argv parsing so that
after parse_orders_arg succeeds and orders is already set, the program rejects
any additional non-flag order-count arguments with the same usage/error path
instead of overwriting the existing value. Keep the --latency handling intact
and use the existing orders variable in main to detect duplicates.

In `@docs/concurrency_model.md`:
- Around line 191-195: The ownership matrix table has a malformed Input row
caused by an extra cell boundary fragment, so fix the markdown in the table
around the Input/Engine/Publisher rows to restore valid column alignment and
readable rendering. Update the table structure in the concurrency model docs so
the Input row cleanly maps to its Thread owns exclusively, Consumes, and
Produces cells without the stray separator, keeping the rest of the table
consistent.

In `@docs/persistence.md`:
- Around line 17-25: The Mermaid diagram currently labels the final disk node in
a way that implies an absolute guarantee; update the wording in the persistence
diagram to reflect the best-effort durability contract described later in the
document. Adjust the label on the `disk` node in the `EventLogWriter::append`
flowchart so it no longer says “Durable, survives power loss,” and use softer
language consistent with the `fsync`/`F_FULLFSYNC` discussion.

In `@docs/release_readiness.md`:
- Around line 80-101: The release readiness paragraph has a markdown formatting
issue where the `#32` reference is left at the start of a wrapped line, which
can be read as a heading token. Update the `Outcome` text in
`release_readiness.md` so the `#32` reference stays inline with the surrounding
sentence, either by reflowing the sentence or moving the reference onto the
previous line while preserving the same meaning.

---

Outside diff comments:
In `@docs/recruiting_notes.md`:
- Around line 95-102: The OCaml path referenced in the recruiting notes is stale
and should match the actual module used by the verifier. Update the description
in the relevant markdown section to point from the old replay_engine symbol path
to the current OCaml replay module path, and make sure the surrounding
explanation still refers to the independent replay implementation and snapshot
checks without mentioning the obsolete file name.
- Around line 57-67: The benchmark bullets are out of sync with the canonical
artifact, so update the recruiting note to match the repo’s current measured
summary. Regenerate the figures from the same source used by the canonical
benchmark output (the `results/latest.txt`-backed summary) and replace the
existing measurements in the benchmark section so the recruiting-facing doc and
live benchmark state stay consistent. Reference the benchmark section in
`docs/recruiting_notes.md` and the measured output source when updating the
listed numbers.

---

Nitpick comments:
In `@tests/CMakeLists.txt`:
- Around line 117-126: Add a smoke test for the qsl-perfeval-allocs binary
alongside qsl_perfeval_smoke in the CMake test list so make check covers the
QSL_PERFEVAL_COUNT_ALLOCS path exercised by apps/qsl-perfeval/main.cpp. Reuse
the existing qsl-perfeval pattern with a tiny run and a PASS_REGULAR_EXPRESSION
that verifies allocs_per_order is reported as numeric, so wiring regressions
between CMakeLists.txt and the main app are caught.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: c6effbdd-93f8-4c5f-b597-2cee234200f8

📥 Commits

Reviewing files that changed from the base of the PR and between da35fef and 88b278a.

⛔ Files ignored due to path filters (3)
  • docs/performance/after.svg is excluded by !**/*.svg
  • docs/performance/before.svg is excluded by !**/*.svg
  • results/flamegraph.svg is excluded by !**/*.svg
📒 Files selected for processing (76)
  • .github/ISSUE_TEMPLATE/review_request.md
  • .github/pull_request_template.md
  • .gitignore
  • AGENTS.md
  • CHANGELOG.md
  • CLAUDE.md
  • CMakeLists.txt
  • CONTRIBUTING.md
  • HANDOFF.md
  • MILESTONES.md
  • PERFORMANCE.md
  • PROGRESS.md
  • README.md
  • SECURITY.md
  • apps/qsl-bench/main.cpp
  • apps/qsl-perfeval/main.cpp
  • cmake/Sanitizers.cmake
  • data/synthetic/README.md
  • docs/adr/0002-independent-ocaml-oracle.md
  • docs/adr/0003-golden-fixture-regeneration.md
  • docs/adr/0004-deterministic-shrinker.md
  • docs/adr/0007-constrained-perf-artifacts-are-partial-evidence.md
  • docs/adr/0008-socket-evidence-loopback-constrained-epoll-deferred.md
  • docs/adr/0011-event-log-durability-modes-and-tail-repair.md
  • docs/allocator_experiment.md
  • docs/architecture.md
  • docs/benchmarking.md
  • docs/binary_protocol.md
  • docs/concurrency_model.md
  • docs/differential_testing.md
  • docs/fix_protocol.md
  • docs/invariants.md
  • docs/linux_performance.md
  • docs/matching_rules.md
  • docs/memory_ordering.md
  • docs/ocaml_verifier.md
  • docs/perf_analysis.md
  • docs/performance/perf-stat.txt
  • docs/persistence.md
  • docs/property_testing.md
  • docs/recruiting_notes.md
  • docs/release_readiness.md
  • docs/replay_and_recovery.md
  • docs/review_feedback.md
  • docs/review_request.md
  • docs/socket_gateway.md
  • docs/socket_hardening.md
  • docs/socket_profiling.md
  • include/qsl/concurrency/pipeline.hpp
  • include/qsl/concurrency/spsc_ring.hpp
  • include/qsl/feed/sequence_tracker.hpp
  • include/qsl/feed/udp_feed.hpp
  • include/qsl/gateway/tcp_server.hpp
  • include/qsl/protocol/endian.hpp
  • include/qsl/protocol/fix.hpp
  • ocaml/lib/diff_report.ml
  • ocaml/test/test_mutation.ml
  • regressions/README.md
  • results/README.md
  • results/dpdk_environment.txt
  • results/flamegraph.txt
  • results/nic_offload_environment.txt
  • scripts/determinism_check.sh
  • scripts/divergence_demo.sh
  • scripts/flamegraph.py
  • scripts/flamegraph.sh
  • src/engine/contiguous_store.hpp
  • src/engine/order_book.cpp
  • src/gateway/epoll_server.cpp
  • src/gateway/tcp_server.cpp
  • src/replay/fixture.cpp
  • tests/CMakeLists.txt
  • tests/concurrency/test_pipeline.cpp
  • tests/shell/test_flamegraph.sh
  • tests/unit/test_fix_protocol.cpp
  • tests/unit/test_shrink.cpp

Comment thread apps/qsl-perfeval/main.cpp
Comment thread docs/concurrency_model.md
Comment thread docs/persistence.md
Comment thread docs/release_readiness.md
…e broke)

CodeRabbit flagged four issues on #150; all real, all fixed:
- qsl-perfeval: `qsl-perfeval 1000 2000` silently ran with 2000. Reject a second
  order count as ambiguous. Extracted parse_args() so main stays under the
  cyclomatic-complexity threshold (CodeScene).
- concurrency_model.md + fix_protocol.md: the em-dash purge turned an em-dash
  table cell into ", ", producing a malformed `|, |` row. Restored the cells
  ("nothing" consumed / "(none)" internal field). Repo-wide scan confirms these
  were the only two corrupted table cells.
- persistence.md: the new durability mermaid node said "Durable, survives power
  loss", overclaiming vs the doc's best-effort fsync contract. Softened.
- release_readiness.md: a wrapped line started with "#32" (markdownlint heading
  false-positive); kept the reference inline.

make check 272/272; CodeScene clean; 0 em/en dashes repo-wide.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

@codescene-delta-analysis codescene-delta-analysis Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Our agent can fix these. Install it.

Gates Passed
6 Quality Gates Passed

Absence of Expected Change Pattern

  • quant-systems-lab/src/replay/fixture.cpp is usually changed with: quant-systems-lab/apps/qsl-export-stream/main.cpp

Quality Gate Profile: Pay Down Tech Debt
Install CodeScene MCP: safeguard and uplift AI-generated code. Catch issues early with our IDE extension and CLI tool.

@div0rce div0rce merged commit afe3f20 into main Jun 25, 2026
8 checks passed
@div0rce div0rce deleted the fix/coderabbit-review-comments branch June 25, 2026 04:39
div0rce added a commit that referenced this pull request Jun 25, 2026
* chore(release): cut v0.2.2

Finalize the v0.2.2 changelog entry to include this session's documentation
overhaul (#147), performance-evidence report (#148), README rebuild (#149), and
the bug/style/mermaid sweep (#150) on top of the post-v0.2.1 hardening + perf
wave (#135-#146). Fix the test count (272/272) and flip the v0.2.2 resume/release
anchors (PROGRESS.md, release_readiness.md) from "in preparation" to released.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* docs: reconcile test count to 272/272 across release records (CodeRabbit)

CodeRabbit flagged docs/release_readiness.md still showing 270/270 while
CHANGELOG/PROGRESS said 272/272. The two perfeval tests added this session took
the count 270 -> 272, so the current-state and verification claims were stale.
Updated all current-state references (release_readiness verification table,
PROGRESS.md status + both summary blocks, the CLAUDE.md/AGENTS.md roadmap memory
kept in sync, HANDOFF.md), and flipped the v0.2.2 "being cut / next action"
phrasing to released. The one remaining 270/270 is a dated entry under
PROGRESS.md "Decision log additions" (a correct historical snapshot). All
em-dash-free.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 <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