把一台机器收到的每一条通知实时抄进本地库,每天汇成一页「这一天发生了什么」。 它不提醒你 —— 它是给你回头看的。
你每天被几十上百条通知划过屏幕。三天后想不起来「周四下午到底跟谁定了什么」—— 翻聊天记录要一个 app 一个 app 翻,而且那条你当时没点开的通知已经不存在了。
| 系统没有通知历史库 | macOS 的通知中心只存「你还没点掉的那些」,点一下就消失。要能回查,只能在通知到达的那一刻抄走 —— 这就是为什么必须有一个常驻进程,而不是每天跑一次的脚本。 |
| 一天七十条流水看不出发生了什么 | 同一个人十分钟里发六条,在流水里是六行,在你脑子里是一件事。所以入库是逐条,展示按「同一个人 15 分钟内连续消息并成一段」,一天七十条塌成十几件事。 |
| 同一条通知会来两遍 | 手机转发过来的和电脑上原生弹的是同一条,但 bundle id 不同(iOS 一个、macOS 一个)。不归一化就会双份入库,日报里每件事都说两遍。 |
| 噪音和正事混在一起 | 脚本巡检、构建结果、营销短信照样入库(漏了就再也补不回来),但默认在视图里折叠,一键可以放回来。「入库」和「展示」是两个判断,别混成一个。 |
| 验证码是唯一需要即时性的 | 只有它有一条静默动作:识别到就进剪贴板,不弹窗、不推送。其余一律只记录。会打扰你的功能被整段删掉了 —— 那是这个工具存在理由的反面。 |
| 通知正文 = 聊天内容 | 这是整个系统最敏感的地方,也决定了它的形状:库不出本机,只有日报页离开这台机器(第 3 节详述)。 |
通知正文里有微信聊天、短信、邮件主题。这一条决定了整个系统的形状 —— 不是先做系统再补隐私,是隐私先定形状。
| 为什么不上传库 | 服务器上放一份聊天正文,风险面是永久的(快照、备份、镜像、任何一次配置失误)。而收益只是「换台机器也能查」—— 这个收益远配不上那个代价,所以直接不做。 |
| 为什么服务器不跑生成逻辑 | 只要服务器要生成日报,它就得能读库。纯静态件是唯一能让服务器「无从泄露」的形态 —— 它手里根本没有原始数据。 |
| 为什么用 rsync 而不是接口推送 | 方向是单向的:本机推、服务器收。服务器没有任何一条能反向拉本机数据的路径。--delete 让过了保留期的旧页在站上也一起消失,避免「本机已抹除、站上还留着」。 |
| 保留期怎么处理 | 超过保留期只抹标题/正文/副标题,保留元数据 —— 长周期的「谁最常找我、几点最吵」这类统计照样能算,正文却已经不在了。 |
| 那条摘要是谁写的 | 日报正文由大模型总结,这意味着当天通知正文会发给它。不接受就一个开关关掉,采集和时间线照常 —— 但要说在前面,不能藏。走的是本机已有的订阅通道,不经第三方 API key。 |
| 怎么防它编 | 抽出来的每一条时间节点必须带原文片段,这是硬要求。带了片段,「它是不是编的」当场能核 —— 核不上的宁可不抽。 |
| 为什么必须常驻 | 文件系统事件(FSEvents / launchd WatchPaths)对系统通知库的容器实测 0 次上报;换成 kqueue(进程持 fd 阻塞在内核事件上)实测 10/10 唤醒、延迟 1–5 秒。「零常驻」和「覆盖到微信这类 app」互斥,这是量出来的,不是取舍偏好。 |
| 四个采集源 | 系统通知库(覆盖本机所有 app)、手机转发的推送归档、短信库、邮件原始文件。四个源产出同一个归一化事件结构,去重和展示只认这个结构。 |
| 去重 | 键 = SHA-256(归一化 bundle | 标题 | 正文 | 60 秒桶),写库时 INSERT OR IGNORE。iOS 与 macOS 的两个 bundle id 先映射到同一个规范名,否则等于没去重。 |
| 合并成「事」 | 同一 app + 同一发信人 + 间隔 ≤ 15 分钟 → 并成一段。合并只发生在展示层,库里永远是逐条 —— 合并规则以后要改,历史数据不用动。 |
| 「你当时没看见」这一位 | 判据不靠猜:通知还在系统队列里 = 你没点掉它。纯读元数据,不因此提醒你。复盘时这一位最有价值 —— 它标出的正是你漏掉的那几条。 |
| 一天怎么划 | 只认这台机器的系统时区,不认 TZ 环境变量。踩过:这台机器的 TZ 表示「人在哪」而不是时间口径,两把尺子各走各的,结果站上每个「日期」装的其实是「昨天下午到今天下午」,而页面看起来完全正常。现在程序侧和数据库侧共用同一把尺子,且代码里不写任何时区名字面量。 |
| 全文检索 | SQLite FTS5 + trigram 分词(中文可搜)。坑:trigram 对 < 3 字符的查询永远返回空且不报错 —— 短查询自动降级模糊匹配,并把降级这件事打印出来,不静默假装检索还在。 |
| 自反馈环闸门 | 实测事故:弹一条「验证码已复制 ××××××」→ 这条通知自己被采集 → 又命中验证码规则 → 再弹,12 秒滚三代。时间桶去重挡不住(每代桶不同)。解法是弹之前把内容哈希落库登记,采集时命中即跳过 —— 落库不放内存,因为进程重启后那条还没被消费的通知仍会被采到。 |
| 模型输出的容错 | 模型漏右方括号是稳定复现不是偶发(同一输入连试三次同样畸形)。所以严格解析失败后过一遍括号修补:扫描时维护容器栈,只补收尾符号、绝不猜内容,修不动就照常报错。不用「重试一次」当解法 —— 同样的输入给同样的畸形,重试只是把同一个错再烧一遍。 |
| 网页按钮怎么够到本机 | 日报是静态件,浏览器点一下没法调本机命令。自定义 URL scheme 是错的方向(在手机上是死的)。走队列:网页只下单 → 本机每分钟领单执行 → 回写状态。并且退出码 0 ≠ 真做成了,只认真正成功那一路打出的标记,否则会出现「页面全绿、实际一条没加」的空转。 |
| 回归测试 | 66 条自检覆盖规则匹配、去重、保留期、自反馈环闸门、时间解析、划天口径、幂等、系统集成传参。每一条都对应一次真事故 —— 拆掉哪道闸就红哪几条,反向验证过。 |