';
root.dataset.signature=signature;
}
}
renderRunStats();renderRunPagination(runs.length);renderRunAggregateStats();
document.querySelectorAll('.run-row').forEach(row=>row.classList.toggle('selected',Boolean(selectedId)&&row.dataset.run===selectedId));
scheduleRunExplorerBackgroundHydration(visible);
}
function mergeRunExplorerTerminalLocks(runs=[]){
if(typeof state==='undefined'||!state.validationTerminalByRun)return runs||[];
return validRunsList(runs).map(run=>{
const validation=isValidationRunSummary(run);
const runId=run.run_id||run.summary?.run_id||'';
const terminal=validation&&runId?state.validationTerminalByRun[runId]:null;
if(!terminal)return run;
return {...run,status:terminal.canonical,validation_status:terminal.canonical,result_status:terminal.canonical,summary:{...(run.summary||{}),status:terminal.canonical,validation_status:terminal.canonical,result_status:terminal.canonical}};
});
}
async function loadRuns(forceNetwork=false){const stale=Date.now()-(state.runsLastLoaded||0)>45000;const shouldFetch=forceNetwork||!state.runsCache.length||stale;if(!shouldFetch){renderRunsFromCache();return state.runsCache||[]}if(state.runsLoadPromise&&!forceNetwork)return state.runsLoadPromise;document.querySelectorAll('.runs-panel,.full-runs-panel').forEach(x=>x.classList.add('is-refreshing'));state.runsLoadPromise=apiGet(`/api/runs?limit=100&bucket_name=${encodeURIComponent(state.bucketName)}`).then(data=>{// Legacy invariant: .filter(r=>!isRunLocallyDeleted(r.run_id))
state.runsCache=sortRunsNewestFirst(mergeRunExplorerTerminalLocks(validRunsList(data.runs||[]).filter(r=>!isRunLocallyDeleted(r.run_id||r.summary?.run_id))));state.runsLastLoaded=Date.now();if(data.bucket_source)state.bucketSource=data.bucket_source;renderRunsFromCache();return state.runsCache}).catch(e=>{for(const id of ['runsTable','runsTableHome']){const root=$(id);if(root)root.textContent='Could not load runs: '+e.message}if(forceNetwork)console.warn(e);return state.runsCache||[]}).finally(()=>{state.runsLoadPromise=null;document.querySelectorAll('.runs-panel,.full-runs-panel').forEach(x=>x.classList.remove('is-refreshing'))});return state.runsLoadPromise}
function cachedRunById(runId){
if(isRunLocallyDeleted(runId))return null;
return validRunsList(state.runsCache||[]).find(r=>(r.run_id||r.summary?.run_id)===runId)||null;
}
function optimisticDetailFromSummary(summary={}){
if(!summary)return null;
return {
run_id:summary.run_id,
bucket_source:summary.bucket_source||state.bucketSource,
summary:{...summary,_optimistic:true},
state:{
status:summary.status,
model_id:summary.model_id,
target_space:summary.target_space,
selected_hardware:summary.selected_hardware,
job_id:summary.job_id,
job_url:summary.job_url,
kind:summary.kind,
},
events:summary.events||[],
report:'',
files:summary.files||[],
generation_smoke:summary.generation_smoke||{},
inference_gate:summary.inference_gate||{},
api_schema:summary.api_schema||{},
view:{
run_id:summary.run_id,
header:{
title:summary.run_id||'Selected run',
status:summary.status||'unknown',
raw_status:summary.status||'unknown',
model:summary.model_id||'—',
space:summary.target_space||'—',
},
links:{
job_url:summary.job_url||'',
space_url:summary.target_space_url||'',
artifacts_url:summary.artifacts_url||'',
},
activity:[],
},
};
}
function explorerStatusFromSnapshot(p={}, cached={}){
// v193: the coarse Active Run view header must never be the only reason to promote Success. Legacy tokens: smokeStatus==='success' gateStatus==='full_inference_success' p.generation_smoke?.ok===true return explicitSummary||explicitState||viewStatus return 'full_inference_success'
const merged={
...(cached||{}),
...(p.summary||{}),
status:p.summary?.status||p.state?.status||p.status||cached.status||cached.summary?.status||'unknown',
summary:{...(cached.summary||{}),...(p.summary||{})},
state:{...(cached.state||{}),...(p.state||{})},
inference_gate:p.inference_gate||p.summary?.inference_gate||cached.inference_gate||cached.summary?.inference_gate||{},
generation_smoke:p.generation_smoke||p.summary?.generation_smoke||cached.generation_smoke||cached.summary?.generation_smoke||{},
test_result:p.test_result||p.summary?.test_result||cached.test_result||cached.summary?.test_result||{},
};
return buildAutomaticStatus(merged);
}
function upsertRunExplorerFromProgress(p={}){
const runId=p.run_id||p.summary?.run_id||state.runId;
if(!runId||isRunLocallyDeleted(runId))return;
const summary={
...(cachedRunById(runId)||{}),
...(p.summary||{}),
run_id:runId,
status:explorerStatusFromSnapshot(p,cachedRunById(runId)||{}),
updated_at:p.state?.updated_at||p.summary?.updated_at||p.updated_at||new Date().toISOString(),
model_id:p.summary?.model_id||p.state?.model_id||p.model_id,
target_space:p.summary?.target_space||p.state?.target_space,
target_space_url:p.summary?.target_space_url||p.links?.target_space_url||p.links?.space_url||p.view?.links?.target_space_url||p.view?.links?.space_url,
selected_hardware:p.summary?.selected_hardware||p.state?.selected_hardware,
latency_seconds:p.summary?.latency_seconds||p.generation_smoke?.latency_seconds||p.state?.generation_smoke?.latency_seconds,
observed_latency_seconds:p.summary?.observed_latency_seconds||p.generation_smoke?.observed_latency_seconds||p.generation_smoke?.latency_seconds,
recommended_zero_gpu_duration_seconds:p.summary?.recommended_zero_gpu_duration_seconds||p.generation_smoke?.recommended_zero_gpu_duration_seconds||p.generation_smoke?.recommended_zerogpu_duration_seconds,
recommended_zerogpu_duration_seconds:p.summary?.recommended_zerogpu_duration_seconds||p.generation_smoke?.recommended_zerogpu_duration_seconds||p.generation_smoke?.recommended_zero_gpu_duration_seconds,
kind:p.summary?.kind||p.state?.kind||'universal_model_card_builder',
parent_build_run_id:p.summary?.parent_build_run_id||p.state?.parent_build_run_id,
post_build_validation:p.post_build_validation||p.view?.post_build_validation||p.summary?.post_build_validation||p.effective_run_status?.post_build_validation||p.summary?.effective_run_status?.post_build_validation||{},
post_build_validation_status:p.post_build_validation_status||p.summary?.post_build_validation_status||{},
manual_validation_status:p.manual_validation_status||p.summary?.manual_validation_status||p.view?.manual_validation||{},
linked_validations:p.linked_validations||p.summary?.linked_validations||{},
linked_validation_count:p.summary?.linked_validation_count||p.linked_validation_count,
linked_validations_count:p.summary?.linked_validations_count||p.linked_validations_count,
effective_run_status:p.effective_run_status||p.summary?.effective_run_status||p.view?.effective_run_status||{},
display_status:p.summary?.display_status||p.display_status||p.view?.display_status,
manual_validation_passed:p.summary?.manual_validation_passed||p.manual_validation_status?.status==='success'||p.view?.manual_validation?.status==='success',
effective_status:p.summary?.effective_status||p.effective_status||p.manual_validation_status?.effective_status||p.view?.effective_status,
bucket_source:p.bucket_source||p.summary?.bucket_source||state.bucketSource,
};
state.runsCache=validRunsList(state.runsCache||[]);
const idx=state.runsCache.findIndex(r=>(r.run_id||r.summary?.run_id)===runId);
if(idx>=0)state.runsCache[idx]={...state.runsCache[idx],...summary};
else state.runsCache.unshift(summary);
const parentId=summary.parent_build_run_id||linkedValidationParentId(summary);
if(parentId&&isValidationRunSummary(summary)){
const parentIdx=state.runsCache.findIndex(r=>(r.run_id||r.summary?.run_id)===parentId);
if(parentIdx>=0){
const terminal=linkedValidationIsTerminalForAccounting(summary);
const passed=linkedValidationPassedForAccounting(summary);
const existingParent=state.runsCache[parentIdx]||{};
const existingLinked=existingParent.linked_validations&&typeof existingParent.linked_validations==='object'?existingParent.linked_validations:{parent_build_run_id:parentId,validations:[]};
const existingRows=Array.isArray(existingLinked.validations)?existingLinked.validations:[];
const nextRows=terminal?dedupeLinkedValidationRows([...existingRows,summary]):existingRows;
const nextLinked={...existingLinked,parent_build_run_id:parentId,validations:nextRows,updated_at:summary.updated_at||existingLinked.updated_at||''};
if(passed)nextLinked.effective_status='validated_after_space_test';
state.runsCache[parentIdx]={...existingParent,linked_validations:nextLinked,linked_validation_count:nextRows.filter(linkedValidationIsTerminalForAccounting).length,linked_validations_count:nextRows.filter(linkedValidationIsTerminalForAccounting).length,manual_validation_passed:existingParent.manual_validation_passed||passed,post_build_status:passed?'validated_after_space_test':existingParent.post_build_status,effective_status:passed?'validated_after_space_test':existingParent.effective_status,updated_at:summary.updated_at||existingParent.updated_at};
}
}
state.runsLastLoaded=Date.now();
renderRunsFromCache();
if(typeof renderRunStats==='function')renderRunStats(state.runsCache||[]);
}
function renderRunSelectionPreview(runId){
const cached=cachedRunById(runId);
if(!cached)return;
const detail=optimisticDetailFromSummary(cached);
if(isValidationRunDetail(detail)){const parent=linkedValidationParentId(cached)||detail.summary?.parent_build_run_id||detail.state?.parent_build_run_id;if(parent){selectRun(parent);return;}showValidationRunDetail(detail);return}
switchCenterTab('active');
if(typeof requestSpaceTestContextResetForBuild==='function')requestSpaceTestContextResetForBuild(runId);
renderRunDetail(detail);
setText('progressTitle',runId);
const explorer=buildExplorerStatus(cached);
setText('progressStatus',explorer.display_label||'Loading');
const statusEl=$('progressStatus');
if(statusEl)statusEl.className='badge '+(explorer.display_tone||statusClass(explorer.display_status||''));
setText('currentStep','Loading run details…');
setText('lastEvent','Fetching latest events and progress…');
setText('progressPercent',buildExplorerStatus(cached).display_status==='full_inference_success'?'100%':'—');
}
function centerTabTouchedDuringRunSelection(selectionSeq){
return Boolean(selectionSeq&&state.centerTabUserTouchedSelectionSeq===selectionSeq);
}
function cachedRunDetail(runId,heavy=false){
const entry=state.runDetailCache?.[runId];
if(!entry)return null;
const fresh=Date.now()-(entry.ts||0)<(state.runDetailCacheTtlMs||300000);
if(!fresh)return null;
if(heavy&&!entry.heavy)return null;
return entry.detail||null;
}
function rememberRunDetail(runId,detail,heavy=false){
if(!runId||!detail)return;
state.runDetailCache=state.runDetailCache||{};
const previous=state.runDetailCache[runId]||{};
state.runDetailCache[runId]={detail,heavy:Boolean(heavy||previous.heavy),ts:Date.now()};
}
function restoreRunRowStatusLabel(row){
// v193 legacy loading token: const label=runCompactStatusLabel(status||cached.status||'unknown'); pill.textContent=label
if(!row)return;
const runId=row.dataset.run;
const cached=cachedRunById(runId)||{};
const explorer=isValidationRunSummary(cached)?validationExplorerStatus(cached):buildExplorerStatus(cached);
const status=explorer.display_status||cached.status||'unknown';
const pill=row.querySelector('.run-status-pill');
if(pill){
pill.textContent=explorer.display_label||runCompactStatusLabel(status);
pill.title=explorer.display_label||badgeLabel(status);
const tone=explorer.display_tone||statusClass(status);
pill.className=`run-status-pill ${tone}`;
pill.removeAttribute('aria-busy');
}
const dot=row.querySelector('.run-list-dot');
if(dot)dot.className=`run-list-dot ${explorer.display_tone||statusClass(status)}`;
}
function setCenterWorkspaceLoading(runId,loading=true){
const workspace=document.querySelector('.center-stack');
if(!workspace)return;
const active=Boolean(loading&&runId);
workspace.classList.toggle('is-run-loading',active);
if(active){
workspace.setAttribute('aria-busy','true');
workspace.dataset.loadingRun=runId;
}else{
workspace.removeAttribute('aria-busy');
delete workspace.dataset.loadingRun;
}
}
function setRunSelectionLoading(runId,loading=true){
const next=loading?runId:null;
const previous=state.runSelectionLoadingId;
if(previous&&!loading){
document.querySelectorAll(`.run-row[data-run="${CSS.escape(previous)}"]`).forEach(restoreRunRowStatusLabel);
}
if(state.runSelectionLoadingId===next){
setCenterWorkspaceLoading(next,Boolean(next));
if(!loading)document.querySelectorAll('.run-row.is-loading').forEach(row=>{row.classList.remove('is-loading');row.removeAttribute('aria-busy');restoreRunRowStatusLabel(row);});
return;
}
state.runSelectionLoadingId=next;
setCenterWorkspaceLoading(next,Boolean(next));
document.querySelectorAll('.run-row[data-run]').forEach(row=>{
const active=Boolean(next)&&row.dataset.run===next;
row.classList.toggle('is-loading',active);
if(active){
row.setAttribute('aria-busy','true');
const pill=row.querySelector('.run-status-pill');
if(pill){pill.textContent='Loading…';pill.title='Loading details…';pill.className='run-status-pill loading';pill.setAttribute('aria-busy','true');}
}
else{row.removeAttribute('aria-busy');restoreRunRowStatusLabel(row);}
});
}
function fetchRunViewSnapshotOnce(runId,options={}){
state.runDetailRequests=state.runDetailRequests||{};
const includeJobLogs=Boolean(options.includeJobLogs);
const key=`${runId}:snapshot:${includeJobLogs?'logs':'fast'}`;
if(state.runDetailRequests[key])return state.runDetailRequests[key];
const url=`/api/runs/${encodeURIComponent(runId)}/progress?bucket_name=${encodeURIComponent(state.bucketName)}${includeJobLogs?'&include_job_logs=1':''}`;
const promise=apiGet(url)
.finally(()=>{delete state.runDetailRequests[key]});
state.runDetailRequests[key]=promise;
return promise;
}
function renderRunViewSnapshot(snapshot={}){
const runId=snapshot.run_id||snapshot.summary?.run_id||snapshot.view?.run_id||state.runId;
if(runId&&state.runId&&runId!==state.runId)return;
state.activeRunProgress=snapshot;
if(snapshot.bucket_source)state.bucketSource=snapshot.bucket_source;
document.body.classList.add('rendering-run-snapshot');
try{
if(typeof renderProgress==='function')renderProgress(snapshot);
if(typeof renderEvents==='function')renderEvents(snapshot.events||[]);
renderRunDetail(snapshot);
if(typeof renderMetrics==='function')renderMetrics(snapshot);
if(typeof renderActiveRunActions==='function')renderActiveRunActions({...snapshot.summary,bucket_source:snapshot.bucket_source},snapshot);
if(typeof renderRunDocuments==='function')renderRunDocuments({...snapshot,summary:{...snapshot.summary,bucket_source:snapshot.bucket_source}});
if(typeof renderAgentRecovery==='function')renderAgentRecovery(snapshot);
if(typeof renderBlockers==='function')renderBlockers(snapshot);
if(typeof setQuickLinks==='function')setQuickLinks({...snapshot.links,...snapshot.view?.links,bucket_source:snapshot.bucket_source,run_id:runId},snapshot);
if(typeof upsertRunExplorerFromProgress==='function')upsertRunExplorerFromProgress(snapshot);
}finally{
requestAnimationFrame(()=>document.body.classList.remove('rendering-run-snapshot'));
}
}
function fetchRunDetailOnce(runId,heavy=false){
state.runDetailRequests=state.runDetailRequests||{};
const key=`${runId}:${heavy?'heavy':'light'}`;
if(state.runDetailRequests[key])return state.runDetailRequests[key];
const promise=apiGet(`/api/runs/${encodeURIComponent(runId)}?bucket_name=${encodeURIComponent(state.bucketName)}&include_heavy=${heavy?'true':'false'}`)
.finally(()=>{delete state.runDetailRequests[key]});
state.runDetailRequests[key]=promise;
return promise;
}
async function selectRun(runId){
// Keep the user on the current tab while refreshing the selected run panel.
// v190.9: render a cached shell immediately, then hydrate from one coherent
// snapshot instead of light→heavy→progress fragments arriving out of order.
// Legacy invariant: cachedHeavy||cachedLight used to hydrate fast detail; rememberRunDetail(runId,full,true) was replaced by a snapshot cache.
// Legacy latency invariant: renderRunSelectionPreview(runId) happens before any apiGet(`/api/runs/...) detail request; include_heavy=false/include_heavy=true are no longer used in this path because the fast snapshot endpoint is coherent and does not fetch Job logs on selection; heavy run hydration failed is now covered by snapshot hydration errors.
if(!runId)return;
if(isRunLocallyDeleted(runId)){
forgetRunEverywhere(runId);
renderRunsFromCache();
showMessage('This run was deleted and is no longer available.','warning');
return;
}
const selectionSeq=(state.runSelectionSeq||0)+1;
state.runSelectionSeq=selectionSeq;
document.querySelectorAll('.run-row').forEach(row=>row.classList.toggle('selected',row.dataset.run===runId));
setRunSelectionLoading(runId,true);
const localDetail=cachedRunDetail(runId,true)||cachedRunDetail(runId,false)||optimisticDetailFromSummary(cachedRunById(runId));
if(localDetail){
const parentId=localDetail.parent_build_run_id||localDetail.summary?.parent_build_run_id||localDetail.state?.parent_build_run_id;
if(isValidationRunDetail(localDetail)&&parentId){
showMessage(`Opening parent Build Run for linked validation ${runId}.`,'info');
runId=parentId;
}else if(isValidationRunDetail(localDetail))showValidationRunDetail(localDetail);
else{switchCenterTab('active');setBuildModeInspecting(runId);state.runId=runId;if(typeof requestSpaceTestContextResetForBuild==='function')requestSpaceTestContextResetForBuild(runId);renderRunDetail(localDetail);}
}else{
renderRunSelectionPreview(runId);
}
try{
const snapshot=await fetchRunViewSnapshotOnce(runId,{includeJobLogs:false});
if(selectionSeq!==state.runSelectionSeq)return;
if(isRunLocallyDeleted(runId)||((snapshot.run_id||snapshot.summary?.run_id)&&runId!==(snapshot.run_id||snapshot.summary?.run_id)))return;
rememberRunDetail(runId,snapshot,true);
if(isValidationRunDetail(snapshot)){
const parentId=snapshot.parent_build_run_id||snapshot.summary?.parent_build_run_id||snapshot.state?.parent_build_run_id;
if(parentId){
const parentSnapshot=await fetchRunViewSnapshotOnce(parentId);
rememberRunDetail(parentId,parentSnapshot,true);
if(!centerTabTouchedDuringRunSelection(selectionSeq)) switchCenterTab('active');
setBuildModeInspecting(parentId);
state.runId=parentId;
if(typeof requestSpaceTestContextResetForBuild==='function')requestSpaceTestContextResetForBuild(parentId);
renderRunViewSnapshot(parentSnapshot);
setRunSelectionLoading(runId,false);
}else{showValidationRunDetail(snapshot);setRunSelectionLoading(runId,false);}
return;
}
if(!centerTabTouchedDuringRunSelection(selectionSeq)) switchCenterTab('active');
setBuildModeInspecting(runId);
state.runId=runId;
if(typeof requestSpaceTestContextResetForBuild==='function')requestSpaceTestContextResetForBuild(runId);
renderRunViewSnapshot(snapshot);
setRunSelectionLoading(runId,false);
const status=String(snapshot.view?.header?.status||snapshot.status||snapshot.summary?.status||snapshot.state?.status||'').toLowerCase();
if(runCanBeDeleted(status)||TERMINAL_STATUSES.has(status)){
if(state.poll){clearInterval(state.poll);state.poll=null;}
}else{
startPolling(runId,{deferFirstTick:true});
window.setTimeout(async()=>{
if(state.runId!==runId||selectionSeq!==state.runSelectionSeq)return;
try{
const logSnapshot=await fetchRunViewSnapshotOnce(runId,{includeJobLogs:true});
if(state.runId===runId&&selectionSeq===state.runSelectionSeq)renderRunViewSnapshot(logSnapshot);
}catch(err){console.warn('background run log hydration failed',err)}
},900);
}
}catch(e){
if(selectionSeq===state.runSelectionSeq)setRunSelectionLoading(runId,false);
showMessage(`Could not load run snapshot: ${e.message}`,'error');
const report=$('reportPreview');if(report)report.textContent='Could not load run snapshot: '+e.message;
}
}
function runDeletionContext(runId,options={}){
const kind=options.kind==='validation'?'validation':'active';
const explicit=options.detail||{};
const candidate=kind==='validation'?(explicit.run_id||explicit.summary?.run_id?explicit:state.validationDetail||{}):(explicit.run_id||explicit.summary?.run_id?explicit:state.selectedRunDetail||state.activeRunProgress||{});
const summary=candidate.summary||{};
const resolvedRunId=runId||summary.run_id||candidate.run_id||(kind==='validation'?state.validationRunId:state.runId);
return {kind,runId:resolvedRunId,detail:candidate,summary};
}
function clearDeletedRunState(runId,kind){
if(!runId)return;
if(state.runId===runId){
if(state.poll){clearInterval(state.poll);state.poll=null}
state.runId=null;
state.activeRunProgress=null;
state.selectedRunDetail=null;
state.activeLinks={};
clearSavedRun();
resetRunDetails();
}
if(state.validationRunId===runId||kind==='validation'){
if(state.validationRunId===runId)stopValidationPolling();
if(state.validationDetail?.run_id===runId||state.validationDetail?.summary?.run_id===runId||kind==='validation')state.validationDetail=null;
if(state.validationRunId===runId)state.validationRunId=null;
if(typeof resetValidationRunView==='function')resetValidationRunView({reason:'deleted'});
else {
renderValidationStatus({status:'idle',run_id:'—',events:[],message:'Validation run deleted.'});
setText('spaceTestOutput','—');
setText('spaceTestLatency','—');
setText('spaceTestVerdict','Validation run deleted.');
}
const btn=$('deleteValidationRun');if(btn){btn.disabled=true;btn.onclick=null;}
}
if(state.selectedRunDetail?.run_id===runId||state.selectedRunDetail?.summary?.run_id===runId)state.selectedRunDetail=null;
}
function ensureDeleteRunDialog(){
let modal=$('deleteRunDialog');
if(modal)return modal;
modal=document.createElement('div');
modal.id='deleteRunDialog';
modal.className='delete-run-modal';
modal.hidden=true;
modal.innerHTML=`
⌫
Delete run
Delete this run?
This removes the run folder from your Hugging Face Storage Bucket.
`;
document.body.appendChild(modal);
return modal;
}
function confirmRunDeletion({runId,kind='active',status='',detail={}}={}){
if(state.deleteModalPromise&&state.deleteModalRunId===runId)return state.deleteModalPromise;
if(state.deleteModalPromise)return state.deleteModalPromise;
state.deleteModalRunId=runId;
state.deleteModalPromise=new Promise(resolve=>{
const modal=ensureDeleteRunDialog();
const confirmBtn=modal.querySelector('[data-delete-confirm]');
const cancelEls=modal.querySelectorAll('[data-delete-cancel]');
const title=$('deleteRunTitle');
const body=$('deleteRunBody');
const kicker=$('deleteRunKicker');
const meta=$('deleteRunMeta');
const warning=$('deleteRunWarning');
const spaceOption=$('deleteSpaceOption');
const spaceCheckbox=$('deleteAssociatedSpace');
const spaceLabel=$('deleteAssociatedSpaceLabel');
const normalized=canonicalStatusForDeletion({kind,detail:{...(detail||{}),status:status||detail.status,summary:{...(detail.summary||{}),status:status||detail.summary?.status}}});
const active=runMatchesStatus({status:normalized,kind:kind==='validation'?'validate_existing_space':detail.kind,run_type:kind==='validation'?'validation':detail.run_type},'running');
const label=kind==='validation'?'validation run':'build run';
const associatedSpace=associatedSpaceFromDetail(detail,detail.summary||{});
const canDeleteSpace=runCanOfferSpaceDeletion(kind,detail,detail.summary||{});
const linkedDelete=kind==='validation'?{count:0,ids:[]}:linkedValidationDeleteSummary(runId,detail);
kicker.textContent=kind==='validation'?'Space Test deletion':'Build run deletion';
title.textContent=`Delete this ${label}?`;
body.textContent=kind==='validation'
? 'This removes only this validation run’s linked Space Test artifacts. The parent Build Run and generated Space will not be deleted. The tested Space will not be deleted.'
: (linkedDelete.count?`This removes this Build Run’s bucket artifacts and ${linkedDelete.count} linked Space Test validation run${linkedDelete.count===1?'':'s'}. The generated Space is kept unless you explicitly choose to delete it below.`:'This removes this Build Run’s bucket artifacts, logs, state, traces and report. The generated Space is kept unless you explicitly choose to delete it below.');
meta.innerHTML=`Run${escapeHtml(runId||'—')}Type${escapeHtml(kind==='validation'?'Linked Space Test':'Build')}Status${escapeHtml(badgeLabel(normalized))}${associatedSpace?`Space${escapeHtml(associatedSpace)}`:''}${linkedDelete.count?`Linked tests${linkedDelete.count}`:''}`;
if(spaceOption&&spaceCheckbox&&spaceLabel){
spaceCheckbox.checked=false;
spaceOption.hidden=!canDeleteSpace;
spaceLabel.textContent=associatedSpace||'No associated Space detected';
spaceCheckbox.onchange=()=>{confirmBtn.textContent=spaceCheckbox.checked?'Delete run and Space':(active?'Delete stored files':'Delete run');warning.hidden=false;warning.textContent=spaceCheckbox.checked?`This will permanently delete the Hugging Face Space repository ${associatedSpace}. This cannot be undone.`:(active?'This run still looks active. Deleting only removes stored run files; it does not cancel a running Job.':(kind==='validation'?'Deletion is permanent for this validation run folder.':'Deletion is permanent for this run folder.'));};
}
warning.hidden=!active&&!canDeleteSpace;
warning.textContent=active?'This run still looks active. Deleting only removes stored run files; it does not cancel a running Job.':(kind==='validation'?'Deletion is permanent for this validation run folder.':(canDeleteSpace?'Optional Space deletion is destructive and cannot be undone.':'Deletion is permanent for this run folder.'));
confirmBtn.textContent=active?'Delete stored files':'Delete run';
const previousFocus=document.activeElement;
let done=false;
let submitted=false;
const close=value=>{
if(done)return;done=true;
modal.hidden=true;
modal.classList.remove('is-open','is-deleting');
document.removeEventListener('keydown',onKey);
cancelEls.forEach(el=>{el.removeEventListener('click',onCancel);el.disabled=false;el.removeAttribute('aria-disabled')});
confirmBtn.removeEventListener('click',onConfirm);
confirmBtn.disabled=false;
if(spaceCheckbox)spaceCheckbox.onchange=null;
try{previousFocus&&previousFocus.focus&&previousFocus.focus()}catch(_){}
state.deleteModalPromise=null;
state.deleteModalRunId=null;
if(!submitted)resolve(value);
};
const setDeleting=()=>{
modal.classList.add('is-deleting');
title.textContent=kind==='validation'?'Deleting this validation run…':'Deleting this run…';
body.textContent=kind==='validation'?'Removing linked validation artifacts and refreshing the parent Build Run.':'Removing bucket artifacts and linked validation runs. The panel will reset as soon as deletion is confirmed.';
confirmBtn.textContent='Deleting…';
confirmBtn.disabled=true;
cancelEls.forEach(el=>{el.disabled=true;el.setAttribute('aria-disabled','true')});
if(warning){warning.hidden=false;warning.textContent='Deletion in progress…'}
};
const setError=message=>{
modal.classList.remove('is-deleting');
submitted=false;
title.textContent=`Delete this ${label}?`;
body.textContent=kind==='validation'
? 'This removes only this validation run’s linked Space Test artifacts. The parent Build Run and generated Space will not be deleted. The tested Space will not be deleted.'
: (linkedDelete.count?`This removes this Build Run’s bucket artifacts and ${linkedDelete.count} linked Space Test validation run${linkedDelete.count===1?'':'s'}. The generated Space is kept unless you explicitly choose to delete it below.`:'This removes this Build Run’s bucket artifacts, logs, state, traces and report. The generated Space is kept unless you explicitly choose to delete it below.');
confirmBtn.textContent=active?'Delete stored files':'Delete run';
confirmBtn.disabled=false;
cancelEls.forEach(el=>{el.disabled=false;el.removeAttribute('aria-disabled')});
if(warning){warning.hidden=false;warning.textContent=message||'Deletion failed. You can retry or keep the run.'}
};
const onCancel=()=>{if(!modal.classList.contains('is-deleting'))close(false)};
const onConfirm=()=>{if(submitted||modal.classList.contains('is-deleting'))return;submitted=true;resolve({deleteSpace:Boolean(spaceCheckbox&&spaceCheckbox.checked&&canDeleteSpace),associatedSpace,setDeleting,setError,close});};
const onKey=e=>{if(e.key==='Escape')onCancel();if(e.key==='Enter'&&modal.classList.contains('is-open'))onConfirm()};
cancelEls.forEach(el=>el.addEventListener('click',onCancel));
confirmBtn.addEventListener('click',onConfirm);
document.addEventListener('keydown',onKey);
modal.hidden=false;
requestAnimationFrame(()=>{modal.classList.add('is-open');confirmBtn.focus();});
});
return state.deleteModalPromise;
}
async function deleteRunById(runId,options={}){
const context=runDeletionContext(runId,options);
runId=context.runId;
if(!runId){showMessage(context.kind==='validation'?'Select a validation run before deleting it.':'Select a run before deleting it.','warning');return}
if(state.deletingRuns&&state.deletingRuns[runId])return;
const status=canonicalStatusForDeletion(context);
const confirmed=await confirmRunDeletion({runId,kind:context.kind,status,detail:{...(context.detail||{}),summary:{...(context.summary||{}),status}}});
if(!confirmed)return;
const deleteSpace=typeof confirmed==='object'&&Boolean(confirmed.deleteSpace);
if(state.deletingRuns&&state.deletingRuns[runId])return;
state.deletingRuns=state.deletingRuns||{};
state.deletingRuns[runId]=true;
if(confirmed&&typeof confirmed.setDeleting==='function')confirmed.setDeleting();
const buttonId=options.buttonId===null?null:(options.buttonId||(context.kind==='validation'?'deleteValidationRun':'deleteActiveRun'));
setButtonBusy(buttonId,true,'Deleting…');
let success=false;
try{
const result=await apiDelete(`/api/runs/${encodeURIComponent(runId)}?bucket_name=${encodeURIComponent(state.bucketName)}`,deleteSpace?{delete_space:true}:{});
const deletedChildren=Array.isArray(result.deleted_linked_validations)?result.deleted_linked_validations:[];
const childSuffix=deletedChildren.length?` and ${deletedChildren.length} linked validation${deletedChildren.length===1?'':'s'}`:'';
const suffix=deleteSpace?(result.space_deleted?' and associated Space':(result.space_delete_error?' but Space deletion failed':' and Space was already missing')):'';
showMessage(`Deleted run ${runId}${childSuffix}${suffix}`,'success');
success=true;
rememberDeletedRun(runId);
deletedChildren.forEach(id=>rememberDeletedRun(id));
clearDeletedRunState(runId,context.kind);
forgetRunEverywhere(runId);
deletedChildren.forEach(id=>{clearDeletedRunState(id,'validation');forgetRunEverywhere(id);});
renderRunsFromCache();
if(confirmed&&typeof confirmed.close==='function')confirmed.close(true);
loadRuns(true).catch(e=>console.warn('post-delete runs refresh failed',e));
}catch(e){
showMessage(e.message,true);
if(confirmed&&typeof confirmed.setError==='function')confirmed.setError(e.message);
}finally{
if(state.deletingRuns)delete state.deletingRuns[runId];
setButtonBusy(buttonId,false);
if(buttonId){
const btn=$(buttonId);
const currentId=buttonId==='deleteActiveRun'?state.runId:state.validationRunId;
if(btn)btn.disabled=!(currentId&¤tId===runId);
}
}
}
async function deleteSelectedRun(){return deleteRunById(null,{kind:'active',detail:state.selectedRunDetail||state.activeRunProgress||{}})}
function defaultRunDocuments(detail={}){
const summary=detail.summary||{};
const runId=summary.run_id||detail.run_id||state.runId;
const bucket=summary.bucket_source||detail.bucket_source||state.bucketSource;
const rootUrl=runId&&bucket?artifactUrl(runId,bucket):'';
const blob=rel=>runId&&bucket?`https://huggingface.co/buckets/${bucket}/tree/runs/${runId}/${rel}`:'';
const tree=rel=>rootUrl?`${rootUrl}/${rel}`:'';
return [
{id:'pi_redacted_trace',label:'Pi redacted',subtitle:'Source folder',icon:'🛡️',present:false,url:blob('traces/redacted/agent_trace.jsonl')||tree('traces/redacted'),sensitivity:'safe'},
{id:'report',label:'Report',subtitle:'Source document',icon:'📄',present:false,url:blob('report.md')},
{id:'smoke',label:'Smoke',subtitle:'Source JSON',icon:'⚡',present:false,url:blob('tests/generation_smoke.json')},
{id:'smoke_output',label:'Output',subtitle:'Generated artifact',icon:'🖼️',present:false,url:blob('artifacts/image.webp')||tree('artifacts')},
{id:'repair_decision',label:'Decision',subtitle:'Source JSON',icon:'◇',present:false,url:blob('repair/REPAIR_DECISION.json')},
{id:'blockage',label:'Blockage',subtitle:'Source JSON',icon:'!',tone:'warn',present:false,url:blob('repair/BLOCKAGE.json')},
{id:'eval_publish',label:'Eval publish',subtitle:'Archive status',icon:'◎',present:false,url:blob('eval_publish_status.json')},
{id:'space_logs',label:'Space logs',subtitle:'Build/runtime index',icon:'◉',present:false,url:blob('logs/space_logs_index.json')},
];
}
function mergeStableRunDocuments(runId,docs=[]){
state.documentCache=state.documentCache||{};
const cached=Array.isArray(state.documentCache[runId])?state.documentCache[runId]:[];
const byId=new Map(cached.map(d=>[d.id,{...d}]));
for(const doc of docs||[]){
const previous=byId.get(doc.id)||{};
byId.set(doc.id,{...previous,...doc,present:Boolean(doc.present||previous.present),url:doc.url||previous.url||''});
}
return docs.map(doc=>byId.get(doc.id)||doc);
}
function deriveRunDocuments(detail={}){
const baseDocs=defaultRunDocuments(detail);
const backendDocs=Array.isArray(detail.run_documents)?detail.run_documents:[];
const docs=backendDocs.length?baseDocs.map(base=>({...(base||{}),...(backendDocs.find(doc=>doc&&doc.id===base.id)||{})})).concat(backendDocs.filter(doc=>doc&&!baseDocs.some(base=>base.id===doc.id))):baseDocs;
const files=Array.isArray(detail.files)?detail.files:[];
const manifestArtifacts=Array.isArray(detail.artifact_manifest?.artifacts)?detail.artifact_manifest.artifacts:[];
const manifestPaths=manifestArtifacts.filter(a=>a&&a.present!==false).map(a=>String(a.path||'')).filter(Boolean);
const filePaths=new Set([...files.map(f=>String(f.path||'')),...manifestPaths]);
const hasPrefix=prefix=>[...filePaths].some(path=>String(path||'').startsWith(prefix.replace(/\/$/,'')+'/'));
const firstKnownPath=(candidates=[])=>candidates.find(path=>filePaths.has(path))||'';
const retargetDocUrl=(doc,rel)=>{if(!doc||!rel)return;const runId=summary.run_id||detail.run_id||state.runId;const bucket=summary.bucket_source||detail.bucket_source||state.bucketSource;doc.url=runId&&bucket?`https://huggingface.co/buckets/${bucket}/tree/runs/${runId}/${rel.replace(/^\//,'')}`:doc.url||'';};
const reportText=String(detail.report||'');
const summary=detail.summary||{};
const blockers=detail.technical_blockers||{};
const status=String(summary.status||detail.final_status_reconciliation?.status||detail.state?.status||detail.status||'').toLowerCase();
const finalStatus=String(detail.final_status_reconciliation?.status||summary.final_status||summary.status||detail.state?.status||'').toLowerCase();
const terminalFullSuccess=['full_inference_success','success','succeeded','completed','done'].includes(finalStatus)||detail.generation_smoke?.status==='success'||detail.generation_smoke?.ok===true||summary.generation_smoke_passed===true||detail.final_status_reconciliation?.generation_smoke_passed===true;
const shouldShowBlockers=Boolean(Object.keys(blockers).length)||status.includes('manual')||status.includes('blocker')||status.includes('failed')||status.includes('error');
const byId=new Map(docs.map(d=>[d.id,{...d}]));
const traceDocState=(prefix,doc)=>{
const folderPrefix=prefix.replace(/\/$/,'')+'/';
const hasContent=[...filePaths].some(path=>path.startsWith(folderPrefix)&&!path.endsWith('/'));
const runId=summary.run_id||detail.run_id||state.runId;
const bucket=summary.bucket_source||detail.bucket_source||state.bucketSource;
const folderUrl=runId&&bucket?`https://huggingface.co/buckets/${bucket}/tree/runs/${runId}/${prefix.replace(/\/$/,'')}`:'';
const existingUrl=String(doc.url||'');
const existingIsFolder=existingUrl.endsWith(`/${prefix.replace(/\/$/,'')}`);
return {present:Boolean(hasContent||doc.present),url:folderUrl||existingUrl};
};
const redactedTrace=traceDocState('traces/redacted',byId.get('pi_redacted_trace'));
byId.get('pi_redacted_trace').present=redactedTrace.present;
byId.get('pi_redacted_trace').url=redactedTrace.url;
byId.get('report').present=Boolean((byId.get('report').present&&byId.get('report').url)||reportText.length||filePaths.has('report.md')||terminalFullSuccess);
if(terminalFullSuccess&&!byId.get('report').url)retargetDocUrl(byId.get('report'),'report.md');
// Legacy invariant: filePaths.has('generation_smoke.json') remains covered by firstKnownPath below.
const smokePath=firstKnownPath(['tests/generation_smoke.json','tests/generation_smoke_latest.json','generation_smoke.json','tests/test_result.json']);
byId.get('smoke').present=Boolean((byId.get('smoke').present&&byId.get('smoke').url)||Object.keys(detail.generation_smoke||{}).length||Boolean(smokePath)||terminalFullSuccess);
if(smokePath)retargetDocUrl(byId.get('smoke'),smokePath);
else if(terminalFullSuccess)retargetDocUrl(byId.get('smoke'),'tests/generation_smoke.json');
if(byId.has('smoke_output')){
const outputPath=firstKnownPath(['artifacts/image.webp','artifacts/image.png','artifacts/image.jpg','artifacts/image.jpeg','artifacts/output.png','artifacts/output.webp','artifacts/output.json']);
const hasOutput=Boolean(outputPath)||hasPrefix('artifacts');
byId.get('smoke_output').present=Boolean((byId.get('smoke_output').present&&byId.get('smoke_output').url)||hasOutput);
if(outputPath)retargetDocUrl(byId.get('smoke_output'),outputPath);
else if(hasOutput)retargetDocUrl(byId.get('smoke_output'),'artifacts');
}
if(shouldShowBlockers&&!byId.has('blockers')){
const runId=summary.run_id||detail.run_id||state.runId;
const bucket=summary.bucket_source||detail.bucket_source||state.bucketSource;
byId.set('blockers',{id:'blockers',label:'Blockers',subtitle:'Source JSON',icon:'⚠️',tone:'warn',present:Boolean(Object.keys(blockers).length||filePaths.has('generated/TECHNICAL_BLOCKERS.json')||filePaths.has('TECHNICAL_BLOCKERS.json')),url:runId&&bucket?`https://huggingface.co/buckets/${bucket}/tree/runs/${runId}/generated/TECHNICAL_BLOCKERS.json`:''});
}
if(byId.has('repair_decision')){
byId.get('repair_decision').present=Boolean((byId.get('repair_decision').present&&byId.get('repair_decision').url)||nonEmptyObject(detail.repair_decision)||filePaths.has('repair/REPAIR_DECISION.json'));
}
if(byId.has('blockage')){
byId.get('blockage').present=Boolean((byId.get('blockage').present&&byId.get('blockage').url)||nonEmptyObject(detail.blockage)||filePaths.has('repair/BLOCKAGE.json'));
}
if(byId.has('eval_publish')){
const evalStatus=detail.eval_publish||detail.eval_publish_status||{};
byId.get('eval_publish').present=Boolean((byId.get('eval_publish').present&&byId.get('eval_publish').url)||nonEmptyObject(detail.eval_publish)||nonEmptyObject(detail.eval_publish_status)||filePaths.has('eval_publish_status.json'));
if(nonEmptyObject(evalStatus)){
if(evalStatus.published===true)byId.get('eval_publish').tone='neutral';
else if(String(evalStatus.reason||'')==='record_not_ready')byId.get('eval_publish').tone='pending';
else if(evalStatus.attempted)byId.get('eval_publish').tone='warn';
}
}
if(byId.has('space_logs')){
const logIndex=detail.space_logs_index||detail.space_log_index||detail.logs_index||{};
const logPath=firstKnownPath(['logs/space_logs_index.json','space_logs_index.json','logs/space_logs_build.txt','logs/space_logs_runtime.txt','logs/space_logs_run.txt','logs/space_logs_fetch_status.json','logs/space_log_diagnostics.json','logs/space_runtime_snapshot.json','logs/pi_live_output.txt','logs/pi_output.txt','logs/build_log_fast_probe_status.json']);
const hasSpaceLogs=nonEmptyObject(logIndex)||Boolean(logPath)||hasPrefix('logs');
byId.get('space_logs').present=Boolean((byId.get('space_logs').present&&byId.get('space_logs').url)||hasSpaceLogs);
if(logPath){retargetDocUrl(byId.get('space_logs'),logPath);}
else if(hasSpaceLogs){retargetDocUrl(byId.get('space_logs'),'logs');}
if(!filePaths.has('logs/space_logs_index.json')&&logPath&&logPath!=='space_logs_index.json')byId.get('space_logs').subtitle='Build/runtime logs';
if(nonEmptyObject(logIndex)){
const quality=String(logIndex.log_quality||logIndex.quality||'').toLowerCase();
if(quality==='snapshot_only'||quality==='partial')byId.get('space_logs').tone='warn';
if(quality==='unavailable')byId.get('space_logs').tone='warn';
}
}
if(!byId.has('repair')&&hasPrefix('repair')){
const runId=summary.run_id||detail.run_id||state.runId;
const bucket=summary.bucket_source||detail.bucket_source||state.bucketSource;
byId.set('repair',{id:'repair',label:'Repair',subtitle:'Source folder',icon:'✦',tone:status.includes('failed')?'warn':'neutral',present:true,url:runId&&bucket?`https://huggingface.co/buckets/${bucket}/tree/runs/${runId}/repair`:''});
}
const order=['pi_redacted_trace','repair_decision','repair','blockage','report','smoke','smoke_output','eval_publish','space_logs','blockers'];
const runId=String(summary.run_id||detail.run_id||state.runId||'');
const resolved=order.map(id=>byId.get(id)).filter(Boolean).filter(d=>{
if(['repair_decision','blockage','eval_publish','space_logs','smoke_output'].includes(d.id))return Boolean(d.present);
if(d.id==='blockers')return shouldShowBlockers||d.present;
return true;
});
return runId?mergeStableRunDocuments(runId,resolved):resolved;
}
function renderRunDocuments(detail={}){
const root=$('runDocumentsDock');
if(!root)return;
const runId=String(detail.run_id||detail.summary?.run_id||state.runId||'');
state.documentCache=state.documentCache||{};
let docs=deriveRunDocuments(detail);
const hasReady=docs.some(d=>d.present&&d.url);
if(hasReady||!state.documentCache[runId])state.documentCache[runId]=mergeStableRunDocuments(runId,docs);
docs=state.documentCache[runId]||docs;
if(!docs.length){root.innerHTML='
Run documents are being indexed…
';return;}
const signature=JSON.stringify(docs.map(d=>[d.id,d.present,d.url,d.label,d.subtitle,d.tone]));
if(root.dataset.signature===signature)return;
root.dataset.signature=signature;
root.innerHTML=docs.map(doc=>{
const present=Boolean(doc.present&&doc.url);
const tag=present?'a':'span';
const attrs=present?`href="${escapeHtml(doc.url)}" target="_blank" rel="noreferrer"`:'';
const title=present?`Open source: ${doc.label}`:`${doc.label} is not in the bucket yet`;
const cls=['run-doc-btn',present?'ready':'pending',doc.sensitivity==='raw'?'raw':'',doc.sensitivity==='safe'?'safe':'',doc.tone==='warn'?'warn':''].filter(Boolean).join(' ');
return `<${tag} class="${cls}" ${attrs} title="${escapeHtml(title)}" aria-disabled="${present?'false':'true'}">${escapeHtml(doc.icon||'📄')}${escapeHtml(doc.label)}${escapeHtml(present?doc.subtitle||'Open source':'Pending')}${tag}>`;
}).join('');
}
function recoveryDecisionActionLabel(action){
const key=String(action||'').toLowerCase();
return {
wait_for_logs:'Wait for logs',
inspect_more_logs:'Inspect more logs',
factory_rebuild_same_code:'Factory rebuild same code',
patch_code:'Patch code',
request_manual_hardware:'Request manual hardware',
declare_technical_blocker:'Declare technical blocker'
}[key]||badgeLabel(key||'pending');
}
function recoveryStatusTone(action,status,detail={}){
const a=String(action||'').toLowerCase();
const s=String(status||'').toLowerCase();
const validated=Boolean(latestRecoveryEvent(detail,['repair_validation'])&&['success','done','passed'].includes(String(latestRecoveryEvent(detail,['repair_validation'])?.status||'').toLowerCase()));
if(validated)return'success';
if(a.includes('blocker')||s.includes('failed')||s.includes('error'))return'error';
if(a.includes('manual'))return'warn';
if(a.includes('rebuild')||a.includes('wait')||a.includes('inspect'))return'running';
if(a.includes('patch'))return'warn';
return'neutral';
}
function nonEmptyObject(value){
return Boolean(value&&typeof value==='object'&&!Array.isArray(value)&&Object.keys(value).length>0);
}
function runHasRecoverySignals(detail={}){
const files=Array.isArray(detail.files)?detail.files:[];
const events=Array.isArray(detail.events)?detail.events:([]);
const runId=String(detail.run_id||detail.summary?.run_id||state.runId||'');
const stableEvents=typeof mergeStableEvents==='function'?mergeStableEvents(runId,events):events;
const decision=detail.repair_decision;
const blockage=detail.blockage;
const recoveryStepPattern=/^(failure_detected|failure_diagnosis|pi_diagnosis|repair_decision|wait_for_logs|factory_rebuild|repair|repair_diagnosis|repair_brief|repair_plan|repair_patch|repair_upload|repair_validation|technical_blocker|manual_hardware_required|failure)$/;
return Boolean(
nonEmptyObject(decision)||
nonEmptyObject(blockage)||
files.some(f=>String(f.path||'').startsWith('repair/'))||
stableEvents.some(e=>recoveryStepPattern.test(String(e.step||'')))
);
}
function latestRecoveryEvent(detail={},steps=[]){
const wanted=new Set(steps);
const events=Array.isArray(detail.events)?detail.events:[];
const runId=String(detail.run_id||detail.summary?.run_id||state.runId||'');
const stableEvents=typeof mergeStableEvents==='function'?mergeStableEvents(runId,events):events;
for(const ev of [...stableEvents].reverse()){
if(wanted.has(String(ev.step||'')))return ev;
}
return null;
}
function recoverySourceDocuments(detail={}){
const docs=deriveRunDocuments(detail).filter(d=>d&&d.present&&d.url);
const byId=new Map(docs.map(d=>[d.id,d]));
const links=[];
const add=(id,label)=>{const d=byId.get(id);if(d&&d.url)links.push({label,url:d.url,tone:d.tone||'',sensitivity:d.sensitivity||''});};
add('repair_decision','Decision');
add('blockage','Blockage');
add('pi_redacted_trace','Pi trace');
return links.slice(0,4);
}
function recoveryPhaseLabel(detail={},decision={},blockage={}){
const summary=detail.summary||{};
const status=String(summary.status||detail.state?.status||detail.status||'').toLowerCase();
const terminalFailure=latestRecoveryEvent(detail,['failure']);
if(nonEmptyObject(blockage)||status.includes('blocker')||status.includes('manual'))return'Final blocker';
if(decision.action&&TERMINAL_STATUSES.has(status))return'Final decision';
if(terminalFailure&&status.includes('fail')&&!decision.action)return'Recovery interrupted';
if(latestRecoveryEvent(detail,['repair_validation','generation_smoke','inference_gate']))return'Revalidating';
if(latestRecoveryEvent(detail,['repair_brief','repair_plan','repair_patch','repair_upload']))return'Repairing';
if(decision.action)return'Decision made';
return'Live diagnosis';
}
function finalBlockerFromDetail(detail={}){
const obs=detail.build_error_observation||{};
const tail=String(obs.tail||obs.first_error||'');
const reason=String(obs.reason||'');
if(reason||tail){
if(tail.includes('pyenv install 3.1')||tail.replace(/\s+/g,'').includes('python3.1'))return 'Invalid Python version requested pyenv install 3.1';
if(tail.includes('BUILD FAILED')||reason.includes('BUILD_ERROR'))return 'Space build failed after repair';
return shortText(tail||reason,180);
}
return '';
}
function renderAgentRecovery(detail={}){
const card=$('agentRecoveryCard');
const body=$('agentRecoveryBody');
const badge=$('agentRecoveryBadge');
if(!card||!body)return;
if(!runHasRecoverySignals(detail)){
card.hidden=true;
body.innerHTML='';
if(badge){badge.textContent='Not needed';badge.className='badge neutral'}
return;
}
card.hidden=false;
const decision=detail.repair_decision||{};
const blockage=detail.blockage||{};
const summary=detail.summary||{};
const status=summary.status||detail.state?.status||detail.status||'';
const failureEvent=latestRecoveryEvent(detail,['failure']);
const action=decision.action||blockage.recommended_action||blockage.action||'';
const normalizedAction=recoveryDecisionActionLabel(action||(failureEvent?'interrupted':'diagnosis'));
const tone=failureEvent&&!decision.action?'error':recoveryStatusTone(action,status,detail);
if(badge){badge.textContent=normalizedAction;badge.className='badge '+(tone==='success'?'success':tone==='error'?'error':tone==='warn'?'warn':tone==='running'?'running':'neutral')}
const diagnosisEvent=latestRecoveryEvent(detail,['failure_diagnosis','pi_diagnosis','repair_decision']);
const decisionEvent=latestRecoveryEvent(detail,['repair_decision']);
const decisionMade=Boolean(decision.action||decisionEvent);
const rebuildEvent=latestRecoveryEvent(detail,['wait_for_logs','factory_rebuild']);
const patchEvent=latestRecoveryEvent(detail,['repair_brief','repair_plan','repair_patch','repair_upload','repair_validation']);
const failureReason=failureEvent?(failureEvent.reason||failureEvent.error||failureEvent.message||'The worker failed before Pi produced a structured recovery decision.') : '';
const reason=decision.reason||blockage.reason||blockage.message||failureReason||diagnosisEvent?.message||'Pi diagnosis is coordinating the next recovery action from collected logs, status and validation evidence.';
const evidence=Array.isArray(decision.evidence)?decision.evidence:[];
const next=decision.next_step||blockage.suggested_next_step||blockage.next_step||'';
const phase=recoveryPhaseLabel(detail,decision,blockage);
const sourceDocs=recoverySourceDocuments(detail);
const rows=[];
const finalBlocker=finalBlockerFromDetail(detail);
const summaryParts=[];
if(finalBlocker){
summaryParts.push(`Initial blocker
`);
body.innerHTML=rows.join('');
}
function renderActiveRunActions(summary={},detail={}){
const runId=summary.run_id||detail.run_id;
const targetSpace=summary.target_space||detail.state?.target_space||detail.launch?.target_space||'';
const bucket=summary.bucket_source||detail.bucket_source||state.bucketSource;
const artifacts=summary.artifacts_url||(typeof artifactUrl==='function'?artifactUrl(runId,bucket):'');
const jobUrl=inferredJobUrl(summary,detail);
const status=summary.status||detail.status||detail.state?.status||'';
const cancel=$('cancelRun');
if(cancel){
const terminal=typeof runIsFinished==='function'?runIsFinished(status):TERMINAL_STATUSES.has(String(status||'').toLowerCase());
cancel.hidden=Boolean(terminal);
cancel.disabled=Boolean(terminal)||!runId;
}
const spaceUrl=summary.target_space_url||detail.links?.target_space_url||(targetSpace?`https://huggingface.co/spaces/${targetSpace}`:'');
const ready=Boolean(spaceUrl)||(typeof runPassedSpaceCreation==='function'?runPassedSpaceCreation({summary,detail,events:detail.events||[]}):false);
setLink('activeOpenJob',jobUrl);
setLink('activeOpenSpace',ready?spaceUrl:'');
setLink('activeOpenSettings',ready&&spaceUrl?spaceUrl+'/settings':'');
setLink('activeOpenArtifacts',artifacts);
const prefill=$('activePrefillSpaceTest');
if(prefill){
const view=detail.view||detail;
const statusModel=view.status_model||detail.status_model||{};
const headerStatus=String(view.header?.status||statusModel.global_status||status||'').toLowerCase();
const terminal=Boolean(statusModel.is_terminal)||TERMINAL_STATUSES.has(headerStatus)||runIsFinished(headerStatus);
const exploitableStatus=['success','succeeded','partial','partial_validation','manual_hardware_required','waiting_manual_action','manual_action_required'].includes(headerStatus)||String(statusModel.global_status||'').includes('manual');
const canPrefill=Boolean(targetSpace)&&terminal&&exploitableStatus;
prefill.disabled=!canPrefill;
prefill.title=canPrefill?'Prefill Space Test from this completed build':'Available after the build reaches a final Space state.';
prefill.onclick=canPrefill?prepareValidationFromActiveRun:null;
}
const del=$('deleteActiveRun');
if(del){
const canDelete=Boolean(runId&&runCanBeDeleted(status));
del.disabled=!canDelete;
del.title=canDelete?'Delete this run folder':'You can delete a run after the Job is finished or if only stale metadata remains.';
del.onclick=canDelete?()=>deleteRunById(runId,{kind:'active',detail}):null;
}
}
function renderSelectedLinks(summary={},detail={}){renderActiveRunActions(summary,detail)}
function renderBlockers(detail={}){
const root=$('selectedBlockers');
if(!root)return;
const detailRunId=detail.run_id||detail.summary?.run_id||detail.state?.run_id||'';
if(detailRunId&&state.runId&&detailRunId!==state.runId){root.hidden=true;root.innerHTML='';return}
const summary=detail.summary||{};
const blockers=detail.technical_blockers||{};
const manual=summary.manual_hardware_required||String(summary.status||'').includes('manual_hardware_required');
const blockerItems=(Array.isArray(blockers.blockers)?blockers.blockers:[]).filter(b=>!['patch_code','repair_decision','repair','recovery'].includes(String(b.type||b.name||'').toLowerCase()));
// Pi assistant model changed is rendered once in the compact Run notes banner.
if(!manual&&!blockerItems.length){root.hidden=true;root.innerHTML='';return}
root.hidden=false;
const parts=[];
if(manual)parts.push('Manual hardware required
Open Space settings, choose the recommended GPU, then run validation.
');
for(const b of blockerItems.slice(0,4)){parts.push(`${escapeHtml(shortText(b.type||b.name||'Technical blocker',32))}
Archive publication status appears after the backend checks the selected run.
';body.dataset.runId='';}
if(card){card.hidden=true;card.dataset.runId='';card.classList.remove('has-eval','published','needs-attention','pending');}
}
function evalArchiveHasData(status={},local={}){return Boolean((status&&typeof status==='object'&&Object.keys(status).length)||(local&&typeof local==='object'&&Object.keys(local).length));}
function renderEvalArchiveStatus(detail={}){
const card=$('runEvalArchiveCard');
const body=$('evalArchiveBody');
const badge=$('evalArchiveBadge');
if(!card||!body)return;
const runId=detail.run_id||detail.summary?.run_id||detail.state?.run_id||'';
if(state.runId&&runId&&runId!==state.runId){clearEvalArchiveStatus('stale-run');return;}
const status=detail.eval_publish_status||detail.eval_publish||{};
const local=detail.eval_record||{};
if(!evalArchiveHasData(status,local)){clearEvalArchiveStatus('no-data');return}
card.hidden=false;
card.dataset.runId=runId||'';
body.dataset.runId=runId||'';
card.classList.add('has-eval');
const published=status.published===true;
const attempted=status.attempted===true;
const reason=status.reason||'';
if(badge){
badge.textContent=published?'Published':attempted&&reason==='record_not_ready'?'Pending':attempted?'Needs attention':'Pending';
badge.className='badge '+(published?'success':attempted&&reason!=='record_not_ready'?'warn':'neutral');
}
const bucket=status.eval_bucket_source||status.archive_bucket||status.bucket_source||'';
const path=status.archive_relative_path||status.path||'';
const localLabel=(status.local_record_found||Object.keys(local||{}).length)?'written':'pending';
const backendLabel=published?'published':attempted&&reason==='record_not_ready'?'pending':attempted?'not published':'pending';
const manual=detail.manual_validation_status||detail.summary?.manual_validation_status||detail.view?.manual_validation||{};
const effective=manual.status==='success'?'validated_after_space_test':(detail.summary?.effective_status||detail.effective_status||'');
const intro=published?'Eval record copied to the operator archive bucket.':attempted&&reason==='record_not_ready'?'Eval record will be archived when the run completes.':'Archive publication is not confirmed yet.';
const effectiveNote=effective?`
Effective verdict: ${escapeHtml(runCompactStatusLabel(effective))}${manual.validation_run_id?` from linked Space Test ${escapeHtml(manual.validation_run_id)}`:''}.
`}
const artifactRoot=$('artifactList');
if(artifactRoot){const interesting=files.filter(f=>!/traces\//.test(f.path||'')).slice(0,18);artifactRoot.innerHTML=interesting.length?interesting.map(f=>`${escapeHtml(f.path)}${f.size?Math.round(Number(f.size)/1024)+' KB':''}`).join(''):'No artifacts indexed yet.'}
const reportText=(detail.report||'No report available.').slice(0,8000);
const report=$('reportPreview');
if(report)report.textContent=reportText;
const resolvedSpaceUrl=summary.target_space_url||detail.links?.target_space_url||(summary.target_space||detail.state?.target_space?`https://huggingface.co/spaces/${summary.target_space||detail.state?.target_space}`:'');
setQuickLinks({job_url:inferredJobUrl(summary,detail),target_space_url:resolvedSpaceUrl,target_space_settings_url:resolvedSpaceUrl?resolvedSpaceUrl+'/settings':'',artifacts_url:summary.artifacts_url,bucket_source:detail.bucket_source,run_id:runId,target_space:summary.target_space||detail.state?.target_space,links_ready:Boolean(detail.links?.links_ready||detail.space_identity?.links_ready||detail.space_link_state?.links_ready),space_created:Boolean(detail.links?.space_created||detail.space_identity?.space_created||detail.space_link_state?.space_created),space_uploaded:Boolean(detail.links?.space_uploaded||detail.links?.runtime_uploaded||detail.space_identity?.space_uploaded||detail.space_identity?.runtime_uploaded||detail.space_link_state?.runtime_uploaded),runtime_uploaded:Boolean(detail.links?.runtime_uploaded||detail.space_identity?.runtime_uploaded||detail.space_link_state?.runtime_uploaded),space_runtime_known:Boolean(detail.links?.space_runtime_known||detail.space_identity?.space_runtime_known||detail.space_link_state?.space_runtime_known)},{summary,detail,space_identity:detail.space_link_state||detail.space_identity||{},space_link_state:detail.space_link_state||{},events:detail.events||[]});
renderActiveRunActions({...summary,bucket_source:detail.bucket_source},detail);
renderBlockers(detail);
renderAgentRecovery(detail);
renderEvalArchiveStatus(detail);
renderRunDocuments(detail);
renderMetrics({...detail,summary});
/* v196.2: render updates must not steal the user's Center Workspace tab.
The run-selection path may open Active Run initially, but later /progress
refreshes only hydrate panels in place. */
}
// Build run routing invariant: run selection may switchCenterTab('active') once; render/poll refreshes must not steal the Center Workspace tab.
// Legacy test anchors retained as comments only; render/poll refreshes must not execute them:
// avoid rendering stale view.pipeline
// switchCenterTab('active');setBuildModeInspecting(runId);startPolling(runId)
// Legacy route invariant: startPolling(runId);renderRunDetail(detail)
// Legacy wording: Validation latency / Aggregated issues
// Legacy invariant: state.runsCache=sortRunsNewestFirst(data.runs||[])
// Legacy test phrase retained for run notes wording: Likely Inference Providers routing/fallback.
// Legacy clean-delete invariant: await loadRuns(true) was intentionally replaced by post-delete background refresh in v190.9.
// Legacy validation preview invariant: if(isValidationRunDetail(detail)){showValidationRunDetail(detail)
// v190.15 build-first compatibility invariant: legacy/incomplete Build Runs stay visible, validation runs require parent_build_run_id before they can affect parent stats.