# Opsx Ru Sync

> Sync and Russian-translate OpenSpec artifacts to the openspec-ru mirror, copying non-markdown files as-is, translating markdown via Subagent (Composer 2.5), and running a file-count parity check. Use when any /opsx command (propose, apply, sync, archive) creates or updates files in openspec/changes or openspec/specs, or after any manual edit under openspec/ that must be mirrored to openspec-ru/.

- Skill: `vari-arti/opsx-ru-sync` (Agent Skill)
- Install (CLI): `npx skillmds@latest add vari-arti/opsx-ru-sync`
- Raw SKILL.md: https://api.skillmd.com/api/skills/vari-arti/opsx-ru-sync/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Docs & Writing
- Author: vari-arti (https://skillmd.com/u/vari-arti)
- Updated: 2026-09-22
- Page: https://skillmd.com/skills/vari-arti/opsx-ru-sync

---


# OpenSpec RU Mirror Sync

## When to use

Use this skill immediately after:
- `/opsx:propose` (artifacts created/updated in `openspec/changes/<change>/`)
- `/opsx:apply` (tasks/design/specs updated in `openspec/changes/<change>/`)
- `/opsx:sync` (main specs updated in `openspec/specs/`)
- `/opsx:archive` (change moved to archive)
- Any manual edit under `openspec/` that should be mirrored to `openspec-ru/`

## Inputs

- `mode`: one of `change`, `main-specs`, `archive`
- `change`: required for `change` and `archive` modes
- `updated_paths`: optional list of changed files; if omitted, sync full target scope

## Rules

- `openspec/` is source of truth. Never translate back from RU to source.
- Translate markdown using Subagent model **Composer 2.5**.
- Keep technical identifiers unchanged:
  - status/reason literals (`quarantine`, `mapping_invalid`, `row_empty_key`, etc.)
  - endpoint paths, file paths, class names, table names, enum values
- Preserve markdown structure exactly, especially checkboxes in `tasks.md` (`- [ ]` / `- [x]`).
- Non-markdown metadata files (e.g., `.openspec.yaml`) are copied as-is.
- Mirror includes all change artifacts: `proposal.md`, `design.md`, `data-model.md`, `reused.md`, `tasks.md`, and `specs/**/*.md`.

## Workflow

1. Resolve source/target scope:
   - `change`: `openspec/changes/<change>/` -> `openspec-ru/changes/<change>/`
   - `main-specs`: `openspec/specs/` -> `openspec-ru/specs/`
   - `archive`: ensure both source trees are archived with same `YYYY-MM-DD-<change>` suffix
2. Ensure target directories exist (create if missing):
   ```bash
   mkdir -p <mirror_scope>
   ```
3. Copy non-markdown files as-is:
   ```bash
   rsync -a --include='*/' --exclude='*.md' --prune-empty-dirs <source_scope>/ <mirror_scope>/
   ```
   *(If bash is unavailable, use `shutil.copy2` in Python for each non-markdown file.)*
4. Translate markdown files via Subagent (Composer 2.5):
   - Invoke the Subagent with the instruction: *"Translate the following markdown file to Russian. Preserve all markdown structure, code blocks, checkbox syntax (`- [ ]`/`- [x]`), and technical identifiers (paths, enum values, status literals, class names) exactly as-is. Only translate human-readable prose."* followed by the full file contents.
   - Write the Subagent output to the corresponding path under the mirror directory.
5. Run parity check:
   ```bash
   diff <(find <source_scope> -type f | sed "s|<source_scope>/||" | sort) \
        <(find <mirror_scope> -type f | sed "s|<mirror_scope>/||" | sort)
   ```
   *(If bash is unavailable, use `os.walk` in Python to compare relative path sets and identify `missing_in_mirror` / `extra_in_mirror`.)*
   - Report any missing or extra entries as skipped/failed files.
6. Report:
   - synced scope
   - translated file count
   - parity result
   - any skipped/failed files with reason

## Output format

Use this concise summary:

```markdown
## RU Sync Result

- Scope: <change|main-specs|archive>
- Source: `<path>`
- Mirror: `<path>`
- Translated: <N> markdown files (Composer 2.5)
- Copied as-is: <M> files
- Parity: <ok|failed>
- Notes: <issues or "none">
```

