Repository modernization

This document tracks the controlled reorganization of the MMA Matlock repository.

Current status

Stage 10 of 10 — Final documentation and maintenance mode: COMPLETE

The staged repository modernization is complete. The repository is now in maintenance mode.

Stages 0–9 established the safety baseline, permanent repository/media contracts, article-owned asset hierarchy, modular Writer source, domain-organized development scripts, consolidated workflow ownership, legacy-page cleanup, explicit data lifecycles, and enforceable repository integrity.

Rollback point

The repository state immediately before modernization is preserved at:

Stage 0 baseline

Measurements from the rollback commit:

Large runtime-data files include:

These are observations, not cleanup targets by themselves.

Safety rules for every stage

  1. Existing public URLs are preserved unless a stage explicitly documents a redirect or retirement.
  2. Existing article media is not relocated merely to make old folders look cleaner.
  3. A file is not moved or removed until the reference audit has been run against it.
  4. Generated files are treated separately from authored source files.
  5. Writer storage behavior changes only in a Writer-specific stage with Writer regression tests.
  6. Every stage must pass repository integrity, Jekyll/site checks, and feature-specific tests it touches.
  7. Structural cleanup is performed in small reversible changes rather than one repository-wide rewrite.

Reference audit

Stage 0 added a repository-aware reference audit that is now part of Site Quality CI.

Run the full inventory/report locally with:

npm run audit:repo

Before changing a specific tracked path, inspect inbound references with:

npm run audit:repo -- --target news.html
npm run audit:repo -- --target assets/some-file.js

Machine-readable output is available with:

npm run audit:repo -- --json

CI runs:

npm run audit:repo -- --check

The check currently protects against duplicate root permalinks and root pages referencing missing page_styles or page_scripts assets. The report also inventories repository responsibilities and identifies legacy/versioned page candidates with inbound references.

Critical production surfaces

Public routes that later stages must continue to protect:

Content invariants:

Automation that must remain operational includes site quality/build checks, Writer production smoke tests, Writer backend quality tests, scheduled publishing, news updates, On This Day generation, Matchmaker generation/validation, and event-data jobs.

Stage 1 organization contract

Stage 1 formalized the stability-first repository model in two forms:

The contract establishes:

The policy is checked in CI with:

npm run check:repo-policy

That check verifies the permanent roots, Jekyll permalink contract, protected paths, media separation, GitHub Release video policy, and staged legacy exceptions before later migrations build on top of them.

Stage 2 article media hierarchy

Stage 2 routes new Writer image uploads into article-owned directories:

assets/uploads/articles/YYYY/MM/article-slug/

The Writer derives the year and month from the article date and uses the saved filename slug when available, falling back to the article title slug for an unsaved article. Existing files under assets/uploads/ are not moved or renamed.

The Writer upload UI and backend allow nested article-media paths, and production smoke coverage verifies that new uploads resolve under the article hierarchy. GitHub Release video uploads remain unchanged and outside Git history.

Stage 2 also made the repository-policy stage validator reusable for later stages. Site Quality, Writer auth quality, Writer production smoke, and GitHub Pages deployment all passed before Stage 2 was closed.

Stage 3 media pipeline separation

Stage 3 formalized three independent media lanes:

AUTHORED ARTICLE IMAGE
assets/uploads/articles/YYYY/MM/article-slug/

RESPONSIVE DERIVATIVE
assets/generated/posts/YYYY/MM/article-slug/

ARTICLE VIDEO
GitHub Release asset: writer-media-YYYY-MM

Legacy image sources and their established generated URLs remain unchanged. The responsive-image generator now uses scripts/media/media-paths.mjs, which keeps legacy output flat while routing future article-owned derivatives into matching article namespaces.

scripts/qa/check-content.mjs now validates generated responsive images recursively so nested derivatives receive the same size checks as legacy flat output.

Stage 3 also added:

The image optimizer completed successfully, Writer production smoke passed, Site Quality passed including the new media check, and GitHub Pages built successfully before Stage 3 was closed.

Stage 4 Writer frontend modules

Stage 4 keeps the browser contract unchanged:

/write/
  → /assets/writer.js

The maintainable source now lives under _writer/:

_writer/
  00-core.js
  01-preview.js
  02-state-library.js
  03-publishing.js
  04-editor-tools.js
  05-media.js
  06-bootstrap.js

scripts/writer/build-frontend-bundles.mjs concatenates those ordered source modules into the existing assets/writer.js compatibility bundle. This deliberately preserves the Writer’s shared closure and runtime ordering instead of introducing a risky browser-module rewrite.

The split reduced the single-file maintenance surface into domains for core/frontmatter helpers, preview rendering, state/library/GitHub transport, publishing, editor tools, media upload/layout, and event/bootstrap behavior.

Safeguards added in Stage 4:

The generated bundle was verified byte-for-byte against the ordered source fragments. Writer auth quality passed, production Writer smoke passed, Site Quality passed the generated-bundle check, and GitHub Pages built successfully before Stage 4 was closed.

Stage 5 development-script organization

Stage 5 moves the previously flat development-script surface into stable responsibility domains:

scripts/
  writer/
  media/
  matchmaker/
  news/
  history/
  site-data/
    events/
    ufc/
    live/
  qa/

The migration preserves the existing human-facing npm commands while changing their implementation paths. GitHub Actions workflows and documentation were updated to the new locations at the same time as the moves.

The migration also repaired path-sensitive scripts whose relative imports or import.meta.url asset lookups changed after relocation, including Matchmaker helpers, UFC portrait tooling, On This Day share tooling, and generated GoBold assets.

Stage 5 added npm run check:scripts, which rejects:

A pre-Stage-5 rollback branch is preserved at archive/repo-modernization-stage4-complete-2026-09-24.

Stage 6 GitHub Actions consolidation

Stage 6 reduces overlapping workflow ownership without combining jobs that have distinct data-writing responsibilities or unsafe concurrency requirements.

The consolidation changes are:

Stage 6 adds npm run check:workflows so CI verifies canonical consolidated workflows, retired workflow removal, unique workflow display names, and valid Pages CMS workflow references.

Stage 6 validation confirmed that the consolidation preserved behavior:

The exact pre-Stage-6 repository state remains available at archive/repo-modernization-stage5-complete-2026-09-24.

Stage 7 legacy/V2/V3 page cleanup

Stage 7 retired the noindex migration/demo page entry points only after the reference audit confirmed they were not canonical public surfaces.

Removed root pages:

about-v3.html
breakdowns-v3.html
contact-v3.html
event-map-v3.html
homepage-v2.html
homepage-v3.html
matchmaker-v3.html
news-v3.html
on-this-day-v3.html
ufc-roster-v3.html
upcoming-events-v3.html

The old Homepage V2-only browser bundle was also removed because its only consumer was homepage-v2.html:

assets/homepage-v2.css
assets/homepage-v2.js

Canonical routes remain unchanged. Browser smoke coverage now targets the canonical live pages instead of migration fixtures, the obsolete Homepage V2 navigation branches were removed from _layouts/default.html, and mobile Lighthouse no longer audits /homepage-v2/.

Version-named V3 assets such as assets/homepage-v3.css, assets/news-v3.css, and assets/matchmaker-v3.css were deliberately retained because the canonical live pages still consume them. Stage 7 removes dead page entry points, not working production styling.

The repository policy now advances to modernization Stage 7 and rejects any new root *-vN.html migration page. Existing legacy-*.html files are retained because they are deliberate redirect stubs that preserve older public article URLs.

The exact pre-Stage-7 repository state is preserved at archive/repo-modernization-stage6-complete-2026-09-24.

Stage 8 runtime-data and cache policy

Stage 8 classifies tracked repository data by lifecycle without relocating established public URLs.

The permanent roots are:

_data/          Jekyll/build-time data
assets/data/    published runtime and operational data
.cache/         disposable local/CI scratch data
assets/generated/ generated media (Stage 3 contract)

The machine-readable registry is .repository-data-policy.json. Every tracked file beneath _data/ and assets/data/ must match exactly one lifecycle rule describing its owner, producer, consumers, regeneration status, deletion status, and whether its path is a browser/runtime contract.

Stage 8 adds npm run check:data and Site Quality enforcement. The check rejects unclassified managed data, overlapping classifications, missing declared files/producers, tracked scratch-cache files, and invalid public-contract metadata.

Important policy decisions:

Local On This Day scratch defaults now use .cache/on-this-day/. Existing workflow-specific poster/share cache branches and their public URLs remain unchanged.

The exact pre-Stage-8 repository state is preserved at archive/repo-modernization-stage7-complete-2026-09-24.

Stage 8 validation confirmed:

Stage 9 repository integrity enforcement

Stage 9 converts the repository conventions from earlier stages into hard CI boundaries.

New enforcement includes:

Earlier enforcement remains in place and forms part of the Stage 9 integrity boundary:

The exact pre-Stage-9 repository state is preserved at archive/repo-modernization-stage8-complete-2026-09-24.

Stage 9 validation confirmed:

The first Stage 9 CI run was useful by design: the new local-media scanner initially included Markdown closing parentheses in asset paths. CI rejected those false positives, the parser was corrected in 37df6a7240101ffc5c526d6cf4766512e15721f7, and the corrected integrity step passed.

Stage 10 final documentation and maintenance mode

Stage 10 converts the completed migration into an everyday maintenance model.

The main entry points are now:

README.md
  concise developer map and common commands

docs/maintenance.md
  day-to-day task runbook, recovery rules, and change workflow

docs/repository-structure.md
  permanent file-placement contract

docs/repository-integrity.md
  CI enforcement and compatibility freezes

docs/data-lifecycle.md
  tracked data ownership and regeneration rules

docs/media-pipeline.md
  authored/generated/video media boundaries

docs/repository-modernization.md
  historical migration record and rollback markers

The README is intentionally present-tense. It no longer instructs maintainers to wait for future migration stages; it describes the structure that is already in force.

The maintenance policy is also machine-readable in .repository-policy.json:

The repository-policy checker verifies these maintenance-mode documents and key README developer-map markers so the final documentation cannot silently disappear while CI still claims the repository is in maintenance mode.

The exact pre-Stage-10 repository state is preserved at archive/repo-modernization-stage9-complete-2026-09-24.

Stage 10 validation confirmed:

Planned stages

Stage Scope Status
0 Baseline, rollback marker, reference audit Complete
1 Permanent organizational rules Complete
2 Future article asset upload hierarchy Complete
3 Media source/generated/video pipeline separation Complete
4 Writer frontend module split Complete
5 Development-script organization Complete
6 GitHub Actions workflow consolidation Complete
7 Legacy/V2/V3 page cleanup Complete
8 Runtime-data and cache policy Complete
9 Repository integrity enforcement Complete
10 Final documentation and maintenance mode Complete

The ten-stage migration is complete. Future structural changes should follow the maintenance runbook rather than extending this stage sequence.

Maintenance-mode handoff

The migration itself should now be treated as historical record.

For routine work, start with:

  1. README.md for the developer map;
  2. docs/maintenance.md for the task/runbook workflow;
  3. docs/repository-structure.md for placement decisions;
  4. docs/repository-integrity.md, docs/media-pipeline.md, or docs/data-lifecycle.md for domain-specific contracts.

The permanent operating rule is simple: preserve working public paths, put new work in the established location, let generators own generated output, run the reference audit before moves/deletes, and rely on CI to reject structural drift.