ci: validate decision document metadata - #309

Open
seekskyworld wants to merge 1 commit into
openpi-dev:mainfrom
seekskyworld:feat/docs-contract-validator
Open

ci: validate decision document metadata#309
seekskyworld wants to merge 1 commit into
openpi-dev:mainfrom
seekskyworld:feat/docs-contract-validator

Conversation

@seekskyworld

Copy link
Copy Markdown

Problem

Issue #198 established repository knowledge and evidence governance, but the standard check had no static guard for required Decision metadata. Missing fields would only be noticed during review.

Value

The check makes governed Decision records fail visibly when required status, ownership, review, and relationship metadata is absent, without treating prose or Benchmark claims as automatically validated.

Approach

  • Add scripts/check-docs-contract.mjs with data-driven recursive Decision discovery.
  • Validate the required YAML frontmatter fields defined by Decision 0001.
  • Add check:docs-contract to the canonical check script.
  • Exclude category indexes and templates, which are not governed Decision records.

Validation

  • node scripts/check-docs-contract.mjs — passed (1 decision records).
  • git diff --check — passed.
  • npx --yes bun@1.3.14 run lint — passed.
  • npx --yes bun@1.3.14 run typecheck — passed.

Impact

  • User-visible behavior: None.
  • Model-visible context/tools: None.
  • Runtime/lifecycle: None.
  • Persisted config/data: None.
  • Compatibility/risk: CI/check-only change; it does not rewrite legacy documents or publish Benchmark evidence.

Related to #198

Signed-off-by: seekskyworld <djh1813553759@gmail.com>

@tt-a1itt-a1i left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review:Changes Requested

固定审查版本 bdcd6035ef346b9d090caa1a0d5946641df0bb24

问题 / 价值 / 方法

在标准 check 中加入 Decision 元数据检查,让缺少状态、owner、关联信息的记录尽早失败。一个小脚本接入现有检查链的方向合理,不需要新治理框架。

Standards / Spec

规范轴没有发现需要额外抽象的设计问题。功能轴有 2 项 P2:Windows 下漏扫全部 Decision;逐行正则没有按 YAML 值语义判断必填字段。均见行内复现。

验证

本轮重新运行 bun run check:失败在新脚本第 51 行的 Biome 格式;线上 Node 22/24 CI 也为失败。请随修复一并格式化,并补上述校验器的回归测试。

只读内存探针执行实际脚本文本、注入 Node 的 path.win32/path.posix 与模拟文件系统:Windows 无 frontmatter 文档竟输出 docs contract (0 decision records) 且成功退出;POSIX 下 owner 为 ""null、仅注释均成功退出;合法 related-issues YAML block list 被误报缺失。这是受控复现,不声称在原生 Windows 上运行过。

此前同一 exact head 的 lint/typecheck 通过;完整测试 Node 1065 通过、1 跳过,Vitest 30 通过。既有测试不覆盖上述新脚本缺口,全量绿色不能代替该功能验证。本轮未改代码、未合并。

const files = markdownFiles(root);
const decisions = files.filter(
(file) =>
file.includes(`${join("docs", "decisions")}${"/"}`) &&

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️[P2] 不要混合平台路径分隔符,否则 Windows 会漏扫所有记录

Windows 上 join("docs", "decisions") 返回反斜杠路径,这里又拼接 /,最终查找的是 docs\\decisions/;实际文件路径是 ...\\docs\\decisions\\0001-....md,不会匹配。使用实际脚本配合 path.win32 的只读探针,即使 Decision 完全没有 frontmatter,也成功输出 docs contract (0 decision records)。下一行 split("/") 同样是 POSIX 假设。

请从明确的 decisions 目录枚举,或统一使用原生路径组件和 basename;补一个 Windows 路径下必须发现记录并拒绝缺失元数据的测试,不能把零记录扫描当成验证成功。

return new Map(
match[1]
.split("\n")
.map((line) => line.match(/^([\w-]+):\s*(.*)$/))

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️[P2] 按 YAML 值判断元数据,不要只判断原始行非空

当前 Map 保存的是未经解析的文本,所以 owner: ""owner: nullowner: # no owner 都被第 51 行当成有值;反过来,合法的 related-issues:\n - "#198" 因首行值为空而被判缺失。对实际脚本的内存 fixture 复现了这四种情况。这会让必填信息遗漏漏过 gate,同时拒绝正常 YAML 写法。

请使用可靠的 YAML 解析并校验所需字段的非空值/允许类型,或者明确规定并严格校验受限格式;加上空字符串、null、注释和列表回归测试。保留当前小检查器即可,不必扩为通用文档框架。

@tt-a1i

Copy link
Copy Markdown
Collaborator

Code Review Summary

Changes Requested:2 项 P2。完整 review,固定版本 bdcd6035

  • Windows 分隔符混用导致漏扫所有 Decision,并错误成功退出。
  • 原始行解析误接受空字符串/null/注释,误拒绝合法 YAML 列表。

实际脚本文本的受控内存探针已复现;本轮 check 仍在新增脚本格式处失败,Node 22/24 CI 为红。建议修两个小边界、补回归并格式化,不增加框架。未改代码、未合并。

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@seekskyworld@tt-a1i
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

ci: validate decision document metadata - #309

Open
seekskyworld wants to merge 1 commit into
openpi-dev:mainfrom
seekskyworld:feat/docs-contract-validator
Open

ci: validate decision document metadata#309
seekskyworld wants to merge 1 commit into
openpi-dev:mainfrom
seekskyworld:feat/docs-contract-validator

Conversation

@seekskyworld

Copy link
Copy Markdown

Problem

Issue #198 established repository knowledge and evidence governance, but the standard check had no static guard for required Decision metadata. Missing fields would only be noticed during review.

Value

The check makes governed Decision records fail visibly when required status, ownership, review, and relationship metadata is absent, without treating prose or Benchmark claims as automatically validated.

Approach

  • Add scripts/check-docs-contract.mjs with data-driven recursive Decision discovery.
  • Validate the required YAML frontmatter fields defined by Decision 0001.
  • Add check:docs-contract to the canonical check script.
  • Exclude category indexes and templates, which are not governed Decision records.

Validation

  • node scripts/check-docs-contract.mjs — passed (1 decision records).
  • git diff --check — passed.
  • npx --yes bun@1.3.14 run lint — passed.
  • npx --yes bun@1.3.14 run typecheck — passed.

Impact

  • User-visible behavior: None.
  • Model-visible context/tools: None.
  • Runtime/lifecycle: None.
  • Persisted config/data: None.
  • Compatibility/risk: CI/check-only change; it does not rewrite legacy documents or publish Benchmark evidence.

Related to #198

Signed-off-by: seekskyworld <djh1813553759@gmail.com>

@tt-a1itt-a1i left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review:Changes Requested

固定审查版本 bdcd6035ef346b9d090caa1a0d5946641df0bb24

问题 / 价值 / 方法

在标准 check 中加入 Decision 元数据检查,让缺少状态、owner、关联信息的记录尽早失败。一个小脚本接入现有检查链的方向合理,不需要新治理框架。

Standards / Spec

规范轴没有发现需要额外抽象的设计问题。功能轴有 2 项 P2:Windows 下漏扫全部 Decision;逐行正则没有按 YAML 值语义判断必填字段。均见行内复现。

验证

本轮重新运行 bun run check:失败在新脚本第 51 行的 Biome 格式;线上 Node 22/24 CI 也为失败。请随修复一并格式化,并补上述校验器的回归测试。

只读内存探针执行实际脚本文本、注入 Node 的 path.win32/path.posix 与模拟文件系统:Windows 无 frontmatter 文档竟输出 docs contract (0 decision records) 且成功退出;POSIX 下 owner 为 ""null、仅注释均成功退出;合法 related-issues YAML block list 被误报缺失。这是受控复现,不声称在原生 Windows 上运行过。

此前同一 exact head 的 lint/typecheck 通过;完整测试 Node 1065 通过、1 跳过,Vitest 30 通过。既有测试不覆盖上述新脚本缺口,全量绿色不能代替该功能验证。本轮未改代码、未合并。

const files = markdownFiles(root);
const decisions = files.filter(
(file) =>
file.includes(`${join("docs", "decisions")}${"/"}`) &&

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️[P2] 不要混合平台路径分隔符,否则 Windows 会漏扫所有记录

Windows 上 join("docs", "decisions") 返回反斜杠路径,这里又拼接 /,最终查找的是 docs\\decisions/;实际文件路径是 ...\\docs\\decisions\\0001-....md,不会匹配。使用实际脚本配合 path.win32 的只读探针,即使 Decision 完全没有 frontmatter,也成功输出 docs contract (0 decision records)。下一行 split("/") 同样是 POSIX 假设。

请从明确的 decisions 目录枚举,或统一使用原生路径组件和 basename;补一个 Windows 路径下必须发现记录并拒绝缺失元数据的测试,不能把零记录扫描当成验证成功。

return new Map(
match[1]
.split("\n")
.map((line) => line.match(/^([\w-]+):\s*(.*)$/))

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️[P2] 按 YAML 值判断元数据,不要只判断原始行非空

当前 Map 保存的是未经解析的文本,所以 owner: ""owner: nullowner: # no owner 都被第 51 行当成有值;反过来,合法的 related-issues:\n - "#198" 因首行值为空而被判缺失。对实际脚本的内存 fixture 复现了这四种情况。这会让必填信息遗漏漏过 gate,同时拒绝正常 YAML 写法。

请使用可靠的 YAML 解析并校验所需字段的非空值/允许类型,或者明确规定并严格校验受限格式;加上空字符串、null、注释和列表回归测试。保留当前小检查器即可,不必扩为通用文档框架。

@tt-a1i

Copy link
Copy Markdown
Collaborator

Code Review Summary

Changes Requested:2 项 P2。完整 review,固定版本 bdcd6035

  • Windows 分隔符混用导致漏扫所有 Decision,并错误成功退出。
  • 原始行解析误接受空字符串/null/注释,误拒绝合法 YAML 列表。

实际脚本文本的受控内存探针已复现;本轮 check 仍在新增脚本格式处失败,Node 22/24 CI 为红。建议修两个小边界、补回归并格式化,不增加框架。未改代码、未合并。

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@seekskyworld@tt-a1i
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

ci: validate decision document metadata - #309

Open
seekskyworld wants to merge 1 commit into
openpi-dev:mainfrom
seekskyworld:feat/docs-contract-validator
Open

ci: validate decision document metadata#309
seekskyworld wants to merge 1 commit into
openpi-dev:mainfrom
seekskyworld:feat/docs-contract-validator

Conversation

@seekskyworld

Copy link
Copy Markdown

Problem

Issue #198 established repository knowledge and evidence governance, but the standard check had no static guard for required Decision metadata. Missing fields would only be noticed during review.

Value

The check makes governed Decision records fail visibly when required status, ownership, review, and relationship metadata is absent, without treating prose or Benchmark claims as automatically validated.

Approach

  • Add scripts/check-docs-contract.mjs with data-driven recursive Decision discovery.
  • Validate the required YAML frontmatter fields defined by Decision 0001.
  • Add check:docs-contract to the canonical check script.
  • Exclude category indexes and templates, which are not governed Decision records.

Validation

  • node scripts/check-docs-contract.mjs — passed (1 decision records).
  • git diff --check — passed.
  • npx --yes bun@1.3.14 run lint — passed.
  • npx --yes bun@1.3.14 run typecheck — passed.

Impact

  • User-visible behavior: None.
  • Model-visible context/tools: None.
  • Runtime/lifecycle: None.
  • Persisted config/data: None.
  • Compatibility/risk: CI/check-only change; it does not rewrite legacy documents or publish Benchmark evidence.

Related to #198

Signed-off-by: seekskyworld <djh1813553759@gmail.com>

@tt-a1itt-a1i left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review:Changes Requested

固定审查版本 bdcd6035ef346b9d090caa1a0d5946641df0bb24

问题 / 价值 / 方法

在标准 check 中加入 Decision 元数据检查,让缺少状态、owner、关联信息的记录尽早失败。一个小脚本接入现有检查链的方向合理,不需要新治理框架。

Standards / Spec

规范轴没有发现需要额外抽象的设计问题。功能轴有 2 项 P2:Windows 下漏扫全部 Decision;逐行正则没有按 YAML 值语义判断必填字段。均见行内复现。

验证

本轮重新运行 bun run check:失败在新脚本第 51 行的 Biome 格式;线上 Node 22/24 CI 也为失败。请随修复一并格式化,并补上述校验器的回归测试。

只读内存探针执行实际脚本文本、注入 Node 的 path.win32/path.posix 与模拟文件系统:Windows 无 frontmatter 文档竟输出 docs contract (0 decision records) 且成功退出;POSIX 下 owner 为 ""null、仅注释均成功退出;合法 related-issues YAML block list 被误报缺失。这是受控复现,不声称在原生 Windows 上运行过。

此前同一 exact head 的 lint/typecheck 通过;完整测试 Node 1065 通过、1 跳过,Vitest 30 通过。既有测试不覆盖上述新脚本缺口,全量绿色不能代替该功能验证。本轮未改代码、未合并。

const files = markdownFiles(root);
const decisions = files.filter(
(file) =>
file.includes(`${join("docs", "decisions")}${"/"}`) &&

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️[P2] 不要混合平台路径分隔符,否则 Windows 会漏扫所有记录

Windows 上 join("docs", "decisions") 返回反斜杠路径,这里又拼接 /,最终查找的是 docs\\decisions/;实际文件路径是 ...\\docs\\decisions\\0001-....md,不会匹配。使用实际脚本配合 path.win32 的只读探针,即使 Decision 完全没有 frontmatter,也成功输出 docs contract (0 decision records)。下一行 split("/") 同样是 POSIX 假设。

请从明确的 decisions 目录枚举,或统一使用原生路径组件和 basename;补一个 Windows 路径下必须发现记录并拒绝缺失元数据的测试,不能把零记录扫描当成验证成功。

return new Map(
match[1]
.split("\n")
.map((line) => line.match(/^([\w-]+):\s*(.*)$/))

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️[P2] 按 YAML 值判断元数据,不要只判断原始行非空

当前 Map 保存的是未经解析的文本,所以 owner: ""owner: nullowner: # no owner 都被第 51 行当成有值;反过来,合法的 related-issues:\n - "#198" 因首行值为空而被判缺失。对实际脚本的内存 fixture 复现了这四种情况。这会让必填信息遗漏漏过 gate,同时拒绝正常 YAML 写法。

请使用可靠的 YAML 解析并校验所需字段的非空值/允许类型,或者明确规定并严格校验受限格式;加上空字符串、null、注释和列表回归测试。保留当前小检查器即可,不必扩为通用文档框架。

@tt-a1i

Copy link
Copy Markdown
Collaborator

Code Review Summary

Changes Requested:2 项 P2。完整 review,固定版本 bdcd6035

  • Windows 分隔符混用导致漏扫所有 Decision,并错误成功退出。
  • 原始行解析误接受空字符串/null/注释,误拒绝合法 YAML 列表。

实际脚本文本的受控内存探针已复现;本轮 check 仍在新增脚本格式处失败,Node 22/24 CI 为红。建议修两个小边界、补回归并格式化,不增加框架。未改代码、未合并。

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@seekskyworld@tt-a1i
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

ci: validate decision document metadata - #309

Open
seekskyworld wants to merge 1 commit into
openpi-dev:mainfrom
seekskyworld:feat/docs-contract-validator
Open

ci: validate decision document metadata#309
seekskyworld wants to merge 1 commit into
openpi-dev:mainfrom
seekskyworld:feat/docs-contract-validator

Conversation

@seekskyworld

Copy link
Copy Markdown

Problem

Issue #198 established repository knowledge and evidence governance, but the standard check had no static guard for required Decision metadata. Missing fields would only be noticed during review.

Value

The check makes governed Decision records fail visibly when required status, ownership, review, and relationship metadata is absent, without treating prose or Benchmark claims as automatically validated.

Approach

  • Add scripts/check-docs-contract.mjs with data-driven recursive Decision discovery.
  • Validate the required YAML frontmatter fields defined by Decision 0001.
  • Add check:docs-contract to the canonical check script.
  • Exclude category indexes and templates, which are not governed Decision records.

Validation

  • node scripts/check-docs-contract.mjs — passed (1 decision records).
  • git diff --check — passed.
  • npx --yes bun@1.3.14 run lint — passed.
  • npx --yes bun@1.3.14 run typecheck — passed.

Impact

  • User-visible behavior: None.
  • Model-visible context/tools: None.
  • Runtime/lifecycle: None.
  • Persisted config/data: None.
  • Compatibility/risk: CI/check-only change; it does not rewrite legacy documents or publish Benchmark evidence.

Related to #198

Signed-off-by: seekskyworld <djh1813553759@gmail.com>

@tt-a1itt-a1i left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review:Changes Requested

固定审查版本 bdcd6035ef346b9d090caa1a0d5946641df0bb24

问题 / 价值 / 方法

在标准 check 中加入 Decision 元数据检查,让缺少状态、owner、关联信息的记录尽早失败。一个小脚本接入现有检查链的方向合理,不需要新治理框架。

Standards / Spec

规范轴没有发现需要额外抽象的设计问题。功能轴有 2 项 P2:Windows 下漏扫全部 Decision;逐行正则没有按 YAML 值语义判断必填字段。均见行内复现。

验证

本轮重新运行 bun run check:失败在新脚本第 51 行的 Biome 格式;线上 Node 22/24 CI 也为失败。请随修复一并格式化,并补上述校验器的回归测试。

只读内存探针执行实际脚本文本、注入 Node 的 path.win32/path.posix 与模拟文件系统:Windows 无 frontmatter 文档竟输出 docs contract (0 decision records) 且成功退出;POSIX 下 owner 为 ""null、仅注释均成功退出;合法 related-issues YAML block list 被误报缺失。这是受控复现,不声称在原生 Windows 上运行过。

此前同一 exact head 的 lint/typecheck 通过;完整测试 Node 1065 通过、1 跳过,Vitest 30 通过。既有测试不覆盖上述新脚本缺口,全量绿色不能代替该功能验证。本轮未改代码、未合并。

const files = markdownFiles(root);
const decisions = files.filter(
(file) =>
file.includes(`${join("docs", "decisions")}${"/"}`) &&

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️[P2] 不要混合平台路径分隔符,否则 Windows 会漏扫所有记录

Windows 上 join("docs", "decisions") 返回反斜杠路径,这里又拼接 /,最终查找的是 docs\\decisions/;实际文件路径是 ...\\docs\\decisions\\0001-....md,不会匹配。使用实际脚本配合 path.win32 的只读探针,即使 Decision 完全没有 frontmatter,也成功输出 docs contract (0 decision records)。下一行 split("/") 同样是 POSIX 假设。

请从明确的 decisions 目录枚举,或统一使用原生路径组件和 basename;补一个 Windows 路径下必须发现记录并拒绝缺失元数据的测试,不能把零记录扫描当成验证成功。

return new Map(
match[1]
.split("\n")
.map((line) => line.match(/^([\w-]+):\s*(.*)$/))

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️[P2] 按 YAML 值判断元数据,不要只判断原始行非空

当前 Map 保存的是未经解析的文本,所以 owner: ""owner: nullowner: # no owner 都被第 51 行当成有值;反过来,合法的 related-issues:\n - "#198" 因首行值为空而被判缺失。对实际脚本的内存 fixture 复现了这四种情况。这会让必填信息遗漏漏过 gate,同时拒绝正常 YAML 写法。

请使用可靠的 YAML 解析并校验所需字段的非空值/允许类型,或者明确规定并严格校验受限格式;加上空字符串、null、注释和列表回归测试。保留当前小检查器即可,不必扩为通用文档框架。

@tt-a1i

Copy link
Copy Markdown
Collaborator

Code Review Summary

Changes Requested:2 项 P2。完整 review,固定版本 bdcd6035

  • Windows 分隔符混用导致漏扫所有 Decision,并错误成功退出。
  • 原始行解析误接受空字符串/null/注释,误拒绝合法 YAML 列表。

实际脚本文本的受控内存探针已复现;本轮 check 仍在新增脚本格式处失败,Node 22/24 CI 为红。建议修两个小边界、补回归并格式化,不增加框架。未改代码、未合并。

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@seekskyworld@tt-a1i
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

ci: validate decision document metadata - #309

Open
seekskyworld wants to merge 1 commit into
openpi-dev:mainfrom
seekskyworld:feat/docs-contract-validator
Open

ci: validate decision document metadata#309
seekskyworld wants to merge 1 commit into
openpi-dev:mainfrom
seekskyworld:feat/docs-contract-validator

Conversation

@seekskyworld

Copy link
Copy Markdown

Problem

Issue #198 established repository knowledge and evidence governance, but the standard check had no static guard for required Decision metadata. Missing fields would only be noticed during review.

Value

The check makes governed Decision records fail visibly when required status, ownership, review, and relationship metadata is absent, without treating prose or Benchmark claims as automatically validated.

Approach

  • Add scripts/check-docs-contract.mjs with data-driven recursive Decision discovery.
  • Validate the required YAML frontmatter fields defined by Decision 0001.
  • Add check:docs-contract to the canonical check script.
  • Exclude category indexes and templates, which are not governed Decision records.

Validation

  • node scripts/check-docs-contract.mjs — passed (1 decision records).
  • git diff --check — passed.
  • npx --yes bun@1.3.14 run lint — passed.
  • npx --yes bun@1.3.14 run typecheck — passed.

Impact

  • User-visible behavior: None.
  • Model-visible context/tools: None.
  • Runtime/lifecycle: None.
  • Persisted config/data: None.
  • Compatibility/risk: CI/check-only change; it does not rewrite legacy documents or publish Benchmark evidence.

Related to #198

Signed-off-by: seekskyworld <djh1813553759@gmail.com>

@tt-a1itt-a1i left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review:Changes Requested

固定审查版本 bdcd6035ef346b9d090caa1a0d5946641df0bb24

问题 / 价值 / 方法

在标准 check 中加入 Decision 元数据检查,让缺少状态、owner、关联信息的记录尽早失败。一个小脚本接入现有检查链的方向合理,不需要新治理框架。

Standards / Spec

规范轴没有发现需要额外抽象的设计问题。功能轴有 2 项 P2:Windows 下漏扫全部 Decision;逐行正则没有按 YAML 值语义判断必填字段。均见行内复现。

验证

本轮重新运行 bun run check:失败在新脚本第 51 行的 Biome 格式;线上 Node 22/24 CI 也为失败。请随修复一并格式化,并补上述校验器的回归测试。

只读内存探针执行实际脚本文本、注入 Node 的 path.win32/path.posix 与模拟文件系统:Windows 无 frontmatter 文档竟输出 docs contract (0 decision records) 且成功退出;POSIX 下 owner 为 ""null、仅注释均成功退出;合法 related-issues YAML block list 被误报缺失。这是受控复现,不声称在原生 Windows 上运行过。

此前同一 exact head 的 lint/typecheck 通过;完整测试 Node 1065 通过、1 跳过,Vitest 30 通过。既有测试不覆盖上述新脚本缺口,全量绿色不能代替该功能验证。本轮未改代码、未合并。

const files = markdownFiles(root);
const decisions = files.filter(
(file) =>
file.includes(`${join("docs", "decisions")}${"/"}`) &&

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️[P2] 不要混合平台路径分隔符,否则 Windows 会漏扫所有记录

Windows 上 join("docs", "decisions") 返回反斜杠路径,这里又拼接 /,最终查找的是 docs\\decisions/;实际文件路径是 ...\\docs\\decisions\\0001-....md,不会匹配。使用实际脚本配合 path.win32 的只读探针,即使 Decision 完全没有 frontmatter,也成功输出 docs contract (0 decision records)。下一行 split("/") 同样是 POSIX 假设。

请从明确的 decisions 目录枚举,或统一使用原生路径组件和 basename;补一个 Windows 路径下必须发现记录并拒绝缺失元数据的测试,不能把零记录扫描当成验证成功。

return new Map(
match[1]
.split("\n")
.map((line) => line.match(/^([\w-]+):\s*(.*)$/))

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️[P2] 按 YAML 值判断元数据,不要只判断原始行非空

当前 Map 保存的是未经解析的文本,所以 owner: ""owner: nullowner: # no owner 都被第 51 行当成有值;反过来,合法的 related-issues:\n - "#198" 因首行值为空而被判缺失。对实际脚本的内存 fixture 复现了这四种情况。这会让必填信息遗漏漏过 gate,同时拒绝正常 YAML 写法。

请使用可靠的 YAML 解析并校验所需字段的非空值/允许类型,或者明确规定并严格校验受限格式;加上空字符串、null、注释和列表回归测试。保留当前小检查器即可,不必扩为通用文档框架。

@tt-a1i

Copy link
Copy Markdown
Collaborator

Code Review Summary

Changes Requested:2 项 P2。完整 review,固定版本 bdcd6035

  • Windows 分隔符混用导致漏扫所有 Decision,并错误成功退出。
  • 原始行解析误接受空字符串/null/注释,误拒绝合法 YAML 列表。

实际脚本文本的受控内存探针已复现;本轮 check 仍在新增脚本格式处失败,Node 22/24 CI 为红。建议修两个小边界、补回归并格式化,不增加框架。未改代码、未合并。

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@seekskyworld@tt-a1i
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

ci: validate decision document metadata - #309

Open
seekskyworld wants to merge 1 commit into
openpi-dev:mainfrom
seekskyworld:feat/docs-contract-validator
Open

ci: validate decision document metadata#309
seekskyworld wants to merge 1 commit into
openpi-dev:mainfrom
seekskyworld:feat/docs-contract-validator

Conversation

@seekskyworld

Copy link
Copy Markdown

Problem

Issue #198 established repository knowledge and evidence governance, but the standard check had no static guard for required Decision metadata. Missing fields would only be noticed during review.

Value

The check makes governed Decision records fail visibly when required status, ownership, review, and relationship metadata is absent, without treating prose or Benchmark claims as automatically validated.

Approach

  • Add scripts/check-docs-contract.mjs with data-driven recursive Decision discovery.
  • Validate the required YAML frontmatter fields defined by Decision 0001.
  • Add check:docs-contract to the canonical check script.
  • Exclude category indexes and templates, which are not governed Decision records.

Validation

  • node scripts/check-docs-contract.mjs — passed (1 decision records).
  • git diff --check — passed.
  • npx --yes bun@1.3.14 run lint — passed.
  • npx --yes bun@1.3.14 run typecheck — passed.

Impact

  • User-visible behavior: None.
  • Model-visible context/tools: None.
  • Runtime/lifecycle: None.
  • Persisted config/data: None.
  • Compatibility/risk: CI/check-only change; it does not rewrite legacy documents or publish Benchmark evidence.

Related to #198

Signed-off-by: seekskyworld <djh1813553759@gmail.com>

@tt-a1itt-a1i left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review:Changes Requested

固定审查版本 bdcd6035ef346b9d090caa1a0d5946641df0bb24

问题 / 价值 / 方法

在标准 check 中加入 Decision 元数据检查,让缺少状态、owner、关联信息的记录尽早失败。一个小脚本接入现有检查链的方向合理,不需要新治理框架。

Standards / Spec

规范轴没有发现需要额外抽象的设计问题。功能轴有 2 项 P2:Windows 下漏扫全部 Decision;逐行正则没有按 YAML 值语义判断必填字段。均见行内复现。

验证

本轮重新运行 bun run check:失败在新脚本第 51 行的 Biome 格式;线上 Node 22/24 CI 也为失败。请随修复一并格式化,并补上述校验器的回归测试。

只读内存探针执行实际脚本文本、注入 Node 的 path.win32/path.posix 与模拟文件系统:Windows 无 frontmatter 文档竟输出 docs contract (0 decision records) 且成功退出;POSIX 下 owner 为 ""null、仅注释均成功退出;合法 related-issues YAML block list 被误报缺失。这是受控复现,不声称在原生 Windows 上运行过。

此前同一 exact head 的 lint/typecheck 通过;完整测试 Node 1065 通过、1 跳过,Vitest 30 通过。既有测试不覆盖上述新脚本缺口,全量绿色不能代替该功能验证。本轮未改代码、未合并。

const files = markdownFiles(root);
const decisions = files.filter(
(file) =>
file.includes(`${join("docs", "decisions")}${"/"}`) &&

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️[P2] 不要混合平台路径分隔符,否则 Windows 会漏扫所有记录

Windows 上 join("docs", "decisions") 返回反斜杠路径,这里又拼接 /,最终查找的是 docs\\decisions/;实际文件路径是 ...\\docs\\decisions\\0001-....md,不会匹配。使用实际脚本配合 path.win32 的只读探针,即使 Decision 完全没有 frontmatter,也成功输出 docs contract (0 decision records)。下一行 split("/") 同样是 POSIX 假设。

请从明确的 decisions 目录枚举,或统一使用原生路径组件和 basename;补一个 Windows 路径下必须发现记录并拒绝缺失元数据的测试,不能把零记录扫描当成验证成功。

return new Map(
match[1]
.split("\n")
.map((line) => line.match(/^([\w-]+):\s*(.*)$/))

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️[P2] 按 YAML 值判断元数据,不要只判断原始行非空

当前 Map 保存的是未经解析的文本,所以 owner: ""owner: nullowner: # no owner 都被第 51 行当成有值;反过来,合法的 related-issues:\n - "#198" 因首行值为空而被判缺失。对实际脚本的内存 fixture 复现了这四种情况。这会让必填信息遗漏漏过 gate,同时拒绝正常 YAML 写法。

请使用可靠的 YAML 解析并校验所需字段的非空值/允许类型,或者明确规定并严格校验受限格式;加上空字符串、null、注释和列表回归测试。保留当前小检查器即可,不必扩为通用文档框架。

@tt-a1i

Copy link
Copy Markdown
Collaborator

Code Review Summary

Changes Requested:2 项 P2。完整 review,固定版本 bdcd6035

  • Windows 分隔符混用导致漏扫所有 Decision,并错误成功退出。
  • 原始行解析误接受空字符串/null/注释,误拒绝合法 YAML 列表。

实际脚本文本的受控内存探针已复现;本轮 check 仍在新增脚本格式处失败,Node 22/24 CI 为红。建议修两个小边界、补回归并格式化,不增加框架。未改代码、未合并。

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@seekskyworld@tt-a1i
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

ci: validate decision document metadata - #309

Open
seekskyworld wants to merge 1 commit into
openpi-dev:mainfrom
seekskyworld:feat/docs-contract-validator
Open

ci: validate decision document metadata#309
seekskyworld wants to merge 1 commit into
openpi-dev:mainfrom
seekskyworld:feat/docs-contract-validator

Conversation

@seekskyworld

Copy link
Copy Markdown

Problem

Issue #198 established repository knowledge and evidence governance, but the standard check had no static guard for required Decision metadata. Missing fields would only be noticed during review.

Value

The check makes governed Decision records fail visibly when required status, ownership, review, and relationship metadata is absent, without treating prose or Benchmark claims as automatically validated.

Approach

  • Add scripts/check-docs-contract.mjs with data-driven recursive Decision discovery.
  • Validate the required YAML frontmatter fields defined by Decision 0001.
  • Add check:docs-contract to the canonical check script.
  • Exclude category indexes and templates, which are not governed Decision records.

Validation

  • node scripts/check-docs-contract.mjs — passed (1 decision records).
  • git diff --check — passed.
  • npx --yes bun@1.3.14 run lint — passed.
  • npx --yes bun@1.3.14 run typecheck — passed.

Impact

  • User-visible behavior: None.
  • Model-visible context/tools: None.
  • Runtime/lifecycle: None.
  • Persisted config/data: None.
  • Compatibility/risk: CI/check-only change; it does not rewrite legacy documents or publish Benchmark evidence.

Related to #198

Signed-off-by: seekskyworld <djh1813553759@gmail.com>

@tt-a1itt-a1i left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review:Changes Requested

固定审查版本 bdcd6035ef346b9d090caa1a0d5946641df0bb24

问题 / 价值 / 方法

在标准 check 中加入 Decision 元数据检查,让缺少状态、owner、关联信息的记录尽早失败。一个小脚本接入现有检查链的方向合理,不需要新治理框架。

Standards / Spec

规范轴没有发现需要额外抽象的设计问题。功能轴有 2 项 P2:Windows 下漏扫全部 Decision;逐行正则没有按 YAML 值语义判断必填字段。均见行内复现。

验证

本轮重新运行 bun run check:失败在新脚本第 51 行的 Biome 格式;线上 Node 22/24 CI 也为失败。请随修复一并格式化,并补上述校验器的回归测试。

只读内存探针执行实际脚本文本、注入 Node 的 path.win32/path.posix 与模拟文件系统:Windows 无 frontmatter 文档竟输出 docs contract (0 decision records) 且成功退出;POSIX 下 owner 为 ""null、仅注释均成功退出;合法 related-issues YAML block list 被误报缺失。这是受控复现,不声称在原生 Windows 上运行过。

此前同一 exact head 的 lint/typecheck 通过;完整测试 Node 1065 通过、1 跳过,Vitest 30 通过。既有测试不覆盖上述新脚本缺口,全量绿色不能代替该功能验证。本轮未改代码、未合并。

const files = markdownFiles(root);
const decisions = files.filter(
(file) =>
file.includes(`${join("docs", "decisions")}${"/"}`) &&

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️[P2] 不要混合平台路径分隔符,否则 Windows 会漏扫所有记录

Windows 上 join("docs", "decisions") 返回反斜杠路径,这里又拼接 /,最终查找的是 docs\\decisions/;实际文件路径是 ...\\docs\\decisions\\0001-....md,不会匹配。使用实际脚本配合 path.win32 的只读探针,即使 Decision 完全没有 frontmatter,也成功输出 docs contract (0 decision records)。下一行 split("/") 同样是 POSIX 假设。

请从明确的 decisions 目录枚举,或统一使用原生路径组件和 basename;补一个 Windows 路径下必须发现记录并拒绝缺失元数据的测试,不能把零记录扫描当成验证成功。

return new Map(
match[1]
.split("\n")
.map((line) => line.match(/^([\w-]+):\s*(.*)$/))

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️[P2] 按 YAML 值判断元数据,不要只判断原始行非空

当前 Map 保存的是未经解析的文本,所以 owner: ""owner: nullowner: # no owner 都被第 51 行当成有值;反过来,合法的 related-issues:\n - "#198" 因首行值为空而被判缺失。对实际脚本的内存 fixture 复现了这四种情况。这会让必填信息遗漏漏过 gate,同时拒绝正常 YAML 写法。

请使用可靠的 YAML 解析并校验所需字段的非空值/允许类型,或者明确规定并严格校验受限格式;加上空字符串、null、注释和列表回归测试。保留当前小检查器即可,不必扩为通用文档框架。

@tt-a1i

Copy link
Copy Markdown
Collaborator

Code Review Summary

Changes Requested:2 项 P2。完整 review,固定版本 bdcd6035

  • Windows 分隔符混用导致漏扫所有 Decision,并错误成功退出。
  • 原始行解析误接受空字符串/null/注释,误拒绝合法 YAML 列表。

实际脚本文本的受控内存探针已复现;本轮 check 仍在新增脚本格式处失败,Node 22/24 CI 为红。建议修两个小边界、补回归并格式化,不增加框架。未改代码、未合并。

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@seekskyworld@tt-a1i
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

ci: validate decision document metadata - #309

Open
seekskyworld wants to merge 1 commit into
openpi-dev:mainfrom
seekskyworld:feat/docs-contract-validator
Open

ci: validate decision document metadata#309
seekskyworld wants to merge 1 commit into
openpi-dev:mainfrom
seekskyworld:feat/docs-contract-validator

Conversation

@seekskyworld

Copy link
Copy Markdown

Problem

Issue #198 established repository knowledge and evidence governance, but the standard check had no static guard for required Decision metadata. Missing fields would only be noticed during review.

Value

The check makes governed Decision records fail visibly when required status, ownership, review, and relationship metadata is absent, without treating prose or Benchmark claims as automatically validated.

Approach

  • Add scripts/check-docs-contract.mjs with data-driven recursive Decision discovery.
  • Validate the required YAML frontmatter fields defined by Decision 0001.
  • Add check:docs-contract to the canonical check script.
  • Exclude category indexes and templates, which are not governed Decision records.

Validation

  • node scripts/check-docs-contract.mjs — passed (1 decision records).
  • git diff --check — passed.
  • npx --yes bun@1.3.14 run lint — passed.
  • npx --yes bun@1.3.14 run typecheck — passed.

Impact

  • User-visible behavior: None.
  • Model-visible context/tools: None.
  • Runtime/lifecycle: None.
  • Persisted config/data: None.
  • Compatibility/risk: CI/check-only change; it does not rewrite legacy documents or publish Benchmark evidence.

Related to #198

Signed-off-by: seekskyworld <djh1813553759@gmail.com>

@tt-a1itt-a1i left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review:Changes Requested

固定审查版本 bdcd6035ef346b9d090caa1a0d5946641df0bb24

问题 / 价值 / 方法

在标准 check 中加入 Decision 元数据检查,让缺少状态、owner、关联信息的记录尽早失败。一个小脚本接入现有检查链的方向合理,不需要新治理框架。

Standards / Spec

规范轴没有发现需要额外抽象的设计问题。功能轴有 2 项 P2:Windows 下漏扫全部 Decision;逐行正则没有按 YAML 值语义判断必填字段。均见行内复现。

验证

本轮重新运行 bun run check:失败在新脚本第 51 行的 Biome 格式;线上 Node 22/24 CI 也为失败。请随修复一并格式化,并补上述校验器的回归测试。

只读内存探针执行实际脚本文本、注入 Node 的 path.win32/path.posix 与模拟文件系统:Windows 无 frontmatter 文档竟输出 docs contract (0 decision records) 且成功退出;POSIX 下 owner 为 ""null、仅注释均成功退出;合法 related-issues YAML block list 被误报缺失。这是受控复现,不声称在原生 Windows 上运行过。

此前同一 exact head 的 lint/typecheck 通过;完整测试 Node 1065 通过、1 跳过,Vitest 30 通过。既有测试不覆盖上述新脚本缺口,全量绿色不能代替该功能验证。本轮未改代码、未合并。

const files = markdownFiles(root);
const decisions = files.filter(
(file) =>
file.includes(`${join("docs", "decisions")}${"/"}`) &&

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️[P2] 不要混合平台路径分隔符,否则 Windows 会漏扫所有记录

Windows 上 join("docs", "decisions") 返回反斜杠路径,这里又拼接 /,最终查找的是 docs\\decisions/;实际文件路径是 ...\\docs\\decisions\\0001-....md,不会匹配。使用实际脚本配合 path.win32 的只读探针,即使 Decision 完全没有 frontmatter,也成功输出 docs contract (0 decision records)。下一行 split("/") 同样是 POSIX 假设。

请从明确的 decisions 目录枚举,或统一使用原生路径组件和 basename;补一个 Windows 路径下必须发现记录并拒绝缺失元数据的测试,不能把零记录扫描当成验证成功。

return new Map(
match[1]
.split("\n")
.map((line) => line.match(/^([\w-]+):\s*(.*)$/))

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️[P2] 按 YAML 值判断元数据,不要只判断原始行非空

当前 Map 保存的是未经解析的文本,所以 owner: ""owner: nullowner: # no owner 都被第 51 行当成有值;反过来,合法的 related-issues:\n - "#198" 因首行值为空而被判缺失。对实际脚本的内存 fixture 复现了这四种情况。这会让必填信息遗漏漏过 gate,同时拒绝正常 YAML 写法。

请使用可靠的 YAML 解析并校验所需字段的非空值/允许类型,或者明确规定并严格校验受限格式;加上空字符串、null、注释和列表回归测试。保留当前小检查器即可,不必扩为通用文档框架。

@tt-a1i

Copy link
Copy Markdown
Collaborator

Code Review Summary

Changes Requested:2 项 P2。完整 review,固定版本 bdcd6035

  • Windows 分隔符混用导致漏扫所有 Decision,并错误成功退出。
  • 原始行解析误接受空字符串/null/注释,误拒绝合法 YAML 列表。

实际脚本文本的受控内存探针已复现;本轮 check 仍在新增脚本格式处失败,Node 22/24 CI 为红。建议修两个小边界、补回归并格式化,不增加框架。未改代码、未合并。

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@seekskyworld@tt-a1i