Built in public · Changelog

How Supernova learned the job.

The product story, newest first: what actually became possible in each stretch, not a list of tweaks. Generated live from the engineering journal; the log is the changelog.

162

improvements shipped

14

days of building

12

shipped per day, avg

9
6 Jul
8
7 Jul
1
8 Jul
2
10 Jul
5
11 Jul
25
12 Jul
6
13 Jul
peak37
14 Jul
7
15 Jul
21
16 Jul
4
17 Jul
22
18 Jul
5
19 Jul
10
20 Jul

Product panorama

One deal, one continuous operating loop.

Seventeen agents live in the product today, two squads (7 sales-side, 10 delivery-side), propose-only, a named human at every gate. Everything below ships; nothing is a mock.

017 agents on the desk

Sell

Daily Brief, Email Drafter, Call Notes, Deal Check, Meeting Prep, Promise Tracker and Enrich run the deal desk, evidence attached.

02provenance quoted

Spec

A won deal births the project; Persona Researcher and Spec Writer read the real corpus and draft the use-case tree, every requirement quoting its source.

03the ratchet

Model

Data Modeler, Role Definer and Page Architect ratchet ontology, roles and the page atlas forward, one approved artifact feeding the next.

04on real components

Design

Designer codifies the design language; Mock Builder renders one mock per page wearing the approved tokens.

05earned, not declared

Run

E2E Writer specs the tests; Tech Stack Advisor and Impact Analyst guard the plan; delivery runs five-state stories, bugs, QA gates and release exit criteria.

06propose-only

Audit

Every run is a session you can open: model calls, tool calls, cost, the audit trail behind every artifact.

19

Jul 2026

Sunday

1 shipped

Fix00:12 IST

Tasks grow up: five states, and bugs become their own issue type

The user called the three-state workflow a toy ("very very very less states on a task, we have no way to raise a bug") and pointed at glue/boostr-web as the reference - whose ticket model…

The user called the three-state workflow a toy ("very very very less states on a task, we have no way to raise a bug") and pointed at glue/boostr-web as the reference - whose ticket model runs FOURTEEN lifecycle stages with agents driving the transitions. Landed the right-sized version: the delivery axis is now To do → In progress → In review → In QA → Done (Blocked stays a flag - work has a place AND a problem, two different facts) across the board's five columns, the dev's verbs (Start / Send to review / Send to QA, each with its way back), and QA's queue (In-QA stories first). The DONE column now belongs to QA: verify-and-close is hard-gated server-side - every test case carrying a latest-run PASS and zero open bugs, or the action refuses with the exact counts - and return-to-dev carries a mandatory note to the assignee. And bugs are first-class issues at last: raised from QA's bench (severity + what-broke detail mandatory), auto-assigned to the story's assignee, walked OPEN → In progress → FIXED by the dev, verified CLOSED (or reasoned WONT_FIX) by QA - every hop audited and notified, open bugs counted on the runway line. The deeper glue lessons (agents as tool-using loops with session ledgers, triage as a pipeline stage, dev plans as artifacts) are recorded as the next horizon in TASKS.

18

Jul 2026

Saturday

2 shipped

Fix10:52 IST

SalerySe's cast was 100% wrong, and the signed agreement knew it

User: "/tech-lead/personas?project=38 is 100% wrong, read please for me." Reading the corpus properly proved it three ways. (1) The uploaded "scope doc" was POISON: 80KB of one sentence…

User: "/tech-lead/personas?project=38 is 100% wrong, read please for me." Reading the corpus properly proved it three ways. (1) The uploaded "scope doc" was POISON: 80KB of one sentence repeated 2000x - the wizard byte-verification test file from the original live-fire, sitting in the corpus as the only readable scope ever since. Deleted. (2) The signed ToD agreement (readable now via the docx extractor) defines the REAL product in its recitals: SalarySe (Critical Path Technologies) is a salary-linked financial wellness platform - UPI-linked credit cards, InstaCash early wage access, tax-saving flexi-benefits, FD investments, integrated into employer payroll - NOT "payroll and compensation software" as the guessed-blind DESIGN.md claims. (3) The cast was engagement STAFF (Delivery Lead, UI/UX Designer, Account Lead), not the product's people.

  • Prompt rule sharpened: the cast is the CLIENT PRODUCT'S people; when the engagement is design/build work FOR a client's product, the cast is that product's users - delivery-side staff are stakeholders, never personas, even when use-case actors name them.
  • Re-ran on SalerySe (3.7 min): the cast pivoted to Salaried Employee (End User), Employer HR/Payroll Partner, Product Owner (approver), Cofounder (buyer), Technical Team (receives the Work Product). Antino's own staff left the cast. Pains now cite the agreement BY CLAUSE ("Clause 5(b): five business days to flag resource performance issues", "Work Product vests exclusively in the Client"). The two product personas carry researched-only pains, honestly - the corpus says what the product IS but not yet what its users suffer; that is what discovery is for.
  • Follow-up (user: "why is the Technical Team there at all?"): right again - receiving the handoff is an engagement relationship, not a product one, and quoting the contract about someone does not make them a product person. Rule sharpened: the CLIENT's engagement-side people (sponsor, deliverable-approver, receiving engineers) are stakeholders too; BUYER/APPROVER mean buyer/approver OF THE PRODUCT. Third run (v3): Salaried Employee [USER], Employer Benefits Administrator [BUYER], and Payroll/HRMS Integration as a [SYSTEM] actor - the engagement people now live only where they belong, the Overview's Team & stakeholders panel. v1/v2/v3 all preserved.
  • Named cascade, not yet fixed: use cases v3, the ontology (DesignEngagement et al), DESIGN.md's identity paragraph, pages, and mocks for 38 were all built on the engagement-as-product misreading and need their regeneration pass through the gate.
Fix09:31 IST

The vanilla theme inspected pixel by pixel, and three fixes

The user asked for a close inspection. Chrome extension was down, so a Playwright harness (tests/e2e/.state, the suite's own storage states) screenshotted seven tech-lead pages AND ran a…

  • The user asked for a close inspection. Chrome extension was down, so a Playwright harness (tests/e2e/.state, the suite's own storage states) screenshotted seven tech-lead pages AND ran a canvas-normalized computed-style audit: every visible text element's fg/bg composited through translucent layers (lab()/oklab() normalized via canvas), true WCAG ratio per pair. Findings and fixes, all measured:
  • text-clay on clay washes had regressed (base clay went hot, so bg-clay/10 text-clay chips - must/BUYER/COMPLETED/Planning - fell to 2.4:1): swept to text-clay-ink across 12 files, and clay-ink itself deepened #b94a0a -> #a34108 (5.2-5.5 on every wash; also fixes the 4.38 near-miss on bg-vanilla chips). Charts ramp + entity-colors follow.
  • muted-foreground was under body-text AA everywhere (3.2-3.6): #8c8475 -> #6f6757 in the light scopes (4.8-5.4 on every app surface). Pre-existing, not a shift regression, fixed anyway.
  • Semantic chips one step light: emerald-600 -> 700, sky-600 -> 700 on approved/EVIDENCED/RESEARCHED/phase chips (4.5-4.9).
  • After fixes: five of seven pages have ZERO sub-AA pairs. Leftovers live in the parallel session's open plan-board.tsx ("active" emerald chip, clay-hot-as-text label) and the deliberate text-muted-foreground/70 timestamp idiom (lifted from 2.3 to ~3.5 by the muted fix; kept as quiet meta).

16

Jul 2026

Thursday

1 shipped

Fix10:37 IST

The app gets its first error boundary; the sign-in "unexpected response" explained

User hit "An unexpected response was received from the server" on /sign-in. Root cause: a STALE TAB, not a code bug - every dev recompile (and every production deploy) rotates Next's…

  • User hit "An unexpected response was received from the server" on /sign-in. Root cause: a STALE TAB, not a code bug - every dev recompile (and every production deploy) rotates Next's server-action IDs, so a tab left open across one submits an action the server no longer recognises. A hard refresh fixed it on the spot.
  • The durable fix: src/app/error.tsx - the first error boundary this app has had. It detects the stale-action message and says the true thing ("This tab is out of date... refresh once and carry on, nothing was lost") with a one-click refresh; every other error gets a calm Daylight card with retry (unstable_retry - this Next's API, not the old reset), full refresh, and the digest for the server log. No more white pages or dev-overlay hieroglyphics for users.
  • Also verified the MEDDPICC score live as an AE (the browser session is Anisha now): 44/100 developing, amber bar, all 8 evidence rows, receipt line - exactly as designed.

14

Jul 2026

Tuesday

4 shipped

Fix19:22 IST

/design goes espresso: the dark-mode contrast pass, fixed in the reusables

The user's read on "the app feels light but not the landing's way" became a direction: the design page now runs the full espresso dark theme as the proving ground. /design wears .app-theme…

The user's read on "the app feels light but not the landing's way" became a direction: the design page now runs the full espresso dark theme as the proving ground. /design wears .app-theme dark, an espresso rail (.section-dark sidebar with the landing wordmark register), the landing's ruled eyebrow on the header, and a dark-aware canvas (faint cream dots, warm glow, never a white haze). Global radius knob turned down 14px→10px (crisper at app density).

The contrast pass then went component by component, every fix in the REUSABLE layer so the whole app inherits:

  • Root cause found: .dark only remaps variables, so any text without an explicit color class inherited body's light-resolved ink — dark-on-dark across the page. Fix: the dark scope carries text-foreground (documented in the page).
  • Table rewritten (ui/table.tsx): mono uppercase header BAND on a tone step with a stronger rule, real cell padding (px-4 py-2.5), theme-real hover (row-hover token, not invisible muted/50), selected rows in the warm clay wash, footer on the strong rule. Now reads as a data grid in both themes; every table in the app upgrades for free.
  • Elevation became theme-aware: --shadow-rest/raised/float now route through --elev-* vars (warm-tinted on cream, real black weight on espresso — a 5% warm shadow is invisible on dark).
  • Skeleton / Progress / Slider tracks: bg-muted (a near-zero tone step on espresso) → foreground-relative washes, visible in both themes.
  • Scrims (dialog/sheet/drawer/alert-dialog): bg-black/10 gets dark:bg-black/45.
  • Sonner on the dark page pins theme="dark" (it otherwise follows the OS, not the page scope).
  • Canvas glow fix shipped to the light app too: the near-white radial that washed every app page pale at the top is now warm cream.
Fix13:32 IST

Close-on-activity: doing the work closes the follow-up (the durable fix)

The backlog rebuilds because "mark done" is a separate step reps skip. So make the work itself close the task. On the SDR lead hub, logging real activity — Send email / Log a call / Book a…

The backlog rebuilds because "mark done" is a separate step reps skip. So make the work itself close the task. On the SDR lead hub, logging real activity — Send email / Log a call / Book a meeting — now completes the lead's next open follow-up in the same action (completeNextForLead, subject-matched to the lead), toasts "Follow-up marked done ✓ — you just did it", and refreshes so it vanishes. The manual Done on the lead's task list now persists too (was toast-only). Both write the task_completions overlay + an audit event (reversible, PREVIEW).

  • Extracted a shared, role-flexible src/lib/tasks/actions.ts (completeTasks bulk + completeNextForLead); the cleanup panel re-exports from it. getLeadTasks now excludes cleared tasks (overlay), so the hub reflects it instantly. Verified end-to-end (lead "Sagar/Anaplan" → "Followup 2" auto-completes + hides).
  • Not yet wired: the inbox (parallel session's /ae/inbox) and the AE lead hub (inline, no rail) — same pattern applies when those are touched.
Fix13:22 IST

Proshort: incremental 10-min sync + a false-match fix

The mirror had gone stale (525 recordings, last one 12-Jul) because the only tooling was a full backfill (~10 min of throttled calls — too heavy to run often). Re-ran it (525 → 548, now…

The mirror had gone stale (525 recordings, last one 12-Jul) because the only tooling was a full backfill (~10 min of throttled calls — too heavy to run often). Re-ran it (525 → 548, now current through today 14-Jul 11:30), then built the missing incremental path:

  • `src/lib/proshort/sync.ts`syncProshortIncremental(): walks the recordings list newest-first and stops as soon as a page holds nothing new, so a routine run is 1 list call + N details (usually N=0). Also refreshes the last 2 days of recordings, whose insights Proshort finishes generating after the call. Writes a DELTA batch row.
  • `POST/GET /api/proshort/sync` — token-guarded (shared token or Vercel Cron's Bearer $CRON_SECRET).
  • Every 10 minutes: vercel.json cron (*/10 * * * *) for deploy, + scripts/proshort/watch.mjs for local (a loop that hits the route; node scripts/proshort/watch.mjs).
  • Bug fix — false recording matches: getMeetingEvent's matcher joined on any shared party email, so a recording could link to a meeting merely because a colleague was in both (only the 30-min window prevented it). Now requires a genuine external party via the shared nonCorporateDomainsSql (which already excludes our own tenants + free providers).

Finding: the "Negotiation Discussion — Right Horizon x Antino" (13-Jul) has no recording because that call was never recorded — the mirror is current and 16 other calls exist from that day; Right Horizons' last recorded call is 03-Jul.

Fix12:45 IST

Two calendar-data bugs found via the briefing: recurring subjects + a 5:30 timezone error

The briefing surfaced two real mirror bugs (both now fixed in the shared DB + at the source):

The briefing surfaced two real mirror bugs (both now fixed in the shared DB + at the source):

  1. 01Recurring occurrences had no subject. 12,813 of 23,523 graph_events (every event_type='occurrence') had subject/organizer null — Graph puts those on the series master, and occurrences only reference it. Backfilled all 12,813 from their masters (subject, organizer, is_online_meeting, location, body_preview). "(no subject)" is gone.
  2. 02Every meeting was 5:30 early (UTC parsed as IST). graph/importer.ts's dt() did new Date(String(v)). Graph event start/end (dateTimeTimeZone) is a naive timestamp (zone in a separate field, always UTC here); JS parses a bare timestamp as local, so on the IST host every event stored 5:30 early — breaking times AND which-day bucketing (evening meetings fell into the wrong day, so "today's meetings" mis-timed and mis-counted). Fix: dt() now appends Z when there's no zone marker (message receivedDateTime/sentDateTime already carry Z, so they're untouched and were always correct). Backfilled graph_events.start_at/end_at +5:30 (one-time; verified against Anisha's real Outlook: 12:30 / 16:00 / 19:00 / 20:00 — exact match). Blast radius confirmed to be events only (the 4 dt() call sites: event start/end broken, message received/sent fine).

Regenerated all 17 briefings — times, day, and counts now correct.

13

Jul 2026

Monday

1 shipped

Fix07:25 IST

AE deal inbox (Outlook-style workspace) + timeline HTML sanitization

"the AE also needs to have an inbox similar to what we built for SDR — without inbox none of this has any value." Built /ae/inbox, the SDR inbox one level up the ontology (deals, not…

"the AE also needs to have an inbox similar to what we built for SDR — without inbox none of this has any value." Built `/ae/inbox`, the SDR inbox one level up the ontology (deals, not leads). Same two-pane, mail-client shape: left = the AE's deals split into "In conversation" (open deals whose buying committee — primary contact + contact-role members — has a live email thread in the Graph mirror, ranked by most-recent message across the whole pipeline) and "Open · quiet" (open deals with no live thread — the ones going dark, paginated); right = the deal header (stage chip, ₹, account, contact, Deal hub ↗) + the unified thread (emails + meetings + calls + notes + tasks via getDealTimeline) + a Copilot-draft compose box (preview — nothing sends). New data layer getDealInbox (verified 162ms / 12 real conversations for Anisha) and draftReplyForDeal (Haiku, grounded in the deal's real thread). Inbox added as the AE's #2 nav item. Note: the Copilot draft currently 401s — the ANTHROPIC_API_KEY in .env is expired (wiring is correct; SDR copilot fails identically) — a key rotation, not a code fix.

HTML sanitization — the thread was leaking raw markup (<div style="display:flex…">…) from Zoho notes pasted out of Proshort and Outlook body fragments, since we render detail as text. New htmlToText helper (src/lib/format/text.ts: strips tags, keeps block breaks as newlines, decodes the common entities incl. emoji &#…;) wired into `getDealTimeline`, `getLeadTimeline`, and the peek pane (email body + note content). Deal hub, both inboxes, and every peek now render clean prose. Also promoted the deal description to a clay-accented "What they want" brief at the top of the Deal hub Details card (was a muted grey footnote under the field grid) — narrative leads, facts follow.

Perf note (not a bug): /ae/pipeline?peek=… logged 3.5s in dev. Traced it — getPipeline 29ms + peekDeal 24ms = ~60ms of real work; the rest is Next.js dev-mode render overhead (Turbopack + React dev renderer, amplified by concurrent session load). Production build serves that route in ~100ms. No code change; the peek is a full server round-trip by design (URL-driven master-detail, not a client Sheet).

11

Jul 2026

Saturday

1 shipped

Fix10:21 IST

HEAD_OF_SALES role (admin-tier) + fixed the KPI dashboards

New HEAD_OF_SALES role, admin-tier: it shares the /admin area and sees everything the CXO admins see (Command Board, users, org, audit, integrations). Rohit Naidu (id 163) promoted to it…

  • New `HEAD_OF_SALES` role, admin-tier: it shares the /admin area and sees everything the CXO admins see (Command Board, users, org, audit, integrations). Rohit Naidu (id 163) promoted to it (audited USER_ROLE_CHANGED; scripts/add-head-of-sales-role.ts, which also runs the ALTER TYPE user_role ADD VALUE 'HEAD_OF_SALES' AFTER 'ADMIN').
  • Access refactor so a role can share another's area: ADMIN_ROLES = [ADMIN, HEAD_OF_SALES], new requireAdmin() in dal.ts (replaces requireRole('ADMIN') across all 11 admin pages/actions), SEGMENT_ALLOWED_ROLES in roles.ts drives proxy gating (was 1:1 SEGMENT_ROLES), roleHome(HEAD_OF_SALES) = /admin, ROLE_NAV[HEAD_OF_SALES] = the admin nav. "Head of Sales" is now an assignable role in /admin/users.
  • Fixed two real crashes on the KPI dashboards (they were listed "working" but actually threw on render): (1) server components passed formatter functions (valueFormatter={formatInr}) to the client chart component — forbidden across the RSC boundary; replaced with a valueFormat="inr"|"count" string the client resolves. (2) weekStart from Postgres wasn't always a Date → Intl.DateTimeFormat threw "Invalid time value"; now coerced with a NaN guard. Both /admin/command and /ae/team render clean now.
  • Verified in Chromium: signed in as admin@glue.tools and as rohit.naidu@antino.com — both land on /admin, reach /admin/command, see ₹ figures + 16 chart SVGs, zero console/render errors.

10

Jul 2026

Friday

1 shipped

Fix16:35 IST

Incremental sync fixed for activity modules; first real delta pulled

First real-world incremental sync surfaced two COQL blind spots: activity modules (Tasks/Calls/Events) reject What_Id — the polymorphic link we must have — and Deals.Stage_Modified_Time /…

  • First real-world incremental sync surfaced two COQL blind spots: activity modules (Tasks/Calls/Events) reject What_Id — the polymorphic link we must have — and Deals.Stage_Modified_Time / Calls.CTI_Entry / Events.Participants are unqueryable. Fix: Tasks/Calls/Events now sync via the same Modified_Time-desc REST walk as Notes (REST returns What_Id fine, deletions still tracked via the deleted API); the COQL path self-heals by dropping any column Zoho names in an INVALID_QUERY error (learned per process, mirroring the bulk-import behavior).
  • Sync then pulled two days of real CRM activity cleanly: Leads +650 upserts/2 deletes, Tasks +1,548/4, Notes +81, Calls/Accounts/Contacts small. Post-sync counts verified against live Zoho: Leads 19,034 / Tasks 588,206 / Contacts 140,500 all exact.
  • Known limitation confirmed in the wild: Zoho exposes no deleted-records API for Notes, so notes deleted in Zoho persist here until the next full import (currently 1 such row).

07

Jul 2026

Tuesday

2 shipped

Fix23:30 IST

Sales leadership designations fixed from the org chart

scripts/fix-sales-designations.ts (idempotent, audited USER_UPDATED): the HR sheet's generic VP/AVP titles were overriding the chart's role labels. Rohit Naidu → Head of Sales (per user;…

  • scripts/fix-sales-designations.ts (idempotent, audited USER_UPDATED): the HR sheet's generic VP/AVP titles were overriding the chart's role labels. Rohit Naidu → Head of Sales (per user; chart label was "Director-Business & Strategy"), Anisha Ratnam → Head of Startup, Nitish Kumar → Head of Growth, Himanshu Gupta → Head of Government. Harshad/Vinay already correct.
  • Reporting tree needed no changes — all 17 chart edges already matched the image.
  • L4 "Key Accounts" people keep their specific HR designations (Business Consultant / Trainee / Intern / Tender Executive); the chart's "Key Accounts" reads as the team grouping, not individual titles.
Fix08:19 IST

Sticky nav fix, login verified, founders added as ADMIN

Sticky nav bug fixed: .section-dark set position: relative outside any cascade layer, which beat the layered sticky utility on the landing nav (unlayered CSS wins). Dropped the position…

  • Sticky nav bug fixed: .section-dark set position: relative outside any cascade layer, which beat the layered sticky utility on the landing nav (unlayered CSS wins). Dropped the position (its isolation: isolate already provides the stacking context); verified in-browser — nav pinned at top: 0 with position: sticky at scrollY 2400.
  • Login flow verified in the browser (Playwright/Chromium against the prod build): admin@glue.tools + dev password → lands on /admin, shell shows Sign out; DB health confirmed.
  • Founders added as ADMIN (scripts/add-founders.ts, idempotent, audited): Rajesh Kumar (Co-Founder & COO, rajesh@antino.io, id 234) and Radhakanth Kodukula (Co-Founder, radhakanth@antino.io, id 235). Emails follow the @antino.io leadership pattern but are assumed (flagged in the audit context). Vinay was already ADMIN. Admins now: Glue Admin, Vinay, Rajesh, Radhakanth. Users total: 234.