{
  "schemaVersion": 1,
  "id": "duck-boo-bee-public-engineering-rules",
  "title": "duck-boo-bee 多 AI 协作工程规则",
  "lastUpdated": "2026-09-16",
  "scope": "duck-boo-bee.neocities.org 的检查、构建、部署、验证与交接",
  "publicSafety": {
    "credentialsExcluded": true,
    "note": "本文件只提供公开工程规则，不包含 API Key、令牌或其他凭据。"
  },
  "authorityOrder": [
    "用户本轮明确指令",
    "线上最新发布状态与当前权威源码的核对结果",
    "本工程规则",
    "全站更新日志",
    "历史部署包、旧日志和旧会话结论"
  ],
  "requiredReadOrder": [
    "/engineering-rules.json",
    "/update-log.json",
    "Neocities /api/list 的实时清单",
    "本轮权威源码、构建脚本与用户新文件"
  ],
  "multiAgentProtocol": [
    "接手任务先读取公开工程规则和全站更新日志，不得只依赖当前对话记忆。",
    "部署前重新获取线上清单并记录目标文件的 SHA-1；本地同名文件不自动等于最新版。",
    "先确认本轮权威源码，再从干净输出目录构建；禁止在历史 dist 上持续叠加补丁。",
    "只上传本轮必要文件及依赖；不得覆盖其他 AI 刚上线但尚未同步的内容。",
    "部署成功后必须在 update-log.json 的 entries 顶部追加记录，并同步 latest、latestKnownState 与 update-log.html。",
    "最终回复必须说明修改范围、上传路径、验证结果、删除情况、已知风险和回滚依据。"
  ],
  "releaseRules": [
    {
      "id": "R01",
      "level": "MUST",
      "rule": "未明确授权不得删除线上文件。旧 hash 资源默认保留。",
      "reason": "旧 HTML、缓存、书签或回滚版本仍可能引用。"
    },
    {
      "id": "R02",
      "level": "MUST",
      "rule": "正式页面只能引用内容 hash 资源；禁止使用 assets/app.css、assets/app.js 等裸共享路径。",
      "reason": "Neocities 无法为站点自定义可靠的 HTTP 缓存响应头。"
    },
    {
      "id": "R03",
      "level": "MUST",
      "rule": "assets/manifest.json 由发布流程生成，不得手工维护 hash。",
      "reason": "避免 manifest、HTML 和文件内容发生静默漂移。"
    },
    {
      "id": "R04",
      "level": "MUST",
      "rule": "manifest 逻辑键必须按 homepage、polish 等发布面命名空间化。",
      "reason": "主页和 Polish 存在同名 app.js、app.css，但它们不是同一资源。"
    },
    {
      "id": "R05",
      "level": "MUST",
      "rule": "新 hash 资源先上传并验证，随后上传 manifest，最后切换引用它们的 HTML。",
      "reason": "避免 HTML 短暂引用尚不存在的资源。"
    },
    {
      "id": "R06",
      "level": "MUST",
      "rule": "source、模板、构建脚本、日志、凭据和临时文件不得作为站点发布产物上传。",
      "reason": "Neocities 是发布目标，不是完整源码仓库。"
    },
    {
      "id": "R07",
      "level": "MUST",
      "rule": "现有线上 source/、build.py、verify.py、_template.html 属历史遗留，不得视为当前权威构建源。",
      "reason": "这些文件早于当前 76 个 Polish 页面与主页 V13，直接使用会回退。"
    },
    {
      "id": "R08",
      "level": "MUST",
      "rule": "Polish 页面只能从已确认的完整权威 source 与模板重建；无法确认时停止部署。",
      "reason": "线上生成页面无法反向恢复完整源文件。"
    },
    {
      "id": "R09",
      "level": "MUST",
      "rule": "Topics 发布必须递增 Service Worker 缓存名，并验证旧缓存升级。",
      "reason": "避免旧客户端长期停留在旧主题资源。"
    },
    {
      "id": "R10",
      "level": "MUST",
      "rule": "每次线上修改都必须更新全站日志；未生成日志条目的发布视为未完成。",
      "reason": "多 AI、多对话必须通过线上事实进行交接。"
    }
  ],
  "assetManifest": {
    "schemaVersion": 2,
    "namespaces": {
      "homepage": ["appCss", "topicsManifestJs", "catalogJs", "appJs"],
      "polish": ["appCss", "contentCss", "catalogJs", "appJs"]
    },
    "verification": [
      "manifest 中的每个路径必须存在",
      "文件名中的短 hash 必须与文件内容 SHA-256 前 8 位一致",
      "主页引用必须等于 homepage 命名空间",
      "Polish 页面引用必须等于 polish 命名空间",
      "正式 HTML 不得残留模板占位符或裸共享资源路径"
    ]
  },
  "updateLogProtocol": {
    "human": "/update-log.html",
    "machine": "/update-log.json",
    "requiredEntryFields": ["date", "scope", "summary", "highlights", "files", "verification", "deletions"],
    "rule": "日志必须描述实际完成的部署和验证，不得提前宣称成功。"
  },
  "stopConditions": [
    "无法确认权威源码是否为最新版",
    "线上状态在构建期间被其他会话改变且差异未分析",
    "manifest、HTML 引用和内容 hash 不一致",
    "关键页面、导航、词典、TTS 或主题交互验证失败",
    "上传或删除目标范围不明确",
    "用户提供的新版本存在重大内容、安全或结构问题"
  ],
  "stableUrls": {
    "home": "/",
    "dictionary": "/Dykt/",
    "updates": "/update-log.html",
    "rules": "/engineering-rules.html",
    "machineUpdates": "/update-log.json",
    "machineRules": "/engineering-rules.json"
  }
}
