Skip to content
Back to skills

Gz Agent Sync

ASecurity

Use after a skill or governance-surface change to regenerate the control surfaces and skill mirrors.

  • 9 stars
  • 0 votes
  • 0 copies
  • 1 view
  • Added October 19, 2026
ai-agentsrustgobashgit

Security analysis

A100/100

Scanned October 19, 2026

npx -y skills add tvproductions/gzkit --skill gz-agent-sync --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Gz Agent Sync?

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

Security grade badge for Gz Agent Sync
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/tvproductions-gz-agent-sync/badge)](https://www.skillsdirectory.com/skills/tvproductions-gz-agent-sync)

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

SKILL.md
---
name: gz-agent-sync
persona: main-session
description: Use after a skill or governance-surface change to regenerate the control surfaces and skill mirrors.
category: agent-operations
lifecycle_state: active
owner: gzkit-governance
last_reviewed: 2026-10-17
metadata:
  skill-version: "1.3.1"
model: haiku
---

# gz agent sync control-surfaces

## Overview

`gz agent sync control-surfaces` (`_run_agent_control_sync` in
`src/gzkit/commands/tidy.py`) regenerates every derived control surface from
canon through `sync_all` in `src/gzkit/sync_surfaces.py`:

- the manifest at `paths.manifest`, and the Codex baseline `.codex/config.toml`
  when it is missing or empty;
- when Codex is enabled, or `.gzkit.json` declares no vendors, `.codex/hooks.json`
  and `.codex/agents/*.toml` (see § Codex delivery);
- in gzkit's own repository only, the wheel copies under `src/gzkit/<surface>/`
  for skills, rules, personas, templates and canonical-class chores;
- `AGENTS.md`, played back byte-for-byte from its committed rendition, or
  bootstrapped from the `agents` template when none is committed. Sync never
  recomposes it: changing that canon goes through the content skills;
- when Claude is enabled, `CLAUDE.md`, the rules under `paths.claude_rules`,
  `.claude/settings.json` (gzkit hook phases merged into operator-added ones)
  and the Claude hook scripts;
- `.github/discovery-index.json` and the nested `AGENTS.md` files;
- skill mirrors at `paths.claude_skills` and `paths.codex_skills`, and persona
  mirrors under each enabled Claude and Codex `surface_root`. `vendor_skill_map`
  in `src/gzkit/sync_skills.py` is the authority for which vendors get a skill
  mirror; OpenCode has none.

A real run first runs the canonical preflight (`refuse_on_sync_blockers`,
`src/gzkit/commands/sync_guard.py`) and exits 1 before writing anything when a
canonical skill is corrupt: a missing `SKILL.md` or frontmatter, a bad
identity field, a malformed date, version or lifecycle value. A stale
`last_reviewed` never blocks (GHI #1099). After writing, it appends an
`agent_sync_completed` ledger event, then re-runs the skill audit and exits 1
if any blocking audit issue other than a stale review remains; the mirrors
are already written by then. Mirror copying only adds and updates files:
mirror-only paths are listed under "Recovery required" and left in place.

Every run prints an `Updated <path>` line for each surface that always
reports, such as the manifest, `AGENTS.md`, `CLAUDE.md`, settings, rules,
hooks and personas, whether its bytes changed or not. Skill mirror files are
listed only when they change.

`--dry-run` renders the same sync into a capture sink (`plan_sync_all`) and
writes nothing, the ledger included. It lists the same paths a real run would
report, not only the changed ones. It skips the preflight, so a plan it prints
can still be refused by the real run.

## Workflow

1. Edit canon only: `.gzkit/skills/`, `.gzkit/rules/`, `.gzkit/personas/`,
   `.gzkit/templates/`, `.gzkit/chores/`, `.gzkit/agents/`. Never edit a mirror
   or `src/gzkit/<surface>/`.
2. Preview with `uv run gz agent sync control-surfaces --dry-run`, then run it
   without the flag.
3. On a preflight refusal (exit 1, "Sync preflight failed"), fix each listed
   canonical skill, then run `uv run gz skill audit --json` and re-run the sync.
4. On a post-check failure (exit 1, "Sync post-check failed"), fix each listed
   error and re-sync.
5. When sync reports stale mirror-only paths, follow the recovery it prints:
   - `uv run gz skill audit --json`
   - remove the listed stale mirror-only paths
   - `uv run gz agent sync control-surfaces`
   - `uv run gz skill audit`
6. Report the exit code, the changed paths, and any recovery done.

## Validation

- `uv run gz validate --surfaces` reports no drift after the sync.
- `uv run gz skill audit` shows no mirror-parity error.

## Codex delivery

When Codex is enabled, sync recovers native `.codex/hooks.json` registrations in
projects carrying `scripts/session_orientation.py`, and renders registered
`.gzkit/agents/roles.json` role bodies into `.codex/agents/*.toml`. Edit the
canonical role body or `src/gzkit/hooks/codex.py` producer, then preview and sync.
Preserve operator-owned hooks and native role metadata. The generated hook status
labels identify owned handlers; customized unmarked role bodies remain user-owned.

Verify `uv run gz validate --surfaces --orientation-freshness`. This proves
delivery coherence, not native dispatch: Codex requires review of each new or
changed hook through `/hooks` before it runs. Report registration, trust, and
observed execution separately. The full parity design remains
`ADR-pool.vendor-alignment-codex`; syncing does not initiate its parked OBPIs.

## Common Rationalizations

These thoughts mean STOP — you are about to create canon/derived drift:

| Thought | Reality |
|---------|---------|
| "I edited `.claude/skills/foo/SKILL.md` directly — it's the runtime path anyway" | `.claude/` is a vendor mirror. The next sync overwrites it. Edit `.gzkit/skills/foo/SKILL.md` (canonical) and run sync. The instinct to edit the mirror is the bug. |
| "The mirrors look identical to canon — skip sync" | Only a sync regenerates the surfaces from canon, and running it on a synced tree changes no surface bytes. Skipping it after a skill edit leaves the drift in place. |
| "Sync will see my edit through the `skill-version` bump" | Sync copies canon bytes over every mirror and never compares versions; it only checks that the value is `X.Y.Z`. Bump the version anyway: `gz-skill-review` requires it, and it is how a reader tells the edit happened. |
| "Sync reported stale mirror-only paths — I'll deal with them next time" | Stale mirror paths mean the canonical source was deleted, renamed or retired. Leaving them means the old skill keeps loading. Run the recovery sequence now. |
| "I can skip `--dry-run`, this edit was small" | The dry-run lists every path the sync would report, before anything is written. It lists unchanged always-reported surfaces too, so read it for the unexpected paths. |
| "Manual copy from canonical to mirror is faster than sync" | Sync also writes the manifest, settings, hooks, nested `AGENTS.md` files and vendor-specific renderings. A manual copy gets the file and leaves the rest stale. |

## Red Flags

- Direct edits to any mirror: `.claude/`, `.agents/` (`paths.claude_skills`,
  `paths.codex_skills` and each vendor's `surface_root` in `.gzkit.json`), or
  `src/gzkit/<surface>/` in gzkit's own repository
- Skill edits without a `skill-version` bump
- Canonical files changed but the sync lists none of their mirrors (something
  is broken)
- Stale mirror-only paths reported and not cleaned up
- A mirror that differs from canon after a sync that exited 0
- Skipping sync because "the mirrors are fine"

## Example

```bash
uv run gz agent sync control-surfaces --dry-run
uv run gz agent sync control-surfaces
uv run gz validate --surfaces
```

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.