test: property-check display-width clustering and parseKey totality - #598
Conversation
Six fast-check properties over the ui-02 measurement layer and the stdin key parser: - displayWidth is total, integer, non-negative, and bounded by two columns per code point over an adversarial alphabet (ZWJ, VS-16, keycap, combining marks, skin tones, regional indicators, CJK, emoji) - plain alphabets (no joiners/modifiers) sum per-character widths exactly and concatenate additively - the table formatter's standing assumption - truncateToWidth returns a self-consistent prefix (its reported width IS displayWidth of the kept text), stays in budget, stops only when the remaining gap is 0 or 1 columns (clusters max out at 2), and is idempotent - truncation prefixes grow monotonically with the width budget - parseKey is total over arbitrary byte buffers and only returns known KeyAction values - the full recognized-sequence table is pinned, and everything else maps to null Companion to the property suites in #574/#575/#592-#597. https://claude.ai/code/session_01XNtnkLbBiXZxfQQYLMpucB
|
Codex usage limits have been reached for code reviews. Please check with the admins of this repo to increase the limits by adding credits. |
|
Warning Review limit reached
More reviews will be available in 29 minutes and 40 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 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 refill rate. 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, the refill rate gradually slows as usage increases. The highest same-day bursts are limited more strictly. Please see our Fair Usage Limits Policy for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro Run ID: 📒 Files selected for processing (1)
✨ Finishing Touches🧪 Generate unit tests (beta)
✨ Simplify code
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 |
One extra budget column can admit at most two more columns of content, which is externally equivalent to 'no cluster wider than 2' - the assumption the truncation maximality bound relies on. https://claude.ai/code/session_01XNtnkLbBiXZxfQQYLMpucB
) * test: property-check forecast recommendation and summary contracts Seven fast-check properties over recommendForecastAccount, summarizeForecast, and buildForecastExplanation with generated result pools (0-8 accounts, full availability/risk/wait/flag space): - a recommendation always points at a recommendable result (not disabled, hard-failed, exhausted, or unavailable); null only when no such candidate exists - a ready candidate always wins with the minimal risk score among ready candidates, and the reason says so - with no ready candidate, the shortest delayed wait wins - an empty candidate pool names the actual blocker class: 'blocked or exhausted' guidance iff some account is blocked/exhausted rather than disabled/hard-failed (the #exhausted-flag regression guard) - the recommendation is invariant under input order - the summary partitions availability exactly (ready + delayed + unavailable === total) and counts high-risk rows - the explanation mirrors inputs in order and marks selected on exactly the recommended index Companion to the property suites in #574/#575/#592-#598. https://claude.ai/code/session_01XNtnkLbBiXZxfQQYLMpucB * test: keep forecast generator in the reachable domain; shuffle permutations Greptile flagged that availability and exhausted were drawn independently (evaluateForecastAccount only emits exhausted accounts as delayed) and that order-invariance only probed reversal. The generator now derives the pairing, and the invariance property checks an arbitrary generated permutation plus the reversal. Validated at FAST_CHECK_NUM_RUNS=1000. https://claude.ai/code/session_01XNtnkLbBiXZxfQQYLMpucB --------- Co-authored-by: Claude <[email protected]>
Summary
lib/ui/display-width.ts(the ui-02 column-measurement implementation with grapheme clustering) andlib/ui/ansi.ts'sparseKey(raw stdin bytes → key action, which must be total).What Changed
New
test/property/display-width.property.test.ts(6 properties):display-width — generated over an adversarial alphabet that includes every cluster mechanic the implementation special-cases (ZWJ, variation selector-16, combining keycap, combining accents, skin-tone modifiers, regional indicators, CJK, emoji):
displayWidthreturns a non-negative integer bounded by two columns per code point, for any combination including pathological joiner/modifier soup.truncateToWidthreturns a prefix whose reported width isdisplayWidthof the kept text (self-consistency between the two exports), never exceeds the budget, stops early only when the remaining gap is 0–1 columns (clusters max out at 2, so a 2-column gap proves the next cluster would have fit), and is idempotent.parseKey:
KeyActionunion; no input throws.null.No SUT bugs found.
Validation
npm test -- test/property/display-width.property.test.ts test/display-width.test.ts test/ansi.test.ts— 25/25 (new 6 + existing suites untouched)npm run typecheck(also via pre-commit hook)npx eslint test/property/display-width.property.test.ts --max-warnings=0Docs and Governance Checklist
Risk and Rollback
test/property/suites.https://claude.ai/code/session_01XNtnkLbBiXZxfQQYLMpucB
Generated by Claude Code
note: greptile review for oc-chatgpt-multi-auth. cite files like
lib/foo.ts:123. confirm regression tests + windows concurrency/token redaction coverage.Greptile Summary
adds six fast-check property tests for
lib/ui/display-width.tsandlib/ui/ansi.ts#parseKey. the suite covers totality/bounds over an adversarial grapheme-cluster alphabet, a plain-text additive-width oracle, truncation self-consistency / maximality / idempotence, budget monotonicity with an embedded cluster-granularity guard, and parseKey totality + known-sequence table fidelity. no SUT bugs were found during the review.step.width - narrow.width ≤ 2assertion.fc.uint8Array→Bufferto probe raw bytes; table-fidelity test covers all 16 recognized ANSI escape sequences and asserts unknown strings map tonull.Confidence Score: 5/5
purely additive test file with no changes to production code — safe to merge
the change is a single new test file exercising well-understood pure functions with no side effects; the properties are logically sound, the adversarial alphabet covers all cluster mechanics the SUT special-cases, and there are no changes to library code, configuration, or any auth/token path
no files require special attention
Important Files Changed
Flowchart
%%{init: {'theme': 'neutral'}}%% flowchart TD A[arbAdversarialText\nfc.array of grapheme cluster atoms] --> P1[Property 1\ndisplayWidth totality + bounds] B[arbPlainText\nfc.array of plain chars] --> P2[Property 2\nplain-text width oracle] A --> P3[Property 3\ntruncation self-consistency\nmaximality · idempotence] A --> P4[Property 4\nmonotonicity + cluster-granularity\nstep.width − narrow.width ≤ 2] C[fc.uint8Array maxLength 12] --> P5[Property 5\nparseKey totality\nKEY_ACTIONS.includes result] D[16 literal ANSI sequences] --> P6a[Table fidelity\nknown sequences → correct action] E[fc.string maxLength 6\nfiltered by pre] --> P6b[Unrecognized → null] P6a --> SUT2[parseKey\nBuffer → KeyAction] P6b --> SUT2 P5 --> SUT2 P1 --> SUT1[displayWidth\nstring → number] P2 --> SUT1 P3 --> SUT3[truncateToWidth\nstring × budget → text × width] P4 --> SUT3%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%% flowchart TD A[arbAdversarialText\nfc.array of grapheme cluster atoms] --> P1[Property 1\ndisplayWidth totality + bounds] B[arbPlainText\nfc.array of plain chars] --> P2[Property 2\nplain-text width oracle] A --> P3[Property 3\ntruncation self-consistency\nmaximality · idempotence] A --> P4[Property 4\nmonotonicity + cluster-granularity\nstep.width − narrow.width ≤ 2] C[fc.uint8Array maxLength 12] --> P5[Property 5\nparseKey totality\nKEY_ACTIONS.includes result] D[16 literal ANSI sequences] --> P6a[Table fidelity\nknown sequences → correct action] E[fc.string maxLength 6\nfiltered by pre] --> P6b[Unrecognized → null] P6a --> SUT2[parseKey\nBuffer → KeyAction] P6b --> SUT2 P5 --> SUT2 P1 --> SUT1[displayWidth\nstring → number] P2 --> SUT1 P3 --> SUT3[truncateToWidth\nstring × budget → text × width] P4 --> SUT3Prompt To Fix All With AI
Reviews (3): Last reviewed commit: "Merge branch 'main' into claude/audit-79..." | Re-trigger Greptile