跳转到主要内容

这是本节的多页打印视图。 .

返回本页常规视图.

设计与开发

在唯一的双语专栏中管理 OINK 维护者契约、已接受决策、带日期的研究记录与候选提案。
OINK 1.2.0 契约

本契约描述 v1.2.0 的正式行为。唯一的中英文契约源文件位于 content/docs/design/。 Hugo Extended 0.160.1 仍为兼容下限,CI 固定使用 0.165.0;下限版本 不作为第二套完整 CI 矩阵。

本专栏是 OINK 可长期维护的设计记录。站内其它专栏按任务讲解如何搭建站点; 这里集中说明现行不变量、这些选择背后的理由、用于比较方案的证据,以及仍处于 候选阶段的工作。

如何阅读本专栏

层次 含义
契约 兼容实现必须保留的规范性行为
决策 用于解释现行行为的已接受理由与边界
研究 带日期且不具规范性的证据,必要时应重新验证
提案 PRD 与 RFC 草案;公开在这里不代表已经实现

契约目录

契约 权威范围
架构契约 构建、配置、诊断、本地化、特色图片、输出、安全、无障碍与性能
组件契约 组件 API、Book 与发布原语、校验和输出降级
外壳与导航契约 导航、搜索、博客展示、操作、分类法与页尾组合
落地页契约 落地页数据、22 种区块注册表、运行时、无障碍与输出
迁移边界 从 0.4 到当前版本所支持的内容与配置迁移

设计记录

集合 内容
设计决策 已接受的诊断、配置与创作模型设计理由
设计研究 Goldmark 探针与真实 OINK 消费站点证据
候选提案 知识图谱、媒体收敛与机器可读索引等活跃 PRD

以后所有 OINK PRD 或 RFC 都必须以中英文页面对的形式放入 content/docs/design/proposals/,不得再在仓库中创建 plan/、plans/ 或 proposal/ 目录。提案被接受后,应同步更新实现、对应检查器与相关契约,把稳定 理由沉淀到“设计决策”,并通过 Git 历史与变更日志退出草案。

权威来源与维护

本目录同时管理英文与中文维护者设计文档。主题仓库管理可执行事实:hugo.yaml 管理公开默认值;对应的解析器与检查器定义可选结构;layouts/ 与 assets/ 管理渲染行为;检查脚本与 tests/goldens/ 管理验收;VENDOR.json 管理内置 依赖的版本、许可证、文件与校验和。

公共行为发生变化时,必须在同一次交付中更新实现、对应检查器以及本目录下相关 契约的中英文版本。测试应验证行为和输出,不应只固定某段文字。

1 - 架构契约

仓库装配、配置、诊断、本地化、输出、性能、安全、CSS、无障碍与发布状态的边界。
OINK 1.2.0 契约

本契约描述 v1.2.0 的正式行为。唯一的中英文契约源文件位于 content/docs/design/。

仓库与装配

仓库根目录是一个完整的 Hugo 模块与主题,不是站点,也不是 npm workspace。 Hugo Extended 负责编译 SCSS 与模板。浏览器运行时与第三方资源都已提交到仓库, 因此普通构建不会访问网络。公开的双语文档、示例与浏览器测试位于同级的 oink.pgsty.com 仓库;主题仓库只在 tests/site/ 中保留范围明确的内部回归 夹具,不再维护独立的公开示例面。

生成的 public/ 与 resources/ 目录绝不是源文件。随主题内置的运行时、字体 家族与 Font Awesome 字形定义属于受支持的发行内容,并非待清理的死代码; VENDOR.json 与 bin/check-vendor.py 固定其完整性。OINK 发布完整的受支持 Font Awesome 发行包,因为用户编写的内容可能使用主题模板本身没有引用的图标。

Font Awesome 官方编译 CSS 作为一份稳定、带指纹的 vendor 样式表发布,并排在由 主题与消费站 SCSS 编译出的指纹 main.css 之前。站点样式的普通修改不会再让图标 发行包失效,同时常规层叠顺序仍允许站点覆盖它。KaTeX、DocSearch、Swagger 与 Asciinema 等能力样式继续保持独立,只在实际使用时加载。内容指纹使不可变 URL 成为 可能;HTTP 缓存响应头属于部署宿主,而不是 Hugo 主题的职责。

Hugo 类型 docs、book、blog 与 swagger 选择阅读外壳; params.ui.shell_types 可以增加类型。落地页使用 layout: landing。OINK 没有 article 类型或第二套博客外壳;沉浸式页面只是外壳契约 定义的一种博客展示方式。

layouts/_partials/shell/config.html 解析共享外壳事实。布局必须先通过 content/render.html 渲染,再执行 scripts.html,因为渲染钩子与 shortcode 会在 Page Store 中登记能力标志。覆盖时应选择范围最窄的 partial;若合并会改变 Hugo 的查找优先级,即使几个基础模板看起来相似,也应保持分离。

配置与诊断

主题策略位于 params.ui.*;comments.giscus、plantuml、drawio 等包含多项 设置的集成保留在顶层。布尔功能直接使用布尔值,除非它还包含多项设置。页面级 覆盖会去掉 ui. 前缀:params.ui.image_zoom 对应 image_zoom,front matter 中绝不嵌套 ui map。hugo.yaml 声明公开默认值;对应的解析器与检查器定义 任何可选配置的结构或范围。

无效输入遵循同一条规则:警告中写明输入值、允许的结构与安全回退,然后使用该 回退,或省略不安全的功能。普通 hugo server 因而仍可使用,而所有发布门禁都 使用 --panicOnWarning。主题绝不调用 errorf,check-params.py 会强制守住 这条边界。不要为无法到达的状态增加臆测式校验。

OINK 没有通用的键名重命名注册表。仍需给出迁移诊断的过渡,应在所属解析器中 添加针对性警告,并配严格的反向测试;已经移除的键绝不能作为兼容路径继续读取。

可能联网的功能必须显式启用,并以关闭方式降级。PlantUML 需要 plantuml.svg_image_url,Draw.io 需要 drawio.drawio_server,Algolia 需要 appId、apiKey 与 indexName;配置不完整时发出警告,而且不产生网络请求。 Draw.io 只在渲染内容含 PNG 或 SVG 候选图片时加载,并且每个不同的图片 URL 只检查一次。 图表端点必须是字符串,内容为带主机的 HTTP(S) URL 或同站路径。不支持的协议、 省略协议的 URL、反斜杠、空白字符及缺少路径的同站引用都会告警,并在选择运行时前关闭该集成。

界面本地化

自 OINK 1.1 起提供

OINK 1.1.0 将原生界面语言包扩展到下方列出的完整语言集合;消费站点编写的正文 仍需自行翻译。

OINK 为 google/docsy@64f51c5 中现有的 31 个 locale 文件名提供原生界面文本,并额外保留通用 zh 作为简体中文 默认值:

ar az bg bn de en es et fa fi fr he hi hu it ja ko nl no oc pl pt-br ro ru
sr-cyrl sr-latn sv tr uk zh-cn zh-tw

这是一项兼容范围,不代表运行时依赖 Docsy,也不声称消费站点编写的正文已经翻译。 Docsy 以后增加的 locale 不会自动成为 OINK 支持项;它必须先补齐完整的 OINK 词条,并接受与现有语言相同的审校。

i18n/en.yaml 管理 194 条消息的 schema。OINK 的 32 份语言包都必须拥有完全相同 的消息集与原生界面文本;只有经过审查的产品名、标点、通行缩写或目标语言真实 同形词可以与英文保持相同,不再生成整段英文 fallback。zh 与 zh-cn 使用简体中文, zh-tw 使用繁体中文。

在兼容下限 Hugo 0.160.x 上,如果同时存在地区化的中文语言包,作为非默认语言的 通用 zh 语言键必须显式设置具体的 locale: zh-CN;从 Hugo 0.161 起,该配置也能 解析裸 locale: zh。这项约束只影响语言配置,不改变语言包文件名 i18n/zh.yaml。

%s、{count}、{{ .Count }} 等运行时占位符可以移到符合目标语言语法的位置, 但字节内容必须保持不变。取值可以是字符串或 Hugo 复数消息映射。复数映射使用该 语言支持的类别(zero、one、two、few、many、other),必须包含 other, 每种形式都是包含相同占位符的字符串。语言包不得包含隐藏的双向文本控制符; 阿拉伯语、波斯语和希伯来语的方向仍由消费站点的语言设置(direction: rtl) 决定,不得把方向字符塞进译文。 bin/check-i18n.py 会检查 locale 集合、schema、取值类型、占位符、方向控制符, 以及少量已审查的英文本地同形词。因此增加可见字符串时,必须在同一变更中为每份 语言包提供译文,不能再运行 fallback 生成器。

Hugo 的 images 是唯一的创作 API;params.images 只作为全站社交卡片回退。

来源 阅读列表缩略图 社交卡片
页面 images,或页面包中的 **featured*、*feature*、{*cover*,*thumbnail*} 是 是
分区 cascade.images 是 是
站点 params.images 否 是

images: [] 会清除显式值或 cascade 继承值,但不会禁止发现页面包资源。只把解析 到的第一张图片作为代表图。Hugo 可以裁剪本地可处理的位图;SVG、static 与远程 资源仍然有效,只是不能执行 Hugo 图片操作。

featured-image-resolve.html 统一决定来源优先级与相对、绝对 URL。页面自己的 显式 images 优先于页面包资源,页面包资源优先于继承的 cascade 图片;显式值与 继承值恰好相同时也遵守此顺序。有源文件的页面通过原始 front matter 判断是否显式 声明,由 Hugo 解析 YAML、TOML 或 JSON;没有源文件的生成页面将解析后的 images 视为显式值。列表缩略图、Open Graph/Twitter/schema 帮助模板、作者头像、Pinterest 图片与博客展示都消费同一个决定。

params.ui.featured_image 只用于博客,默认值为 none;页面或 cascade 可用 front matter 覆盖。banner 在单页标题上方渲染图片,wash 用图片给页头着色, hero 在单页与分区索引上把图片绘制为外壳背景。缺少图片或使用非 HTML 输出时 不渲染图片。

输出与运行时

每个基础模板都会设置 Page.Store.tdOutputFormat:

输出 契约
HTML 完整的语义内容;只为实际用到的能力加载本地运行时
Print 展开的内容;不含外壳导航、搜索或图片缩放运行时;共享操作层仍支持明确的打印控制
Markdown / LLMS 保持源 Markdown 形态,不含 td- 组件标记
LLMSFULL 按顶层 section 选择启用:每个启用 section、每种语言一份 llms-full.txt,按阅读顺序拼接同一份 Markdown
RSS 安全的静态摘要,或明确省略
NAVJSON 按站点选择启用:每种语言一份 navigation.json,序列化侧栏与 pager 已经在读的导航权威
BookManifest 选择启用、供出版打包器消费的有序 JSON 交接;绝不冒充 EPUB 或 PDF

各输出格式按既定顺序执行;可变格式状态并不存在跨格式竞态。但在 Print 内,Hugo 可能并行渲染同一 Book 页面与相互重叠的聚合。因此每页由一个缓存 coordinator 按 固定顺序生成普通与整书两种变体,各调用方只选择自己需要的形态。普通 Print 保留 页面局部标题与带路由的 xref URL;Book 聚合保留带命名空间的标题与文档内 xref。

站点自行选择是否启用自定义输出;OINK 不会强制生成昂贵的整书聚合。HTML 加载 共享操作层、核心层,以及由页面 flag 选择的稳定第一方能力分片。需要模板化的能力 每种语言至多发布一份;flag 只决定引用哪些 script tag,绝不再生成新的组合 bundle。 Print 保留操作层,并且只加载渲染打印功能所需的运行时。大型第三方 UMD 文件保持 独立;未使用的功能运行时不会出现。

顶层 section 在自己 _index front matter 的 outputs 中列出 LLMSFULL 才会启用它, 主题绝不替站点把它加进输出集合。逐页 Markdown 与全文包由同一个渲染器产出,因此全文包 就是那份语义 Markdown(同样不含 td- 组件标记)按侧栏与 pager 的阅读顺序拼接。在顶层 之下启用会告警且不产出任何文件,普通构建仍然可用,而 --panicOnWarning 会拦住发布。

站点在 outputs.home 中启用 NAVJSON,为每种语言在语言根下发布一份 navigation.json。 它序列化侧栏与 pager 所读的同一条权威链:存在显式 data/docs_nav.json 树时用它,否则用 带 weight 的内容树。数组顺序就是契约,weight 绝不序列化,该输出标记为 notAlternative。 schema/nav.v1.schema.json 为该格式提供版本,它是手写的契约产物,随模板与检查器一同修改, 不受生成式配置 Schema 漂移门禁管辖。两种输出默认关闭,都不启用的站点构建结果逐字节不变; bin/check-agent-indexes.py 是它们的归属检查器。

只有 Book 根在 outputs 中明确列出 BookManifest 时才会生成它。它引用该 Book 既有的逐页 Markdown,并记录派生出的页面顺序、标题、编号目标与 xref;主题不会在 其中猜测出版元数据,它也不是可分发的电子书。

主题仓库提供 bin/book-epub.py 与 bin/book-pdf.py 作为显式出版步骤,并用 bin/check-book-epub.py 与 bin/check-book-pdf.py 承担产物门禁。EPUB 打包器组合 BookManifest 与同一份整书 Print HTML,消费站另行传入出版 metadata;PDF runner 只在临时回环地址提供该 Print 产物,通过 script-src 'none' 内容安全策略调用显式指定的 Chrome/Chromium 二进制,输出带 CSS 页码的 A4 页面。两种工具都会拒绝缺失资源或越出构建树的资源;网络资源 与覆盖已有输出分别需要独立的显式开关。网络 opt-in 只允许被动 HTTP(S) 媒体,远程脚本与 本地文件协议仍属非法。EPUB metadata 文件中的相对资源以该文件所在目录为基准,不依赖 调用者的工作目录。普通 Hugo 构建不会执行出版工作;PDF 仍从 Print 派生,而不是另一种 模板输出。

PDF 服务还会应用 CSP sandbox、拒绝 meta refresh 导航,并拒绝指向构建树以外的 符号链接。没有网络 opt-in 时,图片与媒体请求仅限回环同源地址和 data URL, CSS 或 SVG 发起的请求也受此限制。

性能规则如下:

  • 若站点级资源或 partialCached 结果可以承担工作,不要为每一页遍历 .Site.Pages;
  • .Content 只渲染一次,完成后再读取 Page Store 标志;
  • 直接输出正确标记,不要扫描 DOM 后再修复;
  • 浏览器工作按资源 URL 分组,而不是按 DOM 实例重复;
  • 成本显著的普通输出应保持选择启用;
  • 默认不输出 Speculation Rules:必须先由一个明确的生产消费站用可回滚的 moderate 实验测量 Sec-Purpose: prefetch 请求、实际命中导航、传输字节与 CSP 影响;
  • 校验确实可达的作者输入,不校验假想的内部状态。

bin/measure-baseline.py 测量构建时间、输出体积、bundle 数量与 shortcode 密度。

信任边界、CSS 与无障碍

作者可以启用 Goldmark unsafe,但配置与组件参数不能视作原始 HTML。共享属性 策略使用允许清单、校验 class token、放行 data-* 与 aria-*,并在丢弃 style、srcdoc、on*、保留属性与未知属性时发出警告。需要本地 URL 或明确 绝对 URL 时,URL 帮助模板会拒绝危险协议与协议相对 URL。公开 API 承诺支持的 远程 URL 仍然可用,但构建时绝不抓取它们。

主题输出使用 td- class、data-td-* 属性与 --td-* 自定义属性;.steps、 .cards、.full-width 等作者标记保持无前缀。CSS 支持 RTL、打印、强制颜色、 减少动画、超长 token 与窄视口。主题拥有的装饰图标带 aria-hidden;只有包含 任务列表或原始 Font Awesome 元素的页面才加载作者内容无障碍修复。

阅读容器区分指针聚焦与键盘导航。由指针聚焦的 main 区域、表格滚动区或代码 pre 不会仅因读者随后按键而出现边框;Tab、失焦或新的非指针聚焦会清除这项豁免。普通控件 保留自己的焦点样式,滚动容器保留 tabindex,跳过导航的目标在标题附近显示局部边框, 不再包围整篇文章。强制颜色模式保留键盘提示,不使用全局焦点边框重置。

字体角色为 ui、body、heading、code、display、meta、brand 与 print, 通过 --td-*-font-family 暴露。ui 是主字体:body 经它解析,heading 又经 body 解析,因此赋一次值即同时移动界面、正文与标题。params.ui.typography 可取 technical 或 system;两者编译到同一份样式表,不加载运行时。旧 Bootstrap/Docsy Sass 变量继续为这些角色提供初值。

params.ui.fonts 让配置层触达同一组角色,供不愿挂载 SCSS 或新增样式表的站点 使用。它只写字体族名,绝不加载字体文件:所写字体族必须是读者已有的,或站点 自己用 @font-face 声明过的,这也让该键留在网络契约之外。取值只放行纯粹的 字体族语法,输出的 :root 块由匹配到的片段重新拼装;未知角色或不安全取值只 告警并单独丢弃。该块在样式表之后渲染,正是这一点让作者字体在同等优先级下压 过预设。外壳读站点的字体,不自带字体:Book 的编号与题注用正文字体,而非某种 技术字体。

强调色按角色拆开。强调文字(链接、外链、行内代码)跟随 Bootstrap 链接 族与 --bs-code-color,主题色永不重声明它们;行内代码随视觉预设变化:Slate 保留胭脂红明暗对,Paper 使用墨色文字与淡底, 使一页密集的标识符读成「代码与正文」而非「代码与链接」。强调底(选中行、 指针划过导航行时那层更灰的底、hover 淡铺、目录药丸与轨道光点、徽章 hover、 卡片 hover 时的外边、分享按钮 hover 时的实心底、文本选中、焦点环)跟随 --td-accent、--td-accent-rgb 与 --td-accent-hover,它们默认取链接族,也是 params.ui.theme_color 唯一注入的属性。属于外壳而非正文的文字同样跟随它们: 视口正停在其上的目录锚点、以及指针或键盘焦点落在其上的 Book 章节小标题, 按分区颜色点亮,而不是链接蓝。theme_color 与 theme_color_dark 取 #rgb/#rrggbb;front matter 与分区 cascade 覆盖站点值。未配置的站点不注入 任何内容。解析失败的值告警并保留默认配色。解析成功但在主题自身画布上低于 4.5:1 的颜色,带可抑制 id 告警并照常生效:该检查是建议性的,只有解析失败才丢弃颜色。 亮色是主键:没有有效 theme_color 的 theme_color_dark 告警并被忽略,一页要么 两种模式都着色,要么都不着色。省略暗色一半时,向白按 4% 步进提亮,直到在暗色画布 上达到 4.5:1。注入的每个字节 都由解析出的整数通道格式化,绝不来自作者文本。同一个解析器同时回答 head 注入块 与侧栏根切换器的「这一页是什么颜色」。

视觉预设

OINK 1.2.0 默认使用 Paper。params.ui.preset 接受 paper、slate,以及显式 选择的实验预设 ink、terminal;非法值与保留名称(folio、canvas)告警并回退到 paper。params.ui.preset_menu 默认 false;true 提供 Paper、Slate 与站点默认值, 列表指定可选项并可显式开启实验。列表必须包含站点默认值,缺失时告警并补入。不支持页面级预设。

Hugo 为所有文档根元素输出 data-td-preset 与 data-td-site-preset,包括 404 和打印输出。开启读者选择时,head 内联脚本在 CSS 加载前校验 td-preset。选择 带默认标记的预设会删除该存储键。非法存储值被清除;存储被禁用时,控件仍可在当前 页面使用,并显示无法持久化的提示。storage 事件同步标签页,td-preset-change 携带 {preset, previous, stored}。明暗状态独立使用 data-bs-theme、 td-color-theme 与 td-theme-change。浏览器栏颜色跟随实际明暗和预设。禁用 JavaScript 时显示站点默认的浅色预设;外观控件需要 JavaScript。

四套预设编入同一个样式表。Slate 保留 v1.1.0 的基础色板选择器与值。Paper 调整 配色和少量组件规则,不改变外壳列宽、断点或全局间距。Paper 深色块重声明浅色块的 每个色板 token,并覆盖嵌套深色区域。字体角色保持同等选择器优先级,顺序为预设、 typography: system、head 输出的 params.ui.fonts;站点的 _styles_project.scss 仍在最后。brand 单独控制字标。Paper 使用本地 IBM Plex Sans, Slate 保留 Inter;两者的字标保留 Chakra Petch,代码保留 IBM Plex Mono。 系统排版模式不请求内置文字字体,除非站点显式覆盖角色。没有新增外部字体请求。 Ink 统一使用 Inter,配合红色标记、正文链接下划线、直角与无阴影。Terminal 使用 等宽界面和标题、Plex Sans 正文、青色链接、琥珀强调、2 px 圆角与无阴影;仅压紧 桌面导航,保留正文行长与手机触控目标。CSS 标题标记使用空的无障碍替代文字, 不支持的浏览器省略标记。显式 fonts.ui 仍控制主字体,除非设置了有效的 fonts.body。参见实验记录。

Giscus 自动色板同时跟随风格与明暗;显式主题或浅深色样式表配置仍优先。打印使用 当前预设的浅色配色与白纸背景,即使屏幕为深色。Mermaid 与 ECharts 继续只跟随 明暗,API 组件保留供应商色板。参见已接受决策 与本地验收记录。

发布状态

源码完成、本地验证、提交、打标签、推送、消费站点固定版本、部署与生产一致是彼此 独立的状态。一次本地 Hugo 构建只能证明本地验证通过。

2 - 组件契约

OINK 创作原语、校验、Book、发布行为与输出降级的维护者契约。
OINK 1.2.0 契约

本契约描述 v1.2.0 的正式行为。唯一的中英文契约源文件位于 content/docs/design/。

教程与完整示例位于面向读者的组件专栏。本页定义这些 指南所依赖的 API 与行为。

创作模型

一个区块加属性便能表达组件时,使用普通 Markdown;需要复合正文或 Markdown 无法携带的事实时,使用 shortcode。OINK 没有并行的组件注册表。原生形态要求:

markup:
  goldmark:
    renderer: { unsafe: true }
    parser:
      wrapStandAloneImageWithinParagraph: false
      attribute: { block: true }

只有 {{%/* steps */%}} 使用百分号分隔符,因为它的正文属于页面大纲;其它 shortcode 一律使用尖括号分隔符。复合正文通过 content/render-block.html 处理,并使用唯一的 ID 作用域。Shortcode 与组件参数中的 caption、label、title 和 name 是纯文本,Markdown 应放在正文里。落地页叙述字段遵循自己的契约。图标 由一对 Font Awesome class 表示。组件暴露安全的 class 与属性,不接受任意颜色 或内联样式。

公共 API

OINK 有 29 个 shortcode:

  • 核心:tabs、tab、steps、cards、card、fields、field、include、 kbd、badge、param、comment、contributors、asciinema;
  • Book:fig、tbl、eq、eg、xref、book-toc、book-figures、 book-tables、book-equations、book-examples;
  • 发布:release-card、release-assets、download;
  • OpenAPI:swagger、redoc。
组件 原生形态 Shortcode 形态 HTML 运行时
提示块 > [!TYPE]、折叠、{icon=} 无 无
标签页 相邻围栏或表格加 {tab= group= value=} tabs / tab 只在使用页加载 tabs
步骤 有序列表加 {.steps} steps 无
卡片 链接列表加 {.cards} cards / card 无
参数表 表格加 {.fields} fields / field 无
FileTree filetree 数据围栏 无 只有注释存在时加载分隔条运行时
画廊 gallery 数据围栏 无 符合条件时共享图片缩放
图片 Markdown 图片加块属性 无 符合条件时加载图片缩放
表格 属性、caption、编号或标签页 复合 Book 表格使用 tbl 只有标签页表格加载 tabs
Book 目标 图片、表格、passthrough、围栏加 {num=} fig、tbl、eq、eg 无
发布资产 checksums 数据围栏 release-assets HTML 中加载复制功能
数学与化学公式 passthrough、math、chem 围栏 eq 无;构建期渲染并加载本地样式
图表与数据 mermaid、plantuml、markmap、echarts、infographic 围栏 无 只加载选中的本地运行时

校验

无效的作者输入遵循架构契约:发出警告,使用文档 规定的安全回退或省略组件,再由 --panicOnWarning 在发布门禁中把同一条诊断 变为致命错误。命名参数与位置参数不能混用。Book 目标 ID 匹配 [A-Za-z][A-Za-z0-9_.:-]*,Book 编号匹配 [0-9A-Za-z.-]+,class 必须通过 token 校验。渲染钩子与 shortcode 目标共享同一个页面注册表,因此冲突不会生成 重复的输出 ID。

URL 使用 content/url.html;不允许原始反斜杠,因为浏览器可能将其解释为 URL 分隔符。图片依次从页面资源、分区资源、全局 assets、static 或显式远程 URL 中解析。本地位图带固有尺寸;SVG、static 与远程来源仍然有效, 但不能执行 Hugo 图片操作。 资源元数据 alt 必须是字符串;无效值会告警并被忽略,保留正文填写的替代文本。

组件行为

提示块与标签页

提示块类型包括 note、tip、important、warning、caution、success、 danger、question、example、quote 与 details;- 表示初始折叠,+ 表示初始展开。未知类型渲染为保留原标记的普通块引用,不依赖 JavaScript。

只有连续且区块类型相同的相邻标签页才会分组。group 启用 #<group>-<value> hash 与 td-tabs:v1:<group> 存储键;未分组标签页两者都不用。 HTML 在 JavaScript 运行前暴露所有面板,打印输出展开面板,Markdown 保留作者 源文,RSS 接收渲染后的文本摘要。完整形态支持任意 Markdown;tab.label 必填, 父级存在 group 时 value 才严格必填,孤立的 tab 会警告且不渲染。

步骤、卡片、参数表与表格

原生步骤接受普通区块内容。只有某一步必须包含百分号容器时才使用 shortcode。 原生卡片是链接列表;完整形态增加正文、徽章、图标与图片。原生参数表把第一列 映射为名称、最后一列映射为描述,中间列由 meta= 或表头映射;完整形态允许 区块描述。card 与 field 只能放在各自的父容器中。

参数锚点为 field-<name>,名称转小写,连续标点折叠为连字符,因此 params.ui.typography 变成 field-params-ui-typography。重复锚点追加位置后缀。

表格渲染钩子负责响应式包装与 caption。.matrix 把第一列变为行表头; .full-width 加宽普通表格或矩阵表格。.fields 不能与 matrix、full-width、 编号或标签页组合;编号与标签页也互斥。

Markdown 图片钩子是普通图片 API。行内图片保持行内;块图片带 caption 或 num 时变为 figure。图片处理只属于这一原生形态:完整 fig 源形态是编号容器,其参数表 刻意不含 command/options,需要处理的编号图片写成带 num 的原生块图片。 允许的图片属性包括 id、num、caption、width、height、 link、command 与 options,以及共享安全属性。command 与 options 必须同时 出现,并对可处理的本地资源调用 Hugo Fit、Resize、Fill 或 Crop。普通 链接图片使用 Markdown 语法,因此 link 属性要求同时有 caption 或编号。链接 图片与装饰图片不加载缩放。

缩放按钮通过 ARIA 无障碍名称保留图片的 alt 与本地化预览操作,不向正文插入辅助 文字。复制纯文本或富文本 HTML 时,即使编辑器移除主题样式,也不得额外带入 预览提示;作者原有的图片与图注保持不变。资源 metadata 中的 alt 必须是字符串; 无效值会告警并被忽略,保留正文中编写的图片 alt。 Draw.io 与图片缩放共用一张图片时,编辑与缩放是同级的独立按钮。编辑入口支持 键盘访问,并在触摸设备和强制颜色模式下保持可见。

画廊每行接受一张 Markdown 图片,可带描述、链接与 class。FileTree 接受缩进、 - name、可选 /、注释,以及经过校验的 icon、tone、open、type 属性。Markdown 保留作者源文;打印输出渲染展开的静态图片与文件树。

所有代码高亮都使用 Chroma。通用围栏属性包括 title、copy、wrap、 collapse、label、id、行选项、标签页,以及 Book 的 num/caption。复制 操作返回作者源文。Mermaid 色板按明暗切换,与视觉预设独立;默认深色连线标签 背景使用 #404040,使标签文字达到 AA 对比度。显式 params.mermaid.themeVariables 配置仍然优先。

ECharts 输入是声明式 JSON/YAML;回调使用 window.OinkEchartsFunctions 中的 $fn:<name>,绝不执行嵌入脚本。

数学公式使用 Hugo 构建时生成的 KaTeX 产物和本地 CSS,不加载浏览器数学运行时。 共享渲染器在 HTML 和 Print 中将 KaTeX 0.18 之前的类名统一为本地样式支持的类名, 保留 Hugo 0.160.1 兼容下限、MathML 与作者的 TeX 源文。Markmap 使用与样式配套的 本地 KaTeX 运行时。 窄屏中,编号公式的标题在阅读列内换行,长标题不得撑宽整页。

Swagger 与 Redoc 接受 HTTP(S) 规范 URL 或以 static/ 为根的路径,都不解析页面 资源。Redoc 将开头有无斜杠视为等价,并把本地路径与 baseURL 拼接。只有 HTML 输出可交互;Print、Markdown 与 RSS 输出静态规范链接。

Book

book 类型扩展 docs 外壳,并遵循内容树或 data/docs_nav.json。book_number、 book_part、book_kind 与 book_status 是展示元数据,不改变 Hugo 发布状态。

带编号的类型为 fig、tbl、eq 与 eg,默认 ID 是 <kind>-<num>。eg 需要 caption;不带 num 的 eq 是无编号展示公式。xref 要么准确指定一种类型 并可附带 page/anchor,要么指定一个 anchor 和显式文字。带编号的示例是一个 完整的边框正文与 caption。

脚注属于页面文档。原生编号表格与围栏会让脚注留在页面里。Shortcode 正文是独立 的 Goldmark 文档,因此 tbl、eg、fig、card、tab、field 或 include 中的脚注引用会警告并保持字面形式;该检查忽略代码形态的文本。

book-toc 按 1–3 层导航顺序生成目录;四个 book-* 索引各自收集一种目标。 单页 Print 与普通 HTML 保持完全相同的普通标题与脚注 ID。只有多页分区 Print 与整书 Print 会改写跨页链接,并给这些页面局部标题与脚注增加命名 空间,避免聚合后冲突;显式目标 ID 保持不变。消费站点自行选择是否启用这些 潜在成本较高的聚合输出。

发布与下载

发布 front matter 使用一个 https://github.com/<owner>/<repo>/releases/tag/<tag> 形态的 release_url;owner、 项目与 tag 来自 URL,日期来自页面。构建不会抓取远程发布状态。已经移除的 release map、release_products 与 release_group_by_product 会警告并给出 替代项,它们不是兼容路径。分区索引列出所有页面;能解析时使用 project tag, 否则使用页面标题。

校验和可以接受规范行,也可以接受一个源资源,两者不能同时提供;文件名不能是 路径。HTML 增加本地复制功能,静态输出暴露完整 hash。

下载使用 data/download/<key>.yaml。channel 可取 rolling 或 pinned;只有 pinned URL 与命令会插值 ${version} 和 ${tag}。发布前,rolling channel 保持 可用,pinned channel 显示 pending。Markdown 渲染完整 channel 列表;RSS 省略 该组件。

验证

共享输出规则见架构契约,例外随各组件定义。 Markdown 与 RSS 不设置浏览器运行时标志;Print 只保留渲染打印功能需要的标志。 源码检查覆盖参数、渲染钩子策略、运行时隔离与迁移;输出检查比较 HTML、Print、 Markdown、RSS 与 LLMS golden;浏览器测试覆盖交互界面。迁移行为见 迁移边界。

3 - 外壳与导航契约

导航权威、沉浸式博客、搜索、操作、分类法、索引与页尾组合契约。
OINK 1.2.0 契约

本契约描述 v1.2.0 的正式行为。唯一的中英文契约源文件位于 content/docs/design/。

权威来源与导航

关注点 权威来源
全局导航 Hugo menus.main
Docs / Book 侧栏与翻页 内容树或 data/docs_nav.json
根栏目切换器 解析后的顶层内容根
内容发现 各语言的本地搜索索引
页面与命令面板操作 共享操作注册表

任何功能都不能引入另一套菜单或页面树。菜单只允许一层子项交互;更深层级会警告, 并平铺到带链接的分组标题下。外部链接使用 target="_blank" rel="noopener noreferrer";内部链接保持语言与子路径感知。

顶部导航栏的桌面视图与抽屉视图投影同一棵树,每个下拉面板都是一列宽度适中的 “图标 + 标题"行——mega 面板与其 columns 菜单参数已退役,配置 columns 会发出警告并保持单列。菜单描述只是配置数据,不再渲染。链接树在任何宽度都保持居中: lg 以上是文字链接,之下收缩为图标链接。lg 与 md 之间,右端保留搜索、版本、 语言、主题与 GitHub,没有菜单按钮;md 以下外观入口保留在搜索与抽屉入口旁,版本、语言与 GitHub 移入底栏工具组,此时首页 与显式 Landing 页在搜索旁增加一枚抽屉入口,展开完整的带标签菜单树。带侧栏的外壳页面 在这个位置打开自己的侧栏抽屉;从 md 起均不显示抽屉按钮。语言链接指向页面译文,缺少译文时 指向对应语言首页;多个语言共享主机与 base path 时保持相对链接,只有语言拥有 独立 baseURL 时才变成绝对链接;hreflang 始终使用绝对链接,而且只列出真实译文, 不把切换器提供的语言首页回退当成译文。博客分页使用每一页自己的 canonical URL; 后续分页不输出跨语言 alternate,因为不同语言归档的分页边界未必相同。 navbar_autohide 从 768px 起只对精细指针生效,绝不作用于触控或抽屉宽度; 隐藏的导航栏不交还占位:两种状态下布局都保留导航栏横带,固定顶栏正好占满这条 横带、下边框画在带内,显现时原地淡入、不遮挡静止内容,hero 页面忽略该策略、 保留自己的叠加导航栏。首页与 hero 页面共用同一套柔和边界:导航栏不画下边框、 滚动时不投阴影,改由栏下一小段渐隐过渡收束边缘。

侧栏与翻页共享同一个根和顺序。manual_link、build.render: link、分隔行、 隐藏节点与占位节点保留各自已定义的语义。sidebar_icon_policy 可取默认的 all、 groups 或 none;图标是一对 Font Awesome class。无效策略遵循共享的警告与 回退契约。达到 sidebar_cache_limit 后,两种 walker 只有在语言、导航根与实际 影响输出的有效设置均相同时才复用中性标记。没有 JavaScript 时这份标记仍然可见; 普通外壳运行时只补上 active 路径。会输出 sidebar_headings 的 Book 页面保持页面 专属,并绕过共享树缓存。

根候选先收集可链接、非分隔项的顶层分区,再收集 sidebar_root_for: self 分区,并按 URL 去重。 两种来源都遵守显式的 sidebar_root_menu: false;未设置或 true 时保留。 当前解析出的根即使被排除在全站候选之外,仍会追加。零入口不输出控件,单入口 输出静态链接;所有 URL 保留语言和部署路径前缀。分隔项和使用 build.render: never 的分区不会成为切换器链接。

sidebar_divider 叶子保持静态标题;分区节点在两套侧栏遍历器中保留子项,标题不跳转, 启用折叠时提供真正的展开按钮。分组自身不进入翻页序列,子页保持原有顺序。配合 build.render: never 可省略分区自己的输出而不隐藏后代。面包屑显示不带链接的标题, 搜索跳过分组,导航 JSON 提升其子节点,Print 保留子文档。Book 目录保留分组标题和子项链接, 但跳过未发布的分组正文标题。toc_hide 仍隐藏整棵子树, 不能代替分组。显式导航键使用不含语言和部署前缀的路径,实际链接则保留这两个前缀。 显式导航的 sections 数组为空时发出警告,并在所有导航输出中回退到内容树。 两种权威来源都剪掉 toc_hide 子树;导航 JSON 将 manual_link_relref 保留为指向 解析目标的内部链接,不把占位页自身当成页面身份。

侧栏运行时

自 OINK 1.1 起提供

OINK 1.1.0 提供本节的展开状态 API 与隐藏内容隔离;1.0.0 不提供该 API。

window.OinkSidebar 管理已注册的树分支及可搬迁的 TOC、反向链接和分类法分组, 不依赖它们当前的 DOM 父节点。setExpanded(id, boolean, {source}) 对有效目标返回 true,对未知 ID 或非布尔值返回 false。getState(id) 返回新的 {id, expanded} 快照 或 null。ID 使用现有 aria-controls 指定的受控区域 ID,不能修改注册范围之外的元素。

来源为 user、active-path、responsive 和默认的 api。所有写入先提交 aria-expanded、td-is-open、本地化标签和区域的 inert 状态,再向 document 发送一次 oink:sidebar-disclosure 事件,详情为 {id, expanded, source}。重复写入相同状态不发 事件。API 恢复时保留当前路径祖先展开,用户仍可主动折叠这些分支。关闭含焦点的区域时, 先把焦点归还给展开按钮,再执行隔离。

ready 是初始活动路径补全和响应式搬迁完成后解析为 API 的 Promise;isReady 和 oink:sidebar-ready 也提供可供晚加载消费者检查的完成状态。可选的持久化由站点负责: 等待 ready,在 try/catch 中读取存储,再通过 setter 恢复有效 ID。OINK 自身保存整栏 折叠、宽度和滚动位置,不定义读者分支选择的版本/语言存储格式。

桌面折叠和移动抽屉关闭时,面板内容设为 inert,面板标记 aria-hidden。先移出焦点再 隔离,打开时先解除隔离再聚焦。面板本身继续充当 16px 指针感应区,外部恢复按钮保持 可用。悬浮、Escape、遮罩关闭、断点清理和滚动解锁保留原有行为。这些运行时属性不进入 无 JavaScript 的服务端回退标记。

TOC 整栏折叠时也隔离其隐藏面板。如果焦点原本位于折叠按钮,先移至可见的浮动恢复按钮; 恢复整栏后,焦点回到栏内可见的控制按钮。右侧内容搬入移动侧栏时,先清除原先的整栏 隔离,再由抽屉管理交互。抽屉的 Tab 循环只包括可见、非 inert 的控件,排除隐藏或 折叠区域中的后代。

沉浸式博客展示

OINK 没有 article 类型或第二套外壳。沉浸式阅读由普通博客外壳上的四个独立键 组成,可设在页面或分区 cascade 上;分区索引会重复它自己也需要的值:

featured_image: hero
toc_style: flow
toc_taxonomies: false
sidebar_enabled: false

博客外壳默认不渲染面包屑导航——文章应作为独立作品阅读——所以这份配置不需要 相应的键。breadcrumb 仍是普通键,页面或 cascade 可以在任何外壳上明确打开 或关闭它。

hero 在单页与分区索引上把共享特色图片用作装饰性的全出血背景。没有图片时 渲染普通开场;banner 与 wash 仍只用于单页。顶部导航栏以对比遮罩叠在 hero 上,并随页面一起滚动。

toc_style 可取 fixed 或 flow;flow 在文章旁放置更宽的导轨,并且只在滚动 之后固定。它的静止位置与文章信息行对齐;页面没有信息行时,与描述对齐。标题 换行数无法预知,因此由 docs-shell.js 测量偏移;没有 JavaScript 时,导轨从 文章起点开始。toc_taxonomies: false 移除术语云;导轨既无 TOC 又无术语云时 完全不渲染。notoc 仍是页面级 TOC 退出键。这些开关不改变署名、标签、系列、 翻页顺序、feed 或页尾组合;导轨在 xl 断点以下消失。

搜索、操作与运行时

params.offline_search 选择启用各语言的本地索引。启用后默认也在 hugo server 期间构建;大型编辑循环可以设置 offline_search_on_serve: false。HTML 搜索出现 在首页、外壳页面,以及启用 landing_search 的落地页上。其它非外壳页面与 Print 不包含对话框、Lunr 或命令面板。

搜索元数据包括 search_keywords、默认值为 1 的 search_boost,以及 search_exclude。索引携带 URL、标题、分类法、摘录、小标题、description、 正文或摘要、根、分区、类型、关键词、boost、面包屑导航与图标。夹具预算为原始 2 MiB、gzip 512 KiB。站点可以通过 hooks/search-keywords-extra.html 返回额外 字符串。关键词用于匹配与排序;CJK 查询仅命中关键词时,结果显示页面描述或 摘录,不展示关键词列表。正文命中仍使用匹配位置附近的文字作为摘要。

内置操作 ID 包括 copy_markdown、copy_link、open_chatgpt、open_claude、 view_markdown、view_history、edit_page、create_child_page、create_issue、 create_project_issue、print_section、print、switch_preset、switch_theme、 switch_language、switch_version 与 open_github。分享栏之外的 copy_link 只出现在命令面板中。站点通过 languages.<lang>.params.ui.command_palette.commands 配置的命令可以打开安全 URL,或调用内置 ID,绝不能注入 JavaScript。剪贴板的旧式回退恢复此前的焦点、选区及其方向, 但复制期间其他控件已获得焦点时不再抢回。

编辑、历史与新建子页操作要求源文件具有仓库相对路径。物理文件名和站点工作目录 先统一为 / 分隔符,再判断包含关系。path_base_for_github_subdir 匹配归一化后的 路径:站点内内容使用相对工作目录的路径,外部挂载使用绝对路径。字符串正则可以 移除匹配的内容,{from, to} 映射可以替换它;外部来源必须显式匹配规则。 映射并整理路径后,空路径、.、绝对路径、带盘符的路径以及以 .. 路径段开头的 结果都会隐藏这三项操作。文档 issue 与项目 issue 操作仍按各自的仓库配置提供。 Windows 映射应匹配 / 而不是 \;归一化不会改变文件名大小写。

命令面板有空状态、文本搜索状态与 > 命令状态;快捷链接来自导航。它没有历史、 语义搜索、个性化或远程回退。搜索查询留在浏览器内,默认不发送遥测。

OinkSurfaceCoordinator 协调命令面板、抽屉、根栏目、语言与版本菜单。各界面自行 管理焦点恢复与 Escape。键盘导航会忽略可编辑控件与模态框,Ctrl/Cmd+K 同样避让 其他已打开的 dialog,包括固定定位的 ARIA 对话框。/、\、f、c 打开搜索或命令;j/k 移动标题;q/e 翻页;h 改变展示方式;l/y、 t、r 分别打开语言、主题与根栏目选项。侧栏 WASD/方向键导航使用真实焦点, 不会改写 Tab 顺序。 不带链接的分隔分组按钮也参与树导航。从子页按 Left/a 先聚焦父分组,再按一次才折叠; Right/d 展开已折叠的分组,已展开时进入第一个可见子项。上一页/下一页仍只遍历链接, 不会把分组按钮当成页面。

页面大纲从同一套标题模型与滚动容器计算后的 scroll-padding-top 推导光标和可见 标题范围;SVG 线条与圆点共享同一组动画值,不会漂移。合法 URL 片段会被解码; 非法百分号序列则回退到字面的标题 ID,建立链接索引和选中页尾请求的标题时遵循 同一规则。禁止增加臆测性的 DOM 修复遍历。这项跟踪始终由普通外壳运行时负责。params.ui.scroll_spy 与页面键 scroll_spy 在整个 1.x 期间都是静默兼容 no-op,不加载独立运行时;只有未来的 破坏性版本才会删除它们。

搜索尾部扩展

自 OINK 1.1 起提供

OINK 1.1.0 包含该 API,1.0.0 中不存在。

受信任的站点 JavaScript 可调用 OinkCommandPalette.registerSearchTail({id, rows, activate});YAML 和操作清单仍然只接受 数据。资源包继续按本地搜索开关装配。注册要求唯一且符合 [A-Za-z0-9][A-Za-z0-9_-]* 的 ID,以及两个函数;非法或重复注册抛出异常。返回的注销函数可重复调用,旧句柄不能删除 复用该 ID 的新注册。面板打开时的注册变化会合并调度一次渲染,注销会取消该扩展的待完成操作。

rows(context) 同步返回描述符。context 是冻结的 {query, locale, phase, pageResultCount} 快照:query 去除首尾空白,locale 使用 HTML 的语言标签,phase 为 results、empty 或 error,数量只统计上限截取后的本地页面结果。仅在非空文本搜索完成后调用扩展,不在空查询、 命令、选择或加载状态调用。扩展行按注册顺序放在本地化的 Actions 组中,排在全部原生页面及 操作之后。原生空结果、错误提示与输入触发的索引重试保留。

描述符必须提供扩展内唯一、符合相同语法的 id,以及非空字符串 title。 可选的 description、icon、disabledReason 为字符串,available 为布尔值,默认 true。 OINK 复制并冻结这些字段,把显示字符串当作文本渲染。描述符非法、ID 重复、返回异步结果或 回调抛出异常时,本轮跳过整个扩展,其他扩展不受影响。不承诺回调的精确调用次数。

activate(row, context) 只通过普通结果行的激活路径调用,收到复制后的描述符和生成该行时 的上下文,另带 AbortSignal 与 handoff()。操作待完成时阻止其他结果行激活,包括进入原生 选择菜单。同步异常和 Promise 拒绝会释放待完成状态、保持面板打开,并播报本地化的操作失败信息。成功值被忽略;成功时关闭 面板,不从其他界面抢回焦点。关闭、重新打开、渲染的查询改变或注销会取消待完成操作,旧操作 的迟到结果不能修改新会话。

打开另一个受协调器管理的界面前,调用 context.handoff()。它关闭面板,但不归还焦点,也不 取消本次激活。随后由站点管理新界面的焦点与错误提示。之后的新 Palette 会话或注销仍可取消 尚未完成的操作;成功完成不会取消已经移交的操作。OINK 不强制超时。

rows() 必须保持纯净。这是受信任代码的契约,不是安全沙箱。默认查询仍留在本地,不内置 远程服务商或遥测。扩展的网络行为和服务商所需授权由站点负责。

分享

params.ui.share 默认为空,可接受 16 个目标的任意有序子集:x、bluesky、 mastodon、facebook、linkedin、reddit、hackernews、telegram、 whatsapp、line、pinterest、weibo、chatgpt、claude、email、copy。 页面列表会替换继承列表;share: false 退出。未知项会警告并丢弃。只有普通页面 渲染分享栏;Print、Markdown 与 RSS 省略它。

目标是携带页面永久链接与标题的普通 intent 链接,外加本地 copy_link 按钮。 Pinterest 图片来自共享特色图片解析器。ChatGPT 与 Claude 接收构建期生成的永久 链接提示,与页面菜单里的助理操作相互独立。Discord 没有公共 intent 目标,因此 有意不提供。

分享栏不加载平台 SDK、iframe、脚本、样式表、计数器或 campaign 参数;只有读者 主动点击链接时才产生请求。它是一行带无障碍标签的字形。 share/items.html 解析目标,share/bar.html 负责渲染。

注记

页面注记在 annotation-items.html 中解析描述项,再通过 page-meta-lastmod.html 渲染;两者都可以做窄范围覆盖。各行顺序如下:

行 条件
最后修改 已设置 Lastmod
上游 front matter 中的 upstream_link 非空
翻译 配置的权威语言存在译文,而且本页包含作者正文

upstream_link 是页面级事实;cascade 有效,upstream_link: "" 表示退出。 其它上游事实按站点参数 → data/upstreams[upstream_source] → front matter 解析: upstream_name、upstream_copyright、upstream_license、upstream_notice, 以及可选的 upstream_ref、upstream_modified。存在链接时,前四项必填。无效或 残缺的署名会警告,而且不渲染法律声明;不支持的 URL 会被拒绝。发布门禁通过 --panicOnWarning 拒绝这类警告。

upstream_modified 改变署名动词并链接提交历史,不增加新行。notice 页面承载 完整的许可证与免责声明。翻译说明通过 params.ui.translation_notice 选择启用, 以页面键 translation_notice 参与 cascade,跳过生成页面或无正文页面;以本语言 原创的页面可以用 translation_notice: false 关闭。

作者与系列

博客文章页头依次为标题、信息行、术语徽章、作者署名、系列条;description 在其后 引出正文。信息行 article-info.html 始终包含日期;启用 reading_time 后再增加 字数与分钟数。Front matter 的 upstream_link 与注记使用同一个页面级事实, 并在共享 URL 策略保护下增加本地化的原文链接。术语行只是裸徽章组,分类法名称 位于分组标签中,不显示前缀。术语徽章静止时是浅中性底与弱化文字,前置该分类法的 term 图标;可点击徽章在 hover 或 focus 时才取得当前分区的强调色淡铺、边框与文字。 图标词汇表由 taxonomy-icon.html 独家拥有——每个 分类法配一对图标:整体分类法一枚、单个术语一枚(folder-open/folder、 tags/tag、cubes/cube、users/user-pen、series 用 book-bookmark/book,其余用 shapes);params.ui.taxonomy_icons 可覆盖: 字符串同时作用于两个表面,taxonomy/term map 分别设置;无效输入警告并保留 内置。右栏词云只在云头戴整体图标:云 chip 保持"文本 + 计数”——分类法已经亮明 身份,再在每个 chip 上重复图标只是噪声。独立的分类法目录卡片会带一枚术语图标; 作者署名只放人物——头像、姓名与个人资料的一行简介—— 不带标签或日期。列表行、卡片与术语归档共享同一形态的元数据行:日期、一条本地化 的作者与分区短语,以及由同一个 reading_time 开关控制的字数和分钟数。句子下方 是独立成行、自动换行的徽章行,按分类法字母序列出页面在全部分类法下的词条,每枚 徽章佩戴各自的 term 图标;卡片排除 authors——其句中已具名。

只有声明 taxonomies: {author: authors} 才启用作者。作者 term 页面拥有显示名称、 摘要、正文与特色图片头像;没有 profile 时,回退到链接标题、首字母与归档。 authors-resolve.html 在文章页头、列表行中保留 front matter 顺序,并为每位作者 生成一个 RSS dc:creator。没有 authors 时,旧 author 保持原样;两者同时 存在时,authors 无警告胜出。自定义作者分类法复数名按普通分类法处理。

只有声明 taxonomies: {series: series} 才启用系列。Term 页面拥有引言;不新增 参数、数据文件、封面模型或运行时。页面使用 series: [name] 与可选的 series_weight。series-pages.html 先按 weight 排有权重成员,再按日期升序排 无权重成员,并用 Path 打破平局;系列条与 term 页面共享该顺序。第一个命名系列 得到一条 HTML/Print 系列条。面板是半透明加模糊,而不是一张不透明卡片:hero 文章会把题图铺在这一段背后,不透明底色等于在画面上挖个洞;普通文章上这层色调 就落回页面自身的底色,所以一种处理同时服务两种场景。summary 拥有整行与末端 箭头;系列名连同它的分类法图标,仍是 summary 的兄弟链接,覆盖在一份隐藏的等宽 占位文字上,避免 summary 内出现嵌套交互控件。展开后先划一条细线,再在同一层 表面上把成员阅读顺序放进一个保持 DOM 顺序的自适应网格。每个链接都把序号纳入 点击目标,序号贴在固定方格轨道的末端,因此无论多少篇,标题都对齐在同一条边上; 窄屏保持一栏,只有当每个标题仍有可读宽度时才增加等宽栏,因此桌面面板能用满自身 宽度,也不会把一条选中背景拖过整篇正文。悬停与读者所在位置直接借用侧栏导航 处理这两种状态的同两种底色,当前篇再加上填充序号与加粗标题,不靠颜色单独表意。打印时显示同一份展开 列表,收为单栏。单篇系列与非 HTML 输出省略它。编号、交叉引用与聚合输出仍属于 Book。

默认文章分类法徽章会排除保留的 authors 与 series,因为专属界面已经展示 它们。显式设置 params.taxonomy.page_header 可以恢复任意一项。

博客索引与页面组合

博客分区索引使用 params.ui.blog_index:默认的 list 与 cards 都是按最新优先 排列的一段扁平结果,共享 blog_index_size 分页;元数据行已经显示日期,所以不再 需要年份标题。table 把整个分区显示为日期、标题、标签行,不分页。卡片使用共享 首图、本地化日期/作者/分区元数据、标签与三行摘要。

分类法页(/tags/、/authors/)与其术语页共用一个页头 shell/taxonomy-head.html。分类法页以整体分类法图标的着色方块、本地化名称与 术语数开头;术语页以术语标题与取自 ui_taxonomy_pages、按当前 locale 的 CLDR 复数类别选择的页面数开头,没有渲染面包屑时标题上方再加一行 kicker,写明分类法并链回列表页——面包屑开启时它在上一行已经做了这两件事:代表 生成的分类法页的那一级面包屑借用页头同一个本地化标签,而不是 Hugo 的复数名标题。 页头之下,分类法页把术语排成单行卡片网格 shell/taxonomy-cards.html:使用次数 多者在前、同数按字母序(与右栏词云同序),以 auto-fill 填满等宽列,因此术语 很少时两张卡片也不会被拉宽到整页。一张卡片就是术语图标、术语名与页面数,整张 卡片即链接;只有作者以署名同款小头像开头,走同一个头像 partial。卡片不带描述、 不带最新一页:术语没有标题与计数之外值得一说的内容,多出的那一行只会让网格发糊。 不再有筛选芯片行与「全部」芯片:分区根已经在侧栏与顶栏里。术语页保持行列表, 作者资料页保留自己的页头。

分类法页与术语页的右栏以 shell/taxonomy-switcher.html 开头:声明的每种分类法 一行——整体图标、本地化名称、术语数——链向其列表页,当前分类法置于选中底色上。 这是从一种分类法的页面去另一种的路:词云芯片跳到术语页,词云头只负责折叠;只有 一种分类法的站点不渲染切换器。这一组与词云共用 toc_taxonomies 开关。分类法页 的词云按全站统计(taxonomy-root.html 对该 kind 不返回根),并省略自己那一组, 它的术语就是旁边的卡片;术语页保持分区作用域与完整的一组。

params.ui.blog_index_toggle 为当前分页切片渲染三种形态,并允许读者循环切换。 配置值控制首次绘制,隐藏形态不加载图片。读者存储的选择只作用于发布了全部三种 形态的索引:切换器关闭的分区只发布一种形态,并始终显示它。Front matter 或 cascade 可为每个分区覆盖站点模式。没有切换器的 table 仍是完整且不分页的归档。

params.logo 始终是品牌标志;params.wordmark 或站点标题是紧凑宽度下隐藏的 文字部分。Docs、Book、Blog 与 Swagger 共享一个外壳模型。页尾顺序为分享、反馈、 注记、翻页、评论。Docs/Book 翻页遵循侧栏前序遍历;Blog 按 weight 后接日期倒序; pager: false 退出。静态输出省略翻页 UI。

每一种实际渲染的页脚形态,都会在最底层栏右侧保留纯图标工具组,顺序为版本、 语言、主题、快捷键帮助。各菜单向上展开;版本触发器不直接显示当前分支或版本名。 胖页脚的折叠箭头排在工具组之后。低于 lg 时,底层栏放弃版权/居中/工具组的 三列布局,改为三行全宽居中堆叠,工具组在最后一行。这些全局控件不再出现在 侧栏底部;footer_style: none 会移除整条底栏。

OINK 没有归档外壳、任意深度飞出菜单、第二个导航权威、查询上传,也没有针对已 移除配置的浏览器兼容 shim。反馈只通过既有 gtag 发出 docs_feedback,在本地 保存选择,而且不替代 Giscus。

验证

bin/check-navigation-contract.py、bin/check-shell.py、JavaScript 测试、输出 golden 与消费站点浏览器套件覆盖导航、语言与子路径链接、博客变体、页尾顺序、 键盘行为、无障碍与响应式布局。

外观控件

顶栏与底栏共用点击或键盘展开的外观控件,Landing 手机抽屉另有带标签的入口。 preset_menu 允许选择时显示原生风格单选组;dark_mode.show_menu 开启时显示 浅色、深色、跟随系统单选组。选择立即生效,面板保持打开。Enter、Space 或向下 方向键展开;方向键在组内选择,Tab 在组间移动,Escape 关闭并归还焦点。触发按钮 图标表示实际明暗状态:浅色显示太阳,深色显示月亮,跟随系统变化时也同步更新。

英文分组标题为 Style 和 Light,中文为「风格」与「明暗」。风格选项以两列独立 按钮排列,使用带主题色的纸页、叠层、笔尖或终端图标与预设名称,不显示 Aa 预览 或实验标记。站点默认项在悬停提示与无障碍名称中注明,选择后清除保存的风格。 选中项使用淡色背景与边框,键盘焦点另有轮廓线。

桌面使用锚定触发器的非模态 dialog,外部点击或焦点离开时关闭。低于 768 px 或 从 Landing 抽屉进入时,通过 showModal() 在浏览器顶层打开底部表单,提供关闭 按钮和 44 px 选项目标。关闭表单保留下方抽屉。表面协调器在展开前关闭无关弹层。 t 快捷键继续通过 switch_theme 切换明暗;switch_preset 是独立的命令面板选项。

本地 Ink/Terminal 实验仍需显式配置;preset_menu: true 继续提供 Paper/Slate 与站点默认值。两者复用同一套状态、键盘、命令面板与底部表单 机制。Terminal 压紧桌面导航行,保留正文与手机触控目标尺寸。

4 - 落地页契约

落地页数据、内置区块注册表、语言解析、运行时、无障碍与输出的维护者契约。
OINK 1.2.0 契约

本契约描述 v1.2.0 的正式行为。唯一的中英文契约源文件位于 content/docs/design/。

共享规则见架构契约与 组件契约;迁移行为属于 迁移边界。

外壳与数据

任何普通页面都可以声明 layout: landing。它渲染顶部导航栏、全宽画布与页脚, 不显示 docs 侧栏或 TOC 导轨。首页继续把 data/home/<lang>.yaml 作为兼容的创作 路径,并通过同一个渲染器处理。

非首页依次从内联 front matter、data/landing/<key>/<lang>.yaml、单个 data/landing/<key>.yaml 中精确匹配语言的条目,以及英文或无后缀本地数据中 解析 sections。落地页绝不抓取可变事实;星标数、价格、截图与头像必须在 Hugo 运行前提交或生成。

params.ui.landing_search 默认为 true,而且只有启用 offline_search 时才打开 既有本地命令面板。params.ui.github_stars 与 params.ui.alt_site 是可选的本地 界面事实。

区块注册表

注册表恰好有 22 种内置区块:

  • hero、metrics、capabilities、principles、cards、logo-wall、 gallery、testimonials、contributors、faq、markdown、cta;
  • pricing、pricing-compare、command-box、steps、timeline、 code-plate、preview、case-study、download、bar-chart。

条目可以是类型字符串,也可以是包含 type、key、id、enabled、内联 data 或有意指定的本地 partial 的 map。作者提供唯一 ID,OINK 把它规范为 锚点安全值。未知类型遵循共享的警告与安全回退策略,绝不静默消失;发布时 --panicOnWarning 会拒绝它。内置区块由 landing/ partial 负责;已经移除的 home/ partial 名称不是 API。

preview 通过站点渲染钩子,把 Markdown source 放在 RenderString 输出旁, 因此其内容会登记与 docs 内容相同的运行时。源码面板使用 Chroma,并带默认值为 page.md 的 file 名称。Markdown 输出使用四个反引号包围的 markdown 围栏; RSS 省略它。面板标签来自主题 i18n。

hero.align 可取 start 或 center。Center 只适用于文本;与图片组合时会警告, 并回退到 start,同时保留图片。download 消费与 shortcode 相同的 data/download/<key>.yaml 结构,不引入第二套 channel、版本、发布或插值模型。

语言、运行时与无障碍

叙述文件可以按语言拆分。共享事实字段依次解析 <field>_<exact language>——其中 - 规范为 _——再解析 <field>_<primary language>,最后解析无后缀字段。 不接受 camelCase 别名。叙述字段通过站点渲染钩子渲染行内或区块 Markdown;复用 为无障碍名称的值会转为纯文本。区块文案属于站点数据;只有主题控件使用 OINK i18n。

交互式 HTML 设置 hasLanding,从而只按需添加 landing.js。运行时复用 OinkSurfaceCoordinator,负责出现动画、数字递增、复制、紧凑菜单与主题图片 增强。没有 JavaScript 或 Landing 脚本加载失败时,服务端输出仍然完整可见。 出现动画的候选元素默认可见,只有成功安装观察器后才标记为等待动画。数字指标 由服务端按配置输出完整的数字格式、前缀和后缀,递增动画的最后一帧使用同一显示文本。

跑马灯只用 CSS 复制;副本带 aria-hidden 与 inert,本地化复选框无需 JavaScript 也能持久保存暂停状态。减少动画会停用动画,强制颜色保留控件,主题 图片响应共享主题事件。顶部导航栏的 mega 面板与其 columns 参数已退役:仍然配置 columns 的菜单会告警并保持单列。紧凑菜单使用真实链接 与按钮,不捕获焦点,也不复制桌面导航树。

输出与兼容性

输出 契约
HTML 完整静态区块加渐进增强
Print 静态网格与内容,移除控件
Markdown 不带主题 class 的标题、正文、列表、表格与代码
RSS 省略落地页区块

非 HTML 输出不设置 Landing 标志或运行时。根相对链接与资源遵循部署子路径;普通 构建不下载图片。

已经移除的 0.4 组件形态属于迁移工具,不是并行的落地页实现。OINK 不增加价格 周期切换、远程事实 API、热点编辑器、可视化构建器或第二套注册表。既有首页数据 与显式自定义区块 partial 继续有效。

视觉预设

Paper 去掉首屏网格与光晕,使用暖色阴影、Plex Sans 展示标题和链接色主按钮。 Slate 保留技术网格、光晕、Chakra Petch 标题与原有主按钮颜色。两者共用分区结构, 不改变密度。手机抽屉包含共用外观表单,参见外壳契约。

显式开启的 Ink/Terminal 实验也去掉网格、光晕与阴影。Ink 使用高字重 Inter 标题、 直角卡片与红色主按钮;Terminal 使用等宽标题、2 px 圆角、琥珀主按钮与静态光标形 装饰。两者都不新增动画,不改变分区列结构。

5 - OINK 迁移边界

OINK 迁移所支持的源码、配置与验证边界,包含 1.2.0 变化。
OINK 1.2.0 契约

本契约描述 v1.2.0 的正式行为。唯一的中英文契约源文件位于 content/docs/design/。

这是源码与配置指南,不是版本发布流水账。本地源码、提交、标签、推送、消费站点 固定版本、部署与生产一致仍是彼此独立的状态。面向读者的升级流程见 版本升级。

工具范围

bin/migrations/oink06.py 只扫描和自动改写站点内容目录下的 Markdown 文件, 包括受支持的 YAML front matter。它不改写 Hugo 配置、数据文件、布局、资源、 模块或生成输出。TOML/JSON front matter 与有歧义的 Markdown 会连同位置一起报告, 留给人工检查。

默认执行 dry-run;完成后的迁移具有幂等性:

python3 bin/migrations/oink06.py report --sites <dir>... --md report.md --json report.json
python3 bin/migrations/oink06.py migrate --site <dir>
python3 bin/migrations/oink06.py migrate --site <dir> --write
python3 bin/migrations/oink06.py check --site <dir>

代码围栏的内容不会改写,包括与有序或无序列表标记处于同一行、可带引用前缀的围栏。 代码示例里额外的字面引用前缀不会结束该围栏。 book_figures.py 保留范围明确的 TPME、DDIA v1/v2 与 pg-internal profile;它不是通用解析器。

隔离验证工具 bin/measure-baseline.py 和 bin/sites/build-all.py 会在清理已有 输出前,拒绝与任一输入站点、运行工具的 checkout、选中的主题 checkout 或其他 快照交叠的快照目录,包括通过符号链接别名指向这些位置的 --keep 目标,以及 通过 --theme 选择其他主题 checkout 的情况。

更新消费站点仓库

主题发布后,应清点维护中的消费站点 checkout,并升级它们固定的版本。 主题的 bin/update-consumers.py 扫描指定根目录下的直属项目目录,不递归进入 归档、生成站点、缓存或主题测试夹具。

此工具随 OINK 1.2.0 发布。在主题 checkout 中执行,先清点,再升级到正式标签。

python3 bin/update-consumers.py v1.2.0 --roots ~/www ~/pgsty
python3 bin/update-consumers.py v1.2.0 --roots ~/www ~/pgsty --write --check

第一条命令只报告版本采用情况。第二条更新 go.mod 和 go.sum 中的 OINK 条目,核对精确的模块解析图,并对每个选中站点运行将警告视为失败的构建。 执行时禁用 GOWORK、Hugo 模块 workspace 和环境变量中的模块替换。日志与 原始模块文件保存在临时报告目录,也可通过 --report-dir 指定目录。 更新失败会恢复模块文件;构建失败则保留新版本以便排查,并返回失败状态。 扫描根目录无法读取或消费站模块格式错误时,会记录失败条目,继续清点其余站点, 并以非零状态退出。显式选择的目录不存在或不是 OINK 消费站时,也会明确报告失败。

工具跳过链接 worktree、隐藏副本和非默认分支。应检查所有跳过与阻塞条目: 通过 --sites <path>... 显式选择已核对的 checkout,包括已有模块改动的目录。 go.mod 中的 OINK 替换需要手工处理。vendor 主题需先独立核对,再使用 --refresh-vendor 备份并重新生成 _vendor/;只改模块版本不会更新 vendor 中的主题。

保留无关改动,同步站点 README 和配置中的当前主题版本说明,并运行站点自身的 检查与视觉验收。工具不改写正文、不提交、不推送、不部署。这些完成状态必须 分别记录,已使用目标标签的站点也要纳入清点。

从 0.4 内容迁移到当前形态

已移除形态 当前形态 工具键
alert、details、pageinfo、原始 disclosure > [!TYPE] 提示块 callout
tabpane、旧 tab、code-group、code-tab 相邻 {tab=} 区块,或 tabs / tab tabs
FileTree shortcode 或 {.filetree} 列表 filetree 围栏 filetree
Gallery shortcode 或 {.gallery} 列表 gallery 围栏 gallery
ECharts / infographic shortcode 同名数据围栏 datafence
Docsy 卡片家族 .cards 列表或 cards / card cards
imgproc、image Markdown 图片加属性 image
readfile include include
围栏 filename= title= fencetitle
badge outline= 移除 outline badge
叶子 example、book-figures kind= eg、显式 book-* 索引 eg
百分号分隔的 fields 尖括号分隔的 fields / field fieldsdelim
Docsy _param 占位符与 card header= 高亮 Font Awesome / badge / param 或提示块 param_placeholders
不支持的旧 shortcode 报告源码位置,人工检查 reportonly

配置与 front matter

以下配置改动需要手工处理;工具可以报告匹配的 front matter 键,但绝不编辑站点 配置。

旧配置 当前配置
offlineSearch* offline_search*
disable_click2copy_chroma ui.code_copy,取反
content_width `reading_width: slim
github_url github_repo
ui.no_left_sidebar ui.sidebar_enabled,取反
breadcrumb 别名 ui.breadcrumb
ui.scrollSpy 无行为替代;ui.scroll_spy 仅作为 1.x 静默兼容 no-op 保留
ui.showLightDarkModeMenu ui.dark_mode.show_menu
ui.readingtime ui.reading_time
ui.ul_show ui.sidebar_expand_levels
ui.docs_root ui.docs_sidebar_root
ui.pager ui.pager_types
annotation/zoom/keyboard/reading 的 { enable: bool } map 裸布尔值
ui.typography.preset ui.typography
print.disable_toc print.toc,取反

Prism、rss_sections 与 algolia_docsearch 已移除。Chroma 是唯一高亮器;Algolia 配置为 search.algolia。页面级覆盖会去掉 ui. 前缀。旧 hide_feedback、 hide_readingtime、exclude_search、content_width、camelCase 手工链接与嵌套 front matter ui map 会连同替代项一起报告。

从 0.5 到 0.6

  • 用 upstream_link 加 upstream_name、upstream_copyright、 upstream_license、upstream_notice 替代 upstream_attribution;把 downstream_modified 改名为 upstream_modified。
  • 用一个 GitHub release_url 替代 release map;从发布索引移除 release_products 与 release_group_by_product。
  • 博客与默认日期现在采用 ISO 2006-01-02;面向读者的日期继续显式保留 time_format_blog 或 time_format_default。

已移除名称会警告,并采用文档规定的安全回退或不渲染;普通预览可以继续,严格 门禁通过 --panicOnWarning 拒绝它们。blog_index_toggle、 featured_image: hero、toc_style 与 toc_taxonomies 是增量选择启用项,不会 引入内容类型;沉浸式阅读仍使用普通博客外壳。

前置条件与验证

按照组件契约启用 Goldmark unsafe 渲染、块属性与 独立块图片。要使用 \(...\)、\[...\] 或 $$...$$,需要显式启用 passthrough; Hugo 不会合并主题的 markup 配置。

针对改动的契约,使用固定的 Hugo Extended 0.165.0 工具链运行范围最小的源码与输出 检查;运行时变化时执行 JavaScript 测试,并严格构建根路径与子路径。对于维护范围 内的站点,在桌面与窄视口检查有代表性的 EN/ZH Docs 与 Blog 路由,再分别记录固定 版本、部署与线上一致状态。

6 - 设计决策

解释 OINK 现行公开契约与实现为何采用当前形态的已接受选择。
已接受的理由

决策记录解释 OINK 为什么在多个兼容方案中选择了当前设计。上方五份契约仍是 现行行为的规范描述;实现与归属检查器仍是可执行事实。

OINK 过去把评审、PRD 与执行记录放在本地 plan/ 目录中。这样既不便发现有价值的 推理,也容易让已经放弃的设计看起来仍有权威。已经接受的理由现在统一进入这座双语、 版本化的文档站,与它所支撑的契约放在一起。

决策地图

决策 解决的问题
警告与安全回退 为什么普通预览能容忍错误输入,而发布仍保持严格
配置模型 配置放在哪里、页面如何覆盖,以及 OINK 为什么不另造配置命名空间
Markdown 优先创作 为什么优先使用原生 Markdown,以及 Docs、Blog、Book、Landing 如何延长共享系统
生成式配置 Schema 为什么编辑器 Schema 是生成的投影,以及漂移门禁如何阻止第三个配置权威出现
可选 CLI 与结果契约 本地 CLI 候选的独立 Go 可执行文件、版本化诊断、覆盖范围与显式写入边界
视觉预设 Paper 默认、Slate 兼容、可选外观菜单、独立明暗状态与字体边界

记录格式

一份已接受决策应记录背景、选择、后果,以及证明该选择仍然成立的证据。它不重复参数 参考或教程。每份决策都要链接到归属契约与验证面,中英文页面必须同步修改。

决策发生变化时,应在同一次交付中更新实现、检查器、受影响契约与决策记录。旧答案留在 Git 历史和版本变更记录中,不在导航树里并列保留两套“现行”答案。

6.1 - 警告与安全回退

作者输入无效时,预览阶段发出警告并安全降级;–panicOnWarning 在发布阶段恢复硬门禁。
决策

OINK 不调用 Hugo 的 errorf。作者或站点输入无效时,主题发出警告,并使用文档中 明确的安全回退,或者省略无效片段。版本发布与部署构建使用 --panicOnWarning, 因此同一条警告在发布门禁中仍会导致硬失败。

背景

Hugo 把整座站点作为一次事务构建。编辑一页时触发的 errorf 会让该次重建中的所有 URL 都返回错误,包括无关页面和首页。服务器进程仍然存在,修正输入后也会自动恢复,但多人共享 的预览在此期间完全不可用。

警告的开发成本不同。出错的值可以回退,站点其余部分仍可检查,作者也能看到准确消息。 发布构建则不会放过它,因为 OINK 的 CI 与集成门禁都会加上 --panicOnWarning。

决策

校验遵循四条规则:

  1. 点明无效键和值、允许的形状以及实际采用的回退值。
  2. 值来自页面 front matter 时带上页面位置;站点级错误不要在每一页重复刷屏。
  3. 不允许无效值继续参与后续运算。先校验,再用规范化后的值渲染。
  4. 没有诚实回退时,警告并且不渲染。不能为了继续构建而编造内容、发起网络请求或输出 不安全 URL。

枚举、布尔、CSS 长度与数字的共享校验形状位于 layouts/_partials/validate.html。领域 resolver 可以增加更窄的规则,但必须保留同一套 警告与回退契约。

安全边界

继续构建不等于继续输出危险内容。被拒绝的 CSS 长度要在进入 style 属性之前回退;远程服务 配置不完整时,要在浏览器可能发起请求之前省略组件;不安全的操作 URL 直接丢弃。真正的保护是 坏输出没有出现,而不是 Hugo 被终止。

这也把编辑与发布清晰分开:

阶段 无效输入的处理
hugo server 或普通本地构建 警告、回退或省略,其它页面继续可用
CI、版本验收、部署 同一警告在 --panicOnWarning 下让构建以非零状态退出

后果

  • 每个回退值都是公开契约的一部分,必须与主题声明的默认值一致。
  • 从“失败”改成“回退”时,测试也必须改变。负向测试要同时证明普通构建存活、警告文案、 渲染后的回退,以及严格构建失败。
  • 检查器必须直接验证被拒绝的输出。例如 URL 安全测试应断言危险 URL 没有进入产物,不能把 任意构建失败当作充分证据。
  • 渲染产物负责 DOM、属性、顺序与已注入 token 的断言;浏览器套件负责计算后的颜色、尺寸、 间距、断点与交互结果。只要公开结果可以直接观察,检查器就不应冻结某一种 Sass 写法。
  • 源码级检查仍用于 errorf 等禁止构造,以及产物无法证明的少量拓扑不变量,例如唯一 authority、 唯一 resolver,或有意收窄的 caller set。

验证

本决策的归属参考包括 架构契约、 bin/check-params.py,以及主题夹具与本站的严格构建。

6.2 - 配置模型

OINK 延长 Hugo 与 Docsy 兼容配置,不另造第二套命名空间或全局 resolver。
决策

OINK 保留 Hugo 原生键与仍有价值的 Docsy 兼容键,把主题呈现和行为放在 params.ui.* 下,并用同名的顶层 front matter 键提供页面覆盖。它不增加 params.oink.* 配置树,也不建立一套遮蔽 Hugo 配置模型的注册表。

背景

OINK 继承了成熟的配置面,又增加了阅读外壳、内容输出和本地交互。早期设计曾尝试把所有 主题自有键迁入一个新命名空间,并在每页一次性解析完整配置字典。这样会在 Hugo 原生键旁边 再造一种语言,使 section cascade 更复杂,迁移规模甚至超过它要控制的行为本身。

现行模型直接体现每一层的归属:

层次 职责 示例
Hugo 站点身份、语言、菜单、输出、分类法、markup、模块 baseURL、languages、outputs
站点事实与集成 仓库、版本、作者、本地搜索、评论、外部服务 params.github_repo、params.version、params.comments
OINK 界面 外壳、导航、呈现与本地交互 params.ui.sidebar_*、params.ui.typography、params.ui.share
页面或栏目 对可覆盖站点默认值的局部调整 sidebar_enabled、featured_image、share
数据文件 不是开关的结构化事实与有序内容 data/landing、data/download、data/docs_nav.json

决策

配置 API 遵循以下规则:

  1. 站点事实保留在既有顶层;界面选择归入 params.ui.*。
  2. 页面覆盖去掉 ui. 前缀,其余名称保持一致。section 的 cascade 可以把这个顶层键应用到后代。
  3. 一个布尔值足以表达完整政策时使用标量;只有真正存在下级设置时才使用 map。既有 map 可以接受 布尔速记。
  4. 名称采用正向、snake_case,并按功能分组。密切相关的设置共用前缀,不为此再建一层 resolver。
  5. 主题默认值声明在主题的 hugo.yaml 中。只有静态值会抹掉刻意存在的外壳差异时,模板才可以 推导默认值。
  6. 每个功能族负责自己的规范化与校验。共享 helper 提供常见形状,但不存在一套悄悄重写任意旧键的 全局兼容注册表。

完整的现行键、类型与默认值统一放在配置参考中。本决策只记录 归属规则,不再维护第二张参数表。

兼容策略

公开键改名时,由归属 resolver 给出定向警告,同时提供迁移说明和负向测试。已移除或拼错的键 不构成永久别名层的理由。Hugo 与第三方原生 camelCase 键继续保留原样;OINK 自有新增使用 snake_case。

页面值通过 Hugo 普通的 front matter 与 cascade 模型解析。OINK 不要求作者在 front matter 里写嵌套 ui: 树,也不承诺合并任意嵌套页面 map。

后果

  • 新增公开设置时,必须有声明或明确推导的默认值、归属 resolver、文档,以及正向和负向测试。
  • 配置指南链接到唯一参考表,不在各处重复类型与默认值。
  • 只有有序或重复事实才值得新增数据结构,不能只因为不想增加参数就造一个 data 文件。
  • 无效标量值遵循警告与回退决策。

验证

bin/check-params.py 审计声明默认值、页面别名、警告行为与禁止 errorf 的不变量。公开参考及其 中文对页由集成站的双语和渲染链接检查覆盖。

6.3 - Markdown 优先创作

原生 Markdown 承载常见语义;shortcode 只填补真实能力缺口,各内容模型延长共享外壳而不是分叉。
决策

Goldmark 能保留目标语义时,优先提供原生 Markdown 形态。只有原生形态无法表达真实能力时, 才保留 shortcode。新增内容场景时延长既有外壳和数据模型,不另建一套并行渲染系统。

背景

OINK 同时服务短手册、大型参考文档、发布归档、落地页和书籍。对十一个消费站点、五千多篇 Markdown 的盘点呈现了两个极端:有些页面几乎不用主题语法,有些页面则由大量嵌套 shortcode 与站点自有 layout 拼成。

只为后一类优化的组件 API 会变成私有 DSL;只支持纯 Markdown 又会迫使书籍、富图、标签页和 结构化发布退回站点自有 HTML。真正有用的边界是能力,而不是语法看起来是否新颖。

决策

OINK 按以下顺序设计:

  1. 原生 Markdown 优先。 列表可以成为 Steps、Cards 或 FileTree 标记;表格可以成为 Fields 或矩阵;blockquote 可以成为 callout;代码围栏、图片与 passthrough 块通过渲染钩子携带属性。
  2. shortcode 只补能力。 CommonMark 缩进、嵌套容器、处理选项或跨页登记无法安全表达同一结果时, 才保留全量 shortcode 形态。
  3. 语义实现只有一套。 原生形态与全量形态进入同一组规范化 partial 和输出契约,不能只是两种 外观相似的组件。
  4. 沿一条系统延长。 新 Landing 区块进入 section 注册表;新 Blog 呈现仍是 Blog 变体;Book 编号接入内容原语与导航系统。OINK 不为一个功能再造第二套卡片、落地页、导航或 Article 外壳。
  5. 事实不藏在呈现字符串里。 版本、仓库、日期与有序记录来自 front matter、站点参数或数据文件。 shortcode 参数不能成为第二个事实来源。

输出契约

只有在每种已启用输出中都得到明确语义结果,一种创作形态才算完整:

输出 要求
HTML 服务器端先输出完整语义内容,JavaScript 只做增强
Print 静态、展开,不包含依赖交互的控件
Markdown / LLMS 保持源码形态的正文、链接、列表、表格与围栏,不泄漏组件 HTML
RSS 安全的静态内容,或者明确省略

这一要求避免一个漂亮的 HTML-only 组件悄悄破坏 Agent 输出、订阅源或整书打印。

信任与呈现

渲染钩子与 shortcode 使用明确的属性白名单。不安全 URL scheme、内联事件处理器和任意 style 输入会被丢弃。只有在文档明确规定、下游站点 CSS 已属于既有创作契约的表面,才接受作者 class。 图标使用一对 Font Awesome class;OINK 不再发明第二种图标 ID 语言。

后果

  • 提议新组件时,必须先说明 Markdown 加既有渲染钩子为什么不够。
  • 保留全量 shortcode 时,必须点明它独有的能力,并测试两种形态进入相同的规范化输出。
  • 外壳变体使用相互独立的呈现键,因此启用 Hero 或流式大纲不会改变分类法、订阅源、翻页顺序或 内容类型。
  • 消费站证据是带日期的研究,不是永久冻结偶然语法的理由。当前公开面仍由 组件契约与外壳契约定义。

验证

主题的组件、Book、输出与 golden 检查器先验证创作契约,本站的双语示例与浏览器套件再完成集成 验收。原生形态背后的 Goldmark 事实记录在 块属性研究中。

6.4 - 生成式配置 Schema

编辑器 Schema 是从既有配置权威投影生成的,CI 漂移门禁保证它永远不会成为第三个权威。
决策

schema/ 下的两份 JSON Schema 由 bin/generate-config-schema.py 从主题的 hugo.yaml 与模板读取点投影生成,手工编辑无法通过 CI。Schema 是既有权威的 只读投影,不是第三个配置权威。

背景

主题已有两个配置权威:hugo.yaml 在注释旁声明每个默认值;check-params.py 的读取点扫描知道模板实际消费的每一个键。编辑器对两者一无所知,作者只能凭记忆 敲 params.ui.* 和 front matter。

JSON Schema 能给编辑器补全与悬浮文档,风险在于 Schema 悄悄变成会漂移的第三个 权威。任何手工维护的 Schema 都终将与实现脱节,而脱节的补全比没有补全更危险。

决策

bin/generate-config-schema.py 在 schema/ 下生成两个文件: site-params.schema.json 校验站点的 hugo.yaml(类型与默认值取自主题自己的 hugo.yaml,描述取自其注释块);front-matter.schema.json 校验页面 front matter(模板作为创作面读取的全部键,描述继承自对应站点键)。仅为提示「已重命名 或已移除」而读取的键按名排除。

两个刻意的克制成为决策的一部分:

  • front-matter Schema 不带类型约束。多个键在站点类型之外还接受裸布尔退出 (share: false、theme_color: false);对合法输入画红线比没有提示更糟。
  • hugo.yaml 读取器只解析该文件实际使用的形态——嵌套映射、标量、行内列表。 读不懂的构造是硬错误,超出能力时漂移门禁会大声失败而不是错误生成。

后果

改变 Schema 的唯一途径是修改 hugo.yaml 或扫描所读的模板:公开配置面变化时, Schema 在同一次提交中随之再生,不存在需要单独记得维护的第二份清单。代价是 生成器与读取点扫描成为公开配置面的隐含门禁——新增参数键必须能被它们理解, 否则 CI 直接失败。

验证

python3 bin/generate-config-schema.py --check 在内存中重新生成,schema/ 过期或缺失即失败;主题 CI 把它放在参数契约检查旁边运行。编辑器接入方法与 行为描述的规范位置是配置总览。

视觉预设枚举值另从 preset-config.html 提取。preset_menu 联合类型接受布尔值或 由解析器管理的预设名称列表,schema 不另行维护名称清单。

6.5 - 可选 CLI 与结果契约

当前本地 CLI 候选的独立 Go 可执行文件边界、版本化诊断、隔离验证与有保护的维护计划。
当前范围;本地候选

本契约描述 2026-10-04 收缩后的本地 0.1.0-dev 命令界面。保留站点诊断、 真实 Hugo 检查、初始化、构建、升级及有保护的维护计划;使用 Cobra、默认彩色 英文文本与 JSON/YAML 结果。Studio、通用编辑、context、snippets、editor 与 CI 生成已撤下。历史 R1–R8 验收只对记录中的源码和二进制成立,不能替代当前验证。 尚未建立公开 CLI 发布、Homebrew 分发或部署。

背景与归属

主题是 Hugo 模块;消费站工具是可选的可执行文件,具有不同的安装和版本发布周期。 pgsty/oink-cli 负责名为 oink 的可执行文件及其 Go 测试。它调用外部 Hugo 二进制,不引入 Hugo 私有运行时,也不在运行时依赖同级 checkout、Python、Node.js 或未发布的主题脚本。

配置解析、渲染、路由与锚点由 Hugo 负责。CLI 检查 Hugo 的生效配置、模块图、挂载 与渲染文件,不另建路由解析器、导航权威或配置命名空间。仅针对主题的回归脚本继续 作为维护者工具。架构契约仍负责主题行为;本页 负责首期 CLI 边界与结果封套。

配置预处理仅在临时副本中重定位 workspace、replacement 与缓存路径。默认值、 配置合并、语言选择、验证和渲染语义仍由 Hugo 负责。

使用指南提供安装与命令示例。 带日期的验收记录将已执行 检查、未解决限制和发布状态分开说明。 维护验收记录 保留历史 R1–R8 计划与绑定源码的验收证据。 路线图继续保留后续提案和采用假设, 不再重复当前命令参考。

命令与修改边界

命令帮助按日常、维护与发布分组,使用 oink COMMAND --help 查看准确选项。

命令 行为与写入边界
doctor 只读工具链、生效配置、模块来源、workspace/replacement/vendor 诊断
check [links|translations|style] 在隔离副本中检查真实 Hugo 输出及声明的源码/翻译政策
init DIRECTORY 先验证固定 Starter,再创建新的或空站点
dev、build 普通 Hugo 进程;正常输出与缓存写入由 Hugo 管理
upgrade --to TAG 默认预览,只有 --write 才应用验证后的模块修改
translations status、translations diff PAGE 只读关系、哈希审阅状态和差异
translations review SOURCE TARGET、baseline capture 必须提供审阅者与理由,默认预览,可保存新 --plan
new BUNDLE --title TEXT、move SOURCE TARGET 验证候选并预览完整 diff,可保存新 --plan
plans apply FILE 重新验证受支持的已保存计划,仅写选定站点的指定文件
inspect PAGE、impact --since REF 只读真实页面与历史/当前影响事实
workspace list、workspace check [GROUP] 仅选择显式登记的站点
build --check 检查、封存并导出同一次隔离生产渲染
artifacts verify 离线比较本地产物与清单
verify 显式 --network 后比较部署 HTTP 响应与清单

联网默认关闭,所有命令均不交互。Hugo 参数仅在 dev/build 的 -- 后透传。 已撤下命令与其旧计划不能应用;受支持计划类型仅为 authoring.new、 translations.review、baseline.capture、content.move。

版本化结果封套

选项 输出
默认 简洁彩色英文文本
--json、-J 一个 JSON oink.result/v1 对象
--yaml、-Y 一个具有相同结果字段与类型的 YAML 文档
--verbose、-v 全部发现、覆盖明细与工具日志
--no-color 无颜色英文文本

只能选择一种结构化格式。非空 NO_COLOR 或 TERM=dumb 也会关闭文本颜色。 结构化输出不添加终端颜色,工具日志写入 stderr。--format json|yaml 与 --non-interactive 保留为隐藏兼容选项;所有命令均不交互。

默认文本展示状态、计数、最多八条活动发现及明确的未检查覆盖。详细事实与已审阅 发现保留在结构化结果中。计划与升级预览展示完整 diff。Cobra 管理命令分发与各级 帮助。CLI 提示采用 ASD-STE100 风格的简短主动英文句,不宣称认证;用户内容与 外部工具证据保留原语言。

字段 类型与含义
schema_version 字符串;本契约使用 oink.result/v1
version 字符串;CLI 构建版本,开发版本保留相应后缀
command 字符串;请求的命令,或 help / version
site 可选字符串;可取得时的选定源目录或生成目标目录
exit_code 整数;下文定义的 CLI 结果码
diagnostics 发现项数组;空数组表示没有记录发现项
coverage 带范围的覆盖声明数组;调用者必须将它与发现项一并检查
evidence 子进程记录数组;未运行子进程时为空
data 可选的命令专有 JSON 值;当前命令返回诊断事实、初始化来源或升级计划等对象

首版允许添加字段与新规则 ID。消费者应忽略未知字段,将 ID 作为不透明字符串, 不解析其拼写。改变已有封套字段的含义或类型,需要新的 Schema 版本。命令专有事实 与原始工具输出属于证据,不是供用户导入内部 Go 包的 SDK。

机器可读 Schema 随 CLI 仓库提供,路径为 schema/result.v1.schema.json。 其标识符不证明 Schema 端点或 CLI 公开版本已经部署。

每份证据记录包含 command(参数数组)、可选的 directory、stdout、 stderr 和子进程自己的 exit_code。捕获的诊断与构建输出保留在结果中。 dev / build 直接流式输出的内容进入日志流,不再重复缓冲进证据。子进程状态与 CLI 的 0 / 1 / 2 结果码不同;负的子进程状态可能表示未取得正常退出码。

JSON Schema 定义了该结果封装的结构。

发现项、严重度与位置

每个诊断包含 rule_id、severity、message、action,以及可选的 location。 稳定规则 ID 标识问题条件。原始 Hugo 文案、翻译后的消息、路径和特定构建细节不是 稳定 ID。已有 ID 不得重新分配给不同条件。

可选的 incomplete: true 标识必需工作失败,政策不能降级这种失败。 经过审阅的排除项和基线确认仍保留在 diagnostics 中,附带 disposition: "excluded" 或 "baseline", 以及含 reason、reviewed_by 和 RFC 3339 reviewed_at 的 review。 被排除的问题保留已记录严重度并保持可见,但不阻断已完成的政策检查。 任何未完成的必需覆盖(包括 not_checked)都决定退出码 2; 只有 complete 或 not_applicable 满足必需覆盖。

严重度取值为 info、warning 和 error。error 是阻断项,info 与 warning 是信息或建议项。但如果所需 Hugo 构建因 --panicOnWarning 失败,则必要工作未完成。信息性的完成说明与范围解释放在覆盖 详情中。自动化必须读取结果退出码与覆盖状态,不能只统计严重度。

提供 location 时,其中包含 file,以及可选的 kind、line 和 pointer。 kind 区分 source 与 output。渲染产物中的问题指向实际产物,可以在 pointer 中给出元素、属性或 JSON 位置提示;这个字段并不统一承诺采用 RFC 6901 语法。 只有明确知道行号时才提供 line。渲染链接失败不能成为编造 Markdown 源码行号的理由。

CLI 不会仅因生成的编辑器 Schema 未列出某个字段,就拒绝合法的自定义 front matter。 配置有效性继续服从 Hugo 与所属主题解析器、检查器;参见 生成式 Schema 决策。

覆盖范围与退出语义

每个覆盖条目包含 id、status、required(布尔值)和 detail,描述实际运行的 范围。一份报告可能对同一大类提供多条声明,应全部检查。

状态 含义
complete 所述操作、检查或产物检查范围已完成
not_checked 本次没有检查所述范围
not_applicable 对于当前输入,无需执行所述检查
unsupported 不支持所述契约或必需输入形态
incomplete 所述工作属于必要项,但未能完成
CLI 退出码 含义
0 请求中的必要工作已完成,没有阻断项
1 已完成的检查发现政策问题,例如损坏的本地链接或不安全的写入请求
2 必要工作未完成,包括参数、工具、构建、I/O、取消或必需契约不受支持等失败

未完成状态的优先级高于政策问题。未完成的必需覆盖不能返回成功; 只有 complete 或 not_applicable 能满足必需覆盖。 Hugo 构建失败时保留原始证据并停止产物验收,不会把旧产物或部分产物报告为检查通过。 未启用的可选机器输出不构成缺失输出错误。

渲染引用范围包括受支持的 HTML URL、锚点和已输出的机器契约。覆盖声明明确排除 浏览器交互、无障碍、视觉呈现、外部 URL 可访问性、托管重定向及生产部署,也列出 未检查的动态资源与内容语义。静态产物证据不能证明未声明的翻译覆盖、翻译语义等价 或浏览器执行结果。

Hugo 公共 Page.OutputFormats 按页面和启用语言给出预期产物名称与 URL。隔离 副本添加带有本次运行唯一标识、不会进入普通列表的探针;每个启用语言都必须输出 自己的有效清单。产物检查前会移除已识别的探针文件,不改动已有页面选择的输出。 未进入普通列表的静态内容通过 Hugo GetPage 解析,不从源码语法推导路由或输出 文件名。枚举还提供每种语言的生效 base URL 与本地搜索设置。已启用且受支持的机器 产物按这些确切预期检查;未启用的可选输出仍然可选。

同一 Hugo 探针通过公共 Page.Path、Page.File、Page.Translations、 Page.Aliases 和 Page.OutputFormats 提供 data.pages,保留语言、实际 URL、 发布设置、翻译关系及声明输出。没有可靠来源时,sourceKnown: false 和 sourceScope: "unknown" 明确说明未知;生成分区不会得到虚构的源文件。 站点所属的已知路径相对于选定站点,已复制的已知依赖输入明确标记依赖范围。 这些事实描述生产视图;独立的内部分析视图可以包含草稿、未来和过期页面, 但不改变生产产物,也不把它们声称为已发布。

data.references 记录实际观察到的 HTML 和机器输出引用、解析后的实际 URL、 产物文件/位置、存在时的本地目标和已检查时的锚点状态,不推断 Markdown 源码行号。 页面与引用数据仍是可增补的命令证据,不是公开 Go SDK。

项目检查政策

选定站点根目录可以提供普通文件 oink.yaml,使用 schema_version: oink.policy/v1,管理检查选择、严重度覆盖、经审阅的问题排除、 外部 URL 范围、翻译范围、受保护正文声明和可选基线文件路径。 语言、标题、URL、菜单及配置继续归 Hugo 输入所有;依赖版本归模块文件。 符号链接、未知字段/分组、不支持版本、无效审阅元数据或多个 YAML 文档属于必需输入失败 (退出码 2)。诊断与检查只读取这项政策。

没有政策时,链接、翻译和风格均启用且必需。check links、 check translations 或 check style 显式选择一个必需分组,不受政策选择影响。 未选中或禁用的可选分组报告 not_checked。每次检查仍保留必需的严格 Hugo 构建和输出枚举前提。独立检查的翻译与源码引擎另用显式且不可发布的草稿/未来/过期 分析视图,从不替代生产产物。受管理的 build --check 只渲染生产视图,遇到未知且 必需的范围身份时返回 2。

rules 映射向确切且不透明的规则 ID 指定 error、warning 或 info。 经审阅的 exclusions 项须有 rule_id、规范相对 file glob、reason、 reviewed_by 和 RFC 3339 reviewed_at;不支持 ** 和路径逃逸形式。 站点内部源码位置使用相对站点路径匹配;选定站点之外的源码路径不能匹配排除项。 问题及审阅元数据保持可见。必需构建、输入、工具或覆盖失败不能经严重度更改或排除变成成功。

同 origin 但位于配置 base path 之外的 HTML 引用属于政策问题,除非经审阅的 external_scopes URL 声明其为单独部署的路径范围。每项范围要求同样的审阅元数据, 以及不含凭据、query 或 fragment 的绝对 HTTP(S) URL;匹配按完整路径段进行。 范围不能豁免项目内部缺失目标或机器输出的必需本地目标。 不同 origin 的引用在离线静态检查中仍明确标记为未验证。

翻译政策与审阅证据

translations.scopes 按规范绝对 Hugo Page.Path 前缀选择源页面,再通过 Hugo 翻译身份寻找目标,不从文件名推断公开路由或语言。每项范围包含 path、 source_language、required_languages、mode 和 drafts。 mode 默认 localized,也支持 strict。drafts 默认 include; ignore 排除草稿源页面/目标,require-published 要求选定源页面和必需目标实际 存在于生产发布视图。Hugo 已知但禁用的语言为 not_applicable;未知语言属于 无效政策。最具体的匹配路径决定源页面所属范围。

没有范围时,检查以 Hugo 已启用默认语言为源的已有配对及重复关系,不要求全站普遍 本地化;translations.coverage 将未配置语言覆盖记为可选 not_checked。 缺失必需目标和选定关系重复属于政策问题。草稿/发布状态与审阅状态分别记录。

约束均须显式选择:严格模式的 explicit_ids 比较完整的已识别显式 ID 映射, 本地化模式要求选定 ids 列表。ids 要求两份文件均有指定 ID,placeholders 比较指定正文字符串的确切数量,code_labels 保护指定语言/info token 的围栏代码。 required_fields 要求双方指定的点分 front matter 字段非空;equal_fields 比较其实际值。默认没有规则要求标题数量、翻译正文或所有代码块一致。

.oink/translations.json 使用 oink.translations/v1。显式审阅记录绑定 Hugo 源/目标 ID、源语言、完整源文件/译文的字节 SHA-256、审阅人、理由和 RFC 3339 时间。无记录为 unknown;哈希相等为 current;仅源、仅译文或双方改变分别为 source_changed、translation_changed、both_changed。这些状态只证明审阅后 发生变化,不判断翻译语义。文件修改时间不能建立审阅状态。来源未证实则保持未知; 已有审阅或受保护约束无法验证时,返回必需工作未完成。

原生内容规则与覆盖

源码规则从 Markdown 结构和独立的已启用 Hugo 属性提取证据,保留原始 UTF-8 字节、CRLF/BOM、源码偏移及含未知字段的 YAML/TOML/JSON front matter。 实际生效的 Hugo 属性开关和数学透传分隔符控制识别。围栏/行内代码、短代码主体、 原始 HTML 和透传内容不会成为正文或虚构标题。不支持的正文语法保持可见; 必需源码覆盖不能静默通过。

通用规则检测重复的已识别显式 ID,并检查 style.protected 声明中的 file、 确切正文 literal 和预期 count。有界 OINK v1.1.0 目录另提供代码/表格属性、 弃用 front matter 和被丢弃的不安全属性建议。每项规则在 data.native_rule_provenance 中记录模块、版本、不可变 revision、模块 sum、 许可证及确切来源文件的 SHA-256。

只有实际挂载的公开 v1.1.0 模块缓存输入匹配这些哈希时,才运行该目录。 replacement、vendor 副本、其他版本或未知来源不选择最新主题回退: native-theme-rules 为可选 not_checked,通用语法检查仍运行。 这份目录不保证覆盖每个自定义组件或主题功能。

基线与经审阅文件计划

baseline 选择规范相对文件,默认 .oink/baseline.json,使用 oink.baseline/v1。捕获要求工作已完成并有显式审阅元数据。指纹绑定确切规则 ID、 规范化位置/指针和条件消息,不包含严重度。已确认问题保留原严重度,附带 disposition: "baseline" 并保持可见;新条件仍按政策阻断。 必需但未完成的发现项或覆盖不能被确认豁免。

审阅和捕获预览 oink.plan/v1:选定编辑、可读 diff、基础存在状态/字节/模式、 修改后字节及只读保护条件。计划 ID 不包含可变的验证/应用/恢复状态。 --plan FILE 排他保存计划;这些命令不接受 --write。 plans apply FILE --site DIR 要求确切选定站点、通过相同检查重新验证隔离候选, 并在任何写入前重新检查源码保护条件。逃逸、.git、符号链接和非普通文件受保护, 候选与源码目录重叠会被拒绝。过期计划安全失败。可选 external_inputs_hash 将 捕获的非站点输入字节、完整模式和清单绑定计划 ID。这个不透明 SHA-256 不授予 外部路径或读取权限;归属验证器比较新证明的输入,选定写入前后重新核对可信原始 外部保护条件。

排他安装保留提交期间新创建的文件。部分失败只还原本次拥有且未变化的写入,保留 后续编辑器字节、模式或删除状态。报告的恢复目录保存原字节/模式及实际捕获的并发 证据。无关文件和编辑器新建子文件均保留。文件内容不能授权 shell 执行或发布。

捕获页面查询与影响

inspect PAGE 按精确的 language:path ID、Hugo Path、permalink 或已证明的 站点源文件选择实际 Hugo 页面。已知默认语言可消解同一 Path 的多语言匹配;仍有 歧义或未知选择器时返回必需未完成 2。data.inspection 展示源码字节哈希、完整 模式、实际输出身份、观察到的入站/出站引用、翻译与物理 bundle 附件。物理附件与 观察到的发布资源分别记录。

impact --since REF 比较捕获的当前输入与隔离的 Git 已提交树,二者由同一 Hugo 引擎渲染。保留已删除的旧页面与其入站边,纳入未修改的引用页面、翻译同伴、附件及 实际派生产物。全局或不确定输入扩大因果范围;alias 等无法证明页面归属的实际 HTML 输出也会保守扩大为全范围。不会按 alias 声明猜测路由归属。只有证明归属 Git 模式范围的历史输入比较可执行位;其他模块/外部输入与当前事实保留完整模式。

历史 materialization 读取有界 Git 对象,不运行 checkout hook、filter、smudge 或文档内容。上限为 10,000 个文件、单文件 16 MiB、树总计 128 MiB;必需的私有 历史上限为 256 MiB。符号链接、submodule、超限/缺失对象、必需历史不完整及不支持 的 monorepo GitInfo 均明确为未完成。已提交的站点内部依赖可被证明;当前外部本地 replacement/workspace 字节不能替代历史证据。

data.impact.baseline_state 为 complete、incomplete 或 unavailable。 必需基线不可用时返回 2,保留全部已知当前页面、附件、引用与输出,并扩大范围。 不虚构旧页面或变更;只记录实际解析出的 commit。check [GROUP] --since REF 有意执行完整当前检查,并声明 data.check_scope: full,不承诺增量提速或部分 验证。data.impact.full_scope 单独描述因果不确定性,与验证范围分别表达。

完成的 inspect、impact 事实查询返回 0,即使单独报告的 data.current_check 含已完成质量发现 1。必需捕获失败仍为顶层 2。 check --since 保留当前政策的质量退出码和必需完成状态优先级。

context 已移除,页面事实可通过 inspect 的 JSON/YAML 报告读取。

内容移动计划

move SOURCE TARGET [--plan FILE] 预览物理站点相对文件或 bundle 的迁移。 由实际 Hugo 身份确定翻译同伴与新旧输出。计划包含保留字节/完整模式的文件及二进制 附件、可读 diff、已证明的 Markdown 目标重写、观察到的路由变化及 alias 建议。 不通过重写 front matter 自动安装 alias。原始 HTML、shortcode 输出、经过变换的 目标及源码/输出归属歧义保持为可见人工动作;不修改不透明源码片段。重复的普通 Markdown 目标也可能缺少唯一源码/输出出现位置证明,包括聚合/打印视图。仅 URL 匹配不足以授权重写这些出现位置。物理附件迁移不证明新的发布 URL。资源 URL 变化需要配对实际渲染边及相同产物字节;已证明的处理后图片 URL 不证明绝对原始 资源 URL。未证明的原始 URL 保持人工处理,不按目录迁移构造。

原始 before 检查与临时 route_probe 独立于最终候选检查。临时迁移可能因旧入站 链接产生发现 1。只有最终隔离候选及引用证明通过,计划才标记验证或保存。不支持 的身份或必需捕获失败返回 2;实际最终质量失败保持 1,不能保存可应用计划。

内容移动计划必须保存在选定站点之外。oink.plan/v1 的新增 move 选择器与 source_inputs_hash 绑定完整原始源码清单、字节及完整模式,同时应用外部输入与新 目录保护。应用已保存计划时重新生成原始/迁移 Hugo 证明,并在最终引用验证前要求 期望 plan ID 与文件完全一致。写前重新核对当前保护条件,恢复原始模式而非隔离 副本模式,拒绝或受保护恢复时保留后续编辑者的字节/模式。过期输入或已有新目标 无法提供必需证明,返回 2。只有显式 plans apply 写选定文件;预览不 stage 也不提交 Git 变更。

支持的输入边界

首期完整验证支持普通 checkout 或无 Git 元数据的实际文件,包括复制到隔离目录中 的受支持本地模块 replacement。它不会沿已挂载符号链接或外部挂载项返回用户工作区。 有效挂载范围之外的辅助符号链接不复制到快照,也不视为已验证。使用 .git 文件的 关联 Git worktree 需要实际文件审查副本;依赖 Git 的行为需要副本具有自己的 Git 元数据。

快照排除顶层 public、resources、node_modules、tmp 和 Hugo 构建锁。 挂载项需要这些被排除的输入时,不能静默通过。支持根配置与标准 config 树;显式 配置文件必须在选定站点内,自定义 HUGO_CONFIGDIR 位置会被拒绝。受支持的配置 路径重定位不构成第二套 Hugo 验证实现。

内容适配器(_content.gotmpl)可能生成无法通过受支持公共 Hugo API 完整枚举的 隐藏页面,因此完整产物验证对这类输入返回必要工作未完成。禁用页面类型或选择 render segment 导致某个启用语言缺少探针,也属于未完成。多主机语言配置不在首期 完整检查范围内,返回必要工作未完成;单主机的多语言路径仍受支持。上述情况不能 被报告为成功的部分检查。

普通内容计划

new BUNDLE --title TEXT [--language LANG] [--translations LANGS] [--kind page|docs|blog|book] [--plan FILE] 根据捕获的站点自有内容挂载预览普通 Hugo 叶子包。主语言默认采用生效默认语言,选定译文必须是不同的已启用语言。 共享文件名与语言目录布局跟随真实 Hugo 挂载,包括实际 sites.matrix.languages 选择,不假定旧 lang 字段。含糊、过滤或不支持映射需要人工创作。已有包或占用同一页面的同级内容文件会被拒绝。

主索引 draft: false,选定译文索引 draft: true。标题文本来自显式输入,不会 自动翻译,也不创建审阅记录。完整质量分析和隔离候选验证先于共享受保护计划。每份新文件必须对应恰好一个 实际站点自有 Hugo 源页面且有实际渲染输出,译文草稿使用显式分析视图。仅链接/无 输出、忽略、隐藏或 build-never 内容不能仅凭既有站点构建正常而通过,即使普通源码检查组关闭也须验证 必需来源身份。 --plan 只保存新计划文件,显式 plans apply FILE --site DIR 重新验证源码字节/ 模式、存在状态、新目录和后续附件冲突,再应用修改。新目录状态绑定计划身份, 在验证前后、写入之间和完成时核对。回滚保留后续编辑器附件并报告恢复, 不删除无关目录条目。

编辑器设置与 Markdown 片段由站点编辑器管理,editor 与 snippets 已移除。

初始化配置

init DIR [--profile project|docs|blog|book] [--languages en|en,zh|all] 组合同一份内嵌 MIT 许可证 Starter 归档。默认 project 按字节保留此前完整语言投影。 语言选择独立于内容配置,all 表示英语、中文、法语。

显式 docs、blog、book 保留对应归档内容分区及共享首页、资源、示例、工作流与 许可证。原生分区 front matter 定义文档、博客或连续书籍模型与导航。各语言站名/ 描述来自其归档分区,已有本地化首页卡片/动作/CTA 投影到该分区。只序列化这些配置 生成的 hugo.yaml 和 data/home YAML,保留内容与许可证字节不变。 没有四份复制 Starter 树,也不在运行时下载模板。

未知配置在候选验证或写入前拒绝,政策退出 1;必需 Hugo 缺失/验证失败为未完成 2。新建/空目标、先候选验证再发布、排他创建与并发编辑恢复保护适用于全部配置。 预备依赖后,普通 Hugo 可以构建生成站点。归档工作流仍为来源示例,init 不生成或 执行 R3 的校验和绑定 CI 模板。

有界升级比较

upgrade --to TAG 现根据同一原始站点输入捕获基线与候选视图,返回可读模块 diff 及完整模式变化。比较记录实际 Hugo 页面/输出/语言设置、生成文件哈希/大小/模式, 以及原始 alias 声明和单独观察的重定向文件。报告删除/新增 URL、已证明重定向、 alias 目标/字节变化及启用语言/输出/搜索变化。候选构建正常本身不能证明路由或能力 得到保留。

只有在确切旧输出文件处观察到指向对应实际候选页面的重定向,才能证明旧 URL 被保留。 未知/相对定制 alias 身份仍为必需未完成 2;删除此前生成路由或输出为阻断发现 1。 两个实际解析主题版本必须匹配明确选择的 pin;未知/替换 pin、未知/不同的规范 Hugo 版本或环境、意外其他输入变化均保持未完成。比较支持单个 HTTP(S) base origin/path, 多主机输入保持未完成。不宣称配置迁移转换或普遍浏览器/主题兼容,人工审阅保持 明确的可选未检查覆盖。观察到 alias 改指向另一个唯一 Hugo 页面时,独立于同页 URL 移动而阻断。

升级 v2 计划 ID 绑定选定模块计划、复制源码字节/完整模式/文件清单和规范实际比较。 --expect-plan ID 核对新的捕获/比较,不复用此前成功构建。生成文件哈希也绑定计划, 因此非确定性模板即使源码看似不变,也可能需要重新预览。预览返回前、每次写入前及 写入后重新核对保护条件,包括只读核对已证明的本地依赖/workspace 输入。只写选定 模块文件,回滚只恢复该操作拥有且未变化的文件,保留后续编辑器字节。已有脏目标、 replacement 与 vendor 保护继续生效。

文件保护与发布检查

初始化内嵌完整 Starter 提交并保留许可证。来源清单记录其哈希和每项投影:选择已有 语言配置、确切的公开主题 pin 与校验和,以及为新目录关闭 Git 元数据。候选验证先于 目标写入。排他创建拒绝既有文件;回滚只移除本次操作创建且未发生变化的文件,并保留 并发用户编辑、给出恢复证据。

升级只处理单站点选定的 go.mod 与 go.sum 变更。它保留无关依赖与指令, --write 拒绝有未提交修改的目标文件;传入审阅后的计划 ID 时核对该 ID,写入前 再次检查目标,并记录备份与恢复信息。无关的脏源文件不应阻止只读诊断,更不能成为 覆盖这些文件的理由。

check --release 关闭 GOWORK 与 HUGO_MODULE_WORKSPACE,并移除子进程的 环境 replacement。它保留 go.mod replacement,报告冲突的本地 OINK 替换政策, 并将 vendor 证据与公开 requirement 分开。升级拒绝 OINK replacement,也拒绝 _vendor;vendor 刷新保留为单独的显式流程。修改模块 pin 不会被描述为已更新 vendor 字节。实际选中 vendor 主题时,--release 将公开来源验证报告为必需但未完成(退出码 2);仅版本元数据相同不足以证明 vendor 字节来自该公开标签。普通 check 仍可验证 vendor 的实际产物。

Hugo 配置中的模块 replacement 也仅在发布快照中禁用。如果 Hugo 在解析或构建时 修改了该快照的模块文件,CLI 会报告依赖输入需要显式预备和审查,保留原始字节, 而不会静默接受依赖未审查模块文件变更的构建。

已检查构建与产物身份

build --check --destination DIR --manifest FILE 在隔离环境中严格构建生产视图。 Hugo 只渲染一次;检查引擎检查该产物,再封装并导出同一份字节。CLI 不调用第二个 渲染器生成发布目录,源码 checkout 保持不变。只有结果为 0,且必需覆盖已完成 或不适用时,才能封装产物。阻断项或未完成检查不会产生已验证导出。

这个生产视图不包含单独的不可发布维护渲染。显式翻译范围政策所需的 Hugo 身份 因源码被排除发布而未知时,返回 2。CLI 不根据文件名推断缺失翻译,也不静默 跳过范围。独立 check 与 translations 命令保留完整维护视图。

目标必须为新目录或空目录,且父目录已存在;本地清单必须是产物树之外的新文件。 导出通过独占创建保留准确字节和普通文件的完整模式,不受 umask 影响,并按清单 重新检查源树与目标树。既有条目、符号链接和重叠目录树会被拒绝。部分导出失败后, 目标仍是未验证证据并予以保留。空目录和目录模式不属于发布文件清单。

--marker 可选,默认关闭。它添加 .well-known/oink-build.json,只包含 oink.build-marker/v1 和产物 ID。计算产物 ID 时排除该文件条目以避免循环哈希, 再将其准确摘要纳入最终清单。既有标记路径会被拒绝。本地清单不会自动复制到公开 产物树。

单独保存的 oink.artifact/v1 清单记录源码输入哈希、已知源码 Git revision 与 dirty 状态、实际解析的主题身份、CLI/Hugo 版本、生效环境/base URL/发布设置、 必需覆盖、实际 Hugo 路由上下文,以及每个文件的相对路径、大小、完整模式和 SHA-256。规范 URL 和 HTML 语言来自实际 HTML;Hugo 语言键单独保留。 未知 Git 状态仍是未知。原始输入字节和模式在添加临时探针、重定位 workspace 或 replacement 路径之前捕获。公开清单不包含本机绝对路径、任意参数、进程日志或 覆盖条目的自由文本。哈希证明字节身份,不是签名,也不证明本地 checkout 已公开发布。

受管理构建仅接受 -- 后的布尔 Hugo 参数 --minify、--gc、--ignoreCache 和 --noTimes,包括 =true/=false 形式。其他透传参数属于不支持的输入。 普通 build 保持既有透明透传行为。生效的示例/本地地址在普通诊断中是警告, 在已检查发布构建中是错误。--release 仍需独立的实际公开主题解析证据;本地 Git revision 或声明 pin 不能证明 vendor/replacement 字节的公开身份。

本地产物与部署验证

artifacts verify --artifact DIR --manifest FILE 只读且离线,比对准确文件集合、 字节、大小和完整模式。文件修改、缺失、新增、不安全或模式变化会使身份失效 (1)。无效清单、不可读输入以及不支持或中断的检查返回 2。上传器消费产物 之前应立即重新验证;后续编辑不能沿用先前的成功结果。

verify --site URL --manifest FILE --network 显式授权 HTTP 读取。它按清单限制 响应大小并比对解码后的字节摘要,检查每个声明文件和不同的实际 Hugo 路由 URL,包括全部语言与 子路径上下文。已记录的 HTML 规范 URL/语言值和启用的标记也会接受检查。 共享 URL/文件的请求可以合并,但保留其上下文。HTTP 无法验证本地文件模式位。

错误正文、soft-404、错误路由、已捕获规范 URL/语言值变化或错误标记是确定的 发现项(1)。超时、认证失败、限流、服务不可用或缺少必需标记属于未完成工作 (2)。跳转离开选定 origin/base path 时会被阻止;命令不发现或发送凭据。 静态构建检查不执行部署验证。构建联网权限不授权后续验证请求或上传。

已撤下 CI 生成

移除 ci init。CI 配置保留在站点或 Starter 中。 本地 CLI 验证不执行托管 CI,也不部署站点。plans apply 拒绝旧 CI 计划。

显式工作区登记

R6 受支持本地范围已接受

登记与可选工具边界通过冻结归属/运行时、实际协议、四消费者一致性/保护及 规范源码/渲染门禁。A07 适配器与 A15 工作区受支持范围已在 维护记录中本地接受。 记录中的 R1–R8 与 A18 范围通过其历史源码与二进制的验收;当前 CLI 的后续修改需要新证据。

工作区是一份显式指定的 YAML 登记文件,独立版本为 oink.workspace/v1。 它只包含站点名称与目录:

schema_version: oink.workspace/v1
sites:
  - name: docs
    directory: ../docs-site
  - name: blog
    directory: ../blog-site

登记文件必须是非符号链接的普通文件,只包含一份 YAML 文档和已知字段,登记 1–64 个站点,最多 256 KiB。名称符合 [A-Za-z][A-Za-z0-9_-]{0,63},区分大小写。 目录是相对登记文件实际父目录的字面路径,或绝对路径;不展开变量、glob 或扫描同级 目录。显式目录符号链接与操作系统路径别名解析到规范身份。拒绝重名、实际根目录 重复或重叠、文件系统根目录、悬空符号链接,以及非目录祖先。若缺失目录有已证明的 现存祖先,仍可列出;检查该站点返回 2,不会阻止后续选定站点继续检查。

workspace list|check [GROUP] --workspace FILE [--sites NAME,NAME] 在省略 --sites 时选择全部登记站点。显式选择必须使用准确、非空、不重复的登记名称;即使 参数顺序不同,仍保留登记顺序。list 不需要 Hugo 渲染器。check 复用单站引擎、 各站自己的 Hugo 输入与 oink.policy/v1 政策,不在登记文件中复制 Hugo 配置。

现有 oink.result/v1 封套包含 data.registry、selected_sites、 sites: [{name, path, result}]、completed_sites、finding_sites 和 incomplete_sites。每个子项是完整单站结果。已完成站点包括退出 0 与 1;发现 问题的站点是退出 1 的子集。只要有选定站点未完成,汇总退出为 2;否则有阻断项 时为 1,其余为 0。人类可读输出包含逐站结果与发现项,不推断未选站点已完成。

受支持的单站命令接受 --workspace FILE --site NAME,必须显式选一个登记名称, 没有默认站点。init、artifacts 与 verify 不接受这种选择。 保存的 plans apply FILE 必须绑定选定规范目录;改选其他登记站点时,在写入前 返回 2。不自动批量应用计划或升级。既有候选验证及源码/依赖字节与模式保护条件 继续生效。列出或检查登记不会创建缺失站点、安装工具、提交或写入消费者配置。

可选检查适配器

各站 oink.yaml 中的显式 tools 项选择已预备的可执行程序。这些项扩展 oink.policy/v1,不是另一份 Hugo 配置,也不是安装器。每种工具包含 enabled (默认 true)、required(默认 false)、command(默认与工具种类同名)、 config(提供时为站点内干净相对路径的普通文件)与 timeout_seconds (默认 60 秒;非默认值限 1–300)。命令是单个可执行文件名称或绝对路径,不能是 shell 表达式。

种类 归属检查组 当前支持协议 配置边界
markdownlint style markdownlint-cli 0.49.1 可选声明式 JSON/YAML/TOML;不支持 JS、JSONC、自定义规则或 extends
vale style Vale 3.24.0 显式 INI 与已捕获的受支持声明式风格子集
lychee links lychee 0.24.2 可选有界请求设置;显式联网授权

未配置的工具不会自动发现。工具不属于选定检查组时,明确显示 not_checked。 已配置的可选工具若缺失、不受支持或无法完成,会保留遗漏;必需工作未完成返回 2,不能通过规则严重度、排除项或问题基线降级。不能同时设为必需和禁用。 已完成的类型化发现项仍按政策处理:阻断项返回 1。未知工具版本或无效协议输出 不能算作检查完成。

data.adapters 记录每种工具的必需属性、状态、类型化诊断、adapter.KIND 覆盖、原始进程证据、遗漏与来源。来源包含已观察的受支持版本、可执行文件 SHA-256、 捕获配置/风格路径及其 SHA-256 和完整模式,以及固定的公开协议源码。工具日志写入 stderr 和证据;JSON stdout 仍只有一份结果。每个进程的时间与输出受限;可执行文件、 捕获配置发生变化,或工具修改私有输入时,其证据失效。

文字工具接收已证明站点自有 Markdown 的私有遮蔽副本。Front matter、BOM/CRLF 与 UTF-8 偏移、代码、短代码、原始 HTML、已配置数学公式与属性保留其源码边界。 代码正文不参与源码归因;markdownlint 仍能读取 Markdown 结构和围栏/行内代码 边界,Vale 使用纯正文遮蔽。触及排除区域或遮蔽生成文本的发现项不会归因到原文。 只有已证明的原始行/范围才输出源码位置;不支持语法与被抑制发现项保留可见遗漏。 适配器不格式化或改写原文。

Markdownlint 通过不可预测的生成 JSON pointer,在上游 rc 合并之后隔离捕获的规则 对象。拒绝可执行配置、自定义规则加载器与递归 extends。Vale 使用显式捕获 INI、 --no-global 和复制的声明式风格;不支持 sync、packages、actions、scripts、转换 或风格流水线。Lychee 接受有界 timeout、max_retries 与 max_concurrency 设置,以及字面 cache = false;缓存保持关闭,拒绝 cache = true。拒绝预处理器 与任意命令选项。

默认离线。没有显式 --network 时,不调用 lychee,连版本探测也不运行:可选覆盖 为 not_checked,必需覆盖为未完成 2。它只接收实际 Hugo 输出观察到的外部 HTTP(S) 引用;本地链接仍归原生检查。确定失败的 4xx 响应属于政策发现项,但 401、403、408、425 与 429 除外;这些状态、5xx、DNS/TLS 失败和 超时属于不确定结果,必需时返回 2,可选时保留遗漏。不验证外部片段、浏览器行为 或远端内容身份。发现项保留渲染输出文件与 DOM pointer,不从外部 URL 臆造 Markdown 行号。

子进程不接收调用者的代理 URL/凭据设置或 Node 预加载变量。已验证运行时可以传入 字面的 NO_PROXY/no_proxy 主机列表数据。这不保证所有操作系统代理路由都被 禁用,也不是操作系统网络沙箱。工具预备与任何联网操作仍是独立显式动作;这些 命令不安装工具。

离线与兼容性边界

受管理子进程默认离线。依赖缺失属于未完成工作。--network 为当前操作显式启用 联网,不能与 --offline 同时使用。隔离检查可以从已准备的本地模块为临时缓存提供 依赖。在临时缓存下载,并不承诺下一次调用拥有持久缓存。

只有模块下载制品会用于预备缓存,隔离资源缓存从空目录开始。CLI 不复用全局 GetRemote 缓存来承诺远程资源构建可离线运行。必需资源应作为本地输入提供,或为 该次操作显式启用联网。

CLI 不下载 Go 工具链,不安装软件包,不修改全局配置,也不启用遥测。进程政策不是 操作系统网络沙箱。兼容验证记录应区分普通离线执行与确实在操作系统边界禁止出站的 测试。

兼容性依据已执行证据声明,不从交叉编译成功推导。本地候选已经实测 macOS arm64、 Hugo Extended 0.166.0 和公开 OINK v1.1.0;版本门禁接受 Hugo Extended 0.160.1 或更新版本,但不声称这些版本都已测试。初始化站点保留普通 Hugo 输入,移除 CLI 后 只需要站点文档要求的依赖。

已撤下本地 Studio

CLI 移除 studio。使用普通编辑器与 oink dev 预览站点;通过 inspect 及结构化报告读取维护事实。带日期 R7 验收保留为对应输入的历史证据。

已撤下管理 API

CLI 不再提供管理 API,旧 Studio API 验收不代表当前可执行程序。

历史捕获限制

历史 R7 限制归属带日期验收记录;当前命令覆盖与输入范围以本契约为准。

已撤下通用编辑

移除 edit 与 Studio 编辑。使用普通编辑器修改源码,再运行 check。 new、move、审阅记录与基线计划继续保留候选验证和字节/模式保护。 旧编辑计划会被拒绝,带日期 R8 记录保留为历史证据。

已撤下文本和字段编辑

CLI 不再承担通用文本或 front matter 编辑表单。

已撤下片段和附件编辑

使用站点编辑器编写 Markdown、添加附件。CLI 不再提供片段目录或通用附件编辑命令。

已撤下 Studio 编辑

CLI 不提供编辑器,也不接受浏览器 Apply 请求。

验证与剩余范围

使用 make test 验证离线 Go 测试与 vet;使用 make test-hugo 验证真实 Hugo, 并为已配置可选工具运行 make test-tools。跳过集成不等于通过。 当前实现修改需要绑定新的源码与二进制证据;历史记录不自动赋予当前版本运行资格。

当前集成门禁尚未通过

2026-10-04,在 macOS arm64、Go 1.27.1 与 Hugo Extended 0.166.0 上, make test 通过,make test-hugo 的 TestPublicR5CachedPublicModuleMovePreviewApplyAndOrdinaryHugo 失败: 模块收集文本出现在配置 JSON 之前,移动操作返回 2,报错 Hugo config did not return JSON。候选验证拒绝操作,诊断报告源码未改变。 随后的单用例重跑通过,但间歇失败原因尚未明确;单次重跑不构成当前候选的 完整集成门禁通过。

带日期维护验收记录 保留旧 R1–R8 与 A18 证据。声明目标为 macOS arm64、Linux arm64/amd64, Darwin amd64 是未取得资格的实验目标,Windows 不受支持。归档生成、签名、 分发、消费者采用与部署是不同状态。此契约不授权自动提交、推送、发布或部署。

6.6 - Paper 与 Slate 视觉预设

第一阶段已接受的视觉身份与外观控件,分别维护读者的风格和明暗状态。
OINK 1.2.0

Paper 与 Slate 已随 1.2.0 发布。Ink 与 Terminal 作为显式启用的风格一同提供, 后续设计工作见下文记录。

决策

Paper 成为默认,使用暖纸色与墨色、蓝色链接、IBM Plex Sans、标题细线和外框 表格。Slate 保留 v1.1.0 色板、Inter/Chakra/Plex Mono 字体角色与 Landing 网格、 光晕。这样为阅读站点提供更安静的默认外观,同时保留明确的兼容选项。代价是默认 外观发生可见变化:原站点可设置 params.ui.preset: slate。1.2.0 发布注记与升级指南已醒目说明此变化。

读者菜单默认关闭(preset_menu: false),文档站开启。一个外观入口包含原生 风格与明暗单选组,手机通过浏览器顶层模态 dialog 显示底部表单。触屏和键盘无需 悬停即可使用。代价是原来单击即切明暗变成选择面板;t 快捷键仍可直接切换明暗。

风格与明暗使用不同的属性和存储键。选择站点默认预设清除风格键。Hugo 在无 JavaScript 时输出默认值,白名单内联脚本在 CSS 前恢复读者选择,避免初始预设 不一致;禁用存储时仍可操作。预设共用一个样式表,代价是增加少量 CSS。

brand 将字标与展示标题分开。Paper 新增本地 OFL IBM Plex Sans 可变字体,包含 正体、斜体和六个小型文字系统子集,按实际使用下载。系统排版与显式字体角色覆盖 仍优先,中文使用系统栈。第一阶段不加入衬线字体,不新增外部字体请求。

密度由页面任务决定:首页保留展示尺度,长文保留阅读行宽,导航与参数表保持紧凑。 不统一扩大间距,不引入第二套外壳或几何抽象。Giscus 和打印跟随预设,API 供应商 组件与图表保持现有的明暗行为,以此约束第一阶段范围。

后续工作

10 月 5 日随后开展的实验在显式配置后提供 Ink 与 Terminal,见 实验记录。两者尚未成为 稳定默认选项。preset_menu: true 提供 Paper/Slate 与站点默认值;显式列表可以 展示实验。四种风格共用简洁的图标与名称按钮,不另加实验标记。这样可用真实主题 输出评审,同时保留普通菜单的 选项范围,代价是额外的局部 CSS,以及开启实验后更大的菜单。

实验以主题自有组件规则实现直角/2 px 圆角与紧凑桌面导航,不引入全局密度框架。 复用现有本地字体、状态管理与无障碍控件。图表和 API 供应商组件仍只随明暗变化, 评论色板与打印跟随实验预设。剩余工作是视觉定稿、更广设备评审,以及是否晋升为 稳定选项的决定。

依据

架构契约与 外壳契约管理当前行为。 check-presets.py 管理 token 对称、AA 色板、冻结的 Slate v1.1.0 色板及严格配置 输出。字体、参数、vendor、命名空间、动作与运行时检查继续沿用原归属。文档站的 appearance.spec.mjs 检查真实输出;带日期验收记录 区分已执行检查与后续实验。

7 - 设计研究

用于形成 OINK 设计决策的带日期的实验与消费站证据,不具备规范效力。
证据,不是契约

研究记录测量了什么、使用了哪些输入与工具版本。它可以解释决策,但不能覆盖当前契约或实现。

只有其他维护者能够检查方法、理解边界并复现相关检查时,研究才适合进入公开 Design 内容树。 原始 Agent 对话、临时构建日志和本机绝对路径不符合这一标准。

研究地图

记录 证据
Goldmark 块属性 支持的 Hugo 下限版本上,渲染钩子能看到什么,以及 CommonMark 容器的边界
消费站与迁移证据 带日期的语料盘点与确定性 Book 迁移结果
2026-08-26 全面审查 实现、配置、输出、安全、测试、性能与文档审查
2026-09-19 社区 Issue 与 PR 调研 侧栏、焦点与搜索反馈的复现、PR 接收建议和解决方案
2026-09-20 OINK 1.1 发布审查 五项运行时修复、文档准备、验证证据与发布边界
2026-09-29 CLI 验收快照 已执行的 Starter、真实站点、离线、升级及可复现归档检查;最终本地验收与公开发布分别记录
视觉预设验收,2026-10-05 Paper/Slate 本地实现、真实输出与有范围说明的浏览器证据
Ink 与 Terminal 实验,2026-10-05 显式实验预设、设计取舍与真实站点验证
OINK 1.2 发布前审查,2026-10-05 本地候选版本最终检查、清理、本地资源、兼容性与发布边界

发布规则

研究记录必须说明日期、输入、相关版本、方法、结果与已知边界。容易变化的数字明确标为快照。 涉及外部框架的比较,公开前要依据一手资料重新核验,并提炼成与 OINK 有关的结论,不能直接 复制成竞品目录。

研究结果成为稳定产品选择后,从已接受的决策链接它;如果它提出的 行为尚不存在,则把设计问题放入提案。

7.1 - Goldmark 块属性实测

Hugo 0.160.1 与 0.164.0 上列表、图片、表格、passthrough、围栏、callout 与嵌套容器的可复现实测。
已验证快照

这些探针在 Hugo Extended 0.160.1 与 0.164.0 上得到字节一致的相关输出。它们解释 OINK 的原生组件形态;当前组件契约仍是权威。

方法

探针使用一个不带 OINK 模板的最小 Hugo 站点。渲染钩子把上下文字段与 .Attributes 输出为 可见标记。站点开启 Goldmark 块属性、行内与块级数学 passthrough 分隔符,以及为检查原始 HTML 而刻意启用的 unsafe 渲染,并设置 wrapStandAloneImageWithinParagraph: false。

每种源码形态分别用兼容下限版本和当时的当前 Hugo 版本渲染,再逐字节比较相关产物。以下结论 记录平台行为,不涉及视觉样式。

结论

源码形态 钩子结果 设计意义
含段落、围栏、callout、嵌套列表并以 {.steps} 结尾的有序列表 class 落在最外层 <ol>,列表项中的富块内容完整保留 Markdown 列表可以成为 Steps 原生形态
列表项内标题 标题保留在 <li> 内,并进入 .TableOfContents 原生 Steps 可以携带可导航标题
以 {.filetree} 结尾的嵌套列表 class 落在最外层 <ul> FileTree 不需要只为保持层级再包 wrapper
独占图片加 {#id num= caption= .class} render-image 收到 IsBlock=true 和全部属性 Book 图可以有原生图片形态
段落中的行内图片 IsBlock=false,图片收不到块属性 行内图片不能使用块级 figure 契约
块级公式加 {#id num=} render-passthrough 收到 block 类型与属性 编号公式可以使用原生 passthrough 形态
表格加 {.fields #id num= caption=} render-table 收到 class 与命名属性 Fields、矩阵、题注和 Book 编号可以共享一个钩子
代码围栏加 {#id num= caption=} code-block 钩子收到属性 围栏本身可以成为编号示例
callout 加 {icon= tab=} blockquote 钩子同时收到 callout 元数据与属性 折叠、标题行内标记、图标和 tab 元数据可以共存
属性行与目标块之间隔一个空行 属性会静默消失 源码检查必须拒绝孤立属性行
两张相邻表分别带 tab= 每个 table 钩子收到自己的 tab 标签 相邻块 tab 机制可以扩展到代码围栏之外

容器边界

Hugo 的 % shortcode delimiter 会把 .Inner 渲染成 Markdown,但模板必须在内部 Markdown 前后各输出一个空行。缺少任一空行时,后续列表可能被当作 HTML block 的字面内容,而不是 Markdown。

把多行 % 容器放进 CommonMark 列表项还有更硬的限制:生成的 HTML 不会随列表内容缩进,列表会在 容器之前闭合,并在容器之后重新开始。因此,当步骤中必须放另一个全量容器时,OINK 仍保留全量 Steps 形态。普通富块、围栏与 < shortcode 不受这一限制。

在相关收集器形态中,嵌套 % shortcode 收到的也是已经渲染好的内部 HTML。需要保留子项原始 Markdown 的收集器应使用 < delimiter,再通过共享的作用域块渲染器处理捕获到的正文。

属性归属

钩子能看到某个属性,并不等于它自动成为公开属性。每个钩子拥有文档明确的白名单。style 与内联 on* 处理器会被拒绝;携带 URL 的值必须经过共享 URL 策略。只有下游 CSS 已属于既有扩展机制的 表面,才保留站点 class。

实验还表明:gallery 列表项中的图片可以被视为块图,却仍不知道父列表带有什么 marker。因此运行时 要么依赖主题显式输出的标记,要么保留一条窄的结构兜底,不能假设图片钩子能看到任意祖先。

边界与验证

这些结果只覆盖 Hugo 0.160.1、0.164.0 与上述 Goldmark 设置。修改设置的站点或未来 Hugo 版本不在 承诺范围内。调整 Hugo 兼容下限时,应先重跑组件、Book、表格、gallery 与 Markdown 输出检查,再更新 这份快照。

7.2 - Ink 与 Terminal 实验,2026-10-05

真实主题输出中的显式实验预设、设计取舍、检查与后续工作。
本地实验,不代表发布

Ink 与 Terminal 现已编入真实主题样式表,使用现有外观控件,不是截图注入样式。 两者仍为需要显式开启的实验,等待视觉定稿。

输入与方法

本实验基于 10 月 5 日工作树中的 Paper/Slate 实现。 工具为 macOS ARM64 上的 Hugo Extended 0.166.0、Go 1.27.1、Node 26.9.0、 Playwright 1.62.1。集成检查使用文档站与同级本地主题;站点公开 pin 仍为 v1.1.0。 这不是兼容下限、CI 固定工具链或线上验收。

首页、配置、提示块与标签页以相同内容比较四套预设、EN/ZH、390/1440 px 和浅深色。 检查真实字体、溢出、外观控件与本地字体请求。进一步的组件检查覆盖代码、参数字段、 Blog、Book、API、Mermaid、ECharts、搜索与打印。沿用站点既有边界,axe 不检查 API 供应商自有 DOM。

设计选择

选择 改善 代价 / 限制
Ink:黑白画布、Inter、红色标记、正文链接下划线与粗标题线 少量装饰即可形成清楚的层级与链接信号 高字重标题与重复分隔线仍需长页编辑式评审
Terminal:等宽控件与标题,无衬线正文与表格,青色链接与琥珀强调 保留段落可读性,同时形成明确的技术界面 长英文导航会更早换行,中文使用平台回退字体
Ink 直角、Terminal 2 px 圆角,组件无阴影 相同内容与布局也能呈现明显不同的表面 局部组件规则增加 CSS,尚非全局间距/圆角接口
只压紧 Terminal 桌面导航 展示更多有效导航行,不缩小正文 密度属于预设设计,不增加新的读者偏好
复用本地字体与状态管理 不新增字体文件、外部字体服务、框架或持久化机制 所有预设 CSS 仍在同一个样式表内
显式实验菜单选项 评审者可即时切换,普通菜单范围保持稳定 开启四张卡片后菜单更高

Ink 使用 #ffffff / #0b0b0b 画布、#141414 / #ededed 正文与 #c8102e / #ff5c4d 强调。Terminal 使用 #f4f5f2 / #0c0f0e 画布、 #1d211f / #d3dbd6 正文、#0a6560 / #4cc9bd 链接与 #935400 / #f0a73a 强调。站点与栏目强调色覆盖仍然优先。 Terminal 的标题标记使用空的无障碍替代文字,不支持的引擎省略标记。首页光标为 静态图形,不引入打字、闪烁、扫描线或发光效果。

试用

params:
  ui:
    preset: paper
    preset_menu: [paper, slate, ink, terminal]
    dark_mode: true

本地文档站已开启此列表。在外观菜单选择 Ink 或 Terminal,再独立选择亮色、暗色或 跟随系统。10 月 5 日菜单修订后,四个选项统一使用图标与名称按钮,不显示实验标记。 站点可以直接将任一实验设为 preset,不依赖读者菜单。preset_menu: true 仍提供 Paper/Slate 与站点默认值,不包含所有实验。选择站点默认预设会清除保存的预设。 字体覆盖、系统排版与 CSS 加载前初始化沿用 Paper/Slate 的契约。

验证

已执行检查 结果与范围
check-presets.py 三类背景的正文/链接/强调色 AA、浅深色 token 对称、建议性背景亮度、冻结的 Slate v1.1.0 色板;七次严格构建、28 个文档根元素
主题检查 参数、字体角色、32 个语言包的 205 个键、生成 schema、组件/输出契约、运行时隔离与命名空间通过;52 个既有输出 golden 未改动
运行时测试 49 项 Node 测试通过
make check 57 项非浏览器测试通过;EN/ZH 覆盖 142/142,Markdown、渲染内容与站内链接检查通过
标准浏览器套件 八套通过 170 项;修复下述默认 Terminal 构建问题后,外观套件 49 项全通过。九套合计 219 项,记录的是首次运行加专项重跑,不是单次连续成功的 make browser
外观覆盖 四预设 × EN/ZH × 390/1440 px × 浅深色,检查首页、配置、提示块与标签页;本地字体请求、菜单 axe、状态、键盘、打印、Giscus 资源;四组实验/明暗检查覆盖 11 类页面与搜索,并检查共享 Mermaid 对比度
字体/配置构建 真实文档站以 Terminal 为默认值重建:系统字体、不带与带显式覆盖,以及 technical 显式字体覆盖,三组均通过
浏览器引擎 Chromium、Firefox、WebKit 在 390/1440 px 下六项通过,覆盖 CSS 前状态、键盘依次选择 Ink/Terminal、持久化与焦点返回;桌面 Chromium 另用 4 倍 CPU 降速
视觉复核 96 张真实输出视口截图,查看了代表性首页、文档与手机菜单;本地对照页按内容、语言、尺寸与明暗选择截图,不注入样式

标准 sitemap axe 检查限定 15 个路径:EN/ZH 首页、配置、提示块、标签页、OpenAPI; 英文搜索、Mermaid、ECharts、Blog 与 /book/04-design/。既有响应式 axe 矩阵另行 运行,这不是全站穷举。标准浏览器检查使用既有 4173 样例服务器;引擎专项使用来源 已确认的同级主题 1313 开发服务器。外观矩阵未观察到外部字体请求。

首次默认 Terminal 字体构建发现建议性背景亮度表漏项,造成强调色对比度误报警。 现已登记两套实验背景,并由检查器断言与显式强调色样例覆盖。修正后仅重跑受影响的 外观套件。新增研究索引和更新的提案描述经逐项审阅后,刷新 LLMS golden 中对应的 两处变化。

实验暴露了两处新增样式问题:全局禁用下划线的规则覆盖了 Ink 链接,Terminal 搜索 选中行的摘要仍使用弱化文字色。两者均作了局部修正。另一个继承问题是 Mermaid 深色 标签(#cccccc 配 #585858,4.43:1),在 Paper 与 Slate 中同样复现。共享的 明暗色板默认标签背景现改为 #404040,作者显式配置仍优先;没有引入预设图表色板。

后续工作

晋升稳定选项前仍需真实 Windows 与 Android 设备评审,包括中文回退字体、下划线、 等宽标题换行与长参数表。人工屏幕阅读器朗读和首屏逐帧截图仍未验证;CSS 初始化 顺序检查不保证每个绘制帧。

Mermaid/ECharts 保留明暗色板,API 组件保留供应商样式;Giscus 检查针对生成的 色板资源,而非远端 iframe。实验没有引入完整几何/密度 token 框架。是否晋升 Ink/Terminal、是否重做图表色板仍待决定。本记录不包含提交、推送、发布、消费站点 升级或部署。

7.3 - OINK 1.2 发布前审查,2026-10-05

本地 1.2.0 候选版本的审查、清理、兼容性、资源来源与出版验证,以及发布边界。
本地候选版本证据

本次审查覆盖 10 月 5 日工作树,包含尚未提交的修改。 它不代表某个不可变发布提交或已发布 1.2.0 模块的验收结果。 公开主题标签与文档站消费版本仍为 v1.1.0。

范围与输入

主题起点为 a1979a4,文档站起点为 ed2d0e3。受检工作树还包括 CJK 关键词 摘要、字面百分号大纲与仓库源文件路径修复,站点既有的英文编辑修改,以及下列 清理。独立可选 CLI 不属于本次主题发布范围。没有打标签、推送、升级消费站或部署。

多数检查使用 macOS ARM64 上的 Hugo Extended 0.166.0、Go 1.27.1、 Node 26.9.0 和 Playwright 1.62.1。选定兼容性检查使用经校验和验证的官方 Hugo Extended 0.160.1、0.165.0 二进制。这些是本地结果,不是完整 Linux CI 工具链的复跑结果。

审查发现与清理

发现 修正 影响
1.2 发布草案遗漏新默认值与外观控件 同步两种语言的发布草案和升级说明,补充 Paper、Slate 兼容配置、独立持久化、当前状态图标及实验预设选择 读者升级前能明确看到外观变化
部分当前提案、决策、实验记录与源码注释仍描述字母预览、实验标记、独立 Default 卡片或未定发布版本 当前说明对齐紧凑图标/名称按钮、站点默认值恢复与 1.2 发布准备;保留有日期的历史测试证据 当前指南与已接受界面一致,不改写历史结果
工作树的一条忽略规则屏蔽站点整个 tests/,仅放行两个文件 删除宽泛规则,保留已有生成产物排除项 新增回归测试正常出现在 Git 中;没有删除测试或构建产物
开发预览不会暴露仅生产环境加载的统计服务 检查严格生产产物,区分核心本地资源与显式配置服务 本地优先承诺具有可观测边界

这些清理没有要求新增运行时修改。工作树原有运行时修复由各自检查器及最终集成 测试覆盖。

已执行验证

本地候选版本通过下列技术性发布前检查,在受检范围内没有发现阻塞发布的主题 缺陷。数字均为本次工作树审查的带日期快照。

检查 结果与范围
预设检查器 通过:7 次告警即失败的配置构建、28 个文档根节点、浅深色变量对齐、三类表面的文字/链接/强调色 AA 检查及冻结的 Slate v1.1.0 基础色板
运行时测试 49 项 Node 测试通过,覆盖当前状态图标、搜索摘要、大纲跟踪、剪贴板与对话框焦点
主题回归与工具检查 40 项检查器/工具命令通过,包含 90 项迁移测试、快照/消费站安全与现有产物 golden;随后指定浏览器复跑 PDF 检查,3 项隔离测试全部通过
文档检查 最终 make check 的 57 项测试通过;检查 143/143 份双语文件、1,197 个源标题、228 个渲染内容页及站内链接;Markdown golden 仅按审阅结果更新新增研究索引条目及发布标题/描述
标准浏览器套件 一次完整 make browser 运行的 9 个套件、219 项检查全部通过,包含 372 个路由的完整 sitemap axe 扫描;无失败、不稳定或跳过项
文档补充检查 用新构建单独扫描 14 个修订后的中英文路由,包含本报告新增双语页面,axe 检查通过;这补充了之前的完整 sitemap 扫描
浏览器引擎 Chromium、Firefox、WebKit 在 390/1440 px 的 6 项外观检查通过;覆盖 CSS 前状态恢复、键盘选择、持久化与焦点返回;桌面 Chromium 还使用 4 倍 CPU 限速
视觉抽查 查看本轮真实产物截图:中文移动端 Paper 菜单、英文桌面深色 Paper 菜单,以及中文 Terminal 移动/桌面阅读页;确认两列图标/名称选项、当前状态图标与阅读布局
Hugo 兼容下限 0.160.1 通过预设及阅读/数学检查器,以及真实文档站严格压缩生产构建
CI 使用的 Hugo 版本 0.165.0 通过真实站点严格压缩生产构建、Hugo Module/include/static/print 检查、系统字体、旧 Sass 字体覆盖,并按预期拒绝非法字体预设
生产资源 四套风格、七类路由共 28 次访问;核心字体与脚本来自站点自身 origin,显式外部服务另行记录
生产产物安全 按已记录的第三方集成策略,最终严格生产构建的 921 个文件检查通过
Book 出版 根路径与子路径 EPUB 均通过主题检查器及 EPUBCheck 5.3.0,零错误、零告警;两份 PDF 通过 23 页、5 章结构检查;根路径 PDF 脚本隔离探针通过
已发布消费版本 禁用环境替换及两个 workspace 后,既有 v1.1.0 解析与站点 release-pin 检查通过;这不是已发布 v1.2.0 的验证

完整 sitemap 扫描沿用站点现有 axe 策略:检查 OINK 维护的界面,阻断 Giscus 请求,排除 Swagger UI/Redoc 的供应商 DOM。结果不代表这些组件自身的无障碍 验收。响应式检查覆盖 360、768、820、1024、1200、1440 px,以及中英文、浅深色。

外观检查在四套预设、中英文、390/1440 px、浅深色下使用相同首页、配置、提示块 与标签页内容;也覆盖搜索、代码、表格、输入/焦点状态、Blog、Book、API、图表 与打印。Ink、Terminal 仍需显式选择,测试通过不等于把实验提升为稳定预设。

出版使用本地 Pandoc 3.11、Java 26 和 Chrome headless-shell 151.0.7922.34。 第一次使用完整 Chrome for Testing 应用时在本机超时。像 CI 一样显式选择 headless-shell 后,生成的 PDF 通过验证。结果不代表所有 Chrome 安装均兼容; CI 在 Linux 上固定 Pandoc 3.10 与 Java 21。

本地优先的资源边界

IBM Plex Sans、Inter、IBM Plex Mono、Chakra Petch、图标、KaTeX 字体与 核心浏览器库均已本地化。预设切换没有引入运行时字体服务或 CDN 脚本依赖。 系统字体模式与显式字体角色覆盖保留其约定优先级。

生产审计在每套预设下访问首页、中文配置、数学、Mermaid、Markmap、ECharts 及 OpenAPI,再切换浅深色。测试保留生产 base origin,由本地产物提供响应。 请求追踪记录并阻断跨 origin 请求;本地字体与图表仍加载成功,没有未捕获 JavaScript 异常或本地 HTTP 错误。

两个已配置服务会请求外部脚本:Giscus 与 Google Analytics。Giscus 是已接受的 可选评论集成,其 OINK 色板文件来自本地。文档站原本配置了统计 ID,因此生产 产物包含 Google Tag Manager 脚本。二者都不是新预设的必要依赖。本次保留 这些配置,文档站因此不作“零外部请求”的承诺。作者引用的远程媒体与显式选用的 图表服务也保留既有可选边界。

复现检查

先运行主题归属检查,再检查真实站点。以下命令通过约定的 Make 目标选择同级 主题,不能把文件系统模块替换提交进仓库:

python3 bin/check-presets.py
node --test 'tests/js/**/*.test.js'
make -C ../oink.pgsty.com check
env -u A11Y_PATHS -u PLAYWRIGHT_BASE_URL make -C ../oink.pgsty.com browser

完整主题检查器与出版命令定义在 .github/workflows/ci.yml。用新构建的 fixture 运行所有归属检查,覆盖参数/Schema、vendor/字体、导航/搜索/操作、组件、 产物/命名空间/golden、迁移、快照保护、消费站工具及 PDF 隔离。 文档站的独立引擎套件为 npm run test:appearance:engines。

兼容性检查将选定 Hugo 二进制放入 PATH,禁用继承的 Go/Hugo workspace, 并明确同级模块替换。真实站点用 --environment production --minify --printPathWarnings --panicOnWarning 构建到独立输出目录。检查已发布 pin 时, 还须禁用模块替换;两者是不同验证目标。

剩余发布步骤与边界

本地技术性发布前验收通过。正式发布仍需把受检修改整理为提交, 在这些精确提交上运行 CI,发布标签及模块归档,完成消费站采用与托管验证。 仅修改版本号不能替代这些步骤。发布说明仍为草案,既有消费站 pin 没有改变。

尚未验证真实 Windows/Android 设备上的字体表现、人工屏幕阅读器朗读与首绘 逐帧画面。Windows 源文件路径行为使用确定性 fixture 验证,没有使用 Windows 主机。Ink/Terminal 设计后续项仍见 实验记录。

7.4 - 视觉预设验收,2026-10-05

Paper 与 Slate 的本地验证、真实主题输出,以及注明范围的浏览器证据。
仅为本地证据

本记录针对同级主题 checkout 的真实输出,没有注入原型样式;不代表发布版本、 升级消费站点或验收线上站点。

输入

2026-10-05 的主题与文档站工作树;macOS ARM64,Hugo Extended 0.166.0、 Go 1.27.1、Node 26.9.0、Playwright 1.62.1。常规浏览器套件使用 Chromium; 另有 Chromium、Firefox 与 WebKit 专项检查。站点仍固定 v1.1.0, make check、make browser 与 make dev 使用同级本地主题,公开 pin 未修改。 本轮不是 Hugo 0.160.1 下限或 CI 固定工具链验收。

已执行检查

证据 结果与范围
check-presets.py Paper 明暗 token 对称与正文、链接、代码、铜色 AA 对比度;冻结的 v1.1.0 Slate 基础色板;四种严格配置构建与 16 个 HTML 根元素,包括 404 和打印
现有主题检查器 参数、字体角色、vendor 清单、32 个语言目录、动作、外壳、输出、命名空间、Landing 和运行时隔离均通过;生成的 schema 与源码一致
check-goldens.py 52 个表面通过;已审阅并更新根属性、首绘颜色、菜单及其动作与运行时影响的 34 份 HTML/打印期望,其他输出格式未变
严格站点构建 真实本地主题中英文站以 --panicOnWarning 构建成功;翻译、渲染 Markdown 和站内链接检查通过
node --test 'tests/js/**/*.test.js' 49 个运行时测试通过
appearance.spec.mjs 25 个测试通过:Paper/Slate × EN/ZH × 390/1440 px × 浅深色,覆盖首页、配置长文、提示块和标签页;菜单 axe、键盘、持久化、恢复默认、跨语言导航、跨标签同步、禁用存储、非法值、无 JS、打印、命令面板、阅读锚点与断点处理、生成的评论样式表
appearance-engines.spec.mjs 6 项通过:Chromium、Firefox、WebKit × 390/1440 px;CSS 前恢复状态和浏览器栏颜色、原生键盘选择、焦点返回及跨语言导航。Chromium 桌面另加 4 倍 CPU 限速
字体请求 观测到的字体均来自本地;Paper 不请求 Inter,Slate 不请求 Plex Sans。两次真实文档站配置覆盖构建证明系统排版不请求内置文字字体,显式字体角色可覆盖两套预设
make check 完整非浏览器套件通过:57 个测试、141/141 篇翻译页面,以及既有 Markdown、渲染内容与站内链接检查
make browser 九个常规套件共 197 个测试通过;sitemap axe 扫描限定为下述 15 条路由
视觉抽查 已检查真实 Paper 桌面首页、手机 Docs 长文、中英文浅深色外观面板,以及 Slate 深色首页;截图来自浏览器测试,不是样式注入原型

浏览器套件的 sitemap axe 扫描通过 A11Y_PATHS 限定为 15 条代表性路由:中英文 首页、配置、提示块、标签页与 OpenAPI,以及英文搜索、Mermaid、ECharts、Blog 和一个 Book 章节。另运行现有响应式 axe 矩阵。跨域 Giscus 与 API 供应商组件 DOM 沿用既有排除规则,本轮不是全量 sitemap 扫描。

整合检查发现并修复了 Paper 深色高亮代码行的行号对比度,以及平滑滚动干扰阅读 锚点恢复的问题。章节强调色测试现在分别断言 Paper 的暖色不透明选中底和 Slate 原有的半透明选中底。

限制与后续检查

手工读屏播报和逐帧绘制追踪尚未验证。阻塞样式表及 CPU 限速断言验证初始化顺序, 不等同于证明所有浏览器的首个绘制帧。Slate 比较冻结基础色板并检查渲染字体行为, 不宣称包含其他 1.2 改动后的所有组件与 1.1.0 像素等价。

Mermaid/ECharts 继续仅随明暗。Ink 与 Terminal 仍为研究;衬线展示标题、完整 几何与密度 token、图表随预设配色留待后续。本轮没有创建发布标签、推送、跨站 升级或部署。

7.5 - 消费站与迁移证据

塑造 OINK 外壳、创作原语与确定性 Book 迁移策略的定期语料快照。
带日期的语料快照

这些计数描述 2026 年 8 月被检查的仓库。它们是设计选择的证据,不是实时产品指标或兼容承诺。

语料

创作语料盘点扫描了十一个 OINK 消费站点的 content/ 树:共 5,325 个 Markdown 文件,其中 5,293 个带 YAML front matter。样本同时包含单语言英文与中文参考站、双语产品站、发布归档、 自定义落地页,以及独立的 Book 消费站。

盘点刻意测量源码 Markdown,而不是生成后的 HTML。统计项包括 shortcode 调用、代码围栏属性、 callout、表格 marker、原始 HTML、front matter 键、内容类型与站点自有 layout。随后针对五个 长篇内容消费者又做了一轮 Book 专项盘点。

改变设计的结论

证据 形成的选择
内容从近乎纯 Markdown 到大量嵌套组件同时存在 原生 Markdown 是默认形态;只有明确能力缺口才保留全量形态
文档、Blog、Landing、发布与书籍反复在站点侧重做导航或卡片 延长共享外壳、注册表和内容原语,不增加并行系统
站点自有表格 class 很常见,匹配 canonical Fields 表头的表格却很少 钩子属性使用白名单,但保留文档明确的站点 class 扩展点;不能从任意二列表格猜测 Fields
Book 站各自拥有图、表、公式、示例和交叉引用约定 编号原语与迁移 profile 必须确定性分类、保留稳定 ID,并验证渲染目标
站点同时存在单语言、对页双语和生成式语言内容 必须明确语言权威与生成边界;迁移不能把未跟踪的生成树当作源码
富 HTML 页面仍要提供 Print、Markdown、订阅源和 Agent 输出 接受交互 HTML 之前,每个组件先声明所有输出中的降级行为

证据也否决了若干看起来诱人的新增项:文档站不足以支撑第二套 Landing 系统;Book 站不需要新封面 组件;连载归档不值得增加独立 shell type;远程 API 采集属于站点侧 CI,而不是承诺本地构建的 Hugo 主题。

块与表格证据

针对十一个站点与 Book 消费者的专项盘点共发现 11,484 张 pipe table。只有 11 张已经匹配严格的 Fields 表头词汇,约 874 张属于参考型表格,约 1,300 张属于兼容矩阵。因此 OINK 采用显式 .fields 与 .matrix marker,不按表格形状猜测语义。

同一轮盘点在十一个站点中发现 18 个 Steps 块,它们都使用带标题和富内容的全量形态。平台探针表明, 原生有序列表可以承载其中大多数内容,却不能在列表项内安全容纳另一个全量 % 容器。因此 OINK 保留 两种形态是为了技术能力边界,而不只是书写偏好。

确定性 Book 迁移

三个带日期的干跑 profile 用于证明迁移规则能解释每个被识别的来源,而不编造语义:

Profile 快照 分类结果 人工边界
DDIA v2 106 张图、3 张表、22 个代码示例,相关 304 条链接全部入账 1 条题注链接降级为可见文本,无未解释跳过项
DDIA v1 90 张编号图与 203 条匹配引用 14 张装饰性或无编号图片刻意不处理
TPME 31 张图、10 张表、44 条编号引用与 1,018 条通用稳定引用 被识别项目零跳过
私有 Book profile 119 张图、5 张表与 136 条编号引用 3 张歧义图片保留人工复核

每个 profile 都先干跑,只在歧义边界明确后写入;第二次执行变更数为零;随后以警告即失败的模式 构建,并通过渲染后的 kind、编号和锚点检查。公开迁移工具与当前 profile 边界见 创作书籍和 迁移契约。

出版采纳快照

2026-08-24 的隔离验证让两个消费站运行了已发布的通用 Book 出版链路:

消费站 通用出版证据 下游状态
DDIA 23 个有序页面、131 个带类型目标与 292 条已解析交叉引用;EPUBCheck、内部检查与 PDF 检查均通过 该快照中仍保留语义预处理器,等待消费站独立接受新的门禁
TPME 18 个有序页面、41 个带类型目标与 1,062 条已解析交叉引用;同一套通用检查通过 第二个消费站证明了可移植性,没有形成上游迁移门禁

这是下游采纳证据,不是尚未解决的上游设计边界。

边界

这些数字不能直接用于产品宣传,也不能当作当前站点清单。重做研究时,需要重新确定仓库清单并生成 新的带日期报告。本公开记录刻意排除了本机路径、未提交内容、私有仓库名称、原始 Agent 对话与生成 构建产物。

7.6 - OINK 全面审查(2026-08-26)

对 OINK v0.7.0 后主线的实现、配置、输出、安全、测试、性能、双语契约与真实站点所做的证据化全面审查。
审查快照,不是新契约

本文记录 2026-08-26 对 github.com/pgsty/oink 主线与本站集成面的审查证据。 它不会改变既有 API,也不表示文中建议已经实现。当前行为仍以 Design 契约、实现与 owning checker 为准。

其中一部分已被 OINK 0.7.1 取代。 F01–F06 这些代码问题已在该版本修复,见 0.7.1 发布说明。下面的发现应当读作促成修复的证据,而不是主题当前的状态。

审查结论

OINK 的主干质量明显高于一般 Hugo 主题:默认路径可构建、双语完整、组件测试广、输出与安全意识强, 真实站点在桌面、移动端、深浅色和无障碍主路径上没有发现普遍性崩坏。当前 main 与远端一致, 主题 CI 和本站 CI 都是绿色;本次重新执行的主题检查、迁移单测、浏览器单测、全站链接、 Playwright 与 axe 也全部通过。

但「全部绿色」不能等价为「契约全部成立」。本次审查发现 4 项 P1、9 项 P2、5 项 P3。 最重要的共同原因是:项目已经建立了一套很强的原则,却仍有若干早期/边缘实现没有接入这套原则; 而现有门禁主要证明已选中的正向场景不回归,不能系统发现配置空间、静态输出和公开文档的语义漂移。

建议在下一个版本标签前至少完成以下四项:

  1. 关闭 Swagger UI 默认在线 validator,并用非 localhost 的浏览器请求测试锁定「零隐式外联」;
  2. 把所有公开配置和 Landing 数据纳入统一的类型、范围、URL 与 CSS 值验证;
  3. 重做 Swagger、Redoc、Asciinema 的 HTML/Print/Markdown/RSS 降级和 runtime gate;
  4. 修复生成 Schema,并让公开配置/Front matter 参考重新与当前实现对齐。

基线与方法

审查基线

项目 快照
主题仓库 main = fe439fdb1d7c2df745088c9bfcbb8c350403ee63,工作树干净,与 origin/main 一致
当前稳定标签 v0.7.0 = cbb6f4e0bfe47e17ba7aa41d04b8651c943cf858
文档站仓库 main = fd5fcde,工作树干净,公开 pin 为 github.com/pgsty/oink v0.7.0
本机工具 Hugo Extended 0.164.0、Python 3.14.6、Node 26.4.0、npm 11.17.0
远端 CI 主题 HEAD 的 GitHub Actions run 32792753866 成功

实际执行的验证

  • 31 个主题 checker 全部通过;
  • 85 个迁移单测全部通过;
  • 38 个主题浏览器运行时单测全部通过;
  • 40 个 HTML/Print/Markdown/RSS/LLMS golden 表面通过;
  • tests/site 严格 Hugo 构建通过;
  • 真实双语站点的 npm test 通过:121/121 中英页面配对、886 个标题 ID、24,860 个站内链接与 3,172 个 fragment 均通过;
  • 真实站点的完整 Playwright 套件通过:全站 sitemap axe 扫描、29 个无障碍场景、45 个响应式/ 导航场景、16 个键盘场景、10 个内容组件场景、18 个代码块场景、4 个 PRD5 场景与 5 个主题色场景;
  • 额外在 320 CSS px 下人工检查 EN 首页、ZH 配置页、ZH Book 页、OpenAPI/Redoc 页,未发现页面级水平溢出;
  • npm audit 对本站 79 个 npm 依赖报告 0 项漏洞;对 VENDOR.json 的 26 个精确 npm 版本调用 OSV Query API 未返回已知公告;
  • measure-baseline.py assets --fixture-site 的严格隔离构建通过。

判级

级别 含义
P1 违反核心产品承诺、安全/隐私边界或普通编辑可用性;应在下一标签前修复
P2 明显功能/契约/兼容性缺陷;短期内修复并增加行为门禁
P3 维护性、性能、流程或文档治理债务;排入结构化改进

发现摘要

ID 级别 发现 默认站点是否受影响
F01 P1 Swagger UI 在生产 URL 上默认启用在线 validator 仅使用 swagger 的页面
F02 P1 多组非法配置会让普通 Hugo 直接失败或静默生成坏输出 取决于配置输入
F03 P1 Swagger/Redoc/Asciinema 违反静态输出和 runtime 隔离契约 使用这些 shortcode 的页面
F04 P1 Landing 将未验证数据送入 safeCSS,其它错误值静默通过 使用相关 Landing 字段的页面
F05 P2 自定义页面动作与归档版本 URL 绕过共享 URL 策略 配置这些可选项的站点
F06 P2 生成 JSON Schema 的默认值、类型、描述和候选键存在实质错误 使用编辑器 Schema 的作者
F07 P2 「完整」配置与 Front matter 参考大量落后于 v0.7 实现 全部维护者/消费站作者
F08 P2 Design 契约与提案生命周期内部出现双重答案 维护者
F09 P2 OpenAPI 无障碍缺口被测试排除,Redoc 推荐与实测不一致 OpenAPI 页面读者
F10 P2 严格 CSP 文档没有覆盖主题自己的 inline script/style 启用严格 CSP 的站点
F11 P2 浏览器兼容性没有公开基线,自动化只跑 Chromium Firefox/Safari/RTL/强制色用户
F12 P2 输出安全与「Rendered Markdown」门禁存在系统盲区 依赖门禁判定安全/输出纯度的站点
F13 P2 跨仓库真实集成仍是人工、非原子的发布步骤 每次公共行为改动
F14 P3 checker 体系重复且过度依赖源码字符串 维护者与并行工作树
F15 P3 全局 CSS/字体仍是首访主要负担 全部 HTML 页面
F16 P3 vendor 完整性强,但漏洞/SBOM 与 CI 供应链门禁不足 发布维护者
F17 P3 Changelog、已实现提案和无行为元数据造成治理噪音 维护者与升级读者
F18 P3 Print isHTML 的 FIXME 已不能准确说明真实依赖 Print 模板维护者

详细发现

F01 — Swagger UI 会隐式联系在线 validator(P1)

证据。 layouts/_shortcodes/swagger.html 初始化 SwaggerUIBundle 时没有声明 validatorUrl: null。随主题内置的 swagger-ui-bundle.js 把默认值设为 https://validator.swagger.io/validator;它只对包含 localhost 或 127.0.0.1 的 spec URL 跳过在线校验。部署到真实域名后,Swagger UI 会创建在线 validator badge,请求参数包含 spec URL。

影响。 这违反「主题自有网络功能默认关闭」「本地优先」「同源 spec 在浏览器中不访问外部服务」三项承诺。 内网站点尤其会把内部主机名/spec 地址暴露给第三方。由于上游特意跳过 localhost,当前所有本地浏览器测试都看不到它。

建议。 初始化时显式写 validatorUrl: null。若未来允许在线 validator,应做成明确 opt-in 的 URL 配置, 走共享 URL 验证并在隐私/CSP 文档中说明。浏览器测试应使用一个非 localhost 的虚拟 origin,拦截全部请求, 断言同源 spec 页面只请求首方资源。

F02 — 非法配置没有统一 warn/fallback,甚至击穿普通预览(P1)

ui-param.html 明确写着「caller validates the type」,但多个 caller 没有验证。最小复现得到:

输入 实际结果
ui.blog_index_size: nope 普通构建失败:.Paginate 要求正整数
ui.sidebar_expand_levels: nope 普通构建失败:add 无法处理字符串
ui.sidebar_menu_truncate: nope 普通构建失败:first 无法转成整数
offline_search_summary_length: nope 普通构建失败:truncate 无法转成整数
ui.sidebar_width_min: "1; color: red" 零告警成功,输出 --td-shell-sidebar-min: ZgotmplZpx
ui.sidebar_width_min: -50 零告警成功,输出 -50px
blog_index_columns: 2.5 / section_index_columns: 2.5 零告警成功,把 2.5 送入 CSS repeat()
ui.sidebar_item_overflow: clip 零告警成功,静默当成 ellipsis
ui.sidebar_menu_foldable: definitely 零告警成功,非布尔字符串按 truthy 启用
ui.blog_index_size: 0 被 Hugo default 静默吞掉,回到 12

Landing 的 marquee.rows、capabilities.columns 和 Asciinema 的数字参数也直接调用 int/float, 错误文本会终止模板执行。print.toc、offline_search_max_results 等错误类型则静默改变行为。

影响。 这是对 Diagnostics decision 的直接反例:普通 hugo server 可能整体不可用,而错误输入也可能在 --panicOnWarning 下零告警上线。

建议。 为整数、正整数、范围、成对范围和 CSS grid count 增加共享 validator;先归一化再参与运算或输出。 每个公开键至少需要四态用例:合法站点值、合法 page override、非法普通构建(warn+fallback)、非法严格构建(失败)。 对 min <= max、分页大小 >= 1、列数为合理整数等交叉约束加领域 resolver,不要依赖浏览器吞掉坏 CSS。

F03 — OpenAPI 与 Asciinema 仍是 HTML-only 岛(P1)

Architecture/Components 规定 Markdown/LLMS 不含 td-* 组件标记,Print 静态展开且不依赖交互,RSS 只保留安全静态内容或明确省略。 但当前实现与公开示例表明:

  • redoc 在生成 .md 中原样输出 <style>、<div class="td-redoc"> 与 <redoc spec-url=...>;
  • swagger 把可执行 inline initializer 直接写在 shortcode 中;
  • asciinema 的 .md 输出包含整套 td-asciinema HTML 与 JSON script;
  • Asciinema 的 Print 仍加载约 185 KB 的 player JS/CSS,只能碰巧打印某一帧;
  • Swagger/Redoc 在 Print 里留下空容器,并仍可能装载 1–2 MB runtime;
  • 这些 shortcode 没有进入 Markdown/RSS/Print golden 矩阵。

影响。 Agent 输出被主题 HTML 污染;纸面/EPUB 读者拿到空壳;Print/PDF 负担无意义的大 runtime; Swagger inline script 也破坏 CSP。当前用户文档把这些缺陷写成「输出形态」,等于让 reader guide 与规范契约相互否定。

建议。 三者都先读取 tdOutputFormat:HTML 输出完整组件;Print/Markdown/RSS 输出一个有标题的静态链接、 spec/cast 地址与必要的文字说明,或者明确省略。只有交互 HTML 才设置 capability flag。Swagger initializer 应移入稳定 chunk, Redoc 的样式移入 stylesheet,新增四输出 golden 与 runtime-absence 断言。

F04 — Landing 的 CSS/URL/数值入口没有同一安全边界(P1)

layouts/_partials/landing/sections/hero.html 对 title_size 做了 CSS 长度验证,却把 media.ratio 与 media.max_width 原样拼进字符串,再整体 safeCSS。最小输入:

sections:
  - type: hero
    data:
      title: Probe
      image: /icons/logo.svg
      media:
        ratio: "1fr; background-image: url(https://example.invalid/x)"
        max_width: "240px; color: red"

普通和严格构建均零告警,输出:

style="--td-hero-columns: 1fr; background-image: url(https://example.invalid/x);
       --td-hero-media-max: 240px; color: red;"

Landing 允许把 sections 直接写进 front matter,因此这不是只属于仓库管理员的内部常量。 其它 section 的 columns、rules、宽高、style、icon 与 URL 也各自处理;非法 javascript: 通常被 Go template 变成 #ZgotmplZ,但没有 warning,严格门禁仍通过;字符串列数会变成 ZgotmplZ,某些 int 转换则直接终止构建。

建议。 为 Landing 建立一层 section schema/normalizer:所有类型共享 class、icon、URL、CSS length、grid count、 boolean、enum 解析;section partial 只消费规范化结果。hero.media.ratio 应是两个受限 track 值而不是任意 CSS 片段, max_width 走 CSS length validator。所有 link/action 复用 content/url.html,并给每种 section 一个负向用例。

F05 — 两个配置 URL 面绕过共享策略(P2)

params.ui.page_context_menu.links 经 url-template.html 替换占位符后直接 safeURL; url_latest_version 也被当作「trusted site configuration」直接 safeURL。它们没有检查 scheme、host、空白或 protocol-relative URL。

最小配置可零告警产出:

<a class="td-page-actions__item"
   href="javascript:document.body.dataset.pwned=1;undefined">

点击该 URL 会执行 JavaScript。站点配置本身是高信任输入,因此这不是默认远程攻击面,但它与公开的「safe URL」配置模型不一致, 也让复制来的配置片段拥有不必要的执行能力。

建议。 自定义动作只允许 http/https 与明确支持的站内相对 URL,并复用 content/url.html; 归档版本 URL 也应验证。浏览器 action registry 的二次检查值得保留,但 progressive-enhancement 的 <a> 不能绕过它。

F06 — 生成 Schema 与真实 YAML 不一致(P2)

generate-config-schema.py 的小型 YAML parser 不剥离行尾注释,至少 11 个默认值被生成成字符串,例如:

  • print.toc 的默认值是字符串 "true # ...",不是 boolean true;
  • print.section_break_wordcount、section_index_columns、blog_index_columns 变成字符串;
  • footer_style、blog_index、typography 的 enum 默认值包含注释正文。

注释关联也会漂移:解释「breadcrumb 没有全站默认」的注释被挂到 section_index;解释 quick_links 的注释被挂到 sidebar_icon_policy;taxonomy icon 注释被挂到 pager_types;本地 chrome 注释被挂到 image_zoom。

Front matter Schema 还会把探测器读到的已移除键 release、upstream_attribution、downstream_modified 暴露给编辑器, 并把 navbar menu 的 Params.columns 误判成 page front matter。--check 只比较「同一个有 bug 的生成器」与已提交产物, 所以会稳定地保持错误。

建议。 不要继续扩展 ad-hoc YAML parser。使用能保留注释的正式 parser,或为默认值/描述建立显式机器元数据标记; scanner 需要区分 page、menu、shortcode 和 legacy detector 上下文。生成测试必须拿 Schema 默认值与 Hugo 实际解析值逐项比对, 并维护「禁止出现在补全中的已移除键」列表。

F07 — 配置与 Front matter 参考不是当前实现的完整参考(P2)

content/docs/customize/config.md 与 content/docs/write/frontmatter.md 都自称「每个主题实际读取的键的唯一完整参考」, 但当前存在多类实质错误:

  • 日期默认仍写成长英文日期,而 hugo.yaml 已是 ISO 2006-01-02;
  • Blog 只写 none|banner|wash 和 list|cards,遗漏 hero、table、toggle、size、toc_style、toc_taxonomies;
  • Front matter 仍把已移除的 release map、release_products、release_group_by_product 当现行 API,遗漏 release_url;
  • images: [] 被写成「没有 featured image」,但契约明确 bundle resource discovery 仍继续;
  • upstream_modified 被写成新增一行,而现行契约是改变 credit verb,不新增行;
  • 大量页面说非法参数「直接失败」,与 warn/fallback decision 混在一起,普通预览与严格发布门禁没有说清;
  • Book guide 仍说主题止于 Print HTML,而 v0.7 已发布 BookManifest、EPUB 与 PDF 工具;
  • Asciinema/OpenAPI guide 将污染静态输出的现状写成产品契约;
  • Features 页仍写 28 个 vendor 依赖,权威清单是 26 个。

中英文在这些旧答案上通常保持一致,所以 translation parity 不会报错。

建议。 先把配置参考与 Front matter 参考作为一次专门的契约迁移处理;从实现/Schema 生成一份可比对的 key inventory, 人工维护语义文字。发布门禁应检查:现行键全部出现、removed 键只出现在迁移章节、enum/default 与 hugo.yaml/resolver 一致。

F08 — Design 树出现互相冲突的权威和未退休提案(P2)

最直接的矛盾是:Shell 契约声明 navbar columns/mega panel 已退役、配置会 warning 并保持单列; Landing 契约却仍声明「Navbar mega-menu columns accept 1–4」。实现与 checker 支持前者。

提案生命周期也没有按自己的规则执行:config-schema 已标记 implemented,仍位于 Active proposals; Book publication 已把 manifest、EPUB、PDF 和 CI 做完大半,却仍以 Draft proposal 与正式 Architecture contract 重复描述; media-convergence 把已实现里程碑和未完成 M4 混在一份原始设计记录中。

建议。 修正 Landing 契约;把已实现的 config-schema 稳定事实移到 Architecture/Decision 后退休提案; Book proposal 只保留尚未完成的 consumer migration 问题,或拆成新的窄提案。Active proposal 中不应存在第二份现行 API。

F09 — OpenAPI 无障碍承诺与测试排除项不一致(P2)

本站 axe 套件明确排除 .td-swagger-ui 和 .td-redoc。注释记录的已知问题包括 Swagger UI 的无名称 server select、 不可键盘访问的 scrollable version stamp,以及 Redoc operation description 的颜色对比度。

OpenAPI guide 却只公开 Swagger 的问题,并把「真正渲染的 Redoc」作为替代;这会让读者误以为 Redoc 满足本站的零违规门禁。

建议。 立即在 EN/ZH guide 中公开两者的真实边界。短期可通过主题 CSS 修复可修的 Redoc contrast, 对 Swagger 的可修 DOM 用 narrow post-render adapter;不能修的上游问题应有版本化 waiver、issue 链接和单独 axe 报告, 而不是把整块 DOM 排除后仍称全站零违规。

F10 — 当前主题不能直接配合严格 CSP(P2)

部署指南说同源资源使 strict CSP 可行,却只列作者 inline script、ECharts callback、analytics、远程 spec/diagram 和 Giscus。 主题自身在普通 Docs 页就输出两段可执行 inline script(颜色首绘与 shell prepaint)和 inline style;Markmap、Swagger、Algolia、 Google CSE 还增加主题自有 inline initializer。项目没有 nonce 参数、hash manifest 或完整的 CSP 示例。

影响。 script-src 'self' 会阻止主题自己的首绘与 shell 状态恢复;style-src 'self' 会阻止主题色、字体角色、Landing 和多个 inline custom property。站点只能加 'unsafe-inline'、自行维护 hash,或覆盖模板;当前文档没有说清。

建议。 把稳定初始化逻辑移到同源外部 chunk,以 data/JSON 传递页面配置;剩余必须 inline 的内容提供可生成的 CSP hash 清单, 或统一 nonce hook。文档应给出「最小核心」「带 Markmap/OpenAPI」「带第三方集成」三套策略,并明确 style-src 需求。

F11 — 浏览器兼容性承诺缺少基线与跨引擎证明(P2)

Playwright CI 只安装 Chromium;仓库和产品文档没有写最低 Chrome/Firefox/Safari 版本。 但实现依赖或增强使用 :has()、dialog、inert、color-mix()、@property、logical properties、 discrete display transition 等新能力。部分功能有 fallback,但没有一个浏览器矩阵证明它们。

RTL 主要依靠源码 marker、少量 JS 单测和一个临时给元素设置 dir=rtl 的几何测试;没有完整 RTL 语言站。 forced-colors 多数只检查 SCSS 中是否出现字符串,没有浏览器 computed-style/交互测试。

建议。 发布一个小而明确的支持矩阵,并至少对核心 shell/导航/内容/对话框跑 Chromium + Firefox + WebKit。 增加一条真正 languageDirection: rtl 的集成配置,以及 forced-colors、reduced-motion、320px、200% zoom 场景。

F12 — 输出安全和 Markdown 门禁没有检查自己宣称的全部表面(P2)

check-output-security.py 对 .md 只匹配 Markdown link 语法,不把其中 raw HTML 送入 HTML scanner; 因此 Redoc/Asciinema 的 <script>、spec-url 与 raw href 不会被发现。它也不检查 style 中的 url()、JSON config 中的 URL, 而 theme fixture 以全局 --third-party 运行,降低了第三方元素检查的区分度。

本站的 check-rendered-markdown.mjs 名字也容易误导:它扫描的是生成 HTML 的文本节点里是否残留 Markdown 标记, 并不读取生成 .md。真正的 md-output golden 只有 15 个页面,未覆盖 OpenAPI/Asciinema。

建议。 将门禁拆成三个明确工具:HTML trust、machine-output purity、rendered-text residue。 .md 中允许的 raw HTML 应有极窄 allowlist;CSS URL、form/action、JSON URL 与非可执行 JSON script 需要分别解析; 每个 public shortcode 至少进入一个 Markdown/Print/RSS 行为用例。

F13 — 两个仓库之间没有自动的候选提交集成门禁(P2)

主题 CI 只对 tests/site 合成夹具运行;文档站 CI 则只测试 go.mod 固定的公开标签。 主题 PR 的真实 EN/ZH/Playwright 验证依赖维护者本地执行 HUGO_MODULE_REPLACEMENTS,两个仓库的变更也无法原子提交。

这次的结果说明两边可以分别全绿,而公开参考仍与实现漂移。现有 release-state 文字区分是正确的,但自动化没有执行 「实现 + owning checker + EN/ZH contract」同一交付规则。

建议。 增加一个只读的跨仓库候选 workflow:主题 PR checkout 当前 SHA,同时 checkout 文档站指定 main SHA, 用临时 module replace 跑 npm test 与关键浏览器套件;反向也让 Design contract PR 指向待验证主题 SHA。 发布仍保持 tag/pin/deploy 分离,但候选提交应有一个可追溯的联合验证结果。

F14 — checker 维护成本和源码耦合过高(P3)

当前 checker 覆盖面值得肯定,但 34 个 check-*.py 中有 546 次 read_text();多数脚本重复实现 require、临时站点、 写文件、Hugo 命令和错误聚合。大量断言锁定模板/SCSS 的源码拼写、注释附近结构或整文件相等,而不是最终行为。

一部分 helper 又硬编码 theme: oink + --themesDir <repo-parent>,使 checkout/worktree 目录名成为隐藏前提。 项目没有统一的 Python lint/type gate。结果是新增 checker 很快,却更容易出现「门禁全绿但共同盲区没有人拥有」。

建议。 建立共享 fixture builder 和 assertion library;把负向 case 作为表驱动数据; 只给真正的 topology invariant 留源码检查,其余转到解析后的 HTML/JSON/computed style。 测试主题应通过显式 symlink/module replace 装载,不依赖仓库 basename。

F15 — runtime 拆分成功,但基础 CSS/字体仍占主要首访成本(P3)

严格隔离 fixture 基线:

指标 数值
冷/热构建 1.256 s / 1.273 s
页面 249
stable JS chunks 18
main + Font Awesome CSS 549.8 KB raw / 91.1 KB gzip
字体总量(其中 FA) 999.7 KB raw / 248.5 KB gzip
Docs 页 JS 中位数 176.9 KB raw / 55.3 KB gzip
生成 public 26.2 MB
v0.7.0 Go module zip 7.8 MB(展开约 20.5 MB、1,140 文件)

第一方 capability chunk 已经消除了 2^N 组合包,这是正确方向;大第三方 runtime 也按页面隔离。 剩余主要成本来自所有页面都加载的 Bootstrap/主题/Landing CSS 与完整 Font Awesome 分发。

建议。 不要违背现有合同去按模板用量裁剪 Font Awesome。优先测量可独立缓存/按 surface 加载的 Landing、Book、Swagger CSS, 检查真实首访实际加载的 font subset,并给预算建立趋势报告而非武断阈值。

F16 — vendor 可复现,但漏洞与 CI 供应链仍靠人工(P3)

正面证据:VENDOR.json 精确记录 26 个包、56 个 artifact、31 个 license 文件和 tree hash, check-vendor.py 通过;本次 OSV 与 npm audit 均未发现已知漏洞。

缺口:custom manifest 没有进入通用 SBOM/OSV gate,npm audit 也天然看不到这些 vendored 浏览器包; 文档站两个 workflow 通过 curl 下载 Hugo .deb 后直接 sudo dpkg -i,没有校验摘要;Actions 用可移动的 major tag, 主题 CI 的 Python 是浮动 3.x。

建议。 从 VENDOR.json 生成 CycloneDX/SPDX SBOM,增加定期 OSV 扫描;Hugo archive/deb 固定 SHA-256; 高信任 release workflow 的 action 固定 commit SHA;选择明确 Python 版本或建立版本矩阵。

F17 — 设计记录与发行文字的信噪比下降(P3)

CHANGELOG.md 已有 1,768 行,0.7.0 单节约 300 行;Unreleased 用约 20 行解释一次 checker retry。 这些叙事对工程复盘有价值,但升级读者很难快速找到 breaking change、迁移和行为差异。

同时,book_kind/book_part 被契约「认可」并出现在大量内容 front matter,却明确不被模板读取; 它们给作者增加了类似 API 的负担但没有行为。已实现提案仍留在 Active proposals 又放大了重复答案。

建议。 Changelog 保留用户可观察变化、breaking/migration 与修复摘要;长设计故事移到 Blog/Research,并从 changelog 链接。 没有行为的 metadata 要么定义消费者和 schema,要么从公共契约降级为站点自有字段。

F18 — Print isHTML FIXME 已经失真(P3)

hugo.yaml 说「等 Hugo 修复 #14381 前保持 isHTML 未设置」。该 Hugo issue 已于 2026-01-17 修复, 修复进入 OINK 兼容性下限之前的 Hugo 0.155 系列;OINK floor 是 0.160.1。

但在当前主题上简单启用 isHTML: true 仍会产生 page/section/landing print layout missing warnings, 严格构建失败。这说明真实依赖已经从「等待 Hugo alias fix」变成「当前 Print 模板命名依赖 non-HTML lookup 规则」。

建议。 不要直接删除 workaround。先为 HTML-classified Print 补齐 lookup matrix 与 alias/subpath 测试; 若继续保持 false,就更新注释说明当前真实原因,并增加一个测试防止未来维护者依据已关闭 issue 做错误清理。

做得好的地方

  • 主题、文档站、发布标签和消费站 pin 被明确区分,没有把本地 replacement 当成发布;
  • Hugo floor 0.160.1 与 0.164/0.165 的主题矩阵覆盖扎实;
  • 大多数新组件已经遵循 warn/fallback、四输出、共享 URL/attribute policy 与 capability flag;
  • 32 个 locale schema 一致,EN/ZH 真实页面、标题 ID、站内链接和窄屏导航有强门禁;
  • 搜索、键盘、surface coordinator、页面动作和主题色测试既有单测也有浏览器行为测试;
  • vendor license/hash、EPUB/PDF 的路径边界、PDF loopback+CSP 与不可覆盖默认值设计认真;
  • 320px 人工复核未发现页面级水平溢出,当前核心视觉质量良好;
  • 构建性能很好,第一方 JS 已从组合 bundle 迁移到稳定 capability chunk。

建议修复路线

阶段 0:下一个标签前

  1. Swagger 写死 validatorUrl: null,增加 production-origin no-network test;
  2. 建立公开参数 inventory,为 F02/F04 中所有字段补 validator 与负向矩阵;
  3. 重做 Swagger/Redoc/Asciinema 四输出和 runtime gate;
  4. 修复自定义 action/归档版本 URL;
  5. 修复 Schema parser/scanner,并重新生成两份 Schema;
  6. 同步 EN/ZH Config、Front matter、OpenAPI、Asciinema、Book、Features 与 Landing contract。

阶段 1:契约门禁

  1. 为 29 个 shortcode 建立最小 HTML/Print/Markdown/RSS coverage map;
  2. 拆分并增强 output trust / machine-output purity 检查;
  3. 将 Landing section 输入统一归一化;
  4. 外部化 theme-owned inline initializer,发布 CSP 参考;
  5. 建立跨仓库候选提交 workflow。

阶段 2:兼容性与结构

  1. 加 Firefox/WebKit、真实 RTL、forced-colors、200% zoom;
  2. 收敛 Python checker harness 和源码字符串断言;
  3. 评估按 surface 拆 CSS 与字体实际请求;
  4. 生成 SBOM、定期 OSV、固定 CI 下载摘要;
  5. 退休已实现提案并精简 Changelog。

完成判据

  • 使用同源 Swagger spec 的生产 origin 除首方资源外无请求;
  • 每个公开配置错误在普通构建中 warn+fallback/omit,在严格构建中失败,且不出现 Go template ZgotmplZ;
  • 生成 .md 不含 td-*、theme <script>/<style> 或空交互容器;
  • Print 不加载 Swagger/Redoc/Asciinema runtime,并给读者可理解的静态替代;
  • Schema 默认值类型与 Hugo 实际解析完全一致,removed key 不出现在补全中;
  • EN/ZH 配置和 Front matter 参考的 key/enum/default 与实现 inventory 一致;
  • 核心 Playwright 在 Chromium、Firefox、WebKit 通过,真实 RTL 与 forced-colors 有行为断言;
  • 主题候选 SHA 有一条可追溯的真实文档站联合验证记录。

审查边界

本次没有逐一审查全部消费站仓库、真实生产响应头/CDN 缓存、Firefox/Safari 实机、读屏器, 也没有人工逆向 13 MB minified 第三方源代码。漏洞查询是 2026-08-26 的快照,之后可能变化。 DDIA/TPME 的 EPUB/PDF 真实消费站结果引用现有 CI/契约,本次没有重新发布或部署任何站点。

7.7 - 社区 Issue 与 PR 调研,2026-09-19

对社区 Issue 40、41、42、44 与 PR 43 的证据核查、接收建议和具体解决方案。
原始调研快照

本文记录 2026-09-19 的源码审查、GitHub 实时状态、本地构建与定向浏览器观察。 初始调研完成时,这些建议尚未成为已接受契约,功能也尚未实现;当时没有合并 PR、 发布版本或向贡献者发送回复。文末的实施补记单独记录了随后完成的变更。

以下保留最初的调研快照。随后维护者决定先合并 PR #43,再直接在 main 实施其余修复; 最新进展见同日实施与验收补记。

判断结论

这些反馈都有值得处理的内容,但不能全部归为同一种缺陷。应优先修复隐藏导航仍能获得焦点的问题。 PR #43 的小修复方向正确,明确边界并补齐测试后可以接收。搜索尾部扩展与侧栏状态公开接口则属于 新增 API,应分别设计和验收。

项目 判断 建议
PR #43,MagicFollower 收集自根分区时忽略显式的 sidebar_root_menu: false,已复现 有条件接收:补丁正确修复全站候选集合,合并前说明当前根例外、补回归测试并取得 CI 成功记录
#41,imbajin 整个侧栏隐藏后仍可聚焦;展开状态存在多处写入,缺少公开 API 拆成无障碍修复与可选 API 两项工作,前者优先
#44,lloydsun 点击后按键出现边框的现象真实,已在另一平台复现 改进正文容器的焦点样式,保留滚动区域必要的键盘提示;浏览器的判断机制本身符合预期
#42,aucru 现有隐藏和分隔选项不能完整表达“不可跳转的分区标题,下面保留子页” 先解释配置区别并获取作者的最小示例,确认后补齐分组能力
#40,imbajin 当前确实没有受支持的接口,向搜索结果追加依赖本次查询的操作 合理的小范围扩展需求,不是现有本地搜索失效;优先级低于正确性修复

基线与方法

通过 GitHub API 查到 4 个未关闭的外部 Issue 和 1 个未关闭的外部 PR。另一个未关闭的 #37 是维护者自己的版本发布跟踪项。 截至本次快照,这些外部反馈尚无讨论评论,PR 也没有已提交的 review。

输入 已核实的快照
主题远端 main 93ac292014a3cd81f7c41caec4df98ed9d2dc45a
本地主题 75ddc95,相对远端仅有 CHANGELOG.md 发布文字差异
PR #43 HEAD 8eeb8ecaf525097cc56572fe22234db381bfc16a,只改一行模板
本地文档站 ff0ba39,go.mod 仍依赖 OINK v1.0.0
公开版本 GitHub 最新 Release 为 v1.0.0,远端查询没有返回 v1.1.0 标签
构建工具 Hugo Extended 0.166.0、Node 26.9.0、npm 11.19.1
浏览器观察 macOS、Chromium 153.0.0.0、浅色主题;真实同级文档站通过单次命令的模块替换使用本地主题

Design 中的 released-v1.1.0 标记和本地发布准备提交,不构成 v1.1.0 已经公开发布的证据。 源码修改、标签、消费站版本固定与线上部署仍是不同状态。本次没有升级公开消费站。

调研覆盖完整 Issue/PR 正文与评论、精确 diff、双语 Design 契约、相关模板和 JavaScript、 部署在 /sub/ 下的临时双语站点,以及真实文档站的定向浏览器交互。共享工作区中的主题实现未改动。

PR 43:接收小修复,明确它解决到哪里

root-menu-roots.html 第一轮收集顶层分区时会检查 sidebar_root_menu;第二轮收集 sidebar_root_for: self 分区时没有检查。于是第一轮已排除的节点又被第二轮加回来。

PR 给第二轮补上同样的显式 false 判断:

{{- if and .IsSection (ne .Params.sidebar_root_menu false) -}}

这保留了未配置和配置为 true 时的默认行为,也保留了分区类型约束与 URL 去重,不改变侧栏树及 翻页顺序,不破坏按语言缓存。没有必要为这一个遗漏重构整个导航系统。

但是,后面的 root-menu-entries.html 还会把不在集合中的当前根追加回来。这是已有行为,导航指南也提到最后追加当前根,不能误报为 PR 引入的新回归;但它意味着不能宣称“设成 false 后,在所有页面都不再显示”。

临时复现站包含一个顶层 Blog 自根、一个嵌套 Docs 自根,二者均设 sidebar_root_for: self 和 sidebar_root_menu: false,另有可见 Docs 根和未覆盖可见性的自根。 英文、中文结果一致,URL 都正确保留 /sub/ 与语言前缀:

当前浏览页面 修改前 应用 PR 后
不相关的 Docs 页面 两个隐藏自根都出现 两个都消失
隐藏 Blog 根下的页面 Blog 出现 Blog 仍被当前根回退逻辑加回来
隐藏嵌套根下的页面 嵌套根出现 嵌套根仍被当前根回退逻辑加回来
可见自根 出现 继续出现且不重复

建议把契约明确为:false 将节点排除在全站可选根集合之外,但当前根可为位置提示而保留。 保留这个已有例外是改动最小、最兼容的解释,需要在两种语言中写清楚。如果真正希望 false 表示绝对排除,就要另行协调修改当前根回退和切换器标题逻辑,并检查零入口、单入口状态。 只再加一个条件,不足以完成这项语义变化。

合并前应补齐:

  1. 在 bin/check-shell.py 增加输出测试,覆盖顶层与嵌套隐藏自根、未设置/true、去重、当前根 例外、单入口退化,以及 EN/ZH 子路径。
  2. 同步更新 Shell 契约与导航指南。PR 描述示例里的 YAML 注释 // 也应改成 #,保证可复制。
  3. 处理工作流的 action_required 状态,在最终 HEAD 上运行 必要检查。截至快照,PR HEAD 没有成功的 check run 或 commit status。API 返回 MERGEABLE、UNSTABLE,这两个状态都不等于测试通过。

维护者可以保留贡献者的提交并补上这些收尾工作。不应把实现 #40 或完整 #41 作为接收这行修复的前提。

Issue 41:先修隔离,再公开状态

这里有两件不同的事。

第一,整栏隐藏主要依靠 transform,桌面还使用 opacity;抽屉和折叠控制器没有将隐藏控件移出键盘 导航。在浏览器实测中,点击折叠按钮后,焦点留在已经透明的折叠按钮上,再按 Tab 就进入隐藏的根 切换按钮。此时面板 opacity 为零,也没有生效的 inert 或 aria-hidden 祖先。这是可复现的 使用缺陷,不只是缺少给集成方调用的接口。移动端关闭面板的实现同样仅移到屏幕外,没有显式隔离。

第二,展开状态分别由 点击控制器、响应式搬迁 和 缓存活动路径补全 直接写入,没有公开 setter、getter 或状态提交事件。现在对整栏折叠、宽度和滚动位置的存储,并不 等于每个分支的展开选择能跨页面持久保存。创作指南中“读者的展开状态保存在本地”也需要说明这个区别。

建议分步处理:

  1. 集中处理整栏隔离,在初始化及打开、关闭、折叠、悬浮展开、恢复和断点切换时同步更新。 先解除隔离再把焦点移进去;关闭时先把焦点归还给可见的外部控件,再使内容 inert。
  2. 隔离内容区,同时保留外部恢复按钮和桌面边缘的悬浮感应区域。直接把感应区域一起 inert 会破坏 已有悬浮行为。仅用 aria-hidden 不能阻止键盘进入; HTML 的 inert 定义 同时约束交互与无障碍树暴露。
  3. 将分支展开修改另行收敛到一个提交函数:更新 aria-expanded、展开 class 和本地化标签后, 再发送一次事件;重复写入同一状态不重复通知。
  4. 在定义稳定 ID、非法 ID 处理、初始化就绪信号和恢复次序后,再公开最小 setter/getter 与事件。 版本和语言的存储命名空间继续由下游管理,恢复后以当前活动路径展开为准。

原提案有一处范围需要校正:TOC、反向链接和分类法分组在宽屏时会从侧栏移回右栏。 如果控制器只查询“当前侧栏 DOM 下的后代”,就无法同时管理宽屏时的这些写入。 应按 OINK 管理的目标注册元素,不依赖其当下 DOM 父节点;对外的侧栏 API 则只开放约定的注册子集。

验收必须检查隐藏状态下的真实 Tab 顺序与无障碍树、初次载入时恢复折叠、悬浮进出、焦点归还、 Escape、遮罩关闭、滚动解锁,以及 768/1200 断点。还要保留 #24 已修好的无 JavaScript 导航。 静态 axe 扫描通过、或者测试“抽屉可以打开”,不能证明这些状态转换正确。

Issue 44:现象真实,部分行为符合预期

在文档站配置页分别点击文章标题、表头单元格和代码块,会让 main#td-main-content、 div.td-table-scroll、pre.chroma 获得焦点。三者在点击后都不匹配 :focus-visible,按下未绑定 快捷键的字母 z 后都开始匹配。正文和代码块出现浏览器的 auto outline,表格使用主题的实线 outline。这说明不需要作者的 Linux 桌面或 Super 键,也能复现相同机制。

Selectors 规范 明确描述了这种情况:键盘交互可以改变焦点提示,即使焦点元素没有变化。因此,这是一条有价值的 阅读体验反馈,但“鼠标聚焦之后,无论再按什么键都不该出现框”不是浏览器必须遵守的正确性要求。

建议这样处理:

  • 保留 main 作为跳过导航的目标以及它的可聚焦性,把包围整栏的 outline 改成正文入口附近的局部 可见提示,例如标题区提示,并实际验证 skip link。
  • 保留可滚动表格和代码块的键盘焦点提示,必要时统一其视觉样式。可聚焦性使键盘滚动成为可能。
  • 不做全局 outline: none,不删除所有 tabindex,不在任意按键后主动 blur。
  • 如果产品仍决定抑制“鼠标先聚焦再阅读按键”这一路径,需要明确新增语义,只限定这些非编辑容器, 并验证鼠标、Tab、skip link、程序聚焦、深色及强制颜色模式。为这条反馈建立全站输入模式框架 并不划算。

本次证据支持小范围的显示改进,不支持为了消除现象而直接取消表格和代码块的键盘提示。

Issue 42:区分隐藏与分组

提问写的是 _index.json,并依赖截图而没有提供源码复现。本次未能成功完成原始截图的视觉核验, 第一项需求具体想改变哪里仍需澄清。回复时应请作者提供小目录树及实际 index/front matter, 不能没有证据就断言 _index.json 是受支持的页面源文件或只是笔误。

现有选项的含义并不相同:

选项 当前行为与限制
no_list: true 隐藏分区正文里的子页面列表,不隐藏其侧栏节点
hide_summary: true 隐藏父分区正文列表中的某一项,不改变侧栏分组
toc_hide: true 内容树遍历在递归前过滤该节点,也会从这棵树中移除其子树
sidebar_root_menu: false 控制顶部根切换器候选,不控制阅读树中的行;另见 PR #43
sidebar_root_link_self: false 将自根的链接指向父节点,不会变成不可跳转的分组标题
sidebar_divider: true 输出无链接标题,但共享渲染器在这个分支中没有输出已传入的子项
build.render: link 不生成分区 HTML,但保留 permalink;当前侧栏仍会输出指向它的链接,不能单独解决问题

临时站点确认:带 divider 的分区,其子页面 HTML 仍然存在,但侧栏子链接消失;仅设置 build.render: link 的分区没有自己的 HTML,侧栏中却仍有可点击的分区链接和子页。 这与 Hugo 的 构建选项定义 以及主题的 共享节点渲染器 一致。

如果真实需求就是“保留分组标题和子链接,但标题不跳转到目录页”,优先考虑补齐 sidebar_divider 在分区节点上的行为:叶子分隔项保持原样,有子项的分区保留 children,允许折叠 时使用真正的 disclosure button。决定前应检查已有消费站;只有现有 divider 契约无法兼容表达时, 才增加独立的节点级开关。“是否生成分区页面”与“导航标题是否可点击”应分别处理。

实现必须保留两套遍历器中的层级和活动路径展开,使子页继续进入翻页顺序。如果目录页确实不发布, 还要检查面包屑、搜索、根切换器、Print 和机器可读导航,不能留下死链接。直接用 CSS 隐藏整个节点 解决不了这个需求。

Issue 40:可以接受范围受限的扩展方向

源码核实了提案指出的限制: groupsFor 只组合内置页面和操作;公开 Palette 对象没有 provider 注册接口; registerExecutor 只允许内置 action ID。静态 URL command 无法替代携带当前查询的结果行。 现有 Palette/controller 测试通过,证明已有功能能工作,不能证明该扩展能力已经存在。

提议的 search-tail 位置是合理的上游接口边界:同步返回纯数据行、异步执行操作、本地结果优先, 由 OINK 管理渲染、选择、键盘和 ARIA。OINK 不需要因此内置 AI 服务商、凭据、远程搜索或通用插件系统。

接受 API 前,需要定清并测试:

  1. 只在哪些已完成的文本搜索状态调用 provider;保留空查询、命令、选择、加载中,以及未注册扩展时 的原有行为。
  2. 保存生成每一行时的 query/locale 快照,保留原生空结果、索引错误及重试提示,区分本地页面数与 全部可选择操作数。
  3. 校验并复制 descriptor,把标题和描述当文本渲染;隔离 provider 异常、重复 ID 和非法描述符。
  4. 同时处理同步 throw、Promise rejection、pending 释放、重复激活、旧会话取消,以及 ID 重用后的 旧 unregister 句柄。
  5. 验证向另一个对话框移交焦点。现有 Palette 关闭逻辑已经会在焦点移出后避免强行归还,应保留这个 判断。还要区分“成功把交互交给新界面”和“取消”,否则“任何 close 都 abort 激活”的规则可能 把刚打开的助手操作一并取消。
  6. 保持默认查询不出浏览器和按需加载资源的行为。对受信任站点脚本约定 rows() 纯净,不等于主题 有能力建立安全沙箱。

实现前,应把接受的 API 形状沉淀为双语 Design 提案。下游 Ask AI 包装可以继续使用,直到公开标签 包含该接口。它不应成为小型正确性修复的发布前提。

实施顺序与归属

顺序 交付内容 对应验收与文档
第一批 PR #43 收尾与隐藏侧栏隔离,分别交付 check-shell.py;文档站响应式、键盘、无障碍用例;双语 Shell 契约与导航指南
第二批 正文焦点样式,以及确认后的分组行为 对应内容、阅读、导航检查器;浏览器焦点、滚动、skip link 用例;双语架构、外壳与创作说明
后续 公开展开状态控制器,再做 search-tail API 主题 JS 测试及 check-navigation-contract.py / check-palette.py;真实站点 fixture;已接受的双语 API 契约

每项公共行为修改先跑对应检查器,再通过同级文档站的 make check、make browser、make dev 做相关集成与视觉验收。不要把这些不同需求绑成一次大规模侧栏/搜索重写,也不要等待所有新功能 完成才交付小修复。

建议回复内容,尚未发送:对 #43 承认过滤遗漏并解释当前根例外;对 #41 接受隔离缺陷、拆开 API 诉求;对 #44 确认复现并说明标准焦点机制;给 #42 解释配置区别并索取最小输入;把 #40 归为受限 扩展需求,而非本地搜索故障。

历史外部反馈已经关闭:#22 通过开启 Goldmark passthrough 解决,提问者明确确认有效;#21 已提供 Mermaid 查看器与 固定居中展示,任意右对齐选项则明确没有纳入。二者不应被算作新的待处理缺陷。

验证结果与边界

本次实际执行:

  • 本地基线及 PR #43 精确 HEAD 的隔离 checkout 均通过 python3 bin/check-shell.py。
  • Palette 控制器和模型测试通过,共 2 个测试文件,零失败。
  • 对真实 PR diff 应用前后分别进行严格 Hugo 临时构建,在 EN/ZH 与 /sub/ 下复现自根过滤和 当前根回退;同一 fixture 验证了分组配置的限制。
  • 真实双语文档站使用本地主题,通过带 --panicOnWarning 的构建;Chromium 定向交互复现三个 容器的焦点边框,以及桌面侧栏隐藏后的焦点问题。
  • 文档站双语覆盖、渲染与链接检查通过,非浏览器套件的 57 项测试均已通过。首次 make check 因新增报告改变 llms.txt 索引而停在快照检查;确认仅新增报告这一行、同步快照后,重跑该组 及其余测试组全部成功。

新增缺陷断言属于调研探针,尚未成为提交到仓库的回归测试。本次不是完整发布验收,也没有跑所有 浏览器矩阵。本地 Hugo 为 0.166.0,并非 CI 固定的 0.165.0 或声明的 0.160.1 兼容性下限。 Linux Super 键、移动端无障碍树隔离、深色/强制颜色模式及作者 #42 的精确截图,还需要上述验收覆盖。 本次未改变线上部署、公开版本、消费站依赖或上游讨论。

实施与验收补记

维护者决定先合并贡献者补丁,再直接在 main 完成修复与扩展,不另提 PR。 PR #43 已合并为 6e814089, 随后拉取到本地,保留原有发布说明提交。第二阶段实施提交为 56bfe37。

项目 已实现的行为 对应验收
#43 两条根收集路径都遵守显式 false,保留当前根的位置提示;分隔项和未发布分区不成为切换器链接 严格 EN/ZH 子路径 fixture 覆盖顶层/嵌套隐藏根、未设置/true、去重、当前根回退以及零/单入口
#41 单一控制器统一提交 ARIA、类名、标签和 inert 状态;提供晚加载安全的 API,支持下游持久化;隔离隐藏侧栏内容,保留悬浮恢复和抽屉行为 运行时与浏览器测试覆盖事件原子性、重复写入、作用域、活动路径、存储禁用、响应式搬移、焦点归还、真实 Tab 遍历、Escape、遮罩与断点
#44 记录指针来源焦点,抑制后续无关按键触发的容器边框;Tab 与新程序化焦点保留提示,跳转正文时突出标题 正文、表格、代码块在亮色/暗色/强制颜色下的浏览器测试,以及键盘与 skip link 回归
#42 分隔分区显示不带链接的标题并保留子页,配合 build.render: never 省略自身页面;面包屑、搜索、翻页、导航 JSON、Book 目录/Markdown、Print 保持一致;显式导航兼容双语子路径 内容树/数据树严格 fixture、Book 三级标题检查、EN/ZH 浏览器 fixture 和无 JavaScript 遍历
#40 受信任站点脚本可注册同步纯数据搜索尾部行及异步激活;排序、ARIA、校验、异常隔离、取消、注销和焦点移交仍由 OINK 管理 运行时生命周期测试,以及中文页面的鼠标/键盘选择、纯文本显示、上下文快照、外部对话框焦点和注销场景

使用同级主题 checkout,在 macOS、Hugo Extended 0.166.0、Node 26.9.0 与 Chromium 上完成:

  • 主题 JavaScript 测试 44 项全部通过。
  • check-shell.py、check-reading.py、check-palette.py、check-keyboard.py 通过。 按主题 CI 配置扩大检查,另外 31 条命令中 29 条通过;本地两项失败来自媒体检查器固定的图片处理 指纹,以及四份黄金文件中 Hugo 0.166 改变的 KaTeX 输出。保留原有空白格式后,普通导航标记与 黄金文件一致。固定 CI 工具链的结果单独核验,不因此改写无关预期。
  • make -C ../oink.pgsty.com check 通过:双语源文件、渲染与链接检查,以及 57 项非浏览器测试。
  • make -C ../oink.pgsty.com browser 共 141 项通过:无障碍 30,响应式/博客/Palette 45, 键盘 16,内容 10,代码块 18,场景 4,主题色 5,社区回归 13。无障碍套件包含完整双语站点地图逐页扫描。
  • 主题 fixture 严格构建、输出与命名空间检查通过。Book 本地打包生成五章 EPUB,检查零错误; PDF 为 23 页,包含全部五个预期 Book 页面,检查零错误。
  • 通过 make dev 在真实文档站实测桌面亮色、中文暗色、折叠侧栏恢复,以及 375px 移动抽屉。 Escape 关闭后焦点回到可见的打开按钮。验收后已恢复浏览器视口并清理临时开发服务。

已接受的契约写入 Shell 与架构, 中英文同步,并更新导航、组织内容、Palette 和 Print 指南。集成回归留在文档站仓库,主题只保留 专项检查器和合成输入。

PR 合并提交的固定工具链 CI 三个任务全部通过。最终实施提交的 CI 也已全部通过,精确版本为 56bfe37092a43fc12c0e16f865d3d3407c55cbde:Hugo 0.165.0、 浏览器运行时测试与 Book 出版三个任务均成功,包含本地 Hugo 0.166.0 出现差异的媒体和 四状态黄金文件检查,以及根路径/子路径出版。声明的 0.160.1 兼容性下限没有额外复测; 本项目固定的持续测试工具链仍为 0.165.0。

这是源码与集成验收,并非新版本发布:没有创建新标签,文档站仍固定 v1.0.0,生产站没有升级。 同级文档与测试变更在本地 main 为下一次主题发布准备;若立即推送新增浏览器门禁,远端会拿旧公开 依赖测试新接口,无法构成正确验收。本次没有发送贡献者回复,#40、#41、#42、#44 仍保持打开状态。 #42 原始截图和报告中的 Linux Super 键环境没有独立复现;明确的纯分组需求及等价的“点击后按键” 路径已按上表实测。

图片复制补记

维护者另行报告:把博客文章复制到富文本编辑器后,图片下面出现预览提示。博客固定 OINK v1.0.0,并开启 params.ui.image_zoom。该版本与本次审查的 main 都会在每张 符合条件的图片后插入一个视觉隐藏的文字 span。Chromium 原生复制已复现剪贴板额外 带入“打开图片预览”及对应英文文字,因此这是独立于目标编辑器的主题缺陷。

主题提交 75052f8 把图片描述与本地化 操作改放到按钮的 aria-label,不再向文章插入辅助文字节点。图片 alt、作者图注、 原生按钮操作和对话框焦点归还均保留。组件契约 与图片指南 已同步说明复制行为。

check-image-zoom.py 与站点全部 57 项非浏览器测试通过。专项浏览器验收 16 项通过: 14 项内容组件测试,其中包含新增的中英文图片/画廊四项剪贴板回归,以及桌面亮色/ 手机暗色两项对话框无障碍检查。回归读取纯文本与 HTML 两种剪贴板格式,检查脱离样式 后的文字,并核对图片地址、alt、图注和按钮的无障碍名称。

本次没有在真实知乎编辑器里做粘贴验收。博客依赖与线上部署保持原状;消费站升级主题 依赖并重新构建后,公开页面才会获得修复。

7.8 - OINK 1.1 发布审查,2026-09-20

OINK 1.1 的五项已复现运行时缺陷、文档修订、验证证据与发布后续。
发布准备,不是发布声明

本文分别记录审查基线、已提交修复、已完成验证与尚待执行的发布步骤。基线 CI 通过不能 证明后续修复也已通过验收。从正文到“限制”保留发布前快照;后续已核实的发布证据追加在 发布后续中。

范围与基线

审查从主题提交 75052f8a3106d13ef313644836a5ad545135f484 开始,此时社区反馈与图片复制修复已经进入 main。范围包括 v1.0.0..main 差异、 #40、 #41、 #42、 #44 与已合并 PR #43 所要求的行为,以及双语文档和发布边界。 前一轮调研 记录了原始反馈及其实施过程。

方法是检查拥有相关行为的 JavaScript、模板与契约,通过定向回归覆盖状态转换,比较修复前 失败断言与修复后的实现,再运行主题检查器和真实同级文档站的集成、浏览器套件。本轮不扩展 新的功能计划,也不声称进行无边界的完整安全审计。

截至本次快照,公开版本、文档站 go.mod 固定依赖与配置中的公开版本仍为 v1.0.0。 博客消费站固定的主题版本保持不变。

发现与修复

本轮复现并修复了五项 P2 正确性缺陷,已提交为 08f6563 并推送 main。它们涉及新增 API 的时序和既有焦点、导航行为, 不需要新增配置格式或迁移正文内容。

发现 触发条件与观察到的问题 最小修复
P2:侧栏就绪早于活动路径补全 消费代码等待 OinkSidebar.ready 或监听 oink:sidebar-ready;就绪微任务可能在两个 DOMContentLoaded 监听器之间执行,早于缓存侧栏的活动路径补全,读到不完整的初始状态。 把就绪通知放入下一任务,等待初始化监听器与右侧内容搬迁完成,保留 ready Promise 和事件契约。
P2:待完成操作仍可进入原生选择菜单 启动异步搜索扩展操作后,再激活主题切换等原生选择项;pending 检查位于选择分支之后,选择菜单会替换待完成操作的结果行。 将 pending 检查移到所有行类型分支之前;操作完成后恢复正常的选择项激活。
P2:右侧 TOC 整栏折叠后仍可聚焦 桌面端收起右栏后,隐藏的按钮与链接仍是键盘目标,焦点也可能留在隐藏面板内。 为右栏面板设置 inert 和 aria-hidden,把焦点交给可见恢复按钮,恢复时归还栏内按钮;右侧内容搬迁后不继承原栏隔离。
P2:方向键跳过无链接分组 从分隔分组的子页按 Left/a,无法稳定回到父分组按钮并折叠;分组按钮不在树的焦点序列中。 将分组展开按钮纳入树焦点导航,按直接父级回退;Right/d 展开或进入分组,上一页/下一页仍只遍历页面链接。
P2:抽屉焦点循环计入 inert 后代 在移动抽屉中折叠右侧搬入的分组,再按 Shift+Tab 循环;隐藏后代仍被计作可聚焦元素,可能导致循环失败或焦点停滞。 从抽屉可聚焦集合排除 inert、hidden 祖先内的元素,以及 visibility 为 hidden/collapse 的控件。

实现与回归归属:

发现 主题实现 拥有该行为的回归检查
就绪时序 assets/js/sidebar-state.js tests/js/sidebar-state.test.js;站点 tests/browser/community-feedback.spec.mjs 在两种就绪信号中读取 EN/ZH 活动路径快照
待完成选择 assets/js/command-palette.js tests/js/command-palette.test.js 覆盖扩展待完成 → 原生选择 → 完成 → 选择恢复可用
右栏焦点 assets/js/docs-shell.js 站点 tests/browser/community-feedback.spec.mjs 覆盖 EN/ZH 折叠、Tab 遍历、恢复、重载和桌面/平板/手机搬迁
分组按键 assets/js/keyboard-nav.js tests/js/keyboard-nav.test.js 覆盖 LTR/RTL、方向键/WASD 与仅链接翻页;站点社区回归覆盖真实 EN/ZH 分组
抽屉循环 assets/js/docs-shell.js 站点社区回归折叠已搬迁分组,执行 Shift+Tab 与 Tab 循环,并断言焦点不进入 inert 或 hidden 子树

修复前,就绪时序与待完成选择的新增单测在旧实现上失败;右栏隔离的浏览器断言也在中英文 两种页面上失败。修复保持局部:调整就绪通知时序、提前一项 pending 检查、明确右栏隔离、 补齐树焦点目标和抽屉可见性过滤。

这些改动保留已有结果:两个根收集器都遵守 sidebar_root_menu: false;无链接分组保留 子页;指针聚焦不引入正文大边框,键盘提示仍然可见;搜索扩展保留取消与交接契约。图片预览 继续通过无障碍名称表达操作,不向复制的正文插入辅助文字。最终回归结果在下方单独记录, 不由源码检查推断通过。

文档准备

当前使用文档更新覆盖 28 个文件、14 组 EN/ZH 页面:

  • 六组 Design 契约使用 candidate-v1.1.0,描述 main 已实现行为,不提前声明正式发布。
  • 导航、布局和 front matter 指南对齐根过滤、分隔分组、双语部署路径、居中顶栏、窄屏抽屉 与原位淡入的顶栏行为。
  • 内容组织和命令面板指南说明运行时加载顺序、就绪、能力检测,以及站点负责的持久化和集成。 键盘与图片指南说明修复行为和旧版本边界。
  • 安装指南区分验收工具链与公开版本;既有标题 ID 保持稳定,新增侧栏 API 标题的中英文 ID 匹配。

另已准备两份 1.1.0 发布注记和两份升级指南。发布注记保持 draft/candidate 状态,首页中英 发布入口都回到已公开的 1.0 版本。这些源码修改没有更新站点模块依赖,也不代表新行为已经 部署。历史研究继续保留当时的观察,不为消除旧状态而重写。

验证快照

下表数字是主题 08f6563 在 2026-09-20 的验证快照。站点验收通过命令作用域内的模块 替换使用同级 checkout,不证明尚未发布的模块标签可用,也不代表已经部署到生产环境。 本地站点检查使用 Hugo Extended 0.166.0、Node 26.9.0 和 Playwright 1.62.1;候选版本 CI 使用固定的 Hugo 0.165.0 工具链。0.160.1 下限使用官方二进制单独验证。

检查 结果与范围
基线 75052f8 CI 三项全部通过:固定 Hugo 工具链、浏览器运行时测试和 Book 出版。精确基线运行。
修复后的 JavaScript 单测 通过:44 项。
官方 Hugo Extended 0.160.1 定向 i18n 与 shell 检查通过;i18n 覆盖 32 份语言包 × 194 条消息。真实文档站也以本地候选主题通过 --panicOnWarning 生产构建,每种语言 376 页;不输出发布草稿,两个首页入口均指向 1.0.0。这是部分兼容下限证据,不是第二套完整 CI 矩阵。
双语源码与样式检查 包含本报告后通过:129/129 组页面、988 个源标题、Markdown 样式和 git diff --check。
最终定向主题检查器 shell、palette、keyboard 与 image zoom 全部通过。
最终真实站点非浏览器套件 make check 全部 57 项通过;检查 200 个正文页面、331 个含链接 HTML 页面、39,803 条内部链接与 3,863 个锚点链接。仅更新发布摘要和文档索引这两份预期变动的 Markdown golden。下限版本的生产构建也通过链接检查:327 页、39,059 条内部链接与 3,833 个锚点。
最终浏览器套件 make browser 的八组 Chromium 测试全部 149 项通过:无障碍 30、响应式/博客/Palette 45、键盘 16、内容组件 14、代码块 18、场景 4、主题色 5、社区回归 17。包含完整多语言 sitemap、六种屏宽、深浅色、强制配色、剪贴板与无脚本场景。
Agent 文档抽样 50 个同源页面得分 93/100(A);抽样链接均可解析,49 页提供 Markdown,270 处代码围栏均正确闭合。检查器提示 HTML 中的 llms.txt 发现提示缺失或位置过深。
渲染审查 查看了中文发布注记的桌面深色布局与英文窄屏浅色布局。右栏收起后,其后代从无障碍树移除,焦点交给恢复按钮;恢复后焦点返回栏内可见按钮。
最终主题版本及其 CI 08f6563 的 Hugo 0.165.0、浏览器运行时测试和 Book 出版三项全部通过。精确候选运行。
公开 v1.1.0 标签、消费站点升级与部署 未执行。

在本轮审查与验收范围内,未发现尚未解决的实现阻断项,可以进入下方发布流程。

在同级 checkout 中复核,开发期间保留公开依赖固定版本:

# 在主题仓库执行
node --test tests/js/*.test.js
python3 bin/check-shell.py
python3 bin/check-palette.py
python3 bin/check-keyboard.py
python3 bin/check-image-zoom.py

# 站点 Make 目标使用命令作用域内的同级模块替换。
make -C ../oink.pgsty.com check
make -C ../oink.pgsty.com browser

待执行发布步骤

尚未执行发布。最终版本通过验收后:

  1. 确定 CHANGELOG.md、发布日期与发布记录,从通过验证的主题提交发布 v1.1.0 标签 和 GitHub Release。
  2. 验证模块代理可将该标签解析到预期提交。
  3. 一并更新文档站固定依赖、版本配置、首页发布入口、契约状态,以及发布注记的 draft: false 状态。
  4. 不使用 HUGO_MODULE_REPLACEMENTS,从已发布依赖重新构建并验收文档站,再部署 并检查公开路由。

最终结论必须标明被测主题提交,分别说明本地源码验收、公开模块可用与实际部署结果。

可以后续改进的是:为从 HTML 进入的 Agent 提供位置更靠前、一致的 llms.txt 发现提示。 这项评分告警不影响现有 Markdown 输出,也不要求在 1.1 前增加新功能。Safari/Firefox 检查与真实知乎编辑器粘贴验证也是有用的后续工作,本轮 Chromium 验收不涵盖它们。

限制

浏览器证据来自 Chromium,不是 Safari/Firefox 矩阵。无障碍门禁覆盖主题自有界面,保留 对 vendored Redoc 与 Swagger UI 的既有排除。原生剪贴板回归覆盖纯文本、富文本 HTML、图片描述与作者图注,但不证明真实知乎编辑器的粘贴行为。本轮没有修改或验收博客的 依赖固定版本及线上产物。Hugo 下限的定向检查,也不代表该版本上所有出版路径都已执行。

这是对明确源码与行为的发布准备审查,不声称无边界的安全覆盖、生产上线,或支持额外的新功能。

发布后续

审查之后,v1.1.0 正式版 已于 2026-09-20 从提交 3a18234 发布。该版本相对已验收的 08f6563 实现只修改更新日志。创建附注标签并发布稳定版 GitHub Release 前,全部三项发布提交 CI 均已通过。

仅使用官方 Go 模块代理、从全新缓存下载的版本准确解析到该提交。.info、.mod、 .zip、版本列表条目与签名校验和记录均已验证。模块校验和为 h1:121L5g57ChRCPyidzEBBcln2Co+0zYRQ+XDDXjymd0Q=,go.mod 校验和为 h1:pHvbUhJCfseB41n5RGwsF7abT3i32VSTpofLQoq4b7Y=。 公开记录见代理版本信息与 校验和条目。

文档站发布更新在 go.mod 与 go.sum 中固定 v1.1.0,同步公开版本标识和双语首页 入口,公开两篇发布注记,并将六对契约标记为 released-v1.1.0。上方历史验收表继续 描述此前的同级 checkout 运行。公开依赖的验证单独记录在本站的 Site checks 和 Browser quality 工作流中,两者均关闭 Go 与 Hugo 模块工作区。

本地使用该公开模块通过了全部 57 项非浏览器测试、26 项命令面板与社区问题浏览器测试, 以及严格生产构建(每种语言 378 页)。这些检查均设置 GOWORK=off、 HUGO_MODULE_WORKSPACE=off,且未使用 HUGO_MODULE_REPLACEMENTS。完整的 149 项 浏览器套件另由发布提交的 Browser quality 工作流执行;其结果与此前本地候选版本的 运行记录分别记录。

7.9 - 2026-10-03 CLI 维护验收

R1–R8/A18 本地实施的带日期源码与二进制证据,保留初始审计、失败试验与最终受支持验收范围。
历史源码与二进制证据

本记录保留此前 R1–R8/A18 验收,不随命令调整重写历史结果。2026-10-04 的 CLI 精简与 Cobra/文本/JSON/YAML 界面以当前契约和 指南为准;旧运行时资格不能自动证明修改后的二进制。

有限实现已本地验证

下文保留初始审计。R1 实现与归属检查已通过其本地范围, 包括刷新后的消费站报告和限定范围的中英文产物验收。R2 本地范围门禁也已接受, 数值相等比较补充单独测试。R3 运行与双语文档门禁通过,阶段已本地接受。 R4 受支持实现与只读语料门禁已本地通过;受保护规范文档验证在下文单独记录。 R5 修正实现/只读语料及受保护规范文档门禁通过,受支持范围已本地接受。 R6 显式工作区与可选适配器通过冻结归属/运行时、精确二进制消费者及受保护 规范源码/渲染门禁;R6/A07/A15 受支持范围已本地接受。R7 只读 Studio/A16 也通过 浏览器、四消费者及受保护规范渲染门禁。R8 受审阅编辑/A17 通过修正冻结 归属/浏览器、精确二进制消费者及受保护规范源码/渲染门禁。R1–R8 受支持范围 已本地接受。2026-10-04 增补刷新变动后端,并完成三个声明目标的当前 A18 运行时/归档验收。规范生命周期晋升/渲染具有独立准确字节收据边界;没有公开发布、 采用或部署。

范围与证据规则

维护路线图 定义已授权的 R1–R8 范围,当前 CLI 契约 定义兼容基线。原路线图 不会把 Docsy 迁移、版本生命周期、OpenAPI、主题发布或条件性 E1–E4 扩展 加入本计划。Hugo 继续作为外部渲染器,生成站点仍是普通 Hugo 项目。

各阶段按依赖顺序验收。每阶段都需要完整可用的流程、归属测试、相关真实 Hugo 集成、已知限制、可审阅 diff,以及已验收的中英文契约和指南更新。 汇总命令通过不能自动关闭用例。新公开行为只有在实现和验收证据齐备后, 才从提案移入归属契约。

下表中的 已有,未重跑 表示已经检查代码或具名测试,但尚未确认本轮运行结果。 部分已有 表示首个候选提供了所需行为的一部分。未完成 表示缺少新实现或决定性验收证据。 后续记录 通过、失败、未验证 和 不支持 时,必须说明具体执行输入和范围。 历史结果不会改标为本轮通过。

已检查输入与工具

2026-10-03 的初始审计读取了两个仓库的指令、文档站 README 和翻译规则、 维护 PRD 的中英文文件、原提案、当前 CLI 契约,以及已有 Go 包和测试名称。 本次只执行版本与 Git 检查命令,没有运行归属测试套件,也没有写入消费站源码。

输入 初始观察状态
主机与 Go darwin/arm64;go version go1.27.1 darwin/arm64
Hugo hugo v0.166.0+extended+withdeploy darwin/arm64;Homebrew 构建日期为 2026-09-09
Node 与 npm v26.9.0;11.19.1;属于贡献者/文档工具,不是 CLI 消费者要求
Git 2.54.0 (Apple Git-157)
CLI 源码 e623d93d589c49e5c58b8fae1bd5db720fc904cb,main;初始 tracked/untracked 状态干净;生成的 bin/、dist/、tmp/ 已忽略
文档源码 907d873eb05cfc2e194f492462dfa94849e93474,main;初始 porcelain 状态有 184 项,含已有提案、契约、指南及无关内容修改
内嵌 Starter 137843b25bacd76ddd1f7ce71330bf2e3155b954;internal/starter 已记录来源和许可证
声明的主题基线 Starter 与三个选定站点声明 github.com/pgsty/oink v1.1.0;有效解析字节仍须在每次验收中确认

2026-09-29 验收记录 包含首个候选的历史检查,可提供复现输入,但不能证明新的维护范围。 保留已有脏文件;此次初始研究记录不会验收或覆盖它们。

阶段需求与实现证据

阶段 所需完整流程与不变量 初始实现证据 仍需验收证据
R1 由 Hugo 提供共享页面身份、语言、发布状态、来源、实际输出、翻译和观察到的引用;oink.yaml 只管理检查政策;链接/翻译/风格共享分析;严重程度和排除项不能隐藏必需未完成;位置可信 部分已有:internal/site 隔离快照与 Page.OutputFormats 探针、internal/outputcheck、internal/report;初始审计时尚无共享翻译/页面事实或政策命令 真实 Hugo 路由、别名、挂载、未列出/生成来源场景与语言关系;公共分类检查/政策用例;必需未知、工具、构建、输入失败仍为 2;仅在可靠时报告源码位置
R2 三种语言组织;严格/手册和本地化政策;重复、缺失和草稿状态;显式版本化审阅记录绑定源语言及源/译文哈希;有语法边界的原生规则;有效主题覆盖;可见版本化基线;审阅修复先验证再窄范围应用 未完成:初始审计时无翻译/审阅/原生规则/基线公共命令;可复用产物引用检查 A04–A07;经审阅的有效/无效内容语料;不用 mtime 推断审阅;处理禁用/本地化语言;已确认问题仍可见;必需检查缺失仍为未完成;修复保留文件
R3 保留默认透明 build/dev;build --check 在一次严格 Hugo 输出上检查和生成 manifest,只导出到新建/空目标;摘要/来源 manifest 和可选最小公开身份;两种本地 CI 模板上传同一树;发布诊断;显式联网公网验证 部分已有:直接封装、严格隔离检查和有许可证的工作流输入;初始审计时缺少受管理构建/导出、摘要验证、CI 计划和公网 verify A08–A10;恰好一次 Hugo 构建;拒绝字节漂移;revision/dirty/input/theme/tool/settings/coverage 来源不含秘密或本机路径;工作流定制/冲突/来源及不可变源码输入;示例地址政策;回退/语言/资源/canonical/超时/认证/限流 HTTP 夹具
R4 new、片段和编辑器配置创建普通输入且不覆盖;docs/blog/book/project 配置组合复用一个有许可证的 Starter;升级提供可读 diff 及新旧路由、别名、启用输出;不支持迁移给出人工操作;保留原有保护 部分已有:固定归档语言配置、绑定哈希的单站模块升级、候选验证、备份,以及脏文件/workspace/replacement/vendor 保护 A11–A12;所有新增配置/语言组合可用普通 Hugo 构建;保留未知编辑器设置;升级路由/能力回归和可读 diff;保留来源与许可证
R5 inspect、impact --since、受限 context、默认预览 move;共享计划包含文件、diff、基线哈希、翻译、附件、输出/路由变化和别名建议;候选验证与过期/并发安全恢复;含糊引用要求审阅 部分已有:模块专用升级计划/应用基础;初始审计时无共享内容计划或 inspect/impact/context/move 流程 A13–A15;删除 B 包含未改入站 A;翻译/附件/派生产物影响;不确定/全局变化强制全量检查;不执行内容;候选/过期/写入失败保护及含糊链接处理
R6 显式版本化站点注册复用单站引擎;逐站与汇总完成状态;只写选定站点;已配置且预先供应的 markdownlint/Vale/lychee 适配器规范发现项并声明语法/网络覆盖 未完成:初始审计时无 workspace/adapter 公共命令 A07/A15/A18;直接/逐站一致;无同级发现、隐式安装或默认格式化写入;必需工具缺失为 2,可选遗漏可见,外网不确定性明确区分
R7 只读 loopback Studio,提供概览、问题、翻译比较、页面关系和发布视图;筛选、已知来源、真实 Hugo 预览、比较与复制操作;CLI 一致;预构建资源;显式 allowlist、独立预览 origin、Host/Origin/session 保护 未完成:初始审计时无 Studio 服务或资源 A16;真实浏览器/键盘/读屏/移动端/深浅色/长列表流程;使用相同 CLI 结果;拒绝未授权 host/origin/session 和预览到管理接口请求;消费者运行不需要 Node
R8 Markdown/文本和 front matter 表单、选定组件与不覆盖附件复用计划;授权允许范围内写入须有可见 diff、哈希和候选验证;无修改字节及未知字段/注释/顺序/编码/空白保留;表单不支持的语法保留文本模式 未完成:编辑在只读 R7 验收后实施;初始审计时无编辑 API A17/A14;无修改字节一致、YAML 字段定点更新与文本回退;外部编辑器过期保存、路径穿越/符号链接逃逸及预览请求安全失败;附件不覆盖;静态发布无管理 API

R1 本地验证

R1 现已提供共享 Hugo 页面/翻译/来源事实、产物引用与锚点证据、严格 oink.policy/v1 输入、check links、--format json、可见的经审阅排除/外部范围, 以及必需工作优先级。翻译和风格选择明确报告必需但不支持的覆盖,并非已实现引擎。 默认 build/dev 继续直接调用 Hugo。下列证据接受所测共享事实/政策范围, 不关闭 R2–R8 或完整 A01–A18 用例。

需求 已执行证据 当前结果
公共结果/政策与未完成优先级 make test:所有包与 vet;公共严重度/排除/未实现分组/JSON 别名测试;TestEveryRequiredUncompletedCoverageFails R1 范围通过;任何必需未完成状态(含 not_checked)仍为 2
一次构建与共享事实 TestPublicCheckSharesOneBuildAndRenderedFacts 通过;一次严格 Hugo 构建提供页面和实际目标/锚点事实
Hugo 权威与来源映射 真实 TestPageFacts* 夹具:translationKey、实际路由/别名、未知生成节点、自定义挂载、未发布页面分析及失败保护 通过;独立分析保留生产事实/产物字节及源码字节/模式
可复现真实 Hugo 验收 修正后的 make test-hugo 包含 TestPageFacts*、TestHugoRendered* 及 Starter/manifest 夹具 通过;覆盖范围内的路由/引用、经审阅外部范围和原始产物保留场景
新 Starter 双语 init、check links,使用隔离且已供应的 v1.1.0 模块归档运行普通严格 Hugo 退出码 0;223 个文件、4,461 个引用、66 个页面事实;依赖预备仍须显式进行
R1 文档源码与 Schema content/docs Markdown 风格;双语源码检查;CLI/文档结果 Schema JSON 解析及相同检查;限定 diff 空白检查 通过:88 个中文 docs、137/137 组源码、1,085 个标题;Schema 保持可增补的 oink.result/v1 和退出码 0/1/2
最终候选报告与中英文产物 刷新后的当前二进制消费站报告;下文真实产物源码/Markdown/链接归属检查 R1 范围通过;生产环境中已有草案发布页缺失单独记录

较早离线 R1 试验在三个消费站上均返回 0 且无发现项:

较早试验 源文件 产物文件 HTML 文件 引用 页面事实 字节/模式/Git 清单
OINK 文档站 421 1,139 512 74,689 341 前后精确相同
PIG 项目站 858 1,392 424 64,440 248 前后精确相同
软件仓库目录 2,294 3,287 1,635 851,535 1,572 前后精确相同

这些较早报告把可选未选中覆盖写为 not_selected,不属于已有结果 Schema 的枚举值。 最终代码已修正为 not_checked 并包含 project.pages 覆盖。 计数及精确清单仍是较早二进制的有效观察;下方最终刷新报告证明 JSON 合规。 原始证据保留在消费站源码外、带任务名称的本地验收目录。 这些试验不证明外链可访问性、部署、Linux 运行环境或翻译/风格验收。

最终 R1 二进制由基于 e623d93d589c49e5c58b8fae1bd5db720fc904cb 的 CLI 脏工作树重新构建。记录的输入清单包含文件哈希、模式和 Git 状态身份, 按排序后的 JSON 序列化计算 SHA-256 为 518260f07f3c916468ee3d56c4eeca03c131514155aa82539564ccd2f3c1f664。 实际运行二进制 SHA-256 为 3deb7e357fc86f6907df60da0769d93f2d41ba5e01949b641548a67d7f459d12。 它们标识本地输入和已执行二进制,不表示维护提交、公开归档或已发布模块。

最终当前二进制试验 源文件 产物文件 HTML 文件 引用 页面事实 验收
OINK 文档站 421 1,139 512 74,755 341 退出码 0、结果有效、页面事实完整、源码字节/模式/Git 精确保留
PIG 项目站 858 1,392 424 64,440 248 退出码 0、结果有效、页面事实完整、源码字节/模式/Git 精确保留
软件仓库目录 2,294 3,287 1,635 851,535 1,572 退出码 0、结果有效、页面事实完整、源码字节/模式/Git 精确保留

最终结果均有必需的 check.links: complete 和 project.pages: complete。 未选中翻译/风格覆盖为可选的 not_checked。最终离线 make test 与 vet 通过, 修正后的真实 Hugo 归属目标也通过。记录的工具仍为 macOS arm64 上的 Go 1.27.1、 Hugo Extended 0.166.0、Git 2.54.0。编写本记录时独立比较了三个精确前后清单。

生产产物通过 Markdown 和链接检查。全站翻译检查返回 1,唯一原因是已有草稿 content/blog/release/1.2.0.md / .zh.md 正确地没有进入生产产物。 R1 修改页面均已双语渲染。另一个显式分析构建将 HUGO_BUILDDRAFTS、 HUGO_BUILDFUTURE 和 HUGO_BUILDEXPIRED 设为 true,三项归属检查均通过: 137/137 组源码、1,085 个标题、产物 Markdown 与产物链接。 该视图属于不可发布的排除源码证据,从未替代生产产物,也不修改或发布草稿。 没有为了让全站生产检查变绿而修改已有草稿文件。

R2 本地验收

本地候选已实现翻译政策/状态/diff/哈希审阅、有界原生内容规则、可见的经审阅基线, 以及共享 oink.plan/v1 预览/验证/应用。默认 check 要求链接、翻译和风格。 生产输出与显式草稿/未来/过期分析相互独立,后者不可发布。稳定行为与示例见 契约与 指南。R2 本地门禁已通过归属检查、最终冻结输入 消费站报告及产物双语文档。下文分别记录确切实测二进制和后续有界相等比较修复, 不表示公开发布或消费站写入。

需求 已执行归属证据 结果与限制
A04 翻译关系/政策 真实 TestHugoFilenameDirectoryAndTranslationKeyLayouts;范围、重复/缺失/禁用语言、草稿、严格/本地化和选定约束测试 归属测试通过;不要求普遍标题/代码/本地化一致
A05 显式审阅和 diff 完整字节哈希/当前/源/译文/双方变化、不依赖 mtime、未知/不可读/含糊和错误记录;公共 status/diff/review 预览/应用 归属测试通过;审阅状态是变化证据,不是语义判断
A06 源码边界和来源 真实 Hugo 规范 title/块属性开关和配置透传夹具;front matter/CRLF/BOM/短代码/代码/HTML;每个公开 v1.1.0 源码/许可证 SHA 验证 归属测试通过;不支持语法仍未完成,自定义钩子不在目录证明范围内
A07 基线范围 捕获/可见确认/新问题/未完成优先级及错误记录;公共基线预览/应用 R2 基线范围通过;外部工具适配器验收归 R6
A14 共享元数据计划 过期字节/模式/存在/保护条件;验证中编辑;排他提交碰撞;部分恢复;后续字节/模式/删除;旧打开 inode 写入;新目录子文件;范围/身份/diff 归属测试与 vet 通过;拒绝候选/源码重叠;move/引用歧义仍归 R5
冻结运行门禁 macOS arm64 make test/vet、归属真实 Hugo、聚焦 race 通过;日志 /tmp/oink-r2-frozen-go-gate.log、/tmp/oink-r2-frozen-hugo-gate.log、/tmp/oink-r2-frozen-race-gate.log;最终全部归属包 Hugo 门禁 /tmp/oink-r2-owning-hugo-final.log 明确包含配置透传
双语文档 限定源码风格/配对/ID、相等结果 Schema、范围内空白及真实生产/分析 node 检查 范围门禁通过:88 份中文文档、137/137 源码配对、1,092 标题;生产草稿缺失在下文单独记录

冻结解析器语料位于 /var/folders/df/bfm8q07d7bv3kpjf1fjchq4m0000gn/T/oink-r2-source-corpus-lqx25kwr/summary.json, 解析器输入 SHA-256 为 a601200ec4fe275d2bd4baf11d4db7d46a2cc6f1674900c1fd801769e55d12de。 每项范围均完整解析且无发现项。核心范围使用已记录配置下 Hugo 实际站点源码身份; 补充 Markdown 包含禁用/未发布文件,不虚构路由或关系。这些捕获早于已授权的 R2 文档修改。

语料 Hugo 实际源码去重文件数 补充本地 Markdown 源码清单文件数 字节/模式/Git
Starter 52 78 97 精确前后相等
OINK 文档站 272 274 421 精确前后相等
PIG 212 212 858 精确前后相等
软件仓库目录 1,568 1,572 2,294 精确前后相等

初步公共命令报告位于 /var/folders/df/bfm8q07d7bv3kpjf1fjchq4m0000gn/T/oink-r2-final-qu_zprps/summary.json, 使用二进制 c8d87e6d73d3101fefcb62c5d6845518573c02c400f474dc9f4603afafc774d5, CLI 输入清单为 d8a75be0e074365a4164b7aaaa27d82a1e844e04406a36c3dd6d39ff2b6e873f。 这些报告早于最终解析器/文档冻结,不是最终验收证据。最初 Starter 命令错误选择了 外层证据目录并返回 2,属于验证环境选择错误。改选其实际 site 子目录后返回 0,证据位于 /var/folders/df/bfm8q07d7bv3kpjf1fjchq4m0000gn/T/oink-r2-starter-27vmi0w5。

初步检查 退出码 页面事实 构建文件 引用 翻译状态 结果
正确 Starter 子目录 0 66 223 4,461 28 完成;97 个源码文件/清单不变
文档站 0 341 1,139 74,755 144 完成;421 个源码文件/清单不变
PIG 0 248 1,392 64,440 120 完成;858 个源码文件/清单不变
软件仓库目录 1 1,572 3,287 851,535 788 已完成政策检查:既有合并打印输出中有 10,462 项实际 HTML_ID_DUPLICATE;2,294 个源码文件/清单不变

软件仓库目录的结果是已完成的发现项结果,不是站点通过或实现失败。 没有降级政策,也没有修改消费站源码。信息性审阅状态仍保持可见。 最终冻结输入报告位于 /var/folders/df/bfm8q07d7bv3kpjf1fjchq4m0000gn/T/oink-r2-candidate-6xzcs7fk/summary.json, 实测二进制 SHA-256 为 ff88b407a6cddb9007f94275c65a80ed4c9c4fd13f5e821f9b7a4a8973abaa56, CLI 输入清单为 bd8c71b55250a89dc15c7534924bb82a5447d6f2628eba23c8cb3d864309ee9f。 独立比对确认四份源码字节/模式/Git 清单操作前后均精确相等,替代初步公共命令试验:

最终检查 退出码 源码文件 页面事实 构建文件 引用 翻译状态
Starter 0 97 66 223 4,461 28
文档站 0 421 341 1,139 74,825 144
PIG 0 858 248 1,392 64,440 120
软件仓库目录 1 2,294 1,572 3,287 851,535 788

最终报告均无未完成诊断。软件仓库目录保留 10,462 项实际合并打印 HTML_ID_DUPLICATE 和 788 项信息性审阅状态;其他站点保留信息性的未知审阅状态。 这接受实测检查行为和源码保护,并未将软件仓库目录称为通过的发布。

保留的生产文档位于 /private/var/folders/df/bfm8q07d7bv3kpjf1fjchq4m0000gn/T/oink-site-2201601475/public, 产物 Markdown 和链接通过。全站翻译检查返回 1,仅因既有草稿 release 1.2.0 双语页面未进入生产。另一个明确不可发布的草稿/未来/过期分析位于 /private/var/folders/df/bfm8q07d7bv3kpjf1fjchq4m0000gn/T/oink-site-3698773232/public, 三项 node 检查均通过:137 配对/1,092 标题、216 内容页面/41,586 文本节点, 347 页面/48,682 内链/4,171 片段。证据日志为 /tmp/oink-r2-docs-production-{translations,markdown,links}.log 和 /tmp/oink-r2-docs-analysis-{translations,markdown,links}.log。 分析输出或创作草稿均未替代生产,也未发布。

最终审阅发现可选 equal_fields 仍按表示形式比较 JSON 7.0 和 YAML/TOML 数值 7。有界补充现将已解码数值递归规范为精确有理数标签,保留字符串与数值、 映射键及数组顺序的区别。测试覆盖小数/指数、负零、超出 float64 精度的整数、 嵌套差异、源码字节保护,以及不可表示值导致必需未完成。 真实 Hugo 翻译测试在 /tmp/oink-r2-numeric-translations-gate.log 中通过, 全部公共维护真实 Hugo 用例在 /tmp/oink-r2-numeric-public-gate.log 中通过, 归属 vet 和空白检查通过。补充源码 SHA-256 为:

源码 SHA-256
internal/translations/check.go 24664377e14b4ae2fc554d0d7fde2ec33cc987707250e130fd88d9a25d5e1637
internal/translations/translations_test.go f58f4a305fe9fe3f5500ddfcf85faf3cfa37d72f8c220a1cb16ce4ccfbddb74d

冻结真实站点报告及上下文 Linux 验收早于该补充。对应站点没有配置数值相等约束, 记录的输出不受影响,因此没有为这项有界修复重跑。后续完整运行与归档验收必须 刷新后续源码。本次证据修订属于验收运行后已授权文档写入,前后源码保护范围结束 于修订之前。

A18 仍未完成。macOS arm64 已实测;本机尝试 Darwin amd64 运行时, arch -x86_64 返回 posix_spawn: Bad CPU type in executable (/tmp/oink-r2-darwin-amd64-gate.log)。这是主机运行支持不可用,不是代码失败, 也不是 Darwin amd64 验收通过,未安装系统组件。原生 Linux arm64 和 Docker Desktop Rosetta 模拟的 Linux amd64 均实际执行,同一运行/Schema/许可证输入 SHA-256 为 0f786df68ef3c4844c983a51595f79242d1cb1d2bf6c5b5eb7f2c6415fb8d861。 证据保留在 /var/folders/df/bfm8q07d7bv3kpjf1fjchq4m0000gn/T/oink-a18-linux-ajbbnvki 的 arm64-results、amd64-results、commands.json、candidate-inputs.json、 preparation.json 和 qualify.sh。每个目标均通过 270 个测试/子测试,无失败, 仅跳过两项可选外部语料/来源验证:完整真实 Hugo go test ./...、vet、构建 CLI 版本/双语 init/doctor/完整 check/翻译 status,以及缺失 Hugo 退出 2 smoke。 JSON stdout 和源码字节/模式清单均核对。Go 1.27.1 运行在 Linux arm64, Hugo Extended 0.166.0 各架构资源已核对 SHA。这证明对应源码运行路径, 不证明最终归档或托管 CI。Darwin amd64 仍未完成,交叉编译不能关闭它。 后续阶段及未来命令/适配器/浏览器验收仍未完成。

R3 本地验证

R3 新增受管理 build --check、oink.artifact/v1 封存/导出/本地验证、 显式联网 HTTP 验证、发布诊断和受保护的本地 CI 生成。默认 build/dev 保持普通 Hugo。 已执行运行和中英文契约/指南门禁通过,R3 已本地接受;未运行托管 CI 或部署。

需求 已执行归属证据 结果与限制
A08 单份检查产物 公共模拟/真实 Hugo 单渲染器测试;精确导出、manifest/标记、检查后字节/模式/缺失/新增/符号链接篡改、失败/并发及源码保护测试 本地范围通过;失败/未完成检查不能封存或导出;本地产物验证不重建
A09 两种 CI 服务商 离线确定性生成、固定源码/Hugo 归档和 action revision;安全 bootstrap 归档;受保护公共预览/应用/过期输入;真实 Hugo 原始输入绑定 本地配置范围通过;拒绝所有已存在生成目标,定制工作流不变
A09 上传身份 两种本地服务商演练及 TestProviderUploadRehearsalPreservesActualSealedManifestIdentity 通过:一次受管理构建、单独验证、再使用同一树;GitHub tar 包含隐藏标记,Cloudflare 演练接收已验证目录;未执行服务商上传
A09 定制工作流诊断 已生成加其他定制、无元数据定制公共测试,真实 Hugo 预览与归属 vet 补充通过,日志为 /tmp/oink-r3-ci-custom-owning-gate.log 和 /tmp/oink-r3-ci-custom-vet-gate.log;未被元数据表示的工作流保持 unknown、信息级及可选 release.ci: not_checked,有效生成元数据旁也可见
A10 部署身份 本地 HTTP 全部记录文件/路由/语言、标记、canonical/base/惰性 template、HTTP 200 回退、错误字节/语言/构建、缺失资源/Markdown/搜索 JSON 夹具 本地夹具范围通过;确定差异为 1,浏览器 JavaScript 明确未检查
A10 网络未知状态 显式联网/凭据拒绝、响应头前/响应体中超时、认证/限流/服务错误、必需标记缺失、有界响应/gzip、重定向/无 cookie 夹具 本地夹具范围通过;未完成为 2,剩余请求为未知;未访问公开部署
冻结运行门禁 完整测试/vet、归属真实 Hugo 和聚焦 race macOS arm64 通过,日志为 /tmp/oink-r3-frozen-go-gate.log、/tmp/oink-r3-frozen-hugo-gate.log、/tmp/oink-r3-frozen-race-gate.log;后续定制 CI 修改由上述聚焦补充覆盖

最新单二进制语料位于 /var/folders/df/bfm8q07d7bv3kpjf1fjchq4m0000gn/T/oink-r3-ci-final-ahc4csjk/summary.json。 从精确捕获的 CLI 输入副本编译,二进制 SHA-256 为 425845c1d2db7b1cd3c3cdb5f28475cb06ba6f656054909759e2359a39925dd2, 67 个运行/Schema/许可证输入 SHA-256 为 6789a3a0235ff8d81453b9bfde37824979eac7d56af3710da390e4d2ef8479dc, 108 个更广 CLI 输入 SHA-256 为 4ca473a4cb586d232baeb4cee029b281469c5bb03c831cc199b95451e6832c60。 全部运行后运行输入仍精确相等。实时工具为 Darwin arm64 上 Go 1.27.1 和 Hugo Extended 0.166.0;manifest 的规范 Hugo 版本排除发行方构建文本与私有路径。

每次离线 build --check 使用消费站外的新导出/manifest 路径、可选标记和保留隔离 目录。已有本地消费站未使用 --release,保留其配置的 workspace。每份原始报告 均恰好一次严格 Hugo 渲染、零未完成诊断、零必需未完成覆盖。

最终受管理构建 退出码 源码文件 复制源码输入 页面事实 构建文件 引用 导出文件 本地产物验证
Starter 0 97 94 66 223 4,461 224 0
文档站 0 421 427 341 1,139 74,825 1,140 0
PIG 0 858 861 248 1,392 64,440 1,393 0
软件仓库目录 1 2,294 2,299 1,572 3,287 851,535 无 未导出

两份清单均精确比较操作前后字节、模式与文件类型,主清单还比较逻辑 Git 状态。 Git 站点包括 tracked 和未被忽略的 untracked 源码;无 Git Starter 包括既有生成 文件与锁。补充复制源码清单还包括快照读取的被忽略 workspace/编辑器元数据, 排除已有生成输出/缓存树。文件数不是证明,四份对比均精确相等。

软件仓库目录保留 10,462 项既有合并打印 HTML_ID_DUPLICATE,未创建导出或 manifest。 这是完整政策发现,不是通过的发布,也不是实现失败。生产审阅状态为 28/143/120/786; 分析包括未发布页,解释此前 R2 的 144/788。既有定制工作流信息仍可见, Starter 示例地址在此次非发布运行为警告。

三份新导出在全部原始文件 SHA-256、大小与模式上匹配保留的独立普通 Hugo 产物。 唯一新增文件为 .well-known/oink-build.json。原始源码清单与完整 manifest 输入哈希 均匹配此前捕获,复用普通产物未替换输入。辅助源码 SHA-256 为 13e4957a3d7847eb28c8b1eeba3588a4f4a9982c2bfca2ebc729ab2827159607, 二进制 SHA-256 为 b2699fe7a7aa3a34c41f9e4aba4b22d39cf8d0c156a369f3dfc4ca8c8c0fbce5。 原始辅助与普通产物证据位于 /var/folders/df/bfm8q07d7bv3kpjf1fjchq4m0000gn/T/oink-r3-candidate-wb643dhh; 编译辅助程序后删除临时构建源码。

此前 R3 捕获保留为历史:首次捕获早于运行冻结,首份冻结捕获 oink-r3-final-pisrr21h 早于定制 CI 诊断。最初选择 /Users/vonng/pgsty/PIG 返回 2,因为不同仓库不是目标站;改用 pig.pgsty.com 后通过。 保留这些环境选择试验,不改标为候选失败;最新语料替代此前受管理构建结果。 CI 模板/bootstrap 根据已记录服务商第一方契约独立编写,未纳入服务商实现源码。

限定 R3 文档门禁通过,证据为 /var/folders/df/bfm8q07d7bv3kpjf1fjchq4m0000gn/T/oink-r3-docs-render-pljj5aqd/summary.json。 十份成对契约/指南/路线图/索引/概览修改只有匹配原始字节/模式后才安装,哈希位于 /var/folders/df/bfm8q07d7bv3kpjf1fjchq4m0000gn/T/oink-r3-doc-drafts-s0b3g48l/applied-files.json。 源码风格通过 88 个中文文档,翻译通过 137 配对/1,099 标题,Schema 保持相等且限定 空白检查通过。真实生产 Markdown 通过 214 页面/41,871 文本节点,链接通过 345 页面/48,344 内链/4,171 片段。生产翻译仅因未修改的草稿 release 1.2.0 未进入生产返回 1。另一个明确不可发布的草稿/未来/过期分析通过 Hugo 及三项 归属检查:137 配对/1,099 标题、216 页面/42,177 文本节点、347 页面/48,720 内链/ 4,199 片段。产物检查期间 421 个规范源码和 488 个复制源码文件均保持精确字节/模式。 分析没有发布或替代生产,本次验收修订发生于该冻结保护边界之后。

该门禁不宣称托管工作流执行、上传、公开发布、最低版本组合、浏览器行为或本轮 Linux/Darwin amd64 验收。A18 仍未完成,历史 Linux R2 结果保留原始源码哈希。 已授权双语证据/契约/指南写入发生于保护清单之后,不属于其无写入范围。

R4 创作与升级验收

受支持 R4 实现与只读语料范围在冻结归属/全量门禁后已本地接受。本记录覆盖配置、 普通创作/编辑器/片段和有界升级视图。受保护规范文档推广与新产物限定验证也已通过, 详见下文;R5–R8 和最终 A18 验证保持未完成。

已执行配置证据 结果与限制
同一固定许可证归档 针对提交 137843b25bacd76ddd1f7ce71330bf2e3155b954 的快照核对未使用 --write 且通过;归档 SHA e55bde279715f6d8d19d3d88671a2cf7561b515be46915b0f12c640d0ce1d958 和 MIT 许可证不变,投影元数据/脚本匹配
组合与保护 默认/显式 project 字节一致,选定归档模型/本地化首页、无效配置、非空目标、并发验证/发布和取消恢复测试通过;单元/vet/race 门禁通过
普通 Hugo 四种配置 × 三种语言 × 根/子路径,共 24 次真实严格离线构建通过,使用预备的公开 OINK v1.1.0;完整源码字节/模式/无额外文件及产物引用检查通过
公共 init 流程 四种配置 en/en,zh、后续根/子路径实际 Hugo URL 事实/检查、工作流/许可证保护与默认一致通过;未知/非空拒绝 1,Hugo 缺失/失败 2,空/不存在目标及纯 JSON/独立日志已验证
公共创作与来源身份 实际候选/应用/普通 Hugo、未知审阅与源码保护通过,见 /tmp/oink-r4-authoring-public-gate.log;新目录/站点保护与 vet 通过,见 /tmp/oink-r4-new-input-race.log、/tmp/oink-r4-public-core-vet.log。实际被忽略输入即使源码检查组关闭也拒绝 2,不保存计划、不写源码;选定译文草稿仍强制分析来源身份,见 /tmp/oink-r4-authoring-sourceproof-gate.log。受支持归属范围通过
有界升级归属门禁 七个真实 Hugo 固定合成模块用例、观察流摘要/产物清单一致、独立跨页面 alias 改指向阻断,以及源码/并发/排他写入和保留后续编辑的回滚保护通过 race;vet 通过。最终加固日志 /tmp/oink-r4-hardening-owning-gate.log、/tmp/oink-r4-hardening-final-focused.log、/tmp/oink-r4-hardening-vet.log;最终公共/全量冻结门禁通过
创作/编辑器集成加固 实际 Hugo 语言目录计划/应用/普通构建、link/never 新来源拒绝、外部 Schema/许可证/完整模式/模块身份及旧 Schema 重新证明、共享翻译/基线/CI 回归,以及完整 Starter docs→新译文草稿→编辑器→检查→普通 Hugo 流程通过。/tmp/oink-r4-app-authoring-hardening-gate.log(58.241s),聚焦 race/vet 通过;候选后外部修改证明 /tmp/oink-r4-app-external-during-validation.log 通过。不透明保存输入哈希与规范 workspace 来源保护见 /tmp/oink-r4-external-plan-binding-final.log、/tmp/oink-r4-workspace-origin-gate.log 及其 vet 日志。冻结全阶段、语料和限定规范产物文档门禁通过
实际语言挂载 独立的逐语言 contentDir 和显式站点矩阵夹具均通过 config/mounts/严格构建,源码字节/模式不变。Hugo0.166 输出 sites.matrix.languages,不同物理文件具有互为译文的公共关系。/var/folders/df/bfm8q07d7bv3kpjf1fjchq4m0000gn/T/oink-r4-language-mounts-lgmve1sk/summary.json;公共实际语言目录计划/应用/普通 Hugo 集成通过

归属证据保留于 /var/folders/df/bfm8q07d7bv3kpjf1fjchq4m0000gn/T/oink-r4-starter-owning-0pv41lw5/summary.json。 日志为 /tmp/oink-r4-starter-{unit,hugo,vet,snapshot,race}-gate.log、 /tmp/oink-r4-public-init-gate.log 与 /tmp/oink-r4-public-init-vet-gate.log。 生成源码数量为 project 94、docs 58、blog 40、book 34。未编辑 Starter checkout, 未公开发布、消费站采用或部署。

最终冻结门禁均为 0:make test/vet 见 /tmp/oink-r4-frozen-go-gate.log, make test-hugo 见 /tmp/oink-r4-frozen-hugo-gate.log,真实 Hugo 核心 race 见 /tmp/oink-r4-frozen-core-race-gate.log。最终公共流程覆盖 Starter docs → 主页面/ 译文草稿 → 编辑器 → 检查 → 普通 Hugo;候选验证后的外部 Schema 修改仍在写源码前 拒绝。17 份归属与三份最终门禁日志及哈希原样保留在最终语料 owning-gates.json。

准确四站证据为 /var/folders/df/bfm8q07d7bv3kpjf1fjchq4m0000gn/T/oink-r4-corpus-lw2cjyq6/summary.json, 另有有界 summary.compact.json、原始 JSON/日志和逐命令清单。二进制 SHA 为 c169b3d4d046c811dca80867068b86fb66ada5c8ce6910dd5cda7353c406f377;82 份运行时输入 SHA 为 fdff7f50d49b44f03fa1db79eec6b6c9b9bd5e52f8967a88aed84b3207a7b3c6, 与最后根清单完全相等,无运行时修改。139 份完整 CLI 输入 SHA 为 562e838d9eccb628eac86ae59b9b9587c1e23ad52991ec50eafb1e604e3924da。 驱动 SHA 为 d3ac41dc2e18295bfb26134d1a696935c8174913e2801a5766dbf7a1139d89f8。 实际工具为 macOS arm64 上的 Go 1.27.1 与 Hugo 0.166.0 Extended。

冻结消费站 主/复制源码文件 页面;输出文件;引用 受管理构建 / 产物验证 只读 upgrade / new / editor
Starter 97 / 94 66;223;4,461 0 / 0;含 marker 导出 224 份 0 / 0 / 0
文档站 421 / 427 341;1,139;74,937 0 / 0;含 marker 导出 1,140 份 0 / 0 / 0
PIG 858 / 861 248;1,392;64,440 0 / 0;含 marker 导出 1,393 份 0 / 0 / 0
Repository 2,294 / 2,299 1,572;3,287;851,535 已完成发现 1;无导出/manifest 已完成发现 1;阻断后未尝试 new/editor

每次受管理构建恰好使用一次严格生产 Hugo 渲染,没有必需未完成或未完成的必需覆盖。 Git 可见主源码字节/完整模式/逻辑 Git 状态、补充复制输入以及源码目录模式在每条命令 和完整站点流程前后均精确相等。Repo 既有 merged_print 中 10,462 处重复 HTML ID 保持可见;其已完成发现既不是通过产物,也不是实现失败。未调整政策或消费站输入。

消费站升级预览选择已有公开 v1.1.0 pin,不应用写入;跨版本路由/alias/输出回归采用 明确合成夹具 pin,不虚构已发布主题版本。New/editor 计划为已验证预览,未在消费站 保存或应用计划。多主机及未知相对 alias 身份保持未完成。非确定性产物可能需要重新 预览 v2 计划;浏览器/普遍兼容、配置迁移及当前跨平台/归档验证不在此限定结果内。 此前 Linux R2 输入哈希仍属历史证据;Darwin amd64 与最终 A18 刷新仍未验证。 获授权的中英文规范写入只在这份冻结无写入证据边界之后发生。

父任务应用十份受保护文件后,新的规范文档验收通过。证据为 /var/folders/df/bfm8q07d7bv3kpjf1fjchq4m0000gn/T/oink-r4-docs-render-v01eima0/summary.json; 推广清单为 /var/folders/df/bfm8q07d7bv3kpjf1fjchq4m0000gn/T/oink-r4-doc-drafts-3i8bw994/applied-files.json。 冻结 c169b3… CLI 执行一次严格生产构建,定点链接检查返回 0。

新规范文档门禁 已执行结果
源码归属检查 翻译 0:137/137 对、1,104 标题;完整规范样式 0:137 份中文文件、181 处加粗、无强调;十文件空白检查与公共 JSON Schema 一致检查通过
生产 Markdown/链接产物 均为 0:214 个内容页面 / 42,214 个文本节点;345 个页面 / 48,360 个内部链接 / 4,187 个片段
生产翻译 1 仅因既有草稿 content/blog/release/1.2.0.md 不在生产产物中;无新增配对/标题问题
单独不可发布分析 新普通 Hugo 使用实际原快照环境/重定位路径及显式草稿、未来、过期选项,返回 0;三个归属检查均 0:Markdown 216 页 / 42,520 节点,链接 347 页 / 48,736 链接 / 4,215 片段,翻译 137/137 对 / 1,104 标题
源码保护 规范 Git 清单 421 份文件和复制输入 427 份的字节、模式、Git 状态与目录模式完全不变;生产复制 428 份、分析复制 427 份文件在检查中不变;分析构建也保留复制文件完整模式

生产产物保持独立,未被分析树替换;分析不可发布。临时辅助程序复制冻结核心而不 修改它:辅助源码 SHA 7faea7e726a6c6fb2e0747be1a4428f4c5fb5734fa52b6f981157a5fe37d9989, 辅助二进制 SHA 532638e76f96f8b173c122e512b3bf5fc2c4d4a7130f59c99c2c69e135e87073, 与原始日志一并保留。获授权的双语研究补录发生于精确无写入捕获边界之后,另行接受 定点源码检查。R4 本地限定文档门禁已接受;该结果不宣称公开发布、部署、R5–R8 完成或最终 A18 验证。

R5 实现与文档验收

R5 受支持范围在聚焦公开命令/核心、修正冻结全阶段、精确二进制只读消费者及 受保护规范源码/渲染文档门禁后已本地接受。有界结果保持明确,见下文。R6–R8、 workspace A15 与最终 A18 验收保持未完成。首次晋升与单独授权的渲染后状态/证据 修订保留不同的保护边界。

实际公开 Git/Hugo 流程在 /tmp/oink-r5-public-final-flow.log 以 53.963 秒通过。 已提交的合成站点拥有本地主题、双语页面及二进制附件;普通 0640、0600 保持为 完整当前事实,历史 Git 比较仅使用可执行位。删除乙后纳入未改入站甲、剩余翻译、 删除的附件与实际 RSS 输出。实际 alias 入站归属不确定性、全局配置/模板/数据及 未知输入变更扩大为全范围。

完成的 inspect/impact/context 返回 0,单独展示当前检查发现 1;check-since 保留当前质量 1 与完整验证范围。缺失、未提交或外部历史返回 2,保留全部已知 当前页面、附件、引用、输出,不虚构旧身份或变更。已测试无效选择器/限额、缺失工具 及失败渲染器日志。有界上下文提供理由、版本、源码及摘要哈希、可见遗漏/截断,不 执行文档字面指令。

保存移动预览/应用及随后普通 Hugo 已通过,保留二进制字节、原始完整模式、无关 文件与 Git index/revision。实际不透明 HTML/shortcode 引用保持人工动作;inline、 fence 与不透明片段保持不变。它们的最终断链候选返回 1,无保存计划或源文件 写入。源码、配置、附件、模式或新目标漂移返回 2,保留后续编辑。实际候选渲染器 之后的确定性变更同样在写前拒绝,保留编辑者字节/模式。聚焦实际移动 race 在 /tmp/oink-r5-public-move-race.log 以 8.286 秒通过;app vet 在 /tmp/oink-r5-public-vet.log 通过。

缓存模块补充之前,冻结父级 make test/vet 与 make test-hugo 分别在 /tmp/oink-r5-frozen-go-gate.log、/tmp/oink-r5-frozen-hugo-gate.log 通过 (实际 app 夹具 185.709 秒)。实际移动/源码 race 与 vet 在 /tmp/oink-r5-move-hugo-gate.log、/tmp/oink-r5-source-move-race-gate.log 及其 vet 日志通过;完整清单/模式/选择器计划保护在 /tmp/oink-r5-plan-owning-final.log 通过。

首轮冻结消费者试验发现实际缓存公开模块保护缺口:原始关系图含已解析模块输入, 新的外层候选哈希却未纳入它们,产生错误未完成 2,没有源码写入。内容计划现先 解析/捕获同一模块输入再比较,并保留旧元数据/创作计划范围。独立的校验和验证公开 OINK v1.1.0 回归在 /tmp/oink-r5-public-cached-module-move.log 以 27.42 秒 (package 28.220)通过预览、重新验证已保存应用与普通双语 Hugo,保留原始模式、 二进制字节、无关输入与 Git。修正当前二进制语料及补充 race 证据与旧未接受试验 分别记录。

修正当前候选的完整 make test/vet 在 /tmp/oink-r5-corrected-frozen-go-gate.log 通过;实际 make test-hugo 在 /tmp/oink-r5-corrected-frozen-hugo-gate.log 通过(app 278.787 秒)。缓存公开/ 已提交站点内部移动保护 race 在 /tmp/oink-r5-public-cached-seam-race.log 以 38.578 秒通过,app vet 也通过。

/tmp/oink-r5-corrected-runtime-freeze.json 记录 96 个运行输入,SHA-256 为 e5b6e0eda972116dbb94a8086668e6ef34bfaa56138cf31f1f71f4832c477842; 165 个较广 CLI 输入的 SHA-256 为 4965a0c92cb6126f67a6dabd548c7c25ee5d7c9c57e14cce5e55ebb7a22fca2d。 修正二进制 SHA-256 为 d7675aecca2f77b1eb37bb4f664c3314cf5207149e6abbb86523686c5c50bff0。 这些是本地工作输入/可执行文件身份,不是新 commit 或发布归档。修正四消费者捕获 在 831.825 秒内完成 16 个命令,证据位于 /private/var/folders/df/bfm8q07d7bv3kpjf1fjchq4m0000gn/T/oink-r5-corpus-corrected-y2eue81h。 有界 final-receipt.json 的 SHA-256 为 b86e0e6c7dbfbaed62c845c03a55d963068f7d9a16771de5ff3b0974e76fce3b; 记录保留 12 份归属门禁日志、全部 20 条实际移动路由,以及完整原始 JSON/日志和 各移动分类文件的位置。

站点 主源码/复制输入/目录 Inspect/context 当前检查 Impact 移动预览
Starter 97/94/21 0/0 0 2:无 Git 基线 0:已验证,未应用
文档站 421/427/109 0/0 0 0:完整历史比较 1:六条候选缺失引用
PIG 858/861/52 0/0 0 2:历史外部输入来源未完成 1:32 条候选缺失引用
仓库站 2294/2299/48 0/0 1:已有 10,462 个重复 HTML ID 2:未提交 HEAD 基线不可用 1:同一批已有重复 ID

Starter 与仓库站 impact 保留已知当前事实,不虚构旧页面或变更。PIG 实际基线 完整(主题 v1.0.0 对当前 v1.1.0),但必需外部输入来源未完成,因此比较扩大为 全范围并返回 2。这些结果分别记录。文档站 impact 完成,包含 192 个捕获输入 变更、343 个受影响旧/当前页面并采用全范围。已完成事实查询独立展示当前质量发现; 仓库站 inspect/context 仍为 0。

文档站移动证明 18 处重写及四条路由。content/docs/customize/repository.md 第 216、313 行两个普通字面 /docs/admin/comments/ 目标保持人工动作,因为 普通/打印输出的重复源码/输出出现位置无法精确归属。六条候选缺失引用阻止验证。 PIG 移动两个 Markdown 文件及四个二进制附件,证明八条页面/处理后资源路由。 配对且字节相同的输出证明处理后 featured_hu_* 资源,但未证明四个原始绝对图片 引用 /article/pgext-day/{featured,topic,venue,schedule}.webp 的新 URL。 32 条候选缺失引用阻止验证,不猜测重写原始资源 URL。这些普通 Markdown 边界 与不透明 HTML/shortcode 边界分别记录。

仓库站移动证明十处重写及四条路由;候选只有同一批已有 10,462 个重复 ID 发现, 没有新缺失引用或必需未完成发现。Starter 无入链的双语移动已验证。四次移动均未 应用,未保存消费者计划或写入消费者源码。失败候选为 validated: false。 全部 JSON stdout 纯净;主源码、复制输入、完整模式、目录清单及逻辑 Git/index 状态保持不变,包含忽略的复制输入。Git 元数据清单不包含不可变对象存储。 运行与较广 CLI 清单仍匹配捕获身份。本记录不验证其他平台、浏览器运行或部署。

首次十文件受保护规范晋升使用上述修正冻结二进制/运行哈希,在 62.37 秒内 完成验证。独立渲染记录为 /var/folders/df/bfm8q07d7bv3kpjf1fjchq4m0000gn/T/oink-r5-docs-render-ks2tw82c/summary.json, SHA-256 为 06ae844a4b3f1c01bb5faa8a21091d5461c28aab592d12c4310fb34bc176c5d4。

规范文档门禁 已执行结果
源码归属检查 翻译 0:137/137 对、1,109 标题;样式 0:137 份中文文件、181 处加粗、无强调;限定空白与公共 JSON Schema 一致检查通过
冻结 CLI 使用精确修正二进制的生产 check links 返回 0
新普通生产 Hugo 构建 0;Markdown 0:214 页面/42,571 节点;链接 0:345 页面/48,376 链接/4,203 片段
生产翻译归属检查 1 仅为普通生产输出中已有 draft release-1.2 缺失;无新 R5 差异
独立普通分析 Hugo 新的不可发布 -DFE 构建 0,不使用 CLI probe;Markdown 0:216 页面/42,877 节点;链接 0:347 页面/48,752 链接/4,231 片段;翻译 0:137 对/1,109 标题
输入保护 全部逐命令及总体保护条件通过:421 主源码、427 复制输入、109 目录、36 可变 Git 文件保留字节/完整模式/逻辑 Git 状态;两个隔离源码副本均不变

分析树没有替换生产输出,也不可发布。首次晋升的永久 applied-files.json 位于 /var/folders/df/bfm8q07d7bv3kpjf1fjchq4m0000gn/T/oink-r5-doc-drafts-t3_klnck, 保留十个授权文件及其原始模式。这次单独授权的渲染后修订仅触及成对提案/索引/研究 六个文件,发生在已记录无写入边界之后;已验证契约与指南字节保持冻结。受保护原文、 准备 diff 与定点源码检查单独保留。不追溯宣称后续证据字节属于先前渲染捕获,也不 从修订推断完整语料或渲染重跑。

核心归属日志 /tmp/oink-r5-frozen-core-hugo.log、 /tmp/oink-r5-owning-race.log、/tmp/oink-r5-owning-vet.log 已通过。A13 影响 与 A14 移动保护所需受支持 CLI 范围通过;A15 有界上下文通过,workspace/direct 一致性仍属于 R6。不宣称消费者写入、提交、发布、网络部署、远程模型集成或增量提速。

R6 工作区与适配器验收证据

R6 受支持范围在冻结归属/运行时、精确二进制消费者一致性/保护及受保护规范 源码/渲染门禁后已本地接受。受支持登记/工具字段归属 契约与 指南。R1–R6 已本地接受;历史收据保持不变。 A07 适配器与 A15 工作区/直接/context 受支持范围通过下列门禁;R7/R8 与最终 A18 仍未完成。

登记独立版本为 oink.workspace/v1:严格单文档普通 YAML、1–64 个条目、最多 256 KiB、准确 ASCII 名称、字面相对/绝对目录、已证明的规范身份,以及重叠拒绝。 缺失站点保持逐站未完成,后续选定站点继续运行。选择保留登记顺序;不提供默认登记 站点、同级发现、Hugo 设置复制或自动多站应用。可选工具扩展 oink.policy/v1, 固定协议版本,提供配置/完整模式来源,以及类型化遗漏/覆盖。

工作区归属收据

聚焦门禁 已执行本地证据
登记核心 严格字段/文档/大小/名称/字面路径、现存别名/大小写 inode 祖先、重复/重叠拒绝、缺失目录列出与准确子集顺序;go test -race ./internal/workspace -count=1 通过,1.414 秒,/tmp/oink-r6-workspace-core-race.log
公共实际 Hugo OINK_TEST_HUGO=1 go test ./internal/app -run '^TestPublicR6Workspace' -count=1 -v 通过,10.498 秒,/tmp/oink-r6-workspace-public-hugo.log
公共 race 相同公共工作区套件加 -race 通过,12.426 秒,/tmp/oink-r6-workspace-public-race.log;排除的命令明确拒绝登记选择
Vet go vet ./internal/workspace ./internal/app 退出 0,/tmp/oink-r6-workspace-vet.log
公共结果 实际双语已提交夹具站点在 links 与完整检查中保留直接诊断/覆盖/退出一致性。首个缺失站点为 2,后续干净/有问题站点分别为 0/1;显式子集保留登记顺序,错误的未登记同级站点保持原样,人类输出保留发现项
选定应用 保存翻译审阅预览已验证、未应用;改选其他登记名称在写入前拒绝,保留计划/源码字节/完整模式/Git。显式匹配名称应用只写计划中的审阅文件;其他登记及未登记站点保持原样

这些是归属夹具结果,不是消费者采用,也不授权对真实消费者应用计划。已检查核心 workspace.go 的 SHA-256 为 cf2cbc9509e8c83eedf6d8833c9eb0ea6492de9a85c959798112fa3f105213f4; 归属测试为 9070a8e2c3e58680f6567f2394160ec682bf0457c068c2addf354921e7612d6b; 公共测试为 3e57a6417ae2e7604f7cb06933759bb06a2f40758ff7059848593cedbaa6570a。 这三份已检查文件均保留 0600 模式。下方冻结全部运行时清单覆盖这些归属源码 捕获;单独文件哈希不代表实际运行二进制身份。

修正协议与阶段门禁

协议或门禁 记录状态
实际 markdownlint-cli 0.49.1 与 Vale 3.24.0 修正公共试验通过:恰好一个发现项映射到原始 UTF-8/BOM/CRLF 行;排除的 front matter/短代码/数学公式/原始 HTML/已启用属性/代码不产生错误原文归因
实际 lychee 0.24.2 修正试验实际到达本地 HTTP 夹具:200 → 0,404 → 1,401/403/429/503/超时 → 必需 2。可选离线 → 0,必需离线 → 2,两者均零 HTTP 请求
最终聚焦实际工具收据 /tmp/oink-r6-public-actual-tools-final.log 通过,15.192 秒;先前修正后的 14.686 秒运行保留为已有证据。Node 预加载与发现的 JS 配置没有执行;源码完整模式/Git 保留
假工具/协议失败收据 /tmp/oink-r6-public-fake-tools-final.log 通过,13.089 秒:错误输出、版本不符、超时、不安全配置、必需缺失/可选/检查组遗漏与原始 stderr 规范化
聚焦公共 race/vet /tmp/oink-r6-public-tools-race.log 假工具和实际用例通过,30.273 秒;/tmp/oink-r6-public-tools-vet.log 退出 0
冻结运行时输入 父任务在 2026-10-03T10:58:01.807947Z 冻结,/tmp/oink-r6-runtime-freeze.json:103 运行时输入绑定 b85affd96378b45bfc56a996b0c5672d02ee4c6cc9bc95335fa5072f6c42a03b;179 更广 CLI 输入绑定 fbb8176ebc58f1aa26336f4e6036cf9bd5f7a0d62b142f16532b50a8071e9fbe。实际运行的 0.3.0-r6-local 二进制 SHA-256 为 aa8b347fbe01071f9da729f4d98aa2f50d7264456be6c5f05771bcfadadc371f
冻结归属套件 完整 Go/vet 退出 0,/tmp/oink-r6-frozen-go-gate.log;完整实际 Hugo 与固定工具退出 0,/tmp/oink-r6-frozen-hugo-gate.log(app 382.832 秒)。工作区/核心/协议/源码遮蔽/政策/报告 race 与 vet 收据通过,副本保留在最终收据中
四个消费者站点 已验证:全部四站精确二进制直接/汇总诊断、覆盖、退出、身份及登记顺序一致;逐命令/整体源码字节/完整模式/类型/逻辑与可变 Git/被忽略输入/目录保护通过。汇总完成 4,有问题 1,未完成 0,退出 1
规范中英文 通过:受保护首次十文件晋升、源码归属检查与新鲜普通生产/不可发布渲染证据;仅保留已知生产 draft 发布文档缺失
阶段决策 必需收据齐备后 R6/A07/A15 受支持范围已本地接受;R7/R8/最终 A18 未完成;没有公开版本发布、消费者源码写入、采用或部署

永久聚焦工具收据位于 /private/var/folders/df/bfm8q07d7bv3kpjf1fjchq4m0000gn/T/oink-r6-tools-6bf67ltv/r6-public-tools-acceptance.json, SHA-256 为 16b6e47fc0618c76d2f9e3680a4112b6e47b478af8aabd3f2fc84821f840cc8a。 它绑定工具准备记录、可执行文件/配置证据与 1,422 个已解析 Node 包文件。Markdownlint 报告原始 content/tools.md 第 7 行,bytes[80:92](ppears here.);Vale 报告同一行,bytes[71:78](BADTERM)。七个网络用例每个均实际发出一个 HTTP 请求。这些记录不认证全部传递解释器、其他运行时目标或完整消费者语料。

精确二进制消费者收据位于 /private/var/folders/df/bfm8q07d7bv3kpjf1fjchq4m0000gn/T/oink-r6-corpus-59_asiyr/final-receipt.json, 42,212 字节,SHA-256 为 0ad86afaf235bdcff0c474e76b08e0591591a7b22c7992b02e20fb17975d029e; 完成摘要绑定 467b66eb6d178829508115050d4243909313acf1b4d59317ecda37ab7383ca55。 它保留 14 份归属/完成门禁日志副本。六个原始操作合计 314.912887 秒,不计候选编译 和仅收据修正。workspace list 返回 0;四个直接完整检查返回 0/0/0/1; 汇总返回 1,全部四站完成。

站点 保留源码文件 直接/汇总子结果退出 诊断/覆盖 已记录发现项边界
Starter 97 0/0 28/29 仅翻译审阅信息
文档站 421 0/0 144/34 仅翻译审阅信息
PIG 858 0/0 120/41 仅翻译审阅信息
Repository 2,294 1/1 11,250/29 已有 10,462 重复 ID 发现及 788 翻译审阅信息项

直接和汇总子结果的身份、顺序、每项诊断与覆盖记录均一致。全部四消费者源码在每次 操作后及整体保留完整模式/类型、逻辑与可变 Git 元数据、被忽略复制输入和目录清单; 完整根 CLI 清单也仍等于冻结捕获。478,603,149 字节 repository 直接 JSON 与 635,470,795 字节汇总 JSON 通过流式完整验证,没有截断。可选工具协议归属独立 固定工具夹具;消费者登记只存在任务临时目录,不写消费者政策。

初始验收驱动将摘要结果的 command 字符串覆盖为调用 argv,六个 CLI 操作及其 逐操作保护全部完成后,产生错误的一致性异常。失败驱动与摘要仍保留为 pre-correction.r6_qualify.py 与 pre-correction.summary.json。收据完成只修正 调用元数据,验证原始结果 SHA-256 和头部命令不变,保留全部原始完整流诊断/覆盖 摘要,并重查整体消费者/根目录保护。无需 CLI 运行时修正或 Hugo/CLI 重跑。仅收据 完成耗时 2.002 秒,/tmp/oink-r6-corpus-receipt-completion.log 退出 0。

实际执行驱动 SHA-256 为 4d2a360c6f7f6f96c38698bd189bc4d4b2cb02a7509858920d752897fdd85988; 修正后驱动为 4870f5c0374fcc11ad1a6b2e3aefe36f493b6f9f4666c293993dc6a59df8a11b; 收据完成驱动为 cd50d3fe704370f73fa4e7d94ce8e4bc925d11ec8ef04d463aacec37c2053daf。 流式辅助程序绑定 144f778cdb7907372797b47b97f817f340e70423701a2a958dee589281a9a11c, 清单辅助程序绑定 d3ac41dc2e18295bfb26134d1a696935c8174913e2801a5766dbf7a1139d89f8。 此收据验证本地 darwin/arm64,使用 Go 1.27.1、Hugo Extended 0.166.0、Node 26.9.0 与 Apple Git 2.54.0。它不刷新最终 A18,不验证 Darwin amd64 或其他平台, 不应用消费者计划,不公开发布或部署。语料捕获时,规范晋升与实际渲染中英文 归属门禁是独立待完成工作;后续收据在下方关闭该边界。首次晋升字节不能追溯 宣称本次渲染后修订。

初次实际工具试验属于预备证据,不是验证通过证据。它暴露了 Darwin /var 与 /private/var 暂存身份、实际回环代理路由,以及 Vale 夹具中无效的行内块属性/行号 断言。暂存现在使用规范路径;Vale 夹具改为真实独立行块属性,源码遮蔽边界不变。 已验证子环境传入字面的 NO_PROXY/no_proxy 主机列表数据,不传代理 URL/凭据 和 Node 预加载设置。空代理环境与 NO_PROXY=* 都未建立已测试 Darwin 回环路径; 不宣称通用操作系统代理绕过。

受支持源码诊断需要已证明原始范围;渲染 lychee 位置仍是输出文件/DOM pointer, 不推断 Markdown 行号。离线时不调用 lychee。鉴权/限流/服务器/传输不确定性不能 通过严重度、排除项或基线确认变成必需成功。外部片段、浏览器执行与远端内容身份 未经证明。声明、结果封套与必需未完成优先级独立于最终平台/归档验证;Darwin amd64 与最终 A18 仍未完成。

首次受保护十文件晋升及其新鲜渲染验证现已完成。收据位于 /private/var/folders/df/bfm8q07d7bv3kpjf1fjchq4m0000gn/T/oink-r6-docs-render-dcwtcmyl/summary.json, 555,297 字节,SHA-256 为 ee153932900dc6f1ec62beef1a75927fc60b857efccfbcc558bf0e2c2b12cc04。 64.17 秒运行使用上方记录的精确已验证 aa8b347f…371f 二进制及不变的 103 输入 b85affd9…a03b 运行时清单。

首次晋升文档归属检查 实际结果
CLI 生产链接 0;一次严格生产 Hugo 渲染器,无分析构建
普通生产 Hugo / Markdown / 链接 0 / 0 / 0;214 内容页、43,376 文本节点;345 HTML 页、48,438 内部引用、4,259 片段
普通生产翻译 1 仅为已有 draft content/blog/release/1.2.0.md 未进入生产;不是新增 R6 失败
独立普通不可发布 Hugo / Markdown / 链接 / 翻译 全部 0;216 内容页、43,682 文本节点;347 HTML 页、48,814 内部引用、4,287 片段;137/137 组、1,118 标题
源码归属 / Schema 翻译、风格与空白全部 0;137/137 组、1,118 标题;137 中文文件、181 粗体标记、零强调标记;CLI/文档结果 Schema 均绑定 7468c2d04cde8a368ce0ba44a1f27125b5fca364b6d4672353519b9545b3bdda
保护 全部 12 个归属命令、CLI/Schema 检查及整体比对保留 421 主源码、427 复制输入、109 目录、36 可变 Git 文件的完整模式/类型/字节及逻辑 Git;两个私有普通源码副本和全部 103 运行时输入不变

首次晋升安装器收据 oink-r6-doc-drafts-ymjop499/applied-files.json 绑定 13c965592d64056d8365aed1927d2d422fadec8adc54ee7050b22e2ea0ad6270。 它在私有临时存储中保留捕获的实际原始 inode,保护后续旧打开句柄写入;恢复也保留 后续目标修改或删除。随后双语状态/证据修订具有独立完整字节/模式保护及源码归属 收据,只更新当前说明、命令状态和本台账,保留此前收据和配置示例。新字节不是 64.17 秒渲染运行的输入,不将该运行宣称为新字节重渲染。这些门禁后,R6/A07/A15 受支持范围已本地接受;R7/R8 与最终 A18 仍未完成。不宣称重复语料验收、公开 发布、消费者计划应用/采用或部署。

R7 只读 Studio 候选证据

R7 已实现契约与 指南描述的内嵌五视图浏览器及鉴权回环 API 候选。 R1–R6 历史章节及准确收据保持不变。冻结核心/浏览器及精确二进制四消费者验收 及受保护规范渲染门禁在声明范围内通过;R7/A16 受支持只读范围已本地接受。 R1–R7 已本地接受。R8 编辑与最终 A18 未完成。

聚焦原生与浏览器证据

归属边界 证据状态
原生/公共一致性 实际共享检查在 0/1/2 下保留诊断/覆盖/退出身份;显式选定工作区启动、清理/信号及无源码写入证明由归属测试收据单独记录
HTTP 管理/源码/预览 字面回环选择;准确 Host/origin/Bearer 检查;无任意请求路径/写入;捕获源码/diff 限制及源码模式/输出清单保护;下方聚焦核心/新浏览器及本轮语料收据绑定该受支持范围
首次保持界面浏览器 14 次 axe 零违规、14 张截图;五个桌面浅色视图、捕获 BOM/CRLF 源码/diff、桌面深色、移动深色、全部五个 320 像素浅色视图及捕获变化。合成实际 Hugo 夹具保留 228 原生诊断和覆盖一致;建议复制使用私有测试剪贴板,不改宿主剪贴板
浏览器预览攻击 实际攻击脚本在隔离预览执行,但 parent 访问、管理 fetch 与弹窗被阻断;拒绝 token query。仅 draft 页面在生产仍为 404。这证明已测试浏览器/CSP 范围,不是操作系统网络沙箱
快照保护 捕获源码指令/HTML 保持字面数据;显式任务夹具外部编辑后、刷新前,初始捕获仍保留旧字节。除已声明夹具编辑外,源码完整模式/Git/目录保留;changes 展示实际修改捕获输入
前一份保持浏览器 刷新保持 UI/后端收据通过:全部 14 次 axe 零违规、14 张截图,包含声明/捕获主题行。它先于局部预览运行时修正,不证明该新运行时
新局部预览浏览器 新冻结局部预览运行时通过:14 次 axe 零违规、14 张截图;实际 Hugo 正常 HTML 200 与 67,108,865 字节产物 413;原生 1/228 条诊断及覆盖保留,必需局部覆盖可见,Studio/刷新 2

首次浏览器收据位于 /private/var/folders/df/bfm8q07d7bv3kpjf1fjchq4m0000gn/T/oink-studio-browser-AfwaYi/summary.json, SHA-256 为 930fbd1ab86806069b963bff2e3e95aaa07e3634400cec65e2b8c7922e2a1707; 准确二进制绑定 92e5b962e40fbe828a0b006f3ae76a2bddf4ad7e8b1c5b6967e365b8f1827879。 后续声明/捕获主题元数据行不宣称由此前二进制测试。本地验证版本为 Node 26.9.0、 Playwright 1.62.1、@axe-core/playwright 4.13.0、Chromium 151.0.7922.34; 它们是明确预备的贡献者依赖,不是消费者运行时需求或自动安装。剪贴板证据覆盖 实际 UI 点击和私有剪贴板实现,不覆盖完整宿主剪贴板。

刷新保持 UI/后端浏览器收据位于 /private/var/folders/df/bfm8q07d7bv3kpjf1fjchq4m0000gn/T/oink-studio-browser-vn0ofb/summary.json, SHA-256 为 520603779f712539865c6e9ef7a9ad3ad21ec1906adfb067ec607cc69d071b7e, 准确二进制为 73bf90c69dce84849ee20ddfbfe825b9f2dd46f0cd37a228ce1b041a83afa33f。 全部 14 次 axe 与 14 张截图通过,包含声明/捕获主题元数据及全部五个 320 像素 视图。它保留上方针对前一运行时的有界合成夹具/源码/预览/剪贴板声明,不证明 后续局部预览修正;新浏览器、全阶段、消费者及渲染文档验收保持独立。

初次并行完整套件试跑 /tmp/oink-r7-frozen-go-gate.log 与 /tmp/oink-r7-frozen-hugo-gate.log 失败,不属于验收收据。失败原因是并行包负载下 既有 CI 测试十秒截止时间,以及图测试观察器刷新自身 Git 索引。单独 CI 目标组随后 分别用 12.149、2.291 秒通过;受控 Git 观察器图运行用 1.354 秒通过。仅 internal/projectgraph/hugo_test.go 改动:其只读观察器关闭 Git optional locks、 filesystem monitoring 与 untracked cache。该测试修正后,普通实际 Hugo 图运行 用 1.562 秒通过。运行时与内嵌 UI 字节均未改动。

修正冻结收据为 /tmp/oink-r7-corrected-runtime-freeze.json:113 运行时输入保持 15a7de85a1ae9e6a73d8ea6570aa4f97bdd0ad5677ad7ca996fdd081ad43f7b5; 193 更广输入现绑定 67c6d36cf91d175f208f79cdd4d337aab6d2ef71e43453b20394b677678725e8, 相对前一份 85ad60d24c93e899020fbdcd34f8252c578253ce5afaf8652e561a432ecc8067 冻结只改变测试观察器文件。修正后的串行 Go 测试与 vet 已通过,日志为 /tmp/oink-r7-corrected-go-gate.log。修正后的串行实际 Hugo/固定版本工具套件也 已通过,日志为 /tmp/oink-r7-corrected-hugo-gate.log,SHA-256 为 2aed822ff6fc8be04919aa74ca6ada721789232c14c1d77f1d44113bc0d235a7; 应用包耗时 220.782 秒。独立 Go 后源码保护审计收据为 /private/var/folders/df/bfm8q07d7bv3kpjf1fjchq4m0000gn/T/oink-r7-postgo-audit-qygh7bcc/receipt.json, SHA-256 为 5ee45fe041536243bc1229054516835c61b27909a4f296ac226b1a138e4bc8dc。 它验证完整物理/逻辑输入保护,不证明 Hugo 或消费者结果。

持久修正归属门禁收据为 /tmp/oink-r7-corrected-owning-gates.json,SHA-256 为 c7f94a740e33a7349886b3f3689419719f857f39031375e80ca384a3dac36e67。 它将两份串行成功运行绑定到修正冻结,并保留失败试跑为未验收。预备文档渲染驱动 现要求完整消费者收据证明私有捕获源码重建与最终浏览器二进制字节相同。独立 源码审计 oink-r7-docdriver-audit-ig_r8ud1/receipt.json 绑定 SHA-256 858cc48bf602fbdb26fcbda03c78ca485338b1295d64257d32cfb14b24f1ade3, 以及预备驱动 f25d9ac4bf1a7ef43d5526b7b3cbadf84dd64ad8a57fd82d1c82e76fdb2b3435。 该审计没有执行或验收规范渲染。

首次消费者驱动试跑 oink-r7-corpus-h1lOFl 因 KeyError('preview_base_path') 停止:驱动直接索引实际预览基路径为空时合理省略的 字段。该私有重建与最终浏览器二进制 73bf90c69dce84849ee20ddfbfe825b9f2dd46f0cd37a228ce1b041a83afa33f 字节相同;四消费者源码清单与根清单全部保留。失败的驱动运行不构成四消费者 门禁验收。新 oink-r7-corpus-corrected-cByXTa 驱动仅将这两个访问改为 get(..., ''),SHA-256 为 4c409acacbb9b82e658e6705eddefd9a3541def5c63c340b65678a6c9a8354e4。 该新运行随后因仓库产物中一个清单文件超过 64 MiB 而失败:前一运行时拒绝全部 生产预览。原生检查保持结果 1,必需预览不可用使 Studio 结果为 2。 Starter、docs、PIG 在本次运行完成并返回 0;四消费者源码清单与根清单保持 不变。失败 cByXTa 试跑保留,不构成四消费者门禁验收。空基路径驱动修正均未 改动运行时或消费者源码。

父任务随后授权局部预览的窄运行时/测试修正:保持 64 MiB 限制,开放限制内受保护 生产文件,准确跳过的超大路径返回 413,必需 studio.preview 覆盖保持未完成。 原生检查结果不变;必需预览未完成仍使 Studio 返回 2。内嵌 UI 保持不变。 此前浏览器/归属/二进制/语料收据都只描述各自旧运行时边界,不证明此新运行时。 新归属/浏览器门禁在下方独立记录,不从旧收据推断;精确二进制四消费者验收 保持独立。 旧失败捕获证明有产物超过 64 MiB,但未暴露其捕获路径/大小;被忽略仓库产物不 构成该捕获身份的证据。新的有界覆盖 detail 将记录实际省略相对路径、大小与总数。 预备实际 Hugo 浏览器夹具增加 64 MiB 加一字节的 static/oversized.bin,用于 验证可用受保护 HTML 预览、准确跳过文件的 413、原生结果 1 及必需局部视图 结果 2。该夹具准备本身不是浏览器验收;随后已完成浏览器证明在下方记录。

新局部预览冻结收据为 /tmp/oink-r7-partial-preview-runtime-freeze.json,SHA-256 为 c426ce3e641ed7b39bb711a26006306cab22e761c5062f2164f10deb4bea8765。 113 运行时输入绑定 4900ae05abbdf4409b0be54f276fb4135269cf0a49e9071013ccf42544d35c84; 193 更广输入绑定 8b172cef2b228e2642f0139d6cc569136e86843f818e52e412fa4a2d56add25d。 运行时输入仅改动 internal/studio/preview.go;更广改动还包含其测试及 scripts/test-studio.mjs。三个 UI 文件字节与模式全部保持相同。聚焦核心最终 race 用 1.748 秒通过,vet 与限定空白检查也通过。收据 oink-r7-partial-preview-owning-a56dunn4/receipt.json 绑定 SHA-256 7b6ecb491f283d04fe54347e564dba426b1a84d152040a1d945af54bc67756ac。 初次稀疏夹具模式试跑排除:宿主 umask 0077 使请求 0640 的文件实际为 0600; 夹具显式 chmod 到 0640 修正该设置,未改变生产行为。聚焦证明覆盖正常 200、超大 GET/HEAD 的 413、身份变化 409、私有路径 404 及其他未知产物错误拒绝。 它不替代随后独立的更广浏览器/归属/语料/渲染门禁。

新局部预览冻结的完整串行 Go 测试随后用 61.481 秒通过,vet 用 0.571 秒通过。 完整日志为 /tmp/oink-r7-partial-preview-go-gate.log,SHA-256 be7d6eccf99a6f4c1b8f09d1fb782455c7cbd3bad4a2f37e2f0e9da916bcb313, 以及 /tmp/oink-r7-partial-preview-vet-gate.log,空文件 SHA-256 为 e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855。 独立保持输入审计 oink-r7-partial-held-audit-o6p98i1l/receipt.json,SHA-256 e567efc5f580db9395afab8ad36c4db842c3db95db442eb1cb1c740dbd43ec31, 在父任务 Go/vet 运行期间验证全部 113/193 输入及物理/逻辑身份。它不构成套件后 或浏览器/语料/渲染完成声明。新完整实际 Hugo/固定版本工具调用随后用 285.649 秒 完成,退出 1。唯一失败是父任务使用不可用 Markdownlint 准备路径 /md/node_modules;其他实际案例全部通过。该日志保留为失败调用: /tmp/oink-r7-partial-preview-hugo-gate.log,SHA-256 为 1ab6b8cfd399d484e08a1d1f05d25475754caa731991dd1eec1cca03cf6ce970。 唯一归属案例改用准确预备的 /markdownlint/node_modules 可执行文件重跑,源码/ 运行时不变,通过:应用包 2.317 秒,墙钟 3.265 秒。收据为 /tmp/oink-r7-partial-preview-corrected-tools-gate.json,SHA-256 62b75e563e8074995ed9dd354434e653b2f5f2c6d20767226286d0c08d4c667c; 日志 SHA-256 为 e9bddac210654d219d9c5d6ebabaa3b91a0f5f4de4daf228b3ae21aeaac7673a。 可执行文件来自预备收据 268e601e81bc03a263296d57257b85635371bda642d0632532a7d9318c981461。 独立案例矩阵/保持源码审计验证失败完整调用加该修正案例形成累计已执行实际 归属案例覆盖 0。收据 oink-r7-partial-case-matrix-audit-16_bl9hr/receipt.json 绑定 SHA-256 0a9e4a1a1e1a08f597becb2f27e743c9f23df672c713c2757241704edb16b51e。 全部 113/193 物理/逻辑输入保持冻结。可选 TestArtifactCorpus 与 TestPublishedRuleSourceProvenance 案例明确跳过。不能将完整调用重新标为退出 0,也不能宣称跳过案例已经执行。

新 Go 后输入审计 oink-r7-partial-postgo-audit-g1hcqdtl/receipt.json,SHA-256 b369737ec48456f673c850ea702cb3cb7efffb8ecc129d87e00dc03af82b2e3b, 随后确认 Go/vet 后全部保持的 113/193 物理/逻辑输入。该范围不宣称完整 Hugo、 浏览器或消费者完成。

新局部预览浏览器基于准确二进制 f39d6754f7ad13599e4e849394e0f470b2c6f26edf96ce40f199d27b65a8030e 通过,版本 0.4.0-r7-local,16,000,578 字节、模式 0700。摘要为 /private/var/folders/df/bfm8q07d7bv3kpjf1fjchq4m0000gn/T/oink-studio-browser-cE9be3/summary.json, SHA-256 为 9099e6c407fd0f9de3c29ce80e03f034a4223d7d7a7c1f1378052e8b9084e0ae; 来源收据 SHA-256 为 85b9f537fb09eecbb09d133b53a297c78184c11200ab0938734c0d10f3449095。 私有 oink-r7-browser-partial-ZZIqzZ/source-binding.build.json,SHA-256 7a89ab8318c3a38455ab6ce12bcdbc53ae5ce0674fb5aaaa1df0fcf68a093399, 将捕获/构建前后全部 113 运行时及 193 更广源码输入和物理身份绑定到新冻结; 根输入保持不变。全部 14 次 axe 零违规、14 张截图通过,保留上方键盘/移动/深浅色/ 源码/剪贴板/安全检查。实际 Hugo 生成 67,108,865 字节 oversized.bin,经渲染 /sub/oversized.bin 链接实际到达并返回 413;普通实际 HTML 返回 200。 必需局部预览覆盖保持可见;228 条类型化原生诊断、原生覆盖/结果 1 在 CLI/API/UI 中一致,Studio 及随后刷新返回 2。源码保护仍仅排除明确任务夹具外部编辑。 这是有界合成浏览器证明,不是完整四消费者或规范渲染门禁。

另一份未执行的预备语料驱动假定正常可用预览总会附加 studio.preview 覆盖行。 实际正常 Starter/docs/PIG Overview 不输出该行;准备假设已修正,未改变原生覆盖。 修正后的新 oink-r7-corpus-partial-pZLwY0 驱动,SHA-256 47778df62505beeb7432985be927f1b001e03824e9dee3a6dbed9d9b2dbe049c, 已针对这三份保留实际 Overview 及当前局部浏览器捕获复核。正常可用仍需实际 预览 URL 和独立 HTML 200;局部捕获保留真实必需覆盖行、省略总数/身份和 413。 准备审计为 oink-r7-partial-driver-correction-audit-sa98cm6k/receipt.json,SHA-256 a519a5bc6ae83438146ff4710d53f5edb0e656a05d0532c02123e5771416f07e。 此前 f762 准备没有执行或验收。父任务随后释放修正驱动重新运行全部四站点; 其完整验收记录如下。

新四消费者验收用 234.6425 秒完成,驱动结果 0。本轮摘要为 /private/var/folders/df/bfm8q07d7bv3kpjf1fjchq4m0000gn/T/oink-r7-corpus-partial-pZLwY0/summary.json, SHA-256 d7b5a4f1607b6f75ae6a596c19cbab28685fb67dac750096173060ed097c8bf5; 日志 /tmp/oink-r7-partial-corpus-gate.log 绑定 SHA-256 a7b724500569bd594d8e01502ec1956eb089cc9153b04b693992a9322013c811。 持久本轮语料 qualification.receipt.json 绑定 SHA-256 4e5df7c3fda9f0b763091af3e6cb85c68c736c319a1de68030b81d5cd5b384bc; 主源码清单分别包含 97/421/858/2,294 个文件。 私有捕获源码重建与新浏览器二进制 f39d6754f7ad13599e4e849394e0f470b2c6f26edf96ce40f199d27b65a8030e 字节相同。113 运行时/193 更广输入及根物理身份保持冻结;每次操作与整体边界均 保留四消费者字节、完整模式/类型、逻辑/可变 Git、被忽略捕获输入和目录。

消费者 原生结果 类型化诊断 Studio 结果 实际捕获页面
Starter 0 28 条审核信息记录 0 66
docs 0 144 条审核信息记录 0 343
PIG 0 120 条审核信息记录 0 248
repo 1 10,462 条既有重复 ID 发现加 788 条审核信息记录 2 1,576

四站嵌套原生 header、类型化诊断、覆盖及退出与直接 CLI 检查准确一致。Issues 完整分页;其他视图采用有界样本,四站均有捕获物理源码及翻译 diff。前三站实际 生产预览 HTML 返回 200;它们不输出 studio.preview 省略行,驱动没有虚构该行。 仓库正常 HTML 返回 200、60,100 字节。当前捕获准确暴露四个超大 print 路径; 每个实际 HEAD 返回 413,响应体零字节:

捕获省略相对路径 捕获字节大小
_print/pkg/index.html 73,976,221
_print/pkg/pgsql/index.html 69,903,999
zh/_print/pkg/index.html 73,086,240
zh/_print/pkg/pgsql/index.html 69,052,754

这些身份来自本轮有界捕获 detail 与实际请求,不来自此前被忽略产物线索。必需 studio.preview 保持未完成,仓库 Studio 2 因而保留原生 1。docs 与 repo 实际 仅分析 draft 路由在生产返回 404;Starter/PIG 缺少唯一捕获 draft 路由,该测试 明确不适用。工作区子集/全集/健康子集会话仅选登记站点,不捕获并关闭监听器; 未知或选定缺失站点在启动前返回 2。这是本地 Darwin/arm64 CLI/API 证据,使用 Hugo 0.166.0 Extended、Go 1.27.1、Git 2.54.0;浏览器范围保持为独立合成夹具。 没有源码写入、安装、公开发布、采用或部署。独立最终语料审计 oink-r7-final-corpus-audit-xr3_u5dt/receipt.json,SHA-256 b8a8eedf5c899fe5830bdde959783c46b3f191ab144c0d3798077555d55238fc, 不重渲染、不新增 HTTP 请求,验证原始类型化原生/API/退出一致、132 项操作保护 比较及四项整体保护。仅受保护规范晋升/渲染及显式 R7/A16 阶段决策仍待完成;R8 与最终 A18 未完成。

临时磁盘容量准备期间,父任务仅清理三个明确创建的私有 Go build cache,共 366,184,826 字节,收据为 /tmp/oink-r7-private-cache-retirement.json。 源码、二进制与验收证据均保留;未删除全局、用户或系统缓存。此准备操作不是 运行时修正或验收门禁。

剩余阶段门禁与晋升边界

必需门禁 当前状态
冻结运行时输入/二进制身份 新局部预览冻结绑定 113 运行时输入 4900ae05abbdf4409b0be54f276fb4135269cf0a49e9071013ccf42544d35c84 和 193 更广输入 8b172cef2b228e2642f0139d6cc569136e86843f818e52e412fa4a2d56add25d;所有 UI 字节/模式保持不变。源码绑定浏览器二进制 f39d6754f7ad13599e4e849394e0f470b2c6f26edf96ce40f199d27b65a8030e 已通过;新私有消费者重建字节相同
完整 Go/vet 与实际 Hugo 新完整串行 Go/vet 与浏览器已通过。新实际 Hugo/固定版本工具完整调用保持因准备路径退出 1;唯一修正归属案例通过 0,独立验证累计已执行实际案例覆盖 0;两个可选案例明确跳过
四消费者 精确二进制 CLI/API 验收完成;原生 0/0/0/1、Studio 0/0/0/2,准确嵌套原生一致及源码字节/完整模式/类型/Git/被忽略输入/目录保护;仓库局部预览保持必需未完成
规范配对源码/渲染 首次受保护 TEN 晋升及限定实际渲染通过;渲染后状态修订采用独立新源码检查,不宣称重渲染
阶段决策 R7/A16 受支持本地范围已接受;R1–R7 已本地接受,R8 与最终 A18 未完成

下一份预备文档安装器在成功与恢复时都将捕获的实际旧 inode 保留在规范源码外, 不会在较早目标身份检查后取消其最后名称。此私有辅助程序加固及新恢复夹具属于 新的预备边界;已执行 R6 安装器/哈希/收据保持不可变,不追溯宣称包含该修正。 R6 成功晋升已保留原始 inode。本候选文档或本地浏览器夹具不推断消费者计划写入、 公开发布、采用或部署。

首次晋升渲染门禁完成,收据为 /private/var/folders/df/bfm8q07d7bv3kpjf1fjchq4m0000gn/T/oink-r7-docs-render-n8tw2tbw/summary.json,SHA-256 35e79f51d39803b3e4cdf134ed277957dd627acba42e0e0dc785e4745ec3c481,日志 SHA-256 de3a07eac661c15805070e0ed2e364a71ebbd38e15d8907aab3bdf716e95131d,耗时 63.33 秒。准确已验证二进制 f39d6754f7ad13599e4e849394e0f470b2c6f26edf96ce40f199d27b65a8030e 在一次严格 Hugo 构建下通过生产 CLI 链接。无 probe 普通生产 Hugo 通过渲染 Markdown(214 页/44,075 文本节点)及链接(345 页/48,482 内链/4,303 片段)。其翻译归属仅因既有未发布 release 1.2.0 draft 保留退出 1。独立 draft/future/expired 分析通过 Markdown(216 页/44,381 节点)、链接(347 页/48,858 内链/4,331 片段)及翻译(137 对/1,129 标题);未替换生产产物。源码翻译/样式/空白检查通过,CLI/文档 schema 7468c2d04cde8a368ce0ba44a1f27125b5fca364b6d4672353519b9545b3bdda 保持相同。十二项操作、schema 及整体保护均保留 421 主文件、427 捕获输入、109 目录、36 可变 Git 文件和 113 运行时输入。

首次受保护晋升收据 oink-r7-root-promotion-p9g1u7pz/summary.json,SHA-256 323a5ce267e39aaf8f97dc4a12cccbdde83730155a199efb5f3815e29b334e4a,验证实际原始 inode 保留在规范源码外。写入后收据查找曾使用 0 而非 00;该仅元数据驱动失败保留,随后使用不变原始保护完成收据。已成功源码安装没有重复执行。已执行 R6/R7 辅助程序与首次晋升收据保持不可变。

R7/A16 受支持只读本地范围在上述冻结累计归属案例/浏览器/语料及规范门禁后已接受。原完整 Hugo 调用仍退出 1;唯一修正工具案例加独立矩阵形成累计已执行案例覆盖。仓库原生 1 与必需局部预览/Studio 2 保持可见。R1–R7 已本地接受;R8 编辑与最终 A18 未完成。此渲染后状态/证据修订具有独立字节/完整模式保护、不变标题/命令围栏、配对源码检查及保留 inode 安装器夹具。其新字节不宣称由此前 63.33 秒渲染测试;不推断额外渲染、消费者写入、公开发布、采用或部署。

R8 已接受受审阅编辑证据

R8/A17 受支持编辑范围在下文修正冻结归属/浏览器/语料及受保护规范渲染门禁 后已本地接受。CLI edit text、field、 snippet、attachment 预览与显式 studio --edit 相同的绑定 oink.edit/v1 意图。保存计划应用或 Editor 显式确认 Apply 拥有选定源码写入;默认 Studio 会话 保持只读。本节保留捕获时的候选事实和试验,随后记录已完成当前验证;不把先前 R1–R7 证据延伸到变动代码。

候选范围与保护

已知站点所有 UTF-8 Markdown 上限 1 MiB。完整文本及受支持普通顶层 YAML 标量 表单保留声明的 BOM/换行及源码区间保护边界,不支持表单形态保留文本。准确 value_json 数值避免浏览器 Number 舍入。标量表单把数值字面量限制为 4,096 字节、 十进制指数绝对值 10,000,更大/非有限构造保留手工文本。字段 JSON 最多 1 MiB; 转义孤立 surrogate 拒绝,有效 Unicode 对受支持。目录组件使用原始 UTF-8 正文字节偏移; 附件要求实际 leaf-bundle 身份、最多 4 MiB、独占干净新 basename。源码哈希、 完整模式、全部站点/外部输入、重新生成意图及新实际 Hugo 验证绑定同一共享保护 应用路径。

Editor 展示完整 UTF-8 审阅、选中文件基准/结果身份及原生候选结果;审阅上限 2 MiB,确认前对准确可见字节验证哈希。实际选定候选 HTML 是 draft/future/expired 分析,明确不可发布,与原生产预览独立。必需候选视图未完成可以把提议/会话升为 2,而不改写原生发现。页面文件编辑的选定候选源码哈希/完整模式须匹配已审阅 After 状态;附件/no-op 提议的选定页面保持已审阅 Base 状态。 过期/重放计划、附件冲突及不可信预览请求会拒绝;已应用但刷新失败保持明确已应用。

聚焦准备收据

候选证据 当前观察与边界
纯编辑核心 归属聚焦准确数值测试通过:18446744073709551615、7.12345678901234567890123456789、准确 no-op 原始字节及末位小数改动;更广冻结收据待完成
实际 DFE 输出所有权 活跃普通输出通过受限 os.Root、独占目标文件及保护流式读取复制;超过 64 MiB 的文件可捕获,服务限制仍不变
复制取消/race 上下文 helper 聚焦 0/0.703 秒、race 0/1.856 秒、vet/空白 0;实际首块取消保留部分输出,源码字节/模式/身份不变;源码 FIFO 替换不能在 fd 证明前阻塞
Helper 日志身份 聚焦 c227a88210ab0dc46b24eaff50a347d5c494e9ce23f5bdef5d5b822efab4976f;race 13f0616d55fd4df791ecded0712a18096392c88cb9b849383414c305e50b6779;vet 为空 SHA-256 e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
只读候选集成审查 审查选定实际 HTML URI/base 前缀/清单、保留私有 DFE 生命周期、源码 SHA/完整模式一致、原生与视图覆盖及取消;本次代码审查范围未发现新实质缺陷
首次 Editor 浏览器试验 驱动因全局 Open editor 选择器歧义停止;保留失败试验,不宣称 UI 验证
修正选择器 Editor 试验 桌面字段/组件/二进制应用及 axe 检查通过后,320 px draft 审阅横向溢出失败;保留原试验,不是最终浏览器通过
定点布局修正 Editor 审阅哈希/收据文本可换行,固有宽度受限;此前 CSS 与失败证据独立保留。开发重跑通过 12 项 axe/截图,包含真实 320 px 暗色审阅及亮色收据/拒绝;最终冻结源码/二进制重跑待完成

Helper 证据只验证聚焦文件复制/取消,不是整个编辑应用或全部平台支持。浏览器 试验只描述实际停止范围,不构成最终 A17、消费者采用、部署或当前冻结浏览器 二进制成功证明。

前述准备行记录于首次完整 R8 冻结之前,保持开发历史边界。后续首次完整冻结 门禁通过,二进制为 84b804d3246a5be581e44884ed910fa3f45d8be29734b8babdeeb763a11fa882 (0.5.0-r8-local),运行时 123/58517b8e98b80df6642be4ee6275a0074ec187768b20e009f41da2607b635d46, 更广源码 212/d81335c78413acc60e27adee0ac794862285e41cb2a3a7687ec820c1065ba003。 完整门禁摘要为 b49f4a3272af3e3dcc92e7e9b38d4289bb49cb19aa3e9354ea148d2d8cb2cea8: Go 测试 0/56.523 秒、vet 0/0.904 秒、完整实际 Hugo 及三个固定工具 0/320.044 秒、核心 race 0/16.610 秒、公共 R8/helper race 0/48.319 秒。 源码保护通过,这些收据只验证此前对应字节。

首次冻结浏览器收据 eb6977235ef9ae6cec28651b5654eb101685af67abe0cbed0acb0f8375458d9c 绑定相同二进制及源码冻结。Editor 12 项 axe 零违规、12 张截图;保留只读 Studio 为 14/零/14。实际表单保留 1e400 字面量、计划 after 哈希及 diff,随后 丢弃;指数 ±10,001 与 4,097 字节数值在本地拒绝,不发送 API 请求。四次确认的 字段/组件/二进制/draft 应用只发生于一次性夹具。默认只读拒绝、过期输入保留、 no-op 源码字节、预览隔离及原生结果独立性通过。这是首次冻结的开发浏览器 证据,不是四消费者或当前修正运行时的阶段接受。

首次准确二进制消费者试验随后在 Starter 停止,耗时 37.533 秒。不可变失败试验 收据为 853a8397ba4c527c03aa3cc9ac7cacc41c0ab0379549d145b874f1d1ecc3901c。 两项失败分别记录:驱动事件哈希依赖 JSON 对象键顺序,但递归比较证明 API/CLI 数组相等,均为 28 条诊断、29 条覆盖、原生退出 0/0。另一个是真实运行时 问题:重复解析缓存捕获产生 .gitattributes 模块输入重复;必需候选图捕获不完整, 修改结果为 2,原生检查仍为 0,没有实际选定 DFE HTML 或可应用 lease。 公共发布缓存夹具重现该缺陷,保留失败日志为 50ab704e715665096e0f36391bb1364841c3a2b2ac88dd262915ce53fb66afa6。 全部 48 份已记录逐操作源码证明及四份消费者整体保护保留字节、完整模式、类型、 Git、忽略但复制的输入与目录,根输入准确不变。没有 Apply 或保存计划;停止的 试验不构成完成四消费者验证。

定点运行时修正先收集完整解析模块行,再提交新增记录。相同重复或重新排序的 捕获保留原清单。既有范围内哈希/完整模式变化、路径增删、整个范围缺失、身份 冲突或捕获错误都拒绝,不刷新此前证据或追加部分结果;非模块行保持准确。 site 归属收据 e7b284b9dece1c5f2b696cd76166d2286fcbec69e6c48912ab9a78204bdb980b 记录聚焦 0/0.746 秒、site 0/2.123 秒、聚焦 race 0/1.958 秒、vet 0/0.167 秒。这比较重新观察的完整行,不锁定模块文件阻止并发写入。

修正公共发布缓存收据 6358dc81f06e34b789cb47a0f4442d6d036d2e33423a06f5dbe85b3064766da6 使用任务本地复制、校验过的 github.com/pgsty/[email protected] 归档,没有下载或 replacement。原始/候选图各有 1,256 条唯一输入,含 1,198 条模块输入。完整 API/CLI 类型化诊断、覆盖、退出及计划身份一致,实际选定 DFE HTML 返回 200, 源码字节/完整模式/Git 不变,没有 Apply 或保存计划。归属 race 30.255 秒通过, vet 通过;修正 race 日志为 c7d21a30b8af141d9d9604a80ddf9cf3f608320b97a441a06a742376e2119551。

当前完整修正冻结为 fb276500a3d2643bd0aa220f8bebb380fce2c98493d62b0502b6497b2f02949f, 运行时 123/cdf629eeb4bbef6d4d88ee27fe3fb0a73b07b6bf6438336e033a18fb7feb1c17, 更广源码 212/f6e305e792733a550814eb841615d12fa14a9a6bb2a97c4ada85f7275183e579。 相对首次冻结只变动 source_inputs.go、其归属测试及公共发布缓存测试;受控 UI/helper 字节及全部完整模式不变。重建候选为 bd25f9e0b35ec10e227aabf9582ae40b0b367390f64b93668de6ae85222c3d71 (0.5.0-r8-local)。已观察的修正源码绑定浏览器收据 33a698985a55c14c3e64e981da1f8e74c686497083dc0edb241406f185e3eeb8 再次记录 Editor 12/零/12、只读 14/零/14,完整 123/212 前后源码保护通过。 本次证据修订时,修正完整归属门禁、新四消费者语料及受保护规范渲染仍待完成。 R8/A17 尚未阶段接受,最终 A18 保持未完成。

下一次证据观察时,修正完整门禁已完成,绑定前述受控 bd25f9e0…22c3d71 二进制及 fb276500…02949f 冻结。摘要 208f156c0954e803eccbada678a4689683dc1576c543c379e5cc04b3497ef772 记录 Go 测试 0/57.826 秒、vet 0/0.521 秒、完整实际 Hugo 及三个固定工具 0/378.847 秒、核心/site/Studio race 0/17.937 秒、公共 R8/附件/输出 helper race 0/85.159 秒。每项门禁源码前后保护通过。实际 Hugo 日志有 434 项顶层 通过、零失败;两个可选外部夹具 TestArtifactCorpus 与 TestPublishedRuleSourceProvenance 明确保留跳过状态,不宣称已执行对应语料或 来源验证。

修正完整实际 Hugo 日志为 4eb1a2afdce2adbe570b10922fd53b6d8954f7c95747370c3c661e94d2f71a05; Go 日志 ea59463e9649ffe2f8aff9da66c91cf6895c86fde96a524db23c89cd4eb35925, 核心 race cdd3d761b5ca7b5e986b25aee3129d65663e3e5ebb83eecb6fbb080387298a58, 公共 race bb610bdcd7a299cb9b66f4c69e30e246c20546efae47653c01d350b1026ea2de。 前述修正浏览器专项证据继续绑定相同当前源码及二进制。独立授权的新四消费者 试验正在执行;不由这些归属门禁推断完成语料、规范渲染、R8/A17 接受或最终 A18 验证。

前述 434 项通过与两个可选跳过是顶层计数。同次完整调用还跳过嵌套 Unix socket 拒绝夹具,原因是 Darwin 临时路径超过 socket 限制。首次缩短私有路径 试验仍跳过:收据 93106854ca890b497d3c74522b895f597ac60cec55ced42cad7b187d334da200 保留进程退出 0,但明确记录未实际执行 socket、验证失败,不改称夹具通过。

后续不解析别名的短私有 TMPDIR 在 race 下实际执行相同冻结 socket 夹具, 没有跳过,0/2.954 秒。收据 531a503b3b91e1b423c2be61b92ed806d3a813738c38d57e5ec122577b4337f9 与日志 236c84f1842ffce76174c834f3888718a109cec6377ada6f3242b02f551f00b3 绑定 fb276500…02949f,全部 123/212 逻辑/物理/Git 输入前后不变。这补充实际 socket 拒绝用例,没有改动源码或原始完整调用跳过历史。语料、规范渲染、R8/A17 阶段接受及最终 A18 仍待完成。

前述语料待完成陈述记录各自观察时点。随后,修正四消费者试验于 845.705 秒 完成。摘要 af4fc53326163c4a03aa2982c1f01363fbbdd5a447c9baed3639bd8599d46370 与验证收据 4d6fd02543c1920497e1a1bb0a68fcf89b0546130fd9cc12c1df391b7e673e75 绑定逐字节相同私有重建 bd25f9e0…22c3d71、完整受控 123/cdf629ee…feb1c17 运行时及 212/f6e305e7…5183e579 输入。原失败语料、 发布缓存回归与首次冻结浏览器/门禁字节保持独立历史证据;首次失败试验全部 2,383 项准确保留字节/完整模式/类型。

修正消费者 原生当前及原生候选退出 API 候选结果 完整诊断/覆盖 实际选定分析 HTML
Starter 0 / 0 0 28 / 29 200,48,149 字节,/blog/design/content-model/
文档 0 / 0 0 144 / 34 200,61,738 字节,/blog/oink/immersive-reading/
PIG 0 / 0 0 120 / 41 200,55,641 字节,/404/
仓库 1 / 1 2 11,250 / 29 200,92,352 字节,/blog/infra/2020-12/

这些是独立、明确不可发布 draft/future/expired 候选视图中的实际选定 Hugo HTML 路由,预期候选 marker 均存在。API 与 CLI 的完整类型化诊断/覆盖、原生退出、 计划 ID、Base/After 哈希及完整模式、unified diff 和选定页面提议源码一致。 完整准确 API 审阅及其哈希独立验证。 没有消费者 Apply 或保存计划,没有遗留监听器。仓库保留 10,462 条已有重复 ID 发现和 788 条信息记录,四个实际 PRINT 输出仍为必需局部预览未完成: _print/pkg/index.html 73,976,221 字节、 _print/pkg/pgsql/index.html 69,903,999 字节、 zh/_print/pkg/index.html 73,086,240 字节、 zh/_print/pkg/pgsql/index.html 69,052,754 字节。每次有界 HEAD 请求均返回 413、正文为零,选定限内 HTML 保持 200。原生 1 未改动,提议/会话 2 及拒绝 Apply 保持可见。其余三站完整预览不编造显式完整覆盖行,而以实际受保护 HTML 200 作为证据。

准确 53 次受保护操作每次检查全部四站:212 次逐操作源码证明加四次整体证明, 源码字节/完整模式/类型、复制的忽略输入、目录及逻辑/可变 Git 均未改变。每次源码 证明比较四类清单,因此含整体比较共 864 对原始清单。全部 53 次根目录保护及 最终完整 123/212 逻辑/物理输入也相同。所有 issues 与 pages 分页遍历,其他五个 视图端点仅取前 50 项,每站一个已知源码及一个有界 diff。完整原生/CLI 记录 一致性使用已声明有界完整记录 codec;对象顺序规范化,数组顺序、类型、null 和 字段存在性仍有意义。不宣称已人工查看每条关系或编辑每个源码文件。

独立审计收据 6b72ca06d8392a5271fc40757f176f26e1144c21eec93dbd035e0a1bd645657b 验证 69 项产物哈希、完整有界 API/spool/关闭类型化记录及大型原生/CLI 原始文件 摘要绑定,没有单独重复数 GB 原生语义扫描。追加收据 335f137663d4ec0b2a0d3e49c8d70b9918f86078ab6264855171a2644d8aa6c6 还把当前根目录完整逻辑 Git 清单与冻结重新验证,原审计保持不可变。修正归属、 socket、浏览器及四消费者受支持范围已验证。规范 TEN 晋升/渲染、R8/A17 阶段 决策及最终 A18 仍待完成。

前述 R8 候选/试验陈述保留各自捕获时范围。随后,经审阅首次 TEN 晋升通过 受保护保留 inode 安装器,根收据为 7cd9b4604d2340b9e46965a26281c921b967060909d518b8b4b31e5f42d0120c。 实际原源码 inode 保留在文档站外;未选中源码/复制输入、目录和 Git,以及完整 CLI 123/212 逻辑/物理输入保持不变。

独立授权规范渲染随后仅执行一次,于 67.21 秒完成,摘要为 bb0d0710294f810fb14284f7b5b0329befbd290b66c21397b9a45e8382287fb6, 验证收据为 32d3ffeca43bc9ad4615edcca0d3cc47cc932bbc93c6576724c800e0a62405b1。 它使用准确已验证 bd25f9e0…22c3d71 二进制及修正 123/212 冻结。实际 CLI 生产 链接通过 0,只有一次严格 Hugo 构建。独立普通无探针生产 Hugo/Markdown/链接 通过:214 个 Markdown 页面/44,691 个节点,以及 345 个链接页面/48,532 条内部 引用/4,351 个片段。生产翻译归属仅因已有 release/1.2.0 draft 不在生产而保持 1。独立明确不可发布 draft/future/expired Hugo 分析的 Markdown(216 页面/ 44,997 节点)、链接(347 页面/48,908 引用/4,379 片段)及全部翻译均通过 0。 分析没有替换生产输出。

源码翻译通过 137/137 对、1,143 个标题;中文样式通过 137 文件/181 个加粗区间/ 零强调,空白通过,Schema SHA-256 7468c2d04cde8a368ce0ba44a1f27125b5fca364b6d4672353519b9545b3bdda 准确相同。全部 12 个命令、Schema 及整体保护保持 421 个主源码文件、427 个复制 输入、109 个目录和 36 个可变 Git 文件,以及全部 123 运行时/212 更广 CLI 逻辑/物理输入不变。验证收据绑定 60 对规范清单、15 对 CLI 保护及六对私有复制 源码,不宣称消费者写入或部署。

R8/A17 受支持本地编辑范围在修正归属、socket、源码绑定浏览器、精确二进制 四消费者保护及这些受保护规范门禁后已接受。R1–R8 已本地接受;仓库原生发现及 必需局部预览 2/拒绝 Apply 保持可见。最终 A18 当前 Linux/运行时/归档验证仍 未完成。独立平台权限依据审计 762571dab9a07651ac8e4c71764bfef292f8d5eba729a089e72d9d755b7e2d7c 确认初始契约验证实际执行架构:macOS arm64、原生 Linux arm64 与模拟 Linux amd64。Darwin amd64 保持实验归档,实际执行失败/运行时未验证;历史保持不变, 交叉编译成功不能成为运行通过。两种当前 Linux 运行时与最终归档仍须新证明。

本次渲染后状态/证据增补独立保护完整字节/完整模式和 inode,稳定 ID/命令围栏 不变,并有双语源码检查和保留 inode 安装器夹具。新增字节没有经前述 67.21 秒 运行渲染;不推断重复渲染、消费者源码写入、公开发布、采用或部署。

必需门禁矩阵

必需门禁 当前状态
最终不可变运行时/源码冻结与准确 CLI 二进制 修正完整冻结 123/212 与 bd25f9e0…22c3d71 绑定完整归属/浏览器/语料/规范范围;首次冻结试验保持独立
公共 CLI/JSON/退出、过期源码/配置/外部输入及保护写入器测试 修正公共 R8/附件/输出 helper race、完整 Go/vet/实际 Hugo 及规范阶段门禁通过
冻结完整 Go/race/vet 与选定应用后实际 Hugo/普通 Hugo 修正完整 Go/vet/实际 Hugo 及核心/公共 race 通过;434 项顶层通过、零失败、两个可选外部夹具跳过明示,首次试验保持独立
Editor 浏览器五视图一致、文本/表单/组件/二进制附件、准确数值/no-op、过期拒绝及预览隔离 修正二进制源码绑定 Editor 12 项 axe 零违规/12 截图及只读 14/零/14 通过;已绑定完成语料与规范接受
准确二进制四消费者只读验证 修正全四站于 845.705 秒完成;完整类型化原生/API/CLI 候选一致,212 次逐操作源码证明加四次整体,无 Apply/保存/源码写入;首次失败试验保留
受保护规范 TEN 晋升、中英文源码/schema/样式/空白及实际生产/分析渲染 受保护首次晋升与独立准确二进制 67.21 秒渲染通过;生产仅保留已知 draft 翻译遗漏;渲染字节与本次状态字节分别绑定
R8/A17 阶段决策 受支持本地范围在修正完整归属/浏览器/语料/规范门禁后接受;R1–R8 已本地接受
最终 A18/平台/归档交付 未完成;仅编译成功不构成运行时验证

通过与待完成条目明确列出,不推断后续门禁成功。先前 R1–R7 节、完整调用失败及限定接受 收据保持不变。临时验收文件留在规范内容和 Git 外;首次规范晋升与渲染已有准确收据,但本次状态增补仍为受保护提议, 不宣称公开发布或部署。

2026-10-04 当前运行时完成增补

本增补记录 2026-10-04(Asia/Shanghai)的当前候选。带日期页面 URL 与初始 2026-10-03/R1–R7 记录保持不变。此前 R8 阶段及浏览器/渲染收据只证明各自冻结 输入,不验证后来变动的后端字节。三个 UI 文件与已通过浏览器验证的字节/完整模式 准确相同;当前 Go、Hugo、平台、归档与四消费者检查刷新变动后端。

首次当前 ARM 离线单元运行发现真实产物复制完整性缺口:ext4 上增加目录项时, 父目录分配大小和实际观察时间戳可能不变。该失败运行在后续验收前停止。有界 修正捕获并重新验证实际排序目录成员及项身份,同时保留常规文件字节/完整模式 证明。仅 internal/app/studio_output.go 与其归属测试变更。失败收据和独立审计 保留,失败运行不会改标为通过。

前一完整性修正验收的完整冻结为 683daca0e522193c7ff1b0de6ac2fee5d2fca080811bf184a8dfd5b90a33f224: 123 个运行输入哈希为 d346ad15cd4239004e32e1b9f30d727eaf156be0187dc165ca874032a7cf962a, 212 个完整 CLI 输入哈希为 2abd1a044d8192b07f9bbc06b55dc8b4544d66ca17b8867971cec702ba3af088。 0.5.0-r8-local Darwin arm64 候选为 74ad94e73557f6538cd64edd1766d6df92c596d98411031159d94af072c186ec。 下列已观察的完整性修正收据绑定前一源码范围;旧 R2 Linux 与此前 R8 二进制收据保持历史范围。 后续单个归属夹具修改具有独立完整源码身份和已完成的正式验收边界,如下记录。

当前完整源码冻结现为 196245a3ba09305e34b86539c8eb79f1473e4373ee47aa1f56f8933b04a42d43。 123 个运行时输入准确保持 d346ad15cd4239004e32e1b9f30d727eaf156be0187dc165ca874032a7cf962a; 212 个完整 CLI 输入为 2c487bfb4c65ed40ff78356b2860de627e6ac1afa0da2df433b09345dab7f5b0。 只修改发布缓存归属测试,其源码为 54c10ef89310256b5f4c165c7de5de9668e1d4d2991b71751076680141dbe779。 夹具修改有独立保护,生产字节与全部语义断言保持不变。该完整源码的八项当前 归属门禁、刷新归档与完整 plain-Go AMD/ARM 正式验收已通过。根 A18 证明 2c018cb2afa3f26699a9e6b5a0971096246b12405fde5a27e43a9e213e46da60 绑定全部三个声明支持目标与五份复现归档。此前收据保持自身捕获范围, 不改称新测试源码的运行。

当前证明与保留的此前输入边界 已观察结果与绑定收据
新完整源码的正式验收 冻结 196245a3ba09305e34b86539c8eb79f1473e4373ee47aa1f56f8933b04a42d43、归属测试 54c10ef89310256b5f4c165c7de5de9668e1d4d2991b71751076680141dbe779、运行时 123 个输入未变。当前八门禁、host/归档及完整 plain-Go 双 Linux 流程通过,由根 A18 证明 2c018cb2afa3f26699a9e6b5a0971096246b12405fde5a27e43a9e213e46da60 绑定;不宣称最终文档字节已渲染
有界完整性修正 归属收据 6966d768025497b45958073d4c53a2a2981065c8a95857834dcf6a4faa4f0201;独立审计 6cb5d2eabf57b41079026a38a674f46def9f56a15df17ad27e671e4f765798df
前一源码六项归属门禁 构建、完整离线 Go 单元/vet、完整实际 Hugo/固定工具、核心 race 与公共 R8/输出 helper race 均为 0;耗时 3.501/68.257/3.909/333.801/37.070/79.670 秒。汇总 b40b7787b3da8dc1e0763812b6dde529b4b5b69fe479d79940f1161223124e1d;独立审计 20780662b7ff35019b2c8c84e6dc763f9351ae0816f6ef7a7789f7a15be99167
八项当前冻结归属门禁 发布缓存实际 Hugo 与 race、构建、完整离线单元/vet、完整实际 Hugo/固定工具、核心 race 与公共 R8/输出 helper race 均为 0。当前汇总 d6272fcc4dfab114aecfcdf19a7e2b78f1e931817331b460f43ff2056bf754a4;完整 Hugo 原始记录 435 项顶层通过、零失败、两项可选顶层跳过及明确长路径 socket 子项跳过,运行时/二进制字节未变
前一源码 Darwin arm64 与归档 当前提取候选在 checkout 外运行,无消费者 Node 要求。17 个命令和八项实际进程测试(含子进程信号)通过,进程测试无跳过。两个新 release 目录中的五份归档/校验和字节相同,源码/许可证/来源/规范 tar 验证通过。汇总 bcb4d7599e965c1b3cfe7fe698ca14061ad53d45e7a194337aeebb8d37aa77c1;独立审计 60a04771365d8be15ac91fbbd8d485b019aae081598e468018861ca5734e387c
当前 Darwin arm64 与确定归档 17 项提取归档/普通 Hugo/进程命令达到预期退出,缺少 Hugo 明确为 2;八项实际信号/进程案例无跳过。两个独立新构建从当前完整源码复现五份字节相同归档。汇总 3890fd8468b6bce5271bb32ffa1a18bd5daf99c19c43becac0be8e3b908a5d57;源码、工具、模块缓存与 smoke 源码保护准确一致
前一源码 Linux arm64 在 ext4 上以非 root 用户实际运行 Linux arm64,Go 1.27.1、Hugo Extended 0.166.0、Git 2.47.3:完整离线 Go 单元/vet、13 项必需纯测试顶层通过记录,目录成员项及四个子项无跳过、10 项选定实际 Hugo(无跳过)、原生重构归档身份、安装后二语言/离线/普通 Hugo/缺少 Hugo 为 2 的 JSON 与信号/源码模式检查均通过。guest 汇总 409990bc1425f4bf219f8911a71581af6e68729865580121dbeb6d85a06d2ea7;外层收据 a022e40f068703cd59ce6d6a7fb6530cce6907681baa26eb1dfc77c09f0c8898;导出记录审计 24afc50f6f860394d1ebfa7a8b754ddd9cb97f9e88a0dcfcbcb659193ecbfe5f
当前 Linux arm64 当前 Linux arm64 在 ext4 上以非 root 用户实测(QEMU HVF 原生 ARM),Go1.27.1/HugoExtended0.166.0/Git2.47.3:完整离线单元/vet(370 项顶层通过)、13 项决定性纯测试及四项成员子项无跳过、10 项选定实际 Hugo 无跳过、当前归档原生/安装字节身份、双语/离线/普通 Hugo/信号流程通过。24 命令达到预期退出,含缺少 Hugo 为2。guest 268102f69c0950f9d2994d22cd2fd290fc11e24bd6d6f916fd70a93ca4946c74;外层 f3c066fdc9b97feff92160346185a1af978a5172eed5c81904ac7c0e5fc6c982;源码/SDK/借用输入/旧任务保护准确一致,独占 VM 回收。默认可选单元跳过保留具名门控原因,不宣称完整 Linux Hugo 套件/浏览器/linter
前一源码 Linux amd64 失败试验 当前 TCG 试验失败,尚未完成验证;原外层收据 3543664ba5590f2ba5a8f676b196bb636b72bc819913289f415d0a8a841c1bdb、guest 汇总 16075204d287713c7f7650c0a65dd289dd4bd83db07c9ba4b85b3f21244d5240 保持不变。完整离线单元(370 项顶层通过)、vet 和前三项选定 Hugo 案例通过;发布缓存候选请求触发测试 HTTP 客户端的 90 秒截止时间,候选一致性、其余六项选定 Hugo、原生重构归档及安装归档 smoke 尚未执行。截止时间审查 12917b9eb89e3abc5893e08da3b6b6e20743dcb4c14e6f7ba8561628e3566934。A18 未关闭,不推断后续 preflight 或完整验收结果
当前 Linux amd64 当前 Linux amd64 在 ext4 上以非 root 用户实测(QEMU TCG 模拟),Go1.27.1/HugoExtended0.166.0/Git2.47.3:完整离线单元/vet(370 项顶层通过)、13 项决定性纯测试及四项成员子项无跳过、10 项选定实际 Hugo 无跳过、当前归档原生/安装字节身份、双语/离线/普通 Hugo/信号流程通过。49 命令达到预期退出,含缺少 Hugo 为2。guest 3a1a32979efc843de8b95b7c13824026e17f71c06d4c458b738c0b9583fb4723;外层 30cf4950cc83fa0732047d9a0f89bb59e68779ee2e8f5c755724c9679be265e3;源码/SDK/借用输入/旧任务保护准确一致,独占 VM 回收。默认可选单元跳过保留具名门控原因,不宣称完整 Linux Hugo 套件/浏览器/linter
运行时等价的此前四消费者候选语料 源码时期 683daca0…33f224;运行时 123/二进制 74ad 与当前 196245a3…42d43 字节相同,单测试修改后未重跑语料。853.249 秒;原生/候选原生 0/0/0/1,API/视图 0/0/0/2;诊断 28/144/120/11250、覆盖 29/34/41/29。汇总 a1e98ca3e10095a1134381666bacf256f8e8827cd3900c9e811b7120de4c2974、收据 05c4562a50d9f83ba2c99879ec841870c5e753199e41792bd5bc718cf8046e7b、独立审计 3a1b0b6e3a8c6b1a0d82c5f82b46c84b1e44d6c30bab655610cb9e86e6a30b47;最终 TEN 字节具有独立渲染边界
最终规范生命周期与渲染检查 准确晋升 TEN 字节需要独立规范渲染及导航/URL 收据,此前渲染证明不验证这些修订字节

此前六门禁 b40b7787b3da8dc1e0763812b6dde529b4b5b69fe479d79940f1161223124e1d、host/归档 bcb4d7599e965c1b3cfe7fe698ca14061ad53d45e7a194337aeebb8d37aa77c1 与 ARM 外层 a022e40f068703cd59ce6d6a7fb6530cce6907681baa26eb1dfc77c09f0c8898 / guest 409990bc1425f4bf219f8911a71581af6e68729865580121dbeb6d85a06d2ea7 / 审计 24afc50f6f860394d1ebfa7a8b754ddd9cb97f9e88a0dcfcbcb659193ecbfe5f 仅验证自身捕获源码,与新准确源码证明共同保留,不覆盖或改称新结果。历史 26 项 axe/截图与 22 项 codec 案例依据未变 UI/codec/运行时输入复用,不宣称重新执行。

首次 max CPU 的 AMD 试验保持失败:收据 3543664ba5590f2ba5a8f676b196bb636b72bc819913289f415d0a8a841c1bdb、guest 汇总 16075204d287713c7f7650c0a65dd289dd4bd83db07c9ba4b85b3f21244d5240。测试客户端等待候选响应头 90 秒后超时,候选一致性、其余六项选定 Hugo、原生重构/安装 smoke 未执行。guest 输入保持准确;host 保护只记录 .git 目录时间戳变化,原因未证明。独立 qemu64 单案例 preflight 也在未变更的 90 秒 HTTP 客户端截止时间失败:外层收据 fc68173ccdfd8ce263ecdf082a533d9da666a4cc2e1e5e29880ee827286132ac、guest 汇总 e350ff65feeee166ffac1d337db9bbd70d3895b1fb6d93df0a30ca4de09019fc。具名案例耗时 177.71 秒,首次为 176.64 秒,不能推断 CPU 模型提速。其输入准确保留、VM 已回收;两次失败均不改称通过。

随后明确不构成验收的 Go overlay 诊断保留相同生产源码与全部原语义断言。 外层收据 0bc6d563b7cd9ca862717c2123ee0836d83b6b927d00204a0b031049c38e93f0 与原始记录绑定分类 66a1422cdb79ab9f1cf683f441ade0ce4adb4a7a666d524c4b9ed98ebee28708 记录具名案例在 352.40 秒内通过。原始捕获耗时 26.254 秒、Studio 捕获 26.211、 候选 HTTP 94.312、直接预览 94.318、CLI 预览 81.962。两份图均保留 1,256 个 唯一输入,其中模块输入 1,198 个。HTTP 返回时旧的原始捕获 context 已过期; 独立的新直接/CLI context 正常完成。全部 20,564 项 host 保护与五对 guest 命令 保护准确一致,独占 VM 正常回收。该诊断改变测试预算,不构成准确源码或完整 A18 验收。限定归属夹具修改现为该候选请求及独立直接/CLI 操作各提供 300 秒, 约为已观察最慢操作的 3.18 倍。一般/原始捕获 90 秒限制、共享客户端恢复、 15 秒 shutdown 与 Go 默认十分钟上限不变。这是测试夹具上限,不是产品性能 SLA。 正式 plain-Go AMD/ARM 与当前归档验收归上表当前记录;该诊断本身仍不构成验收。

前次语料验证未变更的运行时 CLI 与所捕获、未变更的最终 TEN 修订前消费者输入,不验证 随后修改的规范文档字节;最终 TEN 有独立渲染收据边界。

消费者 driver 比较 API 与 CLI 的完整类型化诊断、覆盖、原生退出、PlanID、所选 Base/After/完整模式、统一 diff 与所选源码,另外独立验证完整字面 API 审阅及其 哈希。附件和 no-op 的所选页面保持审阅 Base,页面文件编辑匹配审阅 After。 非问题视图为有界样本,所有问题/页面分页读取。53 个保护操作具有 212 次全四站 逐操作源码证明与四次整体证明(四种清单类别共 864 对原始清单),以及 53 对 根清单。绑定 71 份保留产物。没有 Apply、保存计划或消费者写入。已完成语料的 纯文件 collector 因旧试验/self-test 文件不在新目录而保留两次元数据修正;未重跑 CLI/Hugo 操作。现有 22 个负向 codec 案例是相同 codec 字节的历史检查,不能 宣称本轮新执行 self-test。

仓库保留 10,462 项已有重复 ID 发现和 788 项审阅信息。所选实际 DFE HTML 可用, 四份过大实际 PRINT 文件保持不服务(413,响应正文零字节): _print/pkg/index.html 73,976,221 字节、_print/pkg/pgsql/index.html 69,903,999、 zh/_print/pkg/index.html 73,086,240、zh/_print/pkg/pgsql/index.html 69,052,754。 逐文件 64 MiB 预览上限不变:必需局部预览未完成仍为 2,原生发现仍为 1, Apply 被拒绝。这是预期诊断结果,不是保护检查失败。

Linux 前置条件在独占私有 guest 中依据签名 Debian 元数据预备:准确十个新包和 三个获准既有包升级,安装前后均验证。SDK/Hugo/模块缓存独立供应后离线复用。 验收在 ext4 上以普通用户运行,缓存输入及全部 212 个源码文件的字节/完整模式受保护。 缺少前置工具的 guest 不隐含可选工具/浏览器通过:默认单元跳过保留实际门控或 不适用原因,所有必需纯测试顶层、无跳过目录成员子项、选定 Hugo 与信号案例必须执行。Linux amd64 在 ARM 主机上通过 QEMU TCG 明确模拟。Darwin amd64 保持实验归档:实际执行 返回 Bad CPU type(errno 86),没有安装 Rosetta 或宣称受支持运行时。Windows 不在声明范围。

当前 Linux 归档摘要为 ac883e54a1df0b820696279c63881ba75a00d279f507330128fe8d5aff59c52e (arm64,4,552,687 字节)与 2dde43bf94ef35aac2111b07dcb9b2766fbf9f883fe39ccd646d14a98b94d734 (amd64,5,034,668 字节)。此前 683daca0…33f224 的摘要 c191383af21913be6940ec41be11755b3d985344bbc0f65cc3f5de16424a96a4 与 6531b27d889260afe804c1f49f37541fbae46e57b5d17a20178c28cb51968794 保持历史范围。交叉编译本身不证明运行支持。SDK/guest 准备失败、 首次 ext4 成员检查失败及此前私有 host 元数据/resources 试验保持不可变证据。 本地完成不建立提交、公开版本、消费者采用、托管 CI 执行、部署或公网站点验证。 未启动 E1–E4 是独立非活动范围,不使有限 R1–R8 完成保持未决。

验收用例台账

下表结合初始审计、已接受 R1–R7 证据与已验证 R8 候选门禁。 每个完整用例只有在全部结果记录后才能关闭; 已验收阶段不关闭后续阶段范围。

用例 所需结果 代码或检查证据 状态与缺少的决定性证据
A01 单个 oink.result/v1 JSON;stderr 日志;政策为 1,必需未完成为 2 协议/公共 R1–R8 命令、冻结归属测试及精确二进制 CLI/API 报告;未改变结果 Schema;当前八项归属门禁/Linux 验收与未变运行时复用的此前语料见 #a18 受支持当前命令范围通过;后续新增命令需要自身证据
A02 Hugo 解析 slug/url/permalinks/aliases、挂载、未列出页面和语言根 真实 PageFacts/manifest/自定义挂载/translationKey 夹具;普通产物保留;最终消费站事实 R1 范围通过;后续阶段使用这些事实仍须自身验收
A03 确定本地缺失路由失败;真实分类 origin/path 外引用和声明外部范围 真实产物引用夹具、子路径/政策回归及最终真实站点 所需 A03 范围通过;外链可访问性仍明确未检查
A04 文件名、目录和 translationKey;重复/缺失/草稿;严格/本地化政策 R2 翻译引擎、真实 Hugo/公共命令、最终报告和数值补充 所需 R2 范围通过
A05 无记录为未知;源/译文哈希变化可见;不依赖 mtime R2 哈希/status/diff、公共预览/应用和最终报告 所需 R2 范围通过
A06 真实围栏、行内代码、短代码、HTML、属性、未知字段和受保护文本边界 R2 真实语法/来源夹具、经审阅语料和最终报告 所需 R2 范围通过;目录及不支持源码限制仍明确
A07 已确认问题可见;新问题按政策阻断;必需工具缺失不能通过 R2 基线/公共计划;R6 假/实际协议、缺失/不安全/离线/网络不确定及必需优先级夹具通过 受支持范围通过;必需不可用/不确定工具保持 2
A08 检查后字节变化使 manifest 无效;服务商上传已验证树而不再次构建 R3 manifest/导出/篡改/公共单构建测试,最终普通 Hugo 对比及服务商演练 所需 R3 本地范围通过;未执行服务商上传
A09 两种 CI 模板;保留定制工作流;权限/变量/来源和过期计划保护 R3 离线生成/bootstrap、公共预览/应用/过期输入、定制工作流补充及本地演练 所需 R3 本地范围通过;定制工作流未知且不变,未运行托管 CI
A10 拒绝 HTTP 200 回退、错误语言/构建、缺失资源/canonical 差异;超时/认证/限流为未完成 R3 显式联网本地 HTTP 和公共结果夹具,含必需身份缺失 所需 R3 夹具范围通过;未验证公开部署或浏览器运行
A11 所有声明配置/语言;目标保护;普通 Hugo;保留未知编辑器设置 R4 24 次普通 Hugo/公共配置、完整 Starter 创作/编辑器流程、片段、实际挂载、来源身份、JSONC 保护与外部 Schema 重新证明 所需受支持 R4 本地实现/语料范围通过;已声明不支持编辑器输入仍明确
A12 可读 diff 和路由比较;脏文件/workspace/replacement/vendor;恢复/并发 冻结真实 Hugo 七个固定合成模块用例、公共升级、源码/外部保护、实际 alias 改指向与受保护部分回滚 所需有界 R4 本地实现/语料范围通过;未知重定向/多主机仍未完成,不宣称自动配置迁移
A13 删除 B 找到未改入站 A;翻译/附件/派生产物;全局全量范围 R5 已提交 Git/实际 Hugo 删除、alias 入站、全局/不确定输入和不可用基线夹具;精确二进制消费者报告 所需受支持 R5 范围通过;不可用或未证明历史输入明确为 2
A14 应用前候选;过期/哈希/写入失败保留后续编辑;含糊引用不变 R2/R4 共享保护、R5 完整模式/清单移动及 R8 重新生成意图/新输入候选验证、保护写入器及过期/后续编辑/附件测试;当前八项归属门禁/Linux 验收与未变运行时复用的此前语料见 #a18 受支持 R5 CLI 与 R8 CLI/Studio 编辑范围通过;含糊或必需不可用输入仍阻断
A15 工作区/直接一致;只写选定站;上下文受限且有路径/版本/原因;不执行内容 R5 有界捕获源码/context 夹具与四站查询;R6 登记/直接/汇总一致及显式名称保存应用、其他站保留 受支持 context/工作区范围通过;无隐式批量写入
A16 五个实用 CLI 一致视图;键盘/移动端/深浅色;来源/预览隔离 已接受 R7 证据保留;历史源码绑定 R8 只读 14 项 axe/截图及 Editor 12 项 axe/截图,UI 字节未变;当前后端门禁、ARM 与语料独立验证、原生/API 一致、预览隔离、四消费者及规范渲染通过;当前八项归属门禁/Linux 验收与未变运行时复用的此前语料见 #a18 受支持本地视图通过;必需局部预览未完成/原生发现仍可见;不宣称通用浏览器/平台认证
A17 无修改字节;YAML 未知/注释/顺序保留;拒绝过期保存和附件冲突 修正冻结核心/公共/保护写入器 race、实际 Hugo/工具、源码绑定 Editor/只读浏览器、精确二进制四消费者提议一致性/保护及受保护规范源码/渲染在 #r8 通过;当前八项归属门禁/Linux 验收与未变运行时复用的此前语料见 #a18 受支持本地编辑范围通过;必需局部预览/原生发现仍阻断 Apply;最终 A18 独立
A18 实测声明 macOS/Linux 环境、子进程信号、已供应离线运行与明确不支持输入 当前冻结/源码与五归档重复复现;Darwin arm64、原生 Linux arm64、模拟 Linux amd64 非 root ext4/完整离线单元-vet/选定 Hugo/原生归档/信号 smoke 在 #a18 通过 当前声明运行时/归档范围通过;可选 guest 前置条件保持明确跳过;Darwin amd64 实验/未验证,Windows 不在范围

候选站点与源码保护

选定验收输入为内嵌 Starter 和三个不同的维护中消费站,复用历史语料但不写入消费站源码。 Starter 源 checkout 是来源输入;生成的配置试验使用临时目录。

同级 checkout 布局中的输入 初始观察身份与用途 本轮候选验收
oink-starter / 生成 Starter 源码 137843b,初始状态两项;有许可证的固定归档,语言/配置/根路径/子路径试验 R1 双语 init/check 与 R4 全配置普通/公共创作流程通过;归档/许可证不变
oink.pgsty.com 源码 907d873 和已有修改;双语文档/回归与显式本地主题试验 最终 R1 检查与源码保护通过;本地主题证据仍与公开固定版本分开
pig.pgsty.com 源码 75050c0,初始状态五项;Docs/Blog 根路由重写、不渲染侧栏条目;声明 v1.1.0 最终 R1 检查与源码保护通过
repo.pgsty.com 未产生提交的 main,无 HEAD revision;已物化的未跟踪源码、生成目录和声明的 v1.1.0 最终 R1 检查与源码保护通过;revision 仍未知

每次运行记录有效模块来源和版本、参数/网络政策、退出码/结果/覆盖、原始证据位置和保护结果。 前后清单必须包含所有 tracked 和未被忽略的 untracked 源码字节与模式、Git 状态/index、 workspace/replacement 文件及有效 vendor 输入。比较精确清单;文件数相同不能证明保留。 报告、隔离候选、产物和缓存放在消费站源码外,并保持不入 Git。 承诺增量速度前,全量构建耗时必须基于同一份当前输入比较。

归属检查与文档验收

先执行最小受影响 Go 包和公共行为测试。仓库现有门槛为 make test(离线测试和 vet) 及 make test-hugo(真实 Hugo Starter、快照、manifest 与公共命令夹具)。 归属 Hugo 门禁现运行全部归属包,不再使用旧的窄测试名称过滤器;新增夹具必须保持在门禁中。 并发计划/服务修改在归属测试需要时使用 race 检查。单元夹具保持离线,联网须显式调用。

文档保留中英文标题数量、顺序和稳定显式 ID。最小源码检查为:

node scripts/check-markdown-style.mjs content/docs/design/research
node scripts/check-doc-translations.mjs

添加本记录及中文对应文件后,两项源码检查均通过:八个中文研究文件通过风格检查; 翻译源码覆盖为 137/137 组,共检查 1,082 个源码标题。 这些检查只证明源码风格、配对和中文显式 ID;此次文档审计没有执行产物验收。

构建相关站点后,完成产物文档验收:

npm run _check:markdown-style
npm run _check:translations
npm run _check:rendered-markdown
npm run _check:rendered-links

make build 验证声明的公开固定版本;make check 选用同级主题执行完整非浏览器回归套件。 两种输入不能互相替代。Studio 需要自身的真实浏览器和无障碍验收。 文案源码检查通过不能证明双语渲染输出或 Studio 交互。

交付状态与剩余限制

状态 当前完成证据,历史保留于上文
本地实现 有限 R1–R8 受支持实现本地完成,包含只读 Studio 与显式受审阅编辑;当前 A18 运行时/归档通过。规范生命周期渲染独立绑定这些准确字节
本地验证 历史 R1–R8 归属/浏览器/语料/渲染记录保留;2026-10-04 当前后端修正和八项当前归属门禁、三个实际目标运行时/归档,以及运行时未变的此前四消费者保护/一致性证据复用在 #a18 通过。必需仓库发现/局部预览保持可见。渲染导航/URL 检查具有独立准确字节收据边界
提交 已识别 CLI 基线提交;本记录未建立维护提交证据
归档与运行环境验收 当前修正源码:Darwin arm64、原生 Linux arm64 与 QEMU TCG 模拟 Linux amd64 的安装归档/离线/信号/文件系统流程通过,两个新构建复现全部五归档;Darwin amd64 实际执行失败,保持实验/未验证
公开分发与消费站采用 本轮未执行
部署与公网内容验证 本轮未执行;本地 HTTP 夹具可在无云凭据时证明验证器

有限 R1–R8 实现与必需当前 A01–A18 运行时/归档范围已有决定性本地证据。 规范生命周期渲染需要这些准确新文档字节的独立收据,此前渲染证据不证明新字节。 未启动 E1–E4 和实验/ 不支持平台不增加未完成核心要求。公开发布、推送、部署、托管 CI 和消费者写入 保持独立未执行;已知仓库发现及必需预览未完成是诊断限制,不隐含通过。

7.10 - 2026-09-29 CLI 验收快照

本地 CLI 候选已执行的 Starter、真实站点、离线、升级与可复现归档检查,以及独立记录的最终验收和发布状态。
本地实现与验收完成

本地 0.1.0-dev 实现已通过本文记录的检查,CLI 源码已提交为 e623d93。 公开发布、下游采用和生产部署仍是独立状态,本轮未执行。

输入与方法

CLI 位于独立的 oink-cli Go 仓库。已接受的边界见 CLI 与结果契约,可复现的用户步骤见 使用指南。Hugo 继续作为外部渲染器,生成站点保留普通 Hugo 输入。

输入 观察到的基线
主机 macOS,darwin/arm64
Go go1.27.1
Hugo 0.166.0+extended+withdeploy
CLI 0.1.0-dev,本地提交 e623d93d589c49e5c58b8fae1bd5db720fc904cb
内嵌 Starter 提交 137843b25bacd76ddd1f7ce71330bf2e3155b954,完整、保留许可证的 Git 归档
生成站点的主题 pin 公开 github.com/pgsty/oink v1.1.0,使用已记录的 Go 校验和
文档站主题 本地主题 HEAD b0af631 加未提交修改;这不等于公开模块的字节身份

Starter 归档哈希为 e55bde279715f6d8d19d3d88671a2cf7561b515be46915b0f12c640d0ce1d958。 已记录的投影包括选择已有语言配置、固定 OINK v1.1.0,以及为新目录设置 enableGitInfo: false。最后一项来自真实故障:原有 enableGitInfo: true 会让 尚无第一次 Git 提交的站点在严格构建中因警告而失败。没有通过创建 Git 仓库或提交 掩盖这一问题。

检查使用临时源副本、模块及渲染缓存、输出目录。CLI 检查没有写入原始 Starter 或 消费站源码,并保留了主题与文档已有的无关修改。下列数量是对应输入与 CLI 修订的 快照,不是要求后续文档修改继续维持的阈值。

Starter 与普通 Hugo

预备模块并隔离缓存后,六组普通 Hugo 用例均通过 --environment production --panicOnWarning:

语言配置 根 URL /manual/ 子路径 Hugo 报告的页面数量
en 通过 通过 EN 90
en,zh 通过 通过 EN 91、ZH 89
all 通过 通过 EN 91、ZH 89、FR 89

测试检查了预期语言根与代表性 Docs、Blog、Book 产物,并比对 Hugo 构建前后的 生成源码字节。公共 CLI 的 init 命令还分别通过了三种语言配置验证,每组均无诊断, 生成 94 个源文件。三种配置的区别在于选定的根配置;其他语言示例仍保留在快照中, 通过既有语言配置禁用。

Starter 包的单元测试、race 与 vet 检查通过。失败用例覆盖非空及符号链接目标、候选 验证失败、计划后目标替换、取消回滚、并发修改或删除,以及归档路径拒绝。重生成脚本 精确复现了固定归档、来源清单与许可证。

真实站点检查快照

下列每次运行均返回 CLI 退出码 0,没有记录诊断。数量描述渲染产物与检查的引用, 不代表作者编写的页面数或独立用户数。

站点形态与主题来源 文件 HTML 文件 引用 机器产物
三语 Starter,公开 v1.1.0,在 /manual/ 做发布检查 316 142 7,042 6
OINK 文档与回归站,本地主题 HEAD b0af631 加未提交修改 1,127 506 72,562 8
PIG 项目站,根 Docs/Blog 路由重写,公开 v1.1.0 1,392 424 64,440 4
仓库文档与生成式目录,公开 v1.1.0 3,287 1,635 851,535 12

后三项是三个不同的本地消费站仓库。PIG 与目录站验证公开 pin 的解析;OINK 文档站 验证明确选定的本地主题修改,不能用来替代公开 pin 或部署站点的验收。执行这些只读 试点前已阅读站点指令。

检查覆盖已实现的 HTML 链接、锚点、资源及已输出的机器产物,不执行 JavaScript, 不检查外部 URL、托管重定向,也不执行浏览器、无障碍或视觉验收。最终 Hugo 清单 分别枚举了 261、766、662、3,192 项输出声明,按实际语言和 URL 要求每个受支持且 已启用的机器输出。前后清单逐项比对 tracked 与未被忽略的 untracked 源文件字节、 模式和 Git 状态:四站全部未变,分别覆盖 94、415、858、2,294 个源文件。

本轮修复了两项真实回归。仅生成英文的 NAVJSON 模板原本会掩盖中文产物缺失, 现在会返回政策退出码 1 并给出产物位置。PIG 有意使用的 build.render: link 侧栏项最初被误认为缺失页面,现在依据 Hugo 的生效参数排除,并有直接声明与 cascade 继承回归测试。双语 Starter 的普通构建与探针构建对照还证明,全部 223 个 原有产物字节完全一致。

离线执行与升级

macOS 上,在依赖齐备后,已初始化双语 Starter 的全站 check 在 sandbox-exec 的 (deny network*) 限制下通过。结果为退出码 0、零诊断、 223 个文件、95 个 HTML 文件、4,461 条引用、4 个机器产物。另一次英语 init 也在相同操作系统网络禁止条件下通过,返回退出码 0、零诊断,并生成预期的 94 个 文件。这些是针对对应操作实际执行的网络禁止测试,不是 Linux 防火墙测试,也不代表 所有消费站的远程资源流程都已验证。

一个依赖 example.invalid/[email protected] 的冷缓存夹具返回 CLI 退出码 2,并保留 Hugo 原始的 module lookup disabled by GOPROXY=off 证据。 依赖缺失因此被报告为必要工作未完成,没有静默启用联网解析。

另一个临时站点执行了真实公开模块从 v1.0.0 到 v1.1.0 的升级,原始消费站没有作为 写入目标:

操作 观察结果
预览 退出码 0;候选验证通过;applied: false;计划只包含 go.mod 与 go.sum
--write --expect-plan 退出码 0;匹配的计划验证通过并应用
重复同一目标版本 退出码 0;候选验证通过;没有待修改内容,applied: false

无关的已修改 README.md 和未跟踪的 user-note.txt 在三次操作后均保留。预览与写入具有相同计划 ID,以及相同 模块文件前后哈希。这证明已执行的单站点路径,不代表 vendor 刷新或独立用户完成 升级。replacement、workspace、脏目标文件、回滚及失败保护场景通过了最终聚焦 Go 测试与 race 检查。写入只改变 go.mod、go.sum,备份清单保留原始字节; 预览与重复执行保留全部源码字节。

另在临时初始化站点运行了真实薄包装验收:build --json 返回 0 并生成 index.html;dev --json 提供 HTTP 200,将 SIGINT 转发给 Hugo,并关闭监听。 Hugo 返回 0,被取消的包装进程按约定返回 2。这些运行使用预备缓存,未启用 --network。

最终 make test(全部包与 vet)、make test-hugo(普通 Hugo、workspace/配置 优先级、输出探针及语言缺失回归)和 go test -race ./... 全部通过。三种公开 init 配置均在操作系统禁止网络的条件下重跑通过,冷依赖夹具再次返回 2。

归档与安装准备

一个冻结的 CLI 源码快照生成了四份二进制归档、一份源码归档,以及 SHA256SUMS。 从源码归档独立重建后,全部五份归档的 SHA-256 均一致。此次打包验证的输入哈希为:

b07c5b98ef787dfe9924ce7b50c57d018c6149ec493124bb0103551a01535547

最终快照替代中途打包实验。全部五份归档的校验和均已核对,并从解压后的源码归档 精确复现。源码与二进制归档均包含版本化 JSON Schema、许可证、依赖 pin 和 Starter 来源记录。make install 安装到临时前缀及安装后二进制的 --version 检查通过。

目标 证据
darwin/arm64 已编译、执行本机二进制,并验证本地安装路径
darwin/amd64 仅交叉编译,未在该架构执行
linux/amd64 仅交叉编译,未在 Linux 执行
linux/arm64 仅交叉编译,未在 Linux 执行

归档构建器记录工具链、参数、源码输入哈希与平台限制,只准备本地文件。这项测试 没有建立公开下载 URL 或已发布的安装标签。

复现相关检查

在依赖已经预备的 CLI checkout 中执行:

make build
make test
make test-hugo
go run scripts/snapshot-starter.go --source ../oink-starter

按同级目录布局复现站点产物检查时,将 JSON 与日志保存在各消费站源码之外:

oink_acceptance_dir="$(mktemp -d)"
mkdir "$oink_acceptance_dir/reports"
./bin/oink init "$oink_acceptance_dir/my-docs" --languages all
./bin/oink check --site "$oink_acceptance_dir/my-docs" --release \
  --base-url https://example.org/manual/ --json \
  > "$oink_acceptance_dir/reports/starter.json" \
  2> "$oink_acceptance_dir/reports/starter.log"
HUGO_MODULE_REPLACEMENTS="github.com/pgsty/oink -> $(cd ../oink && pwd)" \
  ./bin/oink check --site ../oink.pgsty.com --json \
  > "$oink_acceptance_dir/reports/docs.json" \
  2> "$oink_acceptance_dir/reports/docs.log"
./bin/oink check --site ../pig.pgsty.com --release --json \
  > "$oink_acceptance_dir/reports/pig.json" \
  2> "$oink_acceptance_dir/reports/pig.log"
./bin/oink check --site ../repo.pgsty.com --release --json \
  > "$oink_acceptance_dir/reports/catalog.json" \
  2> "$oink_acceptance_dir/reports/catalog.log"

在提供 sandbox-exec 的 macOS 主机上,初始化双语站点之后执行:

./bin/oink init "$oink_acceptance_dir/my-bilingual-docs" --languages en,zh
sandbox-exec -p '(version 1) (allow default) (deny network*)' \
  ./bin/oink check --site "$oink_acceptance_dir/my-bilingual-docs" --json \
  > "$oink_acceptance_dir/reports/offline.json" \
  2> "$oink_acceptance_dir/reports/offline.log"
sandbox-exec -p '(version 1) (allow default) (deny network*)' \
  ./bin/oink init "$oink_acceptance_dir/offline-en" --languages en --json \
  > "$oink_acceptance_dir/reports/offline-init.json" \
  2> "$oink_acceptance_dir/reports/offline-init.log"

升级指南说明预览、计划审查与显式应用步骤。 写入路径测试应使用单独的审查副本。归档实验需保持 Go 工具链和发布版本一致:

make release VERSION=0.1.0-dev DIST=dist/first
mkdir -p dist/rebuild
tar -xzf dist/first/oink_0.1.0-dev_source.tar.gz -C dist/rebuild
make -C dist/rebuild/oink_0.1.0-dev_source release \
  VERSION=0.1.0-dev DIST=dist
cmp dist/first/SHA256SUMS \
  dist/rebuild/oink_0.1.0-dev_source/dist/SHA256SUMS

限制与交付状态

状态 本快照中的情况
本地实现 六个首期命令与版本化结果格式已存在
已执行验证 上述运行针对其记录的输入通过
归属检查与文档站 make check 实现与双语文档更新后通过
提交、标签、推送 CLI 已本地提交 e623d93;没有标签、remote 或推送。文档修改与既有工作一起保留在本地
CLI 公开发布或分发 未执行
消费站源码采用或生产部署 本次检查未执行
独立用户研究或采用 没有已测量的“五人中四人/15 分钟”研究、留存或独立团队采用数据

原始 JSON、日志、源码保留清单、升级恢复证据与归档核验结果保留在 CLI checkout 已忽略的 tmp/acceptance/ 下,归档位于 dist/first/。这些是本地证据,不是公开 下载。本次改变 CLI 行为和文案,不改变主题呈现或交互,因此未运行浏览器套件。

首期候选没有实现 Docsy 转换。上述试点已经使用 OINK,不能验证任意 Docsy 或 MDX 迁移。路线图继续将有范围的 Docsy 评估及后续迁移、主题能力描述、版本生命周期、OpenAPI、MCP 与 Studio 作为 独立提案。本地证据记录没有接受任何后续能力,也没有将它们计为完成。

8 - 设计提案与 PRD

仍在评估中的 OINK PRD 与设计草案的唯一双语归档位置。
非规范性材料

提案描述的行为可能尚不存在。当前行为由契约、已接受决策、实现与归属检查器定义。不能把提案 当作配置参考。

本栏目是 OINK 产品需求文档、RFC 风格设计与未决维护者提案的唯一正本位置。不要在主题仓库或 文档仓库中另建本地 plan/、plans/、proposal/ 或其它并行设计树。

当前提案

提案 当前边界
反向链接与知识图谱 G1(静态反向链接)已接受,已在主题 main 分支实现,随 OINK 0.8.0 发布;局部与全站图谱(G2/G3)保持草案
媒体收敛 部分已实现;media-result 契约与 Landing 资源元数据已交付,M3 决议为原生图片处理,退役(M4)保持开放
OINK CLI 与下一阶段产品路线 独立 Go 仓库与首期边界已接受,本地 CLI 候选已实现、尚未公开发布;后续主题、迁移、采用、版本管理、OpenAPI 与平台阶段保持提案
视觉预设与外观切换 Paper/Slate 已在本地实现;Ink/Terminal 继续研究;当前行为与证据见已接受决策和带日期验收记录

Agent 批量索引提案已在输出交付后退役。稳定行为现在归属 架构,用户步骤归属 Agent 就绪输出。Book 出版提案也在 BookManifest 与 EPUB/PDF 工具交付后退役。稳定行为归属架构与 创作书籍,带日期的下游采纳证据归属 消费站证据。剩余的消费站采纳工作 不会让上游设计提案继续保持活动状态。两份提案草案均由 Git 历史保存。

生成式配置 Schema 提案已按生命周期退役:行为的规范位置是配置总览, 长期理由进入生成式配置 Schema 决策,草案原文由 Git 历史保存。

CLI 工作区与适配器

显式 workspace 与可选适配器保留在当前收缩后的 CLI 中。 当前契约与 使用指南定义命令边界。 带日期 R1–R8/A18 记录是绑定历史源码/二进制的证据,不能证明后续命令或输出修改。 有限维护路线继续退出活动导航,尚未建立公开 CLI 发布或部署。

新 PRD 放在哪里

创建一份英文主页面及其简体中文对页:

content/docs/design/proposals/<slug>.md
content/docs/design/proposals/<slug>.zh.md

两份文件都使用显式、稳定的英文标题 ID。中文页面中的代码、键、路径、版本与 API 名称保持原样。 提案开头要有可见的草案状态,并包含:

  1. 状态、负责人、日期和受影响契约面;
  2. 背景与证据;
  3. 目标与明确非目标;
  4. 提议行为,以及输出、无障碍、安全边界;
  5. 兼容与迁移影响;
  6. 实现与归属检查器计划;
  7. 验收标准与待决问题;
  8. 记录提案自身变化的决策日志。

大型实验可以在 ../research/ 下增加带日期的页面;临时日志与生成 产物不进入 Hugo 内容,也不进入 Git。

生命周期

草案提案
    ├── 拒绝或被替代 → 从活动树移除,由 Git 历史保存
    └── 接受
          ├── 实现与归属检查器
          ├── 受影响的中英文契约
          ├── 理由具有长期价值时新增已接受 Design 决策
          └── 相关受众需要时更新变更记录、迁移与用户文档

提案被接受后不会自动成为第二份契约。稳定行为进入归属契约,稳定理由进入 Decisions,用户步骤进入 相关指南,然后把提案退出活动导航。本地构建、提交、tag、公开模块、消费站 pin 与部署仍是相互独立 的完成状态。

评审门禁

实施前,评审者确认提案没有重复已有外壳、resolver、组件族或数据权威。实施期间,如果设计改变, 先更新这份双语提案,不能让代码悄悄漂移。验收至少覆盖主题的最窄归属检查、真实文档站、渲染后的 中英文、相关输出、无障碍与响应式检查。

只读 Studio 候选

2026-10-04 当前 CLI 移除 Studio。使用 oink dev、普通编辑器与 inspect/check 结构化报告。R7 记录 保留此前浏览器实现的历史验收。

受审阅编辑

当前 CLI 移除通用源码编辑,保留受保护的 new、move、审阅记录与基线计划。 旧编辑计划会被拒绝。R8 记录 继续作为历史证据,不是当前命令 API。

8.1 - 反向链接与知识图谱

从普通 Hugo 链接推导反向链接、局部与全站图谱的三阶段设计草案。
G1 已实现,G2/G3 仍是草案

2026-08-27 决议 G1 的全部待决问题并接受 G1(静态反向链接)。它已在主题 main 分支实现,随 OINK 0.8.0 发布。局部与全站图谱(G2/G3)保持草案状态,等待 G1 的 真实使用证据;它们的名称和配置在被接受之前不是公开 API。

前提

反向导航与页面连接视图是链接图的属性,不是 [[wikilink]] 拼写的属性。Hugo 已经接受普通 Markdown 链接和 ref / relref。OINK 可以从作者已经在写的内容中派生图谱,无需增加解析器、 Goldmark 扩展或并行创作语法。

首要价值是反向链接,而不是可视化。静态入链列表不需要 JavaScript,在 Print 与 Markdown 中也能 降级。交互图谱应当只是完整列表之上的可选增强。

目标与非目标

目标:

  • 每次构建为每种语言派生一份链接索引;
  • 在页面上显示确定性的入链;
  • 可选显示有界的局部邻接图;
  • 可选发布全站视图与机器可读图数据;
  • 编辑链接暂时陈旧或不完整时,普通预览仍然可用。

非目标:

  • 引入 [[wikilink]] 语法;
  • 索引外链、mailto:、同页锚点或自链接;
  • 用 JavaScript 发现正文中已经存在的链接;
  • 把可视化变成唯一导航方式;
  • 承诺从任意 shortcode 参数或原始 HTML 中完整提取语义图。

交付阶段

阶段 交付物 运行时 独立价值
G1 语言内链接索引与反向链接列表 无 HTML、Print、Markdown 中的反向导航
G2 当前页面周围的局部图谱 既有 ECharts 加一个小型本地运行时 以 G1 为无障碍兜底的空间视图
G3 全站图谱页与图数据输出 同一运行时 全站探索与机器可读边

每个阶段单独验收。G1 不等待 G2,G2 也不会强迫每一页加载图谱代码。

提取契约

提议的索引按语言扫描源码一次,每对来源与目标只记录一条边。它先剥离代码围栏和行内代码,再提取 普通 Markdown 链接与 ref / relref;随后只解析站内页面,去掉 fragment 以确定页面身份, 排除自链接,并合并重复引用。

实现至少要测试:

  • 同一目标的重复链接合并为一条边;
  • 围栏与行内代码不产生边;
  • 外链、protocol-relative URL、邮件、同页锚点与自链接被排除;
  • ref 与 relref 被纳入;
  • 每种语言生成相互独立的图;
  • 无法解析的派生边由警告或专项检查报告,但不会让普通 hugo server 不可用。

扫描原始源码存在已知遗漏。自定义 shortcode 参数或原始 <a href> 中的 URL 可能不会进入图谱。 必须明确记录这种遗漏,不能声称得到完整语义图。

G1 在右栏输出一个 aside 组,与目录、分类标签云并列:目录讲这一页写了什么,反向链接 讲哪些页面指向这一页。该组默认展开,先显示前八条,其余折进原生 disclosure,避免被 大量引用的页面把右栏撑满。开关是站点键 params.ui.backlinks(裸布尔,默认关闭),页面用同名去前缀的 front matter 键 backlinks 覆盖,section 可以 cascade。排序必须确定:按稳定页面路径 排序——它与语言无关、与导航自然同组,且不需要第二个排序权威。该组使用普通链接;没有 入链时不渲染。

无法解析的派生边被静默丢弃并作为已知遗漏记录在案:G1 是本地导航增强,不是链接检查器, 让它替站点报告断链只会制造重复告警。

Print 与 Markdown 保留可读列表。除非后续 feed 研究证明反向链接能改善文章订阅而不是制造站点导航 噪音,否则 RSS 省略它。

交互图谱边界

G2 复用本地内置的 ECharts graph series。当前页面是中心,直接入链与出链邻居组成默认深度。硬性 节点上限防止视图不可读或成本失控。键盘焦点、文字替代、reduced motion、forced colors、窄屏和 Print 都是验收要求,不是后续润色。

JavaScript 或 ECharts 不可用时,G1 仍然完整可见。运行时只在真正渲染图谱的页面加载,并进入既有 feature bundle key,避免不同特性页面在资产缓存中撞车。

全站输出

G3 可以新增专用图谱页与 opt-in JSON 输出。JSON schema 包含版本、语言、节点和带稳定 URL 的有向边, 不暴露本机文件路径或未发布页面。它必须和 G1、G2 使用同一索引,避免三种表示各自漂移。

兼容与迁移

普通 Markdown 写法不变,因此无需内容迁移。配置名称继续待定,直到原型证明最小公开面。所有交互 与全站输出默认关闭;静态反向链接列表可以单独讨论,因为它只是本地导航,不涉及网络与浏览器状态。

验收标准

验收需要专项 graph 检查器、提取夹具、HTML/Print/Markdown golden、严格构建负向用例、浏览器无障碍 与响应式测试,以及真实双语站构建。性能在有代表性的大站上测量,但带日期的原型耗时不能自动成为 永久预算。

待决问题

G1 的问题已全部决议(见决策日志)。仍然开放、属于 G2/G3 的问题:

  1. 局部图只暴露一层,还是允许严格限额的第二层?
  2. 哪些页面元数据值得进入 graph JSON?
  3. 在 G1、G2 获得生产证据前,G3 是否值得新增输出格式?

决策日志

  • 2026-08-19:起草三阶段设计。
  • 2026-08-27:决议 G1 并接受,排入 OINK 0.8.0。G1 是 opt-in:站点键 params.ui.backlinks 裸布尔默认关闭,页面覆盖键 backlinks,不按 shell type 区分——策略归站点与页面,不归外壳。排序简化为稳定页面路径单键排序,删去 「section → weight → 标题」的三级链:单一确定性权威已经满足反向导航,多级排序 等于第二个导航权威。无法解析的边静默丢弃并记录为已知遗漏,不产生告警。 G2/G3 与图数据输出继续等待生产证据。
  • 2026-08-27:设计评审把这一块从页尾移到右栏。反向链接是页面元数据,与目录成对; 页尾是读者的收尾区——分享、反馈、出处、翻页、评论。右栏这一组同时引入八条上限, 其余收进原生 disclosure。

8.2 - 媒体收敛

正文图片、编号图、Landing 媒体与代表图片选择之间剩余收敛工作的设计草案。
部分已实现

M1(共享 media-result 契约)与 M2(Landing 资源元数据)已在主题 main 分支实现; M3 已决议为方案 2:图片处理只属于原生 Markdown 图片形态,完整 fig 源形态保持 容器语义,其参数表刻意不含 command/options。M4(兼容退役)在完成消费方盘点 之前保持开放。以下各节为原始设计记录。

当前基线

正文图片钩子、编号 fig、卡片与 gallery 统一通过 content/image-resolve.html 解析页面资源、 section 资源、全局资产、static 文件与显式远程 URL。栅格资源可以提供固有尺寸与处理后派生图。 HTML Zoom 资格使用 data-td-image-zoom 标记;构建期检测只查找主题自己输出的标记。

独占 Markdown 图片已经可以把题注或 Book 编号与图片处理、链接组合起来。编号图片 figure 共用 td-figure 与 td-book-figure 语义。Landing 媒体经过共享 URL 信任策略;代表图片则刻意使用 排序 resolver,因为它的职责是选择代表图片,而不是渲染一个显式来源。

剩余问题

共享安全边界已经比共享媒体模型更成熟。Landing 媒体仍然拿不到与正文图片相同的页面资源元数据和 处理结果;代表图片选择与显式图片解析返回不同结果形状;部分兼容 class 仍保留在标记中;Book 的 全量 fig 形态也不能表达原生图片钩子的所有处理选项。

因此问题已经不再是“替换七种图片入口”,而是:能否在不抹掉各自语义差异的前提下,让剩余表面共享 一份小型结果契约。

目标与非目标

目标:

  • 为 URL、原始 URL、尺寸、替代文字、署名、可处理状态与外部状态定义一个规范化媒体结果形状;
  • 在来源语义重合处,让显式正文图片、Landing 媒体与代表图片复用这个形状;
  • 继续让 figure 标记与 Zoom 资格分别只有一个归属实现;
  • 决定全量 fig 是否需要处理能力,还是要求处理过的编号图使用原生图片形态;
  • 只有在完成消费站证据与 release note 后才退役兼容标记。

非目标:

  • 增加第三方 lightbox 或远程图片服务;
  • 意外把 image Zoom 从 opt-in 改成站点政策;
  • 给 gallery 新增题注、序列或轮播模型;
  • 把表格、公式、示例等非图片 Book 目标合并进只适用于图片的基类;
  • 强迫代表图片排序与显式图片解析完全相同。

提议阶段

M1 — 结果契约

记录正文 resolver 与代表图片 resolver 的返回字段,再把交集提取成一份内部媒体结果契约。代表图片 继续负责来源排序,正文 resolver 继续负责显式来源解析。这是要求字节输出不变的内部重构。

M2 — Landing 资源元数据

允许 Landing 条目中的合格本地资源通过媒体契约解析,获得固有尺寸与相同 URL/安全结论。Landing 数据中显式给出的宽高继续优先。远程与 static 来源仍然合法,但不能伪装成拥有可处理资源元数据。

M3 — 全量 figure 能力决策

从两个答案中明确选择一个:

  1. 为全量 fig 的来源形态增加处理参数,并通过同一处理 helper 规范化;或者
  2. 处理能力只属于原生 Markdown 图片,把全量 fig 明确定义为任意编号块内容的容器。

实现不能让两个答案各完成一半。两种形态的 Markdown/LLMS 输出必须一致地链接到文档规定的原图 或派生图。

M4 — 兼容标记退役

移除旧图片元素 class 或属性之前,先盘点下游 CSS 与 JavaScript。兼容名称仍被使用时,要么保留一个 明确的版本窗口,要么在同一 release train 中迁移归属站点。

安全、输出与无障碍

  • 图片 URL 继续遵守共享 scheme 与远程主机策略。
  • 缺少必需替代文字时发出警告,且只在现行契约允许处渲染装饰性回退。
  • 宽高不能声称 SVG、static 文件或远程来源没有提供的元数据。
  • 带链接的图片不是 Zoom 目标;运行时保留 dialog 焦点、键盘关闭、reduced motion 与窄屏约束。
  • Print、Markdown、RSS 与 LLMS 去掉交互标记,同时保留目标图片、题注、署名、编号与链接。

验收标准

每个阶段分别拥有 HTML 与 Markdown 字节级证据、正文与 Landing resolver 测试、URL/安全检查、图片处理 测试、Book 目标、gallery/Zoom 浏览器测试,以及真实站中英文窄屏审查。只有 M3 的能力选择明确后, 提案才能被接受。

待决问题

  1. 一份共享结果结构是否足够,还是共享更底层的 URL/资源记录会让 resolver 归属更清晰?
  2. Landing 应消费资源署名,还是只消费尺寸与 URL?
  3. 原生图片已经能组合编号、题注、链接和处理后,全量 fig 处理能力是否仍有真实消费需求?
  4. 哪些输出兼容名称仍被真实消费站使用?

8.3 - OINK CLI 与下一阶段产品路线

已接受的独立 CLI 边界与首期本地候选,并明确保留后续采用、主题、迁移及内容模型提案。
首期为本地候选,后续路线仍是草案

用户于 2026-09-29 授权独立 Go 仓库 pgsty/oink-cli 及首期开发。六个命令已有本地 0.1.0-dev 实现,最终本地验收单独记录。当前行为归属 CLI 决策与结果契约及使用指南。这不代表 CLI 已公开发布或已有独立用户采用。主题 1.2、工具能力描述、Docsy 迁移、版本生命周期、OpenAPI、MCP 与 Studio 保持提案状态。

记录 内容
状态 仓库选择与首期范围已接受;本地候选已实现并验证;后续路线保持草案
负责人 OINK 维护者;最终本地验收与公开发布仍为独立状态
日期 2026-09-29
范围 OINK 主题、独立 CLI、现有 Starter 与文档站
受影响契约 架构、配置与诊断、输出、迁移,以及后续的版本导航与 API 内容
源码快照 主题 HEAD 3a18234、文档站 HEAD 85f16bf、Starter HEAD 137843b,以及下文明确标注的本地工作

核心建议

独立建立 oink-cli 仓库,发布名为 oink 的可执行文件,对外继续使用 OINK 这一个产品品牌。主题负责渲染内容;CLI 帮助用户初始化、诊断、校验、升级,随后逐步支持迁移。文档站继续管理公开指南、双语设计记录和集成验收。

仓库选择与 Go 实现现已接受并在本地建立,公开发布仍是独立动作。首期行为已移入 CLI 契约;带日期的验收记录列出实际执行的检查与剩余限制。本路线图继续承载后续阶段和采用目标。

首发应改善从现有仓库到可靠发布的流程,四项实质性能力是 doctor、check、init、upgrade。dev 和 build 可以提供轻量、透明的 Hugo 快捷入口。根据真实输入仓库的证据,再扩展一条有明确支持范围的 Docsy 迁移路径。版本生命周期和 OpenAPI 生成排在首个可用版本之后,同一时间只推进一个主要内容模型项目。

主题必须允许用户不安装 CLI。对于生成内容,这意味着提交生成后的 Hugo 输入,或者以其它明确方式提供这些输入:移除 CLI 后,普通 Hugo 仍能构建站点。重新生成输入是独立操作。

产品定位与目标用户

建议对外描述为:

OINK 是基于 Hugo 的本地优先文档工具箱,将工程知识发布给读者与 Agent。

安装说明和检索入口仍保留“Hugo 主题”,因为它准确描述用户安装的东西。“知识编译器”适合作为架构方向,但目前不足以证明 OINK 已经建立了新的产品类别。新的叙事不应遮蔽现有 Markdown/Hugo 路径。

优先服务使用 Git 的开源基础设施、开发者工具和多语言技术文档维护者。他们眼前的任务是让站点运行起来、定位故障、安全升级,以及在迁移中保留 URL 和内容含义。现有维护站点提供回归证据,独立团队提供采用证据,两者用途不同。

首阶段明确不做可视化 CMS、托管账户、部署控制台、软件包市场、LLM 运行时、语义搜索服务或新渲染引擎。书籍、博客和落地页继续得到支持,但不由这些场景的功能清单驱动本轮路线图。

证据与对研究建议的调整

本提案参考用户提供的战略报告,并对照本地实现、双语 Design 专栏、Starter 和当前官方文档核实。不把报告中的 Star 数、工时估算、商业价格或市场判断视为已验证需求。

观察 产品含义
OINK 已有公开 Starter、生成式配置 Schema、迁移脚本、出版工具和主题检查器 应把选定流程产品化,避免另起一套全量实现
front-matter Schema 刻意不包含类型约束 它不是完整的可执行校验器;严格检查要尊重对应解析器和真实 Hugo 输出
现有版本功能包括跨站菜单、归档横幅和可选的路径拼接 缺口是生命周期与可靠的页面对应关系,不是再加一个菜单或横幅
当前版本文档明确采用各版本独立 Hugo 构建 首先延续该模型,不悄悄引入单次构建内的多版本渲染体系
OpenAPI 组件在 HTML 之外只保留规范链接,并有明确的无障碍豁免 静态、无障碍的端点内容是一项具体的后续改进
反向链接已实现,G2/G3 仍为草案 图谱可视化不是已经接受的交付承诺
bin/update-consumers.py 在当前工作树中属于尚未提交的本地工作 可以参考其版本解析与文件保护规则,不能据此宣称 CLI 已发布
主题和文档站有大量与本提案无关的本地修改 本提案只记录建议,不替这些工作完成验收或发布

原报告正确强调了采用成本和可选工具层。以下四项调整能让它成为可执行计划:

  1. 将安全升级与初始化、诊断并列。现有用户已经有直接、可测试的维护需求。
  2. 区分维护者回归检查器与消费站检查。面向固定夹具的脚本不会自动成为通用站点校验器。
  3. 按明确的输入配置范围承诺迁移,不承诺完整 Docsy 或任意 MDX 转换。
  4. 将同时开展版本化、OpenAPI、图谱和平台建设,改成逐阶段决策。功能列表与工时相加不是人员到位的交付计划。

竞品能够证明流程方向已有先例,不能证明 OINK 自身的需求。Mintlify CLI 提供预览、校验和链接检查;Nimbus 将脚手架与 Agent 可读产物结合,目前仍为 pre-1.0;Docusaurus 明确定义版本快照,也提醒其维护与构建成本。如果照搬 Nimbus 将整套界面源码交给用户的模式,会把升级维护工作转给 OINK 消费者。可以对小型内容模板借鉴该方式,主题本身仍保留可升级模块。

为什么独立建仓

方案 好处 代价 建议
继续扩充主题 bin/ 下的 Python 脚本 小型维护改进最快,可以同时修改并测试 安装分发体验弱,没有统一的公共命令契约 保留内部和历史工具
在主题根 Go 模块内添加 cmd/oink 单一 checkout,源码修改可以原子提交 混合 Hugo 资源模块、应用依赖、二进制发布和消费站支持 不作为公共 CLI 的方案
在主题仓库中使用独立 Go 子模块 保留同仓修改,同时隔离 Go 依赖 仍需管理子模块标签与独立发布,也更容易直接调用未发布主题内部实现 可用于限时原型,不作为首选产品归属
新建 pgsty/oink-cli 可执行工具边界清楚、独立发布,用户无需克隆主题内部工具 必须显式维护兼容性和跨仓验收 已接受;本地 Go 仓库已建立

这是发布与职责划分,不是说单仓在技术上不可行。嵌套模块能够隔离依赖;分仓也确实会带来协作成本:一次渲染行为变化可能需要两个 PR、配套契约与兼容性测试。OINK 已经采用主题、文档站和 Starter 分仓,只要公共边界足够小,这个成本可以接受。

主题与 CLI 不应强制使用相同版本号。建议 CLI 0.1.x 同时支持经过测试的主题 1.1.0 基线和下一受支持版本,按能力声明兼容范围。遇到不支持的功能应明确报告,不能拿最新主题的全部 Schema 去判断所有旧站点。

现在不另建 linter、迁移引擎、OpenAPI 生成器或共享 SDK 仓库,先作为 CLI 内部包。二进制可以用 Go 编写,同时不引用 Hugo 内部 Go 包,也不让主题模块依赖 CLI。

职责划分

范围 归属 边界
布局、组件、样式、导航、搜索、无障碍、输出语义 pgsty/oink 在 Hugo 与静态站点中运行
主题默认值、对应解析器、生成式 Schema、输出 Schema pgsty/oink 主题行为权威及其投影
主题实现检查与小范围非法输入夹具 pgsty/oink 继续作为维护者工具,允许使用 Python 或 JavaScript
环境诊断、消费站检查、初始化、升级,以及后续迁移转换 pgsty/oink-cli 首期命令已在本地实现;迁移保持提案
OpenAPI 解析与源码生成、后续版本快照编排 pgsty/oink-cli 的拟议后续能力 生成普通 Hugo 输入,不负责最终渲染
小型官方站点骨架与语言配置 pgsty/oink-starter CLI 初始化的单一来源;可将固定快照嵌入 CLI 版本
指南、案例、PRD、已接受理由、双语集成与浏览器验收 pgsty/oink.pgsty.com 继续作为公开文档与回归站点的权威
托管凭据、账户开通、部署授权 消费站工作流 使用现有 CI 与服务商工具;CLI 首发不执行部署
                         可选的 oink CLI
                  init / doctor / check / upgrade
                      后续 migrate / generate
                               |
                               v
                 用户拥有的 Markdown + Hugo 配置 + data
                               |
                     Hugo Extended + OINK 主题
                               |
               HTML / Print / Markdown / 搜索 / 索引
                               |
                     读者 / Agent / 可选适配器

CLI 读取 Hugo 的生效配置、实际解析到的主题所发布的契约文件,以及构建产物。不应通过文件名猜测最终页面树,也不维护第二套导航解析器。Hugo config 已能输出生效配置;模块检查还需覆盖 replacement、workspace 与 vendoring。

下一期主题:建议 OINK 1.2

本节保持草案。本地 CLI 候选使用已发布的 OINK v1.1.0 基线;首期 CLI 决策既未接受主题 1.2 发布或新的工具能力描述,也不以它们作为前提。

本版本以降低采用成本为目标:站点能向工具准确说明配置与输出能力,升级不要求引入新的创作模型。范围应足够小,能够独立于后续大路线发布。

优先级 需求 验收
P0 在已有 Schema 旁提供小型、带版本的工具能力描述,声明可用 Schema、输出契约与工具链边界 描述由对应实现校验;CLI 从实际解析的模块读取;不新增逐页产物或运行时请求
P0 让少量高价值配置诊断直接指导修复:参数、非法值、允许形式、回退和对应指南 覆盖真实上手故障,如 Goldmark、输出与语言配置;保留普通预览告警、严格发布失败的约定
P0 读者界面与机器产物继续共用导航和 Markdown 权威 现有输出、导航检查继续覆盖语言、顺序、子路径及可选输出;CLI 不另写渲染器
P0 随版本交付经过测试的 Starter 快照与下游采用记录 将公开模块解析与同级替换构建分开验证,分别记录消费站 pin 和部署
P1 原型证明有必要时,为工具消费的少数诊断加入稳定标识 每个标识有对应检查器;CLI 不依赖对所有人工告警文本的解析

能力描述属于发布元数据,不是新的配置权威。配置 Schema 继续从现有权威生成,可选形态校验仍归对应解析器与检查器。不要违反现有诊断决策,另建通用改名键注册表。迁移转换应属于明确的 CLI 配置范围,而不是模板中的永久兼容路径。

1.2 不要求增加新的视觉组件族。正确性、无障碍和已经发现的回归仍可驱动修改。现有媒体工作保留其独立验收范围,本路线图不把所有草案完成都变成发布条件。

CLI 首发:建议 0.1

下列命令已在本地 0.1.0-dev 候选中实现。当前参数、结果语义与限制由 CLI 契约及使用指南定义;公开分发与最终验收仍为独立状态。

命令 用户结果 首发边界
oink doctor 理解站点为何无法运行,或者本地环境为何与 CI 不同 检查 Hugo Extended 与版本、模块 pin 与实际来源、Starter/工具链要求、必要配置、启用输出;默认不修复
oink check 知道发布构建和本地引用是否有效 在隔离输出中进行一次严格构建,再检查站内链接、锚点、资源与启用的机器产物;报告覆盖范围与不支持的检查
oink init my-docs 得到一个无需 CLI 也能维护的小型中性站点 从固定 Starter 快照生成到新目录或空目录,选择支持的语言配置并固定主题版本
oink upgrade --to <tag> 看清主题升级需要修改哪些内容 默认预览,--write 在验证后应用已审阅范围;保护无关模块依赖、用户修改与 vendor 内容
oink dev / oink build 获得容易记忆的入口,无需学习第二套构建系统 轻量调用 Hugo,展示生效参数;build 使用发布严格度;始终支持直接使用 Hugo

check 是统一质量入口。0.1 不同时设计职责重叠的 lint、validate、audit、check。后续确有需求时,用 --scope 区分源码提示和产物校验。

诊断与质量范围

先覆盖高置信度、可行动的失败:工具链不符、主题未解析、必要配置非法、本地链接目标或锚点或资源缺失、已启用输出的引用不一致。路由和锚点以 Hugo 产物为准,覆盖语言与 base path。不能因为编辑器 Schema 未列出某个自定义 front matter 字段,就把合法输入判成错误。

未启用的可选输出不应触发缺失错误。本地候选不检查翻译完整性;后续完整性规则必须使用站点实际声明的语言和覆盖政策。重复标题、孤儿页、缺少描述、文风与新鲜度仍属后续可选观察项,经过真实误报评审后再决定默认值。静态检查不能声称浏览器无障碍或交互测试已经通过。

本地候选冻结 oink.result/v1:结构化诊断包含稳定规则 ID、严重度、已知位置、解释、行动建议与明确覆盖范围。JSON stdout 只输出结果,日志进入 stderr,所有命令均不等待输入。退出码 0 表示必要工作完成且无阻断项,1 表示政策问题,2 表示必要工作未完成。必需但不支持的检查不能返回成功。详细字段归属结果契约,不为构建派生问题编造行号。

保留 Hugo 原始错误作为子进程证据,其人工文案不构成 CLI 协议。将来可以从同一结果投影 SARIF,而不改变规则语义。

升级与文件保护

现有消费站升级脚本提供了有价值的本地先例:区分声明 pin 与解析版本,发布验证时禁用两套 workspace,识别模块 replacement,检查 _vendor。通过聚焦测试移植这些行为,不能在背后调用未发布的 Python 文件,却宣称是独立 Go 二进制。

0.1 只升级一个明确选择的站点。跨站批量发现暂留维护者脚本,等真实消费者提出需求。普通 check 可以检查有意使用本地主题替换的环境;check --release 必须排除这些替换,验证声明的公开版本。发现 go.mod 中冲突的 replacement 应报告,不应擅自删掉。

先展示将修改的文件,验证候选升级,再应用。只备份涉及的文件;预览后文件又发生变化时拒绝覆盖;保留无关的未提交工作。失败时应说明哪些已应用、哪些未应用,并提供不会覆盖后续编辑的恢复路径。仓库不干净不应阻止只读诊断。刷新 vendor 是单独的显式动作,只改 go.mod 不等于升级了 vendor 输出。

初始化和修复不能顺便 commit、push、部署、修改全局 Agent 设置或安装系统包。向明确的新目录初始化,本身就是用户请求的创建动作;修改既有文件则默认预览。不要为了这些有边界的操作构建通用工作流引擎。

分发与离线行为

本地候选当前提供已测试的源码/Make 安装路径与归档准备。公开 Homebrew formula、下载入口及标签安装仍属后续分发工作。当前运行验收覆盖 macOS arm64;其他归档目标仅为交叉编译候选,尚未在对应平台执行。

采用 Go 可执行文件,提供发布归档、校验和与 Homebrew 安装方式。先正式验证实际测试过的 macOS、Linux 架构,其它平台在文件系统和进程行为验证前标记为实验支持。安装后的 CLI 本身不要求安装 Go 工具链、Python、Node 或注册账户。Hugo 仍为外部渲染器;首次模块解析仍需要站点文档规定的 Git、Go、Hugo 工具链。

嵌入或随版本提供准确、保留许可证的 Starter 快照,保证初始化可重复。不应每次抓取变化中的 main,也不在 CLI 中手工维护 Starter 配置副本。发布 CLI 时检查内嵌模板与来源的一致性。

区分冷安装与离线运行。未在本地提供时,下载 Hugo、主题或未缓存模板需要网络。依赖齐备之后,本地诊断、检查和构建路径应无需外部服务。离线请求遇到缓存缺失应明确失败,不能偷偷下载。外链检查、远程规范等联网行为单独启用。无需默认遥测或后台更新检查。

第一项扩展:迁移

从实际候选站点中选择一套 有文档说明的 Docsy 输入配置范围,参考现有迁移夹具和报告模型。现有 OINK 0.4/0.6 转换并不能证明任意 Docsy 站点已经可以迁移。除 Markdown 语法外,还必须检查配置、导航、资源、语言和路由。

拟议流程为 oink migrate --from docsy --source <site> --output <new-site>。先评估再写入;应用需要显式参数,并输出到独立目录。每个源项目只有一个主要状态:原样兼容、已转换、人工复核、不支持。数量必须能够核对,附理由与源码位置。自定义模板和动态行为应明确列为人工工作。

验收包括源文件保留、支持范围内的转换幂等、不修改字面代码示例、站内引用有效,以及明确的旧新路由对照。优先保持 URL;改变 URL 时须提供适合托管目标的重定向方案。HTML 构建成功不足以证明语义一致或生产重定向生效。

不要承诺“一条命令迁移任意 Docusaurus 站点”。任意 JSX、import、内嵌 React/Vue 是程序,不能执行不受信任的源码来猜测含义,也不能静默删除无法处理的内容。第一条配置范围在没有维护者救场的情况下得到复用后,再开始第二个框架。完整 MDX 迁移是后续产品投入,不是 MVP 的一个解析器任务。

下一项内容能力:版本生命周期

首个 CLI 有用之后,默认优先考虑版本生命周期,因为它延续 OINK 已有的独立构建模型。只有真实 API 用户提出更强、反复出现的需求时,才把 OpenAPI 提前。单一主维护者不同时实现这两个基础。

主题负责读者界面的版本身份、可靠页面切换、归档状态,以及范围正确的搜索和机器输出。CLI 负责查看版本、准备快照、验证页面对应关系、修改声明的生命周期状态。oink --version 表示可执行文件版本;将来的 oink docs version ... 避免与文档版本混淆。

优先采用小型版本清单,记录版本标签、源引用、base URL、状态和默认选择。保留各版本独立构建及现有外部归档。CLI 管理的清单可以生成纳入 Git 的 Hugo 配置;在该模式中,清单由用户维护,配置是接受检查的投影。现有手工管理的 params.versions 继续受支持。原型必须先确定投影关系,再冻结格式。

页面对应关系需要按文档族、语言、版本区分的逻辑页面键。优先复用合适的 translationKey 或显式稳定键,不先引入通用 UUID。目标版本缺页时应明确说明,并进入约定的版本或分区首页,不能伪造等价页或盲目拼接 URL。路由别名处理页面搬迁,与页面身份分开。

内容有实质差异的历史页通常保留自己的 canonical URL,不能全部指向最新版。语言 alternate 应指向同版本中确实存在的翻译。默认搜索与 Agent bundle 保持在当前语言和版本范围内;将来若有跨版本聚合,必须显式启用。归档应保留源码并记录构建产物如何保存,不等于删除,也不悄悄重新部署不可变归档。

NAVJSON v1 的对象 Schema 当前禁止额外字段。因此增加版本或身份字段需要明确的新 Schema、输出契约或独立产物,不能声称是无影响的 v1 字段扩展。仅仅为未来图谱预留空间,不足以成为修改当前页面身份的理由。

随后的能力:静态 OpenAPI 参考

首个 OpenAPI 产品应是 只读静态参考生成器。CLI 解析本地规范及支持的本地引用,输出普通 Markdown/Hugo data,记录来源。主题提供符合无障碍要求的语义呈现和已有输出流水线,再由普通 Hugo 将生成页构建为 HTML、Print、Markdown、搜索和 Agent 索引。

先支持操作、参数、请求与响应正文,以及带链接的 Schema 描述。解析器原型完成后明确支持的 OpenAPI 版本和构造,不能静默丢弃不支持的构造。操作身份按 API/规范分域;缺少 operationId 时可由 method/path 派生,同时提示路径变化会影响身份。不同 API 复用同一 operationId 不能发生冲突。

人工指南与生成事实分开保存。生成必须确定、记录源哈希和生成器版本、能够检测过期输出,遇到非预期人工修改拒绝覆盖。将生成源码纳入站点 Git,或作为带版本的构建输入提供,使渲染本身仍不依赖 CLI。解析远程引用属于显式准备步骤,普通生成不能遍历任意外部 URL。

验收除玩具示例外,还要有真实用户规范;支持的操作完整可核对,循环引用能够处理,路由稳定,选定输出均包含语义内容,新静态渲染器的无障碍检查不继承 Swagger/Redoc 豁免。承诺吞吐指标前先测有代表性的大型规范。

保留现有 Swagger/Redoc 集成的兼容性。交互请求、凭据管理、SDK 生成、mock server 和 API 测试平台不进入本轮生成器增量。

架构与兼容规则

CLI 内部保持简单:命令处理、Hugo/进程适配、诊断、模板加载、限定范围的文件修改。迁移和 OpenAPI 到达对应阶段后再增加内部包。这只是建议分层,不是插件 ABI 或公共 SDK。

三个边界需要版本化:CLI 的机器结果格式、主题的公共 Schema/输出契约、受支持的迁移或生成输入配置范围。优先按能力检测,不一刀切要求“最新 OINK”。遇到更新但不支持的 Schema 时,必须给出可理解的兼容性诊断。

CLI 不能导入同级主题的私有 Python 模块、依赖特定本地 checkout 布局,或者运行时下载可执行检查器。通过行为测试移植选中的消费站操作。模板内部检查器仍留在主题;公开消费规则的后续变化同步更新其对应契约。过渡期间保留现有脚本,替代实现覆盖受支持场景后再退出重复实现。

初期不要求 CLI 配置文件,渲染配置继续由 Hugo 管理。重复使用证明有必要时,工具政策文件可以包含忽略路径、规则严重性和经过审阅的基线,但不能再维护 params.ui、导航、语言或模块 pin 的副本。Lint 基线不能豁免 Hugo 构建失败、输入不可读或必需检查不受支持。

路线图与人力假设

下列时间范围保留原始规划含义,不作为执行日志。阶段 0 与阶段 1 已有首期本地候选,但这不代表公开发布、独立用户研究、迁移或后续内容模型目标已完成。实际证据归入验收记录。

以下是 首阶段 8–12 周的规划范围,假设约一名全职实现负责人,并有部分文档与评审支持。这不是交付承诺,也不是对实际人力的判断。工具链验证、用户招募和双语评审都需要时间;应优先缩小范围,避免名义上的多线并行。

阶段 自批准起的时间 交付物 退出证据
0:确定边界 第 1–2 周 接受仓库选择,收集真实故障,定义结果格式与支持基线,在当前 1.1.0 上原型验证只读 doctor/check Starter 加至少三个不同形态的真实仓库;记录失败与覆盖缺口
1:完成日常流程 第 3–6 周 doctor/check、固定模板 init、轻量 dev/build、单站候选升级与文件保护测试 新用户能定位预置故障;生成站仍可直接 Hugo 构建;没有无法解释的源码修改
2:发布有边界的产品 第 7–12 周 拟议主题 1.2、CLI 0.1、兼容记录、文档、经过验证的安装方式、有限 Docsy 迁移评估与试点 首次使用测试与重复升级使用;迁移限制明确;公开 pin 与下游采用单独验收
3:验证迁移及一个内容模型 第 4–6 月 完善首条迁移路径;按用户证据选择版本生命周期或 OpenAPI;需要时规划主题 1.3 / CLI 0.2 至少两个真实仓库使用所选流程;接受契约后才承诺兼容性
4:证据支持的扩展 第 6 月之后 另一项内容能力,再按需求引入模板、来源信息或 Agent 传输层 有重复使用与维护能力;不自动承诺 SaaS 产品

如果阶段 2 超期,移除该版本中的迁移写入能力,保留评估报告。不能削减升级保护、真实诊断或 CLI 可选性。如果没有独立团队需要这套迁移配置范围,就停止扩充框架覆盖,回到上手体验与定位研究。

新鲜度、归属信息是后续可选质量能力,先以用户确实会处理的报告验证价值。修改日期绝不能冒充验证日期。先提供少量有用的官方页面模板,再考虑 registry。G2/G3 图谱、MCP、分析适配器、可执行示例、Studio 和托管服务,都需要具体用户问题及资源决策,不应现在填入确定日程。已有静态 Agent 输出,使 MCP 的紧迫性低于采用流程。

验收与产品指标

下列用户与采用指标仍是目标。维护者执行的本地试点用于验证实现和文件保护,不能证明独立团队、首次使用成功率、留存或生产采用情况。

范围 初始目标或必须满足的性质
首次成功 前置工具已安装时,5 名不熟悉 OINK 的目标用户中,至少 4 名在 15 分钟内无需维护者干预就完成预览与严格检查;冷安装另行记录
维护价值 至少三个真实站点使用诊断与检查,并重复完成受支持升级;每次失败均有可行动报告
诊断准确性 试点中逐项复核阻断发现,在明确计数、人工标注的样本中争取误报率低于 5%,不能把它当作未经测量的宣传
完整性 零静默内容丢失;迁移输入逐项可核对;重复转换无差异;用户编辑和无关依赖得到保留
独立性 依赖准备好后,初始化或生成的站点可以直接用 Hugo 构建;CLI 与可选输出仍可选择
离线行为 依赖准备完成后,在禁止出站访问的环境验证受支持本地流程;缓存缺失和显式联网功能分别记录
兼容性 当前经过测试的主题基线与候选版本、固定的站点回归工具链、根路径和子路径、中英文场景;不暗示已测试兼容下限以上的每个 Hugo 版本
采用情况 首阶段争取五个独立试点团队,跟踪其是否进入生产及在 30/90 天后继续使用;这是验证目标,不是现有用户成绩

主要采用指标使用独立维护的生产站点,通过公开引用或用户自愿确认核实。稳定文档站不应因为 60 天没有提交而退出统计;主题升级时效与留存分别衡量。Star、下载次数、自有消费站数量和 Agent 生成量都只是辅助信号,不能证明独立采用。

首次本地成功时间、首次生产发布时间、升级成本、迁移人工成本分别记录。部署可能依赖 CLI 之外的账户与服务商,不能把本地验证等同于发布。不要为收集指标引入默认遥测。

实现归属与验证

改动 对应验证
工具能力描述与 Schema 兼容 聚焦的主题描述检查器,以及 generate-config-schema.py --check 和相关参数检查
暴露给消费者的诊断 对应解析器与检查器用例,CLI 诊断结果和退出码测试
已有输出行为 按变化范围选择 check-agent-indexes.py、输出、安全和导航检查
初始化与升级 固定 Starter 快照,以及包含 replacement、vendor、无关依赖、目标文件未提交修改的 CLI 测试仓库
迁移 移植并扩充转换用例、源文件保护与重复运行检查,真实站点路由和内容复核
后续版本与 API 呈现 主题输出检查,以及双语文档站的集成、浏览器、无障碍、响应式和视觉评审

先运行最小归属检查。公共行为变化仍要求实现、检查器和双语契约协调交付。真实集成与视觉验收使用同级站点的 make check、make browser、make dev 流程。公开回归场景不搬回主题的合成夹具树,也不要求普通消费者安装维护者使用的 Node 测试栈。

发布时分别记录本地检查、提交、标签、公开模块或二进制解析、消费站 pin 与部署。主题发布后的采用继续使用现有消费站盘点流程。一个协调 issue 或清单即可连接各仓库,无需新增编排框架。

待决问题与停止条件

仓库选择与首期实现在本地已确定。剩余发布决策包括经过验证的平台、公开分发渠道、有实际执行证据支持的兼容声明,以及独立试点招募。验收记录列明实际本地工具链与选定站点,不代表未来平台或用户已经验证。

本地候选的结果与退出语义已在 CLI 契约中冻结。最小主题能力描述与稳定主题警告 ID 保持独立提案,不追加入首个 CLI 的前提条件。版本 beta 前确定清单投影、归档保存方式和页面对应关系;OpenAPI beta 前确定支持的规范子集与生成源码归属。

如果试点实际只需要一个小型维护脚本,规则必须反复复制模板语义,或者分发维护成本超过测得的用户价值,就重新评估独立 CLI 投入,并保留已经有用的独立脚本。证据变化时可以调整版本化与 OpenAPI 的顺序,不增加同时开展的总范围。

决策日志与来源

日期 记录
2026-09-29 根据提供的战略研究与本地源码评审创建草案。建议独立可选 CLI、小型采用版本、有边界的迁移和依次推进的内容能力。本文件没有接受任何实现或建仓操作。
2026-09-29 随后用户授权并接受独立 Go 仓库与首期开发。本地 0.1.0-dev 候选已实现 doctor/check/init/upgrade/dev/build;稳定行为移入 CLI 决策与使用指南。CLI 提交 e623d93 已通过本地验收;公开发布、独立采用及所有后续阶段提案继续分别记录状态。

查阅的本地权威包括:架构、生成式 Schema 决策、迁移边界、现有版本行为、OpenAPI 限制、图谱提案状态。还检查了主题 bin/、schema/nav.v1.schema.json、现有 Starter 与文档站构建检查命令。本地在途改动没有被表述为公开发布证据。

外部一手资料核实日期为 2026-09-29,包括上文链接的 Mintlify 命令参考、Nimbus 仓库、Docusaurus 版本指南及 Hugo 配置和模块文档。这些来源支持产品比较,不能证明 OINK 的市场需求或拟议时间表。

8.4 - OINK CLI 文档维护路线图

文档维护与 Oink Studio 的 R1–R8 历史需求记录,保留对应验收证据并指向当前精简 CLI 契约。
已实现需求记录

有限 R1–R8 受支持本地实现与 A18 运行时/归档范围对验收增补记录的历史源码和 二进制通过;当前精简 CLI 需要独立验证。本记录保留原 URL 与锚点,保留历史排期文本和失败试验;稳定行为归属 CLI 契约与指南,历史证据归属 2026-10-04 增补。 记录退出活动导航,未启动 E1–E4 是独立非活动范围。渲染导航/URL 验证需要这些准确晋升字节的独立收据。

先完成文档维护,再建立本地可视化工作台。产品应当帮助维护者检查修改、理解影响、 审阅安全变更,并发布刚才通过检查的同一份产物。Studio 使用这些相同能力。

记录 内容
状态 已实现;R1–R8 受支持本地范围与当前 A18 运行时/归档验收通过;渲染生命周期验证具有独立准确字节收据边界
负责人 OINK 维护者;具体研发与评审人员待确认
日期 2026-10-03
已有基线 本地 CLI 0.1.0-dev,提交 e623d93;macOS arm64 上的 Hugo Extended 0.166.0 与 Go 1.27.1
完成范围 R1–R8 及下文验收用例;条件性扩展另有启动条件
受影响范围 CLI 命令与结果契约、Starter 投影、消费站 CI、翻译政策、维护操作、本地 Studio、中英文指南
排期假设 一名全职开发,配合定期文档与评审支持;工期属于规划判断

背景与证据

原 CLI 路线图已接受独立 Go 可执行文件,将首次实现收敛为 doctor、check、init、单站点 upgrade、 dev 与 build。本提案增加有明确边界的文档维护计划。Docsy 迁移、版本生命周期、 OpenAPI 生成与主题 1.2 保留各自范围。

2026-10-03 的本地盘点重新执行了 Go 套件与真实 Hugo 集成测试。初始化的双语站点 检查通过,覆盖 223 个文件、4,461 条引用。PIG 消费站检查通过,覆盖 1,392 个文件、 64,440 条引用;858 个源文件及 Git 状态保持不变。这些是本地验证观察,不代表公开 分发、独立用户采用或部署。

盘点还复现了四项限制:渲染链接缺失时 check 失败而 build 成功;普通 HTML 引用越出配置的 base path 时被标为未检查;doctor --release 接受仍使用 https://example.org/ 的 Starter;两份内嵌部署工作流都直接调用 Hugo,没有执行 CLI 的附加检查。翻译完整性与可读升级 diff 也尚未实现。首批增量由这些发现确定。

产品目标与用户

优先服务多语言工程文档维护者,以及维护多个 Hugo 站点的小团队。高频任务是审阅 翻译、防止发布损坏内容、更新依赖,以及在不丢失引用和公开 URL 的前提下整理文档。

普通消费站能在本地与 CI 使用同一个质量入口,查看受影响页面,审阅并应用修改, 同时保留无关工作,才算实现产品目标。CLI、Studio 与 Agent 调用应得到相同的发现项 和修改计划。

功能取舍

原设计能力 决策 交付阶段
内链、锚点、附件与机器产物 加强已有检查,说明未覆盖情况 R1–R3
环境诊断、预览与严格构建 补齐发布诊断,增加显式的已验证构建流程 R1、R3
翻译完整性与受保护结构 作为核心产品能力建设 R2
初始化与 CI 配置 扩展固定 Starter,管理可审阅的 CI 修改 R3–R4
原生内容规则与项目风格 实现少量确定性核心规则,通用工具按需接入 R2、R6
新建内容、片段与编辑器配置 生成普通 Hugo 输入,保护已有文件 R4
安全升级与迁移预检 增加 diff 和候选对比;框架迁移保持独立范围 R4
页面移动、重命名与影响分析 页面关系与修改计划可靠后再实施 R5
问题面板与翻译对照 先做只读的本地 Studio R7
多站点 在单站引擎上增加显式站点登记 R6
EPUB、PDF 与离线打包 对可分发出版工具的条件性适配 E1
可执行文档示例 使用显式执行配置的条件性功能 E2
Agent 检查、影响与上下文 实现确定性的本地操作 R5
AI 翻译与语义审阅 确定性维护流程可用后,再验证修改提案 E4
来源、证据与知识依赖 本轮限定为构建及审阅来源、已观察到的页面关系 更广的知识管理延后
富文本编辑、实时协作与原生桌面端 只交付安全 Markdown 编辑;更大的平台延后 R8;其余暂缓

范围与非目标

R1–R8 是本 PRD 有限且明确的完成范围,每阶段都能独立产生价值并验收。拟议 CLI 版本 0.2、0.3 与 0.4 仅标识候选交付,不要求创建对应公开标签,也不绑定主题版本。

本计划不包含新渲染器、通用迁移引擎、托管账户管理器、部署 API、内置 LLM、向量 数据库、远程编辑器、实时协作、原生桌面壳或完整所见即所得编辑器。部署由既有 服务商工作流完成;发布权限与凭据继续由消费站所有者管理。

共享项目事实与检查政策

此范围已本地接受。下文保留原始提案需求作为历史;当前行为与参数归 CLI 契约所有。

扩展已有隔离 Hugo 分析,不另建配置解析器或导航权威。拟议内部事实包括页面身份、 语言、发布状态、实际输出 URL、已知源文件、翻译关系及已观察到的渲染引用。

使用 Hugo 公开的 Page.Translations 与 Page.OutputFormats 获取关系和产物。 Page.File可提供来源,但部分页面没有对应文件。 这些发现项必须保留产物位置和源码未知状态。临时探针移除后,普通发布产物的字节 应保持不变。

仅用 oink.yaml 管理检查选择、严重度、翻译政策、已审阅排除项及工具和流程选项。 语言、标题、菜单、URL 与站点配置继续归 Hugo,主题版本归模块文件。先提供共享 同一次分析的 check links、check translations 与 check style。保留 --json; --format json 可以作为兼容性的新增别名。

阻断错误、警告与建议沿用 error、warning、info 严重度。必需工具或输入形态 不受支持时仍返回退出码 2。政策不能把构建失败、输入不可读或必需检查未完成降级 为成功。源码位置需要可靠映射;无法定位时报告实际产物和 pointer。

翻译维护

此范围已本地接受。下文保留原始提案需求作为历史;当前行为与参数归 CLI 契约所有。

支持 Hugo 解析的文件名语言、独立语言内容目录与 translationKey 关系。覆盖政策 在明确的内容范围内选择必需语言;已禁用语言和有意本地化不能变成缺译错误。 检查重复身份以及政策指定的草稿和发布状态。生产构建未包含评估政策所需的源文档时, 使用明确的分析视图;不能把分析视图当成可发布产物。

提供两类政策:技术手册使用严格对译,博客或产品页面使用本地化内容。严格政策可 要求显式 ID、声明的占位符、指定代码块和必要字段一致;本地化政策只检查明确声明 的共同约束。标题数量相等、所有代码块相等都不能成为普遍要求。

拟议提供 translations status、translations diff <page> 和显式的审阅记录操作。 带版本的记录将译文绑定到源文档内容哈希或 Git 修订,并记录译文哈希与声明的源语言。 没有记录表示未知;哈希改变表示审阅后有变更,不自动断言翻译错误。记录审阅必须 来自用户要求的写入,检查器运行本身不能自动生成已审阅状态。

原生内容规则与问题基线

此范围已本地接受。下文保留原始提案需求作为历史;当前行为与参数归 CLI 契约所有。

先从真实消费站故障中提取少量高置信度规则:受支持组件及属性写法非法、显式 ID 冲突、已知弃用形式,以及项目配置的受保护内容。代码块、行内代码、短代码正文、 原始 HTML 和属性块需要各自的语法边界,不能无差别套用正则。

使用实际生效主题版本的契约。没有类型约束的编辑器 Schema 不能作为完整严格验证器。 缺少兼容元数据时,应明确限制覆盖范围,不能拿最新主题规则验证旧项目。基本检查 完成不以未来主题发布为前提。

可见且带版本的问题基线可以用稳定指纹、原因和审阅元数据确认已有发现项。报告 分别显示已确认项和新增项。基线更新必须显式、可审阅,不能隐藏必需检查未完成。 格式化与文风建议属于可选项。自动修复先生成 diff,再验证候选,最后只应用少量 边界明确的文件。

已验证发布产物与 CI

此范围已本地接受。下文保留原始提案需求作为历史;当前行为与参数归 CLI 契约所有。

保留当前 build 默认的透明调用。增加显式受管理的 build --check 流程:严格运行 一次 Hugo,在同一份输出上执行选定检查,再把已验证产物导出到新目录或空目录。 不能删除任意目录,也不能把旧文件混入已验证产物树。默认 build 必须继续说明 附加检查尚未执行。

本地版本化 manifest 记录已知的源码修订与修改状态、源码输入哈希、实际主题身份、 Hugo/CLI 版本、构建设置、base URL、检查覆盖与文件摘要。秘密和本机路径不得进入 公开元数据。启用公开构建标识时,只保留验证所需的最少身份信息。检查后产物字节 发生变化,已有检查结果就不能继续证明该产物。

拟议提供 ci init github-pages 和 ci init cloudflare-pages --mode direct-upload。 只生成本地配置,解释变量与权限,记录模板来源。发现已有工作流时展示 diff,保留 未知修改,并要求显式应用。两种模板使用相同质量引擎,上传已验证输出,中间不能 再运行一次 Hugo。CLI 尚无公开版本时,模板必须接受明确记录的不可变源码或归档 输入,不能假设某个下载标签已经存在。

发布诊断增加示例地址警告;发布政策要求正式地址时,该问题成为阻断项。可取得时, 报告实际本地来源提交和修改状态,并与受支持的已生成 CI 设置比较。未知自定义 CI 仍显示未知。本地 checkout 的提交不能证明公开模块身份;vendor 字节身份保持独立。

拟议提供 verify --site URL --manifest FILE,需要显式联网许可。验证代表性页面、 语言、资源、搜索/Markdown 输出、规范 URL 和产物身份。通用回退页面即使返回 HTTP 200,也必须无法通过身份验证。超时、认证、限流或缺少必需身份信息应报告未知 或未完成,不能伪造成功。通过本地 HTTP 夹具验证这些行为,无需部署到服务商。

创作与升级助手

增加 new、小型片段目录和显式编辑器 Schema 配置。创建页面包、选定语言的译文 草稿和普通 front matter,拒绝覆盖已有文件。译文草稿不代表翻译完成。编辑器提示 跟随实际主题,并保留已有编辑器设置。

通过组合同一份保留许可证的 Starter,为 init 增加 docs、blog、book、project 配置,不维护四份复制模板。接入已有项目时提供诊断与可审阅提案,不替换站点配置。

保留明确标签、单站点升级的保护,增加可读统一 diff,以及原基线和候选的路由、能力 对比。报告消失的 URL、变化的 aliases 和缺失的原已启用产物。候选构建通过本身不能 证明兼容。配置迁移需要已记录的转换与测试;没有时返回人工行动项。冲突 replacement 与 vendor 刷新继续由所有者显式处理。

影响分析与安全内容修改

此受支持范围已本地接受。下文保留原始提案需求作为历史;当前行为、边界与参数归 捕获事实契约、 移动契约及 指南所有。

在共享事实之上提供 inspect <page>、impact --since <ref> 与 context <task>。 Inspect 显示来源、发布状态、引用、翻译及产物。Context 按任务打包相关本地资料, 包含版本、路径、选择原因和大小限制,不需要向量服务或 LLM。文档内容是数据,不能 授权执行其中的命令。

首版 check --since 可以继续全量检查,但必须明确说明。后续优化应覆盖变化的目标、 入站引用、翻译及派生产物。删除 B 时,仍须检查未修改但引用 B 的 A。配置、模板、 导航或无法确认的依赖变化会把范围扩大为全量检查。缓存是可重建证据,不是权威。

拟议 move <source> <target> 默认预览。计划包含涉及文件、可读 diff、基准哈希、 翻译、附件、路由变化和 alias 建议。只改写能够确定理解的链接,含糊的模板或短代码 引用交由人工审阅。应用前核对基准,验证隔离候选,保护并发修改并保留恢复信息。 失败或过期计划不能部分覆盖用户工作。

工作区与可选工具

显式工作区登记选定站点目录,复用单站引擎,报告逐站结果和总体完成状态。写入仅能 发生在明确选择的站点,不能自动发现并升级全部同级仓库,也不重复 Hugo 设置。

可选 markdownlint、Vale 和 lychee 适配器使用明确配置、已预备的工具,统一发现项。 缺少必需工具返回 2,可选遗漏仍然可见。排除适配器无法理解的语法,不改写这些 内容。外链失败有歧义时要区分网络状态。安装工具与联网是独立动作,通用 formatter 默认不得覆盖内容。

R6 已接受本地边界

显式登记与可选适配器的受支持 R6 范围已本地接受。稳定字段和限制见 登记契约与 工具契约,用户步骤归属 指南。下述已接受 R7/R8 边界仍有 自身证据与限制。

oink.workspace/v1 用一份最多 256 KiB 的普通 YAML 文件登记 1–64 个字面目录, 不复制 Hugo 设置,也不发现同级站点。准确名称、规范根目录身份、登记顺序选择、 逐站 0/1/2 一致性及显式名称应用保存计划构成受支持工作区边界。已预备的 markdownlint-cli 0.49.1、Vale 3.24.0 与 lychee 0.24.2 扩展各站政策, 捕获配置并提供类型化协议/源码/网络覆盖;不安装工具或格式化内容。Lychee 需要 显式联网授权;有歧义的外部失败保留未知,不判为确定断链。

冻结 Go/vet、实际 Hugo/固定工具及归属 race 门禁已经通过。精确二进制也通过 四站直接/汇总诊断/覆盖/退出一致性,以及全部源码字节/完整模式/Git/被忽略输入/ 目录保护。初次预备失败仍不计作验证通过证据;仅验收驱动命令元数据的收据修正 独立记录,没有 CLI 运行时修正或重跑。受保护规范中英文源码/渲染检查通过, R6/A07/A15 受支持范围已本地接受,见 R6 记录。 当前 A18 运行时/归档验证通过;Darwin amd64 保持实验/未验证。聚焦测试不能推断版本发布、消费者采用、源码写入或部署。

只读 Oink Studio

建设本地 Web 界面,提供项目总览、问题面板、翻译对照、页面关系和发布面板。 这些视图使用与 CLI/CI 相同的核心结果,支持筛选、跳转已知来源、真实 Hugo 预览、 变更对照和复制建议。大型图谱或内置编辑器不是这一阶段验收的前提。

默认仅监听本机,明确允许访问的站点。将不可信渲染内容与管理界面隔离到不同 origin; 增加写 API 前,做好 Host/Origin 检查和会话授权。UI 预构建后随 CLI 分发,Node 是 贡献者构建依赖,不是消费用户运行依赖。覆盖键盘操作、屏幕阅读器标签、移动端布局、 深浅色和长问题列表的可读性。

R7 候选边界

只读 Studio 候选现已基于同一原生检查与捕获 Hugo 事实,提供内嵌五视图浏览器和 鉴权字面回环 API。稳定候选边界见契约与 指南。显式现存站点/登记选择、类型化分页发现、源码/ diff/哈希状态、真实生产预览及独立可选分析覆盖保留 CLI 权威。

冻结原生/浏览器/核心案例及精确二进制四消费者收据现已验证受支持只读范围, 包含明确局部预览未完成状态。它们覆盖原生 0/1/2 一致性、键盘/移动端/深浅色、 字面源码数据及独立 origin 预览攻击。R7/A16 已通过受保护规范晋升/渲染门禁并 本地接受。R1–R8 受支持范围已接受; 当前 A18 运行时/归档验证通过。不新增消费者 Node 依赖、隐式安装、源码写入、公开发布/采用 或部署。

安全 Markdown 编辑

只读工作台验收后,增加 Markdown 编辑、front matter 表单、选定组件插入和附件。 复用 CLI 修改计划引擎及真实 Hugo 预览,不建立第二套保存与验证机制。

没有修改的打开/保存周期必须保留原始字节。更新一个字段应保留未知字段、注释、顺序、 编码和无关空白。检测外部编辑器修改,拒绝过期保存。表单无法保留某种 front matter 构造时,保留文本编辑并说明表单限制,不通过通用序列化器重新输出整篇文档。

写入需要已授权本地会话、允许目录、基准校验和可见 diff。拒绝目录穿越、符号链接 越界以及来自不可信预览内容的请求。附件不能覆盖既有文件。发布静态站点不会把管理 API 一并发布出去。

R8 已接受编辑边界

R8 已为 CLI edit text、field、snippet、attachment 及显式 studio --edit 实现同一源码保护提议引擎,默认 Studio 保持只读。已知站点所有 Markdown、准确源码哈希、支持顶层 YAML 标量/文本回退、原生目录字节边界插入及 仅新建 leaf-bundle 附件共享同一保存计划和保护写入器。完整可见审阅绑定计划/文件/ 完整模式身份;候选 HTML 来自实际选定不可发布 Hugo 分析,原生发现与必需视图 未完成保持不同。

已接受本地接口见契约及 指南。修正冻结公共/Go/race/vet、实际/普通 Hugo、Editor 浏览器/无障碍/移动端及精确二进制四消费者保护门禁已通过。 R8/A17 受支持本地范围也通过受保护规范源码/渲染门禁并已接受,记录于 R8 记录。 先前失败浏览器/准备试验只证明当次输入,不验证后续字节。R1–R8 受支持范围已接受;当前 A18 运行时/归档验证通过。Darwin amd64 保持实验/未验证,公开发布、采用 与部署是独立未执行状态。

交付顺序与排期

以下按一名开发估算,不代表已经测量的开发效率。T0 是范围批准后的实施起点,尚未 承诺日历开始日期。阶段依赖由顺序验收门禁约束;增加人员可并行独立测试与 UI 工作, 但不能取消门禁。

阶段 有效工作周 交付内容 验收门禁
R1 第 1–2 周 共享事实、检查政策、分类检查、可信位置 Hugo 拥有路由和关系;必需检查未完成不能通过
R2 第 3–5 周 翻译政策及审阅状态、原生检查、可见基线 三种语言组织方式;严格/本地化用例;审阅修复保留文件
R3 第 6–8 周 已验证构建产物、CI init、发布诊断、公网站点验证 上传同一份已检查产物;检测字节漂移与 HTTP 200 回退
R4 第 9–11 周 新建内容、配置组合、片段/编辑器配置、升级 diff 与对比 普通 Hugo 可构建;脏文件、替换、vendor 与路由回归仍安全
R5 第 12–15 周 Inspect、Impact、Context、Move 与共享修改计划 包含未改入站引用及翻译;过期计划不能写入
R6 第 16–17 周 显式工作区与可选检查适配器 逐站结果一致;必需工具缺失为未完成;不隐式安装
R7 第 18–20 周 只读 Studio 与安全边界 五个实用视图;CLI/UI 发现项相同;无障碍与预览隔离通过
R8 第 21–24 周 安全 Markdown/表单/附件与冲突审阅 无修改保存零 diff;注释和未知字段保留;并发保存安全失败

另留 4–6 周用于集成、误报审阅、跨平台执行与修复,分配到各验收门禁。总规划范围为 28–30 个有效工作周。投入约为半职时,日历跨度可能约翻倍;这是需要复核的假设, 不是承诺。

R1–R3 形成拟议 0.2 质量与发布候选,计入早期预留后约在第 9–10 周。R4–R6 形成拟议 0.3 维护候选,累计约第 19–20 周。R7–R8 形成拟议 0.4 本地 Studio 候选,累计约第 28–30 周。公开发布是另行授权的动作,本地候选不要求每阶段都发布。

条件性扩展

扩展 启动条件 拟议边界 独立估算
E1 出版导出 至少两本维护中的书需要重复执行导出流程 复用可分发 EPUB/PDF 工具,打包本地产物,声明外部依赖 R3/R4 后 1–2 周
E2 可执行示例 明确的所有者指定可运行示例及可丢弃环境 审阅的执行配置、时间和资源上限、默认离线;不自动执行发现的正文 R5 后 3–5 周
E3 MCP 既有 Agent 集成确实需要 JSON CLI 调用以外的能力 对 inspect/check/impact/context/plans 的薄适配,沿用权限和诊断 R5 后 1–2 周
E4 AI 审阅与翻译 确定性翻译维护可用,且已有审阅过的评估语料 用户选择服务商,显式网络及费用设置,提案绑定源码哈希;不自动写源文件 R5 后 3–6 周的有限实验

这些估算不计入 R1–R8 总工期。扩展只在相应场景成立时启动;未来需求不是尚未完成 的核心里程碑。远程 Studio、实时协作、原生壳、通用知识来源管理、向量检索与通用 框架迁移需要独立 PRD 和证据。

架构与兼容

核心操作继续用 Go,通过子进程调用 Hugo 和可选工具。已有包拥有相应行为时就在 其中扩展,新包随真实能力加入。实际消费者需要之前,不建设通用插件平台、公共 SDK 或共享服务层。

保留 oink.result/v1、退出码含义和默认薄包装。诊断详情与命令数据可增加字段, 改变字段语义则需要新结果版本。审阅记录、基线、计划、构建 manifest 和工作区登记 分别版本化。从实际主题检测受支持能力,不强制全部用户安装最新版本。

读取/检查/预览、应用本地文件、联网、执行示例和部署是不同副作用。维护操作不顺便 进行遥测、后台更新、发现凭据、清理任意目录、修改全局配置、提交、推送或部署。 消费站只读试点保留源码、replacement、workspace 和 vendor 字节。

验收用例与归属检查

用例 必须达到的结果 主要归属
A01 JSON 与完成状态 stdout 只有一个 JSON;日志分离;发现问题为 1,必需未完成为 2 internal/report、internal/app、Schema
A02 Hugo 权威 Slug/url/permalinks/aliases、自定义挂载、未列出页面与语言根遵循真实 Hugo 结果 internal/site、internal/outputcheck、真实 Hugo 夹具
A03 子路径 确定属于项目的缺失路由失败;越出 origin/path 的引用真实分类;声明外部范围避免误报 产物检查与政策测试
A04 翻译 文件名、目录及 translationKey;重复/缺失/草稿场景;严格/本地化政策 翻译引擎与公共命令测试
A05 审阅状态 无记录为未知;源哈希改变可见;mtime 不决定审阅状态 翻译与审阅记录测试
A06 内容语法 围栏、行内代码、短代码、HTML、属性、自定义字段及受保护文本不产生虚构问题 原生规则测试与真实内容语料
A07 基线与适配器 已确认问题保持可见;新问题按政策失败;必需工具缺失不能通过 政策与适配器测试
A08 产物身份 检查后修改文件使 manifest 验证失败;服务商上传同一导出树,不重新构建 受管理构建与工作流测试
A09 CI 文件保护 两种模板、已定制工作流、权限/变量、预览/应用冲突与来源记录 Starter/CI 测试与本地流程演练
A10 公网验证 HTTP 200 回退、错误语言/构建、资源缺失、canonical 差异、超时/认证/限流 本地 HTTP 夹具,不强制云账户
A11 初始化与创作 支持的配置/语言;空目标保护;生成站直接用 Hugo 构建;编辑器未知设置保留 internal/starter、创作与 Hugo 测试
A12 升级 可读 diff、新旧路由、脏文件、两套 workspace、replacement/vendor、失败恢复及并发修改 internal/upgrade、公共命令/Hugo 测试
A13 影响 删除 B 发现未改 A;包含翻译/附件/派生输出;全局变化扩大范围 影响分析与 Git 基线夹具
A14 修改应用 应用前候选验证;哈希冲突和写入失败保留后续编辑;不改写含糊引用 共享计划/应用与 move 测试
A15 工作区与上下文 逐站结果与直接调用一致;只写选定站点;上下文有路径/版本/原因且受大小限制,不执行正文 工作区与 context 测试
A16 Studio 一致性 五个视图呈现相同 CLI 结果;键盘/移动端/深浅色可用;来源与预览隔离 Studio 浏览器和无障碍测试
A17 编辑保护 无修改保存字节一致;YAML 注释/未知值/顺序保留;拒绝过期保存和附件冲突 编辑器/浏览器与共享应用测试
A18 运行与恢复 在声明的 macOS/Linux 目标实测;信号结束子进程;缓存齐备可离线;不支持输入明确报告 进程/集成/安装测试

先运行最小归属测试,再做更广集成。Go 单元夹具保持离线。解析、快照、探针、初始化 或升级改变后,重跑真实 Hugo 测试。保留聚焦检查,不要求消费用户每改一篇文档就运行 主题内部测试或浏览器套件。

每个候选记录工具版本和源码身份,在 Starter 与三个不同维护站点上只读验证。前后 对比源码字节、模式与 Git 状态。原生新规则需要已审阅的合法/非法语料;成为默认阻断 前先修正误报。承诺增量速度前,应在同一当前站点基线上测量完整构建时间。功能正确 优先于检查项数量。

完成条件与发布证据

每阶段交付已实现行为、已知限制、聚焦测试、真实集成结果、更新的中英文契约/指南 和可审阅 diff。逐项记录需求及用例状态,不能因为某个汇总命令通过就自动关闭全部 需求。只有 R1–R8 及其必需验收用例满足,本 PRD 才算完成。

实现、本地验证、提交、归档和运行平台验收、公开分发、消费站采用、服务商部署与 公网内容验证分别报告。交叉编译不等于运行验收。缺少凭据或尚无公开下载地址不能 成为声称远程交付的理由,也不要求为此建设托管控制台。

受支持行为被接受后,进入归属 CLI 契约、使用指南和长期决策,再按现有生命周期 退役相应提案内容。本 PRD 不作为永久的第二份命令手册。

待决项与停止条件

将相对工作周转换为日历日期前,确认投入和开始日期。R1 决定支持的运行平台、审阅 记录的具体存储、首批原生规则和精确的兼容新增参数。这些是范围内的有限实现选择, 不应因此重开产品边界或等待整个主题发布。

文件保护或正确性工作超过估算时,把可选便利功能移后,不能删掉过期写入保护、真实 完成状态或普通 Hugo 兼容。多轮语料审阅仍无法可靠的规则保持建议级或移除。表单 无法保留源码字节的语法继续用文本模式。不能因为某个扩展值得尝试,就让它进入关键 交付路径。

决策日志

日期 记录
2026-10-03 根据当前 CLI 盘点与提供的功能目标创建草案,提出 R1–R8、可选扩展门禁、投入假设及可执行验收用例。本文不声称新增 CLI 能力、版本发布、消费站采用或部署已经完成。
2026-10-03 R1 共享 Hugo 事实与检查政策通过本地归属/真实 Hugo 检查。稳定行为移入 CLI 契约和指南;验收记录分别跟踪最终报告刷新与中英文产物证据。R2–R8 及条件性扩展仍未完成,不声称公开分发、采用或部署。
2026-10-03 R2 翻译范围/哈希审阅、有界原生规则和可见基线已使用共享保护文件计划。本地归属、真实 Hugo 与聚焦 race 门禁通过,最终消费站刷新和中英文文档验收仍在记录中待完成。已实现行为见契约与指南。R3–R8 仍未完成。
2026-10-03 R2 最终语料与中英文文档门禁通过。R3 一次渲染的已检查导出、准确文件身份、两种服务商的保护 CI 计划、发布诊断和显式联网 HTTP 验证已通过各自本地门禁,包括自定义 workflow 发现。稳定行为移入契约与指南;准确证据与 A08–A10 结果归维护记录所有。R4–R8、最终 A18 运行时/归档刷新及 Darwin amd64 仍未完成。不声称公开分发、托管 CI 已执行、采用或部署。
2026-10-03 R4 受支持本地范围通过冻结 Go/vet、真实 Hugo/race 及准确二进制只读 Starter/文档站/PIG/repository 门禁。同一未修改许可证 Starter 组合全部配置/语言;普通 new/editor/snippet 流程与源码/外部输入保护,以及可读有界升级视图和 alias/输出回归保护均通过。稳定行为归契约与指南,准确 A11/A12 证据和边界归记录。R5–R8、最终 A18 运行时/归档刷新及 Darwin amd64 仍未完成。未公开发布、写消费站/采用或部署。
2026-10-03 R5 修正冻结 Go/vet、实际 Hugo/race 及精确二进制四消费者只读门禁已完成。全部站点 inspect/context 完成;历史影响与移动阻断保持明确。受保护规范源码/渲染门禁及阶段接受仍待完成。稳定行为归契约与指南所有;记录标识 A13/A14/context 证据、缓存模块修正及精确保护记录。R6–R8、workspace A15 与最终 A18 保持未完成;没有消费者写入或部署。
2026-10-03 R5 受支持检查/影响/有界上下文与受保护移动范围在修正冻结归属门禁、精确二进制四消费者保护及首次晋升规范源码/渲染门禁后已本地接受。生产翻译检查仅保留已知 draft 发布文档缺失;独立不可发布分析的全部归属检查通过。稳定行为归契约与指南所有;记录保留精确结果及单独渲染后证据边界。A13/A14 受支持 CLI 范围通过;A15 context 通过,workspace/direct 一致仍归 R6。R6–R8 与最终 A18 未完成;没有发布、消费者写入/采用或部署。
2026-10-03 R6 显式登记与有界可选工具候选已实现;聚焦工作区与修正实际协议试验通过,预备失败独立记录。最终运行时/语料/规范门禁及 A07/A15 阶段接受仍待完成,见 R6 记录。R7/R8 与最终 A18 未完成;无版本发布、消费者写入或部署。
2026-10-03 R6 冻结 Go/vet、实际 Hugo/固定工具、归属 race 及精确二进制四消费者直接/汇总一致性与保护已验证。完成收据记录六个原始操作、repository 已有重复 ID 发现,以及不变原始输出上的驱动命令摘要修正;无需 CLI/Hugo 重跑或运行时修正。规范源码/渲染检查和显式 R6/A07/A15 阶段接受仍在记录中待完成。R7/R8/最终 A18 未完成;没有消费者源码写入、版本发布或部署。
2026-10-03 R6 受支持显式登记与可选工具范围在冻结 Go/vet、实际 Hugo/固定工具、race、精确二进制四消费者一致性/保护及受保护规范源码/渲染门禁后已本地接受。A07 适配器与 A15 工作区/直接/context 受支持范围通过;R6 记录区分首次晋升渲染字节与本次渲染后状态/证据修订。R7/R8 与最终 A18 仍未完成;没有公开发布、消费者源码写入/采用或部署。

| 2026-10-03 | R7 只读内嵌 Studio 候选及鉴权回环视图已实现;冻结核心/浏览器及精确二进制四消费者验收在声明范围内完成;受保护规范晋升/渲染及显式 R7/A16 接受仍待完成。R1–R6 保持已接受;R8/最终 A18 未完成;没有消费者写入、公开发布或部署。 |

| 2026-10-03 | R7/A16 受支持只读 Studio 在冻结累计已执行案例/浏览器证明、精确二进制四消费者一致性/保护及受保护规范源码/渲染门禁后已本地接受。首次晋升渲染字节与本次渲染后状态修订保持不同;完整调用失败与明确局部预览未完成保持可见。R1–R7 已接受;R8/最终 A18 未完成;没有公开发布、消费者写入/采用或部署。 |

| 2026-10-03 | R8 CLI/显式 Editor 源码编辑候选已实现;默认 Studio 保持只读。纯核心/流式输出复制聚焦证据已记录,失败浏览器试验保留。最终冻结公共/浏览器/消费者/规范门禁及 A17 阶段接受仍待完成,见 R8 记录。R1–R7 保持已接受,R8/最终 A18 未完成;没有公开发布或消费者写入/部署。 |

| 2026-10-03 | R8/A17 受审阅 CLI/显式 Editor 受支持本地范围在修正冻结完整归属/浏览器、精确二进制四消费者提议一致性与源码保护,以及受保护首次规范晋升/实际渲染后接受。R1–R8 已本地接受;R8 记录独立绑定首次渲染与本次状态字节,并保留所有失败试验、原生发现与必需局部预览未完成。最终 A18 当前 Linux/归档验证仍未完成;没有消费者写入、公开发布、采用或部署。 |

| 2026-10-04 | 当前后端完整性修正、刷新归属/Hugo/race、未变运行时复用的四消费者保护与三个声明运行时/归档验证通过,见带日期完成增补。有限 R1–R8 实现本地完成;需求记录/锚点保留,退出活动导航,稳定行为归属契约/指南。最终规范渲染生命周期验证独立,E1–E4 未启动;没有公开发布、采用或部署。 |

8.5 - 视觉预设与外观切换

Paper 与 Slate 已在本地实现;Ink 与 Terminal 提供显式开启的实验,等待视觉定稿。
第一阶段随 1.2.0 发布,Ink/Terminal 可显式启用

Paper、Slate 与外观菜单已随 OINK 1.2.0 发布。当前行为与证据由 架构契约、 已接受决策和 验收记录管理。 随后的 Ink/Terminal 实验提供真实可切换输出;本提案继续承载两者的设计定稿。10 月 4 日注入样式生成的截图仍是研究原型, 与 10 月 5 日真实主题输出截图分开看待。

状态与影响面

字段 值
状态 第一阶段随 1.2.0 发布;Ink/Terminal 显式启用
负责人 OINK 维护者
日期 2026-10-04
基线 主题 main(v1.1.0 之后,含未发布的 1.2.0 工作);文档站固定 v1.1.0
受影响契约 架构:信任、CSS 与无障碍(字体角色、强调色角色、行内代码颜色)、外壳(主题控件)、Landing、配置决策、品牌指南
第一阶段 Paper 预设、Slate 预设、默认改为 Paper、读者在 Paper 与 Slate 间切换
后续阶段 Ink/Terminal 视觉定稿;Folio 与 Canvas 只保留名称

背景与依据

以下基线与限制记录 10 月 4 日实施前的研究输入。

OINK 目前只有一套视觉,本文称为 Slate:冷灰蓝画布(#f1f4f8 / #0b1119)、 海军蓝文字、钢蓝链接(#245f94)、铜色点缀;Inter 用于界面与正文,Chakra Petch 用于展示标题与字标,IBM Plex Mono 用于代码与技术标注;Landing 首屏有蓝图网格与 光晕;行内代码为一组深红色。它由 assets/scss/td/_brand.scss 的 Bootstrap 自定义 属性、assets/scss/td/shell/_tokens.scss 的外壳 token,以及 assets/scss/td/_tokens-typography.scss 的字体角色定义。

PG.CENTER 是独立站点,具有维护者希望成为 OINK 未来默认的暖色编辑式阅读风格。 其展示层 token 位于该项目的 media/css/pgsql.css。在本地预览上测量 (2026-10-04,浅色与深色;首页、Docs 索引、长篇手册页、组件手册页):

角色 浅色 深色 说明
画布 #f7f6f3 #161513 暖白 / 暖黑
抬升表面 #ffffff #1d1c19 卡片、代码块
次级表面 #efede8 #262420 表头、悬停
墨色正文 #21201c #ece9e3
次级文字 #56534c #b6b1a7
线与淡底 墨色 4.5–22 % 透明度 浅墨色相近透明度 不使用带色相的灰
圆角 12 px / 8 px 相同
阴影 0 2px 10px rgba(33,32,28,.07) 以黑色为基 暖、柔
动效 160 ms cubic-bezier(.2,.7,.2,1) 相同

字体方面,IBM Plex Sans(可变字重 400–600)用于界面与正文;IBM Plex Mono 用于代码、 日期与版本;Chakra Petch 只用于字标。组件手册页是最好的长文样板:导语 17 px、 最宽 70ch;h2 后跟一条延伸到边缘的细线;带表头底色、无斑马纹的外框表格; 单色提示块加 3 px 竖线。

以下 PG.CENTER 元素属于站点身份,不是可复用的阅读规则:PostgreSQL 品牌蓝 #336791 系列、酒红正文链接、版本状态色、版本条、搜索类型徽标、Wiki 色调、 双色首屏,以及导入的 PostgreSQL 手册约 144 字符的行长。两个值不满足 WCAG AA (弱化文字 3.67:1、链接悬停 4.22:1),下文予以修正而非照搬。

用于对照的 OINK 文档测量值:正文 16 px / 1.7、行长约 76ch、h1 36 px / 700、 h2 24 px / 600、代码 14 px。PG.CENTER Docs 索引:15.5 px / 1.7,约 120ch。

现有限制

  • 颜色只与 data-bs-theme 绑定,没有属性能选择第二套调色板;多个表面绕过 token:Landing 主按钮(#2f6793 与海军蓝光晕)、网格、遮罩 (rgba(4,10,18,.45))、打印颜色、asciinema 表面与 giscus 样式表。
  • 约 85 处字面圆角与若干字面阴影,使扁平预设在没有圆角与阴影尺度前无法实现。
  • 明暗控件靠悬停或聚焦展开。触屏读者无法到达“跟随系统”;触发按钮混用 aria-pressed 与 aria-expanded;Esc 不能关闭。Landing 手机抽屉没有主题控件。
  • contrast-on-canvas.html 硬编码了 Slate 画布亮度,用于 theme_color 警告。
  • dark_mode 默认 false,站点不开启就既没有深色调色板也没有菜单。

目标与非目标

目标:

  • 一个站点配置键选择默认视觉预设;默认改为 Paper;
  • Slate 保留可选,选择它的站点得到与当前一致的输出;
  • 读者可即时切换 Paper 与 Slate,无需刷新,并与浅色/深色/跟随系统彼此独立;
  • 禁用 JavaScript 或存储不可用时,站点配置的默认风格照常呈现;
  • 预设共享模板、组件与布局几何,只改变配色与字体;
  • 只用本地字体、普通 Hugo 构建,不引入新的运行时框架或必需构建工具。

非目标:

  • 第一阶段实现 Ink、Terminal、Folio 或 Canvas;
  • 复制 PG.CENTER 品牌色、版本界面或页面结构;
  • 按页面或栏目切换预设(栏目颜色仍由 theme_color 负责);
  • 第一阶段按预设改变布局几何、密度或导航结构;
  • 在现有明暗处理之外为 Swagger UI、ReDoc 或第三方嵌入换肤。

预设模型

此表与下文第一阶段配置保留原始范围。后续实验增加显式 ink/terminal 配置及 菜单列表选项;true 仍提供稳定选项与站点默认值。当前行为由 架构契约管理。

预设 方向 第一阶段 读者菜单
paper 温暖的编辑式极简 实现,默认 是
slate 技术极简(当前 OINK) 实现 是
ink 排版极简,受瑞士风格启发 规格 + 研究原型 否
terminal 终端工具式功能设计 规格 + 研究原型 否
folio 学术与书籍出版 仅保留名称 否
canvas 活泼几何与创作者 仅保留名称 否

保留名称在实现前会被校验拒绝,警告中列出可用的稳定预设。

配置

params:
  ui:
    preset: paper        # paper | slate        (主题默认:paper)
    preset_menu: false   # false | true | [paper, slate]
  • preset 选择站点默认值。无效或保留值通过现有校验路径警告并回退到 paper; 发布门禁会把警告变成失败。
  • preset_menu 控制读者选择。false 不渲染风格分组、不输出预设初始化脚本; true 提供所有稳定预设;列表提供子集,且必须包含 preset。沿用 dark_mode 的先例,默认 false;文档站开启,Starter 采纳不在本轮范围内。
  • preset 只能在站点级设置,不支持页面与栏目覆盖:逐页切换视觉身份会破坏读者 预期与已保存的选择。
  • 只要 dark_mode.show_menu 或风格选择任一开启,外观菜单就存在。 dark_mode: false 且 preset_menu: true 的站点只显示“风格”分组。

与现有配置的关系

优先级由低到高:

  1. :root / [data-bs-theme] 上的 Slate 基础 token(选择器不变)。
  2. [data-td-preset=X] 上的预设 token。
  3. params.ui.typography: system:在所有预设块之后把字体角色收拢为系统字体, 因此在任何预设下都不请求品牌字体。
  4. params.ui.fonts:在样式表之后以 :root 内联输出;特异性相同、源顺序靠后, 因此覆盖预设字体角色。显式字体永远优先。
  5. theme_color / theme_color_dark:只作用于页面与栏目的强调背景,覆盖预设 强调色;从不触碰链接或行内代码。
  6. 站点 _styles_project.scss:位于样式包最后。

typography: technical 仍表示“使用预设自带字体”。具体是哪些字体由预设决定 (Paper:Plex Sans;Slate:Inter + Chakra Petch)。

读者状态

两个彼此独立的维度:

维度 属性 存储 取值
风格 <html> 上的 data-td-preset localStorage['td-preset'] 稳定预设名
明暗 data-bs-theme(及 .dark-mode、供应商 data-theme 镜像) localStorage['td-color-theme'] light、dark、auto
情形 结果
初次访问 服务端输出 data-td-preset="<站点预设>" 与 data-td-site-preset,不依赖脚本
读者选择预设 立即应用、保存,并派发 td-preset-change
读者选择标有“默认”的预设 删除存储键;之后站点默认值变化能到达该读者
下一页、刷新、切换语言 head 内联脚本在首次绘制前应用已保存的值
已保存的值不再提供 删除,使用站点默认值
存储不可用 选择只作用于当前页面,菜单提示不会保存
禁用 JavaScript 站点默认预设以浅色调色板呈现,与当前主题无脚本时一致;风格与明暗控件不可用
切换风格 从不写入 td-color-theme;切换明暗从不写入 td-preset
其他标签页修改 通过 storage 事件同步

内联脚本位于样式表之前,与现有明暗脚本并列。它用构建时嵌入的允许列表校验已保存的 值,设置属性,并按预设与明暗更新 theme-color meta 与首绘画布颜色。只有菜单提供 多于一个预设时才输出。与菜单无关,head.html 中静态的首绘 <style> 与单个 解析后的 theme-color meta 改为按站点默认预设的画布颜色渲染,取代原先硬编码的 #0b0d12、#ffffff 与 #000000。

切换时,运行时设置 data-td-preset-switching 一帧以抑制颜色过渡;记录第一个可见 标题或块作为滚动锚点;应用属性后恢复锚点偏移,并在 document.fonts.ready 后再校正 一次,因为 Plex Sans 与 Inter 的字形度量不同。焦点、已打开的菜单与表单状态保持不变。 第一阶段不使用淡入淡出或 View Transition。

外观菜单

比较了三个方案:

方案 评估
保留悬停菜单,增加一行风格 触屏与键盘缺口仍在;只能靠悬停发现
风格与明暗分成两个按钮 拥挤的导航栏多一个图标;手机抽屉更长
一个“外观”展开按钮 + 两组单选 选定:单一入口,触屏与键盘均可用,可扩展到更多预设

行为:

  • 触发器:一个图标按钮(aria-expanded、aria-controls,标签“外观”),替换 导航栏与外壳页脚行中现有的主题按钮。太阳表示当前亮色状态,月亮表示暗色。 快捷键 t 继续切换浅色/深色。
  • 面板:非模态弹出层,包含两个原生 fieldset 单选组。10 月 5 日修订后, 风格 使用两列图标与名称按钮,图标采用预设主题色,不显示字母预览或实验标记; 站点默认值在悬停提示与无障碍名称中注明。明暗 为浅色 / 深色 / 跟随系统分段 控件,英文分组名为 Style 和 Light。选择立即生效,面板保持打开以便比较。
  • 键盘:Enter/Space 或 ArrowDown 打开并聚焦已选中的单选;方向键在组内移动 (原生单选行为);Tab 在组间移动;Esc 关闭并把焦点还给触发器;焦点离开面板或 点击外部时关闭。
  • 反馈:选中项使用淡色背景与强调色边框,键盘焦点另有轮廓线。变化由原生 单选语义播报,不额外增加 live region。
  • 恢复默认:选择站点默认预设即清除已保存的选择,无需单独的重置按钮。
  • 手机(< 768 px):触发器保留在紧凑页头,并在文档抽屉页脚与 Landing 手机抽屉的 新行中提供。面板以底部表单打开,44 px 触控目标,同样两组,带关闭按钮。底部表单是用 showModal() 打开的模态 <dialog>,处于顶层:原型显示,粘性页头的 backdrop-filter 否则会成为 position: fixed 表单的包含块,抽屉的层叠上下文 也会把它遮住。
  • 命令面板:在 switch_theme 旁新增 switch_preset 动作。

dark-mode.js 保留存储键与属性,但需同步明暗单选的 checked 状态并监听其 change 事件,取代目前的 aria-pressed 按钮。

Token 架构

所有预设编译进现有的单一 main.css。字体通过 @font-face 声明,只有规则实际使用时 才下载;因此提供一个预设只增加 CSS 字节,在被选中前不增加字体字节。

// Slate:沿用现有选择器与取值
:root, [data-bs-theme='light'] { … }
[data-bs-theme='dark'] { … }

// 其他预设
[data-td-preset='paper'] { /* 浅色 token + 字体角色 */ }               // (0,1,0)
[data-td-preset='paper'][data-bs-theme='dark'],
[data-td-preset='paper'] [data-bs-theme='dark'] { /* 深色 token */ }   // (0,2,0)

// 随后:[data-td-typography='system'] 字体块(移到预设之后)

规则:

  1. Token 对等:每个深色块重新声明其浅色块的全部 token,Slate 深色值不会泄漏 到其他预设。由检查器强制。
  2. 深色孤岛:后代选择器形式覆盖嵌套的 data-bs-theme="dark" 孤岛 (Landing 代码板、预览)。
  3. 字体角色只用 (0,1,0),params.ui.fonts 因而继续优先。
  4. 强调色间接层:预设设置 --td-preset-accent(及 -rgb、-hover), --td-accent 默认取它;theme_color 继续写入 --td-accent,因此在两种明暗下 都能覆盖预设。
  5. Slate 不依赖属性:data-td-preset="slate" 不匹配任何覆盖块,现有站点对品牌 token 的覆盖行为与今天完全相同。
  6. 几何共享:第一阶段预设不改变栅格列、侧栏宽度或断点。
  7. 预设专属规则少而局部:每个预设一个 partial,限定在 [data-td-preset=X] 下; 两个预设都需要的东西就提升为 token。

Paper 之前(第一阶段)需要的新共享 token:--td-shell-scrim、Landing 的 --td-grid / --td-glow / 主按钮 token、--td-callout-tint、--td-code-inline-bg、 --td-hairline,以及 brand 字体角色(--td-brand-font-family,默认 var(--td-display-font-family)),使字标保留 Chakra Petch,而 Paper 的展示标题 使用 Plex Sans。

原第二阶段计划提出全局圆角、阴影与密度尺度。10 月 5 日实验改为仅作用于主题 自有组件的规则;更广泛的 token 重构不作为试用设计的前提。

契约变化:之前的架构契约把行内代码固定为一组深红色。第一阶段把 --bs-code-color 改为 预设 token(Slate 保留深红,Paper 使用墨色底片)。theme_color 仍然从不触碰它。

字体

预设 界面 / 正文 / 标题 展示 品牌(字标) 元信息 代码 新增字节
Paper IBM Plex Sans IBM Plex Sans Chakra Petch IBM Plex Sans IBM Plex Mono Plex Sans
Slate Inter Chakra Petch Chakra Petch IBM Plex Mono IBM Plex Mono 无
Ink Inter Inter Inter Inter(等宽数字) IBM Plex Mono 无
Terminal 界面用 Plex Mono,正文用 Plex Sans IBM Plex Mono IBM Plex Mono IBM Plex Mono IBM Plex Mono Paper 之后无

Paper 将 @fontsource-variable/ibm-plex-sans(OFL-1.1)vendor 到 third_party/ 并登记 VENDOR.json:拉丁、扩展拉丁、西里尔、扩展西里尔、希腊与越南语子集,正体与斜体,字重 100–700。PG.CENTER 仅正体、400–600 的子集为 40,240 B(latin)+ 25,868 B(latin-ext);准确体积在 vendor 时记录。需要斜体,因为 OINK 正文使用强调,PG.CENTER 的合成斜体不可接受。 完整的小型子集保留现有语言覆盖,浏览器按实际字符范围加载;12 个字体文件均登记于 VENDOR.json。

中日韩文字使用排在拉丁字体之后的系统字体栈:-apple-system, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', 'Noto Sans CJK SC', 'Noto Sans SC', sans-serif。IBM Plex Sans SC 因文件达到 MB 级被否决。等宽字体栈在通用 monospace 之前插入 CJK 无衬线字体,使混排代码的中文字形可预期。

typography: system 仍不请求任何品牌字体:system 块位于所有预设块之后,并重置 包括 brand 在内的全部角色。

衬线:第一阶段不使用衬线。拉丁衬线标题与中文无衬线标题并列显得不一致;Windows 默认中文衬线在标题字号下渲染较差;衬线还要多一套字体。第一阶段之后可基于本提案的 同内容对照样稿,评审一个可选的、仅用于展示标题的衬线。

预设规格

共享基础

属于所有预设,而不是 Slate:

  • 布局几何、断点、侧栏/目录宽度、约 76ch 正文行长;
  • 正文 1rem / 1.7,界面 0.875rem,元信息 0.8125rem;
  • 字号比例(h1 2.25rem、h2 1.5rem、h3 1.25rem、h4 1rem)——第一阶段预设只调字重与 字距,不调字号;
  • 焦点环:2 px 强调色描边、2 px 偏移,绝不移除;强制颜色模式回退不变;
  • 语义状态色(note、tip、important、warning、caution)保持色相;预设只改变淡底强度 与边框;
  • 第一阶段语法高亮沿用现有 Chroma 浅色/深色调色板;
  • 动效 token 100/150/250 ms;prefers-reduced-motion 关闭过渡;
  • WCAG AA:两种明暗下正文 4.5:1,大字与界面边界 3:1。

Paper

温暖的编辑式极简。 暖纸色、墨色文字、安静的细线、柔和阴影,舒展但不松散的阅读 节奏。它服务长篇阅读:大面积画布蓝光更少,界面对比更克制,Plex Sans 字怀开阔, 16 px 下易读。

Token 浅色 深色
画布 --bs-body-bg #f7f6f3 #161513
抬升 --td-brand-elev、--td-pre-bg #ffffff #1f1e1a / #121110
次级表面 #efede8 #1f1e1a
正文 #21201c(15.09:1) #ece9e3
次级文字 #56534c(7.10:1) #b6b1a7
三级文字 #6b665d(5.27:1) #958f84(5.68:1)
边框 墨色 12 % 浅墨色 13 %
链接 / 悬停 #2b5f8c(6.23:1)/ #1d68a5(5.43:1) #7db5e6(8.36:1)/ #a3cdf3
强调(铜色) #9c5530(5.17:1) #d99a6c
行内代码 墨色字、墨色 6 % 底片 浅墨色字、8 % 底片
阴影 sm / md 0 2px 10px / 0 14px 38px,墨色 7 % / 13 % 黑色 35 % / 50 %
圆角 代码 12 px、卡片 12 px、控件 8 px 相同

Paper 专属规则:标题 Plex Sans 600,字距 −0.006em(h1 −0.012em);h2 后接延伸到 边缘的细线;外框表格(圆角 10、表头底色、无斑马纹);提示块使用 4 %(深色 6 %)语义 淡底与单条 3 px 竖线;细线引用块;Landing 去掉网格与光晕,主按钮取自 token 并带暖色 阴影,首屏标题 600 / −0.025em;导航选中行使用暖中性底并混入 9 %(深色 12 %)强调色。 链接保持蓝色:这是阅读惯例,不是装饰。悬停与弹出层使用 160 ms ease-out;滚动时 不做动效。

Slate

技术极简。 即当前 OINK 外观,保持不变:冷灰蓝画布、海军蓝墨色、钢蓝与铜色、 Inter 正文、Chakra Petch 展示、Plex Mono 标签与元信息、蓝图网格与首屏光晕、深红 行内代码、8–12 px 圆角。选择 preset: slate 必须复现 v1.1 的 token 值,由检查器 比较。网格、光晕、Chakra 展示标题、等宽元信息与深红行内代码属于 Slate 身份;布局、 焦点、状态色与外壳结构属于共享基础。

Ink

排版极简,受瑞士风格启发的信息设计。 黑、白与中性灰,一个红色强调;层级由字号、 字重与对齐承担,而不是颜色、阴影或圆角表面。

Token 浅色 深色
画布 #ffffff #0b0b0b
正文 #141414 #ededed
次级 / 三级 #474747 / #636363 #b5b5b5 / #8f8f8f
表面 #f4f4f4 #161616
链接 墨色加下划线;悬停为红 浅墨色加下划线;悬停为红
强调 #c8102e(5.88:1) #ff5c4d
圆角 / 阴影 0 / 无 0 / 无

与 Slate 的区别:画布无色相、无蓝色、无网格纹理、无阴影、无圆角;链接靠下划线而非 色相识别;标题使用 Inter 700–800 紧字距,而不是 Chakra Petch。与 Paper 的区别: 中性而非暖色,平面而非柔和,粗线分隔而非细线,下划线链接而非蓝色链接。标志性规则: h2 上方 2 px 黑线;h1 800 / −0.035em;h4、表头与提示块标题大写加字距;导航选中行用 3 px 红色竖条而不是底色;等宽数字。

Terminal

终端工具式功能设计。 体现在结构与信息表达上,而不是 CRT 特效:等宽界面、命令与 路径表达、紧凑控件、明确的面板边界、琥珀或青绿强调。

Token 浅色 深色
画布 #f4f5f2 #0c0f0e
正文 #1d211f #d3dbd6
次级 #4a514d #9aa59f
表面 #e9ebe6 #141a18
链接(青绿) #0a6560(6.31:1) #4cc9bd
强调(琥珀) #935400(5.47:1) #f0a73a
圆角 2 px 2 px

等宽范围:导航、标题、标签、元信息、面包屑、按钮与代码使用 IBM Plex Mono。正文段落、 列表与表格正文使用 Plex Sans,中文使用平台回退字体,因为长段等宽文字与中英混排 等宽行都难以阅读。 标志性规则:标题前的 ## 前缀用 content: '## ' / '' 渲染,辅助技术会忽略它; 方括号提示标签([NOTE]);导航选中行反色并带 ▸ 标记;1 px 强边框面板;首屏静态 ▍ 光标。没有扫描线、辉光、闪烁或打字动画。

差异矩阵

Paper Slate Ink Terminal
色温 暖 冷 中性 中性偏绿
浅色画布 #f7f6f3 #f1f4f8 #ffffff #f4f5f2
深色画布 #161513 #0b1119 #0b0b0b #0c0f0e
正文字体 Plex Sans Inter Inter Plex Sans
标题字体 Plex Sans 600 Inter 600–700 Inter 700–800 Plex Mono
展示 / 字标 Plex Sans / Chakra Chakra / Chakra Inter / Inter Plex Mono
链接信号 蓝色 钢蓝 下划线 + 红色悬停 青绿
强调色 铜色 铜色 红色 琥珀
圆角 8–12 8–12 0 2
阴影 柔和暖色 海军蓝调 无 无
章节分隔 h2 尾随细线 无 2 px 顶线 ## 标记
选中行 暖色底 强调色底 红色竖条 反色 + ▸
行内代码 墨色底片 深红 墨色底片 带框墨色底片
Landing 纹理 无 网格 + 光晕 无 无
界面密度 标准 标准 标准 紧凑

页面密度

密度跟随页面任务,而不是预设:Landing 首屏允许最大的展示字号与品牌表达;Docs 正文 保持 1rem / 1.7 与约 76ch;侧栏、目录、参数表、搜索结果与命令面板保持紧凑行 (0.875rem,行高 1.4–1.5)。第一阶段预设可以改变这些区域的配色,但不改变间距。 Terminal 的紧凑界面属于第二阶段的密度 token。

运行时表面

表面 第一阶段影响
Blog、Book、分类 仅 token;Book 题注保持正文字体
搜索对话框与命令面板 遮罩 token 化;选中行使用 --td-shell-primary-dim
Mermaid、ECharts 颜色在初始化时依 data-bs-theme 固化。只有图表采用预设颜色时才需观察 data-td-preset;第一阶段保持仅随明暗变化
asciinema 表面 token;只有代码字体变化才需重新挂载(第一阶段不变)
giscus 每个预设与明暗各需一份样式表,并在 td-preset-change 时重新下发
Swagger UI、ReDoc 保持供应商样式与现有明暗处理
打印 海军蓝与冷灰 token 化;打印始终使用当前预设的浅色调色板
404 其自有 <html> 必须带上新属性

无障碍、安全与输出

  • 每套调色板在两种明暗下的正文、次级与三级文字、链接与强调色均满足 WCAG AA(见上文 数值)。theme_color 对比度警告按站点默认预设的画布计算。
  • 菜单使用原生单选,不使用 role="menu"。除手机底部表单(模态并恢复焦点)外不捕获焦点。
  • prefers-reduced-motion 与强制颜色模式保持现有行为。
  • 初始化脚本内联、静态,来自已校验的配置;已保存的值使用前先与构建时允许列表比对。
  • 不新增外部字体或脚本请求。输出只增加两个 <html> 属性、一段内联脚本与 CSS。

兼容与迁移

默认改为 Paper 会改变所有未设置 preset 的站点。

  • 想保留当前外观的站点加上 params.ui.preset: slate;升级说明以这一行开头。 Slate 输出必须等于 v1.1 的 token。
  • 在 _styles_project.scss 中覆盖品牌 token 的站点::root 上的浅色覆盖在 Paper 下仍按源顺序生效;[data-bs-theme='dark'] 上的深色覆盖会被 Paper 深色块压过。 这类站点应选择 Slate,或把覆盖改写到 [data-td-preset='paper'][data-bs-theme='dark']。升级说明与品牌指南需说明。
  • theme_color、typography 与 fonts 的含义与优先级不变。
  • dark_mode: false 的站点仍只有一套浅色调色板,只是变为 Paper。
  • 改变默认值的版本必须把它列为可见变化。该版本是次版本(1.x)还是主版本, 是待决问题。
  • 在发布默认值变化前,消费方盘点应报告哪些站点覆盖了品牌 token。

实施计划

第一阶段,按依赖顺序;每步注明负责的检查器。

  1. Token 化 Slate 泄漏点:Landing 主按钮、网格、光晕、遮罩、打印颜色、asciinema 表面;增加 --td-preset-accent、brand 字体角色,以及 contrast-on-canvas.html 的按预设画布亮度。Slate 的计算颜色必须保持等价。 检查器:check-landing.py、check-output.py、check-font-tokens.py。
  2. Vendor IBM Plex Sans:third_party/、VENDOR.json、许可证文件。 检查器:check-vendor.py。
  3. 预设 token:新增 assets/scss/td/_presets.scss(在 _brand.scss 之后导入); 当前实现将 Paper 保留在这个文件中,不另建 presets/_paper.scss。 字体预设块放在 system 重置之前。检查器:扩展 check-font-tokens.py(Plex Sans 字体族、system 块顺序、浅深块 token 对等)。
  4. 配置:hugo.yaml 默认值(preset: paper、preset_menu: false);一个 resolver partial,供 validate.html、document-attrs.html、layouts/404.html 与 head.html(初始化脚本、theme-color、首绘画布)使用;重新生成 schema。 检查器:check-params.py(接受、无效、保留值)、 generate-config-schema.py --check、check-namespace.py。
  5. 外观菜单:共享 partial,供 navbar.html、shell/footer-line.html 与 Landing 手机抽屉使用;preset.js 运行时(或 dark-mode.js 的一节);dark-mode.js 单选同步;命令面板动作 switch_preset;32 个语言目录的 i18n 字符串。 检查器:check-shell.py、check-actions.py、i18n 检查器、 tests/js/preset.test.js、tests/js/dark-mode.test.js。
  6. 第三方表面:按预设的 giscus 样式表与重新下发。
  7. 文档:EN/ZH 架构、外壳与 Landing 契约;品牌指南(预设、迁移、字体); 配置参考;变更日志与升级说明。
  8. 站点验证:make -C ../oink.pgsty.com check、browser(增加预设切换、持久化、 存储失败、无 JS、EN/ZH、桌面/手机、浅色/深色用例),以及用于视觉评审的 dev。

验收标准

以下保留最初的验收目标,已执行检查与剩余限制分别记录在10 月 5 日验收记录中:

  • 未设置 preset 时,输出带 data-td-preset="paper",禁用 JavaScript 也呈现 Paper。
  • preset: slate 在检查器样例上产生与 v1.1 相同的计算颜色与字体角色。
  • 切换风格不改变 td-color-theme;切换明暗不改变 td-preset;两者在导航、刷新与 切换语言后保持。
  • 无效的已保存值被删除;存储失败时页面可用并显示不保存提示。
  • 在 Chromium、Firefox 与 WebKit 的正常及降速 CPU 下,预设之间无首绘闪色。
  • 切换后滚动位置与锚点相差不超过一行。
  • 任何预设下 typography: system 都不触发字体请求;params.ui.fonts 覆盖预设字体。
  • Paper 与 Slate 下,theme_color 在两种明暗中都覆盖强调色。
  • 菜单可完全通过键盘、触屏与屏幕阅读器操作;axe 不报告新增违规。
  • 所有调色板在两种明暗下满足对比度表。
  • 预设不新增外部字体或脚本依赖;Giscus 等显式配置的服务单独说明。 --panicOnWarning 构建通过。

待决问题

  1. 第一阶段已选择 preset_menu: false,文档站开启。原问题:false(与 dark_mode 一样需显式开启)还是 true。
  2. 发布准备目标已确定为 1.2.0:醒目说明 Paper 成为默认,并提供 preset: slate 兼容设置;已随 1.2.0 正式发布。
  3. 第一阶段已选择 brand。原问题:字标字体角色命名:brand 还是 wordmark。
  4. 第一阶段之后,是否把仅用于展示标题的衬线作为 Paper 选项。
  5. 第二阶段图表(Mermaid、ECharts)是否采用预设颜色。

Ink 与 Terminal 后续清单

已实验实现:两套色板、现有字体角色、正文链接与选中信号、标题处理、局部几何、 Terminal 紧凑导航、Giscus 色板、打印与现有切换机制。不新增字体文件、动画或 运行时。真实输出与验证范围见实验记录。

晋升稳定预设前,仍需评审 Ink 长页红色强调密度与中文下划线;Terminal 编号标题、 等宽换行与密集参数表;Windows/Android 回退字体,以及人工屏幕阅读器朗读。 本次实验明确保留 Mermaid/ECharts 与 API 供应商组件仅随明暗变化;全局几何与 密度 token、预设图表色板需要另行决定。

决策记录

日期 变化
2026-10-04 创建草案:Paper/Slate 第一阶段范围、Ink/Terminal 研究规格、外观菜单选择与 token 架构
2026-10-05 第一阶段已在本地实现;默认值、brand 角色、图表仅随明暗的范围已接受;发布版本未定,本轮没有发布
2026-10-05 随后实现显式开启的 Ink/Terminal 实验;保留稳定菜单策略;视觉定稿仍未完成
2026-10-05 按 1.2.0 做发布准备;简洁的风格/明暗控件与当前状态图标取代早期色样方案;未创建标签或部署