The database we refused to install

Jack Buffet models an old-school receivables CMS in Fortran—and explains why Plain Money Notes still ships as static files with no database at all.

For: A practical builder who remembers fixed business systems—or wants to understand why a modern static CMS can be more capable by collecting less.

I am holding an Americano and looking at a content management system with no database.

This pleases me more than it should.

I built real business systems on a PDP-11 minicomputer. The database was fixed, the machine was finite, and every field eventually had to earn the electricity it consumed. Around that era, McDonnell Douglas Reality systems exposed an inquiry language called ENGLISH. Contemporary documentation identifies Reality, ENGLISH, and Data/BASIC as parts of that world; ENGLISH was used to retrieve information and produce reports.12

What follows is my recollection of the shape of the work, not a transcript of a McDonnell Douglas manual. You could ask for something that sounded almost ordinary:

Create me a field with a new four-digit date.

Then the useful questions began. What does the date mean? Is 9007 July 1990, the seventh day of 1990, or an account code wearing a date’s jacket? Is blank allowed? How should it sort? Which reports depend on it? A smart system did not flatter you by accepting ambiguity. It made you define the schema.

That schema could drive the morning work: accounts receivable past 90 days, grouped for review, printed hot off the press, and placed beside the coffee. Email and automated sharing belong to later workflows; the principle is older and better—define the field once so routine reporting stops depending on somebody remembering the question.

The MySQL instinct

If we were building a transactional application in 2026, I would reach for MySQL. I am opinionated about it. Oracle SQL taught generations of systems to take data definitions seriously, PostgreSQL is excellent, and I am still allowed to like what I like.

But Plain Money Notes is a Hugo publication. Articles are Markdown. Author records are YAML. Templates turn both into static HTML. Git records the history. GitHub Pages serves the result. There is no visitor account, no mutable content table, no payment system, and no reason to keep a database awake waiting for a page request.

So this article does not add MySQL. It does something more honest: it models the idea in Fortran and leaves production database-free.

A tiny fixed CMS, written in Fortran

The program below is an educational model. It keeps a field definition and four receivables in memory, validates the four-digit-year choice, and prints the over-90-day report. It does not connect to MySQL, imitate Reality ENGLISH syntax, send email, touch payment data, or power this website.

program plain_money_notes_fixed_cms
  implicit none

  type :: field_definition
    character(len=24) :: name
    character(len=12) :: meaning
    integer           :: year_digits
    logical           :: allow_blank
  end type field_definition

  type :: receivable
    character(len=24) :: account
    integer           :: age_days
    integer           :: amount_dollars
  end type receivable

  type(field_definition) :: due_date
  type(receivable), dimension(4) :: ledger
  integer :: answer

  print '(a)', 'PLAIN MONEY NOTES MORPHEUS: You got it, Jack.'
  print '(a)', 'PLAIN MONEY NOTES MORPHEUS: What schema should the new date field use?'
  print '(a)', 'Enter year width (4 required for this model):'
  read *, answer

  if (answer /= 4) then
    print '(a)', 'Choose four digits so reports sort without guessing.'
    stop 1
  end if

  due_date = field_definition( &
    name        = 'invoice_due_date', &
    meaning     = 'YYYY-MM-DD', &
    year_digits = answer, &
    allow_blank = .false. &
  )

  ledger(1) = receivable('Harbor Hardware',  34,  820)
  ledger(2) = receivable('Sunset Grocery',  117, 2400)
  ledger(3) = receivable('Mission Repair',   91,  675)
  ledger(4) = receivable('Pacific Supply',  143, 3150)

  call print_schema(due_date)
  call print_overdue_report(ledger, 90)

contains

  subroutine print_schema(field)
    type(field_definition), intent(in) :: field

    print '(/,a)',  'SCHEMA READY'
    print '(a,a)',  'Field:        ', trim(field%name)
    print '(a,a)',  'Format:       ', trim(field%meaning)
    print '(a,i0)', 'Year digits:  ', field%year_digits
    print '(a,l1)', 'Allows blank: ', field%allow_blank
  end subroutine print_schema

  subroutine print_overdue_report(items, threshold_days)
    type(receivable), intent(in) :: items(:)
    integer, intent(in)          :: threshold_days
    integer :: i, total

    total = 0
    print '(/,a,i0,a)', 'ACCOUNTS RECEIVABLE OVER ', &
      threshold_days, ' DAYS'
    print '(a)', repeat('-', 58)
    print '(a24,2x,a10,2x,a12)', 'ACCOUNT', 'AGE', 'AMOUNT'

    do i = 1, size(items)
      if (items(i)%age_days > threshold_days) then
        print '(a24,2x,i7,a,2x,a,i8)', &
          trim(items(i)%account), items(i)%age_days, ' days', &
          '$', items(i)%amount_dollars
        total = total + items(i)%amount_dollars
      end if
    end do

    print '(a)', repeat('-', 58)
    print '(a35,a,i8)', 'TOTAL FOR JACK''S MORNING REVIEW: ', '$', total
    print '(a)', 'Report complete. Americano still warm.'
  end subroutine print_overdue_report

end program plain_money_notes_fixed_cms

The interesting part is not the loop. It is the refusal to proceed with a vague date. A field name, meaning, width, blank policy, and reporting rule turn a request into a repeatable system.

Morpheus does not need a database to remember the plan

Our 2026 version uses a lighter harness. AGENTS.md carries repository rules. MEMORY.md carries durable project context. Skills carry narrow workflows. Markdown carries the publication. The generated site carries none of the private repository machinery.

That is a real CMS. It simply manages content before deployment instead of mutating rows after a visitor arrives.

My old machine rewarded precision because resources were scarce. This one rewards precision because attention is scarce. Same lesson. Better coffee.


  1. McDonnell Douglas Computer Systems Company, Series 6000 DATA/BASIC Programming Reference (1987), which identifies Reality, ENGLISH, and Data/BASIC in the product family: https://bitsavers.org/pdf/microdata/reality/6000/87-1360_Series_6000_DATA_BASIC_Programming_Reference_1987.pdf. ↩︎

  2. Rocket Software Host Access documentation maps ENGLISH to McDonnell Douglas Reality’s inquiry language. ↩︎