Skip to content

Releases: DkPanseriya/deckhq

v1.7.0

Choose a tag to compare

@github-actions github-actions released this 09 Oct 18:59

Highlights

The office has been redrawn, and it is lit. Daylight comes in through the windows, furniture looks
like furniture, rooms stand behind solid, glass or low partitions and are dressed like rooms
somebody works in, and each project's room can have a colour of its own; there are eleven styles
to choose from, with Light and Room colours beside them. Sub-agents read as juniors: a
size smaller than their lead, cross-legged on the floor with a laptop and a Junior chip, and a
lead whose crew is still working stays at its desk. A git worktree is a bench inside its
repository's room, not a room of its own. Go to session — one button, or O — brings the
window a session is already running in to the front, and the panel's transcript reads like a
document, with tables, code you can copy and each tool call folded to one line. A Look button
and a Settings button are in the header. A floor where nothing is moving is not redrawn, and a
DeckHQ window pinned to the Windows taskbar keeps DeckHQ's icon.

Added

  • A Look button in the header. Click it, or press L, and a small panel opens under it with
    the six things people change most: agent size (small, medium, large, auto), theme,
    style (eleven presets, as pictures, four to a row so all of them are in view at once),
    density, light and room colours. A click changes the floor straight away. Esc, L
    again or a click anywhere else closes it. All look options… at the bottom opens the full
    Look section. If a choice would leave the floor unreadable, the panel says why under the
    control and changes nothing.
  • Density. One control, Calm / Normal / Lively, for how many plants and props are on the floor.
    It moves the two together. If you want them different, set each one under Advanced.
  • A Settings button in the header. The gear beside Look opens the settings sheet. , does the
    same from the floor. Ctrl K → Settings still works.
  • Section names at the top of Settings. State, Notifications, Resume, Floor, Look, Data and
    Hooks are listed across the top of the sheet and stay there as you scroll. Click one to jump to
    it.
  • A one-time pointer to the Look button. The first time you open a version that has it, one
    line under the button says "Change the floor, the furniture and the agent size here." Press
    Got it, or just use the button, and it does not come back.
  • Light: morning, noon or evening. Three words in the Look panel and at the top of Settings →
    Look, beside Density, moved with a click or the arrow keys. It turns the one light on the floor
    — 30°, 45° or 60°, always falling down and to the right — makes every shadow longer in the
    morning and longer still in the evening, and colours the daylight on the floor cool, warm or
    amber. Noon is the default.
  • Partitions: solid, glass or low. Under Look → Advanced, in Walls and room colours, each
    choice a small picture of two rooms and the wall between them. It changes what stands between two
    rooms. Solid is a band that casts like a wall. Glass is a sheet between two thin dark frame lines
    with a post every few units, and casts nothing. Low is a waist-high divider with rounded ends
    that stops short of each corner. The building's outside wall does not change.
  • Three more floors: oak plank, fine herringbone and felt carpet. In the floor pickers under
    Advanced — oak plank for the office, the rooms and the lounge, fine herringbone for the office
    and the lounge, felt for the office and the rooms. They are laid at the size of a real floor: a
    board about 18 cm wide, a parquet block about 11 cm, and a felt with a fine grain and no weave.
    Their seams are exactly one pixel of your screen wide.
  • Room colours: subtle, zoned or off. A switch in the Look panel and at the top of Settings →
    Look: off is Subtle, on is Zoned. Space or Enter throws it. All three levels are under Advanced,
    in Walls and room colours, and while Off is chosen there the switch reads off and says Off.
    Subtle is the floor as it was: each
    project room's carpet leans a little toward its project's colour, and on a floor of five rooms
    the five are nearly the same beige. Zoned gives each project's room one of six calm colours —
    sage, powder blue, lilac, mint, straw, rose — so two rooms side by side are told apart before
    you read a plate. The colour is the floor's own brightness, so names and state colours read
    exactly as they did: on the Colour plan style a name is 11.2:1 on the default theme, 10.3:1 on
    night shift and 11.7:1 on blueprint, and two neighbouring rooms are at least 14.7, 23.0 and 21.6
    RGB apart (subtle: 1 to 3). It works on every floor a room can have, wood included. Off is the
    bare floor. Your agents keep their own colours.
  • Five more styles, which makes eleven. Daylight studio is pale ash under noon light with
    glass between the rooms. Nordic wool is cool ash, cork and broadloom with low dividers under
    morning light. Graphite loft is grey terrazzo and loop pile with dark frames behind glass, under
    evening light. Colour plan gives every repository its own colour on a neutral building. Walnut
    executive is fine herringbone and cork in a clay wash. ?look=daylight-studio,
    ?look=nordic-wool, ?look=graphite-loft, ?look=colour-plan and ?look=walnut-executive
    open the floor in them, and a look file exported from an earlier version still imports exactly
    as it was.
  • A style's card shows its rooms, its walls and its light. Each of the eleven cards is painted
    by the floor's own painter, and now shows two project rooms side by side in the colours that
    style gives them, the partition between them, and shadows as long as its light throws. Colour
    plan's card has a green room beside a blue one; before, it was a picture of a grey office, much
    the same as two others. The cards' shadows are also the length they are on the floor — they
    were drawn at half of it or less.
  • Daylight is one of the figures under Advanced. The line of measured contrast at the foot of
    the Look section ends with daylight on the floor: how bright the strongest patch of daylight
    is against the floor it lands on, in the light and the theme you are looking at. It is the
    number the light is refused on, and it is never above 1.18:1.
  • Rooms look lived in. A room used to have the right furniture and bare walls. Each project
    room now has a waste bin by its desks (and one at each worktree bench), a coat stand beside its
    door, felt panels on its clear walls, and a lamp over a meeting table. Where one desk sits in a
    room with empty floor, the room also gets a second place: a standing table with stools, a
    reading corner with an armchair and a floor lamp, a booth for a call, or a whiteboard with two
    stools. Nobody is ever seated at these, and nothing is put within a body's width of a seat, in
    a doorway or on the way from the door to a desk. On the demo floor that is 35 more things in
    five rooms; on a 150-agent floor, 199 in 22.
  • Density changes how much of that there is. Calm keeps only the bin and the coat stand.
    Normal adds the panels, the lamps and up to two second places a room, three in a big team's.
    Lively allows three in any room, and a planter run beside a reading corner.
  • A sub-agent's name tag has two rows. The first is a small chip that says Junior, on a
    dark background of its own; the second is its name, without the ·jr that used to follow it. A
    session of your own keeps one row. The same word is in the tooltip, in the deck's rows and in a
    crew's list. On the chip the word is 8.7:1 against its background on the default theme, 12.1:1
    on night shift and 13.2:1 on blueprint.
  • A sub-agent working on the floor has a laptop. It sits cross-legged with a small open laptop
    on the carpet in front of it: the screen is lit green while its transcript is moving, and the
    lid is shut once it has stopped. This was drawn for a crew of three or more and is now drawn for
    one or two beside their lead as well, who used to stand. A sub-agent at a real desk or on a sofa
    sits in the furniture as before.
  • Go to session. The panel has one button under the agent's name that takes you to where that
    session is already running: the terminal, the editor or the Claude desktop app it is in comes to
    the front, and the line beside the button says which — Windows Terminal — tab "fix the parser".
    It never starts a second copy of a running session. O does the same from the keyboard, and
    Ctrl K has Go to …'s session. In Windows Terminal the session's tab is selected when its
    title is the only one of its name; in the desktop app the app is opened on that session. When
    the session has ended, the same button reads Resume in … and resumes it where you chose in
    Settings. When a running session cannot be reached, the button is dead and says why. Measured on
    Windows 11; written and not yet run on macOS and Linux, and deckhq doctor has a
    go to session row that says which your machine is.
  • A reply reads like a document. Tables are tables, task lists have their boxes, headings step
    down in size, and prose stops at a readable line length. A code block shows its language and has
    a copy button. A web link opens in a new tab. A file reference such as src/panel.js:42
    opens that file at that line in your editor.
  • What the agent ran is in the panel. Earlier in the conversation is folded above the answer,
    and it now includes each tool call as one line — Bash npm test, Edit src/panel.js — that
    opens to its input and its result. A sub-agent's hand-back opens to its report. latest ↓
    takes you back to the answer. Claude Code sessions only.
  • Open in the session. An artifact, a picture you attached, and a result too long to show in
    full each have a button that takes you to the session itself...
Read more

v1.6.2

Choose a tag to compare

@github-actions github-actions released this 06 Oct 15:41

Highlights

Subagents now have first names, with a small junior mark (Marta·jr), and keep their names and
numbers when DeckHQ restarts. Names stay next to the people they belong to, even in a crowded
office. A project whose sessions are all waiting on you shrinks to a small room, and your office is
only as wide as its sofas, so the rooms get the space.

Changed

  • Subagents have names. A subagent used to be labelled with its parent's tag and a number,
    MK129.5j8. It now gets a first name from the same list as everyone else, with a small junior
    mark after it, Marta·jr, and keeps that name when DeckHQ restarts. The panel shows its parent
    beside it. A subagent can share a first name with one of your sessions; the mark tells them
    apart, and deckhq open <name> still finds the session.
  • A project whose sessions are all waiting on you gets a small room. If everyone from a
    project is on the sofas in your office and nobody is at a desk, the project keeps a room, but a
    small one along the bottom of the working side, with one desk and its N need you line. The
    room grows back to full size as soon as one of its sessions starts working again.

Fixed

  • Names stay next to the person they belong to. In a crowded office, names could end up a row
    or two away from the people they named, across the rug. A name now goes under the figure, over
    its head, or beside it. If none of those spots is free, the name is drawn smaller, then cut to
    four letters and a dot (Cass.). Only after that can it move further away, and when it does, a
    thin line joins it to its figure. A name in the lounge that has no free spot next to its figure
    is not drawn.

  • Your office no longer takes the whole width when your projects are waiting on you. With
    several projects shrunk to small rooms, the office could stretch across most of the window: a
    long empty rug with the waiting sessions along its edges. The office is now only as wide as its
    sofas need. The extra width goes to the project rooms, so the small rooms stand in one row, and
    the lounge below gets any height left over.

  • A subagent keeps its number when DeckHQ restarts. Subagent numbers were kept in memory, so
    restarting DeckHQ after some subagents had finished could renumber the ones still running.
    Each number is now saved in ~/.deckhq/state.json with the other names and numbers, so a
    subagent keeps it across restarts, and a new subagent takes the next number its parent has not
    used. Only the most recent 64 numbers per session are remembered for subagents that have
    finished, so the file does not grow with every subagent ever run.

Testing

  • The look import and export tests touch nothing outside the test. Once in a full run,
    look-io.test.mjs passed every test and still exited with a failure, with no message. Its
    command-line tests now replace every connection, file and output with a stand-in, and a check
    at the end fails with a name if anything the tests started is still running.

v1.6.1

Choose a tag to compare

@github-actions github-actions released this 24 Sep 17:53

Highlights

A patch for what the first real floor showed. Working subagents were drawn beside a waiting parent
in your office; they now sit at the desks in their project room. On a busy floor, names and room
plate lines no longer vanish, and the building fills your window instead of leaving dark bands.
Subagents in worktrees form one crew, "at desk" counts only the sessions at desks, a subagent keeps
its name, and a finished session stays still.

Fixed

  • Working subagents sit at the desks in their project room, not in your office. With several
    sessions running, the desks could be empty and everyone shown working in the office. Subagents
    were placed beside their parent session wherever it was, so when the parent finished its turn and
    sat on the office sofa to wait for review, its thirteen still-working subagents stood round the
    sofa. Each session is now placed by its own state. A working subagent takes a desk in its
    parent's project room: beside the parent's desk when the parent is at one, and its own desk when
    it is not. Three or more work in the usual arc, cabled to the room's first free desk, with the
    parent's name on that desk and the +N chip beside it. A subagent that has finished rests in the
    lounge, and one that needs your input waits in your office. A project with a working session in
    it always has a room, even when that session is a subagent running in a worktree with no session
    of its own. A benched session stays in the lounge even when it is working again, because the
    bench is yours to lift.
  • Subagents running in git worktrees form one crew. A subagent started in its own worktree
    reports that worktree as its project, so five subagents of one session could be five crews of one
    and the arc never formed. They are now grouped under the parent's project, and they still share
    one room when the parent is not on the floor.
  • "At desk" counts the sessions at desks. The header counted every subagent as at a desk,
    including finished ones and ones shown in your office. It now counts exactly the working and
    stalled sessions the floor seats at a desk, subagents included, and never a finished, benched or
    waiting one.
  • A subagent keeps its name. Subagent names were numbered by position among the ones running,
    so when one finished, the others after it were renamed and a name you had just read pointed at a
    different subagent. Each subagent is now numbered once, when it first appears, and keeps that
    number.
  • The crew chip counts one crew. With reduced motion on, the chip counted working subagents
    among the twelve drawn but divided by the whole crew, so it read "6/13 working" while seven
    were. Both numbers are now over the whole crew, and +N is only the subagents not drawn.
  • Source files no longer contain raw NUL bytes. Four files used one as a separator, which made
    search tools treat them as binary. They use an escape now, and a test keeps it that way.
  • A busy floor in a laptop-sized window keeps its names and its counts. With about 150 sessions
    in a window around 1400 x 800, the floor dropped to its lowest level of detail and stopped drawing
    every name, every room's N need you line, and the cables and +N chip of a subagent crew.
    Detail is now decided by how tall a person is drawn, and the smallest people only lose their
    outline, chest mark and far arm. Names, the need you line, cables and the +N chip are drawn at
    every size. A room plate that is short on space sets its lines smaller before it drops one, drops
    the "doing" line before today's tokens, and never drops the need you line. When the plate is too
    narrow for that line it shortens to the dot and the number.
  • Names no longer land on room plates, people or each other. Names under the bottom row of your
    office were drawn over the Lounge plate, and a crew of subagents printed the same type five times
    on top of itself. Room plates now count as obstacles. A name that has no room below its person
    moves to the side, or above the person's head. A crew shows each type once, with a count, such as
    general-purpose ×5.
  • Finished sessions sit still. A session that has ended used to keep bobbing and blinking in the
    lounge after it powered down. It now powers down once and stays still.
  • The office fills your window. On a wide window the building used to stop short and leave
    dark ground down both sides, a quarter of the width on a busy floor, or above and below it when
    the floor was laid in two rows. The building is now the shape of the window, so it fills it edge
    to edge. The project rooms take the extra width as open floor round their desks, which stay where
    they were. The lounge can widen and come down to meet them, and the reception grows its waiting
    area. A one-room floor on a very wide or very tall window can still leave some ground, rather
    than turn its one room into a hall.
  • No empty strip under the project rooms. When the lounge was taller than the rows of rooms
    beside it, the difference was left as a bare strip of floor under the rooms. The rows and the
    lounge now end on the same line: the rooms grow a little deeper, move into another row, or the
    lounge is laid wider and shorter, whichever leaves the least of your window unused.

v1.6.0

Choose a tag to compare

@github-actions github-actions released this 24 Sep 16:22

Highlights

Studio is complete, from an idea to tracked work. Plan, hire a role, and move its cards across a
six-column board, from the keyboard if you like. A role hands its work back in a file you accept
or bounce; each card shows the tokens and time it spent; a regular pass flags drift; and a card
over its budget is blocked. The robots sit — at desks, on sofas, cross-legged with laptops. The
board fits any window, the floor fills the window again, and Linux screenshots are now checked too.

Added

  • The Studio board. A project with Studio on now has its cards as a board, beside the floor:
    six columns — Backlog, Ready, In progress, Review, Done, Blocked — with each card showing its
    title, who it is assigned to and that person's own robot, how many acceptance criteria it has,
    its budget and any flags raised against it. ⌘K → Studio: board opens it, and so does the
    board control beside board.json in the panel. Esc, the ✕ and Back to floor all close
    it, and closing it selects the assignee of the last card you clicked, so you land on that desk.

    Underneath the columns is a real table of the same cards in the same order, so a screen
    reader gets the whole board rather than a pile of boxes.

    Every card is reachable and every move is performable from the keyboard. Tab walks the cards;
    [ and ] — or the left and right arrows — move the focused card one column, and say where it
    went; Enter opens it for editing. Dragging does the same thing. A move you make is shown
    immediately and, if DeckHQ refuses it, the card goes back where it was and you are told why in
    DeckHQ's own words rather than left looking at a card that silently moved back.

    A card's column stays yours. A session ending, a hook arriving and a scan completing move no
    card — they flag it, and you move it.

  • A card can start the work. Move a card into Ready and the role it is assigned to gets it:
    if that role has no session yet, it is hired with this card as its brief; if it already has one,
    the card is sent as the next thing to do. A card with nobody on it asks who, and never
    guesses
    — nothing is started until you say.

  • Cards are written from the board. New card, or Enter on one you have, opens an editor for the
    title, the acceptance criteria, the milestone, the assignee and the budget. Anything DeckHQ
    refuses is shown beside the field it is about, with what you typed still in it.

  • The handover, and the review gate. A hired role's brief now carries one instruction: when it
    believes a card is done, it writes .deckhq/studio/handovers/<cardId>.md with what changed, the
    tests it ran and their real counts, open questions and the next step. DeckHQ watches that folder.
    When a handover lands, the card is flagged and never moved — the flag shows as a chip on the
    board — and the session's review card shows the handover above what it said, next to the diff of
    its own worktree, so you can read what it claims beside what it actually changed.

    Two answers, and they are yours: Accept handover, where you name the column the card moves to
    — Review or Done — or Bounce, with a note. A bounce leaves the card where it is and the note
    arrives in that role's next brief, so it comes back knowing why.

    Test counts are quoted, never believed. The panel says "the handover says 41 passed" and
    attributes it; DeckHQ runs nothing to check it and never prints the figure as its own. A handover
    that leaves a section out is reported as missing rather than filled in, and a handover whose
    filename matches no card is shown unattached rather than quietly dropped.

  • Tracking, on every card. Each card on the board now shows how many tokens its session spent
    while the card was in progress, how long it spent in progress, and the tests its handover says it
    ran, quoted as the handover's own sentence. Every figure comes from a file you can open — your
    ledger, the card's own record of when it was moved, the handover — and a figure with nothing
    behind it says no data, never zero
    . With Show cost on, a card also shows its list-price
    estimate with the date of the rate card, and a model the rate card cannot price shows no rate
    instead of a number.

  • Milestones and the burn-down. Above the columns, one line per milestone: how many of its
    acceptance criteria are ticked and how many of its cards are left. The ticks are yours — the card
    editor has a checklist of the card's criteria — and nothing DeckHQ observes ever ticks one.

  • The PM pass. Every 30 minutes, and whenever you ask, the planner is handed the blueprint, the
    board and the handovers since the last pass, and asked what has drifted. What it says appears as
    flags on the cards and in the planner's review card. A flag never moves a card, reassigns a
    role or stops a session; what to do about it is your call.

  • The budget stop. When a card in progress runs past its budget — tokens or minutes, whichever
    comes first — DeckHQ moves it to Blocked, stops sending that role's session any more work
    (and says which card and which budget when you try), and sends the session one message asking
    it to stop and write its handover. DeckHQ does not kill the session: it did not start the
    terminal it runs in and it cannot promise to stop it, so it does not claim to. Move the card out
    of Blocked and sending works again — raise its budget first, or the next check stops it again. This is the only time DeckHQ itself
    moves a card, and Blocked is the only place it can move one to.

Testing

  • The Linux goldens are baked on Linux, by CI, and committed by a person. npm run goldens
    only writes the platform it runs on, so the Linux set could only be baked on a Linux machine, and
    until this release test/goldens/linux/ was empty and CI's goldens job reported every capture
    as not yet baked. A new manual workflow, Goldens bake (.github/workflows/goldens-bake.yml,
    optional populations input), runs the bake on ubuntu-latest with Node 22 and the runner's own
    Chrome, prints one line per capture, and uploads test/goldens/linux/ as goldens-linux-<sha>
    for 7 days. It has only the default read token and never pushes. The Linux set now holds all 18
    captures, baked by that workflow and committed after a look.
    node scripts/goldens-import.mjs <dir-or-zip> puts a downloaded artifact into
    test/goldens/linux/. Every file has to be <capture>.png for a capture that
    node scripts/goldens.mjs --list (new) names, and has to be a PNG, or the whole import is
    refused and nothing is placed. It reads the artifact zip without a dependency. An empty input
    exits 2. CONTRIBUTING.md has the four steps.
  • A release refuses to ship with a gap in a Linux set that exists. publish.yml gains a
    goldens job, and publish now needs it. It runs with --strict when test/goldens/linux/ holds
    at least one PNG, and without it when the directory has none. --strict on its own would have
    refused 1.4.0 and 1.5.0, which were both tagged with an empty Linux set. Pushes and pull
    requests stay non-strict. test/unit/goldens-import.test.mjs holds the importer and the shape
    of both workflows (13 tests).

Changed

  • The board fits the window. All six columns are on screen at once, with the panel open or
    shut — the board gives the panel its room and arranges itself in what is left, and it never
    scrolls sideways. Where six side by side will not fit, it becomes two rows of three; in a narrow
    space (under 900 px) it shows one column at a time, with a row of buttons naming all six and how
    many cards each holds — tap one to see it, or drag a card onto one to move it there. An empty
    column is a thin strip with its name on its side, and opens when you point at it or drag a card
    over it. Column names stay in view as you scroll. A card is four short lines: its title, who has
    it, one row of chips, and one line of figures — 400k tok · 12 min · says 43 passed — or a
    single no data when there are none yet. The project's path shows its last two folders (point
    at it for the whole path), and the how-to line is behind a ? beside New card.

  • The robots sit down. Until now every figure on the floor stood, including the ones at a
    desk, on a sofa and in a crew. A session at its desk now sits at the chair with its hands on the
    keys; a session waiting in Your Office, and a benched one on a lounge sofa or at the board-game
    table, sits back on the cushions with its legs out; and a crew of juniors sits cross-legged on
    the floor with each laptop on its knees — the lid open while that junior is writing and shut once
    it has stopped, exactly as the floor laptop did, and the cable now runs into it. Anyone walking,
    queueing, or standing beside a parent's desk stays on their feet.

    Nothing you read moved. Each figure's name, halo, shadow and click target sit where they did,
    under its feet; only the body above them is lower. A raised hand stays exactly where it was, so
    seated it clears the robot's head by more than it did standing, at every zoom. The typing, the
    wave, the page flip and the stall still animate on a seated robot, and a seated robot drawn small
    simplifies to one shorter shape rather than to a smudge of legs.

Fixed

  • The floor fills the window again when it has five or six busy projects. Such a floor could be
    laid as one long row of rooms with the lounge underneath, a building much wider than the window,
    so it was drawn with a dark band above it and another below — on the 1600 × 1000 demo floor the
    building used rows 206–922 of 1000. When one way of laying the floor fits the window and the
    other does not, the two are now compared by how much of the whole window each leaves unused,
    rather than by how much of its own rooms' side is bare. The demo floor now us...
Read more

v1.5.0

Choose a tag to compare

@github-actions github-actions released this 19 Sep 11:01

Highlights

Studio can hire. Ask for a role and DeckHQ makes it a workspace of its own, writes it a brief,
and starts a real session there — and it says plainly what it will not do. Sessions and worktrees
are matched by the folder they are in rather than by how the folder is spelt, so a Windows path
that has two names is recognised either way. The website and the README describe the product and
nothing else: the planning documents have moved to a private repository.

Added

  • Hire — WP-68. Studio's roster now starts people. POST /api/studio/hire takes { role } or
    { roles: […] } and, per role, does four things: git worktree add <state>/worktrees/<project>-<role> -b studio/<role>, an argv array with no shell anywhere in it; a brief file under
    .deckhq/studio/briefs/<role>.md, which is never regenerated under a running session and never
    overwritten when the user has edited it (the regeneration goes beside it as <role>.next.md); a
    session started in that worktree, under that brief, where the brief's path is on the command
    line and the brief's body never is; and roster.roles[i].agentId written down when the ORDINARY
    scan finds the session — no private session list, matched by the worktree directory it is running
    in. The command palette carries one Studio: hire <role> row per role that is not already at a
    desk, and the panel's Studio block grows a line per role beneath the three files: not hired, hired
    with its id, hired-unverified, or the reason the name cannot be hired. Firing leaves the worktree
    and the process alone, and says so.
    docs/DEVIATIONS.md §188.

Changed

  • Planning documents moved to a private repository. The requirements, architecture,
    specifications, plan, deviations and designer mockups are no longer part of this repository;
    the source, its tests, the manual and the adapter contract stay public and MIT.

  • The website is the product now, and the blueprint is not on it — WP-95a. The owner: "The
    website is purely public marketing and PR. Do not put requirements and architecture docs there.
    We only put the product public and its features."
    The site was eleven pages and 171 generated
    ones
    — the whole decision log, an entry per page — plus a Docs page linking every document in
    docs/. It is nine marketing pages now: Home, Features, Look, Characters, Studio, Install, FAQ,
    Privacy and security (new, in plain words, with the route for reporting a vulnerability) and
    Changelog (new, generated from the Highlights paragraph of each release and nothing under
    it). The bar is six links with no "More" disclosure; the footer is GitHub, npm, the licence and
    privacy. A gate in site/build.mjs refuses to write any page carrying docs/plan, DEVIATIONS,
    00-REQUIREMENTS, 02-ARCHITECTURE, ARCHITECTURE-AUDIT, STUDIO-DESIGN, RELAY-DESIGN, a
    work-package id or a section number, and the same list runs over README.md, whose Docs table
    now lists only the guide, the changelog, the security policy, the licence and ADAPTERS.md.
    docs/DEVIATIONS.md §189.

Fixed

  • A session is recognised by its directory, not by how the directory was spelt. DeckHQ finds
    the session it has just started by the folder it started it in, and compared two spellings of
    that folder as strings. Where a folder has two names — a symlink (every macOS temp directory), a
    junction, a Windows short name — the two never matched: a name chosen with + was never applied,
    a Studio planner and a hired role were never recognised, and hiring a role a second time was
    refused
    as "already exists and is not a worktree of this repository" by the hire that made
    it. All four comparisons are by directory now, in one place, src/core/same-path.mjs. A session
    that reports no folder at all no longer matches the folder DeckHQ itself was started in.

  • The project hub's footer survives a tab press. It was appended to #main, and every tab
    switch rewrites main.innerHTML — so the footer was there until the reader pressed a second tab
    and then gone for good. It is inserted after #main now. docs/DEVIATIONS.md §190.2.

  • The project hub's tab bar is bound once, not once per render. renderChrome() attached the
    bar's click listener and the listener calls renderChrome(), so the nth press ran the handler n
    times and re-rendered the page n times over. The delegated listener moved to start-up; the bar's
    element is never replaced, only its innerHTML. §190.3.

  • The site no longer says three shipped features are unbuilt — WP-95a. Look, agent size and the
    crew landed in 1.4.0, and Look and Characters still carried "None of it is built" over four
    mockups of them. Those pages describe what you can go and use, and the site publishes no mockup
    at all.

Testing

  • scripts/dashboard/template.mjs is back under the 900-line ceiling, with no exemption row.
    Prettier's reformatting of the one long template string had put it at 1,109 lines. The stylesheet
    moved verbatim to template-css.mjs (258 lines) and the client script to template-script.mjs
    (756 lines, as clientScript(data) because the footer interpolates two links); template.mjs
    keeps the helpers, the markup and the assembly at 109. Proved a move and not a rewrite: the built
    page is byte-identical before and after, by cmp. §190.1.
  • test/integration/studio-hire.test.mjs's three-role acceptance no longer fails under load.
    Its roster poll ran a fixed five seconds and asked for a scan only every tenth round, so a
    loaded machine could finish the loop before the third role's agentId had been recorded. Every
    round now triggers a scan and waits for it, the loop leaves the moment all three ids are on disk,
    and the 45-second bound is a failure path — reached, it reports the rounds, the elapsed time and
    the roster. The fake CLI fixture fsyncs its transcript before exiting. Ten consecutive runs
    green with a full npm test running beside them. §190.4.

Refused, and why

  • Everything a Hire can refuse is refused before the first worktree exists. No consent, an
    unknown runtime, a runtime with no openNewSession (refused by name, never silently skipped),
    a role that is not in roster.json, a role name carrying a space, a quote, a ;, a leading dash
    or a path separator — git is never asked to escape a name, and a seventh role in one press is
    refused with the count, because "too many" is not a number anybody can act on. A failure after
    that point is reported per role rather than rolled back: a worktree that exists is a fact.

Known gaps

  • Hired roles have not been measured doing work. The one real run of WP-68 made two worktrees,
    two briefs and two real claude sessions on the reference machine, and the ordinary scan found
    both and wrote both ids into roster.json — but the stored login on that machine is expired
    (OAuth session expired and could not be refreshed), so neither session got past authentication.
    §188.1 records it verbatim. One claude login is what is owed.
  • A Codex, Gemini CLI or OpenCode role is hired unverified. No terminal has ever been opened
    on those three by this project. They are hired, the floor degrades for them exactly as it already
    does, and both the response and the panel's roster line say so rather than pretending.
  • There is no roster screen. Roles are added, renamed and rewritten by editing roster.json,
    which the panel opens in your editor, and the daemon validates with the path and the line of
    anything it refuses. The board tab is WP-69 and the handover is WP-70.

v1.4.0

Choose a tag to compare

@github-actions github-actions released this 17 Sep 14:32

Highlights

DeckHQ opens as an app, and one line installs it on a machine with no Node — or a file you download
and run. Every agent is a robot that walks in, sits, types and leaves. The floor is a drawn
interior, and Look chooses its material, its colour and how big the people are. Seating holds: the
same session returns to the same chair. A session running three or more sub-agents grows a crew
around its desk, cabled to it. Counters read tokens, not dollars. Every room carries a plate. A
resume chain is one agent rather than six. Six hundred names. Studio keeps a store and writes a
plan; hiring has not landed. And a pass over the architecture.

Added

  • The crew — WP-89. The owner: "If a chat session fires 3+ agents … the GUI launches all those
    sub-agents (smaller in size), connected by cables to the main chat session agent, surrounding it,
    sat on the floor with their own laptops, feeding data by cables."
    Three or more live sub-agents on
    a session at a desk now turn its desk into a formation: the juniors at 0.65 of the parent,
    seated in an arc of radius 4.2 U in front of it (a crew of twelve opens to 10.3 U), a laptop each,
    and one axis-aligned cable per junior running with two bends — round the furniture, never through
    it — to a port on the desk's front edge. A cable pulses junior→parent, at 1, 2 or 4 pulses a
    loop, only while that junior's transcript was observed to grow inside the last minute; a junior
    whose file has stopped keeps its cable and it goes grey, and its laptop folds. Twelve are drawn and
    the rest are a +N chip, with every one of them still in the panel and in the deck, where a crew is
    one expandable row under its parent rather than N sibling rows. The room grows for it: a crew is
    contents, so it bids for the arc's floor instead of for chairs nobody sits in. One soft door cue
    when a crew forms — never per junior and never per pulse. Two new goldens, crew and
    crew@reduced; the other fourteen are unchanged to the pixel. docs/DEVIATIONS.md §178.
  • The wf_<id> a workflow's transcripts have always carried — WP-89. A multi-agent workflow's
    juniors live one level deeper, under subagents/workflows/, and the floor walked past that segment
    and threw it away. It is kept now, as one field and no extra I/O, so four juniors of one workflow
    can be told from four independent Task calls.
  • The floor is configurable, and two rugs that had never been measured are fixed — WP-88a. The
    owner: "I still don't see any option to configure the overall GUI graphics: office floor carpet
    and colours, rugs, tables, chairs, sofa, plants, etc. We do not flood everything with too many
    options; the interior designer carefully crafts options that can be mixed and matched."
    There are
    now nine floor materials over four zones — herringbone oak, wide ash boards, terrazzo, polished
    concrete, wool broadloom, loop-pile tile, ceramic tile, poured screed and cork — six colour
    schemes, three furniture sets, two rugs in three tones and two patterns, three plant families,
    three planting and three prop densities, and a four-bay lounge kit: 52 options over ten
    pickers
    , with six presets. The default, Studio oak, is the floor exactly as it shipped, byte
    for byte. No UI yet — this package is the model, the derivation and the guards; the Look
    section is WP-88b. docs/DEVIATIONS.md §175.
  • The Look section, where those 52 options are actually chosen — WP-88b. ⌘K → Settings →
    Look: six preset cards, each a real floor thumbnail painted by the floor painter itself; a
    live preview that repaints as you change anything, with the zone edges, both rug ratios and the
    worst floor ink measured underneath it; and a row per picker, every chip a swatch of the material
    it stands for rather than a colour square. A combination the guards refuse shows the reason in
    its own row beside the control that caused it and changes nothing at all
    — not the floor, not
    the control, and nothing is posted. Nine more palette rows (Look: Night lab, Look: reset,
    Look: export, Look: import), Export and Import buttons on the section, and every control
    operable from the keyboard alone: one Tab stop per picker, arrows inside it.
    docs/DEVIATIONS.md §176.
  • Agent size, and the furniture follows the people — WP-88c. The owner: "the user can set the
    size of agents compared to screen; someone with 100 agents wants them smaller, someone with 5–10
    wants them bigger so they are not lost; accordingly the size of table, chair, sofa, everything
    adjusts automatically."
    Small, medium, large or auto, in the Look section and in
    the palette (Agents: large). Everything a body sets moves with it — seats, the pitch between two
    people, desk and sofa depth, the rugs, the planting, the figure's own chrome — and everything the
    building sets does not: the corridors, the room padding, the plate band, the parquet, and every
    label, which stays exactly the size it was. Rooms grow and shrink with their contents, so a floor
    of five people fills the window and a floor of a hundred still fits with every body readable.
    Auto reads how many people are actually on the floor — large under ten, small over forty —
    and holds its choice two either side of each threshold so one session starting does not re-plan
    the building. Medium is the floor as it shipped, byte for byte. ?scale=small paints one tab.
    docs/DEVIATIONS.md §177.
  • A look is a file you own, and unlike a layout it is anonymous — WP-88a. deckhq look export > my-floor.json, deckhq look import my-floor.json, deckhq look presets, plus GET/POST /api/look and ?look=night-lab to paint one tab. A look names no project, no path and no
    session, so it is a file you can post. A malformed one is refused whole with its reason, and so is
    a legal one whose combination the contrast guards will not paint.

Fixed — floor

  • The wool rug was invisible on night shift and the task rug shouted on blueprint — WP-88a. Both
    derived through a constant mix weight while the gap between the carpet and the floor under the rug
    is not constant across themes, so nothing measured them: the wool rug came out at 1.00:1 on
    night shift and the task rug at 1.69:1 on blueprint with every contrast test green. Both are
    now a bisection on the ratio, held to [1.06, 1.45] — measured after: 1.23 / 1.16 / 1.16 and
    1.32 / 1.42 / 1.42. The default floor is unchanged to the channel: all nine default-theme goldens
    are at 0 px moved. The two themed captures were rebaked, and the moved pixels in both are only
    the rugs. test/goldens/linux/demo@night-shift.png and demo@blueprint.png are owed the same
    rebake on Linux.
  • A room plate ranks its lines, and the one you might act on is the biggest — WP-81. The owner:
    "Make sure the calculations on the whiteboard of the project rooms are right and informative and
    not just there for the sake of it. […] how to make it easy to read at a glance in a split second
    so the user does not have to spend effort reading it."
    The plate said orbital-api · 7 sessions · 580k tok · 2 need you over today 5.8M tok · with cache — three numbers in one size, of which
    exactly one is ever acted on. It now reads orbital-api over ● 2 need you · oldest 1d 2h over Elif · Bash npm test over today 5.8M tok · with cache, in four sizes and four
    inks, largest first. When nothing needs you the big line says what the room IS doing — 3 working,
    or quiet — so it is never a zero you have to stop on. docs/DEVIATIONS.md §173.
  • The plate says what each agent is doing right now — WP-81. Up to two live currentTool
    summaries, from the same field the side panel's doing: line and the floor's thought bubble read,
    with the same MCP substitution (mcp__gmail__send reads Gmail · send on all three). An agent
    with no tool open contributes no entry and none is invented for it.
  • Your Office, the Lounge and a pinned room follow the same grammar — WP-81. 2 waiting · oldest 3h, 5 resting, 1 session · pinned. The office says nobody waiting where it used to
    say 0 waiting. A pinned room keeps its session count because with nothing running it is the
    only fact it has.
  • The site shows the product as it is now, and weighs a third of what it did — WP-94b. The
    owner, after reading the site: "The homepage visuals are outdated, the UI changed many times.
    Images load slowly and the Look page images do not load."
    Nothing 404s; Features weighed 6.3 MB
    and Look 4.0 MB. Every image now declares the role it plays, and the role fixes the width it is
    served at and the weight it may reach (hero 1100 px / 600 KB, crop 680 px / 250 KB, gif
    2.5 MB), with a whole-page cap of 2 MB on Home and 3 MB elsewhere. Both are enforced in
    site/build.mjs and again in test/unit/site.test.mjs. Features is 1.4 MB, Look 1.6 MB,
    Home 1.5 MB, Characters 0.6 MB.
  • scripts/site-assets.mjs and site/assets.json — the site's pictures, declared and taken from
    the running product.
    Each asset names a fixture population, a viewport, the keys or clicks that
    reach the state, a crop rectangle in CSS pixels and the width it is written at; the script boots
    one demo daemon per picture on a port the OS chooses with DECKHQ_NOW pinned, takes the shot, and
    takes it down. Fourteen pictures: nine crops of the one thing their words are about (the waiting
    strip, a room plate, Your Office, a lounge bay, the idle popover, the deck's Queue and Usage tabs,
    the panel on a review, and a permission request raised through the real hook endpoint), a themed
    room plate in each of the other two themes, and four GIFs at 25 fps against the old hero's 10:
    the whole floor, typing and thinking, the lounge, and an agent walking to Your Office with its
    hand up. A picture a fixture c...
Read more

v1.3.0

Choose a tag to compare

@github-actions github-actions released this 06 Sep 06:27

Highlights

The panel became a review surface: what the agent said, rendered as markdown, what changed on
disk, and three weighted actions. Replies stream in as they are written, and a permission prompt
raised in the terminal can be answered — Allow or Deny — from the panel; both were run live
against Claude Code on 4 September 2026. The floor is generated from the people on it rather than
the repositories on disk: a room exists because somebody is in it. Every agent arrives with a
face, a name and a rarity — most are common, about one in a hundred legendary. A queue strip sits
under the header, Tab swaps the floor for the same queue as a table, and notifications reach a
closed tab. An append-only event ledger records what the floor did; deckhq stats, the day's
postcard and a weekly Wrapped all read it, computed on the machine and sent nowhere. DeckHQ
installs as a Claude Code plugin, ships a VS Code extension, and prints both a status line and a
terminal deck. Three floor themes are free; the Supporter pack adds more themes and avatars and
takes nothing away. The Codex adapter is verified against real Codex sessions; Gemini CLI and
OpenCode remain unverified. Node 18 or newer, zero dependencies, CI green on Linux, macOS and
Windows.

Added

  • The Supporter pack: more themes and avatars, and nothing else. A pack is one signed JSON
    file. deckhq pack install <file> copies it into ~/.deckhq/packs/<name>/pack.json and a
    running DeckHQ picks it up within a second, no restart. It carries floor themes and avatar sets;
    there is no key in its format for a tier, a licence, an expiry or a feature flag, and one that
    tried to carry a key like that is refused rather than ignored. ⌘K → Settings → Floor now
    shows the pack's themes beside the shipped ones, and an Avatars row appears only when a pack
    actually offers a set — an install with no pack has no row and no advertisement. Choosing "as
    they come" puts every face back exactly, and nothing changes because a file appeared in a
    directory: the set is a setting, empty by default, because a face is the one thing in this
    product that must never change on its own. docs/DEVIATIONS.md §129.
  • deckhq pack — build, verify, install, list, remove. No account, no licence check,
    no activation, no update check and no network call anywhere in it; the only question DeckHQ ever
    asks about a pack is whether it was signed by the Ed25519 publisher key compiled into the build,
    and it answers that locally with node:crypto over the pack's canonical JSON. An unsigned pack,
    one signed by a key this build does not know, or one edited after signing is refused whole
    with its reason and nothing in it loads. A bad ITEM is refused alone: a theme that fails the
    contrast gate is dropped with the measurement and the rest of the pack still installs, so one
    bad colour cannot cost a customer the pack they paid for. deckhq pack verify prints what is
    inside one before you install it.
  • A pack cannot lower a bar. Every theme in a pack goes through the same validateTheme and
    the same assertThemeContrast a theme DeckHQ ships does — this is the door docs/DEVIATIONS.md
    §125.9 left closed, opened exactly this far and no further. Every avatar colour is held to the
    same ≥ 70 sRGB distance from every state colour that public/render/palette.js holds its own
    tables to, so an agent can never wear a state, and a pale "jacket" that would read as the torso
    under it is refused with its luminance. packs/supporter-sample/ is a real pack with two extra
    themes — warehouse (poured concrete and steel racking) and garden (a conservatory in
    leaf) — plus one avatar set, committed as reviewable unsigned source beside the signed artifact
    and a build script.
  • Floor replay: watch yesterday. Free. ⌘K → "Watch yesterday" scrubs the floor through a day
    of your own event ledger at 60×, so a working day is about twenty minutes and dragging the bar
    is instant. Each frame is reconstructQueue(records, t) — the needs-you queue exactly as the
    machine wrote it down, not a re-derivation — and frames land on changes rather than on a clock,
    so a quiet hour is one frame and a busy day is a few dozen. It is read-only: there is no
    writer anywhere in the path, no acknowledgement moves, the ledger file's modification time does
    not change, and an INVARIANT: test drives a whole day to the end and asserts all three. The
    deck, the panel, the header count and the notifications stay live the whole time; only the
    canvas is looking at yesterday. The plan listed replay in the Supporter pack; it ships free,
    because a feature that reads your own ledger cannot be sold without becoming a gate on data you
    already own. §129.
  • A rate-card editor in the settings sheet. Also free. Settings → Data now edits
    ~/.deckhq/rates.json — your own prices per million tokens, merged over the shipped table one
    model at a time, with the shipped model ids offered as completions and the cache columns showing
    the multiplier that will be used if you leave them empty. A malformed row is refused whole with
    the row named and nothing is written; clearing every row removes the file rather than leaving an
    empty one behind that would claim the table is overridden for ever. There is no "fetch the
    latest prices" button and there will not be one. The plan listed this in the pack too; it ships
    free, because the file has existed since WP-26 and anybody can edit it in a text editor — and
    because "cost is an estimate, never a bill" only holds if the person looking at a wrong number
    can correct it. §129.
  • GET /api/packs, GET /api/replay/days, GET /api/replay?day=, and
    GET/POST /api/rates. All loopback, all local, none of them egress. The replay routes are
    two GETs and there is no writer among them, asserted.
  • Two more runtimes: Gemini CLI and OpenCode. Four now, on one floor, with correct attribution
    and no shared state: disabling or removing any one leaves the others fully working, and a runtime
    that is not installed contributes nothing and reports itself cleanly rather than erroring.
    deckhq doctor grew two rows without src/cli/doctor.mjs changing at all, which is the property
    the adapter interface exists for and there is now a test asserting it against the real registry.
    Gemini CLI is read from its JSONL session files under ~/.gemini/tmp/<project>/chats/, including
    juniors; OpenCode through its own JSON-emitting commands — opencode db, session list and
    export — because since v1.2.0 it keeps everything in a SQLite database, and DeckHQ has no
    dependencies and would not guess at a byte layout when the runtime ships a supported interface.
    Resume, new session and send are wired for both, as argv arrays with no shell anywhere.
    Both are unverified — see Known gaps. docs/DEVIATIONS.md §123.
  • docs/ADAPTERS.md — add a runtime without asking us. The RuntimeAdapter contract with what
    each method owes you, the seven stability rules, a worked example that adds a fictional runtime
    end to end, the fixture convention, the checklist, and the honesty rule: an adapter is unverified
    until it has been run against real data and has to say so in three places. Adding a runtime is
    three files in one directory plus one line in the registry and one union member in RuntimeId —
    nothing else in the product names a runtime.
  • Lights out: one card at the end of the day. At 22:00 — or as soon as the last live session
    ends, if the evening is already under way — the floor dims to night and a single card appears:
    "Friday. 40 turns across 6 rooms. orbital-api shipped 6, checkout-flow waited 4h 3m. 6
    agents still up. ≈ $39.46 list price, rate card 2026-09-04. Longest wait today: 1d 2h → still
    standing."
    Every number is a replay of the event ledger. It appears once per local day,
    Escape or a click dismisses it, S saves it as a PNG with a small photograph of the floor it is
    about, and it never comes back on its own — Stardew Valley's day-end save, not a summons. The
    hour is settings.lightsOutHour in the settings sheet's Floor section, and ⌘K → "Today's
    card" shows it again without spending the day's. Nothing in it addresses you, and that is a test
    rather than a convention: the copy generator is driven over synthetic ledgers and every string
    literal in the file is scanned for a second person. docs/DEVIATIONS.md §118.
  • Wrapped, weekly and annual. Monday morning, and from 1 December the year so far. Turns per
    room, tokens, an estimated spend that names its dated rate card, the longest wait and whether it
    fell against the week before, the room that never slept, the session sent the most messages, the
    busiest hour — and the count of "You're absolutely right" across the week's assistant turns.
    Every line carries the window it was computed over, and a ledger younger than the window says
    where it actually starts instead of claiming a week it did not live through. Generated on the
    machine, from the machine: no email, no server, no account, no request of any kind leaves the
    box. One key puts it on the clipboard as a PNG, and Shift+S swaps every project name for its
    MK tag first. ⌘K → "Wrapped". docs/DEVIATIONS.md §119.
  • GET /api/wrapped?kind=week|annual, and a window field on GET /api/stats — what
    happened between two timestamps, room by room, from one walk over the ledger. Both cards read the
    same function, so a day and a week cannot disagree about what a turn is.
  • deckhq doctor --share prints the report as a fenced block you can paste anywhere. The same
    numbers as the report — transcripts, running now, on the floor, waiting on you, hooks, egress —
    with everything that belongs to you taken out: no paths, no project names, no machine name, no
    hook port, no free-text error message...
Read more

v1.2.0 — installable

Choose a tag to compare

@DkPanseriya DkPanseriya released this 03 Sep 16:15

The release that can actually be installed. 1.1.0 called itself the first public release and was
then never pushed to the registry, so npx deckhq — the README's only install instruction —
returned E404 for the whole of its life. Every other improvement in this project was academic
while that was true, so this release is mostly the unglamorous work of making one command work.

Packaging

  • The package is publishable without a private-by-default accident. publishConfig.access is
    now public. A scoped or first-time publish that omits it fails at the registry, or worse
    succeeds as a private package on an account that has no private plan.
  • A broken build can no longer reach the registry. prepublishOnly runs npm run lint and
    npm test before anything is uploaded. Publishing is the one operation in this project that
    cannot be undone — npm unpublish is time-boxed and the version number is burned either way — so
    it is the one that gets the gate.
  • The description is the pitch again. It used to end with "(Codex adapter included but
    unverified.)", which is honest and belongs in the README's Honest limits, where it still is. The
    description is the single line that appears in npm search results next to a dozen competitors;
    spending its last forty characters on a caveat about a secondary adapter was a bad trade. The
    caveat has not been softened, only moved.
  • control-plane dropped from the keywords. DeckHQ does not orchestrate anything and should not
    turn up when someone searches for a tool that does. claude, local-first and privacy added,
    because those are what the intended user actually types.
  • A funding field pointing at GitHub Sponsors, matching the new .github/FUNDING.yml.
  • package-lock.json said 1.0.0. It had not been regenerated for the 1.1.0 bump, so the one file
    whose job is to describe exactly what gets installed was describing a version two releases old.
    Now correct, and *.tgz is ignored so a stray npm pack cannot commit a tarball of the package
    into the package.

The tarball is 42 files and 225 kB: bin, src, public, the README and the licence. It grew by
three files because deckhq doctor added src/cli/. No state, no logs, no tests, no docs/, no
.claude/.

Repository

Everything a stranger looks for before they open a pull request, and none of which existed.

  • CONTRIBUTING.md, leading with the two things that get a change rejected regardless of how good
    it is: the invariant in docs/01-PRODUCT.md §2, and network egress. Both were only written down
    in the README's footer, where a contributor finds them after they have written the code.
  • SECURITY.md, describing the actual model rather than a template one — loopback bind with no
    --host flag, why that is not sufficient on its own and what the CSRF guard adds, path-confined
    static serving, argv-array spawns, conversation text rendered as text — plus a private route to
    report something that is wrong with it.
  • CODE_OF_CONDUCT.md (Contributor Covenant 2.1).
  • Issue forms for bugs and features, and a pull request template. The bug form asks for the output
    of deckhq doctor, so an environment report arrives with the first message instead of after
    three round trips.
  • .github/FUNDING.yml.
  • docs/plan/RELEASE-CHECKLIST.md, the ordered commands for cutting a release, written down
    because the thing that went wrong with 1.1.0 was a step nobody had written down.

Added

  • deckhq doctor. One command that answers "what does DeckHQ actually know about this
    machine": how many sessions are on disk, how many the runtime reports as running, whether hooks
    are installed and — separately, which matters — whether they are being delivered, and whether
    state can be written. --json for scripting. The bug report form asks for its output, so an
    environment report now arrives with the first message instead of after three round trips.
  • deckhq doctor --capture-proof writes a PNG comparing what the runtime reports against what
    DeckHQ holds. It renders the number of finished sessions still waiting on you, which is the only
    version of that comparison that survives a reader checking it — see docs/DEVIATIONS.md §74.

Changed

  • The interface chrome is cold now, and the floor reads as lit. The neutrals were tinted
    toward the accent hue, which put warm chrome around a warm floor: herringbone, carpet and warm
    light sitting on a ground of the same temperature, so the floor never looked illuminated, only
    brown. The neutrals moved to a violet-blue bias, taking hue separation from the floor from about
    66° to about 169°. The seven state colours are untouched — they are a measured contract with the
    renderer, and the rule when something failed was that the ground moves, not the state colour.

Fixed

  • The desktop archive flag was being written into cached session summaries. In memory this was
    masked, because a fresh read re-applied the flag on every poll and only while that read kept
    succeeding. It would not have stayed masked: archived drives let_go, so a persisted copy
    would have re-fired a deliberately rehired agent on every poll, for ever. The flag is now
    stripped both when an entry is written and when one is read off disk, because a cache file can
    arrive from a backup, another machine, or an older build. A cache hit carries no archived key
    at all rather than archived: false — the two mean different things to the registry, and
    neither is a decision a cache is entitled to make.
  • Five interface surfaces set small text in a state or accent colour, all of them below the
    4.5:1 floor the stylesheet's own header already required. The worst was the error toast at
    2.39:1 — the surface that tells you a send has failed. Contrast is now asserted in the test
    suite against every ground the text can actually land on, reading the literal values back out of
    the stylesheet rather than a copy.
  • deckhq doctor aborted with exit 127 after printing a correct report. process.exit() tore
    down the event loop while a loopback socket was still closing. Worth recording how it survived:
    364 tests passed against a binary that could not exit, because every one of them called the
    function and asserted its return value and none spawned the command. A command's contract
    includes how it ends.

Performance

  • The summary cache persists across restarts, so a daemon start no longer re-parses every
    transcript on disk. Measured on 66 real sessions across 307 MB of transcripts: a second start
    falls from 780–854 ms to 59–90 ms. Cold start is unchanged; the only addition is one 62 KB
    atomic write.
  • Only entries that are provably current are served. Painting a stale summary and reconciling
    afterwards was specified, built, and rejected: a stale turnEnded reaches the code that writes
    reviewSince, a user-owned field nothing observed is allowed to clear, and the likeliest reason
    a transcript moved while the daemon was down is that you replied to it in a terminal. That would
    have manufactured a review debt that then survives for ever.

Known gaps

Carried forward from docs/DEVIATIONS.md §8–9, unchanged by this release:

  • Codex support is unverified. The adapter is written against documented rollout-file
    conventions and has never run against real Codex data.
  • openInTerminal() is verified on Windows only. The macOS and Linux paths are implemented and
    reviewed but have not been run.