Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ How the project is landing. Quantum beats filed, sats flow, narrative traction.
| `quantum_beats.by_agent` | Breakdown per agent display name |
| `quantum_beats.last_7d` | Rolling week count |
| `sats_flow` | Bounty #30 + #33 + x402 + inscription revenue |
| `sats_flow.bounty_33_payout_ledger` | Issue #33 payout requests, paid proof rows, and pending/paid sats totals |
| `narrative_traction` | GitHub #33 comments, merged PRs, contributor count |
| `freshness` | Fetch timestamps + next refresh target |

Expand Down
136 changes: 110 additions & 26 deletions public/customer.json
Original file line number Diff line number Diff line change
@@ -1,24 +1,21 @@
{
"schema_version": 2,
"as_of": "2026-05-11",
"schema_version": 3,
"as_of": "2026-05-13",
"quantum_beats": {
"total": 31,
"total": 32,
"by_agent": {
"Amber Otter": 4,
"Trustless Indra": 2,
"Austere Dragon": 12,
"Amber Otter": 5,
"Tall Jett": 1,
"Trustless Indra": 3,
"Opal Gorilla": 1,
"Shining Tiger": 1,
"Austere Dragon": 8,
"Emerald Castle": 1,
"Grand Unicorn": 4,
"Grand Unicorn": 3,
"Ionic Nova": 4,
"Zen Rocket": 2,
"Wide Eden": 1,
"Prime Yeti": 1,
"Valiant Gecko": 1,
"Steel Otter": 1
"Zen Rocket": 1
},
"last_7d": 31,
"last_7d": 32,
"source": "https://aibtc.news/api/signals"
},
"sats_flow": {
Expand All @@ -28,10 +25,93 @@
"note": "Original research bounty (Issue #30), on-chain proof"
},
"bounty_33_pool_sats": 250000,
"bounty_33_paid_confirmed": "unknown — awaiting on-chain payout ledger in #33",
"bounty_33_paid_confirmed": 0,
"bounty_33_payout_ledger": {
"source_url": "https://github.com/1btc-news/news-client/issues/33",
"extracted_at": "2026-05-13T14:54:53.968Z",
"rows": [
{
"author": "wyslsz",
"created_at": "2026-05-11T23:51:56Z",
"comment_url": "https://github.com/1btc-news/news-client/issues/33#issuecomment-4426096246",
"pr": "#44",
"pr_state": "CLOSED",
"amount_sats": 15000,
"btc_address": null,
"txid": null,
"state": "requested",
"note": "Not counted as paid until bounty-poster approval and on-chain/payment proof are visible."
},
{
"author": "slashdevcorpse",
"created_at": "2026-05-12T04:42:44Z",
"comment_url": "https://github.com/1btc-news/news-client/issues/33#issuecomment-4427400238",
"pr": "#46",
"pr_state": "MERGED",
"amount_sats": null,
"btc_address": "bc1qzt33s8l22dgdfu8qdm3q5teu7529pl8tp5hkv8",
"txid": null,
"state": "requested",
"note": "Not counted as paid until bounty-poster approval and on-chain/payment proof are visible."
},
{
"author": "Iskander-Agent",
"created_at": "2026-05-12T20:48:36Z",
"comment_url": "https://github.com/1btc-news/news-client/issues/33#issuecomment-4434671083",
"pr": "#44",
"pr_state": "CLOSED",
"amount_sats": null,
"btc_address": "bc1qmd4y3mjcewp54epetvtxzcy8vamgtf75r5nevr",
"txid": null,
"state": "acked",
"note": "Not counted as paid until bounty-poster approval and on-chain/payment proof are visible."
},
{
"author": "slashdevcorpse",
"created_at": "2026-05-12T22:31:22Z",
"comment_url": "https://github.com/1btc-news/news-client/issues/33#issuecomment-4435360703",
"pr": "#48",
"pr_state": "OPEN",
"amount_sats": null,
"btc_address": "bc1qzt33s8l22dgdfu8qdm3q5teu7529pl8tp5hkv8",
"txid": null,
"state": "requested",
"note": "Not counted as paid until bounty-poster approval and on-chain/payment proof are visible."
},
{
"author": "SimoneMariaRomeo",
"created_at": "2026-05-13T14:27:28Z",
"comment_url": "https://github.com/1btc-news/news-client/issues/33#issuecomment-4442026567",
"pr": "#47",
"pr_state": "MERGED",
"amount_sats": 15000,
"btc_address": "bc1q5z8wd9fzvzzvvtkpvevae7jjh9sxut8lnlzauv",
"txid": null,
"state": "requested",
"note": "Not counted as paid until bounty-poster approval and on-chain/payment proof are visible."
},
{
"author": "SimoneMariaRomeo",
"created_at": "2026-05-13T14:40:22Z",
"comment_url": "https://github.com/1btc-news/news-client/issues/33#issuecomment-4442162797",
"pr": "#51",
"pr_state": "OPEN",
"amount_sats": null,
"btc_address": "bc1q5z8wd9fzvzzvvtkpvevae7jjh9sxut8lnlzauv",
"txid": null,
"state": "requested",
"note": "Not counted as paid until bounty-poster approval and on-chain/payment proof are visible."
}
],
"requested_sats": 30000,
"confirmed_paid_sats": 0,
"pending_requests": 6,
"paid_requests": 0,
"verifier": "Issue #33 comments plus on-chain BTC transaction proof for each address/txid."
},
"revenue_x402_sats": 100,
"revenue_x402_events": 1,
"revenue_x402_last_7d_events": "unknown — revenue KV unavailable during May 11 refresh",
"revenue_x402_last_7d_events": "unknown",
"revenue_x402_recent": [
{
"ts": "2026-04-16T16:44:19.015Z",
Expand All @@ -45,31 +125,35 @@
"inscription_sales_sats": 0
},
"narrative_traction": {
"issue_33_total_comments": 191,
"issue_33_unique_participants": 22,
"issue_33_iskander_comments": 57,
"quantum_visualizer_merged_prs": 13,
"quantum_visualizer_pr_contributors": 6,
"issue_33_total_comments": 212,
"issue_33_unique_participants": 27,
"issue_33_iskander_comments": 59,
"quantum_visualizer_merged_prs": 16,
"quantum_visualizer_pr_contributors": 9,
"pr_contributor_handles": [
"SimoneMariaRomeo",
"slashdevcorpse",
"mySebbe",
"Iskander-Agent",
"lekanbams",
"1feems",
"Dannye013",
"Iskander-Agent",
"SlyHarp",
"lekanbams",
"tearful-saw"
],
"dashboard_visits": "unknown — no analytics instrumented",
"x_engagement": "unknown — x-posting paused (credits depleted)"
},
"freshness": {
"signals_fetched_at": "2026-05-11T04:12:04Z",
"github_fetched_at": "2026-05-11T04:12:04Z",
"revenue_kv_fetched_at": "not refreshed — missing /home/admin/.openclaw/.env Cloudflare token in this environment",
"signals_fetched_at": "2026-05-13T14:54:53.968Z",
"github_fetched_at": "2026-05-13T14:54:53.968Z",
"revenue_kv_fetched_at": "not refreshed - CLOUDFLARE_API_TOKEN not found in environment or .openclaw/.env",
"next_refresh_target": "weekly synthesis (Sundays)"
},
"notes": [
"Silence is not a data point. Unknown fields stay unknown until verified.",
"Regenerate with: node scripts/build-customer.mjs",
"May 11 manual refresh updated public signal and GitHub metrics only; revenue ledger was left unchanged because Cloudflare KV credentials were unavailable."
"bounty_33_payout_ledger is parsed from issue #33 comments. Pending requests are not counted as paid.",
"Revenue KV unavailable in this environment; preserved the previous x402 counters."
]
}
104 changes: 104 additions & 0 deletions public/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,27 @@
.freshness-chip span{font-family:'JetBrains Mono',monospace;color:var(--text-muted);font-size:0.68rem}
@media(max-width:760px){.freshness-body{grid-template-columns:1fr}.freshness-kpis{grid-template-columns:1fr 1fr}.freshness-item{grid-template-columns:1fr}}

/* Payout ledger */
.payout-section{padding:2.5rem 0;border-top:1px solid var(--border)}
.payout-panel{border:1px solid var(--border);border-radius:var(--radius);background:var(--bg-elevated);overflow:hidden}
.payout-head{padding:1.25rem 1.5rem;border-bottom:1px solid var(--border);display:flex;align-items:flex-end;justify-content:space-between;gap:1rem;flex-wrap:wrap}
.payout-sub{font-size:0.82rem;color:var(--text-secondary);margin-top:0.35rem;max-width:720px;line-height:1.6}
.payout-body{padding:1.25rem;background:var(--bg)}
.payout-kpis{display:grid;grid-template-columns:repeat(3,1fr);gap:1px;background:var(--border);border-radius:var(--radius-sm);overflow:hidden;margin-bottom:1rem}
.payout-kpi{background:var(--bg-elevated);padding:0.9rem;min-width:0}
.payout-num{font-family:'JetBrains Mono',monospace;font-size:1.15rem;font-weight:800;letter-spacing:0}
.payout-label{font-size:0.62rem;font-weight:700;letter-spacing:0.07em;text-transform:uppercase;color:var(--text-muted);margin-top:0.2rem}
.payout-table-wrap{border:1px solid var(--border);border-radius:var(--radius-sm);overflow:auto;-webkit-overflow-scrolling:touch}
.payout-table{min-width:760px;font-size:0.82rem}
.payout-table td{background:var(--bg)}
.payout-status{display:inline-flex;align-items:center;justify-content:center;min-width:4.5rem;padding:0.25rem 0.45rem;border:1px solid var(--border);border-radius:100px;font-size:0.68rem;font-weight:700;text-transform:uppercase;letter-spacing:0.05em;color:var(--text-muted);white-space:nowrap}
.payout-status.status-paid{border-color:rgba(34,197,94,0.3);background:rgba(34,197,94,0.1);color:#22c55e}
.payout-status.status-requested,.payout-status.status-acked{border-color:rgba(247,147,26,0.28);background:rgba(247,147,26,0.08);color:var(--accent)}
.payout-link{font-size:0.75rem;color:var(--accent);text-decoration:none;font-weight:500;white-space:nowrap}
.payout-link:hover{text-decoration:underline}
.payout-mono{font-family:'JetBrains Mono',monospace;font-size:0.72rem;color:var(--text-secondary);word-break:break-all}
@media(max-width:760px){.payout-kpis{grid-template-columns:1fr}.payout-body{padding:0.75rem}}

/* API section */
.api-section{padding:2rem 0;border-top:1px solid var(--border)}
.api-card{display:flex;align-items:center;justify-content:space-between;background:var(--bg-elevated);border:1px solid var(--border);border-radius:var(--radius-sm);padding:1rem 1.25rem;flex-wrap:wrap;gap:0.75rem}
Expand Down Expand Up @@ -410,6 +431,40 @@ <h2 class="section-title">Source Freshness Audit</h2>
</div>
</section>

<!-- Payout Ledger -->
<section class="payout-section">
<div class="container">
<div class="payout-panel" id="payout-panel">
<div class="payout-head">
<div>
<h2 class="section-title">Payout Ledger</h2>
<p class="payout-sub">Customer world model view of bounty #33 payout requests and payment proof. Pending requests stay separate from paid sats until an issue comment or on-chain proof verifies payment.</p>
</div>
<span class="section-count" id="payout-asof"></span>
</div>
<div class="payout-body">
<div class="payout-kpis" id="payout-kpis"></div>
<div class="payout-table-wrap">
<table class="payout-table">
<thead>
<tr>
<th>Comment</th>
<th>PR</th>
<th>Amount</th>
<th>Status</th>
<th>Verifier</th>
</tr>
</thead>
<tbody id="payout-ledger-body">
<tr><td colspan="5" class="empty">Loading payout ledger...</td></tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</section>

<!-- Methodology -->
<section class="method-section">
<div class="container">
Expand Down Expand Up @@ -641,6 +696,55 @@ <h4>Ecosystem</h4>

renderFreshnessAudit();

function formatSats(value){
if(value==null||value===''||Number.isNaN(Number(value)))return '--';
return Number(value).toLocaleString()+' sats';
}

function payoutStatusClass(value){
return 'status-'+String(value||'tracked').toLowerCase().replace(/[^a-z0-9]+/g,'-').replace(/^-|-$/g,'');
}

function renderPayoutLedger(customer){
const body=document.getElementById('payout-ledger-body');
const kpis=document.getElementById('payout-kpis');
const asof=document.getElementById('payout-asof');
if(!body||!kpis||!asof)return;
const ledger=customer&&customer.sats_flow&&customer.sats_flow.bounty_33_payout_ledger;
if(!ledger||!Array.isArray(ledger.rows)){
asof.textContent='Customer model unavailable';
kpis.innerHTML='<div class="payout-kpi"><div class="payout-num">--</div><div class="payout-label">requested</div></div><div class="payout-kpi"><div class="payout-num">--</div><div class="payout-label">paid</div></div><div class="payout-kpi"><div class="payout-num">--</div><div class="payout-label">pending</div></div>';
body.innerHTML='<tr><td colspan="5" class="empty">Payout ledger data is not available in /customer.json.</td></tr>';
return;
}
asof.textContent=ledger.extracted_at?'Extracted '+String(ledger.extracted_at).slice(0,10):'Issue #33';
kpis.innerHTML=[
{num:formatSats(ledger.requested_sats),label:'requested'},
{num:formatSats(ledger.confirmed_paid_sats),label:'confirmed paid'},
{num:ledger.pending_requests||0,label:'pending rows'}
].map(k=>`<div class="payout-kpi"><div class="payout-num">${escapeHtml(k.num)}</div><div class="payout-label">${escapeHtml(k.label)}</div></div>`).join('');
const rows=ledger.rows.slice().reverse();
body.innerHTML=rows.length
?rows.map(r=>{
const verifier=r.txid
?`<div class="payout-mono">${escapeHtml(r.txid)}</div>`
:r.btc_address?`<div class="payout-mono">${escapeHtml(r.btc_address)}</div>`:'<span style="color:var(--text-muted)">awaiting proof</span>';
return `<tr>
<td><a class="payout-link" href="${escapeHtml(r.comment_url)}" target="_blank" rel="noopener">${escapeHtml(r.author||'comment')}</a><div class="td-affil">${escapeHtml((r.created_at||'').slice(0,10))}</div></td>
<td>${r.pr?escapeHtml(r.pr):'<span style="color:var(--text-muted)">--</span>'}<div class="td-affil">${escapeHtml(r.pr_state||'unknown')}</div></td>
<td class="td-name">${escapeHtml(formatSats(r.amount_sats))}</td>
<td><span class="payout-status ${payoutStatusClass(r.state)}">${escapeHtml(r.state||'tracked')}</span></td>
<td>${verifier}</td>
</tr>`;
}).join('')
:'<tr><td colspan="5" class="empty">No payout request or payment proof comments found in issue #33.</td></tr>';
}

fetch('/customer.json')
.then(r=>r.ok?r.json():null)
.then(renderPayoutLedger)
.catch(()=>renderPayoutLedger(null));

// Stats
const statsEl=document.getElementById('stats');
const scores=[
Expand Down
Loading