| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107 |
- """Package verified closeout instructions and update only local progress docs."""
- from pathlib import Path
- from datetime import datetime, timezone
- import hashlib
- import json
- import zipfile
- ROOT = Path(__file__).resolve().parents[1]
- DOCS = Path('F:/文档/工作坊当前资料')
- OUT = ROOT / 'work/S5-classroom-completion-20261103'
- PACKAGE = DOCS / 'ksf-S5-classroom-completion-20261103.zip'
- BACKUP = ROOT / 'work/S5-progress-before-completion-preparation-20261103'
- audit = json.loads((ROOT / 'work/S5-completion-live-preflight-20261103.json').read_text(encoding='utf-8'))
- simulation = json.loads((ROOT / 'work/S5-completion-isolated-simulation-20261103.json').read_text(encoding='utf-8'))
- assert audit['ok'] and simulation['ok']
- assert audit['productionBusinessWrites'] == simulation['productionWrites'] == 0
- assert audit['checksPassed'] == simulation['checksPassed'] == 9
- assert audit['currentStage'] == 'S5' and audit['progressState'] == 'in_progress'
- assert not PACKAGE.exists() and not BACKUP.exists()
- sha = lambda data: hashlib.sha256(data).hexdigest()
- old_names = ['52-S5桌面方案审阅与定稿.md', '53-发给运维001-S5方案与报告准备.txt', '54-发给王刚001-S5方案与课堂报告保存.txt', '55-S5方案与课堂报告独立验收结果.md', 'ksf-S5-classroom-next-20261103.zip']
- old_hashes = {n: sha((DOCS / n).read_bytes()) for n in old_names}
- preflight_path = OUT / 'preflight.json'
- preflight = json.loads(preflight_path.read_text(encoding='utf-8'))
- preflight.pop('localStructureOnly')
- preflight.update({
- 'scope': 'Local material preparation plus separately recorded production reads and RAM simulation',
- 'liveReadOnlyPreflight': {'at': audit['at'], 'checksPassed': audit['checksPassed'], 'readCalls': audit['readCalls'], 'currentStage': 'S5', 'progressState': 'in_progress', 'artifactCount': 3, 'eventCount': 7, 'pendingQuestionCount': 13, 'futureWriteAuditMatches': 0, 'productionBusinessWrites': 0},
- 'isolatedSimulation': {'at': simulation['at'], 'checksPassed': simulation['checksPassed'], 'commandSteps': 3, 'negativeControls': simulation['negativeControls'], 'idempotencyControls': simulation['idempotencyControls'], 'productionCalls': 0, 'productionWrites': 0, 'expectedAfter': simulation['expectedAfter']},
- 'currentMessageIdentityVerifiedByCodex': False, 'remoteFilesystemAndProcessesInspected': False,
- })
- preflight_path.write_text(json.dumps(preflight, ensure_ascii=False, indent=2) + '\n', encoding='utf-8', newline='\n')
- with (OUT / '55-S5方案与课堂报告独立验收结果.md').open('xb') as stream:
- stream.write((DOCS / '55-S5方案与课堂报告独立验收结果.md').read_bytes())
- with (OUT / '56-课堂总结与完成条件.md').open('a', encoding='utf-8', newline='\n') as stream:
- stream.write('''
- 独立准备结果:本轮生产只读预检9项通过,实际发起9次只读调用,项目仍S5/in_progress、3成果/1概念/7事件、13问题;未来完成写键没有成功审计。当前部署的转阶段和状态读取命令及相关会话/事件/幂等处理与核查实现一致。Codex未独立核远端文件/进程或本条企微身份。
- 用本次捕获的部署代码和字段表完成本地内存模拟9项:3步CLI流程、3个前提反向控制、2个幂等控制通过。模拟完成后仍3报告/1概念/13问题,只增加第8条completed事件与1条成功审计。模拟重放仅在隔离内存进行,不允许据此自动重试生产。没有生产完成写入或本轮生产浏览器完成态验收;后续仍按57/58执行和回读。
- 独立证据:F:/kangshifu-board/work/S5-completion-live-preflight-20261103.json、F:/kangshifu-board/work/S5-completion-isolated-simulation-20261103.json。历史55号及其首次失败/后续验收证据保持原样。
- ''')
- with (OUT / 'README.txt').open('a', encoding='utf-8', newline='\n') as stream:
- stream.write('已完成9项生产只读预检(9次只读调用)及9项内存模拟;未执行生产完成写入。57号远端落地预检和58号真实消息执行仍待完成。\n')
- names = sorted(p.name for p in OUT.iterdir() if p.is_file())
- assert len(names) == 8
- for name in names:
- text = (OUT / name).read_text(encoding='utf-8')
- for forbidden in ['-----BEGIN', 'X-Parse-Master-Key', 'signingSecret']:
- assert forbidden not in text
- manifest = ''.join(f'{sha((OUT / name).read_bytes())} {name}\n' for name in names)
- with (OUT / 'FILES.sha256').open('x', encoding='utf-8', newline='\n') as stream:
- stream.write(manifest)
- with zipfile.ZipFile(PACKAGE, 'x', compression=zipfile.ZIP_DEFLATED) as archive:
- for name in [*names, 'FILES.sha256']:
- archive.write(OUT / name, arcname=name)
- with zipfile.ZipFile(PACKAGE) as archive:
- assert len(archive.infolist()) == 9
- assert archive.testzip() is None
- for name in names:
- assert archive.read(name) == (OUT / name).read_bytes()
- assert sha(archive.read(name)) == sha((OUT / name).read_bytes())
- for name in ['56-课堂总结与完成条件.md', '57-发给运维001-课堂完成准备.txt', '58-发给王刚001-课堂完成与回读.txt']:
- assert not (DOCS / name).exists()
- with (DOCS / name).open('xb') as stream:
- stream.write((OUT / name).read_bytes())
- originals = {name: (DOCS / name).read_bytes() for name in ['01-工作进展汇报.txt', '02-后续待补资料.md', 'README.md']}
- BACKUP.mkdir()
- for name, content in originals.items():
- with (BACKUP / name).open('xb') as stream:
- stream.write(content)
- with (BACKUP / 'manifest.json').open('x', encoding='utf-8') as stream:
- json.dump({name: sha(content) for name, content in originals.items()}, stream, ensure_ascii=False, indent=2)
- progress = originals['01-工作进展汇报.txt'].decode('utf-8-sig')
- old = '下一步可整理课堂总结与完成条件,再执行相应状态操作;本次没有自动completed。'
- assert old in progress
- progress = progress.replace(old, '课堂总结与完成条件已整理为56号,1份完成模板、57号运维单、58号王刚执行单及固定材料包已备齐;9项生产只读预检和9项隔离模拟通过。本轮仍S5/in_progress,没有完成写入。下一步先交57号+收尾包给运维落地预检,再由王刚001按58号真实消息执行1写2读,最终由Codex核完成态。', 1)
- progress += f'\n课堂收尾固定包:{PACKAGE.name},{PACKAGE.stat().st_size}字节,SHA256={sha(PACKAGE.read_bytes())};9条目、清单8/8核验。更新前快照:{BACKUP.as_posix()}/。\n'
- needs = originals['02-后续待补资料.md'].decode('utf-8-sig')
- old = '下一步可整理课堂总结与完成条件;不重跑53/54号,不补存新版本。'
- assert old in needs
- needs = needs.replace(old, '56号已整理课堂总结,57/58号及收尾固定包已准备并通过9项生产只读预检、9项内存模拟;当前仍S5/in_progress,未完成写入。先交57号与包运维落地,通过后58号由王刚001在真实消息执行1写2读。预期只新增completed事件/成功审计,13问题不变;不重跑53/54号,不补存新版本。', 1)
- readme = originals['README.md'].decode('utf-8-sig')
- old = '下一步可整理课堂总结和完成条件。'
- assert old in readme
- readme = readme.replace(old, '56号课堂总结、57/58号和收尾固定包已准备;9项生产只读预检、9项内存模拟通过,尚未执行完成写入。下一步交57号+包运维落地预检,再按58号真实执行1写2读,预期S5/completed并保留13问题。', 1)
- line = '- 55-S5方案与课堂报告独立验收结果.md:'
- assert line in readme
- readme = readme.replace(line, '- 56-课堂总结与完成条件.md:当前收尾范围,保留13问题、历史requestId偏差和研究/确认边界。\n- 57-发给运维001-课堂完成准备.txt:下一步;落地1份固定模板、核合同/归属/状态/回执/在途,不代跑完成。\n- 58-发给王刚001-课堂完成与回读.txt:57号通过后在真实消息执行3步;project-status→project-progress→project-status,1写2读,只更新课堂完成状态。\n- ksf-S5-classroom-completion-20261103.zip:9条目、清单8/8;模板两ID为null不可直接提交,生产未完成。\n' + line, 1)
- for name, text in {'01-工作进展汇报.txt': progress, '02-后续待补资料.md': needs, 'README.md': readme}.items():
- assert '仍S5/in_progress' in text or 'S5 / in_progress' in text
- (DOCS / name).write_text(text, encoding='utf-8', newline='\n')
- for name, digest in old_hashes.items():
- assert sha((DOCS / name).read_bytes()) == digest
- receipt = {'ok': True, 'at': datetime.now(timezone.utc).isoformat(), 'operation': 'prepare-S5-classroom-completion', 'package': str(PACKAGE), 'bytes': PACKAGE.stat().st_size, 'sha256': sha(PACKAGE.read_bytes()), 'entries': 9, 'manifestFilesVerified': 8, 'templateCount': 1, 'readOnlyPreflightChecks': 9, 'productionReadCalls': 9, 'isolatedSimulationChecks': 9, 'productionBusinessWrites': 0, 'currentStage': 'S5', 'progressState': 'in_progress', 'completionExecuted': False, 'backup': str(BACKUP), 'oldFilesUnchanged': old_hashes}
- with (ROOT / 'work/S5-completion-package-receipt-20261103.json').open('x', encoding='utf-8') as stream:
- json.dump(receipt, stream, ensure_ascii=False, indent=2)
- print(json.dumps(receipt, ensure_ascii=True, indent=2))
|