| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125 |
- """Append the received research round while preserving raw dialogue and report versions."""
- from pathlib import Path
- import difflib
- import hashlib
- import json
- WORK = Path(__file__).resolve().parent
- ROOT = WORK.parents[1]
- def sha(path):
- return hashlib.sha256(path.read_bytes()).hexdigest()
- def main():
- case = json.loads((WORK / 'case.json').read_bytes())
- edits = json.loads((WORK / 'presentation-edits.json').read_bytes())
- for name, expected in edits['originalFileSha256'].items():
- assert sha(WORK / name) == expected, name
- changes = [
- ('rounds/R06/reply-verbatim.md', 'rounds/R06/reply-display.md',
- '线上回读校验通过:HTTP 200、16,907 B、sha256 双向一致,关键内容全部命中。\n\n', '',
- 'omit operational preface; raw received text remains unchanged'),
- ('rounds/R06/reply-verbatim.md', 'rounds/R06/reply-display.md',
- '报告:https://s3.fmode.cn/user/DpPsnlBm0K/report/ksf-consumer-research-r1-20261109.html',
- '报告见“研究成果”中的使用条件研究。', 'point to the received artifact in the same offline presentation'),
- ('rounds/R06/reply-verbatim.md', 'rounds/R06/reply-display.md',
- '本轮全程免费公开资料,未购样、未付费测试、未新增采集、未改 Skill、未改研究库。\n', '',
- 'omit operational tail; preserve all substantive research claims and limitations'),
- ]
- css = '''<style id="presentation-layout">
- body{font-size:16px}.lead,.g,.g th,.g td,.gs,.sr,.sr2,.bd2,.warn,.key,.ex li,.ex em,.exh,.st,.tag,.grd b{font-size:15px!important}
- h2{font-size:21px}h3{font-size:18px!important}.wrap,.ex,.key,.warn{min-width:0;overflow-wrap:anywhere}.sc{max-width:100%;overflow-x:auto}.g{min-width:1080px}.g th,.g td{min-width:150px;overflow-wrap:anywhere}.cond{min-width:145px}.ex li{line-height:1.85}.ex em{color:#52635b}.sr{color:#52635b}
- @media(max-width:640px){.wrap{padding:22px 14px 40px}.g th,.g td{padding:12px 10px}.key,.warn{padding:16px}.exh{line-height:1.7}}
- </style></head>'''
- changes.append(('rounds/R06/artifacts/consumer-research-received.html',
- 'rounds/R06/artifacts/consumer-research-display.html', '</head>', css,
- 'presentation-only readable type and internal table scrolling; no research text changed'))
- displays = {}
- for source, display, before, after, reason in changes:
- text = displays.get(display, (WORK / source).read_text(encoding='utf-8'))
- assert text.count(before) == 1, (source, before[:80])
- displays[display] = text.replace(before, after)
- edit = {'source': source, 'display': display, 'before': before, 'after': after, 'reason': reason}
- if edit not in edits['edits']:
- edits['edits'].append(edit)
- edits['originalFileSha256'][source] = sha(WORK / source)
- for name, text in displays.items():
- (WORK / name).write_text(text, encoding='utf-8', newline='\n')
- edits['originalFileSha256']['rounds/R06/prompt-verbatim.txt'] = sha(WORK / 'rounds/R06/prompt-verbatim.txt')
- downloaded = json.loads((WORK / 'rounds/R06/artifacts/download-receipt.json').read_bytes())
- sixth = next(r for r in case['rounds'] if r['roundId'] == 'R06')
- sixth.update({
- 'status': 'exploratory-reply-received-reviewed-sources-and-inferences-pending',
- 'forwardedConfirmed': None, 'executionConfirmed': True, 'replyReceived': True,
- 'replyPath': 'rounds/R06/reply-verbatim.md',
- 'replySha256': sha(WORK / 'rounds/R06/reply-verbatim.md'),
- 'replyComplete': True, 'reviewPath': 'rounds/R06/review.md',
- 'promptExecutionMatch': 'inferred-from-sequence-exact-prompt-not-verified',
- 'executionEvidence': 'user-relayed-complete-reply; no original VOC or query logs received',
- 'claimsIndependentlyVerified': False,
- 'interviewsConducted': False, 'innovationDirectionSelected': False,
- 'receivedArtifact': {
- 'path': 'rounds/R06/artifacts/consumer-research-received.html',
- 'presentationPath': 'rounds/R06/artifacts/consumer-research-display.html',
- 'url': downloaded['url'], 'httpStatus': downloaded['httpStatus'],
- 'bytes': downloaded['bytes'], 'sha256': downloaded['sha256'],
- 'sourceAnchorLinks': len(downloaded['sourceLinks']), 'embeddedImages': downloaded['images'],
- 'fileIndependentlyDownloaded': True,
- 'scope': 'received file and available text; original quotations, VOC execution and board not independently verified',
- },
- })
- if not any(r['roundId'] == 'R07' for r in case['rounds']):
- case['rounds'].append({
- 'roundId': 'R07', 'moduleId': 'D1-04',
- 'purpose': '收敛使用任务与取舍,准备有来源依据的后续研究',
- 'promptPath': 'rounds/R07/prompt-verbatim.txt',
- 'promptOrigin': 'authored-locally-for-user-forwarding',
- 'status': 'prepared-for-user-forwarding', 'forwardedConfirmed': False,
- 'executionConfirmed': False, 'replyReceived': False,
- 'reportIds': [], 'actualUserDecision': None,
- })
- case['status'] = 'R06-exploratory-consumer-material-received-R07-prepared'
- case['currentModuleId'] = 'D1-04'
- case['moduleComplete'] = False
- case['courseModules'][3]['status'] = 'exploratory-tasks-and-material-received-not-finalized-or-dispatched'
- case['courseModules'][4]['status'] = 'public-material-report-received-autonomous-execution-not-verified'
- case['demonstration'].update({'status': 'six-replies-five-artifacts-layout-pending', 'actualReplies': 6,
- 'latestReplyComplete': True})
- case['operatingContext']['platform'] = 'no fixed model or client; earlier Doubao note describes one example environment'
- case['operatingContext']['actualCapabilities'] = 'verify current integrations separately from installation or model choice'
- (WORK / 'case.json').write_text(json.dumps(case, ensure_ascii=False, indent=2) + '\n', encoding='utf-8')
- (WORK / 'presentation-edits.json').write_text(json.dumps(edits, ensure_ascii=False, indent=2) + '\n', encoding='utf-8')
- # This is a new local draft revision; leave the preceding report-design receipt as history.
- local = WORK / 'rounds/R06/local-skill-review'
- skill = ROOT / 'skills/ksf-workshop-runtime'
- baseline = json.loads((local / 'before-fingerprints.json').read_bytes())
- changed = [name for name, digest in baseline.items() if sha(skill / name) != digest]
- assert changed == ['references/workshop-innovation-reasoning.md'], changed
- runtime = [name for name in baseline if name.startswith('scripts/') or name == 'runtime-lock.json']
- assert len(runtime) == 7 and all(sha(skill / name) == baseline[name] for name in runtime)
- (skill / 'FILES.sha256').write_text(''.join(sha(skill / name) + ' ' + name + '\n' for name in baseline), encoding='utf-8', newline='\n')
- for name in changed + ['FILES.sha256']:
- before = (local / 'before' / name).read_text(encoding='utf-8')
- after = (skill / name).read_text(encoding='utf-8')
- target = local / 'diff' / (name + '.diff')
- target.parent.mkdir(parents=True, exist_ok=True)
- target.write_text(''.join(difflib.unified_diff(before.splitlines(True), after.splitlines(True),
- fromfile='before/' + name, tofile='local/' + name)), encoding='utf-8')
- sealed = ROOT / 'docs/workshop-skill-release-20261109-r6/ksf-workshop-skill-update-20261109-r6.zip'
- assert sha(sealed) == 'c329432b9773cfb0a8e5d4a3e5c162b3778eab28d576b79875da6854f33c4dc5'
- receipt = {'ok': True, 'changedInstructions': changed, 'manifestEntries': len(baseline),
- 'manifestSha256': sha(skill / 'FILES.sha256'), 'runtimeChanged': False,
- 'remoteInstalled': False, 'sealedR6Modified': False,
- 'reason': 'observed attitude/action confusion, overbroad counterevidence and monetary-only tradeoff framing',
- 'changes': [{'path': name, 'before': baseline[name], 'after': sha(skill / name)} for name in changed]}
- (local / 'receipt.json').write_text(json.dumps(receipt, ensure_ascii=False, indent=2) + '\n', encoding='utf-8')
- print(json.dumps({'receivedRound': 'R06', 'actualReplies': 6, 'artifacts': 5,
- 'nextPromptExecuted': False, 'localSkillUpdated': changed, 'remoteInstalled': False}, ensure_ascii=False))
- if __name__ == '__main__':
- main()
|