Files
baiyue-firstleg/scripts/f32-pda-hold-race.mjs
T

230 lines
24 KiB
JavaScript

// Explicit TEST inventory race. Imports perform no network or environment reads.
import fs from 'node:fs'
import { createHash } from 'node:crypto'
import { resolve } from 'node:path'
import { pathToFileURL } from 'node:url'
import { buildEvidenceRemoteScript } from './fba-core-regression-evidence.mjs'
import { warehouseClaim } from './admin-test-env-modules/unified-pda-session-revocation.mjs'
const demand=(condition,message)=>{if(!condition)throw Error(message)}
const digest=value=>createHash('sha256').update(JSON.stringify(value)).digest('hex')
const pause=ms=>new Promise(done=>setTimeout(done,ms))
const literal=value=>`CONVERT(0x${Buffer.from(value).toString('hex')} USING utf8mb4) COLLATE utf8mb4_bin`
const tx=['SET NAMES utf8mb4 COLLATE utf8mb4_bin;','SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;','START TRANSACTION WITH CONSISTENT SNAPSHOT, READ ONLY;']
const parse=raw=>JSON.parse(raw.replace(/([:\[,]\s*)(-?\d{16,})(?=\s*[,}\]])/g,'$1"$2"'))
export function validateRacePlan(p){
const fields=['purpose','marker','customerId','orderId','warehouseId','balanceId','positionId','pdaMembershipId','dispatchItemId','dispatchNo','tripNo','expectedImage','expectedPackages','pickPackages','pickQuantity']
demand(p&&Object.keys(p).length===fields.length&&Object.keys(p).every(key=>fields.includes(key)),'INVALID_RACE_SCHEMA')
demand(p?.purpose==='F32_OWNED_PDA_HOLD_RACE'&&/^[A-Za-z0-9_-]{1,64}$/.test(p.marker||''),'INVALID_RACE_PLAN')
for(const key of ['customerId','orderId','warehouseId','balanceId','positionId','pdaMembershipId','dispatchItemId'])
demand(typeof p[key]==='string'&&/^[1-9][0-9]{0,19}$/.test(p[key]),'INVALID_RACE_IDENTIFIER')
demand(/^[A-Za-z0-9_-]{1,64}$/.test(p.dispatchNo||'')&&/^[A-Za-z0-9_-]{1,64}$/.test(p.tripNo||''),'INVALID_RACE_BUSINESS_NUMBER')
demand(/^sha256:[a-f0-9]{64}$/.test(p.expectedImage||'')&&p.expectedPackages===4&&p.pickPackages===1
&&Number.isSafeInteger(p.pickQuantity)&&p.pickQuantity>0,'INVALID_RACE_BASELINE')
return p
}
const b64=value=>'['+Buffer.from(value).toString('base64').match(/.{1,4000}/g).map(x=>`'${x}'`).join(',')+"].join('')"
export function buildOrderLockLeaseScript(plan,phase,agent){
const p=validateRacePlan(plan)
demand(['HOLD_FIRST','PICK_FIRST'].includes(phase)&&/^[A-Za-z0-9_.-]{1,128}$/.test(agent||''),'INVALID_LEASE_SCOPE')
const tag=`F32_${p.marker}_${phase}`
// The only write-capable transaction contains a locking SELECT and ROLLBACK.
// A fixed server-side 12-second lease releases the row even if the observer disconnects.
const sql=`SET SESSION innodb_lock_wait_timeout=5;START TRANSACTION;SELECT JSON_OBJECT('rowId',CAST(id AS CHAR),'customerId',customer_id,'connectionId',CONNECTION_ID()) FROM ll_order WHERE id=${p.orderId} AND customer_id=${literal(p.customerId)} AND overseas_warehouse_id=${literal(p.warehouseId)} FOR UPDATE;SELECT JSON_OBJECT('marker','${tag}','leaseElapsed',SLEEP(12));ROLLBACK;SELECT JSON_OBJECT('released',JSON_EXTRACT('true','$'));`
const python=`import json,os,subprocess,urllib.parse,re
try:
c=json.loads(subprocess.check_output(['docker','inspect','firstleg-test-lastleg'],text=True,stderr=subprocess.DEVNULL))[0]
e=dict(x.split('=',1) for x in c['Config']['Env'])
if c['Name']!='/firstleg-test-lastleg' or c['Config'].get('Labels',{}).get('com.docker.compose.project')!='firstleg-test' or e.get('DEPLOY_ENV')!='test' or c['Image']!='${p.expectedImage}' or c['State'].get('Health',{}).get('Status')!='healthy':raise RuntimeError('TEST_RUNTIME_CHANGED')
u=urllib.parse.urlsplit(e['LASTLEG_DB_URL'].removeprefix('jdbc:'));host='127.0.0.1' if u.hostname=='host.docker.internal' else u.hostname
childEnv=dict(os.environ,MYSQL_PWD=e['LASTLEG_DB_PASSWORD'])
q=subprocess.run(['mysql','--host='+host,'--port='+str(u.port or 3306),'--user='+e['LASTLEG_DB_USERNAME'],'--batch','--raw','--skip-column-names',u.path.lstrip('/')],input=${JSON.stringify(sql)},capture_output=True,text=True,env=childEnv,timeout=22)
if q.returncode:
code=re.search(r'ERROR ([0-9]{3,5})',q.stderr);print('F32_LEASE_JSON='+json.dumps({'ok':False,'error':'MYSQL_'+(code.group(1) if code else 'UNKNOWN')}))
else:
rows=[json.loads(x) for x in q.stdout.splitlines() if x.strip()]
if len(rows)!=3 or str(rows[0].get('rowId'))!='${p.orderId}' or str(rows[0].get('customerId'))!='${p.customerId}' or rows[-1].get('released')!=True:raise RuntimeError('LEASE_SOURCE_NOT_PROVED')
print('F32_LEASE_JSON='+json.dumps({'ok':True,'rows':rows,'imageId':c['Image']}))
except Exception as error:
print('F32_LEASE_JSON='+json.dumps({'ok':False,'error':str(error) if re.fullmatch('[A-Z_]{1,64}',str(error)) else 'LEASE_FAILED_OR_TIMED_OUT'}))
`
const groovy=`def p=new ProcessBuilder(['python3','-c',new String(java.util.Base64.decoder.decode(${b64(python)}),'UTF-8')]).redirectErrorStream(true).start();def out=p.inputStream.getText('UTF-8');p.waitFor();print(out)`
return `def c=jenkins.model.Jenkins.instance.getComputer('${agent}');if(c==null||c.channel==null)throw new RuntimeException('TEST agent unavailable');print(hudson.util.RemotingDiagnostics.executeGroovy(new String(java.util.Base64.decoder.decode(${b64(groovy)}),'UTF-8'),c.channel))`
}
export function buildLockEvidenceSql(plan,phase){
const p=validateRacePlan(plan);demand(['HOLD_FIRST','PICK_FIRST'].includes(phase),'INVALID_LEASE_SCOPE')
const tag=`F32_${p.marker}_${phase}`
return [...tx,
`SELECT JSON_OBJECT('collection','lease','connectionId',t.trx_mysql_thread_id) FROM performance_schema.data_locks l JOIN information_schema.innodb_trx t ON t.trx_id=l.ENGINE_TRANSACTION_ID WHERE l.OBJECT_SCHEMA=DATABASE() AND l.OBJECT_NAME='ll_order' AND l.INDEX_NAME='PRIMARY' AND l.LOCK_STATUS='GRANTED' AND l.LOCK_DATA=${literal(p.orderId)} AND t.trx_query LIKE ${literal('%'+tag+'%')};`,
`SELECT JSON_OBJECT('collection','wait','requestingConnectionId',r.trx_mysql_thread_id,'blockingConnectionId',b.trx_mysql_thread_id,'orderId',l.LOCK_DATA) FROM performance_schema.data_lock_waits w JOIN performance_schema.data_locks l ON l.ENGINE_LOCK_ID=w.REQUESTING_ENGINE_LOCK_ID JOIN information_schema.innodb_trx r ON r.trx_id=w.REQUESTING_ENGINE_TRANSACTION_ID JOIN information_schema.innodb_trx b ON b.trx_id=w.BLOCKING_ENGINE_TRANSACTION_ID WHERE l.OBJECT_SCHEMA=DATABASE() AND l.OBJECT_NAME='ll_order' AND l.INDEX_NAME='PRIMARY' AND l.LOCK_DATA=${literal(p.orderId)};`,'COMMIT;'].join('\n')
}
export function buildStockEvidenceSql(plan){
const p=validateRacePlan(plan),customer=literal(p.customerId)
return [...tx,
`SELECT JSON_OBJECT('collection','sourceOrder','id',CAST(id AS CHAR),'customerId',customer_id,'warehouseId',overseas_warehouse_id,'picked',COALESCE(picked_package_count,0),'shipped',COALESCE(shipped_package_count,0),'version',version,'detained',detained,'outboundNo',outbound_order_no) FROM ll_order WHERE customer_id=${customer} AND id=${p.orderId};`,
`SELECT JSON_OBJECT('collection','hold','id',CAST(id AS CHAR),'key',idempotency_key,'held',held,'version',order_version) FROM ll_order_hold_history WHERE customer_id=${customer} AND order_id=${p.orderId} ORDER BY id;`,
`SELECT JSON_OBJECT('collection','pick','id',CAST(id AS CHAR),'key',idempotency_key,'packages',packages,'quantity',product_quantity,'positionId',CAST(inventory_position_id AS CHAR)) FROM ll_dispatch_pda_pick WHERE customer_id=${customer} AND dispatch_item_id=${p.dispatchItemId} ORDER BY id;`,
`SELECT JSON_OBJECT('collection','attribution','id',CAST(id AS CHAR),'pickId',CAST(pick_id AS CHAR),'orderId',CAST(order_id AS CHAR),'packages',packages,'quantity',product_quantity) FROM ll_dispatch_pda_pick_order WHERE customer_id=${customer} AND order_id=${p.orderId} ORDER BY id;`,
`SELECT JSON_OBJECT('collection','ledger','id',CAST(id AS CHAR),'key',idempotency_key,'positionId',CAST(position_id AS CHAR),'businessType',business_type,'statusFrom',status_from,'statusTo',status_to,'before',before_packages,'delta',delta_packages,'after',after_packages) FROM ll_inventory_ledger WHERE customer_id=${customer} AND balance_id=${p.balanceId} ORDER BY id;`,'COMMIT;'].join('\n')
}
export function assertContendedRequests(rows,expectedOrderId,firstConnectionId){
const leases=rows.filter(x=>x.collection==='lease'),waits=rows.filter(x=>x.collection==='wait')
demand(leases.length===1,'LIVE_LEASE_NOT_PROVED')
const ids=[...new Set(waits.map(x=>x.requestingConnectionId))]
demand(Number.isSafeInteger(leases[0].connectionId)&&leases[0].connectionId>0
&&waits.every(x=>x.orderId===expectedOrderId&&Number.isSafeInteger(x.requestingConnectionId)&&x.requestingConnectionId>0)
&&!ids.includes(leases[0].connectionId),'LOCK_EVIDENCE_SCOPE_INVALID')
demand(ids.length===(firstConnectionId===undefined?1:2)&&waits.some(x=>x.blockingConnectionId===leases[0].connectionId),'EXACT_REQUEST_CONTENTION_NOT_PROVED')
if(firstConnectionId!==undefined)demand(ids.includes(firstConnectionId),'FIRST_REQUEST_NO_LONGER_WAITING')
return {leaseConnectionId:leases[0].connectionId,requestingConnections:ids,waits}
}
function stableSnapshot(x){return digest(x)}
export function assertRaceInventory(plan,phase,before,after){
const p=validateRacePlan(plan);demand(['HOLD_FIRST','PICK_FIRST'].includes(phase),'INVALID_RACE_PHASE')
const scanned=phase==='PICK_FIRST'?1:0,b=after.balance,order=after.detail.order
const bucketNames=['availablePackages','holdPackages','allocatedPackages','pickedPackages','receivingPackages']
const buckets=x=>bucketNames.reduce((n,k)=>{demand(Number.isSafeInteger(Number(x[k]))&&Number(x[k])>=0,'INVALID_STOCK_BUCKET');return n+Number(x[k])},0)
demand(Number(before.balance.availablePackages)===4&&Number(before.balance.totalPackages)===4
&&before.positions.length===2&&after.positions.length===2
&&new Set(after.positions.map(x=>x.id)).size===2&&after.positions.every(x=>before.positions.some(y=>y.id===x.id))
&&Number(b.availablePackages)===(scanned?3:0)&&Number(b.holdPackages)===(scanned?0:4)
&&Number(b.pickedPackages)===0&&Number(b.allocatedPackages)===0&&Number(b.receivingPackages)===0
&&Number(b.totalPackages)===4-scanned&&buckets(b)===4-scanned
&&after.positions.reduce((n,x)=>n+buckets(x),0)+scanned===4&&order.detained===!scanned,'RACE_INVENTORY_RESULT_INVALID')
const sources=after.sql.filter(x=>x.collection==='sourceOrder')
demand(sources.length===1&&sources[0].id===p.orderId&&sources[0].customerId===p.customerId&&sources[0].warehouseId===p.warehouseId
&&sources[0].picked===scanned&&sources[0].shipped===0&&!sources[0].outboundNo
&&sources[0].version===Number(order.version)&&sources[0].detained===(scanned?0:1),'RACE_SOURCE_ORDER_COUNTERS_INVALID')
const added=collection=>after.sql.filter(x=>x.collection===collection&&!before.sql.some(y=>y.collection===collection&&y.id===x.id))
const pickKey=`${p.marker}-${phase}-PICK`,newPicks=added('pick'),attributed=added('attribution'),ledger=added('ledger'),holds=added('hold')
demand(newPicks.length===scanned&&newPicks.every(x=>x.key===pickKey&&x.positionId===p.positionId&&x.packages===1&&x.quantity===p.pickQuantity),'RACE_PICK_FACTS_INVALID')
demand(attributed.length===scanned&&attributed.every(x=>x.orderId===p.orderId&&x.packages===1&&x.quantity===p.pickQuantity
&&newPicks.some(y=>y.id===x.pickId)),'RACE_SOURCE_ATTRIBUTION_INVALID')
demand(ledger.every(x=>Number.isSafeInteger(x.delta)&&x.before+x.delta===x.after),'RACE_LEDGER_ARITHMETIC_INVALID')
if(scanned){
demand(holds.length===0&&ledger.length===3,'PICK_OR_REJECTED_HOLD_DUPLICATED_FACTS')
for(const [type,from,to,delta] of [['ALLOCATE','AVAILABLE','ALLOCATED',1],['PICK','ALLOCATED','PICKED',1],['SHIP','PICKED','SHIPPED',-1]]){
const rows=ledger.filter(x=>x.businessType===type)
demand(rows.length===1&&rows[0].positionId===p.positionId&&rows[0].statusFrom===from&&rows[0].statusTo===to&&rows[0].delta===delta
&&rows[0].key.startsWith(`DISPATCH:${p.dispatchNo}:${p.dispatchItemId}:${pickKey}:${type}:`),'RACE_SCAN_LEDGER_INVALID')
}
demand(after.positions.every(x=>Number(x.availablePackages)===Number(before.positions.find(y=>y.id===x.id).availablePackages)-(x.id===p.positionId?1:0)
&&Number(x.holdPackages)===0&&Number(x.pickedPackages)===0&&Number(x.allocatedPackages)===0),'RACE_POSITION_DEDUCTION_INVALID')
}else{
demand(holds.length===1&&holds[0].key===`${p.marker}-${phase}-HOLD`&&holds[0].held===1
&&holds[0].version===Number(order.version)&&ledger.length===2,'HOLD_OR_REJECTED_PICK_DUPLICATED_FACTS')
demand(ledger.every(x=>x.businessType==='HOLD'&&x.statusFrom==='AVAILABLE'&&x.statusTo==='HOLD'
&&x.delta===Number(before.positions.find(y=>y.id===x.positionId)?.availablePackages))
&&new Set(ledger.map(x=>x.positionId)).size===2&&ledger.reduce((n,x)=>n+x.delta,0)===4,'RACE_HOLD_LEDGER_INVALID')
}
return{verified:true,scannedOutPackages:scanned,availablePackages:Number(b.availablePackages),heldPackages:Number(b.holdPackages),pickedBucketPackages:0,sourcePickedPackages:sources[0].picked}
}
async function main(argv){
const a={};for(let i=0;i<argv.length;i+=2){demand(argv[i]?.startsWith('--')&&argv[i+1],'EXPLICIT_ARGUMENTS_REQUIRED');a[argv[i].slice(2)]=argv[i+1]}
demand(a.plan&&a.report&&a['confirm-test-runtime']==='yes'&&String(process.env.CHONGCHONG_ENV).toLowerCase()==='test','EXPLICIT_TEST_SCOPE_REQUIRED')
const p=validateRacePlan(JSON.parse(fs.readFileSync(a.plan))),env=process.env
for(const key of ['JENKINS_URL','JENKINS_USER','JENKINS_API_TOKEN','CHONGCHONG_ADMIN_API_BASE_URL','CHONGCHONG_ADMIN_USERNAME','CHONGCHONG_ADMIN_PASSWORD','PDA_USERNAME','PDA_PASSWORD','PDA_MEMBERSHIP_ID'])demand(env[key],'EXPLICIT_TEST_CREDENTIALS_REQUIRED')
demand(env.PDA_MEMBERSHIP_ID===p.pdaMembershipId,'OWN_PDA_PROFILE_REQUIRED')
const report={scope:p,success:false,phases:[],requests:[],at:new Date().toISOString()}
const fd=fs.openSync(a.report,'wx',0o600),checkpoint=a.report+'.checkpoint.json'
fs.writeFileSync(checkpoint,JSON.stringify(report),{flag:'wx'})
const save=()=>{
const checkpointFd=fs.openSync(checkpoint,'w',0o600)
try{fs.writeFileSync(checkpointFd,JSON.stringify(report,null,2));fs.fsyncSync(checkpointFd)}finally{fs.closeSync(checkpointFd)}
}
const base=env.CHONGCHONG_ADMIN_API_BASE_URL.replace(/\/$/,''),agent='java-test-agent';let admin,pda,activationAttempted=false
const call=async(method,path,body,token=admin?.accessToken)=>{
const entry={method,path:path.split('?')[0],phase:'INTENT'};report.requests.push(entry);save()
let res;try{res=await fetch(base+path,{method,redirect:'error',signal:AbortSignal.timeout(20000),headers:{Accept:'application/json',...(token?{Authorization:'Bearer '+token}:{}),...(body===undefined?{}:{'Content-Type':'application/json'})},...(body===undefined?{}:{body:JSON.stringify(body)})})}catch{entry.phase='OUTCOME_UNKNOWN';save();throw Error('API_OUTCOME_UNKNOWN_NO_AUTO_RETRY')}
const payload=parse(await res.text());Object.assign(entry,{phase:'ACKNOWLEDGED',http:res.status,code:String(payload.code),requestId:res.headers.get('x-request-id')});save();return{http:res.status,body:payload}
}
const ok=r=>{demand(r.http===200&&String(r.body?.code)==='200','API_SUCCESS_REQUIRED');return r.body.data}
const remote=async(script,prefix)=>{
const res=await fetch(new URL('scriptText',env.JENKINS_URL.replace(/\/?$/,'/')),{method:'POST',redirect:'error',signal:AbortSignal.timeout(55000),headers:{Authorization:'Basic '+Buffer.from(env.JENKINS_USER+':'+env.JENKINS_API_TOKEN).toString('base64'),'Content-Type':'application/x-www-form-urlencoded'},body:new URLSearchParams({script})})
demand(res.ok,'JENKINS_HTTP_FAILURE');const lines=(await res.text()).split(/\r?\n/).filter(x=>x.startsWith(prefix+'='));demand(lines.length===1,'REMOTE_RESULT_AMBIGUOUS');const value=JSON.parse(lines[0].slice(prefix.length+1));demand(value.ok===true,/^[A-Z_0-9]+$/.test(value.error||'')?value.error:'REMOTE_FAILED');return value
}
const sql=async query=>(await remote(buildEvidenceRemoteScript('lastleg',query,agent),'FBA_CORE_JSON')).rows
const snapshot=async()=>{
const detail=ok(await call('GET',`/platform/v1/last-leg/orders/${p.orderId}?customerId=${p.customerId}`))
const balance=ok(await call('GET',`/platform/v1/last-leg/inventory/balances/${p.balanceId}?customerId=${p.customerId}`))
const positions=ok(await call('GET',`/platform/v1/last-leg/inventory/balances/${p.balanceId}/positions?customerId=${p.customerId}`))
const task=ok(await call('GET',`/pda/v1/last-leg/dispatches/${p.dispatchNo}`,undefined,pda.accessToken))
demand(String(detail.order.id)===p.orderId&&String(detail.order.customerId)===p.customerId&&String(balance.inboundOrderId)===p.orderId
&&String(balance.customerId)===p.customerId&&String(balance.overseasWarehouseId)===p.warehouseId
&&positions.length===2&&positions.every(x=>String(x.customerId)===p.customerId&&String(x.inboundOrderId)===p.orderId)
&&task.tripNo===p.tripNo&&task.dispatchNo===p.dispatchNo,'SNAPSHOT_SCOPE_INVALID')
return{detail,balance,positions,task,sql:await sql(buildStockEvidenceSql(p))}
}
// Explicit headers for immutable command keys; never mint a different key after an unknown result.
const command=async(type,body,key)=>{
const path=type==='HOLD'?`/platform/v1/last-leg/orders/${p.orderId}/hold?customerId=${p.customerId}`:`/pda/v1/last-leg/dispatches/${p.dispatchNo}/items/${p.dispatchItemId}/pick`
const token=type==='HOLD'?admin.accessToken:pda.accessToken,method=type==='HOLD'?'PUT':'POST'
const entry={method,path:path.split('?')[0],type,key,body,phase:'INTENT'};report.requests.push(entry);save()
let res;try{res=await fetch(base+path,{method,redirect:'error',signal:AbortSignal.timeout(20000),headers:{Authorization:'Bearer '+token,'Content-Type':'application/json',...(type==='HOLD'?{'Idempotency-Key':key}:{})},body:JSON.stringify(body)})}catch{entry.phase='OUTCOME_UNKNOWN';save();throw Error('COMMAND_OUTCOME_UNKNOWN_NO_AUTO_RETRY')}
const payload=parse(await res.text());Object.assign(entry,{phase:'ACKNOWLEDGED',http:res.status,code:String(payload.code),message:payload.message,requestId:res.headers.get('x-request-id')});save();return{http:res.status,body:payload}
}
try{
admin=ok(await call('POST','/auth/login',{loginId:env.CHONGCHONG_ADMIN_USERNAME,password:env.CHONGCHONG_ADMIN_PASSWORD},''))
const users=ok(await call('GET',`/platform/v1/iam/users?page=1&size=20&keyword=${encodeURIComponent(env.PDA_USERNAME)}`))
const user=users.records.find(x=>String(x.membershipId)===p.pdaMembershipId)
demand(user&&!user.protectedAccount&&user.status==='DISABLED'&&String(user.overseasWarehouseId)===p.warehouseId,'OWN_DISABLED_PDA_REQUIRED')
activationAttempted=true;ok(await call('PUT',`/platform/v1/iam/users/${p.pdaMembershipId}/status`,{status:'ACTIVE'}))
pda=ok(await call('POST','/auth/login',{loginId:env.PDA_USERNAME,password:env.PDA_PASSWORD},''));demand(warehouseClaim(pda.accessToken)===p.warehouseId,'PDA_WAREHOUSE_MISMATCH')
for(const phase of ['HOLD_FIRST','PICK_FIRST']){
const before=await snapshot(),row=before.detail.order,source=before.sql.find(x=>x.collection==='sourceOrder')
demand(row.currentStatus==='INBOUND_COMPLETED'&&row.detained===false&&source?.id===p.orderId&&source.customerId===p.customerId
&&source.warehouseId===p.warehouseId&&source.version===Number(row.version)&&source.detained===0
&&source.picked===0&&source.shipped===0&&!source.outboundNo&&Number(before.balance.availablePackages)===4
&&Number(before.balance.holdPackages)===0&&Number(before.balance.pickedPackages)===0&&before.task.canPick===true,'LEGAL_UNPICKED_SOURCE_REQUIRED')
const evidence={phase,before,commands:{},lockSamples:[]};report.phases.push(evidence);save()
const holdKey=`${p.marker}-${phase}-HOLD`,pickKey=`${p.marker}-${phase}-PICK`
const holdBody={held:true,chargeable:false,reason:`${p.marker} ${phase}`,expectedVersion:Number(row.version)}
const pickBody={positionId:p.positionId,packages:1,productQuantity:p.pickQuantity,idempotencyKey:pickKey,remark:`${p.marker} ${phase}`}
evidence.commands={hold:{key:holdKey,body:holdBody},pick:{key:pickKey,body:pickBody}};save()
const pending=[],leasePromise=remote(buildOrderLockLeaseScript(p,phase,agent),'F32_LEASE_JSON').then(x=>({value:x}),error=>({error:error.message}))
const waits=async count=>{
for(let i=0;i<12;i++){
const rows=await sql(buildLockEvidenceSql(p,phase));evidence.lockSamples.push(rows);save()
const leases=rows.filter(x=>x.collection==='lease'),connections=[...new Set(rows.filter(x=>x.collection==='wait').map(x=>x.requestingConnectionId))]
if(leases.length===1&&connections.length===count)return rows
if(connections.length>count)throw Error('FOREIGN_SOURCE_CONTENTION');await pause(100)
}throw Error('EXPECTED_MYSQL_LOCK_WAIT_NOT_OBSERVED')
}
try{
await waits(0)
const firstType=phase==='HOLD_FIRST'?'HOLD':'PICK',secondType=firstType==='HOLD'?'PICK':'HOLD'
const start=type=>command(type,type==='HOLD'?holdBody:pickBody,type==='HOLD'?holdKey:pickKey).then(value=>({type,value}),error=>({type,error:error.message}))
pending.push(start(firstType));const one=assertContendedRequests(await waits(1),p.orderId);evidence.firstWait=one;save()
pending.push(start(secondType));evidence.twoWaiters=assertContendedRequests(await waits(2),p.orderId,one.requestingConnections[0]);save()
}finally{evidence.lease=await leasePromise;evidence.responses=await Promise.all(pending);save()}
demand(!evidence.lease.error&&evidence.lease.value.rows.at(-1).released===true&&evidence.responses.length===2
&&evidence.lease.value.rows[0].connectionId===evidence.twoWaiters?.leaseConnectionId
&&evidence.lease.value.rows[1].marker===`F32_${p.marker}_${phase}`,'LEASE_OR_BOTH_REQUESTS_UNPROVED')
const win=evidence.responses.find(x=>x.type===(phase==='HOLD_FIRST'?'HOLD':'PICK')),lose=evidence.responses.find(x=>x!==win)
demand(win&&!win.error&&lose&&!lose.error,'RACE_RESPONSE_UNKNOWN');ok(win.value)
demand(lose.value.http===200&&String(lose.value.body.code)==='A0409','RACE_LOSER_NOT_CONFLICT')
const after=evidence.after=await snapshot(),order=after.detail.order
evidence.inventoryProof=assertRaceInventory(p,phase,before,after)
ok(await command(win.type,win.type==='HOLD'?holdBody:pickBody,win.type==='HOLD'?holdKey:pickKey));const replay=evidence.replay=await snapshot()
demand(stableSnapshot(after)===stableSnapshot(replay),'RACE_REPLAY_DRIFT')
if(phase==='HOLD_FIRST'){
ok(await command('HOLD',{held:false,chargeable:false,reason:`${p.marker} release own first phase`,expectedVersion:Number(order.version)},`${p.marker}-RELEASE`))
evidence.restored=await snapshot();demand(evidence.restored.detail.order.detained===false&&Number(evidence.restored.balance.availablePackages)===4&&Number(evidence.restored.balance.holdPackages)===0,'OWN_HOLD_RELEASE_FAILED')
}
evidence.verified=true;save()
}
report.success=report.phases.length===2&&report.phases.every(x=>x.verified)
}catch(error){report.success=false;report.error=/^[A-Z_0-9]+$/.test(error.message)?error.message:'F32_RACE_FAILED_INSPECT_CHECKPOINT'}
finally{
try{if(pda){ok(await call('POST','/auth/logout',{refreshToken:pda.refreshToken},pda.accessToken));report.pdaSessionClosed=true}}catch{report.pdaSessionClosed=false;report.success=false}
try{if(activationAttempted){const user=ok(await call('PUT',`/platform/v1/iam/users/${p.pdaMembershipId}/status`,{status:'DISABLED'}));report.operatorRestored=user.status==='DISABLED';demand(report.operatorRestored,'PDA_DISABLE_NOT_PROVED')}}catch{report.operatorRestored=false;report.success=false}
try{if(admin){ok(await call('POST','/auth/logout',{refreshToken:admin.refreshToken},admin.accessToken));report.adminSessionClosed=true}}catch{report.adminSessionClosed=false;report.success=false}
fs.writeFileSync(fd,JSON.stringify(report,null,2));fs.fsyncSync(fd);fs.closeSync(fd);save()
}
console.log(JSON.stringify({success:report.success,report:resolve(a.report),phases:report.phases.map(x=>({phase:x.phase,verified:!!x.verified})),error:report.error,operatorRestored:report.operatorRestored}))
if(!report.success)process.exitCode=1
}
if(process.argv[1]&&import.meta.url===pathToFileURL(resolve(process.argv[1])).href)main(process.argv.slice(2)).catch(error=>{console.error(/^[A-Z_0-9]+$/.test(error.message)?error.message:'F32_RACE_ARGUMENT_OR_REPORT_ERROR');process.exitCode=1})