design spec · 2026-06-12 · awaiting operator review (PR constellation-metis#73)

Meeting Proposals Platform

Foundation build + Track F feature map — short branded links, one-click proposed-time accept, prep material, full pipeline test.

Product athena Domain metis Frontend apollo Credentials hades DDL proteus Board #8 Themis-PM · Track F

The problem

Proposing a meeting today means a long parameter-encoded Cal.com URL — fragile in transit (broke in the Arndís test), ugly to send, and the recipient lands on a generic booker: no "this is the proposed time" framing, no prep material.

The link becomes: meet.boas.dev/p/arndis-jun18 — short, branded, zero parameters. The page does the rest.

What the recipient experiences

Short link meet.boas.dev/p/… Proposal page proposed time (her tz) prep material accept · or pick another accept other slot Cal.com v2 API books proposed slot Day-prefilled booker long URL stays server-side Existing pipeline ICS invite → webhook → meetings/events → /calendar

Both paths converge on the proven booking pipeline — nothing downstream changes.

Decisions this spec resolves rulings

DecisionRuling
Board placement#8 Themis-PM, new Track F epic — project-grep verified all scheduling/meet/cal work lives there. No new board.
athena-063 (#39) — meet.boas.dev canonical repoconstellation-metis. Apollo PRs into it; metis reviews domain code.
metis-072 (#60) — Cal.com revive or dropStays. Accept-flow + slot inventory are built on it. Close #60 with this ruling.
Short-link domainmeet.boas.dev/p/<slug> — existing Pages project, /p/ avoids room catch-all. No new zone.
Long URLs to recipientsForbidden (operator). Slug is the link; Cal params stay server-side.

Foundation — what we build now build

1Data — proposals table

Pantheon Supabase, sibling of meetings/events. Slug, proposed time, attendee, prep markdown, status (pending/accepted/declined/expired), booking_uid on accept. New RLS role proposal_writer; anon read by slug only — slug is the capability, no enumeration. DDL via proteus (data-feed leg).

2Mint — sched-mcp proposal_create

Any agent session: "propose 18 Jun 11:00 to Arndís" → validates slot against Cal.com availability → inserts row → returns the short link. Companions: proposal_list, proposal_cancel.

3Page — Pages Function GET /p/<slug>

Hero: title + proposed time in the recipient's local timezone. One-click Accept → server-side Cal.com v2 booking (email prompted if not pre-set). Fallback slot picker, day-prefilled. Prep markdown rendered. States: pending / accepted / expired / declined.

4Secrets — hades

CAL_API_KEY newly minted (recurring server-side need now justified), PROPOSAL_WRITER_KEY RLS-scoped JWT — both vaulted + staged on the meet-boas-dev Pages project. Zero key material client-side.

Error posture

Slot taken between mint and accept → "that time was just taken" + picker fallback. Missing env → fail-closed 503, never silent degrade (Hub mock-tier lesson). {error} envelopes everywhere.

Testing & handover

Engineering hands over with unit tests green (Cal API mocked) + preview deploys verified. Metis then owns the full-pipeline E2E: mint → page → accept → Cal invite → webhook → meetings/events → /calendar render → ICS feed. That E2E is the "full test of this pipeline" ordered — covering the task-023 gap (source-verified, never click-tested).

Feature map — filed on Track F, not built later

#FeatureNote
F2Operator creation UImint from /calendar or /me — removes agent-mediated minting
F3Multi-option proposals (2–3 slots)most-requested scheduling pattern
F4Multi-attendee pollsdoodle-class; bigger model, separate design
F5Expiry + automatic nudgesneeds send-infra decision (Cal vs mercury/SMTP)
F6Decline-with-message + reschedule request
F7CRM linkageattendee ↔ contacts; auto-prep from CRM; ties to B0.8
F8Proposal templates + prep defaults
F9Analytics (open/accept rates)privacy-light, page-side only
F10Branded short domain (boas.dev/m/…)only if meet branding insufficient

Rollout order

StepWhoWhat
1proteusDDL + proposal_writer role (data-feed leg per operator ruling)
2hadesCAL_API_KEY mint + key staging
3apollopage + functions + mcp tool — PRs into constellation-metis, Class C → heph
4metisratify Track F (#73 merge) + roadmap amendment + full E2E + integration sign-off
5athenaepic + F2–F10 children on #8 · close #39/#60 with rulings · evidence comment
Out of scope (foundation): platform-sent email (Cal sends the invite; operator delivers the short link) · creation UI (F2) · multi-slot (F3) · transcription/notes (Track D).