# Table System Migration

> Audit, migrate, and regression-test table systems across content-heavy websites, blogs, documentation sites, and admin surfaces. Use when Codex needs to normalize many ad hoc HTML table styles into a canonical table component, preserve legacy/admin table behavior, build a no-new-violations ratchet, add real-browser CSS regression coverage for table layout, or prepare a public-safe writeup/skill from a private table cleanup.

- Skill: `bogdanbaciu21/table-system-migration` (Agent Skill, multi-file: 6 files)
- Install (CLI): `npx skillmds@latest add bogdanbaciu21/table-system-migration`
- Raw SKILL.md: https://api.skillmd.com/api/skills/bogdanbaciu21/table-system-migration/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Web & Frontend
- Author: bogdanbaciu21 (https://skillmd.com/u/bogdanbaciu21)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/bogdanbaciu21/table-system-migration

---


# Table System Migration

## Overview

Use this skill to turn a messy estate of one-off HTML tables into a durable table system: a canonical component, compatibility rules for legacy/admin surfaces, a ratcheting linter, and real-browser layout regression tests.

## Confidentiality Gate

Before writing or publishing any reusable output, scrub it as if the target repository is public.

- Do not include local absolute paths, private repo names, production domains, customer names, emails, usernames, hostnames, tokens, passwords, keys, analytics IDs, database credentials, or commit hashes.
- Do not paste private source files, proprietary copy, unreleased content, exact defect counts, or internal incident details into the skill or writeup.
- Generalize examples. Prefer "content site", "admin grid", "canonical table class", and "legacy table class" over project-specific names.
- If the user explicitly wants project-specific wording, keep it in the private repo or ask before staging it in a public skills repo.
- Run a secret/string scan on the final diff before staging. Treat suspicious matches as blockers until explained or removed.

## Workflow

### 1. Map The Table Estate

Inspect the repository before editing.

- Identify content directories, templates/components, CSS entry points, generated assets, test commands, and CI gates.
- Inventory table markup patterns: canonical classes, legacy classes, wrapper classes, naked `<table>` elements, per-page `<style>` blocks, captions, footnotes, scroll wrappers, numeric cells, total rows, and admin/data-grid tables.
- Separate user-facing content tables from operational/admin grids. They may share CSS selectors but often need different layout behavior.
- Note existing failures or intentional baseline debt. Do not promise a full cleanup if the requested task is only a ratchet or migration of priority surfaces.

### 2. Define The Canonical System

Specify the smallest table API that covers the real use cases.

- Choose one canonical table class and one canonical wrapper class.
- Define header, body, numeric, label, total-row, caption, source, footnote, methodology/detail, grouped-header, and horizontal-scroll behavior only when each is actually needed.
- Preserve a compatibility layer for legacy/admin table classes if removing them would widen the blast radius.
- Avoid one-off per-post or per-page table classes unless they encode a genuinely distinct component.

### 3. Migrate In Risk Order

Make narrow, reviewable passes.

- Start with the reported broken table or highest-traffic content.
- Convert repeated old patterns to the canonical wrapper/table pair.
- Keep content semantics intact: headings remain headings, captions remain captions, source notes remain source notes, and data values do not change unless the user asked for content edits.
- Preserve intentional wide-table behavior with a wrapper-level scroll container instead of forcing every cell to wrap.
- For a long supporting table that sits below a summary or callout, collapse it by default inside a native disclosure element and surface a row-count or scope hint in the toggle, so the summary carries the answer and the full table stays available as on-demand detail.
- Avoid unrelated copy edits while touching content files.

### 3a. Adding The Canonical Class Is Not Enough — Neutralize Competing Overrides

This is the silent failure of a class-only migration. You add the canonical class, the table validates, the ratchet is green — and it still renders off-brand, because a **pre-existing per-page rule out-specifies the canonical component and wins.**

- **The mechanism.** The canonical header rule is typically `table.<canonical> thead th` (specificity 0,1,3). A leftover page rule like `table.<legacy> thead th { background: #1a2330 }` has the **same** specificity (0,1,3), so the cascade falls through to **source order** — and a page `<style>` block (or any later stylesheet) comes *after* the linked canonical CSS, so the leftover **wins**. The header silently keeps its old color. Multi-class (`.a.b th`), id (`#x th`), and `!important` rules beat the canonical component outright.
- **A `.legacy thead th` (0,1,2) without the `table.` prefix LOSES** to the canonical `table.<c> thead th` (0,1,3) — so it is already overridden and harmless. The dangerous ones are element-prefixed (`table.X …`), multi-class, id-scoped, or `!important`. The bundled ratchet's `canonical_override` check flags exactly these.
- **Remediation: remove the competing paint, do not re-add it.** Delete the `background`/`color` from the offending rule so the canonical styling takes over. **Preserve structural rules** in the same block — `min-width` (horizontal scroll), `position: sticky`, `@media` card-mode, `display:none` hidden columns, numeric `text-align`, special semantic cell classes, `::before/::after` content. Removing the whole block is fine when it is pure cosmetic re-implementation; reduce it to the structural declarations when it is not.
- **Do not blanket-strip — preserve genuine visualizations.** Heatmaps, comparison matrices where header color *encodes data*, frozen-corner pivots, and JS-rendered/sortable tables are deliberate. Allowlist their class and re-baseline; do not flatten them to the canonical look.
- **Verify the canonical style actually wins — by computed style, with the cache bypassed.** Stylesheet caching is notoriously sticky: a page can keep rendering the old header until a hard reload. Confirm the fix by reading the *computed* `background-color` of a `thead th` (e.g. it equals the canonical brand value) after a cache-ignoring reload — never trust source-only or a soft refresh.

### 4. Add A Ratchet

Add a deterministic check that blocks new table debt without requiring a full historical cleanup.

- Start from the bundled `table-ratchet.py` script and
  `references/table-ratchet-checklist.md` when the target repo does not already
  have a table-debt gate. The checklist lives under `references/` because it is
  implementation guidance; the executable script stays at the skill root so it
  can be copied or invoked directly.
- Configure the canonical table class, canonical wrapper class, generated-folder excludes, and any narrow legacy/admin table allowlists before creating the baseline.
- Scan content/templates for new unsanctioned table classes, new per-page table CSS, new unwrapped tables, and **`canonical_override`** rules (page-local selectors that out-specify and re-paint the canonical header — see step 3a). The `canonical_override` kind is what catches the "class is present but it still looks wrong" case that the other three checks miss.
- Store a baseline when legacy debt already exists.
- Refresh the baseline only after reviewing current debt and confirming the
  new counts are intentional:

```bash
python3 table-ratchet.py --root <repo> \
  --canonical-table-class <class> \
  --canonical-wrapper-class <wrapper> \
  --write-baseline
```

- Fail only when a file exceeds the baseline or a new file introduces debt.
- Print actionable remediation text: which file regressed, what count increased, and which canonical classes to use.

### 5. Add Real-Browser Regression Tests

Use browser-backed tests for layout behavior that DOM-only environments cannot see.

- Mount minimal fixtures for each shared surface: content table, admin grid, wide table, caption/source block, total row, grouped header, and any special numeric alignment convention.
- Assert computed style and actual box geometry where layout matters: widths, min-width behavior, wrapping, sticky columns, overflow, hover backgrounds, and padding after prose resets.
- Assert that the canonical styling actually wins on a migrated table: read the computed `thead th` `background-color` and confirm it equals the canonical brand value, not a leftover per-page color (the `canonical_override` regression, step 3a). A class-presence assertion is not enough — it passes even when the header is silently overridden.
- Build/import the real compiled CSS bundle rather than duplicating CSS in the test.
- Include at least one test that protects admin/data-grid tables from changes made for prose/content tables.

### 6. Validate Before Calling Done

Run the smallest complete gate set for the touched stack.

- Run the table ratchet.
- If using the bundled artifact, run `python3 table-ratchet.py --root <repo> ...` with the same class and allowlist flags used to write the baseline.
- Rebuild CSS/assets if tests import generated bundles.
- Run browser/CSS regression tests.
- Run compile/type/lint checks that CI uses for touched code.
- Check `git diff --check` and confirm the working tree contains only intended files.
- If full tests are known to have unrelated failures, report the exact focused gates that passed and the known reason full tests were not used.

## Output Contract

When reporting status, distinguish these clearly:

- **Landed changes:** canonical CSS/classes, migrated files, tests, linter, docs.
- **Verification:** exact commands run and pass/fail results, including the table-ratchet command and baseline path if one was added.
- **Remaining debt:** legacy classes/unwrapped tables that are intentionally baselined.
- **Review notes:** files staged, files not staged, and any suspicious scrub findings that were removed or intentionally kept.

## Example Prompts

- "Use `$table-system-migration` to migrate this blog's tables to one canonical component and add a no-new-violations check."
- "Use `$table-system-migration` after this table CSS change; I want proof that admin grids did not collapse."
- "Use `$table-system-migration` to turn this private table cleanup into a public-safe skill without leaking project details."

## Skill Maintenance

When editing the ratchet script, run:

```bash
PYTHONDONTWRITEBYTECODE=1 python3 -m unittest tests/test_table_ratchet.py
```

