diff --git a/.github/README.md b/.github/README.md index 1234370733..4276ef2b4c 100644 --- a/.github/README.md +++ b/.github/README.md @@ -235,14 +235,14 @@ Empty `var` = the skill's default behavior (scan everything, auto-pick topics). The default model for all skills is set in `aeon.yml` (or from the dashboard header dropdown): ```yaml -model: claude-sonnet-4-6 +model: claude-sonnet-5 ``` -Options: `claude-sonnet-4-6` (default), `claude-opus-4-8`, `claude-fable-5`, `claude-opus-4-7`, `claude-sonnet-5`, `claude-haiku-4-5-20251001`. Per-run overrides are available via workflow dispatch, and individual skills can override to optimize cost: +Options: `claude-sonnet-5` (default), `claude-opus-5`, `claude-haiku-4-5-20251001`. Per-run overrides are available via workflow dispatch, and individual skills can override to optimize cost: ```yaml skills: - token-movers: { enabled: true, schedule: "30 12 * * *", model: "claude-sonnet-4-6" } + token-movers: { enabled: true, schedule: "30 12 * * *", model: "claude-haiku-4-5-20251001" } ``` > These ids apply to the **claude** harness. Each other [harness](../docs/harnesses.md) carries its own model list (Codex `openai/*`, Kimi `moonshotai/*`, Vibe `mistralai/*`, Pi `deepseek/*`), which the dashboard picker swaps in when you select that harness. diff --git a/.github/workflows/aeon.yml b/.github/workflows/aeon.yml index ba11efd990..d30fcf4983 100644 --- a/.github/workflows/aeon.yml +++ b/.github/workflows/aeon.yml @@ -23,11 +23,8 @@ on: # "Resolve harness" forwards them verbatim as the harness model. options: - '(config default)' - - claude-opus-4-8 - - claude-opus-4-7 - - claude-fable-5 - claude-sonnet-5 - - claude-sonnet-4-6 + - claude-opus-5 - claude-haiku-4-5-20251001 - grok-4.5 - openai/gpt-5-mini @@ -287,7 +284,7 @@ jobs: # 3. a per-harness cheap default. # aeon-native ids (claude-*/grok-*) mean nothing to an OpenRouter CLI, so # they're treated as "unset" and fall through to the default — a repo that - # never touched the model picker (still `model: claude-sonnet-4-6`) still + # never touched the model picker (still `model: claude-sonnet-5`) still # gets a working default instead of a dead id. The greps carry `|| true` # for the same reason as the harness greps above (no key ≠ fatal). # Each harness defaults to its own native family (the dashboard's @@ -782,7 +779,7 @@ jobs: elif [ -n "$SKILL_MODEL" ]; then MODEL="$SKILL_MODEL" else - MODEL="${CONFIG_MODEL:-claude-sonnet-4-6}" + MODEL="${CONFIG_MODEL:-claude-sonnet-5}" fi # --- Harness resolution (which agent CLI runs the skill) --- diff --git a/.github/workflows/messages.yml b/.github/workflows/messages.yml index 71c9e1374e..773702a06b 100644 --- a/.github/workflows/messages.yml +++ b/.github/workflows/messages.yml @@ -445,7 +445,7 @@ jobs: run: | TODAY=$(date -u +%Y-%m-%d) CONFIG_MODEL=$(grep -E '^model:' aeon.yml | sed 's/^model: *//' | tr -d ' ') - MODEL="${CONFIG_MODEL:-claude-sonnet-4-6}" + MODEL="${CONFIG_MODEL:-claude-sonnet-5}" # Harness resolution — inbound messaging isn't a per-skill run, so it # follows the repo's global `harness:` in aeon.yml (same default/guard as diff --git a/aeon.yml b/aeon.yml index 0533afe7ea..4e6994c164 100644 --- a/aeon.yml +++ b/aeon.yml @@ -2,7 +2,7 @@ # # Enable skills by setting enabled: true. Multiple skills at the same time run in parallel. # Set var: "value" to pass a default parameter to the skill. -# Set model: "claude-sonnet-4-6" per skill to override the default model (cost optimization). +# Set model: "claude-haiku-4-5-20251001" per skill to override the default model (cost optimization). # Set harness: "grok" per skill to run it through the Grok Build CLI instead of the # default Claude Code harness (see the top-level `harness:` key below). @@ -177,14 +177,16 @@ chains: # - skill: routine, consume: [token-movers, hn-digest, issue-triage, github-trending] # Default model for all skills. Override per-run via workflow_dispatch. -# Options: claude-opus-4-8, claude-fable-5, claude-sonnet-5, claude-sonnet-4-6, claude-haiku-4-5-20251001 -# (Grok harness models: grok-4.5 — flagship reasoning model & grok's current default, -# run with --no-subagents in CI; grok-composer-2.5-fast — fast/cheap single-agent. -# The older grok-build-0.1 is gateway-only, via XAI_API_KEY + the GROK_MODEL var.) +# Options: claude-sonnet-5, claude-opus-5, claude-haiku-4-5-20251001 +# (Grok harness model: grok-4.5, the flagship reasoning model and grok's current +# default, run with --no-subagents in CI. It's the only id the grok CLI accepts on an +# X-account login, and it's the gateway default too. The older coding ids +# (grok-build-0.1, grok-composer-2.5-fast, grok-4.3) are gateway-only, reachable via +# XAI_API_KEY + the GROK_MODEL var.) # The non-claude harnesses use their OWN model ids (codex openai/*, kimi moonshotai/*, # vibe mistralai/*, pi deepseek/*) — surfaced in the dashboard picker per harness; see # docs/harnesses.md. The value below only applies to the claude/grok harnesses. -model: claude-sonnet-4-6 +model: claude-sonnet-5 # Agent harness — which coding-agent CLI runs your skills. # claude (default) — Claude Code (`claude -p`); uses the AI Gateway below. diff --git a/apps/dashboard/app/page.tsx b/apps/dashboard/app/page.tsx index bd3be834dd..a842361a66 100644 --- a/apps/dashboard/app/page.tsx +++ b/apps/dashboard/app/page.tsx @@ -42,7 +42,7 @@ export default function Dashboard() { const [skills, setSkills] = useState([]) const [runs, setRuns] = useState([]) const [secrets, setSecrets] = useState([]) - const [model, setModel] = useState('claude-sonnet-4-6') + const [model, setModel] = useState('claude-sonnet-5') const [harness, setHarness] = useState('claude') const [gateway, setGateway] = useState('auto') const [repo, setRepo] = useState('') diff --git a/apps/dashboard/lib/config.test.ts b/apps/dashboard/lib/config.test.ts index ad2cfef6f6..a790013b24 100644 --- a/apps/dashboard/lib/config.test.ts +++ b/apps/dashboard/lib/config.test.ts @@ -26,16 +26,16 @@ import { const MINIMAL_YAML = `skills: heartbeat: { enabled: true, schedule: "0 12 * * *" } -model: claude-sonnet-4-6 +model: claude-sonnet-5 `; const FULL_YAML = `# Aeon configuration skills: morning-brief: { enabled: false, schedule: "0 7 * * *" } - market-pulse: { enabled: true, schedule: "0 12 * * *", model: "claude-sonnet-4-6" } + market-pulse: { enabled: true, schedule: "0 12 * * *", model: "claude-sonnet-5" } heartbeat: { enabled: true, schedule: "0 12 * * *" } -model: claude-opus-4-8 +model: claude-opus-5 gateway: provider: direct @@ -55,7 +55,7 @@ describe("parseConfig", () => { assert.equal(config.skills["heartbeat"].schedule, "0 12 * * *"); assert.equal(config.skills["heartbeat"].var, ""); assert.equal(config.skills["heartbeat"].model, ""); - assert.equal(config.model, "claude-sonnet-4-6"); + assert.equal(config.model, "claude-sonnet-5"); }); it("parses a full config with all fields", () => { @@ -64,16 +64,16 @@ describe("parseConfig", () => { assert.equal(config.skills["morning-brief"].enabled, false); assert.equal(config.skills["morning-brief"].schedule, "0 7 * * *"); assert.equal(config.skills["market-pulse"].enabled, true); - assert.equal(config.skills["market-pulse"].model, "claude-sonnet-4-6"); - assert.equal(config.model, "claude-opus-4-8"); + assert.equal(config.skills["market-pulse"].model, "claude-sonnet-5"); + assert.equal(config.model, "claude-opus-5"); assert.equal(config.gateway.provider, "direct"); assert.equal(config.jsonrenderEnabled, true); }); - it("defaults model to claude-sonnet-4-6 when absent", () => { + it("defaults model to claude-sonnet-5 when absent", () => { const yaml = `skills:\n test: { enabled: false, schedule: "0 0 * * *" }\n`; const config = parseConfig(yaml); - assert.equal(config.model, "claude-sonnet-4-6"); + assert.equal(config.model, "claude-sonnet-5"); }); it("defaults gateway to auto when absent", () => { @@ -106,7 +106,7 @@ describe("parseConfig", () => { it("handles empty skills section", () => { // yaml library parses `skills:` with no entries as null, not an empty map - const yaml = `skills:\n\nmodel: claude-sonnet-4-6\n`; + const yaml = `skills:\n\nmodel: claude-sonnet-5\n`; const config = parseConfig(yaml); assert.equal(Object.keys(config.skills).length, 0); }); @@ -138,8 +138,8 @@ describe("updateSkillInConfig", () => { }); it("sets a model override on a skill", () => { - const updated = updateSkillInConfig(MINIMAL_YAML, "heartbeat", { model: "claude-sonnet-4-6" }); - assert.ok(updated.includes("model: claude-sonnet-4-6") || updated.includes("model: 'claude-sonnet-4-6'")); + const updated = updateSkillInConfig(MINIMAL_YAML, "heartbeat", { model: "claude-sonnet-5" }); + assert.ok(updated.includes("model: claude-sonnet-5") || updated.includes("model: 'claude-sonnet-5'")); }); it("returns original yaml for non-existent skill", () => { @@ -164,9 +164,9 @@ describe("updateSkillInConfig", () => { describe("updateModelInConfig", () => { it("updates the top-level model", () => { - const updated = updateModelInConfig(MINIMAL_YAML, "claude-opus-4-8"); + const updated = updateModelInConfig(MINIMAL_YAML, "claude-opus-5"); const config = parseConfig(updated); - assert.equal(config.model, "claude-opus-4-8"); + assert.equal(config.model, "claude-opus-5"); }); it("replaces an existing model", () => { @@ -321,7 +321,7 @@ describe("addSkillToConfig", () => { }); it("inserts at end when heartbeat is absent", () => { - const yaml = `skills:\n alpha: { enabled: false, schedule: "0 0 * * *" }\n\nmodel: claude-sonnet-4-6\n`; + const yaml = `skills:\n alpha: { enabled: false, schedule: "0 0 * * *" }\n\nmodel: claude-sonnet-5\n`; const updated = addSkillToConfig(yaml, "beta"); const config = parseConfig(updated); assert.ok(config.skills["beta"]); @@ -353,9 +353,9 @@ describe("round-trip config mutations", () => { }); it("update model and gateway independently", () => { - let yaml = updateModelInConfig(MINIMAL_YAML, "claude-opus-4-8"); + let yaml = updateModelInConfig(MINIMAL_YAML, "claude-opus-5"); const config1 = parseConfig(yaml); - assert.equal(config1.model, "claude-opus-4-8"); + assert.equal(config1.model, "claude-opus-5"); // Model change should not affect skills assert.equal(config1.skills["heartbeat"].enabled, true); @@ -390,7 +390,7 @@ describe("upsertSkillInConfig", () => { const config = parseConfig(yaml); assert.equal(config.skills["market-pulse"].schedule, "0 6 * * *"); // Pre-existing fields survive, and the key appears exactly once. - assert.equal(config.skills["market-pulse"].model, "claude-sonnet-4-6"); + assert.equal(config.skills["market-pulse"].model, "claude-sonnet-5"); assert.equal(yaml.match(/^\s*market-pulse:/gm)?.length, 1); }); diff --git a/apps/dashboard/lib/config.ts b/apps/dashboard/lib/config.ts index 081bbb6e6d..75f9212828 100644 --- a/apps/dashboard/lib/config.ts +++ b/apps/dashboard/lib/config.ts @@ -47,7 +47,7 @@ export function parseConfig(raw: string): AeonConfig { } } - const model = String(doc.get('model') ?? 'claude-sonnet-4-6') + const model = String(doc.get('model') ?? 'claude-sonnet-5') const harnessRaw = String(doc.get('harness') ?? 'claude') const harness: Harness = HARNESSES.find(h => h === harnessRaw) ?? 'claude' diff --git a/apps/dashboard/lib/constants.ts b/apps/dashboard/lib/constants.ts index ad67b2d777..26f9d054c4 100644 --- a/apps/dashboard/lib/constants.ts +++ b/apps/dashboard/lib/constants.ts @@ -5,11 +5,8 @@ import { HARNESS_AUTH } from './harness-auth' // harness-switch snap uses (modelsForHarness(...)[0] in app/page.tsx). Keep it in // sync with the config default in lib/config.ts and aeon.yml `model:`. export const MODELS = [ - { id: 'claude-sonnet-4-6', label: 'Sonnet 4.6' }, - { id: 'claude-opus-4-8', label: 'Opus 4.8' }, - { id: 'claude-opus-4-7', label: 'Opus 4.7' }, - { id: 'claude-fable-5', label: 'Fable 5' }, { id: 'claude-sonnet-5', label: 'Sonnet 5' }, + { id: 'claude-opus-5', label: 'Opus 5' }, { id: 'claude-haiku-4-5-20251001', label: 'Haiku 4.5' }, ] diff --git a/docs/ADK.md b/docs/ADK.md index c1c3428510..aaaa9bc611 100644 --- a/docs/ADK.md +++ b/docs/ADK.md @@ -189,7 +189,7 @@ Everything on-demand goes through one workflow - `aeon.yml` accepts `workflow_di |---|---| | `skill` | required; must match `^[a-zA-Z0-9_-]+$` and a directory under `skills/` | | `var` | the skill's input for this run | -| `model` | override, e.g. `claude-opus-4-8` - must be one of the workflow's `choice` options or GitHub rejects with **422** | +| `model` | override, e.g. `claude-opus-5` - must be one of the workflow's `choice` options or GitHub rejects with **422** | | `harness` | `claude` (default) or `grok` - see [Harnesses](harnesses.md) | ```ts diff --git a/docs/attestation.md b/docs/attestation.md index eb026f05e8..bab944f504 100644 --- a/docs/attestation.md +++ b/docs/attestation.md @@ -205,7 +205,7 @@ To read the richer metadata, verify the manifest and inspect its bytes: ```bash gh attestation verify output/.attest/-.json --repo / cat output/.attest/-.json -# { "skill": "...", "model": "claude-opus-4-8", "mode": "read-only", +# { "skill": "...", "model": "claude-opus-5", "mode": "read-only", # "trigger": "schedule", "commit": "", "run_id": "", # "output": { "path": "output/.attest/-.md", "sha256": "" } } ``` diff --git a/harness-adapter/adapters/pi.sh b/harness-adapter/adapters/pi.sh index b570e7fd3a..8b6774e1ae 100755 --- a/harness-adapter/adapters/pi.sh +++ b/harness-adapter/adapters/pi.sh @@ -27,7 +27,7 @@ command -v pi >/dev/null 2>&1 || { ARGS=(--mode json --no-session --approve) # model: pi is multi-provider — pass anything through (its registry matches -# patterns like "claude-sonnet-4-6", "openai/gpt-4o", or bare "sonnet") +# patterns like "claude-sonnet-5", "openai/gpt-4o", or bare "sonnet") [ -n "${RH_MODEL:-}" ] && [ "${RH_MODEL}" != "default" ] && ARGS+=(--model "$RH_MODEL") # read-only -> tool subsetting (pi's only native lever; advisory without the diff --git a/scripts/llm-gateway.sh b/scripts/llm-gateway.sh index 2b40365092..a4ba63b2ee 100644 --- a/scripts/llm-gateway.sh +++ b/scripts/llm-gateway.sh @@ -183,14 +183,14 @@ case "${GATEWAY:-direct}" in echo "::notice::Routing through Bankr Gateway (https://llm.bankr.bot)" ;; - openrouter) # NATIVE — Anthropic "skin", carries Opus 4.8 + openrouter) # NATIVE — Anthropic "skin", carries Opus 5 require_secret OPENROUTER_API_KEY export ANTHROPIC_BASE_URL="https://openrouter.ai/api" # NOT /api/v1 export ANTHROPIC_AUTH_TOKEN="$OPENROUTER_API_KEY" # Bearer; API_KEY must be blank unset ANTHROPIC_API_KEY CLAUDE_CODE_OAUTH_TOKEN # Map EVERY model slot Claude Code uses to OpenRouter slugs (opus/sonnet/haiku). - export ANTHROPIC_DEFAULT_OPUS_MODEL="${OPENROUTER_MODEL:-anthropic/claude-opus-4.8}" - export ANTHROPIC_DEFAULT_SONNET_MODEL="${OPENROUTER_MODEL_SONNET:-anthropic/claude-sonnet-4.6}" + export ANTHROPIC_DEFAULT_OPUS_MODEL="${OPENROUTER_MODEL:-anthropic/claude-opus-5}" + export ANTHROPIC_DEFAULT_SONNET_MODEL="${OPENROUTER_MODEL_SONNET:-anthropic/claude-sonnet-5}" export ANTHROPIC_DEFAULT_HAIKU_MODEL="${OPENROUTER_MODEL_HAIKU:-anthropic/claude-haiku-4.5}" MODEL="$ANTHROPIC_DEFAULT_OPUS_MODEL" echo "::notice::Routing through OpenRouter (Anthropic-native) as ${MODEL}" @@ -201,7 +201,7 @@ case "${GATEWAY:-direct}" in export ANTHROPIC_BASE_URL="https://api.usepod.ai/proxy/${USEPOD_TOKEN}" export ANTHROPIC_AUTH_TOKEN="unused" # UsePod auths via the path token unset ANTHROPIC_API_KEY CLAUDE_CODE_OAUTH_TOKEN - # UsePod mirrors the upstream Anthropic surface, so aeon's claude-opus-4-8 id + # UsePod mirrors the upstream Anthropic surface, so aeon's claude-opus-5 id # is passed through by default. If UsePod needs marketplace-specific ids, set # USEPOD_MODEL (+ _SONNET / _HAIKU) to override. if [ -n "${USEPOD_MODEL:-}" ]; then MODEL="$USEPOD_MODEL"; fi @@ -218,10 +218,13 @@ case "${GATEWAY:-direct}" in export ANTHROPIC_BASE_URL="${XAI_ANTHROPIC_BASE_URL:-https://api.x.ai}" export ANTHROPIC_AUTH_TOKEN="$XAI_API_KEY" # Bearer; API_KEY must be blank unset ANTHROPIC_API_KEY CLAUDE_CODE_OAUTH_TOKEN - # Pin every model slot to a grok coding model. GROK_MODEL overrides — e.g. set it - # to grok-4.5 (xAI's current flagship, available on api.x.ai) instead of the - # conservative grok-build-0.1 default kept here for backward-compatible behavior. - grok_model="${GROK_MODEL:-grok-build-0.1}" + # Pin every model slot to a grok coding model. Defaults to grok-4.5, xAI's current + # flagship and the same id the grok harness offers (GROK_MODELS in the dashboard's + # constants.ts), so the gateway and CLI paths name the same model. GROK_MODEL + # overrides: the older coding ids (grok-build-0.1, grok-composer-2.5-fast, + # grok-4.3) are api.x.ai model strings that still work here, even though the grok + # CLI rejects them on an X-account OAuth login. + grok_model="${GROK_MODEL:-grok-4.5}" export ANTHROPIC_DEFAULT_OPUS_MODEL="$grok_model" export ANTHROPIC_DEFAULT_SONNET_MODEL="$grok_model" export ANTHROPIC_DEFAULT_HAIKU_MODEL="$grok_model" @@ -236,22 +239,23 @@ case "${GATEWAY:-direct}" in # uses dot-form ids: drop any trailing -YYYYMMDD date, then convert each # - to .. SURPLUS_MODEL overrides; opus-4.8 is the # fallback when $MODEL is unset. - surplus_model="${SURPLUS_MODEL:-$(printf '%s' "${MODEL:-claude-opus-4-8}" | sed -E 's/-[0-9]{8}$//; s/([0-9])-([0-9])/\1.\2/g')}" + surplus_model="${SURPLUS_MODEL:-$(printf '%s' "${MODEL:-claude-opus-5}" | sed -E 's/-[0-9]{8}$//; s/([0-9])-([0-9])/\1.\2/g')}" start_ccr_sidecar surplus \ "https://www.surplusintelligence.ai/api/inference/v1/chat/completions" \ "$SURPLUS_API_KEY" "$surplus_model" echo "::notice::Routing through Surplus via claude-code-router (${surplus_model})" ;; - venice) # SIDECAR — OpenAI-compatible (dash-form ids); tops out ~Opus 4.6 + venice) # SIDECAR — OpenAI-compatible (dash-form ids); carries Opus 5, no haiku require_secret VENICE_API_KEY # Set VENICE_CLEANCACHE=1 to add the cleancache transformer (1h TTL, avoids # the shared 4-block prompt-cache limit) if you hit cache errors. - # The sidecar pins ONE model, so track aeon's $MODEL — but Venice's catalog - # caps at ~Opus 4.6, so a newer $MODEL (opus 4.7/4.8, fable) would 404. Derive - # only for models Venice is known to carry (dash-form, date suffix stripped); - # anything else keeps the safe opus-4-6 default. VENICE_MODEL overrides. - # (Confirm/extend the allowlist when Venice is live-validated.) + # The sidecar pins ONE model, so track aeon's $MODEL. Venice names models with + # aeon's own dash-form ids, so the picker's ids pass straight through (date + # suffix stripped) when Venice carries them. It carries NO haiku at all, so + # haiku, and anything else off-catalog, falls back to sonnet-5 rather than + # 404ing on a model Venice never had. VENICE_MODEL overrides. + # Allowlist verified against api.venice.ai/api/v1/models on 2026-07-24. # VENICE_BASE_URL (repo variable) points the sidecar at any Venice-compatible # endpoint — a self-hosted relay, a billing proxy, a regional mirror — same # override pattern as VENICE_MODEL. Defaults to Venice's public API. @@ -259,8 +263,9 @@ case "${GATEWAY:-direct}" in if [ -z "$venice_model" ]; then m="$(printf '%s' "${MODEL:-}" | sed -E 's/-[0-9]{8}$//')" case "$m" in - claude-opus-4-6|claude-sonnet-4-6|claude-haiku-4-5) venice_model="$m" ;; - *) venice_model="claude-opus-4-6" ;; + claude-opus-5|claude-sonnet-5|claude-fable-5|claude-opus-4-8|claude-opus-4-7|\ + claude-opus-4-6|claude-opus-4-5|claude-sonnet-4-6|claude-sonnet-4-5) venice_model="$m" ;; + *) venice_model="claude-sonnet-5" ;; esac fi start_ccr_sidecar venice \ diff --git a/scripts/tests/test_run_grok.sh b/scripts/tests/test_run_grok.sh index 8d21836886..d59355841e 100755 --- a/scripts/tests/test_run_grok.sh +++ b/scripts/tests/test_run_grok.sh @@ -86,7 +86,7 @@ grep -qx -- "--permission-mode" "$ARGS_FILE" && grep -qx "bypassPermissions" "$A grep -qx -- "--rules" "$ARGS_FILE" && pass "passes --rules compat preamble" || bad "passes --rules compat preamble" # 4b. --model is OMITTED for a leftover claude-* id or empty (grok uses its default) -echo "p" | GROK_FAKE_OUT='{"text":"x"}' MODEL=claude-sonnet-4-6 SKILL_MODE=write XAI_API_KEY=xai-test bash "$R" >/dev/null 2>&1 +echo "p" | GROK_FAKE_OUT='{"text":"x"}' MODEL=claude-sonnet-5 SKILL_MODE=write XAI_API_KEY=xai-test bash "$R" >/dev/null 2>&1 if grep -qx -- "--model" "$ARGS_FILE"; then bad "omits --model for claude-* id"; else pass "omits --model for claude-* id"; fi echo "p" | GROK_FAKE_OUT='{"text":"x"}' MODEL="" SKILL_MODE=write XAI_API_KEY=xai-test bash "$R" >/dev/null 2>&1 if grep -qx -- "--model" "$ARGS_FILE"; then bad "omits --model for empty model"; else pass "omits --model for empty model"; fi diff --git a/skills/create-skill/SKILL.md b/skills/create-skill/SKILL.md index e544936e6f..e6fffe1587 100644 --- a/skills/create-skill/SKILL.md +++ b/skills/create-skill/SKILL.md @@ -67,7 +67,7 @@ Today is ${today}. Your task is to generate a complete, production-ready skill f - **Variable behavior** — what `${var}` controls; what happens when empty (sane default OR clean abort with notify). - **Steps** — 4-8 numbered, following the standard pattern: read context → fetch/search → process/analyze → write output → log → notify. - **Schedule suggestion** — choose a cron slot. Read existing schedules in `aeon.yml`; avoid co-scheduling at the same minute as heavy skills (article, repo-scanner, deep-research, telegram-digest) unless the new skill is lightweight (<30s expected). Prefer a `:30` minute offset if the natural hour is already crowded. - - **Model** — default `claude-opus-4-7`. Pick `claude-sonnet-4-6` if the skill is high-frequency aggregation/digestion (cost optimization). Document the choice in the PR body. + - **Model** — default `claude-sonnet-5`. Pick `claude-haiku-4-5-20251001` if the skill is high-frequency aggregation/digestion (cost optimization), or `claude-opus-5` if it needs the strongest reasoning. Document the choice in the PR body. - **Category** — the pack the skill joins. Pick one: `research` `dev` `crypto` `onchain-security` `social` `productivity` `meta`. (`core` and `fleet` are curated in `packs.config.json`, not chosen here.) If none fits, omit it and the skill lands in the **Lab** catch-all for later triage. See `docs/skill-packs.md`. 6. **Write the SKILL.md draft** at `skills/{skill-name}/SKILL.md` with this exact structure: @@ -139,7 +139,7 @@ Today is ${today}. Your task is to generate a complete, production-ready skill f 9. **Register in `aeon.yml`.** Insert the new skill in the appropriate time-slot section: - Format: ` {skill-name}: { enabled: false, schedule: "{suggested_cron}" }` - - Add `model: "claude-sonnet-4-6"` if chosen in step 5. + - Add `model: "claude-haiku-4-5-20251001"` (or `"claude-opus-5"`) if chosen in step 5. - Add `var: ""` if the skill takes a default var. - Add a brief trailing comment if the name doesn't make purpose obvious. - Place near related skills (crypto with crypto, content with content, etc.). diff --git a/skills/feature/SKILL.md b/skills/feature/SKILL.md index 27f8f5f71d..e6c93924f3 100644 --- a/skills/feature/SKILL.md +++ b/skills/feature/SKILL.md @@ -71,8 +71,8 @@ All branches read operator-controlled files under `memory/` (runtime config — - text-davinci ## Current models (suggest these as replacements) - - claude-sonnet-4-6 - - claude-opus-4-7 + - claude-sonnet-5 + - claude-opus-5 - gpt-4o - gemini-2.0 ``` diff --git a/skills/skill-repair/SKILL.md b/skills/skill-repair/SKILL.md index b7a9edd5bb..ec2676d59a 100644 --- a/skills/skill-repair/SKILL.md +++ b/skills/skill-repair/SKILL.md @@ -118,7 +118,7 @@ Categories follow `CLAUDE.md`. Pick the **most specific** category that fits the |---|---| | **`api-change`** | WebFetch the live API spec / status page / release notes. Update endpoints, payload shape, headers, error codes in the skill. Cite the spec URL in the PR body. Never guess — if WebFetch fails, drop to `REPAIR_DIAGNOSED_NO_FIX`. | | **`rate-limit`** | Add backoff (`sleep`), reduce request count, or add a fallback endpoint. Never raise the limit from the skill side. If the skill's `schedule` is too aggressive, propose a less-frequent cron in the PR body but **don't edit `aeon.yml`** unless the issue file already authorizes it. | -| **`timeout`** | Split work into stages, add early-return on partial success, downgrade `model:` to `claude-sonnet-4-6` or `claude-haiku-4-5-20251001` for the skill that doesn't need Opus. | +| **`timeout`** | Split work into stages, add early-return on partial success, downgrade `model:` to `claude-haiku-4-5-20251001` for the skill that doesn't need Sonnet or Opus. | | **`sandbox-limitation`** | Usually the "sandbox blocks the network" myth — there is **no** network sandbox. The real cause is a bare `$SECRET` on the command line (refused by the Bash permission layer) or a non-allowlisted command. Fix: route auth-required calls through `./secretcurl` with a `{ENV_NAME}` placeholder, or `gh api` for GitHub (auth handled internally). **Irreversible side-effects** (email / spend / on-chain / deploy) run **in-run** via `./secretcurl` as the skill's final, fail-closed action — never for reads. Add/refresh a "Network note" section. (There are **no** `scripts/prefetch-*.sh` or `scripts/postprocess-*.sh` scripts — both patterns were retired; auth'd reads and irreversible sends alike happen in-run.) | | **`prompt-bug`** | Minimum-edit specificity insertion. Don't rewrite — add the missing constraint, a forbidden phrase, a required output structure, or a clarifying example. Diff should be < 30 added/removed lines. | | **`output-format`** / **`quality-regression`** | Re-read the target skill's own output spec in its `SKILL.md`. Edit the skill so the next run satisfies that spec. Cite the exact requirement (section / line) in the PR body. |