ChelseaKR/habitable
GitHub: ChelseaKR/habitable
一款离线优先、端到端加密的租户宜居性证据收集与法庭文档生成工具,通过内容哈希、RFC 3161 可信时间戳和哈希链接保管链确保证据防篡改且可独立验证。
Stars: 1 | Forks: 0
# habitable — 为租户工会提供可在法庭上使用的宜居性证据,离线且加密
[](https://scorecard.dev/viewer/?uri=github.com/ChelseaKR/habitable)
—— 一份诚实且逐项列出的供应链自我评估;请参阅以下带有日期的报告
[`docs/audits/scorecard-2026-07.md`](docs/audits/scorecard-2026-07.md),了解当前分数的含义及其影响因素。
**状态:** 可用的参考实现 · **alpha** —— 证据核心、CLI、点对点
同步、独立验证器,以及一个可访问的双语(EN/ES)可安装 Web 应用程序均已实现
并在 Python 3.14 上进行了测试(`make verify` 通过;该应用程序在两种语言中均通过了真实的 `axe-core` 扫描门控)。目前仍需完成录制的人工屏幕阅读器测试以及签名的原生应用商店二进制文件,因此
**目前请勿将其用于真实的法律事务** ·
独立的个人开源项目 · AGPL-3.0 ·
不隶属于任何雇主或客户;不包含任何专有或客户资料;非
政府系统,也非为政府客户而建。
**支持的版本:** pre-1.0,仅支持**最新版本**(见 `SECURITY.md`)。
**为什么选择这个领域。** 一个因取暖器损坏而扣留租金或对抗驱逐的租户需要
证据,而证据正是住房权力失衡所剥夺他们的东西:房东控制着
房产、维护记录,而且通常是唯一写下时间线的人。租户们用手机
拍照,但带有可编辑 EXIF 数据的裸露 JPEG 是薄弱的证据,其日期也会受到房东律师的
质疑。承诺解决此问题的现有应用程序通常是通过将每个租户的照片和
家庭住址上传到公司的云端来实现,这创建了一个单一的“蜜罐”和一个容易被施压、
被破坏或被传唤的当事方。habitable 颠覆了这一点。证据存在于租户的
设备上并经过加密;受信任的时间戳和内容哈希使得篡改可被检测到;工会
进行点对点同步,因此没有公司介于租户与他们自己的记录之间。它是本作品集中
公民数据项目在隐私和本地优先方面的同胞项目,并继承了它们在
可审计性、可访问性以及坦白说明该工具不能做什么方面的严谨态度。
## 它的功能
- **捕获**作为结构化记录的宜居性问题:照片和短视频、状况备注、
类别(供暖、霉菌、害虫、水、电气、结构)、受影响的房间,以及
随问题持续或复发时的观察时间线。
- **使每次捕获都达到证据级别。** 在捕获时,该工具会计算
原始媒体的内容哈希(SHA-256),将原始文件原封不动地密封,并写入一个只追加的保管链
条目——所有这些都瞬间且完全离线完成。然后,一旦
设备有网络连接,它就会在该哈希上获取**受信任的时间戳**(RFC 3161),
在附加签名 token 之前,该项目显示为*等待时间戳*状态。EXIF 被明确处理:
保留密封的原始文件(包括其嵌入的捕获
时间和任何 GPS)以确保证据完整性,而租户选择
共享的任何副本都可以去除位置信息。
- **记录每个问题的时间线**:发送的维修请求、房东的回应或沉默、检查,
以及恶化的情况,每个条目都带有时间戳和哈希处理,因此该序列是防篡改的。
- **点对点同步。** 组织者和案件中的租户通过
使用 CRDT 的端到端加密、直接设备到设备同步来保持记录同步,因此两个人离线编辑同一个
案件时,在重新连接后能干净地合并。没有服务器保存明文,也完全不需要
服务器。
- **导出可直接用于法庭的文档包。** 一条命令即可为某个问题或整个单元汇编一份分页的、可供法庭和检查员使用的 PDF
(以及可访问的 HTML 渲染,加上结构化的 `bundle.json`):
一份**封面表**(案件、范围、计数、日期范围),一份单独的**按时间顺序排列的证据时间线**
(在各个问题之间穿插笔记和照片),每个问题的详细信息,以及一份**保管链 /
完整性摘要**——每个项目的哈希、RFC 3161 时间戳机构和只追加保管
证明,在显示完整的同时不导出谁查看或复制了每个项目——因此接收方可以验证
事后没有任何内容被更改。
- **与组织者进行端到端共享。** 租户可以将案件——或选定的部分问题,
可选择性地隐藏单元标签——移交给一位不在该案件中的租户工会组织者,
签名并**密封至组织者已验证的公钥**,因此任何中继或信使看到的都只是
密文(`habitable share` / `receive`;信任模型在 `docs/sharing-trust-model.md` 中)。
- **起草维修请求。** `habitable letter` 根据记录的证据生成一封带有日期的
维修请求 / 通知信函给房东(可访问的 HTML + PDF),具有感知司法管辖区的
*仅作框架设定*以及常设的“非法律建议”免责声明(`docs/letter-generator.md`)。
```
$ habitable export --unit "4B" --since 2026-01-01 --out 4B-packet.pdf
habitable: unit 4B — 3 issues, 27 captures, 14 timeline entries
all 27 media items: content hash present, RFC 3161 timestamp verified
chain of custody: intact (no gaps, no out-of-order entries)
evidence appendix: hashes + timestamp tokens + custody proof (chain verified; identities not exported)
location data: stripped from shared copies; originals sealed in case vault
$ habitable verify 4B-packet.pdf
habitable: 27/27 items verify against their sealed originals and timestamp tokens — packet intact
```
验证命令是核心所在:一个文档包不是“相信我”,而是一组第三方可以针对时间戳机构和哈希独立检查的声明。
## 试用
需要 [uv](https://docs.astral.sh/uv/);正确的 Python (3.14) 会自动获取。
```
$ uv sync # create the env and install habitable + dev tools
$ uv run habitable demo # capture → seal+hash → RFC 3161 → packet → verify, on synthetic data, offline
$ make verify # the full gate: ruff + mypy --strict + pytest (property-based + tamper-detection)
```
`habitable demo` 会伪造几张带有嵌入位置的照片,将其作为证据捕获,
构建一个文档包(从共享副本中剥离了位置),并独立验证它——无需
网络且无需真实的租户数据。从那里开始:`uv run habitable --help`。
**只想看看?** 我们故意没有提供托管的应用程序(它在 `localhost` 上运行,因此您的案件永远不会
离开设备),但一个静态的 **[落地页 + 实时示例文档包](https://chelseakr.github.io/habitable/)**
展示了它的产出。安全的手机安装包**尚未发布**;请参阅诚实的
[`docs/mobile.md`](docs/mobile.md) 支持边界。要运行可选的同步中继,请参阅
[`docs/relay-deploy.md`](docs/relay-deploy.md)。
## 截图
| 本地应用程序(English / Español) | 一个导出的、可验证的文档包 |
| --- | --- |
|  |  |
该应用程序是双语的(EN/ES),可访问(WCAG 2.2 AA,受 axe 门控),并且完全在您的设备上运行。
每次导出都会附带一个可访问的 `packet.html`、一个分页的 PDF,以及一个可验证的 `bundle.json`。
## 硬性规则(已强制执行,而非纸上谈兵)
1. **永远不包含服务器端的个人数据。** 没有包含租户、地址、
照片或案件的中央数据库。明文从不会在未加密的情况下离开设备。唯一可选的网络
组件是一个仅能看到密文的同步中继,以及一个只能看到
哈希而永远看不到文件本身的公共时间戳机构。中继仍然会观察连接 *元数据*——哪些节点连接、何时连接,
以及大约传输了多少数据——即使它无法读取任何内容;缓解措施包括
无日志、可自托管的中继,以及完全没有中继的纯点对点同步,详见
`docs/threat-model.md`。本项目运营的任何内容都不会因租户的内容而被传唤,
因为它从未持有过这些内容。不要只听信我们的话:`habitable prove-no-plaintext` 会通过进程内中继运行一次真实的
同步,捕获传输中的每一个字节,并在其中搜索植入的明文
标记——或者您也可以根据
[`docs/prove-no-plaintext.md`](docs/prove-no-plaintext.md) 自己使用 `tcpdump` 捕获真实的中继。
2. **对工会记录没有中央权威。** 每个工会持有自己的密钥和自己的数据;
该项目不提供账户系统,没有可以读取或撤销工会证据的管理员,也没有
拥有记录的托管服务。复刻代码或自己运行中继不会
改变谁可以读取数据:除了密钥持有者之外,依然没有任何人能读取。
3. **防篡改是强制性的,而非可选的。** 每个捕获的项目在捕获时都会获得内容哈希,
并在设备有网络连接时尽快获得受信任的时间戳,并且每个记录都位于
只追加的、哈希链接的日志中。如果某个项目的哈希、
时间戳或保管链未通过验证,导出操作将拒绝将其作为证据呈现;它会暴露差距而不是掩盖它。
4. **原件被密封;共享是一种刻意且最小化的操作。** 原始媒体会被
逐字节保存以确保完整性。任何共享或导出的副本默认都会剥离位置信息,并且用户可以
在生产文档包之前准确看到它将披露什么。该工具绝不会悄悄
发布家庭的坐标。
5. **报复即是威胁模型。** 默认设置假设对手拥有资源和动机:静态
数据已加密;一种可隐藏案件内容的防胁迫安全开启状态 *已计划但尚未
实现*——目前唯一的静态保护是保险库加密,当构建完成后,该状态将是一种带有已记录限制的缓解措施,而不是针对胁迫或取证
对手的保证——并且该工具不收集任何分析数据,也不进行任何外部通信。工会决定
向谁披露什么,记录在 `docs/threat-model.md` 中。
## 诚实的局限 —— habitable 不做什么
在法庭上,精确界定边界是保持可信度的一部分;一个过度承诺的工具
会让依赖它的人失望。
- **不是法律建议,也不保证可采性。** habitable 会生成记录详尽的
证据。法院或机构是否采纳它,或者它有多大的分量,这是一个法律问题,
该工具无法回答。
- **它无法捏造事实不支持的案件。** 防篡改证明项目在捕获后未被
更改,而时间戳界定了它存在的时间;这两者都不能证明潜在的
情况如租户所描述的那样。该工具强化了真实的记录,但它不能创造记录。
- **它不托管任何东西。** 没有账户,没有案件云,也没有可以读取、生产
或撤销工会数据的运营者——这也意味着没有备份的丢失密钥意味着数据丢失(参见
*可恢复性*)。
- **中继只能看到元数据,看不到内容。** 如果使用同步中继,它仅读取
密文,但仍然可以观察谁与谁同步以及何时同步;纯点对点同步连这一点都可以避免。
- **时间戳机构只能看到哈希,看不到文件本身**——而且 RFC 3161 token 界定的是内容
存在 *何时*,而不是 *谁* 创建了它或它描绘了 *什么*。
- **胁迫和取证限制。** 防胁迫状态 *已计划,但尚未实现*;目前
唯一的静态保护是保险库加密。当构建完成后,它将隐藏案件内容,但不会
成为针对能力极强的胁迫或取证对手的绝对保证,并且将适用这些已记录的限制。
完整的威胁模型以及针对每个限制的缓解措施位于 `docs/threat-model.md` 中。
## 架构
```
habitable/
├── README.md
├── src/habitable/
│ ├── capture.py # media intake → hash → RFC 3161 timestamp → seal original
│ ├── evidence.py # content hashing, fixity checks, chain-of-custody log
│ ├── exif.py # explicit EXIF handling: seal original, strip shared copies
│ ├── model.py # CRDT document model for cases/issues/timeline (offline-first)
│ ├── crypto.py # local encryption at rest; E2E sync keys; key backup/rotation
│ ├── sync.py # peer-to-peer encrypted sync; relay client sees ciphertext only
│ ├── packet.py # assemble court/inspector PDF + evidence appendix
│ ├── verify.py # independent verification of hashes, timestamps, custody
│ └── config.py # timestamp authorities, sync peers, policy as versioned files
├── app/ # local-first client (PWA / desktop): capture, review, export
├── relay/ # optional ciphertext-only sync relay (encrypted deltas + metadata, never contents)
├── tests/
│ ├── fixtures/ # sample cases, tampered items, broken chains for verify tests
│ └── ... # unit, property-based, and tamper-detection tests
├── docs/ # ARCHITECTURE, threat-model.md, privacy.md, sustainability.md, evidence-method.md, governance.md, ADRs, audits/ (+ onboarding, baseline), accessibility/, recruitment/ (call for reviewers)
└── pyproject.toml
```
数据模型是每个案件对应一个 CRDT 文档,在每个设备上加密存储,因此该应用程序完全
可以在没有网络的情况下使用,并且两个离线编辑同一案件的组织者在同步时可以无冲突地
收敛。捕获是一个流水线过程:媒体输入,原件被密封并哈希处理,通过哈希获取时间戳 token,
追加保管条目。同步直接在节点之间移动加密的增量数据,
或者通过一个只能看到密文的中继进行,因此添加中继增加了可用性,而不会增加能够读取任何内容的
一方。验证是一个独立的模块,不依赖其他部分,因此
法院或反对方可以使用一个小巧的、可审计的工具来检查文档包。
## 证据引擎(法庭赖以运转的部分)
一张照片的好坏取决于对“我们怎么知道它没有被编辑过,以及它确实是在你说的时间拍摄”这一问题的回答。habitable 的构建使得这些答案可以被独立核查,而非仅仅口头声称。
- **捕获时的固定性。** 在捕获或导入媒体的那一刻,原始字节会被哈希处理
(SHA-256)并写入一个密封的案件保险库,应用程序将其视为不可变。任何后续的读取
都会重新检查哈希,因此静默损坏或篡改会表现为固定性检查失败,而不是
悄然更改的展品。
- **受信任的时间戳。** 哈希——绝不是照片本身——会被发送到 **RFC 3161** 时间戳
机构,该机构返回一个签名 token,证明内容存在的时间 *不晚于* 该时间:这是关于其创建时间的
上限,因此除非被检测到,否则项目不可能被伪造或在事后被编辑。捕获永远不会因网络而阻塞:离线时项目会立即被哈希并密封,
请求会排队,项目显示 *等待时间戳* 状态,直到
网络连接允许获取并附加 token。可以配置多个机构,因此
证明不依赖于某一方,并且 token 包含在文档包中以便进行离线验证。
- **保管链。** 对项目的每个操作——捕获、查看、为共享而复制、包含在
文档包中——都是只追加的、哈希链接日志中的一个条目。链条中的断裂或重新排序是
可检测的,导出操作会报告它,而不是将有问题的项目伪装成干净的状态呈现出来。
- **刻意处理 EXIF。** 密封的原始文件保留其嵌入的捕获时间和任何 GPS,
因为该元数据是证据记录的一部分。共享和导出的副本默认会剥离位置信息,
因此生成文档包不会泄露租户的居住地,并且该工具会精确地
显示每个输出保留或删除了哪些元数据。
- **可独立验证。** `habitable verify` 会重新推导每个哈希,验证每个时间戳
token 的签名及其返回到受信任 RFC 3161 机构的完整证书链,并遍历
保管链——仅使用文档包和密封的原始文件,无需访问工会的
其他数据。由于 TSA 的签名证书最终会过期,长期持有的文档包可以
被重新打上时间戳(在现有 token 之上打上归档时间戳),以便旧证据继续通过验证。
验证工具本身小巧且可独立审计,因此怀疑者可以在不信任
本项目的情况下确认文档包。
## 质量属性(经过工程化设计,而非凭空假设)
下面的每一个决策都响应特定的质量属性,为了可读性而分组到不同的集群中。
在对抗性威胁模型下的证据工具,其生存依赖于完整性、机密性和
可验证性,因此这些集群的权重最高。
### 完整性、证据和记录信任
**正确性** 和 **准确性** —— 捕获保留了原始字节和元数据;时间线
按发生的顺序记录了发生的事情。**精确度** 和 **保真度** —— 原件被逐字节
密封,没有重新编码;哈希精确定位确切内容,时间戳精确定位确切时间。**完整性**
—— 内容哈希加上只追加的、哈希链接的保管,使得任何更改都可被检测到。**可审计性**
—— 每个项目都带有其哈希、时间戳 token 和可验证的保管完整性证明,而完整的操作记录保留在工会的保险库中,而不是被导出。
**可证明性** —— 文档包的声明可以根据外部时间戳机构进行检查,而不是盲目相信。**可追溯性**
—— 捕获 → 密封 → 保管条目 → 文档包项目整个过程都被端到端记录。
**确定性** 和 **可预测性** —— 在任何机器上对同一文档包进行验证都会得出相同的结论。**可重复性** 和 **可复现性**
—— `habitable verify` 确定性地重现固定性和
时间戳检查;对于给定的案件状态,文档包的组装是确定性的。
**相关性** 和 **有效性** —— 文档包包含了法庭或检查员采取行动实际所需的内容,
这是根据已记录的证据要求来衡量的,而不是随意填充的。
### 隐私、安全、问责制、自治
**机密性** 和 **可保障性** —— 静态数据和同步均采用端到端加密;中继和
时间戳机构只能看到密文或纯哈希,永远看不到内容;无分析,无遥测。
**完整性**(供应链)—— 锁定、经过哈希处理的依赖项;每个发布版本包含 Sigstore 签名的构建来源
证明(签名的发布 **标签** 正在进行中——见 `docs/releasing.md`);
GitHub Actions 固定到 commit SHA。
**漏洞** 管理 —— CI 中的 pip-audit、gitleaks 和 CodeQL;发布了威胁模型和
带有披露路径的 SECURITY 策略。**问责制** —— 只追加的保管日志和提交的
`docs/audits/` 记录了谁对数据做了什么,同时没有任何外部方可以读取数据本身。
**可信度** 和 **透明度** —— README 明确说明了该工具 *不是* 什么(参见 *诚实的
局限 —— habitable 不做什么*)以及每个保证是如何执行的,而不是要求信任。
**自治** —— 每个工会持有自己的密钥和记录;没有运营者可以撤销、读取或
没收它们。
### 可用性、可学习性、覆盖范围
**可访问性** —— 强制执行 WCAG 2.2 AA 作为合并门控;捕获、时间线和审查完全可以
通过键盘和屏幕阅读器操作,任何视觉状态都有文本等效项。**可用性** 和
**便利性** —— 只需轻点几下即可捕获问题;一条命令即可导出文档包;无需在
压力下创建账户。**可学习性**、**熟悉度** 和 **直观性** —— 人们已经从相册中
了解的照片加笔记流程,证据机制在底层处理。**交互性** 和
**响应性** —— 捕获和审查在设备上立即运行,无需等待网络。**可发现性**
—— 引导式首个案件以及应用程序内关于如何创建强有力记录的解释。**可演示性**
—— `make demo` 通过无需真实租户数据的示例案件,演示了从捕获到验证文档包的全过程。
**可理解性** —— 每个项目都使用通俗易懂的语言显示其证据状态(已哈希、已加盖时间戳、保管链完整)。
**无缝衔接** —— 捕获、同步和导出都在一个本地文档上操作。
**本地化能力** —— 所有字符串都在按语言划分的包中;鉴于服务社区的需要,v1 版本随附西班牙语。**移动性** 和
**普及性** 是设计要求,因为记录工作发生在公寓内,通常是在租户拥有的唯一一台设备上。响应式 PWA 外壳已经存在,但一个安全的、
独立的手机安装包仍然是发布的阻碍。
### 可靠性、弹性、安全性
**可靠性** 和 **可信性** —— 该应用程序完全离线运行;网络中断永远不会
阻碍证据捕获。**可用性** —— 没有因停机而阻止租户的中央服务;
中继是可选的、可替换的。**容错性**、**弹性**、**健壮性** 和
**生存性** —— CRDT 合并容忍并发的离线编辑;损坏的项目会被固定性检查标记出来,
而不会导致案件崩溃;通过节点同步和加密备份,数据在任一设备丢失的情况下都能存活。
**可恢复性** —— 加密备份加上恢复的密钥可以恢复工会完整的案件
集;重新同步的节点会重建本地状态。**可降级性** 和 **故障透明度** ——
缺失的时间戳 token 或断裂的链条会显示为降级的证据状态,绝不会悄悄通过
显示为干净状态。**冗余** —— 多个同步节点和可配置的多个时间戳机构消除了
单点故障。**稳定性** 和 **持久性** —— 密封的原始文件是不可变的;文档包
格式和验证协议使用 semver。**安全性** —— 剥离位置的共享减少了租户面临的
伤害,而防胁迫安全开启状态(已计划,尚未实现;带有硬性
规则和 *诚实的局限* 中设定的限制)旨在加强这一点;该工具将输出定位为记录,绝不是
法律建议或对法庭结果的承诺。
### 性能、规模、成本
**效率** —— 哈希和同步增量是渐进式的;应用程序不会重新处理密封的媒体。
**可扩展性** 和 **弹性** —— 同步是点对点的,没有中央瓶颈;如果使用中继,它只
转发密文,在会话之间扩展至零。**及时性** —— 捕获、哈希和密封
在没有网络参与的情况下在瞬间完成,一旦设备在线,RFC 3161 token 就会被异步
获取;CI 中断言了[本地路径的延迟预算](docs/performance-budget.md)。
**可负担性** —— 该工具是免费的,使用免费的公共时间戳机构,不需要任何付费
基础设施。在租户现有的手机上安全运行仍然是一个打包目标,而不是目前的
声明。**流程能力** 和 **可生产性** —— `make verify` 重现了完整的门控;一次发布即是一条带标签的、签名的命令。
### 可维护性、可演进性、模块化
**可维护性**、**可修改性** 和 **可演进性** —— 接口背后的小型模块;ruff +
mypy strict;时间戳机构和同步传输层是可插拔的。**可扩展性** 和
**灵活性** —— 新的问题类别、导出模板和时间戳机构无需触及证据核心即可
插入。**适应性** —— 文档包模板通过配置适应司法管辖区的
期望,同时不改变验证协议。**模块化**、**可组合性** 和
**正交性** —— 捕获、证据、加密、同步、文档包和验证是独立的层,
验证不依赖于其他任何层。**简单性** —— 本地文件加上 CRDT,没有服务器,没有
账户系统。**可重用性** —— 证据和验证模块是可导入的,可以在
另一个本地优先的工具中强化捕获功能。**可分析性** —— 类型化、有文档记录,带有架构和威胁模型
文档。**可配置性**、**可定制性** 和 **可裁剪性** —— 一个配置文件即可设置机构、同步
节点、共享策略和语言。**可升级性** —— 固定的依赖项带有已记录的升级路径;
文档包格式是有版本的,因此旧的文档包仍能通过验证。
### 可操作性、可服务性、可持续性
**可操作性** 和 **可管理性** —— 可选的中继随附操作手册和健康状态端点;
组织者无需任何这些即可工作。**可管理性** —— 没有需要集中管理的东西;
策略是提交的配置,工会可以自行编辑。**可观察性** —— 捕获和
同步事件的设备端日志,保留在本地,从不外泄;中继只记录密文传输指标。
**可调试性** —— 在 debug 标志下,案件可以从捕获到保管再到文档包进行追踪,
而不会在设备外暴露明文。**可服务性 / 可支持性** 和 **可修复性** —— 问题
模板和“在示例数据上重现”的路径;大多数修复都是模板或配置编辑,
验证工具独立用于支持。**可部署性** 和 **可安装性** —— 用于 CLI 的 `pipx install`,可安装的应用程序构建,以及可选的一键中继部署。
**敏捷性** —— 每个 PR 都有 CI 冒烟测试套件。**自治**、**自我可持续性** 和 **可持续性** —— 没有付费依赖和
需要资助的服务,因此工会可以在没有预算和供应商的情况下保持工具运行。
### 兼容性、互操作性、标准、验证
**兼容性** 和 **互操作性** —— RFC 3161 时间戳和 SHA-256 哈希是标准的,
可以使用现成的工具进行验证;文档包是 PDF 加上结构化的机器可读的 bundle。
**可互换性** —— 时间戳机构和同步传输在不触及调用方的情况下进行替换;
文档包可以使用捆绑的工具或通用的 RFC 3161 和哈希实用程序进行验证。
**标准合规性** —— RFC 3161 受信任的时间戳、WCAG 2.2 AA、semver、约定式提交、SPDX
标头以及 AGPL-3.0 的源码义务。**可检查性** —— 哈希、token 和保管日志是
可查看且可独立检查的。**可组合性** —— 结构化的 bundle 是法律援助
工具可以摄取的纯数据。**可测试性** —— 干净、篡改和保管链断裂的案件的固定装置
使得证据和验证路径可进行单元测试;验证属性(可证明性、可重复性、
可复现性、可追溯性、可演示性)在上面已经涵盖,并由验证工具本身进行了演练。
### 分发、可移植性、安装
**可分发性** —— 客户端以可安装的应用程序和 PyPI 包的形式发布;中继以容器
镜像的形式发布。**可移植性** —— 本地优先的客户端可在 Android、iOS (PWA) 和
桌面上运行,数据是可移植的加密文件,工会可以在任何地方移动或备份。**可安装性** —— 一条命令用于
CLI 以及有文档记录的应用程序安装;中继是可选的且可自托管。**可部署性** —— 提交的
IaC 为需要中继的工会建立中继,对于运行纯点对点的工会,不会出现任何故障。
## 可访问性和 Section 508 合规性
habitable 的目标是 **WCAG 2.2 Level AA** 并符合 **修订后的 Section 508 标准**
(36 CFR Part 1194),该标准通过引用将 WCAG 2.0 A/AA 纳入 Web 内容中,并增加了 3 章的功能
性能标准。租户工会工具不是联邦 ICT,因此法律上不要求
遵守 Section 508。无论如何坚持遵守它既是价值观的体现,也是出于实际考虑:残疾人租户面临着极高的
住房歧视和宜居性伤害,如果一个旨在赋予租户权力的工具让残疾人租户无法使用,那它在目标上就已经失败了。符合政府所审计的标准,
也使得文档包和应用程序可供接收它们的法律援助人员和检查员使用。
- 使用 **VPAT 2.5 (Rev 508)** 模板的已提交的 **无障碍合规报告 (ACR)** 位于
`docs/accessibility/ACR.md`,其中包含 WCAG 2.x A/AA 成功标准、修订后的 508
软件(第 5 章)和支持文档(第 6 章)标准,以及 **功能性能
标准**(无视力、视力有限、无听力、伸展和力量有限、认知有限的
情况下使用)的表格。
- 每个视觉证据状态指示器都有 **文本等效项**:项目的已哈希、已加盖时间戳和
保管链完整的状态都会以文字播报,绝不是仅通过颜色或图标来指示。案件时间线
和审查列表可以通过键盘和屏幕阅读器操作,导出的 PDF 文档包带有标签,
具有辅助功能并带有文本层,以便屏幕阅读器用户可以阅读证据附录。
- 该应用程序通过了自动化检查,并具有 **已记录的人工屏幕阅读器协议**
(`docs/accessibility/manual-testing.md`);*录制完成的* NVDA/VoiceOver 通过测试仍然是 v1.0 的门控项,
尚未关闭(见 `docs/accessibility/ACR.md`)—— 捕获无需精确的指针控制即可工作,并且时间
限制是可以避免的,因此在压力下记录的租户不会被催促。
- 可访问性是一个 **合并阻断 CI 门控**;出现回归将导致构建失败。每次发布时都会重新生成并
重新提交 ACR,这与证据方法的审计即工件的原则相同。
## 构建计划
阶段 1–3 已在库 + CLI 级别 **实现** 并有测试覆盖;阶段 4(可安装的
最终用户应用程序和本地化)是剩余的工作。有关超越这些阶段的战略性、多年
规划——保障、可访问性、平台、治理以及 v1.0 门控——
请参阅 **[`ROADMAP.md`](ROADMAP.md)**。
- **阶段 1 —— 捕获和证据核心。** ✅ 媒体捕获、内容哈希、密封的原始文件、
只追加的保管日志以及明确的 EXIF 处理。本地加密存储。完成定义:问题
可以离线捕获,并且项目的固定性和元数据处理可在本地验证。
- **阶段 2 —— 时间戳、文档包和验证。** ✅ 基于哈希的 RFC 3161 时间戳;
带有证据附录的法庭/检查员 PDF;独立的 `verify` 工具。针对更改和保管链断裂项目的
固定装置进行的篡改检测测试。
- **阶段 3 —— 本地优先同步。** ✅ CRDT 案件模型、端到端加密的点对点同步、
可选的仅限密文的中继,以及带有密钥轮换的加密备份。并发离线编辑
收敛经过测试(基于属性)。
- **阶段 4 —— 可访问的应用程序和泛化。** 大部分已完成:一个可访问的、双语的 (EN/ES) Web 应用程序
(`habitable app`),受两种语言的真实 **axe-core** 扫描以及结构 + i18n 一致性
测试门控(✅);一个带有 PNG/可遮罩图标、Apple touch icon 和离线 service
worker 的 **可安装 PWA**(✅,见 `docs/mobile.md`);通过相同 axe
门控的 **可访问的 `packet.html`** 渲染,以及声明其语言并带有可导航大纲的 PDF(✅);可配置的
文档包模板(✅),威胁模型文档(✅),设置指南(✅),以及已记录的人工
屏幕阅读器协议(✅ `docs/accessibility/manual-testing.md`)。**剩余:** *录制完成的* 人工
NVDA/VoiceOver 通过测试;完全标记的 **PDF/UA** 结构树(在 reportlab 的
开源 API 中不可用——在此之前,HTML 文档包是可访问的渲染版本);以及签名的原生
应用商店二进制文件或另一个经过独立审查的设备上安装包。
## 工程和开源实践
### 标准合规性
本仓库是针对作品集范围的工程标准集
(质量、安全、CI/CD、发布、可访问性、可观察性、i18n、
AI 评估、文档和负责任的技术框架)开发的。根据该
标准自身的 README,悄悄省略此声明本身就是一种缺陷
—— 因此在此声明,而不是隐而不发。“适用”并不意味着
“完全合规”;它意味着该标准的控制措施在范围内并已被追踪,
指出了公开的差距而不是隐瞒。
| # | 标准 | 是否适用? | 追踪位置 |
|---|---|---|---|
| 1 | 质量与指标 | 适用(所有仓库) | `make verify`(覆盖率底线,复杂度门控);下方的 [完成定义](#definition-of-done) |
| 2 | 代码质量 | 适用(Python;TS/Node/frontend-toolchain 控制项为 N/A —— PWA 是无构建的 vanilla JS,没有 `package.json`) | `pyproject.toml`(ruff + mypy --strict 配置);`.pre-commit-config.yaml` |
| 3 | 安全与供应链 | 适用(发布代码、发布版本以及用于中继的 Dockerfile) | `SECURITY.md`;`.github/workflows/ci.yml`(gitleaks),`secret-scan-scheduled.yml`(TruffleHog),`codeql.yml`,`zizmor.yml`;`docs/audits/scorecard-2026-07.md` |
| 4 | CI/CD | 适用(`.github/workflows/` 下的工作流) | 本 README 的构建/验证描述;`.github/rulesets/`(分支/标签规则集——已起草,尚未应用,见补救日志) |
| 5 | 发布与版本控制 | 适用(带标签的 GitHub Releases) | `docs/releasing.md`;`ROADMAP.md` §发布与版本控制;**差距:** 签名的发布标签尚未到位(已在此处追踪) |
| 6 | 可访问性 | 适用(输出 HTML:`app/` 中的 PWA,`packet.html`,`site/` 落地页) | 下方的 [可访问性和 Section 508 合规性](#accessibility-and-section-508-conformance);`docs/accessibility/ACR.md`;**差距:** 录制的人工屏幕阅读器通过测试仍未完成,在 `ROADMAP.md` 中作为 v1.0 门控项追踪 |
| 7 | 可观察性 | 适用(可选中继为 Tier A,CLI 为 Tier C;无遥测原则导致了 N/A 行) | `ROADMAP.md` §可观察性 |
| 8 | 国际化 | 适用(双语 EN/ES 公民界面) | `docs/I18N.md`("i18n status: IN-SCOPE");`docs/adr/0005-i18n-g12-cldr-na-by-design.md` |
| 9 | AI 评估 | **N/A —— 无 LLM/AI 功能**(已验证:`[project].dependencies` 或开发组中没有 LLM SDK;没有 AI 代码路径) | — |
| 10 | 文档 | 适用(所有仓库) | 本 README;`docs/` 目录树;`CHANGELOG.md` |
| 11 | 负责任的技术框架 | 适用(所有仓库) | `docs/audits/`,`docs/privacy.md`,`docs/threat-model.md`;**差距:** 本表所代表的 A–F 适用性矩阵仅在 2026-07-05 添加,独立的 `docs/RESPONSIBLE-TECH-AUDITS.md` 仍待完成 |
上面的每一个“差距”也都在本仓库带有日期的补救记录中指出了
(来自 2026-07-05 合规性审计的 `habitable-REMEDIATION.md`);截至该日期,正式的
针对差距的追踪 issue 尚未提交——为每一行未关闭的记录提交一个 issue 本身就是
一项追踪中的后续工作,而不是假设由于该表的存在就已经完成了。
pytest 加上基于属性和防篡改检测的测试,用于证据、加密、同步和验证路径;
CI 中的 ruff + mypy strict;验证和文档包组装是确定性和可重现的;`make
verify` 端到端重现了完整的门控。该仓库包含 LICENSE (AGPL-3.0)、NOTICE(独立性
声明)、CODE_OF_CONDUCT、CONTRIBUTING、带有协调披露路径的 SECURITY,涵盖
文档包格式和验证协议的 semver 策略、ADR、提交的 `docs/threat-model.md`,以及
提交的 `docs/audits/`。约定式提交;GitHub Actions 固定到 commit SHA,带有
构建来源证明和每个发布的 SBOM;Dependabot。**签名的发布标签**
尚未到位(追踪于:`docs/releasing.md` §一次性设置,ROADMAP 的 v1.0 门控)——
直截了当地说明,而不是提前声称。
**为什么选择 AGPL-3.0。** 该工具保护处于面临报复威胁的人群,而可信的承诺是
没有任何运营者可以悄悄读取或削弱数据。AGPL 关闭了托管服务的漏洞:任何
为他人运行修改后的中继或托管变体的人都必须发布其更改,因此一个悄悄添加
数据窃取路径或后门时间戳流程的复刻版本,无法在不迫使该
运营者发布其修改后的源代码的情况下作为服务提供给他人。该法律手段不同于——
并且是对——哈希、时间戳和独立验证器已经提供的
技术完整性的补充。对于隐私至关重要的工具,copyleft 是安全保证的一部分,
而不仅仅是许可证偏好。
捆绑的 `verify` 工具是人们可能希望广泛嵌入和重新分发的唯一组件。它
在额外许可(GPLv3 §7)下提供,该许可同时也以宽松的 Apache-2.0 对其进行许可,
因此法院、法律援助团体或反对方可以在他们自己的软件中嵌入验证并发布
它,而不会让 AGPL 触及他们的代码。该授权位于 verify 源码标头和 LICENSE 中,
NOTICE 指向了它。(仅仅 *运行* 验证器在任何情况下都不会触发 copyleft——该
例外情况是关于嵌入和重新分发的。)
## 参与进来 —— 该项目需要外部的审视
habitable 将保持 **alpha** 标签,直到独立审查员检查了它的声明——
这就是 *验证,而不是信任* 工具的全部要旨,也是目前的优先事项。
如果您能提供帮助,**[审查员招募](docs/recruitment/README.md)** 包含了范围明确的简报、
资金路径以及针对每个角色的一键登记:
- **[安全 + 加密审计员](docs/recruitment/role-auditor.md)** —— 附带一份
[审计资金操作手册](docs/recruitment/audit-funding.md)(拨款 / 无偿 / 付费)。
- **[可访问性测试员](docs/recruitment/role-accessibility-tester.md)**,使用
辅助技术,进行录制完成的 NVDA + VoiceOver 测试(付费/有津贴)。
- **[住房/租户律师](docs/recruitment/role-legal-reviewer.md)** 以及
**[租户工会 / 法律援助试点合作伙伴](docs/recruitment/role-pilot-partner.md)**
(目前范围限定在加利福尼亚州)。
请通过 [审查员登记表](https://github.com/ChelseaKR/habitable/issues/new?template=reviewer-intake.yml) 发出提议;
**安全漏洞**请通过 [`SECURITY.md`](SECURITY.md) 私下提交,绝不要提交公开的 issue。
## 完成定义
租户可以在受支持的设备构建版本上离线捕获发霉的浴室;照片在
捕获时被密封并计算哈希,并在设备上线后立即加盖时间戳;另一台设备上的组织者进行端到端加密同步
该案件,无需服务器;工会导出
带有 4B 单元证据附录的分页文档包;接收方运行 `habitable verify`,针对密封的原始文件和时间戳 token 确认
每个项目完好无损——服务器上没有任何个人数据,
并且每个 CI 门控(包括可访问性门控)均为绿色(通过)。
标签:可信时间戳, 多模态安全, 安全规则引擎, 无障碍, 点对点同步, 离线优先, 租客权益, 端到端加密, 证据保全, 逆向工具