3.5 KiB
ADR-003:按作者隔离仓库,以索引登记文章
状态与日期
已接受,2026-10-16。替代 ADR-001 中共享仓库、slug 前缀隔离与固定正文路径的决定;唯一 Git 写入口、SSH 双重授权和账户存储现状不变。
决定
-
每位作者拥有
/srv/ingress/authors/<用户名>.git,API 在私有数据卷按作者分别保存 Git 缓存。 -
客户端仍只使用
content.git别名,SSH 强制命令按服务器公钥绑定的身份选定真实仓库,不接受客户端指定路径。 -
Git 全局信任范围仅限受控
/srv/ingress/authors/*目录,以支持跨 UID 本地读取,不信任其他目录。 -
仓库首次访问时自动创建,作者无须服务器 shell 或手动建裸仓库。
-
不同仓库不共享对象库或历史。
-
根目录
index.txt使用 UTF-8 三列文本,每行文章ID posts/文件夹 正文文件名,空格或 Tab 分隔,无表头,允许空行。 -
每作者 ID 唯一、文件夹不重复,正文为指定的 txt/md/markdown 文件,元信息保留 YAML Frontmatter,slug 可省略。
-
站内 ID 为
用户名~文章ID,两部分均不能含~,避免重名与歧义;目录或正文改名不改变身份。 -
pre-receive 在 Git quarantine 中检查完整候选树、单个线性提交、索引引用、白名单、文件模式、文本和图片内容与配额。
-
接收层能够拒绝非法文件,故整次拒绝非法推送,不静默过滤后制造与作者提交不同的服务端分支。
-
未登记目录和未选中的正文不导入阅读内容及数据库,但仍受校验和存储配额限制,不能作为隐藏载荷通道。
-
只作为资源导入所选正文引用的已验证图片。
-
API 再次验证各作者候选内容,构建私有集合快照及公开阅读快照。
-
数据库
blog_articles保存有效登记的作者、本地 ID、正文路径、格式、元信息和源提交;公开检索继续使用blog_posts/blog_tags。 -
索引条目移除后撤回正文和图片入口,并在数据库可用时事务重建派生记录。
-
数据库失败不阻止已导入文章阅读,恢复后自动对账重建。
-
集合版本是作者提交映射的摘要,单个作者 Git 提交仍单独保存。
取舍
索引是发布登记依据,不是远程代码执行配置。路径和文件名不允许空格、隐藏段或任意嵌套,暂不支持 SVG、HTML、脚本、配置或证书文件。文本中的 PEM 标记直接拒绝,包括代码块;这有意比一般技术博客严格,不能据此保证识别任意编码或伪装的秘密。
单作者 Git 历史仍保留自己的已删内容,移除索引不会释放历史占用;硬磁盘配额和管理员离线维护仍必要。站点总导入配额可能使通过单作者检查的推送等待处理,Git 接收不等于内容已导入或数据库已同步。当前按完整集合重建派生表,未来账户、互动、审核和站长管理状态必须用独立持久表,不能随着索引重建丢失。
旧共享仓库需要停机备份、按所有权导出最新文件、建立无共享历史的个人仓库,并重新生成索引。不会自动猜测所有权或清除旧数据;迁移方式见运维与迁移。已经分发的旧历史无法收回,旧 URL 的重定向尚未实现。
站长审核仅列入 TODO;本轮校验通过且状态为 published 的登记文章自动公开。后续应在索引导入与公开发布之间加入审核,审核未通过的修改不能替换原已通过版本。