Skip to content

test(viewer): tokens SSOT proptest surface (WBS-6.2 #450) - #463

Closed
KooshaPari wants to merge 1 commit into
mainfrom
fix/viewer-tokens-properties-20260808
Closed

test(viewer): tokens SSOT proptest surface (WBS-6.2 #450)#463
KooshaPari wants to merge 1 commit into
mainfrom
fix/viewer-tokens-properties-20260808

Conversation

@KooshaPari

@KooshaPari KooshaPari commented Aug 9, 2026

Copy link
Copy Markdown
Owner

User description

Summary

Adds crates/sl-viewer/tests/properties_viewer_tokens.rs with 10 proptest properties pinning the tokens module SSOT invariants (WBS-6.2 #450).

lab_coat::* (4 properties)

  • Every hex is a well-formed #RRGGBB (7-char lowercase ASCII hex).
  • Every hex is non-empty.
  • All 16 documented hex constants are pairwise distinct.
  • Every hex appears in TOKENS_CSS.

REQUIRED_CSS_VARS (4 properties)

  • Every entry starts with --.
  • Every entry is non-empty.
  • The set is duplicate-free.
  • Every entry appears in TOKENS_CSS.

VIEWER_COLOR_SCHEME (2 properties)

  • Declares both :root and :root[data-theme="dark"] selectors.
  • Uses color-scheme exactly twice.

Validation

  • cargo test -p sl-viewer --test properties_viewer_tokens --features "desktop parquet" --locked — 10 passed
  • cargo fmt --all --check — clean

WBS / TRACEABILITY

WBS-6.2 evidence list and TRACEABILITY.json gain crates/sl-viewer/tests/properties_viewer_tokens.rs. CHANGELOG Unreleased documents the new surface.


CodeAnt-AI Description

Add property coverage for viewer design tokens and theme wiring

What Changed

  • Adds 10 property tests that verify viewer color values are valid, unique, and present in the shared CSS token definitions
  • Checks required CSS variables are valid, unique, and included in the token stylesheet
  • Verifies light and dark theme selectors both define the browser color scheme
  • Records the new test coverage in the changelog and WBS traceability documents

Impact

✅ Earlier detection of mismatched viewer colors
✅ Fewer missing or duplicate CSS variables
✅ Safer light and dark theme behavior

💡 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.

Adds crates/sl-viewer/tests/properties_viewer_tokens.rs with 10
proptest properties pinning the design-token SSOT invariants:

* lab_coat::*:
  * Every hex is a well-formed #RRGGBB (7-char lowercase ASCII hex).
  * Every hex is non-empty.
  * All 16 documented hex constants are pairwise distinct.
  * Every hex appears in TOKENS_CSS so the Rust mirror and the
    CSS SSOT stay in sync.
* REQUIRED_CSS_VARS:
  * Every entry starts with --.
  * Every entry is non-empty.
  * The set is duplicate-free.
  * Every entry appears in TOKENS_CSS.
* VIEWER_COLOR_SCHEME:
  * Declares both :root and :root[data-theme dark] selectors.
  * Uses color-scheme exactly twice.

Updates WBS-6.2 evidence list, TRACEABILITY.json, and CHANGELOG.
Copilot AI lite review requested due to automatic review settings August 9, 2026 22:06
@codeant-ai

codeant-ai Bot commented Aug 9, 2026

Copy link
Copy Markdown

🤖 CodeAnt AI — Review Status

Status Commit Started (UTC) Finished (UTC)
✅ Reviewed your PR 3f5b68b Aug 09, 2026 · 22:06 22:08

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.

@codeant-ai

codeant-ai Bot commented Aug 9, 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

@codeant-ai codeant-ai Bot added the size:L This PR changes 100-499 lines, ignoring generated files label Aug 9, 2026
@coderabbitai

coderabbitai Bot commented Aug 9, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Summary

The PR adds property tests for viewer token formatting, uniqueness, CSS synchronization, required variables, and color-scheme declarations. It also updates WBS-6.2 evidence and documentation.

Must Fix

The lab_coat_hex_list() test list is manually maintained. Adding a new lab_coat constant will not fail the tests until a developer also updates the test list. Therefore, the claimed exhaustiveness check does not enforce the SSOT invariant.

Use a single source for the constant list, or add an explicit test mechanism that detects newly added lab_coat constants.

Should Fix

The tests named as property tests use constant dummy ranges such as 0u8..4 for whole-list invariants. Use ordinary unit tests for deterministic collection checks, or generate meaningful inputs.

Run the repository-mandated full checks if CI does not cover them:

  • cargo test --all-features --locked
  • cargo clippy --all-targets --all-features
  • cargo fmt --all --check

Consider

The contains checks validate substring presence, not complete CSS declarations. Matching the variable or color token in the expected declaration would reduce false positives.

Approve / Request Changes

Request changes. The manual constant list undermines the primary exhaustiveness claim of the new test surface.

Walkthrough

The PR adds property-based tests for sl_viewer::tokens invariants. It validates Lab-Coat colors, required CSS variables, token CSS inclusion, and light/dark color-scheme declarations. Changelog and WBS traceability records now reference the test coverage.

Changes

Viewer token validation

Layer / File(s) Summary
Token property tests and evidence
crates/sl-viewer/tests/properties_viewer_tokens.rs, CHANGELOG.md, docs/ops/TRACEABILITY.json, docs/ops/WBS.md
Property tests validate color formatting, non-empty and unique values, CSS variable names, token CSS inclusion, and exactly two color-scheme declarations. Changelog and WBS evidence references include the new test coverage.

Estimated code review effort: 2 (Simple) | ~10 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description check ✅ Passed The description clearly summarizes the viewer token property tests, validation, and related traceability updates.
Title check ✅ Passed The title concisely identifies the viewer token property-test surface and its WBS-6.2 scope.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
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.
✨ Finishing Touches 💡 2
⚔️ Resolve merge conflicts 💡
  • Resolve merge conflict in branch fix/viewer-tokens-properties-20260808
🛠️ Fix failing CI checks 💡
  • Create stacked PR
  • Commit on current branch
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/viewer-tokens-properties-20260808
✨ Simplify code
  • Create PR with simplified code
  • Commit simplified code in branch fix/viewer-tokens-properties-20260808

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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 4

🤖 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 `@crates/sl-viewer/tests/properties_viewer_tokens.rs`:
- Around line 126-147: Update required_css_var_nonempty to validate that each
REQUIRED_CSS_VARS entry contains at least one character after the "--" prefix,
rather than only checking that the full string is non-empty. Preserve the
existing indexed property-test structure and diagnostic context.
- Around line 113-120: The property tests lab_coat_hex_in_tokens_css and the
corresponding test at lines 154-160 must validate Rust-to-CSS pairs on actual
declaration lines rather than using broad TOKENS_CSS.contains checks. Reuse the
pairwise declaration-matching pattern from tokens.rs and assert every required
CSS variable is declared with its expected value, excluding comments and
unrelated uses.
- Around line 8-18: Make the Lab-Coat inventory authoritative by defining a
canonical exported array alongside the lab_coat constants in tokens.rs, or
generate both from one shared definition. Update lab_coat_hex_list() and all
related property checks in properties_viewer_tokens.rs to consume that canonical
inventory, ensuring newly added lab_coat::* constants cannot be omitted from
validation.
- Around line 167-185: Strengthen the tests around
viewer_color_scheme_declares_both_selectors and
viewer_color_scheme_declares_color_scheme_property by verifying the complete
:root and :root[data-theme="dark"] selector blocks, including a color-scheme
declaration with the required value in each. Do not rely on independent contains
checks or substring counts; assert the selector-specific CSS structure directly
or parse the stylesheet to validate both declarations.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

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

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 69b3a02c-f6f3-4c9e-b6d2-80a4bcf2b82b

📥 Commits

Reviewing files that changed from the base of the PR and between 89dbbcc and 3f5b68b.

📒 Files selected for processing (4)
  • CHANGELOG.md
  • crates/sl-viewer/tests/properties_viewer_tokens.rs
  • docs/ops/TRACEABILITY.json
  • docs/ops/WBS.md
📜 Review details
⏰ Context from checks skipped due to timeout. (3)
  • GitHub Check: semgrep-cloud-platform/scan
  • GitHub Check: Summary
  • GitHub Check: browser e2e · axe · responsive · visual
⚠️ CI failures not shown inline (2)

GitHub Check: Summary: The current Mergify configuration is invalid

Conclusion: failure

View job details

* Invalid condition 'author=dependabot[bot] | renovate[bot]' @ root → pull_request_rules → item 1 → conditions → item 0 → author=dependabot[bot] | renovate[bot]
```
Invalid GitHub login
```
* Invalid condition 'author=trunk-io[bot] | mergify[bot] | github-actions[bot]' @ root → pull_request_rules → item 2 → conditions → item 0 → author=trunk-io[bot] | mergify[bot] | github-actions[bot]
```
Invalid GitHub login
```
* Invalid condition 'age>=30d' @ root → pull_request_rules → item 8 → conditions → item 2 → age>=30d
```
Invalid attribute
```
* Extra inputs are not permitted @ root → pull_request_rules → item 0 → actions → post_merge
* Extra inputs are not permitted @ root → pull_request_rules → item 1 → actions → post_merge
* Extra inputs are not permitted @ root → pull_request_rules → item 3 → actions → request_reviews → github_accounts

GitHub Check: Mergify Merge Queue: The current Mergify configuration is invalid

Conclusion: failure

View job details

* Invalid condition 'author=dependabot[bot] | renovate[bot]' @ root → pull_request_rules → item 1 → conditions → item 0 → author=dependabot[bot] | renovate[bot]
```
Invalid GitHub login
```
* Invalid condition 'author=trunk-io[bot] | mergify[bot] | github-actions[bot]' @ root → pull_request_rules → item 2 → conditions → item 0 → author=trunk-io[bot] | mergify[bot] | github-actions[bot]
```
Invalid GitHub login
```
* Invalid condition 'age>=30d' @ root → pull_request_rules → item 8 → conditions → item 2 → age>=30d
```
Invalid attribute
```
* Extra inputs are not permitted @ root → pull_request_rules → item 0 → actions → post_merge
* Extra inputs are not permitted @ root → pull_request_rules → item 1 → actions → post_merge
* Extra inputs are not permitted @ root → pull_request_rules → item 3 → actions → request_reviews → github_accounts
🧰 Additional context used
📓 Path-based instructions (5)
*

📄 CodeRabbit inference engine (AGENTS.md)

*: Perform feature work in a git worktree under .claude/worktrees/, created from origin/main on a branch named <type>/<topic>, rather than working directly on main.
Do not make direct commits to protected main; use a pull request.
Do not use git reset --hard, git stash, or git clean in worktrees.
Do not use --no-verify or bypass hooks without operator approval.
Do not work on a branch or worktree another actor is using.

Files:

  • CHANGELOG.md
**/*.{rs,toml}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{rs,toml}: Use the Rust toolchain pinned in rust-toolchain.toml; the workspace MSRV is Rust 1.85.
Validate Rust workspace changes with the prescribed locked build, all-features test suite, Clippy, and rustfmt checks where applicable.

Files:

  • crates/sl-viewer/tests/properties_viewer_tokens.rs
**/*.rs

📄 CodeRabbit inference engine (AGENTS.md)

Fix Clippy warnings; do not add #[allow] unless it includes a tracking-issue comment.

Files:

  • crates/sl-viewer/tests/properties_viewer_tokens.rs
crates/sl-viewer/**/*.{rs,toml}

📄 CodeRabbit inference engine (AGENTS.md)

crates/sl-viewer/**/*.{rs,toml}: The sl-viewer crate uses Dioxus 0.6; use the Dioxus CLI/toolchain for desktop development and bundling.
Use cargo check -p sl-viewer as the fast inner-loop check for viewer changes.

Files:

  • crates/sl-viewer/tests/properties_viewer_tokens.rs
crates/sl-viewer/**/*

📄 CodeRabbit inference engine (AGENTS.md)

When packaging the macOS viewer, account for the documented Electrobun/Dioxus code-signing requirements.

Files:

  • crates/sl-viewer/tests/properties_viewer_tokens.rs
🪛 LanguageTool
docs/ops/WBS.md

[uncategorized] ~32-~32: The official name of this software platform is spelled with a capital “H”.
Context: ...; fuzz/fuzz_targets/jsonl_ingest.rs; .github/workflows/ci.yml; .github/workflows/b...

(GITHUB)


[uncategorized] ~32-~32: The official name of this software platform is spelled with a capital “H”.
Context: ...ingest.rs; .github/workflows/ci.yml; .github/workflows/bench-gate.yml; docs/ops/pe...

(GITHUB)

🔇 Additional comments (5)
crates/sl-viewer/tests/properties_viewer_tokens.rs (2)

1-7: LGTM!

Also applies to: 20-42, 72-107, 123-125


74-186: 📐 Maintainability & Code Quality

Run the repository-required Rust checks.

This change touches Rust/Cargo files, so show the locked Rust toolchain checks before merge: cargo check -p sl-viewer, locked all-features workspace build, locked all-features workspace test suite, locked Clippy with warnings denied, and locked rustfmt.

CHANGELOG.md (1)

31-31: LGTM!

docs/ops/TRACEABILITY.json (1)

322-322: LGTM!

docs/ops/WBS.md (1)

32-32: LGTM!

Comment on lines +8 to +18
//! * Every `lab_coat::*` hex constant is a well-formed `#RRGGBB` string
//! (7 chars, leading `#`, then 6 hex digits).
//! * All Lab-Coat hex constants are pairwise distinct — no two share
//! the same value (catches drift where a constant is silently
//! re-aliased to another).
//! * Every Lab-Coat hex appears somewhere in `TOKENS_CSS` so the
//! Rust mirror and the CSS SSOT stay in sync.
//! * Every `REQUIRED_CSS_VARS` entry starts with `--`, has no
//! duplicates, and appears as a substring of `TOKENS_CSS`.
//! * `VIEWER_COLOR_SCHEME` mentions both `:root[data-theme="dark"]`
//! and `:root` so the dark-mode flip is wired.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift

Make the lab_coat::* inventory authoritative.

lab_coat_hex_list() is a manually maintained test-only list. Every index strategy uses this list, and no assertion compares it with the declarations in crates/sl-viewer/src/tokens.rs. A new lab_coat::* constant can be omitted from the list and still pass every property, despite the exhaustiveness claim. Export a canonical array from tokens.rs, or generate the constants and array from one definition.

Also applies to: 44-69

🤖 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 `@crates/sl-viewer/tests/properties_viewer_tokens.rs` around lines 8 - 18, Make
the Lab-Coat inventory authoritative by defining a canonical exported array
alongside the lab_coat constants in tokens.rs, or generate both from one shared
definition. Update lab_coat_hex_list() and all related property checks in
properties_viewer_tokens.rs to consume that canonical inventory, ensuring newly
added lab_coat::* constants cannot be omitted from validation.

Comment on lines +113 to +120
fn lab_coat_hex_in_tokens_css(i in lab_coat_hex_indices_strategy()) {
let hex = lab_coat_hex_list()[i];
prop_assert!(
TOKENS_CSS.contains(hex),
"TOKENS_CSS missing lab_coat hex {:?}",
hex,
);
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Check CSS declarations and Rust-to-CSS pairs.

TOKENS_CSS.contains(hex) only proves that a value occurs somewhere. It passes when a value is assigned to the wrong variable or appears in a comment. TOKENS_CSS.contains(var) can also match a comment or a use without a declaration. Assert each (CSS variable, Rust value) pair on a declaration line, and assert each required variable is actually declared. The existing check in crates/sl-viewer/src/tokens.rs Lines 91-109 shows the required pairwise pattern.

Also applies to: 154-160

🤖 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 `@crates/sl-viewer/tests/properties_viewer_tokens.rs` around lines 113 - 120,
The property tests lab_coat_hex_in_tokens_css and the corresponding test at
lines 154-160 must validate Rust-to-CSS pairs on actual declaration lines rather
than using broad TOKENS_CSS.contains checks. Reuse the pairwise
declaration-matching pattern from tokens.rs and assert every required CSS
variable is declared with its expected value, excluding comments and unrelated
uses.

Comment on lines +126 to +147
/// Property: every `REQUIRED_CSS_VARS` entry starts with `--` (CSS
/// custom property convention).
#[test]
fn required_css_var_starts_with_double_dash(i in required_var_index_strategy()) {
let var = REQUIRED_CSS_VARS[i];
prop_assert!(var.starts_with("--"), "var {:?} must start with '--'", var);
}

/// Property: `REQUIRED_CSS_VARS` has no duplicates.
#[test]
fn required_css_vars_unique(_i in 0u8..4) {
let list = REQUIRED_CSS_VARS;
let set: HashSet<_> = list.iter().collect();
prop_assert_eq!(set.len(), list.len());
}

/// Property: every `REQUIRED_CSS_VARS` entry is non-empty (no
/// empty `--` strings accidentally added).
#[test]
fn required_css_var_nonempty(i in required_var_index_strategy()) {
let var = REQUIRED_CSS_VARS[i];
prop_assert!(!var.is_empty(), "REQUIRED_CSS_VARS[{}] is empty", i);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Make the empty-name check effective.

The prefix check and !var.is_empty() both accept the literal "--". This does not reject the empty custom-property suffix described by the test comment. Check that at least one character follows --.

🤖 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 `@crates/sl-viewer/tests/properties_viewer_tokens.rs` around lines 126 - 147,
Update required_css_var_nonempty to validate that each REQUIRED_CSS_VARS entry
contains at least one character after the "--" prefix, rather than only checking
that the full string is non-empty. Preserve the existing indexed property-test
structure and diagnostic context.

Comment on lines +167 to +185
/// Property: `VIEWER_COLOR_SCHEME` declares both the default
/// (`:root`) and dark (`:root[data-theme="dark"]`) selectors so the
/// viewer's color-scheme flip is wired.
#[test]
fn viewer_color_scheme_declares_both_selectors(_i in 0u8..4) {
prop_assert!(VIEWER_COLOR_SCHEME.contains(":root"));
prop_assert!(VIEWER_COLOR_SCHEME.contains("[data-theme=\"dark\"]"));
}

/// Property: `VIEWER_COLOR_SCHEME` declares `color-scheme` for
/// both modes (the W3C CSS prop that triggers browser scrollbar
/// and form-control color flips).
#[test]
fn viewer_color_scheme_declares_color_scheme_property(_i in 0u8..4) {
prop_assert!(VIEWER_COLOR_SCHEME.contains("color-scheme"));
// Both modes must set the property.
let occurrences = VIEWER_COLOR_SCHEME.matches("color-scheme").count();
prop_assert_eq!(occurrences, 2);
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Assert complete selector-specific color-scheme declarations.

The two contains calls can pass when :root and [data-theme="dark"] occur in separate selectors. They do not prove that :root[data-theme="dark"] exists. Counting color-scheme substrings also does not verify two declarations or the required values for each selector. Assert the complete default and dark blocks, or parse the CSS and verify the selector-specific declarations.

🤖 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 `@crates/sl-viewer/tests/properties_viewer_tokens.rs` around lines 167 - 185,
Strengthen the tests around viewer_color_scheme_declares_both_selectors and
viewer_color_scheme_declares_color_scheme_property by verifying the complete
:root and :root[data-theme="dark"] selector blocks, including a color-scheme
declaration with the required value in each. Do not rely on independent contains
checks or substring counts; assert the selector-specific CSS structure directly
or parse the stylesheet to validate both declarations.

@KooshaPari

Copy link
Copy Markdown
Owner Author

Closing due to merge conflicts.

@KooshaPari KooshaPari closed this Aug 9, 2026
@KooshaPari
KooshaPari deleted the fix/viewer-tokens-properties-20260808 branch August 9, 2026 22:14
KooshaPari added a commit that referenced this pull request Aug 10, 2026
…ace (WBS-6.2 #463) (#479)

* test(viewer): async_states SkeletonLayout proptest surface (WBS-6.2 #458)

Adds crates/sl-viewer/tests/properties_viewer_async_states.rs with
7 proptest properties pinning the async_states SSOT:

* SkeletonLayout::default() is Bundles.
* SkeletonLayout exposes exactly three variants
  (Bundles, ListDetail, StreamFeed).
* Every variant's Debug label is non-empty, single-line, and
  matches one of the documented names.
* SkeletonLayout::default() matches the first arm in the match
  block in ContentSkeleton.
* list_rows.clamp(3, 6) lands in [3, 6] for every input.
* The clamp is monotonic non-decreasing.
* The clamp has the documented fixed points (0/2 -> 3, 6/MAX -> 6).

Updates WBS-6.2 evidence list, TRACEABILITY.json, and CHANGELOG.

* test(viewer): session-ledger OKF document validator proptest surface (WBS-6.2 #459)

Adds crates/sl-viewer/tests/properties_session_ledger_okf.rs with
12 proptest properties pinning the session-ledger OKF SSOT:

* OkfDocument::new(b, c) always produces okf = "1.0".
* OkfDocument::new(b, c) propagates bundle.source_id into
  source_id and provenance.source_id.
* OkfDocument::new(b, c) propagates c into provenance.corpus.
* OkfDocument::new(b, c) starts with empty entities, relations,
  tags.
* validate_okf_document reports exactly one unsupported_version
  error per non-"1.0" okf (with offending version in message).
* validate_okf_document reports exactly one source_id_mismatch
  error per provenance/source mismatch.
* Duplicate entity ids each surface a duplicate_entity_id error.
* Dangling relation source / target surface their respective
  errors.
* Every OkfValidationError carries non-empty field / code /
  message.

First property test to exercise session_ledger (the core domain
crate) from sl-viewer's test harness, pivoting the bounded lane
beyond the viewer-only surface.

Updates WBS-6.2 evidence list, TRACEABILITY.json, and CHANGELOG.

* test(viewer): session-ledger worklog projector proptest surface (WBS-6.2 #460)

Adds crates/sl-viewer/tests/properties_session_ledger_worklog.rs
with 11 proptest properties pinning the session-ledger worklog
projector (crash-recovery / lost-work pipeline):

* Empty sessions project None.
* Final Role::User turn -> AwaitingAssistantResponse.
* Final Role::Tool / Role::Subagent -> InterruptedExecution.
* Final assistant turn with one of the 9 documented completion
  markers (complete / completed / done / [completed] /
  <completed> / status: complete / status: completed /
  task complete / task completed) projects None.
* Final assistant turn without any marker projects as
  MissingCompletionMarker.
* UnfinishedWorkItem carries the originating session id, corpus,
  and message_count.
* summary never exceeds 241 chars and is single-line.
* project_unfinished_work returns one item per unfinished
  session in input order and is deterministic.
* WorklogProjection::from_session carries message_count and
  matches detect_unfinished exactly.

Updates WBS-6.2 evidence list, TRACEABILITY.json, and CHANGELOG.

* test(viewer): session-ledger OKF export adapter proptest surface (WBS-6.2 #461)

Adds crates/sl-viewer/tests/properties_session_ledger_export.rs with
8 proptest properties pinning session_ledger::export_to_okf
(the OKF v1 export pipeline entry point):

* export_to_okf always produces okf = "1.0" and propagates
  bundle.source_id into source_id + provenance.source_id.
* export_to_okf propagates the corpus arg into provenance.corpus.
* Empty bundles yield zero entities / relations / tags.
* Every exported document passes validate_okf_document.
* export_to_okf is deterministic across calls.
* Intent bundles emit exactly one goal entity (label = goal),
  one acceptance entity per acceptance signal, one constraint
  entity per constraint.
* Context bundles emit exactly one resource entity when cwd is
  present.
* Acceptance bundles emit exactly one gate entity with
  label = "resume-gate" and properties.ready = true /
  scope_sized = true.
* The exporter never produces duplicate entity ids across
  mixed intent / context / acceptance / contract bundles.

Updates WBS-6.2 evidence list, TRACEABILITY.json, and CHANGELOG.

* test(viewer): session-ledger distill compiler proptest surface (WBS-6.2 #462)

Adds crates/sl-viewer/tests/properties_session_ledger_distill.rs
with 9 proptest properties pinning session_ledger::distill::compile
and compile_and_store:

* compile(session) always produces a bundle whose source_id
  equals session.id.
* compile(session) always produces an injectable bundle
  (carries an Acceptance slice) — the load-bearing contract
  for resume.
* compile(session) always emits one slice for every documented
  kind (Acceptance / Intent / Context / Contract / Provenance /
  Worklog) — even when the session is empty.
* compile(session) always returns a bundle whose
  total_token_estimate() equals the sum of per-slice
  token_estimate values.
* compile(session) is deterministic across calls.
* The Worklog slice body deserializes to a WorklogProjection
  whose message_count equals session.messages.len().
* compile_and_store returns an injectable bundle with the
  input source_id.
* compile_and_store writes exactly 3 episodic memories
  (intent / contract / context) to the memory store.
* compile_and_store is deterministic across fresh stores.

Updates WBS-6.2 evidence list, TRACEABILITY.json, and CHANGELOG.

* test(viewer): session-ledger heuristic intent extractor proptest surface (WBS-6.2 #463)

Adds crates/sl-viewer/tests/properties_session_ledger_intent.rs
with 10 proptest properties pinning
session_ledger::distill::extractor::HeuristicIntentExtractor::extract_intent
(the P1 SSOT for what the user wants — drives resume prompt,
search index, and wiki/docs view):

* user_turn_count always equals the count of Role::User messages
  and ignores Assistant / Subagent / Tool / System messages.
* Empty sessions produce an empty Intent.
* Repeated acceptance / constraint patterns are deduplicated.
* Every documented acceptance pattern (16) and every documented
  constraint pattern (19) is recognized in any user message.
* Labeled Goal: / Objective: / Task: lines win over preamble.
* Labeled Constraint: / Requirement: / Boundary: lines carry
  their full text.
* extract_intent is deterministic across calls.

Updates WBS-6.2 evidence list, TRACEABILITY.json, and CHANGELOG.

---------

Co-authored-by: SessionLedger Bot <team@sessionledger.local>
KooshaPari added a commit that referenced this pull request Aug 10, 2026
…ptest surfaces (WBS-6.2 #462 #463) (#481)

* test(viewer): session-ledger worklog projector proptest surface (WBS-6.2 #460)

Adds crates/sl-viewer/tests/properties_session_ledger_worklog.rs
with 11 proptest properties pinning the session-ledger worklog
projector (crash-recovery / lost-work pipeline):

* Empty sessions project None.
* Final Role::User turn -> AwaitingAssistantResponse.
* Final Role::Tool / Role::Subagent -> InterruptedExecution.
* Final assistant turn with one of the 9 documented completion
  markers (complete / completed / done / [completed] /
  <completed> / status: complete / status: completed /
  task complete / task completed) projects None.
* Final assistant turn without any marker projects as
  MissingCompletionMarker.
* UnfinishedWorkItem carries the originating session id, corpus,
  and message_count.
* summary never exceeds 241 chars and is single-line.
* project_unfinished_work returns one item per unfinished
  session in input order and is deterministic.
* WorklogProjection::from_session carries message_count and
  matches detect_unfinished exactly.

Updates WBS-6.2 evidence list, TRACEABILITY.json, and CHANGELOG.

* test(viewer): session-ledger OKF export adapter proptest surface (WBS-6.2 #461)

Adds crates/sl-viewer/tests/properties_session_ledger_export.rs with
8 proptest properties pinning session_ledger::export_to_okf
(the OKF v1 export pipeline entry point):

* export_to_okf always produces okf = "1.0" and propagates
  bundle.source_id into source_id + provenance.source_id.
* export_to_okf propagates the corpus arg into provenance.corpus.
* Empty bundles yield zero entities / relations / tags.
* Every exported document passes validate_okf_document.
* export_to_okf is deterministic across calls.
* Intent bundles emit exactly one goal entity (label = goal),
  one acceptance entity per acceptance signal, one constraint
  entity per constraint.
* Context bundles emit exactly one resource entity when cwd is
  present.
* Acceptance bundles emit exactly one gate entity with
  label = "resume-gate" and properties.ready = true /
  scope_sized = true.
* The exporter never produces duplicate entity ids across
  mixed intent / context / acceptance / contract bundles.

Updates WBS-6.2 evidence list, TRACEABILITY.json, and CHANGELOG.

* test(viewer): session-ledger distill compiler proptest surface (WBS-6.2 #462)

Adds crates/sl-viewer/tests/properties_session_ledger_distill.rs
with 9 proptest properties pinning session_ledger::distill::compile
and compile_and_store:

* compile(session) always produces a bundle whose source_id
  equals session.id.
* compile(session) always produces an injectable bundle
  (carries an Acceptance slice) — the load-bearing contract
  for resume.
* compile(session) always emits one slice for every documented
  kind (Acceptance / Intent / Context / Contract / Provenance /
  Worklog) — even when the session is empty.
* compile(session) always returns a bundle whose
  total_token_estimate() equals the sum of per-slice
  token_estimate values.
* compile(session) is deterministic across calls.
* The Worklog slice body deserializes to a WorklogProjection
  whose message_count equals session.messages.len().
* compile_and_store returns an injectable bundle with the
  input source_id.
* compile_and_store writes exactly 3 episodic memories
  (intent / contract / context) to the memory store.
* compile_and_store is deterministic across fresh stores.

Updates WBS-6.2 evidence list, TRACEABILITY.json, and CHANGELOG.

* test(viewer): session-ledger heuristic intent extractor proptest surface (WBS-6.2 #463)

Adds crates/sl-viewer/tests/properties_session_ledger_intent.rs
with 10 proptest properties pinning
session_ledger::distill::extractor::HeuristicIntentExtractor::extract_intent
(the P1 SSOT for what the user wants — drives resume prompt,
search index, and wiki/docs view):

* user_turn_count always equals the count of Role::User messages
  and ignores Assistant / Subagent / Tool / System messages.
* Empty sessions produce an empty Intent.
* Repeated acceptance / constraint patterns are deduplicated.
* Every documented acceptance pattern (16) and every documented
  constraint pattern (19) is recognized in any user message.
* Labeled Goal: / Objective: / Task: lines win over preamble.
* Labeled Constraint: / Requirement: / Boundary: lines carry
  their full text.
* extract_intent is deterministic across calls.

Updates WBS-6.2 evidence list, TRACEABILITY.json, and CHANGELOG.

---------

Co-authored-by: SessionLedger Bot <team@sessionledger.local>
KooshaPari added a commit that referenced this pull request Aug 10, 2026
…WBS-6.2 #460 #461) (#480)

* test(viewer): session-ledger worklog projector proptest surface (WBS-6.2 #460)

Adds crates/sl-viewer/tests/properties_session_ledger_worklog.rs
with 11 proptest properties pinning the session-ledger worklog
projector (crash-recovery / lost-work pipeline):

* Empty sessions project None.
* Final Role::User turn -> AwaitingAssistantResponse.
* Final Role::Tool / Role::Subagent -> InterruptedExecution.
* Final assistant turn with one of the 9 documented completion
  markers (complete / completed / done / [completed] /
  <completed> / status: complete / status: completed /
  task complete / task completed) projects None.
* Final assistant turn without any marker projects as
  MissingCompletionMarker.
* UnfinishedWorkItem carries the originating session id, corpus,
  and message_count.
* summary never exceeds 241 chars and is single-line.
* project_unfinished_work returns one item per unfinished
  session in input order and is deterministic.
* WorklogProjection::from_session carries message_count and
  matches detect_unfinished exactly.

Updates WBS-6.2 evidence list, TRACEABILITY.json, and CHANGELOG.

* test(viewer): session-ledger OKF export adapter proptest surface (WBS-6.2 #461)

Adds crates/sl-viewer/tests/properties_session_ledger_export.rs with
8 proptest properties pinning session_ledger::export_to_okf
(the OKF v1 export pipeline entry point):

* export_to_okf always produces okf = "1.0" and propagates
  bundle.source_id into source_id + provenance.source_id.
* export_to_okf propagates the corpus arg into provenance.corpus.
* Empty bundles yield zero entities / relations / tags.
* Every exported document passes validate_okf_document.
* export_to_okf is deterministic across calls.
* Intent bundles emit exactly one goal entity (label = goal),
  one acceptance entity per acceptance signal, one constraint
  entity per constraint.
* Context bundles emit exactly one resource entity when cwd is
  present.
* Acceptance bundles emit exactly one gate entity with
  label = "resume-gate" and properties.ready = true /
  scope_sized = true.
* The exporter never produces duplicate entity ids across
  mixed intent / context / acceptance / contract bundles.

Updates WBS-6.2 evidence list, TRACEABILITY.json, and CHANGELOG.

* test(viewer): session-ledger distill compiler proptest surface (WBS-6.2 #462)

Adds crates/sl-viewer/tests/properties_session_ledger_distill.rs
with 9 proptest properties pinning session_ledger::distill::compile
and compile_and_store:

* compile(session) always produces a bundle whose source_id
  equals session.id.
* compile(session) always produces an injectable bundle
  (carries an Acceptance slice) — the load-bearing contract
  for resume.
* compile(session) always emits one slice for every documented
  kind (Acceptance / Intent / Context / Contract / Provenance /
  Worklog) — even when the session is empty.
* compile(session) always returns a bundle whose
  total_token_estimate() equals the sum of per-slice
  token_estimate values.
* compile(session) is deterministic across calls.
* The Worklog slice body deserializes to a WorklogProjection
  whose message_count equals session.messages.len().
* compile_and_store returns an injectable bundle with the
  input source_id.
* compile_and_store writes exactly 3 episodic memories
  (intent / contract / context) to the memory store.
* compile_and_store is deterministic across fresh stores.

Updates WBS-6.2 evidence list, TRACEABILITY.json, and CHANGELOG.

* test(viewer): session-ledger heuristic intent extractor proptest surface (WBS-6.2 #463)

Adds crates/sl-viewer/tests/properties_session_ledger_intent.rs
with 10 proptest properties pinning
session_ledger::distill::extractor::HeuristicIntentExtractor::extract_intent
(the P1 SSOT for what the user wants — drives resume prompt,
search index, and wiki/docs view):

* user_turn_count always equals the count of Role::User messages
  and ignores Assistant / Subagent / Tool / System messages.
* Empty sessions produce an empty Intent.
* Repeated acceptance / constraint patterns are deduplicated.
* Every documented acceptance pattern (16) and every documented
  constraint pattern (19) is recognized in any user message.
* Labeled Goal: / Objective: / Task: lines win over preamble.
* Labeled Constraint: / Requirement: / Boundary: lines carry
  their full text.
* extract_intent is deterministic across calls.

Updates WBS-6.2 evidence list, TRACEABILITY.json, and CHANGELOG.

---------

Co-authored-by: SessionLedger Bot <team@sessionledger.local>
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