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