Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions .claude-config/bin/verify-ops-selftest.sh
Original file line number Diff line number Diff line change
Expand Up @@ -422,6 +422,24 @@ ln -s "$HOME/pool-removed" "$HOME/.claude/projects/-gone/memory"
run check_memory_links
chk "dangling memory link -> WARN naming memory-init" "$([ "$WARNS" = 1 ] && printf '%s' "$OUT" | grep -q -- '-gone' && printf '%s' "$OUT" | grep -q 'memory-init'; echo $?)"

# 26. SKILLS/synced (Claude Code's claude.ai skill sync) is gitignored and not an OPS skill: the
# index check skips it, and a copy already committed WARNs with the untrack command.
new_case skills-synced
mkdir -p "$OPS/SKILLS/synced/org-skill"
printf -- '---\nname: org-skill\n---\n' > "$OPS/SKILLS/synced/org-skill/SKILL.md"
cp "$SRC_OPS/.gitignore" "$OPS/.gitignore"
# The index check is a substring match and the shipped README says "un-synced"; reword it so
# only the skip, not that word, can keep the synced dir out of the index.
sed -i 's/synced/sync-ed/g' "$OPS/SKILLS/README.md"
git -C "$OPS" init -q
run check_skills_index
chk "untracked synced dir -> no WARN" "$([ "$WARNS" = 0 ]; echo $?)"
chk "the shipped .gitignore ignores SKILLS/synced" "$(git -C "$OPS" check-ignore -q SKILLS/synced/org-skill/SKILL.md; echo $?)"
git -C "$OPS" add -f SKILLS/synced/org-skill/SKILL.md
git -C "$OPS" -c user.name=selftest -c user.email=selftest@example.invalid commit -q -m fixture
run check_skills_index
chk "committed synced dir -> WARN with the untrack command" "$([ "$WARNS" = 1 ] && printf '%s' "$OUT" | grep -q 'rm -r --cached --quiet SKILLS/synced'; echo $?)"

if [ "$fails" -eq 0 ]; then
echo "verify-ops-selftest: all cases pass"
exit 0
Expand Down
7 changes: 6 additions & 1 deletion .claude-config/bin/verify-ops.sh
Original file line number Diff line number Diff line change
Expand Up @@ -151,14 +151,19 @@ check_secrets() {
fi
}

# 9. SKILLS/README index covers every skill dir.
# 9. SKILLS/README index covers every skill dir. SKILLS/synced is Claude Code's claude.ai skill
# sync (gitignored), not an OPS skill; a copy already committed is flagged so the owner untracks it.
check_skills_index() {
local missing=""
for d in "$OPS"/SKILLS/*/; do
local b; b="$(basename "$d")"
[ "$b" = synced ] && continue
grep -q "$b" "$OPS/SKILLS/README.md" || missing="$missing $b"
done
[ -z "$missing" ] && ok "SKILLS README indexes all entries" || warn "skills absent from SKILLS/README.md index:$missing"
if [ -n "$(git -C "$OPS" ls-files -- SKILLS/synced 2>/dev/null | head -1)" ]; then
warn "SKILLS/synced is tracked: claude.ai org skills are committed to this repo; untrack them with: git -C \"$OPS\" rm -r --cached --quiet SKILLS/synced && git -C \"$OPS\" commit -m 'chore(skills): stop tracking synced org skills'"
fi
}

# 10. projects-map covers every repo dir under every org cluster.
Expand Down
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ desktop.ini
# skills-vendor.sh staging dirs: an interrupted sync leaves one, and the next
# sync cleans it; until then the daily backup must not commit a mirror copy.
SKILLS/.vendor.*/
# Claude Code syncs claude.ai org and Anthropic skills into ~/.claude/skills/synced, and
# deploy.sh links ~/.claude/skills to SKILLS/. Those skills belong to the org and refresh at
# every session start; the daily backup's `git add -A` would commit them into this repo.
SKILLS/synced/

# --- PROJECTS: repo subdirs (2nd-level) are their own repos (ignored).
# Cluster folders (1st-level: ExampleOrg/, AnotherOrg/, etc.)
Expand Down
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,16 @@ Notable changes to OPS, newest first. Format: the date, then what changed and wh
matters. This file starts fresh at the public release; the harness's private
prehistory is deliberately not part of it.

## 2026-11-05: synced org skills stay out of your OPS repo

Claude Code syncs claude.ai org and Anthropic skills into `~/.claude/skills/synced`, and
`deploy.sh` links `~/.claude/skills` to `SKILLS/`, so those skills landed in `SKILLS/synced/`.
Nothing ignored them, and the daily backup's `git add -A` committed them to each owner's OPS
repo. `.gitignore` now ignores `SKILLS/synced/`. `verify-ops` check 9 skips that directory in
the README index and WARNs, with the untrack command, when a copy is already committed
(ignoring a path does not untrack files already in the repo). `verify-ops-selftest` case 26
covers all three.

## 2026-10-19: one always-loaded core, private-only pushes, lane-aware hooks, the sandbox, and a CI gate

OPS booted through a foreman charter and an identity digest that a `claude()`
Expand Down