#!/usr/bin/env node const fs = require('fs'); const os = require('os'); const path = require('path'); const { spawnSync } = require('child_process'); const root = path.resolve(__dirname, '..'); function main() { const tmp = fs.mkdtempSync(path.join(os.tmpdir(), 'tihao-round-deposition-')); const outputs = path.join(tmp, 'outputs'); const statusDir = path.join(outputs, 'optimization-status-latest'); const evidenceDir = path.join(outputs, 'evidence-index-latest'); const handoffDir = path.join(outputs, 'optimization-handoff-latest'); const proofGapDir = path.join(outputs, 'proof-gap-request-latest'); const proofGapClosureDir = path.join(outputs, 'proof-gap-closure-latest'); const feedbackLoopClosureDir = path.join(outputs, 'feedback-loop-closure-latest'); const homepageEvidenceReadinessDir = path.join(outputs, 'homepage-evidence-readiness-latest'); const intakeReadinessDir = path.join(outputs, 'intake-readiness-latest'); const longRunReadinessDir = path.join(outputs, 'long-run-readiness-latest'); const optimizationCompletionDir = path.join(outputs, 'optimization-completion-latest'); const businessProofProgressDir = path.join(outputs, 'business-proof-progress-latest'); const businessProofNextActionsDir = path.join(outputs, 'business-proof-next-actions-latest'); const businessExecutionIndexDir = path.join(outputs, 'business-execution-index-latest'); const realProofIntakeBundleDir = path.join(outputs, 'real-proof-intake-bundle-latest'); const intakeFieldChecklistDir = path.join(outputs, 'intake-field-checklist-latest'); const manualReviewLabelGuideDir = path.join(outputs, 'manual-review-label-guide-latest'); const proofGapOperatorPackDir = path.join(outputs, 'proof-gap-operator-pack-latest'); const proofGapSoftwareFormDir = path.join(outputs, 'tihao-proof-gap-software-form-latest'); const latestFormIndexDir = path.join(outputs, 'latest-form-index-latest'); const localSeedToIntakeWorklistDir = path.join(outputs, 'local-seed-to-intake-worklist-latest'); const realGapMaterialAuditDir = path.join(outputs, 'real-gap-material-audit-latest'); const realProofClosureWorkOrderDir = path.join(outputs, 'real-proof-closure-work-order-latest'); const planExecutionStatusDir = path.join(outputs, 'plan-execution-status-latest'); const outputDir = path.join(outputs, 'round-deposition-latest'); for (const dir of [statusDir, evidenceDir, handoffDir, proofGapDir, proofGapClosureDir, feedbackLoopClosureDir, homepageEvidenceReadinessDir, intakeReadinessDir, longRunReadinessDir, optimizationCompletionDir, businessProofProgressDir, businessProofNextActionsDir, businessExecutionIndexDir, realProofIntakeBundleDir, intakeFieldChecklistDir, manualReviewLabelGuideDir, proofGapOperatorPackDir, proofGapSoftwareFormDir, latestFormIndexDir, localSeedToIntakeWorklistDir, realGapMaterialAuditDir, realProofClosureWorkOrderDir, planExecutionStatusDir]) fs.mkdirSync(dir, { recursive: true }); const implementationLog = path.join(tmp, 'implementation-log.md'); const proofActionOrder = path.join(tmp, 'business-proof-action-order.md'); const videoAbPreflightEvidence = [ 'passed=true', 'mode=unknown', 'collectionMode=unknown', 'generatedBy=unknown', 'provider=ok', 'preflight.readyForVideoAb=false', 'preflight.failureCount=4', 'preflight.generatedBy=acceptance:video-ab-preflight', 'preflight.proofLevel=not_business_proof', 'preflight.canCloseProofGap=false', 'runtimeCredentialPresent=false', 'companyResolved=false', 'vocSocialProviderTokenPresent=false', 'videoAnalysisTokenPresent=false' ].join(', '); const videoAbLiveProofRequirements = [ 'proofContext.mode=live', 'proofContext.collectionMode=live', 'proofContext.generatedBy=acceptance:video-ab', 'proofContext.requiresRuntimeCredential=true', 'proofContext.requiresVocSocialProvider=true', 'proofContext.requiresVideoAnalysisProvider=true', 'videoAbPreflight.readyForVideoAb=true', 'videoAbPreflight.proofContext.requiresRuntimeCredential=true', 'videoAbPreflight.proofContext.requiresVocSocialProvider=true', 'videoAbPreflight.proofContext.requiresVideoAnalysisProvider=true', 'videoAbPreflight.company resolved for live run' ]; const discoveredHistorySource = 'outputs/optimization-pipeline-latest/history-audit/historical-dataset-audit.json'; const discoveredCustomerEffectSource = 'outputs/optimization-pipeline-latest/customer-effect-audit/customer-effect-summary.json'; const historicalDatasetConcreteRequirements = [ 'acceptance.readyForCustomerEffectProof=true', 'briefCount>=5', 'acceptance.minBriefsMet=true', 'items.length>=5' ]; const customerEffectConcreteRequirements = [ 'acceptance.overallPass=true', 'acceptance.customerSelectedRateMeasured=true', 'currentHistoryAudit.briefCount>=5' ]; const historicalDatasetConcreteEvidence = 'briefCount=1, readyForCustomerEffectProof=false'; const customerEffectConcreteEvidence = `overallPass=false, customerSelectedRate=0, referenceCustomerSelectedRate=0, manualSupplementReductionRate=1, historyAuditPath=${discoveredHistorySource}`; const videoAbLiveProofNextAction = `npm run acceptance:video-ab; missing proof: ${videoAbLiveProofRequirements.join('; ')}`; fs.writeFileSync(proofActionOrder, [ '# 提号长期优化补证操作顺序', '', '- sample、smoke、dry-run 和 provider fallback 不能作为业务证明。', '- 客户效果不可宣称,除非 customer-effect:audit 通过。', '- npm run intake:readiness', '- npm run longrun:readiness', '- npm run customer-effect:audit', '- npm run optimization:completion -- --output outputs\\optimization-completion-latest', '- optimization:completion 必须 readyForClaim=true 后才可进入长期完成判断。' ].join('\n'), 'utf8'); fs.writeFileSync(implementationLog, [ '# 提号优化实施日志', '', '## 2026-06-07 每轮沉淀样例', '', '- 命令记录:npm.cmd run optimization:status;npm.cmd run evidence:index;npm.cmd run handoff:summary;npm.cmd run proof-gap:request;npm.cmd run proof-gap:closure;npm.cmd run intake:readiness;npm.cmd run longrun:readiness。', '- 输出目录:outputs/optimization-status-latest、outputs/evidence-index-latest、outputs/optimization-handoff-latest、outputs/proof-gap-request-latest、outputs/proof-gap-closure-latest、outputs/intake-readiness-latest、outputs/long-run-readiness-latest。', '- live 标记:liveEnabled=false,本轮不把 sample 当成真实证明。', '- 严格 provider 门禁:strict provider gates 未开启真实 live,只保留验收入口。', '- 视频资源真实性:真实视频资源未到位,video A/B 仍是 ready_not_proven。', '- failureCount=0,failedGateCount=0,overallPass=true 只代表本地门禁样例。', '- 软件端重复键=0,排名连续=true。', '- 人工复核指标和客户选中率仍需 review:metrics 与 customer-effect:audit。', '- 仍未证明边界:ready_not_proven=2,blocked_by_external_data=2。', '- proof-gap 缺口:真实证明缺口请求包 unresolvedCount=5,proof-gap closure openCount=4,仍需真实历史数据、候选视频和客户选择。' ].join('\n'), 'utf8'); fs.writeFileSync(path.join(statusDir, 'optimization-status-summary.json'), JSON.stringify({ complete: false, counts: { passed: 23, ready_not_proven: 2, blocked_by_external_data: 2 }, items: [ { id: 'software-table', status: 'passed' }, { id: 'video-ab-proof', status: 'ready_not_proven' }, { id: 'customer-effect-proof', status: 'blocked_by_external_data' } ] }, null, 2), 'utf8'); fs.writeFileSync(path.join(statusDir, 'optimization-status-report.md'), '# 状态审计\n', 'utf8'); fs.writeFileSync(path.join(evidenceDir, 'evidence-index-summary.json'), JSON.stringify({ counts: { real_evidence: 1, smoke_or_local: 2, not_business_proof: 4 }, byType: { 'optimization-status': 1, 'optimization-handoff': 1, 'proof-gap-request': 1, 'proof-gap-closure': 1, 'feedback-loop-closure': 1, 'homepage-evidence-readiness': 1, 'business-execution-index': 1, 'local-seed-to-intake-worklist': 1, 'real-gap-material-audit': 1, 'real-proof-closure-work-order': 1, 'video-ab-runtime-preflight': 1 }, entries: [ { type: 'video-ab-runtime-preflight', proofLevel: 'not_business_proof', status: 'not_ready', summary: 'readyForVideoAb=false, failureCount=4, generatedBy=acceptance:video-ab-preflight', next: '补齐运行时凭证后生成 video-hit-rate-summary.json;preflight 失败不证明视频提升。' } ] }, null, 2), 'utf8'); fs.writeFileSync(path.join(evidenceDir, 'evidence-index-report.md'), '# 证据台账\n', 'utf8'); const proofGapOperatorPackFixture = { passed: true, complete: false, directCustomerProof: false, proofLevel: 'not_business_proof', openCount: 5, rowCount: 5, gapIds: ['historical-dataset', 'video-real-candidate', 'video-ab-live-proof', 'live-provider-overnight-proof', 'manual-review-and-customer-effect'], fillFileCount: 3, recheckCommandCount: 7, ownerGroupCount: 3, ownerArtifactCount: 3, evidenceRowCount: 5, nextActionCount: 5, missingProofRequirementCount: 23, files: { summary: 'outputs/proof-gap-operator-pack-latest/proof-gap-operator-pack-summary.json', report: 'outputs/proof-gap-operator-pack-latest/proof-gap-operator-pack.md', csv: 'outputs/proof-gap-operator-pack-latest/proof-gap-operator-pack.csv', byOwnerDir: 'outputs/proof-gap-operator-pack-latest/by-owner' }, ownerGroups: [ { owner: '商务', actionCount: 2, topPriority: 1, fillFiles: ['outputs/data-intake-pack-latest/history-data-template.csv', 'outputs/data-intake-pack-latest/manual-review-template.csv'], recheckCommands: ['npm run intake:readiness', 'npm run history:audit', 'npm run customer-effect:audit'], gapIds: ['historical-dataset', 'manual-review-and-customer-effect'] }, { owner: '商务/投放', actionCount: 1, topPriority: 2, fillFiles: ['outputs/video-intake-pack-latest/video-resource-template.csv'], recheckCommands: ['npm run video:resource-readiness'], gapIds: ['video-real-candidate'] }, { owner: '技术/AI', actionCount: 2, topPriority: 3, fillFiles: ['outputs/video-intake-pack-latest/video-resource-template.csv', 'outputs/data-intake-pack-latest/history-data-template.csv'], recheckCommands: ['npm run acceptance:video-ab', 'npm run longrun:readiness', 'npm run overnight:quality'], gapIds: ['video-ab-live-proof', 'live-provider-overnight-proof'] } ], ownerArtifacts: [ { owner: '商务', markdown: 'outputs/proof-gap-operator-pack-latest/by-owner/business.md', csv: 'outputs/proof-gap-operator-pack-latest/by-owner/business.csv', actionCount: 2, topPriority: 1, gapIds: ['historical-dataset', 'manual-review-and-customer-effect'], evidenceRowCount: 2, nextActionCount: 2 }, { owner: '商务/投放', markdown: 'outputs/proof-gap-operator-pack-latest/by-owner/business-media.md', csv: 'outputs/proof-gap-operator-pack-latest/by-owner/business-media.csv', actionCount: 1, topPriority: 2, gapIds: ['video-real-candidate'], evidenceRowCount: 1, nextActionCount: 1 }, { owner: '技术/AI', markdown: 'outputs/proof-gap-operator-pack-latest/by-owner/tech-ai.md', csv: 'outputs/proof-gap-operator-pack-latest/by-owner/tech-ai.csv', actionCount: 2, topPriority: 3, gapIds: ['video-ab-live-proof', 'live-provider-overnight-proof'], evidenceRowCount: 2, nextActionCount: 2 } ], rows: [ { gapId: 'historical-dataset', owner: '商务', title: '真实历史 Brief 数据集', priority: 1, fillFiles: ['outputs/data-intake-pack-latest/history-data-template.csv'], recheckCommands: ['npm run intake:readiness', 'npm run history:audit'], evidence: historicalDatasetConcreteEvidence, nextAction: '补齐真实历史 Brief 后重跑 history:audit', missingProofRequirements: historicalDatasetConcreteRequirements, acceptance: 'historyReady=true', boundary: '补齐历史材料不证明客户效果。' }, { gapId: 'video-real-candidate', owner: '商务/投放', title: '真实候选视频资源', priority: 2, fillFiles: ['outputs/video-intake-pack-latest/video-resource-template.csv'], recheckCommands: ['npm run video:resource-readiness'], evidence: 'realCandidate=0, failureCount=1', nextAction: '补真实候选视频后重跑 video:resource-readiness', missingProofRequirements: ['acceptance.readyForVideoAbPreflight=true', 'failureCount=0', 'counts.realCandidateRows>=1'], acceptance: 'readyForVideoAbPreflight=true', boundary: '补齐视频资源只证明 A/B 前置资源齐备,不证明客户效果。' }, { gapId: 'video-ab-live-proof', owner: '技术/AI', title: '真实视频 A/B live proof', priority: 3, fillFiles: ['outputs/video-intake-pack-latest/video-resource-template.csv'], recheckCommands: ['npm run acceptance:video-ab'], evidence: 'mode=unknown, collectionMode=unknown', nextAction: '真实 provider 与真实视频到位后重跑 acceptance:video-ab', missingProofRequirements: ['proofContext.mode=live', 'proofContext.collectionMode=live', 'proofContext.generatedBy=acceptance:video-ab', 'proofContext.requiresRuntimeCredential=true', 'proofContext.requiresVocSocialProvider=true', 'proofContext.requiresVideoAnalysisProvider=true'], acceptance: 'proofContext.mode=live', boundary: 'sample 或接口 200 不证明视频分析提升提号率。' }, { gapId: 'live-provider-overnight-proof', owner: '技术/AI', title: '真实 live/provider 长跑证明', priority: 4, fillFiles: ['outputs/data-intake-pack-latest/history-data-template.csv', 'outputs/video-intake-pack-latest/video-resource-template.csv'], recheckCommands: ['npm run longrun:readiness', 'npm run overnight:quality'], evidence: 'liveEnabled=false, overallPass=false', nextAction: 'longrun ready 后运行 overnight:quality', missingProofRequirements: ['manifest.liveEnabled=true', 'acceptance.overallPass=true'], acceptance: 'liveEnabled=true', boundary: '长跑通过只证明 provider/live 流程稳定,不单独证明客户效果。' }, { gapId: 'manual-review-and-customer-effect', owner: '商务', title: '商务复核和客户效果证明', priority: 5, fillFiles: ['outputs/data-intake-pack-latest/manual-review-template.csv'], recheckCommands: ['npm run review:metrics', 'npm run customer-effect:audit'], evidence: customerEffectConcreteEvidence, nextAction: '补客户选择和人工补号量后重跑 customer-effect:audit', missingProofRequirements: customerEffectConcreteRequirements, acceptance: 'customer-effect:audit overallPass=true', boundary: '缺客户选择、历史基线或本轮人工补号量时,不得宣称客户效果。' } ] }; Object.assign(proofGapOperatorPackFixture.rows.find(item => item.gapId === 'video-ab-live-proof'), { status: 'open', evidence: videoAbPreflightEvidence, nextAction: videoAbLiveProofNextAction, missingProofRequirements: videoAbLiveProofRequirements }); const localSeedToIntakeWorklistFixture = { proofLevel: 'not_business_proof', materialType: 'seed_to_intake_worklist', directCustomerProof: false, canCloseProofGap: false, complete: false, counts: { historyDraftRows: 1, referenceSeedRows: 4, candidateSeedRows: 12, videoWorklistRows: 5, videoCandidateNeedsResourceRows: 3 }, targetFiles: [ 'outputs/data-intake-pack-latest/history-data-template.csv', 'outputs/video-intake-pack-latest/video-resource-template.csv', 'outputs/data-intake-pack-latest/manual-review-template.csv' ], missingProofRequirements: [ '至少 5 个真实历史 Brief', '真实候选视频 URL', '客户最终选中/拒绝记录' ], nextActions: [ { owner: '商务', title: '把 history-intake-draft.csv 扩成真实 Brief', action: '补齐真实历史 Brief 和客户选择。', boundary: '补表草稿不证明客户效果' } ] }; const localSeedToIntakeWorklistIndexedFixture = { ...localSeedToIntakeWorklistFixture, title: '本地种子转 intake 补表 worklist', usage: '用于把本地种子转成可转写补表草稿,不写入正式 intake 模板,不等同于客户效果证明。', exists: true, markdown: 'outputs/local-seed-to-intake-worklist-latest/local-seed-to-intake-worklist.md', csv: 'outputs/local-seed-to-intake-worklist-latest/local-seed-to-intake-worklist.csv', summary: 'outputs/local-seed-to-intake-worklist-latest/local-seed-to-intake-worklist-summary.json', historyDraft: 'outputs/local-seed-to-intake-worklist-latest/history-intake-draft.csv', videoWorklist: 'outputs/local-seed-to-intake-worklist-latest/video-resource-worklist.csv', candidateWorklist: 'outputs/local-seed-to-intake-worklist-latest/candidate-seed-worklist.csv', historyDraftRows: 1, referenceSeedRows: 4, candidateSeedRows: 12, videoWorklistRows: 5, videoCandidateNeedsResourceRows: 3, missingProofRequirementCount: 3, nextActionCount: 1 }; const realProofClosureWorkOrderOwnerArtifacts = [ { owner: '商务', workOrderCount: 8, topPriority: 1, markdown: 'outputs/real-proof-closure-work-order-latest/by-owner/business.md', csv: 'outputs/real-proof-closure-work-order-latest/by-owner/business.csv', targetFiles: ['outputs/data-intake-pack-latest/history-data-template.csv', 'outputs/data-intake-pack-latest/manual-review-template.csv'], gapIds: ['historical-dataset', 'manual-review-and-customer-effect'] }, { owner: '商务/投放', workOrderCount: 5, topPriority: 20, markdown: 'outputs/real-proof-closure-work-order-latest/by-owner/business-media.md', csv: 'outputs/real-proof-closure-work-order-latest/by-owner/business-media.csv', targetFiles: ['outputs/video-intake-pack-latest/video-resource-template.csv'], gapIds: ['video-real-candidate'] }, { owner: '技术/AI', workOrderCount: 6, topPriority: 40, markdown: 'outputs/real-proof-closure-work-order-latest/by-owner/tech-ai.md', csv: 'outputs/real-proof-closure-work-order-latest/by-owner/tech-ai.csv', targetFiles: ['outputs/proof-gap-closure-latest/proof-gap-closure-summary.json', '/aggregate-summary.json'], gapIds: ['video-ab-live-proof', 'live-provider-overnight-proof', 'optimization-pipeline'] } ]; const realProofClosureWorkOrders = [ { id: 'intake-history-min-briefs', owner: '商务', targetFile: 'outputs/data-intake-pack-latest/history-data-template.csv', targetFields: ['brief编号', '客户原始Brief'], rowSelector: '新增至少 4 行真实历史 Brief。', requiredAction: '补 5-10 个真实历史 Brief。', acceptanceCommand: 'npm run intake:readiness -- --data-pack outputs\\data-intake-pack-latest --video-pack outputs\\video-intake-pack-latest --output outputs\\intake-readiness-latest', acceptance: 'historyReady=true。', requiresHumanRealMaterial: true, directCustomerProof: false, canCloseProofGap: false, proofLevel: 'not_business_proof' }, { id: 'intake-review-customer-decision', owner: '商务', targetFile: 'outputs/data-intake-pack-latest/manual-review-template.csv', targetFields: ['客户选择', '反馈原因', '本轮人工补号量'], rowSelector: 'manual-review-template.csv 至少一批真实候选行。', requiredAction: '补客户最终选中/拒绝、负样本归因、反馈原因和本轮人工补号量。', acceptanceCommand: 'npm run customer-effect:audit -- --review-csv <已标注CSV> --history-audit --current-manual-supplement-count <本轮人工补号量> --output <客户效果输出目录> --strict', acceptance: 'customer-effect:audit overallPass=true。', requiresHumanRealMaterial: true, directCustomerProof: false, canCloseProofGap: false, proofLevel: 'not_business_proof' }, { id: 'video-real-candidate', owner: '商务/投放', targetFile: 'outputs/video-intake-pack-latest/video-resource-template.csv', targetFields: ['资源角色', '是否真实资源', '视频链接'], rowSelector: '新增或更新至少 1 行资源角色=候选视频、是否真实资源=是。', requiredAction: '为候选账号补真实视频 URL 和至少一种封面/ASR/帧图/正文证据。', acceptanceCommand: 'npm run video:resource-readiness -- --input outputs\\video-intake-pack-latest\\video-resource-template.csv --output outputs\\video-resource-readiness-latest --strict', acceptance: 'readyForVideoAbPreflight=true、realCandidateRows>=1。', requiresHumanRealMaterial: true, directCustomerProof: false, canCloseProofGap: false, proofLevel: 'not_business_proof' }, { id: 'gap-video-ab-live-proof', owner: '技术/AI', targetFile: 'outputs/video-intake-pack-latest/video-resource-template.csv', targetFields: ['proofContext.mode', 'proofContext.collectionMode'], rowSelector: '真实视频 A/B 输出目录。', requiredAction: '真实视频资源和真实 provider 就绪后运行 acceptance:video-ab。', acceptanceCommand: 'npm run acceptance:video-ab', acceptance: 'proofContext.mode=live、collectionMode=live。', requiresHumanRealMaterial: true, directCustomerProof: false, canCloseProofGap: false, proofLevel: 'not_business_proof' }, { id: 'completion-longrun-readiness', owner: '技术/AI', targetFile: '/aggregate-summary.json', targetFields: ['manifest.liveEnabled', 'acceptance.overallPass'], rowSelector: '真实 live/provider overnight aggregate。', requiredAction: 'longrun:readiness ready=true 后再跑真实 provider overnight:quality。', acceptanceCommand: 'npm run longrun:readiness;真实 provider 就绪后运行 npm run overnight:quality', acceptance: 'liveEnabled=true、overallPass=true。', requiresHumanRealMaterial: true, directCustomerProof: false, canCloseProofGap: false, proofLevel: 'not_business_proof' } ]; Object.assign(realProofClosureWorkOrders.find(item => item.id === 'gap-video-ab-live-proof'), { gapId: 'video-ab-live-proof', source: 'proof-gap-closure', currentEvidence: videoAbPreflightEvidence, missingProofRequirements: videoAbLiveProofRequirements }); const realProofClosureWorkOrderFixture = { passed: true, complete: false, proofLevel: 'not_business_proof', materialType: 'real_proof_closure_work_order', directCustomerProof: false, canCloseProofGap: false, requiresHumanRealMaterial: true, workOrderCount: 19, ownerGroupCount: 3, seedSuggestionCount: 13, sourceState: { intakeOverallReady: false, intakeFailureCount: 9, videoReadyForAbPreflight: false, videoFailureCount: 1, realCandidateRows: 0, proofGapComplete: false, proofGapOpenCount: 5, optimizationReadyForClaim: false }, workOrders: realProofClosureWorkOrders, ownerArtifacts: realProofClosureWorkOrderOwnerArtifacts }; const realProofClosureWorkOrderIndexedFixture = { ...realProofClosureWorkOrderFixture, title: '真实证明闭环工单', usage: '用于把未关闭项拆成负责人、目标模板、字段、行范围、种子线索和复验命令;不写正式模板,不等同于客户效果证明。', exists: true, markdown: 'outputs/real-proof-closure-work-order-latest/real-proof-closure-work-order.md', csv: 'outputs/real-proof-closure-work-order-latest/real-proof-closure-work-order.csv', summary: 'outputs/real-proof-closure-work-order-latest/real-proof-closure-work-order-summary.json', proofGapOpenCount: 5, intakeFailureCount: 9, videoFailureCount: 1, realCandidateRows: 0 }; const realGapMaterialAuditFixture = { generatedAt: new Date().toISOString(), materialType: 'three_real_gap_material_audit', proofLevel: 'not_business_proof', directCustomerProof: false, canCloseProofGap: false, complete: false, gapCount: 3, materialFoundCount: 3, openGapCount: 3, gaps: [ { gapId: 'historical-dataset', projectMaterialFound: true, canCloseNow: false }, { gapId: 'video-ab-live-proof', projectMaterialFound: true, canCloseNow: false }, { gapId: 'manual-review-and-customer-effect', projectMaterialFound: true, canCloseNow: false } ], markdown: 'outputs/real-gap-material-audit-latest/real-gap-material-audit.md', csv: 'outputs/real-gap-material-audit-latest/real-gap-material-audit.csv', summary: 'outputs/real-gap-material-audit-latest/real-gap-material-audit-summary.json' }; const realGapMaterialAuditIndexedFixture = { title: '三缺口材料审计', usage: '用于确认三个真实缺口已有项目材料入口;不关闭 proof-gap,不证明提号效果。', exists: true, ...realGapMaterialAuditFixture }; fs.writeFileSync(path.join(localSeedToIntakeWorklistDir, 'local-seed-to-intake-worklist-summary.json'), JSON.stringify(localSeedToIntakeWorklistFixture, null, 2), 'utf8'); fs.writeFileSync(path.join(realGapMaterialAuditDir, 'real-gap-material-audit-summary.json'), JSON.stringify(realGapMaterialAuditFixture, null, 2), 'utf8'); fs.writeFileSync(path.join(realGapMaterialAuditDir, 'real-gap-material-audit.md'), '# 三缺口材料审计\n\nmaterialFoundCount=3\ncanCloseProofGap=false\n', 'utf8'); fs.writeFileSync(path.join(realGapMaterialAuditDir, 'real-gap-material-audit.csv'), 'gapId,projectMaterialFound,canCloseNow\nhistorical-dataset,true,false\nvideo-ab-live-proof,true,false\nmanual-review-and-customer-effect,true,false\n', 'utf8'); fs.writeFileSync(path.join(realProofClosureWorkOrderDir, 'real-proof-closure-work-order-summary.json'), JSON.stringify(realProofClosureWorkOrderFixture, null, 2), 'utf8'); fs.writeFileSync(path.join(handoffDir, 'optimization-handoff-summary.json'), JSON.stringify({ complete: false, readyCapabilities: Array.from({ length: 23 }, (_, index) => ({ id: `cap-${index}` })), readyNotProven: [{ id: 'video-ab-proof' }], externalBlockers: [{ id: 'customer-effect-proof' }], nextCommands: [ { command: 'npm run history:from-csv' }, { command: 'npm run history:audit' }, { command: 'npm run review:metrics' }, { command: 'npm run customer-effect:audit' }, { command: 'npm run proof-gap:request' }, { command: 'npm run proof-gap:closure' }, { command: 'npm run longrun:readiness -- --mode full-matrix' }, { command: 'npm run latest-form:index' }, { command: 'npm run evidence:index' } ], supportDocs: [ { doc: 'docs/tihao-experience-optimization-plan.zh-CN.md' }, { doc: 'docs/business-proof-action-order.zh-CN.md' } ], localSeedToIntakeWorklist: localSeedToIntakeWorklistIndexedFixture, realGapMaterialAudit: realGapMaterialAuditIndexedFixture, realProofClosureWorkOrder: realProofClosureWorkOrderIndexedFixture, businessProofProgress: { dir: 'outputs/business-proof-progress-latest', summary: 'outputs/business-proof-progress-latest/business-proof-progress-summary.json', report: 'outputs/business-proof-progress-latest/business-proof-progress-report.md', complete: false, counts: { pass: 4, fail: 2, pending: 2, blocked_by_external_data: 7 }, operatorPackOwnerArtifactCount: 3, operatorPackOwnerArtifacts: proofGapOperatorPackFixture.ownerArtifacts, proofGapOperatorPackOwnerArtifactCount: 3, businessExecutionOperatorPackOwnerArtifactCount: 3, businessExecutionOperatorPackOwnerArtifactRowCount: 3 }, latestFormIndex: { summary: 'outputs/latest-form-index-latest/latest-form-index-summary.json', report: 'outputs/latest-form-index-latest/latest-form-index.md', passed: true, primaryFormCsv: 'outputs/tihao-proof-gap-software-form-latest/tihao-proof-gap-software-form.csv', clientListCsv: 'outputs/software-client-latest/software-client-list.final.csv', complete: false, actionCount: 5, proofOpenCount: 5, ownerGroupCount: 3, ownerArtifactCount: 3, sourceState: { progressComplete: false, proofGapOpenCount: 5 }, topActions: [ { id: 'step-03', priority: 1, owner: '商务', title: '填真实历史 Brief', status: 'blocked_by_external_data', command: '填写 outputs\\data-intake-pack-latest\\history-data-template.csv', acceptance: 'historyReady=true' }, { id: 'step-04', priority: 2, owner: '商务/投放', title: '填真实视频资源', status: 'blocked_by_external_data', command: '填写 outputs\\video-intake-pack-latest\\video-resource-template.csv', acceptance: 'videoReady=true' }, { id: 'step-12', priority: 4, owner: '商务', title: '人工复核标注', status: 'blocked_by_external_data', command: '填写 outputs\\data-intake-pack-latest\\manual-review-template.csv', acceptance: '客户选择齐全' }, { id: 'gap-video-ab-live-proof', priority: 24, owner: '技术/AI', title: '真实视频 A/B 验收', status: 'open', command: 'npm run acceptance:video-ab', acceptance: '真实 provider 下通过' }, { id: 'gap-live-provider-overnight-proof', priority: 25, owner: '技术/AI', title: '真实 live/provider 长跑证明', status: 'open', command: 'npm run longrun:readiness;真实 provider 就绪后运行 npm run overnight:quality', acceptance: 'liveEnabled=true' } ], businessExecutionIndex: { markdown: 'outputs/business-execution-index-latest/business-execution-index.md', csv: 'outputs/business-execution-index-latest/business-execution-index.csv', summary: 'outputs/business-execution-index-latest/business-execution-index-summary.json', directCustomerProof: false, rowCount: 15, operatorPackOwnerArtifactCount: 3, operatorPackOwnerArtifacts: proofGapOperatorPackFixture.ownerArtifacts, fieldOwnerRowCount: 1, recheckCommandRowCount: 1 }, planExecutionStatus: { markdown: 'outputs/plan-execution-status-latest/plan-execution-status.md', csv: 'outputs/plan-execution-status-latest/plan-execution-status.csv', summary: 'outputs/plan-execution-status-latest/plan-execution-status-summary.json', passed: true, complete: false, directCustomerProof: false, rowCount: 8, proofOpenCount: 5, operatorPackOwnerArtifactCount: 3, operatorPackOwnerArtifacts: proofGapOperatorPackFixture.ownerArtifacts, businessExecutionOperatorPackOwnerArtifactCount: 3, businessExecutionOperatorPackOwnerArtifactRowCount: 3 }, proofGapOperatorPack: { ...proofGapOperatorPackFixture, markdown: 'outputs/proof-gap-operator-pack-latest/proof-gap-operator-pack.md', csv: 'outputs/proof-gap-operator-pack-latest/proof-gap-operator-pack.csv', summary: 'outputs/proof-gap-operator-pack-latest/proof-gap-operator-pack-summary.json' }, longRunReadiness: { report: 'outputs/long-run-readiness-latest/long-run-readiness-report.md', summary: 'outputs/long-run-readiness-latest/long-run-readiness-summary.json', mode: 'full-matrix', ready: false, directCustomerProof: false, proofLevel: 'not_business_proof', passCount: 1, failCount: 5, warnCount: 0 }, localSeedToIntakeWorklist: localSeedToIntakeWorklistIndexedFixture, realGapMaterialAudit: realGapMaterialAuditIndexedFixture, realProofClosureWorkOrder: realProofClosureWorkOrderIndexedFixture, intakeFieldChecklist: { markdown: 'outputs/intake-field-checklist-latest/intake-field-checklist.md', csv: 'outputs/intake-field-checklist-latest/intake-field-checklist.csv', ownerGroups: [ { owner: '商务', section: 'history', itemCount: 2, files: ['outputs/data-intake-pack-latest/history-data-template.csv'], nextAction: '补真实历史 Brief', acceptance: 'historyReady=true', boundary: '补齐材料,不证明客户效果' }, { owner: '商务/投放', section: 'video', itemCount: 2, files: ['outputs/video-intake-pack-latest/video-resource-template.csv'], nextAction: '补真实视频 URL', acceptance: 'videoReady=true', boundary: '补齐材料,不证明客户效果' } ], recheckCommands: [ { stage: '真实材料预审', owner: '技术/AI', command: 'npm run intake:readiness -- --data-pack outputs\\data-intake-pack-latest --video-pack outputs\\video-intake-pack-latest --output outputs\\intake-readiness-latest', acceptance: 'overallReady=true', boundary: '预审通过不证明客户效果' }, { stage: '刷新本轮交接', owner: '技术/AI', command: 'npm run round:refresh -- --output-root outputs --strict', acceptance: 'round-deposition.passed=true', boundary: '刷新交接不证明业务效果' }, { stage: '客户效果审计', owner: '技术/AI', command: 'npm run customer-effect:audit -- --review-csv <已标注CSV> --history-audit --current-manual-supplement-count <本轮人工补号量> --output <客户效果输出目录> --strict', acceptance: 'overallPass=true', boundary: '缺客户选择不得宣称效果' }, { stage: '视频 A/B 验收', owner: '技术/AI', command: 'npm run acceptance:video-ab', acceptance: '真实 provider 下通过', boundary: 'sample 不证明视频提升提号率' } ] }, repairActions: { dataIntake: { csv: 'outputs/intake-readiness-latest/intake-readiness-repair-actions.csv', repairActionCount: 9 }, videoResource: { csv: 'outputs/video-resource-readiness-latest/video-resource-repair-actions.csv', repairActionCount: 1 }, homepageEvidence: { csv: 'outputs/homepage-evidence-readiness-latest/homepage-evidence-repair-actions.csv', repairActionCount: 2 } }, ownerArtifacts: [ { owner: '商务', repairArtifacts: [ { csv: 'outputs/intake-readiness-latest/intake-readiness-repair-actions.csv', actionCount: 6 } ] }, { owner: '商务/投放', repairArtifacts: [ { csv: 'outputs/video-resource-readiness-latest/video-resource-repair-actions.csv', actionCount: 1 }, { csv: 'outputs/homepage-evidence-readiness-latest/homepage-evidence-repair-actions.csv', actionCount: 1 } ] }, { owner: 'tech-ai', repairArtifacts: [ { csv: 'outputs/homepage-evidence-readiness-latest/homepage-evidence-repair-actions.csv', actionCount: 1 } ] } ], manualReviewLabelGuide: { markdown: 'outputs/manual-review-label-guide-latest/manual-review-label-guide.md', csv: 'outputs/manual-review-label-guide-latest/manual-review-label-guide.csv', summary: 'outputs/manual-review-label-guide-latest/manual-review-label-guide-summary.json', passed: true, directCustomerProof: false, proofLevel: 'smoke_or_local', labelCount: 10, positiveLabelCount: 2, negativeLabelCount: 6, attributionTypeCount: 8, negativeLabelsRequireAttribution: true }, businessFillGuide: { title: '商务填表执行视图', directCustomerProof: false, proofLevel: 'smoke_or_local', rowCount: 2, rows: [ { order: 1, owner: '鍟嗗姟', section: 'history', file: 'outputs/data-intake-pack-latest/history-data-template.csv', firstItemIds: ['FIELD-001'], issueCount: 2, fillAction: '琛ョ湡瀹炲巻鍙?Brief', recheckCommand: 'npm run intake:readiness -- --data-pack outputs\\data-intake-pack-latest --video-pack outputs\\video-intake-pack-latest --output outputs\\intake-readiness-latest', acceptance: 'historyReady=true', boundary: '补齐材料,不证明客户效果' }, { order: 2, owner: '鍟嗗姟/鎶曟斁', section: 'video', file: 'outputs/video-intake-pack-latest/video-resource-template.csv', firstItemIds: ['FIELD-003'], issueCount: 2, fillAction: '琛ョ湡瀹炶棰?URL', recheckCommand: 'npm run video:resource-readiness -- --input outputs\\video-intake-pack-latest\\video-resource-template.csv --output outputs\\video-resource-readiness-latest --strict', acceptance: 'videoReady=true', boundary: '补齐材料,不证明客户效果' } ], guardrail: '本视图只帮助商务按表补齐真实材料,不代表客户效果已达标。' } }, planExecutionStatus: { markdown: 'outputs/plan-execution-status-latest/plan-execution-status.md', csv: 'outputs/plan-execution-status-latest/plan-execution-status.csv', summary: 'outputs/plan-execution-status-latest/plan-execution-status-summary.json', passed: true, complete: false, directCustomerProof: false, rowCount: 8, proofOpenCount: 5, operatorPackOwnerArtifactCount: 3, operatorPackOwnerArtifacts: proofGapOperatorPackFixture.ownerArtifacts, businessExecutionOperatorPackOwnerArtifactCount: 3, businessExecutionOperatorPackOwnerArtifactRowCount: 3 }, longRunReadiness: { report: 'outputs/long-run-readiness-latest/long-run-readiness-report.md', summary: 'outputs/long-run-readiness-latest/long-run-readiness-summary.json', mode: 'full-matrix', ready: false, directCustomerProof: false, proofLevel: 'not_business_proof', passCount: 1, failCount: 5, warnCount: 0 }, businessProofNextActions: { complete: false, actionCount: 5, ownerGroupCount: 3, ownerArtifactCount: 3, sourceState: { progressComplete: false, proofGapOpenCount: 5 }, topActions: [ { id: 'step-03', priority: 1, owner: '商务', title: '填真实历史 Brief', status: 'blocked_by_external_data', command: '填写 outputs\\data-intake-pack-latest\\history-data-template.csv', acceptance: 'historyReady=true' }, { id: 'step-04', priority: 2, owner: '商务/投放', title: '填真实视频资源', status: 'blocked_by_external_data', command: '填写 outputs\\video-intake-pack-latest\\video-resource-template.csv', acceptance: 'videoReady=true' }, { id: 'step-12', priority: 4, owner: '商务', title: '人工复核标注', status: 'blocked_by_external_data', command: '填写 outputs\\data-intake-pack-latest\\manual-review-template.csv', acceptance: '客户选择齐全' }, { id: 'gap-video-ab-live-proof', priority: 24, owner: '技术/AI', title: '真实视频 A/B 验收', status: 'open', command: 'npm run acceptance:video-ab', acceptance: '真实 provider 下通过' }, { id: 'gap-live-provider-overnight-proof', priority: 25, owner: '技术/AI', title: '真实 live/provider 长跑证明', status: 'open', command: 'npm run longrun:readiness;真实 provider 就绪后运行 npm run overnight:quality', acceptance: 'liveEnabled=true' } ], ownerArtifacts: [ { owner: '商务', repairArtifacts: [ { csv: 'outputs/intake-readiness-latest/intake-readiness-repair-actions.csv', actionCount: 6 } ] }, { owner: '商务/投放', repairArtifacts: [ { csv: 'outputs/video-resource-readiness-latest/video-resource-repair-actions.csv', actionCount: 1 }, { csv: 'outputs/homepage-evidence-readiness-latest/homepage-evidence-repair-actions.csv', actionCount: 1 } ] }, { owner: '技术/AI', repairArtifacts: [ { csv: 'outputs/homepage-evidence-readiness-latest/homepage-evidence-repair-actions.csv', actionCount: 1 } ] } ] }, manualReviewLabelGuide: { markdown: 'outputs/manual-review-label-guide-latest/manual-review-label-guide.md', csv: 'outputs/manual-review-label-guide-latest/manual-review-label-guide.csv', summary: 'outputs/manual-review-label-guide-latest/manual-review-label-guide-summary.json', passed: true, directCustomerProof: false, proofLevel: 'smoke_or_local', labelCount: 10, positiveLabelCount: 2, negativeLabelCount: 6, attributionTypeCount: 8, negativeLabelsRequireAttribution: true }, manualReviewLabelGuide: { markdown: 'outputs/manual-review-label-guide-latest/manual-review-label-guide.md', csv: 'outputs/manual-review-label-guide-latest/manual-review-label-guide.csv', summary: 'outputs/manual-review-label-guide-latest/manual-review-label-guide-summary.json', passed: true, directCustomerProof: false, proofLevel: 'smoke_or_local', labelCount: 10, positiveLabelCount: 2, negativeLabelCount: 6, attributionTypeCount: 8, negativeLabelsRequireAttribution: true }, businessFillGuide: { title: '商务填表执行视图', directCustomerProof: false, proofLevel: 'smoke_or_local', rowCount: 2, rows: [ { order: 1, owner: '鍟嗗姟', section: 'history', file: 'outputs/data-intake-pack-latest/history-data-template.csv', firstItemIds: ['FIELD-001'], issueCount: 2, fillAction: '琛ョ湡瀹炲巻鍙?Brief', recheckCommand: 'npm run intake:readiness -- --data-pack outputs\\data-intake-pack-latest --video-pack outputs\\video-intake-pack-latest --output outputs\\intake-readiness-latest', acceptance: 'historyReady=true', boundary: '补齐材料,不证明客户效果' }, { order: 2, owner: '鍟嗗姟/鎶曟斁', section: 'video', file: 'outputs/video-intake-pack-latest/video-resource-template.csv', firstItemIds: ['FIELD-003'], issueCount: 2, fillAction: '琛ョ湡瀹炶棰?URL', recheckCommand: 'npm run acceptance:video-ab', acceptance: 'videoReady=true', boundary: '补齐材料,不证明客户效果' } ], guardrail: '本视图只帮助商务按表补齐真实材料,不代表客户效果已达标。' }, proofGapOperatorPack: { ...proofGapOperatorPackFixture, markdown: 'outputs/proof-gap-operator-pack-latest/proof-gap-operator-pack.md', csv: 'outputs/proof-gap-operator-pack-latest/proof-gap-operator-pack.csv', summary: 'outputs/proof-gap-operator-pack-latest/proof-gap-operator-pack-summary.json' }, businessExecutionIndex: { summary: 'outputs/business-execution-index-latest/business-execution-index-summary.json', report: 'outputs/business-execution-index-latest/business-execution-index.md', csv: 'outputs/business-execution-index-latest/business-execution-index.csv', passed: true, rowCount: 15, repairRowCount: 2, operatorPackOwnerArtifactRowCount: 3, operatorPackOwnerArtifactCount: 3, operatorPackOwnerArtifacts: proofGapOperatorPackFixture.ownerArtifacts, fieldOwnerRowCount: 1, recheckCommandRowCount: 1, proofOpenCount: 5, directCustomerProof: false, longRunReadiness: { report: 'outputs/long-run-readiness-latest/long-run-readiness-report.md', summary: 'outputs/long-run-readiness-latest/long-run-readiness-summary.json', status: 'blocked', actionCount: 5, ready: false, failCount: 5, expectedArtifact: 'outputs/long-run-readiness-latest/long-run-readiness-summary.json', acceptance: 'ready=false,failCount=5', boundary: '长跑前置门禁只判断启动条件,不证明客户效果;ready=false 时不能启动或宣称 full-matrix/live 长跑完成。', directCustomerProof: false, proofLevel: 'not_business_proof' }, optimizationCompletion: { report: 'outputs/optimization-completion-latest/optimization-completion-report.md', summary: 'outputs/optimization-completion-latest/optimization-completion-summary.json', status: 'blocked', actionCount: 3, complete: false, readyForClaim: false, proofGapOpenCount: 5, blockingReasonCount: 3, expectedArtifact: 'outputs/optimization-completion-latest/optimization-completion-summary.json', acceptance: 'complete=false,readyForClaim=false,proofGapOpenCount=5,blockingReasons=3', boundary: '优化完成度审计只判断能否进入完成声明,不证明客户效果;readyForClaim=false 时不得宣称提号率提升、客户效果达标或人工补号量下降。', directCustomerProof: false, proofLevel: 'not_business_proof' } }, optimizationCompletion: { report: 'outputs/optimization-completion-latest/optimization-completion-report.md', summary: 'outputs/optimization-completion-latest/optimization-completion-summary.json', complete: false, readyForClaim: false, proofGapOpenCount: 5, blockingReasonCount: 3, directCustomerProof: false, proofLevel: 'not_business_proof', canClaim: { tihaoRateImproved: false, customerEffectAchieved: false, manualSupplementReduced: false }, nextRequiredCommandCount: 5 }, intakeFieldChecklist: { summary: 'outputs/intake-field-checklist-latest/intake-field-checklist-summary.json', report: 'outputs/intake-field-checklist-latest/intake-field-checklist.md', csv: 'outputs/intake-field-checklist-latest/intake-field-checklist.csv', passed: true, itemCount: 4, missingRequiredCount: 2, placeholderCount: 2, ownerGroups: [ { owner: '商务', section: 'history', itemCount: 2, missingRequiredCount: 1, placeholderCount: 1, files: ['outputs/data-intake-pack-latest/history-data-template.csv'], nextAction: '补真实历史 Brief', acceptance: 'historyReady=true', boundary: '补齐材料,不证明客户效果' }, { owner: '商务/投放', section: 'video', itemCount: 2, missingRequiredCount: 1, placeholderCount: 1, files: ['outputs/video-intake-pack-latest/video-resource-template.csv'], nextAction: '补真实视频 URL', acceptance: 'videoReady=true', boundary: '补齐材料,不证明客户效果' } ], manualReviewLabelGuide: { markdown: 'outputs/manual-review-label-guide-latest/manual-review-label-guide.md', csv: 'outputs/manual-review-label-guide-latest/manual-review-label-guide.csv', summary: 'outputs/manual-review-label-guide-latest/manual-review-label-guide-summary.json', passed: true, directCustomerProof: false, proofLevel: 'smoke_or_local', labelCount: 10, positiveLabelCount: 2, negativeLabelCount: 6, attributionTypeCount: 8, negativeLabelsRequireAttribution: true }, recheckCommands: [ { stage: '真实材料预审', owner: '技术/AI', command: 'npm run intake:readiness -- --data-pack outputs\\data-intake-pack-latest --video-pack outputs\\video-intake-pack-latest --output outputs\\intake-readiness-latest', acceptance: 'overallReady=true', boundary: '预审通过不证明客户效果' }, { stage: '刷新本轮交接', owner: '技术/AI', command: 'npm run round:refresh -- --output-root outputs --strict', acceptance: 'round-deposition.passed=true', boundary: '刷新交接不证明业务效果' }, { stage: '客户效果审计', owner: '技术/AI', command: 'npm run customer-effect:audit -- --review-csv <已标注CSV> --history-audit --current-manual-supplement-count <本轮人工补号量> --output <客户效果输出目录> --strict', acceptance: 'overallPass=true', boundary: '缺客户选择不得宣称效果' }, { stage: '视频 A/B 验收', owner: '技术/AI', command: 'npm run acceptance:video-ab', acceptance: '真实 provider 下通过', boundary: 'sample 不证明视频提升提号率' } ], directCustomerProof: false }, proofGapClosure: { summary: 'outputs/proof-gap-closure-latest/proof-gap-closure-summary.json', report: 'outputs/proof-gap-closure-latest/proof-gap-closure-report.md', sourceFiles: { history: discoveredHistorySource, customerEffect: discoveredCustomerEffectSource }, complete: false, intakeReady: false, closedCount: 0, openCount: 5, businessClosedCount: 0, businessOpenCount: 5, businessGapCount: 5, totalRows: 6, precheckRowCount: 1, precheckClosedCount: 0, precheckOpenCount: 1, countSemantics: { openCount: 'business_gap_open_count_excludes_precheck_rows', closedCount: 'business_gap_closed_count_excludes_precheck_rows', businessOpenCount: 'same_as_openCount', businessClosedCount: 'same_as_closedCount', precheckOpenCount: 'precheck_rows_reported_separately' }, rows: [ { id: 'intake-readiness', status: 'open', missingProofRequirements: ['acceptance.overallReady=true', 'failureCount=0'] }, { id: 'historical-dataset', status: 'open', evidence: historicalDatasetConcreteEvidence, missingProofRequirements: historicalDatasetConcreteRequirements }, { id: 'video-real-candidate', status: 'open', missingProofRequirements: ['acceptance.readyForVideoAbPreflight=true', 'failureCount=0', 'counts.realCandidateRows>=1'] }, { id: 'video-ab-live-proof', status: 'open', missingProofRequirements: [ 'proofContext.mode=live', 'proofContext.collectionMode=live', 'proofContext.generatedBy=acceptance:video-ab', 'proofContext.requiresRuntimeCredential=true', 'proofContext.requiresVocSocialProvider=true', 'proofContext.requiresVideoAnalysisProvider=true' ] }, { id: 'manual-review-and-customer-effect', status: 'open', evidence: customerEffectConcreteEvidence, missingProofRequirements: customerEffectConcreteRequirements }, { id: 'live-provider-overnight-proof', status: 'open', missingProofRequirements: ['manifest.liveEnabled=true', 'acceptance.overallPass=true'] } ] }, feedbackLoopClosure: { summary: 'outputs/feedback-loop-closure-latest/feedback-loop-closure-summary.json', report: 'outputs/feedback-loop-closure-latest/feedback-loop-closure-report.md', csv: 'outputs/feedback-loop-closure-latest/feedback-loop-closure.csv', passed: false, complete: false, directCustomerProof: false, proofLevel: 'not_business_proof', negativeFeedbackCount: 0, blockedCreatorCount: 0, leakedCount: 0, teamRuleSuggestionCount: 0, missingInputs: ['feedback csv', 'preference memory json', 'second-round sourcing result json'] }, homepageEvidenceReadiness: { summary: 'outputs/homepage-evidence-readiness-latest/homepage-evidence-readiness-summary.json', report: 'outputs/homepage-evidence-readiness-latest/homepage-evidence-readiness-report.md', csv: 'outputs/homepage-evidence-readiness-latest/homepage-evidence-repair-actions.csv', ready: false, complete: false, directCustomerProof: false, proofLevel: 'not_business_proof', failureCount: 2, providerEvidenceCreators: 0, creatorsWithPosts: 0, creatorsWithEnoughRecentPosts: 0, repairActionCount: 2 }, guardrails: [ '不能把 sample、smoke、dry-run 当成客户效果证明。', '没有客户选择时不能声明客户效果完成。' ] }, null, 2), 'utf8'); fs.writeFileSync(path.join(handoffDir, 'optimization-handoff-report.md'), '# 提号优化交接摘要\n', 'utf8'); fs.writeFileSync(path.join(proofGapDir, 'proof-gap-request-summary.json'), JSON.stringify({ complete: false, unresolvedCount: 5, rows: [ { id: 'historical-dataset', status: 'missing_real_data', templateCommand: 'npm run data:intake-template -- --output outputs\\data-intake-pack-latest', templateArtifact: 'outputs\\data-intake-pack-latest\\history-data-template.csv' }, { id: 'video-real-candidate', status: 'missing_real_data', templateCommand: 'npm run video:intake-template -- --output outputs\\video-intake-pack-latest', templateArtifact: 'outputs\\video-intake-pack-latest\\video-resource-template.csv' } ] }, null, 2), 'utf8'); fs.writeFileSync(path.join(proofGapDir, 'proof-gap-request-report.md'), '# 提号真实证明缺口请求包\n\n| ID | 模板命令 | 模板产物 |\n| --- | --- | --- |\n| historical-dataset | `npm run data:intake-template` | history-data-template.csv |\n', 'utf8'); fs.writeFileSync(path.join(proofGapDir, 'proof-gap-request-table.csv'), '缺口ID,负责人,状态,模板命令,模板产物\nhistorical-dataset,商务,missing_real_data,npm run data:intake-template,history-data-template.csv\n', 'utf8'); fs.writeFileSync(path.join(proofGapClosureDir, 'proof-gap-closure-summary.json'), JSON.stringify({ complete: false, intakeReady: false, sourceFiles: { history: discoveredHistorySource, customerEffect: discoveredCustomerEffectSource }, closedCount: 0, openCount: 5, businessClosedCount: 0, businessOpenCount: 5, businessGapCount: 5, totalRows: 6, precheckRowCount: 1, precheckClosedCount: 0, precheckOpenCount: 1, videoAbPreflightReadyForVideoAb: false, videoAbPreflightFailureCount: 4, countSemantics: { openCount: 'business_gap_open_count_excludes_precheck_rows', closedCount: 'business_gap_closed_count_excludes_precheck_rows', businessOpenCount: 'same_as_openCount', businessClosedCount: 'same_as_closedCount', precheckOpenCount: 'precheck_rows_reported_separately' }, rows: [ { id: 'intake-readiness', status: 'open', missingProofRequirements: ['acceptance.overallReady=true', 'failureCount=0'] }, { id: 'historical-dataset', status: 'open', evidence: historicalDatasetConcreteEvidence, missingProofRequirements: historicalDatasetConcreteRequirements }, { id: 'video-real-candidate', status: 'open', missingProofRequirements: ['acceptance.readyForVideoAbPreflight=true', 'failureCount=0', 'counts.realCandidateRows>=1'] }, { id: 'video-ab-live-proof', status: 'open', evidence: 'passed=true, mode=unknown, collectionMode=unknown, generatedBy=unknown, provider=ok; preflight.readyForVideoAb=false, preflight.failureCount=4, preflight.generatedBy=acceptance:video-ab-preflight, runtimeCredentialPresent=false', missingProofRequirements: [ 'proofContext.mode=live', 'proofContext.collectionMode=live', 'proofContext.generatedBy=acceptance:video-ab', 'proofContext.requiresRuntimeCredential=true', 'proofContext.requiresVocSocialProvider=true', 'proofContext.requiresVideoAnalysisProvider=true', 'videoAbPreflight.readyForVideoAb=true', 'videoAbPreflight.company resolved for live run' ] }, { id: 'manual-review-and-customer-effect', status: 'open', evidence: customerEffectConcreteEvidence, missingProofRequirements: customerEffectConcreteRequirements }, { id: 'live-provider-overnight-proof', status: 'open', missingProofRequirements: ['manifest.liveEnabled=true', 'acceptance.overallPass=true'] } ] }, null, 2), 'utf8'); fs.writeFileSync(path.join(proofGapClosureDir, 'proof-gap-closure-report.md'), '# 提号真实证明缺口关闭审计\n', 'utf8'); fs.writeFileSync(path.join(feedbackLoopClosureDir, 'feedback-loop-closure-summary.json'), JSON.stringify({ complete: false, passed: false, directCustomerProof: false, proofLevel: 'not_business_proof', negativeFeedbackCount: 0, blockedCreatorCount: 0, blockedInMemoryCount: 0, leakedCount: 0, teamRuleSuggestionCount: 0, missingInputs: ['feedback csv', 'preference memory json', 'second-round sourcing result json'] }, null, 2), 'utf8'); fs.writeFileSync(path.join(feedbackLoopClosureDir, 'feedback-loop-closure-report.md'), '# 反馈二轮闭环审计\n', 'utf8'); fs.writeFileSync(path.join(feedbackLoopClosureDir, 'feedback-loop-closure.csv'), '\uFEFF账号,写入记忆,泄漏进第二轮,泄漏状态,反馈原因\n', 'utf8'); fs.writeFileSync(path.join(homepageEvidenceReadinessDir, 'homepage-evidence-readiness-summary.json'), JSON.stringify({ ready: false, complete: false, directCustomerProof: false, proofLevel: 'not_business_proof', failureCount: 2, counts: { candidates: 1, providerEvidenceCreators: 0, creatorsWithPosts: 0, creatorsWithEnoughRecentPosts: 0 }, repairActions: [ { type: 'missing-provider-evidence' }, { type: 'missing-recent-posts' } ] }, null, 2), 'utf8'); fs.writeFileSync(path.join(homepageEvidenceReadinessDir, 'homepage-evidence-readiness-report.md'), '# 主页近期内容证据就绪审计\n', 'utf8'); fs.writeFileSync(path.join(homepageEvidenceReadinessDir, 'homepage-evidence-repair-actions.csv'), '\uFEFF优先级,负责人,类型\n1,技术/AI,missing-provider-evidence\n2,商务/投放,missing-recent-posts\n', 'utf8'); fs.writeFileSync(path.join(intakeReadinessDir, 'intake-readiness-summary.json'), JSON.stringify({ acceptance: { overallReady: false, historyReady: false, videoReady: false, reviewMetricsReady: false, customerEffectReady: false }, failureCount: 9 }, null, 2), 'utf8'); fs.writeFileSync(path.join(intakeReadinessDir, 'intake-readiness-report.md'), '# 真实材料 Intake Readiness 审计\n', 'utf8'); fs.writeFileSync(path.join(longRunReadinessDir, 'long-run-readiness-summary.json'), JSON.stringify({ mode: 'full-matrix', ready: false, counts: { pass: 1, fail: 5, warn: 0 }, checks: [ { name: 'local-acceptance-required', status: 'pass' }, { name: 'intake-readiness-overall-ready', status: 'fail' }, { name: 'intake-readiness-no-failures', status: 'fail' } ] }, null, 2), 'utf8'); fs.writeFileSync(path.join(longRunReadinessDir, 'long-run-readiness-report.md'), '# 提号长跑就绪度审计\n', 'utf8'); fs.writeFileSync(path.join(optimizationCompletionDir, 'optimization-completion-summary.json'), JSON.stringify({ complete: false, readyForClaim: false, sourceFiles: { history: discoveredHistorySource, customerEffect: discoveredCustomerEffectSource }, proofGapOpenCount: 5, videoAbPreflightReadyForVideoAb: false, videoAbPreflightFailureCount: 4, blockingReasons: [ { id: 'proof-gap-closure', status: 'blocked', missingProofRequirements: ['proofGapClosure.complete=true', 'proofGapClosure.openCount=0', ...historicalDatasetConcreteRequirements.map(item => `historical-dataset: ${item}`), ...customerEffectConcreteRequirements.map(item => `manual-review-and-customer-effect: ${item}`)] }, { id: 'longrun-readiness', status: 'blocked', missingProofRequirements: ['longRunReadiness.ready=true', 'longRunReadiness.counts.fail=0'] }, { id: 'customer-effect-proof', status: 'blocked', missingProofRequirements: customerEffectConcreteRequirements } ], gates: [ { id: 'video-ab-live-proof', status: 'blocked', evidence: 'passed=true, mode=unknown, collectionMode=unknown, generatedBy=unknown, provider=ok; preflight.readyForVideoAb=false, preflight.failureCount=4, preflight.generatedBy=acceptance:video-ab-preflight, runtimeCredentialPresent=false', missingProofRequirements: [ 'proofContext.mode=live', 'proofContext.collectionMode=live', 'proofContext.generatedBy=acceptance:video-ab', 'proofContext.requiresRuntimeCredential=true', 'proofContext.requiresVocSocialProvider=true', 'proofContext.requiresVideoAnalysisProvider=true', 'videoAbPreflight.readyForVideoAb=true', 'videoAbPreflight.company resolved for live run' ] } ], canClaim: { tihaoRateImproved: false, customerEffectAchieved: false, manualSupplementReduced: false }, nextRequiredCommands: [ 'npm run intake:readiness', 'npm run video:resource-readiness', 'npm run proof-gap:closure', 'npm run optimization:pipeline', 'npm run round:refresh' ] }, null, 2), 'utf8'); fs.writeFileSync(path.join(optimizationCompletionDir, 'optimization-completion-report.md'), '# 优化完成度审计\n', 'utf8'); fs.writeFileSync(path.join(businessProofProgressDir, 'business-proof-progress-summary.json'), JSON.stringify({ complete: false, counts: { pass: 4, fail: 2, pending: 2, blocked_by_external_data: 7 }, operatorPackOwnerArtifactCount: 3, operatorPackOwnerArtifacts: proofGapOperatorPackFixture.ownerArtifacts, rows: Array.from({ length: 15 }, (_, index) => ({ order: index + 1, owner: index < 2 ? '商务' : '技术/AI', title: `补证步骤 ${index + 1}`, status: index < 4 ? 'pass' : index < 11 ? 'blocked_by_external_data' : index < 13 ? 'fail' : 'pending', evidence: 'smoke fixture', next: '继续每轮刷新。' })) }, null, 2), 'utf8'); fs.writeFileSync(path.join(businessProofProgressDir, 'business-proof-progress-report.md'), '# 提号补证 15 步进度表\n', 'utf8'); fs.writeFileSync(path.join(businessProofNextActionsDir, 'business-proof-next-actions-summary.json'), JSON.stringify({ complete: false, actionCount: 5, ownerGroupCount: 3, sourceState: { progressComplete: false, proofGapOpenCount: 5 }, topActions: [ { id: 'step-03', priority: 1, owner: '商务', title: '填真实历史 Brief', command: '填写 outputs\\data-intake-pack-latest\\history-data-template.csv', acceptance: 'historyReady=true,真实历史 Brief 数 >= 5,且无模板占位。' }, { id: 'step-04', priority: 2, owner: '商务/投放', title: '填真实视频资源', command: '填写 outputs\\video-intake-pack-latest\\video-resource-template.csv', acceptance: 'videoReady=true' }, { id: 'step-12', priority: 4, owner: '商务', title: '人工复核标注', command: '填写 outputs\\data-intake-pack-latest\\manual-review-template.csv', acceptance: '客户选择齐全' }, { id: 'gap-video-ab-live-proof', priority: 24, owner: '技术/AI', title: '真实视频 A/B 验收', command: 'npm run acceptance:video-ab', acceptance: 'proofContext.mode=live' }, { id: 'gap-live-provider-overnight-proof', priority: 25, owner: '技术/AI', title: '真实 live/provider 长跑证明', command: 'npm run overnight:quality', acceptance: 'manifest.liveEnabled=true' } ], actions: [ { id: 'step-03', priority: 1, owner: '商务', title: '填真实历史 Brief', command: '填写 outputs\\data-intake-pack-latest\\history-data-template.csv', acceptance: 'historyReady=true,真实历史 Brief 数 >= 5,且无模板占位。', missingProofRequirements: historicalDatasetConcreteRequirements }, { id: 'step-04', priority: 2, owner: '商务/投放', title: '填真实视频资源', command: '填写 outputs\\video-intake-pack-latest\\video-resource-template.csv', acceptance: 'videoReady=true,至少有真实参考视频和真实候选视频。', missingProofRequirements: ['acceptance.readyForVideoAbPreflight=true', 'failureCount=0', 'counts.realCandidateRows>=1'] }, { id: 'step-12', priority: 4, owner: '商务', title: '人工复核标注', command: '填写 outputs\\data-intake-pack-latest\\manual-review-template.csv', acceptance: '客户选择、负样本归因和本轮人工补号量齐全。', missingProofRequirements: customerEffectConcreteRequirements }, { id: 'gap-video-ab-live-proof', priority: 24, owner: '技术/AI', title: '真实视频 A/B 验收', command: 'npm run acceptance:video-ab', acceptance: 'acceptance:video-ab 必须在真实 provider 和真实视频资源下通过。', missingProofRequirements: ['proofContext.mode=live', 'proofContext.collectionMode=live'] }, { id: 'gap-live-provider-overnight-proof', priority: 25, owner: '技术/AI', title: '真实 live/provider 长跑证明', command: 'npm run longrun:readiness;真实 provider 就绪后运行 npm run overnight:quality', acceptance: 'overnight aggregate 必须 liveEnabled=true、overallPass=true、failureCount=0、failedGateCount=0。', missingProofRequirements: ['manifest.liveEnabled=true', 'acceptance.overallPass=true'] } ] }, null, 2), 'utf8'); fs.writeFileSync(path.join(businessProofNextActionsDir, 'business-proof-next-actions-report.md'), '# 提号补证下一步行动队列\n', 'utf8'); fs.writeFileSync(path.join(businessProofNextActionsDir, 'business-proof-next-actions.csv'), '优先级,负责人,动作\n1,商务,填真实历史 Brief\n', 'utf8'); fs.writeFileSync(path.join(businessExecutionIndexDir, 'business-execution-index-summary.json'), JSON.stringify({ passed: true, rowCount: 15, actionRowCount: 5, repairRowCount: 2, operatorPackOwnerArtifactRowCount: 3, operatorPackOwnerArtifactCount: 3, operatorPackOwnerArtifacts: proofGapOperatorPackFixture.ownerArtifacts, fieldOwnerRowCount: 1, recheckCommandRowCount: 1, fileRowCount: 2, proofOpenCount: 5, proofLevel: 'smoke_or_local', directCustomerProof: false, sourceFiles: { longRunReadiness: 'outputs/long-run-readiness-latest/long-run-readiness-summary.json', optimizationCompletion: 'outputs/optimization-completion-latest/optimization-completion-summary.json', proofGapOperatorPack: 'outputs/proof-gap-operator-pack-latest/proof-gap-operator-pack-summary.json' }, rows: [ { owner: '商务', type: '负责人行动', title: '填真实历史 Brief', acceptance: 'historyReady=true', boundary: '补证任务,不证明业务效果' }, { owner: '商务/投放', type: '负责人行动', title: '填真实视频资源', acceptance: 'videoReady=true', boundary: '补证任务,不证明业务效果' }, { owner: '商务', type: '负责人行动', title: '人工复核标注', acceptance: 'review=true', boundary: '补证任务,不证明业务效果' }, { owner: '技术/AI', type: '负责人行动', title: '真实视频 A/B 验收', acceptance: 'acceptance:video-ab=true', boundary: '补证任务,不证明业务效果' }, { owner: '技术/AI', type: '负责人行动', title: '真实 live/provider 长跑证明', acceptance: 'overnight live=true', boundary: '补证任务,不证明业务效果' }, { owner: '商务', type: '修复清单', title: '历史数据/商务复核修复清单', acceptance: 'failureCount=0', boundary: '修复清单是补证执行材料,不证明客户效果' }, { owner: '商务/投放', type: '修复清单', title: '视频资源修复清单', acceptance: 'failureCount=0', boundary: '修复清单是补证执行材料,不证明客户效果' }, { owner: '商务', type: '操作包负责人附件', title: 'proof-gap 操作包负责人附件', mainFile: 'outputs/proof-gap-operator-pack-latest/by-owner/business.md', csv: 'outputs/proof-gap-operator-pack-latest/by-owner/business.csv', actionCount: 2, acceptance: 'actionCount=2;evidenceRowCount=2;nextActionCount=2;gapIds=historical-dataset;manual-review-and-customer-effect', boundary: '负责人附件只用于补证派工,不证明客户效果' }, { owner: '商务/投放', type: '操作包负责人附件', title: 'proof-gap 操作包负责人附件', mainFile: 'outputs/proof-gap-operator-pack-latest/by-owner/business-media.md', csv: 'outputs/proof-gap-operator-pack-latest/by-owner/business-media.csv', actionCount: 1, acceptance: 'actionCount=1;evidenceRowCount=1;nextActionCount=1;gapIds=video-real-candidate', boundary: '负责人附件只用于补证派工,不证明客户效果' }, { owner: '技术/AI', type: '操作包负责人附件', title: 'proof-gap 操作包负责人附件', mainFile: 'outputs/proof-gap-operator-pack-latest/by-owner/tech-ai.md', csv: 'outputs/proof-gap-operator-pack-latest/by-owner/tech-ai.csv', actionCount: 2, acceptance: 'actionCount=2;evidenceRowCount=2;nextActionCount=2;gapIds=video-ab-live-proof;live-provider-overnight-proof', boundary: '负责人附件只用于补证派工,不证明客户效果' }, { owner: '商务', type: '关键文件', title: '最新提号补证表单', acceptance: 'rowCount=5', boundary: '补证表单不证明客户效果' }, { owner: '技术/AI', type: '关键文件', title: '长跑前置门禁报告', status: 'blocked', mainFile: 'outputs/long-run-readiness-latest/long-run-readiness-report.md', expectedArtifact: 'outputs/long-run-readiness-latest/long-run-readiness-summary.json', actionCount: 5, acceptance: 'ready=false,failCount=5', boundary: '长跑前置门禁只判断启动条件,不证明客户效果;ready=false 时不能启动或宣称 full-matrix/live 长跑完成。' }, { owner: '技术/AI', type: '关键文件', title: '优化完成度审计报告', status: 'blocked', mainFile: 'outputs/optimization-completion-latest/optimization-completion-report.md', expectedArtifact: 'outputs/optimization-completion-latest/optimization-completion-summary.json', actionCount: 3, acceptance: 'complete=false,readyForClaim=false,proofGapOpenCount=5,blockingReasons=3', boundary: '优化完成度审计只判断能否进入完成声明,不证明客户效果;readyForClaim=false 时不得宣称提号率提升、客户效果达标或人工补号量下降。' }, { owner: '商务', type: '字段补齐负责人', title: '历史 Brief字段补齐', acceptance: 'historyReady=true', boundary: '补齐材料,不证明客户效果' }, { owner: '技术/AI', type: '补齐后复验命令', title: '真实材料预审', acceptance: 'overallReady=true', boundary: '预审通过不证明客户效果' }, ] }, null, 2), 'utf8'); fs.writeFileSync(path.join(businessExecutionIndexDir, 'business-execution-index.md'), '# Business Execution Index\n\n- passed: true\n- directCustomerProof: false\n', 'utf8'); fs.writeFileSync(path.join(businessExecutionIndexDir, 'business-execution-index.csv'), 'owner,type,title,acceptance,boundary\nbusiness,owner-action,fill real historical Brief,historyReady=true,not customer proof\n', 'utf8'); fs.writeFileSync(path.join(proofGapOperatorPackDir, 'proof-gap-operator-pack-summary.json'), JSON.stringify(proofGapOperatorPackFixture, null, 2), 'utf8'); fs.writeFileSync(path.join(proofGapOperatorPackDir, 'proof-gap-operator-pack.md'), [ '# Proof Gap Operator Pack', '', '- directCustomerProof: false', '- proofLevel: not_business_proof', '- gapIds: historical-dataset,video-real-candidate,video-ab-live-proof,live-provider-overnight-proof,manual-review-and-customer-effect', '- recheckCommandCount: 7', '- evidenceRowCount: 5', '- nextActionCount: 5' ].join('\n'), 'utf8'); fs.writeFileSync(path.join(proofGapOperatorPackDir, 'proof-gap-operator-pack.csv'), [ 'gapId,owner,evidence,primaryFillFile,primaryRecheckCommand,nextAction', `historical-dataset,business,"${historicalDatasetConcreteEvidence}",outputs/data-intake-pack-latest/history-data-template.csv,npm run intake:readiness,补齐真实历史 Brief 后重跑 history:audit`, `manual-review-and-customer-effect,business,"${customerEffectConcreteEvidence}",outputs/data-intake-pack-latest/manual-review-template.csv,npm run customer-effect:audit,补客户选择和人工补号量后重跑 customer-effect:audit` ].join('\n'), 'utf8'); fs.writeFileSync(path.join(realProofIntakeBundleDir, 'real-proof-intake-bundle-summary.json'), JSON.stringify({ passed: true, complete: false, directCustomerProof: false, proofLevel: 'not_business_proof', proofOpenCount: 5, exportRowCount: 37, recheckCommandCount: 6, operatorPackEvidenceRowCount: 5, operatorPackNextActionCount: 5, operatorPackMissingProofRequirementCount: 23, operatorPackOwnerArtifactCount: 3, operatorPackOwnerArtifacts: proofGapOperatorPackFixture.ownerArtifacts, proofGapRows: [ { gapId: 'video-ab-live-proof', status: 'open', evidence: videoAbPreflightEvidence, nextAction: videoAbLiveProofNextAction, missingProofRequirements: videoAbLiveProofRequirements, recheckCommands: ['npm run acceptance:video-ab'] } ], sourceState: { operatorPackEvidenceRowCount: 5, operatorPackNextActionCount: 5, operatorPackMissingProofRequirementCount: 23, operatorPackOwnerArtifactCount: 3, longRunReadinessReady: false, longRunReadinessFailCount: 5, longRunReadinessProofLevel: 'not_business_proof', longRunReadinessDirectCustomerProof: false }, templateFiles: [ { owner: '技术/AI', title: '长跑前置门禁报告', path: 'outputs/long-run-readiness-latest/long-run-readiness-report.md', status: 'ready=false,failCount=5', boundary: '长跑前置门禁入口不证明客户效果;ready=false 时不能启动或宣称 full-matrix/live 长跑完成。' } ], recheckCommands: [ { stage: '长跑前置门禁', owner: '技术/AI', command: 'npm run longrun:readiness -- --mode full-matrix --output outputs\\long-run-readiness-latest', acceptance: 'ready=true 且 failCount=0', boundary: 'ready=false 时不能启动或宣称 full-matrix/live 长跑完成。' } ], exportRows: [ { type: '打开文件', target: 'outputs/long-run-readiness-latest/long-run-readiness-report.md' }, { type: '复验命令', target: 'npm run longrun:readiness -- --mode full-matrix --output outputs\\long-run-readiness-latest' }, { type: '证明缺口', target: 'video-ab-live-proof', evidence: videoAbPreflightEvidence, nextAction: videoAbLiveProofNextAction } ] }, null, 2), 'utf8'); fs.writeFileSync(path.join(realProofIntakeBundleDir, 'real-proof-intake-bundle.md'), '# 真实验收材料收集总包\n\nlong-run-readiness-report.md\n', 'utf8'); fs.writeFileSync(path.join(realProofIntakeBundleDir, 'real-proof-intake-bundle.csv'), '类型,文件或命令\n打开文件,long-run-readiness-report.md\n', 'utf8'); fs.writeFileSync(path.join(intakeFieldChecklistDir, 'intake-field-checklist-summary.json'), JSON.stringify({ passed: true, proofLevel: 'smoke_or_local', directCustomerProof: false, itemCount: 4, missingRequiredCount: 2, placeholderCount: 2, ownerGroups: [ { owner: '商务', section: 'history', itemCount: 2, missingRequiredCount: 1, placeholderCount: 1, files: ['outputs/data-intake-pack-latest/history-data-template.csv'], firstItemIds: ['FIELD-001', 'FIELD-002'], nextAction: '补真实历史 Brief 和客户选择。', acceptance: 'historyReady=true。', boundary: '补齐材料,不证明客户效果' }, { owner: '商务/投放', section: 'video', itemCount: 2, missingRequiredCount: 1, placeholderCount: 1, files: ['outputs/video-intake-pack-latest/video-resource-template.csv'], firstItemIds: ['FIELD-003', 'FIELD-004'], nextAction: '补真实视频 URL。', acceptance: 'videoReady=true。', boundary: '补齐材料,不证明客户效果' } ], recheckCommands: [ { stage: '真实材料预审', owner: '技术/AI', command: 'npm run intake:readiness -- --data-pack outputs\\data-intake-pack-latest --video-pack outputs\\video-intake-pack-latest --output outputs\\intake-readiness-latest', acceptance: 'overallReady=true', boundary: '预审通过不证明客户效果' }, { stage: '刷新本轮交接', owner: '技术/AI', command: 'npm run round:refresh -- --output-root outputs --strict', acceptance: 'round-deposition.passed=true', boundary: '刷新交接不证明业务效果' }, { stage: '客户效果审计', owner: '技术/AI', command: 'npm run customer-effect:audit -- --review-csv <已标注CSV> --history-audit --current-manual-supplement-count <本轮人工补号量> --output <客户效果输出目录> --strict', acceptance: 'overallPass=true', boundary: '缺客户选择不得宣称效果' }, { stage: '视频 A/B 验收', owner: '技术/AI', command: 'npm run acceptance:video-ab', acceptance: '真实 provider 下通过', boundary: 'sample 不证明视频提升提号率' } ], items: [ { owner: '商务', section: 'history', issueType: 'missing_required', field: '客户原始Brief', fixAction: '补真实 Brief', boundary: '补齐材料,不证明客户效果' }, { owner: '商务', section: 'history', issueType: 'placeholder', field: '参考账号或视频', fixAction: '替换 example.com', boundary: '补齐材料,不证明客户效果' }, { owner: '商务', section: 'review', issueType: 'missing_required', field: '客户选择', fixAction: '补客户选择', boundary: '补齐材料,不证明客户效果' }, { owner: '商务/投放', section: 'video', issueType: 'placeholder', field: '视频链接', fixAction: '补真实视频 URL', boundary: '补齐材料,不证明客户效果' } ] }, null, 2), 'utf8'); fs.writeFileSync(path.join(intakeFieldChecklistDir, 'intake-field-checklist.md'), '# 真实材料字段级补齐核对表\n\n- directCustomerProof: false\n', 'utf8'); fs.writeFileSync(path.join(intakeFieldChecklistDir, 'intake-field-checklist.csv'), 'ID,负责人,区域,问题类型\nFIELD-001,商务,history,missing_required\n', 'utf8'); fs.writeFileSync(path.join(manualReviewLabelGuideDir, 'manual-review-label-guide-summary.json'), JSON.stringify({ passed: true, directCustomerProof: false, proofLevel: 'smoke_or_local', labelCount: 10, positiveLabelCount: 2, negativeLabelCount: 6, attributionTypeCount: 8, negativeLabelsRequireAttribution: true, labels: [ { label: '可直接发客户', category: 'positive' }, { label: '商务复核', category: 'positive' }, { label: '跑偏', category: 'negative', requiresAttribution: true }, { label: '硬性规则违约', category: 'negative', requiresAttribution: true }, { label: '调性不符', category: 'negative', requiresAttribution: true }, { label: '主页质感不符', category: 'negative', requiresAttribution: true }, { label: '参考账号不像', category: 'negative', requiresAttribution: true }, { label: '客户拒绝', category: 'customer_result', requiresAttribution: true } ], attributionTypes: [ { type: '需求解析错' }, { type: '隐性规则漏' }, { type: '召回关键词错' }, { type: '主页证据不足' }, { type: '视频证据误判' }, { type: '排序权重错' }, { type: '输出解释错' }, { type: '软件端表重复或排名不连续' } ] }, null, 2), 'utf8'); fs.writeFileSync(path.join(manualReviewLabelGuideDir, 'manual-review-label-guide.md'), '# 人工复核标签与归因指南\n', 'utf8'); fs.writeFileSync(path.join(manualReviewLabelGuideDir, 'manual-review-label-guide.csv'), '类型,ID,名称\nlabel,MRL-001,可直接发客户\n', 'utf8'); fs.writeFileSync(path.join(proofGapSoftwareFormDir, 'tihao-proof-gap-software-form-summary.json'), JSON.stringify({ passed: true, headerMatches: true, rowWidthOk: true, rowCount: 5, duplicateIdCount: 0, actualTitles: [ '真实历史 Brief 数据集', '真实视频资源表', '真实视频证据 A/B', '真实 live/provider 长跑证明', '商务复核和客户效果' ] }, null, 2), 'utf8'); fs.writeFileSync(path.join(planExecutionStatusDir, 'plan-execution-status-summary.json'), JSON.stringify({ passed: true, complete: false, rowCount: 8, proofOpenCount: 5, roundPassed: true, operatorPackOwnerArtifactCount: 3, operatorPackOwnerArtifacts: proofGapOperatorPackFixture.ownerArtifacts, businessExecutionOperatorPackOwnerArtifactCount: 3, businessExecutionOperatorPackOwnerArtifactRowCount: 3, guardrails: [ 'proofOpenCount 不为 0 时,不得宣称客户效果、命中率提升或人工补号量下降。', 'sample/smoke/provider fallback 只能证明流程可用。' ] }, null, 2), 'utf8'); fs.writeFileSync(path.join(planExecutionStatusDir, 'plan-execution-status.md'), '# 长期计划执行状态面板\n', 'utf8'); fs.writeFileSync(path.join(planExecutionStatusDir, 'plan-execution-status.csv'), 'section,status\n', 'utf8'); fs.writeFileSync(path.join(latestFormIndexDir, 'latest-form-index-summary.json'), JSON.stringify({ passed: true, primaryForm: { directCustomerProof: false, csv: 'outputs/tihao-proof-gap-software-form-latest/tihao-proof-gap-software-form.csv' }, clientList: { directCustomerProof: false, csv: 'outputs/software-client-latest/software-client-list.final.csv', summary: 'outputs/software-client-latest/software-client-list.final.summary.json', rowCount: 28, sourceDuplicateRemovedCount: 32, finalDuplicateGroupCount: 0, duplicateCountMeaning: 'source_duplicate_removed_count', rankContinuous: true }, localSeedToIntakeWorklist: localSeedToIntakeWorklistIndexedFixture, realGapMaterialAudit: realGapMaterialAuditIndexedFixture, realProofClosureWorkOrder: realProofClosureWorkOrderIndexedFixture, manualReviewLabelGuide: { markdown: 'outputs/manual-review-label-guide-latest/manual-review-label-guide.md', csv: 'outputs/manual-review-label-guide-latest/manual-review-label-guide.csv', summary: 'outputs/manual-review-label-guide-latest/manual-review-label-guide-summary.json', passed: true, directCustomerProof: false, proofLevel: 'smoke_or_local', labelCount: 10, positiveLabelCount: 2, negativeLabelCount: 6, attributionTypeCount: 8, negativeLabelsRequireAttribution: true }, intakeFieldChecklist: { directCustomerProof: false, markdown: 'outputs/intake-field-checklist-latest/intake-field-checklist.md', csv: 'outputs/intake-field-checklist-latest/intake-field-checklist.csv', summary: 'outputs/intake-field-checklist-latest/intake-field-checklist-summary.json', itemCount: 4, missingRequiredCount: 2, placeholderCount: 2, ownerGroups: [ { owner: '商务', section: 'history', itemCount: 2, files: ['outputs/data-intake-pack-latest/history-data-template.csv'], nextAction: '补真实历史 Brief', acceptance: 'historyReady=true', boundary: '补齐材料,不证明客户效果' }, { owner: '商务/投放', section: 'video', itemCount: 2, files: ['outputs/video-intake-pack-latest/video-resource-template.csv'], nextAction: '补真实视频 URL', acceptance: 'videoReady=true', boundary: '补齐材料,不证明客户效果' } ], recheckCommands: [ { stage: '真实材料预审', owner: '技术/AI', command: 'npm run intake:readiness -- --data-pack outputs\\data-intake-pack-latest --video-pack outputs\\video-intake-pack-latest --output outputs\\intake-readiness-latest', acceptance: 'overallReady=true', boundary: '预审通过不证明客户效果' }, { stage: '刷新本轮交接', owner: '技术/AI', command: 'npm run round:refresh -- --output-root outputs --strict', acceptance: 'round-deposition.passed=true', boundary: '刷新交接不证明业务效果' }, { stage: '客户效果审计', owner: '技术/AI', command: 'npm run customer-effect:audit -- --review-csv <已标注CSV> --history-audit --current-manual-supplement-count <本轮人工补号量> --output <客户效果输出目录> --strict', acceptance: 'overallPass=true', boundary: '缺客户选择不得宣称效果' }, { stage: '视频 A/B 验收', owner: '技术/AI', command: 'npm run acceptance:video-ab', acceptance: '真实 provider 下通过', boundary: 'sample 不证明视频提升提号率' } ] }, businessFillGuide: { title: '商务填表执行视图', directCustomerProof: false, proofLevel: 'smoke_or_local', rowCount: 2, rows: [ { order: 1, owner: '鍟嗗姟', section: 'history', file: 'outputs/data-intake-pack-latest/history-data-template.csv', firstItemIds: ['FIELD-001'], issueCount: 2, fillAction: '琛ョ湡瀹炲巻鍙?Brief', recheckCommand: 'npm run intake:readiness -- --data-pack outputs\\data-intake-pack-latest --video-pack outputs\\video-intake-pack-latest --output outputs\\intake-readiness-latest', acceptance: 'historyReady=true', boundary: '补齐材料,不证明客户效果' }, { order: 2, owner: '鍟嗗姟/鎶曟斁', section: 'video', file: 'outputs/video-intake-pack-latest/video-resource-template.csv', firstItemIds: ['FIELD-003'], issueCount: 2, fillAction: '琛ョ湡瀹炶棰?URL', recheckCommand: 'npm run acceptance:video-ab', acceptance: 'videoReady=true', boundary: '补齐材料,不证明客户效果' } ], guardrail: '本视图只帮助商务按表补齐真实材料,不代表客户效果已达标。' }, businessExecutionIndex: { directCustomerProof: false, markdown: 'outputs/business-execution-index-latest/business-execution-index.md', csv: 'outputs/business-execution-index-latest/business-execution-index.csv', summary: 'outputs/business-execution-index-latest/business-execution-index-summary.json', rowCount: 15, operatorPackOwnerArtifactCount: 3, operatorPackOwnerArtifacts: proofGapOperatorPackFixture.ownerArtifacts, fieldOwnerRowCount: 1, recheckCommandRowCount: 1 }, proofGapOperatorPack: { ...proofGapOperatorPackFixture, markdown: 'outputs/proof-gap-operator-pack-latest/proof-gap-operator-pack.md', csv: 'outputs/proof-gap-operator-pack-latest/proof-gap-operator-pack.csv', summary: 'outputs/proof-gap-operator-pack-latest/proof-gap-operator-pack-summary.json' }, planExecutionStatus: { directCustomerProof: false, markdown: 'outputs/plan-execution-status-latest/plan-execution-status.md', csv: 'outputs/plan-execution-status-latest/plan-execution-status.csv', summary: 'outputs/plan-execution-status-latest/plan-execution-status-summary.json', passed: true, complete: false, rowCount: 8, proofOpenCount: 5, operatorPackOwnerArtifactCount: 3, operatorPackOwnerArtifacts: proofGapOperatorPackFixture.ownerArtifacts, businessExecutionOperatorPackOwnerArtifactCount: 3, businessExecutionOperatorPackOwnerArtifactRowCount: 3 }, longRunReadiness: { report: 'outputs/long-run-readiness-latest/long-run-readiness-report.md', summary: 'outputs/long-run-readiness-latest/long-run-readiness-summary.json', mode: 'full-matrix', ready: false, directCustomerProof: false, proofLevel: 'not_business_proof', passCount: 1, failCount: 5, warnCount: 0 }, supportDocs: [ { path: 'docs/tihao-experience-optimization-plan.zh-CN.md' }, { path: 'docs/business-proof-action-order.zh-CN.md' } ], nextActions: { complete: false, actionCount: 5, proofOpenCount: 5, ownerGroupCount: 3, ownerArtifactCount: 3, sourceState: { progressComplete: false, proofGapOpenCount: 5 }, topActions: [ { id: 'step-03', priority: 1, owner: '商务', title: '填真实历史 Brief', status: 'blocked_by_external_data', command: '填写 outputs\\data-intake-pack-latest\\history-data-template.csv', acceptance: 'historyReady=true' }, { id: 'step-04', priority: 2, owner: '商务/投放', title: '填真实视频资源', status: 'blocked_by_external_data', command: '填写 outputs\\video-intake-pack-latest\\video-resource-template.csv', acceptance: 'videoReady=true' }, { id: 'step-12', priority: 4, owner: '商务', title: '人工复核标注', status: 'blocked_by_external_data', command: '填写 outputs\\data-intake-pack-latest\\manual-review-template.csv', acceptance: '客户选择齐全' }, { id: 'gap-video-ab-live-proof', priority: 24, owner: '技术/AI', title: '真实视频 A/B 验收', status: 'open', command: 'npm run acceptance:video-ab', acceptance: '真实 provider 下通过' }, { id: 'gap-live-provider-overnight-proof', priority: 25, owner: '技术/AI', title: '真实 live/provider 长跑证明', status: 'open', command: 'npm run longrun:readiness;真实 provider 就绪后运行 npm run overnight:quality', acceptance: 'liveEnabled=true' } ], ownerArtifacts: [ { owner: '商务', markdown: 'outputs/business-proof-next-actions-latest/by-owner/business.md', csv: 'outputs/business-proof-next-actions-latest/by-owner/business.csv', repairArtifacts: [ { csv: 'outputs/intake-readiness-latest/intake-readiness-repair-actions.csv', actionCount: 6 } ] }, { owner: '商务/投放', markdown: 'outputs/business-proof-next-actions-latest/by-owner/business-media.md', csv: 'outputs/business-proof-next-actions-latest/by-owner/business-media.csv', repairArtifacts: [ { csv: 'outputs/video-resource-readiness-latest/video-resource-repair-actions.csv', actionCount: 1 }, { csv: 'outputs/homepage-evidence-readiness-latest/homepage-evidence-repair-actions.csv', actionCount: 1 } ] }, { owner: '技术/AI', markdown: 'outputs/business-proof-next-actions-latest/by-owner/tech-ai.md', csv: 'outputs/business-proof-next-actions-latest/by-owner/tech-ai.csv', repairArtifacts: [] } ] }, repairActions: { dataIntake: { csv: 'outputs/intake-readiness-latest/intake-readiness-repair-actions.csv', repairActionCount: 9 }, videoResource: { csv: 'outputs/video-resource-readiness-latest/video-resource-repair-actions.csv', repairActionCount: 1 }, homepageEvidence: { csv: 'outputs/homepage-evidence-readiness-latest/homepage-evidence-repair-actions.csv', repairActionCount: 2 } } }, null, 2), 'utf8'); const result = spawnSync(process.execPath, [ path.join(root, 'scripts', 'round-deposition-audit.js'), '--outputs', outputs, '--implementation-log', implementationLog, '--proof-action-order', proofActionOrder, '--output', outputDir, '--strict' ], { cwd: root, encoding: 'utf8' }); if (result.status !== 0) { process.stderr.write(result.stderr || result.stdout || ''); throw new Error('round-deposition-audit should pass with complete local deposition artifacts'); } const defaultDocOutputDir = path.join(outputs, 'round-deposition-default-doc'); const defaultDocResult = spawnSync(process.execPath, [ path.join(root, 'scripts', 'round-deposition-audit.js'), '--outputs', outputs, '--implementation-log', implementationLog, '--output', defaultDocOutputDir, '--strict' ], { cwd: root, encoding: 'utf8' }); if (defaultDocResult.status !== 0) { process.stderr.write(defaultDocResult.stderr || defaultDocResult.stdout || ''); throw new Error('round-deposition-audit should pass with default Chinese proof action order document'); } const defaultDocSummary = JSON.parse(fs.readFileSync(path.join(defaultDocOutputDir, 'round-deposition-summary.json'), 'utf8')); assert(defaultDocSummary.sources.proofActionOrder.includes('business-proof-action-order.zh-CN.md'), 'default proof action order should prefer Chinese document'); const summary = JSON.parse(fs.readFileSync(path.join(outputDir, 'round-deposition-summary.json'), 'utf8')); const report = fs.readFileSync(path.join(outputDir, 'round-deposition-report.md'), 'utf8').replace(/^\uFEFF/, ''); assert(summary.passed === true, 'round deposition summary should pass'); assert(summary.checks.some(item => item.id === 'proof-boundaries'), 'summary should include proof boundary check'); assert(summary.checks.some(item => item.id === 'proof-gap-unresolved-recorded'), 'summary should include proof-gap unresolved check'); assert(summary.checks.some(item => item.id === 'proof-gap-template-entry-recorded'), 'summary should include proof-gap template entry check'); assert(summary.checks.some(item => item.id === 'proof-gap-template-columns-exported'), 'summary should include proof-gap template column export check'); assert(summary.checks.some(item => item.id === 'proof-gap-operator-pack-summary'), 'summary should include proof-gap operator pack summary check'); assert(summary.checks.some(item => item.id === 'proof-gap-operator-pack-actionable'), 'summary should include proof-gap operator pack actionable check'); assert(summary.checks.some(item => item.id === 'proof-gap-operator-pack-missing-proof-by-gap'), 'summary should include proof-gap operator pack missing proof by gap check'); assert(summary.checks.some(item => item.id === 'proof-gap-closure-recursive-proof-artifact-discovery'), 'summary should include proof-gap closure recursive proof artifact discovery check'); assert(summary.checks.some(item => item.id === 'proof-gap-operator-pack-video-ab-preflight-context'), 'summary should include proof-gap operator pack video A/B preflight context check'); assert(summary.checks.some(item => item.id === 'intake-readiness-summary'), 'summary should include intake readiness summary check'); assert(summary.checks.some(item => item.id === 'intake-readiness-boundary-recorded'), 'summary should include intake readiness boundary check'); assert(summary.checks.some(item => item.id === 'longrun-readiness-summary'), 'summary should include longrun readiness summary check'); assert(summary.checks.some(item => item.id === 'longrun-readiness-intake-gate'), 'summary should include longrun intake gate check'); assert(summary.checks.some(item => item.id === 'latest-form-index-longrun-readiness'), 'summary should include latest form longrun readiness entry check'); assert(summary.checks.some(item => item.id === 'handoff-longrun-readiness'), 'summary should include handoff longrun readiness entry check'); assert(summary.checks.some(item => item.id === 'handoff-latest-form-longrun-readiness'), 'summary should include handoff latest form longrun readiness entry check'); assert(summary.checks.some(item => item.id === 'business-proof-progress-summary'), 'summary should include business proof progress summary check'); assert(summary.checks.some(item => item.id === 'business-proof-progress-steps'), 'summary should include business proof progress steps check'); assert(summary.checks.some(item => item.id === 'business-proof-progress-operator-owner-artifacts'), 'summary should include business proof progress operator owner attachment check'); assert(summary.checks.some(item => item.id === 'handoff-business-proof-progress-operator-owner-artifacts'), 'summary should include handoff business proof progress operator owner attachment check'); assert(summary.checks.some(item => item.id === 'business-proof-next-actions-summary'), 'summary should include business proof next actions summary check'); assert(summary.checks.some(item => item.id === 'business-proof-next-actions-open'), 'summary should include business proof next actions open check'); assert(summary.checks.some(item => item.id === 'business-proof-next-actions-deduped'), 'summary should include business proof next actions dedupe check'); assert(summary.checks.some(item => item.id === 'business-proof-next-actions-missing-proof-requirements'), 'summary should include business proof next actions missing proof requirement check'); assert(summary.checks.some(item => item.id === 'handoff-business-proof-next-actions-top-actions'), 'summary should include handoff business proof next actions top action check'); assert(summary.checks.some(item => item.id === 'optimization-completion-summary'), 'summary should include optimization completion summary check'); assert(summary.checks.some(item => item.id === 'optimization-completion-boundary'), 'summary should include optimization completion boundary check'); assert(summary.checks.some(item => item.id === 'optimization-completion-recursive-proof-artifact-discovery'), 'summary should include optimization completion recursive proof artifact discovery check'); assert(summary.checks.some(item => item.id === 'business-execution-index-summary'), 'summary should include business execution index summary check'); assert(summary.checks.some(item => item.id === 'business-execution-index-passed'), 'summary should include business execution index pass check'); assert(summary.checks.some(item => item.id === 'business-execution-index-longrun-readiness'), 'summary should include business execution longrun readiness check'); assert(summary.checks.some(item => item.id === 'business-execution-index-optimization-completion'), 'summary should include business execution optimization completion check'); assert(summary.checks.some(item => item.id === 'real-proof-intake-bundle-summary'), 'summary should include real proof intake bundle summary check'); assert(summary.checks.some(item => item.id === 'real-proof-intake-bundle-longrun-readiness'), 'summary should include real proof bundle longrun readiness check'); assert(summary.checks.some(item => item.id === 'real-proof-intake-bundle-video-ab-preflight-context'), 'summary should include real proof bundle video A/B preflight context check'); assert(summary.checks.some(item => item.id === 'handoff-business-execution-index'), 'summary should include handoff business execution index check'); assert(summary.checks.some(item => item.id === 'handoff-business-execution-index-longrun-readiness'), 'summary should include handoff business execution longrun readiness check'); assert(summary.checks.some(item => item.id === 'handoff-optimization-completion'), 'summary should include handoff optimization completion check'); assert(summary.checks.some(item => item.id === 'handoff-business-execution-index-optimization-completion'), 'summary should include handoff business execution optimization completion check'); assert(summary.checks.some(item => item.id === 'intake-field-checklist-summary'), 'summary should include intake field checklist summary check'); assert(summary.checks.some(item => item.id === 'intake-field-checklist-passed'), 'summary should include intake field checklist pass check'); assert(summary.checks.some(item => item.id === 'handoff-intake-field-checklist'), 'summary should include handoff intake field checklist check'); assert(summary.checks.some(item => item.id === 'proof-gap-software-form-summary'), 'summary should include proof-gap software form summary check'); assert(summary.checks.some(item => item.id === 'proof-gap-software-form-passed'), 'summary should include proof-gap software form pass check'); assert(summary.checks.some(item => item.id === 'latest-form-index-summary'), 'summary should include latest form index summary check'); assert(summary.checks.some(item => item.id === 'latest-form-index-passed'), 'summary should include latest form index pass check'); assert(summary.checks.some(item => item.id === 'latest-form-index-client-list-delivery-quality'), 'summary should include latest form client list delivery quality check'); assert(summary.checks.some(item => item.id === 'latest-form-index-intake-field-checklist'), 'summary should include latest form intake field checklist check'); assert(summary.checks.some(item => item.id === 'latest-form-index-business-fill-guide'), 'summary should include latest form business fill guide check'); assert(summary.checks.some(item => item.id === 'latest-form-index-support-docs'), 'summary should include latest form support docs check'); assert(summary.checks.some(item => item.id === 'latest-form-index-repair-actions'), 'summary should include latest form repair actions check'); assert(summary.checks.some(item => item.id === 'latest-form-index-owner-repair-actions'), 'summary should include latest form owner repair actions check'); assert(summary.checks.some(item => item.id === 'latest-form-index-next-actions-top-actions'), 'summary should include latest form next actions top actions check'); assert(summary.checks.some(item => item.id === 'latest-form-index-proof-gap-operator-pack'), 'summary should include latest form proof-gap operator pack check'); assert(summary.checks.some(item => item.id === 'local-seed-to-intake-worklist-summary'), 'summary should include local seed to intake worklist summary check'); assert(summary.checks.some(item => item.id === 'local-seed-to-intake-worklist-boundary'), 'summary should include local seed to intake worklist boundary check'); assert(summary.checks.some(item => item.id === 'latest-form-index-local-seed-to-intake-worklist'), 'summary should include latest form local seed to intake worklist check'); assert(summary.checks.some(item => item.id === 'real-proof-closure-work-order-summary'), 'summary should include real proof closure work order summary check'); assert(summary.checks.some(item => item.id === 'real-proof-closure-work-order-boundary'), 'summary should include real proof closure work order boundary check'); assert(summary.checks.some(item => item.id === 'real-proof-closure-work-order-actionable'), 'summary should include real proof closure work order actionable check'); assert(summary.checks.some(item => item.id === 'real-proof-closure-work-order-video-ab-preflight-context'), 'summary should include real proof closure work order video A/B preflight context check'); assert(summary.checks.some(item => item.id === 'latest-form-index-real-proof-closure-work-order'), 'summary should include latest form real proof closure work order check'); assert(summary.checks.some(item => item.id === 'handoff-real-proof-closure-work-order'), 'summary should include handoff real proof closure work order check'); assert(summary.checks.some(item => item.id === 'handoff-latest-form-real-proof-closure-work-order'), 'summary should include handoff latest form real proof closure work order check'); assert(summary.checks.some(item => item.id === 'evidence-index-real-proof-closure-work-order'), 'summary should include evidence index real proof closure work order check'); assert(summary.checks.some(item => item.id === 'evidence-index-video-ab-runtime-preflight-boundary'), 'summary should include video A/B runtime preflight boundary check'); assert(summary.checks.some(item => item.id === 'handoff-local-seed-to-intake-worklist'), 'summary should include handoff local seed to intake worklist check'); assert(summary.checks.some(item => item.id === 'handoff-latest-form-local-seed-to-intake-worklist'), 'summary should include handoff latest form local seed to intake worklist check'); assert(summary.checks.some(item => item.id === 'handoff-latest-form-index'), 'summary should include handoff latest form index check'); assert(summary.checks.some(item => item.id === 'handoff-latest-form-index-next-actions-top-actions'), 'summary should include handoff latest form next actions top actions check'); assert(summary.checks.some(item => item.id === 'handoff-latest-form-repair-actions'), 'summary should include handoff latest form repair actions check'); assert(summary.checks.some(item => item.id === 'handoff-proof-gap-operator-pack'), 'summary should include handoff proof-gap operator pack check'); assert(summary.checks.some(item => item.id === 'handoff-support-docs'), 'summary should include handoff support docs check'); assert(summary.checks.some(item => item.id === 'handoff-owner-repair-actions'), 'summary should include handoff owner repair actions check'); assert(summary.checks.some(item => item.id === 'business-proof-action-order'), 'summary should include business proof action order check'); assert(summary.checks.some(item => item.id === 'proof-gap-closure-open-recorded'), 'summary should include proof-gap closure open check'); assert(summary.checks.some(item => item.id === 'proof-gap-closure-count-semantics'), 'summary should include proof-gap closure count semantics check'); assert(summary.checks.some(item => item.id === 'proof-gap-closure-missing-proof-requirements'), 'summary should include proof-gap closure missing proof requirements check'); assert(summary.checks.some(item => item.id === 'handoff-proof-gap-closure'), 'summary should include handoff proof-gap closure check'); assert(summary.checks.some(item => item.id === 'feedback-loop-closure-summary'), 'summary should include feedback loop closure summary check'); assert(summary.checks.some(item => item.id === 'feedback-loop-closure-boundary'), 'summary should include feedback loop closure boundary check'); assert(summary.checks.some(item => item.id === 'handoff-feedback-loop-closure'), 'summary should include handoff feedback loop closure check'); assert(summary.checks.some(item => item.id === 'homepage-evidence-readiness-summary'), 'summary should include homepage evidence readiness summary check'); assert(summary.checks.some(item => item.id === 'homepage-evidence-readiness-boundary'), 'summary should include homepage evidence readiness boundary check'); assert(summary.checks.some(item => item.id === 'handoff-homepage-evidence-readiness'), 'summary should include handoff homepage evidence readiness check'); assert(summary.checks.some(item => item.id === 'business-execution-index-operator-owner-artifacts'), 'summary should include business execution operator owner artifacts check'); assert(summary.checks.some(item => item.id === 'handoff-business-execution-index-operator-owner-artifacts'), 'summary should include handoff business execution operator owner artifacts check'); assert(summary.checks.some(item => item.id === 'plan-execution-status-operator-owner-artifacts'), 'summary should include plan execution operator owner artifacts check'); assert(summary.checks.some(item => item.id === 'closure-command-recorded'), 'summary should include proof-gap closure command check'); assert(summary.observed.proofGapUnresolvedCount === 5, 'summary should record proof-gap unresolved count'); assert(summary.observed.proofGapTemplateRowsReady === true, 'summary should record proof-gap template row readiness'); assert(summary.observed.proofGapTemplateColumnsReady === true, 'summary should record proof-gap template column readiness'); assert(summary.observed.evidenceVideoRuntimePreflightCount === 1, 'summary should record video A/B runtime preflight count'); assert(summary.observed.proofGapOperatorPackPassed === true, 'summary should record proof-gap operator pack pass state'); assert(summary.observed.proofGapOperatorPackOpenCount === 5, 'summary should record proof-gap operator pack open count'); assert(summary.observed.proofGapOperatorPackRowCount === 5, 'summary should record proof-gap operator pack row count'); assert(summary.observed.proofGapOperatorPackOwnerGroupCount === 3, 'summary should record proof-gap operator pack owner group count'); assert(summary.observed.proofGapOperatorPackOwnerArtifactCount === 3, 'summary should record proof-gap operator pack owner artifact count'); assert(summary.observed.proofGapOperatorPackFillFileCount === 3, 'summary should record proof-gap operator pack fill file count'); assert(summary.observed.proofGapOperatorPackRecheckCommandCount === 7, 'summary should record proof-gap operator pack recheck command count'); assert(summary.observed.proofGapOperatorPackEvidenceRowCount === 5, 'summary should record proof-gap operator pack evidence row count'); assert(summary.observed.proofGapOperatorPackNextActionCount === 5, 'summary should record proof-gap operator pack next action count'); assert(summary.observed.proofGapOperatorPackMissingProofRequirementCount === 23, 'summary should record proof-gap operator pack missing proof requirement count'); assert(summary.observed.proofGapOperatorPackOpenRowsWithMissingProofRequirements === 5, 'summary should record proof-gap operator pack open rows with missing proof requirements'); assert(summary.observed.proofGapOperatorPackVideoAbPreflightContext === true, 'summary should record proof-gap operator pack video A/B preflight context'); assert(summary.observed.proofGapOperatorPackGapIds.includes('historical-dataset'), 'summary should record historical dataset gap ID'); assert(summary.observed.proofGapOperatorPackGapIds.includes('manual-review-and-customer-effect'), 'summary should record customer effect gap ID'); assert(summary.observed.proofGapOperatorPackDirectCustomerProof === false, 'summary should record proof-gap operator pack proof boundary'); assert(summary.observed.intakeReadinessReady === false, 'summary should record intake readiness state'); assert(summary.observed.intakeReadinessFailureCount === 9, 'summary should record intake readiness failure count'); assert(summary.observed.longRunReadinessReady === false, 'summary should record longrun readiness state'); assert(summary.observed.longRunReadinessFailCount === 5, 'summary should record longrun fail count'); assert(summary.observed.businessProofProgressComplete === false, 'summary should record business proof progress completion state'); assert(summary.observed.businessProofProgressCounts.blocked_by_external_data === 7, 'summary should record business proof progress blocker count'); assert(summary.observed.businessProofProgressOperatorPackOwnerArtifactCount === 3, 'summary should record business proof progress operator owner artifact count'); assert(summary.observed.handoffBusinessProofProgressOperatorPackOwnerArtifactCount === 3, 'summary should record handoff business proof progress operator owner artifact count'); assert(summary.observed.businessProofNextActionsComplete === false, 'summary should record business proof next actions completion state'); assert(summary.observed.businessProofNextActionsCount === 5, 'summary should record business proof next actions count'); assert(summary.observed.businessProofNextActionsTopCount === 5, 'summary should record business proof next actions top action count'); assert(summary.observed.businessProofNextActionsWithMissingProofRequirements === 5, 'summary should record business proof next actions missing proof requirement count'); assert(summary.observed.handoffBusinessProofNextActionsCount === 5, 'summary should record handoff business proof next actions count'); assert(summary.observed.handoffBusinessProofNextActionsTopCount === 5, 'summary should record handoff business proof top action count'); assert(summary.observed.handoffBusinessProofNextActionsProofGapOpenCount === 5, 'summary should record handoff business proof next action open count'); assert(summary.observed.optimizationCompletionComplete === false, 'summary should record optimization completion state'); assert(summary.observed.optimizationCompletionReadyForClaim === false, 'summary should record optimization ready-for-claim state'); assert(summary.observed.optimizationCompletionProofGapOpenCount === 5, 'summary should record optimization completion proof-gap count'); assert(summary.observed.optimizationCompletionBlockingReasonCount === 3, 'summary should record optimization completion blocking reason count'); assert(summary.observed.optimizationCompletionBlockingReasonsWithMissingProofRequirements === 3, 'summary should record optimization completion blocking reasons with missing proof requirements'); assert(summary.observed.optimizationCompletionMissingProofRequirementCount === 14, 'summary should record optimization completion missing proof requirement count'); assert(summary.observed.proofGapClosureHistorySource.includes('historical-dataset-audit.json'), 'summary should record proof-gap closure history source'); assert(summary.observed.proofGapClosureCustomerEffectSource.includes('customer-effect-summary.json'), 'summary should record proof-gap closure customer-effect source'); assert(summary.observed.proofGapClosureRecursiveProofArtifactDiscovery === true, 'summary should record proof-gap closure recursive discovery state'); assert(summary.observed.optimizationCompletionHistorySource.includes('historical-dataset-audit.json'), 'summary should record optimization completion history source'); assert(summary.observed.optimizationCompletionCustomerEffectSource.includes('customer-effect-summary.json'), 'summary should record optimization completion customer-effect source'); assert(summary.observed.optimizationCompletionRecursiveProofArtifactDiscovery === true, 'summary should record optimization completion recursive discovery state'); assert(summary.observed.optimizationCompletionCanClaimTihaoRateImproved === false, 'summary should record tihao-rate claim boundary'); assert(summary.observed.optimizationCompletionCanClaimCustomerEffectAchieved === false, 'summary should record customer-effect claim boundary'); assert(summary.observed.optimizationCompletionCanClaimManualSupplementReduced === false, 'summary should record manual-supplement claim boundary'); assert(summary.observed.optimizationCompletionVideoAbPreflightReadyForVideoAb === false, 'summary should record optimization completion video A/B preflight readiness'); assert(summary.observed.optimizationCompletionVideoAbPreflightFailureCount === 4, 'summary should record optimization completion video A/B preflight failure count'); assert(summary.observed.businessExecutionIndexPassed === true, 'summary should record business execution index pass state'); assert(summary.observed.businessExecutionIndexRowCount === 15, 'summary should record business execution index row count'); assert(summary.observed.businessExecutionIndexActionRowCount === 5, 'summary should record business execution index action row count'); assert(summary.observed.businessExecutionIndexRepairRowCount === 2, 'summary should record business execution index repair row count'); assert(summary.observed.businessExecutionIndexOperatorPackOwnerArtifactRowCount === 3, 'summary should record business execution operator owner artifact row count'); assert(summary.observed.businessExecutionIndexOperatorPackOwnerArtifactCount === 3, 'summary should record business execution operator owner artifact count'); assert(summary.observed.businessExecutionIndexFieldOwnerRowCount === 1, 'summary should record business execution index field owner row count'); assert(summary.observed.businessExecutionIndexRecheckCommandRowCount === 1, 'summary should record business execution index recheck command row count'); assert(summary.observed.businessExecutionIndexProofOpenCount === 5, 'summary should record business execution index proof open count'); assert(summary.observed.businessExecutionIndexDirectCustomerProof === false, 'summary should record business execution index proof boundary'); assert(summary.observed.businessExecutionIndexLongRunReadinessSummary.includes('long-run-readiness-summary.json'), 'summary should record business execution longrun readiness source'); assert(summary.observed.businessExecutionIndexLongRunReadinessReport.includes('long-run-readiness-report.md'), 'summary should record business execution longrun readiness report'); assert(summary.observed.businessExecutionIndexLongRunReadinessReady === false, 'summary should record business execution longrun ready state'); assert(summary.observed.businessExecutionIndexLongRunReadinessFailCount === 5, 'summary should record business execution longrun fail count'); assert(summary.observed.businessExecutionIndexOptimizationCompletionSummary.includes('optimization-completion-summary.json'), 'summary should record business execution optimization completion source'); assert(summary.observed.businessExecutionIndexOptimizationCompletionReport.includes('optimization-completion-report.md'), 'summary should record business execution optimization completion report'); assert(summary.observed.businessExecutionIndexOptimizationCompletionReadyForClaim === false, 'summary should record business execution optimization ready-for-claim state'); assert(summary.observed.businessExecutionIndexOptimizationCompletionBlockingReasonCount === 3, 'summary should record business execution optimization blocking reason count'); assert(summary.observed.handoffBusinessExecutionIndexLongRunReadinessReport.includes('long-run-readiness-report.md'), 'summary should record handoff business execution longrun readiness report'); assert(summary.observed.handoffBusinessExecutionIndexLongRunReadinessSummary.includes('long-run-readiness-summary.json'), 'summary should record handoff business execution longrun readiness summary'); assert(summary.observed.handoffBusinessExecutionIndexLongRunReadinessStatus === 'blocked', 'summary should record handoff business execution longrun status'); assert(summary.observed.handoffBusinessExecutionIndexLongRunReadinessReady === false, 'summary should record handoff business execution longrun ready state'); assert(summary.observed.handoffBusinessExecutionIndexLongRunReadinessFailCount === 5, 'summary should record handoff business execution longrun fail count'); assert(summary.observed.handoffBusinessExecutionIndexOperatorPackOwnerArtifactCount === 3, 'summary should record handoff business execution operator owner artifact count'); assert(summary.observed.handoffOptimizationCompletionReport.includes('optimization-completion-report.md'), 'summary should record handoff optimization completion report'); assert(summary.observed.handoffOptimizationCompletionReadyForClaim === false, 'summary should record handoff optimization ready-for-claim state'); assert(summary.observed.handoffOptimizationCompletionProofGapOpenCount === 5, 'summary should record handoff optimization proof-gap count'); assert(summary.observed.handoffOptimizationCompletionBlockingReasonCount === 3, 'summary should record handoff optimization blocking reason count'); assert(summary.observed.handoffBusinessExecutionIndexOptimizationCompletionReport.includes('optimization-completion-report.md'), 'summary should record handoff business execution optimization completion report'); assert(summary.observed.handoffBusinessExecutionIndexOptimizationCompletionSummary.includes('optimization-completion-summary.json'), 'summary should record handoff business execution optimization completion summary'); assert(summary.observed.handoffBusinessExecutionIndexOptimizationCompletionStatus === 'blocked', 'summary should record handoff business execution optimization completion status'); assert(summary.observed.handoffBusinessExecutionIndexOptimizationCompletionReadyForClaim === false, 'summary should record handoff business execution optimization ready-for-claim state'); assert(summary.observed.handoffBusinessExecutionIndexOptimizationCompletionBlockingReasonCount === 3, 'summary should record handoff business execution optimization blocking reason count'); assert(summary.observed.realProofIntakeBundlePassed === true, 'summary should record real proof intake bundle pass state'); assert(summary.observed.realProofIntakeBundleComplete === false, 'summary should record real proof intake bundle incomplete state'); assert(summary.observed.realProofIntakeBundleProofOpenCount === 5, 'summary should record real proof intake bundle proof open count'); assert(summary.observed.realProofIntakeBundleExportRowCount === 37, 'summary should record real proof intake bundle export row count'); assert(summary.observed.realProofIntakeBundleRecheckCommandCount === 6, 'summary should record real proof intake bundle recheck command count'); assert(summary.observed.realProofIntakeBundleOperatorPackEvidenceRowCount === 5, 'summary should record real proof bundle operator evidence row count'); assert(summary.observed.realProofIntakeBundleOperatorPackNextActionCount === 5, 'summary should record real proof bundle operator next action count'); assert(summary.observed.realProofIntakeBundleOperatorPackMissingProofRequirementCount === 23, 'summary should record real proof bundle operator missing proof requirement count'); assert(summary.observed.realProofIntakeBundleOperatorPackOwnerArtifactCount === 3, 'summary should record real proof bundle operator owner artifact count'); assert(summary.observed.realProofIntakeBundleLongRunReadinessReport.includes('long-run-readiness-report.md'), 'summary should record real proof bundle longrun readiness report'); assert(summary.observed.realProofIntakeBundleLongRunReadinessReady === false, 'summary should record real proof bundle longrun ready state'); assert(summary.observed.realProofIntakeBundleLongRunReadinessFailCount === 5, 'summary should record real proof bundle longrun fail count'); assert(summary.observed.realProofIntakeBundleLongRunReadinessProofLevel === 'not_business_proof', 'summary should record real proof bundle longrun proof level'); assert(summary.observed.realProofIntakeBundleLongRunReadinessDirectCustomerProof === false, 'summary should record real proof bundle longrun proof boundary'); assert(summary.observed.realProofIntakeBundleVideoAbPreflightContext === true, 'summary should record real proof bundle video A/B preflight context'); assert(summary.observed.intakeFieldChecklistPassed === true, 'summary should record intake field checklist pass state'); assert(summary.observed.intakeFieldChecklistItemCount === 4, 'summary should record intake field checklist item count'); assert(summary.observed.intakeFieldChecklistMissingRequiredCount === 2, 'summary should record intake field checklist missing required count'); assert(summary.observed.intakeFieldChecklistPlaceholderCount === 2, 'summary should record intake field checklist placeholder count'); assert(summary.observed.intakeFieldChecklistDirectCustomerProof === false, 'summary should record intake field checklist proof boundary'); assert(summary.observed.intakeFieldChecklistOwnerGroupCount === 2, 'summary should record intake field checklist owner group count'); assert(summary.observed.intakeFieldChecklistRecheckCommandCount === 4, 'summary should record intake field checklist recheck command count'); assert(summary.observed.proofGapSoftwareFormPassed === true, 'summary should record proof-gap software form pass state'); assert(summary.observed.proofGapSoftwareFormRowCount === 5, 'summary should record proof-gap software form row count'); assert(summary.observed.proofGapSoftwareFormDuplicateIdCount === 0, 'summary should record proof-gap software form duplicate id count'); assert(summary.observed.latestFormIndexPassed === true, 'summary should record latest form index pass state'); assert(summary.observed.latestFormIndexPrimaryForm.includes('tihao-proof-gap-software-form.csv'), 'summary should record indexed proof form'); assert(summary.observed.latestFormIndexClientList.includes('software-client-list.final.csv'), 'summary should record indexed client list'); assert(summary.observed.latestFormIndexClientListRowCount === 28, 'summary should record indexed client list row count'); assert(summary.observed.latestFormIndexClientListSourceDuplicateRemovedCount === 32, 'summary should record source duplicate rows removed'); assert(summary.observed.latestFormIndexClientListFinalDuplicateGroupCount === 0, 'summary should record zero final duplicate groups'); assert(summary.observed.latestFormIndexClientListDuplicateCountMeaning === 'source_duplicate_removed_count', 'summary should record duplicate count meaning'); assert(summary.observed.latestFormIndexClientListRankContinuous === true, 'summary should record client list rank continuity'); assert(summary.observed.latestFormIndexClientListDirectCustomerProof === false, 'summary should record client list proof boundary'); assert(summary.observed.latestFormIndexBusinessExecutionIndex.includes('business-execution-index.md'), 'summary should record indexed business execution index'); assert(summary.observed.latestFormIndexBusinessExecutionIndexOperatorPackOwnerArtifactCount === 3, 'summary should record indexed business execution operator owner artifact count'); assert(summary.observed.latestFormIndexBusinessExecutionIndexFieldOwnerRowCount === 1, 'summary should record indexed business execution index field owner row count'); assert(summary.observed.latestFormIndexBusinessExecutionIndexRecheckCommandRowCount === 1, 'summary should record indexed business execution index recheck command row count'); assert(summary.observed.latestFormIndexIntakeFieldChecklist.includes('intake-field-checklist.md'), 'summary should record indexed intake field checklist'); assert(summary.observed.latestFormIndexIntakeFieldChecklistItemCount === 4, 'summary should record indexed intake field checklist item count'); assert(summary.observed.latestFormIndexIntakeFieldChecklistOwnerGroupCount === 2, 'summary should record indexed intake field checklist owner group count'); assert(summary.observed.latestFormIndexIntakeFieldChecklistRecheckCommandCount === 4, 'summary should record indexed intake field checklist recheck command count'); assert(summary.observed.latestFormIndexChinesePlanDoc.includes('tihao-experience-optimization-plan.zh-CN.md'), 'summary should record indexed Chinese optimization plan'); assert(summary.observed.latestFormIndexChineseActionOrderDoc.includes('business-proof-action-order.zh-CN.md'), 'summary should record indexed Chinese action order'); assert(summary.observed.latestFormIndexDataRepairCsv.includes('intake-readiness-repair-actions.csv'), 'summary should record data repair csv'); assert(summary.observed.latestFormIndexDataRepairActionCount === 9, 'summary should record data repair action count'); assert(summary.observed.latestFormIndexVideoRepairCsv.includes('video-resource-repair-actions.csv'), 'summary should record video repair csv'); assert(summary.observed.latestFormIndexVideoRepairActionCount === 1, 'summary should record video repair action count'); assert(summary.observed.latestFormIndexHomepageRepairCsv.includes('homepage-evidence-repair-actions.csv'), 'summary should record homepage repair csv'); assert(summary.observed.latestFormIndexHomepageRepairActionCount === 2, 'summary should record homepage repair action count'); assert(summary.observed.latestFormIndexOwnerRepairSummary.includes('intake-readiness-repair-actions.csv'), 'summary should record latest form owner data repair artifact'); assert(summary.observed.latestFormIndexOwnerRepairSummary.includes('video-resource-repair-actions.csv'), 'summary should record latest form owner video repair artifact'); assert(summary.observed.latestFormIndexOwnerRepairSummary.includes('homepage-evidence-repair-actions.csv'), 'summary should record latest form owner homepage repair artifact'); assert(summary.observed.latestFormIndexProofGapOperatorPack.includes('proof-gap-operator-pack.md'), 'summary should record latest form proof-gap operator pack report'); assert(summary.observed.latestFormIndexProofGapOperatorPackOpenCount === 5, 'summary should record latest form proof-gap operator pack open count'); assert(summary.observed.latestFormIndexProofGapOperatorPackOwnerGroupCount === 3, 'summary should record latest form proof-gap operator pack owner group count'); assert(summary.observed.latestFormIndexProofGapOperatorPackOwnerArtifactCount === 3, 'summary should record latest form proof-gap operator pack owner artifact count'); assert(summary.observed.latestFormIndexProofGapOperatorPackRecheckCommandCount === 7, 'summary should record latest form proof-gap operator pack recheck command count'); assert(summary.observed.latestFormIndexProofGapOperatorPackEvidenceRowCount === 5, 'summary should record latest form proof-gap operator pack evidence row count'); assert(summary.observed.latestFormIndexProofGapOperatorPackNextActionCount === 5, 'summary should record latest form proof-gap operator pack next action count'); assert(summary.observed.latestFormIndexProofGapOperatorPackGapIds.includes('historical-dataset'), 'summary should record latest form proof-gap operator pack gap IDs'); assert(summary.observed.latestFormIndexNextActionsTopCount === 5, 'summary should record latest form next actions top action count'); assert(summary.observed.latestFormIndexNextActionsProofGapOpenCount === 5, 'summary should record latest form next actions proof-gap open count'); assert(summary.observed.latestFormIndexPlanExecutionStatusOperatorPackOwnerArtifactCount === 3, 'summary should record latest form plan execution operator owner artifact count'); assert(summary.observed.latestFormIndexLongRunReadinessReport.includes('long-run-readiness-report.md'), 'summary should record latest form longrun readiness report'); assert(summary.observed.latestFormIndexLongRunReadinessReady === false, 'summary should record latest form longrun ready state'); assert(summary.observed.latestFormIndexLongRunReadinessFailCount === 5, 'summary should record latest form longrun fail count'); assert(summary.observed.latestFormIndexLongRunReadinessProofLevel === 'not_business_proof', 'summary should record latest form longrun proof level'); assert(summary.observed.latestFormIndexLongRunReadinessDirectCustomerProof === false, 'summary should record latest form longrun proof boundary'); assert(summary.observed.localSeedToIntakeWorklistProofLevel === 'not_business_proof', 'summary should record local seed worklist proof level'); assert(summary.observed.localSeedToIntakeWorklistDirectCustomerProof === false, 'summary should record local seed worklist proof boundary'); assert(summary.observed.localSeedToIntakeWorklistCanCloseProofGap === false, 'summary should record local seed worklist proof-gap boundary'); assert(summary.observed.localSeedToIntakeWorklistHistoryDraftRows === 1, 'summary should record local seed worklist history rows'); assert(summary.observed.localSeedToIntakeWorklistCandidateSeedRows === 12, 'summary should record local seed worklist candidate rows'); assert(summary.observed.localSeedToIntakeWorklistVideoCandidateNeedsResourceRows === 3, 'summary should record local seed worklist video candidate needs resource rows'); assert(summary.observed.latestFormIndexLocalSeedToIntakeWorklistMarkdown.includes('local-seed-to-intake-worklist.md'), 'summary should record latest form local seed worklist markdown'); assert(summary.observed.latestFormIndexLocalSeedToIntakeWorklistHistoryDraftRows === 1, 'summary should record latest form local seed worklist history rows'); assert(summary.observed.latestFormIndexLocalSeedToIntakeWorklistCandidateSeedRows === 12, 'summary should record latest form local seed worklist candidate rows'); assert(summary.observed.latestFormIndexLocalSeedToIntakeWorklistVideoCandidateNeedsResourceRows === 3, 'summary should record latest form local seed worklist video candidate resource rows'); assert(summary.observed.latestFormIndexLocalSeedToIntakeWorklistCanCloseProofGap === false, 'summary should record latest form local seed worklist proof-gap boundary'); assert(summary.observed.realProofClosureWorkOrderProofLevel === 'not_business_proof', 'summary should record real proof closure work order proof level'); assert(summary.observed.realProofClosureWorkOrderDirectCustomerProof === false, 'summary should record real proof closure work order direct proof boundary'); assert(summary.observed.realProofClosureWorkOrderCanCloseProofGap === false, 'summary should record real proof closure work order proof-gap boundary'); assert(summary.observed.realProofClosureWorkOrderRequiresHumanRealMaterial === true, 'summary should record real proof closure work order human material requirement'); assert(summary.observed.realProofClosureWorkOrderWorkOrderCount === 19, 'summary should record real proof closure work order count'); assert(summary.observed.realProofClosureWorkOrderOwnerArtifactCount === 3, 'summary should record real proof closure work order owner artifact count'); assert(summary.observed.realProofClosureWorkOrderProofGapOpenCount === 5, 'summary should record real proof closure work order open proof gap count'); assert(summary.observed.realProofClosureWorkOrderIntakeFailureCount === 9, 'summary should record real proof closure work order intake failure count'); assert(summary.observed.realProofClosureWorkOrderRealCandidateRows === 0, 'summary should record real proof closure work order real candidate rows'); assert(summary.observed.realProofClosureWorkOrderVideoAbPreflightContext === true, 'summary should record real proof closure work order video A/B preflight context'); assert(summary.observed.latestFormIndexRealProofClosureWorkOrderMarkdown.includes('real-proof-closure-work-order.md'), 'summary should record latest form real proof closure work order markdown'); assert(summary.observed.latestFormIndexRealProofClosureWorkOrderWorkOrderCount === 19, 'summary should record latest form real proof closure work order count'); assert(summary.observed.latestFormIndexRealProofClosureWorkOrderOwnerArtifactCount === 3, 'summary should record latest form real proof closure work order owner artifact count'); assert(summary.observed.latestFormIndexRealProofClosureWorkOrderCanCloseProofGap === false, 'summary should record latest form real proof closure work order proof-gap boundary'); assert(summary.observed.handoffChinesePlanDoc.includes('tihao-experience-optimization-plan.zh-CN.md'), 'summary should record handoff Chinese optimization plan'); assert(summary.observed.handoffChineseActionOrderDoc.includes('business-proof-action-order.zh-CN.md'), 'summary should record handoff Chinese action order'); assert(summary.observed.handoffLatestFormIndexOwnerGroupCount === 2, 'summary should record handoff latest form owner group count'); assert(summary.observed.handoffLatestFormIndexRecheckCommandCount === 4, 'summary should record handoff latest form recheck command count'); assert(summary.observed.handoffLatestFormIndexNextActionsTopCount === 5, 'summary should record handoff latest form next actions top action count'); assert(summary.observed.handoffLatestFormIndexNextActionsProofGapOpenCount === 5, 'summary should record handoff latest form next actions proof-gap open count'); assert(summary.observed.handoffLocalSeedToIntakeWorklistMarkdown.includes('local-seed-to-intake-worklist.md'), 'summary should record handoff local seed worklist markdown'); assert(summary.observed.handoffLocalSeedToIntakeWorklistHistoryDraftRows === 1, 'summary should record handoff local seed worklist history rows'); assert(summary.observed.handoffLocalSeedToIntakeWorklistCandidateSeedRows === 12, 'summary should record handoff local seed worklist candidate rows'); assert(summary.observed.handoffLocalSeedToIntakeWorklistVideoCandidateNeedsResourceRows === 3, 'summary should record handoff local seed worklist video candidate resource rows'); assert(summary.observed.handoffLocalSeedToIntakeWorklistCanCloseProofGap === false, 'summary should record handoff local seed worklist proof-gap boundary'); assert(summary.observed.handoffLatestFormIndexLocalSeedToIntakeWorklistMarkdown.includes('local-seed-to-intake-worklist.md'), 'summary should record handoff latest form local seed worklist markdown'); assert(summary.observed.handoffLatestFormIndexLocalSeedToIntakeWorklistHistoryDraftRows === 1, 'summary should record handoff latest form local seed worklist history rows'); assert(summary.observed.handoffLatestFormIndexLocalSeedToIntakeWorklistCandidateSeedRows === 12, 'summary should record handoff latest form local seed worklist candidate rows'); assert(summary.observed.handoffLatestFormIndexLocalSeedToIntakeWorklistVideoCandidateNeedsResourceRows === 3, 'summary should record handoff latest form local seed worklist video candidate resource rows'); assert(summary.observed.handoffLatestFormIndexLocalSeedToIntakeWorklistCanCloseProofGap === false, 'summary should record handoff latest form local seed worklist proof-gap boundary'); assert(summary.observed.handoffRealProofClosureWorkOrderMarkdown.includes('real-proof-closure-work-order.md'), 'summary should record handoff real proof closure work order markdown'); assert(summary.observed.handoffRealProofClosureWorkOrderWorkOrderCount === 19, 'summary should record handoff real proof closure work order count'); assert(summary.observed.handoffRealProofClosureWorkOrderOwnerArtifactCount === 3, 'summary should record handoff real proof closure work order owner artifact count'); assert(summary.observed.handoffRealProofClosureWorkOrderCanCloseProofGap === false, 'summary should record handoff real proof closure work order proof-gap boundary'); assert(summary.observed.handoffLatestFormIndexRealProofClosureWorkOrderMarkdown.includes('real-proof-closure-work-order.md'), 'summary should record handoff latest form real proof closure work order markdown'); assert(summary.observed.handoffLatestFormIndexRealProofClosureWorkOrderWorkOrderCount === 19, 'summary should record handoff latest form real proof closure work order count'); assert(summary.observed.handoffLatestFormIndexRealProofClosureWorkOrderOwnerArtifactCount === 3, 'summary should record handoff latest form real proof closure work order owner artifact count'); assert(summary.observed.handoffLatestFormIndexRealProofClosureWorkOrderCanCloseProofGap === false, 'summary should record handoff latest form real proof closure work order proof-gap boundary'); assert(summary.observed.handoffLongRunReadinessReport.includes('long-run-readiness-report.md'), 'summary should record handoff longrun readiness report'); assert(summary.observed.handoffLongRunReadinessReady === false, 'summary should record handoff longrun ready state'); assert(summary.observed.handoffLongRunReadinessFailCount === 5, 'summary should record handoff longrun fail count'); assert(summary.observed.handoffLongRunReadinessProofLevel === 'not_business_proof', 'summary should record handoff longrun proof level'); assert(summary.observed.handoffLongRunReadinessDirectCustomerProof === false, 'summary should record handoff longrun proof boundary'); assert(summary.observed.handoffLatestFormIndexLongRunReadinessReport.includes('long-run-readiness-report.md'), 'summary should record handoff latest form longrun readiness report'); assert(summary.observed.handoffLatestFormIndexLongRunReadinessReady === false, 'summary should record handoff latest form longrun ready state'); assert(summary.observed.handoffLatestFormIndexLongRunReadinessFailCount === 5, 'summary should record handoff latest form longrun fail count'); assert(summary.observed.handoffPlanExecutionStatusOperatorPackOwnerArtifactCount === 3, 'summary should record handoff plan execution operator owner artifact count'); assert(summary.observed.handoffOwnerRepairSummary.includes('intake-readiness-repair-actions.csv'), 'summary should record handoff owner data repair artifact'); assert(summary.observed.handoffOwnerRepairSummary.includes('video-resource-repair-actions.csv'), 'summary should record handoff owner video repair artifact'); assert(summary.observed.handoffOwnerRepairSummary.includes('homepage-evidence-repair-actions.csv'), 'summary should record handoff owner homepage repair artifact'); assert(summary.observed.handoffProofGapOperatorPackReport.includes('proof-gap-operator-pack.md'), 'summary should record handoff proof-gap operator pack report'); assert(summary.observed.handoffProofGapOperatorPackSummary.includes('proof-gap-operator-pack-summary.json'), 'summary should record handoff proof-gap operator pack summary'); assert(summary.observed.handoffProofGapOperatorPackOpenCount === 5, 'summary should record handoff proof-gap operator pack open count'); assert(summary.observed.handoffProofGapOperatorPackOwnerGroupCount === 3, 'summary should record handoff proof-gap operator pack owner group count'); assert(summary.observed.handoffProofGapOperatorPackOwnerArtifactCount === 3, 'summary should record handoff proof-gap operator pack owner artifact count'); assert(summary.observed.handoffProofGapOperatorPackRecheckCommandCount === 7, 'summary should record handoff proof-gap operator pack recheck command count'); assert(summary.observed.handoffProofGapOperatorPackEvidenceRowCount === 5, 'summary should record handoff proof-gap operator pack evidence row count'); assert(summary.observed.handoffProofGapOperatorPackNextActionCount === 5, 'summary should record handoff proof-gap operator pack next action count'); assert(summary.observed.handoffProofGapOperatorPackGapIds.includes('manual-review-and-customer-effect'), 'summary should record handoff proof-gap operator pack gap IDs'); assert(summary.observed.proofGapClosureOpenCount === 5, 'summary should record proof-gap closure open count'); assert(summary.observed.proofGapClosureBusinessOpenCount === 5, 'summary should record proof-gap closure business open count'); assert(summary.observed.proofGapClosureBusinessClosedCount === 0, 'summary should record proof-gap closure business closed count'); assert(summary.observed.proofGapClosureBusinessGapCount === 5, 'summary should record proof-gap closure business gap count'); assert(summary.observed.proofGapClosureTotalRows === 6, 'summary should record proof-gap closure total rows'); assert(summary.observed.proofGapClosurePrecheckOpenCount === 1, 'summary should record proof-gap closure precheck open count separately'); assert(summary.observed.proofGapClosureCountSemanticsOpenCount === 'business_gap_open_count_excludes_precheck_rows', 'summary should record proof-gap closure count semantics'); assert(summary.observed.proofGapClosureVideoAbPreflightReadyForVideoAb === false, 'summary should record proof-gap closure video A/B preflight readiness'); assert(summary.observed.proofGapClosureVideoAbPreflightFailureCount === 4, 'summary should record proof-gap closure video A/B preflight failure count'); assert(summary.observed.proofGapClosureOpenRowsWithMissingProofRequirements === 5, 'summary should record proof-gap closure open rows with missing proof requirements'); assert(summary.observed.handoffProofGapClosureOpenCount === 5, 'summary should record handoff proof-gap closure open count'); assert(summary.observed.handoffProofGapClosureBusinessOpenCount === 5, 'summary should record handoff proof-gap closure business open count'); assert(summary.observed.handoffProofGapClosureBusinessClosedCount === 0, 'summary should record handoff proof-gap closure business closed count'); assert(summary.observed.handoffProofGapClosureBusinessGapCount === 5, 'summary should record handoff proof-gap closure business gap count'); assert(summary.observed.handoffProofGapClosureTotalRows === 6, 'summary should record handoff proof-gap closure total rows'); assert(summary.observed.handoffProofGapClosurePrecheckOpenCount === 1, 'summary should record handoff proof-gap closure precheck open count separately'); assert(summary.observed.handoffProofGapClosureCountSemanticsOpenCount === 'business_gap_open_count_excludes_precheck_rows', 'summary should record handoff proof-gap closure count semantics'); assert(summary.observed.handoffProofGapClosureRows === 6, 'summary should record handoff proof-gap closure rows'); assert(summary.observed.handoffVideoAbMissingProofCount === 6, 'summary should record handoff video A/B missing proof requirements'); assert(summary.observed.handoffProofGapClosureOpenRowsWithMissingProofRequirements === 5, 'summary should record handoff proof-gap closure open rows with missing proof requirements'); assert(summary.observed.feedbackLoopClosureDirectCustomerProof === false, 'summary should record feedback loop proof boundary'); assert(summary.observed.feedbackLoopClosureLeakedCount === 0, 'summary should record feedback loop leaked count'); assert(summary.observed.handoffFeedbackLoopClosureDirectCustomerProof === false, 'summary should record handoff feedback loop proof boundary'); assert(summary.observed.homepageEvidenceReadinessReady === false, 'summary should record homepage readiness state'); assert(summary.observed.homepageEvidenceReadinessDirectCustomerProof === false, 'summary should record homepage readiness proof boundary'); assert(summary.observed.homepageEvidenceReadinessProofLevel === 'not_business_proof', 'summary should record homepage readiness proof level'); assert(summary.observed.homepageEvidenceReadinessFailureCount === 2, 'summary should record homepage readiness failure count'); assert(summary.observed.homepageEvidenceReadinessRepairActionCount === 2, 'summary should record homepage readiness repair action count'); assert(summary.observed.handoffHomepageEvidenceReadinessDirectCustomerProof === false, 'summary should record handoff homepage readiness proof boundary'); assert(summary.observed.planExecutionStatusOperatorPackOwnerArtifactCount === 3, 'summary should record plan execution operator owner artifact count'); assert(summary.observed.planExecutionStatusBusinessExecutionOperatorPackOwnerArtifactRowCount === 3, 'summary should record plan execution business execution operator owner artifact row count'); assert(summary.checks.some(item => item.id.startsWith('log-')), 'summary should include implementation-log hint checks'); assert(report.includes('# 每轮沉淀审计'), 'report should be Chinese'); assert(report.includes('proofGap.unresolvedCount'), 'report should show proof-gap unresolved count'); assert(report.includes('proofGap.templateRowsReady'), 'report should show proof-gap template row readiness'); assert(report.includes('proofGap.templateColumnsReady'), 'report should show proof-gap template column readiness'); assert(report.includes('proofGapOperatorPack.gapIds'), 'report should show proof-gap operator pack gap IDs'); assert(report.includes('proofGapOperatorPack.ownerArtifactCount'), 'report should show proof-gap operator pack owner artifact count'); assert(report.includes('proofGapOperatorPack.recheckCommandCount'), 'report should show proof-gap operator pack recheck command count'); assert(report.includes('proofGapOperatorPack.evidenceRowCount'), 'report should show proof-gap operator pack evidence row count'); assert(report.includes('proofGapOperatorPack.nextActionCount'), 'report should show proof-gap operator pack next action count'); assert(report.includes('proofGapOperatorPack.openRowsWithMissingProofRequirements'), 'report should show proof-gap operator pack missing proof row count'); assert(report.includes('proofGapOperatorPack.videoAbPreflightContext'), 'report should show proof-gap operator pack video A/B preflight context'); assert(report.includes('intakeReadiness.ready'), 'report should show intake readiness state'); assert(report.includes('longRunReadiness.ready'), 'report should show longrun readiness state'); assert(report.includes('businessProofProgress.blocked_by_external_data'), 'report should show business proof progress blocked count'); assert(report.includes('businessProofProgress.operatorPackOwnerArtifactCount'), 'report should show business proof progress operator owner artifact count'); assert(report.includes('handoff.businessProofProgressOperatorPackOwnerArtifactCount'), 'report should show handoff business proof progress operator owner artifact count'); assert(report.includes('businessProofNextActions.count'), 'report should show business proof next actions count'); assert(report.includes('businessProofNextActions.topActionCount'), 'report should show business proof next actions top action count'); assert(report.includes('businessProofNextActions.withMissingProofRequirements'), 'report should show business proof next actions missing proof requirement count'); assert(report.includes('handoff.businessProofNextActions.count'), 'report should show handoff business proof next actions count'); assert(report.includes('handoff.businessProofNextActions.topActionCount'), 'report should show handoff business proof next top action count'); assert(report.includes('handoff.businessProofNextActions.proofGapOpenCount'), 'report should show handoff business proof next proof gap open count'); assert(report.includes('optimizationCompletion.readyForClaim'), 'report should show optimization ready-for-claim state'); assert(report.includes('optimizationCompletion.blockingReasonsWithMissingProofRequirements'), 'report should show optimization completion missing proof row count'); assert(report.includes('optimizationCompletion.canClaim.tihaoRateImproved'), 'report should show tihao-rate claim boundary'); assert(report.includes('optimizationCompletion.sourceFiles.history'), 'report should show optimization completion history source'); assert(report.includes('optimizationCompletion.sourceFiles.customerEffect'), 'report should show optimization completion customer-effect source'); assert(report.includes('optimizationCompletion.recursiveProofArtifactDiscovery'), 'report should show optimization completion recursive proof artifact discovery'); assert(report.includes('optimizationCompletion.videoAbPreflightFailureCount'), 'report should show optimization completion video A/B preflight failure count'); assert(report.includes('businessExecutionIndex.rowCount'), 'report should show business execution index row count'); assert(report.includes('businessExecutionIndex.operatorPackOwnerArtifactCount'), 'report should show business execution operator owner artifact count'); assert(report.includes('businessExecutionIndex.fieldOwnerRowCount'), 'report should show business execution index field owner row count'); assert(report.includes('businessExecutionIndex.recheckCommandRowCount'), 'report should show business execution index recheck command row count'); assert(report.includes('businessExecutionIndex.directCustomerProof'), 'report should show business execution index proof boundary'); assert(report.includes('businessExecutionIndex.longRunReadinessReport'), 'report should show business execution longrun readiness report'); assert(report.includes('businessExecutionIndex.longRunReadinessReady'), 'report should show business execution longrun ready state'); assert(report.includes('businessExecutionIndex.optimizationCompletionReport'), 'report should show business execution optimization completion report'); assert(report.includes('businessExecutionIndex.optimizationCompletionReadyForClaim'), 'report should show business execution optimization ready-for-claim state'); assert(report.includes('handoff.businessExecutionIndex.longRunReadinessReport'), 'report should show handoff business execution longrun readiness report'); assert(report.includes('handoff.businessExecutionIndex.longRunReadinessStatus'), 'report should show handoff business execution longrun readiness status'); assert(report.includes('handoff.businessExecutionIndex.operatorPackOwnerArtifactCount'), 'report should show handoff business execution operator owner artifact count'); assert(report.includes('handoff.optimizationCompletionReport'), 'report should show handoff optimization completion report'); assert(report.includes('handoff.businessExecutionIndex.optimizationCompletionReport'), 'report should show handoff business execution optimization completion report'); assert(report.includes('handoff.businessExecutionIndex.optimizationCompletionStatus'), 'report should show handoff business execution optimization completion status'); assert(report.includes('realProofIntakeBundle.exportRowCount'), 'report should show real proof intake bundle export row count'); assert(report.includes('realProofIntakeBundle.operatorPackEvidenceRowCount'), 'report should show real proof bundle operator evidence row count'); assert(report.includes('realProofIntakeBundle.operatorPackNextActionCount'), 'report should show real proof bundle operator next action count'); assert(report.includes('realProofIntakeBundle.operatorPackOwnerArtifactCount'), 'report should show real proof bundle operator owner artifact count'); assert(report.includes('realProofIntakeBundle.longRunReadinessReport'), 'report should show real proof bundle longrun readiness report'); assert(report.includes('realProofIntakeBundle.longRunReadinessReady'), 'report should show real proof bundle longrun ready state'); assert(report.includes('realProofIntakeBundle.videoAbPreflightContext'), 'report should show real proof bundle video A/B preflight context'); assert(report.includes('intakeFieldChecklist.itemCount'), 'report should show intake field checklist item count'); assert(report.includes('intakeFieldChecklist.directCustomerProof'), 'report should show intake field checklist proof boundary'); assert(report.includes('intakeFieldChecklist.ownerGroupCount'), 'report should show intake field checklist owner group count'); assert(report.includes('intakeFieldChecklist.recheckCommandCount'), 'report should show intake field checklist recheck command count'); assert(report.includes('proofGapSoftwareForm.passed'), 'report should show proof-gap software form pass state'); assert(report.includes('proofGapSoftwareForm.rowCount'), 'report should show proof-gap software form row count'); assert(report.includes('latestFormIndex.passed'), 'report should show latest form index pass state'); assert(report.includes('latestFormIndex.primaryForm'), 'report should show indexed proof form'); assert(report.includes('latestFormIndex.clientListFinalDuplicateGroupCount'), 'report should show client list final duplicate group count'); assert(report.includes('latestFormIndex.clientListDuplicateCountMeaning'), 'report should show client list duplicate count meaning'); assert(report.includes('latestFormIndex.businessExecutionIndex'), 'report should show indexed business execution index'); assert(report.includes('latestFormIndex.businessExecutionIndexOperatorPackOwnerArtifactCount'), 'report should show indexed business execution operator owner artifact count'); assert(report.includes('latestFormIndex.businessExecutionIndexFieldOwnerRowCount'), 'report should show indexed business execution index field owner row count'); assert(report.includes('latestFormIndex.businessExecutionIndexRecheckCommandRowCount'), 'report should show indexed business execution index recheck command row count'); assert(report.includes('latestFormIndex.intakeFieldChecklist'), 'report should show indexed intake field checklist'); assert(report.includes('latestFormIndex.intakeFieldChecklistOwnerGroupCount'), 'report should show indexed intake field checklist owner group count'); assert(report.includes('latestFormIndex.intakeFieldChecklistRecheckCommandCount'), 'report should show indexed intake field checklist recheck command count'); assert(report.includes('latestFormIndex.chinesePlanDoc'), 'report should show indexed Chinese optimization plan'); assert(report.includes('latestFormIndex.chineseActionOrderDoc'), 'report should show indexed Chinese action order'); assert(report.includes('latestFormIndex.nextActionsTopCount'), 'report should show latest form next actions top action count'); assert(report.includes('latestFormIndex.nextActionsProofGapOpenCount'), 'report should show latest form next actions proof-gap open count'); assert(report.includes('latestFormIndex.dataRepairCsv'), 'report should show data repair csv'); assert(report.includes('latestFormIndex.videoRepairCsv'), 'report should show video repair csv'); assert(report.includes('latestFormIndex.homepageRepairCsv'), 'report should show homepage repair csv'); assert(report.includes('latestFormIndex.ownerRepairSummary'), 'report should show latest form owner repair summary'); assert(report.includes('latestFormIndex.proofGapOperatorPack'), 'report should show latest form proof-gap operator pack'); assert(report.includes('latestFormIndex.proofGapOperatorPackOwnerArtifactCount'), 'report should show latest form proof-gap operator pack owner artifact count'); assert(report.includes('latestFormIndex.planExecutionStatusOperatorPackOwnerArtifactCount'), 'report should show latest form plan execution operator owner artifact count'); assert(report.includes('latestFormIndex.longRunReadinessReport'), 'report should show latest form longrun readiness report'); assert(report.includes('latestFormIndex.longRunReadinessReady'), 'report should show latest form longrun ready state'); assert(report.includes('localSeedToIntakeWorklist.historyDraftRows'), 'report should show local seed worklist history rows'); assert(report.includes('localSeedToIntakeWorklist.candidateSeedRows'), 'report should show local seed worklist candidate rows'); assert(report.includes('latestFormIndex.localSeedToIntakeWorklist'), 'report should show latest form local seed worklist'); assert(report.includes('latestFormIndex.localSeedToIntakeWorklistCanCloseProofGap'), 'report should show latest form local seed worklist proof-gap boundary'); assert(report.includes('realProofClosureWorkOrder.workOrderCount'), 'report should show real proof closure work order count'); assert(report.includes('realProofClosureWorkOrder.canCloseProofGap'), 'report should show real proof closure work order proof-gap boundary'); assert(report.includes('realProofClosureWorkOrder.videoAbPreflightContext'), 'report should show real proof closure work order video A/B preflight context'); assert(report.includes('latestFormIndex.realProofClosureWorkOrder'), 'report should show latest form real proof closure work order'); assert(report.includes('handoff.realProofClosureWorkOrder'), 'report should show handoff real proof closure work order'); assert(report.includes('handoff.latestFormIndex.realProofClosureWorkOrder'), 'report should show handoff latest form real proof closure work order'); assert(report.includes('handoff.chinesePlanDoc'), 'report should show handoff Chinese optimization plan'); assert(report.includes('handoff.chineseActionOrderDoc'), 'report should show handoff Chinese action order'); assert(report.includes('handoff.latestFormIndex.ownerGroupCount'), 'report should show handoff latest form owner group count'); assert(report.includes('handoff.latestFormIndex.recheckCommandCount'), 'report should show handoff latest form recheck command count'); assert(report.includes('handoff.latestFormIndex.nextActionsTopCount'), 'report should show handoff latest form next actions top action count'); assert(report.includes('handoff.latestFormIndex.nextActionsProofGapOpenCount'), 'report should show handoff latest form next actions proof-gap open count'); assert(report.includes('handoff.localSeedToIntakeWorklist'), 'report should show handoff local seed worklist'); assert(report.includes('handoff.latestFormIndex.localSeedToIntakeWorklist'), 'report should show handoff latest form local seed worklist'); assert(report.includes('handoff.longRunReadinessReport'), 'report should show handoff longrun readiness report'); assert(report.includes('handoff.latestFormIndex.longRunReadinessReport'), 'report should show handoff latest form longrun readiness report'); assert(report.includes('handoff.planExecutionStatusOperatorPackOwnerArtifactCount'), 'report should show handoff plan execution operator owner artifact count'); assert(report.includes('handoff.ownerRepairSummary'), 'report should show handoff owner repair summary'); assert(report.includes('handoff.proofGapOperatorPackReport'), 'report should show handoff proof-gap operator pack report'); assert(report.includes('handoff.proofGapOperatorPackOwnerArtifactCount'), 'report should show handoff proof-gap operator pack owner artifact count'); assert(report.includes('handoffProofGapClosure.openCount'), 'report should show handoff proof-gap closure open count'); assert(report.includes('handoffProofGapClosure.businessOpenCount'), 'report should show handoff proof-gap closure business open count'); assert(report.includes('handoffProofGapClosure.precheckOpenCount'), 'report should show handoff proof-gap closure precheck open count'); assert(report.includes('handoffProofGapClosure.countSemantics.openCount'), 'report should show handoff proof-gap closure count semantics'); assert(report.includes('handoffProofGapClosure.videoAbMissingProofCount'), 'report should show handoff video A/B missing proof count'); assert(report.includes('handoffProofGapClosure.openRowsWithMissingProofRequirements'), 'report should show handoff proof-gap closure missing proof row count'); assert(report.includes('feedbackLoopClosure.directCustomerProof'), 'report should show feedback loop proof boundary'); assert(report.includes('feedbackLoopClosure.leakedCount'), 'report should show feedback loop leaked count'); assert(report.includes('homepageEvidenceReadiness.ready'), 'report should show homepage readiness state'); assert(report.includes('homepageEvidenceReadiness.directCustomerProof'), 'report should show homepage readiness proof boundary'); assert(report.includes('homepageEvidenceReadiness.failureCount'), 'report should show homepage readiness failure count'); assert(report.includes('planExecutionStatus.operatorPackOwnerArtifactCount'), 'report should show plan execution operator owner artifact count'); assert(report.includes('planExecutionStatus.businessExecutionOperatorPackOwnerArtifactRowCount'), 'report should show plan execution business execution operator owner artifact row count'); assert(report.includes('proofGapClosure.openCount'), 'report should show proof-gap closure open count'); assert(report.includes('proofGapClosure.businessOpenCount'), 'report should show proof-gap closure business open count'); assert(report.includes('proofGapClosure.precheckOpenCount'), 'report should show proof-gap closure precheck open count'); assert(report.includes('proofGapClosure.countSemantics.openCount'), 'report should show proof-gap closure count semantics'); assert(report.includes('proofGapClosure.sourceFiles.history'), 'report should show proof-gap closure history source'); assert(report.includes('proofGapClosure.sourceFiles.customerEffect'), 'report should show proof-gap closure customer-effect source'); assert(report.includes('proofGapClosure.recursiveProofArtifactDiscovery'), 'report should show proof-gap closure recursive proof artifact discovery'); assert(report.includes('proofGapClosure.videoAbPreflightFailureCount'), 'report should show proof-gap closure video A/B preflight failure count'); assert(report.includes('proofGapClosure.openRowsWithMissingProofRequirements'), 'report should show proof-gap closure missing proof row count'); assert(report.includes('evidence.video-ab-runtime-preflight'), 'report should show video A/B runtime preflight evidence count'); assert(report.includes('补证操作顺序'), 'report should show proof action order source'); assert(!/sk-[A-Za-z0-9_-]{10,}/.test(report), 'report should not contain model token patterns'); assert(!/r:[A-Za-z0-9]{20,}/.test(report), 'report should not contain Parse sessionToken patterns'); console.log(JSON.stringify({ ok: true, outputDir, passCount: summary.counts.pass, failCount: summary.counts.fail, proofGapUnresolvedCount: summary.observed.proofGapUnresolvedCount, latestFormIndexNextActionsTopCount: summary.observed.latestFormIndexNextActionsTopCount, handoffLatestFormIndexNextActionsTopCount: summary.observed.handoffLatestFormIndexNextActionsTopCount }, null, 2)); } function assert(condition, message) { if (!condition) throw new Error(message); } main();