| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122 |
- """Archive the fourth actual reply and product comparison without altering claims."""
- from pathlib import Path
- from html.parser import HTMLParser
- import hashlib
- import json
- import re
- import shutil
- WORK = Path(__file__).resolve().parent
- def sha(path):
- return hashlib.sha256((WORK / path).read_bytes()).hexdigest()
- class Visible(HTMLParser):
- def __init__(self):
- super().__init__()
- self.hidden = 0
- self.parts = []
- def handle_starttag(self, tag, attrs):
- if tag in ('style', 'script'):
- self.hidden += 1
- def handle_endtag(self, tag):
- if tag in ('style', 'script'):
- self.hidden -= 1
- def handle_data(self, value):
- if not self.hidden:
- self.parts.append(value)
- def visible(value):
- parser = Visible()
- parser.feed(value)
- return re.sub(r'\s+', ' ', ''.join(parser.parts)).strip()
- def main():
- snapshot = WORK / 'internal-archive/R03-reviewed'
- snapshot.mkdir(parents=True, exist_ok=True)
- for path in ['案例样板演示.html', 'demo-build.json', 'browser-checks.json', 'case.json']:
- if not (snapshot / path).exists():
- shutil.copy2(WORK / path, snapshot / path)
- edits = json.loads((WORK / 'presentation-edits.json').read_bytes())
- edits['edits'] = [e for e in edits['edits'] if e['source'] not in {
- 'rounds/R04/reply-verbatim.md', 'rounds/R04/artifacts/comparison-received.html'}]
- def present(src, dst, replacements):
- value = (WORK / src).read_text(encoding='utf-8')
- for before, after, reason in replacements:
- assert value.count(before) == 1, (src, before)
- value = value.replace(before, after, 1)
- edits['edits'].append({'source': src, 'display': dst, 'before': before,
- 'after': after, 'reason': reason})
- (WORK / dst).write_text(value, encoding='utf-8')
- return value
- raw = (WORK / 'rounds/R04/reply-verbatim.md').read_text(encoding='utf-8')
- present('rounds/R04/reply-verbatim.md', 'rounds/R04/reply-display.md', [
- ('全部核验通过。新件已经进入公开看板,是 52 条中的第 1 条,标记为 S1 / owner 用户8108 / live / v1。\n\n', '', 'omit operational board receipt only'),
- ('对照图:https://s3.fmode.cn/user/DpPsnlBm0K/report/ksf-products-compare-r1-20261109.html', '对照图见“研究成果”中的产品对照。', 'replace implementation URL with local embedded received artifact'),
- (raw[raw.index('本轮无付费、无实物测试、无新增采集;产线、成'):], '', 'omit incomplete operational tail; never reconstruct missing content'),
- ])
- src = 'rounds/R04/artifacts/comparison-received.html'
- dst = 'rounds/R04/artifacts/comparison-display.html'
- atlas = (WORK / src).read_text(encoding='utf-8')
- assert not re.search(r'<script|<iframe|<link|<img|\bon\w+\s*=|@import|url\(', atlas, re.I)
- style = '''<style id="presentation-layout">
- body{font-size:16px}.sub,.meta-line,.glogic,table,th,td,td.pname small,.base-tag,.b,.gc>div,.gc h4,.dim,.note,.alert,.unknown-list li,.q dt,.q dd,.q h4,footer,th span,td span{font-size:15px!important}
- .card,.gc>div{min-width:0;overflow-wrap:anywhere}.tscroll{max-width:100%;overflow-x:auto}.dims{min-width:0;flex-wrap:wrap}.dim{white-space:normal}
- @media(max-width:640px){.wrap{padding:0 14px}.card{padding:17px 14px}.gc{grid-template-columns:minmax(0,1fr)}table{min-width:880px}}
- </style>'''
- replacements = [
- ('<code>evidence-rules.json v1.0</code>', '本次研究规则', 'remove private implementation filename only'),
- ('未改研究库与 Skill', '未改研究资料', 'remove operational tool identity'),
- ('</head>', style + '</head>', 'presentation-only readable fonts and mobile scrolling'),
- ]
- displayed = present(src, dst, replacements)
- expected_text = atlas
- for before, after, _ in replacements[:-1]:
- expected_text = expected_text.replace(before, after)
- assert visible(displayed) == visible(expected_text)
- edits['originalFileSha256'].update({p: sha(p) for p in [
- 'rounds/R04/reply-verbatim.md', 'rounds/R04/prompt-verbatim.txt', src]})
- edits['artifactBusinessTextPreserved'] = True
- (WORK / 'presentation-edits.json').write_text(json.dumps(edits, ensure_ascii=False, indent=2) + '\n', encoding='utf-8')
- case = json.loads((WORK / 'case.json').read_bytes())
- fourth = next(r for r in case['rounds'] if r['roundId'] == 'R04')
- fourth.update({'status': 'reply-received-reviewed-incomplete-tail', 'forwardedConfirmed': None,
- 'executionConfirmed': True, 'replyReceived': True,
- 'replyPath': 'rounds/R04/reply-verbatim.md', 'replySha256': sha('rounds/R04/reply-verbatim.md'),
- 'reviewPath': 'rounds/R04/review.md', 'replyComplete': False,
- 'completeness': 'received message ends at 产线、成; no missing text reconstructed',
- 'executionEvidence': 'user-relayed-reply; prompt association inferred from conversation sequence',
- 'claimsIndependentlyVerified': False,
- 'reportedArtifacts': [{'artifactId': None, 'publicBoardVisible': 'reported',
- 'boardCount': 52, 'independentlyVerifiedHere': False}],
- 'receivedArtifact': {'path': src, 'presentationPath': dst,
- **json.loads((WORK / 'rounds/R04/artifacts/download-receipt.json').read_bytes())}})
- fifth = {'roundId': 'R05', 'moduleId': 'D1-03',
- 'purpose': '固定四款产品版本,核准包装与食用说明及评论归属',
- 'promptPath': 'rounds/R05/prompt-verbatim.txt', 'promptOrigin': 'authored-locally-for-user-forwarding',
- 'status': 'prepared-for-user-forwarding', 'forwardedConfirmed': False,
- 'executionConfirmed': False, 'replyReceived': False, 'reportIds': [], 'actualUserDecision': None}
- case['rounds'] = [r for r in case['rounds'] if r['roundId'] != 'R05'] + [fifth]
- case['status'] = 'R04-product-comparison-received-identity-corrections-needed-R05-prepared'
- case['currentModuleId'] = 'D1-03'
- case['moduleComplete'] = False
- case['courseModules'][2]['status'] = 'comparison-received-product-identity-and-evidence-unresolved'
- case['demonstration'].update({'actualReplies': 4, 'latestReplyComplete': False,
- 'status': 'four-replies-three-artifacts-awaiting-layout-check'})
- (WORK / 'case.json').write_text(json.dumps(case, ensure_ascii=False, indent=2) + '\n', encoding='utf-8')
- print(json.dumps({'actualReplies': 4, 'latestReplyComplete': False, 'nextPromptExecuted': False,
- 'artifactBusinessTextPreserved': True}, ensure_ascii=False))
- if __name__ == '__main__':
- main()
|