package-S5-classroom-next.py 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. """Package prepared, reviewed and checked S5 inputs. Local filesystem only."""
  2. from pathlib import Path
  3. import hashlib
  4. import json
  5. import zipfile
  6. ROOT = Path(__file__).resolve().parents[1]
  7. DOCS = Path('F:/文档/工作坊当前资料')
  8. OUT = ROOT / 'work/S5-classroom-next-20261103'
  9. ZIP = DOCS / 'ksf-S5-classroom-next-20261103.zip'
  10. assert not ZIP.exists()
  11. audit = json.loads((ROOT / 'work/S5-classroom-live-preflight-20261103.json').read_text(encoding='utf-8'))
  12. simulation = json.loads((ROOT / 'work/S5-classroom-isolated-simulation-20261103.json').read_text(encoding='utf-8'))
  13. assert audit['ok'] and simulation['ok']
  14. assert audit['currentStage'] == 'S4' and audit['productionBusinessWrites'] == simulation['productionWrites'] == 0
  15. assert len(simulation['calls']) == 8
  16. assert simulation['expectedFinal']['progressState'] == 'in_progress'
  17. preflight_file = OUT / 'preflight.json'
  18. preflight = json.loads(preflight_file.read_text(encoding='utf-8'))
  19. preflight.update({
  20. 'liveReadOnlyPreflight': {'at': audit['at'], 'checksPassed': audit['checksPassed'], 'currentStage': audit['currentStage'],
  21. 'projectId': audit['projectId'], 'conceptCount': audit['conceptCount'], 's5ArtifactCount': audit['s5ArtifactCount'],
  22. 'matchedFutureWriteAuditRows': audit['matchedFutureWriteAuditRows'], 'deployedCommandCount': len(audit['deployedCodeChecks']),
  23. 'productionBusinessWrites': 0, 'remoteFilesystemAndProcessesInspected': False, 'currentMessageIdentityVerifiedByCodex': False},
  24. 'localSimulation': {'at': simulation['at'], 'checksPassed': simulation['checksPassed'], 'orderedCommandCount': len(simulation['calls']),
  25. 'negativeControls': simulation['negativeControls'], 'productionCalls': 0, 'productionWrites': 0,
  26. 'expectedFinal': simulation['expectedFinal'], 'simulatedOnly': True},
  27. })
  28. preflight_file.write_text(json.dumps(preflight, ensure_ascii=False, indent=2) + '\n', encoding='utf-8', newline='\n')
  29. review_file = OUT / '52-S5桌面方案审阅与定稿.md'
  30. with review_file.open('a', encoding='utf-8', newline='\n') as f:
  31. f.write(f'''
  32. 独立准备结果:现网只读预检{audit['checksPassed']}项通过,当前仍S4/in_progress,无concept、S5系列成果或本次成功写入审计。四来源及证据绑定/quote重新按编号读回;S4固定内容、归属保持一致。当前4个部署入口的相关命令体及会话/项目/事件/幂等处理与核对实现匹配,包含concept-save的精确字段与pendingQuestions持久化位置。
  33. 以本次捕获的现网处理代码和运行时字段表,在本地内存完成8步模拟,{simulation['checksPassed']}项结果检查及2个反向控制通过:无项目S4成果不能转S5;首次concept不能跳过v1。模拟最终S5/in_progress、同项目3份成果、1个concept v1、0配料条目、7事件,预期3条成功写入。模拟没有生产调用或写入,不替代未来每步回读与匿名生产浏览器验收。
  34. 本地独立记录:F:/kangshifu-board/work/S5-classroom-live-preflight-20261103.json、F:/kangshifu-board/work/S5-classroom-isolated-simulation-20261103.json。preflight.json中localStructureOnly描述原始模板生成,后续liveReadOnlyPreflight与localSimulation另行列出;不能把本轮概括为“从未访问业务接口”,实际发生了生产只读访问。
  35. ''')
  36. readme_file = OUT / 'README.txt'
  37. with readme_file.open('a', encoding='utf-8', newline='\n') as f:
  38. f.write(f'已完成:现网只读预检{audit["checksPassed"]}项、8步内存模拟{simulation["checksPassed"]}项及2反向控制。远端落地、当前真实身份、在途与逐次生产回读仍须53/54执行。\n')
  39. names = sorted(p.name for p in OUT.iterdir() if p.is_file())
  40. assert len(names) == 10
  41. allowed = {'.json', '.md', '.txt'}
  42. for name in names:
  43. assert Path(name).suffix in allowed
  44. data = (OUT / name).read_text(encoding='utf-8')
  45. assert '-----BEGIN' not in data and 'X-Parse-Master-Key' not in data and 'signingSecret' not in data
  46. manifest = [hashlib.sha256((OUT / name).read_bytes()).hexdigest() + ' ' + name for name in names]
  47. with (OUT / 'FILES.sha256').open('x', encoding='utf-8', newline='\n') as f:
  48. f.write('\n'.join(manifest) + '\n')
  49. with zipfile.ZipFile(ZIP, 'x', compression=zipfile.ZIP_DEFLATED, compresslevel=7) as bundle:
  50. for p in sorted(OUT.iterdir()):
  51. bundle.write(p, p.name)
  52. with zipfile.ZipFile(ZIP) as bundle:
  53. assert bundle.testzip() is None
  54. assert len(bundle.namelist()) == 11
  55. for line in manifest:
  56. digest, name = line.split(' ', 1)
  57. assert hashlib.sha256(bundle.read(name)).hexdigest() == digest
  58. for name in ['52-S5桌面方案审阅与定稿.md', '53-发给运维001-S5方案与报告准备.txt',
  59. '54-发给王刚001-S5方案与课堂报告保存.txt', 'S5桌面方案第1版-审阅稿.md']:
  60. with (DOCS / name).open('xb') as f:
  61. f.write((OUT / name).read_bytes())
  62. receipt = {
  63. 'ok': True, 'zip': str(ZIP), 'bytes': ZIP.stat().st_size, 'sha256': hashlib.sha256(ZIP.read_bytes()).hexdigest(),
  64. 'entries': 11, 'manifestVerified': 10, 'currentStage': 'S4', 'saved': False, 'productionBusinessWrites': 0,
  65. 'liveReadOnlyPreflightPassed': audit['checksPassed'], 'localSimulationChecksPassed': simulation['checksPassed'],
  66. 'templates': {name: {'bytes': (OUT / name).stat().st_size, 'sha256': hashlib.sha256((OUT / name).read_bytes()).hexdigest()}
  67. for name in names if name.endswith('.template.json')},
  68. }
  69. with (ROOT / 'work/S5-classroom-next-package-receipt-20261103.json').open('x', encoding='utf-8', newline='\n') as f:
  70. json.dump(receipt, f, ensure_ascii=False, indent=2)
  71. f.write('\n')
  72. backup = ROOT / 'work/S5-progress-before-package-20261103'
  73. backup.mkdir()
  74. for name in ['01-工作进展汇报.txt', '02-后续待补资料.md', 'README.md']:
  75. with (backup / name).open('xb') as f:
  76. f.write((DOCS / name).read_bytes())
  77. index_file = DOCS / 'README.md'
  78. index = index_file.read_text(encoding='utf-8')
  79. start = index.index('当前状态(')
  80. end = index.index('\n\n', start)
  81. index = index[:start] + '当前状态(2026年11月3日):S4 / in_progress。S4已独立验收;王刚001的S5文字草稿已按52号审阅定稿,三份固定模板与53/54号已准备,现网只读预检及8步本地模拟通过。下一步将53号与S5固定材料包交运维落地预检,再由王刚001按54号真实消息执行。尚未转S5、尚未保存concept或S5报告;不重复改稿、不要求先交实物,不重跑S1—S4。' + index[end:]
  82. old51 = next(line for line in index.splitlines() if line.startswith('- 51-'))
  83. index = index.replace(old51, '- 51-发给王刚001-S5桌面方案草稿.txt:已收到文字草稿,52号已审阅定稿,保留原单,不重跑该轮只读。\n- 52-S5桌面方案审阅与定稿.md:当前审阅结果;证据边界、研究记录与产品路径、13项未决问题已校正,无需再退回重写。\n- 53-发给运维001-S5方案与报告准备.txt:当前下一步;原样落地3模板并只读核合同、归属、来源、历史、在途。\n- 54-发给王刚001-S5方案与课堂报告保存.txt:运维预检通过后在真实消息执行8步;project-progress→concept-save→workshop-save,最终S5/in_progress,不自动completed。\n- S5桌面方案第1版-审阅稿.md:拟保存的正文审阅稿,尚未保存生产。\n- ksf-S5-classroom-next-20261103.zip:3固定模板、runbook、审阅及交接;11条目、10/10清单核验。sessionId/projectId为null,不可直接提交。')
  84. index_file.write_text(index, encoding='utf-8', newline='\n')
  85. progress_file = DOCS / '01-工作进展汇报.txt'
  86. text = progress_file.read_text(encoding='utf-8')
  87. old = next(line for line in text.splitlines() if line.startswith('下一步执行单51号'))
  88. text = text.replace(old, 'S5文字草稿已收到并按52号直接校正定稿:不以P1断言信息分散,不把P2当包装错误证明,不用未定义“多数”为停止线,研究记录与产品路径分开。原S4八条未决问题逐字保留,加五条设计问题共13条。三份固定模板、53号运维单、54号王刚执行单及审阅稿已打包;现网只读预检13项及8步本地模拟8项/2反向控制通过。系统仍S4,无concept或S5报告、无本次成功写入。下一步交53号+S5包运维落地,通过后54号真实执行,不再退回改稿或重查样品。实际试吃/市场/量产均未做。新数字人接入、实名绑定及旧机器人密钥轮换仍为待办。')
  89. text += f'\nS5固定材料包:ksf-S5-classroom-next-20261103.zip,{receipt["bytes"]}字节,SHA256={receipt["sha256"]};11条目、清单10/10。\n'
  90. progress_file.write_text(text, encoding='utf-8', newline='\n')
  91. pending_file = DOCS / '02-后续待补资料.md'
  92. text = pending_file.read_text(encoding='utf-8')
  93. old = next(line for line in text.splitlines() if line.startswith('软件流程下一步:'))
  94. text = text.replace(old, '软件流程下一步:S5草稿已按52号审阅定稿,原八项缺口加五项设计问题共13条;规格数值null、formulaItems/productionSteps为空。53号+S5固定材料包交运维只读准备,通过后54号由王刚001真实执行。无需重复改稿或要求用户先供实物。本轮系统仍S4、concept与S5报告均未保存;拟执行后保持S5/in_progress,课堂研究未决项继续保留,不自动完成或正式发布。')
  95. pending_file.write_text(text, encoding='utf-8', newline='\n')
  96. print(json.dumps(receipt, ensure_ascii=True, indent=2))