In 1999 NASA lost the Mars Climate Orbiter after one team's software reported thrust in pound-force and another team's software read it as newtons. The spacecraft worked. The navigators were good at their jobs. One figure, in one file, carried the wrong unit, and nothing downstream gave anyone a reason to look at it again. A company blog fails the same way, with less fire and a smaller budget. A post written last spring can be well argued, well ranked and still quote a price that changed months ago.
The content audit templates that turn up in search have one row per post. They list the URL, the traffic, the word count, the date it was last updated and a verdict such as keep, merge or kill. That sheet answers a fair question about whether a post earns its place. But a row per post holds one date and one verdict for two thousand words, and the stale plan name in paragraph four never gets a cell of its own. So the old price survives every audit. We think the unit is wrong, and the fix is to count facts instead.
A database researcher solved this in 1970
In 1970 Edgar Codd, then a researcher at IBM, published the paper that set out the relational model. Its central habit was to store each fact once and point to it from everywhere else, and almost every database built since has followed it. Blogs never got that treatment. A price gets typed fresh into each post that mentions it, by whoever wrote that post, in whatever wording felt right that week. That is how one company ends up publishing three prices for the same plan without anyone deciding to.
The sheet below is a crude way to give those copies a shared address. It won't stop anyone from typing a price into a post. It records where they typed it.
Six columns do the work
Here is the template. Copy it into any spreadsheet.
| Fact as written | Post and paragraph | Source | Owner | Last checked | Source says today |
|---|---|---|---|---|---|
The first column holds the fact exactly as the post states it, typos and all. The second says where it lives, down to the paragraph, so a fix later takes a minute instead of a reread. The third names the one place that decides whether the fact is true, which for a price is the pricing page and for a feature is whatever page or document the product team keeps current. Owner is a person, by name. Last checked is a date somebody looked at the source and compared it. The last column is what the source says now, and every row where it disagrees with the first column is a sentence to rewrite.
We kept it to six on purpose. Earlier versions of this kind of sheet tend to grow columns for priority, severity and status, and then nobody fills them in.
Filling it takes an afternoon
Open the oldest post first and read it with one job in mind. Copy out every number, plan name, feature name, person and date, each into its own row. A good test for whether something belongs is whether the sentence would turn false after someone changes something elsewhere in the company. Prices pass that test. So do job titles, integrations, limits, launch dates and the name of the plan that used to be called something else. Opinions don't, and neither do arguments, which can age badly without becoming wrong.
Keep the wording as the post had it. If one post said "$500/mo" and another said "five hundred a month", both go in as written, since the point is to find every spelling a search would miss. Fill the source column as you go. Leave the last two columns blank for now. When we tried this kind of extraction on posts, the facts came out faster than expected, and the sources took longer, since half of them turned out to live in someone's head.
Our own pricing table as the worked example
We used our pricing table for the example, since it is the set of facts we change most deliberately. The post names below are placeholders.
| Fact as written | Post and paragraph | Source | Owner | Last checked | Source says today |
|---|---|---|---|---|---|
| Propaganda Light is free forever | Post A, para 2 | Pricing page | Whoever sets prices | $0 / forever | |
| Propaganda costs $500 a month | Post A, para 3 | Pricing page | Whoever sets prices | $500 / mo | |
| Propaganda costs $500 a month | Post B, para 6 | Pricing page | Whoever sets prices | $500 / mo | |
| Propaganda + a human is $999 a month | Post C, para 4 | Pricing page | Whoever sets prices | $999 / mo |
Every row points at the same page. That repetition looks wasteful in a sheet of four rows, and it is the whole trick in a sheet of four hundred.
Sort by source and the damage lists itself
Sort the sheet by the source column, and every fact that depends on the pricing page lands in one block. If we raised a plan's price tomorrow, the rows under the pricing page would name every post and every paragraph that still quoted the old figure. Nobody would need to search the blog for dollar signs or remember which post from last year got into pricing. The sheet would already know.
The same sort works for the product changelog, the team page and the list of integrations. A feature that was renamed shows up as a block of rows with the old name in the first column and the new one in the last. A sheet sorted by post, which is how the usual audit works, can't do this at all.
Each fact needs an owner
The person who changed the price is the one who knows it changed. That sounds too obvious to write down, and yet the marketing side of a small company usually hears about a new price from a customer who quoted the old one back. So each row gets a name in the owner column, and the name belongs to whoever decides the fact, which at a company of ten people is often the founder. The arrangement asks one thing of them. When they change the source, they open the sheet and sort.
We'd stop short of making owners responsible for the posts. Their job is to say the fact changed. Rewriting the sentence belongs to whoever looks after the blog, even when that person is also the founder on a different afternoon.
Rerun it the day a source changes
Ward Cunningham launched the first wiki in 1995, and the format spread on the promise that anyone could keep a document current. Wikis turned out to be correct on the day someone wrote each page and gradually less correct after that, which is the fate of company documents in general. A quarterly content review inherits the same problem. It checks every fact on a schedule that has nothing to do with when the facts changed, so a price that moved the week after the review stays wrong for three months.
We'd rather tie the audit to the change. The day a source moves, its owner sorts by that source, fills in the last two columns for its block and hands over the list of paragraphs. The rest of the sheet can wait. A full pass once a year still earns its keep, mostly to catch new posts whose facts never got rows.
Where the spreadsheet runs out
Dan Bricklin and Bob Frankston shipped VisiCalc for the Apple II in 1979, and the spreadsheet has been the default tool for this kind of bookkeeping ever since. It earned that place. For a blog with a few dozen posts and a price list that moves twice a year, this sheet is plenty, and we would tell you to use it before you buy anything.
It breaks once facts change faster than anyone reopens the file. A company shipping features every month, renaming plans and hiring people with new titles will find the source column out of date before the owner column is filled in. We built Keep it true for that point. It is in beta, and it flags every post that used a fact when the fact changes, along with the fix, so the sort happens without anyone remembering to run it.