diff --git a/site/src/pages/roadmap.astro b/site/src/pages/roadmap.astro index b829caed..5e85c732 100644 --- a/site/src/pages/roadmap.astro +++ b/site/src/pages/roadmap.astro @@ -1,105 +1,355 @@ --- import Layout from '../layouts/Layout.astro'; -import Cloud from '../components/Cloud.astro'; +import HeroAtmosphere from '../components/HeroAtmosphere.astro'; import Icon from '../components/Icon.astro'; import CTA from '../components/CTA.astro'; +// Roadmap items are seeded from the previous version of this page, +// the actual codebase (CLAUDE.md), and the live changelog. +// Categories: Warmup · Inbox · API · Security · CRM · Workers · Pricing · Contacts · Deliverability · Platform + +const shipped = [ + { cat: 'API', tone: 'sky', title: 'Per-key API scopes and rotation', note: 'Per-key scopes, last-used timestamps, one-click rotation.', link: '/changelog/#api-keys-dashboard' }, + { cat: 'Deliverability',tone: 'sky', title: 'Per-mailbox health bands', note: 'Healthy, watch, quarantined, blocked. Pool selection skips anything below healthy.', link: '/changelog/' }, + { cat: 'Contacts', tone: 'sky', title: 'CSV, XLSX, and JSON contact export', note: 'Field picker and scope, with import wizard for column mapping and dedup.', link: '/changelog/' }, + { cat: 'Contacts', tone: 'sky', title: 'Categories on contacts', note: 'Reuses the existing categories group, deprecates Tags.', link: '/changelog/' }, + { cat: 'Warmup', tone: 'sky', title: 'Recovery pool for quarantined mailboxes', note: '7-day cooldown plus a 20-delivery probation before re-entry.', link: '/changelog/' }, + { cat: 'Workers', tone: 'sky', title: 'Per-worker concentration warnings', note: 'Surfaces when a shared worker is carrying too much active cold volume.', link: '/changelog/' }, + { cat: 'Workers', tone: 'sky', title: 'Worker rebalancing without downtime', note: 'Move accounts between workers as machines come and go.', link: '/changelog/' }, +]; + +const inProgress = [ + { cat: 'Security', tone: 'amber', title: 'SOC 2 Type II audit', note: 'Observation window underway. Report targeting Q3 2026.' }, + { cat: 'Security', tone: 'amber', title: 'Customer-managed KMS keys', note: 'Bring your own AWS KMS root for envelope encryption on Business plans.' }, + { cat: 'Security', tone: 'amber', title: 'SSO and SAML on Business plan', note: 'OIDC and SAML 2.0, with SCIM provisioning to follow.' }, + { cat: 'API', tone: 'amber', title: 'Tenant-scoped IP allowlist for the API', note: 'Per-key allowlist on top of scope-based authorisation.' }, + { cat: 'Inbox', tone: 'amber', title: 'Multi-workspace switcher in the inbox', note: 'Read every workspace you belong to without re-logging in.' }, + { cat: 'CRM', tone: 'amber', title: 'Attio and Folk integrations', note: 'Two-way contact sync with field mapping and change attribution.' }, +]; + +const researching = [ + { cat: 'Inbox', tone: 'slate', title: 'AI reply triage suggestions', note: 'Opt-in. Suggest disposition only, never auto-reply on the user\'s behalf.' }, + { cat: 'Deliverability', tone: 'slate', title: 'Predictive placement scores from warmup', note: 'Use warmup probe history to forecast cold-campaign placement.' }, + { cat: 'Deliverability', tone: 'slate', title: 'Seed-list inbox placement testing on demand', note: 'Trigger a fresh placement test before kicking off a sequence.' }, + { cat: 'Workers', tone: 'slate', title: 'Per-region dedicated workers in APAC', note: 'Mirror the existing US and EU dedicated-worker availability.' }, + { cat: 'Deliverability', tone: 'slate', title: 'BIMI and VMC tooling', note: 'Setup checks, status surfacing, and provider guidance.' }, +]; + +// Quarter strip. Counts represent shipped feature items recorded in the +// changelog and roadmap for each window. Q2 2026 includes May items. +const quarters = [ + { label: 'Q1 2026', range: 'Jan to Mar', shipped: 4, theme: 'Sequences, tracking edge, plain-text default' }, + { label: 'Q2 2026', range: 'Apr to Jun', shipped: 5, theme: 'Health bands, recovery pool, API keys', current: true }, + { label: 'Q3 2026', range: 'Jul to Sep', shipped: 0, theme: 'SOC 2, SSO, BYOK, integrations' }, + { label: 'Q4 2026', range: 'Oct to Dec', shipped: 0, theme: 'Researching items move into build' }, +]; + +// Cadence stats, computed from the seed lists above. +const specs = [ + { k: 'Items shipped in the last 90 days', v: String(shipped.length) }, + { k: 'Items currently in progress', v: String(inProgress.length) }, + { k: 'Items under active research', v: String(researching.length) }, + { k: 'Average weeks between releases', v: '~2 weeks' }, + { k: 'Roadmap items per quarter (median)',v: '4 to 6' }, + { k: 'Roadmap refresh cadence', v: 'Monthly' }, +]; + +// How we prioritise. +const priorities = [ + { n: '01', t: 'User-requested features', b: 'Feature requests from /contact, in-app feedback and our community channels are read weekly. Repeat requests rank highest.' }, + { n: '02', t: 'Deliverability incidents', b: 'Anything that protects shared pool reputation jumps the line. Quarantine bands and the recovery pool both shipped this way.' }, + { n: '03', t: 'Infrastructure debt', b: 'Worker rebalancing, concentration warnings, and tracking edge dedupe are debt items that paid for themselves within a quarter.' }, + { n: '04', t: 'Compliance and contracts', b: 'SOC 2 and SSO are gates for the customers we want next. They get sequenced ahead of new surface area while audits are open.' }, + { n: '05', t: 'Quality of life', b: 'Smaller items get bundled together. We do not let a quarter pass without at least one quality-of-life batch.' }, +]; + +const faq: Array<[string, string]> = [ + ['Why is the roadmap public?', 'Sales-driven secrecy makes it harder for customers to plan. If we are working on it, you can see it. If it stalls, you can see that too.'], + ['How often does the roadmap change?', 'Items rotate monthly. The full board is reviewed every quarter. Anything that ships moves to the changelog with the same wording.'], + ['Can I request a feature?', 'Yes. Use the request link, or open an issue if it is a bug. We read every request weekly and respond to common ones in the next roadmap pass.'], + ['Will you commit to dates?', 'We commit to quarters, not weeks. Security and audit items have firmer windows because partners gate on them. Everything else slips when reality demands it.'], +]; + +// Tone class lookup, kept simple to satisfy Astro’s JSX parser. +const tone = (t: string) => { + if (t === 'sky') return { dot: 'bg-emerald-500', chip: 'bg-emerald-50 text-emerald-700', rail: 'bg-emerald-500' }; + if (t === 'amber') return { dot: 'bg-amber-500', chip: 'bg-amber-50 text-amber-700', rail: 'bg-amber-500' }; + return { dot: 'bg-sky-500', chip: 'bg-sky-50 text-sky-700', rail: 'bg-sky-500' }; +}; + +const catChip = (c: string) => + 'inline-flex items-center h-5 px-1.5 rounded text-[10.5px] font-medium font-mono uppercase tracking-[0.08em] bg-[color:var(--surface-1)] text-foreground/70 ring-1 ring-[color:var(--border)]'; + +// Pre-compute column metadata so the JSX stays simple. const columns = [ - { - title: 'Shipped', - sub: 'Past 90 days', - dot: 'bg-emerald-500', - chip: 'bg-emerald-50 text-emerald-700', - items: [ - 'Per-key API scopes & rotation', - 'CSV · XLSX · JSON contact export', - 'Contact import wizard with column mapping', - 'Categories on contacts (deprecates Tags)', - 'Recovery pool for quarantined mailboxes', - 'Per-worker concentration warnings', - 'Worker rebalancing without downtime', - ], - }, - { - title: 'In progress', - sub: 'Active build · Q2–Q3 2026', - dot: 'bg-amber-500', - chip: 'bg-amber-50 text-amber-700', - items: [ - 'SOC 2 Type II audit', - 'Customer-managed KMS keys (BYOK)', - 'SSO / SAML on Business plan', - 'Tenant-scoped IP allowlist for the API', - 'Multi-workspace switcher in the inbox', - 'Attio + Folk integrations', - ], - }, - { - title: 'Researching', - sub: 'Targeting H2 2026', - dot: 'bg-sky-500', - chip: 'bg-sky-50 text-sky-700', - items: [ - 'AI reply triage suggestions (opt-in)', - 'Predictive placement scores from warmup probes', - 'Seed-list inbox placement testing on demand', - 'Per-region dedicated workers · APAC', - 'BIMI + VMC support docs and tooling', - ], - }, + { title: 'Shipped recently', sub: 'Past 90 days', items: shipped, dot: 'bg-emerald-500', chipTone: 'bg-emerald-50 text-emerald-700' }, + { title: 'In progress', sub: 'Q2 to Q3 2026', items: inProgress, dot: 'bg-amber-500', chipTone: 'bg-amber-50 text-amber-700' }, + { title: 'Researching', sub: 'Targeting H2 2026', items: researching, dot: 'bg-sky-500', chipTone: 'bg-sky-50 text-sky-700' }, ]; --- - -
-
- -
+ +
+ -
-
Roadmap
-

- Public roadmap, on purpose. +
+
+ Roadmap + Public on purpose +
+ +

+ What is shipping,
and what is next.

-

- No sales-driven secrecy. If we are working on it, you can see it. +

+ No sales-driven secrecy. The whole board is here, including what is researched but not committed. If a feature matters to you, tell us, and it gets weighed against the rest.

+ +

- -
+ +
-
- {columns.map((c) => ( -
-
-
- -
{c.title}
+
+
+
+
Live board
+

Three columns. Updated monthly.

+
+ +
+ +
+ {columns.map((c) => ( +
+
+
+ +
{c.title}
+
+ {c.items.length}
- {c.items.length} +
{c.sub}
+ +
    + {c.items.map((it: any) => ( +
  • +
    + {it.cat} + {it.link ? ( + + log + + + ) : ( + queued + )} +
    +
    {it.title}
    + {it.note ? ( +

    {it.note}

    + ) : null} +
  • + ))} +
+
+ ))} +
+
+
+
+ + +
+
+
+
Quarter by quarter
+

+ One year, four windows. +

+

+ We size work in quarters. Anything smaller than a quarter is a ship, not a roadmap entry. Anything larger gets broken down before it lands on the board. +

+
+ +
+ {quarters.map((q) => ( +
+
+
+
+
{q.label}
+ {q.current ? ( + Now + ) : ( + {q.range} + )} +
+ +
+ {q.shipped} + shipped +
+ +

{q.theme}

-
{c.sub}
-
    - {c.items.map((it) => ( -
  • - {it} -
  • - ))} -
))}
+ +
+ Counts pull from /changelog. Future quarters fill as items ship, not when they are scheduled. +
+
+
+ + +
+
+
+
Cadence
+

+ The shape of how we ship. +

+

+ Steady, boring, and visible. Most weeks see something land. Most months see a roadmap update. Most quarters see one larger piece complete end to end. +

+
+ +
+ {specs.map((d, i) => ( +
+
+ {String(i + 1).padStart(2, '0')} · {d.k} +
+
+
{d.v}
+
+
+ ))} +
+ +
+ Source: this roadmap and /changelog. Refreshed each month. +
+
+
+ + +
+
+
+
How we pick
+

+ Five inputs decide the next quarter. +

+

+ We weigh user requests, deliverability incidents, infrastructure debt, compliance commitments, and quality of life. No single input wins by default, and we publish the result on this page. +

+ + Request a feature + + +
+ +
    + {priorities.map((s) => ( +
  1. + {s.n} +
    +
    {s.t}
    +

    {s.b}

    +
    +
  2. + ))} +
+
+
+ + +
+
+
+
Roadmap FAQ
+

+ Four questions about how this works. +

+

+ Want a feature considered? Tell us. +

+
+ +
+ {faq.map(([q, a]) => ( +
+ +
+
+

{a}

+
+
+
+ ))} +
+ +