THE COPILOT SPEC — the agent surface

Authority: FEED-IA §196.2 (E193.02). Supersedes the assistant contract's shape — the task-card dialog, the thread rail and the two modes — while keeping every behavioural claim INTX-UTL-A01…A12 makes about what the agent may do. Where this document and an older description of the assistant disagree about layout, this one wins; where they disagree about AUTHORITY, the older one wins, because §196.2 changed the surface and not the boundary.

Peter, 2026-09-04, recorded whole in FEED-IA §196:

the copilot has to be in the fucking ux ui i told you, properly. idk how many times to tell u. the supply issue and the catalogue shit is just suggestions but it's literally an agent and should have the same shit like all top agents with other sessions etc. i told u to port from the fucking app.soyrocoto.com which has the exact UX i wanted for the actual chat and composer in full even down to the grid.

Three sentences, three requirements: it is an agent (sessions), it is ported (the live app's chat and composer, grid included), and the two flows are conversations rather than a suggestions box.

Where it lives. app/src/prototypes/cedar/copilot/ — types.ts (session · message · card · the provider seam) · store.ts (the sessions) · router.ts (what it answers with) · composer.tsx (the ported editor) · flows.tsx (the cards) · surface.tsx (the column). app/assistant.tsx is now the DOOR and the names only: openAssistant and AssistantHost, so every call site — the day bar's launcher, the stock toolbar, a category row, the Product Sheet — is unchanged.


1 · The surface

Part What it is Testid
The column The frame's third grid track (E193.16), full height, standing BESIDE the work — gridColumn: 3, sticky, one screen tall, the rail's own recipe mirrored. Standing IN FRONT of the work instead (E195.30) it is fixed to the glass with the scrim under it (z 10 — over the chats panel's 9, under Base's popovers at 12), the same 416 on a desk-sized window and the whole screen on a phone. data-posture states which of the four it is drawn as; the frame states the reserved width as data-copilot-track. assistant-dialog
Head «Copilot», the sessions control (where the rail is not beside), New session, Close. Every control ≥ 44 px. copilot-head · workflow-close · copilot-new · assistant-history-toggle
Sessions The list, its own head built to the same recipe so both heads come out the same height. Beside the conversation at ≥ 1440; over the thread — never over the head — everywhere else. assistant-history · copilot-session-<id> · copilot-forget-<id>
Thread The only scrollport. Ruled paper. Turns read down the page. assistant-thread · copilot-turn-<id>
Floor Starters and the two doors on the composer's doorstep (empty session only), the composer, the disclaimer. assistant-composer-dock · copilot-starters · assistant-task-actions · copilot-disclaimer
Composer The port's editor: one box, the writing surface above a control row holding the ghost mic and an always-present send. assistant-composer (+ -box, -input, -controls, -mic, -send, -help, -state)

Postures and measures (shell/viewport.ts owns every number; copilotPostureAt(width) is the pure function, read off the WINDOW):

Posture Window What it is Track reserved
phone ≤ 612 the screen, its height following the visual viewport so the composer stays above the on-screen keyboard 0
sheet 613–887 416 px docked at the right edge OVER the work, with the scrim, the shadow and one tap out — the same box the desk stands beside, standing in front instead, because the room cannot hold both 0
desk 888–1727 416 px beside the work — the kit's own conversation measure (§40.1); the sessions rail opens over the thread 416
desk-wide ≥ 1728 216 px rail + 416 px conversation, both standing at once 632

⚠ AND WITH A DOCUMENT SHOWING MONEY OPEN, THE TWO DESK RUNGS MOVE (§200.3 · E199). The table above is the ladder for work that has no row law standing in it. A priced albarán does, so the agent yields — the rungs become 1664 and 2072, and §11 below derives both from what the work cannot go under. The agent's own measure never changes; what changes is whether the work reflows beside it or is scrimmed behind it.

THE AGENT'S OWN WIDTH IS 416 AT EVERY RUNG ABOVE A PHONE (copilotWidthOf), and that is the whole of E195.30. What the window decides is not how big the agent is; it is whether the WORK reflows beside it or is scrimmed behind it. desk starts at 888 and the number is derived the way every other rung of §103's ladder is — DESK_FLOOR (472: the rail's 64 plus the widest of the desk's two fixed lines, the river pane's 392 + 8 and the day bar's own 408) + COPILOT_COLUMN (416). Above it both things on the screen stand at their own floors; below it one of them would have to lie about what it can hold.

AND THE DESK'S FLOOR WAS CORRECTED WHILE DOING IT. It read 464 — the river pane's line alone — and the DAY BAR is the wider of the desk's two fixed lines at 408 (48 padding + 109 for the day at its longest + 12 + 238 for a way out with its mark alone, on the 8-grid). At 484 px of work the bar could not hold three things and painted «Sales» straight through «Assistant» and «Export» (photographed at 880 and 900). The bar states what it can hold now: under 616 the launcher keeps its mark and drops its word, under 544 the area's name leaves the line, and the day — the one fact on that line stated nowhere else — never leaves. shell/viewport.ts owns all the numbers.

⚠ AND BOTH RUNGS WERE READ OFF THE WRONG NAME FIRST (the E195.30 repair). They came off «Sales» (48 px), the NARROWEST name route-meta.ts holds, so between 468 and 544 the bar put «Your business» (124 px) on a line with room for a third of it — and the item that yielded was the DAY: 62 px of «Friday 22.08» at a 560 px window on #/admin, 102 at 600, 72 at 640, and 91 and 101 on #/customers, ellipsised, measured on the element. A rung is a FLOOR, and a floor read off the best case is not a floor. Both are derived from AREA_NAME_WIDEST now (124, «Your business» — the whole register is measured in shell/viewport.ts), so the bar sheds at the SAME width in every area and every name it states is stated whole. The day carries min-width: max-content on a desk besides, so the item that yields is the name — which has flex: 0 1 auto, a 32 % cap and an ellipsis of its own to yield with — for any name the register grows later.

AND THE SHEET'S OWN FLOOR IS DERIVED TOO — 613. A sheet is a LAYER: it reserves no track, so the work beneath keeps the line it had (that is what makes «one tap out» honest — what a person comes back to is what they left) and the sheet covers the bar's right-hand end, the area's name and the launcher's word. That is the acceptance, and it is stated rather than discovered: reflowing the bar into the strip beside a sheet is not available at any width of this rung, because the strip is the window less the conversation and this rung is defined as the widths where that is under the desk's own floor — 471 px at the widest sheet against a bar that needs 408 plus the rail's 64. What the rung does guarantee is the DAY, the one fact the bar exists for (§37.1), and the floor is that guarantee's arithmetic: 64 (the rail at rest) + 24 (the bar's own left padding) + 109 (the day) + 416 (the conversation) = 613. It read 600 — chosen, not derived — and 601–612 drew a sheet whose left edge landed at 185–196 px, through the day's own 197. Under 613 the agent takes the screen instead, which states no half of anything. drive-204 asserts both halves of the acceptance in its sheet branch: the bar keeps the line it had across the press, and the day stands clear of the sheet's left edge and whole.

AND IT IS NOT E193.16'S DEFECT WEARING A NEW HAT, which is worth saying because it photographs the same. In the sheet's shots the area's name is a fragment at the sheet's left edge — «Sa» at 887, «P» at 768 (e195r/shots-204/887-sales.png, 768-product.png). E193.16's own OWED photographed «Sales» half covered too, and that WAS a defect: the column there was the app's permanent posture at that width, with no scrim, over work a person was still meant to use, and the header stayed clipped for as long as they worked. This is a dismissible layer with a scrim over inert work and one tap out, which is what an overlay looks like in every product that has one — the page behind it keeps its shape. OWED, and stated rather than smuggled: the bar COULD shed its name and the launcher's word for as long as a layer stands in front (nothing else the person can see would move — the day is left-aligned and stays put), and the only thing that costs is a piece of state the shell does not have today: stateCopilotOpen reports open && !inFront, so the day bar cannot tell a sheet standing from an agent away. If the fragment reads badly to Peter, that is the fix, and it is a change to the shell's state plumbing rather than to this rung.

⚠ REPEALS E193.16's screen. From 601 to 1095 the agent used to BE the window — 1095 px wide at 1095, 416 px wide at 1096, so one pixel of browser width swapped the product for a different one, against §195. Its reason («the desk is already standing its own two panes one at a time here, so there is no room to put a third thing beside them») reasoned about the wrong pair: the panes stack because they cannot both stand, and the question the agent asks is whether ONE honest pane and the conversation can. At 900 the work keeps 484 px, which is over its own floor. The centred maxWidth cap that lived inside the takeover goes with it — a box that keeps the conversation's measure has nothing left to cap.

THE OWED IS CLOSED (E193.16). It read: «the live app's copilot is the desk grid's THIRD COLUMN, so the work reflows beside it — the kit's column DOCKS over the work instead, because the shell's frame is not this package's territory», and the audit photographed the cost («Sales» in the day bar half covered, the right pane gone behind the column, the launcher it was opened from underneath it).

shell/frame.tsx reserves the track now — ${railWidth}px minmax(0,1fr) ${copilotTrack}px, the column's own width read from useCopilotTrack() so the track and the thing standing in it can never disagree — and the column is a real grid item in it rather than a layer over it. Sticky, not fixed: the frame is exactly 100vh only while a surface is in PANES, and on the settings seats the page grows and scrolls, where a 100vh item in a 3.000px row would take its composer off the bottom of the world. The rail solved the same problem the same way.

And the ROOM then decides the rung. §103's ladder reads the width minus this track, so a 1366px desk with the agent open has 886px of work — the stacked rung's room, not the compressed rung's — and the panes stand one at a time instead of squeezing a 640px document into 494. The housing question (usePhone) stays the window's: no docked column may put phone furniture on a desk. The reserve is read off the WINDOW, never off the room, because a reserve that shrank the room deciding it would oscillate forever.

desk-wide moved from 1440 to 1728, and the number is derived — 216 + 416 + 1096, the room two honest panes need (COPILOT_RAIL + COPILOT_COLUMN + STACK_MAX + 1). 1440 was right while the column was an overlay costing the work nothing; as a track, 632px of a 1600px desk is forty per cent of the screen and the desk lost BOTH its panes to a list of past sessions.

⚠ ONE BACK STEP PER LAYER, found here. Reserving the track makes the frame re-render when the agent closes, and useHistoryLayer's write effect re-runs on every render (its snapshot is a fresh object at nearly every call site). history.back() is asynchronous, so the second run saw the layer still on the stack and popped AGAIN — two steps out of a one-layer stack, off the app's own first entry, and the drive photographed a white screen with localStorage denied. The guard is in app/navigation.ts, where it protects every layer rather than the one that happened to expose it.

2 · Sessions

type CopilotSession = {
  id; title; createdAt; updatedAt;
  origin: 'general' | 'supply' | 'catalogue';   // the door that opened it
  context: AssistantContext;                     // product / products / category / order
  messages: CopilotMessage[];
  flow?: { report?: OperatorReport; review?: SupplyReviewDraft };
};

3 · Messages

type CopilotMessage = {
  id; at; role: 'operator' | 'copilot'; text;
  activity?: Activity[];      // short completed/pending/blocked rows off REAL results
  card?: CopilotCard;         // a flow mounted inside this turn
  proposal?: { id; revision; digest; receipt? };   // the receipt of a reviewed send
  dictated?: boolean;         // the words were spoken, and the turn says so
};

The operator's turn is a small card on the right; the agent's is prose on the paper — one voice reading down the page, which is the shape the port settled on («less like chat, more like AI»). Activity is a disclosure, never a chain of thought and never a progress animation: its rows name what was read and how many rows it came from.

4 · The composer contract

Ported from app.soyrocoto.com/src/chat/Composer.tsx's editor variant and composer-editor.css:

5 · What the agent may act on

Superseded by THE-OUTPUTS-SPEC.md OUT-05.2 (E200 · FEED-IA §202). Opening a conversation is reading, so the Copilot’s «Open chat» and «Open the email» stand always; sending keeps its own authority. The history below is kept.

It may It may only propose It may never
Save a catalogue category (Save category, with an exact target AND a recorded reason) The supply message's wording, the affected-order selection, the alternatives Send a customer message where customerOutbound is unverified — the review then reads Draft only and offers the native doors
Record a supply report as evidence on the session A stock correction (it hands over to the Stock workflow and returns) Count stock, subtract a lot, reserve a substitute, change a price
File, retitle and forget its own sessions Claim a delivery a receipt did not confirm: the receipt is checked against the proposal id, digest, sector, revision and the exact recipient set, and a mismatch records nothing as sent

A turn's words never grant authority. Only a card's own explicit control acts, and each of them is capability-gated where the capability exists.

The one act that leaves the house has a server boundary, and it is unchanged by this release: specs/intelligence/v1/assistant-action.schema.json (assistant.supply_dispatch.request / .receipt). The kit's client seam mirrors it exactly — a proposal id, a text digest, the sector, the revision and the exact recipient set — and a receipt that does not match any one of them records nothing as sent. tenant_id is resolved from authenticated server scope; the browser's sector is never accepted as one.

6 · The doors

Superseded by THE-OUTPUTS-SPEC.md OUT-05.2 (E200 · FEED-IA §202). The Copilot opens a chat and an email inside the app through the shell’s own openers. The history below is kept.

openAssistant({ kind, context }) — dispatched by the day bar's launcher (general), the stock toolbar's «Report supply issue» (supply), a category row's «Discuss category» and the Product Sheet's category Edit (catalogue).

7 · What the port deliberately left behind

8 · Proof

drives/drive-195-copilot.py — eight viewports (1920, 1536, 1366, 900, 768, 393, 390, 360): the column's dock, width and posture; the ruled paper's four layers and its absence everywhere else; the composer's anatomy, its keyboard grammar, its growth and its 44 px floors; sessions filed only by work, listed, reopened, surviving a reload, and left alone by New; the supply and catalogue flows as cards inside the conversation with the composer live beside them; and the honest dictation state with the runtime pointed at a port nothing answers on.

AND drives/drive-204-copilot-midwidth.py holds the mid-width posture itself (E195.30) at thirteen widths — 601 · 612 · 613 · 640 · 768 · 887 · 888 · 900 · 1024 · 1095 · 1096 · 1366 · 1600, all three boundary pairs included: the agent's one measure, its head on top and its composer on the floor of its own column; the work unobscured wherever a track is reserved (day bar, river, document, launcher all ending at or before the column's left edge); the scrim and the head's Close each proven to be one tap out; the sessions list behind its icon and opening over the thread below the head; the 44 px floors at every width; and E192's row law under the narrowest room the agent leaves the work — one plan per document, the identity at or above 160, the terminal above 88, nothing clipped, no sideways scroll. It walks the day bar on its own as well — no agent standing, over the register's shortest name, its middle and its widest (Sales 48 · Customers 95 · Your business 124) at 560 · 600 · 640 · 704 · 1024 · 1366: the workspace's own mark stated whole on the element (the day moved to Sales' picker), the name stated whole wherever it is stated at all, both rungs held in both directions, nothing standing on anything, and the line never taking the page sideways.

drives/drive-198-copilot-mind.py holds the MIND (E198) at 1600 and 390, in three postures. OFFLINE: the runtime pinned at a port nothing answers on — the Copilot says what it is reading, the sentence carries no word about what is out of reach, the report card still opens and the review still states the exact affected orders. RECORDED: the drive itself answers /api/copilot, and it answers off the CONTEXT the kit sent — so the request is inspected whole (the day, the area, the day's orders with their numbers and accounts, the floor, the session, the caps) and every proposal kind is asserted where the surface draws it: the reply turn, its evidence line, the supply-report card, «Open order» on an id that is on the book, the stock note as a line, and §196.9's drafts prefilling the composer with nothing sent. LIVE: a local uvicorn of the real runtime with the house's Gemini key — one real ask, a reply inside 30 s, a supply report, and every order it names on the seeded day. Six-viewport screenshots come off the recorded posture, so the conversation in them is the same conversation tomorrow. §200.3's one name is asserted in every posture. 189 GREEN / 0 RED, and RED-PROVED against the pre-E198 build (36 GREEN / 56 RED, led by «the Copilot says what it is reading right here», «the ask reaches the runtime · None» and «no «Assistant» is visible anywhere · Assistant | aria-label="AI assistant" | title="AI assistant"»). No regression: drive-195-copilot 515 / 0 at its pin, drive-204-copilot-midwidth 923 / 0 at its pin.

drives/drive-202-phone-targets.py sweeps the agent too (E195.31): six scoped sweeps at 393 · 390 · 360 over the empty room, the conversation, the sessions list, the supply card, the catalogue card and the row while a take is running, plus eleven of its controls measured by name.

9 · The mind (E198)

Sessions, the ported composer and cards that do real work made a body. What answered inside it was copilot/router.ts: a keyword table, hay.includes('short'), and one fixed sentence. §196.2 asks for «the same shit like all top agents», and a top agent has a mind. This section is that mind.

9.1 · Where it lives, and why it is not in the browser

In the kit runtime (mock-api/app/copilot.py; the wired product's mind is the backend's, STACK.md), behind POST /api/copilot, for the same reason Parsewise, Deepgram, Places and Twilio are there: the kit is a static page and a static page cannot hold a key. One seam, two providers, chosen by COPILOT_MODEL — Gemini 2.5 Flash answers today, Claude Fable 5.1 is the first choice the moment the API credit exists (§199.3 · §199.6). /api/health reports WHICH mind is standing — gemini · anthropic · awaiting key — because those are three different products to the person reading the reply.

9.2 · The contract

The kit sends the desk as it stands; the mind sends back words and proposals.

POST /api/copilot
{ session: { id, messages: [{ role: "person"|"copilot", text, at }] (last 20) },
  context: { day, area,
             document: { number, customer, state, lines: [{ product, qty, unit, price? }] } | null,
             orders: [{ id, number, customer, customerId, state, flags: [string],
                        lines: [{ product, qty, unit }] }]   (≤ 40),
             stock:  [{ product, available, unit, expected? }] (≤ 60),
             customer: { name, tariff, rhythm? } | null },
  ask: string }
→
{ reply: { text },
  proposals: [ { kind: "supply-report", product?, orderIds: [id] }
             | { kind: "drafts", drafts: [{ orderId, customer, text }] }
             | { kind: "open-order", orderId }
             | { kind: "open-chat", customerId }
             | { kind: "stock-note", product, text }
             | { kind: "answer" } ],
  evidence: { model, ms, tokens } }

The proposals are the shapes the surface already renders. supply-report mounts §1's report card — the one the keyword table already mounted. drafts is §196.9's killer feature and it lands in the composer's own starter grammar: pressing a draft writes it INTO the box, where the person edits it, speaks over it or deletes it, and the send stays theirs. open-order and open-chat are controls on the turn. stock-note is a line. answer is the words alone. Nothing new was designed for the mind; the mind slotted in behind the surface.

The context is assembled from surfaces a person can already look at (copilot/context.ts): useSupplyIssues is the fold the stock screen draws, flagsOf is the judgement the river's rows wear, the open document is the one in the address bar. So a reply naming «A-2452 · 40 kg» names a row the person can go and check.

9.3 · Prompt discipline

9.4 · What it never does

9.5 · The three postures

Posture When What the person gets
Live the runtime answers the mind's words, grounded proposals, and the evidence on the turn
Offline no runtime, or the runtime answered a failure the Copilot says what it is reading right here and runs the flows it owns — the keyword table, kept whole, doing the job it always did
Unreadable the mind replied twice in a shape the runtime could not read one sentence saying what to do next, and the answer proposal

The local answer leads with the result. Collapsed Sources retains its Workspace records basis and the records used; Response details retains actual model timing/token evidence where a model answered. The entrance explains the development workspace. This progressive disclosure follows the operations hub refinement.

9.6 · The thinking state, now that it is honest

§7 refused a «pensando…» shimmer while there was no model behind the kit, because it would have been a picture of work that was not happening. The mind is here and the call takes seconds, so the room says so: one line, in the agent's own seat in the thread, in words — «Reading the day…» — rather than three grey skeleton bars, because a skeleton is a picture of an answer's SHAPE and nobody can know that yet. The ask in flight stands above it, and neither is filed: the store still takes exactly one write of the person's words and the agent's answer, so a reload mid-thought comes back to the conversation as it stood.

10 · One name (§200.3)

«Assistant» is gone from everything a person reads: the launcher's word, its aria-label and its title, every heading and every sentence. The data-testid="assistant-*" handles stay, because a testid is a handle for a machine rather than a word for a person, and five drives pin them. drive-198-copilot-mind.py walks the whole DOM — text nodes, aria-label, title, placeholder — and fails on the word.


11 · The yield, beside a document with prices (§200.3 · §200.4 · E199)

Peter, 2026-09-04, looking at 1536-supply-conversation.png:

the copilot: it's not meant to be a sidebar unless it's okay to load as a sidebar. Maybe that's fine for it to be compact when you don't have prices, but when you do have prices, I'm not sure … I don't know if you have tested what the albarán delivery note would actually look like when the copilot is open and actually has data. You need to make it actually work in terms of design and stuff, especially in the list of orders and stuff.

notice how massive the fucking card is in that test of the copilot that you put. It's a bit confusing, no?

11.1 · What was measured

It had not been tested. On the E198 bundle, with the long-value albarán open (a six-digit quantity, «unidades», a 40-character name) and the agent docked:

window room the document's pane the row
1512 1096 511 — under its 640 stacked
1536 1120 535 — under its 640 stacked
1600 1184 599 — under its 640 stacked
1728 1096 511 — under its 640, and NARROWER THAN AT 1600 stacked
1920 1288 648 stacked

Three failures in one table. The document went under its own snug measure at four of the five widths measured — the dishonest narrowing §103 exists to ban, on the one surface §192–§195 spent four releases pinning. It was not monotonic: 1728 handed the document less room than 1600 did, because desk-wide reserves 632 there — the same «one pixel of browser width swapped the product» defect E195.30 killed at 1095. And at 1366 the docked column dropped the room to 950, which is the stacked rung, so opening the agent took the river off the screen outright — «especially in the list of orders and stuff».

11.2 · The two rungs, derived

   208   the rail at rest on a desk (RAIL_EXPANDED — a desk boots with the rail open)
 + 392   the river pane's floor (LIST_FLOOR)
 +   8   its overlay scrollbar, counted exactly as DESK_FLOOR counts it
 + 640   the document's snug measure (SHEET_SNUG) — a line's fields on ONE row before any wrap
 ────
  1248   PRICED_WORK_FLOOR — the room a priced document and its river cannot go under
 + 416   the conversation (COPILOT_COLUMN)
 ────
  1664   COPILOT_PRICED_DESK_MIN — at and above this the agent may stand BESIDE the work
  1440   what the desk needs to keep BOTH panes at their FULL anatomy (WIDE_MIN — the sheet's 720)
 + 216   the sessions rail (COPILOT_RAIL)
 + 416   the conversation
 ────
  2072   COPILOT_PRICED_RAIL_BESIDE — and only here may it also bring its history

The rail's rung is read off the top measure, not the floor, and that is deliberate. A list of past sessions is the least load-bearing thing on the screen, so it is paid for out of SLACK. Read off the floor the number is 1880, and at 1920 the rail stood and took the document from 687px of card to 607 — a wider screen showing a narrower document, which is the defect this section exists to close.

And it is ONE threshold, not a hole. A rule that docked below 1512 (where the room falls to stacked and the document takes the whole box) and again above 1664 would leave a 152px band of sheet between two bands of column: a person dragging a window edge would watch the product change twice. Below 1664 the agent is the sheet E195.30 already built — in front of the work, with the scrim, one tap out — and because a sheet reserves no track, the work keeps the line it had: the river with its rows, its flags and its acts, and the document at its own measure.

What declares the fact. usePricedDocumentDeclared(pricingAvailable) from a layout effect in detail.tsx, and there only. It reads the CAPABILITY rather than «has at least one priced line», because the latter would reflow the layout under the hand that was typing a price in; and it counts rather than flips, because React runs a leaving effect's cleanup after the arriving one's effect and a boolean would let a surface on its way out switch off a document that is still standing.

⚠ The nascent card deliberately does not declare it, and that was measured rather than argued. It did for one round — the composer is the albarán one moment earlier — until the drives photographed the cost: that card is the sales pane's RESTING content, so the agent yielded to a sheet at every width under 1664 on #/sales with nothing open at all, against Peter's own «maybe that's fine for it to be compact when you don't have prices». What a person gets instead is the posture the stacked desk already has: at 950 and 1024, pressing «New albarán» opens the ASK SHEET (data-ask=yes) over the river (§75.7), which is what the agent's own rung leaves at 1366 and at 900 too — and drive-199 asserts the compact frame on that sheet as well as on the pane's card.

⚠ OWED, and stated rather than smuggled: an ALREADY-OPEN composer does not survive that reflow. Press «New albarán» at 1366 and then open the agent: the track drops the room to 950, and areas/sales.tsx's React.useEffect(() => { if (pushed) setComposing(false); }, [pushed]) — there so the desk's §66.3 landing composer does not stand where the river should — fires on the reflow and CLOSES the card instead of converting it. Two lines away is the conversion it should reach: composerSheet = pushed && composing mounts exactly the ask sheet a fresh boot at 950 gives. The fix is to tell a composer somebody OPENED from one that is only the pane's landing, and that is a change to this surface's own state rather than to the agent's rung, so E199 states it and leaves it. Nothing is lost that the ledger does not hold — a named draft is in the drafts door — but the person is put back on the river without asking.

11.3 · The Copilot's own cards are rows (§200.4)

Every affected order in a supply conversation was a seven-line poster: the name, an accent line saying it was selected, the asked/available line, a «Message preview» label, the WHOLE customer message as a paragraph, and the acts. The message was identical on every row — the card's own wording field states it once — so each row re-printed the one fact the card had just stated, in the tallest way available.

A row now, in the row law's own grammar: the identity on the first line · the quantities and the day small under it, the day said the way the house says it («Friday 22.08», never the id) · the row's own first line of message as a one-line preview, clipped — it is on the row only because the quantity in it is theirs · the acts as compact text on one line. The count is stated once, at the head of the rows it counts. ≤ 96px on a desk, measured; taller on a phone only because INTX-12 puts a 44px floor under every act. The drafted replies (§196.9) are the same row, with «Use draft» as their act.

11.4 · The new albarán's frame (§200.4)

«Whose albarán» drew three skeleton rows, a ghost total and two grey placeholder buttons under its four intake doors. §83.1 asked for that structure and was right about the card it was written against — a head with a placeholder and nothing under it. That card is gone: the four doors (§196.5) stand between the name and the lines now, so the structure a ghost was drawing is already on the card in controls a person can press, and three grey rows under them read as «this document is loading» — the one meaning src/rocoto/ghost exists to avoid.

The frame is the head, the four doors on one row with «Lines appear here once the paper is read» riding the same band, and the foot stating «0 lines». 261px at 1600 — head 93 + intake band 117 + foot 49 + two hairlines — against 487 measured on the published kit, 254 of which was grey. It grows when there are lines to grow for.

The sentence rides the doors' band rather than standing in one of its own, because the doors and it are ONE idea — here is how the paper gets in, here is where it lands — and a band of its own put a third rule across a card that has said nothing yet, for 32px of padding around a 20px sentence. The brief asked for 240 and the card is 261, which is stated rather than shaved: each of the three bands is one idea at the theme's own padding, and reaching 240 would mean giving this card paddings no other card in the kit has.

11.5 · Proof

drives/drive-199-copilot-with-data.py at 1366 · 1536 · 1600 · 1920 (+ 1700 and 2100 for the document alone, so every posture family has two members, + 390): the posture the priced ladder states and the track the frame reserves; the document never under its own measure and never narrower in a wider window standing in the same posture; the row law inside the room the agent leaves (one plan per document, the unit price under the total right-aligned, nothing clipped, no sideways scroll); the river's rows keeping their identity, their flags and their acts; the agent's rows inside 96px with every text line on one line box; and the compact frame with no skeleton row, no grey button and one sentence — on the pane's own card where two panes stand, and on §75.7's ask sheet at 1366 · 900 · 393 · 390 where the desk stands one. 210 GREEN / 0 RED.

RED-PROVED against the published kit (ROCOTO_URL=https://kit.soyrocoto.com/app.html, ONLY=1600,900): 23 GREEN / 14 RED, led by «the document never goes under its own snug measure · card 551 ≥ 592», «the agent takes the posture the priced ladder states · desk vs sheet», «a sheet reflows nothing: the document keeps the width it had · 687 → 551», «§200.4 · no skeleton line rows · 3», «no grey placeholder buttons under it · 1», «one sentence says what comes · None» and «the empty frame is inside 264px · 487».

No regression: drive-192-row-plan 240/0 · drive-193-sticky-head 142/0 · drive-195-copilot 515/0 — all three at their pins. drive-204-copilot-midwidth re-pinned: it opens d1-cansole half-way through its walk, so from that press it is held to the PRICED ladder, and 1366 and 1600 draw the sheet where they used to draw a docked column over a document squeezed to 511 and 599. drive-75.py's §83.1 walk is re-pinned to §200.4.

Search documentation

Type to find a guide or section.

↑ ↓ to choose · Enter to open · Esc to close