You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@maka.apache.org by wy...@apache.org on 2026/10/20 22:45:59 UTC

(maka) branch rust-preview updated: fix(files): remove directory scan limits and reconcile macOS watches

This is an automated email from the ASF dual-hosted git repository.

M4n5ter pushed a commit to branch rust-preview
in repository https://gitbox.apache.org/repos/asf/maka.git


The following commit(s) were added to refs/heads/rust-preview by this push:
     new cb1937c4ae fix(files): remove directory scan limits and reconcile macOS watches
cb1937c4ae is described below

commit cb1937c4aea10d5ebebe62694fad0c95c48f9121
Author: Wang <m4...@gmail.com>
AuthorDate: Wed Oct 21 06:45:51 2026 +0800

    fix(files): remove directory scan limits and reconcile macOS watches
    
    Remove unsupported directory entry-count and depth admission limits while
    retaining bounded pages, held directory authority and Session revocation.
    Reconcile macOS watches against complete shallow metadata snapshots so
    persistent changes remain observable when native hints do not arrive.
    Adapt scan spacing to measured work and join cancellation and cleanup.
    
    Cover large and deep directories, timer-only changes and authority loss;
    synchronize API documentation and generated dependency inventory.
    Core macOS/Linux suites and build/static gates pass. Independent Terminal
    history visibility and macOS Source-toggle failures remain recorded for
    separate fixes; this is not an all-green product validation claim.
    
    Generated-by: Codex
---
 plugins/agent/api/README.md                        |   6 +-
 plugins/agent/api/README.zh-CN.md                  |   6 +-
 plugins/agent/native/src/owner.rs                  |   4 +
 plugins/agent/native/src/owner/files.rs            | 179 +++++++++++++----
 plugins/agent/native/src/owner/tests.rs            |   2 +
 .../agent/native/src/owner/tests/file_browsing.rs  | 167 ++++++++++++++-
 .../native/src/owner/tests/file_reconciliation.rs  | 223 +++++++++++++++++++++
 .../workspace/workspace-files/engine/src/files.rs  |  89 ++++++--
 .../workspace-files/engine/src/files/tests.rs      |  58 ++++++
 products/maka/cli/DEPENDENCIES.rust.tsv            |  11 +-
 10 files changed, 678 insertions(+), 67 deletions(-)

diff --git a/plugins/agent/api/README.md b/plugins/agent/api/README.md
index ba1d980083..0053b75005 100644
--- a/plugins/agent/api/README.md
+++ b/plugins/agent/api/README.md
@@ -43,8 +43,10 @@ Executor `execute` receives immutable files through one optional binary resource
 
 These are fresh, read-only observations, not repository snapshots. Status returns the complete list of staged, worktree and untracked entries. Per-file diff reads complete inputs and returns text, binary, unchanged or unsupported; text patches are returned in full. Repository metadata, control files, status entries, diff inputs and patches are buffered in memory. Cancellation is cooperative; these queries do not promise bounded memory or a fixed execution time. The workspace must be the  [...]
 
-`listFiles` lists direct children of the selected Session workspace; `watchFiles` reports when that directory needs rereading. Both also work for WorkHub coordinator sessions. Use null `path` for the workspace root, or a `WorkspacePath` carrying exact relative pathname bytes as `bytesBase64`. Symlinks are leaf entries; `.git`, the workspace marker and private Host state/control directories are excluded, including in unrestricted model workspaces. Only the Session’s validated managed work [...]
+`listFiles` lists direct children of the selected Session workspace; `watchFiles` reports when that directory needs rereading. Both also work for WorkHub coordinator sessions. Use null `path` for the workspace root, or a `WorkspacePath` carrying exact relative pathname bytes as `bytesBase64`. Symlinks are leaf entries; `.git`, the workspace marker and private Host state/control directories are excluded, including in unrestricted model workspaces. Only the Session’s validated managed work [...]
 
-Start the watch, wait for `ready`, then read the first list page and compare its `directoryIdentity` with `ready`. Follow `next` for further pages; a `changed` notification means discard the cursor and reread from the beginning. Pages are live observations, so concurrent edits can change pagination. Notifications can coalesce and are not a replayable event history: reconnect with a new watch and fresh listing. Detected deletion or replacement of a selected subdirectory ends the watch wit [...]
+Start the watch, wait for `ready`, then read the first list page and compare its `directoryIdentity` with `ready`. Follow `next` for further pages; a `changed` notification means discard the cursor and reread from the beginning. Pages are live observations, so concurrent edits can change pagination. Notifications can coalesce and are not a replayable event history: reconnect with a new watch and fresh listing. Detected deletion or replacement of a selected subdirectory ends the watch wit [...]
+
+On macOS, active watches also compare direct-child metadata. Each scan is followed by a pause of at least one second, extended to nine times the scan duration for expensive directories; this targets a 10% scanning duty cycle per subscription, rather than a fixed delivery deadline or total CPU limit. This detects persistent changes even when native notifications arrive late; unchanged scans emit nothing. Scans do not read file contents, follow symlinks or descend into child directories. ` [...]
 
 [Source](src/lib.rs) · [Cargo manifest](Cargo.toml)
diff --git a/plugins/agent/api/README.zh-CN.md b/plugins/agent/api/README.zh-CN.md
index 8da3fb407e..96a202ed56 100644
--- a/plugins/agent/api/README.zh-CN.md
+++ b/plugins/agent/api/README.zh-CN.md
@@ -43,8 +43,10 @@ Executor 的 `execute` 通过名为 `attachments` 的单个可选二进制资源
 
 这些查询提供当前的只读观察,不是仓库快照。状态完整返回已暂存、工作区和未跟踪的条目列表。单文件 diff 读取完整输入,区分文本、二进制、未变化和不支持的情况;文本补丁完整返回。仓库元数据、control 文件、状态条目、diff 输入和补丁在内存中缓冲。取消采用协作方式;这些查询不承诺有界内存或固定执行时限。所选工作区必须是仓库根目录;外部过滤器、稀疏检出、子模块等不支持的仓库特性会明确失败,不执行配置中的命令。工作区或比较基准变化后应重新查询。协议类型见 [Git 声明](src/contract_git.rs);`snapshotPatch` 在工作区写者全部结清后捕获已完成工作的不可变补丁。捕获会读取完整源内容,并在发布前将完整补丁缓冲在内存中;`readPatch` 分页读取该原始产物,后续执行和 Host 重启不会改变它。
 
-`listFiles` 列出所选 Session 工作区中一个目录的直接子项,`watchFiles` 通知该目录需要重新读取;也适用于 WorkHub 协调者会话。`path` 为 null 表示工作区根目录,其他路径使用 `WorkspacePath`,以 `bytesBase64` 保留相对文件名的原始字节。符号链接作为叶子展示,不进入其目标;排除 `.git`、工作区标记及 Host 私有状态/control 目录,模型配置为无限制访问时也不例外。私有状态内仅允许读取 Session 已验证的受管 worktree。每页最多 128 项、512 KiB,最多扫描 100,000 个直接子项;路径最多 4,096 字节、64 层。平台无法表示的文件名明确报错,不做有损转换。
+`listFiles` 列出所选 Session 工作区中一个目录的直接子项,`watchFiles` 通知该目录需要重新读取;也适用于 WorkHub 协调者会话。`path` 为 null 表示工作区根目录,其他路径使用 `WorkspacePath`,以 `bytesBase64` 保留相对文件名的原始字节。符号链接作为叶子展示,不进入其目标;排除 `.git`、工作区标记及 Host 私有状态/control 目录,模型配置为无限制访问时也不例外。私有状态内仅允许读取 Session 已验证的受管 worktree。每页最多 128 项、512 KiB;路径最多 4,096 字节。平台无法表示的文件名明确报错,不做有损转换。
 
-先订阅并等待 `ready`,再读取第一页,并核对它与 `ready` 的 `directoryIdentity` 一致;通过 `next` 继续分页。收到 `changed` 后丢弃游标,从第一页重新读取。分页反映实时目录,并发编辑可能改变分页结果。通知可合并,不提供历史事件重放;重连后重新订阅和读取。检测到所选子目录删除或替换后,以 `unavailable` 结束订阅;Session/工作区授权失效或原生监听失败则以错误结束。macOS 上,空闲工作区根目录的移动可能直到下一次通知、读取或重连才被发现。离开目录时关闭订阅。
+先订阅并等待 `ready`,再读取第一页,并核对它与 `ready` 的 `directoryIdentity` 一致;通过 `next` 继续分页。收到 `changed` 后丢弃游标,从第一页重新读取。分页反映实时目录,并发编辑可能改变分页结果。通知可合并,不提供历史事件重放;重连后重新订阅和读取。检测到所选子目录删除或替换后,以 `unavailable` 结束订阅;Session/工作区授权失效或文件系统观察失败则以错误结束。离开目录时关闭订阅。
+
+macOS 上,活动订阅还会比较直接子项的元数据。每次扫描后至少等待一秒;扫描耗时较长时,等待时间延长到该次扫描耗时的九倍,目标是每个订阅约用 10% 的时间扫描,并不承诺固定通知期限或限制总 CPU 用量。即使原生通知延迟,也能发现持续存在的变化;未变化时不发送通知。扫描不读取文件内容、不跟随符号链接,也不进入子目录。`ready` 会等待首次扫描;大目录或较慢的存储可能延迟就绪和后续通知。关闭订阅会等待其正在执行的文件系统工作结束。
 
 [源码](src/lib.rs) · [Cargo 配置](Cargo.toml)
diff --git a/plugins/agent/native/src/owner.rs b/plugins/agent/native/src/owner.rs
index 37f93c471b..a0ea00f84e 100644
--- a/plugins/agent/native/src/owner.rs
+++ b/plugins/agent/native/src/owner.rs
@@ -194,6 +194,8 @@ pub(crate) struct Owner {
     producer_gate: Arc<Mutex<()>>,
     #[cfg(test)]
     title_write_gate: std::sync::Mutex<Option<Arc<title::WriteGate>>>,
+    #[cfg(all(test, target_os = "macos"))]
+    file_native_hints: std::sync::atomic::AtomicBool,
     stop: CancellationToken,
 }
 #[derive(Clone, Copy)]
@@ -474,6 +476,8 @@ impl Owner {
             producer_gate: Arc::default(),
             #[cfg(test)]
             title_write_gate: std::sync::Mutex::default(),
+            #[cfg(all(test, target_os = "macos"))]
+            file_native_hints: std::sync::atomic::AtomicBool::new(true),
             stop,
         }))
     }
diff --git a/plugins/agent/native/src/owner/files.rs b/plugins/agent/native/src/owner/files.rs
index 136685602f..d962a9ac9f 100644
--- a/plugins/agent/native/src/owner/files.rs
+++ b/plugins/agent/native/src/owner/files.rs
@@ -156,51 +156,137 @@ impl Owner {
         watch: &mut Watch,
         context: &Context,
     ) -> Result<Value, String> {
-        // Subscribe before revalidating the captured Session. Earlier changes
-        // are caught by the read; later changes remain pending on this receiver.
-        let mut commits = self.store.subscribe_commits();
-        commits.borrow_and_update();
-        let mut change = Some(FileChange::Ready {
-            directory_identity: directory.directory_identity().clone(),
-        });
-        loop {
-            let capture = directory.clone();
-            let valid = worktrees::blocking(context.scope(), &self.stop, move |_| {
-                capture.validate().map_err(file_failure)
-            })
-            .await;
-            self.check_file_session(session, original, context.scope())
-                .await?;
-            match valid {
-                Ok(()) => {}
-                Err(error) if error == "agent_files_changed" => {
-                    let terminal = FileChange::Unavailable {
-                        reason: FileUnavailable::DirectoryChanged,
-                    };
-                    return self.emit_file_change(terminal, context).await;
-                }
-                Err(error) => return Err(error),
+        #[cfg(target_os = "macos")]
+        let mut snapshot = None;
+        let result = async {
+            // Subscribe before revalidating the captured Session. Earlier changes
+            // are caught by the read; later changes remain pending on this receiver.
+            let mut commits = self.store.subscribe_commits();
+            commits.borrow_and_update();
+            #[cfg(not(all(test, target_os = "macos")))]
+            let native_hints = true;
+            #[cfg(all(test, target_os = "macos"))]
+            let native_hints = self.file_native_hints.load(std::sync::atomic::Ordering::Relaxed);
+            #[cfg(target_os = "macos")]
+            let mut next_scan;
+            #[cfg(target_os = "macos")]
+            {
+                self.check_file_session(session, original, context.scope()).await?;
+                let capture = directory.clone();
+                let baseline = worktrees::blocking(context.scope(), &self.stop, move |cancel| {
+                    let started = std::time::Instant::now();
+                    let current = capture.snapshot(&cancel).map_err(file_failure)?;
+                    Ok((current, started.elapsed()))
+                }).await;
+                let (current, elapsed) = match baseline {
+                    Ok(value) => value,
+                    Err(error) => {
+                        self.check_file_session(session, original, context.scope()).await?;
+                        if error == "agent_files_changed" {
+                            return self.emit_file_change(FileChange::Unavailable {
+                                reason: FileUnavailable::DirectoryChanged,
+                            }, context).await;
+                        }
+                        return Err(error);
+                    }
+                };
+                snapshot = Some(current);
+                next_scan = next_file_scan(elapsed);
+                self.check_file_session(session, original, context.scope()).await?;
             }
-            if let Some(change) = change {
-                self.emit_file_change(change, context).await?;
+            let mut change = Some(FileChange::Ready {
+                directory_identity: directory.directory_identity().clone(),
+            });
+            loop {
+                let capture = directory.clone();
+                let valid = worktrees::blocking(context.scope(), &self.stop, move |_| {
+                    capture.validate().map_err(file_failure)
+                })
+                .await;
+                self.check_file_session(session, original, context.scope())
+                    .await?;
+                match valid {
+                    Ok(()) => {}
+                    Err(error) if error == "agent_files_changed" => {
+                        let terminal = FileChange::Unavailable {
+                            reason: FileUnavailable::DirectoryChanged,
+                        };
+                        return self.emit_file_change(terminal, context).await;
+                    }
+                    Err(error) => return Err(error),
+                }
+                if let Some(change) = change {
+                    self.emit_file_change(change, context).await?;
+                }
+                change = tokio::select! {
+                    biased;
+                    _ = context.scope().cancellation.cancelled() => return Err("agent_files_cancelled".into()),
+                    _ = self.stop.cancelled() => return Err("agent_files_cancelled".into()),
+                    // A due scan precedes advisory/commit traffic. Non-macOS has no
+                    // snapshot or timer; this permanently pending branch is inert.
+                    _ = async {
+                        #[cfg(target_os = "macos")]
+                        tokio::time::sleep_until(next_scan).await;
+                        #[cfg(not(target_os = "macos"))]
+                        std::future::pending::<()>().await;
+                    } => {
+                        #[cfg(target_os = "macos")]
+                        {
+                            self.check_file_session(session, original, context.scope()).await?;
+                            let capture = directory.clone();
+                            let previous = snapshot.take().expect("baseline snapshot");
+                            let current = worktrees::blocking(context.scope(), &self.stop, move |cancel| {
+                                let started = std::time::Instant::now();
+                                let current = capture.snapshot(&cancel).map_err(file_failure)?;
+                                let changed = previous != current;
+                                drop(previous);
+                                Ok((current, changed, started.elapsed()))
+                            }).await;
+                            let changed = match current {
+                                Ok((current, changed, elapsed)) => {
+                                    snapshot = Some(current);
+                                    next_scan = next_file_scan(elapsed);
+                                    Ok(changed)
+                                }
+                                Err(error) => Err(error),
+                            };
+                            self.check_file_session(session, original, context.scope()).await?;
+                            match changed {
+                                Ok(changed) => changed.then_some(FileChange::Changed),
+                                Err(error) if error == "agent_files_changed" => {
+                                    return self.emit_file_change(FileChange::Unavailable {
+                                        reason: FileUnavailable::DirectoryChanged,
+                                    }, context).await;
+                                }
+                                Err(error) => return Err(error),
+                            }
+                        }
+                        #[cfg(not(target_os = "macos"))]
+                        unreachable!("reconciliation is macOS only")
+                    },
+                    result = watch.changed(), if native_hints => {
+                        // A native observation failure ends the stream. Reconnect
+                        // starts with a fresh read, never an invented replay cursor.
+                        result.map_err(file_failure)?;
+                        Some(FileChange::Changed)
+                    },
+                    result = commits.changed() => {
+                        result.map_err(|_| "agent_observation_closed")?;
+                        commits.borrow_and_update();
+                        None
+                    },
+                };
             }
-            change = tokio::select! {
-                biased;
-                _ = context.scope().cancellation.cancelled() => return Err("agent_files_cancelled".into()),
-                _ = self.stop.cancelled() => return Err("agent_files_cancelled".into()),
-                result = watch.changed() => {
-                    // A native observation failure ends the stream. Reconnect
-                    // starts with a fresh read, never an invented replay cursor.
-                    result.map_err(file_failure)?;
-                    Some(FileChange::Changed)
-                },
-                result = commits.changed() => {
-                    result.map_err(|_| "agent_observation_closed")?;
-                    commits.borrow_and_update();
-                    None
-                },
-            };
+        }.await;
+        #[cfg(target_os = "macos")]
+        if let Some(snapshot) = snapshot.take() {
+            worktrees::blocking(context.scope(), &self.stop, move |_| {
+                drop(snapshot);
+                Ok(())
+            })
+            .await?;
         }
+        result
     }
 
     async fn emit_file_change(
@@ -221,6 +307,15 @@ impl Owner {
     }
 }
 
+#[cfg(target_os = "macos")]
+fn next_file_scan(elapsed: std::time::Duration) -> tokio::time::Instant {
+    // Keep small active directories fresh. Large scans rest for nine times
+    // their duration, targeting 10% scan duty per subscription rather than
+    // consuming a core continuously; native hints remain active between scans.
+    let pause = std::time::Duration::from_secs(1).max(elapsed.saturating_mul(9));
+    tokio::time::Instant::now() + pause
+}
+
 // Only backend-owned static causes cross the service boundary. OS paths and
 // arbitrary error Display strings never become a client error or log payload.
 fn file_failure(error: io::Error) -> String {
diff --git a/plugins/agent/native/src/owner/tests.rs b/plugins/agent/native/src/owner/tests.rs
index 87cd1cd109..b537533997 100644
--- a/plugins/agent/native/src/owner/tests.rs
+++ b/plugins/agent/native/src/owner/tests.rs
@@ -53,6 +53,8 @@ mod files;
 
 #[path = "tests/file_browsing.rs"]
 mod file_browsing;
+#[path = "tests/file_reconciliation.rs"]
+mod file_reconciliation;
 
 #[path = "tests/health.rs"]
 mod health;
diff --git a/plugins/agent/native/src/owner/tests/file_browsing.rs b/plugins/agent/native/src/owner/tests/file_browsing.rs
index 68e88a8d50..1824fae262 100644
--- a/plugins/agent/native/src/owner/tests/file_browsing.rs
+++ b/plugins/agent/native/src/owner/tests/file_browsing.rs
@@ -24,6 +24,35 @@ fn path(name: &str) -> Value {
     json!({"bytesBase64":STANDARD.encode(name.as_bytes())})
 }
 
+// Keep the actual query's Scope until both Host cleanup and native work settle.
+async fn settled_list_files(f: &Fixture, input: Value) -> Result<Value, String> {
+    let observed = scope(&f.issuer, true);
+    let accepted = f
+        .app
+        .client()
+        .start(
+            f.binding(2).await,
+            "listFiles".into(),
+            input,
+            observed.clone(),
+            Attachments::new().into(),
+        )
+        .await;
+    let result = match accepted {
+        Ok(accepted) => {
+            let completed = accepted.completion().await;
+            completed.cleanup.and(completed.result)
+        }
+        Err(error) => Err(error),
+    };
+    let finished = observed.resources.finish().await;
+    finished.map_err(|error| format!("listFiles resources: {error:?}"))?;
+    if !observed.resources.is_idle() {
+        return Err("listFiles resource custody did not settle".into());
+    }
+    result
+}
+
 #[tokio::test]
 async fn list_files_reads_selected_directories_without_crossing_session_or_symlink_boundaries() {
     tokio::time::timeout(Duration::from_secs(45), async {
@@ -271,9 +300,58 @@ async fn watch_files_invalidates_reconnects_and_settles_without_retaining_observ
     tokio::time::timeout(Duration::from_secs(60), async {
         let f = Fixture::new("http://127.0.0.1:1/v1", None).await;
         let session = f.create("Watched files").await;
-        let selected = "parent/a/b/c/d/e/f/g/h/i/j/k/l/m/n/target";
+        let selected = "parent/d01/d02/d03/d04/d05/d06/d07/d08/d09/d10/d11/d12/d13/d14/d15/d16/d17/d18/d19/d20/d21/d22/d23/d24/d25/d26/d27/d28/d29/d30/d31/d32/d33/d34/d35/d36/d37/d38/d39/d40/d41/d42/d43/d44/d45/d46/d47/d48/d49/d50/d51/d52/d53/d54/d55/d56/d57/d58/d59/d60/d61/d62/d63/target";
         let directory = f.workspace.join(selected);
         std::fs::create_dir_all(&directory).unwrap();
+        // Probe both public methods and settle their resources before asserting
+        // failures, so a refused observation cannot strand its owners.
+        let parent = selected.rsplit_once('/').unwrap().0;
+        let parent_page = settled_list_files(&f, json!({"sessionId":session,"path":path(parent),"after":null})).await;
+        let listed = settled_list_files(&f, json!({"sessionId":session,"path":path(selected),"after":null})).await;
+        let observed = scope(&f.issuer, true);
+        let subscription = f.app.client().subscribe(
+            f.binding(2).await,
+            "watchFiles".into(),
+            json!({"sessionId":session,"path":path(selected)}),
+            observed.clone(),
+            Attachments::new().into(),
+        ).await;
+        let watch_probe: Result<Value, String> = match subscription {
+            Ok(mut stream) => {
+                let first = tokio::time::timeout(Duration::from_secs(10), stream.recv()).await;
+                stream.cancel();
+                let completed = stream.completion().await;
+                match completed.cleanup {
+                    Err(error) => Err(format!("watch cleanup failed: {error:?}")),
+                    Ok(()) => match first {
+                        Err(error) => Err(format!("watch first item timed out: {error}")),
+                        Ok(None) => Err(format!("watch ended before Ready: {:?}", completed.result)),
+                        Ok(Some(value)) => Ok(value),
+                    },
+                }
+            }
+            Err(error) => Err(error),
+        };
+        let finished = observed.resources.finish().await;
+        let idle = observed.resources.is_idle();
+        f.drained().await;
+        if parent_page.is_err() || listed.is_err() || !watch_probe.as_ref().is_ok_and(|event| event["kind"] == "ready") || finished.is_err() || !idle {
+            let app_shutdown = f.app.shutdown().await;
+            let config_shutdown = f.config.shutdown().await;
+            assert!(app_shutdown.is_ok(), "app shutdown: {app_shutdown:?}");
+            assert!(config_shutdown.is_ok(), "config shutdown: {config_shutdown:?}");
+            assert!(finished.is_ok(), "watch resource finish: {finished:?}");
+            assert!(idle, "watch resource custody must settle");
+            assert!(listed.is_ok() && watch_probe.is_ok(), "65-component public observations must succeed: listFiles={listed:?}; watchFiles={watch_probe:?}; parent={parent_page:?}");
+            panic!("65-component preflight failed: parent={parent_page:?}; watchFiles={watch_probe:?}");
+        }
+        let parent_page = parent_page.unwrap();
+        assert_eq!(parent_page["entries"], json!([{"path":path(selected),"kind":"directory"}]));
+        assert_eq!(parent_page["next"], Value::Null);
+        let listed = listed.unwrap();
+        assert_eq!(listed["entries"], json!([]));
+        assert_eq!(listed["next"], Value::Null);
+        assert_eq!(watch_probe.unwrap(), json!({"kind":"ready","directoryIdentity":listed["directoryIdentity"]}));
         let request = json!({"sessionId":session,"path":path(selected)});
         let denied = f
             .app
@@ -330,8 +408,8 @@ async fn watch_files_invalidates_reconnects_and_settles_without_retaining_observ
                 .await
                 .unwrap();
             let expected = match operation {
-                0 | 1 => json!([{"path":path("parent/a/b/c/d/e/f/g/h/i/j/k/l/m/n/target/created"),"kind":"file"}]),
-                2 => json!([{"path":path("parent/a/b/c/d/e/f/g/h/i/j/k/l/m/n/target/renamed"),"kind":"file"}]),
+                0 | 1 => json!([{"path":path("parent/d01/d02/d03/d04/d05/d06/d07/d08/d09/d10/d11/d12/d13/d14/d15/d16/d17/d18/d19/d20/d21/d22/d23/d24/d25/d26/d27/d28/d29/d30/d31/d32/d33/d34/d35/d36/d37/d38/d39/d40/d41/d42/d43/d44/d45/d46/d47/d48/d49/d50/d51/d52/d53/d54/d55/d56/d57/d58/d59/d60/d61/d62/d63/target/created"),"kind":"file"}]),
+                2 => json!([{"path":path("parent/d01/d02/d03/d04/d05/d06/d07/d08/d09/d10/d11/d12/d13/d14/d15/d16/d17/d18/d19/d20/d21/d22/d23/d24/d25/d26/d27/d28/d29/d30/d31/d32/d33/d34/d35/d36/d37/d38/d39/d40/d41/d42/d43/d44/d45/d46/d47/d48/d49/d50/d51/d52/d53/d54/d55/d56/d57/d58/d59/d60/d61/d62/d63/target/renamed"),"kind":"file"}]),
                 3 => json!([]),
                 _ => unreachable!(),
             };
@@ -378,7 +456,7 @@ async fn watch_files_invalidates_reconnects_and_settles_without_retaining_observ
         assert_eq!(current["directoryIdentity"], fresh["directoryIdentity"]);
         assert_eq!(
             current["entries"],
-            json!([{"path":path("parent/a/b/c/d/e/f/g/h/i/j/k/l/m/n/target/fresh"),"kind":"file"}])
+            json!([{"path":path("parent/d01/d02/d03/d04/d05/d06/d07/d08/d09/d10/d11/d12/d13/d14/d15/d16/d17/d18/d19/d20/d21/d22/d23/d24/d25/d26/d27/d28/d29/d30/d31/d32/d33/d34/d35/d36/d37/d38/d39/d40/d41/d42/d43/d44/d45/d46/d47/d48/d49/d50/d51/d52/d53/d54/d55/d56/d57/d58/d59/d60/d61/d62/d63/target/fresh"),"kind":"file"}])
         );
         // Closing an observer leaves the Session and Owner available.
         stream.cancel();
@@ -528,3 +606,84 @@ async fn watch_files_rechecks_session_authority_on_commits_without_filesystem_ch
     .await
     .unwrap();
 }
+
+#[tokio::test]
+async fn list_files_keeps_returned_cursor_live_after_directory_grows_past_100000_entries() {
+    let f = Fixture::new("http://127.0.0.1:1/v1", None).await;
+    let session = f.create("Large live file cursor").await;
+    let directory = f.workspace.join("many");
+    // Keep the two remaining files' original bytes, independent of listing.
+    let original_99999 = b"original suffix 099999\0\xff";
+    let original_100000 = b"original suffix 100000\0\xfe";
+    let observed: Result<_, String> = async {
+        std::fs::create_dir(&directory).map_err(|error| error.to_string())?;
+        for index in 99_871..=100_000 {
+            let bytes: &[u8] = match index {
+                99_999 => original_99999,
+                100_000 => original_100000,
+                _ => b"",
+            };
+            std::fs::write(directory.join(format!("file-{index:06}")), bytes)
+                .map_err(|error| error.to_string())?;
+        }
+        let first = settled_list_files(
+            &f,
+            json!({"sessionId":session,"path":path("many"),"after":null}),
+        )
+        .await?;
+        // Every new key sorts before the unmodified, genuinely returned cursor.
+        // No native watcher is open during these 99,871 metadata creations.
+        for index in 0..=99_870 {
+            std::fs::File::create_new(directory.join(format!("file-{index:06}")))
+                .map_err(|error| error.to_string())?;
+        }
+        let second = settled_list_files(
+            &f,
+            json!({"sessionId":session,"path":path("many"),"after":first["next"]}),
+        )
+        .await;
+        let count = std::fs::read_dir(&directory)
+            .map_err(|error| error.to_string())?
+            .try_fold(0_usize, |count, entry| entry.map(|_| count + 1))
+            .map_err(|error| error.to_string())?;
+        let preserved_99999 =
+            std::fs::read(directory.join("file-099999")).map_err(|error| error.to_string())?;
+        let preserved_100000 =
+            std::fs::read(directory.join("file-100000")).map_err(|error| error.to_string())?;
+        Ok((first, second, count, preserved_99999, preserved_100000))
+    }
+    .await;
+    // Settle the original Host before asserting either query result.
+    f.drained().await;
+    let app_shutdown = f.app.shutdown().await;
+    let config_shutdown = f.config.shutdown().await;
+    assert!(app_shutdown.is_ok(), "app shutdown: {app_shutdown:?}");
+    assert!(
+        config_shutdown.is_ok(),
+        "config shutdown: {config_shutdown:?}"
+    );
+    let (first, second, count, preserved_99999, preserved_100000) = observed.unwrap();
+    let expected: Vec<_> = (99_871..=99_998)
+        .map(|index| json!({"path":path(&format!("many/file-{index:06}")),"kind":"file"}))
+        .collect();
+    assert_eq!(first["entries"], json!(expected));
+    assert_eq!(
+        first["next"],
+        json!({"directoryIdentity":first["directoryIdentity"],"after":path("many/file-099998")})
+    );
+    assert_eq!(count, 100_001);
+    assert_eq!(preserved_99999, original_99999);
+    assert_eq!(preserved_100000, original_100000);
+    let second = second.expect(
+        "listFiles must apply its returned live cursor in a directory with 100001 real entries",
+    );
+    assert_eq!(
+        second["entries"],
+        json!([
+            {"path":path("many/file-099999"),"kind":"file"},
+            {"path":path("many/file-100000"),"kind":"file"}
+        ])
+    );
+    assert_eq!(second["directoryIdentity"], first["directoryIdentity"]);
+    assert_eq!(second["next"], Value::Null);
+}
diff --git a/plugins/agent/native/src/owner/tests/file_reconciliation.rs b/plugins/agent/native/src/owner/tests/file_reconciliation.rs
new file mode 100644
index 0000000000..617b2692c6
--- /dev/null
+++ b/plugins/agent/native/src/owner/tests/file_reconciliation.rs
@@ -0,0 +1,223 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#![cfg(target_os = "macos")]
+
+use super::*;
+use base64::{Engine, engine::general_purpose::STANDARD};
+use maka_host_runtime::application::Subscription;
+
+fn path(name: &str) -> Value {
+    json!({"bytesBase64":STANDARD.encode(name.as_bytes())})
+}
+
+async fn next(stream: &mut Subscription) -> Result<Value, String> {
+    tokio::time::timeout(Duration::from_secs(10), stream.recv())
+        .await
+        .map_err(|error| format!("reconciliation item deadline: {error}"))?
+        .ok_or_else(|| "reconciliation observation ended early".into())
+}
+
+async fn quiet(stream: &mut Subscription) -> Result<(), String> {
+    // A negative behavior window spanning the one-second cadence, not a sleep
+    // used to synchronize a mutation or wait for a successful observation.
+    match tokio::time::timeout(Duration::from_millis(1200), stream.recv()).await {
+        Err(_) => Ok(()),
+        Ok(value) => Err(format!("unchanged snapshot invented an item: {value:?}")),
+    }
+}
+
+async fn changed(stream: &mut Subscription) -> Result<(), String> {
+    let value = next(stream).await?;
+    if value == json!({"kind":"changed"}) {
+        Ok(())
+    } else {
+        Err(format!(
+            "expected actual-state invalidation, received {value:?}"
+        ))
+    }
+}
+
+async fn listed(
+    f: &Fixture,
+    session: &str,
+    identity: &Value,
+    name: Option<&str>,
+) -> Result<(), String> {
+    let page = f
+        .query(
+            "listFiles",
+            json!({"sessionId":session,"path":path("reconciled"),"after":null}),
+        )
+        .await?;
+    let entries = match name {
+        Some(name) => json!([{"path":path(&format!("reconciled/{name}")),"kind":"file"}]),
+        None => json!([]),
+    };
+    if page["directoryIdentity"] != *identity
+        || page["entries"] != entries
+        || page["next"] != Value::Null
+    {
+        return Err(format!(
+            "unexpected reconciled page: {page:?}, expected {entries:?}"
+        ));
+    }
+    Ok(())
+}
+
+async fn phase(f: &Fixture, session: &str, reconnect: Option<&Value>) -> Result<Value, String> {
+    let observed = scope(&f.issuer, true);
+    let subscription = f
+        .app
+        .client()
+        .subscribe(
+            f.binding(2).await,
+            "watchFiles".into(),
+            json!({"sessionId":session,"path":path("reconciled")}),
+            observed.clone(),
+            Attachments::new().into(),
+        )
+        .await;
+    let mut failures = Vec::new();
+    let result = match subscription {
+        Ok(mut stream) => {
+            // Keep every fallible business result until the original native
+            // Watch, Host subscription and Scope have all settled below.
+            let result = async {
+                let ready = next(&mut stream).await?;
+                if ready["kind"] != "ready" {
+                    return Err(format!("expected Ready: {ready:?}"));
+                }
+                let identity = ready["directoryIdentity"].clone();
+                if reconnect.is_some_and(|original| original != &identity) {
+                    return Err("reconnect changed the original directory identity".into());
+                }
+                listed(f, session, &identity, reconnect.map(|_| "created")).await?;
+                quiet(&mut stream).await?;
+                let directory = f.workspace.join("reconciled");
+                if reconnect.is_none() {
+                    std::fs::write(directory.join("created"), b"first")
+                        .map_err(|e| e.to_string())?;
+                    changed(&mut stream).await?;
+                    listed(f, session, &identity, Some("created")).await?;
+                    if std::fs::read(directory.join("created")).map_err(|e| e.to_string())?
+                        != b"first"
+                    {
+                        return Err("created bytes differ".into());
+                    }
+                } else {
+                    // Reopening establishes a baseline containing this existing
+                    // child; a directory-only watcher cannot cover its overwrite.
+                    std::fs::write(directory.join("created"), b"other")
+                        .map_err(|e| e.to_string())?;
+                    changed(&mut stream).await?;
+                    listed(f, session, &identity, Some("created")).await?;
+                    if std::fs::read(directory.join("created")).map_err(|e| e.to_string())?
+                        != b"other"
+                    {
+                        return Err("same-size overwrite bytes differ".into());
+                    }
+                    std::fs::rename(directory.join("created"), directory.join("renamed"))
+                        .map_err(|e| e.to_string())?;
+                    changed(&mut stream).await?;
+                    listed(f, session, &identity, Some("renamed")).await?;
+                    if std::fs::read(directory.join("renamed")).map_err(|e| e.to_string())?
+                        != b"other"
+                        || directory.join("created").exists()
+                    {
+                        return Err("rename did not preserve bytes and remove the old name".into());
+                    }
+                    std::fs::remove_file(directory.join("renamed")).map_err(|e| e.to_string())?;
+                    changed(&mut stream).await?;
+                    listed(f, session, &identity, None).await?;
+                    quiet(&mut stream).await?;
+                    // With native hints disabled, only the scheduled scan can
+                    // notice that the held directory is no longer at its path.
+                    std::fs::rename(&directory, f.workspace.join("moved-reconciled"))
+                        .map_err(|e| e.to_string())?;
+                    let terminal = next(&mut stream).await?;
+                    if terminal != json!({"kind":"unavailable","reason":"directory_changed"}) {
+                        return Err(format!("expected terminal directory change: {terminal:?}"));
+                    }
+                    if tokio::time::timeout(Duration::from_secs(10), stream.recv())
+                        .await
+                        .map_err(|error| format!("terminal observation deadline: {error}"))?
+                        .is_some()
+                    {
+                        return Err("directory change did not end observation".into());
+                    }
+                }
+                Ok(identity)
+            }
+            .await;
+            stream.cancel();
+            let completed = stream.completion().await;
+            if let Err(error) = completed.cleanup {
+                failures.push(format!("watch cleanup: {error}"));
+            }
+            result
+        }
+        Err(error) => Err(error),
+    };
+    let finished = observed.resources.finish().await;
+    if let Err(error) = finished {
+        failures.push(format!("Scope finish: {error:?}"));
+    }
+    if !observed.resources.is_idle() {
+        failures.push("original watch Scope retained resources".into());
+    }
+    f.drained().await;
+    match result {
+        Ok(identity) if failures.is_empty() => Ok(identity),
+        Ok(_) => Err(failures.join("; ")),
+        Err(error) => {
+            failures.insert(0, error);
+            Err(failures.join("; "))
+        }
+    }
+}
+
+#[tokio::test]
+async fn actual_shallow_changes_reconcile_without_consuming_native_hints() {
+    tokio::time::timeout(Duration::from_secs(45), async {
+        let f = Fixture::new("http://127.0.0.1:1/v1", None).await;
+        f.owner
+            .file_native_hints
+            .store(false, std::sync::atomic::Ordering::Relaxed);
+        let session = f.create("Independent file reconciliation").await;
+        let result = async {
+            std::fs::create_dir(f.workspace.join("reconciled")).map_err(|e| e.to_string())?;
+            let identity = phase(&f, &session, None).await?;
+            phase(&f, &session, Some(&identity)).await?;
+            Ok::<(), String>(())
+        }
+        .await;
+        f.drained().await;
+        let app_shutdown = f.app.shutdown().await;
+        let config_shutdown = f.config.shutdown().await;
+        assert!(app_shutdown.is_ok(), "app shutdown: {app_shutdown:?}");
+        assert!(
+            config_shutdown.is_ok(),
+            "config shutdown: {config_shutdown:?}"
+        );
+        assert!(result.is_ok(), "independent reconciliation: {result:?}");
+    })
+    .await
+    .unwrap();
+}
diff --git a/plugins/workspace/workspace-files/engine/src/files.rs b/plugins/workspace/workspace-files/engine/src/files.rs
index d529d561a4..fbbf1765e8 100644
--- a/plugins/workspace/workspace-files/engine/src/files.rs
+++ b/plugins/workspace/workspace-files/engine/src/files.rs
@@ -37,10 +37,8 @@ pub use watch::Watch;
 #[cfg(test)]
 mod tests;
 
-const MAX_SCAN: usize = 100_000;
 const PAGE_SIZE: usize = 128;
 const MAX_PAGE_BYTES: usize = 512 * 1024;
-const MAX_DEPTH: usize = 64;
 
 #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
 #[serde(rename_all = "camelCase", deny_unknown_fields)]
@@ -101,6 +99,25 @@ pub enum FileUnavailable {
     DirectoryChanged,
 }
 
+/// Actual admitted shallow state; no file content or descendant traversal.
+#[cfg(target_os = "macos")]
+#[derive(Debug, PartialEq, Eq)]
+pub struct Snapshot(BTreeMap<Vec<u8>, EntryMetadata>);
+
+#[cfg(target_os = "macos")]
+#[derive(Debug, PartialEq, Eq)]
+struct EntryMetadata {
+    dev: u64,
+    ino: u64,
+    mode: u32,
+    nlink: u64,
+    size: u64,
+    mtime: i64,
+    mtime_nsec: i64,
+    ctime: i64,
+    ctime_nsec: i64,
+}
+
 struct Anchor {
     path: PathBuf,
     directory: Dir,
@@ -133,9 +150,6 @@ impl Directory {
                 .map_err(|_| error("files_invalid_path"))?,
                 None => PathBuf::new(),
             };
-            if relative.components().count() > MAX_DEPTH {
-                return Err(error("files_invalid_path"));
-            }
             let directory = crate::directory::open(workspace, identity)?;
             let root = dunce::canonicalize(workspace)?;
             let private_root = dunce::canonicalize(private_root)?;
@@ -211,6 +225,59 @@ impl Directory {
             || (path.starts_with(&self.private_root)
                 && !(self.managed && path.starts_with(&self.anchors[0].path)))
     }
+    fn excluded_child(&self, directory: &Path, name: &std::ffi::OsStr) -> bool {
+        name.as_encoded_bytes().eq_ignore_ascii_case(b".git")
+            || name == std::ffi::OsStr::new(crate::workspace::MARKER_FILE)
+            || self.excluded(&directory.join(name))
+    }
+    /// Reconcile only direct, admitted entries through the held target descriptor.
+    #[cfg(target_os = "macos")]
+    pub fn snapshot(&self, cancel: &AtomicBool) -> io::Result<Snapshot> {
+        use cap_std::fs::MetadataExt;
+        expose((|| {
+            interrupted(cancel)?;
+            self.validate_inner()?;
+            interrupted(cancel)?;
+            let target = self.anchors.last().expect("target anchor");
+            let mut entries = BTreeMap::new();
+            for entry in target.directory.entries()? {
+                interrupted(cancel)?;
+                let entry = match entry {
+                    Ok(entry) => entry,
+                    Err(error) if error.kind() == io::ErrorKind::NotFound => continue,
+                    Err(error) => return Err(error),
+                };
+                let name = entry.file_name();
+                if self.excluded_child(&target.path, &name) {
+                    continue;
+                }
+                let metadata = match target.directory.symlink_metadata(&name) {
+                    Ok(metadata) => metadata,
+                    Err(error) if error.kind() == io::ErrorKind::NotFound => continue,
+                    Err(error) => return Err(error),
+                };
+                interrupted(cancel)?;
+                entries.insert(
+                    name.as_encoded_bytes().to_vec(),
+                    EntryMetadata {
+                        dev: metadata.dev(),
+                        ino: metadata.ino(),
+                        mode: metadata.mode(),
+                        nlink: metadata.nlink(),
+                        size: metadata.size(),
+                        mtime: metadata.mtime(),
+                        mtime_nsec: metadata.mtime_nsec(),
+                        ctime: metadata.ctime(),
+                        ctime_nsec: metadata.ctime_nsec(),
+                    },
+                );
+            }
+            interrupted(cancel)?;
+            self.validate_inner()?;
+            interrupted(cancel)?;
+            Ok(Snapshot(entries))
+        })())
+    }
     pub fn list(&self, after: Option<&FileCursor>, cancel: &AtomicBool) -> io::Result<FilePage> {
         expose(self.list_inner(after, cancel))
     }
@@ -236,17 +303,11 @@ impl Directory {
             .transpose()?;
         let target = self.anchors.last().expect("target anchor");
         let mut entries = BTreeMap::new();
-        for (visited, entry) in target.directory.entries()?.enumerate() {
+        for entry in target.directory.entries()? {
             interrupted(cancel)?;
-            if visited >= MAX_SCAN {
-                return Err(error("files_too_large"));
-            }
             let entry = entry?;
             let name = entry.file_name();
-            if name.as_encoded_bytes().eq_ignore_ascii_case(b".git")
-                || name == std::ffi::OsStr::new(crate::workspace::MARKER_FILE)
-                || self.excluded(&target.path.join(&name))
-            {
+            if self.excluded_child(&target.path, &name) {
                 continue;
             }
             let relative = gix::path::to_unix_separators_on_windows(
@@ -309,7 +370,7 @@ impl Directory {
         self.validate_inner()?;
         Ok(page)
     }
-    /// Install the bounded nonrecursive chain before emitting Ready or reading a list.
+    /// Install the nonrecursive anchor chain before emitting Ready or reading a list.
     pub fn watch(&self) -> io::Result<Watch> {
         expose(watch::open(self))
     }
diff --git a/plugins/workspace/workspace-files/engine/src/files/tests.rs b/plugins/workspace/workspace-files/engine/src/files/tests.rs
index 64e9764a91..4689155ab1 100644
--- a/plugins/workspace/workspace-files/engine/src/files/tests.rs
+++ b/plugins/workspace/workspace-files/engine/src/files/tests.rs
@@ -183,3 +183,61 @@ async fn ancestor_move_wakes_without_reading_the_moved_outside_directory() {
     watch.close().await.unwrap();
     assert_eq!(result.unwrap_err().to_string(), "files_changed");
 }
+
+#[cfg(target_os = "macos")]
+#[test]
+fn shallow_snapshot_observes_actual_entries_without_native_hints() {
+    use std::os::unix::{
+        ffi::OsStringExt,
+        fs::{MetadataExt, symlink},
+    };
+    let f = Fixture::new();
+    let directory = f.open(None).unwrap();
+    let cancel = AtomicBool::new(false);
+    let empty = directory.snapshot(&cancel).unwrap();
+    assert_eq!(empty.0.len(), 0);
+    fs::write(f.private.join("private"), b"private").unwrap();
+    fs::write(f.control.join("control"), b"control").unwrap();
+    fs::create_dir(f.root.join(".GiT")).unwrap();
+    fs::write(f.root.join(crate::workspace::MARKER_FILE), b"marker").unwrap();
+    assert_eq!(directory.snapshot(&cancel).unwrap(), empty);
+    let raw = std::ffi::OsString::from_vec(b"raw-\\name".to_vec());
+    fs::write(f.root.join(&raw), b"first").unwrap();
+    let created = directory.snapshot(&cancel).unwrap();
+    assert_eq!(
+        created.0.keys().cloned().collect::<Vec<_>>(),
+        vec![b"raw-\\name".to_vec()]
+    );
+    fs::write(f.root.join(&raw), b"other").unwrap();
+    let updated = directory.snapshot(&cancel).unwrap();
+    assert_ne!(updated, created);
+    let old_metadata = fs::metadata(f.root.join(&raw)).unwrap();
+    fs::write(f.root.join("replacement"), b"other").unwrap();
+    std::fs::File::open(f.root.join("replacement"))
+        .unwrap()
+        .set_times(std::fs::FileTimes::new().set_modified(old_metadata.modified().unwrap()))
+        .unwrap();
+    fs::rename(f.root.join("replacement"), f.root.join(&raw)).unwrap();
+    let replaced_metadata = fs::metadata(f.root.join(&raw)).unwrap();
+    assert_eq!(replaced_metadata.len(), old_metadata.len());
+    assert_eq!(
+        replaced_metadata.modified().unwrap(),
+        old_metadata.modified().unwrap()
+    );
+    assert_ne!(replaced_metadata.ino(), old_metadata.ino());
+    assert_ne!(directory.snapshot(&cancel).unwrap(), updated);
+    symlink(f.temp.path().join("absent"), f.root.join("link")).unwrap();
+    assert_eq!(directory.snapshot(&cancel).unwrap().0.len(), 2);
+    fs::remove_file(f.root.join(&raw)).unwrap();
+    let removed = directory.snapshot(&cancel).unwrap();
+    assert_eq!(
+        removed.0.keys().cloned().collect::<Vec<_>>(),
+        vec![b"link".to_vec()]
+    );
+    assert_eq!(directory.snapshot(&cancel).unwrap(), removed);
+    cancel.store(true, Ordering::Relaxed);
+    assert_eq!(
+        directory.snapshot(&cancel).unwrap_err().to_string(),
+        "files_cancelled"
+    );
+}
diff --git a/products/maka/cli/DEPENDENCIES.rust.tsv b/products/maka/cli/DEPENDENCIES.rust.tsv
index 1fb7607fd8..82820fde73 100644
--- a/products/maka/cli/DEPENDENCIES.rust.tsv
+++ b/products/maka/cli/DEPENDENCIES.rust.tsv
@@ -833,7 +833,7 @@ pin-project@1.1.13		X									X
 pip-preview@0.32.0											X					
 piper@0.2.5		X									X					
 pkcs1@0.7.5		X									X					
-pkcs1@0.8.0-rc.4		X									X					
+pkcs1@0.8.0-rc.5		X									X					
 pkcs8@0.10.2		X									X					
 pkcs8@0.11.0		X									X					
 pkg-config@0.3.34		X									X					
@@ -931,7 +931,7 @@ ropey@2.0.0-beta.1		X									X
 roxmltree@0.20.0		X									X					
 roxmltree@0.21.1		X									X					
 rquickjs@0.12.9											X					
-rsa@0.10.0-rc.18		X									X					
+rsa@0.10.0-rc.19		X									X					
 rsa@0.9.10		X									X					
 rusqlite@0.39.0											X					
 rustc_version@0.4.1		X									X					
@@ -1029,7 +1029,7 @@ spin@0.10.1											X
 spin@0.9.9											X					
 spirv@0.4.0+sdk-1.4.341.0		X														
 spki@0.7.3		X									X					
-spki@0.8.0		X									X					
+spki@0.8.1		X									X					
 sponge-cursor@0.1.0		X									X					
 sqlx-core@0.9.0		X									X					
 sqlx-macros-core@0.9.0		X									X					
@@ -1226,13 +1226,16 @@ windows_x86_64_msvc@0.48.5		X									X
 windows_x86_64_msvc@0.52.6		X									X					
 windows_x86_64_msvc@0.53.1		X									X					
 windows-collections@0.3.2		X									X					
+windows-core@0.57.0		X									X					
 windows-core@0.58.0		X									X					
 windows-core@0.59.0		X									X					
 windows-core@0.62.2		X									X					
 windows-future@0.3.2		X									X					
+windows-implement@0.57.0		X									X					
 windows-implement@0.58.0		X									X					
 windows-implement@0.59.0		X									X					
 windows-implement@0.60.2		X									X					
+windows-interface@0.57.0		X									X					
 windows-interface@0.58.0		X									X					
 windows-interface@0.59.3		X									X					
 windows-link@0.1.3		X									X					
@@ -1241,6 +1244,7 @@ windows-native-keyring-store@1.1.0		X									X
 windows-numerics@0.3.1		X									X					
 windows-registry@0.4.0		X									X					
 windows-registry@0.6.1		X									X					
+windows-result@0.1.2		X									X					
 windows-result@0.2.0		X									X					
 windows-result@0.3.4		X									X					
 windows-result@0.4.1		X									X					
@@ -1258,6 +1262,7 @@ windows-targets@0.53.5		X									X
 windows-threading@0.2.1		X									X					
 windows-version@0.1.7		X									X					
 windows-win@3.0.0						X										
+windows@0.57.0		X									X					
 windows@0.58.0		X									X					
 windows@0.59.0		X									X					
 windows@0.62.2		X									X					


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@maka.apache.org
For additional commands, e-mail: commits-help@maka.apache.org