From a58c1a1afff8fa345e2aa7bb84329effc85d6a50 Mon Sep 17 00:00:00 2001 From: Bo Date: Fri, 29 May 2026 19:55:46 -0400 Subject: [PATCH] feat(skills): skill-builder scaffolds codex override-catalog entry (ag-cw2y item 4) A new skill previously tripped validate-codex-override-coverage ('source skill missing from Codex catalog'), the 4th gate that cost /burndown #600 a CI round. - scripts/append-codex-override-entry.sh: idempotent, JSON-aware helper that appends a parity_only entry (name/treatment/wave=catalog-parity/reason) to skills-codex-overrides/catalog.json if the skill is absent. parity_only is the default for skill-builder's canonical-derived codex form; author flips to bespoke + scaffolds the override dir if a Codex-only divergence is needed. Repo-root-injectable for testing. - init.sh: calls it in the new-skill plumbing block alongside the dispositions row (#609/#610) and --fix-counts (#610). Codex artifact: refreshed skill-builder source/generated hash only (6 unrelated pre-existing main drifts left untouched). PR-scope codex validation passes. Closes-scenario: ag-cw2y#override-catalog-scaffold Bounded-context: BC4-factory Evidence: tests/scripts/append-codex-override-entry.bats --- scripts/append-codex-override-entry.sh | 43 ++++++++++++++++ skills-codex/.agentops-manifest.json | 2 +- .../skill-builder/.agentops-generated.json | 2 +- skills/skill-builder/scripts/init.sh | 6 +++ .../scripts/append-codex-override-entry.bats | 51 +++++++++++++++++++ 5 files changed, 102 insertions(+), 2 deletions(-) create mode 100755 scripts/append-codex-override-entry.sh create mode 100644 tests/scripts/append-codex-override-entry.bats diff --git a/scripts/append-codex-override-entry.sh b/scripts/append-codex-override-entry.sh new file mode 100755 index 000000000..06f7bdc91 --- /dev/null +++ b/scripts/append-codex-override-entry.sh @@ -0,0 +1,43 @@ +#!/usr/bin/env bash +# append-codex-override-entry.sh — ensure a new skill has a row in +# skills-codex-overrides/catalog.json (ag-cw2y item 4). +# +# Idempotent: appends a parity_only entry (canonical-derived codex form, which is +# what skill-builder produces by default) only if the skill is absent — so a +# newly-scaffolded skill is one-shot-green against validate-codex-override-coverage +# ("source skill missing from Codex catalog"). If the codex form is later made +# bespoke, the author flips treatment to "bespoke" and scaffolds the override dir. +# +# Usage: append-codex-override-entry.sh [repo-root] +set -euo pipefail + +SKILL="${1:?usage: append-codex-override-entry.sh [repo-root]}" +REPO_ROOT="${2:-$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)}" +CATALOG="$REPO_ROOT/skills-codex-overrides/catalog.json" + +if [[ ! -f "$CATALOG" ]]; then + echo "append-codex-override-entry: no catalog at $CATALOG" >&2 + exit 1 +fi + +SKILL="$SKILL" python3 - "$CATALOG" <<'PY' +import json, os, sys +path = sys.argv[1] +skill = os.environ["SKILL"] +with open(path) as f: + cat = json.load(f) +skills = cat.setdefault("skills", []) +if any(s.get("name") == skill for s in skills): + print(f"append-codex-override-entry: '{skill}' already cataloged — no-op") + sys.exit(0) +skills.append({ + "name": skill, + "treatment": "parity_only", + "wave": "catalog-parity", + "reason": f"TODO: confirm parity_only or flip to bespoke (+scaffold override dir) for {skill}", +}) +with open(path, "w") as f: + json.dump(cat, f, indent=2, ensure_ascii=False) + f.write("\n") +print(f"append-codex-override-entry: added parity_only entry for '{skill}'") +PY diff --git a/skills-codex/.agentops-manifest.json b/skills-codex/.agentops-manifest.json index e0128c0c5..b085003df 100644 --- a/skills-codex/.agentops-manifest.json +++ b/skills-codex/.agentops-manifest.json @@ -1045,7 +1045,7 @@ { "name": "skill-builder", "source_skill": "skills/skill-builder", - "source_hash": "816d7c6f9f2e409c6568ef8a7d5d163917074a76f8931ccfd91cfcea96746b11", + "source_hash": "941104f935c7d69640bcc42dcd83768f634c6150502746110c1028861e802b0b", "generated_hash": "4d8b01766df9b10099f4f669e60c74dede37bd604e70d7b6a9a732cb5b2a5c05" }, { diff --git a/skills-codex/skill-builder/.agentops-generated.json b/skills-codex/skill-builder/.agentops-generated.json index 26f42cda9..db9ab06de 100644 --- a/skills-codex/skill-builder/.agentops-generated.json +++ b/skills-codex/skill-builder/.agentops-generated.json @@ -2,6 +2,6 @@ "generator": "manual-maintained", "source_skill": "skills/skill-builder", "layout": "modular", - "source_hash": "816d7c6f9f2e409c6568ef8a7d5d163917074a76f8931ccfd91cfcea96746b11", + "source_hash": "941104f935c7d69640bcc42dcd83768f634c6150502746110c1028861e802b0b", "generated_hash": "4d8b01766df9b10099f4f669e60c74dede37bd604e70d7b6a9a732cb5b2a5c05" } diff --git a/skills/skill-builder/scripts/init.sh b/skills/skill-builder/scripts/init.sh index a49200d82..e19de1a26 100755 --- a/skills/skill-builder/scripts/init.sh +++ b/skills/skill-builder/scripts/init.sh @@ -265,6 +265,12 @@ if [[ -x "$REPO_ROOT/scripts/check-registry-drift.sh" ]]; then bash "$REPO_ROOT/scripts/check-registry-drift.sh" --fix-counts >/dev/null 2>&1 \ || echo "init.sh: WARN registry-drift --fix-counts could not run — bump counts manually" >&2 fi +# 3. Codex override catalog entry — else validate-codex-override-coverage fails +# ("source skill missing from Codex catalog"). Default parity_only (derived). +if [[ -f "$REPO_ROOT/scripts/append-codex-override-entry.sh" ]]; then + bash "$REPO_ROOT/scripts/append-codex-override-entry.sh" "$SKILL_NAME" "$REPO_ROOT" \ + || echo "init.sh: WARN could not add codex override catalog entry — add one manually" >&2 +fi echo "init.sh: created skill skeleton at $NEW_DIR" echo "init.sh: codex parity at $CODEX_DIR" diff --git a/tests/scripts/append-codex-override-entry.bats b/tests/scripts/append-codex-override-entry.bats new file mode 100644 index 000000000..0b5675e7a --- /dev/null +++ b/tests/scripts/append-codex-override-entry.bats @@ -0,0 +1,51 @@ +#!/usr/bin/env bats +# ag-cw2y item 4: skill-builder must add a skills-codex-overrides/catalog.json +# entry for a new skill so it is one-shot-green against +# validate-codex-override-coverage ("source skill missing from Codex catalog"). +# Default treatment is parity_only (canonical-derived codex form). Idempotent + +# repo-root-injectable. + +setup() { + HELPER="$BATS_TEST_DIRNAME/../../scripts/append-codex-override-entry.sh" + FIX="$(mktemp -d)" + mkdir -p "$FIX/skills-codex-overrides" + cat > "$FIX/skills-codex-overrides/catalog.json" <<'EOF' +{ + "version": 1, + "description": "fixture", + "waves": [ { "id": "catalog-parity", "title": "Catalog parity" } ], + "skills": [ + { "name": "existing", "treatment": "parity_only", "wave": "catalog-parity", "reason": "already here" } + ] +} +EOF +} + +teardown() { rm -rf "$FIX"; } + +@test "appends a parity_only catalog entry for a new skill" { + run bash "$HELPER" newskill "$FIX" + [ "$status" -eq 0 ] + run python3 -c "import json,sys; d=json.load(open('$FIX/skills-codex-overrides/catalog.json')); e=[s for s in d['skills'] if s['name']=='newskill']; assert len(e)==1; assert e[0]['treatment']=='parity_only'; assert e[0]['wave']=='catalog-parity'; print('ok')" + [[ "$output" == *"ok"* ]] +} + +@test "produced catalog remains valid JSON" { + bash "$HELPER" newskill "$FIX" + run python3 -c "import json; json.load(open('$FIX/skills-codex-overrides/catalog.json')); print('valid')" + [[ "$output" == *"valid"* ]] +} + +@test "is idempotent — no duplicate entry" { + bash "$HELPER" newskill "$FIX" + bash "$HELPER" newskill "$FIX" + run python3 -c "import json; d=json.load(open('$FIX/skills-codex-overrides/catalog.json')); print(sum(1 for s in d['skills'] if s['name']=='newskill'))" + [[ "$output" == *"1"* ]] +} + +@test "does not duplicate an already-cataloged skill" { + run bash "$HELPER" existing "$FIX" + [ "$status" -eq 0 ] + run python3 -c "import json; d=json.load(open('$FIX/skills-codex-overrides/catalog.json')); print(sum(1 for s in d['skills'] if s['name']=='existing'))" + [[ "$output" == *"1"* ]] +}