v0.1.9: per-company progress reviews + deck-quality guidance
progress.py reads the whole graded ledger and answers two questions the
per-deck scorecard can't: is the company actually progressing (composite/
BDEF-category/KPI trajectories, recurring vs resolved flags), and is the
material good enough to judge them by — a deterministic gap engine spots
what the decks are NOT showing (no profitability visibility, untargeted
KPIs, no forward guidance, broken forecast chain, silently dropped KPIs,
thin-evidence BDEF categories, no board asks) and renders each gap as a
concrete, paste-ready request for the next deck.
Served live from the ledger (no GPU) at /api/companies/{slug}/progress(.md),
written to /data/ledger/<slug>/PROGRESS.md + /data/reports/latest-progress.md
after each graded deck, and viewable/downloadable from the dashboard company
card ("View progress review"). 18 new tests.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
506e6c79bd
commit
9b9c7e58c1
@@ -149,6 +149,7 @@
|
||||
<div id="coDecks"><div class="muted">—</div></div>
|
||||
<div class="row">
|
||||
<button onclick="toggleScorecard()" id="scBtn">View SCORECARD.md</button>
|
||||
<button onclick="toggleProgress()" id="prBtn">View progress review</button>
|
||||
</div>
|
||||
<div id="coViewer" style="margin-top:10px"></div>
|
||||
</div>
|
||||
@@ -419,11 +420,15 @@ async function openCompany(slug,silent){
|
||||
}catch(e){ if(!silent) alert('load company failed: '+(e.message||e)); }
|
||||
}
|
||||
function closeCompany(){
|
||||
currentSlug=null; scorecardOpen=false;
|
||||
currentSlug=null; resetViewerToggles();
|
||||
document.getElementById('coViewer').innerHTML='';
|
||||
document.getElementById('scBtn').textContent='View SCORECARD.md';
|
||||
document.getElementById('companyCard').style.display='none';
|
||||
}
|
||||
function resetViewerToggles(){
|
||||
scorecardOpen=false; progressOpen=false;
|
||||
document.getElementById('scBtn').textContent='View SCORECARD.md';
|
||||
document.getElementById('prBtn').textContent='View progress review';
|
||||
}
|
||||
|
||||
let currentRecs=[];
|
||||
function renderDetail(d,changed){
|
||||
@@ -469,9 +474,8 @@ function renderDetail(d,changed){
|
||||
// Only reset the viewer when switching companies — periodic re-renders must
|
||||
// not close whatever report the user has open.
|
||||
if(changed){
|
||||
scorecardOpen=false;
|
||||
resetViewerToggles();
|
||||
document.getElementById('coViewer').innerHTML='';
|
||||
document.getElementById('scBtn').textContent='View SCORECARD.md';
|
||||
}
|
||||
}
|
||||
async function deleteCompany(){
|
||||
@@ -525,11 +529,11 @@ async function viewDeckJson(deckId){
|
||||
deckBase(deckId), `${currentSlug}-${deckId}.json`);
|
||||
}catch(e){ alert('load record failed: '+(e.message||e)); }
|
||||
}
|
||||
let scorecardOpen=false;
|
||||
let scorecardOpen=false, progressOpen=false;
|
||||
async function toggleScorecard(){
|
||||
if(!currentSlug) return;
|
||||
const v=document.getElementById('coViewer'), btn=document.getElementById('scBtn');
|
||||
if(scorecardOpen){ v.innerHTML=''; scorecardOpen=false; btn.textContent='View SCORECARD.md'; return; }
|
||||
if(scorecardOpen){ v.innerHTML=''; resetViewerToggles(); return; }
|
||||
try{
|
||||
const url='/api/companies/'+encodeURIComponent(currentSlug)+'/scorecard';
|
||||
const r=await fetch(url);
|
||||
@@ -539,9 +543,21 @@ async function toggleScorecard(){
|
||||
scorecardOpen=true; btn.textContent='Hide SCORECARD.md';
|
||||
}catch(e){ alert(e); }
|
||||
}
|
||||
async function toggleProgress(){
|
||||
if(!currentSlug) return;
|
||||
const v=document.getElementById('coViewer'), btn=document.getElementById('prBtn');
|
||||
if(progressOpen){ v.innerHTML=''; resetViewerToggles(); return; }
|
||||
try{
|
||||
const url='/api/companies/'+encodeURIComponent(currentSlug)+'/progress.md';
|
||||
const r=await fetch(url);
|
||||
const t=await r.text();
|
||||
setViewer('Progress review', r.ok? mdToHtml(t) : `<pre class="tall">${esc('error: '+t)}</pre>`,
|
||||
url, `${currentSlug}-PROGRESS.md`);
|
||||
progressOpen=true; btn.textContent='Hide progress review';
|
||||
}catch(e){ alert(e); }
|
||||
}
|
||||
function setViewer(title,html,dlHref,dlName){
|
||||
scorecardOpen=false;
|
||||
document.getElementById('scBtn').textContent='View SCORECARD.md';
|
||||
resetViewerToggles();
|
||||
const dl=dlHref?`<a class="mini" style="margin-left:auto" href="${dlHref}" `+
|
||||
`download="${esc(dlName||'report.txt')}" title="Download">⬇ download</a>`:'';
|
||||
document.getElementById('coViewer').innerHTML=
|
||||
|
||||
Reference in New Issue
Block a user