Repository navigation
Front page: languages on one line; body folds to a scannable summary - #10
Conversation
…anguage invitation The full Languages section at the bottom keeps the per-grammar detail; the front page now answers 'does it speak my language' without scrolling, and both places say what adding one costs: a vendored tree-sitter grammar, its queries, one row in the declarative extension table. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…click for the prose The front page above the nav-link rule is untouched: hero, languages line, install one-liner, with/without table, the round-4 retrieval table and its two literary retellings, the token/quality claims, and the two output examples. That block was designed as a pitch and still reads as one. Everything below it now leads with 1-3 sentences that carry the section's actual claim — numbers kept, never hidden — and folds the expository prose into <details> blocks with informative summaries, using the pattern the page already used twice. A scroll from "What it answers" to the licence now reads as an executive summary with every deep dive one click away. Nothing was deleted or reworded: every line of the previous README is still in the file byte-for-byte, verified line-by-line, so the gates that pin sentences and numbers here (readmedrift, readmeexample, floormark, emittertruth, cuda, metal, deck, skillinstall, …) see the same text. New sentences were added, not substituted. Headings all stay outside the folds so every anchor — #languages, #measured, #in-the-numbers, #what-it-saves-you-in-tokens — still resolves, and the counterexample list #in-the-numbers points at stays unfolded so the link lands on visible text. Install/command fences, the documentation table, the with/without table, the benchmark tables and the Languages section stay in the open. 21 new folds across 10 sections. pargates: 361 gates, 358 pass, 3 standing skips, 0 fail.
📝 WalkthroughSummary by CodeRabbit
WalkthroughREADME.md was reorganized with expanded documentation for language support, usage, builds, quality metrics, benchmarks, profiling, MCP, prompts, and language extensions. ChangesREADME documentation
Estimated code review effort: 1 (Trivial) | ~5 minutes Suggested reviewers: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 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 `@README.md`:
- Around line 17-20: Update the top-level language contribution note in
README.md to mention that adding a language also requires its query file,
alongside the vendored tree-sitter grammar and declarative table row. Keep the
existing language list and reference link unchanged.
- Around line 814-817: Update the README section describing the two faster
builds so all prose matches the CMake defaults shown in the table: LTO is
enabled by default, while PGO remains opt-in. Remove or revise any wording that
says both options are disabled by default, including the nested details text.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
| **Languages:** C · C++ · Objective-C/C++ · Metal · CUDA · Python · TypeScript · JavaScript · Java · | ||
| Ruby · Bash · Go · Rust · Swift · C# · JSON — [sixteen vendored grammars](#languages), and adding | ||
| another is a vendored tree-sitter grammar plus one row in a declarative table. | ||
|
|
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win
Include the query file in the top-level language contribution note.
The top note requires a vendored grammar and one table row. The full instruction at Lines 1073-1076 also requires a query file. A contributor following only the top note can create an incomplete language integration.
Proposed wording
- another is a vendored tree-sitter grammar plus one row in a declarative table.
+ another is a vendored tree-sitter grammar, its query file, and one row in a declarative table.As per path instructions: “Focus on major issues impacting performance, readability, maintainability and security. Avoid nitpicks and avoid verbosity.”
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| **Languages:** C · C++ · Objective-C/C++ · Metal · CUDA · Python · TypeScript · JavaScript · Java · | |
| Ruby · Bash · Go · Rust · Swift · C# · JSON — [sixteen vendored grammars](#languages), and adding | |
| another is a vendored tree-sitter grammar plus one row in a declarative table. | |
| **Languages:** C · C++ · Objective-C/C++ · Metal · CUDA · Python · TypeScript · JavaScript · Java · | |
| Ruby · Bash · Go · Rust · Swift · C# · JSON — [sixteen vendored grammars](`#languages`), and adding | |
| another is a vendored tree-sitter grammar, its query file, and one row in a declarative table. |
🤖 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 `@README.md` around lines 17 - 20, Update the top-level language contribution
note in README.md to mention that adding a language also requires its query
file, alongside the vendored tree-sitter grammar and declarative table row. Keep
the existing language list and reference link unchanged.
Source: Path instructions
| </details> | ||
|
|
||
| <details> | ||
| <summary>The two opt-in faster builds — LTO on by default, PGO at 14–25% cold, and why the output stays byte-identical</summary> |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
Resolve the LTO default contradiction.
The summary says LTO is on by default. The nested text says both options are off by default. The table also says the default build has LTO enabled. This gives users conflicting build instructions. State that LTO is on by default and PGO is opt-in, if the table reflects the CMake default.
Proposed wording
-<summary>The two opt-in faster builds — LTO on by default, PGO at 14–25% cold, and why the output stays byte-identical</summary>
+<summary>The faster builds — LTO on by default, PGO at 14–25% cold, and why the output stays byte-identical</summary>
- Two build options answer that, both off by default:
+ LTO is on by default; PGO is opt-in:As per path instructions: “Focus on major issues impacting performance, readability, maintainability and security. Avoid nitpicks and avoid verbosity.”
🤖 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 `@README.md` around lines 814 - 817, Update the README section describing the
two faster builds so all prose matches the CMake defaults shown in the table:
LTO is enabled by default, while PGO remains opt-in. Remove or revise any
wording that says both options are disabled by default, including the nested
details text.
Source: Path instructions
…losure's OWN paging decision (jsoncheck #10) verify-wave1 R2: mcpverbs.h emitted grep's row total under 'no --limit/--offset given' while M2 made pageDisclosure's quintet (which carries total) ride whenever the listing was CUT, so every bare cut answer — MCP grep and the CLI --batch grep: CDATA — carried the key twice. isPaging now asks computePageDisclosure(...).paging, the one decision both halves share. Gate: jsoncheck.sh #10, a duplicate-key sweep (json.loads + object_pairs_hook) over every CLI --json verb (#1-#7 + the #8b universe), every tools/list verb's MCP envelope + payload (31 verbs, 11 JSON payloads on an alpha fixture with a >100-hit grep), and every --batch CDATA payload. RED on e3b52d3 (MCP grep + --batch 'duplicate key total'), GREEN after; total survives on the uncapped bare payload (total=1 shown=1). Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…s it cannot honour Wave-2 verifier finding R2. V1 made --pr-context's est_tokens price the document exactly, and that is what made this legible: the number is now true, it is visibly larger than the ceiling the caller stated, and the root said nothing. At fc71640, on a clean tree: --max-tokens=500 budget_tokens="500" est_tokens="2002" trim_level="0" truncated="none" 4.0x --max-tokens=1000 budget_tokens="1000" est_tokens="2002" trim_level="0" truncated="none" --max-tokens=2000 budget_tokens="2000" est_tokens="2002" trim_level="0" truncated="none" The NON-empty root already labels the identical condition (pickPrTrimLevel's last rung appends ";budget-floor-exceeded"), so the vocabulary existed; this root never reached it, because its whole document is the legend and it has no ladder to descend. That is the same rule lane V2 closed on --for this round ("a stated budget is never a SILENT overshoot"), applied to the root V1 made honestly priced, and V1's own found-not-fixed #1 predicted it in words. THE FIX. prEmptyRootPrice decides the price and the label together, because the second changes the first: price at level 0; if a budget is in force and the price is over it, apply truncated="budget-floor-exceeded" and RE-PRICE once. One pass is the fixpoint for pickPrTrimLevel's own reason — the suffix lengthens the root tag, and a document already over budget cannot come back under by growing — so the printed est_tokens is the delivered document's real price either way. Verified: at --max-tokens=500 the clean root emits 5,305 B and est_tokens="2122" = round(5305/2.50) exactly, delta 0. budgetTokens == 0 is UNLIMITED and no ceiling can be exceeded against it. The legend now DEFINES the token it emits. The BUDGET clause described the floor condition but never spelled "budget-floor-exceeded", so the attribute value was undefined prose on the non-empty root too; one sentence names it, and names the clean-tree case explicitly. GATE FIRST: test/prbudgetcheck.sh gains arm #10. The verifier's point was that F4's empty-root budget arm (:175) only ever read the DEFAULT-budget root, where 2002 <= 8000 passes and the floor is never reached. #10 states the property over BOTH root emitters and sweeps eight explicit --max-tokens values across three roots (dirty working tree, clean working tree, =BASE) = 24 rungs, in both directions: est_tokens > budget_tokens => truncated= carries budget-floor-exceeded (no silent overshoot) est_tokens <= budget_tokens => it does not (no false label) plus: every rung echoes the budget it was given, and the labelled root ships the legend clause that defines the term. It refuses to pass vacuously — at least one rung of the sweep must actually go over and one must be inside, asserted as its own arm. RED at fc71640: FAIL (#10) a --pr-context root exceeded its stated --max-tokens with nothing on the root saying so [empty-diff root, budgets 100/500/1000/2000: est=2027, truncated="none", up to a SILENT 20.2x overshoot] FAIL (#10) --pr-context --max-tokens=500 on a clean tree carries no budget-floor-exceeded label GREEN after: prbudgetcheck: ALL PASS, rc=0 (all four #10 arms) Determinism x2 + xmllint on six roots (clean and =HEAD~1, each with no budget / --max-tokens=500 / --max-tokens=100000): all DET, all well-formed, and est_tokens recounts the emitted bytes at 2.50 B/tok with delta 0 on every one — the label does not break the pricing fixpoint. Gates green: prcontextcheck prbudgetcheck estchargecheck attrvocabcheck legendcoveragecheck legenddriftcheck floormarkcheck jsonparitycheck pagingsweepcheck formatgatecheck deckcheck readmedriftcheck. --edit-check=prEmptyRootTail: status="contract-change" params 4 -> 5, callers=1, incompatible=0 — deliberate, it is what carries the label. --quality-delta regressions=0 gating=0 (5 acked by exact kind with a reason). Extracting prEmptyRootPrice rather than inlining the branch leaves writePrContext's own complexity (154) and LOC (376) unchanged by this commit. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
--eval-retrieval built its gold set by walking symbol ids from 0 and stopping at the first 150 doc-commented symbols. Ids are assigned in crawl order and the crawl is sorted by path, so the gold set was "whichever 150 doc-commented symbols sort earliest by path". bench/ sorts before src/. A contributor who documented a benchmark harness -- touching no ranking code at all -- moved a published number. Every retrieval figure this project publishes was drawn from that sample. Reproduced as a controlled experiment at db6a416: one identical 60-symbol doc-commented probe file, one otherwise byte-identical corpus, only the probe's path varied. aaa_probe/probe.h (early) subtoken/name 0.834 subtoken/doc-phrase 0.620 zzz_probe/probe.h (late) subtoken/name 0.729 subtoken/doc-phrase 0.976 0.105 and 0.356 MRR from path spelling alone. A second instance of the same defect sat in the metric: rankOfSymbol broke score ties by `i < gold`, i.e. by id, i.e. by path. Invisible where the ranker has signal and total where it has none -- on name-exact/doc-phrase nearly everything ties at zero, so the rank was "how many files sort before mine" and that row's recall@1 was luck. Gate first. test/knownitemcheck.sh gains three arms, all red on db6a416: #8 order-independence -- the same probe at an early vs late path must give identical numbers (the defect, reproduced as a test; mirror case included so it cannot pass by accident) #9 sample self-disclosure -- population=/scored=/rule= must be emitted, population >= scored #10 population re-derivation -- adding N doc-commented symbols must raise population by exactly N, derived from a controlled input rather than by reimplementing docPhraseFirstLine (which would clone the bug) Fix: the population is every qualifying symbol and the eval is exhaustive over it (rule=exhaustive; a disclosed path-free cut by smallest fnv1a64(scope::name) is the safety valve above kMaxScored, cutting on the key so an identity is never split). Ties use the midrank 1 + #better + #tied/2, which no ordering can move. PUBLISHED NUMBERS MOVED. Not a ranking change -- the ranker is byte-identical. Repository root, decomposed one fix at a time: subtoken/name name-exact/name ne/name r@1 path-ordered 150-slice, id ties (old) 0.598 0.829 75.3% census population, id ties 0.724 0.939 90.8% census population, midrank ties (now) 0.724 0.922 85.4% On THIS root the sampler fix does nearly all of it and moves numbers UP. That direction is NOT a property of head-slicing: the slice reports whichever corner of the tree sorts first, and the two published roots disagree -- at the root it UNDERSTATED (0.598 vs a true 0.724), in src/ it OVERSTATED slightly (name-exact/name 0.977 vs 0.974). The honest word is ARBITRARY, and an earlier draft of this message calling it "systematically harder" was the same overreach the entry exists to record. The consistent downward movement in src/ is therefore the MIDRANK fix, not the sampler: on src/ the sampler moved name-exact/name MRR by 0.003, the midrank by 0.014. Most of that is tie-luck removed, but part is the convention -- midrank is deliberately pessimistic, scoring a two-way tie at the top as 1.5, taking no recall@1 credit where id-tiebreak gave rank 1 whenever gold's id was lowest. Not all of it is luck. README's src/ headline is re-pinned 98.0% -> 91.3% recall@1. NOT all instrument: the 98.0% was last measured on an older corpus, and no clean decomposition of corpus-drift vs instrument is available for that figure, so it is re-pinned rather than explained. The two defects COMPOUND, which is why neither was visible alone: a sample biased toward early-path symbols, graded by a metric that rewards early-path symbols. Re-pinned in the same commit: README.md, docs/EVALS.md S4, bench/ANSWERQUALITY.md, docs/COMMANDS.md (regenerated through docs_commands_build.py from an updated capture). docs/EVALS.md S7 gains the dated record so the discontinuity is not misread later as a ranking regression. Two dated records are deliberately NOT rewritten -- the Terminality round A pre-registration and the 2026-08-08 fa4639e A/B -- because retroactively editing a pre-registration is the thing pre-registration exists to prevent. NOT done: the fixture was not touched. Stripping the docstrings or excluding bench/ would have restored 0.600 while leaving the defect in place, would need redoing every time an early-sorting file gained a comment, and would teach the next contributor that documenting code breaks the build. Cost: exhaustive scoring is ~23x the old slice (each scored symbol drives eight whole-corpus rankings, two of them full PageRank power iterations). It buys nothing for users -- the ranker is unchanged -- and nobody pays it in a normal workflow: not an MCP verb, classed a maintainer harness in skills/ripwire-router/SKILL.md, and the only automated caller is knownitemcheck on src/. It buys honest published numbers. Follow-up not taken here: ~45% of the eval's CPU is system time from allocating and freeing N-sized vectors inside the per-query loop. Hoisting those would roughly halve the runtime without changing a digit of output. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
CodeRabbit #127 finding 3985249704 (src/mcpverbs.h:1269, +1313) — VALID. `blast_radius` and `forgotten` are both windowed by pageWindow with the same limit/offset, and the payload carried no shown count, no total, no has_more and no next_offset for either. A caller could not tell that rows had been omitted and could not construct a next request. The CLI twin has disclosed its blast-radius cut in prose since C1 F-10 (situ.h's situShowingNote: "showing 8 of N files — shown=8 total=N capped=1"), so this was the two dialects saying different things about the same run. THE SHAPE IS --test-gate's, not a new one (§B7.1, situ.h::writeTestGateReportJson): two INDEPENDENT listings in one report is exactly the case pageview.h rule 6 answers with rule 1's noun-prefixed exception, because a bare `shown` next to two arrays is ambiguous in a way `shown_blast_radius` cannot be. So the payload now carries shown_blast_radius / blast_radius_capped — the pair for listing one shown_forgotten / forgotten_capped / forgotten_total — listing two, with its own row population (no other key carried it) total / has_more / next_offset / offset / limit — pageview.h's ONE disclosure under the JSON syntax row, describing the PRIMARY listing (blast_radius, the array it precedes). Its `total` IS blast_radius's total; a second spelling would be the duplicate key jsoncheck #10 pins. Both _capped bits and both shown counts are DERIVED from the rows the document actually emits. pagingDisclosure emits nothing when no window applied, so a bare call (this verb's default is unbounded) gains only the four derived counts. Live, on this repo: bare shown_blast_radius=5 blast_radius_capped=false shown_forgotten=80 forgotten_capped=false forgotten_total=80 limit=2 shown_blast_radius=2 blast_radius_capped=true shown_forgotten=2 forgotten_capped=true forgotten_total=80 total=5 has_more=true next_offset=2 offset=0 limit=2 GATE ARM, test/mcpcontractcheck.sh §G, beside the three live paging probes already there: eleven checks over a bare run and a limit=2 run, every one of them DERIVED (shown must equal the rows served; capped must equal shown < total), so a hand-written constant cannot satisfy it. CAN GO RED, observed against the pre-fix binary: all eleven fail with shown_blast_radius=None … total=None has_more=None next_offset=None offset=None limit=None Green: mcpcontractcheck ALL PASS, mcpattrparitycheck ALL PASS, mcpclidiffcheck ALL PASS, jsoncheck ALL PASS (incl. the --json determinism gate).
…— the default comparator aborted every Linux G1 ingest The asan (ubuntu-24.04) job on #135 (run 34583440115, head fed22de) failed at its first gate after the fixture: EVERY ripwire invocation in packtaskcheck died rc=134 with empty stderr, the --pack-task refusal arms included. Reproduced in an ubuntu:24.04 container (clang 18 + libstdc++ 13) with CI's exact ASAN/UBSAN/LSAN options and log_path dropped so the report reaches stderr: include/c++/13/string_view:576:38: runtime error: unsigned integer overflow: 8 - 13 cannot be represented in type 'size_type' (aka 'unsigned long') #0 std::basic_string_view<char>::_S_compare string_view:576 #8 std::sort<vector<string_view>::iterator> #9 rw::extent::resetExtentScratch src/extentsuspect.h:185 #10 rw::extent::classifyFileExtents src/extentsuspect.h:221 #11 rw::(anonymous)::markExtentSuspects src/ingest_model.h:403 #12 rw::ingest src/ingest.cpp:320 Not a leak, not an ODR violation, not init order: UBSan's `integer` group on a libstdc++-internal wrap. libstdc++'s string_view::compare settles a prefix pair by computing `n1 - n2` in size_type; G1 runs -fsanitize=integer under -fno-sanitize-recover=all, so the first comparison of two same-file C++ class names where one prefixes the other kills the process. libc++ never subtracts, which is why both macOS legs (macOS ASan included) and every local run were clean, and why no ignorelist entry covers it — the three libstdc++ entries name bits/string_view.tcc and basic_string, not <string_view> itself. It fires inside ingest, before verb dispatch: hence the empty stderr on the refusal arms. test/fixture holds no prefix pair, so the fixture step passed; src/ holds one, so every run over it aborted. main 096e354, built and run the same way, is clean (--for rc=0 with no report; bare --pack-task refuses rc=1). The house rule already existed — src/infra/sortutil.h: order string_views through svLess, never operator< (main went red the same way at 69a17f9). The extent detector's std::sort over ExtentScratch::cppClassNames and std::binary_search over its span both took the default comparator. Both now pass rw::sortutil::svLess, the SAME total order operator< defines, so the sorted table and every R2 answer are byte-identical: no kParserVer or kCacheVersion bump, no capture regeneration. WHY THE EXISTING GUARD MISSED IT, AND THE ARM THAT NOW SEES IT. portablebuildcheck #6 greps for binary_search|lower_bound|upper_bound|equal_range on lines that SPELL string_view. Neither call names its element type (a member declared 67 lines up, a span parameter), and std::sort was never matched at all. New arm #6b takes every ordered algorithm called at default arity, resolves the container its first argument ranges over through the nearest preceding declaration in the same file, and exempts static_assert; planted positive and negative controls run every time, so a scanner that goes quiet fails the arm. Red-first: on fed22de it fails with exactly src/extentsuspect.h:159 and :185 (exit 1); green on this fix and on main 766913d (exit 0); about 0.7 s over src/. Stated blind spots: a container declared in another file, an auto-typed container, a comparator lambda that applies < to string_views itself. Dynamic twin: extentsuspect_unit gains an R2 case whose class names prefix one another (Tree, TreeGuard, TreeGuardScope). extentcheck (U) builds the driver with the binary's own flags, so under the Linux ASan build the unfixed header aborts it (`9 - 14` from resetExtentScratch, rc=134, (U) FAIL); with the fix it passes and pins the answers on every platform. VERIFIED in an ubuntu:24.04 aarch64 container (clang 18, libstdc++ 13) under the asan job's exact env, log_path=/tmp/asanlog included: ripwire_asan_fixture rc=0; packtaskcheck ALL PASS (39, both refusal arms print again) with /tmp/asanlog* empty; tracecheck, qualitycheck, mergescoutcheck, cachefuzzcheck, extentcheck and macroreparsecheck ALL PASS; det-gate and xmllint pass; --for over src/ rc=0; a bare --pack-task refuses rc=1. editcheckcheck and cppqualcheck went red in that container for a reason that is neither this lane's nor CI's: the vendored tree-sitter-yaml scanner returns SCN_FAIL (-1) from `static char scn_pln_cnt` (third_party/deps/yaml/src/scanner.c:828), char is UNSIGNED on aarch64 Linux, and G1's implicit-integer-sign-change aborts every whole-repo ingest that meets a YAML file. x86-64 and Apple arm64 have signed char, so neither CI leg can see it; main 096e354 fails both gates identically in the same container. With that one file exempted by a verification-only ignorelist (not part of this commit), whole-repo --for, editcheckcheck (48 PASS / 0 FAIL), cppqualcheck (66 / 0) and --doc-drift all exit 0 with /tmp/asanlog* empty — so no ripwire code, #135's extent and re-parse passes over the whole repo included, trips a sanitizer there. macOS plain build --clean-first: portablebuildcheck, extentcheck ((U) 20 rule cases), macroreparsecheck, packtaskcheck, gateexitcheck, binoverridecheck, worktreeleakcheck, manifestcheck, ripwirepubliccheck, docscommandscheck and showcasecapturecheck pass; --quality-delta gating=0 (two minor rows: the unit driver's main() grew by its new case). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
… row A C++ out-of-line member of a class template whose template-argument list spans source lines has a scope holding that line break verbatim, and --pin-census wrote ids raw. One C row became a 6-field line plus a continuation line starting with neither C/S/O nor #, and the symbol's S row broke the same way (seen once on a large private C++ corpus). The map never had the defect: escapeXml writes the same scope as &redhat-et#10;. Five more spellings reproduce on the pre-fix binary: a TAB or a form feed in the argument list, a backslash line splice, CRLF source, and a | inside an id, which is the targets separator. The fix: every id and callee field goes through appendCensusField (a Byteset256 + appendCleanRun escaper, the escapeXml shape): \ -> \\, TAB/LF/CR -> \t \n \r, every other C0 byte and | -> \xHH. Columns are unchanged and an id without those bytes is byte-identical to v2; the header line says v3 and documents the escape. bench/scip_match_diag.py decodes the fields (it opens files by an id's path); scip_pin_precision.py joins ids as opaque keys. Measured, pre-fix vs fixed binary over a clean `git archive a55b118` export: 99 of 51,821 rows change (18 C, 81 S; 98 hold |, 1 a backslash) and all 99 decode back to their pre-fix bytes; the 18 C rows are Markdown-heading targets such as `--token-budget=N[K|M|G]` that a |-split read as 2-6 targets (18 misread before, 0 after). Every other row is byte-identical. Gate: test/pincensuscheck.sh arm (L), over a generated fixture (a pipe|dir directory, CRLF and TAB bytes are never committed). Every non-comment line is a C/S/O row with its field count (also over the (B) and (G) censuses); each awkward caller id decodes to its source bytes, re-encodes identically and is an S id verbatim; the | target splits to one id; dispositions and summary counts match what a line reader parses; a control un-escapes one C row and the same shape check sees it. (B) now expects v3. The \xHH digits come from a constexpr table, not a format call into a char[] (test/fixedbufsweep.sh refuses an unclassified fixed buffer), and a form-feed case holds the zero-padded low-byte path to the documented rule. Red on the pre-fix binary: 12 FAIL (a line reader parsed 2 of 6 C rows and 12 of 16 S ids). Green: 52 PASS, also under ./asan/ripwire, which reports nothing over the census fixtures. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…led like the appended token On a clean tree --pr-context's whole truncated= value is "budget-floor-exceeded" (no trim level to append to), so the settle that removes ";budget-floor-exceeded" from an answer that fits once compacted missed it: est_tokens=374 inside --max-tokens=500..2000 still claimed the floor was exceeded (prbudgetcheck redhat-et#10). The whole attribute is removed there, and its compact reading with it. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Two reader-facing changes, both content-preserving:
<details>blocks (21 new, 25 total). Scrolling the README now reads as an executive summary with every deep-dive one click away.Nothing was deleted or reworded: every non-blank pre-edit line is still present verbatim (verified mechanically); all heading anchors still resolve, including the ones other docs link into.
### In the numbersdeliberately stays unfolded — the counterexample list is link-targeted and should never hide.Gate suite:
gates=361 pass=358 skip=3 fail=0(the three standing skips), deckcheck clean on the new prose.🤖 Generated with Claude Code