// Round-trip the actual fixed inputs through the real wrapper/backend in memory only. import fs from 'node:fs'; import crypto from 'node:crypto'; import assert from 'node:assert/strict'; import {createApplication} from '../server/src/core.mjs'; import {runWorkshop} from '../skills/ksf-workshop-runtime/scripts/ksf-workshop.mjs'; const data=JSON.parse(fs.readFileSync('server/references/runtime-data.json','utf8')); const rows={},copy=structuredClone;let seq=0; const store={ async transaction(fn){const before=copy(rows);try{return await fn(this);}catch(e){for(const key of Object.keys(rows))delete rows[key];Object.assign(rows,before);throw e;}}, async lock(){}, async get(name,id){return copy(rows[name]?.find(r=>r.objectId===id)||null);}, async list(name,{where={},afterId,limit=200}={}){return copy((rows[name]||[]).filter(r=>Object.entries(where).every(([key,v])=>JSON.stringify(r[key]??null)===JSON.stringify(v))).filter(r=>!afterId||r.objectId>afterId).sort((a,b)=>a.objectId.localeCompare(b.objectId)).slice(0,limit));}, async create(name,fields){for(const key of Object.keys(fields))assert.ok(data.tables[name][key],name+'.'+key);const row={...copy(fields),objectId:'local'+String(++seq).padStart(7,'0'),createdAt:new Date().toISOString(),updatedAt:new Date().toISOString()};(rows[name]??=[]).push(row);return copy(row);}, async update(name,id,fields){for(const key of Object.keys(fields))assert.ok(data.tables[name][key],name+'.'+key);const row=rows[name]?.find(r=>r.objectId===id);assert.ok(row);Object.assign(row,copy(fields));return copy(row);} }; const app=createApplication({store,crypto,Parse:{},data,settings:{signingSecret:'local-verification-only'},files:{}}); const actor={id:'local-input-check',kind:'service',scopes:['source:write','data:read','ingest:write'],projectIds:['*']}; const call=async(name,p)=>(await app.dispatch(name,JSON.parse(JSON.stringify(p)),actor)).data; // This fixture never leaves memory and is not an employee or registered production Agent. const agentProfile={key:'agent-account:'+'a'.repeat(64),name:'本地输入校验夹具',role:'workshop',identityBasis:'runtime_config',runtimePlatform:'hermes',channel:'wecom',registeredAt:'2026-11-02T00:00:00Z',account:{platform:'wecom',accountId:'fixture-local-only'}}; const checks=[],inputHashes={}; for(const key of ['cq-01','cq-02','cq-03','cq-04']){ const input=fs.readFileSync('work/consumer-quote-inputs-20261102/'+key+'.input.json'); inputHashes[key+'.input.json']=crypto.createHash('sha256').update(input).digest('hex'); const task=JSON.parse(input),record=task.records[0],locator=record.data.locator; assert.equal(task.source.sourceKind,'social');assert.equal(task.source.dataMode,'live');assert.equal(task.source.platform,'smzdm'); assert.equal(task.records.length,1);assert.equal(record.className,'KfEvidence'); assert.equal(record.data.productRef,undefined);assert.equal(record.data.sourceRef,undefined); assert.equal(record.data.publishedAt,null);assert.equal(locator.publicationTimezone,'unknown'); assert.equal(locator.purchaseVerified,false);assert.equal(locator.realIdentityVerified,false); assert.equal(record.data.collectedAt,locator.browserReadAt);assert.equal(task.source.collectedAt,locator.httpCollectedAt); assert.equal(record.data.evidenceKind,'public_user_experience_self_report'); assert.equal([...task.source.rawText].slice(locator.startCharacter,locator.endCharacter).join(''),record.data.quote); const sourcesBefore=(rows.KfSource??[]).length,evidenceBefore=(rows.KfEvidence??[]).length; const preflight=await runWorkshop('workshop-dedup',task,{requestId:key+':preflight',call}); assert.equal(preflight.readOnly,true);assert.equal((rows.KfSource??[]).length,sourcesBefore);assert.equal((rows.KfEvidence??[]).length,evidenceBefore); assert.equal(preflight.source.operation,'no-exact-match');assert.equal(preflight.items[0].reason,'SOURCE_NOT_REGISTERED'); const result=await runWorkshop('workshop-import',task,{requestId:key+':import',agentProfile,call}); assert.equal(result.status,'succeeded');assert.equal(result.items.length,1);assert.equal(result.counts.created,1); const source=(await runWorkshop('workshop-read',{className:'KfSource',objectId:result.sourceId},{requestId:key+':read-source',call})).record; const evidence=(await runWorkshop('workshop-read',{className:'KfEvidence',objectId:result.items[0].objectId},{requestId:key+':read-evidence',call})).record; for(const [field,value]of Object.entries(task.source))assert.deepEqual(source[field],value,key+' source '+field); for(const [field,value]of Object.entries(record.data))assert.deepEqual(evidence[field],value,key+' evidence '+field); assert.equal(evidence.sourceRef.objectId,result.sourceId);assert.equal(evidence.productRef??null,null);assert.equal(evidence.publishedAt,null); const duplicate=await runWorkshop('workshop-dedup',task,{requestId:key+':post-preflight',call}); assert.equal(duplicate.source.operation,'unchanged');assert.equal(duplicate.items[0].decision,'reuse'); const replay=structuredClone(task);replay.records[0].externalKey+=':local-reuse-check'; const reused=await runWorkshop('workshop-import',replay,{requestId:key+':reuse-check',agentProfile,call}); assert.equal(reused.sourceOperation,'unchanged');assert.equal(reused.counts.created,0);assert.equal(reused.counts.unchanged,1); assert.equal(reused.sourceId,result.sourceId);assert.equal(reused.items[0].objectId,result.items[0].objectId); checks.push({key,inputMatchesSchema:true,actualWrapperImportAndReadback:true,unicodeQuoteLocatorMatched:true, actualCollectionTimesPreserved:true,unknownPublicationTimezonePreserved:true,productUnlinked:true,duplicateReused:true}); } assert.equal(rows.KfSource.length,4);assert.equal(rows.KfEvidence.length,4); for(const name of ['KfCategory','KfProduct','KfSession','KfArtifact','KfProject','KfOpportunity','KfConcept'])assert.equal((rows[name]??[]).length,0,name); const result={ok:true,operation:'consumer-quote-inputs-validated-locally',at:new Date().toISOString(),scope:'real backend and wrapper, isolated in-memory store', checks,inputHashes,networkRequests:0,productionBusinessWrites:0,localSources:4,localEvidence:4,localProducts:0,localReports:0}; const output='work/consumer-quote-inputs-verified-20261102.json';assert.equal(fs.existsSync(output),false,'Retain previous verification'); fs.writeFileSync(output,JSON.stringify(result,null,2)+'\n',{flag:'wx'}); console.log(JSON.stringify(result,null,2));