Our own ledger
We have no customers to show you. Here is our own record instead.
Every decision below was made while building Decize. The outcomes are what actually happened, not what we hoped would. 6 of the 11 that have resolved went badly, and two of those were reversed the day after they were made.
A ledger showing only good calls would prove nothing except that we were willing to edit it.
12
decisions recorded
5
held up
6
regretted or reversed
45%
of the 11 resolved went well
4 Aug 2026
RegretRun the inbound retry on a fifteen-minute cron
Schedule /api/cron/inbound-retry at `15 * * * *` so a message that failed triage is picked up within the hour.
Why, at the time
Email capture was about to become the main way decisions arrive, and a queue that drains once a day would make the channel feel broken.
What happened
Vercel’s Hobby plan refuses any cron that runs more than once a day, and it rejects the deployment at creation — so no deployment record is ever produced. The dashboard showed nothing wrong and the live site quietly kept serving the 3 August build for twenty-six days. Roughly four weeks of merged work, including the entire email capture path, was never actually in production.
Lesson. A merged branch is not a deployed one. Verify against the running site, not against git.
29 Aug 2026
HeldDrain the queue inside the request instead of buying Vercel Pro
Move the retry cron to daily and have the inbound webhook drain up to five pending messages via `after()`, once the 200 is already on its way back.
Why, at the time
Restoring sub-daily schedules costs money. That is a spend decision, and it should not be made by accident to work around an engineering constraint.
What happened
The channel stayed responsive on the free plan. A stuck message no longer waits a full day while mail is still arriving, and the runbook records the constraint so the next person does not rediscover it.
2 Sept 2026
HeldShip the Content Security Policy in report-only first
Deploy the CSP as report-only, watch it, and promote it to enforcing only once the reports came back clean — keeping an environment variable to demote it again.
Why, at the time
An enforcing CSP that is wrong breaks the site for everyone at once, and the failure mode is silent for anyone not watching a console.
What happened
Report-only ran clean, the policy was promoted to enforcing, and nothing broke. The escape hatch has not been needed.
Lesson. Ship the observation before the enforcement.
4 Aug 2026
HeldBecome organization-only and drop the individual product
Make an organization workspace mandatory. Remove the personal-journal product rather than maintaining both.
Why, at the time
The individual and team products were pulling the data model in opposite directions, and the research said the individual framing had a retention problem we had no answer for.
What happened
The model simplified sharply — every decision now belongs to an organization, and row-level security has one rule to enforce instead of two. It has held with no pressure to reverse it.
4 Aug 2026
ReversedMake the application unable to read captured email content
Add row-level security (migration 0029) so that even the application could not read the body of a captured message.
Why, at the time
Handing a product your inbox is the moment you should be suspicious of it, and a guarantee enforced by the database is worth more than a promise in a policy.
What happened
The organization-only migration two changes later dropped the policies, the function and the column, and nobody noticed at the time. The guarantee is gone; the site now says plainly that every active member can read the ledger and the captured mail behind it.
Lesson. A guarantee a later migration can silently remove was never a guarantee. If it matters, something has to fail loudly when it disappears.
1 Jul 2026
RegretBuild Slack capture
Build a Slack slash-command handler so decisions could be captured without leaving chat.
Why, at the time
Slack is where the discussion already happens, and asking people to open another tab is how decision tools die.
What happened
The handler was built and never given a way for anyone to actually install it. Zero installations exist. It was removed from every piece of marketing on 4 September, two months after it was written.
Lesson. An integration nobody can turn on is not a feature. Ship the entry point or do not ship the integration.
2 Sept 2026
HeldLeave two security-advisor warnings unfixed, on purpose
Accept that anonymous callers can execute two SECURITY DEFINER functions, and document why in the migration instead of revoking the grant.
Why, at the time
Revoking it breaks anonymous reads across nine tables that rely on those functions inside their own row-level security policies. The advisor flags the shape, not the consequence.
What happened
The grant stayed, the reads kept working, and the reasoning now sits in the migration where the next person to see the warning will find it.
Lesson. An advisory warning is an input to a decision, not a decision.
3 Sept 2026
Too soon to tellPrice on decisions, never on seats
Meter the product on decisions recorded per month, with unlimited people on every plan, and never charge per user.
Why, at the time
A decision record is only worth keeping if everyone who makes a decision writes it down. Per-seat pricing gives you a reason not to invite people, which attacks the one behaviour the product depends on.
What happened
Published on 3 September. Billing is not switched on and no one has paid anything, so there is nothing to report yet. Recorded here so that the claim is on the record before the result is known.
3 Sept 2026
RegretLead with “decision intelligence”
Use “Decision Intelligence for Organizations” as the tagline, the page title and the meta description.
Why, at the time
It sounded like an established category, and being in a category people already search for seemed safer than inventing a name.
What happened
It is an enterprise business-intelligence category owned by companies with sales teams and a decade of backlinks. Unwinnable for a product with no customers, and the traffic it does attract is looking for dashboards. Replaced the next day with the terms an operations lead actually types.
Lesson. Picking a category you cannot rank in is choosing to be invisible in a respectable-sounding way.
3 Sept 2026
RegretShip a three-thousand-word landing page
Publish a ten-section landing page that answered every objection a buyer might raise, in full, with the real numbers.
Why, at the time
The product asks people to hand over their email and trust a ledger. Honesty in that much detail felt like the differentiator.
What happened
Roughly half the page’s height was objection-handling placed before any reason to want the product, and the section that makes anyone want it sat at sixty-five percent scroll depth. Cut by forty-seven percent the following day, with the detail moved to a second page rather than deleted.
Lesson. The problem was never the length. It was answering questions the reader had not asked yet.
4 Sept 2026
HeldDelete the per-member analytics screen rather than hide it
Remove the screen that showed one person’s decision record, and withhold any rate that could be traced back to an individual below five data points.
Why, at the time
A decision ledger is one product decision away from becoming an employee-monitoring tool, and a screen that merely sits behind a flag can be turned back on by anyone in a hurry.
What happened
The screen is gone rather than disabled. The organization dashboard is computed from a database view that physically contains no title, summary or message text, so a reporting bug cannot leak decision content into a chart.
29 Aug 2026
RegretRun the dependency audit as an advisory CI step
Add `npm audit` to the verify workflow with `|| true`, so a known vulnerability in a transitive dependency is visible without blocking unrelated work.
Why, at the time
Blocking every pull request on a third-party advisory we cannot fix teaches people to ignore the pipeline.
What happened
The step talks to the registry and hung twice in a row, taking the whole job to its fifteen-minute timeout. Two runs reported as cancelled even though lint, type-checking, the tests and the production build had all passed — and both commits were already live. Fixed with a two-minute timeout on the step.
Lesson. `|| true` guards against a non-zero exit, which was not the failure mode. An advisory step needs a timeout, or it is not advisory.
About this page
What this is, and what it is not.
These are real decisions, checked against the commit or database migration that carries each one before it was written down. Nothing here is illustrative.
It is not a live export from a Decize workspace. Our repository is private, so commit references would be links you could not open — evidence you cannot check is decoration. What is printed instead are the specifics: dates, durations and exact constants, which are the parts that would be awkward to invent. If we ever open the repository, every entry gets a link and this page becomes something you can verify rather than something you have to take on trust.
It will get less flattering, not more. The honest thing about a decision ledger is that it accumulates the calls you would rather forget, and the forecast on the pricing decision above has not resolved yet.