LearnNewsExamplesServices
Frontmatter
id17561
titleTasks view: a list.Base with section header records
stateClosed
labels
enhancementdesignaiagent-os
assigneesneo-fable-clio
createdAtAug 22, 2026, 6:58 PM
updatedAtAug 23, 2026, 12:28 AM
githubUrlhttps://github.com/neomjs/neo/issues/17561
authorneo-fable-clio
commentsCount1
parentIssue17559
subIssues[]
subIssuesCompleted0
subIssuesTotal0
contentTrust
projected
quarantined0
signals[]
blockedBy[x] 17560 Fleet view folder: topology move and base-class naming (mechanical)
blocking[]
closedAtAug 23, 2026, 12:28 AM

Tasks view: a list.Base with section header records

Closed Backlog/active-chunk-18 enhancementdesignaiagent-os
neo-fable-clio
neo-fable-clio commented on Aug 22, 2026, 6:58 PM

Context

Leaf of #17559 (laws 0–2), owned by the author of the offending view. The Tasks surface (#17329 / PR #17542) ships a correct data path — the fleetTasks read-observe verb, the fleetTasksSource reducers with their producer-contract witnesses, FleetTask model + FleetTasks store — under a view layer that hand-rolls three sections of nested containers and per-row components. The operator critique of 2026-08-22 names it directly: a container with nested containers and components where a library primitive belongs.

The Problem

TasksPane renders running / queued / recent rows by mapping records into container configs (rowConfig), re-creating the row components on every snapshot. Twelve rows never needed buffering, but they did need a list: item identity, header sections, keyboard navigation and selection are all primitives Neo.list.Base already owns.

The Architectural Reality

  • Neo.list.Base: store-bound items (createItem/createItemContent), useHeaders with isHeader records (src/list/Base.mjs createItem's neo-list-header branch), native focus/arrow navigation, selectionModel.
  • The existing row grammar (state word as the always-present text channel, native <progress value max> + percent/done / total text, the source pill, the T5 viewer-time title) is a presentation contract to preserve — it becomes the createItemContent output.
  • The envelope/freshness line (wired · partial · unavailable, the reason, the labeled cold sample) and the Refresh intent stay; they belong to a thin tasks/Container that hosts the list, with a tasks/Controller owning the refresh intent (law 2). The cockpit's read drive (boot / liveness tick / reconnect) stays where it is until #17335's decomposition moves it.

The Fix

  1. view/fleet/tasks/List.mjsAgentOS.view.fleet.tasks.List extends Neo.list.Base, bound to the provider-hosted tasks store; useHeaders: true; the view inserts one header record per non-empty section at section boundaries (store sorted by section order, then the source's ordering); createItemContent renders the existing row grammar verbatim.
  2. view/fleet/tasks/Container.mjs — the freshness line + Refresh + the list; tasks/Controller.mjs — the refresh intent (tasksRequest) and the cold/partial/wired presentation state.
  3. The cold-spine sample stays a labeled sample (sample records in the store under the unavailable envelope), never beside live rows — the existing contract, now expressed as store content.
  4. TasksPane.scsstasks/List.scss + tasks/Container.scss; tokens only; the freshness pill stays the shared cockpit vocabulary.
  5. tasksPane.spec.mjs and FleetTasksPaneNL.spec.mjs migrate to the list (same assertions: progress value/max in a real DOM, refresh → second wire request → replacement).

Contract Ledger Matrix

Target Surface Source of Authority Proposed Behavior Fallback / Edge Case Docs Evidence
AgentOS.view.fleet.tasks.List (new) #17559 laws 0+1; Neo.list.Base store-bound list with section header records and the existing row grammar empty section → no header; unavailable envelope → labeled sample records class docblock migrated unit + e2e specs
tasksRequest intent existing cockpit controller seam fired by tasks/Controller, consumed by the cockpit unchanged n/a docblock existing cockpit spec
fleetTasks verb / source / model / store #17329 ledger unchanged n/a existing existing 29 + 8 witnesses stay green

Acceptance Criteria

  • The Tasks surface renders through Neo.list.Base with useHeaders section records — the same three sections, the same row grammar (state word + <progress value max> + text + source pill + T5 title), witnessed in the migrated unit spec.
  • Cold sample, transport-cold, source-unavailable, partial and wired states render exactly as the #17329 contract states (migrated assertions, no semantic changes).
  • Refresh intent round-trip witnessed headed through the authenticated loopback transport (the migrated FleetTasksPaneNL journey).
  • Suffix law holds for every new class; token-only SCSS; check-theme-surfaces green.
  • The #17329 source/wire witnesses stay untouched and green.

Out of Scope

Moving the cockpit's read drive into the surface controller (#17335), buffering (twelve rows), any change to the fleetTasks wire contract.

Related

Epic: #17559. Blocked by: PR #17542 (the data path must land first) and the topology move leaf (born in the new folder). Origin of the view: #17329.

Live latest-open sweep: checked latest 20 open issues at 2026-08-22T16:55:35Z; no equivalent. A2A claim sweep: no competing claim.

Origin Session ID: 28bee2e0-4dc8-4375-8514-78fcf38d0d30 Retrieval Hint: query_raw_memories("tasks view list.Base section header records useHeaders row grammar progress")

tobiu referenced in commit 7469003 - "feat(agentos): the tasks surface renders through list.Base section records (#17561) (#17575) on Aug 23, 2026, 12:28 AM
tobiu closed this issue on Aug 23, 2026, 12:28 AM