[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6C2EVP7YDJ379FZ8PS3FSGD":3,"skill-same:01M6C2EVP7YDJ379FZ8PS3FSGD":64},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":15,"categories":16,"keywords":17,"publishedAt":38,"linkOnly":39,"markdownContent":40,"markdownBody":41,"frontMatter":42,"refName":43,"commitSha":44,"skillDirectory":45,"forksCount":46,"repositoryHtmlUrl":47,"repositoryHomepageUrl":6,"ownerHtmlUrl":48,"ownerBlogUrl":6,"ownerDescription":6,"updatedAt":49,"install":50,"resources":63},"01M6C2EVP7YDJ379FZ8PS3FSGD","sync-live-config",null,"Judge and propagate drift between this repo's .claude\u002F.codex\u002Fhermes content and live agent-config directories (this machine's ~\u002F.claude, ~\u002F.codex, ~\u002F.hermes, and optionally remote hosts over SSH). Use when a fix may have been committed to this repo but not reached the live harness, or vice versa.","jleechanorg\u002Fjleechan-skills","jleechanorg","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F221404966?v=4","01M6C1VJ99XG950X1DWPEBCBGX","01M6C1VJDK5YVDNT3362RT5WSB",6,"MIT","https:\u002F\u002Fgithub.com\u002Fjleechanorg\u002Fjleechan-skills\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Fsync-live-config\u002FSKILL.md",[],[18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],"sync","sync live config","config","live","but","judge","hosts","drift","when","remote","machine","directories","content","hermes","use","ssh","fix","repo","codex","harness","2026-11-10 10:12:30",false,"---\nname: sync-live-config\ndescription: Judge and propagate drift between this repo's .claude\u002F.codex\u002Fhermes content and live agent-config directories (this machine's ~\u002F.claude, ~\u002F.codex, ~\u002F.hermes, and optionally remote hosts over SSH). Use when a fix may have been committed to this repo but not reached the live harness, or vice versa.\n---\n\n# Sync live config\n\nThis repo is normally a downstream **export** of live agent config — usually\n`~\u002F.claude\u002F` is the source of truth and the export script\n(`~\u002F.claude\u002Fcommands\u002Fexportcommands.sh`) pushes it here. But\nthat direction isn't guaranteed: a fix can land straight in this repo and\nnever flow back, or the live side can move on independently after the last\nexport. When both contain useful work, reconcile semantics in the canonical\nsource before choosing a propagation direction.\n\n**The script never decides direction. You do.** `scripts\u002Fsync_live_config.py`\nhas two subcommands:\n\n- `report [--full] [--remote HOST]... [--json] [--remote-only]` — gathers\n  evidence only, writes nothing. For every scoped file: `new` (missing live),\n  `modified`, or `ok`, plus the repo's last commit touching that path, and —\n  if the live path turns out to live inside its *own* distinct git repo (e.g.\n  `~\u002F.hermes` is its own checkout of a separate harness repository) — that repo's last commit on the\n  same path, plus a capped unified diff for small text files. The snippet is a\n  discovery aid, not complete review evidence: read both full files and create\n  a complete diff before deciding. It also reports\n  a **`live_only`** status: files present live but absent from the repo's\n  tracked scope, which a repo-only file scan would otherwise never see (this\n  is the exact shape of the `hermes\u002Fskills` rename\u002Fdelete drift below). Remote\n  targets get the same per-file commit\u002Fdiff enrichment as local **and** the\n  same `live_only` directory walk. A remote path with a symlinked component anywhere in it (leaf\n  or parent directory) reports status **`symlink`** instead, with hash\u002Fsize\u002F\n  commit\u002Fdiff all withheld — see \"Remote targets\" for why.\n- `apply --direction {repo-to-live,live-to-repo} --paths PATH [PATH ...] [--remote HOST] [--dry-run]`\n  — mechanically copies exactly the paths you name, in exactly the\n  direction you name. **`--dry-run` previews the whole decision without writing\n  anything**: per path it prints the exact source and destination absolutes,\n  whether the destination would be `CREATE`d, `OVERWRITE`n, is already `SAME`,\n  or why it would `FAIL`, with full hashes when available (`dst=missing` for\n  creates) — and exits non-zero if any path would fail\n  validation, so it doubles as a preflight. Reach for it before\n  every `apply`, especially a multi-path one. It refuses `--remote` rather than\n  silently previewing only the local half. No inference, no batch-wide default. Every path is\n  validated to resolve inside one of the allowed roots (`.claude\u002F`,\n  `.codex\u002Fhooks\u002F`, `hermes\u002Fskills\u002F` and their live counterparts) before\n  anything is touched — traversal, absolute paths, and symlink escapes are\n  rejected, since the paths applied here come from your own judgment calls\n  and should be checked like any other trust boundary.\n\n## Default vs full scope\n\n- **Default**: the README's `### Highlighted skills · left\u002Fright shift\n  strategy` table (currently `superpowers-quick`, `advice`, `web-advice`,\n  `redgreen`, `4layer`, `evidence-review`, `harness-engineering`), parsed\n  live from README.md — not a hardcoded, driftable list — plus any command\n  dispatcher `.md` that references one of those skills.\n- **`--full`**: every tracked file under `.claude\u002F`, `.codex\u002Fhooks\u002F`,\n  `hermes\u002Fskills\u002F`. Expect this to surface a lot more — go per-directory\n  first (see below), don't try to judge thousands of individual files.\n  Runtime\u002Fstate subtrees (`projects\u002F`, `state\u002F`, `venvs\u002F`, `node_modules\u002F`,\n  `plugins\u002F`, session and history dirs — see `RUNTIME_DIRS`) are pruned during\n  the walk: they are not syncable config, and `~\u002F.claude\u002Fprojects` alone is\n  ~72k files. Commit lookups are batched once per enclosing repo, so a full\n  report is minutes, not a hang. A run over ~3.5k tracked files yields ~5k\n  `live_only` rows; judge those per-directory, never row by row.\n\n## Protocol — this is where the judgment happens\n\n1. **Gather evidence, not conclusions.**\n   ```bash\n   python3 scripts\u002Fsync_live_config.py report --json [--full] [--remote HOST]\n   ```\n   Read the JSON yourself. Do not skip straight to `apply`.\n\n2. **Read the complete scoped source before judging drift.** `diff_snippet` is\n   capped and cannot establish that omitted parts agree. Re-pin the repository\n   commit and live target, read the full contents of each changed file, compare\n   complete diffs, and inspect linked companion files and live-only files in the\n   same scope. Use hashes as well as text; report filters and greps are only\n   prefilters.\n\n3. **Reconcile meaning before choosing direction.** For each file or tightly\n   related group, record which semantic units to keep, adapt or reject and why.\n   Preserve useful valid requirements from both copies. Do not default to the\n   repository or live copy, concatenate conflicting prose, or infer authority\n   from mtime or commit recency. Resolve conflicts through the active instruction hierarchy and each\n   rule’s declared scope and owner; preserve repository-specific requirements\n   within their domain. A canonical location establishes edit ownership, not\n   that useful installed changes are obsolete. Commit history and `live_repo_root` are\n   freshness evidence, never authority by themselves. Inspect scoped live-only files before deciding\n   whether they are intentional, renamed or disposable. When the hierarchy\n   resolves a conflict, make the smallest coherent best-of-both edit in the\n   canonical repository source before propagating it. Escalate only a genuine\n   unresolved owner, access or scope decision; state the exact conflict and\n   attempted routes. A `symlink` row is not a direction decision: inspect its\n   target owner, bytes and history read-only, retaining the automatic apply\n   refusal unless a separately verified canonical target is handled through an\n   authorized diff-first decision.\n\n4. **Account for report states per path.** `ok` needs no action. For `new` or\n   `modified`, inspect the full contents and relevant history. A missing live\n   path usually favors repo→live only after checking that the feature belongs\n   on that host. An independent `live_repo_root` calls for particular care but\n   does not decide direction. A `live_only` file has no repository history;\n   determine whether it is intentional, a rename or residue from its contents\n   and owner. Test caches and `.pytest_cache\u002F` artifacts are prefiltered, but\n   inspect other scoped files.\n\n5. **`hermes\u002Fskills\u002F` and `.claude\u002Fskills_archive\u002F` are known inversion\n   risks** (confirmed 2026-09-06: this repo's `hermes\u002Fskills\u002F` snapshot\n   traced entirely to a single stale 2026-08-01 `exportcommands.sh` push,\n   while live `~\u002F.hermes` — its own actively-committed repo — had moved on\n   for 5+ weeks; a blind repo→live `--full` there would have resurrected\n   already-renamed\u002Fdeleted content). For any diff under these paths: check\n   `live_repo_root`\u002F`live_last_commit` first, and default to *recommending\n   a fresh `exportcommands.sh` run* (live→repo) over silently pushing the old\n   snapshot down, unless the evidence clearly says otherwise.\n\n6. **Re-pin and prepare before every write.** Refresh the source commit and\n   hashes, destination hashes and working-tree state immediately before\n   applying. If any input changed, repeat the full comparison and judgment.\n   For each overwrite, preserve the exact destination bytes in configured\n   Scratch and record the backup path\u002Fhash; record an explicit missing\n   destination for a create. Run `apply --dry-run` for local writes and resolve\n   every result. For remote writes, where dry-run is refused, verify the\n   destination and reviewed backup through an authorized read-only route first.\n\n7. **Apply per decision, not per batch.** Once you've judged a file (or a\n   small consistent group of files with the same, clearly-justified\n   direction), apply exactly those paths:\n   ```bash\n   python3 scripts\u002Fsync_live_config.py apply --direction repo-to-live --paths \u003Cpath> [\u003Cpath> ...]\n   python3 scripts\u002Fsync_live_config.py apply --direction live-to-repo --paths \u003Cpath> [\u003Cpath> ...] --remote \u003Cssh-host>\n   ```\n   Never run `apply` over an entire report's file list without having\n   individually judged each one.\n\n8. **Verify and report.** Read every destination back from its target host,\n   compute its SHA256 and compare it with the reconciled source bytes. Report\n   each path's keep\u002Fadapt\u002Freject decisions, source and destination hashes,\n   direction (or \"skipped — unresolved conflict\"), reason and whether it was\n   applied. A successful copy command alone does not prove synchronization.\n\n9. **Never delete.** Applying in either direction only adds\u002Foverwrites the\n   destination file; it never removes anything that exists only on one\n   side.\n\n## Remote targets\n\n`report --remote HOST` resolves the remote `$HOME` once, then runs a single\nbatched script over SSH that returns, per path, its hash, enclosing-repo last\ncommit, and (for files under the diff-snippet size cap) base64 content so a\nreal unified diff can be computed locally — the per-file judgment inputs\nmatch local, including the `live_only` directory walk (files present live but\nnever repo-tracked), which now runs against the remote host too — so a\nremote-side rename\u002Fdelete drift (the `hermes\u002Fskills` incident shape) is\nvisible on a remote target, not just locally. The remote walk honours the same\nnoise filters and reports a symlinked path as `symlink` with all metadata\nwithheld, exactly like the tracked-file pass.\n\nIf that walk fails on a host, `report` prints a `warning: remote live_only scan\nincomplete on \u003Chost>` line to stderr and still returns the tracked-file\nresults. A bare clean remote result therefore means \"no drift in the\ntracked-file scope\"; check for that warning before reading it as \"no drift at\nall.\" `apply --remote HOST` transfers only the files you named:\n`tar`+`scp`+remote-extract for repo-to-live, or a guard-checked remote `cat`\nfor live-to-repo (see below — this is not a bare `ssh ... cat`).\nDestination paths are always fully resolved in Python before being sent to\nthe remote shell — never left for the remote side to expand a `$HOME`-style\nvariable itself. The remote batch script uses portable primitives: a\n`sha256sum`-with-`shasum -a 256`-fallback for hashing, and `git -C \"$dir\" log\n-- \"$p\"` (letting git resolve the pathspec itself against the absolute path)\nfor the commit lookup instead of manually reconstructing a relative path —\nboth an earlier `realpath --relative-to` version (GNU-only) and its\nreplacement prefix-strip silently dropped commit metadata whenever `$HOME` or\nany path component was a symlink.\n\n**Symlink handling is asymmetric between local and remote, by design and\nverified in review, not accidentally uniform:**\n- **Remote** (both `report`'s evidence gathering and both `apply`\n  directions) walks every path component between the mapped root and the\n  target through a shared bash function and refuses the operation entirely\n  if *any* component is a symlink — including the leaf. A symlinked remote\n  path shows up in `report` as status `symlink`, with hash\u002Fsize\u002Fcommit\u002Fdiff\n  all withheld (an earlier version withheld only file content, which still\n  let a symlinked path's exact hash and size leak as a confirmation oracle\n  for an arbitrary file elsewhere on the host).\n- **Local** (`live_abs_for`\u002F`repo_abs_for`) resolves the full path and checks\n  that the result stays within the *specific* mapped root (e.g.\n  `home\u002F.claude`), which blocks escaping that root but does **not** walk\n  component-by-component — a symlink whose target is still inside the same\n  mapped root (e.g. `.claude\u002Fskills\u002Ffoo\u002FSKILL.md -> .claude\u002Fsettings.json`)\n  is allowed through. This is intentionally less strict locally than\n  remotely; see \"Accepted residual risks\" below.\n\n## Bootstrapping on a machine that has never run this before\n\n`\u002Fsync-live-config` is a thin dispatcher pointing at\n`${CLAUDE_HOME:-$HOME\u002F.claude}\u002Fskills\u002Fsync-live-config\u002FSKILL.md` — on a\nmachine where this skill has never been synced, that path doesn't exist yet\nand the slash command can't resolve. The first sync on a new machine must be\ndone by running the script directly from a repo checkout:\n`python3 scripts\u002Fsync_live_config.py report` — once this skill itself is\nincluded in whatever scope you sync, the slash command becomes available for\nevery subsequent run.\n\n## Accepted residual risks\n\nThis tool operates on the caller's own `$HOME` under their own account — it\nis not designed to defend against an adversary who already has local write\naccess to that account. Two known gaps are accepted rather than chased\nfurther, both discussed and agreed in review:\n\n- **A symlinked check-then-write TOCTOU window.** Every containment check\n  resolves symlinks and then performs a normal `open`\u002F`cp`; a symlink\n  swapped in between the check and the write would be followed. Closing this\n  properly needs `O_NOFOLLOW`\u002F`dir_fd`-relative opens, which is disproportionate\n  for a single-user tool that only ever targets its own account.\n- **The top-level mapped root itself being a symlink.** Containment is\n  checked against `home\u002F.claude` (etc.) *as resolved* — if `~\u002F.claude` itself\n  is a symlink to some other location (a real, common dotfiles pattern),\n  everything computed relative to it is still \"relative to\" that resolved\n  root, so operations transparently follow it. This is indistinguishable\n  from the legitimate case without asking the operator, and this repo\n  explicitly wants to support \"my `~\u002F.claude` is symlinked to my dotfiles\n  repo\" as normal, not broken.\n","# Sync live config\n\nThis repo is normally a downstream **export** of live agent config — usually\n`~\u002F.claude\u002F` is the source of truth and the export script\n(`~\u002F.claude\u002Fcommands\u002Fexportcommands.sh`) pushes it here. But\nthat direction isn't guaranteed: a fix can land straight in this repo and\nnever flow back, or the live side can move on independently after the last\nexport. When both contain useful work, reconcile semantics in the canonical\nsource before choosing a propagation direction.\n\n**The script never decides direction. You do.** `scripts\u002Fsync_live_config.py`\nhas two subcommands:\n\n- `report [--full] [--remote HOST]... [--json] [--remote-only]` — gathers\n  evidence only, writes nothing. For every scoped file: `new` (missing live),\n  `modified`, or `ok`, plus the repo's last commit touching that path, and —\n  if the live path turns out to live inside its *own* distinct git repo (e.g.\n  `~\u002F.hermes` is its own checkout of a separate harness repository) — that repo's last commit on the\n  same path, plus a capped unified diff for small text files. The snippet is a\n  discovery aid, not complete review evidence: read both full files and create\n  a complete diff before deciding. It also reports\n  a **`live_only`** status: files present live but absent from the repo's\n  tracked scope, which a repo-only file scan would otherwise never see (this\n  is the exact shape of the `hermes\u002Fskills` rename\u002Fdelete drift below). Remote\n  targets get the same per-file commit\u002Fdiff enrichment as local **and** the\n  same `live_only` directory walk. A remote path with a symlinked component anywhere in it (leaf\n  or parent directory) reports status **`symlink`** instead, with hash\u002Fsize\u002F\n  commit\u002Fdiff all withheld — see \"Remote targets\" for why.\n- `apply --direction {repo-to-live,live-to-repo} --paths PATH [PATH ...] [--remote HOST] [--dry-run]`\n  — mechanically copies exactly the paths you name, in exactly the\n  direction you name. **`--dry-run` previews the whole decision without writing\n  anything**: per path it prints the exact source and destination absolutes,\n  whether the destination would be `CREATE`d, `OVERWRITE`n, is already `SAME`,\n  or why it would `FAIL`, with full hashes when available (`dst=missing` for\n  creates) — and exits non-zero if any path would fail\n  validation, so it doubles as a preflight. Reach for it before\n  every `apply`, especially a multi-path one. It refuses `--remote` rather than\n  silently previewing only the local half. No inference, no batch-wide default. Every path is\n  validated to resolve inside one of the allowed roots (`.claude\u002F`,\n  `.codex\u002Fhooks\u002F`, `hermes\u002Fskills\u002F` and their live counterparts) before\n  anything is touched — traversal, absolute paths, and symlink escapes are\n  rejected, since the paths applied here come from your own judgment calls\n  and should be checked like any other trust boundary.\n\n## Default vs full scope\n\n- **Default**: the README's `### Highlighted skills · left\u002Fright shift\n  strategy` table (currently `superpowers-quick`, `advice`, `web-advice`,\n  `redgreen`, `4layer`, `evidence-review`, `harness-engineering`), parsed\n  live from README.md — not a hardcoded, driftable list — plus any command\n  dispatcher `.md` that references one of those skills.\n- **`--full`**: every tracked file under `.claude\u002F`, `.codex\u002Fhooks\u002F`,\n  `hermes\u002Fskills\u002F`. Expect this to surface a lot more — go per-directory\n  first (see below), don't try to judge thousands of individual files.\n  Runtime\u002Fstate subtrees (`projects\u002F`, `state\u002F`, `venvs\u002F`, `node_modules\u002F`,\n  `plugins\u002F`, session and history dirs — see `RUNTIME_DIRS`) are pruned during\n  the walk: they are not syncable config, and `~\u002F.claude\u002Fprojects` alone is\n  ~72k files. Commit lookups are batched once per enclosing repo, so a full\n  report is minutes, not a hang. A run over ~3.5k tracked files yields ~5k\n  `live_only` rows; judge those per-directory, never row by row.\n\n## Protocol — this is where the judgment happens\n\n1. **Gather evidence, not conclusions.**\n   ```bash\n   python3 scripts\u002Fsync_live_config.py report --json [--full] [--remote HOST]\n   ```\n   Read the JSON yourself. Do not skip straight to `apply`.\n\n2. **Read the complete scoped source before judging drift.** `diff_snippet` is\n   capped and cannot establish that omitted parts agree. Re-pin the repository\n   commit and live target, read the full contents of each changed file, compare\n   complete diffs, and inspect linked companion files and live-only files in the\n   same scope. Use hashes as well as text; report filters and greps are only\n   prefilters.\n\n3. **Reconcile meaning before choosing direction.** For each file or tightly\n   related group, record which semantic units to keep, adapt or reject and why.\n   Preserve useful valid requirements from both copies. Do not default to the\n   repository or live copy, concatenate conflicting prose, or infer authority\n   from mtime or commit recency. Resolve conflicts through the active instruction hierarchy and each\n   rule’s declared scope and owner; preserve repository-specific requirements\n   within their domain. A canonical location establishes edit ownership, not\n   that useful installed changes are obsolete. Commit history and `live_repo_root` are\n   freshness evidence, never authority by themselves. Inspect scoped live-only files before deciding\n   whether they are intentional, renamed or disposable. When the hierarchy\n   resolves a conflict, make the smallest coherent best-of-both edit in the\n   canonical repository source before propagating it. Escalate only a genuine\n   unresolved owner, access or scope decision; state the exact conflict and\n   attempted routes. A `symlink` row is not a direction decision: inspect its\n   target owner, bytes and history read-only, retaining the automatic apply\n   refusal unless a separately verified canonical target is handled through an\n   authorized diff-first decision.\n\n4. **Account for report states per path.** `ok` needs no action. For `new` or\n   `modified`, inspect the full contents and relevant history. A missing live\n   path usually favors repo→live only after checking that the feature belongs\n   on that host. An independent `live_repo_root` calls for particular care but\n   does not decide direction. A `live_only` file has no repository history;\n   determine whether it is intentional, a rename or residue from its contents\n   and owner. Test caches and `.pytest_cache\u002F` artifacts are prefiltered, but\n   inspect other scoped files.\n\n5. **`hermes\u002Fskills\u002F` and `.claude\u002Fskills_archive\u002F` are known inversion\n   risks** (confirmed 2026-09-06: this repo's `hermes\u002Fskills\u002F` snapshot\n   traced entirely to a single stale 2026-08-01 `exportcommands.sh` push,\n   while live `~\u002F.hermes` — its own actively-committed repo — had moved on\n   for 5+ weeks; a blind repo→live `--full` there would have resurrected\n   already-renamed\u002Fdeleted content). For any diff under these paths: check\n   `live_repo_root`\u002F`live_last_commit` first, and default to *recommending\n   a fresh `exportcommands.sh` run* (live→repo) over silently pushing the old\n   snapshot down, unless the evidence clearly says otherwise.\n\n6. **Re-pin and prepare before every write.** Refresh the source commit and\n   hashes, destination hashes and working-tree state immediately before\n   applying. If any input changed, repeat the full comparison and judgment.\n   For each overwrite, preserve the exact destination bytes in configured\n   Scratch and record the backup path\u002Fhash; record an explicit missing\n   destination for a create. Run `apply --dry-run` for local writes and resolve\n   every result. For remote writes, where dry-run is refused, verify the\n   destination and reviewed backup through an authorized read-only route first.\n\n7. **Apply per decision, not per batch.** Once you've judged a file (or a\n   small consistent group of files with the same, clearly-justified\n   direction), apply exactly those paths:\n   ```bash\n   python3 scripts\u002Fsync_live_config.py apply --direction repo-to-live --paths \u003Cpath> [\u003Cpath> ...]\n   python3 scripts\u002Fsync_live_config.py apply --direction live-to-repo --paths \u003Cpath> [\u003Cpath> ...] --remote \u003Cssh-host>\n   ```\n   Never run `apply` over an entire report's file list without having\n   individually judged each one.\n\n8. **Verify and report.** Read every destination back from its target host,\n   compute its SHA256 and compare it with the reconciled source bytes. Report\n   each path's keep\u002Fadapt\u002Freject decisions, source and destination hashes,\n   direction (or \"skipped — unresolved conflict\"), reason and whether it was\n   applied. A successful copy command alone does not prove synchronization.\n\n9. **Never delete.** Applying in either direction only adds\u002Foverwrites the\n   destination file; it never removes anything that exists only on one\n   side.\n\n## Remote targets\n\n`report --remote HOST` resolves the remote `$HOME` once, then runs a single\nbatched script over SSH that returns, per path, its hash, enclosing-repo last\ncommit, and (for files under the diff-snippet size cap) base64 content so a\nreal unified diff can be computed locally — the per-file judgment inputs\nmatch local, including the `live_only` directory walk (files present live but\nnever repo-tracked), which now runs against the remote host too — so a\nremote-side rename\u002Fdelete drift (the `hermes\u002Fskills` incident shape) is\nvisible on a remote target, not just locally. The remote walk honours the same\nnoise filters and reports a symlinked path as `symlink` with all metadata\nwithheld, exactly like the tracked-file pass.\n\nIf that walk fails on a host, `report` prints a `warning: remote live_only scan\nincomplete on \u003Chost>` line to stderr and still returns the tracked-file\nresults. A bare clean remote result therefore means \"no drift in the\ntracked-file scope\"; check for that warning before reading it as \"no drift at\nall.\" `apply --remote HOST` transfers only the files you named:\n`tar`+`scp`+remote-extract for repo-to-live, or a guard-checked remote `cat`\nfor live-to-repo (see below — this is not a bare `ssh ... cat`).\nDestination paths are always fully resolved in Python before being sent to\nthe remote shell — never left for the remote side to expand a `$HOME`-style\nvariable itself. The remote batch script uses portable primitives: a\n`sha256sum`-with-`shasum -a 256`-fallback for hashing, and `git -C \"$dir\" log\n-- \"$p\"` (letting git resolve the pathspec itself against the absolute path)\nfor the commit lookup instead of manually reconstructing a relative path —\nboth an earlier `realpath --relative-to` version (GNU-only) and its\nreplacement prefix-strip silently dropped commit metadata whenever `$HOME` or\nany path component was a symlink.\n\n**Symlink handling is asymmetric between local and remote, by design and\nverified in review, not accidentally uniform:**\n- **Remote** (both `report`'s evidence gathering and both `apply`\n  directions) walks every path component between the mapped root and the\n  target through a shared bash function and refuses the operation entirely\n  if *any* component is a symlink — including the leaf. A symlinked remote\n  path shows up in `report` as status `symlink`, with hash\u002Fsize\u002Fcommit\u002Fdiff\n  all withheld (an earlier version withheld only file content, which still\n  let a symlinked path's exact hash and size leak as a confirmation oracle\n  for an arbitrary file elsewhere on the host).\n- **Local** (`live_abs_for`\u002F`repo_abs_for`) resolves the full path and checks\n  that the result stays within the *specific* mapped root (e.g.\n  `home\u002F.claude`), which blocks escaping that root but does **not** walk\n  component-by-component — a symlink whose target is still inside the same\n  mapped root (e.g. `.claude\u002Fskills\u002Ffoo\u002FSKILL.md -> .claude\u002Fsettings.json`)\n  is allowed through. This is intentionally less strict locally than\n  remotely; see \"Accepted residual risks\" below.\n\n## Bootstrapping on a machine that has never run this before\n\n`\u002Fsync-live-config` is a thin dispatcher pointing at\n`${CLAUDE_HOME:-$HOME\u002F.claude}\u002Fskills\u002Fsync-live-config\u002FSKILL.md` — on a\nmachine where this skill has never been synced, that path doesn't exist yet\nand the slash command can't resolve. The first sync on a new machine must be\ndone by running the script directly from a repo checkout:\n`python3 scripts\u002Fsync_live_config.py report` — once this skill itself is\nincluded in whatever scope you sync, the slash command becomes available for\nevery subsequent run.\n\n## Accepted residual risks\n\nThis tool operates on the caller's own `$HOME` under their own account — it\nis not designed to defend against an adversary who already has local write\naccess to that account. Two known gaps are accepted rather than chased\nfurther, both discussed and agreed in review:\n\n- **A symlinked check-then-write TOCTOU window.** Every containment check\n  resolves symlinks and then performs a normal `open`\u002F`cp`; a symlink\n  swapped in between the check and the write would be followed. Closing this\n  properly needs `O_NOFOLLOW`\u002F`dir_fd`-relative opens, which is disproportionate\n  for a single-user tool that only ever targets its own account.\n- **The top-level mapped root itself being a symlink.** Containment is\n  checked against `home\u002F.claude` (etc.) *as resolved* — if `~\u002F.claude` itself\n  is a symlink to some other location (a real, common dotfiles pattern),\n  everything computed relative to it is still \"relative to\" that resolved\n  root, so operations transparently follow it. This is indistinguishable\n  from the legitimate case without asking the operator, and this repo\n  explicitly wants to support \"my `~\u002F.claude` is symlinked to my dotfiles\n  repo\" as normal, not broken.\n",{"name":5,"description":7},"main","38dcf4c6273c10908c805d3a34e24e62fcf0966c",".claude\u002Fskills\u002Fsync-live-config",0,"https:\u002F\u002Fgithub.com\u002Fjleechanorg\u002Fjleechan-skills","https:\u002F\u002Fgithub.com\u002Fjleechanorg","2026-11-11 22:19:36",{"source":8,"skillName":5,"commands":51,"prompt":61,"zipAvailable":62},[52,55,58],{"tool":53,"command":54},"npx","npx skills add jleechanorg\u002Fjleechan-skills --skill sync-live-config",{"tool":56,"command":57},"bunx","bunx skills add jleechanorg\u002Fjleechan-skills --skill sync-live-config",{"tool":59,"command":60},"pnpm","pnpm dlx skills add jleechanorg\u002Fjleechan-skills --skill sync-live-config","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fjleechanorg\u002Fjleechan-skills\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Fsync-live-config\u002FSKILL.md",true,[],[65,81,103,117,131,146],{"skillNo":66,"name":67,"nameZh":6,"description":68,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":69,"categories":70,"keywords":71,"publishedAt":38},"01M716Y5MTJ6GYJZ2ATXCJK8G4","instinct","Use when the user invokes \u002Finstinct or \u002Fin, or asks to \"message Instinct\", \"ask Instinct\", \"tell Instinct\", \"check Instinct\", or read replies from the configured peer assistant. iMessage first, WhatsApp Web as fallback.","https:\u002F\u002Fgithub.com\u002Fjleechanorg\u002Fjleechan-skills\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Finstinct\u002FSKILL.md",[],[67,72,26,73,74,32,75,76,77,78,79,80],"user","replies","check","identity","whatsapp","gmail","read","message","ask",{"skillNo":82,"name":83,"nameZh":6,"description":84,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":85,"categories":86,"keywords":92,"publishedAt":38},"01M716Y4HF7FVVMJSA2CCVN5VF","hr","Compatibility alias for history-resume; produce the same fresh-state, provenance-aware resume briefing.","https:\u002F\u002Fgithub.com\u002Fjleechanorg\u002Fjleechan-skills\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Fhr\u002FSKILL.md",[87],{"categoryNo":88,"categoryName":89,"taxonomyType":90,"taxonomyTypeDesc":91},"01JBSEEDCAT000000000000038","人力资源","PROFESSION","适用职业",[83,93,94,95,96,97,98,99,100,101,102],"resume","compatibility","provenance","for","history","produce","alias","briefing","state","fresh",{"skillNo":104,"name":105,"nameZh":6,"description":106,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":107,"categories":108,"keywords":110,"publishedAt":38},"01M716Y1FFNFKFJYYKF8HQA6T8","history-resume","Resume briefing for the current repository branch or worktree using fresh state and admitted history sources.","https:\u002F\u002Fgithub.com\u002Fjleechanorg\u002Fjleechan-skills\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Fhistory-resume\u002FSKILL.md",[109],{"categoryNo":88,"categoryName":89,"taxonomyType":90,"taxonomyTypeDesc":91},[97,93,111,112,72,113,100,114,96,115,116,101,102],"history resume","branch","analysis","repository","worktree","sources",{"skillNo":118,"name":119,"nameZh":6,"description":120,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":121,"categories":122,"keywords":123,"publishedAt":38},"01M716XWXJ8EPHK4RH9T14TR85","grok","Alias for the canonical grokbot browser conversation workflow; \u002Fgrok talks to the Grok bot the same way \u002Fdot talks to Dot.","https:\u002F\u002Fgithub.com\u002Fjleechanorg\u002Fjleechan-skills\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Fgrok\u002FSKILL.md",[],[119,124,125,126,96,127,99,128,129,130],"dot","bot","workflow","canonical","conversation","browser","grokbot",{"skillNo":132,"name":133,"nameZh":6,"description":134,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":135,"categories":136,"keywords":137,"publishedAt":38},"01M70N9Q07DTE0EW5KFXMMMSJ0","codexa-bench","Compare `codexa` and normal `codex` on a fair split of comparable work by default; use `--strict` for duplicate runs of the exact same task.","https:\u002F\u002Fgithub.com\u002Fjleechanorg\u002Fjleechan-skills\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Fcodexa-bench\u002FSKILL.md",[],[138,139,140,32,141,96,142,143,144,145,36],"codexa bench","work","split","default","duplicate","task","compare","normal",{"skillNo":147,"name":148,"nameZh":6,"description":149,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":150,"licenseFileUrl":151,"sourceHtmlUrl":152,"categories":153,"keywords":165,"publishedAt":38},"01M6C24S2X60SP8BBFGAEKPEGW","frontend-design","Create distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, artifacts, posters, or applications (examples include websites, landing pages, dashboards, React components, HTML\u002FCSS layouts, or when styling\u002Fbeautifying any web UI). Generates creative, polished code and UI design that avoids generic AI aesthetics.","Apache-2.0","https:\u002F\u002Fgithub.com\u002Fjleechanorg\u002Fjleechan-skills\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Ffrontend-design\u002FLICENSE.txt","https:\u002F\u002Fgithub.com\u002Fjleechanorg\u002Fjleechan-skills\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Ffrontend-design\u002FSKILL.md",[154,159,162],{"categoryNo":155,"categoryName":156,"taxonomyType":157,"taxonomyTypeDesc":158},"01JBSEEDCAT000000000000009","前端开发","SCENARIO","使用场景",{"categoryNo":160,"categoryName":161,"taxonomyType":157,"taxonomyTypeDesc":158},"01JBSEEDCAT000000000000015","视觉设计",{"categoryNo":163,"categoryName":164,"taxonomyType":90,"taxonomyTypeDesc":91},"01JBSEEDCAT000000000000032","设计师",[166,167,168,32,169,170,171,72,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,26,190],"frontend","design","frontend design","generic","ui design","react","html","components","code","artifacts","ui","aesthetics","Production","web components","landing","applications","quality","web","css","create","examples","with","react components","web ui","pages"]