A migration has three truths: what the old system does, what the new system promises to preserve, and how the new system works. Gator keeps each in its own charter, so an agent loads only the one the change needs.

Why migrations need their own charter structure

Without structure, migration knowledge accumulates in one chronological charter. Legacy behaviour, porting decisions, review findings, retired designs and target implementation details pile up together, and a single charter can grow to thousands of lines. Every change then loads all of it.

Reviewers must recover a small number of active invariants from that history. Relevant constraints become hard to locate, contradictions are easy to import from superseded milestones, and new findings are appended as more prose instead of sharpening a small current contract. Review rounds repeat because the governing context is too large and too historical. Some findings will always be ordinary implementation mistakes; the structural problem is that the map stopped being a map.

The goal is a sharper active map, not a loss of institutional memory. History stays in Git and artifacts; charters hold what is true and binding now.

Three layers of charters

Three charter layers for a migration At the top, a small hub box: "migration-cross-cutting", shared rules for all three layers. Below it, three boxes from left to right, joined by arrows. First, "Legacy source", files named legacy-star, answering "What does the old system do?"; lifecycle: frozen after discovery. Second, "Migration contract", files named migration-star, answering "What must stay the same, and how do we prove it?"; lifecycle: active until cutover. Third, "Target implementation", files named target-star, answering "How does the new system work now?"; lifecycle: survives the migration. Dashed lines connect the hub to each layer. migration-cross-cutting shared rules for all three layers Legacy source legacy-* What does the old system do? FROZEN AFTER DISCOVERY Migration contract migration-* What must stay the same, and how do we prove it? ACTIVE UNTIL CUTOVER Target implementation target-* How does the new system work now? SURVIVES THE MIGRATION
Figure 1 — three families of charters, each answering one question, with a small shared hub. Arrows show the direction of authority: observed behaviour informs the contract, and the contract governs the implementation.

Legacy source

What does the original system actually do?

Owns

  • canonical entry points and call paths
  • source data reads and writes
  • ordering, deduplication, missing-value and stateful-processing semantics
  • hard-coded parameters and lookup behaviour
  • ambiguous variants and unresolved questions about the production source
  • source-specific tripwires that a port must understand

Does not own

  • target implementation details
  • “ported at milestone X” chronology or deployment history
  • accepted divergences (it links to the contract)

Lifecycle: relatively frozen after the source baseline is established. It changes only when evidence corrects our understanding of the old system.

Migration contract

What equivalence or intentional difference are we committing to, and how will we prove it?

Owns

  • the source-to-target semantic mapping
  • invariants that must survive the migration
  • explicitly accepted divergences and their rationale
  • source precedence when references disagree
  • parity fixtures, acceptance gates and cutover evidence
  • temporary safeguards and their removal conditions
  • open decisions that materially affect equivalence

Does not own

  • complete descriptions of either codebase
  • a log of every review finding and fix
  • retired design alternatives once a decision is final

Lifecycle: active during the migration. At cutover it shrinks to the few permanent compatibility constraints, or moves out of active routing into an archival artifact.

Target implementation

How does the replacement work now?

Owns

  • current public surfaces and module ownership
  • function names and dependency direction
  • tables, files, procedures, privileges and other external state read or written
  • active operational and security tripwires
  • negative space: what the module deliberately does not do
  • links to the contract where behaviour is parity-sensitive

Does not own

  • milestone-by-milestone landing history or superseded designs
  • detailed test transcripts or review IDs
  • repeated explanations of the old system’s behaviour

Lifecycle: survives the migration as an ordinary code charter, edited in place as behaviour changes, never with a new “landed in milestone N” section per increment.

A small migration-cross-cutting.md holds the rules that span all three layers: authority, source precedence, change routing, shared invariants and evidence tiers. It is a hub, not a fourth lifecycle layer, and it must not become another milestone history.

One fact, one owner

Every material fact has exactly one authoritative charter. Other layers link to it instead of restating it.

Take a deduplication rule: when two records match, which one wins?

FactOwner
The old system keeps the first matching record in file orderLegacy source charter
Whether the new system must match that, and any accepted divergenceMigration contract
How the new code’s ordering and tie-breaker implement the current behaviourTarget implementation charter

This prevents three similar paragraphs from drifting apart, and it forces reviewers to keep three things distinct: observed source truth, migration policy, and implementation mechanism.

Source precedence

Observed executable behaviour of the old system outranks its comments and plans. The active migration contract decides whether the target must match or intentionally diverge. The target charter describes how the approved contract is implemented; it cannot silently redefine the contract.

Route each change to the smallest charter

The value of the split comes from selective routing. Three sections in one large file would keep the same context problem. INDEX.md maps precise code paths to the smallest target charter, and names the legacy and contract charters as conditional context.

ChangeCharters to read and update
Internal refactor, behaviour unchangedThe target charter only
Change to output ordering or matching semanticsTarget charter + the migration contract
Newly discovered behaviour of the old systemLegacy charter; the contract too only if the promise changes
More parity fixtures, no contract changeTarget test entry or a test artifact; do not rewrite the legacy charter
Deployment-driver changeTarget deployment charter; the contract only if cutover evidence changes
Rule

Never touch all three layers merely to satisfy a hook. A charter changes only when a fact it owns changes. Code changes normally touch one target charter.

Shared migration invariants

These belong in the cross-cutting charter, because they apply to every step of the migration:

Evidence tiers

  1. Local unit and structural tests prove helper and construction contracts.
  2. Test-environment parity fixtures prove deployed behaviour on controlled data.
  3. Probes against real data prove shape, cost, scale and operational safety.
  4. Trusted outputs from the old system prove business parity, when they are available.
Rule

Passing a lower tier never implies that a higher tier passed.

Keep every charter small

The structure only helps if each charter stays sharp. The layers must enforce the charter guide, not reproduce the old content under more file names.

MaterialWhere it belongs instead
Current priorities and completion statusroadmap.md, pulse, or a migration status artifact
Proposed implementation sequenceAn implementation plan artifact
Deep architectural reasoningA design artifact
Review findings awaiting actionwhiteboard.md
Deployment output and query profilesLogs in .gator/vault/
Historical decisions and the exact change sequenceGit commits and session snippets
Operator instructionsThe project’s operations documentation

File layout and templates

Keep all migration charters directly in .gator/charters/, with a family prefix. Do not nest them in subfolders: the pre-commit hook matches staged charters by file name, so nested paths cause false charter-index-gap failures. Split target charters by code domain, not by milestone.

.gator/charters/
  migration-cross-cutting.md

  legacy-<system>-<area>.md
  migration-<step>-contract.md
  target-<platform>-<domain>.md

Start each family from a template:

Legacy source charter

# Legacy Source Charter: <system/domain>

## Owns
- Observed behaviour of the original executable system.
- Entry points, reads/writes, ordering, missing-value rules, tripwires.

## Does Not Own
- Migration acceptance policy or target implementation mechanics.
- Porting chronology.

## Flow
### `<source entry point>`
File: `<path>`
What it does; data read and written.
← caller
→ dependency
! Non-obvious source behaviour that changes outcomes.

## Open Source Ambiguities
- Questions that need production evidence or owner confirmation.

## Connections
-> Relevant migration contract (link; do not restate it).

Migration contract

# Migration Contract: <step/domain>

## Scope
Source boundary, target boundary, and current migration status.

## Required Equivalence
- Behaviours the target must preserve.

## Accepted Divergences
- Bounded difference, rationale, affected surface, proof fixture.

## Acceptance Gates
- Local, test-environment, real-scale and source-output evidence
  required for cutover.

## Open Decisions
- Unresolved choices that materially affect equivalence.

## Cutover and Retirement
- Conditions to activate the target and retire migration-only
  safeguards.

## Connections
-> Legacy authority and target implementation charter.

Target implementation charter

# Target Implementation Charter: <domain>

## Owns
- Current landed implementation, public surfaces, state access,
  and active tripwires.

## Does Not Own
- Original-system semantics or migration policy (link to those).
- Milestone and review history.

## Current Surface
### `<function/object>`
File: `<path>`
Reads/writes and behaviour.
← caller
→ dependency
! Implementation constraint that must survive changes.

## Negative Space
- Capabilities deliberately absent from this implementation.

## Connections
-> Relevant migration contract and neighbouring target charters.

Adopting the structure: start with a pilot

Restructure one step first, the one with the most review pressure and the clearest overlap between source semantics, migration decisions and target implementation.

  1. Finish any in-flight product change first. Do not mix a governance rewrite into a product-code diff.
  2. In a separate, governance-only commit, extract that step’s material from the oversized charters.
  3. Build the first three-file chain: legacy charter → migration contract → target charter.
  4. Add a narrower target charter if the remaining material would push a target charter past the size limit.
  5. Rewrite INDEX.md so work on that step loads only the cross-cutting charter, its target charter, and the contract when semantics or parity change.
  6. Run the next change under the new routing. Watch whether review findings become fewer, more local and less repetitive.
  7. If the pilot works, apply the structure to the other steps, each in its own governance-only commit.

Do not delete information during the pilot. Material that is valuable but not charter-shaped moves to an artifact or stays recoverable in Git.

How you know it worked

RiskGuardrail
The three families become three copiesEnforce one fact, one owner, and cross-link instead of restating.
Contracts become activity diariesKeep status and chronology in artifacts and Git; contracts hold only active commitments.
Excessive fragmentationSplit by code domain, not by file or milestone; the index must make the right path obvious.
Charter rewrites obscure product changesUse governance-only commits, never combined with product fixes.
Useful rationale disappearsMove deep rationale to artifacts, keep links, and rely on Git for removed history.