<!-- SOLID CITY · part 3761 -->
ng can approve completion.',state:'open',owner:null,previousOwner:null,work:'Release target: Harbor Shuttle Board\nScope: planned inaugural service board\nRequired approvals: distance verification + safety language + explicit human confirmation',events:[
      ev('blocker','Workshop','Human approval is required before this release task can be completed.',null)
    ]}
  ];
  var tasks=taskSeed;
  function ev(type,actor,message,workerId,source,from,to){clock+=1;return{id:'e'+clock,type:type,actor:actor,message:message,workerId:workerId||null,source:source||null,from:from||null,to:to||null,order:clock,time:'E'+String(clock).padStart(2,'0')}}
  function allEvents(){var a=[];tasks.forEach(function(t){t.events.forEach(function(e){a.push({task:t,event:e})})});return a.sort(function(a,b){return b.event.order-a.event.order})}
  function ownerName(id){return id&&workers[id]?workers[id].name:'Unassigned'}
  function stateClass(s){return s==='in-progress'?'progress':s}
  function esc(v){return String(v==null?'':v).replace(/[&<>"]/g,function(c){return{'&':'&amp;','<':'&lt;','>':'&gt;','"':'&quot;'}[c]})}
  function taskById(id){return tasks.find(function(t){return t.id===id})}
  function addEvent(t,type,actor,msg,wid,source,from,to){t.events.push(ev(type,actor,msg,wid,source,from,to));renderAll()}
  function renderTasks(){var out='';tasks.forEach(function(t,i){out+='<article class="task '+(selectedTask===t.id?'active':'')+'" tabindex="0" role="button" data-task="'+t.id+'"><div class="task-num">'+String(i+1).padStart(2,'0')+'</div><div><h3>'+esc(t.title)+'</h3><div class="task-meta"><span class="state '+stateClass(t.state)+'">'+esc(t.state)+'</span><span class="owner">'+esc(ownerName(t.owner))+'</span><span>'+t.events.length+' events</span></div></div><span class="task-arrow">›</span></article>'});document.getElementById('taskList').innerHTML=out}
  function renderWorkers(){var out='';Object.keys(workers).forEach(function(k){var w=workers[k],held=tasks.filter(function(t){return t.owner===w.id&&t.state!=='done'}).length;out+='<div class="worker"><div class="avatar '+(w.kind==='human'?'human':(w.id==='safety'?'safe':''))+'">'+w.initials+'</div><div><strong>'+esc(w.name)+'</strong><span>'+esc(w.role)+' · '+esc(w.capabilities)+'</span></div><div class="worker-status">'+held+' TASK'+(held===1?'':'S')+'<br>'+w.status.toUpperCase()+'</div></div>'});document.getElementById('workerList').innerHTML=out}
  function renderFeed(){var events=allEvents(),out='';events.slice(0,18).forEach(function(x){var e=x.event,cls=e.type==='handoff'||e.type==='exchange'?'exchange':e.type.indexOf('info')===0?'info':e.type==='edit'?'edit':e.type==='blocker'?'blocker':'';out+='<div class="feed-item"><span class="feed-dot '+cls+'"></span><div><p><strong>'+esc(e.actor)+'</strong> · '+esc(e.message)+'</p><time>'+e.time+' · '+esc(x.task.title)+'</time></div></div>'});document.getElementById('activityFeed').innerHTML=out;document.getElementById('feedCount').textContent=events.length+' EVENTS';document.getElementById('navEvents').textContent=events.length+' events'}
  function activeBlockers(){return allEvents().filter(function(x){return x.event.type==='blocker'&&x.task.state!=='done'})}
  function sources(){var map={};allEvents().forEach(function(x){if(x.event.source){var key=x.event.source+'|'+x.task.id;map[key]={source:x.event.source,task:x.task,event:x.event}}});return Object.keys(map).map(function(k){return map[k]})}
  function exchanges(){return allEvents().filter(function(x){var e=x.event;return (e.type==='handoff'&&e.from&&e.to&&e.from!=='king'&&e.to!=='king')||e.type==='info-answer'||e.type==='exchange'})}
  function renderStats(){var done=tasks.filter(function(t){return t.state==='done'}).length,active=tasks.length-done,pct=Math.round(done/tasks.length*100),src=sources(),ex=exchanges(),blocks=activeBlockers();document.getElementById('navOpen').textContent=active+' active';
    var cards=[['1','ACTIVE PROJECT','Harbor Shuttle Board','highlight'],[done+'/'+tasks.length,'TASKS COMPLETE',pct+'% from recorded states',''],[src.length,'SOURCE REFERENCES','Attached to result events',''],[ex.length,'AI ↔ AI EXCHANGES','Recorded in task histories','highlight'],[blocks.length,'OPEN BLOCKERS','Human gates remain visible',''],[done,'COMPLETED WORK','Tasks with completion events','']];
    document.getElementById('statCards').innerHTML=cards.map(function(c){return'<div class="stat '+c[3]+'"><div class="number">'+c[0]+'</div><div class="label">'+c[1]+'</div><div class="note">'+c[2]+'</div></div>'}).join('');
    document.getElementById('progressSummary').textContent=pct+'% complete · '+done+' task'+(done===1?'':'s')+' with recorded completion events';
    document.getElementById('ownershipStats').innerHTML=tasks.map(function(t){return'<div class="stats-row"><div><strong>'+esc(t.title)+'</strong><p>'+esc(ownerName(t.owner))+' · '+esc(t.state)+' · '+t.events.length+' recorded events</p><div class="progress-track"><div class="progres