Skip to content

Expand run-sampler --compact: results register, vanished-output grouping, scope tier, visual-only tier#265

Open
michieldegezelle wants to merge 3 commits into
mainfrom
sampler-compact-diff-v2
Open

Expand run-sampler --compact: results register, vanished-output grouping, scope tier, visual-only tier#265
michieldegezelle wants to merge 3 commits into
mainfrom
sampler-compact-diff-v2

Conversation

@michieldegezelle

Copy link
Copy Markdown
Contributor

Summary

Follow-up to #236/#261's --compact mode, driven by real feedback while reviewing PR #894's sampler run against nl_market: the named_results-only diff missed real signal and got unreadable fast (78KB/~19.7K tokens on a 202-entry NL run). This PR:

  • Diffs the results register alongside named_results - 0/1 flag arrays render as a triggered-indicator count (e.g. 1/1 triggered), other shapes (raw numeric values) fall back to a plain value diff.
  • Groups entries whose named_results/results collapsed entirely (≥3 keys lost at once, all to undefined) into a single "output vanished" finding per template - previously this showed as dozens of individual "value → undefined" lines and could dominate the whole summary.
  • Adds a scope/dependency tier (dependencies/rollforward_params/required_keys_missing), kept separate from the data diff so a dependency change is never mistaken for a data regression. dependencies renders as one sub-line per category (ledgers/handles/account ranges/company.attributes) instead of a semicolon-packed single line.
  • Adds a visual-only tier: entries where view.html changed but the data diff found nothing to explain it - a rendering-only regression the old diff couldn't see at all. Described field-by-field via Silverfin's data-name attribute where one anchors the change, with an honest "compare the files directly" fallback where it doesn't.
  • Truncates long values (accounting-policy paragraphs, notes) and caps per-template/per-entry change lists, always disclosing what was elided rather than silently dropping it.
  • Every finding now links to a concrete follow-up: the entry's live app URL when known, else its path inside the results directory.
  • Adds run-sampler --from-zip <path>: build the compact diff from an already-downloaded results.zip, with no sampler run or network call - lets a reviewer re-analyze a real result (or iterate on the compact-diff format itself) without a 30-60 min re-run against the shared staging backend.

Net effect measured on the real PR #894 zip (202 entries, 6 templates changed + 21 collapsed + 9 visual-only): output went from 78KB/~19.7K tokens (old format) to ~31.7KB while covering strictly more signal.

Why keeping this open for now

This is currently pointed at from nl_market's and lu_market's run_sampler.yml (temporarily, on this branch) so we can gather real feedback across their approved PRs before merging - see the follow-up in each of those repos.

Test plan

  • npm test - 640/640 passing

  • npm run lint - clean

  • Validated against a real downloaded results.zip from nl_market PR #894 via --from-zip, output reviewed in full

  • Real end-to-end validation via a live download URL (only the local-zip path has been exercised against real data so far; the live-download path is covered by mocked tests)

  • Feedback gathered from nl_market/lu_market usage before merge

  • Skip bumping the CLI version

🤖 Generated with Claude Code

…ing, scope tier, visual-only tier

- Diff the `results` register alongside `named_results` (0/1 flag arrays render
  as a triggered-indicator count, other shapes fall back to a plain value diff).
- Group entries whose named_results/results collapsed entirely (>=3 keys lost
  at once) into a single "output vanished" finding per template, instead of one
  line per lost key.
- Add a scope/dependency tier (`dependencies`/`rollforward_params`/
  `required_keys_missing`), separate from the data diff, with `dependencies`
  rendered as one sub-line per category rather than a semicolon-packed line.
- Add a visual-only tier: entries where `view.html` changed but the data diff
  found nothing, described field-by-field via Silverfin's `data-name` anchor
  where possible, with an honest fallback note otherwise.
- Truncate long values and cap per-template/per-entry change lists, always
  disclosing what was elided.
- Every finding now links to a concrete follow-up: the entry's live app URL
  when known, else its path inside the results directory.
- Add `run-sampler --from-zip <path>` to build the compact diff from an
  already-downloaded results.zip, with no sampler run or network call.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

@claude claude 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.

⚠️ Code review skipped — your organization's overage spend limit has been reached.

Code review is billed via overage credits. To resume reviews, an organization admin can raise the monthly limit at claude.ai/admin-settings/claude-code.

Once credits are available, reopen this pull request to trigger a review.

@coderabbitai

coderabbitai Bot commented Jul 22, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 57d35cf8-9130-4ec6-9028-aa393ceed3ed

📥 Commits

Reviewing files that changed from the base of the PR and between 3aa9484 and cb345b6.

📒 Files selected for processing (2)
  • lib/liquidSamplerCompact.js
  • tests/lib/liquidSamplerCompact.test.js
🚧 Files skipped from review as they are similar to previous changes (1)
  • tests/lib/liquidSamplerCompact.test.js

Walkthrough

The compact sampler diff now includes results, scope/dependency changes, vanished output, and visual-only view.html changes. Output is capped and grouped. run-sampler --from-zip generates the diff from a local archive without network calls.

Changes

Compact sampler diff

Layer / File(s) Summary
Diff signal helpers
lib/liquidSamplerCompact.js, tests/lib/liquidSamplerCompact.test.js
Register parsing, result vectors, scope/dependency comparisons, missing-key handling, truncation, and field-level HTML change detection were added and tested.
Tiered extraction and Markdown output
lib/liquidSamplerCompact.js, tests/lib/liquidSamplerCompact.test.js
Compact extraction and formatting now group data, vanished output, scope, and visual-only changes with caps, disclosures, example links, and expanded coverage.
Live and local zip execution
lib/liquidSamplerRunner.js, bin/cli.js, tests/lib/liquidSamplerRunner.test.js, tests/bin/cli.test.js
Runner extraction is shared across live and buffer workflows, --from-zip performs offline processing, and CLI partner validation depends on the selected path.
Release metadata
CHANGELOG.md, package.json
Release metadata documents version 1.58.0 and the compact-diff changes.

Estimated code review effort: 4 (Complex) | ~45 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: expanding --compact with results, vanished-output, scope, and visual-only tiers.
Description check ✅ Passed The description covers the main changes and testing, though it omits the explicit Fixes # line and uses a looser format than the template.
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
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch sampler-compact-diff-v2

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: 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 `@bin/cli.js`:
- Around line 554-556: Update the CLI flow around options.fromZip and the
-p/--partner validation so the from-zip offline path does not require a partner
id. Preserve partner validation for all non-zip execution paths, and continue
passing options.partner to LiquidSamplerRunner when available.

In `@lib/liquidSamplerCompact.js`:
- Around line 734-736: The headline construction using summary.templatesChanged
and summary.entriesChanged misrepresents runs whose findings exist only in
collapsed, scope, or visual tiers. Update the summary-count logic and the
headline generation around summary.templatesChanged, summary.entriesChanged, and
the nothingChanged guard so non-data findings are reflected in the counts, or
explicitly label the headline as data-diff-specific and suppress the
contradictory zero-count line when other tiers contain findings.
🪄 Autofix (Beta)

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: CHILL

Plan: Pro

Run ID: 51b15e33-e97d-4eea-8a7b-b93f47d281b7

📥 Commits

Reviewing files that changed from the base of the PR and between 3bfdeb7 and fad591d.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (7)
  • CHANGELOG.md
  • bin/cli.js
  • lib/liquidSamplerCompact.js
  • lib/liquidSamplerRunner.js
  • package.json
  • tests/lib/liquidSamplerCompact.test.js
  • tests/lib/liquidSamplerRunner.test.js

Comment thread bin/cli.js
Comment thread lib/liquidSamplerCompact.js Outdated
Comment thread lib/liquidSamplerCompact.js Outdated
Comment thread lib/liquidSamplerCompact.js
Comment thread lib/liquidSamplerCompact.js Outdated
Comment thread lib/liquidSamplerCompact.js
Comment thread lib/liquidSamplerCompact.js
- Make -p/--partner optional for --from-zip, which never touches the
  partner/sampler API; still required (with a clear error) for every
  other run-sampler path.
- Fix the compact-diff headline misreporting '0 template(s) changed'
  when findings exist only in the collapsed/scope/visual tiers - it's
  now worded as data-diff (named_results/results) specific and no
  longer contradicts the sections printed below it.
- Guard dependencyLedgers/diffStringSet against malformed (non-array)
  dependencies.ledgers/account_ranges register values so one bad entry
  can't throw and abort the whole run's diff.
- Validate exampleRef's url as http(s) before interpolating it into
  Markdown link syntax, since with --from-zip that url no longer
  necessarily comes from Silverfin's own sampler backend.
- Decode HTML entities in <input> field values, consistent with the
  <textarea>/<select> branches.
- Distinguish an explicit results: null from a genuinely absent
  register in formatResultsValue/diffResultsRegister, so a legitimate
  null doesn't get miscounted into the 'output vanished' heuristic.
- Give truncated long values a short content hash alongside the
  length, so two different values that share the same truncated prefix
  and total length no longer collide under the same cross-entry dedup
  key.

🤖 Generated with Claude Code

Co-authored-by: Cursor <cursoragent@cursor.com>
@michieldegezelle

Copy link
Copy Markdown
Contributor Author

Addressed all outstanding review comments in 3aa9484:

  • -p/--partner required even for --from-zip (CodeRabbit): -p/--partner is now optional at the Commander level; printCompactDiffFromZip never touches the partner/sampler API, so that path no longer needs it. Every other path now gets a manual consola.error check instead (matches the rest of the CLI's convention of .option + manual validation rather than .requiredOption).
  • Headline misreports "0 template(s) changed" when findings are only in the collapsed/scope/visual tiers (CodeRabbit): the headline is now worded as data-diff (named_results/results) specific and only prints the "N template(s) changed" count when that tier has findings; otherwise it says so plainly and points to the other tiers below instead of printing a contradictory "0 ... 0" line.
  • dependencyLedgers/.account_ranges throws on a malformed (non-array) register value: diffStringSet and dependencyLedgers now treat a non-array value as empty instead of throwing, so one bad entry can't abort the whole run's diff.
  • exampleRef interpolates an unvalidated url into Markdown: now validated as http(s) before use, falling back to the output/... path reference otherwise - relevant now that --from-zip's sample_entry_ids.yml isn't guaranteed to come from Silverfin's own backend.
  • <input> field values weren't entity-decoded, unlike <textarea>/<select>: fixed for consistency.
  • results: null vs. a genuinely absent register both rendered as "undefined": formatResultsValue now distinguishes them, so a legitimate explicit null no longer gets miscounted into the "output vanished" collapse heuristic.
  • Dedup key collision on truncated long values: truncated values now include a short content hash alongside the length, so two different long values sharing the same truncated prefix and total length no longer collide under the same cross-entry dedup key.

Added/updated tests for all of the above; npm test (647/647) and npm run lint both clean.

@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: 1

🤖 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 `@lib/liquidSamplerCompact.js`:
- Around line 700-712: The exampleRef function currently validates only the URL
scheme, allowing Markdown link syntax injection through destinations containing
delimiters. Parse the URL, require an http(s) protocol, and reject or escape
Markdown-sensitive characters before interpolation; apply the same sanitizer to
any visual-only link rendering.
🪄 Autofix (Beta)

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: CHILL

Plan: Pro

Run ID: 05e1bb82-e9ba-4c30-a8c8-426dbbd6142f

📥 Commits

Reviewing files that changed from the base of the PR and between fad591d and 3aa9484.

📒 Files selected for processing (4)
  • bin/cli.js
  • lib/liquidSamplerCompact.js
  • tests/bin/cli.test.js
  • tests/lib/liquidSamplerCompact.test.js
🚧 Files skipped from review as they are similar to previous changes (2)
  • bin/cli.js
  • tests/lib/liquidSamplerCompact.test.js

Comment thread lib/liquidSamplerCompact.js
CodeRabbit follow-up: an http(s) scheme check alone isn't enough - a
value like 'https://trusted.example/a) [injected](https://attacker)'
still passes it but closes the generated (...) link early and injects
arbitrary Markdown. Add a shared sanitizeUrl() that requires a
parseable http(s) URL and rejects parentheses/whitespace/angle
brackets/control characters outright, and use it for both exampleRef
and the visual-only section's 'open in app' link (which previously
interpolated entry.url with no validation at all).

🤖 Generated with Claude Code

Co-authored-by: Cursor <cursoragent@cursor.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant