Dial
In development
An invitee-first, self-hosted scheduler for one business or independent host.
Dial is in development. It has no public source release or install path yet, and no date. This page shows the requirements and documents its publisher has released so far.
- Category
- Scheduling
- Licence
- MIT
- Version
0.1.0- Requirements
- 69 clauses
- Publisher’s stage
- runtime-spine-public-port
- Instead of
- Calendly
Screenshots
From the project’s own visual and verification records. Its handover says what was exercised.
Outside services
The services the project declares it sends data to, each with its reason.
google-calendar- A scheduler must read the host's real busy time and place accepted bookings on the calendar people already use; Cloudflare has no calendar primitive. EVENT-006 blocks publishing any event type without a healthy destination-calendar connection, and AVAIL-004 fails booking closed without a readable calendar.
google-meet- The prototype's default location is a real Google Meet conference, which requires provider-side conference creation. EVENT-004 also lets an event type use a fixed link, a phone number, or an in-person address instead, so a deployment can run with no event type ever using Meet.
resend- Cloudflare does not provide transactional email delivery or bounce webhooks; confirmations and change notices must reach external inboxes. EVENT-006 also blocks publishing any event type without a healthy mail-provider connection.
Scope and limits
What it will not do
- Multiple hosts or workspaces
- Roles and permissions
- Team round-robin or collective scheduling
- Group events, classes, waitlists, or resource capacity
- Additional invitee guests on a booking
- Bookings that wait for host approval before they are confirmed
- Payments, deposits, refunds, or booking fees
- Recurring booking series or scheduling polls
- Marketplace discovery, ratings, or invitee-submitted reviews
- SMS, WhatsApp, phone automation, CRM, campaigns, or marketing automation
- Automatic adoption of arbitrary external-calendar time or location edits
- AI routing or ranking
- Native mobile apps
Extension points
Optional conveniences for common changes. Owners can change any source, including core logic, schema and infrastructure.
operator.route.v1operator.page.v1operator.navigation.v1operator.settings-section.v1job.handler.v1cron.handler.v1queue.consumer.v1operator.management.v1booking.questions.v1availability.recommendation.v1booking.reschedule.v1booking.cancellation.v1availability-request.routing.v1reminder.schedule.v1calendar.external-deletion.v1profile.updated.v1event-type.published.v1event-type.disabled.v1event-type.deleted.v1booking.confirmed.v1booking.rescheduled.v1booking.cancelled.v1availability-request.created.v1availability-request.handled.v1availability-request.closed.v1calendar.connection-health-changed.v1delivery.failed.v1operator.navigation.after.v1operator.dashboard.after.v1event-type.header.actions.v1event-type.settings.after.v1booking.list.row-actions.v1booking.detail.sidebar.after.v1booking.detail.actions.after.v1availability-request.detail.after.v1public.profile.after.v1public.event.before-booking.v1public.confirmation.after.v1settings.calendar.after.v1calendar.provider.v1mail.sender.v1
Declared limits
- Status
- estimated-until-load-tested
- Estimated At
- 2026-08-31
- Max Operators
- 10
- Max Event Types
- 100
- Max Focus Areas
- 6
- Max Focus Area Chars
- 40
- Max Social Proof Entries
- 3
- Max Social Proof Chars
- 280
- Max Booking Questions Per Event Type
- 25
- Max Question Options Per Question
- 50
- Max Availability Overrides Per Event Type
- 1,000
- Max Request Dates Per Request
- 10
- Max Request Windows Per Request
- 20
- Max Conflict Calendars
- 10
- Availability Lookahead Days
- 365
- Max Bookings
- 100,000
- Max Bookings Per Month
- 10,000
- Concurrent Slot Claims
- 50
- Public Requests Per Ip Per Minute
- 120
- Booking Mutations Per Ip Per Minute
- 10
- Alternative Requests Per Ip Per Hour
- 5
- Webhook Requests Per Provider Per Minute
- 600
- Max Upload Bytes
- 5,242,880
- Allowed Upload Types
- image/jpeg, image/png, image/webp, image/avif
Requirements
All 69 clauses of Dial’s CONTRACT.md. They say what the project must do; the handover and verification records say what is built and tested.
AUTH 5 clauses
AUTH-001Public authority. SupersedesBASE-ACCESS-004for the paths listed inseed.json → deploy.publicPathsand for no others. Those paths authorise the caller by the capability material named inAUTH-002toAUTH-005instead of an operator session, each capability grants exactly the one action or record it names, and a request carrying no valid capability material changes nothing. Every other mutation requires a valid operator session and a server-side ownership check.AUTH-002Booking nonce. Reaching the details step for a selected slot, and reaching the review step of an alternative request, each issue a single-use nonce of at least 256 bits from a cryptographically secure random source, bound to the event type and to either the selected slot or the composed alternative request, and expiring 30 minutes after issue. The nonce is not bound to a browser: possession of an unexpired, unconsumed nonce is what authorises the confirmation. A confirmation whose nonce is missing, unknown, expired, or bound to different values creates nothing and answers perPUBLIC-003; a nonce that has already been consumed is answered byBOOK-003.AUTH-003Booking access. A booking is readable and changeable from a public surface only through the manage token defined inBOOK-006. A booking ID, an invitee email address, or any other guessable identifier grants access to no booking data.AUTH-004Calendar authorisation callback. The calendar OAuth callback accepts only signed state that is bound to the operator session that started the connection and was issued less than 10 minutes earlier. State that is missing, unsigned, mismatched, replayed, or expired stores no credential, connects no account, and returns 400.AUTH-005Provider callbacks. A calendar or mail provider callback is accepted only when the provider's own authentication passes — its registered channel identity or its request signature — together with the secret configured for that provider. A callback that fails the check returns 401 and changes nothing.
OPER 4 clauses
OPER-001Equal operators. Every operator can see and act on the same host profile, event types, availability, calendar connections, bookings, and requests. There are no roles.OPER-002Operator management. Operators are invited to, and removed from, the sign-in allow-list in settings. Removing an operator ends their sessions within 60 seconds and changes no record they created, including the calendar connection they authorised. Policy:operator.management.v1; default: any operator may invite or remove another, the operator configured at setup can be removed only by themselves, and the last remaining operator cannot be removed.OPER-003Booking workspace. Operators can list bookings filtered by the lifecycle states ofBOOK-004, and independently by whether the start instant is in the future or the past, by event type, by date range, and by whether any external delivery has failed. Case-insensitive substring search over invitee name and email address returns within 500ms. Lists are sorted by start instant.OPER-004Booking record. A booking record shows the event type, every invitee answer and custom-field value, the start and end in both the host's and the invitee's IANA zones, the location or meeting link, the history fromBOOK-010, the separate state of the calendar event, the meeting link, and each email, and every recorded failure with itsCAL-005orNOTIFY-005reason.
PROFILE 3 clauses
PROFILE-001Host profile. Operators edit the host's name, title, biography, avatar, IANA timezone, focus areas, and social-proof entries, within the counts and lengths inseed.json → limits. A social-proof entry is a quotation and an attribution typed by an operator: Dial collects no invitee feedback and publishes no rating, score, or count it did not receive from an operator. There is exactly one host timezone per deployment and it is the zone every other clause means by "the host's zone". The in-app preview renders the same content as the public page.PROFILE-002Public profile. The host profile is served at/book/<handle>, where the handle is set by an operator. It shows the configured host content and every published, listed event type, and never a draft, unlisted, or disabled one. An operator can change the handle; the previous handle then answers perPUBLIC-005.PROFILE-003Avatar asset. SupersedesBASE-INPUT-003for the/media/prefix only. The avatar is an upload within the size and type limits inseed.json → limits, stored in R2 and served under/media/with its declared content type and inline rather than with a download disposition, because it renders as an image on the public profile and event pages. That prefix is the public delivery channel the baseline requires a product contract to name; every other upload rule still applies, and no other upload in this product is publicly readable.
EVENT 6 clauses
EVENT-001Event type lifecycle. Operators create, edit, publish, disable, and delete event types. An event type is draft, published, or disabled, and a published one is either listed on the public profile or unlisted and reachable only by its own URL. Each carries a title, description, a single duration of 5 to 480 minutes, colour, location, and a slug unique among event types, and is served at/book/<handle>/<slug>. A slug can be edited; the previous slug is not retained and then answers perPUBLIC-005, while existing bookings and their manage links are unaffected.EVENT-002Scheduling constraints. Each event type configures its recurring availability, date-specific overrides, slot start increment of 5, 10, 15, 30, or 60 minutes, minimum notice of 0 minutes to 7 days, maximum booking horizon of 1 day toseed.json → limits.availabilityLookaheadDays, before and after buffers of 0 to 120 minutes each, and an optional maximum number of bookings per host day, where a host day is one calendar date in the host's timezone. A new event type starts at a 30-minute duration, a 15-minute increment, 4 hours' minimum notice, a 60-day horizon, no buffers, and no host-day limit.EVENT-003Invitee questions. Each event type has ordered booking questions of type text, textarea, single choice, multiple choice, or checkbox, each required or optional, within the question and option counts inseed.json → limits. Choice options have stable values and editable labels, and a submitted option not configured on the event type is rejected. A name and a syntactically valid email address are always required. Policy:booking.questions.v1; default: name and email, plus an optional agenda of at most 500 characters, on every new event type.EVENT-004Location. An event type uses exactly one location: a Google Meet conference provisioned perCAL-003, a fixed link the operator supplies, a host phone number the invitee calls, or an in-person address. The public event page shows only the location's label; the link, number, or street address appears only after confirmation — in the receipt, the invitee's email, and the calendar event. Dial never collects an invitee phone number.EVENT-005Removing an event type. SupersedesBASE-DATA-003for event types only: disabling or deleting an event type removes its public page and all its future availability but does not cascade to its bookings, which keep their times, manage links, calendar events, history, and their own copy of the event title, duration, and location. Invitee data is erased underDATA-002, not by deleting an event type.EVENT-006Publication readiness. An event type can be published only when it has at least one open availability window and when its transactional-mail configuration, its destination calendar, and, where its location is provider-generated, its conferencing capability each passed a connection check within the last 24 hours or since they last changed. A connection check is a live read of the destination calendar, a credential probe against the mail provider, and, where conferencing is used, a capability check against the conferencing provider; an operator can run it on demand. The operator sees each unmet requirement named. A requirement that becomes unhealthy after publication does not unpublish the event type: the connection state changes underCAL-006and public booking behaves underAVAIL-004.
HOME 1 clause
HOME-001Owner front door. The deployment root/is a sessionless owner-facing landing, not a vendor marketing page. It renders the deployment-configured owner identity and single-line description, and links to the host's public booking profile when one is available. ItsPowered by Dial · runeditrun.comfooter credit is a static link controlled by deployment configuration, enabled by default and omitted when disabled.
PUBLIC 6 clauses
PUBLIC-001Event presentation. A published event page names the host and the event and shows its description, duration, public location label, the invitee's selected timezone, the recommended times ofAVAIL-007, every other valid slot in the displayed week, week-by-week navigation bounded by today and the booking horizon, the change window thebooking.reschedule.v1andbooking.cancellation.v1policies currently enforce, and, when the event type enables it, the alternative-request path.PUBLIC-002Invitee-first flow. An invitee views availability and completes a booking without an account and without signing in. Before confirmation the flow asks only for the event type's configured questions, names who receives the answers — the host and the connected calendar provider — and links the privacy notice URL configured for the deployment.PUBLIC-003Progress and recovery. The public flow has distinct choose-time, details, and confirmation states, each at its own URL, and reloading or navigating back preserves a still-valid selection. The selection and its nonce are carried in the URL and in the browser's session storage; the public flow sets no cookie. An expired nonce, or an expired or rotated manage token, returns 410; an unknown or mismatched one returns 404. Both render a page that offers a fresh start and that contains no booking, invitee, or sample data.PUBLIC-004Embed. Operators copy an asynchronous script tag naming a public event slug andinlineormodalmode. Inline mode renders where the tag sits; modal mode opens only from an element whosedata-dial-embedattribute names that embed. The initial script is under 50KB gzipped, and the embedded flow offers the same booking, reschedule, and cancel actions as the standalone page.PUBLIC-005Unavailable pages. An unknown, draft, disabled, deleted, or renamed profile or event URL returns 404 and reveals nothing about whether a record ever existed there. This governs profile and event URLs only; manage-token responses are governed byPUBLIC-003, where a rotated or expired token deliberately returns 410 so the invitee knows to ask for a new link. A published event type with no valid slot inside its horizon still returns 200, says so, and offers the alternative-request path when the event type enables it.PUBLIC-006Abuse. A public request refused by the rate limits ofBASE-ACCESS-003returns 429 and the flow keeps the invitee's selection and answers so the same person can retry without re-entering them. An operator can block an email address or a domain; a submission from a blocked address is refused with a message that does not say it was blocked, and creates no booking, request, notification, or calendar event.
AVAIL 9 clauses
AVAIL-001Schedule and overrides. Recurring availability is a set of wall-clock windows per weekday in the host's IANA timezone. A date override replaces the recurring windows for one host date and may open or close that whole date. Editing a schedule or an override changes future availability only; it never alters a confirmed booking.AVAIL-002Valid slots. A slot is offered only when every one of these holds: its start falls on the event type's start increment measured from the start of its open window; the full duration fits inside that one window; the start is within the booking horizon and beyond the minimum notice; its host day is under the event type's booking limit; and it overlaps no booking in theconfirmedstate for this host on any event type and no busy interval from any selected conflict calendar, an external event the provider marks free being ignored. Anything else is not offered.AVAIL-003Buffers. The event type's before and after buffers extend the interval that must be free around a candidate slot, over both confirmed Dial bookings and external busy intervals. A buffer never changes the invitee's start or end time, the duration shown anywhere, or the times on the calendar event and invitation.AVAIL-004Freshness and failure. Availability is recomputed when the event page or a week loads. Changing the invitee's timezone re-renders and re-ranks the same slots and needs no new calendar read, because slot validity does not depend on the invitee's zone. A displayed slot may rest on cached provider busy data no more than 5 minutes old; the final check inBOOK-001uses provider data no more than 60 seconds old. Every selected conflict calendar is required, and a provider read that does not complete within 5 seconds counts as unreadable. If a required calendar is unreadable at either point, Dial offers and confirms no slot for that host and tells the invitee that booking is temporarily unavailable, rather than offering unverified time.AVAIL-005Timezones. Every invitee-facing time is rendered in the invitee's selected timezone, which starts as the browser's IANA zone when the browser reports one and as the host's zone when it does not. The zone is resolved in the browser and slot instants are fetched in UTC, so no visitor-derived value reaches the server on page load, asBASE-PUBLIC-001requires: the invitee's zone is sent only with a request their own action causes — changing the zone, moving week, or selecting a slot. The invitee can change the zone at any point before confirmation, every rendered time carries its zone name and UTC offset, and the details and confirmation surfaces also show the host's local time. A confirmed booking stores the UTC instant and both the host's and the invitee's IANA zone identifiers.AVAIL-006Daylight saving time. A local time that does not exist during a forward transition is never offered. Repeated wall-clock times during a backward transition are shown with distinct UTC offsets, so each offered time maps to exactly one instant. A DST transition between confirmation and the meeting never moves a booking's stored UTC instant, and the host and invitee renderings each follow their own zone's rules.AVAIL-007Recommendations and filters. At most 5 recommended times are shown, each a slot already valid underAVAIL-002and each showing the reason it was chosen. The ordering is deterministic: the same inputs always produce the same order. The first render of a page ranks in the host's zone alone; the ranking is recomputed once the invitee's zone reaches the server underAVAIL-005. An invitee-facing filter only narrows or reorders slots already valid underAVAIL-002and can never surface one that is not. Policy:availability.recommendation.v1; default: slots fully inside 09:00–17:00 in both the host's and the invitee's selected zone first, then the larger sum of contiguous free minutes immediately before and after the slot, then the earlier UTC start.AVAIL-008Response time. Loading one week of availability for one event type returns within 2 seconds.AVAIL-009Operator diagnostics. For any time an operator evaluates, Dial names which rule excluded it — schedule, date override, start increment, minimum notice, horizon, buffer, host-day limit, an existing Dial booking, or a conflict-calendar busy interval — without disclosing external event detail thatCAL-002does not retain.
BOOK 12 clauses
BOOK-001Final validation. Confirming a booking revalidates every answer against the event type's current questions and rechecks the selected slot underAVAIL-002against a fresh conflict-calendar read. Any failure creates no booking, no calendar event, and no email, and names the reason: an invalid or missing answer returns 400, and a slot that is no longer valid returns 409.BOOK-002Atomic claim. Every slot admits at most one booking in theconfirmedstate. Claiming the slot and recording its calendar, meeting, and notification commands happen in one transaction that either commits entirely or leaves nothing behind. Of any number of concurrent confirmations for the same slot exactly one commits; every other returns 409 with aslot_takencode and is returned to the choose-time step with availability recomputed.BOOK-003Idempotent confirmation. Replaying a confirmation with an already-consumed nonce and an identical payload returns the stored result of the original booking and creates no second booking, calendar event, meeting link, or email. Replaying it with a different payload returns 409 and creates nothing.BOOK-004States and occurrences. A booking is confirmed, cancelled, or rescheduled, and has one or more occurrences of which exactly one is current: a reschedule closes the current occurrence and opens a new one under the same booking ID and iCalendar UID. The calendar event, the meeting link, and each email carry their own pending, succeeded, or failed state; none of them changes the booking's state, and no external failure silently cancels or moves a booking.BOOK-005Confirmation receipt. Within 2 seconds of a successful claim the invitee is shown the event, the start and end in their own zone and in the host's, the duration, the host, the location or its pending state, the calendar file ofCAL-009, and the manage link ofBOOK-006. The join control is enabled only when a provisioned joining URL is stored on the booking; whileCAL-003is still pending it is disabled and labelled as pending.BOOK-006Manage link. Every confirmed booking has a manage link whose token carries at least 256 bits from a cryptographically secure random source and grants view and change access to that one booking, without creating an invitee account. The token is transmitted only to the invitee, in their own email and on their confirmation page; operator surfaces show the booking but never the token, offering an action that copies or resends the link instead. A reschedule keeps the token, which always resolves to the booking's current occurrence. The token expires 90 days after the booking's start instant, and an operator can rotate it, which invalidates the previous token immediately. A request with an expired, rotated, or unknown token answers perPUBLIC-003and discloses no booking data.BOOK-007Invitee rescheduling. The holder of a booking's manage link can move it to another slot on the same event type. The new slot is validated underBOOK-001with only this booking's own occurrence excluded from internal conflicts, then claimed underBOOK-002before the old slot is released; if any step fails, the original booking is unchanged and still confirmed. Policy:booking.reschedule.v1; default: any number of reschedules, allowed until the booking's start.BOOK-008Invitee cancellation. The holder of a booking's manage link can cancel it with an optional reason. Cancellation cannot be reversed, releases the slot and its buffers within 5 seconds and before the next availability computation, and repeating it returns the same result without sending a second notification. Policy:booking.cancellation.v1; default: allowed until the booking's start.BOOK-009Operator changes. An operator can reschedule or cancel any confirmed booking underBOOK-002,BOOK-007,BOOK-008,BOOK-010,CAL-003, andNOTIFY-004. The reschedule and cancellation policies constrain invitees only: an operator may also act on a booking that has already started, and may reschedule onto a time outside published availability after confirming that override explicitly, but never onto a time that overlaps another confirmed booking.BOOK-010History. Rescheduling records the original occurrence as rescheduled and links it to its replacement. Every creation, cancellation, and reschedule records who acted — the manage-link holder, the named operator, or the calendar provider underCAL-008— the time, the previous and new start, and any reason given.BOOK-011Attendance. After a booking has ended an operator can mark it attended or a no-show and add a note. The mark records the operator and the time, appears in the booking record and the export, changes no lifecycle state and no calendar event, and sends the invitee nothing.BOOK-012Operator-created booking. An operator can create a booking, for an invitee whose name and email address they enter, on any slot valid underAVAIL-002, optionally overriding the minimum notice and the horizon but never the conflict and buffer checks. The invitee then receives the ordinaryNOTIFY-001confirmation and manage link, andBOOK-010records the operator as the actor.
CAL 9 clauses
CAL-001Calendar connection. An operator connects the host's Google Calendar account through OAuth underAUTH-004, selects up toseed.json → limits.maxConflictCalendarscalendars whose busy intervals block availability, and selects exactly one calendar to receive Dial's bookings. There is exactly one connection; it belongs to the deployment rather than to the operator who authorised it, reconnecting replaces it and keeps the destination selection, and an operator can disconnect. After a disconnect, sync stops, the connection shows as disconnected, published event types keep their pages but offer no slot underAVAIL-004, and existing bookings and their history are unchanged. The implementation is replaceable throughcalendar.provider.v1.CAL-002Busy privacy. A calendar read retains only the identifiers, time bounds, transparency, and deletion state needed for conflict detection and sync. Titles, descriptions, attendees, and locations from conflict calendars are never stored, and so are never shown to an invitee or to an operator.CAL-003Managed event. Within 60 seconds of a successful claim the destination calendar holds one event for the booking carrying the event title, the booking's start and end with explicit timezone data, a stable iCalendar UID, the configured location or a Google Meet conference provisioned for this booking, and the invitee as an attendee so the provider's own invitation and updates also reach them — or the booking's calendar state is pending andCAL-005applies. An unsuccessful or ambiguous result is handled underCAL-004andCAL-005.CAL-004Idempotent side effects. Every calendar and meeting command carries the booking and occurrence IDs as its provider idempotency key. After a timeout, a lost response, or any other ambiguous result, the next attempt looks the object up by that key and updates it instead of creating a second one.CAL-005Provider failure. A transient calendar or meeting failure is retried up to 5 times over 1 hour. Until it succeeds the operator and the invitee receipt show the side effect as pending; after the retries are exhausted the operator sees a typed sanitised error code, safe remediation, and a retry action, while the invitee sees only that calendar setup is incomplete and that they should contact the host. The booking stays confirmed, and raw provider errors are neither persisted nor rendered.CAL-006Connection health. Revoked credentials, a refused token refresh, an invalid sync cursor, a push channel that cannot be renewed, or exhausted provider quota puts the connection in an unhealthy state that operators see in settings by name and that raisescalendar.connection-health-changed.v1. An invalid cursor or a lapsed channel triggers a full resync before the next availability computation. While a required conflict or destination calendar is unreadable, public booking fails closed underAVAIL-004and no event type can be published underEVENT-006.CAL-007Provider callbacks. Calendar push channels are renewed before they expire. A callback authenticated underAUTH-005is processed independently of arrival order: duplicate or out-of-order delivery cannot duplicate a booking change or undo a newer one, and a callback describing a state older than the one held is discarded.CAL-008External deletion and edits. Deleting Dial's managed event in the destination calendar cancels the booking exactly once and sends the ordinary cancellation notices ofNOTIFY-004. Any other external edit to the event's time or location is recorded as a sync conflict on the booking showing both times; the operator resolves it by restoring the managed event to the canonical time or by cancelling underBOOK-009, and Dial never adopts such an edit by itself. Policy:calendar.external-deletion.v1; default: deletion cancels the booking.CAL-009Calendar file. The confirmation and manage pages offer an.icsdownload for the booking carrying its stable UID and current occurrence. A reschedule increments that file's sequence and a cancellation marks the occurrence cancelled, so an invitee's calendar updates the same entry rather than gaining an unrelated one. The download makes no request to any provider not declared inseed.json → externals.
REQUEST 5 clauses
REQUEST-001Compose. Where an event type enables it, an invitee can select future dates and time windows within the counts inseed.json → limits, whose starts precede their ends and which do not overlap each other, together with their IANA timezone, a name, an email address, and an optional note of at most 500 characters, and can review the exact request before submitting. A request that omits a date, a window, a name, or a valid email address, or that contains an overlapping or reversed window, is rejected with the offending field named and stores nothing.REQUEST-002Submit. A valid request is recorded once, acknowledged to the invitee on screen, and notified to operators within 60 seconds. The acknowledgement states the response expectation the operator configured, or, where none is configured, only that the host will follow up by email. Replaying the same nonce returns the existing request. A request reserves no time and creates no booking.REQUEST-003Operator workflow. Operators can list requests by submitted, handled, or closed state, open the invitee's windows rendered in both the invitee's and the host's zone, mark one handled or closed, and create a booking for an agreed time. That booking runs the ordinaryBOOK-012path and marks the request handled.REQUEST-004Routing. A new request notifies every operator unless the routing policy selects a subset or suppresses email; suppressing email never suppresses the in-app record. Policy:availability-request.routing.v1; default: every operator.REQUEST-005Invitee updates. Submitting sends the invitee one acknowledgement email restating the requested windows in their own zone. Marking a request handled or closed sends the invitee exactly one further email; the closed one says the host cannot offer a time, and neither is sent twice however often the state is set again.
NOTIFY 7 clauses
NOTIFY-001Booking confirmation. Within 60 seconds of confirmation Dial emails, throughmail.sender.v1, the invitee and every operator: the event, the time in each recipient's relevant zone, the duration, the answers, and the current calendar state. The invitee's copy also carries their manage link and the.icsfile ofCAL-009; no operator copy contains the manage token. Where the meeting link is still pending the email says so instead of inventing one. An operator can mute booking mail — confirmations, changes, and reminders — for themselves in settings; the invitee's copy is never suppressed.NOTIFY-002Link completion. When a pending joining link becomes available Dial updates the managed calendar event and sends the invitee exactly one link-ready email, however many times the completion job runs.NOTIFY-003Reminders. A confirmed future booking schedules invitee and operator reminders carrying the event, the time in the recipient's zone, the location or join link, and, for the invitee, the manage link. A reminder is sent within 5 minutes of its scheduled offset. Rescheduling replaces the scheduled times and cancellation removes them, so no reminder is ever sent for a time the booking no longer holds. Policy:reminder.schedule.v1; default: 24 hours and 1 hour before the start, scheduling only the offsets still in the future at confirmation or reschedule.NOTIFY-004Changes. A reschedule or a cancellation sends the invitee and every operator exactly one email naming who made the change, the previous time, the new time or the cancellation reason, and the current calendar state.NOTIFY-005Delivery failure. A transient email failure is retried up to 5 times over 1 hour. A permanent failure or a bounce is marked failed on the booking or request with a typed sanitised reason and safe remediation, and can be resent without duplicating a delivery that already succeeded. Raw provider errors are neither persisted nor rendered.NOTIFY-006No mail loops. Product mail is sent from a no-reply address. Mail delivered to that address is discarded and never creates a booking, a request, or a notification.NOTIFY-007Connection alerts. Within 60 seconds of the calendar connection becoming unhealthy underCAL-006, every operator is emailed once, naming the cause and the reconnect action, because public booking is failing closed meanwhile. This alert is operational and the mute ofNOTIFY-001does not suppress it. No further alert is sent for that connection until it has recovered, and recovery is announced the same way.
DATA 2 clauses
DATA-001Export contents. SupersedesBASE-DATA-001for OAuth credentials only. The export contains every operator, host profile, event type, question, availability rule and override, calendar-connection metadata and sync state, booking and occurrence, invitee answer and custom-field value, attendance mark, alternative request, delivery attempt, setting, and audit entry as JSON, plus every uploaded asset in its original form. Access and refresh tokens are credentials and are never exported: after an import the calendar connection is unhealthy underCAL-006until an operator re-authorises it.DATA-002Erasure targets. An operator can delete a booking or an alternative request. Deleting one removes its invitee answers, notes, attendance mark, and uploaded content, invalidates its manage token, and cancels its managed calendar event without sending the invitee a Dial email; the audit entries survive with the invitee reference anonymised, asBASE-DATA-003requires. Deleting every booking and request carrying an email address erases that person from the deployment, since Dial keeps no separate invitee record.
Baseline
Selected ownership clauses from the 22 in the project’s BASELINE.md. They are declared requirements; evidence is recorded separately.
BASE-DATA-005Independence. The deployment makes no request to the marketplace or the seed author. There is no telemetry, phone-home, licence check, or kill switch.BASE-DATA-001Export and import.pnpm exportproduces every record and attachment;pnpm importrestores it into an empty deployment; export, import, export yields an archive with equivalent contents.BASE-DATA-004Outbound flows. User data leaves the deployment only through externals declared inseed.json → externals. No other outbound request carries user data.BASE-PUBLIC-001Privacy. Public surfaces (widgets, booking pages, forms, status pages) set no cookies, load nothing from third-party domains, and send no visitor data before the visitor's first interaction.BASE-SECRET-001No leakage. No secret appears in the client bundle, in logs, or in an error response.
View as agent
Everything on this page is in these files, copied unmodified from the release. An agent evaluating Dial can read them instead of the page.
AGENTS.md- Instructions for the coding agent that maintains an installation.
BASELINE.md- The baseline requirements the project declares.
CONTRACT.md- The requirements on this page, in source form.
HANDOVER.md- Maintainer orientation and verification status.
seed.json- The manifest: capabilities, outside services, extension points, limits, operating cost and deployment needs.
Every project, with its availability, is in /agents/catalogue.json; the agents page describes the machine-readable files.



