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.
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.
What does the original system actually do?
Lifecycle: relatively frozen after the source baseline is established. It changes only when evidence corrects our understanding of the old system.
What equivalence or intentional difference are we committing to, and how will we prove it?
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.
How does the replacement work now?
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.
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?
| Fact | Owner |
|---|---|
| The old system keeps the first matching record in file order | Legacy source charter |
| Whether the new system must match that, and any accepted divergence | Migration contract |
| How the new code’s ordering and tie-breaker implement the current behaviour | Target 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.
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.
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.
| Change | Charters to read and update |
|---|---|
| Internal refactor, behaviour unchanged | The target charter only |
| Change to output ordering or matching semantics | Target charter + the migration contract |
| Newly discovered behaviour of the old system | Legacy charter; the contract too only if the promise changes |
| More parity fixtures, no contract change | Target test entry or a test artifact; do not rewrite the legacy charter |
| Deployment-driver change | Target deployment charter; the contract only if cutover evidence changes |
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.
These belong in the cross-cutting charter, because they apply to every step of the migration:
Passing a lower tier never implies that a higher tier passed.
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.
| Material | Where it belongs instead |
|---|---|
| Current priorities and completion status | roadmap.md, pulse, or a migration status artifact |
| Proposed implementation sequence | An implementation plan artifact |
| Deep architectural reasoning | A design artifact |
| Review findings awaiting action | whiteboard.md |
| Deployment output and query profiles | Logs in .gator/vault/ |
| Historical decisions and the exact change sequence | Git commits and session snippets |
| Operator instructions | The project’s operations documentation |
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: <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: <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: <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.
Restructure one step first, the one with the most review pressure and the clearest overlap between source semantics, migration decisions and target implementation.
INDEX.md so work on that step loads only the cross-cutting charter, its target charter, and the contract when semantics or parity change.Do not delete information during the pilot. Material that is valuable but not charter-shaped moves to an artifact or stays recoverable in Git.
| Risk | Guardrail |
|---|---|
| The three families become three copies | Enforce one fact, one owner, and cross-link instead of restating. |
| Contracts become activity diaries | Keep status and chronology in artifacts and Git; contracts hold only active commitments. |
| Excessive fragmentation | Split by code domain, not by file or milestone; the index must make the right path obvious. |
| Charter rewrites obscure product changes | Use governance-only commits, never combined with product fixes. |
| Useful rationale disappears | Move deep rationale to artifacts, keep links, and rely on Git for removed history. |