Skip to content

滑动窗口与延时播放

buffered 将观察、落盘、云端上传与首页展示分别调度。应用与 Music 的每次已观测语义变化立即进入有序内存窗口,硬件采用较慢采样和变化阈值;每 5 分钟上传最近 15 分钟的完整窗口。网页通常落后 7 分钟,在本地按时间回放,再将短时间内的多次普通应用/歌曲切换合并展示,减少闪动。首页的合并不会删除时间线中的事件,也不增加 KV 写入。

默认参数

参数默认值作用
应用与 Music 变化系统通知优先尽早观察切换,不把通知当作可靠消息队列
Music 兜底采样2 秒异步读取播放状态与元数据,弥补未收到的通知
电池、系统负载采样30 秒电量按整数百分比/供电变化记;负载按阈值记录;小幅真变化在 120 秒门槛后的成功采样合并记录
普通本机检查点10 秒将期间的内存变化合并成一次原子保存,安全边界立即保存
无变化覆盖心跳30 秒更新磁盘中的观测范围,不添加重复状态事件
上传间隔300 秒每包一次 Worker 请求、一次 KV 写入
滑动窗口最多 900 秒含起点基线、之后的变化与明确缺口;相邻正常包重叠 600 秒
正常播放延迟420 秒300 秒分批 + 120 秒传播与拉取余量;不是全球准时保证
网页拉取60 秒一次获取整个窗口,其余播放在页面内存中完成
首页普通状态切换通常最多每 2 秒一次短时间连续变化只显示最后候选;隐私遮蔽、清空等立即处理
云端截止时间window_end + 600 秒绝对过期,不因旧包晚到或读取而延长
包大小/条目上限512 KiB/2048 个事件/128 个缺口内存、磁盘、上传和解析有界;溢出明确记缺口

上述采集、落盘与展示值均为当前实现的固定策略,不新增可分别调整的配置键;v2 的上传、窗口和播放策略字段保持不变。新安装默认 buffered,已有 ecorealtime 安装保留原模式,须显式迁移。运行只依赖 macOS 自带工具和 osascript 执行的 JXA,不需要 Node.js、Python 或第三方守护进程。

变化记录、落盘与展示

层次行为保留的内容
内存事件应用/Music 每次已观测语义变化立即入队,保留顺序和时间不因 10 秒落盘或 2 秒展示节奏删除这些事件;仍受 900 秒窗口及容量限制
私有检查点普通变化最多每 10 秒合并写入;无变化时每 30 秒保存覆盖心跳一次写入包含期间所有仍在窗口内的事件
上传包每 300 秒一次完整窗口与磁盘写入次数、首页画面切换次数无关
API 回放分类接口按服务器时间减 420 秒投影,时间线接口返回原窗口没有首页的 2 秒视觉合并
首页展示前台应用、Music 和运行列表的普通切换通常最多每 2 秒一次短时间连续变化只显示最后候选,不保证每个原始事件都出现在首页

检查点周期从上次成功保存计算;重复的应用/Music 状态不触发新的待保存变化。启动、睡眠、隐私配置变化、上传前后等安全边界立即保存,不等待普通检查点周期。普通事件先存在内存中,意外崩溃可能损失最近约 10 秒尚未保存的变化;这不是掉电无损日志。没有事件变化时只按 30 秒心跳推进已观测覆盖,不制造重复事件。

硬件仍每 30 秒采样。电量按整数百分比记录,或在充电/供电状态变化时记录。系统负载与最后已记录值比较:任一负载的差值达到 max(0.20, |旧值| × 5%) 时记录整个 system;较小但真实的变化在距上次记录达到 120 秒后,于随后一次成功采样时记录最新值,通常约 2 分钟,也可能多一个 30 秒采样周期及任务延迟。数值与 null 之间的转换立即记录。阈值以下的每个微小波动不会全部保留,这项策略减少重复写入和近似相同的事件,不改变 API 的数字字段类型。

首页以原始回放状态作为展示候选,合并后的画面仅供渲染,并不代表精确单一时刻的 API 快照;敏感应用遮蔽、字段清空、音乐停止/不可用、运行列表移除条目、缺口、离线和新会话会立即清除旧显示,不等待 2 秒。相同曲目的封面补充也可以立即显示。这里的“立即”指页面已经取得并回放到该状态之后,不绕过 7 分钟延时或 KV 传播。需要精确消费窗口事件时使用 /api/timeline,或复用未经视觉合并的 WindowPlayback接入示例

一次窗口如何播放

假设 10:00 开始一个新会话:

本机时间本机观察/上传网页行为
10:00记录当前状态作为基线尚无有效上传窗口时显示离线/等待窗口
10:01Code → Safari记录应用字段变化,暂不上传
10:02歌曲 A → 歌曲 B记录整段 music 替换,包含曲名和可用封面 URL
10:05上传 10:00–10:05 窗口拉取后保存到页面内存,显示暖机倒计时
10:07持续采集开始播放 10:00 的基线
10:08持续采集展示 10:01 的 Safari 切换
10:09持续采集展示 10:02 的歌曲 B
10:20上传 10:05–10:20 窗口以重叠内容接续播放,不重复播放旧事件

首次正常播放约在启动 7 分钟后;首包上传前浏览器尚不知道本机已经启动,可能显示离线/等待窗口,取得首包后才有暖机倒计时。网络与平台延迟可能使等待更久。网页不会把窗口末尾的最新状态直接跳到播放头;展示层只合并当前播放头附近的短时间普通变化,也不会为了显得在线而延续未观察到的状态。简单分类 API 仍可按需读取,它们返回服务器时间减 420 秒对应的切片;窗口尚未覆盖该时刻或该时刻落在缺口内时返回 offline

数据结构

每个 schema_version: 2 包都能独立重建自身窗口,不依赖 Worker 保存上一包。baseline 是窗口起点完整 v1 快照;events 只携带发生变化的顶层字段,字段对象整体替换,不做深层 JSON Patch。事件具有会话内序号和实际观测时间;序号严格递增,时间不倒退。同一时间可以有多个有序变化。

例如下面片段表示一次换歌;这不是可单独提交的完整包:

json
{
  "seq": 27,
  "at": "2026-09-09T10:02:00.000Z",
  "changes": {
    "music": {
      "state": "playing",
      "track": "Example Song B",
      "artist": "Example Artist"
    }
  }
}

窗口滑动时,过旧变化折叠到新的起点基线,过期事件退出队列。敏感应用在进入队列之前已过滤。关闭采集项或更改屏蔽名单会清空本机队列并建立新会话,防止下次批次重新发出旧隐私设置下的数据。完整字段与边界 · OpenAPI

缓存、故障与恢复

情况处理
无状态变化不重复添加事件,每 30 秒保存本机覆盖心跳,仍按 5 分钟上传窗口
意外崩溃恢复最近私有检查点;普通变化最多约 10 秒尚在内存,未保存部分无法保证恢复
短暂断网或一次上传失败保留本机有界窗口;下次发送最新完整窗口,利用重叠恢复尚未淘汰的变化
休眠、采集失败、进程重启、时钟异常标记 sleepcollectionrestartclock 缺口或重建会话;时钟回拨不能形成负长度缺口,未知时段不补造事件
窗口容量耗尽增加 dropped_events 并推进窗口起点;仍有可表示的正长度缺口时记录 overflow,不把丢弃部分当作连续历史
网页一次拉取失败或读到较旧 KV保留已经验证且未过期的内存窗口;不回退到旧批次,不重播已消费事件
播放到尚未取得的窗口末尾显示缓冲中并停播,后续窗口覆盖播放头时按顺序续播;实际延迟可超过 7 分钟
断网超过可恢复范围明确展示不可恢复的缺口,再从仍保留的最早位置恢复;不无限补传历史
隐私配置或会话变化清理旧队列;网页接到新会话后丢弃旧窗口并重新暖机

本机 window-cache.json 位于权限 700 的安装目录,文件权限 600,保存的单个窗口时间跨度最多 15 分钟。磁盘检查点通常落后内存至多约 10 秒的普通变化、或 30 秒无变化覆盖,加上阻塞/调度延迟;最早记录可能因此早于当前时间减 15 分钟,不能理解成文件内容恰在 15 分钟时立即物理删除。网页仅在内存保存窗口,不写 localStorage。Worker 覆盖同一个 KV 键,不给每个事件建立单独键。API 的精确截止为窗口末尾之后 10 分钟,KV 物理绝对过期按秒向上取整(最多多不足 1 秒),因此一个最早的事件在云端最多可被当前窗口覆盖约 25 分钟。这是短期活动缓冲,不能称为“完全没有历史”。本机休眠或程序停止时无法主动执行磁盘清理,重新运行会裁剪已过期窗口。隐私与删除边界

这不是无损操作录像。采集仅包括允许公开的应用、Music 和硬件状态,不包括按键、点击、文档、屏幕或浏览历史。非常快的切换、未送达的通知、采样间隔内的短暂状态或设备休眠都可能无法观测。Apple 说明分布式通知可能延迟或丢弃,不能作为可靠事件日志;MacFlare 的通知加轮询仍不能保证捕捉每次真实操作。Apple 通知机制

KV 为最终一致存储,旧值或不存在的结果也可能被缓存,更新传播可能需要 60 秒或更久,没有固定最长传播时间。420 秒是正常运行的播放目标,不能保证所有地区无停顿或绝不漏片。Cloudflare 一致性说明

额度与迁移

全天定时写入估算为 86400 / 300 = 288 次,比 eco 的 720 次减少 60%,比 realtime 的 2880 次减少 90%。变化数量主要影响包大小,不增加该包的 KV 写入次数;启动、手动发送、失败后重试和同账户其他项目仍需另计。免费 KV 当前每日 1000 写入,多个命名空间共享账户额度;同一键最高每秒一次写入。Cloudflare 定价 · 平台限制

先发布新版 Worker,再迁移当前用户的 Agent:

sh
npm ci
npm run deploy
/bin/bash scripts/install.sh --profile buffered

STATUS_TTL_SECONDS 继续控制旧快照模式,不改变 v2 窗口策略。新 Worker 同时接受旧 /api/update,便于逐步升级;旧 Worker 没有 /api/batch,因此不可反过来先启动新版批量 Agent。首次安装和回退步骤见 配置部署

MIT License · 文档使用本地搜索,无第三方分析脚本。