Journal · 14 Apr 2026

The shadow spreadsheet is your best requirements document.

Every private workbook is a specification written by the person who does the work. Read it before you write a single ticket.

Published
14 Apr 2026
Reading time
6 min
Readers
—
Topics
DiscoveryInternal toolsNorthframeProcess
On this page

Key takeaways

  • A shadow spreadsheet records what the official system fails to: exceptions, holds, and judgement calls.
  • Columns are requirements; colour-coding is policy; comments are edge cases.
  • Read the workbook before interviewing anyone, then ask about the parts that look strange.
  • The goal is not to migrate the sheet. It is to make it unnecessary without losing what it knew.

Every operations team has one. A workbook that lives on someone's desktop, is emailed around on Fridays, and is quietly more accurate than the system of record. Leadership usually treats it as a problem. We treat it as the best requirements document in the building.

Why the workbook exists

A private spreadsheet is a rational response to friction. The official system was designed for the common case; the person at the desk handles the uncommon one forty times a week. So they built the thing that fits: a grid, a few filters, and some colour.

That makes the workbook an unusually honest artifact. Nobody built it to impress anyone. Every column exists because someone needed it twice.

The workbookSomeone's fastest tool
ColumnsHidden states and decisions
ColourUnwritten policy
CommentsEdge cases and exceptions
Product modelStates, rules, owners
From a private workbook to a product model

How to read one

Columns are requirements

List the columns. For each, ask what decision it supports. A column called "Holding?" is a state. A column called "Ask Jonas" is a missing permission. A column of free-text notes is a workflow nobody has named yet.

Colour is policy

If rows turn red, there is a rule. Find it. It is usually a business policy that exists nowhere else — not in the system, not in a wiki, only in the person who set the conditional format.

Comments are edge cases

Cell comments and strike-through rows are where exceptions are recorded. They are the most valuable and least structured data you will find, and they are where a naive migration loses information.

Hidden tabs are integrations

A tab of pasted export data is an integration someone performs by hand. Count how often it is refreshed; that is your required sync frequency.

In the workbookWhat it usually meansWhat the product should do
A column of yes/no flagsA hidden state machineModel the states explicitly
Conditional colourAn unwritten policyWrite the rule down and enforce it
Free-text notesAn unnamed workflowName it, or keep a note field on purpose
Pasted export tabA manual integrationAn adapter with a visible retry
Initials in a columnOwnershipAssignment with a required owner
A "do not touch" rowFear of a broken formulaRemove the fear by removing the formula
Every column exists because someone needed it twice. That is a better requirements process than any workshop.

A short discovery routine

  1. Ask for the workbook before the first meeting. Read it alone.
  2. Write down every question the columns raise. Do not ask them yet.
  3. Sit with the owner while they use it during a real shift. Watch, do not interview.
  4. Then ask about the parts that look strange. Strange is where the policy is.
  5. Write the non-goals: what the new system will explicitly not model.

Ask about the deletions

The most revealing question is: what did you stop tracking because it was too much effort? Those absent columns are usually the ones the business needs.

Migrate the sheet

  • Reproduces its accidents
  • Loses comments and colour rules
  • Shames the person who built it

Read the sheet

  • Extracts states, policy, and edge cases
  • Names what the new system will not model
  • Makes the owner the first user

What not to do

  • Do not migrate the sheet as-is. You will reproduce its accidents.
  • Do not shame the owner. They are the domain expert, and you need them to be the first user.
  • Do not promise the sheet will be deleted on day one. It will be retired when it stops being needed, and not before.
3Columns that became Northframe's spine: consequence, reopen reason, owner
30 daysUntil the workbook simply stopped being needed
6 weeksTo the first production cut

Halcyon's version

Halcyon's night managers kept a private workbook because it was faster than the official system. It had a column for whether finance would care, a colour for "reopened", and initials for who had the problem. Those three things became the spine of Northframe's exception model: consequence, reopen reasons, and owners.

Within thirty days of go-live the workbook was retired. Nobody deleted it. It simply stopped being useful, which is the only retirement that lasts.

Questions to ask the workbook's owner

  • Which column would you miss most if it disappeared?
  • What do the colours mean, and who decided?
  • What did you stop tracking because it was too much effort?
  • Which tab do you refresh by hand, and how often?
  • What would make you trust a new system enough to close this one?

A workbook audit template

Before designing anything, audit the workbook like a codebase. The audit produces a one-page inventory that everyone can argue about, which is far cheaper than arguing about a half-built product.

Inventory itemWhat to recordExample
Sheets and tabsName, purpose, refresh method"TMS_paste" — pasted export, refreshed by hand each morning
ColumnsName, type, who fills it, source"Holding?" — yes/no, set by night lead
FormulasWhat business rule each encodes=IF(C2<TODAY()+4/24,"URGENT","") — the four-hour window rule
Conditional formattingRule and meaningRow turns red when reopened twice
Comments and notesCategories of edge case"customer changed window after departure"
Macros or scriptsAutomation and its ownerEmail digest sent at 05:30
AccessWho can view and editThree people edit; six view by email

Formulas are business rules in disguise

A formula that turns a row red is a policy with no owner and no history. Extract every formula into a sentence — "an exception is urgent when the delivery window closes within four hours" — and ask the workbook's owner to confirm it. Those sentences become your ruleset.

From columns to schema: a worked example

Here is the translation for a simplified night-desk workbook. The point is not the exact schema; it is how each spreadsheet habit becomes an explicit, constrained fact.

Workbook habitBecomes
Column "Status" with free textA state enum with an allowed set and defined transitions
Initials in a columnA required owner_id foreign key, nullable only in the unassigned state
Colour meaning "reopened"A reopened_count and a required reopen_reason
Column "Will finance ask?"A finance_impact boolean with a reason
Notes in a commentA child table of exception_notes with author and time
A pasted export tabAn adapter that records source_ref and last_synced_at
Illustrative schema — states, ownership, and reasons are constrained, not conventionalSQL
CREATE TYPE exception_state AS ENUM ('unassigned','assigned','waiting','approved','closed','reopened');

CREATE TABLE exceptions (
  id              uuid PRIMARY KEY DEFAULT gen_random_uuid(),
  source_ref      text NOT NULL,                 -- load id in the TMS
  state           exception_state NOT NULL DEFAULT 'unassigned',
  owner_id        uuid REFERENCES staff(id),
  finance_impact  boolean NOT NULL DEFAULT false,
  reopen_reason   text,
  reopened_count  int NOT NULL DEFAULT 0,
  created_at      timestamptz NOT NULL DEFAULT now(),
  CHECK (state = 'unassigned' OR owner_id IS NOT NULL),
  CHECK (reopened_count = 0 OR reopen_reason IS NOT NULL)
);

CREATE TABLE exception_notes (
  id           uuid PRIMARY KEY DEFAULT gen_random_uuid(),
  exception_id uuid NOT NULL REFERENCES exceptions(id),
  author_id    uuid NOT NULL REFERENCES staff(id),
  body         text NOT NULL,
  created_at   timestamptz NOT NULL DEFAULT now()
);

The two CHECK constraints do more to protect the desk than any training session. An exception cannot be assigned without an owner, and it cannot be reopened without a reason. The database enforces the policy the workbook only implied [1].

Cutting over without a heroic weekend

MirrorNew tool reads the workbook nightly
Dual entryOwner enters in the tool; sheet is read-only reference
ReconcileCompare weekly; explain every difference
FreezeWorkbook becomes read-only on a stated date
ArchiveKept, labelled, and forgotten
A cutover that keeps the workbook alive until it is no longer needed
  • Do not delete the workbook. Archive it read-only, with a note explaining what replaced it and when.
  • Import history selectively. Bring in open items and the last month of closed ones. Ten years of archived rows will import ten years of accidents.
  • Keep a translation table. Map old free-text statuses to new states explicitly, and list the ones that did not map cleanly for a human to resolve.

Privacy, permissions, and the person who built it

Workbooks accumulate sensitive data: customer names, prices, staff notes. Auditing them means seeing that data. Agree in advance who will look at it, what will be copied out, and how it will be handled. Workbooks also carry a person: the one who built the formulas and knows why. Treat them as the domain expert and the first user, and give them credit in the launch note. The system works best when its most knowledgeable critic is its earliest champion.

Domain-driven design [2] frames this as building a shared model with the people who hold the knowledge. The spreadsheet is simply the fastest way to see their model before they explain it.

Closing

A shadow spreadsheet is not technical debt. It is a field study you get for free. Read it carefully, and the specification mostly writes itself.

References & further reading

  1. 1
    PostgreSQL Documentation: Constraints — PostgreSQL Global Development Group
  2. 2
    Domain-Driven Design: Tackling Complexity in the Heart of Software — Eric Evans, Addison-WesleyThe chapters on ubiquitous language are directly relevant to naming states.
  3. 3
    Bliki: Strangler Fig Application — Martin Fowler, martinfowler.com
Found this useful? Share it

Get the next essay in your inbox

Practical writing on payments infrastructure, operations software, and shipping real systems. No spam, no sales sequence.

We only use your email to send the studio's writing. See the privacy policy.

About the author

Product behaviour described here reflects what is implemented and tested; anything else is marked as planned. Code samples are illustrative.

All writing

Have a system like this to run?

Explore the catalog, or write down the problem and the constraints. We respond when the fit is real.

Free apps from the studio. Enter your email, get a private download link. Free for personal use.

Get them free

Have a product to sell? We review, list, and sell it for you — you keep 90% of every sale.

Apply to sell with us