Rutter written sailing directions
Editor's cut · Build recap

How League Report got built

League Report is a custom platform for the leagues Austin runs. This reads a build that did two jobs at once: stand up a new site, and rescue a decade of data from a service going dark.

league.report

Before the agent came aboard

The leagues had lived for years on leaguelineup.com, an external service that announced it was shutting down. The software here is brand new, but it inherited a decade of schedules, rosters, and brackets that had to be pulled out before the lights went off.

30
Sessions
560
Headings
103
Landmarks
24M
Tokens out
Opus 4.8
Model
The chart · the passage plotted

The route, plotted

Eight waypoints across three months, a build and a data rescue at the same time. Hover any marker to read the direction that set it.

48°24′N 004°29′W
Departure / made port Heading (a direction given) Landmark (evidence handed over) A tack (course correction)
May · Session b3b003f6

Build and rescue at once

102 headings · a batch import from a dying service

The longest session was mostly a data rescue. Leagues were crawled from the old service into a local database, then imported in batches, with the agent given standing permission to fix what it found:

Heading 3

Let's start the import. If you see anything broken or being missed, feel free to adjust and improve.

That permission mattered, because a decade of real-world data is messy. Duplicate and malformed records surfaced constantly:

Heading 15

The URLs should be unique. We somehow got 2 /league/lcseniorsoftball/. The one is malformed. Can you fix?

One hundred and three screenshots changed hands over the project, most of them pointing at a team card, a bracket, or a broken import that needed a human eye.

The wake · Apr 5 → Jul 5

What came next

Three months, ninety-two days of build and migration. A real project, not a sprint.

Apr 5

Start against a deadline. The old platform is shutting down. Build a custom WordPress replacement.

May 9

Build the league surfaces. Schedules, teams, standings, brackets.

May 18

Rescue the data. leaguelineup.com is going offline. Crawl and preserve everything possible.

May 19

Import in batches. Test on five leagues, then widen. Fix parse bugs and duplicate URLs as they appear.

Jun ·

Deploy to the real sites. Ship the plugin to softballreport.org and the senior leagues over SSH.

Jul 5

Keep it accurate. More leagues come across; stewardship continues.

Reading the direction

What to borrow

A build that is also a migration rewards a particular kind of direction.

A deadline is the best spec

"The platform is going away" set scope, priority, and urgency in a single sentence. External pressure clarifies.

Rescue is a build task

Half the work was importing and repairing data from a dying service. Treat the migration as a first-class feature, not cleanup.

Grant standing permission to fix

"If you see anything broken or being missed, feel free to adjust and improve." That keeps a long batch moving without a round-trip per row.

Ninety-two days is a real project

560 headings over three months. Rutter records the marathon, not just the demo.

Sailing directions

If you built this again

Knowing that half the work was a data rescue, here is how you would start a similar build. Copy a prompt and adapt it.

Opening prompt
I manage several sports leagues that currently live on an external service which is shutting down. Build a custom WordPress theme and plugin to replace it: schedules, teams, standings, and brackets. Treat migrating and preserving the old data as a first-class feature, not cleanup. Here is a crawl of the old data to import from.

Names the deadline and the surfaces, and makes the migration first-class up front.

Import with permission to fix
Import in batches. Start with 5 leagues to validate, then widen. If you see anything broken or missing, fix it and tell me. Expect a decade of messy real-world entries: duplicate slugs, malformed URLs, and bad dates.

Grants standing permission and warns about dirty data, saving the debugging detours.

Ship incrementally, resumably
Deploy to the live league sites over SSH as we go, and keep a MIGRATION_STATE file so we can stop and resume across sessions without losing the thread.

Bakes in the incremental deploys and the resumable-state habit.

This recap is the output of an editor pass over the project's agent transcripts. A deterministic extract (command-center flow --editor) pulls the direction, the agent trace, and the embedded screenshots from the most representative session. A single model pass captions each image and writes the narrative.

Every quoted heading is verbatim, typos and all. Landmark captions were recovered from images embedded in the transcript, then summarized. The originals are never reproduced or shared.

← Back to the Harbor