#014Everwood BookingLearningIntermediate

Our Reschedule Email Says Update. The File It Sends Cannot.

I went into this research expecting to scope Apple and Google Wallet passes. What I found first was a promise we were already making and could not keep. When an appointment moves, we email the customer a button that says update your calendar, and the file behind that button has no way to say it replaces anything. A wallet pass would not fix that. It would make the same promise louder, and put a service we have to keep running behind it.

By the Everwood founder · September 8, 2026 · 11 min read

Tools
iCalendarApple WalletGoogle WalletNext.jsTypeScript
Concepts
Ownership of StateCopy as ContractPush Versus PullOperating CostSilent Failure
Mission Brief
Goal

Work out whether Everwood should add Apple and Google Wallet passes on top of the calendar export we already ship, and what a first version of better appointment details should actually contain.

Problem

I was comparing two delivery formats. The real difference between them is who stays responsible for keeping the customer's copy accurate after we hand it over, and by that measure we already promise more than we deliver.

Lesson

Decide who keeps a copy of an appointment true before deciding what the copy looks like. A wallet pass is not a nicer calendar entry. It is custody, and custody costs something every day the feature exists.

Read as

The Build

Nothing shipped from this research. No wallet pass exists, no code was written for one, and the roadmap node this came from is still marked idea. What changed is what I think a first version should be.

The customer problem is the one part I did not verify. Between booking and arriving, the details live in an email, and the customer has to go and find that email. My hypothesis is that a lot of what people call forgetting an appointment is really failing to retrieve it, and that details which surface on the device beat details someone has to dig for. I have no Everwood data behind that. What would settle it is sorting our support contacts against reschedules, which I have not done. Treat it as the assumption the whole idea rests on, not a finding.

The research I started from proposed two phases. First, a standards-compatible calendar export. Then wallet passes, validated separately. That shape is right, and it is also the shape of something we half built already. Build Note #013 covered the first half of that discovery: the calendar export exists, and holding it against the standard turned up gaps. The punctuation one has since been fixed. The rest are open.

This note is about the half I did not see the first time.

The Problem

Reading our booking emails next to the calendar file they hand out turned up two different kinds of defect. One is about what the copy contains. The other is about who keeps it true. They look like the same feature and they are not, and separating them is what the rest of this note is about.

Start with the second one. When an appointment moves, the customer gets two buttons, both of which say update: one for Google Calendar, one for Apple and Outlook.

The file behind those buttons has no way to say it is an update. The standard carries a revision number for exactly that purpose and ours does not use it. The appointment keeps a stable identity, which is the part people usually get wrong and we got right. But identity with no revision is a file that says here is the event. It does not say here is a newer version of the event.

So the button says update, and what sits behind it cannot express one. What the customer receives is the same event again. What their calendar does with that is the calendar's business, not ours.

There is a worse one. When an appointment is cancelled, we send an email with no calendar link at all. Not a broken one. None. Cancellation is the single change where I know for certain that the entry sitting in the customer's calendar is now wrong, and it is the only one where we send nothing capable of correcting it.

That is the custody thread. The completeness thread is smaller and it annoyed me more, because the fix is sitting right there. The confirmation email prints the salon's address, and the calendar file built alongside it carries no address at all. The customer reads the place in the email and carries a time with no place into their calendar. We have the information and drop it on the way out the door. The description fares no better, carrying a fragment of an internal reference or a bare count of services. Build Note #013 catalogued that. What I had not registered is that completeness costs almost nothing and custody costs a service.

Assumption vs Reality

What I Thought Would Work

Wallet passes are the next feature stacked on top of calendar export. Calendar is the cheap baseline. Wallet is the premium version, with the certificates and the push notifications, and the decision in front of me was whether the premium version earns its engineering cost.

What Actually Happened

They are not two tiers of the same thing. They are two different answers to a question I had not asked: who owns the copy after it leaves us. A calendar file is a handoff. We give the customer a snapshot, and from that moment the copy is theirs and we have no further say in it. A wallet pass is custody. We keep a live connection to that copy and we are on the hook for its accuracy until the appointment happens. Choosing wallet is not choosing a nicer surface. It is choosing to run an update service.

The Fix

What changed is the design, not the code. Three things I now believe.

The honesty problem is already ours, and it is not a wallet problem. We ship a button promising an update through something that cannot express one. That is fixable inside what we already send, and it should be fixed before we add a second delivery channel. The naming advice in the research was to say export and never say sync, because the word sets an expectation the mechanism has to meet. We broke that rule in our own email, and I did not catch it until I read the two sides next to each other.

The gap between Apple and Google is wider than I expected, and it lands entirely on operations. Apple's model makes us run a small service that never sleeps: every phone that installs a pass checks in with us, and every change means telling those phones to come back for a new copy. That comes with a certificate that expires and registrations that go stale when people change phones. Google's model is closer to updating a record on their servers and letting Google deliver it, with nothing for us to host.

So the cheap half of wallet is the half that reaches Android users with a Google account. The expensive half is the one that reaches iPhones. There is no version where we take the easy one and skip the hard one, because our customers' customers are on both.

The failure mode is the one we already have, only quieter. The thing I keep circling is a reported behaviour: an Apple pass installs cleanly against a broken service and then silently stops updating, with nothing surfaced to the user. I could not find that in Apple's documentation and I am not stating it as fact. If it is true, a wallet pass built before we can operate the service does not solve staleness. It gives staleness a nicer interface, somewhere I can watch it even less closely than a calendar app.

Lesson Unlocked

Rank the options by responsibility rather than by polish and they stop looking like tiers. A downloaded file: the customer owns the copy, we own nothing after the click, and we should say so plainly. A subscribed calendar feed: the customer's app checks back on its own schedule, which the standard lets us suggest and never lets us set, and we do not run one of those anyway. A wallet pass: we own the copy until the appointment passes. Picking a format is picking a level of responsibility. I had been picking on the basis of which one looked better on a phone. The version I want to carry into other features is this. Any time we hand a customer a copy of something that can change, decide who is going to keep it true before deciding what it looks like.

Business Translation

For a salon owner, this is about what happens after you move an appointment. Today, when you reschedule, we email your customer a button that says update their calendar. The file behind it may not replace the old entry. Their calendar can end up holding both times, or only the old one. If they turn up at the wrong hour, they will not blame a missing revision number in a text file. They will think you told them the wrong time. If you cancel, we send them nothing for their calendar at all. The appointment stays on their phone as though it is still happening. I want to be exact about what this is. No customer has reported either of these to us. I found them by reading our own code next to a specification. They are defects waiting for the right sequence of events, not an incident, and I am not going to dress up a code reading as a support ticket. The wallet pass, the thing this research was supposed to be about, would sit on a customer's lock screen and change itself when you move the appointment. It is better. It is also a service we would have to keep running correctly for as long as we offer it, and a pass that quietly stops updating is worse than no pass, because the customer has learned to trust it.

Builder Notes

A research pass on wallet passes that turned into an audit of the promise our existing calendar export already makes. Nothing was fixed. No wallet work has started.

Technical Note 1

Shipped today: an add-to-calendar file, served behind a signed link rather than a guessable public address. Confirmation emails carry buttons for Google Calendar and for Apple and Outlook. The punctuation gap from Build Note #013 has been fixed since that note went out. The other gaps in it remain open.

Technical Note 2

Copy against mechanism: the reschedule email says update, and the file behind it carries no revision number and is permanently marked confirmed. The standard defines that revision number as the thing that goes up whenever an appointment is modified. Fix the copy or fix the file. They cannot both stay as they are.

Technical Note 3

Cancellation: the cancellation email sends no calendar link at all. A real cancellation would tell the calendar the appointment is off, against the same appointment it already knows about. This is the one change where the customer's existing entry is definitely wrong, and it is the one we say nothing about.

Technical Note 4

The address: the confirmation email already prints it, and the calendar file built alongside it leaves it out. Putting it in needs no new information and no change to how appointments are stored. Highest value for the least work anywhere in this idea.

Technical Note 5

On the calendar standard, checked against the specification rather than a summary of it: the suggested refresh interval applies to a subscribed feed, not to a single downloaded event, so it does nothing for the file we actually send. A brand colour and a logo on the entry are possible, if we ever want them.

Technical Note 6

Apple wallet, from Apple's own documentation: passes are packaged and signed, every device that installs one registers with a service we would have to run, and updates happen by pushing a nudge that sends the phone back for a fresh copy. Behind that sit a certificate that expires and registrations that go stale when customers change phones.

Technical Note 7

One Apple detail worth designing around: a pass can name only a small fixed number of places where it should surface, ten of them. Generous for a single-site salon, a real ceiling for a chain, and better known now than discovered later.

Technical Note 8

The token a pass carries so a phone can check in with us is a shared secret for that purpose and nothing else. It must never quietly become a way into an Everwood account. Apple also requires a plain description on every pass, which is what a screen reader reads aloud, so it is an accessibility field rather than a marketing one.

Technical Note 9

Google wallet, from Google's reference: the pass lives as a record on Google's servers and is updated by changing that record, with nothing documented for us to host. That is an absence in the reference rather than a promise about how fast a saved pass changes on a device.

Technical Note 10

Reported and not verified: an Apple pass installs against a broken service and then silently stops updating. Also reported: tap-to-check-in needs hardware at the salon and extra approval from Apple or Google. I confirmed neither, and neither should drive a decision yet.

Technical Note 11

Content boundary, restated from Build Note #013 because a pass makes it easier to get wrong: nothing on the customer's device is inside anything we can protect. No provider notes, no payment details, no intake answers, no keys. A booking reference is a pointer for a human, not a credential.

Technical Note 12

Cut from the research: the competitor comparison table. Every row was a claim about another platform with no primary source behind it, so none of it survived the evidence gate. Also cut, a no-show reduction figure, an app-fatigue statistic, and a polling latency range.

Before / After

How I was framing it
  • Calendar export is the cheap tier and wallet is the premium tier
  • The wallet decision is about visual polish and customer delight
  • Our calendar export is a finished handoff
  • Apple and Google Wallet are roughly the same amount of work
  • The first phase in the research is something we have not started
How I frame it now
  • Calendar export and wallet passes differ by who owns the copy, not by quality
  • The wallet decision is about whether we can run an update service indefinitely
  • Our calendar export promises an update it has no way to deliver
  • Apple costs a service that never sleeps. Google costs one update call
  • That first phase is mostly written and needs finishing, not starting

What I'd Do Differently

I would have read the emails and the file they hand out in the same sitting.

Build Note #013 came out of reading the calendar file against the standard, and it found real gaps. It did not find this one, because this one is not visible on either side alone. The file is internally consistent. Nothing is wrong with the email either. What breaks sits in the gap between a button label and what the button delivers, and neither side would flag it on its own.

Here is the general version. A feature's contract is not in the thing that implements it. It is in the words the customer reads next to it. Checking the implementation against a standard catches standards bugs. Checking it against your own copy catches promise bugs, and those are the ones customers actually experience.

Next Experiment

Two things, and neither is a wallet pass. Put the address in the calendar entry. We already have it, we already print it in the email, it needs nothing new stored, and it turns a time into a place. That is the best ratio of customer value to work anywhere in this idea. Then settle the reschedule promise on purpose. Either give appointments a way to track their own revisions so the file can say it is an update, or change the button to say add rather than update until it can. I would rather ship weaker copy that is true than stronger copy that is not, and I would rather make that call deliberately than leave it as an accident. The wallet question stays open, and what would move it is not more reading. It is how our customers' customers split between iPhone and Android. Heavily Android, and a Google-only pass becomes a cheap real experiment. Heavily iPhone, and the honest answer is that we are not ready to run an Apple pass service. Saying that out loud is the finding.

ResearchSaaS ArchitectureBooking WidgetStandards

The information on this website is provided for general educational purposes only and may not apply to your specific setup or environment. It should not be considered professional advice. Always consult a qualified technician when appropriate.