From e35edb0c5274a4223cba9a6920bdc14e253d84f4 Mon Sep 17 00:00:00 2001 From: Lily Shen <115414357+lilyshen0722@users.noreply.github.com> Date: Sun, 1 Nov 2026 02:30:11 -0800 Subject: [PATCH] =?UTF-8?q?design(d215):=20draw=20the=20task=20record=20?= =?UTF-8?q?=E2=80=94=20log,=20nothing=20recorded,=20not=20available=20at?= =?UTF-8?q?=201440=20and=20390=20(TASK-757)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Sonnet 5.5 Co-authored-by: ux-lead Agent-Model: claude/claude-opus-5-5/high --- .../artboards/d215/cap/measure_after.js | 2 +- .../artboards/d215/cap/measure_after.test.js | 4 +- docs/design/artboards/d215/index.html | 58 ++++++++++++++++++- docs/design/artboards/d215/targets.json | 24 ++++++++ 4 files changed, 84 insertions(+), 4 deletions(-) diff --git a/docs/design/artboards/d215/cap/measure_after.js b/docs/design/artboards/d215/cap/measure_after.js index ad1b43d45..c6cff3694 100644 --- a/docs/design/artboards/d215/cap/measure_after.js +++ b/docs/design/artboards/d215/cap/measure_after.js @@ -18,7 +18,7 @@ const fs = require('fs'); const HERE = __dirname; const TARGETS = path.join(HERE, '..', 'targets.json'); -const SURFACES = ['settings', 'agent-settings', 'agent-memory', 'board', 'connectors', 'chat', 'sidebar', 'byo', 'byo-handoff', 'firstrun-welcome', 'firstrun-waiting', 'firstrun-connected', 'firstrun-error', 'activity-queue', 'activity-empty', 'activity-error', 'profile-person', 'profile-empty', 'profile-error']; +const SURFACES = ['settings', 'agent-settings', 'agent-memory', 'board', 'connectors', 'chat', 'sidebar', 'byo', 'byo-handoff', 'firstrun-welcome', 'firstrun-waiting', 'firstrun-connected', 'firstrun-error', 'activity-queue', 'activity-empty', 'activity-error', 'profile-person', 'profile-empty', 'profile-error', 'taskrecord-log', 'taskrecord-empty', 'taskrecord-error']; // byo-handoff is drawn but can't be captured on prod: reaching it issues a real key. The first-run // dialog is a latch-gated overlay, and the Scout welcome only exists in a brand-new pod, so neither is measured on prod. const PROD_SURFACES = SURFACES.filter(s => s !== 'byo-handoff' && !s.startsWith('firstrun-')); diff --git a/docs/design/artboards/d215/cap/measure_after.test.js b/docs/design/artboards/d215/cap/measure_after.test.js index ebdf2904f..25543a01e 100644 --- a/docs/design/artboards/d215/cap/measure_after.test.js +++ b/docs/design/artboards/d215/cap/measure_after.test.js @@ -29,7 +29,7 @@ test('--only with an unknown surface throws', () => { test('the committed targets.json passes its own validation', () => { const t = JSON.parse(fs.readFileSync(path.join(__dirname, '..', 'targets.json'), 'utf8')); - assert.strictEqual(Object.keys(t).length, 38); + assert.strictEqual(Object.keys(t).length, 44); validateTargets(t); }); @@ -39,7 +39,7 @@ test('an empty or partial measurement is refused', () => { const partial = { ...t }; delete partial['board-390']; assert.throws(() => validateTargets(partial), /missing board-390/); assert.throws(() => validateTargets({ ...t, 'chat-1440': { helperWords: NaN, innerRatio: 2 } }), /invalid chat-1440/); - assert.strictEqual(EXPECTED.length, 38); + assert.strictEqual(EXPECTED.length, 44); }); // A page whose SPA shell answers 200 and then redirects to `landsOn`. Its metrics would score diff --git a/docs/design/artboards/d215/index.html b/docs/design/artboards/d215/index.html index 3597e6e99..d4ee468d7 100644 --- a/docs/design/artboards/d215/index.html +++ b/docs/design/artboards/d215/index.html @@ -640,6 +640,36 @@ .app.m .v2-profile__chip { height: 44px; } .app.m .v2-profile__error { flex-direction: column; align-items: stretch; } .app.m .v2-profile__error .b { height: 44px; } +/* taskrecord: the live v2-run-trace / v2-task-record names, lifted onto the connectors page's primitives. */ +.v2-rec { width: 100%; max-width: 860px; margin: 0 auto; display: flex; flex-direction: column; gap: 12px; min-width: 0; } +.v2-run-trace__retention { margin: 0; font: 500 11.5px/1.5 var(--f-mono); color: var(--mu); } +.v2-run-trace__summary { display: grid; gap: 8px; padding: 14px 16px; border-radius: 12px; background: var(--sf); box-shadow: inset 0 0 0 1px var(--d); min-width: 0; } +.v2-run-trace__sumtop { display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap; } +.v2-run-trace__sumtop strong { font: 700 16px/1.25 var(--f-display); color: var(--ink); } +.v2-run-trace__sumtop span, .v2-run-trace__sub { font-size: 13px; line-height: 1.45; color: var(--se); margin: 0; } +.v2-run-trace__summary code, .v2-run-trace__call code { font: 500 11.5px/1.4 var(--f-mono); color: var(--mu); overflow-wrap: anywhere; } +.v2-task-record__downloads { display: flex; gap: 8px; flex-wrap: wrap; } +.v2-run-trace__note { margin: 0; padding: 12px 14px; border-radius: 12px; background: var(--sf); box-shadow: inset 0 0 0 1px var(--d); font-size: 13.5px; line-height: 1.45; color: var(--se); } +.v2-run-trace__alert { padding: 14px; border-radius: 12px; background: var(--sf); box-shadow: inset 0 0 0 1px var(--d); font-size: 13.5px; line-height: 1.5; color: var(--ink); } +.v2-run-trace__alert p { margin: 0; } +.v2-task-record__entries, .v2-run-trace__turns { list-style: none; margin: 0; padding: 0; display: grid; gap: 0; border-radius: 12px; background: var(--sf); box-shadow: inset 0 0 0 1px var(--d); overflow: hidden; } +.v2-task-record__entry { display: grid; grid-template-columns: 28px minmax(0, 1fr); gap: 12px; padding: 11px 14px; border-top: 1px solid var(--d); } +.v2-task-record__entry:first-child { border-top: 0; } +.v2-task-record__mark { display: grid; place-items: center; width: 28px; height: 28px; border-radius: 50%; background: var(--t); box-shadow: inset 0 0 0 1px var(--d); color: var(--se); } +.v2-task-record__mark svg.i { width: 16px; height: 16px; } +.v2-task-record__copy { display: grid; gap: 2px; min-width: 0; } +.v2-task-record__top { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; } +.v2-task-record__top strong { font-size: 14px; color: var(--ink); font-weight: 600; } +.v2-task-record__top span { font: 500 11.5px/1.4 var(--f-mono); color: var(--mu); } +.v2-task-record__who { font-size: 12.5px; line-height: 1.4; color: var(--mu); } +.v2-rec dl { display: grid; grid-template-columns: 120px minmax(0, 1fr); gap: 2px 12px; margin: 6px 0 0; } +.v2-rec dt { font: 500 11.5px/1.5 var(--f-mono); color: var(--mu); } +.v2-rec dd { margin: 0; font: 500 11.5px/1.5 var(--f-mono); color: var(--ink); overflow-wrap: anywhere; } +.v2-run-trace__back-m { margin: -2px 0 2px; } +.v2-run-trace__back-m .b { height: 44px; padding-left: 4px; } +.app.m .v2-rec dl { grid-template-columns: minmax(0, 1fr); } +.app.m .v2-rec dd { margin-bottom: 4px; } +.app.m .v2-run-trace__summary .b { height: 44px; }

Same look. Less said.

  • One screen firstRepeated blocks become a table; rare settings collapse.
  • @@ -1076,6 +1106,32 @@

    Same look. Less said.

    +
    +

    Task record

    /v2/pods/:podId/tasks/:taskId/record
    helper words log – → 58empty – → 32scroll 390 – → 1.0×
    +
    +
    Record · 1440six entries

    Task record

    What happened on this task, in order. Each entry carries the hash of the one before it, so a changed entry breaks the chain.

    TASK-616 entriesRun run_8f31c0
    1. ClaimedEntry 1
      Kai (agent) ·
    2. Grant issuedEntry 2
      Policy: slack-write ·
      grantId
      g_41c2
      scope
      slack.post
    3. Approval requestedEntry 3
      Kai (agent) ·
      tool
      slack.post
      channel
      #launch
    4. Approval decidedEntry 4
      Dana Okafor ·
      decision
      approved
    5. Tool callEntry 5
      Kai (agent) ·
      tool
      slack.post
      outcome
      ok
    6. DoneEntry 6
      Kai (agent) ·
    +
    Nothing recorded · 1440new task

    Task record

    What happened on this task, in order. Each entry carries the hash of the one before it, so a changed entry breaks the chain.

    Nothing has been recorded for this task yet.

    +
    +
    +
    Not available · 1440no access or no records

    Task record

    +
      +
    • An audit page, so it reads as a log. One row per entry, oldest first. The 16px mark says the kind; the kind, the entry number, then actor · time. The fields an entry carries sit under it as mono key and value pairs.
    • +
    • Two downloads, both bordered. JSONL and OTLP are equal; neither is the page's main act, so nothing here is ink. The only other key is Back to board, a ghost.
    • +
    • The chain is said once. The intro explains that each entry carries the hash of the one before; entries do not repeat it.
    • +
    • At 390 the back key moves under the head as a 44px row, the downloads stay on one line, and the fields stack key over value.
    • +

    Each state, one line

    + + + +
    RecordCounts line reads "N entries"; the run id sits beside it when the first entry has one.
    Nothing recordedThe intro stays; one line below says nothing has been recorded yet. No downloads.
    Not availableOnly the explanation, and no Retry, because a missing record or lost access does not come back by retrying. A store outage or a failed load keeps "Try again".
    +
    +
    +
    Record · 390

    Task record

    What happened on this task, in order. Each entry carries the hash of the one before it, so a changed entry breaks the chain.

    TASK-616 entriesRun run_8f31c0
    1. ClaimedEntry 1
      Kai (agent) ·
    2. Grant issuedEntry 2
      Policy: slack-write ·
      grantId
      g_41c2
      scope
      slack.post
    3. Approval requestedEntry 3
      Kai (agent) ·
      tool
      slack.post
      channel
      #launch
    4. Approval decidedEntry 4
      Dana Okafor ·
      decision
      approved
    Pods
    3Needs you
    Team
    Settings
    +
    Nothing recorded · 390

    Task record

    What happened on this task, in order. Each entry carries the hash of the one before it, so a changed entry breaks the chain.

    Nothing has been recorded for this task yet.

    Pods
    3Needs you
    Team
    Settings
    +
    Not available · 390

    Task record

    Pods
    3Needs you
    Team
    Settings
    +
    +
    +

    Dark mode

    one dark value per token
    diff --git a/docs/design/artboards/d215/targets.json b/docs/design/artboards/d215/targets.json index 4ecb139c4..9ee175a04 100644 --- a/docs/design/artboards/d215/targets.json +++ b/docs/design/artboards/d215/targets.json @@ -150,5 +150,29 @@ "profile-error-390": { "helperWords": 0, "innerRatio": 1 + }, + "taskrecord-log-1440": { + "helperWords": 58, + "innerRatio": 1 + }, + "taskrecord-empty-1440": { + "helperWords": 32, + "innerRatio": 1 + }, + "taskrecord-error-1440": { + "helperWords": 0, + "innerRatio": 1 + }, + "taskrecord-log-390": { + "helperWords": 48, + "innerRatio": 1 + }, + "taskrecord-empty-390": { + "helperWords": 32, + "innerRatio": 1 + }, + "taskrecord-error-390": { + "helperWords": 0, + "innerRatio": 1 } }