Skip to content

feat(fs): add opt-in deterministic ordering to ls#1968

Draft
fengluodb wants to merge 1 commit into
volcengine:mainfrom
fengluodb:feat/fs-ls-deterministic-sort
Draft

feat(fs): add opt-in deterministic ordering to ls#1968
fengluodb wants to merge 1 commit into
volcengine:mainfrom
fengluodb:feat/fs-ls-deterministic-sort

Conversation

@fengluodb
Copy link
Copy Markdown
Collaborator

Introduce an enable_sort flag (default false) on the ls path so callers can request a stable, files-first / case-folded-name-asc order with a truncation window that no longer drifts under node_limit. The default behaviour is unchanged: entries follow the raw AGFS order, preserving backwards compatibility for all existing callers.

The flag is plumbed through VikingFS.ls / _ls_original / _ls_agent, the fs service, the HTTP /api/v1/fs/ls route, and the Rust ov CLI as --enable-sort.

Description

Related Issue

Type of Change

  • Bug fix (non-breaking change that fixes an issue)
  • New feature (non-breaking change that adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Documentation update
  • Refactoring (no functional changes)
  • Performance improvement
  • Test update

Changes Made

Testing

  • I have added tests that prove my fix is effective or that my feature works
  • New and existing unit tests pass locally with my changes
  • I have tested this on the following platforms:
    • Linux
    • macOS
    • Windows

Checklist

  • My code follows the project's coding style
  • I have performed a self-review of my code
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings
  • Any dependent changes have been merged and published

Screenshots (if applicable)

Additional Notes

Introduce an `enable_sort` flag (default false) on the ls path so callers
can request a stable, files-first / case-folded-name-asc order with a
truncation window that no longer drifts under node_limit. The default
behaviour is unchanged: entries follow the raw AGFS order, preserving
backwards compatibility for all existing callers.

The flag is plumbed through VikingFS.ls / _ls_original / _ls_agent, the
fs service, the HTTP /api/v1/fs/ls route, and the Rust ov CLI as
`--enable-sort`.
@github-actions
Copy link
Copy Markdown

PR Reviewer Guide 🔍

Here are some key observations to aid the review process:

⏱️ Estimated effort to review: 3 🔵🔵🔵⚪⚪
🏅 Score: 85
🧪 No relevant tests
🔒 No security concerns identified
✅ No TODO sections
🔀 Multiple PR themes

Sub-PR theme: Add enable_sort flag to Python core FS ls implementation

Relevant files:

  • openviking/server/routers/filesystem.py
  • openviking/service/fs_service.py
  • openviking/storage/viking_fs.py

Sub-PR theme: Add --enable-sort flag to Rust CLI

Relevant files:

  • crates/ov_cli/src/client.rs
  • crates/ov_cli/src/commands/filesystem.rs
  • crates/ov_cli/src/handlers.rs
  • crates/ov_cli/src/main.rs
  • crates/ov_cli/src/tui/tree.rs

⚡ Recommended focus areas for review

API Response Change

The _ls_agent method now unconditionally adds a "name" field to agent output entries, even when enable_sort is false. This changes the API response shape for the "agent" output format, which may break existing clients that do not expect this field.

new_entry = {
    "uri": self._path_to_uri(f"{path}/{name}", ctx=ctx),
    "size": 0 if is_dir else entry.get("size", 0),
    "isDir": is_dir,
    "modTime": format_simplified(parsed_time, now),
    # Carry the raw name so the deterministic sort key is stable
    # regardless of any later URI rewriting.
    "name": name,
}
Truncation Behavior

When enable_sort is true, the scan cap is applied to raw AGFS entries before filtering (access checks, hidden files). This can result in fewer than node_limit entries being returned even when more eligible entries exist beyond the scan cap.

if enable_sort:
    scan_cap = max(node_limit * self._LS_SCAN_FACTOR, self._LS_SCAN_FLOOR)
    raw = entries[:scan_cap]
else:
    raw = entries

@github-actions
Copy link
Copy Markdown

PR Code Suggestions ✨

No code suggestions found for the PR.

@fengluodb fengluodb marked this pull request as draft May 11, 2026 11:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

Status: Backlog

Development

Successfully merging this pull request may close these issues.

1 participant