segreant 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (142) hide show
  1. package/LICENSING.md +5 -3
  2. package/README.md +57 -19
  3. package/bin/segreant-statusline.mjs +20 -0
  4. package/bin/segreant.mjs +19 -8
  5. package/dist/alerts/detect.js +13 -0
  6. package/dist/billing/epistemic.js +4 -0
  7. package/dist/billing/importer.js +29 -10
  8. package/dist/billing/reconcile.js +122 -32
  9. package/dist/billing/scope.js +7 -0
  10. package/dist/budget/guard.js +33 -4
  11. package/dist/cli/allocCmd.js +73 -4
  12. package/dist/cli/askModelPrices.js +59 -0
  13. package/dist/cli/backupCmd.js +2 -1
  14. package/dist/cli/basisLines.js +45 -0
  15. package/dist/cli/billingCmd.js +68 -9
  16. package/dist/cli/capitalCmd.js +2 -1
  17. package/dist/cli/connectCmd.js +50 -9
  18. package/dist/cli/egressCmd.js +15 -3
  19. package/dist/cli/evidenceCmd.js +6 -3
  20. package/dist/cli/flags.js +68 -0
  21. package/dist/cli/homeCmd.js +117 -0
  22. package/dist/cli/importCmd.js +210 -54
  23. package/dist/cli/launchCmd.js +2 -1
  24. package/dist/cli/opsCmd.js +49 -2
  25. package/dist/cli/planCmd.js +181 -0
  26. package/dist/cli/pricingDeclareCmd.js +178 -0
  27. package/dist/cli/quotaCmd.js +190 -0
  28. package/dist/cli/runCmd.js +203 -51
  29. package/dist/cli/showCmd.js +37 -11
  30. package/dist/cli/teamCmd.js +5 -5
  31. package/dist/cli/ui.js +24 -8
  32. package/dist/cli/valueCmd.js +189 -14
  33. package/dist/cli.js +102 -21
  34. package/dist/config.js +95 -6
  35. package/dist/connect/antigravity.js +310 -0
  36. package/dist/connect/claudeCode.js +43 -3
  37. package/dist/connect/codex.js +38 -1
  38. package/dist/connect/importShared.js +58 -5
  39. package/dist/connect/opencode.js +37 -9
  40. package/dist/connect/protobuf.js +126 -0
  41. package/dist/connect/registry.js +46 -0
  42. package/dist/connect/repoRoot.js +112 -0
  43. package/dist/cost/basis.js +168 -0
  44. package/dist/cost/declarations.js +37 -0
  45. package/dist/cost/exactPricing.js +4 -1
  46. package/dist/cost/firstSight.js +98 -0
  47. package/dist/cost/overrides.js +230 -0
  48. package/dist/cost/pricing.js +228 -15
  49. package/dist/cost/reprice.js +130 -0
  50. package/dist/dashboard/claim-support.js +11 -8
  51. package/dist/dashboard/contracts.js +23 -3
  52. package/dist/dashboard/routes.js +980 -112
  53. package/dist/dashboard/sessions.js +345 -0
  54. package/dist/dashboard/settings.js +2 -1
  55. package/dist/dashboard/value-cache.js +105 -0
  56. package/dist/dashboard/web/app/components/claimInspector.js +6 -5
  57. package/dist/dashboard/web/app/components/drawer.js +105 -35
  58. package/dist/dashboard/web/app/components/ruleFields.js +144 -0
  59. package/dist/dashboard/web/app/components/spine.js +54 -24
  60. package/dist/dashboard/web/app/components/workflow.js +82 -0
  61. package/dist/dashboard/web/app/core/actions.js +734 -23
  62. package/dist/dashboard/web/app/core/api.js +37 -1
  63. package/dist/dashboard/web/app/core/chain.js +11 -4
  64. package/dist/dashboard/web/app/core/claimLayers.js +179 -51
  65. package/dist/dashboard/web/app/core/claimTypes.js +30 -0
  66. package/dist/dashboard/web/app/core/fmt.js +19 -2
  67. package/dist/dashboard/web/app/core/generated-contract.js +23 -3
  68. package/dist/dashboard/web/app/core/generated-payload-contract.js +1944 -465
  69. package/dist/dashboard/web/app/core/generated-types.js +1 -1
  70. package/dist/dashboard/web/app/core/griffin.js +10 -0
  71. package/dist/dashboard/web/app/core/jobs.js +12 -0
  72. package/dist/dashboard/web/app/core/period.js +35 -0
  73. package/dist/dashboard/web/app/core/periodWords.js +10 -0
  74. package/dist/dashboard/web/app/core/periods.js +32 -0
  75. package/dist/dashboard/web/app/core/pricingActions.js +264 -0
  76. package/dist/dashboard/web/app/core/privacyText.js +78 -0
  77. package/dist/dashboard/web/app/core/reconcileWords.js +63 -0
  78. package/dist/dashboard/web/app/core/registry.js +79 -46
  79. package/dist/dashboard/web/app/core/slug.js +9 -0
  80. package/dist/dashboard/web/app/core/theme.js +48 -0
  81. package/dist/dashboard/web/app/core/view.js +69 -0
  82. package/dist/dashboard/web/app/main.js +197 -15
  83. package/dist/dashboard/web/app/views/allocation.js +249 -61
  84. package/dist/dashboard/web/app/views/control.js +57 -16
  85. package/dist/dashboard/web/app/views/data.js +4 -4
  86. package/dist/dashboard/web/app/views/evidence.js +336 -87
  87. package/dist/dashboard/web/app/views/privacy.js +13 -0
  88. package/dist/dashboard/web/app/views/spend.js +30 -15
  89. package/dist/dashboard/web/app/views/statement.js +189 -0
  90. package/dist/dashboard/web/app/views/system.js +44 -4
  91. package/dist/dashboard/web/app/views/value.js +105 -59
  92. package/dist/dashboard/web/app/views/workbench.js +312 -0
  93. package/dist/dashboard/web/classic.html +16 -4
  94. package/dist/dashboard/web/index.html +1 -1
  95. package/dist/dashboard/web/styles/app.css +536 -23
  96. package/dist/demo/seed.js +153 -14
  97. package/dist/economics/ledger.js +1 -1
  98. package/dist/egress/policy.js +129 -5
  99. package/dist/export/allocationCsv.js +70 -0
  100. package/dist/export/billingCsv.js +6 -2
  101. package/dist/export/csv.js +10 -2
  102. package/dist/export/economic.js +6 -2
  103. package/dist/export/statementCsv.js +104 -0
  104. package/dist/git/correlate.js +86 -9
  105. package/dist/git/quality.js +107 -24
  106. package/dist/git/repoScope.js +207 -0
  107. package/dist/git/survivalStore.js +186 -0
  108. package/dist/guide.js +9 -4
  109. package/dist/plans/detect.js +147 -0
  110. package/dist/proxy/server.js +134 -14
  111. package/dist/proxy/usage.js +9 -4
  112. package/dist/quota/limits.js +138 -0
  113. package/dist/quota/statusline.js +68 -0
  114. package/dist/quota/view.js +122 -0
  115. package/dist/scan/knownApps.js +6 -2
  116. package/dist/scan/scan.js +9 -0
  117. package/dist/store/allocation.js +14 -0
  118. package/dist/store/db.js +259 -34
  119. package/dist/store/realization.js +78 -14
  120. package/dist/store/schema.js +59 -1
  121. package/dist/store/scopeEvidence.js +67 -0
  122. package/dist/util/pool.js +19 -0
  123. package/dist/util/time.js +7 -0
  124. package/dist/value/realization.js +321 -30
  125. package/dist/value/report.js +28 -8
  126. package/dist/value/selfReported.js +10 -9
  127. package/docs/ARCHITECTURE.md +8 -4
  128. package/docs/CAPABILITY-EVIDENCE-CONTRACT.md +33 -11
  129. package/docs/CLI-JSON-CONTRACT.md +38 -0
  130. package/docs/DATA-BOUNDARIES.md +66 -6
  131. package/docs/FAQ.md +43 -9
  132. package/docs/GETTING-STARTED.md +19 -12
  133. package/docs/GUIDE.md +81 -18
  134. package/docs/INTEGRATIONS.md +9 -9
  135. package/docs/METHODOLOGY.md +3 -2
  136. package/docs/NEUTRALITY.md +1 -1
  137. package/docs/PRIVACY.md +51 -0
  138. package/docs/README.md +1 -0
  139. package/docs/RELEASE-GATE.md +52 -7
  140. package/docs/THREAT-MODEL.md +2 -1
  141. package/package.json +3 -2
  142. package/pricing/models.json +1366 -60
@@ -22,30 +22,35 @@
22
22
  import { h } from '../core/dom.js';
23
23
  import { signal, scopedEffect } from '../core/signal.js';
24
24
  import { api } from '../core/api.js';
25
- import { usd, count, pct, isPrecise } from '../core/fmt.js';
25
+ import { usd, count, pct, share, isPrecise } from '../core/fmt.js';
26
26
  import { actionCard } from './spend.js';
27
- /** What each gate means, for the funnel counts. */
27
+ /** Each gate as a step name, for the passed / failed / not checked table. */
28
28
  const GATE_WORDS = {
29
- proposed: 'was suggested',
30
- accepted: 'was accepted',
31
- committed: 'was committed',
32
- tested: 'was tested',
33
- merged: 'was merged',
34
- shipped: 'shipped',
35
- survived: 'survived in production',
36
- clean: 'survived without rework',
29
+ proposed: 'Suggested by the AI',
30
+ accepted: 'Accepted',
31
+ committed: 'Committed',
32
+ tested: 'Tests passed',
33
+ merged: 'Merged',
34
+ shipped: 'Shipped',
35
+ survived: 'Still in the code after 14 days',
36
+ clean: 'Kept without rework',
37
37
  };
38
- /** The same gates named as a stage a unit STOPPED at, for the waste breakdown. */
39
- const STOPPED_AFTER = {
40
- proposed: 'being suggested',
41
- accepted: 'being accepted',
42
- committed: 'being committed',
43
- tested: 'being tested',
44
- merged: 'being merged',
45
- shipped: 'shipping',
46
- survived: 'surviving in production',
47
- clean: 'surviving without rework',
48
- unverified: 'never being verified',
38
+ /**
39
+ * The waste breakdown is keyed by `diedAt`, the FIRST FAILED gate, so each
40
+ * label says what went wrong. It used to read "stopped after surviving in
41
+ * production" for work that failed the survival check.
42
+ */
43
+ const FAILED_AT = {
44
+ proposed: 'Suggestion not used',
45
+ accepted: 'Not accepted',
46
+ committed: 'Never committed',
47
+ tested: 'Tests failed',
48
+ merged: 'Not merged',
49
+ shipped: 'Not shipped',
50
+ survived: 'Gone from the code within 14 days',
51
+ clean: 'Needed rework',
52
+ unverified: 'No signal to judge it by',
53
+ conflicted: 'Results disagree',
49
54
  };
50
55
  const plural = (n, one, many) => (n === 1 ? one : many);
51
56
  /** Operator reports have their own basis and never feed the git realization card. */
@@ -111,13 +116,25 @@ function selfReportedCard(report, refresh) {
111
116
  if (report.status === 'disabled') {
112
117
  return h('section', { class: 'section' }, h('h2', { class: 'section-title', text: 'Chat, image and other work' }), h('p', { class: 'basis', text: 'Self-reported value is disabled; nothing was computed.' }));
113
118
  }
114
- return h('section', { class: 'section' }, h('h2', { class: 'section-title', text: 'Chat, image and other work' }), h('p', { class: 'basis', text: report.basis }), h('p', { class: 'basis', text: `${report.units.length} reported results · ${report.unlinkedOutcomes} without matched spend · ${report.inferredLinks} inferred links. Coding git outcomes have a separate basis.` }), ...rows.map((row) => h('p', { class: 'basis', text: `${row.key}: ${row.accepted}/${row.outcomes} accepted, ${row.used} used; cost/accepted ${row.costPerAcceptedUsd === null ? 'unknown' : usd(row.costPerAcceptedUsd)}; cost/used ${row.costPerUsedUsd === null ? 'unknown' : usd(row.costPerUsedUsd)} (self-reported, ${row.linked}/${row.outcomes} linked)` })), h('details', { class: 'card', style: 'margin-top: var(--s4)' }, h('summary', { text: 'Record a result' }), h('p', { class: 'basis', text: 'Preview first. The result and your verdict stay on this machine.' }), field('Result ID', outcomeId, 'my-result-1'), choice('Kind', kind, [['chat', 'Chat'], ['image', 'Image'], ['other', 'Other']]), choice('Spend link', linkType, [['session', 'Session ID'], ['request', 'Request ID'], ['window', 'Time window + tool (inferred)']]), () => linkType() === 'window'
119
+ return h('section', { class: 'section' }, h('h2', { class: 'section-title', text: 'Chat, image and other work' }), h('p', { class: 'basis', text: report.basis }), h('p', { class: 'basis', text: `${report.units.length} reported results · ${report.unlinkedOutcomes} without matched spend · ${report.inferredLinks} inferred links. Coding git outcomes have a separate basis.` }), ...rows.map((row) => h('p', { class: 'basis', text: `${row.key}: ${row.accepted}/${row.outcomes} accepted, ${row.used} used; cost/accepted ${row.costPerAcceptedUsd === null ? 'unknown' : usd(row.costPerAcceptedUsd)}; cost/used ${row.costPerUsedUsd === null ? 'unknown' : usd(row.costPerUsedUsd)} (self-reported, ${row.linked}/${row.outcomes} linked)` })), h('details', { class: 'card', style: 'margin-top: var(--s4)' }, h('summary', { text: 'Record a result' }), h('p', { class: 'basis', text: 'Preview first. The result and your answer stay on this machine.' }), field('Result ID', outcomeId, 'my-result-1'), choice('Kind', kind, [['chat', 'Chat'], ['image', 'Image'], ['other', 'Other']]), choice('Spend link', linkType, [['session', 'Session ID'], ['request', 'Request ID'], ['window', 'Time window + tool (inferred)']]), () => linkType() === 'window'
115
120
  ? h('div', null, field('From (ISO time)', from), field('To (ISO time)', to), field('Tool/source', tool))
116
121
  : field(linkType() === 'request' ? 'Request ID' : 'Session ID', linkId), field('Rating 1–5 (optional)', rating), field('Short note (optional)', note), choice('Decision', decision, [['', 'Unknown'], ['accepted_as_is', 'Accepted as-is'], ['edited_before_use', 'Edited before use'], ['rejected', 'Rejected']]), choice('Used afterward', use, [['', 'Unknown'], ['exported', 'Exported'], ['copied', 'Copied'], ['shipped', 'Shipped'], ['published', 'Published'], ['not_used', 'Not used']]), field('Attempts until accepted (optional)', attempts), choice('Regenerated', regenerated, [['', 'Unknown'], ['true', 'Yes'], ['false', 'No']]), choice('Still in use', stillInUse, [['', 'Unknown'], ['true', 'Yes'], ['false', 'No']]), h('div', { class: 'actions' }, h('button', { class: 'btn-ghost', type: 'button', disabled: () => busy(), onclick: () => { void submit(false); }, text: 'Preview' }), () => preview() && !preview().apply
117
122
  ? h('button', { class: 'btn-primary', type: 'button', disabled: () => busy(), onclick: () => { void submit(true); }, text: 'Apply record' })
118
123
  : null), () => error() ? h('p', { class: 'drawer-error', role: 'alert', text: error() }) : null, () => preview() ? h('p', { class: 'basis', role: 'status', text: `${preview().apply ? 'Recorded' : 'Preview'}: ${preview().matchedRequests} request(s) matched; ${preview().linkStatus}; ${preview().event.link.basis} link; ${preview().basis}` }) : null));
119
124
  }
120
125
  const MARKET_ROWS = 8;
126
+ function publicPrice(price) {
127
+ if (price === null)
128
+ return 'no public price';
129
+ const amount = typeof price.blendedUsdPerMillion === 'number'
130
+ ? `${usd(price.blendedUsdPerMillion)}/M tokens`
131
+ : typeof price.usdPerImage === 'number'
132
+ ? `${usd(price.usdPerImage)}/image`
133
+ : null;
134
+ if (amount === null)
135
+ return 'no public price';
136
+ return amount + (price.match === 'normalized' ? ` (as ${price.pricedAs})` : '');
137
+ }
121
138
  function marketBoard(b) {
122
139
  const head = h('div', { class: 'card-head' }, h('span', { class: 'card-title', text: b.label }), h('span', { class: 'basis', text: `${b.licence}` }));
123
140
  if (b.status !== 'available') {
@@ -137,9 +154,7 @@ function marketBoard(b) {
137
154
  return h('tr', null, h('td', { text: x.model }), h('td', { text: `${x.passRatePercent.toFixed(1)}%` }), h('td', { text: x.runCostUsd === null ? 'not published' : usd(x.runCostUsd) }), h('td', { text: x.costPerSolvedTaskUsd === null ? '—' : usd(x.costPerSolvedTaskUsd) }), h('td', { text: x.frontier === null ? '—' : x.frontier ? 'yes' : '' }));
138
155
  }
139
156
  const x = r;
140
- const price = x.price === null ? 'no public price'
141
- : (x.price.blendedUsdPerMillion !== undefined ? `${usd(x.price.blendedUsdPerMillion)}/M tokens` : `${usd(x.price.usdPerImage ?? 0)}/image`)
142
- + (x.price.match === 'normalized' ? ` (as ${x.price.pricedAs})` : '');
157
+ const price = publicPrice(x.price);
143
158
  return h('tr', null, h('td', { text: x.model }), h('td', { text: `${x.rating.toFixed(0)} (${x.ratingLower.toFixed(0)}–${x.ratingUpper.toFixed(0)})` }), h('td', { text: count(x.votes) }), h('td', { text: price }), h('td', { text: x.frontier === null ? '—' : x.frontier ? 'yes' : '' }));
144
159
  }))));
145
160
  return h('div', { class: 'card', style: 'margin-top: var(--s3)' }, head, h('p', { class: 'basis', text: when }), table, b.rows.length > rows.length ? h('p', { class: 'basis', text: `${b.rows.length - rows.length} more on the command line: segreant market --all` }) : null, b.frontier.length ? h('p', { class: 'basis', text: `Frontier: ${b.frontier.slice(0, 10).join(', ')}${b.frontier.length > 10 ? ` and ${b.frontier.length - 10} more` : ''}` }) : null, ...b.notes.map((n) => h('p', { class: 'basis', text: n })));
@@ -149,11 +164,11 @@ function consensusTable(c) {
149
164
  if (c.status !== 'available')
150
165
  return h('div', { class: 'card', style: 'margin-top: var(--s3)' }, title, ...c.notes.map((n) => h('p', { class: 'basis', text: n })));
151
166
  const rows = c.rows.slice(0, 10);
152
- return h('div', { class: 'card', style: 'margin-top: var(--s3)' }, title, h('p', { class: 'basis', text: 'Expected score on a typical benchmark of this kind, 0–100. The range is how far it moves if any one benchmark is dropped.' }), h('div', { class: 'table-wrap' }, h('table', { 'aria-label': 'Consensus quality score, top models' }, h('thead', null, h('tr', null, ...['Model', 'Score', 'Range', 'Benchmarks', 'List price', 'Frontier'].map((t) => h('th', { scope: 'col', text: t })))), h('tbody', null, ...rows.map((r) => h('tr', null, h('td', { text: r.label }), h('td', { text: r.score.toFixed(0) }), h('td', { text: `${r.low.toFixed(0)}–${r.high.toFixed(0)}` }), h('td', { text: String(r.benchmarks.length), title: r.benchmarks.map((b) => `${b.benchmark}: ${(b.score * 100).toFixed(0)}`).join('\n') }), h('td', { text: r.price === null ? 'no public price' : `${usd(r.price.blendedUsdPerMillion ?? 0)}/M tokens${r.price.match === 'normalized' ? ` (as ${r.price.pricedAs})` : ''}` }), h('td', { text: r.frontier === null ? '—' : r.frontier ? 'yes' : `beaten by ${r.beatenBy?.label ?? '—'}${r.beatenBy && !r.beatenBy.clear ? ' (within range)' : ''}` })))))), h('details', null, h('summary', { text: 'How each benchmark is weighted' }), ...c.weights.map((w) => h('p', { class: 'basis', text: `${w.benchmark}: weight ${w.weight.toFixed(2)} = independence ${w.independence} × contamination resistance ${w.contamination} × currency ${w.currency} (newest ${w.newest ?? 'undated'}, ${w.models} models). ${w.why}` }))), ...c.notes.map((n) => h('p', { class: 'basis', text: n })));
167
+ return h('div', { class: 'card', style: 'margin-top: var(--s3)' }, title, h('p', { class: 'basis', text: 'Expected score on a typical benchmark of this kind, 0–100. The range is how far it moves if any one benchmark is dropped.' }), h('div', { class: 'table-wrap' }, h('table', { 'aria-label': 'Consensus quality score, top models' }, h('thead', null, h('tr', null, ...['Model', 'Score', 'Range', 'Benchmarks', 'List price', 'Frontier'].map((t) => h('th', { scope: 'col', text: t })))), h('tbody', null, ...rows.map((r) => h('tr', null, h('td', { text: r.label }), h('td', { text: r.score.toFixed(0) }), h('td', { text: `${r.low.toFixed(0)}–${r.high.toFixed(0)}` }), h('td', { text: String(r.benchmarks.length), title: r.benchmarks.map((b) => `${b.benchmark}: ${(b.score * 100).toFixed(0)}`).join('\n') }), h('td', { text: publicPrice(r.price) }), h('td', { text: r.frontier === null ? '—' : r.frontier ? 'yes' : `beaten by ${r.beatenBy?.label ?? '—'}${r.beatenBy && !r.beatenBy.clear ? ' (within range)' : ''}` })))))), h('details', null, h('summary', { text: 'How each benchmark is weighted' }), ...c.weights.map((w) => h('p', { class: 'basis', text: `${w.benchmark}: weight ${w.weight.toFixed(2)} = independence ${w.independence} × contamination resistance ${w.contamination} × currency ${w.currency} (newest ${w.newest ?? 'undated'}, ${w.models} models). ${w.why}` }))), ...c.notes.map((n) => h('p', { class: 'basis', text: n })));
153
168
  }
154
169
  /** Public evidence only. It never reads the ledger and never enters a figure above it. */
155
- function marketCard(payload, failure) {
156
- const title = h('h2', { class: 'section-title', text: 'Public model market — public evidence, not your results' });
170
+ function marketCard(payload, failure, titled = true) {
171
+ const title = titled ? h('h2', { class: 'section-title', text: 'Public model market — public evidence, not your results' }) : null;
157
172
  if (failure)
158
173
  return h('section', { class: 'section' }, title, h('p', { class: 'drawer-error', role: 'alert', text: failure }));
159
174
  if (!payload)
@@ -201,9 +216,12 @@ function usageCoverageCard(usage) {
201
216
  if (!usage)
202
217
  return null;
203
218
  const retention = usage.retention;
219
+ const before = retention.prunedBeforeMs;
220
+ const boundary = typeof before === 'number' && Number.isFinite(before) && before > 0 && before <= 8.64e15
221
+ ? new Date(before).toISOString() : 'an unrecorded boundary';
204
222
  return h('div', { class: 'card', style: 'margin-top: var(--s4)' }, h('div', { class: 'card-head' }, h('span', { class: 'card-title', text: () => (isPrecise() ? 'Usage without code signals' : 'Chat, research, and drafting') })), h('div', { class: 'facts' }, h('div', { class: 'fact' }, h('span', { class: 'fact-key', text: () => (isPrecise() ? 'observed sessions' : 'sessions') }), h('span', { class: 'fact-val', text: count(usage.units.length) })), h('div', { class: 'fact' }, h('span', { class: 'fact-key', text: () => (isPrecise() ? 'reported realized' : 'realized') }), h('span', { class: 'fact-val', text: count(usage.realizedUnits) })), h('div', { class: 'fact' }, h('span', { class: 'fact-key', text: () => (isPrecise() ? 'surviving cost' : 'cost recorded') }), h('span', { class: 'fact-val', text: usd(usage.totalCostUsd) }))), retention.truncated
205
223
  ? h('p', { class: 'drawer-error', role: 'status', text: () => (isPrecise()
206
- ? `This usage window reaches behind retention: ${count(retention.rowsRemoved)} request row(s) were deleted before ${retention.prunedBeforeMs === null ? 'an unrecorded boundary' : new Date(retention.prunedBeforeMs).toISOString()}. Figures cover what survived, not everything metered.`
224
+ ? `This usage window reaches behind retention: ${count(retention.rowsRemoved)} request row(s) were deleted before ${boundary}. Figures cover what survived, not everything metered.`
207
225
  : 'Some requests in this usage window were deleted by retention, so these figures cover what remains rather than everything metered.') })
208
226
  : null, h('p', { class: 'basis', text: () => (isPrecise()
209
227
  ? 'These sessions have no captured code proposals; reported outcomes remain observational and do not become coding value.'
@@ -241,7 +259,7 @@ function modelSwitchCoverageCard(frontier) {
241
259
  : null, retentionUnknown > 0
242
260
  ? h('p', { class: 'basis', role: 'status', text: () => (isPrecise()
243
261
  ? `${count(retentionUnknown)} included unit(s) predate the retention-coverage record, so whether their spend window lost rows is unknown.`
244
- : `For ${count(retentionUnknown)} included unit(s), we cannot tell whether retention deleted spend because their snapshots predate the coverage record.`) })
262
+ : `For ${count(retentionUnknown)} included unit(s) there's no record of whether old spend was deleted: they're older than that record.`) })
245
263
  : null, h('p', { class: 'basis', text: () => (isPrecise()
246
264
  ? `Observed headroom ${usd(recommendation.historicalEquivalentHeadroomUsd)}; this is a local list-price comparison, not provider-billed savings.`
247
265
  : `Observed headroom ${usd(recommendation.historicalEquivalentHeadroomUsd)}; this is not a promise of future savings.`) }));
@@ -266,7 +284,7 @@ export function valueView() {
266
284
  .then((payload) => causal.set(payload))
267
285
  .catch((e) => causalError.set(e instanceof Error ? e.message : String(e)));
268
286
  });
269
- return h('div', null, h('div', { class: 'view-head' }, h('h1', { class: 'view-title', text: 'Realized' }), h('p', { class: 'view-plain', text: () => isPrecise()
287
+ return h('div', null, h('div', { class: 'view-head' }, h('h1', { class: 'view-title', text: 'Value' }), h('p', { class: 'view-plain', text: () => isPrecise()
270
288
  ? 'Realized value over matured work units, rework-discounted. Acceptance is not an outcome and is never counted as one.'
271
289
  : 'What the AI spend actually produced — counting only work that shipped and stayed shipped, not work that merely got accepted.' })), () => {
272
290
  const err = error();
@@ -278,13 +296,15 @@ export function valueView() {
278
296
  const matured = d.realization?.matured ?? null;
279
297
  const established = (matured?.realizedUnits ?? 0) > 0;
280
298
  if (!established) {
281
- return h('div', null, h('div', { class: 'notyet' }, h('h2', { text: () => (isPrecise() ? 'Realized value is not established' : 'We cannot tell you this yet') }), h('p', { text: () => (isPrecise()
299
+ return h('div', null, h('div', { class: 'notyet' }, h('h2', { text: () => (isPrecise() ? 'Realized value is not established' : 'Nothing to show yet') }), h('p', { text: () => (isPrecise()
282
300
  ? 'No work units have matured into verified outcomes on this machine. This is an absence of evidence, not a realized value of zero — the two must not be reported alike.'
283
- : 'Nothing has been observed all the way through to a shipped, surviving outcome yet. That is missing evidence, not an answer of nothing.') }), h('p', { class: 'basis', text: () => (isPrecise()
301
+ : 'No work has been followed all the way to shipped and kept yet. That is missing evidence, not zero.') }), h('p', { class: 'basis', text: () => (isPrecise()
284
302
  ? 'Maturation requires observable outcomes: a repository whose history can be read, or imported units with recorded gate results.'
285
- : 'Segreant needs somewhere to watch outcomes happen — usually a code repository — before it can say what the spend produced.') })), causalStudyCard(causal(), causalError()), usageCoverageCard(d.usage), selfReportedCard(d.selfReported, refresh), marketCard(market(), marketError()), actions());
303
+ : 'Segreant needs somewhere to watch outcomes happen — usually a code repository — before it can say what the spend produced.') })), selfReportedCard(d.selfReported, refresh), fold(() => (isPrecise() ? 'Usage without code signals' : 'Chat, research and drafting'), usageCoverageCard(d.usage)), fold(() => (isPrecise() ? 'Causal study evidence' : 'Is any of this proven to be caused by AI?'), causalStudyCard(causal(), causalError())), fold(() => 'Public model market: public evidence, not your results', marketCard(market(), marketError(), false)), actions());
286
304
  }
287
305
  const funnel = matured?.instrumentation ?? {};
306
+ const gatePasses = matured?.gatePasses ?? {};
307
+ const maturedUnits = matured?.units ?? 0;
288
308
  // Gates where two sources disagreed. Shown separately from the counts
289
309
  // because a contradiction is not a measurement of the gate, and because
290
310
  // the legacy projection renders it as a plain failure (AII-003).
@@ -296,7 +316,7 @@ export function valueView() {
296
316
  const drift = d.drift ?? null;
297
317
  const ret = d.roi?.returnRatio ?? null;
298
318
  const economic = matured?.economic ?? null;
299
- return h('div', null, d.demo ? h('div', { class: 'banner banner-demo' }, h('span', { class: 'pill pill-demo', text: 'demo' }), h('p', null, h('strong', { text: 'Sample data. ' }), 'These outcomes were seeded, not observed on your machine.')) : null, causalStudyCard(causal(), causalError()),
319
+ return h('div', null, d.demo ? h('div', { class: 'banner banner-demo' }, h('span', { class: 'pill pill-demo', text: 'demo' }), h('p', null, h('strong', { text: 'Sample data. ' }), 'These outcomes were seeded, not observed on your machine.')) : null,
300
320
  // Basis before figure. Which of the two sources produced this, and whether
301
321
  // the dollars are scoped to the project or merely summed over a window,
302
322
  // change what the headline means.
@@ -335,13 +355,13 @@ export function valueView() {
335
355
  (matured?.spendWindowUnknownUnits ?? 0) > 0
336
356
  ? h('span', { class: 'basis', text: () => (isPrecise()
337
357
  ? `${count(matured?.spendWindowUnknownUnits)} unit(s) predate the retention-coverage record, so whether their spend window lost rows is unknown.`
338
- : `For ${count(matured?.spendWindowUnknownUnits)} of these we cannot tell whether any cost records were deleted.`) })
358
+ : `For ${count(matured?.spendWindowUnknownUnits)} of these, Segreant has no record of whether any cost rows were deleted.`) })
339
359
  : null), economic
340
360
  ? h('p', { class: 'basis', role: 'status', text: () => {
341
361
  if (economic.coverage === 'legacy_unknown' || economic.total === null) {
342
362
  return isPrecise()
343
363
  ? 'Exact economic coverage: legacy_unknown — these snapshots predate exact request evidence, so numeric costs are compatibility projections.'
344
- : 'Exact economic coverage is not available for these snapshots; the cost figures are legacy compatibility totals.';
364
+ : 'These older snapshots have no exact per-request prices, so their costs are approximate totals.';
345
365
  }
346
366
  const total = economic.total;
347
367
  if (economic.coverage === 'partial' || total.unresolvedRequests > 0) {
@@ -373,22 +393,22 @@ export function valueView() {
373
393
  : ret.supervisionPriced
374
394
  ? 'the AI spend plus your own measured time, priced at your labour rate'
375
395
  : 'the AI spend plus an estimate of the time it took you') })))
376
- : h('div', { class: 'notyet', style: 'margin-top: var(--s4)' }, h('h2', { text: () => (isPrecise() ? 'Realized value is not priced' : 'We cannot put a figure on this') }), h('p', { text: () => (isPrecise()
377
- ? 'Work matured, but no labour rate is configured, so the value it produced cannot be expressed in dollars. The rate below is still computable; the money figure is not.'
378
- : 'Work did get finished, but Segreant has no hourly rate to value it against — so it can tell you how much stuck, but not what it was worth.') })),
396
+ : h('div', { class: 'notyet', style: 'margin-top: var(--s4)' }, h('h2', { text: () => (isPrecise() ? 'Value of kept work: no price set' : 'No dollar figure yet') }), h('p', { text: () => (isPrecise()
397
+ ? 'Work matured, but no labour rate is set, so its value has no dollar figure. The rate below is still computed.'
398
+ : 'Work did get finished, but Segreant has no hourly rate to value it against. It can tell you how much you kept, not what it was worth.') })),
379
399
  // The money face is an observed/manual-equivalent scenario. A separate
380
400
  // qualified randomized study is required for causal economics.
381
401
  ret && typeof ret.grossRatio === 'number'
382
402
  ? h('div', { class: 'card', style: 'margin-top: var(--s4)' }, h('div', { class: 'card-head' }, h('span', { class: 'card-title', text: () => (isPrecise() ? 'Observed value scenario' : 'The value it looks like it delivered') }), h('span', {
383
403
  class: 'pill pill-warn',
384
- text: 'not causal evidence',
404
+ text: () => (isPrecise() ? 'not causal evidence' : "doesn't prove cause"),
385
405
  })), h('div', { class: 'stat', text: `${ret.grossRatio.toFixed(2)}\u00d7` }), h('span', { class: 'basis', text: () => (isPrecise()
386
406
  ? 'realized manual-equivalent value divided by tokens plus measured time; a qualified randomized study is required for causal net benefit'
387
- : 'This uses the value of work that stuck and what it cost in AI and time. It cannot tell us what would have happened without AI.') }))
407
+ : "This compares the value of work you kept with what it cost in AI and time. It doesn't show what would have happened without AI.") }))
388
408
  : null,
389
409
  // Realization rate with its partial-identification bounds. A point estimate
390
410
  // alone would overstate how precisely this is known.
391
- h('div', { class: 'card', style: 'margin-top: var(--s4)' }, h('div', { class: 'card-head' }, h('span', { class: 'card-title', text: () => (isPrecise() ? 'Realization rate' : 'How much of the work stuck') })), h('div', { class: 'stat', text: pct(matured?.realizationRate, 0) }), bounds
411
+ h('div', { class: 'card', style: 'margin-top: var(--s4)' }, h('div', { class: 'card-head' }, h('span', { class: 'card-title', text: () => (isPrecise() ? 'Realization rate' : 'How much of the work you kept') })), h('div', { class: 'stat', text: pct(matured?.realizationRate, 0) }), bounds
392
412
  ? h('span', { class: 'basis', text: () => (isPrecise()
393
413
  ? `partial-identification bounds ${pct(bounds.lower, 0)}–${pct(bounds.upper, 0)} over n=${count(bounds.n)}`
394
414
  : `somewhere between ${pct(bounds.lower, 0)} and ${pct(bounds.upper, 0)}, based on ${count(bounds.n)} pieces of work`) })
@@ -398,26 +418,26 @@ export function valueView() {
398
418
  text: () => (drift.alarm
399
419
  ? (isPrecise()
400
420
  ? `Drift alarm: the recent realization rate (${pct(drift.recentRate, 0)}) has departed from the overall rate (${pct(drift.overallRate, 0)}) beyond chance.`
401
- : `Warning: work has recently been sticking much less often than it used to (${pct(drift.recentRate, 0)} against ${pct(drift.overallRate, 0)} overall).`)
421
+ : `Change alert: lately, much less of the work has been kept (${pct(drift.recentRate, 0)}, against ${pct(drift.overallRate, 0)} overall).`)
402
422
  : (isPrecise()
403
423
  ? `The drift alarm did not fire over n=${count(drift.n)} mature units.`
404
424
  + (drift.referenceDriftWouldFire === false
405
425
  ? ' At this length the same test does not fire even on a total regime change, so its silence carries no information.'
406
426
  : ' An e-process bounds false alarms and not missed ones, so this is not evidence that the rate held.')
407
- : `Nothing has tripped the drift watch over ${count(drift.n)} pieces of work`
427
+ : `No change alert fired over ${count(drift.n)} pieces of work`
408
428
  + (drift.referenceDriftWouldFire === false
409
- ? ', but that is too few for this check to notice a change at all yet.'
410
- : ' — which is not the same as knowing the rate held steady.'))),
429
+ ? ", but that's too few for the check to notice a change yet."
430
+ : ". That doesn't prove the rate held steady."))),
411
431
  })
412
432
  : null),
413
433
  // The actionable part: where units die and what that costs.
414
434
  waste.length > 0
415
- ? h('section', { class: 'section' }, h('h2', { class: 'section-title', text: () => (isPrecise() ? 'Where value is lost' : 'Where the work fell over') }), h('p', { class: 'view-plain', text: () => (isPrecise()
416
- ? `Of ${usd(matured?.totalCostUsd)} attributed to matured units, ${usd(matured?.spendOnRealizedUnitsUsd)} reached a kept outcome and ${usd(wasteCost)} did not. These are spend figures, not value.`
417
- : `Of the ${usd(matured?.totalCostUsd)} spent on this work, ${usd(matured?.spendOnRealizedUnitsUsd)} went on work that stuck and ${usd(wasteCost)} went on work that did not.`) }), h('div', { class: 'ledger', role: 'table', 'aria-label': 'Where value was lost, by stopping stage' }, h('div', { class: 'ledger-head', role: 'row' }, h('span', { role: 'columnheader', text: () => (isPrecise() ? 'Stopped at' : 'Where it stopped') }), h('span', { class: 'num cell-calls', role: 'columnheader', text: 'Units' }), h('span', { class: 'num cell-cost', role: 'columnheader', text: 'Cost' }), h('span', { class: 'num cell-share', role: 'columnheader', text: 'Share' })), ...waste
435
+ ? h('section', { class: 'section' }, h('h2', { class: 'section-title', text: () => (isPrecise() ? 'Where value is lost' : 'Where work was lost') }), h('p', { class: 'view-plain', text: () => (isPrecise()
436
+ ? `Of ${usd(matured?.totalCostUsd)} attributed to matured units, ${usd(matured?.spendOnRealizedUnitsUsd)} reached a realized outcome and ${usd(wasteCost)} did not. These are spend figures, not value.`
437
+ : `Of the ${usd(matured?.totalCostUsd)} spent on this work, ${usd(matured?.spendOnRealizedUnitsUsd)} went on work you kept and ${usd(wasteCost)} on work you didn't.`) }), h('div', { class: 'ledger', role: 'table', 'aria-label': 'Where value was lost, by stopping stage' }, h('div', { class: 'ledger-head', role: 'row' }, h('span', { role: 'columnheader', text: () => (isPrecise() ? 'First failed gate' : 'What went wrong') }), h('span', { class: 'num cell-calls', role: 'columnheader', text: 'Units' }), h('span', { class: 'num cell-cost', role: 'columnheader', text: 'Cost' }), h('span', { class: 'num cell-share', role: 'columnheader', text: 'Share' })), ...waste
418
438
  .slice()
419
439
  .sort((a, b) => b.costUsd - a.costUsd)
420
- .map((w) => h('div', { class: 'ledger-row', role: 'row' }, h('span', { class: 'ledger-key', role: 'cell', text: () => (isPrecise() ? w.stage : `stopped after ${STOPPED_AFTER[w.stage] ?? w.stage}`) }), h('span', { class: 'num cell-calls', role: 'cell', text: `${count(w.units)} ${plural(w.units, 'unit', 'units')}` }), h('span', { class: 'num cell-cost ledger-cost', role: 'cell', text: usd(w.costUsd) }), h('span', { class: 'num cell-share', role: 'cell', text: wasteCost > 0 ? pct(w.costUsd / wasteCost, 0) : '—' }), h('span', {
440
+ .map((w) => h('div', { class: 'ledger-row', role: 'row' }, h('span', { class: 'ledger-key', role: 'cell', text: () => (isPrecise() ? w.stage : (FAILED_AT[w.stage] ?? w.stage)) }), h('span', { class: 'num cell-calls', role: 'cell', text: `${count(w.units)} ${plural(w.units, 'unit', 'units')}` }), h('span', { class: 'num cell-cost ledger-cost', role: 'cell', text: usd(w.costUsd) }), h('span', { class: 'num cell-share', role: 'cell', text: wasteCost > 0 ? share(w.costUsd / wasteCost) : '—' }), h('span', {
421
441
  class: 'ledger-bar',
422
442
  'aria-hidden': 'true',
423
443
  style: `--fill: ${wasteCost > 0 ? Math.max(0.5, (w.costUsd / wasteCost) * 100) : 0}%`,
@@ -425,11 +445,26 @@ export function valueView() {
425
445
  : null,
426
446
  // The funnel, as counts. Deliberately after the waste breakdown: the
427
447
  // question worth asking is where work dies, not how big the pipeline is.
448
+ // Passed, failed and not checked, side by side. This list used to show
449
+ // only how many units were CHECKED at each gate, under words like "was
450
+ // merged", so it read as a funnel that grew: merged 10, shipped 10,
451
+ // survived 13 (more work surviving than shipped).
428
452
  Object.keys(funnel).length > 0
429
- ? h('section', { class: 'section' }, h('h2', { class: 'section-title', text: () => (isPrecise() ? 'Instrumented gates' : 'How far work got') }), h('div', { class: 'facts' }, ...Object.entries(funnel).map(([stage, n]) => h('div', { class: 'fact' }, h('span', { class: 'fact-key', text: () => (isPrecise() ? stage : (GATE_WORDS[stage] ?? stage)) }), h('span', { class: 'fact-val', text: count(n) })))), gateConflicts.length > 0
453
+ ? h('section', { class: 'section' }, h('h2', { class: 'section-title', text: () => (isPrecise() ? 'Checks passed at each step' : 'How far the work got') }), h('p', { class: 'view-plain', text: () => (isPrecise()
454
+ ? `Matured units: ${count(maturedUnits)}. Each gate is judged on its own evidence, so a later gate can pass more often than an earlier one that had no signal.${gateConflicts.length > 0 ? ' Failed counts include contradicted evidence, listed below.' : ''}`
455
+ : `Out of ${count(maturedUnits)} finished ${plural(maturedUnits, 'piece', 'pieces')} of work. "Not checked" means Segreant had no signal for that step, not that it failed.`) }), h('div', { class: 'ledger ledger-gates', role: 'table', 'aria-label': 'Checks passed at each step, finished work' }, h('div', { class: 'ledger-head', role: 'row' }, h('span', { role: 'columnheader', text: () => (isPrecise() ? 'Gate' : 'Step') }), h('span', { class: 'num', role: 'columnheader', text: 'Passed' }), h('span', { class: 'num', role: 'columnheader', text: 'Failed' }), h('span', { class: 'num', role: 'columnheader', text: 'Not checked' })), ...Object.entries(funnel).map(([stage, checked]) => {
456
+ const passed = gatePasses[stage] ?? 0;
457
+ const failed = Math.max(0, checked - passed);
458
+ const unchecked = Math.max(0, maturedUnits - checked);
459
+ return h('div', { class: 'ledger-row', role: 'row' }, h('span', { class: 'ledger-key', role: 'cell', text: () => (isPrecise() ? stage : (GATE_WORDS[stage] ?? stage)) }), h('span', { class: 'num gate-pass', role: 'cell', text: count(passed) }), h('span', { class: failed > 0 ? 'num gate-fail' : 'num', role: 'cell', text: count(failed) }), h('span', { class: 'num gate-unchecked', role: 'cell', text: count(unchecked) }), h('span', {
460
+ class: 'ledger-bar',
461
+ 'aria-hidden': 'true',
462
+ style: `--fill: ${maturedUnits > 0 ? (passed / maturedUnits) * 100 : 0}%`,
463
+ }));
464
+ })), gateConflicts.length > 0
430
465
  ? h('p', { class: 'section-note', text: () => (isPrecise()
431
- ? `Contradicted evidence at ${gateConflicts.map(([stage, n]) => `${stage} (${n})`).join(', ')}: sources both supported and refuted these gates. The unit records a failure only because the three-valued projection has no other option — it is unadjudicated, not refuted.`
432
- : `Some evidence disagrees with itself at ${gateConflicts.map(([stage]) => (GATE_WORDS[stage] ?? stage)).join(', ')}. That is a conflict to resolve, not a result.`) })
466
+ ? `Conflicting results at ${gateConflicts.map(([stage, n]) => `${stage} (${n})`).join(', ')}: some sources passed these steps and others failed them. They count as failed only because a step has no third "disputed" value; the conflict is unresolved, not a fail.`
467
+ : `Results disagree with each other at ${gateConflicts.map(([stage]) => (GATE_WORDS[stage] ?? stage)).join(', ')}. That needs resolving; it isn't a result.`) })
433
468
  : null)
434
469
  : null, d.reclaimed && typeof d.reclaimed.workWeeksSaved === 'number'
435
470
  ? h('div', { class: 'card', style: 'margin-top: var(--s4)' }, h('div', { class: 'card-head' }, h('span', { class: 'card-title', text: () => (isPrecise() ? 'Time reclaimed' : 'Time this saved') })), h('div', { class: 'stat', text: `${d.reclaimed.workWeeksSaved.toFixed(1)} work weeks` }),
@@ -457,10 +492,15 @@ export function valueView() {
457
492
  ? `${count(d.reclaimed?.uncreditedUnits)} matured ${plural(d.reclaimed?.uncreditedUnits ?? 0, 'unit', 'units')} earned no time credit (died, or had no baseline).`
458
493
  : `${count(d.reclaimed?.uncreditedUnits)} ${plural(d.reclaimed?.uncreditedUnits ?? 0, 'piece', 'pieces')} of work got no credit here — they either failed, or we had nothing to compare them against.`) })
459
494
  : null)
460
- : null, modelSwitchCoverageCard(d.frontier), usageCoverageCard(d.usage), selfReportedCard(d.selfReported, refresh), marketCard(market(), marketError()),
495
+ : null, selfReportedCard(d.selfReported, refresh),
496
+ // Supporting evidence, folded. It used to run at full length after the
497
+ // answer, which made this a 7,500 px page (13,000 on a phone) with the
498
+ // public market tables alone longer than everything above them. Each
499
+ // fold says what it holds; nothing is removed.
500
+ h('h2', { class: 'section-title fold-head', text: () => (isPrecise() ? 'Supporting evidence' : 'More detail, if you want it') }), fold(() => (isPrecise() ? 'Model-switch trials' : 'Cheaper model trials'), modelSwitchCoverageCard(d.frontier)), fold(() => (isPrecise() ? 'Usage without code signals' : 'Chat, research and drafting'), usageCoverageCard(d.usage)), fold(() => (isPrecise() ? 'Causal study evidence' : 'Is any of this proven to be caused by AI?'), causalStudyCard(causal(), causalError())), fold(() => 'Public model market: public evidence, not your results', marketCard(market(), marketError(), false)),
461
501
  // Per-user. The guardrail state is the content when the cohort is suppressed.
462
502
  team
463
- ? h('div', { class: 'card', style: 'margin-top: var(--s4)' }, h('div', { class: 'card-head' }, h('span', { class: 'card-title', text: () => (isPrecise() ? 'Cohort distribution' : 'Across the people using it') }), h('span', {
503
+ ? fold(() => (isPrecise() ? 'Cohort distribution' : 'Across the people using it'), h('div', { class: 'card', style: 'margin-top: var(--s4)' }, h('div', { class: 'card-head' }, h('span', { class: 'card-title', text: () => (isPrecise() ? 'Cohort distribution' : 'Across the people using it') }), h('span', {
464
504
  class: `pill ${team.suppressed || !team.enabled ? 'pill-unverified' : 'pill-ok'}`,
465
505
  text: !team.enabled ? 'off' : team.suppressed ? 'suppressed' : 'distribution only',
466
506
  })), !team.enabled
@@ -475,14 +515,20 @@ export function valueView() {
475
515
  ? `Distribution over ${count(team.distribution?.cohortSize)} users; individuals are never identified.`
476
516
  : `Spread across ${count(team.distribution?.cohortSize)} people. Segreant never shows who is who.`) }), h('div', { class: 'facts' }, h('div', { class: 'fact' }, h('span', { class: 'fact-key', text: () => (isPrecise() ? 'median extraction' : 'typical person gets back') }), h('span', { class: 'fact-val', text: pct(team.distribution.medianExtraction, 0) })), h('div', { class: 'fact' }, h('span', { class: 'fact-key', text: () => (isPrecise() ? 'dispersion' : 'how evenly spread') }), h('span', { class: 'fact-val', text: team.distribution.broadBased
477
517
  ? (isPrecise() ? `${team.distribution.dispersion.toFixed(2)} — broad-based` : 'fairly even')
478
- : (isPrecise() ? `${team.distribution.dispersion.toFixed(2)} — concentrated` : 'concentrated in a few') })), h('div', { class: 'fact' }, h('span', { class: 'fact-key', text: () => (isPrecise() ? 'coaching headroom' : 'possible if everyone matched the middle') }), h('span', { class: 'fact-val', text: usd(team.distribution.coachingHeadroomUsd) })))))
518
+ : (isPrecise() ? `${team.distribution.dispersion.toFixed(2)} — concentrated` : 'concentrated in a few') })), h('div', { class: 'fact' }, h('span', { class: 'fact-key', text: () => (isPrecise() ? 'coaching headroom' : 'possible if everyone matched the middle') }), h('span', { class: 'fact-val', text: usd(team.distribution.coachingHeadroomUsd) }))))))
479
519
  : null, (d.roi?.notes?.length ?? 0) > 0
480
- ? h('section', { class: 'section' }, h('h2', { class: 'section-title', text: () => (isPrecise() ? 'Method notes' : 'How this was worked out') }), h('p', { class: 'scope-note', text: () => (isPrecise()
520
+ ? fold(() => (isPrecise() ? 'Method notes' : 'How this was worked out'), h('section', null, h('p', { class: 'scope-note', text: () => (isPrecise()
481
521
  ? 'These notes are stated on the manual-equivalent value basis (the figures in Realized value and Honest cost above), not on the attributed-spend basis used in the waste breakdown.'
482
- : 'These notes talk about what the work was worth and what your time cost — not the smaller AI-spend figures further down the page.') }), h('ul', { class: 'drawer-notes' }, ...(d.roi?.notes ?? []).slice(0, 8).map((n) => h('li', { text: n }))))
522
+ : 'These notes talk about what the work was worth and what your time cost — not the smaller AI-spend figures further down the page.') }), h('ul', { class: 'drawer-notes' }, ...(d.roi?.notes ?? []).slice(0, 8).map((n) => h('li', { text: n })))))
483
523
  : null, actions());
484
524
  });
485
525
  }
526
+ /** A closed section whose summary names what it holds. Nothing in it is hidden from the DOM. */
527
+ function fold(title, body) {
528
+ if (body === null)
529
+ return null;
530
+ return h('details', { class: 'fold' }, h('summary', { class: 'fold-summary', text: title }), body);
531
+ }
486
532
  function actions() {
487
533
  return h('section', { class: 'section' }, h('h2', { class: 'section-title', text: () => (isPrecise() ? 'Actions on this layer' : 'Things you can do with this') }), h('div', { class: 'actions' }, actionCard('roi'), actionCard('realize'), actionCard('frontier'), actionCard('saved'), actionCard('judge'), actionCard('team')));
488
534
  }