"""Create a local browsing page and review note for the source-bound evidence sidecar.""" import argparse from html import escape import json from pathlib import Path import shutil ROOT=Path(__file__).resolve().parents[1] def main(): p=argparse.ArgumentParser(description=__doc__) p.add_argument('--prepared',type=Path,required=True) p.add_argument('--audit',type=Path,required=True) args=p.parse_args() policy=json.loads((args.prepared/'policy-usage.json').read_bytes()) coverage=json.loads((args.audit/'coverage-matrix.json').read_bytes()) ranks=json.loads((args.audit/'ranking-source-readiness.json').read_bytes()) assert policy['generation']==coverage['generation']==ranks['generation'] for source in args.audit.glob('*.json'): shutil.copyfile(source,args.prepared/source.name) (args.prepared/'scripts').mkdir(exist_ok=True) for name in ('query-industry-policy-usage.py','build-industry-policy-usage.py','audit-industry-free-mainline.py','render-industry-policy-usage.py'): shutil.copyfile(ROOT/'scripts'/name,args.prepared/'scripts'/name) states={'PDF_PAGE_VERIFIED':'PDF原页已核','ARCHIVED_OFFICIAL_HTML_VERIFIED':'归档官方HTML已核','PENDING_ORIGINAL':'待原件'} clause_table='\n'.join('| '+str(r['sourceLine'])+' | '+r['documentId']+' | '+r['clause']+' | '+states[r['verification']]+' | '+r['topic']+' |' for r in policy['clauses']) stores_table='\n'.join('| '+r['name']+' | '+str(r['historicalListingProducts'])+' / '+str(r['currentSnapshotProducts'])+' | '+str(r['snapshotReviewRows'])+' | '+str(r['snapshotPriceRows'])+' | '+str(r['productsWithDetailResponse'])+' / '+str(r['productsWithDetailText'])+' |' for r in coverage['stores']) date_table='\n'.join('| '+r['documentId']+' | '+r['metadataPublishedAtRaw']+' | '+str(r['visiblePublishedDate'])+' |' for r in policy['documents'] if r.get('publicationDateConflict')) details=[] for r in policy['clauses']: if r['verification']=='PENDING_ORIGINAL':continue refs=[] for ref in r['sourceReferences']+r.get('supportingSourceReferences',[]): if ref.get('pdfPage'): refs.append('['+r['documentId']+' PDF第'+str(ref['pdfPage'])+'页 / 印刷第'+ref['printedPage']+'页]('+ref['file']+'#page='+str(ref['pdfPage'])+')') else: refs.append('['+ref['headingStart']+'原文]('+ref['file']+')(抽取文本字符'+str(ref['textStart'])+'至'+str(ref['textEndExclusive'])+',右端不含)') details.append('### '+str(r['sourceLine'])+' · '+r['topic']+'\n\n适用:'+r['applies']+'。\n\n所需资料:'+';'.join(r['inputs'])+'。\n\n'+ '\n'.join(str(i)+'. '+step for i,step in enumerate(r['steps'],1))+'\n\n使用边界:'+r['limits']+'\n\n原文定位:'+';'.join(refs)+'。\n\n完整条款ID:`'+r['clauseId']+'`。\n') report=f'''# 政策使用证据与主线覆盖核查 核查日期:2026-11-08。固定库代际:`{policy['generation']}`。这是一份本地只读核查交付,尚未导入线上库或发布到看板。 ## 已完成和未完成 9份PDF与库内期望SHA逐件一致,9个封面的标准号、标题和日期已看图核对。只对本次引用的相关页面作实质核验,不将全部388页说成逐页审读。GB17400、GB29921无可抽取文字层,未把空文本误判为没有正文。 25份资料中,13份有匹配原件(9 PDF、4份归档官方HTML),12份仍缺匹配原件。31条全部建成核查记录,其中7条PDF引用、5条官方HTML引用已核,19条待原件。4份HTML的原始观察时间保留为2026-11-04;本轮没有新取官方页面,没有证明今天仍然有效。 本次补充了钠与纤维声称的表注、适用对象和计量基准,并为12条已核记录逐条写了输入、方法和边界。核心信息8处在蔬菜水果章节,摘要应保留该语境。方法与研发解释分别标识,不当作法规原句;每条保留完整条款ID供Agent查询。 ## 31条核查索引 | 序 | 文件ID | 条款 | 原文核查 | 主题 | | --- | --- | --- | --- | --- | {clause_table} ## 已核条款的具体用法 {chr(10).join(details)} ## 日期差异保留 以下3份归档HTML的元数据PubDate与页面可见发布时间不同。两者均保留,不根据URL目录日期或元数据替选一个“正确日期”;不影响本次文字与原件SHA的对应核验,发布日期仍待官方澄清。 | 文件 | 元数据日期时间 | 页面可见日期 | | --- | --- | --- | {date_table} 2025版GB7718、GB28050封面均标2027-03-16实施,本轮未核后续修订和过渡安排;不只凭实施日期推导完整现行状态。 ## 主店和竞品的真实覆盖 主店京东1000084104:165件,79件有评价;746行→去无正文28行后718行→同商品主评/追评组合去重701份。85件有284条历史价格观察;41件有详情响应,其中12件有详情文字。已核全可访问评价历史商品数为0。每件商品的证据状态、价格来源日期、规格状态和详情来源SHA均见`coverage-matrix.json`。 | 门店 | 历史目录 / 当前库目录 | 评价行 | 历史价格行 | 有详情响应 / 有详情文字商品 | | --- | --- | --- | --- | --- | {stores_table} 历史目录为2026-11-04的8店64页1444件;当前库对应目录1445件,白象202/203分列,不推断新增或下架。现有库不等于全平台全品类;上述评价仅描述收录覆盖,不用于销量或市场发生率。标题宣称不冒充详情原文,详情字段顺序也不代表页面视觉卖点排序。 逐商品真实付费缺页量和金额仍未知。50项只是历史第2页候选,不能作为当前派发队列;244页/¥73.20估算不采用。 ## 榜单入口核查 复核封存目录与55份原详情证据,确认21个真实榜ID;仍只属于详情徽标。归档中可解析到部分官方活动跳转候选,但本轮未新抓榜页,榜型、周期、TopN及完整范围仍未核。完整Top100=0、Top400=0,不能生成上升或新入榜比较。 现有目录没有声明京东/天猫完整商品榜接口,这是本地能力目录的边界,不证明所有供应商都不支持。快手购物榜只声明子榜参数,未核面类范围、分页和TopN,不能替代京东/天猫目标。4项“京东/天猫×100/400”分别保留来源缺口,见`ranking-source-readiness.json`。 ## Agent使用 ```powershell py -3.14 -X utf8 -B scripts/query-industry-policy-usage.py --input policy-usage.json --keyword 钠 py -3.14 -X utf8 -B scripts/query-industry-policy-usage.py --input policy-usage.json --document-id GB17400-2015 py -3.14 -X utf8 -B scripts/query-industry-policy-usage.py --input policy-usage.json --include-pending --limit 100 ``` 查询默认只返回有原件核查的记录;待核记录必须显式包含。输出含代际、数据SHA、原文定位、实际使用步骤及未知项,不触发网络或写库。`index.html`可直接打开,支持政策搜索、核验状态筛选、逐商品范围查看与榜单ID回查。 ## 后续条件 1. 政策:补12份文件的匹配原件及相关批准/标准附件,才能关闭19条待核;3份日期差异继续保留。 2. 采集:在本次覆盖矩阵上核实际可访问范围、发前认领和预算;持续监听还需频率。已有成功响应复用、收费缺正文找旧件、归属冲突阻断分别处理。 3. 榜单:先落实真正完整的面类商品榜来源,再取首期与同口径第二期;不由单次徽标拼榜。 本轮上游调用0、付费0、研究数据库写入0、生产变更0。已扣¥46.20、未决¥0、保护¥3.80;收费保持停止。A/B/C、八店v3、线上服务和机会排序未调整。主线尚未全部完成。 ''' total_pages=sum(r.get('pdfPages',0) for r in policy['documents']) report=report.replace('全部388页',f'全部{total_pages}页') (args.prepared/'README.md').write_text(report,encoding='utf-8',newline='\n') payload=json.dumps({'policy':policy,'coverage':coverage,'rankings':ranks},ensure_ascii=False).replace('<','\\u003c') html=r'''行业数据核查 · 2026-11-08
本地核查交付 · 2026-11-08

政策使用证据与数据覆盖

查原文、看适用条件,再使用研究解释。31条款中12条已核原件,19条继续待核。商品和榜单均显示实际收录范围。

'''.replace('__PAYLOAD__',payload) (args.prepared/'index.html').write_text(html,encoding='utf-8',newline='\n') print(json.dumps({'ok':True,'clauses':31,'primaryProducts':165,'rankIds':21,'htmlBytes':len(html.encode()),'pdfPagesInOriginals':total_pages},ensure_ascii=False)) if __name__=='__main__': main()