package-report-evidence-ui.py 5.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. """Build a fixed three-file site patch. No site or database writes."""
  2. from pathlib import Path
  3. import hashlib
  4. import json
  5. import zipfile
  6. ROOT=Path(__file__).resolve().parents[1]
  7. DELIVERY=Path('F:/文档/工作坊当前资料')
  8. FILES=['src/core/report.js','src/core/evidence/chain.js','src/layout/kf-app.js']
  9. def sha(body):
  10. return hashlib.sha256(body).hexdigest()
  11. def main():
  12. baseline=json.loads((ROOT/'work/report-evidence-before.json').read_text(encoding='utf-8'))
  13. by_path={row['path']:row for row in baseline['files']}
  14. manifest={
  15. 'version':'ksf.report-evidence.publish.v1',
  16. 'release':'ksf.report-evidence.20261102.v1',
  17. 'homepageSha256':by_path['index.html']['sha256'],
  18. 'baselineObservedAt':baseline['at'],
  19. 'files':[{'path':name,'sha256':sha((ROOT/name).read_bytes()),
  20. 'priorNormalizedSha256':[by_path[name]['normalizedSha256']],'allowMissing':False} for name in FILES],
  21. }
  22. manifest_path=ROOT/'deploy/report-evidence-files-20261102.json'
  23. manifest_path.write_text(json.dumps(manifest,ensure_ascii=False,indent=2)+'\n',encoding='utf-8')
  24. instructions='''运维001:发布报告引文显示修复,只改三个前端文件,无业务数据写入。
  25. 原因:S1第2版G8IrkkDG7X的正文、五段引文和六条待补问题已独立回读通过;但报告是表格/段落结构,旧页面未生成引用入口。修复补齐所有report.evidence的入口,并保留引用的sourceId,避免已入库原文误标为“未落入知识库”。不修改报告内容、不补造消费者结论。
  26. 包:ksf-report-evidence-ui-20261102.zip。先核FILES.sha256六项。发布器为独立新文件scripts/publish-report-evidence.mjs,旧九文件发布器不变。
  27. 只允许三个文件:
  28. src/core/report.js
  29. src/core/evidence/chain.js
  30. src/layout/kf-app.js
  31. 原首页SHA-256=dfeb6a6d0b63e8e1190f9308bf6619a5ca523a5a2f91af5f7ca5ad5fc9642db3。
  32. 旧文件基线来自2026-11-02线上独立只读读取,并已与本地原件逐字核对;manifest记载完整旧/新指纹。任何未知版本或首页不符都停止,不改指纹放行。
  33. 1. 解压到与站点目录互不嵌套的独立目录,核对6/6。由站点维护人使用此前核实的kangshifu.fmode.cn实际静态文件目录;不能用数字人容器/opt/data冒充站点目录,也不能根据域名猜目录。
  34. 2. 在解包根目录以Node执行只读计划(把占位符替换为维护人已核实的绝对目录):
  35. node scripts/publish-report-evidence.mjs --target-dir <实际站点绝对目录>
  36. 检查filesChecked=3、homepageModified=false,changes仅上述三文件。如果全部unchanged,直接回读,不重复发布。
  37. 3. 计划通过,执行一次:
  38. node scripts/publish-report-evidence.mjs --target-dir <同一实际站点绝对目录> --apply
  39. 发布器在站点目录外先备份三个旧文件,然后逐个原子替换并回读;同时保护首页与目标指纹。失败会尝试回退且不覆盖别人的并发改动,保留backup和journal,不循环重试。
  40. 4. 回报计划/apply退出码、changes、三个文件回读hash、首页hash、备份路径、filesystemVerified。站点文件更新不等于域名已更新,CDN缓存如存在需由维护人按既有方式处理,并如实回报;由Codex再验正常URL的三个模块指纹和匿名浏览器。
  41. 回退:从本次backup读取journal,在恢复每个旧文件前先确认目标仍是journal里本次afterSha256;不符就保留现场报告并发变化。仅恢复这三文件,不动index.html,不清空或重建站点目录。备份保留。
  42. 边界:不跑完整deploy.sh、不改首页/样式/登录流程、不改Skill、Function或schema,不重启网关,不重新保存S1或导入资料。王刚001当前没有待执行的业务命令。
  43. Codex隔离浏览器已使用真实线上公开数据、仅替换上述三模块进行桌面和390px检查:五段引文均可点击查看、六条问题可见、旧报告保留、页面无横向溢出。该结果不代表生产站点已应用修复,线上browserVerified仍待本次发布后的独立验收。
  44. '''
  45. payload={name:(ROOT/name).read_bytes() for name in FILES}
  46. payload['scripts/publish-report-evidence.mjs']=(ROOT/'scripts/publish-report-evidence.mjs').read_bytes()
  47. payload['deploy/report-evidence-files-20261102.json']=manifest_path.read_bytes()
  48. payload['INSTALL.txt']=instructions.encode('utf-8')
  49. payload['FILES.sha256']=''.join(sha(body)+' '+name+'\n' for name,body in payload.items()).encode('utf-8')
  50. DELIVERY.mkdir(parents=True,exist_ok=True)
  51. target=DELIVERY/'ksf-report-evidence-ui-20261102.zip'
  52. with zipfile.ZipFile(target,'w',compression=zipfile.ZIP_DEFLATED) as archive:
  53. for name,body in payload.items():
  54. archive.writestr(name,body)
  55. with zipfile.ZipFile(target) as archive:
  56. assert archive.testzip() is None
  57. for line in archive.read('FILES.sha256').decode('utf-8').splitlines():
  58. expected,name=line.split(' ',1)
  59. assert sha(archive.read(name))==expected
  60. (DELIVERY/'07-发给运维001-报告引文显示修复.txt').write_text(instructions,encoding='utf-8')
  61. receipt={'file':str(target),'bytes':target.stat().st_size,'sha256':sha(target.read_bytes()),'manifestChecked':'6/6',
  62. 'frontendFiles':FILES,'sitePublished':False,'businessWrites':0,'homepageModified':False}
  63. (ROOT/'work/report-evidence-ui-package-receipt.json').write_text(json.dumps(receipt,ensure_ascii=False,indent=2)+'\n',encoding='utf-8')
  64. print(json.dumps(receipt,ensure_ascii=True,indent=2))
  65. if __name__=='__main__':
  66. main()