Skip to content

test(viewer): session-ledger token estimator proptest surface (WBS-6.2 #467) - #487

Merged
KooshaPari merged 1 commit into
mainfrom
fix/viewer-token-estimator-properties-20260809
Aug 12, 2026
Merged

test(viewer): session-ledger token estimator proptest surface (WBS-6.2 #467)#487
KooshaPari merged 1 commit into
mainfrom
fix/viewer-token-estimator-properties-20260809

Conversation

@KooshaPari

@KooshaPari KooshaPari commented Aug 10, 2026

Copy link
Copy Markdown
Owner

User description

WBS-6.2 surface 7: session-ledger distill pipeline.

Branch off fix/viewer-mock-data-properties-20260809 rebased main. Test file compiles and passes locally.


CodeAnt-AI Description

Add property coverage for session-ledger token estimation

What Changed

  • Added randomized checks that text estimates use Unicode character counts and round up at four-character boundaries
  • Verified estimates remain deterministic, monotonic, finite, and safe across empty, repeated, Unicode, and boundary-length inputs
  • Verified JSON estimates match compact serialized content and the shared estimator behavior
  • Recorded the new token-estimator coverage in the changelog, WBS evidence, and traceability records

Impact

✅ Reliable token budgets for Unicode session content
✅ Consistent JSON token estimates
✅ Fewer silent budget calculation errors

💡 Usage Guide

Checking Your Pull Request

Every time you make a pull request, our system automatically looks through it. We check for security issues, mistakes in how you're setting up your infrastructure, and common code problems. We do this to make sure your changes are solid and won't cause any trouble later.

Talking to CodeAnt AI

Got a question or need a hand with something in your pull request? You can easily get in touch with CodeAnt AI right here. Just type the following in a comment on your pull request, and replace "Your question here" with whatever you want to ask:

@codeant-ai ask: Your question here

This lets you have a chat with CodeAnt AI about your pull request, making it easier to understand and improve your code.

Example

@codeant-ai ask: Can you suggest a safer alternative to storing this secret?

Preserve Org Learnings with CodeAnt

You can record team preferences so CodeAnt AI applies them in future reviews. Reply directly to the specific CodeAnt AI suggestion (in the same thread) and replace "Your feedback here" with your input:

@codeant-ai: Your feedback here

This helps CodeAnt AI learn and adapt to your team's coding style and standards.

Example

@codeant-ai: Do not flag unused imports.

Retrigger review

Ask CodeAnt AI to review the PR again, by typing:

@codeant-ai: review

Check Your Repository Health

To analyze the health of your code repository, visit our dashboard at https://app.codeant.ai. This tool helps you identify potential issues and areas for improvement in your codebase, ensuring your repository maintains high standards of code health.

Copilot AI lite review requested due to automatic review settings August 10, 2026 08:39
@codeant-ai

codeant-ai Bot commented Aug 10, 2026

Copy link
Copy Markdown

🤖 CodeAnt AI — Review Status

Status Commit Started (UTC) Finished (UTC)
✅ Incremental review completed 56f617f Aug 12, 2026 · 08:13 08:13
✅ Reviewed your PR 9d5b044 Aug 10, 2026 · 08:40 08:42

@codeant-ai

codeant-ai Bot commented Aug 10, 2026

Copy link
Copy Markdown

Thanks for using CodeAnt! 🎉

We're free for open-source projects. if you're enjoying it, help us grow by sharing.

Share on X ·
Reddit ·
LinkedIn

Copilot AI 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.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@coderabbitai

coderabbitai Bot commented Aug 10, 2026

Copy link
Copy Markdown

Warning

Review limit reached

@KooshaPari, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 2 minutes

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

How can I continue?

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

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

How do review limits work?

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

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

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 410c80d3-7ee8-41bb-8cd8-19ea2b703887

📥 Commits

Reviewing files that changed from the base of the PR and between 5d2c60c and 9d5b044.

📒 Files selected for processing (6)
  • CHANGELOG.md
  • crates/sl-viewer/tests/properties_session_ledger_context.rs
  • crates/sl-viewer/tests/properties_session_ledger_contract.rs
  • crates/sl-viewer/tests/properties_session_ledger_token_estimator.rs
  • docs/ops/TRACEABILITY.json
  • docs/ops/WBS.md

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.

@codeant-ai codeant-ai Bot added the size:XXL This PR changes 1000+ lines, ignoring generated files label Aug 10, 2026
…#467)

Shards the unique viewer proptest from #487 onto main without the
obsolete pre-rename daemon source churn.
@KooshaPari
KooshaPari force-pushed the fix/viewer-token-estimator-properties-20260809 branch from 9d5b044 to 56f617f Compare August 12, 2026 08:13
@KooshaPari
KooshaPari merged commit 44f5186 into main Aug 12, 2026
4 of 8 checks passed
@codeant-ai

codeant-ai Bot commented Aug 12, 2026

Copy link
Copy Markdown

Thanks for using CodeAnt! 🎉

We're free for open-source projects. if you're enjoying it, help us grow by sharing.

Share on X ·
Reddit ·
LinkedIn

@KooshaPari
KooshaPari deleted the fix/viewer-token-estimator-properties-20260809 branch August 12, 2026 08:13
@codeant-ai codeant-ai Bot added size:L This PR changes 100-499 lines, ignoring generated files and removed size:XXL This PR changes 1000+ lines, ignoring generated files labels Aug 12, 2026
Comment thread CHANGELOG.md
- session-ledger heuristic context extractor property surface (WBS-6.2 #464): `crates/sl-viewer/tests/properties_session_ledger_context.rs` adds 20 proptest properties pinning `session_ledger::distill::context_extractor::HeuristicContextExtractor::extract_context` (the P2 adapter for [`ContextExtractor`] — drives the working-context slice of any `ContinuationBundle`). `cwd` and `title` are always copied verbatim from the session. Empty sessions and whitespace-only messages yield an empty `Context`. Every detected file path is non-empty, ≥3 chars, and either contains a `/` or ends with a documented extension. Every documented file extension (28 of them: `.rs`, `.ts`, `.tsx`, `.js`, `.jsx`, `.py`, `.go`, `.java`, `.kt`, `.rb`, `.c`, `.h`, `.cpp`, `.hpp`, `.cs`, `.swift`, `.toml`, `.json`, `.yaml`, `.yml`, `.md`, `.sql`, `.css`, `.scss`, `.html`, `.sh`, `.tf`, `.lock`) is detected. Files / symbols / decisions / environment notes are deduplicated across messages. Decision summaries all read `Session contains '<pattern>' language` and rationale equals the source message. Every documented decision pattern (15 of them) and every documented environment pattern (19 of them) is detected, both case-insensitively. Symbols are extracted only from tokens containing `::` or `()`. `extract_context` is deterministic across calls, and the `ContextExtractor` trait path returns the same `Context` as the associated function.
- session-ledger heuristic contract extractor property surface (WBS-6.2 #465): `crates/sl-viewer/tests/properties_session_ledger_contract.rs` adds 18 proptest properties pinning `session_ledger::distill::contract_extractor::HeuristicContractExtractor::extract_contract` (the P2 adapter for [`ContractExtractor`] — drives the acceptance-contract slice of any `ContinuationBundle`). Empty sessions and whitespace-only messages yield an empty `Contract`. Every section string has a documented prefix and suffix shape (`Goal/requirement: '...'`, `Verification: '...'`, `Constraint: '...'`, `Do-not-touch: '...'`). Every documented criteria pattern (12 of them), test pattern (21 of them), constraint pattern (15 of them), and do-not-touch pattern (14 of them) is detected, and all patterns match case-insensitively. Success criteria / tests / constraints / do-not-touch lists are deduplicated across messages. `extract_contract` is deterministic across calls, and the `ContractExtractor` trait path returns the same `Contract` as the associated function. `is_empty()` is true iff every collection is empty.
- session-ledger heuristic acceptance extractor property surface (WBS-6.2 #466): `crates/sl-viewer/tests/properties_session_ledger_acceptance.rs` adds 25 proptest properties pinning `session_ledger::distill::acceptance_extractor::HeuristicAcceptanceExtractor::extract_acceptance` (the P3 adapter for [`AcceptanceExtractor`] — drives the acceptance-evidence slice of any `ContinuationBundle`). Empty sessions and whitespace-only messages yield an empty `Acceptance`. Every section string has a documented prefix and suffix shape (`Evidence: '...'`, `Testing: '...'`). Every documented EVIDENCE_PATTERN (31 of them), USER_CONFIRMATION_PATTERN (19 of them), and TESTING_EVIDENCE_PATTERN (14 of them) is detected, and all patterns match case-insensitively. `user_confirmed` is gated on `Role::User` messages — assistant-side confirmation phrases do NOT trigger `user_confirmed`. Evidence and testing_evidence are deduplicated across messages and emit in sorted order. `satisfaction_score = (unique_evidence + user_messages_with_confirmation) * 10`, capped at 100, and saturates at 100 once the signal budget is exceeded. `extract_acceptance` is deterministic across calls, and the `AcceptanceExtractor` trait path returns the same `Acceptance` as the associated function. `is_empty()` is true iff every collection is empty AND `user_confirmed` is false (a non-zero `satisfaction_score` alone does NOT make `Acceptance` non-empty).
- session-ledger token estimator property surface (WBS-6.2 #467): `crates/sl-viewer/tests/properties_session_ledger_token_estimator.rs` adds 24 proptest properties pinning `session_ledger::distill::token_estimator::CharCountTokenEstimator` (the bounded token-budget accountant for the distill pipeline — backs every `token_estimate()` query on a `Bundle` slice). `estimate_text` always equals `(chars + 3) / 4` (ceiling-division rounding up at every 4-char boundary), the documented fixed points (`n=1..=9` → `1, 1, 1, 1, 2, 2, 2, 2, 3`) hold, and the estimator counts unicode scalar values (chars) — not UTF-8 bytes (4 × `🦀` = 4 chars = 1 token, even though those are 16 UTF-8 bytes). `estimate_text` is deterministic, finite (u32), never panics on any unicode input (CJK / RTL / emoji / combining marks), and is monotonic for prefixes (`est(text) ≥ est(prefix)`). `estimate_text(s.repeat(n))` follows the exact `(chars(s) * n + 3) / 4` contract. `estimate_json(&v)` always equals `estimate_text(&v.to_string())` — i.e. it uses compact serialisation with no whitespace — and is total over `Null / Bool / Number / String / Array / Object`. `CharCountTokenEstimator` is `Default + Copy + Clone`, and the trait-default `estimate_json` delegates to `estimate_text` (verified with a dummy estimator that overrides `estimate_text`).

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

WARNING: Acceptance extractor (#466) entry removed from CHANGELOG

The acceptance extractor property surface (WBS-6.2 #466) entry was replaced by the token estimator (#467) entry. The CHANGELOG should add the new #467 entry while preserving the existing #466 entry. Removing historical PR entries breaks the changelog's role as an audit trail.


Reply with @kilocode-bot fix it to have Kilo Code address this issue.

"crates/sl-viewer/tests/properties_session_ledger_context.rs",
"crates/sl-viewer/tests/properties_session_ledger_contract.rs",
"crates/sl-viewer/tests/properties_session_ledger_acceptance.rs",
"crates/sl-viewer/tests/properties_session_ledger_token_estimator.rs",

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

WARNING: Acceptance extractor test file removed from TRACEABILITY.json

The acceptance extractor test file (properties_session_ledger_acceptance.rs) was replaced by the token estimator test file in the traceability list. TRACEABILITY.json should include ALL property test files, not replace existing entries. This breaks traceability to PR #466.


Reply with @kilocode-bot fix it to have Kilo Code address this issue.

Comment thread docs/ops/WBS.md
| WBS-5.1 | P5 deterministic dedup merge and crash/lost-work recovery E2E | done | machine | `src/domain/merge.rs`; `src/domain/worklog.rs`; `tests/merge_recovery.rs` | FR-011; T-024, T-035; C03 |
| WBS-6.1 | P6 85% coverage gate and deterministic golden corpus | done | machine | `.github/workflows/ci.yml`; `tests/okf_golden.rs`; `tests/fixtures/okf/` | T-037, T-038; C01, C08 |
| WBS-6.2 | P6 property tests, fuzzing, race checks, and enforced performance budgets | partial | machine | `tests/properties.rs`; `crates/sl-viewer/tests/properties_viewer.rs`; `crates/sl-viewer/tests/properties_viewer_theme_url.rs`; `crates/sl-viewer/tests/properties_viewer_unfinished_tab.rs`; `crates/sl-viewer/tests/properties_viewer_timeline.rs`; `crates/sl-viewer/tests/properties_viewer_search_memory.rs`; `crates/sl-viewer/tests/properties_viewer_history.rs`; `crates/sl-viewer/tests/properties_viewer_web_exports.rs`; `crates/sl-viewer/tests/properties_viewer_bundle_detail.rs`; `crates/sl-viewer/tests/properties_viewer_bundle_diff.rs`; `crates/sl-viewer/tests/properties_viewer_mock_data.rs`; `crates/sl-viewer/tests/properties_viewer_cli_help.rs`; `crates/sl-viewer/tests/properties_viewer_corpus_cta.rs`; `crates/sl-viewer/tests/properties_viewer_theme.rs`; `crates/sl-viewer/tests/properties_viewer_settings.rs`; `crates/sl-viewer/tests/properties_viewer_corpus_paths.rs`; `crates/sl-viewer/tests/properties_viewer_help_overlay.rs`; `crates/sl-viewer/tests/properties_viewer_settings_tab.rs`; `crates/sl-viewer/tests/properties_viewer_menu.rs`; `crates/sl-viewer/tests/properties_viewer_async_states.rs`; `crates/sl-viewer/tests/properties_session_ledger_okf.rs`; `crates/sl-viewer/tests/properties_session_ledger_worklog.rs`; `crates/sl-viewer/tests/properties_session_ledger_export.rs`; `crates/sl-viewer/tests/properties_session_ledger_distill.rs`; `crates/sl-viewer/tests/properties_session_ledger_intent.rs`; `crates/sl-viewer/tests/properties_session_ledger_context.rs`; `crates/sl-viewer/tests/properties_session_ledger_acceptance.rs`; `fuzz/fuzz_targets/okf_roundtrip.rs`; `fuzz/fuzz_targets/jsonl_ingest.rs`; `.github/workflows/ci.yml`; `.github/workflows/bench-gate.yml`; `docs/ops/perf-baseline.json`; `scripts/bench-gate.ps1`; `benches/pipeline.rs`; `tests/loom_model.rs` | DESIGN P6 residual; C00 L6-L8; C07 L66-L68; C08 L74; perf-budget enforced Wave-26 #223; p95 latency enforced Wave-30 #256; FSM properties Wave-31 #261; soft loom Wave-31 #264; viewer corpus_paths/parquet/settings properties #425; viewer theme + daemon_url properties #427; viewer unfinished_tab properties + fuzz/rootless CI drift fixes #428; viewer bundle_diff + timeline properties + web_exports/hmetic-pin cleanups #432; viewer bundle_diff properties #434; viewer search/memory properties #435; viewer history_tab properties #444; viewer web_exports properties #437; viewer bundle_list + detail_pane properties #436; viewer mock_data fixture properties #451; viewer cli_help / command_palette properties #452; viewer corpus_cta constants properties #453; viewer theme + settings properties #454; viewer corpus_paths round-trip properties #446; viewer help_overlay shortcuts properties #455; viewer settings_tab HealthStatus properties #456; viewer menu id taxonomy properties #457; viewer async_states SkeletonLayout properties #458; session-ledger OKF document validator properties #459; session-ledger worklog projector properties #460; session-ledger OKF export adapter properties #461; session-ledger distill compiler properties #462; session-ledger heuristic intent extractor properties #463; session-ledger heuristic context extractor properties #464; session-ledger heuristic contract extractor properties #465; session-ledger heuristic acceptance extractor properties #466; full loom/shuttle unpaid |
| WBS-6.2 | P6 property tests, fuzzing, race checks, and enforced performance budgets | partial | machine | `tests/properties.rs`; `crates/sl-viewer/tests/properties_viewer.rs`; `crates/sl-viewer/tests/properties_viewer_theme_url.rs`; `crates/sl-viewer/tests/properties_viewer_unfinished_tab.rs`; `crates/sl-viewer/tests/properties_viewer_timeline.rs`; `crates/sl-viewer/tests/properties_viewer_search_memory.rs`; `crates/sl-viewer/tests/properties_viewer_history.rs`; `crates/sl-viewer/tests/properties_viewer_web_exports.rs`; `crates/sl-viewer/tests/properties_viewer_bundle_detail.rs`; `crates/sl-viewer/tests/properties_viewer_bundle_diff.rs`; `crates/sl-viewer/tests/properties_viewer_mock_data.rs`; `crates/sl-viewer/tests/properties_viewer_cli_help.rs`; `crates/sl-viewer/tests/properties_viewer_corpus_cta.rs`; `crates/sl-viewer/tests/properties_viewer_theme.rs`; `crates/sl-viewer/tests/properties_viewer_settings.rs`; `crates/sl-viewer/tests/properties_viewer_corpus_paths.rs`; `crates/sl-viewer/tests/properties_viewer_help_overlay.rs`; `crates/sl-viewer/tests/properties_viewer_settings_tab.rs`; `crates/sl-viewer/tests/properties_viewer_menu.rs`; `crates/sl-viewer/tests/properties_viewer_async_states.rs`; `crates/sl-viewer/tests/properties_session_ledger_okf.rs`; `crates/sl-viewer/tests/properties_session_ledger_worklog.rs`; `crates/sl-viewer/tests/properties_session_ledger_export.rs`; `crates/sl-viewer/tests/properties_session_ledger_distill.rs`; `crates/sl-viewer/tests/properties_session_ledger_intent.rs`; `crates/sl-viewer/tests/properties_session_ledger_context.rs`; `crates/sl-viewer/tests/properties_session_ledger_token_estimator.rs`; `fuzz/fuzz_targets/okf_roundtrip.rs`; `fuzz/fuzz_targets/jsonl_ingest.rs`; `.github/workflows/ci.yml`; `.github/workflows/bench-gate.yml`; `docs/ops/perf-baseline.json`; `scripts/bench-gate.ps1`; `benches/pipeline.rs`; `tests/loom_model.rs` | DESIGN P6 residual; C00 L6-L8; C07 L66-L68; C08 L74; perf-budget enforced Wave-26 #223; p95 latency enforced Wave-30 #256; FSM properties Wave-31 #261; soft loom Wave-31 #264; viewer corpus_paths/parquet/settings properties #425; viewer theme + daemon_url properties #427; viewer unfinished_tab properties + fuzz/rootless CI drift fixes #428; viewer bundle_diff + timeline properties + web_exports/hmetic-pin cleanups #432; viewer bundle_diff properties #434; viewer search/memory properties #435; viewer history_tab properties #444; viewer web_exports properties #437; viewer bundle_list + detail_pane properties #436; viewer mock_data fixture properties #451; viewer cli_help / command_palette properties #452; viewer corpus_cta constants properties #453; viewer theme + settings properties #454; viewer corpus_paths round-trip properties #446; viewer help_overlay shortcuts properties #455; viewer settings_tab HealthStatus properties #456; viewer menu id taxonomy properties #457; viewer async_states SkeletonLayout properties #458; session-ledger OKF document validator properties #459; session-ledger worklog projector properties #460; session-ledger OKF export adapter properties #461; session-ledger distill compiler properties #462; session-ledger heuristic intent extractor properties #463; session-ledger heuristic context extractor properties #464; session-ledger heuristic contract extractor properties #465; session-ledger token estimator properties #467; full loom/shuttle unpaid |

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

WARNING: Acceptance extractor file and PR reference removed from WBS-6.2

The WBS-6.2 row replaces the acceptance extractor test file and PR #466 reference with the token estimator file and PR #467. The WBS tracking table should accumulate evidence, not replace prior entries. This breaks the WBS audit trail for #466.


Reply with @kilocode-bot fix it to have Kilo Code address this issue.

@kilo-code-bot

kilo-code-bot Bot commented Aug 12, 2026

Copy link
Copy Markdown

Code Review Summary

Status: 3 Warnings Found | Recommendation: Address in follow-up (PR already merged)

Overview

Severity Count
CRITICAL 0
WARNING 3
SUGGESTION 0
Issue Details (click to expand)

WARNING

File Line Issue
CHANGELOG.md 73 Acceptance extractor (#466) entry removed from CHANGELOG
docs/ops/TRACEABILITY.json 336 Acceptance extractor test file removed from TRACEABILITY.json
docs/ops/WBS.md 32 Acceptance extractor file and PR reference removed from WBS-6.2
Files Reviewed (4 files)
  • CHANGELOG.md - 1 warning
  • docs/ops/TRACEABILITY.json - 1 warning
  • docs/ops/WBS.md - 1 warning
  • crates/sl-viewer/tests/properties_session_ledger_token_estimator.rs - no issues

Fix these issues in Kilo Cloud


Reviewed by step-3.7-flash · Input: 119K · Output: 28.6K · Cached: 1.7M

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:L This PR changes 100-499 lines, ignoring generated files

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants