Six sections of the binder are not rooms — Money, Papers & permits, People, Care, Plans & drawings, The build so far — and they sit in one quiet list under The house and look alike there. They are not alike. Mockup 41 draws The build so far; these are the other five. People and Plans & drawings are built and routed, Money is built but knows nothing about rooms, and Care is project-wide with a room-shaped hole in it. This page draws all five and says which is which under each phone. Papers & permits was the last door on the dock with no screen behind it at all, and this page used to say mockup 13 drew it, which was never true: 13 is Money.
The cabinet quote came back higher than the allowance.
The allowance, the quote and the line items. decision_allowances is a real table, unique on (project_id, decision_id), and quote_line_items and quote_line_item_decisions ship with it. Category budgets are a JSON string in projects.category_budgets, added by migration 0005.
The middle card. Nothing about money is scoped to a room today. An allowance hangs off a decision, a quote line has a category and no zone, and the budget categories are a JSON blob rather than a table. Every figure in "What each room has left" is derived, not read.
The derivation itself needs no migration: decision_zones already joins a decision to its spaces. What it needs is a product answer. A line item tagged to decisions in three different rooms has to land somewhere, and the weight column at 0014:74 is nullable and its own comment calls it unused. The rollup at strategies.go:297 divides evenly, which is a placeholder rather than an answer.
The first card is always present for an owner and opens /house/people/seats. With one owner it is where an invitation starts; with more it expands into the responsibility overview. Household members are not mixed with builders and trades because seats and contacts carry different meanings.
contacts, contact_projects, contact_zones and contact_systems sync for the delivered directory. Active seats and member_tags sync for the delivered household drill. The builder is identified by the builder seat, never guessed from contacts; the person's optional phone is projected through that seat, and the call action is absent when no number was supplied.
Project-scoped Room and System assignments supply the scope shown under each name and the routing list. Within an axis, any selected value matches; when both axes are present, both must match. A contact with no assigned scope still appears in the directory but not in routing.
Sheets are filed by number, not by room. To find the kitchen you open A-1 and look for it, the same as you would with the paper set on the table.
0041_drawing_reader_p5.sql gives drawing_sets a selected immutable extraction run and gives sheets their number, title, discipline, revision and stated scale. DrawingsScreen reads the API-backed set and sheet projections at /house/plans; no sheet row or storage credential is synced to the phone.
P6 can answer a question such as "where is the kitchen?" from retained spaces and cite the exact sheet region. P7 now writes sheet_zones through the explicit owner-only preview/apply decision; P8 still owns replacement when a later revision is selected.
The screen groups by the explicit discipline returned by the selected P5 run. It does not infer discipline from the sheet number, and a read failure never becomes a calm empty filing cabinet.
Range hood filter degrease and Fall gutter cleaning are authored rows in data/library/content/maintenance.json. The rebuild has a minimal maintenance_tasks placeholder today. Y4 adds the imported catalog, project schedule, completion ledger and reversal ledger; the client never invents the next date.
Catalog definitions receive authored room-archetype relationships, and materialization creates one task per matching classified project zone. A manually added zone with only a label receives no inferred archetype and no room-scoped Care work until it is explicitly classified.
House-level work uses The house itself. Definitions that depend on a water softener, radon system, garage door or another unrecorded property feature remain inactive until the later property inventory exists. Empty applicability is never used to show equipment work confidently to every house.
The certificate of occupancy. It is the last paper the house gets and the one that matters most afterward, and there is nothing useful to show about it before it exists.
The file, and only the file. project_documents carries file_id, file_name, mime_type, uploaded_by, uploaded_at, document_type, an extraction status and supersedes_document_id (0001_init.sql:1373-1394). Upload, storage, supersession and the extraction pipeline all work.
Every field on every row above. A permit number, an issuing authority, an issue date, an expiry, an inspection state and whose move it is are six values and the table has none of them — uploaded_at is when somebody put the PDF in, which is a different date and never the one a permit turns on. And a paper cannot be uploaded in the first place: knownDocumentTypes is a closed set of seven and all seven are plan drawings (documents.go:92-101), so a permit, a contract and a certificate are all refused at the handler.
Waiting first, live second, signed third. The obvious tab is a file list newest-first, which is a folder with a search box — the reason to open this door is almost always is the thing that is holding us up still holding us up, and that question has one answer at the top or it has none. The lead card is the only one that ever changes.
A drawing at a quarter inch to the foot needs every pixel it can get, so the sheet takes the whole width and everything else is one line under it. What that line carries is the thing a person standing in a half-built house actually needs: which revision this is and who sent it, because the argument on site is almost always that somebody is holding an older sheet.
You opened A-1 from a list of nine, so swiping moves through those nine. A viewer that returned you to the list between every sheet would be making you re-answer a question you already answered, and comparing the floor plan against the elevation is most of why anybody opens these at all.
This strip carried a second ghost CTA until Q150 ruled on it. A sheet leaving as a file hands somebody's plan set to the operating system, where seat removal, archive and account deletion cannot reach it; a sheet leaving as a link is a sixth links.type and a subject column the table has no analog for, on behalf of an affordance the frame's own argument never makes. That argument is about the builder's signal, not about handing a sheet to a third party, so the control is removed rather than left standing as a promise.
It is there because a job site has no signal and a builder asking to see something does not care whose app it is in. The offline rule on 00 says what still works rather than what broke; this is the same idea one step earlier, letting somebody take the thing with them before the signal goes.
AE1 shipped it into a drift table, app-private, so seat removal and account deletion reach it and an archive deliberately does not. Once a sheet is kept the strip says so and offers the release instead — a hold somebody chose needs a way out that is not deleting the app, and 26 frame 4’s “no way to clear this” is about the cache the phone manages rather than about this. It also reads the kept copy when there is no signal, and says out loud that it is not a fresh read: the argument on site is almost always about which revision somebody is holding, and a stored sheet drawn silently would be this app joining that argument on the wrong side. Q238 is the ruling.
I will answer from the retained drawing knowledge and show the sheet behind every answer.
Questions do not change your plans or house record.
The opened revision is the first object on the screen. A candidate set can be asked only after the user deliberately opens it, and every later turn inherits this visible boundary.
This conversation lives inside Plans & drawings. It does not follow the user around the app or compete with the three-door dock.
Which sheet shows the first floor?
The question stays in the transcript while HouseChalk works. The four lines are stages the system owns, with no fake percentage, denominator or spinner.
Which sheet shows the first floor?
A-1 is the first-floor plan. It is the architectural sheet drawn at 1/4 inch to 1 foot.
This identifies the sheet. It does not verify dimensions or anything inferred from scale.
The source follows the claim in reading order and opens the evidence region. A follow-up keeps the same revision unless the user deliberately starts from another set.
The model is allowed to say less than the question hoped for. The boundary on scale-derived measurements is visible before somebody carries the answer onto the job site.
“A-1 · First floor plan · 1/4 in. = 1 ft”
The region exists because the answer cited it. It does not turn the viewer into an annotation tool, and leaving the question clears the layer.
Frame 6 on the record-tabs page already settled the sheet-first composition. P6 adds evidence to that screen rather than creating a second drawing viewer.
What finish is specified for the primary bath floor?
The indexed sheets do not name a floor finish for the primary bath.
All relevant sheets were checked
This does not mean a finish has not been chosen somewhere else.
The answer names what this revision does not contain, then keeps the conversation open. It does not say the house has no floor finish or recommend one.
What finish is specified for the primary bath floor?
A-2 did not finish reading, and it may contain the primary bath note. I will not call the answer missing while that sheet is unknown.
Retry the sheet before answering this question.
This is the product rule P6 exists to enforce. A calm empty state here would turn one failed read into a claim about the house.
What finish is specified for the primary bath floor?
A-2 did not finish reading, and it may contain the primary bath note.
You can leave. This recovery will stay with the question.
The old question remains anchored to the incomplete run. This panel follows the new P5 run instead of pretending the blocked answer can become complete by refreshing.
Retry A-2 only retries the sheet. HouseChalk waits for an explicit re-ask before it spends another question call.
What finish is specified for the primary bath floor?
The blocked reply stays as it was.
Ask again creates a linked question against the recovered run. The previous blocked turn remains visible, and the new paid call is deliberate.
Which sheet shows the first floor?
Your plans are still here, and nothing in the house record changed.
Retry the exact request when you are ready.
A failed job is not an empty answer and not a reason to clear the field. The user can retry the exact request or leave it and ask something else.
The call may incur cost. Nothing silently repeats it just because a screen remained open.
Which sheet shows the first floor?
Nothing changed
Nothing in the house record changed.
Which sheet shows the first floor?
The failed question is immutable. Try again creates a linked request against the same retained run instead of resetting the failed row to queued.
The repeated person bubble records the deliberate action. HouseChalk never silently resubmits a failed provider call.
I will show you all nine before anything changes in your house record.
The seven clear matches are summarized, not confirmed one at a time. The review exists only because two proposals fell below the configured threshold or were ambiguous.
Starting review does not create a zone, a sheet link or a decision. The owner sees one complete preview before the canonical apply.
The name stays Office either way. This only controls what belongs in that space.
Office
File work-space decisions here.
Bedroom
File sleeping-room decisions here.
The live screen opens with both choices unselected. This frame shows the result of the owner's tap so the selection treatment is visible; Continue stays unavailable until a choice is made.
The immutable drawing space remains Office. The chosen library room type controls valid decision seeding without rewriting what the sheet says.
The name stays Guest bath. I only need to know which set of decisions fits it.
Full bath
Includes a tub or shower.
Powder room
Sink and toilet only.
The position marker is honest because the review count is known before the owner begins. A third prompt cannot appear halfway through this run.
The proposal's retained candidates supply the room types. Neither of these opens a free-form taxonomy picker; the quiet escape handles a genuinely different room.
Adding these creates the spaces and only the decisions that fit them. It does not change Rev 3.
Every proposed space is present before apply, not just the uncertain ones. The owner can trace every row back to its sheet and see which two classifications came from them.
Add nine spaces creates the canonical zones, their sheet links and the valid decision set as one owner-authorized operation. Back edits retained choices; closing leaves the proposal untouched.
9 spaces
47 decisions now sit in the rooms where they belong.
The success screen names what changed and offers the two places the owner is likely to go. It does not repeat all nine rows after the transaction has already committed.
The canonical spaces keep their Rev 3 proposal and sheet evidence behind them. P8 can later compare a new revision without pretending these were entered manually.
Only a project owner can choose the room types and add these spaces to the house record.
The non-owner can inspect the retained result but cannot submit review decisions or discover an apply endpoint through disabled controls. The action is absent because the permission is absent.
Sam is the project owner in the pinned fiction. Naming the person who can move this is more useful than a generic permission error.
The house record still has no spaces from Rev 3. Try again when your connection is steady.
A partial apply would be worse than a visible failure: spaces, sheet links and valid decisions commit together. The error therefore reports an unchanged house record, not a fraction.
The immutable proposal and the owner's two review choices remain available. Retry repeats the apply operation, not the questions.
Nothing in your house record will change. There is no space list to add from this revision.
The run completed, but zero proposals cannot become a successful binder update. This state has no primary action and creates no durable apply command.
Rev 3 remains readable in Plans & drawings. The copy names the narrow absence: this retained run produced no space list to review.
Opening Rev 4 still lets the owner read and ask it. The only new action is Compare; the current marker stays on Rev 3 until an explicit adoption transaction commits.
This is still the Plans & drawings tab. The dock disappears only after the owner enters the bounded comparison and decision flow.
Your Garage work is protected. A later plan cannot erase something you or Nora changed.
Sheet pixels are evidence, not the decision. The owner sees matched, changed, added and absent rooms after the retained runs have been compared.
Garage is absent from Rev 4 but already carries human work. The comparison says it will survive before asking what to do with rooms and decisions that have no choices, answers, notes or files.
Your choices, answers, notes and files stay with you. Rev 4 cannot remove them.
Update from Rev 4
Use Rev 4 only for rooms and decisions with no choices, answers, notes or files.
Remove Rev 3 rooms and decisions with nothing saved
This removes only rooms and decisions with no choices, answers, notes or files. It adds nothing from Rev 4.
Keep your current rooms and decisions
Change nothing in your binder. Rev 4 stays in Plans & drawings.
Update makes Rev 4 current and changes only rooms and decisions with no human work. Remove makes Rev 4 current but adds none of its rooms or decisions. Keep leaves Rev 3 current and returns to Plans without a confirmation screen.
Protection is not a fourth option and not a per-room burden. The server finds choices, answers, notes, files and other human work, rechecks them under lock, and keeps them in all three paths.
If anything changes while this preview is open, I will stop and show you the comparison again.
The preview names additions, replacements, protected exceptions and retained history. The button repeats both adoption and treatment; generic Confirm would hide the consequence.
The preview token covers the comparison and the rooms and decisions with human work. New work invalidates it, so the transaction cannot remove something a person changed while the preview was open.
Pantry and Powder room will stay in the drawing set only. They will not appear as rooms in your binder.
The action removes only rooms and decisions HouseChalk created from Rev 3 that still have no human work. It does not remove plan sets, evidence, questions or anything a person changed.
The preview explicitly says the two Rev 4 rooms stay in Plans & drawings. Otherwise Remove could look like a temporary step before the new plan silently adds them again.
Rev 3 is still in Plans & drawings as the source that came before this one.
The owner sees not only what changed but that Garage survived. “Everything updated” would be shorter and false.
Rev 4 becomes active and Rev 3 points forward to it, but the prior set, selected run, evidence and applications remain readable provenance.
Rev 3 is still in Plans & drawings as the source that came before this one.
Human work remains in the binder, so the result names both what was removed and what stayed. The owner is never shown a false blank-slate claim.
Rev 4 becomes the active source for viewing and questions even though the owner declined to seed canonical rooms or decisions from it.
No plan set, room or decision changed. Try again when your connection is steady.
Activation, supersession and canonical treatment commit together. The error can promise Rev 3 stayed current because no partial state is permitted.
The treatment and preview remain durable enough to retry, but any stale protection fingerprint returns to comparison rather than forcing the old preview through.
Your rooms and decisions are still protected. I need to check the same request before I can tell you what changed.
The implementation reuses a deterministic command key derived from the candidate, treatment and preview token, so route disposal or restart cannot create a second command.
An explicit server rollback still uses frame 32. Only a network failure, unreadable response or lost response uses frame 33; this state makes no claim that the request succeeded, rolled back or changed the current set.
The sort from frame 5 does not move: waiting permits, live permits, then ordinary papers. The action follows the record instead of replacing it.
On a phone, Add a paper opens the platform file picker immediately. Cancel returns here without creating a route, upload or document.
Owners and builders see the action. A viewer sees the same synced record without an inert or disabled upload control.
Contracts, change orders, plans and inspections remain owned by their source flows. Y3 joins inspections to their permits. Y9 brings the other source read models into this tab; this intake never duplicates them as binder documents.
Drop a file here, or choose a file
Only this bordered surface accepts a drop. Clicking it opens the same picker. The rest of Papers remains ordinary navigation.
The flow accepts one paper at a time because the next fields belong to that file. Batch selection would create an unlabeled queue and make a permit type easy to attach to the wrong upload.
Paper type opens a bottom sheet on compact and an anchored menu on wide. The first set is Permit, Certificate and Other paper. Plans, contracts and change orders stay in their own flows.
The existing upload-session lifecycle retains the bytes. Restart keeps only the pending session id and expiry. The app asks for fresh signed PUT details and creates a new OPFS object URL for each web attempt; neither enters Drift. The document writer accepts only a completed upload from this project, and the upload id never reaches sync.
An interrupted upload remains Waiting to upload and retries with the same local task. Papers gains no document row until both upload completion and the idempotent document write succeed.
A permit can be saved with a label and application date before it has a number or issue date. Empty means not issued yet; it does not mean the record failed to load.
Application, issue and expiration dates use the platform calendar control. If entered, application cannot follow issue, and issue cannot follow expiration. The field always prints the localized date rather than storing formatted copy.
The name explains who is following up on the permit. It does not create a task, notify that person or claim they accepted responsibility.
If the permit write fails, the completed upload and entered facts remain on this screen. Retry sends the same idempotency key, so it cannot create a second document or permit.
Every project seat may ask to open an accessible document. The gateway authorizes the document, issues a short-lived storage URL and marks the response private and no-store. The URL, signed headers, storage key and completed upload id never enter Drift. Only the pending upload session id and expiry survive a restart.
The action carries the observed due date, 18 September 2028. A second device that has already advanced this task receives the changed-task state instead of appending another completion.
The 18 June entry carries its Kitchen identity and label snapshot. Renaming, reclassifying or deleting the room cannot rewrite where the work was done.
The sheet focuses this heading on entry, traps focus, reads Close then the two actions, and returns focus to the task row when dismissed. Only an owner or builder in a writable project sees completion actions.
The mockup draws the HouseChalk field that opens it, not a custom calendar. Compact and desktop use the same date bounds and localized result.
The client permits a local date through today. The server also requires the date to be on or after closing and no earlier than the latest effective completion for this task.
The queued assertion stores this date-only value and the observed scheduled due date. It does not replace the payload with a later retry date.
Care starts from your closing date.
Set closing date is online-only, carries the observed project version, and reconciles the imported catalog in the same locked project transaction.
This state does not draw future chores or a caught-up card. Without a closing date, the system does not know when any interval begins.
The action opens the themed platform calendar, announces the selected date, and returns focus here when the calendar closes.
Care starts from your closing date.
A builder can complete Care work after closing, but cannot author the project's closing date. A viewer can only read. Neither seat sees an unavailable Set closing date button.
The explanation does not change by role. Only the action changes, and absence of authority is expressed by absence of the control.
On 18 September 2028, fall runs through 30 November 2028. This alternate state assumes the September and October work is complete; the December task remains reachable under Later.
This is the existing year-two settled pattern — a tick and a sentence on the outline rung, where a sage card used to say it. It reports a useful result and never appears when the canonical query failed.
The local overlay moves the row into Already done, but the server still owns next_due_on. Sync clears the overlay only after both the completion and updated task arrive.
If delivery never started, Undo removes the local assertion. Once an attempt begins, Undo queues a dependent reversal and first replays the original idempotency key to recover the canonical completion id.
Sign-out or account switch blocks this drain before credentials change. Another person or another seat can never send Sam's queued assertion.
The Care view model keeps loading, data and error separate. It never tells someone their house is caught up because the read failed.
The spoken state announces once. Try again is a real action, and retry does not move focus into an empty schedule while the read is unresolved.
Transport and retryable server failures preserve the date, occurrence and idempotency key. Retry sends the same assertion instead of minting a second completion.
An authorization failure removes the overlay and refreshes membership. An invalid date returns to date selection. A stale occurrence uses frame 45 and is never retried as the old occurrence.
The server locked the task and rejected the old observed due date without appending history. Sync then supplied the canonical December occurrence.
The optimistic overlay is gone. The changed state announces once without stealing focus, and the reader must open the refreshed task before acting again.
projectWritePosture removes completion, reversal and closing-date actions while the project is read-only or its posture is unknown.
Restore resumes only the originating principal's drain. The state announcement does not steal focus, and there is no Retry button while archive still blocks the command.
The save carries If-Match for the observed project update and one idempotency key. The project update and Care reconciliation share one project lock and transaction.
Untouched tasks re-anchor. Recurring work with history stays derived from its latest effective completion, completed one-time work remains retired, and no historical room or completion snapshot changes.
Clearing is offered only while no completion exists. It retires catalog tasks as care not started instead of deleting synced rows.
The fiction's earliest completion is 18 June 2027. The server rejects 22 June with closing_after_care_history before it can make that completion precede closing.
The field keeps the rejected selection visible, explains the valid boundary in the reader's terms, and returns focus to date selection.
care_history_exists leaves the closing date, schedule and append-only ledger untouched. The only available next act is a valid correction.
The conflict is announced once, preserves keyboard focus, and contains no disabled Remove action.
The dialog carries the same title, guidance, room, due date, history and actions as frame 37. It does not turn desktop into a second Care information architecture.
Focus enters on the heading, remains trapped, closes with Escape, and returns to the invoking task row. The tab order is Close, Mark done today, then Choose another date.
The dialog appears only for an active task in a writable project held by an owner or builder. A retired one-time task opens history-only.
The field launches the themed platform date picker and returns its localized date here. Compact and desktop share the same upper bound and the same first-history ceiling.
Save carries the project version observed when this dialog opened. If the project changed, Care refreshes rather than overwriting a newer closing date.
This action is present only when the project has no completion row. Once history exists, frame 49 replaces it with the explanation and correction path.
This state appears only after the completion row and updated task arrive from the server. The pending overlay in frame 42 has cleared.
17 December comes from the canonical fold over the completed 18 September occurrence. The device never adds 90 days itself.
The action carries the completion id and opens the reversed-history state. It appends a reversal; it never deletes the completion.
The 18 September completion remains visible with its room snapshot and a linked reversal fact. The record does not pretend the first action never happened.
The same scheduled occurrence is active again because its completion no longer participates in the effective fold.
Only the seat that created the completion may reverse it during the allowed Undo window. A second reversal is refused rather than treated as success.
The settled message and two record sections reflow into columns. Their order, content and actions remain equivalent to frame 52.
The completed summary stays plain record text. Undo is the only trailing action for the completion just created.
The December occurrence is the gateway result displayed at desktop width, not a second calculation.
The active September occurrence and the reversed history entry can be read together without treating either as the other.
Desktop reads the same completion and reversal identities as compact. Width changes presentation, never the ledger.
The status announcement does not steal focus. The restored task row is the next reachable action.
They look identical on the contents page. They are not, and the difference is not effort in the abstract, it is which layer is missing.
decision_allowances is unique on (project_id, decision_id). Quote line items carry a category and no zone. Budget categories are a JSON string on the projects row, added by 0005_project_category_budgets.sql, not even a table. A per-room rollup is derivable through the decision_zones junction with no migration at all, so the cost is a query and a screen. What it also needs, and this is the part that is not engineering, is a product answer for a line item tagged to decisions spanning several rooms. The weight column at 0014:74 was created for exactly that, is nullable, and its own comment says it is unused; the rollup at strategies.go:297 divides evenly in the meantime. Even is a placeholder, not a decision./house/people reads synced contacts, project membership, explicit Room/System responsibility and builder-seat phone projection; /house/people/seats reads owner seats, member tags and decision scope for the household overview. Responsibility is entered by the builder and remains editable, per Q6, rather than inferred from workstreams or attributed from decisions after the fact. Plan 5 delivered the homeowner add-seat invitation and second-seat first-run handoff, so Z8 is complete while the rest of Track Z remains open.drawing_sets, sheets, immutable selected-run knowledge, the six P6 question tables and P7's review/application provenance live in migrations 0041, 0049 and 0051. /house/plans opens the API-backed filing cabinet; one selected set opens its no-dock conversation or bounded space review; every factual answer opens the retained derivative at its exact evidence polygon. Frames 25–33 propose P8's later-revision decision; P8 is not built.data/library/content/maintenance.json is the authored source, while the rebuild has only a minimal maintenance_tasks placeholder. Y4 adds the imported catalog and room relationships, the reachable closing-date writer, project schedule, immutable completion and reversal ledgers, sync and Drift projections, the principal-bound offline outbox, and the Care screen. Active catalog definitions must match a fact the project actually stores; property-dependent work waits for the later inventory rather than becoming universal by guess.One dead end worth a line. The appliances table has had a zone_id column since 0001_init.sql:90, and it has no handler, no route and no Dart model. The one place in the schema where a thing is already attached to a room is the one place nothing reads.
<span class="c"> in the same .tx, which the shared rule already stacks. This page adds no CSS of its own, which is the state mockup 13 got to and worth holding..card-absent until 2026-09-06 — a filled block at the card radius, which is a region wearing a card’s shape — and losing the box lost nothing, because the meaning was in the words the whole time. A homeowner reading "sheets are filed by number, not by room" understands it immediately; a badge saying "not built" tells them about our backlog._ds/FICTION.md has since taken them — the five allowances, the three quotes, and the $3,400 that is both the cabinet overrun here and CO-3's impact on the time pages. One number, two tabs, and neither can drift now. The people, firms, dates and the maintenance titles come from the arbiter or from data/library/content/maintenance.json. The sheet numbers extend the two the fiction already carries, A-1 and A-3, in the same short style rather than the A-101 form the migration comment uses, so the two pages agree.gutter_fall in data/library/content/maintenance.json, trade exterior. It is here because the second heading is the argument — a room-grouped Care tab needs somewhere to put what no room owns, and two kitchen appliances cannot make that point. Flagged in the source comment rather than quietly kept; the cap probably wants to read "no invented title".