dashboard-primer.html 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570
  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="utf-8">
  5. <meta name="viewport" content="width=device-width, initial-scale=1">
  6. <title>Clanker-Saddle dashboard &mdash; Curated Primer (sampler 1 of 3)</title>
  7. <style>
  8. /* DIRECTION 1 — CURATED PRIMER. GitHub/Primer lineage, disciplined.
  9. ~14 named tokens; the existing blue #0969da as accent; light default. */
  10. :root {
  11. --surface-sunken: #f6f8fa; /* page */
  12. --surface: #ffffff; /* cards */
  13. --surface-inset: #eff2f5; /* wells, code chips */
  14. --ink: #1f2328; /* primary text */
  15. --ink-muted: #59636e; /* secondary text */
  16. --ink-faint: #6e7681; /* meta, placeholders */
  17. --line: #d1d9e0; /* card borders */
  18. --line-soft: #e4eaef; /* dividers */
  19. --accent: #0969da; /* the existing blue */
  20. --accent-surface: #ddf4ff; /* selected/tinted blue */
  21. --success: #1a7f37; /* done / running / idle */
  22. --warning: #9a6700; /* queued / blocked / review */
  23. --danger: #cf222e; /* failed / stuck */
  24. --radius: 8px;
  25. --font-mono: ui-monospace, "Cascadia Code", Menlo, Consolas, monospace;
  26. }
  27. @media (prefers-color-scheme: dark) {
  28. :root {
  29. --surface-sunken: #0d1117;
  30. --surface: #151b23;
  31. --surface-inset: #1c2430;
  32. --ink: #e6edf3;
  33. --ink-muted: #9198a1;
  34. --ink-faint: #6e7681;
  35. --line: #3d444d;
  36. --line-soft: #262c36;
  37. --accent: #4493f8;
  38. --accent-surface: #121d2f;
  39. --success: #3fb950;
  40. --warning: #d29922;
  41. --danger: #f85149;
  42. }
  43. }
  44. * { box-sizing: border-box; }
  45. html { scrollbar-gutter: stable; }
  46. body {
  47. margin: 0;
  48. font: 15px/1.55 system-ui, -apple-system, "Segoe UI", sans-serif;
  49. color: var(--ink);
  50. background: var(--surface-sunken);
  51. }
  52. a { color: var(--accent); text-decoration: none; }
  53. a:hover { text-decoration: underline; }
  54. .top {
  55. display: flex; align-items: baseline; gap: 1rem;
  56. max-width: 66rem; margin: 0 auto; padding: 0.9rem 1rem 0.7rem;
  57. border-bottom: 1px solid var(--line);
  58. background: var(--surface);
  59. }
  60. .brand {
  61. margin: 0; font-size: 1rem; font-weight: 650; letter-spacing: -0.01em;
  62. color: var(--ink); display: flex; align-items: center; gap: 0.5rem;
  63. }
  64. .brand-emblem { height: 1.75rem; width: auto; display: block; }
  65. .top-nav { display: flex; gap: 0.25rem; flex: 1; flex-wrap: wrap; align-items: center; }
  66. .nav-menu { position: relative; display: inline-block; }
  67. .nav-menu > summary {
  68. cursor: pointer; list-style: none; user-select: none;
  69. border-radius: 6px; padding: 0.25rem 0.6rem;
  70. font-size: 0.875rem; color: var(--ink-muted);
  71. display: inline-flex; align-items: center; gap: 0.35rem;
  72. }
  73. .nav-menu > summary::-webkit-details-marker { display: none; }
  74. .nav-menu > summary::after { content: "▾"; font-size: 0.7em; color: var(--ink-faint); }
  75. .nav-menu > summary:hover { background: var(--line-soft); color: var(--ink); }
  76. .nav-menu[open] > summary { background: var(--line-soft); color: var(--ink); }
  77. .nav-menu[open] > summary::after { transform: rotate(180deg); }
  78. .nav-dropdown {
  79. position: absolute; top: calc(100% + 0.3rem); left: 0; z-index: 50;
  80. background: var(--surface); border: 1px solid var(--line);
  81. border-radius: 6px; box-shadow: 0 4px 14px #0002;
  82. min-width: 9rem; padding: 0.25rem;
  83. display: flex; flex-direction: column;
  84. }
  85. @media (prefers-color-scheme: dark) {
  86. .nav-dropdown { box-shadow: 0 4px 14px #0008; }
  87. }
  88. .nav-dropdown a, .nav-dropdown .linklike {
  89. text-align: left; border-radius: 6px; padding: 0.3rem 0.6rem;
  90. font-size: 0.875rem; color: var(--ink); background: none;
  91. border: none; cursor: pointer; font-family: inherit; white-space: nowrap;
  92. }
  93. .nav-dropdown a:hover, .nav-dropdown .linklike:hover {
  94. background: var(--line-soft); text-decoration: none;
  95. }
  96. .nav-dropdown a[aria-current="page"] { color: var(--accent); font-weight: 600; }
  97. .nav-menu.account { margin-left: auto; }
  98. .nav-menu.account > summary { color: var(--ink); }
  99. .sampler-note {
  100. max-width: 66rem; margin: 0 auto 1rem; padding: 0.5rem 1rem 0;
  101. font-size: 0.8125rem; color: var(--ink-faint);
  102. }
  103. .sampler-note a { color: var(--ink-muted); }
  104. main { max-width: 66rem; margin: 0 auto 3rem; padding: 0 1rem; }
  105. /* ---- ZONE 1: advisor, first and loudest ---- */
  106. .zone-advisor h1 {
  107. margin: 0.2rem 0 0.35rem; font-size: 1.5rem; letter-spacing: -0.02em;
  108. }
  109. .lede { margin: 0 0 1rem; color: var(--ink-muted); max-width: 46rem; }
  110. .composer {
  111. background: var(--surface); border: 1px solid var(--line);
  112. border-radius: var(--radius); padding: 0.75rem;
  113. }
  114. .composer:focus-within { border-color: var(--accent); }
  115. .composer textarea {
  116. display: block; width: 100%; border: none; resize: vertical;
  117. background: transparent; color: var(--ink);
  118. font: inherit; padding: 0.35rem 0.45rem;
  119. }
  120. .composer textarea:focus { outline: none; }
  121. .composer textarea::placeholder { color: var(--ink-faint); }
  122. .composer-bar {
  123. display: flex; align-items: center; justify-content: space-between;
  124. gap: 1rem; margin-top: 0.5rem; padding: 0 0.25rem;
  125. }
  126. .hint { margin: 0; font-size: 0.8125rem; color: var(--ink-faint); font-family: var(--font-mono); }
  127. .btn {
  128. font: inherit; font-size: 0.875rem; cursor: pointer;
  129. border: 1px solid var(--line); border-radius: 6px;
  130. background: var(--surface); color: var(--ink);
  131. padding: 0.3rem 0.9rem;
  132. }
  133. .btn:hover { border-color: var(--ink-muted); }
  134. .btn.primary {
  135. background: var(--accent); border-color: rgba(31, 35, 40, 0.15);
  136. color: #fff;
  137. }
  138. .btn.quiet { color: var(--ink-muted); }
  139. .exchange { margin-top: 1.4rem; }
  140. .exchange h2 {
  141. font-size: 0.9375rem; margin: 0 0 0.75rem; font-weight: 600;
  142. color: var(--ink-muted); display: flex; gap: 0.75rem; align-items: baseline;
  143. }
  144. .exchange h2 .more { font-size: 0.8125rem; }
  145. .msg { max-width: 44rem; margin-bottom: 0.75rem; }
  146. .msg p { margin: 0; }
  147. .from-user { margin-left: auto; padding-right: 0; text-align: right; }
  148. .from-user p { display: inline-block; text-align: left; }
  149. .from-user > p:first-child, .from-advisor > p:first-child { margin: 0; }
  150. .from-advisor { color: var(--ink); }
  151. .from-user > p {
  152. background: var(--accent-surface); border-radius: 12px;
  153. padding: 0.55rem 0.9rem; max-width: 40rem;
  154. }
  155. .from-advisor > p {
  156. border-left: 2px solid var(--line); padding-left: 0.9rem;
  157. }
  158. .suggested {
  159. border: 1px solid var(--line); border-left: 2px solid var(--accent);
  160. border-radius: 6px; padding: 0.65rem 0.9rem; margin-top: 0.6rem;
  161. background: var(--surface); max-width: 40rem;
  162. }
  163. .suggested-kind {
  164. margin: 0 0 0.25rem; font-size: 0.6875rem; text-transform: uppercase;
  165. letter-spacing: 0.08em; color: var(--accent); font-weight: 600;
  166. }
  167. .suggested-title { margin: 0 0 0.2rem; font-weight: 600; }
  168. .suggested-meta { margin: 0 0 0.6rem; font-size: 0.8125rem; color: var(--ink-muted); }
  169. .suggested-actions { display: flex; gap: 0.5rem; }
  170. .all-chats { font-size: 0.875rem; margin: 0.9rem 0 0; }
  171. /* ---- ZONE 2: compact status strip ---- */
  172. .zone-status {
  173. margin-top: 2.2rem; padding-top: 1.2rem;
  174. border-top: 1px solid var(--line);
  175. display: grid; grid-template-columns: minmax(0, 1.9fr) minmax(0, 1fr);
  176. gap: 1.5rem;
  177. }
  178. .zone-status h2 {
  179. font-size: 0.9375rem; margin: 0 0 0.75rem; font-weight: 600;
  180. }
  181. .count {
  182. margin-left: 0.4rem; color: var(--ink-faint); font-weight: 500; font-size: 0.8125rem;
  183. }
  184. .needs-list { list-style: none; margin: 0; padding: 0; }
  185. .need {
  186. display: grid; grid-template-columns: 6.5rem minmax(0, 1fr) auto;
  187. gap: 0.9rem; padding: 0.7rem 0; align-items: start;
  188. border-top: 1px solid var(--line-soft);
  189. }
  190. .need:first-child { border-top: none; padding-top: 0; }
  191. .need-kind { margin: 0.15rem 0 0; }
  192. .need-title { margin: 0 0 0.15rem; font-weight: 550; }
  193. .need-meta { margin: 0; font-size: 0.8125rem; color: var(--ink-muted); }
  194. .need-act { margin: 0; display: flex; gap: 0.5rem; flex-wrap: wrap; }
  195. .tag {
  196. display: inline-block; font-size: 0.6875rem; font-weight: 550;
  197. padding: 0.1rem 0.5rem; border-radius: 10px; line-height: 1.5;
  198. }
  199. .tag.review { background: #fff1e0; color: #9a4700; }
  200. .tag.question { background: var(--accent-surface); color: var(--accent); }
  201. .tag.parked { background: var(--surface-inset); color: var(--ink-muted); }
  202. .tag.working { background: #fff8c5; color: var(--warning); }
  203. .tag.queued { background: #8884333d; color: #4d4d33; }
  204. .tag.suspended { background: var(--surface-inset); color: var(--ink-muted); }
  205. .tag.blocked { background: #fff8c5; color: #9a6700; }
  206. .tag.done { background: #dafbe1; color: var(--success); }
  207. .tag.failed { background: #ffebe9; color: var(--danger); }
  208. .tag.progress { background: #dafbe1; color: var(--success); }
  209. .tag.comment { background: #f0f0f0; color: #6e7781; }
  210. .tag.system { background: var(--surface-inset); color: var(--ink-muted); }
  211. @media (prefers-color-scheme: dark) {
  212. .tag.review { background: #3d1e00; color: #d4a72c; }
  213. .tag.question { background: #121d2f; color: #4493f8; }
  214. .tag.working { background: #2b2b12; color: #d4a72c; }
  215. .tag.queued { background: #2b2b12; color: #d4a72c; }
  216. .tag.blocked { background: #2b2b12; color: #d4a72c; }
  217. .tag.done, .tag.progress { background: #12261e; color: #3fb950; }
  218. .tag.failed { background: #2d1214; color: #f85149; }
  219. .tag.comment { background: #262c36; color: #9198a1; }
  220. }
  221. .health { border-left: 1px solid var(--line-soft); padding-left: 1.5rem; }
  222. .metrics { display: grid; grid-template-columns: repeat(4, 1fr); margin: 0 0 1rem; gap: 0.5rem; }
  223. .metric dt { font-size: 0.75rem; color: var(--ink-faint); text-transform: none; }
  224. .metric dd {
  225. margin: 0.1rem 0 0; font-size: 1.6rem; font-weight: 650;
  226. font-variant-numeric: tabular-nums; line-height: 1.1;
  227. }
  228. .metric dd.warn { color: var(--warning); }
  229. .saddles { list-style: none; margin: 0; padding: 0; font-size: 0.875rem; }
  230. .saddles li { display: flex; align-items: center; gap: 0.5rem; padding: 0.25rem 0; }
  231. .state {
  232. width: 0.5rem; height: 0.5rem; border-radius: 50%;
  233. display: inline-block; flex: none;
  234. }
  235. .state.busy { background: var(--success); }
  236. .state.idle { background: var(--ink-faint); }
  237. .state.offline { background: transparent; border: 1px solid var(--ink-faint); }
  238. /* ---- ZONE 3: ambient ---- */
  239. .zone-ambient { margin-top: 2.2rem; padding-top: 1.2rem; border-top: 1px solid var(--line); }
  240. .panel { margin-bottom: 1.1rem; }
  241. .panel > summary {
  242. cursor: pointer; list-style: none; display: flex; align-items: baseline; gap: 0.5rem;
  243. }
  244. .panel > summary::-webkit-details-marker { display: none; }
  245. .panel > summary::after { content: "+"; color: var(--ink-faint); font-weight: 400; }
  246. .panel[open] > summary::after { content: "–"; }
  247. .panel > summary h2 {
  248. font-size: 0.9375rem; font-weight: 600; margin: 0; color: var(--ink);
  249. }
  250. .summary-meta { font-size: 0.8125rem; color: var(--ink-faint); }
  251. .panel > div, .panel > ul, .panel > p, .panel > table { margin-top: 0.75rem; }
  252. .notes { list-style: none; margin: 0.75rem 0 0; padding: 0; }
  253. .note { display: flex; gap: 0.6rem; padding: 0.4rem 0; }
  254. .note-state {
  255. flex: none; width: 0.8rem; height: 0.8rem; margin-top: 0.2rem;
  256. border: 1px solid var(--ink-faint); border-radius: 3px;
  257. }
  258. .note.done .note-state { background: var(--success); border-color: var(--success); }
  259. .note.promoted .note-state {
  260. background: var(--accent-surface); border-color: var(--accent);
  261. }
  262. .note-body p:first-child { margin: 0 0 0.1rem; }
  263. .note-meta { font-size: 0.8125rem; color: var(--ink-faint); }
  264. .note.done .note-body p:first-child { color: var(--ink-muted); }
  265. .discoveries { list-style: none; margin: 0.75rem 0 0; padding: 0; max-width: 50rem; }
  266. .discoveries li { padding: 0.4rem 0; border-top: 1px solid var(--line-soft); }
  267. .discoveries li:first-child { border-top: none; }
  268. .discoveries li > p:first-child { margin: 0 0 0.1rem; }
  269. .more-row { margin: 0.5rem 0 0; font-size: 0.875rem; }
  270. .tasks { width: 100%; border-collapse: collapse; font-size: 0.875rem; }
  271. .tasks th {
  272. text-align: left; font-size: 0.75rem; font-weight: 600;
  273. color: var(--ink-faint); padding: 0.3rem 0.75rem 0.3rem 0;
  274. border-bottom: 1px solid var(--line);
  275. }
  276. .tasks td {
  277. padding: 0.45rem 0.75rem 0.45rem 0; border-bottom: 1px solid var(--line-soft);
  278. vertical-align: top;
  279. }
  280. .tasks td.when, .tasks td.empty { color: var(--ink-faint); }
  281. .tasks .when { color: var(--ink-faint); }
  282. .when { color: var(--ink-faint); font-size: 0.8125rem; }
  283. .activity { list-style: none; margin: 0.75rem 0 0; padding: 0; font-size: 0.875rem; }
  284. .activity li { display: flex; gap: 0.75rem; padding: 0.28rem 0; }
  285. .activity .when { flex: none; width: 3.2rem; font-variant-numeric: tabular-nums; }
  286. .activity .what { margin: 0; }
  287. .activity .what a { font-weight: 500; }
  288. .foot {
  289. max-width: 66rem; margin: 0 auto; padding: 1rem; font-size: 0.8125rem;
  290. color: var(--ink-faint); border-top: 1px solid var(--line-soft);
  291. }
  292. .foot p { margin: 0; }
  293. @media (max-width: 50rem) {
  294. .zone-status { grid-template-columns: 1fr; }
  295. .health { border-left: none; padding-left: 0; border-top: 1px solid var(--line-soft); padding-top: 1rem; }
  296. .need { grid-template-columns: minmax(0, 1fr); }
  297. .need-kind { margin: 0; }
  298. .need-act { margin-top: 0.2rem; }
  299. }
  300. </style>
  301. </head>
  302. <body>
  303. <header class="top">
  304. <p class="brand"><img class="brand-emblem" alt=""
  305. src="data:image/png;base64,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">ClankerSaddle</p>
  306. <nav class="top-nav" aria-label="Primary">
  307. <details class="nav-menu">
  308. <summary>Work</summary>
  309. <div class="nav-dropdown">
  310. <a href="#" aria-current="page">Dashboard</a>
  311. <a href="#">Tasks</a>
  312. <a href="#">Goals</a>
  313. <a href="#">Chats</a>
  314. </div>
  315. </details>
  316. <details class="nav-menu">
  317. <summary>Library</summary>
  318. <div class="nav-dropdown">
  319. <a href="#">Projects</a>
  320. <a href="#">Rules</a>
  321. <a href="#">Stacks</a>
  322. <a href="#">Discoveries</a>
  323. </div>
  324. </details>
  325. <details class="nav-menu">
  326. <summary>Admin</summary>
  327. <div class="nav-dropdown">
  328. <a href="#">Saddles</a>
  329. <a href="#">Users</a>
  330. <a href="#">Model</a>
  331. </div>
  332. </details>
  333. <details class="nav-menu account">
  334. <summary>marta</summary>
  335. <div class="nav-dropdown">
  336. <a href="#">Profile</a>
  337. <button type="button" class="linklike">Log out</button>
  338. </div>
  339. </details>
  340. </nav>
  341. </header>
  342. <main id="main">
  343. <p class="sampler-note">Sampler 1 of 3 &mdash; Curated Primer. Static mock, not live data.
  344. <a href="dashboard-primer.html">1 Curated Primer</a> &middot;
  345. <a href="dashboard-control.html">2 Control Room</a> &middot;
  346. <a href="dashboard-swiss.html">3 Swiss Flat</a></p>
  347. <!-- ZONE 1: the advisor conversation composer, first and loudest -->
  348. <section class="zone-advisor" aria-labelledby="advisor-h">
  349. <h1 id="advisor-h">Ask the advisor</h1>
  350. <p class="lede">Reads your projects, tasks, goals, rules and discoveries &mdash; asks
  351. you questions and suggests work. It never runs commands.</p>
  352. <form class="composer" onsubmit="return false">
  353. <textarea rows="3" placeholder="What should the fleet work on next?"></textarea>
  354. <div class="composer-bar">
  355. <p class="hint">claude-sonnet &middot; last fleet snapshot 14:02</p>
  356. <button type="submit" class="btn primary">Start chat</button>
  357. </div>
  358. </form>
  359. <p class="all-chats"><a href="#">All 14 chats &rarr;</a></p>
  360. </section>
  361. <!-- ZONE 2: compact status strip. Needs-you items sit above queue health. -->
  362. <section class="zone-status" aria-labelledby="needs-h">
  363. <div class="needs">
  364. <h2 id="needs-h">Needs a human <span class="count">3</span></h2>
  365. <ol class="needs-list">
  366. <li class="need">
  367. <p class="need-kind"><span class="tag review">review</span></p>
  368. <div class="need-body">
  369. <p class="need-title"><a href="#">Ghost-working sweep: requeue stale open
  370. sessions from the dispatcher tick</a></p>
  371. <p class="need-meta">task 211 &middot; Clanker-Saddle &middot; report waiting 12 min</p>
  372. </div>
  373. <p class="need-act"><button type="button" class="btn">Review report</button></p>
  374. </li>
  375. <li class="need">
  376. <p class="need-kind"><span class="tag parked">parked</span></p>
  377. <div class="need-body">
  378. <p class="need-title"><a href="#">Goal compare: diff two branches&rsquo;
  379. task trees</a></p>
  380. <p class="need-meta">task 198 &middot; hit the 40-turn cap at 13:51 &middot;
  381. wake to continue, or leave it parked</p>
  382. </div>
  383. <p class="need-act"><button type="button" class="btn">Wake</button>
  384. <button type="button" class="btn quiet">Leave parked</button></p>
  385. </li>
  386. <li class="need">
  387. <p class="need-kind"><span class="tag question">question</span></p>
  388. <div class="need-body">
  389. <p class="need-title">Should the discovery list paginate at 50 rows, or
  390. keep one long scroll?</p>
  391. <p class="need-meta">task 197 &middot; asked 2 h ago &middot; options 50 / 100 / keep scroll</p>
  392. </div>
  393. <p class="need-act"><button type="button" class="btn">Answer</button></p>
  394. </li>
  395. </ol>
  396. </div>
  397. <div class="health">
  398. <h2>Queue health</h2>
  399. <dl class="metrics">
  400. <div class="metric"><dt>running</dt><dd>3</dd></div>
  401. <div class="metric"><dt>stuck</dt><dd class="warn">1</dd></div>
  402. <div class="metric"><dt>queued</dt><dd>5</dd></div>
  403. <div class="metric"><dt>draft</dt><dd>2</dd></div>
  404. </dl>
  405. <ul class="saddles">
  406. <li><span class="state busy"></span>atlas &mdash; busy &middot; task 214</li>
  407. <li><span class="state busy"></span>meridian &mdash; busy &middot; goal 31</li>
  408. <li><span class="state idle"></span>kestrel &mdash; idle &middot; 41 min</li>
  409. <li><span class="state offline"></span>portland &mdash; offline &middot; 3 h</li>
  410. </ul>
  411. </div>
  412. </section>
  413. <!-- ZONE 3: ambient. Reduced density, collapsed where sensible. -->
  414. <section class="zone-ambient" aria-label="Ambient">
  415. <details class="panel" open>
  416. <summary><h2>Notes</h2><span class="summary-meta">3</span></summary>
  417. <ul class="notes">
  418. <li class="note open"><span class="note-state"></span>
  419. <div class="note-body">
  420. <p>Dashboard hierarchy: advisor first, needs-you second, ambient
  421. below &mdash; decide between the three samplers before touching app.css.</p>
  422. <p class="note-meta">today 13:04</p>
  423. </div>
  424. </li>
  425. <li class="note done"><span class="note-state"></span>
  426. <div class="note-body">
  427. <p>Check goal badge contrast under the dark scheme.</p>
  428. <p class="note-meta">yesterday &middot; done</p>
  429. </div>
  430. </li>
  431. <li class="note promoted"><span class="note-state"></span>
  432. <div class="note-body">
  433. <p>Ship the web-push test notification end to end.</p>
  434. <p class="note-meta">promoted to <a href="#">goal 24</a></p>
  435. </div>
  436. </li>
  437. </ul>
  438. </details>
  439. <details class="panel" open>
  440. <summary><h2>Latest discoveries</h2><span class="summary-meta">2</span></summary>
  441. <ul class="discoveries">
  442. <li>
  443. <p>json-glib writes invalid UTF-8 verbatim: a byte-count clamp that lands
  444. mid-character poisons the whole payload, and the stored row loses its
  445. members on read-back. Back the cut off over continuation bytes at every
  446. serialisation boundary.</p>
  447. <p class="note-meta">2 Oct &middot; Saddle</p>
  448. </li>
  449. <li>
  450. <p>A harness seeding a row the app also lazily creates must INSERT OR
  451. IGNORE &mdash; two read-then-insert writers race and the loser dies on
  452. UNIQUE, taking the whole sequential suite with it.</p>
  453. <p class="note-meta">1 Oct &middot; Clanker-Saddle</p>
  454. </li>
  455. </ul>
  456. <p class="more-row"><a href="#">All discoveries &rarr;</a></p>
  457. </details>
  458. <details class="panel">
  459. <summary><h2>Active tasks</h2><span class="summary-meta">6</span></summary>
  460. <table class="tasks">
  461. <thead>
  462. <tr><th>Task</th><th>Status</th><th>Branch</th><th>Latest</th></tr>
  463. </thead>
  464. <tbody>
  465. <tr>
  466. <td><a href="#">214 &middot; Mock dashboard: three visual directions as static
  467. HTML samplers</a></td>
  468. <td><span class="tag working">working</span></td>
  469. <td>web-stack</td>
  470. <td>writing mocks/dashboard-primer.html <span class="when">14:02</span></td>
  471. </tr>
  472. <tr>
  473. <td><a href="#">213 &middot; Split parked and failed runs on the goal branch
  474. view</a></td>
  475. <td><span class="tag queued">queued</span></td>
  476. <td>goal/branch-view</td>
  477. <td class="empty">&mdash;</td>
  478. </tr>
  479. <tr>
  480. <td><a href="#">198 &middot; Goal compare: diff two branches&rsquo; task
  481. trees</a></td>
  482. <td><span class="tag suspended">suspended</span></td>
  483. <td>goal/compare</td>
  484. <td>parked at turn cap 41/40 <span class="when">13:51</span></td>
  485. </tr>
  486. <tr>
  487. <td><a href="#">196 &middot; Notification digest: batch question and RFC
  488. pushes</a></td>
  489. <td><span class="tag blocked">blocked</span></td>
  490. <td>notify/digest</td>
  491. <td>asked: digest window 5 or 15 min <span class="when">12:37</span></td>
  492. </tr>
  493. <tr>
  494. <td><a href="#">189 &middot; Rate-limit the events endpoint</a></td>
  495. <td><span class="tag failed">failed</span></td>
  496. <td>api/rate-limit</td>
  497. <td>429 loop under parallel suites; needs backoff <span class="when">11:20</span></td>
  498. </tr>
  499. <tr>
  500. <td><a href="#">195 &middot; Advisor chat export to markdown</a></td>
  501. <td><span class="tag done">done</span></td>
  502. <td>advisor/export</td>
  503. <td>report accepted <span class="when">09:58</span></td>
  504. </tr>
  505. </tbody>
  506. </table>
  507. </details>
  508. <details class="panel">
  509. <summary><h2>Activity</h2><span class="summary-meta">7 events</span></summary>
  510. <ul class="activity">
  511. <li><p class="when">14:02</p>
  512. <p class="what"><span class="tag progress">progress</span> <a href="#">214</a>
  513. writing mocks/dashboard-primer.html</p></li>
  514. <li><p class="when">13:58</p>
  515. <p class="what"><span class="tag question">question</span> <a href="#">197</a>
  516. discovery list pagination &mdash; 50, 100, or one scroll?</p></li>
  517. <li><p class="when">13:50</p>
  518. <p class="what"><span class="tag review">review</span> <a href="#">211</a>
  519. report ready &mdash; ghost-working sweep</p></li>
  520. <li><p class="when">13:44</p>
  521. <p class="what"><span class="tag comment">comment</span> goal 31 &mdash;
  522. &ldquo;keep needs-a-human above queue health&rdquo;</p></li>
  523. <li><p class="when">13:31</p>
  524. <p class="what"><span class="tag progress">progress</span> <a href="#">196</a>
  525. digest skeleton, window still undecided</p></li>
  526. <li><p class="when">13:04</p>
  527. <p class="what"><span class="tag system">saddle</span> kestrel idle after
  528. task 197 parked</p></li>
  529. <li><p class="when">11:20</p>
  530. <p class="what"><span class="tag failed">failed</span> <a href="#">189</a>
  531. exit 1 &mdash; 429 loop under parallel suites</p></li>
  532. </ul>
  533. </details>
  534. </section>
  535. </main>
  536. <footer class="foot">
  537. <p>Curated Primer sampler &middot; static mock for the dashboard overhaul &middot; toggle your
  538. OS or devtools colour scheme to check the second variant</p>
  539. </footer>
  540. </body>
  541. </html>