{
  "blueprint": "client-onboarding-tracker",
  "builder": "Claude, following the phase prompts in order (a fresh subagent per phase that saw only the spec and the build folder)",
  "testedSpecSha256": "1721ef1a3b3c349bfe2f721e23386c3a6fe48af55499298619b6b30c9e734d3a",
  "reviewDate": "2026-10-29",
  "reviewMethod": "Playwright scripts (Chromium) clicked through the build as the named seed people and asserted on what was on screen, with direct requests where a check says the server must refuse something; the client progress page was opened in a separate browser context with no cookies. The run below is the single final run on a fresh database after all spec gaps were fixed, resetting to the seed before each phase's checks. Earlier per-phase runs found the gaps and are not counted. Results are final post-fix checks, not first-attempt success rates or an independent human audit.",
  "automatedTests": {
    "passed": 119,
    "total": 119,
    "command": "npm test",
    "rerunDuringReview": true
  },
  "gapsFixed": 18,
  "runs": [
    {
      "startedAt": "2026-10-29T09:04:05.233Z",
      "finishedAt": "2026-10-29T09:04:32.659Z",
      "phases": [
        1,
        2,
        3,
        4
      ],
      "passed": 28,
      "total": 28,
      "items": [
        {
          "phase": 1,
          "text": "Admin → People lists the seven people from section 15 with their titles. Dana and Ana are admins.",
          "status": "pass",
          "evidence": "7 rows: Dana Ruiz (Head of Ops, admin Yes); Ana Lima (Finance lead, admin Yes); Maya Chen (Customer success lead, admin No); Sam Okafor (Engineering lead, admin No); Ben Cho (IT, admin No); Jo Park (Account manager, admin No); Lee Park (Engineer, admin No)"
        },
        {
          "phase": 1,
          "text": "Signed in as Jo, there is no Admin menu, and opening the Admin → Templates address directly shows \"Admins only.\" Signed in as Ana, all three Admin screens open.",
          "status": "pass",
          "evidence": "Jo: no Admin menu; GET /admin/templates -> 403 \"Admins only.\"; direct POST -> 403. Ana opened /admin/people, /admin/templates, /admin/settings."
        },
        {
          "phase": 1,
          "text": "Admin → Templates shows \"Implementation · standard\" as Usable with six tasks (owners Dana, Maya, Sam, Ben, Maya, Dana; offsets 1, 2, 5, 6, 9, 10; \"Verify access and permissions\" marked Internal) and \"Enterprise · draft\" as \"Incomplete: needs Setup and Training tasks\".",
          "status": "pass",
          "evidence": "List: standard \"Usable\" (2/2/2), draft \"Incomplete: needs Setup and Training tasks\". Editor lists the six tasks in order with owners Dana, Maya, Sam, Ben, Maya, Dana and offsets 1, 2, 5, 6, 9, 10; only Verify access and permissions is tagged Internal."
        },
        {
          "phase": 1,
          "text": "Dana cannot save a new template named \"implementation · STANDARD\" (duplicate name) or a task with offset 366. A task with offset 365 saves.",
          "status": "pass",
          "evidence": "Duplicate name refused (\"A template named \"Implementation · standard\" already exists.\"), still 2 templates. Offset 366: browser input invalid (checkValidity false), direct POST -> 400, not saved. Offset 365 task saved and listed \"Offset: 365 days\"."
        },
        {
          "phase": 1,
          "text": "Dana deactivates Lee: he disappears from the sign-in-as switcher and from the default-owner picker. Reactivating him brings him back in both places.",
          "status": "pass",
          "evidence": "After Deactivate: switcher [Ana Lima (admin)|Ben Cho|Dana Ruiz (admin)|Jo Park|Maya Chen|Sam Okafor] without Lee, default-owner picker without Lee. After Reactivate: Lee Park in switcher and picker [Project owner|Ana Lima|Ben Cho|Dana Ruiz|Jo Park|Lee Park|Maya Chen|Sam Okafor]."
        },
        {
          "phase": 1,
          "text": "Moving the clock forward one day changes the date in the header and moves every date in the Templates live example one day later. Moving it back restores them.",
          "status": "pass",
          "evidence": "Header after +1 day: \"App date: Fri, Oct 30, 2026 · 05:04\". Live example dates Oct 30, Oct 31, Nov 3, Nov 4, Nov 7, Nov 8 -> Oct 31, Nov 1, Nov 4, Nov 5, Nov 8, Nov 9; after −1 day back to Oct 30, Oct 31, Nov 3, Nov 4, Nov 7, Nov 8."
        },
        {
          "phase": 2,
          "text": "The Board shows Northwind · Customer portal in Kickoff (Dana, 0%, \"2 overdue\"), Bluebird · Analytics rollout in Setup (Sam, 33%, \"2 overdue\"), Harbor Studio · Team workspace in Training (Maya, 67%, \"1 due today\") and Kestrel · Support launch in Live (Dana, 100%). The header reads \"3 in progress · 4 overdue tasks\".",
          "status": "pass",
          "evidence": "Header \"3 in progress · 4 overdue tasks\". Cards: kickoff: Northwind Customer portal Owner: Dana Ruiz 0% 2 overdue In Kickoff 3d | setup: Bluebird Analytics rollout Owner: Sam Okafor 33% 2 overdue In Setup 6d | training: Harbor Studio Team workspace Owner: Maya Chen 67% 1 due today In Training 3d | live: Kestrel Support launch Owner: Dana Ruiz 100% Live since Oct 25"
        },
        {
          "phase": 2,
          "text": "Jo creates client \"Ridgeway\", project \"Partner portal\", from \"Implementation · standard\", starting today, owner Dana. The preview and the saved project both show six tasks due 1, 2, 5, 6, 9 and 10 days from today, owned by Dana, Maya, Sam, Ben, Maya and Dana. Ridgeway appears in Kickoff below Northwind.",
          "status": "pass",
          "evidence": "Preview and saved project: Confirm success criteria: Dana Ruiz · due Oct 30; Run kickoff workshop: Maya Chen · due Oct 31; Import client data: Sam Okafor · due Nov 3 · Starts after Kickoff; Verify access and permissions: Ben Cho · due Nov 4 Internal · Starts after Kickoff; Train client champions: Maya Chen · due Nov 7 · Starts after Setup; Approve go-live checklist: Dana Ruiz · due Nov 8 · Starts after Setup. Kickoff column order: Northwind, Ridgeway."
        },
        {
          "phase": 2,
          "text": "Creating \"ridgeway\" / \"Partner Portal\" again is refused as a duplicate; \"Ridgeway\" / \"Billing migration\" is accepted. \"Enterprise · draft\" is listed but disabled, and a direct request that uses it is refused.",
          "status": "pass",
          "evidence": "Duplicate refused: \"Ridgeway · Partner portal already exists.\". Ridgeway · Billing migration created. \"Enterprise · draft\" option disabled; direct POST with it -> 400, no project created."
        },
        {
          "phase": 2,
          "text": "Signed in as Jo, Northwind's checkboxes are disabled and a direct request to complete \"Confirm success criteria\" is refused. Signed in as Maya, \"Train client champions\" on Northwind shows \"Starts after Setup\" and a direct request to complete it is refused.",
          "status": "pass",
          "evidence": "Jo: 6 disabled checkboxes; direct POST /projects/:id/tasks/:id/complete -> 403. Maya: \"Train client champions Maya Chen · due Nov 4 · Starts after Setup\"; direct complete -> 409 (\"Training hasn&#39;t started yet. This task starts after Setup.\"). Tasks still open."
        },
        {
          "phase": 2,
          "text": "Dana presses Hand off on Northwind and sees \"Kickoff isn't finished: 2 open tasks (Confirm success criteria, Run kickoff workshop).\" Dana and Maya each complete their own task. Northwind shows 33% and no overdue label.",
          "status": "pass",
          "evidence": "Gate message: \"Kickoff isn't finished: 2 open tasks (Confirm success criteria, Run kickoff workshop).\". After Dana and Maya tick their tasks: project \"33% (2 of 6 closed)\", \"None overdue\"; card \"Northwind Customer portal Owner: Dana Ruiz 33% In Kickoff 3d\"."
        },
        {
          "phase": 2,
          "text": "Dana hands Northwind off to Sam with the note \"Data export arrives Friday\". The card moves to Setup with owner Sam; \"Import client data\" still belongs to Sam and \"Verify access and permissions\" to Ben; the Kickoff checkboxes are locked. A second handoff is refused until Setup is finished.",
          "status": "pass",
          "evidence": "Card in Setup: \"Northwind Customer portal Owner: Sam Okafor 33% In Setup 0d\". Import client data: Sam Okafor; Verify access and permissions: Ben Cho. Kickoff section \"Kickoff · Finished, locked\", checkboxes disabled. Second handoff refused: \"Setup isn't finished: 2 open tasks (Import client data, Verify access and permissions).\"."
        },
        {
          "phase": 2,
          "text": "On Bluebird, Sam skips \"Import client data\" with the reason \"Client has no legacy data\" (progress 50%), then reassigns \"Verify access and permissions\" to Lee. Signed in as Lee, it is listed under Overdue in My tasks; he completes it (67%). Sam hands off to Maya and Bluebird moves to Training.",
          "status": "pass",
          "evidence": "Skip -> 50% (3 of 6). Verify reassigned: \"Verify access and permissions Lee Park · due Oct 27 · 2 days overdue Internal Edit Skip\". Lee's My tasks Overdue: \"Overdue (1) Verify access and permissions Bluebird · Analytics rollout · Setup · due Oct 27 · 2 days overdue\". Lee ticked it -> 67% (4 of 6). Handoff to Maya: card in Training \"Bluebird Analytics rollout Owner: Maya Chen 67% In Training 0d\"."
        },
        {
          "phase": 2,
          "text": "On Harbor Studio, Maya completes \"Train client champions\" and then cannot change its owner until she reopens it. Setting the due date of \"Approve go-live checklist\" to the day before the project's start date is refused.",
          "status": "pass",
          "evidence": "Done task has no Edit link (\"Train client champions Maya Chen · due Oct 29 Done by Maya Chen, Oct 29, 2026, 05:04 Reopen the task to edit it.\"); direct owner change -> 409 \"Reopen the task first.\". After reopening, owner changed to Lee Park. Due date 2026-10-19 (day before start 2026-10-20): browser input invalid (true), direct POST -> 400 \"The due date can&#39;t be before the project&#39;s start date (Oct 20, 2026).\"; still \"due Oct 30\"."
        },
        {
          "phase": 2,
          "text": "Kestrel has no Hand off button and its checkboxes are locked; a direct request to reopen \"Approve go-live checklist\" is refused. Northwind's activity log lists its creation, both completions and the handoff with its note, each with actor and time.",
          "status": "pass",
          "evidence": "Kestrel: no Hand off button, 6 checkboxes disabled, direct reopen -> 409. Northwind activity log (4): Dana Ruiz handed off Kickoff → Setup, owner Dana Ruiz → Sam Okafor. Note: Data export arrives Friday Dana Ruiz · Oct 29, 2026, 05:04 | Completed by Maya Chen: “Run kickoff workshop”. Maya Chen · Oct 29, 2026, 05:04 | Completed by Dana Ruiz: “Confirm success criteria”. Dana Ruiz · Oct 29, 2026, 05:04 | Jo Park created the project from Implementation · standard, starting Oct 26, owner Dana Ruiz. Jo Park · Oct 26, 2026, 09:00"
        },
        {
          "phase": 3,
          "text": "With the clock at 07:00 today (team time), Run job now creates no digests. At 08:00 it creates exactly five, for Dana, Ana, Maya, Sam and Ben. Running it again at 09:00 creates none.",
          "status": "pass",
          "evidence": "07:00: 0 digests. 08:00: 5 digests (Sam Okafor sam@copperline.example; Maya Chen maya@copperline.example; Dana Ruiz dana@copperline.example; Ben Cho ben@copperline.example; Ana Lima ana@copperline.example). 09:00: still 5."
        },
        {
          "phase": 3,
          "text": "The digests match the table in section 13. Sam's lists \"Import client data · Bluebird (3 days)\" under Overdue and \"Verify access and permissions · Bluebird (Ben, 2 days)\" under On your projects. Maya's lists \"Train client champions · Harbor Studio\" under Due today. Ana's contains only \"Import client data · Bluebird (Sam, 3 days)\".",
          "status": "pass",
          "evidence": "Dana — Overdue: - Confirm success criteria · Northwind (2 days) / On your projects: - Run kickoff workshop · Northwind (Maya, 1 day) / Late across the team: - Import client data · Bluebird (Sam, 3 days) || Ana — Late across the team: - Import client data · Bluebird (Sam, 3 days) || Maya — Overdue: - Run kickoff workshop · Northwind (1 day) / Due today: - Train client champions · Harbor Studio || Sam — Overdue: - Import client data · Bluebird (3 days) / On your projects: - Verify access and permissions · Bluebird (Ben, 2 days) || Ben — Overdue: - Verify access and permissions · Bluebird (2 days)"
        },
        {
          "phase": 3,
          "text": "Dana completes both Northwind Kickoff tasks (the activity log shows \"Completed by Dana Ruiz for Maya Chen\") and hands off to Sam with a note. The outbox gains exactly two emails: the handoff to Sam, with the note and \"Import client data\", and \"Setup has started on Northwind · Customer portal\" to Ben. With no email provider configured, both show \"logged\".",
          "status": "pass",
          "evidence": "Log: \"Completed by Dana Ruiz for Maya Chen\". Outbox +2: to Sam Okafor sam@copperline.example (handed_off, logged): \"Dana Ruiz handed Northwind · Customer portal to you at Setup. Note: Data export arrives Friday. Your tasks: Import client data, due Oct 31.\"; to Ben Cho ben@copperline.example (stage_started, logged): \"Setup has started on Northwind · Customer portal\"."
        },
        {
          "phase": 3,
          "text": "Sam puts Bluebird on hold with the reason \"Client paused for budget review\". Its card shows On hold and no overdue label. Signed in as Ben, \"Verify access and permissions\" cannot be ticked and a direct request is refused. Ben, Maya and Dana each get an on-hold email; Sam does not.",
          "status": "pass",
          "evidence": "Card: \"Bluebird Analytics rollout Owner: Sam Okafor 33% In Setup 6d On hold\". Ben: checkbox disabled; direct complete -> 409. On-hold emails to Dana Ruiz dana@copperline.example, Maya Chen maya@copperline.example, Ben Cho ben@copperline.example; none to Sam."
        },
        {
          "phase": 3,
          "text": "Move the clock 5 days forward. Sam resumes Bluebird; the dialog proposes moving open due dates 5 days later and he accepts. Each open task is due 5 days later than before, and the card shows \"2 overdue\" again (3 days and 2 days).",
          "status": "pass",
          "evidence": "Resume form proposed 5 days (\"Resume On hold for 5 days. Resuming proposes moving every open due date (4 tasks) by the days on hold. Change it to any number, or 0 to keep the dates. Move ope\"). Due dates Import client data Oct 26 -> Oct 31; Verify access and permissions Oct 27 -> Nov 1; Train client champions Oct 30 -> Nov 4; Approve go-live checklist Oct 31 -> Nov 5. Card \"Bluebird Analytics rollout Owner: Sam Okafor 33% 2 overdue In Setup 11d\"; Import client data 3 days overdue, Verify access and permissions 2 days overdue."
        },
        {
          "phase": 3,
          "text": "Signed in as Sam, Harbor Studio has no Cancel action and a direct request is refused. Dana cancels it with the reason \"Client churned\": it leaves the Board (it shows with \"Show cancelled\"), its checkboxes are locked, and Maya gets a cancellation email.",
          "status": "pass",
          "evidence": "Sam: no Cancel action; direct POST -> 403. Dana cancelled: 6 checkboxes disabled; not on Board; with Show cancelled: \"Harbor Studio Team workspace Owner: Maya Chen 67% In Training 8d Cancelled\". New outbox rows: Maya Chen maya@copperline.example (cancelled)."
        },
        {
          "phase": 3,
          "text": "Dana tries to deactivate Ben and is told he owns 2 open tasks. She uses \"Reassign all to…\" Lee: both \"Verify access and permissions\" tasks (Northwind and Bluebird) move to Lee, Lee gets one email listing them, and Ben can now be deactivated. Admin → Templates warns that Ben Cho is inactive, and a new project from \"Implementation · standard\" gives that task to its project owner.",
          "status": "pass",
          "evidence": "Refused: \"Ben Cho still owns 2 open tasks and 0 projects that are active or on hold. Use “Reassign all to…” to move them first.\". Reassign all to Lee: Verify on Northwind and Bluebird now Lee Park; one email to Lee listing both (\"Dana Ruiz reassigned Ben Cho's work to you. Tasks: Verify access and permissions on Bluebird · Analytics rollout, due Nov 1; Verify access and permissions on Northwind · Customer portal, due Nov 1.\"). Ben then deactivated (Ben Cho ben@copperline.example IT No Inactive 0 0 Edit Reactivate). Templates: \"Warning: Ben Cho is inactive; “Complete security questionnaire” will go to the project owner.\". New Ridgeway project preview \"Ben Cho is inactive; assigned to Dana Ruiz.\"; saved task: \"Verify access and permissions Dana Ruiz · due Nov 9 Internal · Starts after Kickoff Edit Skip\"."
        },
        {
          "phase": 4,
          "text": "Sam creates a client link on Bluebird. In a private window, without signing in, it shows Copperline, \"Bluebird · Analytics rollout\", the stage tracker at Setup, \"2 of 5 done\" and five tasks. \"Verify access and permissions\", Sam's comment, email addresses and overdue labels do not appear.",
          "status": "pass",
          "evidence": "Signed-out context (0 cookies) at /p/<token>: 200; \"Copperline Bluebird · Analytics rollout Kickoff Done Setup Current stage Training Live 2 of 5 done Kickoff Confirm succe\"; tracker aria-current = setup; \"2 of 5 done\"; tasks: Confirm success criteria · Dana Done Oct 22; Run kickoff workshop · Maya Done Oct 23; Import client data · Sam Due Oct 26; Train client champions · Maya Due Oct 30; Approve go-live checklist · Dana Due Oct 31. HTML has no \"Verify access and permissions\", no comment, no email address, no \"overdue\". Headers: cache-control no-store, x-robots-tag noindex, referrer-policy no-referrer."
        },
        {
          "phase": 4,
          "text": "After the page is opened, Bluebird's link panel shows a \"Last viewed\" time. Signed in as Jo, Bluebird has no link actions and a direct request to create one is refused.",
          "status": "pass",
          "evidence": "Sam's panel: \"Last viewed Oct 29, 2026, 05:04\". Jo's panel: \"Client link A read-only progress page the client can open without signing in. It shows tasks shared with the client, never Internal tasks, comments or reasons. The client link is active. Created Oct 2\", 0 buttons; direct POST create/replace/revoke -> 403/403/403."
        },
        {
          "phase": 4,
          "text": "Sam revokes the link. Reloading the page shows \"This link is not active. Ask your Copperline contact for a new one.\" A newly created link works; the old one stays inactive.",
          "status": "pass",
          "evidence": "Old link after revoke -> 404 \"This link is not active. Ask your Copperline contact for a new one.\". New link -> 200 with \"Bluebird · Analytics rollout\". Old link again -> 404 not-active page."
        },
        {
          "phase": 4,
          "text": "Dana creates a link for Kestrel: it shows \"Live since\" the go-live date 4 days ago and \"5 of 5 done\". With the clock moved 27 days forward, the same link shows the not-active page, and Kestrel is gone from the Live column unless \"Show older live projects\" is on. Then move the clock back 27 days.",
          "status": "pass",
          "evidence": "Kestrel page: \"Live since Oct 25\", \"5 of 5 done\". Clock +27 days (2026-11-25 05:04): link -> 404 not-active page; Live column \"Live (0) No projects in Live.\"; with Show older live projects: \"Live (1) Kestrel Support launch Owner: Dana Ruiz 100% Live since Oct 25\". Clock back to 2026-10-29: Kestrel in Live again."
        },
        {
          "phase": 4,
          "text": "Handoffs lists the six seeded handoffs newest first: Harbor Studio Setup → Training (Sam Okafor → Maya Chen, 3 days ago) at the top, Kestrel Kickoff → Setup (12 days ago) at the bottom.",
          "status": "pass",
          "evidence": "Six handoffs, newest first: Oct 26, 2026, 17:00 · 3 days ago Harbor Studio · Team workspace Setup → Training Owner: Sam Okafor → Maya Chen Handed off by Sam Okafor | Oct 25, 2026, 17:00 · 4 days ago Kestrel · Support launch Training → Live Owner: Maya Chen → Dana Ruiz Handed off by Maya Chen | Oct 23, 2026, 17:00 · 6 days ago Bluebird · Analytics rollout Kickoff → Setup Owner: Dana Ruiz → Sam Okafor Handed off by Dana Ruiz | Oct 22, 2026, 17:00 · 7 days ago Harbor Studio · Team workspace Kickoff → Setup Owner: Dana Ruiz → Sam Okafor Handed off by Dana Ruiz | Oct 21, 2026, 17:00 · 8 days ago Kestrel · Support launch Setup → Training Owner: Sam Okafor → Maya Chen Handed off by Sam Okafor | Oct 17, 2026, 17:00 · 12 days ago Kestrel · Support launch Kickoff → Setup Owner: Dana Ruiz → Sam Okafor Handed off by Dana Ruiz"
        },
        {
          "phase": 4,
          "text": "Signed in as Dana, Projects → Export CSV downloads four rows. Bluebird's has stage \"setup\", progress_percent 33 and overdue 2; Kestrel's has days_to_live 10. Signed in as Jo, there is no Export button and a direct request is refused.",
          "status": "pass",
          "evidence": "Dana's download projects-2026-10-29.csv: header \"client,project,template,stage,status,owner,start_date,live_date,tasks_total,tasks_done,tasks_skipped,tasks_open,overdue,progress_percent,days_in_stage,days_to_live\", 4 rows. Bluebird: Bluebird,Analytics rollout,Implementation · standard,setup,active,Sam Okafor,2026-10-21,,6,2,0,4,2,33,6,. Kestrel: Kestrel,Support launch,Implementation · standard,live,active,Dana Ruiz,2026-10-15,2026-10-25,6,6,0,0,0,100,4,10. Jo: no Export button; GET /projects/export.csv -> 403."
        }
      ]
    }
  ],
  "notTested": [
    "Production sign-in: Google sign-in limited to the company domain was built, but every check used the development \"sign in as\" switcher.",
    "Real email delivery: notifications and digests were written to the outbox and logged, not sent; a failing provider was simulated only in automated tests.",
    "The hourly job on a real scheduler: it was run from \"Run job now\" with the development clock; the /api/cron/tick endpoint and its secret were exercised only in automated tests.",
    "Copying the client link to the clipboard and opening it on a client's own device: checks read the link from the panel and opened it in a signed-out browser context.",
    "Two people handing off the same project at the same moment from two browsers: automated tests only.",
    "Hosting: the build ran on SQLite on one server."
  ]
}