Skill: sync-template
Purpose
Sync structural/template improvements between project and https://github.com/Rheinmir/setup.git.
When to use
- Upstream: Improved template locally → save to Master.
- Downstream: Master has newer fixes → bring into project.
FAST PATH — downstream 1 lệnh --full (< 30s, mặc định)
Downstream sync là 1 script non-interactive tự chứa. Gọi 1 lần với --full → mọi bước
hậu-sync (Step 6a/6b/8 + ghi log) chạy trong CÙNG process. Agent đọc 1 report rồi báo cáo —
KHÔNG lặp lại lệnh riêng. Bench repo này: full steady-state 0.27s · full pull+install+verify 0.76s
(harness/metrics/sync-template-bench.json).
python3 harness/scripts/sync-template.py --full # ⭐ MẶC ĐỊNH: sync + OKF backfill + fingerprint + verify ×3 + ghi log, 1 process
python3 harness/scripts/sync-template.py --full --json # như trên, output máy đọc (đọc okf_migrated / verify_bad)
python3 harness/scripts/sync-template.py --dry-run # xem trước, không ghi (kèm --full để xem OKF sẽ migrate gì)
python3 harness/scripts/sync-template.py --strategy pull # ghi đè cả CONFLICT bằng remote (backup .local-bak)
Chạy
--full1 lần là xong — đừng gọi tiếpokf-check,health-check --update, vòng verify, hay tựEditlog.md (script đã làm hết). Đó là cách giữ skill dưới 30s: nút thắt cũ là số round-trip agent quanh các bước hậu-sync, không phải CPU. Không cờ--full= hành vi cũ y nguyên.
Phân loại bằng hash 3 mốc — disk ↔ R0 (remote tại lần sync trước, lưu ở version.json:remote_synced) ↔ remote hiện tại:
NEW(thiếu local) +UPDATE(remote mới hơn, local chưa đụng) → tự PULL.KEPT(mình đã custom, remote không mới hơn) → giữ nguyên, không hỏi.CONFLICT(cả hai cùng đổi) → mặc định giữ local + lưu bản remote ra/tmp/sync-template-conflicts/để diff; exit code 3. Không bao giờ tự--strategy pullđể rút ngắn thời gian.
Quy trình tự động trong script (--full): fetch remote version.json+manifest → phân loại → tải song song → OKF backfill in-process (migrate bold→YAML, idempotent) → refresh version.json (fingerprint SAU OKF + template_version + remote_synced) → cài skill ra 3 chỗ (.claude/commands/, ~/.claude/skills/, ~/.claude/commands/) → self-verify 3 vị trí → append wiki/log.md. Exit: 0 sạch · 1 lỗi tải/OKF/verify · 3 CONFLICT cần quyết.
Khi nào CẦN can thiệp tay (chạy script trước, đọc report):
- Report có
CONFLICTvà bạn muốn lấy remote → chạy lại--strategy pull(1 quyết định, không phải 3). - Branch remote KHÁC
version.json:branch→--branch <tên>(xem Step 2 để audit branch). - Cấu trúc
skills/cũ cần migrate (Step 3), hoặc cần upstream (đẩy lên) → dùng MANUAL STEPS bên dưới.
⚠ Bug đã fix:
health-check --updateđặt baseline = disk → sync KHÔNG phân biệt được "remote mới" vs "mình đã custom" → suýt ghi đè file custom. Script này dùng baseline riêngremote_synced(hash remote tại lần sync) nên phân biệt đúng. Đừng quay lại dùngpatterns(disk) làm baseline phân loại.
MANUAL STEPS (fallback — upstream, migrate cấu trúc cũ, hoặc debug)
Step 0: Pre-flight — health-check (chẩn đoán trước khi sync)
Chạy /health-check (python3 harness/scripts/health-check.py --root .) để biết NÊN sync hướng nào:
NEEDS-SYNC(behind/missing) → downstream (kéo về).DRIFT(đã sửa local) → upstream (đẩy lên) hoặc revert.OK→ không cần sync, dừng.
Step 1: Load Manifest
Read .template-manifest.json — inclusion list + remote URL.
Step 2: Fetch & Branch Audit
- CRITICAL: List all remote branches:
gh api repos/<owner>/<repo>/branches. - Check commit date per branch — don't assume
master/mainis newest. - Unclear → ask user which branch.
- Fetch via
gh api+curl— nogit clone.
Step 3: Detect Old Structure Migration
Check for old skills/ layout needing migration to llmwiki/:
# Signs of old structure:
[ -d "skills/" ] && [ ! -d "llmwiki/skills/" ] # old only
[ -d "skills/" ] && [ -d "llmwiki/skills/" ] # both exist → migration in progress
Old skills/ + new llmwiki/skills/ coexist:
- List
skills/(flat .md + subdirs:dev-loop/,wiki-loop/, etc.) - Map old → new:
skills/dev-loop/*.md→llmwiki/skills/dev-loop/*.mdskills/wiki-loop/*.md→llmwiki/skills/wiki-loop/*.mdskills/orchestrate/*.md→llmwiki/skills/orchestrate/*.mdskills/utils/*.md→llmwiki/skills/utils/*.mdskills/*.md(flat) → already covered by subdirs, skip duplicates
- Content matches → old stale, safe to remove.
- Show migration table → confirm before delete.
Step 4: Compare Manifest Files
diff local vs remote for each file in includes:
BASE="https://raw.githubusercontent.com/<owner>/<repo>/<branch>"
for file in <includes>; do
http_code=$(curl -s -o /dev/null -w "%{http_code}" "$BASE/$file")
# SAME / DIFF / MISSING / NEW / ABSENT
done
Status:
SAME— skipDIFF— content differsMISSING— remote only → downstream candidateNEW— local only → upstream candidateABSENT— neither
Step 5: Sync Plan
Show table. STOP → ask user: pull all / push all / specific files / direction per DIFF.
Step 6: Execute
- Downstream:
mkdir -p→curl -sfL <url> -o <local_path>→ updatewiki/log.md - Upstream: commit + push via
gh/git - File by file — no
cp -R
Step 6a/6b/8 đã GỘP vào
--full. Nếu bạn chạy FAST PATH--fullthì BỎ QUA 6a/6b/8 — script đã OKF-backfill + refresh fingerprint + verify + ghi log trong process. Các bước dưới chỉ dùng khi chạy MANUAL (debug / upstream / migrate cấu trúc cũ), không phải sau--full.
Step 6a: OKF backfill (MANUAL — --full đã làm)
Template/skill mới có thể nâng định dạng wiki (vd chuẩn OKF v0.1). Sau khi pull, convert mọi file content cũ còn dùng pseudo-frontmatter dạng bold **Type:** sang YAML frontmatter để khỏi vướng R9:
python3 harness/scripts/okf-check.py --check # exit 3 = có file chưa đạt OKF
python3 harness/scripts/okf-check.py --migrate # convert bold → YAML (chỉ THÊM frontmatter, giữ body/## Origin)
- Idempotent — file đã có
---frontmatter được bỏ qua. Reserved (index/log/README/decisions/_template…) tự miễn. - Sau migrate: chạy lại
--checkđến khiDAT CHUAN OKF v0.1, rồi cập nhật index/log như mọi thay đổi wiki.
Step 6b: Refresh version fingerprint (MANUAL — --full đã làm)
Nội dung pattern vừa đổi → cập nhật lại harness/version.json để health-check khỏi báo DRIFT giả:
python3 harness/scripts/health-check.py --update # KHÔNG --bump ở project con
--bump major|minor|patchCHỈ chạy ở repo templateRheinmir/setupkhi PHÁT HÀNH version pattern mới.- Upstream sync ở repo template: sau khi push, chạy
--update --bump <part>rồi commitharness/version.json.
Step 7: Install as Native Skills (runs every downstream sync)
Collect skill files synced (under llmwiki/skills/ in manifest). Skip: README.md, index.md, log.md, no-## Purpose/## Steps files.
A. Project-level (.claude/commands/ — this repo):
mkdir -p .claude/commands/
# Add description: frontmatter if missing, then copy
printf -- "---\ndescription: %s\n---\n\n" "$desc" | cat - <src> > .claude/commands/<name>.md
B. Global user-level (~/.claude/skills/<name>/SKILL.md — all projects):
mkdir -p ~/.claude/skills/<name>/
# Requires name: + description: frontmatter
printf -- "---\nname: %s\ndescription: %s\n---\n\n" "$name" "$desc" | cat - <src> > ~/.claude/skills/<name>/SKILL.md
C. Global slash command (~/.claude/commands/<name>.md):
printf -- "---\ndescription: %s\n---\n\n" "$desc" | cat - <src> > ~/.claude/commands/<name>.md
Install cả 3. Report:
| Skill | Project .claude/commands/ | ~/.claude/skills/ | ~/.claude/commands/ |
|----------------|---------------------------|-------------------|---------------------|
| propose | ✓ | ✓ | ✓ |
| ingest | ✓ | ✓ | ✓ |
| ... | ... | ... | ... |
Step 8: Verify & Finalize
for name in <skill-list>; do
[ -f ".claude/commands/$name.md" ] && echo "✓ proj $name" || echo "✗ proj $name"
[ -f "$HOME/.claude/skills/$name/SKILL.md" ] && echo "✓ global $name" || echo "✗ global $name"
done
Fix ✗ before done. No restart needed.
Agent Compatibility
| Agent | Run? | Reason |
|---|---|---|
| Claude Code | Yes | Full tool access |
| OpenCode | Yes | Full tool access |
| Antigravity | No | Sandbox blocks file/command tools |
Rules
- NEVER sync
.env, credentials, business docs. - ALWAYS audit remote branches — non-default may be newest.
- ALWAYS show diff for
[CONFLICT]→ wait for instruction. - NEVER
cp -R— file by file. - Step 3 every sync — detect old
skills/, offer migrate. - Step 7 every downstream sync — install all 3 Claude Code locations.
[NEW]: add to manifest BEFORE upstream commit.[MISSING]: add to manifest AFTER downstream copy.- Frontmatter:
name:+description:for skills;description:only for slash commands. - Skip
README.md,index.md,log.md, no-Purpose/Steps files.
Output Report
After all main skill tasks complete, write a propose draft to the wiki.
Steps
1. Build the filename:
- Format:
DDMMYY-<ten>.md DDMMYY= today (e.g.,020626for 2 June 2026)<ten>= 2–4 kebab-case words summarising what was done (e.g.,landing-page-coteccons,brand-kit-fintech,ingest-auth-spec)
2. Write llmwiki/wiki/sources/draft/DDMMYY-<ten>.md:
# DDMMYY-<ten>
**Type:** draft
**Status:** proposed
**Tags:** <skill-name>, output-report
**Proposed:** YYYY-MM-DD
## What
<One sentence — what this skill invocation produced or decided>
## Output
<Key artefacts, files created/modified, or decisions made>
## Files
| File | Action |
|------|--------|
| `path/to/file` | created / modified |
## Notes
- Invoked via: `/<skill-name>` skill
## Origin
- **Draft:** `wiki/sources/draft/DDMMYY-<ten>.md`
- **Commit:** _(filled by verify-before-commit)_
- **Date promoted:** _(filled by verify-before-commit)_
3. Update wiki index & log:
llmwiki/wiki/index.md— append one row:| [DDMMYY-<ten>](sources/draft/DDMMYY-<ten>.md) | draft | YYYY-MM-DD |llmwiki/wiki/log.md— append:## YYYY-MM-DD — <skill-name> — <ten>
Skip only when the skill produces zero artefacts and zero decisions (e.g., a pure display mode like
/caveman-stats).