Skip to content
Back to skills

Adopt Site

ASecurity

Adopt a site into Movar, or repair an adoption after a redesign. Two phases: Phase 1 teaches Movar to switch the SITE's own language (picker, language gate/modal, hreflang, cookie/path/query, redirect SiteRule); Phase 2 — only for sites whose correctly-switched pages still show blocked-language CONTENT items (search results, feeds, recommendations, UGC) — models the page structure (@movar/page-content extractor) so Movar filters per-card. Use when the user asks to add/support a new site ("add...

  • 34 stars
  • 0 votes
  • 0 copies
  • 3 views
  • Added September 10, 2026
testinggonodegit

Security analysis

A100/100

Pro scans all 2 files and shows the line behind each finding

Scanned September 10, 2026

npx -y skills add rejifald/movar --skill adopt-site --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Adopt Site?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Adopt Site
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/rejifald-adopt-site/badge)](https://www.skillsdirectory.com/skills/rejifald-adopt-site)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: adopt-site
description: |
  Adopt a site into Movar, or repair an adoption after a redesign. Two
  phases: Phase 1 teaches Movar to switch the SITE's own language (picker,
  language gate/modal, hreflang, cookie/path/query, redirect SiteRule);
  Phase 2 — only for sites whose correctly-switched pages still show
  blocked-language CONTENT items (search results, feeds, recommendations,
  UGC) — models the page structure (@movar/page-content extractor) so Movar
  filters per-card. Use when the user asks to add/support a new site ("add
  rozetka", "X still serves Russian", "X ignores my language preference"),
  when an adopted site redesigned and cards leak through ("movar misses
  videos on YouTube", "X changed markup"), when asked to survey or verify a
  site's DOM against the model, or when an enforce-mode rule needs its
  SPA-navigation safety re-verified. Do NOT use for: language-detection /
  classifier work (@movar/lang-detect), concealment UI (curtains, tooltips,
  page-mode), marketing or store copy, or bug fixes that don't touch site
  adoption.
---

# Adopt a site (or repair an adoption)

Movar adopts a site in two phases, in order. Most sites stop after Phase 1.
This skill is the orchestration; the invariants live in the canonical docs it
points at — read them at the step that needs them, never restate them.

## Ground rules (both phases)

- **Live proof is mandatory.** Every claim about a site's markup or behavior
  is verified against the live site in a browser, with the probes in
  [references/probes.md](references/probes.md). Prefer Claude-in-Chrome (real
  sessions); fall back to the in-app Browser pane (logged-out — note the
  difference in your report). Logged-out caveats: feeds/grids sometimes stall
  hydration — that is transient, retry the page before concluding "empty";
  survey mobile via the mobile viewport preset (UA emulation) against the
  `m.` host; NEVER solve a CAPTCHA — fall back to corpus evidence and say so
  in the report.
- **Say what you could not observe.** A surface you could not reach is
  reported as unverified, never silently assumed covered.
- Cheapest lever wins: never start Phase 2 work a Phase 1 rule would solve.

## Step 0 — Surface inventory (before either phase)

Adoption starts with an inventory, not a survey: enumerate **every page type
the site serves** and classify each row before touching any code. Two axes:

- **Hosts** — everything the host predicate will match (a suffix predicate
  like `*.youtube.com` drags music/kids/studio subdomains into scope whether
  intended or not; each matched host is a row).
- **Routes** — home/feed, search + every vertical it serves, item pages
  (alone and with list/queue context), section/channel/category tabs, list
  pages, posts/UGC surfaces, hashtag/topic pages, live hubs, the mobile
  host's mirrors of all of the above. Use the route-inventory probe
  ([references/probes.md](references/probes.md)) plus the site's own nav.

Classify every row as one of: **switch** (Phase 1 acts), **model** (Phase 2
extracts), **ignore** (deliberately out of scope — record the stance, e.g.
"the player itself", "user's own queue"), or **unverified** (could not
observe — say why). The inventory is the adoption's contract: the phases
below work through its `switch`/`model` rows, the done-bar requires every
row classified, and the extractor header + PR carry the final table. A row
nobody classified is a gap, not a stance.

## Phase 1 — whole-site language switching

Goal: the site itself serves the target language.

1. **Survey the site's own levers live** — what does it already offer? A
   picker/gate (`@movar/lang-pickers` may already detect it — check
   [packages/lang-pickers/AGENTS.md](../../../packages/lang-pickers/AGENTS.md)),
   `<link rel="alternate" hreflang>`, a cookie/localStorage key, a path
   segment or subdomain, query params. Use the census probe; confirm each
   lever by DRIVING it live and watching the URL/cookie/render.
2. **Author the `SiteRule`.** The strategy menu, wiring steps (registry,
   `SAMPLE_HOSTS`, behavioural test), and risk notes are canonical in
   [apps/extension/src/sites/CONTRIBUTING-A-SITE.md](../../../apps/extension/src/sites/CONTRIBUTING-A-SITE.md).
   Follow its wiring list verbatim.
3. **`enforce: true` needs two extra proofs** (search-engine-shaped sites):
   the strategy is no-op-safe at target (re-run changes nothing), and the
   SPA-navigation safety holds — run the nav-timing and guard-dance probes
   and read [docs/pitfalls.md](../../../docs/pitfalls.md) §5 before touching
   anything event-driven.
4. **Corpus fixture.** Capture the picker/redirect surface per
   [packages/page-content/fixtures/README.md](../../../packages/page-content/fixtures/README.md)
   into `fixtures/pickers/` or `fixtures/redirect-sites/`.
5. **Live-drive the finished switch** on the real site as the closing proof.

## Phase gate — does this site need Phase 2?

Graduate to Phase 2 only when the correctly-switched site still shows
blocked-language **content items**: search results, feeds, recommendations,
user-generated content (Google and YouTube are the two residents today). A
site that fully re-renders in the chosen language stops at Phase 1 — a
Phase-2 model is a budgeted content-script chunk plus a corpus and a standing
maintenance surface; it must earn that cost.

## Phase 2 — page-structure model

Goal: a `@movar/page-content` extractor that turns every hot-path page into
per-card `ContentNode`s.

1. **Hot-path survey.** Enumerate the surfaces before modelling: home/feed,
   search, item page (and item page with list/queue context), section and
   channel/category pages, list pages, the mobile host. Run the census and
   card-anatomy probes on each; record which surfaces you could not observe.
2. **Write the shapes.** Selector and sampling discipline are canonical in
   [packages/page-content/AGENTS.md](../../../packages/page-content/AGENTS.md)
   and [docs/pitfalls.md](../../../docs/pitfalls.md) §1 — durable anchors
   only, allow-list text sampling, fail open. Kind/hideMode semantics live in
   `packages/page-content/src/types.ts`; nested cards get outermost-wins
   dedup (see `google.ts`/`youtube.ts` for the pattern).
3. **Wire the chunk.** `apps/extension/src/sites/<site>/` model descriptor +
   lazy `models/<site>.js` chunk (copy `./youtube/`), inside the byte budget
   (`CAPABILITY_BUDGETS_KB`, enforced at build — see
   [apps/extension/AGENTS.md](../../../apps/extension/AGENTS.md)).
4. **Tests + corpus.** Synthetic unit tests per shape; one real-capture
   fixture per new/changed surface per the corpus README recipe. **Verify
   every verdict against `classifyBySnippet` before pinning it** (probe the
   classifier with the exact serialized samples); a case the pipeline gets
   wrong is encoded loudly as an asserted false-keep with a note, never
   dropped.
5. **Live shape-mirror, before and after.** Mirror the shipped shapes in-page
   (probes.md) on EVERY claimed surface: expected node counts, expected
   nested-dedup count, zero empty samples (except documented fail-open
   cells). The before-run is the drift evidence; the after-run is the proof.
6. **Record provenance + non-goals** in the extractor header: the dated
   survey table and the surfaces deliberately NOT extracted, with the stance
   — so the next audit can tell stance from gap. Update the package
   AGENTS.md youtube/google-style bullet for the new extractor.

## Definition of done (all of it, both phases)

- [ ] Surface inventory complete — every host × route row classified
      switch / model / ignore (with stance) / unverified (with reason)
- [ ] Package-scoped tests, lint, typecheck green (`pnpm --filter <pkg> …`)
- [ ] Corpus fixture(s) per changed surface, classifier-verified verdicts
- [ ] Live proof captured: Phase-1 switch driven / Phase-2 mirror clean on
      every surface (or the unreached surfaces named as unverified)
- [ ] Extractor header carries the dated survey + non-goals; AGENTS.md updated
- [ ] Extension build green — chunk budgets hold
- [ ] `pnpm test:coverage && pnpm gen:readme --refresh` (metrics-gate snapshot)
- [ ] `pnpm nx reset`, then a plain `git push` (hooks must run; never
      `--no-verify`)
- [ ] PR carries the hot-path coverage matrix, the non-goals, and named
      follow-ups

Files in this skill

  • SKILL.md8.2 KB
  • references/probes.md10.7 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.