# 隐私与数据说明 Viff 是本地优先的 Git 桌面客户端。**Viff 不自动上传诊断数据,也没有使用统计或产品分析**。它唯一的默认网络请求是[应用内更新检查](#应用内更新检查)(可在设置中关闭);此外只有你主动执行 `clone` / `fetch` / `push` 时,Git 才会访问你配置的 remote。日志、崩溃记录和诊断信息只保存在这台电脑上,是否交给维护者由你决定。 本文说明 Viff 记录什么、放在哪里、保留多久、如何删除,以及把诊断包发到公开 Issue 前要注意什么。面向维护者的实现说明见 [observability.md](observability.md)。 ## 一句话总结 - 只有你主动执行 `clone` / `fetch` / `push` 等 Git 操作时,Git 才会按你配置的 remote 访问网络;Viff 自身唯一的网络请求是应用内更新检查,不会为了日志或诊断发起请求。 - 日志默认写在本地配置目录,最多 5 个文件、总量约 10 MiB、保留 14 天。 - 诊断包只在你点击保存时生成,保存位置由你选择,不会自动上传。 - 发给公开 Issue 前请先预览内容;安全漏洞请走私密渠道(见 [SECURITY.md](../SECURITY.md))。 ## 应用内更新检查 - **时机**:启动时检查一次(设置里“Check for updates at startup”默认开启,可关闭),或点击 `Help → Check for Updates…` 手动检查。 - **请求**:`GET https://api.github.com/repos/1lck/viff/releases`,只读取公开的版本、发布说明、资产文件名/大小和 `SHA256SUMS`。请求不含账号身份、令牌、仓库内容、路径或使用数据;`User-Agent` 只带 Viff 版本号。 - **下载**:发现新版本后,只有你点击 Update 才会从 GitHub Releases 下载对应平台的安装包;下载完成后用 `SHA256SUMS` 做 SHA-256 校验,不一致不会安装。 - **缓存**:安装包与替换 helper 保存在用户缓存目录的 `Viff/updates/` 下(macOS `~/Library/Caches/Viff/updates/`,Windows `%LocalAppData%\Viff\updates\`,Linux `$XDG_CACHE_HOME/Viff/updates/`)。安装成功后旧文件会自动清理;你也可以直接删除该目录,Viff 下次需要时会重新下载。 - **失败与关闭**:自动检查失败时静默,不打扰你;手动检查才显示错误。关闭自动检查后,Viff 不会在启动时发起该请求。 - **边界**:更新检查不包含遥测、A/B 实验或远程配置;它只用于回答“是否有新版本”和下载用户确认的安装包。 ## Viff 会记录什么 | 类别 | 内容 | 用途 | | --- | --- | --- | | 应用事件(JSONL) | 启动/退出、设置加载、仓库打开/刷新/监听、任务开始/结束/取消、通知、诊断导出等事件的时间、级别、耗时、计数、错误码 | 还原"什么时候、对哪个仓库、做了什么、失败了什么" | | Git 事件 | Git 子命令名、是否写操作、退出码、错误分类、耗时;失败时附脱敏后截断的错误输出摘要 | 定位失败命令与原因 | | Console 镜像 | Git 工具窗口 Console 中最近一段命令与输出(脱敏、截断) | 导出时附带失败上下文 | | 崩溃记录 | panic 栈、崩溃发生位置、崩溃前最近的事件快照,写入 `crash/` 目录 | 启动闪退、异常退出时保留现场 | | 诊断会话 | 你点击 `Help → Report a Problem…` 后才开始:临时提高日志级别并给期间事件加 `incident` 标记 | 只保留"出事那段时间"的详细上下文 | | 环境快照 | 仅导出时收集:操作系统与架构、Viff 版本/commit/构建日期、Go/Viva/Git 版本、主题/缩放/字体、配置目录占位 | 判断是否与平台、版本、渲染环境相关 | 说明: - 这里的"记录"指结构化诊断事件,**不录屏、不录音、不记录键盘输入或剪贴板内容**。`Report a Problem…` 不会采集你的屏幕画面或声音;它只记录诊断事件,直到你手动停止或退出 Viff。 - 诊断会话只在你手动停止时生成诊断包;不点 `Stop Recording and Save Diagnostics…` 不会产出文件。 - 日志是 JSONL 事件流,不是自由文本聊天记录。 ## Viff 不会记录什么 以下内容不会写入日志或诊断包: - 仓库文件内容、diff、补丁正文、提交说明/提交消息; - 完整命令行参数(默认只记录子命令与安全的少量参数,不记完整 argv); - 环境变量; - 令牌、口令、私钥等凭据(脱敏规则命中即替换为 `***`); - remote 的完整 URL(默认只保留 scheme 和主机名)、仓库绝对路径(用哈希或占位替代); - 设置中的密钥类字段值(如 SSH 命令、签名 key、凭据助手的值;只记录字段名,不导出值); - 你的屏幕画面、键盘输入、剪贴板内容。 ## 脱敏与残留风险 日志落盘和导出前会经过统一脱敏: - 常见凭据格式(`ghp_…`、`github_pat_…`、`glpat-…`、`AKIA…`、`xox…`、私钥块、`token=…` / `password=…` 等)替换为 `***`; - remote URL 去掉用户名、令牌和路径,只保留主机名; - 家目录替换为 `~`,仓库根目录替换为 ``,其他绝对路径替换为 ``; - Git 输出按条截断(错误摘要约 2 KiB)。 但脱敏不是万能的:Git 的原始错误里仍可能带出项目名、分支名、主机名、邮箱等上下文;默认设置下也保留仓库内的相对文件路径和分支名(排查冲突/路径问题需要)。因此: - 分享前请先打开诊断包查看 `summary.md` 与 `events.jsonl`; - 如果发现不想公开的信息,请不要上传公开 Issue,可只保留最小片段或改用私密渠道。 ## 日志存放位置与保留期 | 平台 | 日志目录 | 崩溃记录 | | --- | --- | --- | | macOS | `~/Library/Application Support/Viff/logs/` | `~/Library/Application Support/Viff/crash/` | | Windows | `%AppData%\Viff\logs\` | `%AppData%\Viff\crash\` | | Linux | `~/.config/Viff/logs/`(遵循 `$XDG_CONFIG_HOME`) | `~/.config/Viff/crash/` | - 目录权限 `0700`,日志文件权限 `0600`;文件名为 `viff-*.jsonl`。 - 单个日志文件约 2 MiB 轮转;最多保留 5 个文件、总量约 10 MiB、超过 14 天的文件在启动时清理。 - `crash/` 保存崩溃记录(栈与崩溃前最近事件);导出诊断包时最多带最新 3 份。你可以随时删除该目录。 - 日志写入是异步、有界的:队列满时丢弃新事件并计数,不会阻塞界面。 ## 诊断包:只在你主动导出时生成 - 入口:`Help → Report a Problem…`(先录制再导出)或 `Help → Save Diagnostics…`(直接导出最近 30 分钟)。 - 保存位置和文件名由你在保存对话框中选择;不保存、不上传、不分享,文件就只在本机。 - 诊断包是 zip,总大小上限约 5 MiB,可能包含: ```text viff-diagnostics-<日期>.zip ├── summary.md # 自动生成的人读摘要(先看这个) ├── manifest.json # 版本、时间窗、文件清单、哈希、脱敏档位、截断标记 ├── env.txt # 平台、版本、渲染与字体等环境信息 ├── settings-summary.json # 设置摘要(不含密钥值) ├── events.jsonl # 时间窗内的结构化事件 ├── console.txt # 脱敏、截断后的最近 Git 命令与输出 ├── repo.txt # 仓库摘要(路径已哈希) └── crash/ # 如有,最多 3 份崩溃记录 ``` - 条目超限时会被截断,并在 `manifest.json` 中标记;包内不含仓库文件内容、diff 或提交说明。 - 导出成功后界面会提示 zip 路径;若提供 `Copy Issue Template`,可把模板粘贴到 Issue。 ## 公开 Issue 是公开场所 GitHub Issue 的正文和附件对所有人可见,并可能被搜索引擎、镜像和归档服务长期保留。上传诊断包前请记住: - 先预览 zip 内容(解压或用系统压缩工具打开),确认没有你不想公开的信息; - 私有仓库名、客户名、内部主机名、邮箱等是否可公开,由你判断; - 安全问题不要开公开 Issue,请使用 [私密漏洞报告](https://github.com/1lck/viff/security/advisories/new),见 [SECURITY.md](../SECURITY.md); - 无法公开诊断包时,只提供 `summary.md` 的相关片段、错误码和时间点,维护者可以据此给出下一步排查建议。 ## 如何删除诊断数据 1. 退出 Viff(日志写入是异步的,退出前会尽量刷盘)。 2. 打开日志目录:`Help → Open Log Folder`,或按上表手动进入。 3. 删除 `logs/` 目录;如需一并删除崩溃记录,回到上一级删除 `crash/` 目录。 4. 已导出的诊断包 zip 在你保存的位置,请自行删除。 5. 更新下载缓存可在缓存目录的 `Viff/updates/` 中删除(见[应用内更新检查](#应用内更新检查))。 6. 最近事件的内存环在进程退出后清空;Viff 不保留云端副本,删除后无法恢复。 只想清理日志、保留设置时,只删 `logs/` 与 `crash/`;删除整个 `Viff` 目录会同时移除设置和最近项目记录。 ## AI 生成提交信息(可选,默认关闭) 提交面板的 AI 按钮是可选的:设置里 `AI 端点` 留空即不启用,界面只在点击后显示一张说明卡片。 启用后,点击按钮会把当前改动发给**你自己配置的端点**: - 发:分支名、最近五条提交的哈希与标题、变更文件的状态与路径、每个文件的 diff,以及模型收到的规则文本(内置规则,或你自己写的规则); - 不发:未变更文件、仓库以外的任何文件、设置、日志、诊断包,密钥只用于鉴权头,不进入请求正文; - 范围限制:diff 每个文件截断到 4000 字符、最多 8 个文件,lock 文件(`go.sum`、`package-lock.json` 等)与二进制 diff 跳过;自定义规则只改变模型收到的指令,不会放宽这些限制; - 接收方由你决定:换成别的 Base URL 就是换成别的接收方,Viff 不代理、不记录请求与响应内容; - 结果只填进提交输入框,不会自动提交。 规则与项目选择的记录保存在与 `settings.json` 同目录的 `prompts.json` 里(只含你写的规则文本、「哪个仓库用哪条」以及最近一次选中的规则,不含密钥);端点、模型与密钥保存在 `settings.json` 里(密钥为明文),与 SSH、签名设置同一处理方式;详见 [0027](decisions/0027-ai-commit-message.md) 与 [0035](decisions/0035-ai-prompt-rules.md)。 ## 冲突上下文复制(Copy for AI) 冲突查看器里的 `Copy for AI` 与 `Copy This Block` 只做一件事:把当前冲突的结构化上下文写进**系统剪贴板**,由你自己粘贴到外部 AI 工具。 - 发:仓库根路径、文件路径、操作类型(merge/rebase/cherry-pick/revert)、ours/theirs 的实际来源标签、冲突类型与行尾信息,以及每个冲突块的行范围与 ours/base/theirs 原文; - 不发:Viff 不调用任何模型、不发起网络请求;这段文本只留在剪贴板,直到被其他程序读取或被你覆盖; - 范围限制:单块超过 200 行或 20 KB、全文超过 200 KB 时截断,并在截断处写明丢了多少行、哪些块没有包含; - 不记:复制的内容不写入日志、崩溃记录或诊断包,界面只提示"已复制",不记录文本本身; - 边界:剪贴板对同机其他程序可见;粘到哪里、发给谁由你决定。外部工具保存文件后,Viff 的文件监听会刷新冲突视图,之后仍由你手动"标记为已解决"。 这次复制不经过 Viff 的网络层,也不需要配置端点或密钥;取舍与复审条件见 [0032](decisions/0032-ai-conflict-context.md)。 ## 未来如果增加上传功能 当前版本没有自动上传、没有崩溃上报服务端,也没有向任何服务器发送诊断数据。如果未来增加诊断包上传: - 会另立架构决策记录(ADR)并更新本说明; - 必须对每份诊断包取得你的显式同意,而不是一个默认开启的总开关; - 会同时给出服务端保留期与按 ID 删除的方式; - 不会静默改变现在的"本地保存、用户主动分享"行为。 ## 相关文档 - 遇到问题如何排查、如何生成诊断包:[troubleshooting.md](troubleshooting.md) - 安全漏洞私密报告:[SECURITY.md](../SECURITY.md) - 维护者设计说明:[observability.md](observability.md)(日志/诊断的设计与实现) - 应用内更新的取舍与限制:[decisions/0023-app-update.md](decisions/0023-app-update.md)