sync

A command for synchronising shared coding-agent files between a source repository, templates, and projects. It follows different steps depending on the repository's role.

In plain words
What is it for?
Reviewing repository changes, distributing Python or Rust variants, updating downstream projects, and correcting or checking repository metadata before syncing.
Why use it?
It reduces manual copying and helps keep generated project files aligned with their source templates.

Command for Claude Code

Install

Getting it into your agent

One page per mod, every tool's command on it. A separate URL per tool would split the same page into five that compete with each other.

agentmods
npx agentmods add commands/terrene-foundation/metis/sync
Clone the repo
git clone --depth 1 https://github.com/terrene-foundation/metis

Made for: Claude Code.

Per session 21 Only the description is in the session, so the agent can decide to use it. The body loads when it is invoked.
When invoked 3,978 The whole file, excluding the scripts and references it only reads on demand.
Security scan D 2 findings. Scan, not verified.
Origin original No closer match found in the catalogue.
Token cost

What it costs to keep this loaded

Counted locally with the o200k_base tokenizer, which is exact for GPT models; Claude uses its own tokenizer and its counts differ. Treat this as one consistent yardstick across the catalogue rather than a bill. Prices are per million input tokens.

ModelPer sessionOnce invoked
Fable 5 $0.00021 $0.03978
Opus 5 $0.00010 $0.01989
Sonnet 5 $0.00004 $0.00796
Haiku 4.5 $0.00002 $0.00398

Measured 2d ago against content hash c355a7123d39, method: parsed. Prices are Anthropic first-party input rates as of 2026-08-30, from the pricing page.

Security

Grade D, and why

sync scanned grade D with 2 findings against 26 rules in 11 categories — prompt injection, anti-refusal, data exfiltration, privilege escalation, supply chain, agent snooping, system-prompt leakage, SSRF and excessive agency — measured 2d ago.

A static scan of the body, not an audit. Every finding is printed with the line that produced it so you can judge whether it matters here. A mod is markdown that instructs an agent; that is exactly why what it instructs is worth reading.

Reads agent configuration directoriesmediumAgent snooping

.claude/, .codex/, .gemini/ hold keys, settings and other credentials a mod has no legitimate need for.

2. **Read obsoleted list from the resolved template**: `cat "$RESOLVED_TEMPLATE_PATH/.claude/.coc-obsoleted"` (slim purpose-built file; emitted by coc-sync Step 4.5). Each non-comment, non-blank line is a repo-relative p

Recursive force deletehighDestructive command

rm -rf with a variable or a broad path is one typo away from removing the wrong tree.

rm -rf "./$path"
.claude/commands/sync.md · 180 lines

How it starts

The opening of the file, as written. The whole thing — 180 lines — stays where its author put it; the contents beside it link to each section on GitHub.

Sync CO/COC artifacts. Behavior depends on repo type (from .claude/VERSION).

Usage: /sync [target]

  • At loom/ (coc-source): target = py, rs, or all. If omitted, ask.
  • At downstream projects (coc-project): no target needed.

Step 0: Detect Repo Type

Read .claude/VERSIONtype field:

  • coc-source → Gate 1 + Gate 2 (below)
  • coc-project → Downstream Sync (next section)
  • coc-use-template / coc-buildMUST verify the repo is the actual template/BUILD repo before routing to loom. Check basename $(pwd) + git remote get-url origin (normalize SSH git@host:owner/repo.gitowner/repo) against known repos: kailash-coc-claude-{py,rs,rb,prism}, kailash-{py,rs,prism}. If match → "receives artifacts from loom/, run /sync at loom/". If no match → treat as coc-project and auto-correct VERSION in-place (type → coc-project, upstream → {template, template_repo, template_version, synced_at, sdk_packages} per .claude/hooks/lib/version-utils.js::correctTemplateDerivedVersion), then Downstream Sync.
  • Missing → ask user what type this repo is

Downstream Sync (coc-project repos)

Pull latest artifacts from the USE template repo. No target needed — reads template identity from VERSION.

Process:

  1. Resolve template (canonical resolver, v2.9.1+): node "$RESOLVED_TEMPLATE_PATH/.claude/bin/resolve-template.js" if a previous sync already exists locally, OR for first-time sync: node "$(npm root -g 2>/dev/null)/.../bin/resolve-template.js" is unavailable — instead, replicate the resolver inline. Resolution order:
    • Step 1KAILASH_COC_TEMPLATE_PATH env var. If set and contains .claude/, use it. Source: env-override.
    • Step 2 — Cache at ~/.cache/kailash-coc/<template>/. Auto-update via git -C <cache> fetch --depth 1 origin main && git -C <cache> reset --hard origin/main. Source: cache.
    • Step 3 — If no cache: git clone --depth 1 --single-branch --branch main https://github.com/<template_repo>.git ~/.cache/kailash-coc/<template>/. Source: cloned.
    • Step 4 (offline fallback only) — Local sibling at ../<template>/ or ~/repos/loom/<template>/. Used ONLY when steps 2-3 all fail (network unreachable). Source: sibling-offline-fallback. Emit a freshness NOT guaranteed notice.
    • If a local sibling is detected during online resolution but NOT used, emit one stderr notice telling the user to set KAILASH_COC_TEMPLATE_PATH if they meant to use it.
    • Known slugs: kailash-coc-claude-{py,rs,rb,prism} and the new multi-CLI kailash-coc-{py,rs} all live under terrene-foundation/.
    • NEVER use the legacy scripts/resolve-template.js shim — it was added to the manifest's obsoleted: list in v2.9.1 and is purged in step 3 below.
  2. Read obsoleted list from the resolved template: cat "$RESOLVED_TEMPLATE_PATH/.claude/.coc-obsoleted" (slim purpose-built file; emitted by coc-sync Step 4.5). Each non-comment, non-blank line is a repo-relative path; trailing slash means directory. If the file is missing, the template predates v2.9.1 — log a one-line warning, skip step 3, and proceed; the obsoleted purge will happen on the NEXT sync once the template upgrades.
  3. Purge obsoleted paths in this consumer (MUST, before any merge): For each entry in the obsoleted list:
    for path in <obsoleted-paths>; do
      if [ -e "./$path" ]; then
        rm -rf "./$path"
        echo "obsoleted: removed ./$path"
      fi
    done
    
    This is the ONLY mechanism by which downstream consumers purge stale orphan directories from former COC layouts. Skipping it leaves require("./lib/...") resolving against the wrong sibling and ships hooks that fail at every CC session start with MODULE_NOT_FOUND.
  4. Diff template's .claude/ against local — MUST diff EVERY child directory under .claude/, NOT only the COC-tier directories. Specifically the diff MUST include:
    • .claude/agents/**, .claude/commands/**, .claude/rules/**, .claude/skills/**, .claude/guides/** (the codegen-content tiers)
    • .claude/hooks/** — runtime enforcement scripts (canonical location since v2.9.1; required for SessionStart, PreToolUse, etc. to fire)
    • .claude/hooks/lib/** — sibling helper modules (workspace-utils.js, etc.) loaded via require("./lib/...") from hooks/*.js
    • .claude/bin/** — resolver + emitter binaries (resolve-template.js, emit.mjs); without these the resolver cannot run
    • .claude/.coc-obsoleted — the obsoleted-purge contract file itself (read in step 2; updates land here)
    • Top-level scripts/migrate.py and other items declared in the manifest's variant_only: block — these live OUTSIDE .claude/ but are part of the syncable set
    • NOT scripts/hooks/ or .claude/scripts/ — those are obsoleted (purged in step 3) and MUST NOT be re-emitted. BLOCKED rationalizations: "hooks/ are not codegen artifacts so the diff skips them" / "the manifest tiers section doesn't list hooks/**, so hooks aren't in the syncable set" / "the consumer's settings.json hooks paths are normalized in step 7, so the scripts arriving on disk is a separate concern". The .claude/hooks/ directory MUST physically exist on the consumer's disk for the normalized settings.json paths to resolve at runtime — hook-path normalization without hook-script delivery is a no-op that ships a broken session.
  5. Additive merge (same semantics as Gate 2 step 4):
    • Template files overwrite matching local files
    • Local-only files preserved (never deleted) except paths matching the manifest's obsoleted: list (handled in step 3 above)
    • NEVER overwritten (downstream-owned): CLAUDE.md, .claude/VERSION, .claude/settings.local.json, .env, .git/, .claude/.proposals/, .claude/learning/
    • Other exclusions: see sync-flow guide § "What downstream NEVER gets"
  6. Present merge plan with per-file decisions before applying — include the obsoleted-path deletions from step 3 in the plan output so the user sees exactly what's being removed.
  7. Normalize settings.json hook paths: scan the consumer's .claude/settings.json for any hooks[].command entry containing $CLAUDE_PROJECT_DIR/scripts/hooks/ and rewrite to $CLAUDE_PROJECT_DIR/.claude/hooks/. Stale references would still fail with MODULE_NOT_FOUND after step 3 deleted the directory.
  8. Verify hook paths in settings.json resolve on disk under .claude/hooks/ AND grep -F 'scripts/hooks' .claude/settings.json returns zero matches.
  9. Update .claude/VERSION in-place (never replace the file — only update specific fields): upstream.template_version ← template VERSION's version, upstream.template_repo ← resolved GitHub slug, upstream.synced_at ← now, upstream.sdk_packages ← from template. MUST preserve type: coc-project, upstream.template (name), and all other fields.
  10. Update SDK pins in pyproject.toml/Cargo.toml from template VERSION's upstream.sdk_packages
  11. Install: uv sync (py) or cargo check (rs) — MANDATORY
  12. Update .claude/.coc-sync-marker with timestamp + list of obsoleted paths purged in step 3 (audit trail for the migration)

Read the full file on GitHub · 180 lines

Changes

What this file has done since we first saw it

Hashed on every crawl. A supply-chain change to an agent config is a question of when, not whether, so the history is kept rather than the latest state alone.

  1. 2d ago First seen · 180 lines · 21 tokens per session scan D c355a7123d39

Subscribe to this mod's changes

sync is a command published in the GitHub repository terrene-foundation/metis (2 stars, last pushed 4mo ago), licensed Apache-2.0. It adds 21 tokens to every session and 3,978 once invoked, about $0.0001 per session on Opus 5. A static security scan graded it D with 2 findings (reads agent configuration directories, recursive force delete). No closer match exists in the catalogue, so it is treated as the original; first seen 2026-08-31.