2 Commits

Author SHA1 Message Date
root
357dd10670 SKILL.md sync: reject isolated edits to the .agents/ copy
Diego asked the right question: what if someone edits the Codex
side directly? Until now the sync was unidirectional (root →
.agents/) but the hook only fired when root SKILL.md was staged —
isolated .agents/ edits sneaked past the hook locally and only got
caught by CI's --check. A future ``make sync-skill`` would then
silently destroy them.

Hardened both layers to reject the asymmetric case at the moment
of the commit/PR:

- Pre-commit hook now classifies the staged set and REJECTS
  commits that stage .agents/skills/.../SKILL.md in isolation,
  with a step-by-step message: move the edit into root SKILL.md
  and re-stage. The hook still auto-syncs when root SKILL.md is
  staged.

- CI gate adds a second step (PR-only) that diffs the PR's base
  against head; if .agents/ moved but root SKILL.md didn't, fails
  with an actionable error before the build proceeds.

- README documents the direction explicitly: edits land in root
  SKILL.md; .agents/ is auto-generated; Codex-specific instructions
  belong in AGENTS.md, not in the SKILL.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-25 23:00:51 -03:00
root
fba2d23d5d SKILL.md sync: pre-commit hook + CI gate + make install-hooks
Three-layer defense to keep root SKILL.md (Claude Code) and
.agents/skills/oci-deal-accelerator/SKILL.md (Codex) byte-aligned.
Without this, Claude Code and Codex can drift and give the user
contradictory instructions — exactly the failure mode that produced
the workload-driven-mode incident on 2026-04-25.

Layers (least → most enforcement):

1. Local pre-commit hook (.githooks/pre-commit, opt-in via
   ``make install-hooks`` which sets core.hooksPath). When SKILL.md
   is staged, auto-runs scripts/sync-skill.py and stages the
   regenerated .agents/ copy in the same commit. Idempotent.

2. ``make install-hooks`` target + a tip line in ``make venv``'s
   output so any new clone discovers the hook setup.

3. CI gate (.gitea/workflows/skill-sync.yaml) on every push/PR
   touching SKILL.md or the .agents/ copy. Runs
   ``scripts/sync-skill.py --check`` and fails the build on drift.
   Catches anyone who skipped the hook.

README documents the rationale and the three layers.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-25 22:58:33 -03:00