---
name: architect-kit-mirror
description: >
  Encodes the kit-mirror discipline for the L4 platform kit. Manages MIRRORED FROM headers,
  one-way pull from source kits, drift detection between sync events, and conflict resolution
  when local changes meet upstream changes. Triggered when the operator says any of: "sync the
  kit", "mirror from upstream", "check for drift", "pull kit updates", "mirror discipline",
  "kit sync", "is the kit drifted", "platform kit mirror". The skill reasons about mirror
  chains (kit -> instance -> sub-platform), not just mirror pairs. Refuses to push back into
  source kits unless an explicit ADR authorizes bidirectional sync. Pairs with the deploy
  skill when Q6 posture is one of partial-internal, mature-internal-mirror, mature-external-mirror,
  or mirror-this-kit.
---

# architect-kit-mirror

Encodes the kit-mirror discipline. One-way sync from source to mirror; `MIRRORED FROM` headers track provenance; drift detection between sync events; conflict resolution when local changes meet upstream changes. Reasons about mirror chains (kit -> instance -> sub-platform), not just pairs.

## Core principles

The kit + mirror pattern is one-way by default. Source-of-truth lives at the kit; consumers mirror. Improvements flow source-to-consumer at sync time. Bidirectional sync requires an explicit ADR authorizing it; without that, the mirror is read-only.

## When to invoke

- Operator says: "sync the kit", "mirror from upstream", "check for drift", "pull kit updates", "mirror discipline", "kit sync", "is the kit drifted", "platform kit mirror"
- The deploy skill's L4 template branch is one of: `partial-internal`, `mature-internal-mirror`, `mature-external-mirror`, `mirror-this-kit`
- Scheduled cadence (typically biweekly) per the L4 platform-kit's mirror manifest
- An upstream change-event arrives in the inbox (e.g., kit-sync-event from {{platform_team_name}})

## Operating modes

The skill operates in one of four modes. Determine mode by reading L4 platform-kit's posture token in the deployed instance's `kit/PLATFORM-KIT.md`.

### Mode A: First sync (mirror not yet established)

Run when the deploy skill scaffolds a fresh instance with mirror posture.

1. Read source kit's manifest (file list, versions, hashes)
2. For each source file: copy to mirror path; prepend `MIRRORED FROM: {source_path}` line + `MIRRORED AT: {date}` line; preserve relative path structure
3. Generate mirror manifest at `{instance_root}/kit/MANIFEST.md` listing each mirrored file + version + sync date
4. Mark mirror status as `live` for each component in `kit/PLATFORM-KIT.md`'s mirror manifest table
5. Log first-sync as a session log entry

### Mode B: Routine re-sync (cadence-driven)

Run on scheduled cadence (typically biweekly) or on inbox kit-sync-event arrival.

1. Compare current mirror manifest against source manifest
2. For each component:
   - **Source unchanged:** mirror status stays `live`; no action
   - **Source updated, mirror has no local changes:** pull update; refresh `MIRRORED AT` date; re-eval if component is eval-affecting
   - **Source updated, mirror has local changes:** trigger Mode D conflict resolution
   - **Source removed:** mirror file moves to archive; log to BACKLOG for cleanup
3. Update `kit/MANIFEST.md` + `kit/PLATFORM-KIT.md` mirror manifest table
4. Log re-sync as a session log entry

### Mode C: Drift detection (no action; just report)

Run on demand or when validate skill asks for drift status.

1. Compare current mirror manifest against source manifest
2. Report:
   - Days since last sync per component
   - Number of upstream changes pending pull per component
   - Mirror-status classification: `live` (no upstream changes), `declared-but-inactive` (drift exists)
3. Output a drift report; do not pull anything; surface to operator

### Mode D: Conflict resolution

Run when source and mirror both have changes since last sync.

1. Identify the conflicted file(s)
2. For each: classify the conflict
   - **Local change is a customization that should not exist** (someone edited a mirrored file directly): demote local change to a fork; write an ADR explaining the local change; mark file as locally-owned (remove `MIRRORED FROM` header)
   - **Local change is a fix that source should adopt:** open inbox-outbox entry to source kit's owner with the proposed change; do not pull source version yet
   - **Both changes are compatible:** merge if straightforward; otherwise treat as fork + ADR
3. Block the routine re-sync until conflicts are resolved
4. Log conflict resolution as a session log entry

## Mirror chain reasoning

A real deployment may have mirror chains:

```
{source_kit} ──MIRRORED FROM──▶ {instance_kit} ──MIRRORED FROM──▶ {sub_platform_kit}
```

When the source kit changes, the instance kit pulls; when the instance kit pulls, the sub-platform kit must also pull (eventually). The skill reasons about chains:

- A drift event at the top of the chain creates pending updates throughout the chain
- Re-sync events cascade in dependency order (top of chain first)
- Conflicts at any link block the cascade

If the deployed instance's L4 is `mirror-this-kit` (the kit eats its own output), the chain becomes recursive: every sync of the deployment kit refreshes the L4. Handle with care; pair with deploy skill's self-update protocol.

## MIRRORED FROM header format

Every mirrored file has these two lines as the first non-frontmatter content (or first content if the file has no frontmatter):

```
<!-- MIRRORED FROM: {source_relative_path} -->
<!-- MIRRORED AT: YYYY-MM-DD -->
```

For machine-readable formats (JSON, YAML, .py, .ts), use the format-appropriate comment syntax.

The header is the source attribution; the absence of a `MIRRORED FROM` header on a file in `{instance_root}/kit/` means the file is locally owned and not subject to sync.

## Drift classification

Per BOOTSTRAP-BRIEF Section IV's relationship semantics:

- **Mirror is `live`:** mirror is current with source; last sync is within cadence window
- **Mirror is `declared-but-inactive`:** mirror has stale content vs. source; cadence window exceeded; re-sync needed

Default assumption is `declared-but-inactive` unless evidence shows otherwise. Evidence is:

- Mirror manifest's last-sync date within cadence window
- No upstream changes since last sync, OR last sync ran successfully against current source

Without both, mirror is `declared-but-inactive`.

## Refusal conditions

The skill refuses to push back into the source kit unless:

- An explicit ADR authorizes bidirectional sync for the specific component
- The skill's invocation includes evidence of that ADR (path or number)

If pushed (operator says "push my local change to upstream"): refuse; explain the one-way default; offer to open an inbox-outbox capability-request entry instead.

## Cross-references inside the kit

- `BOOTSTRAP-BRIEF.md` Section II - kit + mirror pattern definition
- `templates/L4-platform-kit.md` - the template this skill scaffolds against
- `examples/martech-mature-instance/kit/PLATFORM-KIT.md` - reference example
- `examples/martech-mature-instance/decisions/ADR-0002-kit-mirror-direction.md` - reference ADR for one-way pull discipline
- `skills/deploy/SKILL.md` - paired during initial mirror setup
- `skills/validate/SKILL.md` - validate skill calls Mode C (drift detection) as part of its audit
