Skip to content

docs: resolve Codex resume-anchor + PMU findings from PRs #127/#128#129

Merged
div0rce merged 3 commits into
mainfrom
docs/codex-resume-anchor-sync
Jun 22, 2026
Merged

docs: resolve Codex resume-anchor + PMU findings from PRs #127/#128#129
div0rce merged 3 commits into
mainfrom
docs/codex-resume-anchor-sync

Conversation

@div0rce

@div0rce div0rce commented Jun 21, 2026

Copy link
Copy Markdown
Owner

Summary

Resolves the Codex review findings that were left unaddressed on main by the two latest PRs (#127 v0.2.0 release, #128 resume-anchor sync). Both Codex reviews flagged that /resume-critical files still pointed at the merged PR #125 branch and still carried pre-v0.2.0 "constrained Docker" evidence wording, plus one overstated PMU claim. This PR makes those files internally consistent with the released v0.2.0 state.

Docs/memory only — no code or benchmark artifacts changed.

Codex findings addressed

  1. Stale /resume next-action (Codex on docs: sync resume anchors to the v0.2.0 released state #128, PROGRESS.md). Removed the ## Next action remains block that still said the current action was PR Refresh Linux host artifacts #125 on perf/linux-host-artifact-refresh (merged as d9094df). Replaced with the v0.2.0 between-releases state: no active milestone; highest-value work is gated on External technical review request #94 (external review) and M29 follow-up: full cache-counter PMU evidence (bare-metal Apple PMU now partial; cache events unsupported) #90 (full cache-PMU evidence).
  2. AGENTS.md out of sync with CLAUDE.md (Codex on release: v0.2.0 — bare-metal evidence refresh, partial-PMU reframe, and staleness sweep #127 and docs: sync resume anchors to the v0.2.0 released state #128). AGENTS.md still described the perf artifacts as "constrained Docker validation only" and still referenced the active perf/linux-host-artifact-refresh follow-up. Brought the constraints bullet, the "correct claim" block, and the "M29 perf evidence status" subsection into agreement with CLAUDE.md's v0.2.0 partial-PMU reframe. The stale follow-up line is updated in both AGENTS.md and CLAUDE.md.
  3. Overstated Blizzard PMU claim (Codex on release: v0.2.0 — bare-metal evidence refresh, partial-PMU reframe, and staleness sweep #127, docs/perf_analysis.md). The doc said the Avalanche and Blizzard PMUs report live counts, but results/perf_stat_linux.txt shows every apple_blizzard_pmu/... row as <not counted>. Narrowed the claim: the single-threaded benchmark is scheduled on the Avalanche P-cores, so only those counters carry counts; the E-core rows read <not counted> because the workload never ran there — expected scheduling, not a missing counter.

Verification

  • AGENTS.mdCLAUDE.md now agree on perf-evidence wording, the released state, and the non-overclaiming rules (per the project's mirror requirement).
  • Swept the repo: no remaining active claims label the current artifacts as "constrained Docker"; remaining Docker mentions are correct history (CHANGELOG, ADR-0007, decision log, unsupported-host examples).
  • No .cpp/.hpp/build/script changes, so make check is unaffected.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Documentation
    • Updated performance monitoring guidance to clarify that Linux perf results on bare-metal Apple M2 provide partial hardware PMU evidence (real core counters present, cache counters missing).
    • Expanded explanations for how the counters map to CPU scheduling behavior, and noted when “not counted” rows appear.
    • Refreshed project evidence/status and roadmap messaging to reflect recent milestone progress, while reiterating that remaining work is gated on external review and completion of full cache-PMU evidence.

…ollow-up)

Resolve the Codex review findings left on `main` by PRs #127 and #128:

- PROGRESS.md: remove the stale "Next action remains" block that still steered
  /resume to the merged PR #125 on `perf/linux-host-artifact-refresh`; replace
  with the v0.2.0 between-releases state (no active milestone; #94/#90 gated).
- AGENTS.md: bring it into sync with CLAUDE.md's v0.2.0 partial-PMU reframe. The
  constraints bullet, the "correct claim" block, and the "M29 perf evidence
  status" subsection no longer label the artifacts "constrained Docker
  validation"; the stale `perf/linux-host-artifact-refresh` follow-up line is
  updated (also in CLAUDE.md) to the released state.
- docs/perf_analysis.md: narrow the PMU claim so it no longer implies the Apple
  Blizzard (E-core) PMU carries live counts. The `apple_blizzard_pmu/...` rows
  read `<not counted>` in results/perf_stat_linux.txt because the single-threaded
  benchmark stays on the Avalanche P-cores — expected scheduling, not a counter.

Docs/memory only; no code or artifacts changed.

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

coderabbitai Bot commented Jun 21, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: c909b34c-6f3b-4eeb-8b7f-091de0c22c39

📥 Commits

Reviewing files that changed from the base of the PR and between dfa4da2 and 4a2aa67.

📒 Files selected for processing (2)
  • AGENTS.md
  • CLAUDE.md
🚧 Files skipped from review as they are similar to previous changes (1)
  • AGENTS.md

📝 Walkthrough

Walkthrough

Documentation-only sync across four files (AGENTS.md, CLAUDE.md, PROGRESS.md, docs/perf_analysis.md) to replace prior "constrained-environment" perf evidence language with "bare-metal partial hardware PMU evidence" from an Apple M2 Fedora Asahi host, document that cache counters are absent (issue #90), and update roadmap/milestone state through the v0.2.0 release.

Changes

Partial PMU Evidence Documentation Sync

Layer / File(s) Summary
perf_analysis.md evidence classification detail
docs/perf_analysis.md
Expands the Current Status paragraph with explicit host virtualization signals (systemd-detect-virt = none, no hypervisor CPU flag), per-PMU counter scheduling (Avalanche P-core vs. Blizzard E-core), and why Blizzard rows show <not counted>; preserves the partial hardware PMU evidence label.
AGENTS.md partial-PMU reframe (four sections)
AGENTS.md
Updates Known Constraints, Phase III/IV roadmap, M29 perf evidence status definition, and post-M35 roadmap memory block; all change from constrained/full-PMU wording to bare-metal partial-PMU language, forbid relabeling artifacts as full PMU evidence, and pin remaining gates to issues #90 and #94.
CLAUDE.md and PROGRESS.md state and decision-log updates
CLAUDE.md, PROGRESS.md
CLAUDE.md expands the post-M49 status block with resolved issue references, PR #125/#127/#128 milestones, and a no-active-milestone declaration. PROGRESS.md updates the Current State docs-sync bullet, adds a dated [2026-06-21] decision-log entry listing the three specific doc corrections made, and rewrites the Next Action Remains section with partial-PMU clarifications and explicit no-relabeling and no-automation-action instructions.

Estimated code review effort

🎯 1 (Trivial) | ⏱️ ~5 minutes

Possibly related issues

  • #90: Documentation updates directly address the acceptance criteria to distinguish partial PMU evidence artifacts from full cache-counter evidence, explicitly referencing #90 as the remaining work while detailing bare-metal Apple M2 partial-PMU validation on Fedora Asahi with Avalanche/Blizzard core specifics.

Possibly related PRs

  • div0rce/quant-systems-lab#113: Both PRs update the same roadmap/evidence documentation in AGENTS.md and CLAUDE.md, specifically the "current post-M35 roadmap memory" narrative framing Issue #90 / PMU evidence debt and evidence gaps.
  • div0rce/quant-systems-lab#127: Further refines the same "partial vs. full PMU evidence" documentation claims in docs/perf_analysis.md, AGENTS.md, CLAUDE.md, and PROGRESS.md that were introduced by the v0.2.0 work referenced in this PR.

Suggested reviewers

  • codescene-delta-analysis

Poem

🐇 Hoppity-hop through the docs I go,
Partial PMU counters — now the world shall know!
Blizzard says <not counted>, Avalanche rings true,
Cache misses still missing — issue #90 in queue.
No active milestone, just memory kept neat,
A docs-only bunny with tidy, careful feet. 🥕

🚥 Pre-merge checks | ✅ 3 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Description check ⚠️ Warning The description is detailed and complete, covering summary, findings addressed, and verification. However, it does not follow the required template structure with Milestone, Definition of Done, Tests, or Notes sections. Restructure the description to match the template: add Milestone section, create Definition of Done checklist, include Tests section with commands run, and move verification items to Notes/decisions.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title directly matches the PR's primary objective: resolving Codex review findings from PRs #127 and #128 through documentation updates.
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 docs/codex-resume-anchor-sync

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 and usage tips.

codescene-delta-analysis[bot]

This comment was marked as outdated.

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 587778dd84

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread PROGRESS.md
supersedes CodeRabbit's PR #126, whose generated tests covered only trimming and were based on
`d8c16b2` (where `qsl_publish_artifact` does not yet exist, so #126 could not merge before #125);
#126 was closed as superseded. Do not merge from automation; the human squash-merges PR #125.
- [2026-06-21] Codex-followup resume-anchor sync (`docs/codex-resume-anchor-sync`). Resolved the

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Refresh current state for this follow-up

When /resume reads PROGRESS.md, it starts with the ## Current state bullets, which still list the v0.2.0 release / PR #127 as the last action and docs sync. Recording this follow-up only down in the decision log means the next agent can miss that this resume-anchor/PMU sync already happened or duplicate it; update the top current-state bullets alongside this new entry.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

Addressed in dfa4da2: the top ## Current state bullets now record this resume-anchor/PMU sync as the "Last action" and "Last completed docs sync", with the v0.2.0 release demoted to a "Prior action" bullet — so /resume no longer reads PR #127 as the latest action.

The decision-log entry and bottom "Next action remains" block already
covered this follow-up, but the top `## Current state` bullets — the first
thing `/resume` reads — still presented the v0.2.0 release (PR #127) as the
"Last action". A resuming agent could therefore miss that this resume-anchor
/ PMU sync already happened and duplicate it.

Record the sync as the current "Last action" and "Last completed docs sync",
demoting the v0.2.0 release detail to a "Prior action" bullet. Docs-only.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
codescene-delta-analysis[bot]

This comment was marked as outdated.

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: dfa4da28d3

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread AGENTS.md Outdated
- The gateway and feed are loopback-only, unauthenticated simulator surfaces.
- The core engine cannot depend on wall-clock time or floating-point prices.
- M29 perf artifacts are constrained-environment evidence until issue #90 is completed.
- Perf artifacts are now **partial hardware PMU evidence** from a bare-metal Apple M2 (aarch64)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Scope PMU claim to perf-stat only

This labels all perf artifacts as partial hardware PMU evidence, but the committed perf-record artifact is explicitly a software profile (results/perf_report_linux.txt has Artifact: software sampling hot-symbol profile and Record event: cpu-clock); only results/perf_stat_linux.txt carries the hardware counter rows. When future agents use AGENTS.md as the resume source for benchmark/recruiting docs, this plural wording can propagate a false PMU-evidence claim for the perf-record report, so scope the statement to the perf-stat artifact or call out perf-record separately.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

Fixed in 4a2aa67. The constraints bullet now scopes "partial hardware PMU evidence" to the perf stat artifact (results/perf_stat_linux.txt, real cycles/instructions/branches/branch-misses) and adds an explicit sentence that the perf record hot-symbol report (results/perf_report_linux.txt) is a software cpu-clock sampling profile, not PMU evidence. Applied identically to AGENTS.md and CLAUDE.md so the two memories stay in sync, and propagated up the #130/#131/#133 stack.

div0rce added a commit that referenced this pull request Jun 22, 2026
Propagate the #129/#130/#131 Codex fixes up the stack and resolve the v0.2.1
release-anchor Codex findings (#133):

- Reconcile the PROGRESS/HANDOFF backlog conflict to the release state: #29
  (FIX adapter) and #32 (flamegraph) are both done, shipped in v0.2.1; no open
  legacy backlog remains.
- Sync AGENTS.md and CLAUDE.md released-state anchors from v0.2.0 to v0.2.1,
  recording the #129/#130/#131 content (the canonical files a resume reads).
- Refresh docs/release_readiness.md for v0.2.1: 263/263 tests, the FIX-adapter
  and flamegraph coverage, the bare-metal flamegraph artifact, and the next
  release re-pointed to v0.2.1.
- Update the v0.2.1 current-state test count 261 -> 263 (the two new FIX
  rejection tests) and add a decision-log entry for this second Codex round.

make check / make asan 263/263 on the bare-metal Apple M2 Fedora Asahi host.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
… profile (Codex #129)

The constraints bullet labeled all perf artifacts as partial hardware PMU
evidence, but only results/perf_stat_linux.txt carries real PMU counters
(cycles/instructions/branches/branch-misses). results/perf_report_linux.txt
is a software cpu-clock sampling profile, not PMU evidence. Scope the claim
to the perf-stat artifact and call out perf-record separately, identically in
AGENTS.md and CLAUDE.md so the two memories stay in sync.

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.

No application code in the PR — skipped Code Health checks.

See analysis details in CodeScene

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 94fb544 into main Jun 22, 2026
8 checks passed
@div0rce div0rce deleted the docs/codex-resume-anchor-sync branch June 22, 2026 16:43
div0rce added a commit that referenced this pull request Jun 22, 2026
* docs: sync resume anchors and PMU claims to v0.2.0 (Codex #127/#128 follow-up)

Resolve the Codex review findings left on `main` by PRs #127 and #128:

- PROGRESS.md: remove the stale "Next action remains" block that still steered
  /resume to the merged PR #125 on `perf/linux-host-artifact-refresh`; replace
  with the v0.2.0 between-releases state (no active milestone; #94/#90 gated).
- AGENTS.md: bring it into sync with CLAUDE.md's v0.2.0 partial-PMU reframe. The
  constraints bullet, the "correct claim" block, and the "M29 perf evidence
  status" subsection no longer label the artifacts "constrained Docker
  validation"; the stale `perf/linux-host-artifact-refresh` follow-up line is
  updated (also in CLAUDE.md) to the released state.
- docs/perf_analysis.md: narrow the PMU claim so it no longer implies the Apple
  Blizzard (E-core) PMU carries live counts. The `apple_blizzard_pmu/...` rows
  read `<not counted>` in results/perf_stat_linux.txt because the single-threaded
  benchmark stays on the Avalanche P-cores — expected scheduling, not a counter.

Docs/memory only; no code or artifacts changed.

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

* perf: add flamegraph generator and make target (#32)

Add `make flamegraph`, the missing-flamegraph follow-up tracked by issue #32.
The perf stat/record text workflow already existed; this renders a perf
call-graph flamegraph.

- scripts/flamegraph.sh: records `perf record --call-graph dwarf -F 4000 -g -e
  cpu-clock` on qsl-bench and writes results/flamegraph.svg plus a
  results/flamegraph.txt provenance/classification companion (top folded
  stacks). Mirrors perf_record.sh: Linux-only, reuses qsl_common.sh provenance
  + qsl_publish_artifact, and honours QSL_PERF_ALLOW_PARTIAL for constrained
  hosts. DWARF call graphs unwind correctly despite the Release `bench` preset
  omitting frame pointers.
- scripts/flamegraph.py: dependency-free (stdlib-only) stackcollapse + SVG
  renderer, so the artifact is reproducible from the repo without vendoring the
  Perl FlameGraph toolkit. Deterministic: frames sorted by name, colors a pure
  function of the name, no RNG/timestamps in the drawn body.
- tests/shell/test_flamegraph.sh: CTest-registered (python3-only, skips cleanly
  if absent) — folding (offset/dso stripping, perf-order reversal, comm-at-base,
  count aggregation, sortedness), SVG well-formedness, XML escaping,
  determinism, empty-input handling.
- docs (perf_analysis.md, results/README.md), command lists (CLAUDE.md,
  AGENTS.md), MILESTONES.md backlog, PROGRESS.md log.

`make check` 242/242. Full hardware cache-PMU evidence stays in #90.

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

* perf: add generated flamegraph artifact on bare-metal Fedora Asahi (#32)

results/flamegraph.svg + results/flamegraph.txt generated by `make flamegraph`
from the clean committed tree on the bare-metal Apple M2 (aarch64) Fedora Asahi
host: 397 cpu-clock samples, 171 folded stacks, `Dirty inputs: no`. The hot
paths resolve to real engine symbols (OrderBook::modify/cancel/add_limit, the
dispatch_storage cancel path, decode_new_order, the gateway Session path,
replay::generate_flow). Software cpu-clock sampling hot-symbol profile — not a
latency/throughput claim; full hardware cache-PMU evidence stays in #90.

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

* perf: harden flamegraph collapsed-stack parsing (Codex review)

Address two Codex review findings in scripts/flamegraph.py::parse_collapsed:

- Prefer a tab separator when present so a tab-separated folded line whose stack
  contains spaces (C++ signatures) splits on the trailing count instead of an
  interior space and is silently dropped.
- Ignore non-positive sample counts, so hand-crafted --from-collapsed input with
  0/negative counts cannot render a misleading SVG (all-non-positive input now
  fails with exit 1 via the existing empty-folded guard).

Adds test coverage in tests/shell/test_flamegraph.sh (19/19).

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

* perf: regenerate flamegraph artifact after parser hardening

flamegraph.py is a provenance input, so regenerate results/flamegraph.svg +
.txt from the clean tree to keep the Source digest consistent (423 samples,
Dirty inputs: no).

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

* refactor: improve flamegraph.py code health (CodeScene gate)

CodeScene's delta gate scored scripts/flamegraph.py at 7.81 (render_svg: Large
Method + Excess Arguments + complexity; fold_perf_script: Bumpy Road / nested
complexity). Restructure without changing output:

- fold_perf_script: move per-line state into a small _Folder helper so the
  parsing loop is a flat if/elif/else instead of a nested block.
- render_svg: bundle styling knobs into a FlameOptions dataclass (2 args, was
  7) and extract _append_chrome, _frame_svg, _truncate; geometry constants
  (_SIDE/_PAD_TOP/_PAD_BOTTOM) hoisted to module scope and a _Canvas dataclass
  carries derived geometry.

Emitted SVG/collapsed bytes are unchanged; tests/shell/test_flamegraph.sh 19/19.

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

* perf: regenerate flamegraph artifact after code-health refactor

flamegraph.py is a provenance input; regenerate results/flamegraph.svg + .txt
from the clean tree (402 samples, Dirty inputs: no).

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

* refactor: flatten flamegraph.py remaining complexity (CodeScene)

Clear the last two CodeScene flags on scripts/flamegraph.py:

- _clean_symbol: replace the balanced-paren dso scan (a deep nested loop) with a
  flat regex _DSO_RE. perf prints a space before the "(dso)" and dso strings
  never contain parens, so a non-nested " (...)$" match is exact and won't strip
  a C++ signature's own parentheses.
- _layout: drop the unused `total` parameter (5 args -> 4).

Output unchanged; tests/shell/test_flamegraph.sh 19/19.

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

* perf: regenerate flamegraph artifact after complexity flattening

Provenance input changed; regenerate from clean tree (416 samples, Dirty
inputs: no).

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

* docs: record resume-anchor sync in PROGRESS current-state (Codex #129)

The decision-log entry and bottom "Next action remains" block already
covered this follow-up, but the top `## Current state` bullets — the first
thing `/resume` reads — still presented the v0.2.0 release (PR #127) as the
"Last action". A resuming agent could therefore miss that this resume-anchor
/ PMU sync already happened and duplicate it.

Record the sync as the current "Last action" and "Last completed docs sync",
demoting the v0.2.0 release detail to a "Prior action" bullet. Docs-only.

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

* perf: harden flamegraph.sh classification + sample gating (Codex #130)

Address five Codex review findings on the flamegraph driver:

1. Classify `zero-sized data` (perf script's no-sample report) as a perf
   limitation, matching scripts/perf_record.sh, so the documented
   QSL_PERF_ALLOW_PARTIAL=1 constrained-host path works instead of tripping
   the unexpected-failure exit.
2. Remove any prior results/flamegraph.svg when a partial run captures no
   folded stacks, so a constrained rerun cannot leave a previous host's SVG
   beside a .txt that says there is no sample report.
3. Accept perf's `(~N samples)` estimate marker (optional `~`), and base the
   minimum-sample gate on the authoritative folded sample total rather than
   perf record's self-described estimate. Report both counts.
4. Capture flamegraph.py --collapse-only's exit status instead of `|| true`;
   a renderer/parser failure now exits 4 (unmaskable) rather than being
   published as a constrained-environment artifact.
5. Derive the sampling-kind label/caveat from the selected event (software
   cpu-clock/task-clock vs hardware-PMU) so the artifact type, SVG comment,
   and text companion stay consistent for QSL_FLAMEGRAPH_EVENT=cycles etc.

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

* perf: regenerate flamegraph artifact after classification hardening

Bare-metal Apple M2 (aarch64) Fedora Asahi, cpu-clock @ 4000Hz: 329 folded
samples / 159 stacks, classified `flamegraph (software cpu-clock sampling
hot-symbol profile)`, `Dirty inputs: no`. Source digest now covers the
hardened scripts/flamegraph.sh; the .txt reports both the folded total and
perf record's estimate.

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

* docs: scope partial-PMU claim to perf-stat; perf-record is a software profile (Codex #129)

The constraints bullet labeled all perf artifacts as partial hardware PMU
evidence, but only results/perf_stat_linux.txt carries real PMU counters
(cycles/instructions/branches/branch-misses). results/perf_report_linux.txt
is a software cpu-clock sampling profile, not PMU evidence. Scope the claim
to the perf-stat artifact and call out perf-record separately, identically in
AGENTS.md and CLAUDE.md so the two memories stay in sync.

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

* docs: embed the flamegraph as a visible image in the README

The flamegraph artifact, generator, provenance companion, and docs already
existed but no page actually displayed the SVG — it was only referenced by
filename. Embed the rendered results/flamegraph.svg as a visible image under
the Benchmarks section, with a caption that classifies it honestly as a
software cpu-clock sampling hot-symbol profile (not PMU evidence), names the
hot frames, and links the provenance .txt and docs/perf_analysis.md.

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

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
div0rce added a commit that referenced this pull request Jun 22, 2026
* docs: sync resume anchors and PMU claims to v0.2.0 (Codex #127/#128 follow-up)

Resolve the Codex review findings left on `main` by PRs #127 and #128:

- PROGRESS.md: remove the stale "Next action remains" block that still steered
  /resume to the merged PR #125 on `perf/linux-host-artifact-refresh`; replace
  with the v0.2.0 between-releases state (no active milestone; #94/#90 gated).
- AGENTS.md: bring it into sync with CLAUDE.md's v0.2.0 partial-PMU reframe. The
  constraints bullet, the "correct claim" block, and the "M29 perf evidence
  status" subsection no longer label the artifacts "constrained Docker
  validation"; the stale `perf/linux-host-artifact-refresh` follow-up line is
  updated (also in CLAUDE.md) to the released state.
- docs/perf_analysis.md: narrow the PMU claim so it no longer implies the Apple
  Blizzard (E-core) PMU carries live counts. The `apple_blizzard_pmu/...` rows
  read `<not counted>` in results/perf_stat_linux.txt because the single-threaded
  benchmark stays on the Avalanche P-cores — expected scheduling, not a counter.

Docs/memory only; no code or artifacts changed.

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

* perf: add flamegraph generator and make target (#32)

Add `make flamegraph`, the missing-flamegraph follow-up tracked by issue #32.
The perf stat/record text workflow already existed; this renders a perf
call-graph flamegraph.

- scripts/flamegraph.sh: records `perf record --call-graph dwarf -F 4000 -g -e
  cpu-clock` on qsl-bench and writes results/flamegraph.svg plus a
  results/flamegraph.txt provenance/classification companion (top folded
  stacks). Mirrors perf_record.sh: Linux-only, reuses qsl_common.sh provenance
  + qsl_publish_artifact, and honours QSL_PERF_ALLOW_PARTIAL for constrained
  hosts. DWARF call graphs unwind correctly despite the Release `bench` preset
  omitting frame pointers.
- scripts/flamegraph.py: dependency-free (stdlib-only) stackcollapse + SVG
  renderer, so the artifact is reproducible from the repo without vendoring the
  Perl FlameGraph toolkit. Deterministic: frames sorted by name, colors a pure
  function of the name, no RNG/timestamps in the drawn body.
- tests/shell/test_flamegraph.sh: CTest-registered (python3-only, skips cleanly
  if absent) — folding (offset/dso stripping, perf-order reversal, comm-at-base,
  count aggregation, sortedness), SVG well-formedness, XML escaping,
  determinism, empty-input handling.
- docs (perf_analysis.md, results/README.md), command lists (CLAUDE.md,
  AGENTS.md), MILESTONES.md backlog, PROGRESS.md log.

`make check` 242/242. Full hardware cache-PMU evidence stays in #90.

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

* perf: add generated flamegraph artifact on bare-metal Fedora Asahi (#32)

results/flamegraph.svg + results/flamegraph.txt generated by `make flamegraph`
from the clean committed tree on the bare-metal Apple M2 (aarch64) Fedora Asahi
host: 397 cpu-clock samples, 171 folded stacks, `Dirty inputs: no`. The hot
paths resolve to real engine symbols (OrderBook::modify/cancel/add_limit, the
dispatch_storage cancel path, decode_new_order, the gateway Session path,
replay::generate_flow). Software cpu-clock sampling hot-symbol profile — not a
latency/throughput claim; full hardware cache-PMU evidence stays in #90.

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

* feat: add FIX-like text protocol adapter (#29)

Add a human-readable `tag=value` text protocol alongside the binary codec,
mapping the same internal message structs (issue #29, reprioritized by the human
from the backlog).

- include/qsl/protocol/fix.hpp + src/protocol/fix.cpp: SOH-framed `tag=value`
  adapter with genuine FIX framing — 8 BeginString / 9 BodyLength / 35 MsgType /
  ... / 10 mod-256 CheckSum — for the client->gateway order path:
  NewOrderSingle (35=D) -> NewOrder, OrderCancelRequest (35=F) -> CancelOrder.
  Decoding is total, deterministic, and noexcept (fixed field table,
  std::from_chars, std::string_view; no heap on the decode path) and reports
  every malformed input through a FixError taxonomy mirroring the binary codec's
  DecodeError. Documented, deliberate simplifications: Symbol (55) carries the
  numeric SymbolId; Price (44) carries integer ticks and is always present, so
  NewOrder<->FIX is a lossless bijection like the binary codec (price is never a
  float).
- tests/unit/test_fix_protocol.cpp: mirrors the binary required tests and adds a
  cross-codec equivalence test (binary and FIX decode the same order to identical
  structs across all Side x OrdType x TIF), a byte-pinned fixture, and rejection
  of malformed framing / unsupported BeginString / unknown-or-wrong MsgType /
  BodyLength mismatch / CheckSum mismatch / missing field / invalid field /
  invalid enum / out-of-range / oversized messages.
- docs/fix_protocol.md (+ pointer from docs/binary_protocol.md); MILESTONES.md
  and PROGRESS.md updated.

make check 260/260; make asan 260/260 (the adapter parses untrusted text).

Closes #29.

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

* perf: harden flamegraph collapsed-stack parsing (Codex review)

Address two Codex review findings in scripts/flamegraph.py::parse_collapsed:

- Prefer a tab separator when present so a tab-separated folded line whose stack
  contains spaces (C++ signatures) splits on the trailing count instead of an
  interior space and is silently dropped.
- Ignore non-positive sample counts, so hand-crafted --from-collapsed input with
  0/negative counts cannot render a misleading SVG (all-non-positive input now
  fails with exit 1 via the existing empty-folded guard).

Adds test coverage in tests/shell/test_flamegraph.sh (19/19).

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

* perf: regenerate flamegraph artifact after parser hardening

flamegraph.py is a provenance input, so regenerate results/flamegraph.svg +
.txt from the clean tree to keep the Source digest consistent (423 samples,
Dirty inputs: no).

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

* fix: enforce FIX-required ClOrdID on OrderCancelRequest (Codex review)

decode_cancel_order validated only OrigClOrdID (41) and Symbol (55), so a 35=F
message missing ClOrdID (tag 11) — which FIX requires and encode() emits — was
accepted. Validate tag 11 (present and numeric) on decode without storing it,
keeping decode symmetric with encode. Adds a rejection test and clarifies the
docs/fix_protocol.md note for tag 11.

make check 261/261; make asan 261/261.

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

* refactor: improve flamegraph.py code health (CodeScene gate)

CodeScene's delta gate scored scripts/flamegraph.py at 7.81 (render_svg: Large
Method + Excess Arguments + complexity; fold_perf_script: Bumpy Road / nested
complexity). Restructure without changing output:

- fold_perf_script: move per-line state into a small _Folder helper so the
  parsing loop is a flat if/elif/else instead of a nested block.
- render_svg: bundle styling knobs into a FlameOptions dataclass (2 args, was
  7) and extract _append_chrome, _frame_svg, _truncate; geometry constants
  (_SIDE/_PAD_TOP/_PAD_BOTTOM) hoisted to module scope and a _Canvas dataclass
  carries derived geometry.

Emitted SVG/collapsed bytes are unchanged; tests/shell/test_flamegraph.sh 19/19.

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

* perf: regenerate flamegraph artifact after code-health refactor

flamegraph.py is a provenance input; regenerate results/flamegraph.svg + .txt
from the clean tree (402 samples, Dirty inputs: no).

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

* refactor: reduce decode_new_order complexity in fix.cpp (CodeScene gate)

CodeScene's delta gate scored src/protocol/fix.cpp at 8.02 (decode_new_order:
Complex Method / Complex Conditional / Overall Code Complexity). Restructure
without changing behavior:

- Extract map_side / map_ord_type / map_tif (the enum-code switches) and
  expect_msg_type (the tag-35 check) as small helpers.
- Add a FieldReader accumulator that reads required integer/coded fields and
  short-circuits on the first error, so decode_new_order and decode_cancel_order
  become a flat fluent chain plus a single error check instead of a long
  if-return ladder with three inline switches.

make check 261/261; make asan 261/261; FIX tests 19 cases / 140 assertions.

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

* refactor: flatten flamegraph.py remaining complexity (CodeScene)

Clear the last two CodeScene flags on scripts/flamegraph.py:

- _clean_symbol: replace the balanced-paren dso scan (a deep nested loop) with a
  flat regex _DSO_RE. perf prints a space before the "(dso)" and dso strings
  never contain parens, so a non-nested " (...)$" match is exact and won't strip
  a C++ signature's own parentheses.
- _layout: drop the unused `total` parameter (5 args -> 4).

Output unchanged; tests/shell/test_flamegraph.sh 19/19.

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

* perf: regenerate flamegraph artifact after complexity flattening

Provenance input changed; regenerate from clean tree (416 samples, Dirty
inputs: no).

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

* refactor: remove decoder duplication and split parse_envelope (CodeScene)

Clear the remaining CodeScene flags on src/protocol/fix.cpp (Code Duplication,
Complex Method, Complex Conditional):

- Extract a decode_typed<T> skeleton (validate envelope -> confirm MsgType ->
  fill body via FieldReader -> error check) so decode_new_order and
  decode_cancel_order collapse to just their field maps, removing the duplicated
  prologue/epilogue.
- Split parse_envelope into tokenize / check_envelope_shape /
  verify_length_and_checksum, each a small single-purpose function, and fold the
  8/9/10 ordering check into a named bool.

Behavior unchanged: make check 261/261, make asan 261/261, FIX tests 19 cases /
140 assertions.

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

* refactor: table-driven enum maps + simpler msg-type check (CodeScene)

Clear the last two CodeScene advisory flags on src/protocol/fix.cpp:

- Code Duplication: the three near-identical map_side/map_ord_type/map_tif
  switches are replaced by one generic FieldReader::coded(tag, out, table) that
  looks a code up in a small constexpr {code, enum} table; the decoder supplies
  the per-enum tables. No per-enum mapping duplication remains.
- Complex Conditional: expect_msg_type's 3-term `||` is split so each branch has
  a single operator.

make check 261/261; make asan 261/261; FIX tests 19 cases / 140 assertions.

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

* docs: record resume-anchor sync in PROGRESS current-state (Codex #129)

The decision-log entry and bottom "Next action remains" block already
covered this follow-up, but the top `## Current state` bullets — the first
thing `/resume` reads — still presented the v0.2.0 release (PR #127) as the
"Last action". A resuming agent could therefore miss that this resume-anchor
/ PMU sync already happened and duplicate it.

Record the sync as the current "Last action" and "Last completed docs sync",
demoting the v0.2.0 release detail to a "Prior action" bullet. Docs-only.

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

* perf: harden flamegraph.sh classification + sample gating (Codex #130)

Address five Codex review findings on the flamegraph driver:

1. Classify `zero-sized data` (perf script's no-sample report) as a perf
   limitation, matching scripts/perf_record.sh, so the documented
   QSL_PERF_ALLOW_PARTIAL=1 constrained-host path works instead of tripping
   the unexpected-failure exit.
2. Remove any prior results/flamegraph.svg when a partial run captures no
   folded stacks, so a constrained rerun cannot leave a previous host's SVG
   beside a .txt that says there is no sample report.
3. Accept perf's `(~N samples)` estimate marker (optional `~`), and base the
   minimum-sample gate on the authoritative folded sample total rather than
   perf record's self-described estimate. Report both counts.
4. Capture flamegraph.py --collapse-only's exit status instead of `|| true`;
   a renderer/parser failure now exits 4 (unmaskable) rather than being
   published as a constrained-environment artifact.
5. Derive the sampling-kind label/caveat from the selected event (software
   cpu-clock/task-clock vs hardware-PMU) so the artifact type, SVG comment,
   and text companion stay consistent for QSL_FLAMEGRAPH_EVENT=cycles etc.

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

* perf: regenerate flamegraph artifact after classification hardening

Bare-metal Apple M2 (aarch64) Fedora Asahi, cpu-clock @ 4000Hz: 329 folded
samples / 159 stacks, classified `flamegraph (software cpu-clock sampling
hot-symbol profile)`, `Dirty inputs: no`. Source digest now covers the
hardened scripts/flamegraph.sh; the .txt reports both the folded total and
perf record's estimate.

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

* fix: enforce FIX envelope MsgType position + reject duplicate tags (Codex #131)

Two Codex review findings on the FIX adapter's parser strictness:

- check_envelope_shape now requires MsgType (35) as the first body field,
  immediately after BodyLength, so a non-standard header like 8/9/34/35/.../10
  is rejected as Malformed instead of decoding via a first-match scan.
- tokenize now rejects any repeated tag. This adapter maps each business tag
  exactly once (no repeating groups), so a duplicate such as `55=2` then
  `55=999` is an ambiguous/malformed frame rather than a silently-ignored
  later value.

Adds a deterministic rejection test for each. (The earlier ClOrdID-required
finding was already resolved by 3e4c8e3 and is covered by an existing test.)
make check 263/263, make asan 263/263.

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

* docs: drop delivered #29 from open-backlog anchors (Codex #131)

The decision log marks #29 (FIX adapter) closed by this PR, but the
current-state / resume anchors in PROGRESS.md and HANDOFF.md still listed it
as open backlog, so /resume could send the next session to re-implement work
this PR just added. Remove #29 from those backlog lists and note it as
delivered in this PR. (#32 stays listed here; the v0.2.1 release PR removes it
as part of its release sweep.)

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

* docs: scope partial-PMU claim to perf-stat; perf-record is a software profile (Codex #129)

The constraints bullet labeled all perf artifacts as partial hardware PMU
evidence, but only results/perf_stat_linux.txt carries real PMU counters
(cycles/instructions/branches/branch-misses). results/perf_report_linux.txt
is a software cpu-clock sampling profile, not PMU evidence. Scope the claim
to the perf-stat artifact and call out perf-record separately, identically in
AGENTS.md and CLAUDE.md so the two memories stay in sync.

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

* docs: embed the flamegraph as a visible image in the README

The flamegraph artifact, generator, provenance companion, and docs already
existed but no page actually displayed the SVG — it was only referenced by
filename. Embed the rendered results/flamegraph.svg as a visible image under
the Benchmarks section, with a caption that classifies it honestly as a
software cpu-clock sampling hot-symbol profile (not PMU evidence), names the
hot frames, and links the provenance .txt and docs/perf_analysis.md.

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

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
div0rce added a commit that referenced this pull request Jun 22, 2026
…), anchor sweep (#133)

* docs: sync resume anchors and PMU claims to v0.2.0 (Codex #127/#128 follow-up)

Resolve the Codex review findings left on `main` by PRs #127 and #128:

- PROGRESS.md: remove the stale "Next action remains" block that still steered
  /resume to the merged PR #125 on `perf/linux-host-artifact-refresh`; replace
  with the v0.2.0 between-releases state (no active milestone; #94/#90 gated).
- AGENTS.md: bring it into sync with CLAUDE.md's v0.2.0 partial-PMU reframe. The
  constraints bullet, the "correct claim" block, and the "M29 perf evidence
  status" subsection no longer label the artifacts "constrained Docker
  validation"; the stale `perf/linux-host-artifact-refresh` follow-up line is
  updated (also in CLAUDE.md) to the released state.
- docs/perf_analysis.md: narrow the PMU claim so it no longer implies the Apple
  Blizzard (E-core) PMU carries live counts. The `apple_blizzard_pmu/...` rows
  read `<not counted>` in results/perf_stat_linux.txt because the single-threaded
  benchmark stays on the Avalanche P-cores — expected scheduling, not a counter.

Docs/memory only; no code or artifacts changed.

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

* perf: add flamegraph generator and make target (#32)

Add `make flamegraph`, the missing-flamegraph follow-up tracked by issue #32.
The perf stat/record text workflow already existed; this renders a perf
call-graph flamegraph.

- scripts/flamegraph.sh: records `perf record --call-graph dwarf -F 4000 -g -e
  cpu-clock` on qsl-bench and writes results/flamegraph.svg plus a
  results/flamegraph.txt provenance/classification companion (top folded
  stacks). Mirrors perf_record.sh: Linux-only, reuses qsl_common.sh provenance
  + qsl_publish_artifact, and honours QSL_PERF_ALLOW_PARTIAL for constrained
  hosts. DWARF call graphs unwind correctly despite the Release `bench` preset
  omitting frame pointers.
- scripts/flamegraph.py: dependency-free (stdlib-only) stackcollapse + SVG
  renderer, so the artifact is reproducible from the repo without vendoring the
  Perl FlameGraph toolkit. Deterministic: frames sorted by name, colors a pure
  function of the name, no RNG/timestamps in the drawn body.
- tests/shell/test_flamegraph.sh: CTest-registered (python3-only, skips cleanly
  if absent) — folding (offset/dso stripping, perf-order reversal, comm-at-base,
  count aggregation, sortedness), SVG well-formedness, XML escaping,
  determinism, empty-input handling.
- docs (perf_analysis.md, results/README.md), command lists (CLAUDE.md,
  AGENTS.md), MILESTONES.md backlog, PROGRESS.md log.

`make check` 242/242. Full hardware cache-PMU evidence stays in #90.

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

* perf: add generated flamegraph artifact on bare-metal Fedora Asahi (#32)

results/flamegraph.svg + results/flamegraph.txt generated by `make flamegraph`
from the clean committed tree on the bare-metal Apple M2 (aarch64) Fedora Asahi
host: 397 cpu-clock samples, 171 folded stacks, `Dirty inputs: no`. The hot
paths resolve to real engine symbols (OrderBook::modify/cancel/add_limit, the
dispatch_storage cancel path, decode_new_order, the gateway Session path,
replay::generate_flow). Software cpu-clock sampling hot-symbol profile — not a
latency/throughput claim; full hardware cache-PMU evidence stays in #90.

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

* feat: add FIX-like text protocol adapter (#29)

Add a human-readable `tag=value` text protocol alongside the binary codec,
mapping the same internal message structs (issue #29, reprioritized by the human
from the backlog).

- include/qsl/protocol/fix.hpp + src/protocol/fix.cpp: SOH-framed `tag=value`
  adapter with genuine FIX framing — 8 BeginString / 9 BodyLength / 35 MsgType /
  ... / 10 mod-256 CheckSum — for the client->gateway order path:
  NewOrderSingle (35=D) -> NewOrder, OrderCancelRequest (35=F) -> CancelOrder.
  Decoding is total, deterministic, and noexcept (fixed field table,
  std::from_chars, std::string_view; no heap on the decode path) and reports
  every malformed input through a FixError taxonomy mirroring the binary codec's
  DecodeError. Documented, deliberate simplifications: Symbol (55) carries the
  numeric SymbolId; Price (44) carries integer ticks and is always present, so
  NewOrder<->FIX is a lossless bijection like the binary codec (price is never a
  float).
- tests/unit/test_fix_protocol.cpp: mirrors the binary required tests and adds a
  cross-codec equivalence test (binary and FIX decode the same order to identical
  structs across all Side x OrdType x TIF), a byte-pinned fixture, and rejection
  of malformed framing / unsupported BeginString / unknown-or-wrong MsgType /
  BodyLength mismatch / CheckSum mismatch / missing field / invalid field /
  invalid enum / out-of-range / oversized messages.
- docs/fix_protocol.md (+ pointer from docs/binary_protocol.md); MILESTONES.md
  and PROGRESS.md updated.

make check 260/260; make asan 260/260 (the adapter parses untrusted text).

Closes #29.

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

* perf: harden flamegraph collapsed-stack parsing (Codex review)

Address two Codex review findings in scripts/flamegraph.py::parse_collapsed:

- Prefer a tab separator when present so a tab-separated folded line whose stack
  contains spaces (C++ signatures) splits on the trailing count instead of an
  interior space and is silently dropped.
- Ignore non-positive sample counts, so hand-crafted --from-collapsed input with
  0/negative counts cannot render a misleading SVG (all-non-positive input now
  fails with exit 1 via the existing empty-folded guard).

Adds test coverage in tests/shell/test_flamegraph.sh (19/19).

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

* perf: regenerate flamegraph artifact after parser hardening

flamegraph.py is a provenance input, so regenerate results/flamegraph.svg +
.txt from the clean tree to keep the Source digest consistent (423 samples,
Dirty inputs: no).

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

* fix: enforce FIX-required ClOrdID on OrderCancelRequest (Codex review)

decode_cancel_order validated only OrigClOrdID (41) and Symbol (55), so a 35=F
message missing ClOrdID (tag 11) — which FIX requires and encode() emits — was
accepted. Validate tag 11 (present and numeric) on decode without storing it,
keeping decode symmetric with encode. Adds a rejection test and clarifies the
docs/fix_protocol.md note for tag 11.

make check 261/261; make asan 261/261.

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

* refactor: improve flamegraph.py code health (CodeScene gate)

CodeScene's delta gate scored scripts/flamegraph.py at 7.81 (render_svg: Large
Method + Excess Arguments + complexity; fold_perf_script: Bumpy Road / nested
complexity). Restructure without changing output:

- fold_perf_script: move per-line state into a small _Folder helper so the
  parsing loop is a flat if/elif/else instead of a nested block.
- render_svg: bundle styling knobs into a FlameOptions dataclass (2 args, was
  7) and extract _append_chrome, _frame_svg, _truncate; geometry constants
  (_SIDE/_PAD_TOP/_PAD_BOTTOM) hoisted to module scope and a _Canvas dataclass
  carries derived geometry.

Emitted SVG/collapsed bytes are unchanged; tests/shell/test_flamegraph.sh 19/19.

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

* perf: regenerate flamegraph artifact after code-health refactor

flamegraph.py is a provenance input; regenerate results/flamegraph.svg + .txt
from the clean tree (402 samples, Dirty inputs: no).

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

* refactor: reduce decode_new_order complexity in fix.cpp (CodeScene gate)

CodeScene's delta gate scored src/protocol/fix.cpp at 8.02 (decode_new_order:
Complex Method / Complex Conditional / Overall Code Complexity). Restructure
without changing behavior:

- Extract map_side / map_ord_type / map_tif (the enum-code switches) and
  expect_msg_type (the tag-35 check) as small helpers.
- Add a FieldReader accumulator that reads required integer/coded fields and
  short-circuits on the first error, so decode_new_order and decode_cancel_order
  become a flat fluent chain plus a single error check instead of a long
  if-return ladder with three inline switches.

make check 261/261; make asan 261/261; FIX tests 19 cases / 140 assertions.

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

* refactor: flatten flamegraph.py remaining complexity (CodeScene)

Clear the last two CodeScene flags on scripts/flamegraph.py:

- _clean_symbol: replace the balanced-paren dso scan (a deep nested loop) with a
  flat regex _DSO_RE. perf prints a space before the "(dso)" and dso strings
  never contain parens, so a non-nested " (...)$" match is exact and won't strip
  a C++ signature's own parentheses.
- _layout: drop the unused `total` parameter (5 args -> 4).

Output unchanged; tests/shell/test_flamegraph.sh 19/19.

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

* perf: regenerate flamegraph artifact after complexity flattening

Provenance input changed; regenerate from clean tree (416 samples, Dirty
inputs: no).

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

* refactor: remove decoder duplication and split parse_envelope (CodeScene)

Clear the remaining CodeScene flags on src/protocol/fix.cpp (Code Duplication,
Complex Method, Complex Conditional):

- Extract a decode_typed<T> skeleton (validate envelope -> confirm MsgType ->
  fill body via FieldReader -> error check) so decode_new_order and
  decode_cancel_order collapse to just their field maps, removing the duplicated
  prologue/epilogue.
- Split parse_envelope into tokenize / check_envelope_shape /
  verify_length_and_checksum, each a small single-purpose function, and fold the
  8/9/10 ordering check into a named bool.

Behavior unchanged: make check 261/261, make asan 261/261, FIX tests 19 cases /
140 assertions.

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

* refactor: table-driven enum maps + simpler msg-type check (CodeScene)

Clear the last two CodeScene advisory flags on src/protocol/fix.cpp:

- Code Duplication: the three near-identical map_side/map_ord_type/map_tif
  switches are replaced by one generic FieldReader::coded(tag, out, table) that
  looks a code up in a small constexpr {code, enum} table; the decoder supplies
  the per-enum tables. No per-enum mapping duplication remains.
- Complex Conditional: expect_msg_type's 3-term `||` is split so each branch has
  a single operator.

make check 261/261; make asan 261/261; FIX tests 19 cases / 140 assertions.

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

* release: v0.2.1 — FIX text protocol adapter, perf flamegraph, anchor sweep

Bump the project version 0.2.0 -> 0.2.1 and record the release.

- CMakeLists.txt: project VERSION 0.2.1.
- CHANGELOG.md: new [0.2.1] section — FIX-like text protocol adapter (#29),
  `make flamegraph` + dependency-free renderer (#32), and the Codex
  resume-anchor / PMU-claim consistency sweep (#127/#128 follow-up); [Unreleased]
  reset.
- PROGRESS.md / HANDOFF.md: release and resume anchors brought to the v0.2.1
  released state; #29 and #32 marked done.

No code or benchmark artifacts change in this release PR. On squash-merge, tag
`v0.2.1` on the merge commit and publish the GitHub release. make check 261/261.

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

* docs: record resume-anchor sync in PROGRESS current-state (Codex #129)

The decision-log entry and bottom "Next action remains" block already
covered this follow-up, but the top `## Current state` bullets — the first
thing `/resume` reads — still presented the v0.2.0 release (PR #127) as the
"Last action". A resuming agent could therefore miss that this resume-anchor
/ PMU sync already happened and duplicate it.

Record the sync as the current "Last action" and "Last completed docs sync",
demoting the v0.2.0 release detail to a "Prior action" bullet. Docs-only.

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

* perf: harden flamegraph.sh classification + sample gating (Codex #130)

Address five Codex review findings on the flamegraph driver:

1. Classify `zero-sized data` (perf script's no-sample report) as a perf
   limitation, matching scripts/perf_record.sh, so the documented
   QSL_PERF_ALLOW_PARTIAL=1 constrained-host path works instead of tripping
   the unexpected-failure exit.
2. Remove any prior results/flamegraph.svg when a partial run captures no
   folded stacks, so a constrained rerun cannot leave a previous host's SVG
   beside a .txt that says there is no sample report.
3. Accept perf's `(~N samples)` estimate marker (optional `~`), and base the
   minimum-sample gate on the authoritative folded sample total rather than
   perf record's self-described estimate. Report both counts.
4. Capture flamegraph.py --collapse-only's exit status instead of `|| true`;
   a renderer/parser failure now exits 4 (unmaskable) rather than being
   published as a constrained-environment artifact.
5. Derive the sampling-kind label/caveat from the selected event (software
   cpu-clock/task-clock vs hardware-PMU) so the artifact type, SVG comment,
   and text companion stay consistent for QSL_FLAMEGRAPH_EVENT=cycles etc.

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

* perf: regenerate flamegraph artifact after classification hardening

Bare-metal Apple M2 (aarch64) Fedora Asahi, cpu-clock @ 4000Hz: 329 folded
samples / 159 stacks, classified `flamegraph (software cpu-clock sampling
hot-symbol profile)`, `Dirty inputs: no`. Source digest now covers the
hardened scripts/flamegraph.sh; the .txt reports both the folded total and
perf record's estimate.

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

* fix: enforce FIX envelope MsgType position + reject duplicate tags (Codex #131)

Two Codex review findings on the FIX adapter's parser strictness:

- check_envelope_shape now requires MsgType (35) as the first body field,
  immediately after BodyLength, so a non-standard header like 8/9/34/35/.../10
  is rejected as Malformed instead of decoding via a first-match scan.
- tokenize now rejects any repeated tag. This adapter maps each business tag
  exactly once (no repeating groups), so a duplicate such as `55=2` then
  `55=999` is an ambiguous/malformed frame rather than a silently-ignored
  later value.

Adds a deterministic rejection test for each. (The earlier ClOrdID-required
finding was already resolved by 3e4c8e3 and is covered by an existing test.)
make check 263/263, make asan 263/263.

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

* docs: drop delivered #29 from open-backlog anchors (Codex #131)

The decision log marks #29 (FIX adapter) closed by this PR, but the
current-state / resume anchors in PROGRESS.md and HANDOFF.md still listed it
as open backlog, so /resume could send the next session to re-implement work
this PR just added. Remove #29 from those backlog lists and note it as
delivered in this PR. (#32 stays listed here; the v0.2.1 release PR removes it
as part of its release sweep.)

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

* docs: scope partial-PMU claim to perf-stat; perf-record is a software profile (Codex #129)

The constraints bullet labeled all perf artifacts as partial hardware PMU
evidence, but only results/perf_stat_linux.txt carries real PMU counters
(cycles/instructions/branches/branch-misses). results/perf_report_linux.txt
is a software cpu-clock sampling profile, not PMU evidence. Scope the claim
to the perf-stat artifact and call out perf-record separately, identically in
AGENTS.md and CLAUDE.md so the two memories stay in sync.

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

* docs: embed the flamegraph as a visible image in the README

The flamegraph artifact, generator, provenance companion, and docs already
existed but no page actually displayed the SVG — it was only referenced by
filename. Embed the rendered results/flamegraph.svg as a visible image under
the Benchmarks section, with a caption that classifies it honestly as a
software cpu-clock sampling hot-symbol profile (not PMU evidence), names the
hot frames, and links the provenance .txt and docs/perf_analysis.md.

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