S1: Task for slot S09. It builds part of the Ops canvas's area 6 for #1165. Decision D632. Migration 422, only if a store is missing.
| Board |
Screen |
Where it lives |
| V1 |
ct-variants |
/raise/cap-table/variants/[variant]: a draft variant, edited in place |
| S1 |
st-invite |
/firm/seats: the inviter’s side |
| S2 |
st-accept |
/invite/[token]: the colleague’s accept page (phone) |
The design
The screens are in the Ops canvas, which arrives in #1387:
What is on main
The work (Worker first)
Before building a screen, confirm the Worker route answers everything it draws. Where it does not, the Worker change comes first, in the same PR.
- Draft variants (V1).
- Rename a variant.
- Edit its founders, option pool, SAFEs, rounds and exit value in place.
- The main cap table stays one per company.
- The inviter (S1).
- Right after inviting, show the invite link to copy, once, because no email is sent.
- Then show the seat with its state and "Revoke".
- The invite call returns the link once. Listing seats never returns it, and the screen never asks it to.
- The colleague (S2).
- Who invited them, and what the seat gives.
- A warning that accepting turns their account into an investor account.
- Its states:
- signed out: sign in, then come back;
- the wrong account: the invite was for another email;
- revoked;
- already accepted;
- the inviter's plan no longer covers seats.
Rules
-
Where a screen goes. A canvas route label says where the screen lives. Build it into the page that already serves that address, as a tab or a panel where the canvas draws one. Add a new address only where nothing serves it, and add its ROUTE_MAP.md row.
-
States. Each screen draws the canvas's states:
- loading;
- empty;
- "Not recorded", with its one-line reason;
- "Unreadable", with "Try again".
A failed read never shows a zero or an empty list.
-
Writes. Every write records its actor, through logAdminAction or activity_logs, and every refusal the route can give reads as a sentence.
-
Phone. Draw the 390-wide layout for each screen the board marks as phone.
-
Copy. The AI is Eadwyn. Product copy never says advisor, advice, recommendation or fiduciary; a human advisor role is fine.
Files this task owns
- the page that serves the cap table’s variants
- the page where an Institutional investor manages seats today (find it from
App.jsx), and frontend/src/pages/AcceptInvestorSeatPage.jsx
- the seat Worker routes, only where one does not answer what the screen draws
- new frontend and Worker tests
documentation/architecture/decisions/D632.md, and the ROUTE_MAP.md rows it changes
The canvas files are read, never edited.
Done when
- Tests render each screen's real component in its states:
- the invite link shown once and never re-read from the list
- each accept state, including the wrong account
- Each Worker change has a route test.
- Every new assertion is mutation-checked.
npm run build, then npm run test:drift, exits 0.
Generated by Claude Code
S1: Task for slot S09. It builds part of the Ops canvas's area 6 for #1165. Decision D632. Migration 422, only if a store is missing.
ct-variants/raise/cap-table/variants/[variant]: a draft variant, edited in placest-invite/firm/seats: the inviter’s sidest-accept/invite/[token]: the colleague’s accept page (phone)The design
The screens are in the Ops canvas, which arrives in #1387:
design/canvases/integrated/ops-data.jsholds each screen asscreens['<id>']: its labels, columns, actions, refusals and states. It reads as plain text.Ops Page.dc.htmldraws the screens, andOps · Boards.dc.htmllays them out (setdeals).git fetch origin claude/spinout-lab-workspace-wuyyqd, thengit show FETCH_HEAD:design/canvases/integrated/ops-data.js.What is on
main/invite/:tokenisAcceptInvestorSeatPage.jsx, which callsacceptInvestorSeat. D611 (Colleague seats: the invite reaches the colleague, and accepting never turns an admin into an investor (D611) #1311, merged as D611: colleague seat invites reach the colleague #1329) added it: the colleague seat's invite arrives, and nothing changes a role silently. Compare it with S2, and build what is missing.updateCapTableScenario.The work (Worker first)
Before building a screen, confirm the Worker route answers everything it draws. Where it does not, the Worker change comes first, in the same PR.
Rules
Where a screen goes. A canvas route label says where the screen lives. Build it into the page that already serves that address, as a tab or a panel where the canvas draws one. Add a new address only where nothing serves it, and add its
ROUTE_MAP.mdrow.States. Each screen draws the canvas's states:
A failed read never shows a zero or an empty list.
Writes. Every write records its actor, through
logAdminActionoractivity_logs, and every refusal the route can give reads as a sentence.Phone. Draw the 390-wide layout for each screen the board marks as phone.
Copy. The AI is Eadwyn. Product copy never says advisor, advice, recommendation or fiduciary; a human advisor role is fine.
Files this task owns
App.jsx), andfrontend/src/pages/AcceptInvestorSeatPage.jsxdocumentation/architecture/decisions/D632.md, and theROUTE_MAP.mdrows it changesThe canvas files are read, never edited.
Done when
npm run build, thennpm run test:drift, exits 0.Generated by Claude Code