Cycles by week
Week of Sep 21

9 started, 4 closed, 14 carried live.

Busiest record: c92 qcontrol New Pages (45 entries) · 57 carried cycles have gone quiet · layer v0.9.21 → v0.9.22

Started
9
Still open
71
Closed
4
Record entries
98
Commits
216
Captures
144
Releases · deploys
2
Endpoints listing — after todos-2026-09-24 plan 03
c92qcontrol New Pages98 captures · 45 log entries — the week's busiest recordSee all 98 shots ↓

The c90 preview pages running in the real qcontrol app (qdash) on live /api/* data — a shell-owned global filter with a permanent timeframe, listing bands with honest devices, and six actor detail pages on one frame

Commits

216 commits across 9 repos, on each repo's checked-out branch.

Cycles

Started 9

c99Nuxt Backend Interface

Audit every qdash page's data provenance, write the front-end data-interface bible (page → context component → library component; composables modelled on app.qpoint.io's), then plan and execute the conversion of the qdash UI's vibe-coded data layer onto it

started Sep 279 in the log
c98Nav Submenu

A layer nav item that owns child items and discloses them by URL. First use: THE FLEET › Inventory in the qcontrol sidebar shows its 9 listing pages whenever /inventory is in the URL.

started Sep 268 in the log
c97Gen-1 Origin

Put the vibe-coded qdash prototype at the start of the page-evolution record — recovered screenshots now, a populated rebuild as its own thread

started Sep 253 in the log
c95Trigger-Bar Column Picker

Seat c93's UxColumnPicker on the right edge of c92's FilterTriggerBar as a default-but-optional add-on — one strip above every qdash listing table instead of two controls competing for the same edge

started Sep 2510 in the log
c94TODO Execution Process

Turn the c92 todos workflow (Mark's per-page meeting notes → one plan per page → parallel narrow-context executors → record) into a repeatable process: a /todos skill that reads the notes straight from Logseq, a sheet grammar, a page registry, and the templates the c92 run used by hand

started Sep 254 in the log
c93Table Column Picker

A checkbox popover that shows/hides a table's columns — UxColumnPicker on a new UxPopover primitive — prototyped on the design site, then extracted to q-nuxt-layer and wired into a qdash listing

started Sep 224 in the log
c12Micro ProblemsMarket Analyst

Reshape market-analyst into a design tool first — the source of truth for Qpoint's problem space — by adding a micro-problem layer (use case → micro problem → observations) on top of the existing market lens, with a curated registry, extraction-proposed candidates, computed standing, product surfaces, document intake, and briefs/stories that cite problems.

started Sep 218 in the log

Still open 14

c92qcontrol New Pages

Stand up the c90 qcontrol-preview pages in the real qcontrol app (qdash UI) — phase 1 the combined Teams, Users & Devices listing, alongside a qdash global filter that replicates app.qpoint.io's behaviour, then the remaining detail/listing pages

started Sep 182 wks · moved this week45 in the log
c90qcontrol Preview

Assemble seven page mocks (Teams & Users, User Details, Team Details, Sessions, Session Details, Devices, Device Details) behind shared app chrome that mimics the real qcontrol shell, ahead of integration with the real app

started Sep 162 wks · moved this week
c49Fix the Cloudflare Pages Deploy

Make push to main reliably deploy the design site to Cloudflare Pages *(2026-09-25: reframed as "make the build a manual local step", see PICKUP.md)*

started Jun 1116 wks · moved this week2 in the log
c89Teams–Sessions Listings

First-pass mocks for Teams listing header upgrade and net-new Sessions listing page in phase1 dashboard style

started Sep 152 wks · quiet 1
c88Global Filter

Extract app.qpoint.io's global filter into q-nuxt-layer as presentational components (Phase 1), then design and build a v2 segmented-bar redesign (Phase 2).

started Sep 152 wks · quiet 1
c84Cycles Status Page

Redesign /cycles into a living Design status surface - working now, decisions, seeds, blocked work, abandoned ideas, and the existing atlas

started Sep 34 wks · quiet 2
c81Phase 1 Pages

First-pass mocks for all 17 Phase-1 dashboard pages (Linear PRO-19…35) on one unified fixture world — the simplest literal execution of the listing → expand → detail → actor-web pattern

started Sep 14 wks · quiet 2
c7avoma-notesMarket Analyst

Explore and integrate Avoma notes data into extraction pipeline and dashboard visualizations.

started Feb 25parked
c4refinementMarket Analyst

Refine how extracted data is displayed in the dashboard and improve extraction quality where gaps exist.

started Feb 24parked
c3oauthMarket Analyst

Add Google OAuth to restrict dashboard access to @qpoint.io team members.

started Feb 20parked
c69Operating System

Methods & tooling retro — evaluate how we work against the design methodology, restore order, modernize the skill/agent tooling, and make the philosophy load-bearing

started Aug 15parked
c62build-partner

Build-partner portal — research, ideation, and a plan for a page that makes partners insiders

started Aug 8parked
c55agent-market-definition

Align the qcontrol agent-monitoring dashboard to specific personas and find market alignment — hypothesis-first, validated against calls later.

started Jul 24parked

Closed 4

c98Nav Submenu

A layer nav item that owns child items and discloses them by URL. First use: THE FLEET › Inventory in the qcontrol sidebar shows its 9 listing pages whenever /inventory is in the URL.

closed Sep 26 · started Sep 268 in the log
c97Gen-1 Origin

Put the vibe-coded qdash prototype at the start of the page-evolution record — recovered screenshots now, a populated rebuild as its own thread

closed Sep 25 · started Sep 253 in the log
c96Page Evolution

Build a before/after tool and page-evolution view to correlate captures across cycles and threads

closed Sep 25 · started Sep 253 in the log

Pages & components

What this week's captures picture — 54 pages, 11 components, 1 pattern · 43 first captured this week. Each links to its evolution: every moment it was shot, across cycles.

Patterns 1

Log

Key Changes entries dated inside the week, from each cycle's record — newest first within a cycle.

c99 Nuxt Backend Interface

Sep 27
  • 2026-09-27 · kick-off. Mark's rulings when asked:
    • Each track builds a sibling app in its own worktree and branch, both apps runnable and unconnected. This track wrote the shared convention, PARALLEL-APPS.md; the Fable track adopted it and added two rules.
    • Nuxt side only; /api/* is a frozen contract.
    • Foundation + Team exemplar first, then waves.
    • Library components are staged locally and flagged for q-nuxt-layer, not extracted.
    • This track: app crates/qdash/apps/claude-code-opus-5.5/, branch c99/claude-code-opus-5.5, app :3031, seed :7881.
    • Record: claude-code-opus-5.5/README.md.
Sep 27
  • 2026-09-27 · Phase 2 study. Six readers covered app.qpoint.io's composables and composition, the layer library tier, qdash as it stands, the founding docs, and a Tyler-lens rubric built from his commits. A cross-check re-verified 38 claims (31 held outright; the rest were corrected in place) and settled 16 contradictions against source → claude-code-opus-5.5/phase2/studies/.
Sep 27
  • 2026-09-27 · Phase 1 complete. 44 per-page reports (43 routes plus the shell, 1,964 classified elements), each checked by an adversarial verifier, with an index and four backend reference files → claude-code-opus-5.5/phase1/README.md. The headline: the browser invents little (17 SAMPLE and 106 PROJECTED literals, 61 LOCAL). The biggest shim is the backend join key. Attribution runs through agent_instances.run_id, which only the retired run envelope sets, so on a real fleet harness, user and team attribution goes empty. The Meridian seed hides this. The findings and posture reports were re-run as text after the harness blocked one subagent's writes.
Sep 27
  • 2026-09-27 · Phase 2 bible. The Qpoint data interface, now at v1.3. It was attacked four times before any page code: a four-lens review (82 findings), a recheck, a six-planner read-back (102 gaps) and a three-lens plan critique (76 findings). Every round and its disposition is recorded in review.md and phase3/critique.md. The data tier held through every round; the UI-tier seams (links, tables, states, proportion) were settled in v1.2 and v1.3.
Sep 27
  • 2026-09-27 · Phase 3 plan. phase3/plan.md, with:
    • a registry of every composable, rule, type, shim and component;
    • five family bills of materials (5,670 lines);
    • the critiques;
    • Stage 0 contracts;
    • an ownership map and a sign-off sheet.

    Execution runs in stages: S0 contracts → S1 shared-file freeze → S2 Team exemplar → checkpoint A → S3 lanes → S4 integration. Section 7 answers "how clear were the instructions".
Sep 27
  • 2026-09-27 · Phase 4 chassis. Built by hand on c99/claude-code-opus-5.5 (facd47e4 → 2efaef93): the transport, the primitive (11 specs), the query layer (one queue; 7 specs), the shell, the tier test, the typecheck and the parity harness. The parity harness caught a real divergence on its first run: a route map ported from the main checkout, which carries another session's uncommitted reorder.
Sep 27
  • 2026-09-27 · Stages 0–2a. Stage 0 settled one contract per shared component (bible v1.3, contracts.md); an adversarial check found no blockers.
    • Stage 1 (the shared-file freeze, 3718b156 → 7e2c3c10): the shared port vocabulary, wire types for every route (checked against 43 seed payloads), 21 shared-chrome library components with a /lab fixture gallery, the route map and shell, and parity v2. It went through a Tyler-lens review with 22 fixes.
    • Stage 2a (c88fc6fd → d60f2703): the Team data tier, the governance rules and shims, and the live plumbing, in three parallel lanes, each reviewed and fixed. The gate stands at 828 specs across 92 files, with the tier test and typecheck green.
    • The design-side record is committed at 90dd145.
Sep 27
  • 2026-09-27 · Stage 2b and checkpoint A.
    • The Team exemplar: establish pattern for a listing (599b7f28, /team/users) and for a detail page (bf61ca89, /team/users/detail). /team/sessions repeats the listing pattern verbatim.
    • The Inventory (I1), governance (G1) and fleet-views (F1) data tiers landed beside them. Each lane was built, reviewed through the Tyler lens and fixed before INT committed it.
    • At checkpoint A, INT took the lanes' requests. Three unruled strip differences now replicate the reference: value order, the pressed state, and Back after the Flagged tile. Other changes:
      • the entity exposes its stored record;
      • a POST's 404 throws in the backend's words;
      • TONE_BADGE, the data port fields and seriesData were added;
      • LAYER-CANDIDATES gained 9 incubating components and 11 layer fixes;
      • SIGNOFF was amended: V1, V3, Δ1, Δ3, Δ5, Δ6 and Δ16 changed, and B12 and B13 were added.
    • Gate: 1327 specs, tier test 16/16, typecheck clean. Parity on Team: 27 pass, 0 fail (a new back step checks the Flagged tile against the reference).
    • Commits run through 77dd8ab0. Record: claude-code-opus-5.5/README.md § Execution status.
Sep 27
  • 2026-09-27 · Stage 3 wave 1. HA registered the live plugin. Five lanes then ran in parallel, each building two steps, followed by a Tyler-lens review and a fix:
    • T2: teams and endpoints;
    • I-a: HarnessIdentityTable first (HI), then harnesses and models;
    • I-b: the four inventory listings;
    • G: campaigns, the first page on useQdashEntity, plus the staged rules moved into lib; then findings and alerts;
    • F: /live (its file-mode replay of 49,996 events shows 0 differences), performance and identity.

    INT committed 11 path-scoped commits (12b129de → 130d3c02), then gated them:
    • the strip shows an unserved active value only when a fixed vocabulary names it, which undoes checkpoint A's overreach;
    • one EntityChip mark lever replaces the two the lanes asked for;
    • LIVENESS_DOT, a /lab overlay frame, and 36 new LAYER-CANDIDATES components with 19 layer fixes;
    • one of those fixes is the layer's un-prebundled highlight.js, which broke skill detail on both apps.

    Gate: 1450 specs, tier test 16/16, typecheck clean, and all five family manifests pass. App at 5644c1f3, design at 28373a92.

c49 Fix the Cloudflare Pages Deploy

Sep 27

The deploy branch (2026-09-27):

Sep 25

Broken again (2026-09-25): both pushes failed on Cloudflare (f632245, 8fa2225). pr.yml fails npm ci with a 403 read_package on @qpoint-io/qmap@0.1.0 (token GH_NPM_READ_JON_PAT; rerun identical). The lockfile had been cached, so earlier runs never re-downloaded qmap; the layer 0.9.21 lockfile bump changed the cache key and exposed the missing access. The June Scope's "Out" rationale came true: the Git integration moved the auth problem into Cloudflare's builder. Mark's direction: make the build a manual local step (local GITHUB_TOKEN can read qmap, and a local build sees the sibling repos, so the atlas deploys complete). Options A (commit built output) / B (local wrangler pages deploy, the lean) and the decision queue → PICKUP.md. Parked the same day.

c98 Nav Submenu

Sep 26
  • Kick-off (2026-09-26): plan drafted, four decisions settled, cycle activated.
Sep 26
  • Layer + demo (2026-09-26):
    • NavVerticalSubmenu (q-nuxt-layer/components/nav/VerticalSubmenu.vue): the parent row is a NavVerticalItem (:sub="false") or a toggle <button>, followed by a role="group" list. Disclosure is segment-aware prefix match (defaults to to), with v-model:open as the override.
    • Rail: a ::before pseudo, so the top-2 bottom-2 inset doesn't push the children down. It uses stroke-strong, which matches the reference pixel for pixel (rgb 212, the same stroke as the section title rule).
    • NavVerticalItem gains sub (default undefined, which inherits via inject('navSubmenu')): bold italic, py-0.5. The measured result is 15px/700 italic, 26px rows against the parent's 30px. The reference pitch is ~27.5px.
    • Demo _demos/NavVerticalSubmenu.vue: interactive sidebar + empty / minimal / typical / unmatched / button / controlled / overflow scenarios. Registry entry added; the NavVerticalItem entry and demo gain sub. Layer CLAUDE.md: Nav table rows + an unreleased migration note.
    • Gotcha: the button's first class name ._toggle collided with UxToggle's unscoped ._toggle::after (a 2px white dot). It was renamed ._submenu-toggle, and the rail class ._submenu-rail.
Sep 26
  • Sub weight + size props (2026-09-26, Mark): NavVerticalSubmenu gains subWeight (reg | med | semi | bold | exbold | black, default bold) and subSize (px on the type scale 11–16, default 15).
    • How it reaches the children: the submenu now provides { weight, size } instead of true. NavVerticalItem maps them through literal class tables, so Tailwind sees every class; an off-scale value falls back to bold 15.
    • Demo: a weight dropdown + a 11–16 size slider. All six weights and six sizes verified in the browser. The parent row stays semi 15.
    • Consistency: named weight steps + scale-bound sizes keep it inside "size is constrained", with no arbitrary px.
Sep 26
  • Provisional subGap (2026-09-26, Mark): px of space between child rows (default 4, the old py-0.5), split into top/bottom padding by inline style so the click area stays contiguous. Demo slider 0–16.
    • Measured pitch = line-height + gap − 2 (the link's -mb-[2px]): 0 → 22px, 4 → 26px, 8 → 30px, 16 → 38px at 15px text. The reference's ~27.5px pitch sits at a gap of about 5–6.
    • To be removed once dialed: bake the chosen value into NavVerticalItem's SUB constant and drop the prop, the provide field and the demo slider.
Sep 26
  • Sub defaults dialed (2026-09-26, Mark, from the demo controls): subWeight med, subSize 13, subGap 1 are now the defaults (were bold / 15 / 4).
    • Measured: children render 500 13px italic with 0.5px top/bottom padding, 23px rows. The parent row is unchanged at semi 15.
    • Scope: NavVerticalItem's SUB constant holds the same values, so sub forced outside a submenu matches, and the scoped .sub py-0.5 rule is gone. subGap stays provisional until the next look; if 1 holds, bake it into SUB and drop the prop.
Sep 26
  • qdash wiring (2026-09-26): in qcontrol/crates/qdash/ui/app/components/AppSidebar.vue, a nav item listed in a SUBMENUS map renders as a NavVerticalSubmenu. Today that is only /inventory, whose children are WORKING_LISTINGS filtered to /inventory/*, so they're derived rather than typed a second time. Everything else renders as a NavVerticalItem, as before.
    • Active rules: new isSubActive is a segment-aware prefix match for children. The top-level isActive stays exact. WORKING is untouched.
    • Verified on the live :3030 server (NUXT_LOCAL_LAYER):
      • / and /users: collapsed.
      • /inventory: open, parent grape, no child lit.
      • /inventory/models/detail?id=…: open, parent ink, Models lit.
      • /inventory/workspaces: Repos & Workspaces lit.
      • Children render 500 13px italic, 23px rows, rail rgb 212.
      • working-nav.test.ts passes (6/6).
Sep 26
  • THE FLEET moved up (2026-09-26, Mark): qdash NAV now reads WHERE ARE WE → THE FLEET → WHAT GOOD LOOKS LIKE → ACT → PROVE. The groups still follow the Rust dashboard's 5-section IA, but the order now diverges from it; AppSidebar.vue notes this. Verified on :3030.
Sep 26
  • Inventory page title (2026-09-26, Mark): /inventory PageHeader "Harness Inventory" → "Inventory", matching the nav label. That was its only use of the old title in qdash.

c92 qcontrol New Pages

Sep 26

detail-titles (2026-09-26): Mark: "exploring adding the title of the various details page to the title bar / breadcrumb, let's experiment with Harness Detail", then "let's add it to all the details pages" (detail-titles-prompt.md; executed directly, no plan; twin record qdash cycles/c15 §detail-titles). qdash PageHeader passes titleSize to UxPageTitle; every detail page closes its breadcrumb with the entity name at crumb size (15px — ActorHeader keeps the hero name; ids mono), and a new useDetailTitle composable names the browser tab <name> · <section> · qdash. Then "restructure so that accounts appears under providers so that the nav item is highlighted": Account detail moved to /inventory/providers/accounts/detail (links + Working nav repointed; todos-pages.json route updated). Verified on :3030 across all 12 detail pages. Committed qcontrol cc411276 (Header, composable, the nine tracked detail pages); Endpoint / Account / User / Team detail hunks and the Account move stay on disk with their uncommitted pages. Open: Harness install's trail reads Inventory / Claude Code, same as Harness detail — Inventory / Harnesses / Claude Code / <user> offered.

Sep 26

toggle-cell (2026-09-26): Control Center policy rows — Mark: "there are times where I accidentally trigger the toggle when I mean to open the page…" (toggle-cell-prompt.md with toggle-cell-reference.webp / toggle-cell-open-track.png; executed directly; twin record qdash cycles/c15 §toggle-cell). The toggle <td> is its own zone: grape wash (10%) + inset outline on hover; the row's hover muted with :has() (colours only — zeroing border widths caused a one-pixel row jump); any click in the cell toggles and never expands the row; toggling ON no longer auto-opens the row; the off track darkens on expanded rows (content/18%) and on hover (26%). A "stuck" wash turned out to be stale Chromium paint from the layer's ._stretchy td fade (computed background already clear) — !transition-none on the cell. All page-local in pages/controls/index.vue; layer untouched. Committed qcontrol ae1dc78f (the harness-rename's egress wording hunk in the same file stays on disk); pushed feat/new-pages @ 52fa4de7. No dist rebuild (Mark: this session's hunks only).

Sep 26

team-nav (2026-09-26): Mark: "let's add a team nav item under the fleet, when clicked show these sub item listing pages : users, team & endpoints", then Sessions too, then "endpoints and session need to be moved physically to a team subdir … what do you think makes the most sense?" (team-nav-prompt.md; executed directly, no plan; twin record qdash cycles/c15 §team-nav). IA ruling: Inventory = what's in the fleet (equipment); Team = who and from where — Users, Teams, Endpoints, Sessions, all moved to /team/* (pages physically under pages/team/, ~100 links rewritten, breadcrumbs Team / …, a team-routes.global.ts middleware redirects the old /users, /teams, /inventory/endpoints, /inventory/sessions paths with query kept). THE FLEET is now Fleet Overview · Inventory · Team; Fleet Overview moved off / to /fleet. Landings: /fleet, /inventory, /team render a new DesignInProgress component (48px bold headline, one line, the section's listings stacked left between hairlines) — the Inventory overview and Fleet Overview they replaced are saved here as *-pre-placeholder.vue (Harness install detail keeps its door through Harness detail's installs ledger). Home: / is the page behind the sidebar logo; its content is the Working jump list, extracted from AppSidebar into WorkingNav (sidebar toggle + home share one example fetch). Verified on :3030 and on the rebuilt release binary against the seed (:7881); vitest 372, cargo test qdash 76. Committed with the whole qcontrol + layer trees at Mark's ask ("let's commit all the changes in qcontrol and q-nuxt-layer … and build etc"): layer 764ce82 (c95 listing strip) + 25fdf9f (c92 band-polish restyle); qcontrol 4e5795f6 (backend + qevents skill-definition schema + seed), 38a74e88 (UI — this thread plus every c92 thread on disk), 480de013 (dist from local layer 25fdf9f). Unpushed; layer unreleased (pending 0.9.22 — qdash's lockfile still pins the old layer SHA).

Sep 25

todos housekeeping (2026-09-25): the todo sheets are now named by their Logseq journal date (the meeting day), not the paste day: todos-2026-09-24.md + todos-2026-09-24/ → todos-2026-09-23.*, and the new sheet todos-2026-09-25.md → todos-2026-09-24.md (source journal core/journals/2026_09_24.md, not yet planned). References repointed in this record, the plan README, component-registry.ts (FilterNoMatches description), the qdash twin record and six qdash source comments. The workflow itself — sheet → per-page plans → parallel executors — is reviewed in c94, which will own the shorthand and the skill.

Sep 25

todos plan 00 executed (2026-09-25): Sweep (todos-2026-09-24/00-sweep.md; twin record qdash cycles/c15 §todos plan 00). Decisions 00.1–00.4 taken at their defaults (Mark had not answered). TUD removal: pages/teams-users-devices.vue deleted; THE FLEET sidebar now lists Teams · Users · Devices (exact-path active); route dropped from working-nav.ts and surface-rollups.ts LISTING_KEYS (no listingTo targets /teams or /devices, so no new entries); Team / User detail crumbs are one segment; comments in usePeopleData, devices, users, teams reworded; /teams-users-devices now renders the Nuxt 404. Logos: no new component — layer AgentAvatar logo-only ([&>span]:hidden) adopted at 8 cells: Harnesses listing name cell (24 px), Tool detail ×3 (configured-on, harnesses, recent calls), MCP server detail configuration ledger, Sessions listing harness cell, Provider detail accounts ledger harness types pills, Account detail users ledger harness chips (14 px); qdash now has 34 [&>span]:hidden sites for the later logoOnly layer prop. Sites assigned to 04 / 11 / 12 / 16 left to them; EXP pages untouched. Columns: runs removed from Provider detail (harness-types + accounts ledgers), Account detail (users + instances ledgers; users ledger initial sort runs → tokens), Tool detail and MCP server detail harness ledgers; Provider detail models ledger harnesses count removed. Left to owners: Endpoints runs (03), Workspaces runs (15), Workspace runs (16), Skill detail runs (12), Providers listing count columns (05); listing harness-count columns kept (00.4); sessions-labelled columns kept. Provider detail's harness-types ledger keeps its instances column (not in the inventory). npm test 344; after shots in todos-2026-09-24/after/ (harnesses, teams, devices, provider, tool, mcp-server, sessions, account, tud — five ids added to todos-pages.json: harnesses, provider, mcp-server, sessions, devices). Committed qcontrol e193adb3 (sidebar, working-nav, surface-rollups, usePeopleData, devices, TUD delete, Harnesses listing, Tool / MCP server detail, Sessions listing — hunks applied onto HEAD, other sessions' rewrites left unstaged); not committed, on disk only because those files carry other sessions' uncommitted rewrites or are untracked: Provider detail, Account detail (untracked — plan 06 commits it), Team / User detail crumbs (untracked), Users / Teams listing comments (new files staged by another session).

Sep 25

todos plan 00 corrected (2026-09-25, Mark): Devices was wrongly kept as a THE FLEET sidebar entry — Devices is not Endpoints and goes entirely: /devices page deleted, AppSidebar.vue + lib/working-nav.ts entries removed (qcontrol 81d2880c); Team detail's Endpoints-ledger footer All devices → now All endpoints → (/inventory/endpoints?team=, on disk — the file is untracked). DevicesOverview.vue is now unmounted but carries another session's uncommitted edits — left for its owner; deviceRows/devicesBand stay (Team detail and tests read them).

Sep 25

todos plan 01 executed (2026-09-25): Harness (todos-2026-09-24/01-harness.md; twin record qdash cycles/c15 §todos plan 01). Decisions 01.1–01.3 taken at their defaults (Mark had not answered): versions otherwise unchanged; installs ledger keeps its expand and gains an open → column; most used model = most sessions, ties alphabetical. Meta: Most used model pair after Default models (harnessBand().topModel, provenance N sessions of M sessions · K models on hover) — claude-sonnet-4-6 on the seed. DM: Providers tile keeps its count and adds a #below DataRankedBars of API calls via shareOf (top 4; provenance Anthropic carries 100 % of 3.4k calls). Ledger: trailing open → column to /inventory/agents/detail?agentId= (shadows —); lede names it. Versions tile: Mark, 2026-09-25: Versions tile removed for now — the band is Installs · Providers · Spend (3 columns); harnessBand().versions trimmed to { latest, ranked } (the Surface Versions panel's inputs), tests rewritten; Meta pair, ledger column, Surface panel and backend untouched. Surface: Providers panel deleted (providerRows import dropped, the export stays), Teams moved to the first sibling so Users · Teams share a row. Backend (/api/harnesses?adapterId=): installs_detail[].agent_id (latest runtime identity on the install, null for shadows) and models_detail now ranked [{model, runs}] (runs desc, ties by name; model-less runs uncounted) — harness_installs_attribute_a_user_by_run_then_by_machine_owner extended. npm test 346 (344 + 2), cargo test -p qdash 76. Verified: curl on :7880 (14/14 monitored rows carry an agent_id; top model sonnet 69 runs), open → on priya-x1 lands on the Harness install page (Claude Code · priya / priya-x1), ?installId=ec899f6b… still finds and expands its row; after shot todos-2026-09-24/after/harness.png. Plan correction: the seed's priya-x1 link is 3a3e0b9f… (the same identity agents_detail uses), not the plan's f8b6bdee… — both resolve to the same page. Both seeds (:7879, :7880) restarted on the new binary. Not committed in qcontrol: all four files (harnesses/detail.vue, lib/detail-bands.ts + test, web.rs) build on other sessions' uncommitted hunks (2026-09-23 plan 2 state) — on disk only; twin record committed qcontrol 80cf800c.

Sep 25

todos plan 01 corrected (2026-09-25, Mark): Harness installs ledger — row click opens the Harness install page (shadows, no agent_id, stay inert); the open → column, the row expand (path / default model / MCP / skills / plugins / warnings / settings), the section description and the N total count removed. ?installId= landing now scrolls + rings without clicking. Decision 01.2 → its alternative (row-click, drop expand). Page file still uncommitted (sits on the 2026-09-23 plan 2 hunks).

Sep 25

todos plan 02 executed (2026-09-25): Harness install (todos-2026-09-24/02-harness-install.md; twin record qdash cycles/c15 §todos plan 02). Decisions 02.1 and 02.3 taken at their defaults (Mark had not answered): the card replaces the User / Endpoint metadata pairs (subline owner chain stays); Skills bar = fleet installs, no backend. 02.2 → none (Mark, 2026-09-25: footprint strip removed entirely — sparks, "N → M" / "mostly flat" captions and the four count tiles gone, no sessions tile; rampTo / trendLabel / footprint and the surfModels / surfMcp / surfWs / surfToolCalls computeds that only fed it deleted). Owner card (Mark, 2026-09-25: user + endpoint in one card; owner card is a reusable layer component): new layer PeopleOwnerCard (q-nuxt-layer/components/people/OwnerCard.vue, committed c3e39cd, unreleased — prod qdash needs the next layer tag) — one bordered frame, User (initials / avatar image, bold name = name or the email's local part, email, grey team pill) and Endpoint (laptop glyph, mono host, OS —) columns split by a hairline, each part a link via userTo / hostTo, only="user" for the Endpoint page (plan 04); inline-style pixel sizes (no arbitrary classes). Documented here: new people group + registry entry + _demos/PeopleOwnerCard.vue (all 12 props in adminProps; empty / user-only / typical / missing-team / overflow). Mounted under the Harness install header with ownerTeam from /api/teams (priya → Payments, not the plan's "Data"). Skills: skillsOnInstalls(skills, installIds) in qdash lib/harness-surface.ts (one id or many; rows {skill, description, installs, here, calls}, sorted here ↓ · installs ↓ · name; +3 tests) and SurfaceSkillsPanel (components/surface/SkillsPanel.vue: rows, barKey = installs, barLabel = fleet installs, caption, empty, expandCap; rows → Skill detail, all → Skills) — plans 09 and 16 reuse both. priya-x1 lists deploy 24 · review-pr 15 · commit 14 · db-migrate 7. At-rest config the Harness ledger expand used to show: this page shows version, binary fingerprint, binary path, config source and first seen (Show All tail) and live MCP servers / models from Surface — not path-level default model, configured skills beyond the panel, plugins or warnings. npm test 349 (346 + 3). Verified on :7879: both f8b6bdee… and 3a3e0b9f… resolve to priya-x1 (program id kept); runs 40, tokens.calls 24 (plan said 17); links → /users/detail?user=priya%40meridian.dev, /inventory/endpoints/detail?host=priya-x1&from=agent&agentId=…, /inventory/skills/detail?skill=deploy; after shot todos-2026-09-24/after/harness-install.png. Committed qcontrol 830e3523 (SkillsPanel); not committed: inventory/agents/detail.vue (edits sit inside the uncommitted 2026-09-23 plan 3 header) and lib/harness-surface.ts + test (untracked, earlier plans' content).

Sep 25

todos plan 03 executed (2026-09-25): Endpoints (todos-2026-09-24/03-endpoints.md; twin record qdash cycles/c15 §todos plan 03). Decisions 03.1–03.6 taken at their defaults (Mark had not answered; 03.3 — no $ helper this round). Band: Install Coverage (coverage %, fully / partial / unmonitored segment bar, M of N hosts · K installs scanned) · Endpoint Hosts (host count, OS rolldown macOS · Windows · Linux · Containers · unknown from new endpointsBand().osBars / osSegments / osKnown + exported OS_BUCKETS / normalizeOs / osLabel in lib/actor-bands.ts); Spend tile removed, third column left as the issues donut's seat (not built). Table: harnesses column lists harness-type chips with AgentAvatar logos (shadow installs dimmed) → Harness page; installs → coverage; runs → OS (— until reported). Backend: /api/endpoints rows (listing + ?host=) gain harnesses[] {adapter_id, name, vendor, monitored} and os; installations.os column added in place (db.rs add_missing_columns, no epoch bump); endpoints_window_runs_but_keep_installed_hosts extended. OS chain: column + API + test landed; the monitor producer (qevents InstallationRecord.os) and seed are follow-ups, so every seed host reads unknown. Verified headless (after/endpoints.png): 100 % · 9 / 5 / 0, Endpoint Hosts 14 all unknown, tomas-mba = Claude Code + Codex CLI chips, chen-mba a dimmed windsurf shadow; npm test 351, cargo test -p qdash 76; :7879 / :7880 restarted on the new binary. LATER: issues donut (03.4 sources), moneyShare $ sweep (Mark to assign), OS producer + seed. Committed qcontrol a0479169 (db.rs) + 51d58982 (twin record); web.rs, actor-bands.ts + test stay on disk (inside the uncommitted machines→endpoints rename) and endpoints/index.vue stays on disk (staged by another session).

Sep 25

todos plan 04 executed (2026-09-25): Endpoint (todos-2026-09-24/04-endpoint.md; twin record qdash cycles/c15 §todos plan 04). Decisions 04.1–04.5 taken at their defaults (Mark had not answered) except §C's device, per Mark's clarification: the Harnesses replacement is a DataMachine with a rolldown, not the Surface-panel rows in the image. Owner card: layer PeopleOwnerCard only="user" (label Owner (most seen), team pill from /api/teams, link → User detail) under the header at half width so it lines up with plan 02's user column — the plan's qdash-local PersonCard was superseded by plan 02's layer component. Meta: the 16 px UxAvatar override left the Users chips (04.2 default). Band (3 columns): Coverage (the Installs tile renamed, donut kept) · Harnesses — headline = harnesses with a runtime identity on the host, DataRankedBars rolldown of the top 3 by all-time sessions (Team detail's Spend device; scale="max", value at the right; label harness · user only when the host has more than one user), provenance 29 sessions · 1 user on tomas-mba (Codex CLI 16 + Claude Code 13), from new endpointBand().agents.top (shareOf) · Spend; At-risk posture tile gone. endpointBand(hostAgents, hostInst) drops the findings argument, atRisk and openRisk (+1 test: ranking, cross-foot, multi-user label, empty). No harness logo on the bars: DataRankedBars rows carry a color mark only, no icon slot. Ledger: titled Harnesses on this endpoint, no expand (the #details at-rest block is gone, 04.5), row click → rowTo() (Harness install page, or the Harness page's installId row for shadows), footer Show all N harnesses, pill Harnesses; Findings section and the /api/security fetch removed. Surface: :only omits agents and users. The plan's initialSort="lastMs" "fix" was wrong: layer DataTable sorts by column label, so "last active" stays. npm test 352. Verified headless: after shot todos-2026-09-24/after/endpoint.png; a Claude Code row click lands on /inventory/agents/detail?agentId=1bf2e087-…&from=endpoint&host=tomas-mba; no expand controls, no Findings. LATER: harness logos on DataRankedBars rows (layer per-row icon); the Surface lede still says "who was at the keyboard" (SurfaceSection copy). Not committed in qcontrol: endpoints/detail.vue (staged by another session), and lib/detail-bands.ts + test (endpointBand itself is uncommitted in HEAD, so my hunks can't be separated); twin record committed qcontrol e421afb5.

Sep 25

todos plan 05 executed (2026-09-25): Providers (todos-2026-09-24/05-providers.md; twin record qdash cycles/c15 §todos plan 05). Decisions 05.1–05.3 taken at their defaults. Table: the requests column label is now API requests (key and slot unchanged). The band has no Requests tile, so the column is the page's only "requests". Mark then queried whether the line meant a DataMachine elsewhere. Mark's follow-up applied the same rename in qcontrol ee96427f: the Provider detail Requests tile and Show-All metadata row, and the Model detail tile and metadata row. The Account detail Sessions-tile provenance (N API requests in accountBand) was renamed on disk only, because detail-bands.ts isn't separable. The instance column (key agents, label harnesses) and its slot are removed. The type column is relabelled harness types → harnesses, and the subtitle now reads "models, harnesses and accounts". providersBand() never read agents, so no helper or test changed. There is no runs column on this page; the sweep inventory (§C) belongs to 00. npm test 352 (the README's 344 predates plans 00–04). Verified headless: after shot todos-2026-09-24/after/providers.png, whose headers read provider · models · harnesses · users · accounts · API requests · tokens · share · spend · last used. Anthropic shows harnesses 2 and the tiles are unchanged. Committed qcontrol 92d7080a (page + twin record, built from the HEAD blobs through a scratch index). The page's older uncommitted DataMachineGroup band restyle and Inventory crumb hunks stay on disk.

Sep 25

todos plan 06 executed (2026-09-25): Account (todos-2026-09-24/06-account.md; twin record qdash cycles/c15 §todos plan 06). Decision 06.1 was taken at its default: the account surface scope stays in web.rs and surface-rollups.ts as a dormant scope, and /api/surface?account= still answers. Surface removed: pages/inventory/accounts/detail.vue loses the <SurfaceSection>, its sec-surface jump pill, the scope computed and the SurfaceScope import, and the header comment no longer mentions it. The page now ends after the Sessions ledger, and the pills read Users · Harnesses · Sessions. Band, attention block and ledgers are unchanged. Decision 06.2 (commit the page) was overridden by the dependency check. HEAD 92d7080a lacks four things the page needs: accountBand in lib/detail-bands.ts; the account kind in ENTITY_GLYPH (lib/entity-chip.ts); the account-detail fields on /api/accounts?account= in web.rs (provider_label, harness_types, users_detail, other_accounts, sessions_detail, reached_detail, endpoints_detail, anonymous_runs); and the layer's DataMachineGroup, which is untracked in q-nuxt-layer and not in v0.9.21. Committing the page alone would leave HEAD with a page that can't build, so it stays untracked on disk. It lands together with those four. Verified headless (todos-pages.json / account, baseline vs after): no Surface heading. npm test stays at 352, and there is no backend change. Qcontrol commit is record-only (twin §todos plan 06), and the page is not committed.

Sep 25

todos plan 07 executed (2026-09-25): Teams (todos-2026-09-24/07-teams.md; twin record qdash cycles/c15 §todos plan 07). Decisions 07.1–07.3 were taken at their defaults. Mark 2026-09-25: 03.3 carried by plan 07. Band and table: Est. spend → Spend on the tile (description "Estimated from measured tokens") and on the table column. The Assigned tile is removed together with assignedSeen / assignedPct / assignedSegments, the people prop and teamsBand's people parameter, leaving two cards in the 3-col grid. $ sweep: the layer's DataRankedBars has no prefix, unit or format prop, but it draws row.display in place of its compact number. So the fix is one helper, moneyShare() in lib/actor-bands.ts, which formats with fmtC, the house formatter ($156.22, $12.3k). It is applied to every costTop band (models, workspaces, endpoints, agents, sessions, providers) and to teamsBand.spendTop. Values, shares and totals are unchanged, and no layer prop was needed. Pages that now read $ on their ranked spend rows: Teams (Spend tile), Providers (Spend), Models (Spend), Repos & Workspaces (Spend) and Sessions (the cost rows under Tokens). Team detail already formatted its rows inline. Every spend table cell (fmtC), tile value ($ slot or unit) and provenance string (est. $331.44) already carried $. npm test 353 (+1 moneyShare). Verified headless: after/{teams,providers,workspaces,sessions}.png. Teams reads Payments $156.22 · Frontend $69.86 · Data $63.06, the same as its table cells. The Models listing has no program entry and was checked live through :3030 ($899.97 · $723.93 · $149.53). Qcontrol 7480b1e0 carries the $ helper and tests. The Teams page hunks stay on disk: TeamsOverview.vue, pages/teams/index.vue (staged by another session) and the teamsBand Assigned removal in people-rollups + test. HEAD's TeamsOverview predates the uncommitted band restyle, and HEAD has no Teams page.

Sep 25

todos plan 08 executed (2026-09-25): Users (todos-2026-09-24/08-users.md; twin record qdash cycles/c15 §todos plan 08). Decisions 08.1–08.3 were taken at their defaults: "Users using AI agents" in sentence case, "Users needing Attention" left as is, and Team detail's Active tile left as is. Band: User Coverage → Coverage, with its projected badge and "N seen · M known" kept. Active → Activity, with the description line "Users using AI agents" under the title. Mark, 2026-09-25: identity-integration line removed. That is the "○ Okta not connected · projected · N people seen by the sensor" row under the band, plus its identityIntegrations computed. PROJECTED's okta entry stays in people-rollups. Part B, Mark 2026-09-25: DataListingBar + key dropdown on every listing (c95 wiring). Users: the roster keeps UxTableList, because rows pre-open by ref from ?user= and it has its own cross-field search, which DataTable doesn't expose. It gains a column model instead: a catalog from its cols map with Person locked, v-if per header and cell, and colspans that follow the visible count. Hiding the sorted column drops back to the roster order. The strip is DataListingBar (Team; Provider has no column). Teams: usePeopleData({ register: 'teams' }) registers team, the page filters visibleTeams, and TeamsOverview takes a quickFilter prop with the strip in DataTable #toolbar. ?team= is now the table's filter, no longer forwarded to Team detail; ?user= still forwards. Endpoints: the strip starts on Team, and the endpoint column (whose cell shows users · team) answers user/team via filterKey. Providers: Provider (label column → filterKey: 'provider'). Models: Provider. Repos & Workspaces: users/hosts annotated user/host, but both carry more values than the strip seats, so the toolbar holds a standalone UxColumnPicker until a short key has a column (plan 15's team key + teams column switches it to the bar by itself). Fleet index: the Harnesses strip moves to useQuickFilter (posture only, no caret). useQuickFilter gains a cap: a key with more than QUICK_FILTER_MAX_OPTIONS (8) values stays off the strip. The segmented bar has no overflow handling, and fourteen hostnames pushed its key segment off the page. The seven c95 strips are unchanged: their carets and values were checked live. Verified live through :3030 on Users, Teams, Endpoints, Providers, Models, Workspaces and Fleet: the bar renders, Columns hides a column and the table follows, picking a value filters and writes the URL, and sorting by a column then hiding it falls back. npm test 353. After shots are after/users.png, plus after/{endpoints,providers,models,workspaces,teams,fleet}.png published -p08; the program gains a models entry. Qcontrol b36a026e carries Part A only, applied to HEAD's band. The rest is on disk: Part B depends on the untracked useQuickFilter and the unreleased layer DataListingBar, and pages/{teams,users}/index.vue and inventory/endpoints/index.vue are staged by another session.

Sep 25

todos plan 09 executed (2026-09-25): User (todos-2026-09-24/09-user.md; twin record qdash cycles/c15 §todos plan 09). Decisions 09.1–09.3 were taken at their defaults: adjacent "Devices" words on other pages are left, shadow-install skills are counted, and the Skills panel header is harnesses. Mark, 2026-09-25: Devices → Endpoints on the tile and table titles (User detail + Team detail), and the tile says Endpoints throughout. Endpoints: on User detail, the band tile, the section heading and the jump pill now read Endpoints; the keys (band.devices, sec-devices, PeopleDeviceCard) stay. userBand()'s tile strings already said endpoints, so detail-bands is unchanged. On Team detail, the section heading and pill read Endpoints. Team detail has no Devices tile, and its Devices metadata pair, device column and lede are left. Surface: :only is models · mcp_servers · workspaces · tools · sensitive_files · egress, so Harnesses and Endpoints are gone. Skills: plan 02's SurfaceSkillsPanel sits in the section's slot over skillsOnInstalls(/api/skills, monitored installationIds + detected installIds), with the bar on here and the header harnesses. PersonDetectedInstall gains installId, and its test asserts it. Verified live through :3030 (priya, 30d): Endpoints 1 · Harnesses 4 · Spend; pills Endpoints · Sessions · Surface · Attention; Surface is Models, MCP Servers, Repos & Workspaces, Tools and Skills 4 distinct (deploy 2 · review-pr 2 · commit 1 · db-migrate 1), with no Harnesses or Endpoints panel. The rows open /inventory/skills/detail?skill=… and all → opens /inventory/skills. npm test 353. After shot after/user.png, published as c92-todos0924-user-{before,after}. Qcontrol 3fed378a carries the people-rollups installId hunks and the twin record. pages/users/detail.vue and pages/teams/detail.vue stay on disk, because they are untracked and HEAD lacks userBand/teamBand, harness-surface.ts, SurfaceSection's slot and PeopleDeviceCard.

Sep 25

todos plan 10 executed (2026-09-25): Model (todos-2026-09-24/10-model.md; twin record qdash cycles/c15 §todos plan 10). Decisions 10.1–10.5 were taken at their defaults: only the Default-on tile goes (the "Configured as default" ledger stays), the chip strip is dropped, the type rows come from a client rollup, there is no instance-count column, and the header's "Harnesses 22" is left and flagged. Mark, 2026-09-25: table column reads API requests, matching the tile (the coordinator had already renamed the tile and its Show-All metadata row in qdash ee96427f). Band: API requests · Tokens · Spend on one row (md:grid-cols-3); modelBand() loses defaultOn, and its test becomes "rounds spend to cents". Harnesses: the "Harness types" chip strip is gone, and the instance ledger (22 rows, capped at 10, row → Harness install) is now one row per harness type. modelHarnessRows() in lib/detail-bands.ts rolls up agents_detail into harness · users · endpoints · sessions · API requests · tokens · spend · last active, with the AgentAvatar logo at 14 px. Rows open Harness detail and the footer reads All harnesses → /inventory/harnesses. The rollup has four new vitest cases. Surface: the section, its pill and the SurfaceScope/listingTo import are removed, so the pills are Harnesses · Default on. Verified live through :3030 (claude-sonnet-4-6): claude-cli 14 · 14 · 252 · 2,019 · 72.7M · $1412.84, cursor-cli 5 · 5 · 77 · 630 · 19.7M · $390.91, claude-desktop 3 · 3 · 21 · 205 · 7.62M · $152.49. The cross-foot holds: API requests Σ 2,854 = the tile (2.9k) and tokens Σ 99,988,633 = the Tokens tile (100M). The plan's 1,242 / 45.8M came from an earlier seed; both seeds now serve 2,854 / 99,988,633. Configured as default still lists 22 installs. npm test 353 → 357. After shot after/model.png, published as c92-todos0924-model-{before,after}. Qcontrol 7d697cc5 (code, built on HEAD blobs) and 5de0e37f (twin record); the page's and lib's foreign hunks (the DataMachineGroup band, harness-rename wording, other bands) stay on disk.

Sep 25

todos plan 11 executed (2026-09-25): Skills (todos-2026-09-24/11-skills.md; twin record qdash cycles/c15 §todos plan 11). Mark, 2026-09-25: both tiles kept, each gains a top-10 rolldown. This overrides the plan's §A reading, "remove Invocations, add two machines". Decisions 11.1–11.5 were otherwise taken at their defaults. Band: skillsBand() caps callsTop at 10 (it was 3) and adds installsTop, the top 10 by installs. Each of its bars is the skill's coverage of the scanned fleet rather than a share of the sum, because installs aren't exclusive (11.2). Its tooltip reads "on N of M scanned installs". The Installs tile keeps its title, headline and provenance, and its % bar gives way to a #below DataRankedBars (11.1). The Invocations tile keeps its title, headline and real-zero provenance and gains an unconditional #below DataRankedBars, which draws an honest em-dash while every call count is zero, with no fallback to installs (11.5). Table: the columns are skill · harnesses · source · installs · invocations · last invoked · first registered. definitions, people and hosts are gone (11.3), and harness types became harnesses (11.4). The harnesses cell draws logo-only AgentAvatar :size="14" marks. None of the removed columns carried a filterKey, so the strip's Harness key is unchanged. Verified live through :3030: Installs 25 ("64 % of 39 scanned installs"), with rolldown deploy 24 (62 %) · review-pr 15 · commit 14 · db-migrate 7 · incident-runbook 4 · storybook 4 · dbt-model 3. Invocations 0 with an em-dash. deploy and review-pr show the Claude + Codex marks and storybook shows Claude + Cursor. The harness filter cursor-cli narrows the page to storybook (Installs 4, one bar), and the Columns picker shows 7 of 7. npm test 357 → 358. After shot after/skills.png, published as c92-todos0924-skills-{before,after}. Qcontrol 5027b042 holds the band, the test, the page's table hunks (logo cell, two columns out) and the twin record, all built on HEAD blobs. The tile rolldowns, the definitions removal and the label rename stay on disk: they sit inside the uncommitted DataMachineGroup band and c95 listing strip, and they need the unreleased layer's DataMachine #below and DataRankedBars thin / valuePosition.

Sep 25

todos plan 11 follow-up (2026-09-25, Mark): Skills tile selector. Mark asked for "an optional slot to the DataMachine component to the right of the title" holding a simple selector over all three rankings, and for the configured info to go. Layer (f783613 + 640fb24, unreleased; pending 0.9.22): DataMachine #title-right lays the title row out as title · slot, justify-between, baseline-aligned; clicks inside it don't reach to; in a card too narrow for both it wraps under the title, right-aligned and capped at the card width; unused it renders the unchanged title div. New UxSelectInline: the current label + a small primary triangle caret over an invisible native <select> (options { value, label }[], v-model, ariaLabel, keyboard-only focus ring; a long label truncates). Nothing was reused: UxSimpleSelect's grey chevron ships to many consumers, and the FilterTriggerBar key segment isn't separable. qdash: the Skills tile loses its "across N harnesses · N configured, never called" provenance and the configured/called DataSegmentBar. Its title row carries UxSelectInline People (default) · Installs · Invocations (Mark, 2026-09-25: short picker labels (People default); the description swaps per view to say what the rolldown means; this replaced an interim "Total People Using" label), which switches a #below DataRankedBars (top 10, valuePosition="right" thin :labelWidth="140", scale="max" for Invocations only). skillsBand() gains usersTop: each bar is the skill's people of peopleTotal, the distinct identified people with an agent on any scanned install (peopleOnScannedInstalls over /api/agents?period=all, proxy-only excluded; 14 today). It drops idle / sourceSegments, which nothing else read. The static description "Called at runtime or configured" is gone; the description now says what the rolldown means: People "People with each skill on at least one of their installs"; Installs "Harness installs carrying each skill, of the N scanned" (N = band.installsTotal, 39 today, never typed by hand); Invocations "Runtime calls per skill in this period". Mark, 2026-09-25: the headline takes unit="skills" and reads "7skills" — DataMetricValue's dimmed suffix sits flush, as req / requests do elsewhere; on one line at every width, beside the selector. Verified on :3030: People (the default) reads commit 14 · deploy 14 · review-pr 8 · db-migrate 7 · incident-runbook 4 · dbt-model 3 · storybook 3, tooltips "deploy: 14 people using"; Installs puts deploy 24 on top (deploy 24 · review-pr 15 · commit 14 · db-migrate 7 · incident-runbook 4 · storybook 4 · dbt-model 3), so the two orders differ at the top (commit ties deploy on people) and at the tail; Invocations shows the em-dash. Tab + typeahead switch it with a keyboard-only ring; the Teams / Providers / Endpoint detail DataMachines render the unchanged title div; the console is clean. npm test 358 → 361. Design docs (on disk until the layer releases): two #title-right scenarios in the DataMachine demo, the slot in its registry entry, and a UxSelectInline registry entry + adminProps demo. Qcontrol 22e67c7a + fe7119bd + f1c31efd hold the band + tests; the page hunk stays on disk (foreign DataMachineGroup restyle + unreleased layer). Mark, 2026-09-25: no headline; short per-view description + provenance explain the rolldown. This supersedes the per-view descriptions and unit="skills" above. The Skills tile is device-only: no val, and the rolldown moves to #right, which owns the row, so no empty value row opens a gap (no layer change). People: "Total people with this skill" / "of 14 people on scanned installs". Installs: "Installs with this skill" / "of 39 scanned installs". Invocations: "Calls to this skill" / "none reported yet by any harness" ("N calls this period" once any exist). Every number comes from the band (peopleTotal, installsTotal, calls). The separate Installs tile drops its headline the same way. It keeps "With at least one of these skills" and its rolldown, and its provenance stands alone: "25 of 39 scanned installs carry a skill" (carrying, installsTotal). Mark, 2026-09-25 (later): the Invocations tile drops its headline too, so none of the three tiles has one. It is device-only with the rolldown in #right. With calls, its provenance carries the count on its own: "N calls · M of K skills exercised", plus " · D denied" when there are denials (calls, exercised, skills, denied). At zero it keeps the honest line "no harness emits runtime skill attribution yet — a real zero" over the em-dash rolldown. Nothing else wraps at 1440 or 1100; that honest-zero line wraps to two lines at 1100, as it did before. After shots c92-todos0924-skills-after-p11b (interim) and -p11c (final).

Sep 25

todos plan 11 follow-up 2 (2026-09-25, Mark): Skills tile — layout A. Mark, 2026-09-25: layout A — Skills picker Team (default) · People · Installs · Harness · Drift; Installs tile removed; Invocations only as its own tile. Band: skillsBand() takes an opts bag { teamIndex, harnessNames }. skillsTeamIndex(agents, teams) maps install id → the teams of the identified people with an agent on it (/api/agents?period=all × /api/teams; a person on no team → unassigned, proxy-only never counts). teamsTop counts each team's distinct skills; each bar is out of all skills, because skills aren't exclusive across teams (tooltip "Data: 4 of 7 skills"). unassigned ranks only when it has skills. harnessesTop counts the skills per harness type, each bar out of all skills, labelled with the /api/harnesses name. driftTop lists skills with definitions > 1, scaled to the most-drifted (tooltip "deploy: 2 definitions across 24 installs"), and drifting counts them. Page: the Installs tile is gone, so the grid shows Skills · Invocations with the third column empty. The Invocations tile is unchanged. Team and harness labels drop the mono face. Copy: Team "Skills installed per team" / "of 7 skills · 4 teams"; Harness "Skills per harness" / "of 7 skills"; Drift "Skills whose installs disagree" / "1 of 7 skills has more than one definition" (with none, an em-dash over "every install carries the same definition"). People and Installs are unchanged. Not done: (1) Harness names read "Codex CLI" / "Cursor CLI" rather than the expected "Codex" / "Cursor": the harness cell's resolver (layer components/agent/registry.js resolveAgent) isn't exported, so matching it needs a layer export. (2) No harness logos: DataRankedBars has no leading-icon slot. (3) Drift rows don't link to Skill detail: the device has no row link. Verified on :3030: Team (default) Data 4 · Payments 4 · Platform 4 · Frontend 3, with no unassigned row. People commit 14 · deploy 14 · review-pr 8 · db-migrate 7 · incident-runbook 4 · dbt-model 3 · storybook 3. Installs deploy 24 · review-pr 15 · commit 14 · db-migrate 7 · incident-runbook 4 · storybook 4 · dbt-model 3. Harness Claude Code 7 · Codex CLI 2 · Cursor CLI 1. Drift deploy 2. With cursor-cli on the strip, every view recomputes: Team Frontend 1 ("of 1 skill · 4 teams"), People storybook 3, Installs storybook 4, Harness Claude Code 1 · Cursor CLI 1 (the storybook row carries both), and Drift an em-dash over "every install carries the same definition". Tab + typeahead switch every view with the keyboard-only ring, and the console is clean. npm test went from 361 to 366. LATER: a Risk view for skills that bundle executable scripts or widen allowed-tools, which needs a backend field on /api/skills listing rows (today only Skill detail sees files and frontmatter). Qcontrol abc61c61 holds the band + tests and aebf636e the twin record; the page hunk stays on disk (foreign DataMachineGroup restyle + unreleased layer). After shot c92-todos0924-skills-after-p11d.

Sep 25

todos plan 11 correction (2026-09-25, Mark): Installs back out of the Skills picker — moving it in was a miscommunication. Installs is its own tile again (no headline; description "With at least one of these skills"; provenance "25 of 39 scanned installs carry a skill" from band.carrying / installsTotal; rolldown installsTop), so the band is Skills · Installs · Invocations; the Skills picker is Team (default) · People · Harness · Drift. Page on disk only (same reasons as plan 11). Verified on :3030 unfiltered.

Sep 25

todos plan 13 executed (2026-09-25): Tools (todos-2026-09-24/13-tools.md; twin record qdash cycles/c15 §todos plan 13). Decisions 13.1–13.2 were taken at their defaults. Tiles: Tools → Tool type. Its headline is still the tool count (26), with the kind segment bar as the device. Calls → Invocations, with its headline kept (1.4k over 30d, 330 over 7d). The Outcome description now reads "weighted by invocations". toolsBand() is unchanged. Words: every rendered "call(s)" on the page is now "invocations" (subtitle, tile, empty state, column header). Keys stay calls. initialSort moves to "invocations", because DataTable matches initialSort against labels; the plan kept the key, which would have dropped the default sort. Table: the denied and success columns merge into one outcome column (success_pct, 160px). It shows the percent, then an N failed pill in neutral and an N denied pill in warning, nonzero parts only. Skill rows show —. The column sorts by the percent, and the denied count is no longer a sort target. On :3030 over 30d, Write shows 100% 8 denied and Bash shows 100% 6 denied; the seed has no failed invocations. Also checked: outcome sorts both ways (skills sink), and the Columns picker lists outcome (7 of 7). Hiding outcome falls back to the invocations sort. The only "call" text left on the page is a skill description ("on-call"). The after shot (7d default) shows no pills, since that window has 0 denied. npm test 366. LATER: HEAD's Skills listing opens in API order (initialSort="installs" against a HEAD label of "configured on"; the disk version is fine); Sessions still says "denied calls". Committed qcontrol f7d94625 (HEAD-based page hunks; the equivalent edits sit on disk inside foreign code) + 95b3650c (twin). Atlas pair c92-todos0924-tools-{before,after}(-full).png.

Sep 25

todos plan 14 executed (2026-09-25): Tool (todos-2026-09-24/14-tool.md; twin record qdash cycles/c15 §todos plan 14). Decisions 14.1–14.2 were taken at their defaults: the header's Denied cell stays, and no /controls link replaces the tile. Surface: the SurfaceSection and its jump pill are gone, so the pills read Harnesses · Recent invocations. The lib's 'tool' scope stays, now unconsumed. Band: the Denied tile (the page's only /controls door) is removed and the grid narrows to three: Invocations · Success · Harnesses. Denied lives on in the header cell (red when > 0), the donut's denied slice and the per-call decision pills. Words: every rendered "call(s)" now reads "invocation(s)", including the tile, the empty states, the lede, the Recent invocations h2, the footer and the ledger column (label: 'invocations', 100px). initialSort moves to "invocations" (it matches labels). toolBand() provenances and the one test assertion follow; keys stay calls. Plan 00's state is confirmed: logos on the harness cells, no runs column. Verified live through :3030. The detail request carries no period, so the numbers are all-time. Glob: Denied 0 · Invocations 298 ("by 31 harnesses · avg 1953 ms") · Success 100 % · Harnesses 31, with the ledger sorted 39 → 11. Write: Denied 16 in red · 246 · 100 % ("judged 230 · 230 ok · 0 failed") with an orange denied slice · 34, and two denied pills (config, user) past the first 10 recent rows. The console is clean. npm test 366. LATER: the skill branch is unreachable (redirect), and band.denied.provenance is no longer rendered. Committed qcontrol f0f78d8e (HEAD-based page, lib and test hunks; the equivalent edits sit on disk inside the foreign harness-rename hunks) + 1d81822a (twin). Atlas c92-todos0924-tool-before(-full).png + c92-todos0924-tool-after-p14(-full).png (plan 00 had published tool-after).

Sep 25

todos plan 15 executed (2026-09-25): Workspaces (todos-2026-09-24/15-workspaces.md; twin record qdash cycles/c15 §todos plan 15). Decisions 15.1–15.3 were taken at their defaults: a top-3 Tokens rolldown, name labels kept although three payments-core rows collide, and the team key added. Band: the Runs tile becomes Tokens. It takes the Spend tile's shape: a Σ tokens headline, the provenance top 3 = N % of tokens, and DataRankedBars below it with Spend's on-disk props. workspacesBand(): runs → tokens, sharedRunSegments out, tokensTop beside costTop. The Runs tile's one other fact, shared, moves into the Workspaces tile's provenance (… · N shared · by last activity). Table: users, hosts and runs are out; teams and tokens (fmtN mono) are in. Teams come from the Endpoints listing's user → team join (teamByUser over /api/teams, a set per row). The team key is registered (suggestions + matcher), while user / host stay in the Filter bar. Strip: the teams column carries filterKey: 'team' and useQuickFilter starts on team, so the page moves from plan 08's standalone UxColumnPicker to the full DataListingBar (Team · All · Data · Frontend · Payments · Platform · Columns). Verified live through :3030 against the :7879 seed. Default Past 7 days: Workspaces 14 ("0 with a git remote · 0 shared"), Tokens 24m = curl Σ 23,954,170, with the rolldown etl-pipelines 3.3M · payments-core 3M · web-checkout 2.5M ("top 3 = 37 %"), and Spend $331. At 30d: Tokens 122m = curl Σ 122,393,771, with payments-core 19.9M · etl-pipelines 13.5M · payments-core 12M (37 %). Headers kind · workspace · harnesses · teams · tokens · spend · last active, sorted by last active descending. team:Payments leaves 4 rows (tomas / marcus / elena payments-core, priya payments-migration) and Tokens 8.1m, then was cleared. The Columns picker shows 7 of 7 with workspace locked, and hiding and restoring tokens works. The console is clean and the global filter was left {}. npm test 366 (unchanged; the workspacesBand block was rewritten in place). Committed qcontrol 21cdbaae (HEAD-based page, lib and test hunks; the Tokens tile uses HEAD's Spend props there) + 417c8dec (twin). On disk only: the listing-strip half (useQuickFilter(gf, 'team'), the #toolbar strip; useQuickFilter is untracked and DataListingBar unreleased), plus the on-disk Tokens-tile props that sit on the foreign Spend restyle. Atlas c92-todos0924-workspaces-before(-full).png + c92-todos0924-workspaces-after(-full).png.

Sep 25

todos plan 16 executed (2026-09-25): Workspace (todos-2026-09-24/16-workspace.md; twin record qdash cycles/c15 §todos plan 16). Decisions 16.1–16.5 were taken at their defaults. The Runs tile is out, so the band is Harnesses · Tokens · Spend in three columns. The Harnesses table became Users: new lib/workspace-rollups.ts userRows() rolls agents_detail up per person with the team from /api/teams, the columns are user · team · harnesses · sessions · tokens · spend · last active, and a row click opens User detail. Recent runs is now Sessions (latest N), and "no runs yet" now reads sessions. The Surface lost its Endpoints axis and gained plan 02's SurfaceSkillsPanel. There is no backend change: the plan's skills[] was replaced by a client join (workspaceInstallIds() matches agents_detail system_id@host → /api/installations, then skillsOnInstalls()), which is equivalent on the seed because it has no duplicate adapter-on-host installs. Verified via :3030 (payments-core, all-time): the Users row tomas · Payments · 2 · 29 · 31.2M · $389.55 cross-foots with the curl Σ, and Skills reads deploy 2 · review-pr 2 · commit 1 · db-migrate 1. npm test 372. LATER: the shared Surface panels still say Calls, and the Surface lede still names endpoints. After shots: c92-todos0924-workspace-*. Committed qdash 8aac2792 + 47fdd603 (twin) as HEAD-based hunks; the Skills panel stays on disk because HEAD lacks skillsOnInstalls and SurfaceSection's slot.

Sep 25

todos plan 12 executed (2026-09-25): Skill (todos-2026-09-24/12-skill.md; twin record qdash cycles/c15 §todos plan 12). Mark, 2026-09-25: VS Code-style — file tray left, small editor right (tabs, Preview/Source with line numbers); UxFileTree + editor frame in the layer, unreleased. Decisions 12.1, 12.2, 12.3 and 12.5 were taken at their defaults; 12.4 became two layer components plus a UxCodeBlock prop, with no release. The Definition section is one UxEditorFrame. Its tray is a UxFileTree of the skill directory, with SKILL.md first, ⚙ for executables, ○ for bundled-only files and a footer caption. The editor shows one tab and a Preview / Source UxTabGroup in #toolbar. Preview shows the evidence line, frontmatter pills (drifted keys warning-tinted), dashed decoded pills and the lib/skill-markdown body. Source is UxCodeBlock lineNumbers. Other files open an inventory card that gives size · lines · mode, "Referenced from SKILL.md line N — body line M" and "Contents not captured" once. The Bundle section is gone. Surface is out; its five Reach tiles now sit under the editor. The band is now Installs 24 · Invocations 0: skillBand() drops people and candidates.provenance, with two test assertions removed. Verified via :3030 (7d): deploy canonical has preflight.sh at 1.3 KB · 52 lines · executable · line 12 / body line 7. The drift definition 3b2e6f7c adds force-unlock.sh ⚙ ○, the Rollback section and a warning-tinted allowed-tools pill. commit has a one-row tree. Tray keyboard works, and there are no Bundle or Surface headings. The console is clean. npm test 372. The design site documents UxFileTree (empty / single / typical / adornments / overflow) and UxEditorFrame (full composition, minimal, typical, long tab name, #tab), and adds a lineNumbers scenario to UxCodeBlock. LATER: line highlight for "show in source", multiple tabs, and file contents (12.3). After shots: c92-todos0924-skill-*. Committed layer c28b37c (local main, unpushed) and qdash 0f55fd7a (twin). The page and skillBand hunks stay on disk because they sit on the uncommitted skill-definition build and need the unreleased layer.

Sep 25

todos plan 12 follow-up (2026-09-25, Mark): "In the skill definition section, can we have a syntax highlighter for .md files?" The layer's UxCodeBlock gains an optional lang prop. It uses highlight.js core on a private instance with four grammars: markdown/md, yaml/yml, bash/sh/shell/zsh and json. highlight.js ^11.12.0 is now a layer dependency; the lockfile gained only that package. For markdown, a leading --- frontmatter block is highlighted as YAML, because hljs would read its last line as a setext heading. Fenced blocks are highlighted in their info-string language, and left plain when the language isn't registered. An unknown lang renders escaped plain text. Without lang the render is unchanged: the design demo's SSR body was byte-identical before and after the layer edit, apart from nondeterministic icon ids. The .hljs-* classes map to tokens in an unscoped <style> anchored under .ux-codeblock-hl, so the no-lang DOM gains no scope attribute:

Sep 24

trigger-bar (2026-09-24 → 25): Layer FilterTriggerBar restyled to a screenshot from Mark, executed directly (trigger-bar-prompt.md + trigger-bar-reference.png, no plan). One bordered bar (rounded-8, py-1): a key segment whose stretched-SVG chevron points into single-select value segments — "All" (was "View All") plus one per option, hairline-divided; the endcap image and "Add Filter" label are gone, a label prop covers the screenshot's "Global Filter :" lead-in, and the key caret + dropdown appear only when there is more than one key (every qdash consumer passes one). The component owns its alignment — full-width, right-aligned — so all eight qdash consumers sit over their table's right edge with no page edits (Sessions' flex-row wrapper had held it left). A follow-up cruft pass: the colour classes gathered into one TONE role map (lineBorder … focusRing) as the first step toward tokens — still off-token by Mark's call, legacy brand blue at opacity + stock slate-500, and the comment says so; inset keyboard-focus rings (the bar's overflow-hidden clipped outset ones, and the invisible key <select> never showed one); the first segment's padding derived from the chevron overlap; orphaned assets/svgs/filter/bar.svg removed; comments on every atypical choice. Design site: registry entry rewritten, demo gains a label control and a lead-in scenario. A mid-thread "move it higher" instruction was meant for another session — its qdash edits were reverted in full, so qdash has no net change. Verified in the browser on qdash :3030 (both themes) and the design demo. Not done: layer release — consumers see it only through NUXT_LOCAL_LAYER.

Sep 24

todos plan 1 executed (2026-09-24): Harnesses listing (todos-2026-09-23/01-harnesses-listing.md; twin record qdash cycles/c15 §todos plan 1). qdash /inventory/harnesses: title "Harness types" → Harnesses with full reach (Working-nav label, detail-page crumb and empty text, endpoint detail's "All harnesses →", surface captions, posture tooltip; left as "harness type" only where a runtime-harness column sits beside it — Providers, Skills, Accounts, Models pages, the Fleet index sentence); Installs card before Work; columns now harness · installs · endpoints · coverage · providers · sessions · spend (versions, configured, harnesses count gone; hosts key relabelled endpoints; sessions = the API's in-window runs). Backend web.rs: providers on every /api/harnesses row — [{ provider, label, calls }] most calls first, deduped in-window responses per run bucketed by wire provider (run_provider_calls_in / providers_of_runs, same dedup group as run_cost_map_in), shared with plan 2; test extended (cargo test 76). Rendered as ◈ pills linking to the provider page (no logo assets exist). Mark's note on the empty state became a layer component: FilterNoMatches (components/filter/NoMatches.vue — "No {subject} match the current filter." + a Clear filter button, @clear to the consumer) plus a #empty slot on DataTable inside its own empty chrome; documented here (registry entry in the Filter group, adminProps demo with minimal / typical-in-a-DataTable / overflow, DataTable demo gains a filtered-to-nothing scenario). Found and fixed while verifying headlessly: two gf.clear() calls in one tick collapse to one (the batched URL write re-reads the stale query), so the page clears with a single keyValFilters = [] write. Not yet a layer release — qdash's :3030 runs the local layer; ship needs a tag. LATER: approved / unapproved (no per-adapter approval field today).

Sep 24

todos naming correction (2026-09-24, plans 2–4 re-pointed before execution): the first draft had the two harness detail pages inverted — Mark's shorthand header "Harness Details (becomes Harness Install Detail)" sat above the type page's list, so plan 2 named harnesses/detail.vue (Claude Code across the fleet) "Harness Install Detail" and plan 3 left agents/detail.vue (Claude Code on one person's machine) as "Harness detail"; plan 1's executor had already written the type page's Working-nav label as Harness install detail. Mark's ruling: hierarchy is Harness (type, adapterId) → Harness install (instance, agentId; the runtime identity is keyed harness kind × user, web.rs:1402, host + installation_id attached) → Session; the type page is Harness Detail, the instance page Harness Install Detail, nav labels swap. Consequence for decision 8: an endpoint-detail row's primary link is the instance page when monitored, and only shadow installs (no identity, no page) fall back to the type page's ledger row via plan 2 §A.1's ?installId=; the secondary "runtime →" chip is gone. README (note, Vocabulary, decisions 3 + 8), plan 2 §A/§A.1, plan 3 new §A.0, plan 4 §C/§D/Verify rewritten; plan file names kept (02-harness-install-detail.md is still the type page) so briefed executors' links hold — titles are authoritative. Nothing in qdash changed in this thread; plan 2 carries the one-line label revert.

Sep 24

todos plan 2 executed (2026-09-24): Harness Detail, the type page (todos-2026-09-23/02-harness-install-detail.md; twin record qdash cycles/c15 §todos plan 2). Working-nav labels swapped to Harness detail (type) / Harness install detail (instance), fixing what plan 1 had set. Configured metadata out; band Installs · Providers · Versions (most-used version as the headline, a string in #right since DataMetricValue only formats numbers) · Spend; ledger "Harness installs" with columns user · endpoint · version · sessions · tokens · most used model · status (monitored / unmonitored) · spend, path and default model moved into the expand. Backend: per-install runs, top_model, monitored (the listing's predicate per row, so it cross-foots with the donut). Surface drops Endpoints and adds Versions (older pill) / Skills / Providers / Teams from lib/harness-surface.ts, in the same grid via a new default slot on qdash SurfaceSection. ?installId= lands on, expands and rings one ledger row (plan 4's shadow-row target). cargo test 76, npm test 337, verified headless. Not committed.

Sep 24

todos plan 3 executed (2026-09-24): Harness Install Detail (todos-2026-09-23/03-harness-detail.md; twin record qdash cycles/c15 §todos plan 3). qdash inventory/agents/detail.vue only, no backend: empty/not-found text says "harness install"; Security Score cell (+ DataSmile, sec) gone, Spend alone; subline leads with the owner chain user / ▭ endpoint (both linked) ahead of vendor / kind / state (decision 7); metadata = User (now a link) · Endpoint (laptop glyph) · OS (—, no field anywhere — decision 6) · Last updated, Credential / Terminal / Host-OS-user dropped; Show-All tail keeps Organization · Version · Binary fingerprint · Binary path · Config source · First seen, minus Account / Model / Working dir / PID (decision 5); Sessions above Surface (pills swapped); Surface only = models, MCP, workspaces, tools, sensitive files, egress (no Users / Endpoints), footprint strip 5 → 4 (endpoints out). Working-nav labels were already Harness install detail / Harness detail when this ran. Inbound link wording left for a later sweep (AgentCard.vue ×2, AgentExpandDetail.vue, endpoints/detail.vue crumb). Verified headless against :7880 (chen-mba Claude Code): layout, both owner links, Show-All tail, console clean; npm test 337. Not committed (the file also carries the uncommitted harness-rename edits).

Sep 24

todos plan 4 executed (2026-09-24): Endpoint detail (todos-2026-09-23/04-endpoint-detail.md; twin record qdash cycles/c15 §todos plan 4). qdash inventory/endpoints/detail.vue, no backend: the Harnesses and Installs ledgers merged into one Harness installs on this endpoint table — one row per scanned install with its runtime identity joined on installation_id (lib/endpoint-rollups.ts installRows, + agents with no scanned install appended), columns harness · user · version · sessions · tokens · cost · last active · status (monitored / unmonitored) · posture; path / configured / first seen moved into the expand. rowTo links runtime rows to Harness Install Detail (from=endpoint crumb) and shadow rows to their ledger row on Harness Detail (installId, plan 2) — the name cell carries the link because DataTable ignores onRow on expandable rows (row click still expands). Instrumented-but-never-ran installs read no runs yet rather than shadow. from=agent crumb now Harness install. Verified headless (chen-mba, felix-tower, both link branches); npm test 344. Not committed.

Sep 24

band-polish (2026-09-24 → 25): A conversational polish pass over the qdash bands and the layer devices under them (band-polish-prompt.md — 82 turns verbatim — / band-polish-plan.md). Layer (unreleased): DataMachineGroup (new) aligns a band's value rows on a 4-row CSS subgrid — missing or wrapped descriptions no longer drift siblings, empty rows collapse, the body is one cell; DataMachine gains #below, a filling #right, an italic hairline footer; DataRankedBars gains scale, row marks + legend, valuePosition, thin and solid bars; DataSegmentBar / DataRankedBars fill their container; UxPercentBar gains solid / titlePosition / thin / titleSize; DataMetricValue unit="$"; DataDonutChart align + one-line legend items; the categorical palette → black · slate · grey from Mark's reference (fails the validator's slate↔grey separation — legend + titles carry identity, recorded); UxPill outlined for every tone + size; metadata hairlines in ActorHeader; the global Filter restyled to the reference (Config → Filter). Arbitrary-value Tailwind introduced mid-thread was back-fixed to inline/scoped CSS. qdash: every band in a DataMachineGroup; ranked lists thin with right-hand values, Spend / Tokens / Coverage / Tools-exposed in #below; three hand-built row sets replaced by DataRankedBars; descriptions audited (timeframe removed — the pill owns it; redundant ones dropped; filler → caveats); identity segments on the default slots, Flagged denied → error; "Harness Inventory" → "Inventory", "Tools & Skills" → "Tools"; Endpoints shows the host's top model, from /api/endpoints now ordering models by runs (web.rs; cargo test 76; :7879 rebuilt + restarted). npm test 331/331. Captures c92-polish-* (13, programs scripts/shot-programs/c92-polish-{qdash,design}.json). Not done: layer release; FilterTriggerBar (c95); MCP detail vs listing Source pill tone; nothing committed.

Sep 24

todos-2026-09-24 planned (2026-09-25, not executed): Mark's 2026-09-24 product-review notes read straight from the Logseq journal (core/journals/2026_09_24.md; no sheet file — the block is quoted verbatim in the README) and turned into 17 per-page plans under todos-2026-09-24/ by the new /todos skill (c94): README (verified shared ground incl. a dead :7879 seed found and restarted, seed ids per route, wave order, 62 decisions with defaults, Voices, Notes) + 00-sweep (TUD page removal, harness logos via the layer's existing AgentAvatar registry — no new component, runs/harness-count column inventory with owners) + 01-harness … 16-workspace, written by seven parallel agents grouped listing+detail, every edit row verified against the live feat/new-pages files. Backend needed by three plans only: 01 (installs_detail[].agent_id, ranked models_detail), 03 (harnesses[], os — no OS source exists anywhere in the pipeline, schema chain documented), 16 (skills[] per workspace). Shared pieces: 02 creates the owner card and the skills-on-installs join that 04, 09, 16 reuse; 12 may need a layer release (UxFileTree). Baselines for all 18 page ids in todos-2026-09-24/baselines/ via scripts/shot-programs/todos-pages.json. Two sheet readings corrected in planning: "no logo assets exist" was stale (the layer ships 17 harness marks), and Providers has no runs column (read as two column families).

Sep 23

skill-definition wireframed (2026-09-23, phase 3 — Skill detail's missing object): Mark's ask ("we need to show the actual skill definition … research typical skill definitions … handle multi-file skills … a preview of the raw skill … start by mocking up a few options in the design project via the bob-wire wireframing skill" — skill-definition-prompt.md). Research (skill-definition-plan.md §1): every harness reads the agentskills.io standard — a directory with SKILL.md (YAML frontmatter + Markdown body) plus optional scripts/ · references/ · assets/, disclosed in three tiers (name + description always ≈100 tokens; body on trigger, <500 lines guidance; supporting files on demand by relative path); per-harness paths (.agents/skills is now cross-vendor), Codex's agents/openai.yaml sidecar, three spellings of the invocation policy, and load-time !`cmd` shell as the security-relevant construct. Most skills are one file; the multi-file ones are dominated by scripts (docx: 91 lines of prose over ~40 script files). What qcontrol has: SkillDetail { name, description } from Claude Code's user-scope skills/ only — the plan's §2 lists the six inspector/endpoint additions in cost order, and names the grain question every option must answer (the page keys on a name; definitions live per install and drift → group carrying installs by SKILL.md hash, elect a canonical). Four lo-fi wireframes on the design site under /pages/phase1/skill-definition-wf1…wf4 (registry collapse c92-skill-definition, listed on the Phase 1 index as "New — not yet in Linear"), each keeping the built Skill detail chassis (Phase1SkillDefFrame: actor header · band · jump pills · shipped sections collapsed) and a fixture switch across pdf (12 files, 3 fleet variants) / capture (single file) / deploy (Codex + a curl script) from app/data/skill-definition-fixtures.ts: WF1 Dossier (frontmatter fact grid + rendered body with Rendered ⇄ Raw, Bundle ledger with preview drawers), WF2 Bundle Browser (two-pane file tree + raw preview with an evidence header), WF3 Load Order (the three disclosure tiers as sections, invocation controls with defaults spelled out, a Reach strip), WF4 Fleet Variants (Definitions band + hash ledger + frontmatter comparison + the picked variant raw with drift shaded). Two lo-fi helpers (Phase1SkillDefRaw, Phase1SkillDefProse) — wireframe-only, not layer candidates. Recommendation (plan §4, a default): WF4's band only when definitions > 1, WF1's Definition + Bundle as the body with WF3's tier labels as captions and WF2's evidence header inside the drawers. Verified headless (/tmp/c92/skill-def/verify.mjs): 4 routes SSR 200, 15 screenshots across fixtures and interactions, 0 console errors. Note: the design dev server on :3000 was found wedged (vite-node "IPC connection closed" on every route, pre-existing) and restarted detached — the one state change outside the repo. Not done: any qdash/inspector change; captures into public/cycles/; a Linear note on PRO-30. Combined + mocked (2026-09-23, same day, Mark: "let's try combining them as you recommend. Then build a details page mockup based on our details pages and using our existing q-nuxt-layer components wherever possible"): WF5 /pages/phase1/skill-definition-wf5-combined draws the §4 recommendation (the frame gained a v-model for the fixture so a page can read it in its own scope); then /qcontrol/skill?skill=pdf|capture|deploy (app/pages/qcontrol/skill.vue, registry qcontrol-skill) — WF5 on the real actor frame, section for section with qdash's inventory/skills/detail.vue, every device the layer's (ActorHeader/ActorHeaderCell, DataMachine, NavJumpPills, DataSegmentBar, DataTable with a #details drawer, UxTabGroup, UxCodeBlock, UxPill, AgentAvatar, DataSurfaceSection/DataSurfacePanel, MDCRenderer); plan §5 has the anatomy. Found: the MDC parser can't run in this project's client bundle and python fences hit a highlight route the site doesn't serve — the body parses in server/api/skill-definition/body.get.ts (the cycles pages' recipe) and the Rendered/Raw panes are v-show. Verified headless: three fixtures SSR 200, drift pick swaps the rendered body and the raw frontmatter, Rendered survives the toggle, 0 console errors (/tmp/c92/skill-def/verify-m1.mjs, mdc-probe3.mjs). Not done: commit; captures into public/cycles/; qdash. Wording (Mark, same day): "Sessions on carrying installs" → Sessions (caveat into the provenance line and ledger caption), "Configured on" → Installs (cell, tile, ledger, pill), "behind the carrying installs" → "who own those installs", and carrying swept out of every visible string on the mockup and the shared wireframe frame — plan §5a; proposals for the qdash page, not applied there. Built in qcontrol (2026-09-23, Mark: "let's build the page in ../qcontrol now"; skill-definition-build-prompt.md / -build-plan.md, twin qdash cycles/c15 §skill-definition): the whole path, bottom up — SkillDetail grows the definition (frontmatter verbatim, capped body, sha256, mtime, bundle inventory; additive, make schemas, CHANGELOG pending), the Claude inspector captures it (+3 tests), qdash gains the additive install_skill_definitions table with the body redacted on ingest, /api/skills?skill= serves definitions[] grouped by hash with canonical election and a structured delta (+1 test, 426 pass), the seed emits real definitions with one drifted install, and inventory/skills/detail.vue is rebuilt on the mockup with the wording rulings and the box last (lib/skill-markdown.ts + skillBand.definitions + definitionDelta, vitest 329). Bundle rows have no preview drawer — contents aren't captured, the page says so. Headless on an isolated :7882/:3032 stack: 24/24, console clean. Left for Mark: commit; regenerate the live seed and restart :7879/:7880; dist.

Sep 23

user-details executed (2026-09-23, phase 3 thread 2 of 5): /users/detail?user=<email> in qdash from the c90 user-v3 mock on the actor frame, per Mark's ask ("based on user-v3, use the header pattern found on the other details pages" — user-details-prompt.md, executed directly; twin record qdash cycles/c15 §user-details). Header: the layer ActorHeader — avatar · name · team / ● last active, a Coverage pill cell, the mock's fact grid as Metadata with endpoints / models / providers / the projected Accounts line behind Show All. Data: the PersonRow the Users listing already builds, so every tile equals the row that opened the page; this person's rows from the same windowed /api/sessions feed drive the Sessions tile, the ledger and the chart. userBand + dailyTotals in lib/detail-bands.ts (vitest 306 total, +6). Where it departs from the detail-pages guide, deliberately: the chart beside the band is kept — a person's own session rows are an honest daily series (the Sessions listing's idiom), so the mock's clickable tiles survive for Sessions per day and Tokens per day (run totals, captioned as distinct from the Tokens tile's Cost-feed usage); the per-device cards (guide Q, "design-only") are built as PeopleDeviceCard over the row's harnesses and detected-only installs regrouped by endpoint. No backend change — the fleet feed's 200-session cap is stated on the page. Doors: pages/users.vue → users/index.vue so the route can nest; every ?user= link (endpoint / session / workspace / provider / skill detail, the Surface users axis, the /teams forward) retargeted to the page; person link kind; user detail → in the Users expand row; a Working-nav entry resolving the busiest person. Verified headless on the rebuilt-binary seed :7879 through a :3031 dev server (/tmp/c92/user-details/verify.mjs): 55 checks, 0 failures over 8 page loads, both themes, console clean — tiles = the feeds recomputed (costs by_user, agents, installations, sessions), Sessions tile = ledger rows = chart caption, tile click swaps the chart, one card per host with the detected-only row inside, not-found / no-param states, all three doors land. Concurrency: a sibling session had the machines → endpoints rename on disk uncommitted across ~80 files (including people-links, working-nav, detail-bands); every file was re-read before its edit and the new page speaks endpoints. Not done: commit (left for Mark with the rename thread's tree), dist regeneration, design-site demo (no new layer component), archive captures kept in /tmp/c92/user-details/.

Sep 23

account-details executed (2026-09-23): /inventory/accounts/detail?account=&provider= in qdash from Linear PRO-27, per Mark's ask ("a new details page for account — who's using the account, what harness are they using", then "this should be an account with a provider type … I have two Claude accounts, my personal account and the company account"; executed directly; twin record qdash cycles/c15 §account-details). The model: an account is a (provider, id) pair with a type — the id is the harness's own user.account_uuid, so it is that vendor's account (vendor_provider); type is company / personal from org_id presence; dual use is another account on the same provider. Seed: one uuid per (user, provider) instead of per user, plus personal_accounts in world.json (dana: Anthropic, jake: OpenAI) presenting a no-org id on ~⅓ of their runs — 33 accounts on the seed, two real dual-use pairs. Page: actor frame with Type and Provider as the headline cells, the attention block from served fields only, the Users ledger with each person's other same-provider accounts as typed doors, harness-type chips + the harness-instance ledger, sessions, Surface. Backend: /api/accounts (list + ?account=&provider= + ?user=), provider detail's Accounts ledger now the provider's own accounts (typed), /api/surface?account=, session detail carries the run's account posture + provider; cargo test 75, npm test 317. Doors from provider / agent / session / user detail and the Working nav. Verified headless on the rebuilt seed: 87 checks, 0 failures over 17 page loads, both themes. Not done: the accounts listing, dist, commit.

Sep 23

todos-2026-09-23 planned (2026-09-24, not executed): Mark's shorthand todo sheet (todos-2026-09-23.md, the prompt) turned into five per-page plans under todos-2026-09-23/ — README index (shared ground, verification recipe, nine collected questions with defaults) + 01-harnesses-listing (Harness types → Harnesses: columns endpoints/providers/sessions, versions/configured/harnesses count out, Installs card first; backend providers per adapter row), 02-harness-install-detail (Harness type detail → Harness Install Detail: Providers tile replaces Harnesses, Versions tile = most used, installs columns sessions/tokens/most-used-model/monitored, Surface gains Versions/Skills/Providers/Teams and drops Endpoints; backend per-install runs/top_model/monitored), 03-harness-detail (security score out, metadata = User · Endpoint · OS · Last updated, Sessions above Surface, Surface without Users/Endpoints; no OS field exists anywhere — flagged), 04-endpoint-detail (Harnesses + Installs ledgers merged into one "Harness installs on this endpoint" table joined on installation_id = install_id, rows linking to the install-detail page), 05-models-listing ("fix the data machines": nothing renders broken on seed or live :7878 — four candidate fixes listed, headline alignment / 331USD vs $ idiom / stale "all-time" subtitle / Other outweighing the top-3). Each plan is meant for a different executing agent; baselines captured to /tmp/c92/todos/*.png via /tmp/c92/todos/shots.mjs. Plans 1+2 share the providers backend change.

Sep 22

providers-skills executed (2026-09-22): Two new inventory categories in qdash from Linear PRO-25 / PRO-30 (providers-skills-prompt.md / -plan.md, planned and executed the same session, every decision on its default; twin record qdash cycles/c15 §providers-skills). The problem's shape was the grain: a provider in qdash is the wire provider (who receives the prompts — llm_usage.provider), not the harness vendor (Cursor's harness is Anysphere's, its wire provider is cursor, and it routes Claude and GPT models), so PRO-25's vendor → technology → instance hierarchy reads provider → harnesses → agents; a skill is a configured capability with no runtime witness anywhere in the field, so the page is the register against the exercise and the exercise is an honest zero with the sessions on carrying installs as candidates — the phase-1 mock's sharpest sentence ("40 sessions on 24 installs carrying deploy in the past 7 days; none invoked it."). Backend: /api/providers grouped from the deduped usage rows (not /api/models' first-seen provider), with accounts as distinct account_uuid and org_id presence as the honest org-scoped ⇄ unscoped proxy for enterprise vs personal; /api/skills joining the register to harness, machine, person and runs through agent_instances.installation_id, unioned with runtime tool_kind = 'skill'; /api/surface?provider= / ?skill=; cargo test 72. Seed: the Meridian generator now emits installation.details for every instrumented install (a 7-skill catalog by harness × team, team MCP registrations, default models, plugins) — the first time qdash's at-rest surface (harness MCP/skills, MCP configured side, Model "Default on") is populated on the seed; no runtime skill call is invented. The generator's self-validation turns out to fail on the current binary with or without the change (shadow installs read as instrumented, coverage 92 %) — recorded in the twin, not chased. qdash UI: four pages on the listing anatomy and the actor frame, providersBand / skillsBand / providerBand / skillBand (vitest 300), ◈ / ✦ glyphs, scope kinds, Working nav entries, and the doors (Models' provider cell, Tools & Skills' skill rows and the old tools/detail?kind=skill address, Harness detail's skill chips). Both new detail pages register period-only so their tiles equal the listing row that opened them — the plan hadn't foreseen the mismatch the headless run surfaced (listing at 7 days, detail all-time); this is a proposal for the six older actor pages (detail-pages decision 6). Verified headless on the rebuilt binary + regenerated seed (/tmp/c92/providers-skills/verify.mjs): 346 checks, 0 failures over 36 page loads, both themes, console clean; :7879 (the dev proxy) restarted on the new binary + db so the pages are populated at :3030. Concurrency: two other sessions were mid-thread in the same trees (devices-labels / header-margin landed during this thread; a harness-rename plan and a dist regeneration were on disk) — the two files both threads touched (harnesses/detail.vue, tools/detail.vue) were staged as this thread's hunk only (HEAD blob + substitution), dist left alone. Not done: dist regeneration; design-site demos (no new layer component — every device already existed); archive captures kept in /tmp/c92/providers-skills/.

Sep 22

devices-labels (2026-09-22): Three-line vocabulary ruling from Mark on the qdash Devices page, executed directly (devices-labels-prompt.md, no plan; twin record qdash cycles/c15 §devices-labels). Sensored = monitored → one Devices Monitored card ("Sensor installed and checking in", real share + segment bar), the projected unseen count folded onto the MDM line behind its PROJECTED badge; Shadow Processes → Shadow Harnesses (card, Coverage cell, flag reason, footnote); Installs = Harnesses → the table column is "Harnesses" with "(N shadow)" as its sub-count. Data keys and tests untouched; other pages' "Installs" ledgers out of scope. Verified headless (/tmp/c92/devices-labels.mjs), dist regenerated.

Sep 22

header-margin (2026-09-22): Spacing ruling from Mark, executed directly (header-margin-prompt.md, no plan; twin record qdash cycles/c15 §header-margin). Detail pages: the header-closing hairline's gap to the band 16 → 40px on all eight actor detail pages (Harness first, approved from a screenshot). Listing pages through the header component: qdash PageHeader bottom margin 24 → 40px, which also evens out the detail pages' breadcrumb → identity header gap; Devices / Users / Teams drop their extra mt-2. Layer ActorHeader untouched.

Sep 22

harness-rename executed (2026-09-22): "Agent" → "Harness" on every qdash page (harness-rename-prompt.md / -plan.md, executed with all seven decisions on their defaults; twin record qdash cycles/c15 §harness-rename). The rename collided with the existing adapter-level "Harnesses" entity, so the plan's decision 1 renamed that entity to "Harness types" throughout — listing title, tiles, breadcrumb, jump-nav, and every "All harnesses →" / "Show all N" string that refers to the adapter (Claude Code, Cursor…) rather than the monitored tool × user instance. Routes, query params, API paths, component names, scope-kind values, event type names, and CSV column keys were left untouched per the plan's own rule — only rendered text changed, across ~60 files: every /inventory/* listing and detail page, the fleet index, Live, Findings, Posture, Cost, Performance, DLP, Compliance, Identity, Users, Controls, Integrations, AppSidebar, the shared components (AgentExpandDetail, AgentCard, live-page chips/tables, integration previews), and the label helpers in lib/ and utils/ — including the generic AI-agent prose in policies.ts and frameworks.ts (decision 3, renamed by default). The concurrently-landed providers-skills pages (/inventory/providers, /inventory/skills) weren't in the original plan's file list but used the same Agent/Harnesses vocabulary, so they got the same treatment for consistency — including a same-day naming interaction with the devices-labels vocabulary ruling (DevicesOverview.vue's "Shadow Harnesses" already meant the adapter-type sense before this thread ran; it was left as Mark's explicit, freshly-landed wording rather than reflowed into "Shadow harness types"). Rust-served strings picked up too (decision 4): the Control Center's "Agent autonomy" category → "Harness autonomy" in rules.rs, and two web.rs finding strings. npm test 300/300, cargo test -p qdash 72/72 after three test assertions and a plural() call-site update (the helper's default plural adds a bare "s", so agent/agents counts needed the explicit 'harness', 'harnesses' form); cargo build --release -p qdash clean. Verified via a whole-tree regression grep (only identifiers, routes, and comments survive) plus a 200-status curl pass over every registered route on the live :3030 dev server — that server is a CSR shell, so rendered text wasn't checked in a browser; a headless pass is recommended before the layer step below. Concurrency: a second live session was mid-edit on largely the same files (providers-skills, then committed as 3c4883af/a44bf3b6); every edit here re-read each file's current disk content immediately before writing, rather than reusing earlier reads, and two edits the first pass missed (machines/detail.vue's "Show all N agents" ledger footer, providers/detail.vue's "Agents" section heading) were caught by the regression grep and fixed. Not done: the two layer-component strings (agent/MiniCard.vue's "Go to Agent" button, policy-config/ListEditor.vue's raw-scope-value rendering) — decision 5's default asks for new props plus a layer release and a lockfile refresh across every consumer, which is a separate, outward-facing action (publishes a package other live projects depend on); left as a flagged follow-up rather than run unattended. dist/ not regenerated; qcontrol's running seed processes (:7878/:7879/:7880) still serve the pre-rename binary — the Rust rebuild is on disk, not deployed to those instances. Follow-up (2026-09-22, Mark's screenshot): the fleet index's Harness-types lens (lens-harnesses on /inventory — "Harnesses · 7 tools · 39 installs", tool/footprint/versions/coverage table) had been missed by the rename pass entirely — it duplicated the renamed Harnesses (agent-entity) section's label in the jump nav. Removed rather than renamed: the section, its harnessRows/harnessCols computed, the harnessGroups import, and the jump-nav entry; the page-intro sentence's stale "the harnesses they run in" fixed to "the harness types they run as". /inventory/harnesses (the standalone Harness-types listing) is untouched — this was only the fleet-index's embedded copy of it. npm test still 300/300.

Sep 21

session-header (2026-09-21): Session detail's identity ribbon replaced by the shared ActorHeader (session-header-prompt.md, executed directly — no plan): technology mark + name, ⇄ person and status in the subline; the Duration cell and the run's metadata grid (Account, full id, Harness behind Show All) parked at the bottom in a Working section per Mark's follow-up. The header is added for consistency only — the body is the mock unchanged, so the rail keeps its tiles, its labelled fields (deliberately repeating the header's), Files and the projected summary. TranscriptPanel capped at 640px; hairline under the header; the Transcript ⇄ Surface switch sticky, the rail static and sitting against the 640px column rather than the far edge; the shared SurfaceSection above the Working section, scoped to the run via a new /api/surface?run= scope; the rail padded 50px at the top so it aligns with the transcript card. Verified headless on the seed, console clean; committed on qcontrol feat/new-pages, twin record updated.

Sep 21

documented (2026-09-21): Visual record captured for the atlas (/cycles/design/c92) — until now every thread had kept its shots in /tmp/c92/. qdash (24 states, scripts/shot-programs/c92-qdash.json against the :3030 dev server proxied to the rebuilt-binary Meridian seed on :7879): the combined and three solo people pages, the fleet index, all eight listings (Agents also filtered at 30d and Models also in the dark theme), the seven actor detail pages plus session detail with its ActorHeader, and the sidebar with Working on — full-page renders wherever a page runs past the fold. Design site (11 shots, content mode): the DataSurfaceSection, DataSegmentBar, DataRankedBars and ActorHeader demos, the DataMachine presets, the Listing Overview Band and Actor Detail Frame pattern sections as element crops (the page-top hero showed Form Layout), the Filter timeframe-only and FilterItem removable scenarios, the qcontrol/teams mock with the pill (chrome kept — content mode hides the title block the pill lives in) and user-v3 on the chrome. Three archive entries for the cycle's highlights (the combined people page on real data, the actor detail frame, the listing overview bands); captions and the "New in this cycle" line in the capture manifest; Scope brought up to date with the layer releases through 0.9.20, the backend changes each thread actually made, and the two threads the list had missed (day-series, session-header). Left as found, deliberately: timeframe-always's design-site edits (Filter / FilterItem demos, both registries, qcontrol/teams.vue) are on disk uncommitted for Mark's review — the captures show that state; its timeframe-always-prompt.md / -plan.md are committed with this pass since the record already cites them.

c102 qdash TODOs — 2026-09-25 review

Sep 25

todos-2026-09-25 planned (2026-09-29): Mark's 2026-09-25 product-review notes (journal 2026_09_25, #QPT-Product) turned into 15 per-page plans under todos-2026-09-25/ by seven parallel plan writers — README (shared ground, run order, 48 decisions with defaults) + 00-sweep (nothing to sweep; owners for four cross-page renames) + 01-harness (Installs rename, Versions · Skills up, egress panel; builds #after-<axis> Surface slots) · 02-endpoints (OS rolldown: no empty buckets, biggest first) · 03-model (More detail / default section out) · 04-sessions (exit/flags out, endpoint in, model + tools after user) · 05-mcp-servers / 06-mcp-server (MCP Servers · Tool Calls · Tools Used; Installs; More detail out) · 07-skills (Installs first; variable tile's title becomes its dropdown — layer 0.9.23, runs last) · 08-skill (Reach row out, host → endpoint, person → user, harness-detail column out) · 09-tools / 10-tool (type, Success Rate; Harnesses table trimmed; arguments → session link) · 11-workspace (Teams beside Users, Tools beside Skills; ordered only) · 12-teams / 13-team (Coverage via sensorCoverage(); Monitored Harnesses; Surface reordered) · 14-users (devices → Endpoints; attention card by reason). Registry refreshed for the /team/ move; shot program routes refreshed, mcp-servers + team added. Baselines wait on R.1 (:3030 proxies the live monitor, not the seed).

Sep 25

todos-2026-09-25 re-targeted (2026-09-30, Mark): "do your work on the Fable branch running on port 3032" — every plan re-written in place by seven parallel writers against the c99 Fable-track app (qcontrol-c99-fable, branch c99/claude-code-fable-5.1, crates/qdash/apps/claude-code-fable-5.1/, :3032 → seed :7882), holding the c99 data-interface bible (thin pages → context components → composables → lib rollups; R3/R4/R9/R17/R24). README shared ground rewritten; R.1 resolved (the Fable app reads its own seed), new R.3 (backend + layer read-only on this branch → 01.1 egress blocked, 10.1 alt blocked) and R.4 (this record only, no twin). Plan 07 no longer needs a layer release — c100's uncommitted layer change already carries DataMachine #title — so the run is plain sheet order. Baselines of all 14 pages captured from :3032 into todos-2026-09-25/baselines/. Test baseline: 539 + bible-check clean.

c97 Gen-1 Origin

Sep 25

Kick-off (2026-09-25): Cycle created from the c96 close conversation; the six PNGs recovered from qcontrol commit 9c9371601 into the scratchpad and reviewed.

Sep 25

Import executed (2026-09-25): The six PNGs copied to public/cycles/design/gen1-<view>.png and added to the manifest with capturedAt / asOf = the bot's commit time (2026-06-30T21:44Z), local: true, surface: app, explicit subjects (page/fleet-overview, page/inventory, page/control-center, page/policy-enforcement, page/alerts, page/targets), hash routes (/#fleet-overview — the prototype switched views on location.hash), captions, one newThing, and a new origin: { id: 'gen1', label: 'Gen-1 prototype', note }. Evolution builder: origin stands in for the cycle in the moment key and on the strip / record (with its note in italics), asOf drives a moment's date and sort so a later rebuild can shoot the prototype today and still land in June; subject summaries gain origins, and the index card's span reads "Gen-1 prototype → c92". Verified on :3000: Inventory reads Gen-1 → c81 → c92 across qdash → mock → qdash, Fleet Overview and Control Center and Enforcement each gain their Gen-1 first moment, Alerts and Targets stand alone; console clean. Archive entry 2026-06-30-c97-gen1-prototype.md (designer devin, era seed, phase 0.9; "recovered, not captured" stated). gen1-rebuild-prompt.md + -plan.md written for the populated capture — worktree at PR 521 4af0e01dc, event replay, program with origin + asOf; not executed. The gen-1 filename prefix keeps the atlas out (it keys on c<N>-), so the prototype shows only where it belongs: the evolution pages and the archive. Capture c97-evolution-inventory (+full).

Sep 25

gen1-rebuild executed (2026-09-25): gen1-rebuild-plan.md run end to end, every decision on its default. Worktree at PR 521 4af0e01dc; cargo build -p qdash took eleven seconds; the June binary's ingest --from-file accepted a generated NDJSON pair (gen1-replay.mjs → gen1-replay-run.jsonl 237 events / gen1-replay-scan.jsonl 8 — three users, four agents, a yolo + root run, credential-file reads, non-allowlisted and plaintext egress, two untapped installs) and serve --port 7899 rendered every view populated (8 agents, 6 sessions, $7.95, 15 findings). Two traps, both recorded in the program: the prototype has no URL routing — one page, views switched only by .nav-item clicks — so the first pass returned fifteen Fleet Overviews and the second, with the view in the route string, fifteen 404s; the working program points every page at / and switches with clickSel "[data-view='<id>']". The recovered six had their /#view routes corrected to /. capture.mts now copies a program-level origin + asOf onto entries. Fifteen shots (+ fulls) as gen1-<view>[-populated].png, asOf 2026-07-01 (the merge date) so they form the second Gen-1 moment after the empty 06-30 set; nine views had no surviving image before this. Archive entry gallery extended. Capture c97-evolution-teams (+full). Gen-1.5 (the June 30 Nuxt branch in qcontrol-qdash-ref) not added — decision 3's "if smoothly" clause was met, but it is a different artifact and deserves its own line in the record; left for a later thread. Worktree removed, port 7899 released.

c96 Page Evolution

Sep 25

Kick-off (2026-09-25): Created cycle, wrote initial-prompt.md and CYCLE.md. Open questions documented in Scope; plan and architecture next.

Sep 25

Planned (2026-09-25): plan.md written, nothing executed. Verified first: the manifest is the only join surface (229 design entries, every hero manifested); route repeats across cycles only 6 times, but stripping -vN / ?query joins 31 families, and the same product page lives on three hosts (mock → /qcontrol preview → qdash local). A dry run of route→subject derivation resolves 215/229 entries into 136 subjects, 22 with real history (page/teams: 6 moments, c81→c92, three surfaces). Design: an explicit kind-prefixed subject (page/teams, component/data-ranked-bars) + derived surface / variant on every manifest entry, a small alias registry (app/data/subjects.ts), a backfill script, a moments model (buildEvolution.ts) with fans (parallel versions on one day) and lanes (state / theme variants), /evolution index + /evolution/[kind]/[slug] with UxImageCompare (wipe · onion · side · sequence) and deep-linkable ?a=&b=, history chips on atlas figures, an Evolution section on component docs, UxLightbox extracted (rule of three). Seven decisions ruled the same day: single subject field; qdash captures join as the app surface; bulk backfill now; view nested under /cycles (/cycles/evolution, evolution reserved as a project id); components prototyped design-local then extracted; pixel diff is stretch; design-only.

Sep 25

Executed (2026-09-25): Phases 1–5 of plan.md run end to end on the design repo; nothing committed yet. Identity: app/data/subjects.ts (kind-prefixed subject, surface, variant; derivation rules + alias table — page/user and page/users → page/user-detail, page/teams-users-devices → page/teams, qdash /inventory/<x>/detail → page/<x>-detail), PageEntry.subject, capture.mts tagging every mode (--subject / --surface / --variant, program subject + per-shot variant), scripts/backfill-subjects.mts (npm run shots:backfill). Backfill: 215 / 229 design entries tagged into 132 subjects, 23 with more than one moment; the 14 unresolved are site chrome. Data: server/data/evolution/buildEvolution.ts — moments keyed by cycle + thread + day + surface, sorted day → cycle → surface → clock (so c90 and c92 shot the same day read in cycle order), fans (several routes in one moment: teams-ideas v2–v7 in c67) and lanes (state=clear); /api/evolution and /api/evolution/[kind]/[slug]. View: /cycles/evolution (cards pairing first and latest capture, kind tabs, history-only toggle) and /cycles/evolution/[kind]/[slug] (lane control, EvolutionStrip, UxImageCompare wipe · onion · side with synced scroll, a sequence flipbook with autoplay, step buttons + arrow keys, the record for A and B with cycle, thread, surface, route, caption, newThing, hero / full-page lightbox; ?a=&b=&mode=&lane= deep links, Copy link). Hooks: atlas figures carry history · N moments → when their subject recurs (51 of c92's 72 figures); component docs pages gain an Evolution section (client-fetched, only when history exists — DataRankedBars shows two moments); UxLightbox extracted from the atlas and archive copies, both now call it. Docs: /capture Subjects section, /document-cycle capture + verification lines. Verified on the live :3000 server: Teams reads six moments across mock → preview → qdash, teams-ideas keeps its fan, data-ranked-bars its thread label; all four modes and the URL sync exercised in the browser pane, console clean; captures c96-evolution-teams (+full), -onion, -index (+full) tagged page/evolution / page/evolution-index on the docs surface. Not done: layer extraction of the three components (+ demos, at close), pixel-diff scoring (stretch), Outcome / archive entry / HISTORY.

c95 Trigger-Bar Column Picker

Sep 25
  • Workspaces gets the full bar (2026-09-25, design c92 todos plan 15): Repos & Workspaces moves from plan 08's standalone UxColumnPicker to the full DataListingBar with a Team key. The new teams column (user → team via /api/teams) carries filterKey: 'team', and useQuickFilter(gf, 'team') starts there: Team · All · Data · Frontend · Payments · Platform · Columns. The users / hosts columns are gone, so user / host (both over the cap) live only in the Filter bar. qdash on disk (the strip half is uncommitted, like every other strip consumer).
Sep 25
  • new consumers (2026-09-25, design c92 todos plan 08 Part B): Mark: "the trigger bar doesn't have our new column editor or the dropdown key option we just created — add it to this and other instances on the other listing pages." qdash (feat/new-pages, on disk): UsersOverview swaps FilterTriggerBar for DataListingBar and gains a column model on its UxTableList (not DataTable: rows pre-open by ref, own search); TeamsOverview + pages/teams/index (usePeopleData({ register: 'teams' }) → team key, ?team= now the filter, not a forward); inventory/{endpoints (Team; endpoint column filterKey: 'user','team'), providers (label→filterKey: 'provider'), models (Provider), workspaces (users/hosts→user/host)}, all in DataTable #toolbar; inventory/index Harnesses strip onto useQuickFilter. useQuickFilter gains QUICK_FILTER_MAX_OPTIONS (8): a key with more values stays off the strip — FilterTriggerBar has no overflow handling and a 14-host key pushed the key segment off-screen (layer question, not changed here); Workspaces, whose only keys are over the cap, seats a standalone UxColumnPicker until a short key has a column. The seven existing strips are unchanged.
Sep 25
  • build (2026-09-25): Mark's follow-up — add a DataTable slot, skip the deep Phase 1, execute. Layer: UxPopover + UxColumnPicker moved from design app/components/ux/ to components/ux/ (popover root inline-flex, inset focus ring; picker gains a #trigger slot exposing { open, label, visibleCount, hiddenCount, total }); FilterTriggerBar gains #end (trailing hairline-divided segment, scope { tone }) with the overflow clip moved inward to the key+values group so a popover can escape; DataTable gains #toolbar (title row when titled, own row otherwise, outside the scroll box) and the c93 sort-by-hidden-column gap closes (fallback to initialSort, else first sortable); new DataListingBar (data/ListingBar.vue) composes bar + picker — bar props pass through, columns + v-model:visibleColumns add the picker, columnPicker=false opts out, side defaults to above, segment reads "Columns" until something is hidden then "N of M" in the selected tone. Design site: local prototypes deleted; registry entries for both extracted components point at the layer and list the new slots; new DataListingBar entry + _demos/DataListingBar.vue (live filter + picker in a titled DataTable; opt-out / nothing-hidden / three-hidden / multi-key + lead-in / overflow + extra #end scenarios); FilterTriggerBar, UxColumnPicker, DataTable demos gain the slot scenarios; /pages/column-picker gains a "Seated in the listing bar" section. qdash (feat/new-pages): DevicesOverview and inventory/{index (Harnesses table), harnesses, sessions, tools, skills, mcp-servers} swap FilterTriggerBar for DataListingBar inside DataTable #toolbar, first column locked, visible keys as a local ref; UsersOverview keeps the bar (UxTableList, no column model). Layer CLAUDE.md migration notes added (unreleased). Not committed, not released — Mark reviews first.
Sep 25
  • key dropdown (2026-09-25): Mark, with the c92 reference screenshot: "the original filter bar shows the left filter item as a dropdown, can we integrate that as well?" The bar already renders the key caret + dropdown when filterKeyDefs has more than one entry (c92 rule: a caret only when there is a choice); every qdash strip passed one key, so none showed it — while every page registers two or three keys with suggest() in gf.register(). Fix is wiring, not a control: new qdash composables/useQuickFilter.ts turns the page's registration into the strip's inputs (keyDefs = registered keys with suggestions, plus the initial key; filterKey; options via suggest(key) + formatVal; value; onValue → gf.set/clear), returned reactive so v-model:filterKey binds directly. Seven strips switched: inventory/{sessions (status·flagged), harnesses (provider·kind), tools (kind·server), skills (adapter·source), mcp-servers (source)}, DevicesOverview + UsersOverview (team·provider) — the two presentational components now take one quickFilter prop in place of teamOptions/activeTeam/update:team; pages/{devices, users/index, teams-users-devices} build the objects (the combined page gets one per strip so the two key segments are independent); usePeopleData drops teamOptions. inventory/index (posture only) stays single-key by the caret rule. Design: the DataListingBar demo's default instance now shows the multi-key form. No layer change.
Sep 25
  • keys restricted to columns (2026-09-25): Mark: "populate that dropdown with the columns from the table" → of three models (table-local filter · hybrid · global keys restricted to columns) he chose global keys only, restricted to columns. DataListingBar now offers only the filterKeyDefs its catalog has a column for (restrictKeys, default true); a column matches by key or by the new Col.filterKey?: string | string[]; a current key the table can't answer is replaced by the first offered one (emitted). qdash annotations: sessions exit_code→status, risk→flagged; harnesses adapter_id→['provider','kind'] (its cell shows vendor · kind); skills harnessList→adapter; UsersOverview filters to its cols map. Net: Devices and Users offer Team only (no caret — Provider isn't a column); Sessions Status·Flagged; Harnesses Provider·Kind; Tools Kind·Server; Skills Harness·Source; MCP servers Source. Demo gains a restricted-keys scenario.
Sep 25
  • setup-order bug (2026-09-25): useQuickFilter first evaluated each page's suggest() during setup (an immediate watcher, then a plain watch on a computed — which also evaluates its source at creation); Harnesses/Skills/Tools declare the lists suggest reads after gf.register(), so setup threw "Cannot access 'vendors' before initialization" and the pages rendered blank. Fix: suggestions live in lazy computeds evaluated at render; async results settle through a watch created in onMounted. Verified on all seven strips.
Sep 25
  • key-select ring (2026-09-25): Mark's styling note (blue outline on the key segment after a pick) → the c92 peer-focus-visible overlay removed; Chrome treats a clicked <select> as keyboard-focused, so the ring showed on every mouse pick.
Sep 25
  • decisions (2026-09-25, follow-up): DataTable seat added; Phase 1 collapsed; picker chrome via #trigger slot + bar #end scope rather than a variant prop.
Sep 25
  • decisions (2026-09-25): prototype both visual joins now, ahead of the Figma; absorb c93's layer extraction into this cycle's Phase 3; roll out Devices first then every trigger-bar DataTable listing. Ownership: Mark's two readings (grow FilterTriggerBar vs. a super component) weighed in plan.md "Ownership fork" → super component; the bar stays filter-only with an #end slot. All six questions closed.
Sep 25
  • plan (2026-09-25): survey of the bar (layer, eight qdash consumers, TONE rulings) and the picker (design-local, trigger chrome slot-owned) → three composition options (slot / props / props + slot, recommending props + slot), two candidate visual joins (segment inside the bar / sibling beside it), five phases, six open questions → plan.md.

c94 TODO Execution Process

Sep 25
  • review (2026-09-25): c92's todos workflow reconstructed from its artifacts → c92-todos-review.md: the seven-step path, what worked, an eleven-row friction table with the fix each implies, the grammar already in the notes, the shorthand proposal, Logseq findings (graph on disk, paste loss proven by diffing the journals, no connector, HTTP API off), the build list, eight questions — all answered the same day.
Sep 25
  • housekeeping (2026-09-25): c92's sheets renamed to their journal dates (todos-2026-09-23.*, todos-2026-09-24.md), references repointed across design, memory, and qdash; recorded in c92.
Sep 25
  • skill built (2026-09-25): .claude/skills/todos/ — SKILL.md (four stages: ingest · plan · brief · record, plus the rules c92 taught), reference/grammar.md (shape, six section ids, objects-as-rendered, the verb set, the three markers, sweeps, a worked Endpoint example), reference/pages.md (28 qdash page ids with aliases, routes, files, APIs, band helpers, surface scopes, nav labels — verified against feat/new-pages; shared pieces every plan touches), templates/{README,plan,brief,record}.md lifted from todos-2026-09-23/. scripts/shot-programs/todos-pages.json: one full shot per page id against :3030 with seed ids; --out puts baselines beside the plans.
Sep 25
  • first run — ingest + plan (2026-09-25): the 2026-09-24 journal read straight from the Logseq graph (no sheet file; the block is quoted verbatim in the README, mtime recorded), 17 page headings resolved to ids (one alias problem: "Harness details" vs "Harness install details" resolved by the 2026-09-23 Nav ruling), the one image copied to assets/, the Mark Peterson line routed to Voices, "versions?" to Decisions. cycles/c92.qcontrol-new-pages/todos-2026-09-24/README.md written with verified shared ground (branch, 291 uncommitted paths, servers by pid, npm test 344, seed ids per detail route); plans 00-sweep + 01–16 written by seven parallel agents (grouped listing+detail; 145k–245k tokens each, 6–14 min), README index assembled with backend flags, four waves, shares, and 62 plan.n decisions with defaults; 18 baselines captured by the program (first pass wasted on a dead seed — the plan stage now checks the seed answers, not just the dev server). Lessons for the skill from this run: a stale "verified fact" in the README propagates to every agent (the logo claim) — shared ground must be re-verified, not copied from the previous README; agents write to a shared README only through the coordinator; plan-local decision numbers need the plan.n scheme from the start.

c93 Table Column Picker

Sep 22
  • plan (2026-09-22): survey of existing pieces + seven open questions → plan.md; all seven answered the same day.
Sep 22
  • prototype (2026-09-22): UxPopover + UxColumnPicker built as design-local components under app/components/ux/; /pages/column-picker demo with the Devices catalog live table, five scenarios, and the UxTableList pattern. Verified on the live :3000 server via scripts/shot-programs/c93-column-picker.json (closed → open → Owner toggled off: badge 7→6 of 10, column drops); captures public/cycles/design/c93-column-picker{,-full,-open,-toggled}.png. Polish from the shots: locked/last-standing rows dim; list cap raised to max-h-96 so a 10-column catalog doesn't scroll. Not committed — Mark reviews first (push = deploy).
Sep 22
  • component docs (2026-09-22): both prototypes registered in component-registry.ts (UxPopover under Interactive, UxColumnPicker under Table) with _demos/UxPopover.vue + _demos/UxColumnPicker.vue (adminProps cover every prop; minimal / typical / overflow scenarios, guard state) — so they appear on /components now, not only after extraction. source is display-only, so it reads the design-local path with a note.
Sep 22
  • side prop (2026-09-22): Mark's note that the panel covered the very columns being toggled → UxPopover gains side: 'below' | 'above' (passed through UxColumnPicker); the live demo and the DevCanvas default open upward over the title area so the table stays fully visible. Trade-off: 'above' needs headroom — a picker at the very top of a page would push the list off-screen, so it suits tables that sit under a title band (every qdash listing does) and the default stays 'below'.

c12 Micro Problems market-analyst

Sep 21
  • kick-off (2026-09-21): Lens analysis and plan written (lens-analysis.md, plan.md); four unlocking decisions confirmed with Mark; redefinition captured in agent memory; identity rewrite made explicit as T4/K. Pending edit to data/call-classifications.json (Aug 7 Mark call → null) is Mark's and left unstaged.
Sep 21
  • T0 archaeology (2026-09-21): problems-draft.md — 15 micro problems hand-drafted from the six phase-2 calls + the Cam and c21 briefs + design c55/c92, each with pain statement, product-facing question, personas, situation, use cases, surfaces, cited evidence (call#index, speaker, perspective, verbatim) and hand-computed standing: 4 recurring (unknown-agent-fleet, personal-vs-enterprise-accounts, unexplained-ai-spend, prove-posture-over-time), 11 observed. Five candidates deliberately not promoted (e.g. "who owns this" fails the addressability test). Seed PRODUCT_SURFACES (23 page families) and personas (c55 P1–P11 + a missing P12 end user/developer). Three problems have no use case → missing hypotheses (governance evidence & reporting; session-record governance; endpoint coexistence proof); gateway-bypass-detection has no problem under it. Plan amendments (§5): problemId on session items; advisor first-hand counts toward standing (labelled) — to confirm; challenge evidence from day one; non-screen surfaces; shown-artifacts earns its keep (Sep 3 reactions to mocks). Awaiting Mark's review before T1.
Sep 21
  • problem-pages thread (2026-09-21): Mark asked for a home for the problem framing in the site. Surveyed all eight pages, the layout, useCallData.ts, and the ten components; wrote problem-pages-plan.md (expands plan §2J; becomes the T2 spec): nav gains Problems in second position; dashboard re-ordered (problem KPIs + problem-space card first, child-problem chips on use-case cards, sales KPIs demoted, nothing removed); new /problems registry page in the InsightCategoryCard idiom with standing pills, company chips carrying source type, a candidates section with copy-JSON promotion, and a missing-hypothesis callout; /problems/[id] detail; a Problems section at the top of the call page (tagged + candidates); small placements on calls table, companies, insights filter facets, feedback (lifecycle retired, "not a tracker" banner), about. Data contract for T1/T2 and a bridge: problems.json carries hand-curated evidence[] refs from the T0 draft so the pages ship before extraction tags flow. Five decisions queued (§6). Prompt: problem-pages-prompt.md.
Sep 21
  • T0 review + registry bridge (2026-09-21): Mark confirmed the 15 problems, advisor first-hand as first-class (labelled), the two new hypotheses + account-identity-control (gateway-bypass parked), surfaces + personas "try it out"; Q6 legacy Cam reconnect deferred with a pros/cons note in plan.md §5. Built: data/problems.json (15, curated evidence refs), data/personas.json (12), PRODUCT_SURFACES / PROBLEM_STANDINGS / PROBLEM_STATUSES / PROBLEM_DIRECTIONS in vocabularies.ts, problem/persona/candidate types in call.ts (+ problemId, problemDirection, surface, artifactRef on observations; problemId on session items; candidateProblems[] on calls), schemas/problem-standing.ts (computeStanding), build-index.ts → data/problems-index.json (curated refs ∪ extraction tags, org key via the new org on the Mark Peterson override). Rule fix found in the wiring: variant refs must not count toward recurring — now 4 recurring / 11 observed, matching the hand draft.
Sep 21
  • problem-pages T2 build (2026-09-21): Site: useCallData.ts loads problems / problems-index / personas (feedback.json dropped) and exposes problemRollup (standing recomputed client-side under the global filters), problemsByStanding, problemsForCall, candidateProblems, problemStats; Filters gains surface + persona. New StandingPill, ProblemChip, ProblemEvidence components; utils/format.ts gains standing/status/direction pills and surface helpers. New /problems (KPIs, missing-hypothesis callout, collapsible registry rows with company·source chips, candidates with copy-JSON, folded-in "feedback not tied to a problem") and /problems/[id] (standing card, by-organization table, evidence by perspective, status history, related). Dashboard: problem KPIs + Problem Space card first, child-problem chips on use-case cards ("no problem under this hypothesis" on gateway-bypass), chips on Direction items, Problems-by-Surface chart, sales KPIs moved below Direction. Call page: Problems section (tagged + candidates), Shown row, chips on evidence/feedback. Calls table + companies pages gain problem columns/cards; About gains the Micro Problems section; nav = Dashboard · Problems · Calls · Companies · Insights · Segments · About; /feedback page removed, route redirects to /problems. Verified: nuxi typecheck clean (Segments errors pre-existing), production build + preview on :3100 — all routes 200, redirect 307, data files served.
Sep 21
  • T1 extraction + T4 docs/loop (2026-09-21): Triage gains shown[] (artifacts on screen); extract-call.md gains the Named Micro Problems section ({{PROBLEMS}}), product surfaces, and guidelines 18–20 (problemId + direction; candidateProblems — "forming the problem is the problem"; surfaces + artifactRef); prompt.ts renders the registry into the cached static part and the shown list into the dynamic profile block; validation.ts rule 3 drops unknown problemIds and artifactRefs outside the declared list, validates surface, problemDirection, and candidateProblems[]; finalize.ts / batch.ts pass problemIds + shown; curated refs carry curatedAgainst (index warns after a re-extract). Pilot (Tiled 08-25 prospect×demo; Mark Peterson 09-03 advisory×roadmap with design/qcontrol/{teams,device,session} declared): both PASSED; cache read 14,128 tokens on call 2; Tiled 26 obs / 11 tagged across 8 problems incl. challenges on safe-to-enforce, 2 candidates with questions (AI-review sufficiency; no shared AI-usage framework); Sep 3 17 obs / 10 tagged + 4 session tags, 9 artifactRefs across the three mocks, 11 surfaces, 2 candidates (MDM deep-link from a flagged device; quota-vs-overage cost). Curated refs for the two re-extracted calls dropped (tags cover them); standing now 5 recurring / 10 observed — the extractor tagged Phil Chen's self-hosted-control-plane relief (Tiled) to session-transcript-governance, making it recurring alongside Moto; a fair reading of "the customer holds the keys", flagged for Mark's review. 4 candidates now on the Problems page. pipeline/consumers.ts (npm run consumers) → data/consumers.json (finds the Cam brief in design c55/c78/c81; no problem:<id> tokens downstream yet); build-index warns when a cited problem is still open; site shows consumers on the problem page. Identity rewrite: CLAUDE.md (design tool first; problem registry in the tree, data flow, schema, conventions), goals.md (Design Lens leads, Market Lens kept), README.md (micro problems, triage shown, promotion + consumers runbook), /extract /analyze /brief skills, briefs/TEMPLATE.md + INDEX.md (kind, problem:<id> line; existing briefs retro-tagged), design CLAUDE.md Sister Projects + brand/pipeline.md (stage 2b, hand-off rule 4; committed in design as 5abc754). data/feedback.json deleted. Gotcha: the agent shell exports an empty ANTHROPIC_API_KEY, which --env-file will not override — pipeline runs from the agent need env -u ANTHROPIC_API_KEY.
Sep 21
  • T3 document intake + story + analysis readout (2026-09-21): npm run ingest -- <file> --source … --author … --date … [--extract] (pipeline/ingest.ts) writes data/raw/doc-<slug>.txt + a source: document sidecar + a declared profile, then runs the normal extraction; CALL_TYPES gains document, MeetingSource gains document, the prompt renders a Document Metadata block and an "input is a written document" line in the profile block; the site shows a DOC pill (meetingSourcePill). Pilot: inbox/qcontrol-as-signal-updated-text.md as internal × document → 14 observations, all internal, 2 problem tags, 2 candidates (local-only agents with no egress; attested heartbeat vs AI-shaped traffic), no standing change — an internal draft is direction only, as designed. Story brief briefs/story-coverage-to-accounts.md (kind: story; five problems in one drill path, persona P5+P4, verbatims with perspective, fixture-world note for c92 Meridian) + INDEX row. analyze-overview.md + output-schema.ts gain problemSpace (readout, recurringUnbriefed, challenged, missingHypotheses, candidatesToPromote, surfacesWithoutFirstHand) fed by loadProblemSpace() in analyze.ts (registry + index + candidates); npm run analyze re-run — readout names session-transcript-governance as recurring-but-open, safe-to-enforce as challenged ("not what I am buying yet"), endpoint-coexistence-proof as a missing proof-artifact hypothesis; rendered as an Analysis Readout card on /problems. 6 candidates now await review.
Sep 21
  • Corpus re-extracted under the c12 prompt (2026-09-21): all six calls + the ingested doc now carry extraction tags. The Aug 31 roadmap call hit the 32K output ceiling on the first pass (33.4K needed) — EXTRACT_MAX_TOKENS is now 48K with an ANTHROPIC_EXTRACT_MAX_TOKENS override. Cache read 14,176 tokens on every call after the first. Tags per call: Tiled 11, Mark M Aug 20 12 (+5 session), Aug 31 12 (+6 session), Sep 3 10 (+4), AMZ Sep 2 5, Zscaler 7, doc 2; 16 candidates now await review. Curated refs: a first word-overlap remap dropped 26 items and knocked safe-to-enforce to candidate; redone from the original registry (62f8cb4) + original processed files by verbatim match (transcript text is stable across extractions) → 57 remapped; the remaining unmatched refs were either duplicates collapsing onto one new item or already covered by extraction tags, and four were re-pinned by hand (advisor "inventory nearly there" → unknown-agent-fleet; Sam Curry's governance-gap line → agent-identity-scoped-access + variant on prove-posture-over-time; Aug 31 "discovery before governance" → safe-to-enforce). Standing: 5 recurring / 10 observed, identical to the pilot state (transcript governance recurring via Tiled, flagged for review). Lesson for the runbook: re-extracting a call invalidates curated indices — pin by verbatim, not by index, when it matters.

Captures

144 screengrabs taken this week, 118 of a subject with an evolution history.

The c90 preview pages running in the real qcontrol app (qdash) on live /api/* data — a shell-owned global filter with a permanent timeframe, listing bands with honest devices, and six actor detail pages on one frame

Endpoints listing — after todos-2026-09-24 plan 03
Endpoints listing — after todos-2026-09-24 plan 03
Skill detail — deploy — Source view, syntax-highlighted (todos-2026-09-24 plan 12 follow-up)
Skill detail — deploy — Source view, syntax-highlighted (todos-2026-09-24 plan 12 follow-up)
Skill detail — deploy — after todos-2026-09-24 plan 12
Skill detail — deploy — after todos-2026-09-24 plan 12
Workspace detail — payments-core — after todos-2026-09-24 plan 16
Workspace detail — payments-core — after todos-2026-09-24 plan 16
Workspaces listing — after todos-2026-09-24 plan 15
Workspaces listing — after todos-2026-09-24 plan 15
Tool detail — Glob — after todos-2026-09-24 plan 14
Tool detail — Glob — after todos-2026-09-24 plan 14
Tools listing — after todos-2026-09-24 plan 13
Tools listing — after todos-2026-09-24 plan 13
Skills listing — after todos-2026-09-24 plan 11 (layout A)
Skills listing — after todos-2026-09-24 plan 11 (layout A)

NavVerticalSubmenu: a sidebar row that owns child rows and opens them by URL. In qdash, THE FLEET moves up to second and Inventory lists its 9 listing pages (italic, med 13, 1px gap on a stroke-strong rail) on every /inventory page

qdash /inventory: THE FLEET now sits second in the rail, and Inventory (grape, the current page) has its 9 listings open under it on the stroke-strong rail. The page title reads 'Inventory', no longer 'Harness Inventory'
qdash /inventory: THE FLEET now sits second in the rail, and Inventory (grape, the current page) has its 9 listings open under it on the stroke-strong rail. The page title reads 'Inventory', no longer 'Harness Inventory'
The same demo with the tuning knobs pushed: subWeight black, subSize 16, subGap 8. Only the children change; the parent row stays semi 15. Mark dialed these knobs back to med 13 with a 1px gap, now the defaults. subGap is provisional
The same demo with the tuning knobs pushed: subWeight black, subSize 16, subGap 8. Only the children change; the parent row stays semi 15. Mark dialed these knobs back to med 13 with a 1px gap, now the defaults. subGap is provisional
The NavVerticalSubmenu demo at its dialed defaults (italic, med 13, 1px gap): the interactive THE FLEET sidebar opened by a `match` on the demo's own path, then the scenarios: no children (no rail), one child, the 9 inventory listings, an unmatched route (collapsed), the button form, v-model:open, and overflow
The NavVerticalSubmenu demo at its dialed defaults (italic, med 13, 1px gap): the interactive THE FLEET sidebar opened by a `match` on the demo's own path, then the scenarios: no children (no rail), one child, the 9 inventory listings, an unmatched route (collapsed), the button form, v-model:open, and overflow
qdash Model detail (claude-sonnet-4-6): sub-items prefix-match, so Models stays lit on its own detail pages and the open submenu still says which listing you came from. Top-level items keep the exact-match rule
qdash Model detail (claude-sonnet-4-6): sub-items prefix-match, so Models stays lit on its own detail pages and the open submenu still says which listing you came from. Top-level items keep the exact-match rule
qdash /inventory/models: the submenu stays open because the route is under /inventory. Models lights up and the Inventory row drops back to ink, so only the current page is grape
qdash /inventory/models: the submenu stays open because the route is under /inventory. Models lights up and the Inventory row drops back to ink, so only the current page is grape
qdash Fleet Overview: outside /inventory the submenu is collapsed to its parent row, and the rail reads WHERE ARE WE → THE FLEET → WHAT GOOD LOOKS LIKE → PROVE
qdash Fleet Overview: outside /inventory the submenu is collapsed to its parent row, and the rail reads WHERE ARE WE → THE FLEET → WHAT GOOD LOOKS LIKE → PROVE

UxColumnPicker on a new UxPopover primitive — a checkbox popover above the table that shows/hides DataTable columns, with a locked identity column and a min-one guard; prototyped as design-local components before layer extraction

The Devices listing with the picker closed — 7 of 10 columns visible, the badge on the trigger says so; scenarios below: minimal, overflow, guard, long labels, UxTableList
The Devices listing with the picker closed — 7 of 10 columns visible, the badge on the trigger says so; scenarios below: minimal, overflow, guard, long labels, UxTableList
Sep 22
Picker open with side=above — the list rises over the title area, so every column of the Devices table stays visible while toggling; Device locked, Show all in the header, count + Done in the footer
Picker open with side=above — the list rises over the title area, so every column of the Devices table stays visible while toggling; Device locked, Show all in the header, count + Done in the footer
Sep 22
Owner unchecked — the column drops out of the fully visible table while the panel stays open; the badge reads 6 of 10
Owner unchecked — the column drops out of the fully visible table while the panel stays open; the badge reads 6 of 10
Sep 22
/components/table/ux-column-picker
/components/table/ux-column-picker
Sep 22

Page evolution (c96): every capture carries a subject (page/teams, component/data-ranked-bars) so the same page joins across cycles, threads, and surfaces — mock → qcontrol preview → qdash; /cycles/evolution lists the subjects and each subject page compares any two moments by wipe, onion skin, side-by-side, or sequence

/cycles/evolution/page/teams — six moments of the Teams page from the c81 mock through the c89 teams-v3 mock, the c90 qcontrol preview, and qdash after c92 band-polish; the strip on top, the wipe stage comparing c81 (A) with c92 (B), the record for each side beneath
/cycles/evolution/page/teams — six moments of the Teams page from the c81 mock through the c89 teams-v3 mock, the c90 qcontrol preview, and qdash after c92 band-polish; the strip on top, the wipe stage comparing c81 (A) with c92 (B), the record for each side beneath
/cycles/evolution — 132 subjects, 23 with history; cards pair the first and latest capture, name the cycles spanned and the surfaces seen; history only is the default filter
/cycles/evolution — 132 subjects, 23 with history; cards pair the first and latest capture, name the cycles spanned and the surfaces seen; history only is the default filter
Sep 25
The same pair in onion-skin mode — B blended over A at the slider's opacity; the mode and both captures are in the URL, so a before/after is a link
The same pair in onion-skin mode — B blended over A at the slider's opacity; the mode and both captures are in the URL, so a before/after is a link

Gen-1 origin (c97): six PR 521 screenshots of the vibe-coded qdash prototype recovered from qcontrol git history and placed as the first moment on Fleet Overview, Inventory, Control Center, Enforcement, Alerts, and Targets — origin + asOf fields on the manifest let pre-cycle artifacts sort at their own date

/cycles/evolution/page/inventory after the import — Gen-1 prototype (2026-06-30, qdash) → c81 mock → c92 qdash; the Gen-1 origin labels the moment where a cycle would, and the wipe compares the empty prototype table with the live page
/cycles/evolution/page/inventory after the import — Gen-1 prototype (2026-06-30, qdash) → c81 mock → c92 qdash; the Gen-1 origin labels the moment where a cycle would, and the wipe compares the empty prototype table with the live page
/cycles/evolution/page/teams after the rebuild — the Teams page now begins at the Gen-1 prototype (rebuilt from PR 521, replayed data: Priya, Marcus, Samir, Dana ranked by risk) before the c81 mock, the c89 mock, the c90 preview, and qdash after c92
/cycles/evolution/page/teams after the rebuild — the Teams page now begins at the Gen-1 prototype (rebuilt from PR 521, replayed data: Priya, Marcus, Samir, Dana ranked by risk) before the c81 mock, the c89 mock, the c90 preview, and qdash after c92
No cycle15 shots
Fleet Overview populated — the scorecard goes red where the replay trips it (two critical findings, non-allowlisted egress, 2 of 5 installs untapped), token usage by agent, what agents do, fleet posture, top risks, activity and token charts, the agents-in-use ledger
Fleet Overview populated — the scorecard goes red where the replay trips it (two critical findings, non-allowlisted egress, 2 of 5 installs untapped), token usage by agent, what agents do, fleet posture, top risks, activity and token charts, the agents-in-use ledger
Agent Identity — credential governance from observed auth: oauth vs api_key, org and account ids, quota
Agent Identity — credential governance from observed auth: oauth vs api_key, org and account ids, quota
Agent Inventory populated — one row per tool × user with sessions, tokens, cost, activity, posture (Marcus's yolo run reads Critical), last active
Agent Inventory populated — one row per tool × user with sessions, tokens, cost, activity, posture (Marcus's yolo run reads Critical), last active
Alerts populated — delivery channels and rule matches
Alerts populated — delivery channels and rule matches
Compliance — framework control mapping with per-control depth and honest evidence
Compliance — framework control mapping with per-control depth and honest evidence
Control Center populated — the same eleven seeded controls now with live match counts, and the framework packs' provable rows lit
Control Center populated — the same eleven seeded controls now with live match counts, and the framework packs' provable rows lit
Cost Center — spend by model, by agent, by user and over time from list-price estimates plus provider-billed cost on llm.response
Cost Center — spend by model, by agent, by user and over time from list-price estimates plus provider-billed cost on llm.response
Data Protection — sensitive-file access by category, volume, and user
Data Protection — sensitive-file access by category, volume, and user

A living Design status surface for /cycles — four lo-fi directions (workboard, standup feed, matrix, rulings), four layer mockups of the same, and the promoted M5 Current Matrix: live work first, closed archive hidden, a decision queue, explicit row and column definitions

/pages/_meta/cycles-status-wf1-workboard — WF1 Workboard — lo-fi: four operational lanes make working-now, waiting, seeds, blocked and recently-closed cycles visible at standup speed
/pages/_meta/cycles-status-wf1-workboard — WF1 Workboard — lo-fi: four operational lanes make working-now, waiting, seeds, blocked and recently-closed cycles visible at standup speed
Sep 21
/pages/_meta/cycles-status-wf4-rulings — WF4 Rulings — lo-fi: decision-first desk where parked, blocked and needs-ruling cycles sit above ordinary active work
/pages/_meta/cycles-status-wf4-rulings — WF4 Rulings — lo-fi: decision-first desk where parked, blocked and needs-ruling cycles sit above ordinary active work
Sep 21
/pages/_meta/cycles-status-wf3-matrix — WF3 Matrix — lo-fi: stage-by-attention portfolio map that exposes imbalance, stale work and backlog shape
/pages/_meta/cycles-status-wf3-matrix — WF3 Matrix — lo-fi: stage-by-attention portfolio map that exposes imbalance, stale work and backlog shape
Sep 21
/pages/_meta/cycles-status-wf2-standup — WF2 Standup Feed — lo-fi: chronological work feed with a decision-queue rail for teammates asking what changed since the last look
/pages/_meta/cycles-status-wf2-standup — WF2 Standup Feed — lo-fi: chronological work feed with a decision-queue rail for teammates asking what changed since the last look
Sep 21
/pages/_meta/cycles-status-m5-current-matrix — M5 Current Matrix — the promoted candidate: M3 evolved with live work first, closed archive hidden by default, a decision queue and explicit row / column definitions
/pages/_meta/cycles-status-m5-current-matrix — M5 Current Matrix — the promoted candidate: M3 evolved with live work first, closed archive hidden by default, a decision queue and explicit row / column definitions
Sep 21
/pages/_meta/cycles-status-m4-rulings — M4 Rulings — layer mockup: decision-first ruling surface for parked, blocked, stale and abandon-candidate work
/pages/_meta/cycles-status-m4-rulings — M4 Rulings — layer mockup: decision-first ruling surface for parked, blocked, stale and abandon-candidate work
Sep 21
/pages/_meta/cycles-status-m3-matrix — M3 Matrix — layer mockup: stage matrix plus a dense supporting table on the data-table pattern
/pages/_meta/cycles-status-m3-matrix — M3 Matrix — layer mockup: stage matrix plus a dense supporting table on the data-table pattern
Sep 21
/pages/_meta/cycles-status-m2-standup — M2 Standup Feed — layer mockup: event-feed landing with compact decision and seed rails
/pages/_meta/cycles-status-m2-standup — M2 Standup Feed — layer mockup: event-feed landing with compact decision and seed rails
Sep 21

The qcontrol preview — seven page mocks behind a left nav and app chrome that mimics the real shell

/qcontrol/teams — the combined Teams, Users & Devices listing behind the qcontrol chrome: NavJumpPills over three sections, User Coverage / Devices Sensored band, the Team trigger bar (later flipped to the timeframe pill in c92)
/qcontrol/teams — the combined Teams, Users & Devices listing behind the qcontrol chrome: NavJumpPills over three sections, User Coverage / Devices Sensored band, the Team trigger bar (later flipped to the timeframe pill in c92)
/qcontrol/device-v2 — Device Detail (working copy; device.vue frozen as the archive), the page still in manual design when c92 rebuilt Machine Detail without it
/qcontrol/device-v2 — Device Detail (working copy; device.vue frozen as the archive), the page still in manual design when c92 rebuilt Machine Detail without it
/qcontrol/devices — Devices listing: a DeviceRow per world device with coverage gap and headline, its band and verdict
/qcontrol/devices — Devices listing: a DeviceRow per world device with coverage gap and headline, its band and verdict
/qcontrol/team — Team Details: team switcher, verdict, coverage / sensored rings, using-AI and tokens tiles, People ranked uncovered first
/qcontrol/team — Team Details: team switcher, verdict, coverage / sensored rings, using-AI and tokens tiles, People ranked uncovered first
/qcontrol/user-v3 — User Detail v3 executing the dropped annotated mock: compact identity header, 'Total Session per Agent' history graph with clickable headline stats, scroll-anchor tabs, device cards with nested Agents tables
/qcontrol/user-v3 — User Detail v3 executing the dropped annotated mock: compact identity header, 'Total Session per Agent' history graph with clickable headline stats, scroll-anchor tabs, device cards with nested Agents tables
/qcontrol/user-v2 — User Detail v2, frozen as the historical archive: verdict line, chain strip, Models card, full Accounts / Surface detail
/qcontrol/user-v2 — User Detail v2, frozen as the historical archive: verdict line, chain strip, Models card, full Accounts / Surface detail
/qcontrol/sessions — Sessions listing copied from c89's phase1/sessions: verdict, a stat pair with no ring, a named 'needs a look' list, the DataTable
/qcontrol/sessions — Sessions listing copied from c89's phase1/sessions: verdict, a stat pair with no ring, a named 'needs a look' list, the DataTable

Releases & deploys

Layer releases 2

v0.9.22Sep 26v0.9.22: UxCodeBlock lang, NavVerticalSubmenu, DataListingBar + UxPopover + UxColumnPicker, DataMachineGroup + listing restyle, UxPageTitle zero-height #right
v0.9.21Sep 25v0.9.21: FilterTriggerBar restyle (right-aligned segmented bar), FilterNoMatches, DataTable #empty slot

Design-site deploys 0

No deploys recorded this week.

Note: Deploys come from this checkout's deploy-branch reflog, which starts 2026-10-16.

Qpoint Brand Style Guide