fix(skills): reconcile team-template skill names so role bindings actually bind
Every skill reference in every team template was failing to resolve. The TOMLs used snake_case slugs (`write_rust`, `index_selection`) while the authored skills under `skills/**/*.md` declare kebab-case names (`write-rust-current-edition`, `postgres-index-selection`), so `get_by_name` missed on all of them: 128 skipped bindings across 51 distinct names, and no mission agent received any of its template's skills. The mirror-image half was equally invisible: ten authored skills — including `int-xx-marker-protocol`, whose own `when_to_use` says "pin on every coding role" — were referenced by no role at all, so nothing could ever load them. - Rename the 14 references that have authored skills behind them, and dedupe the two that now collapse onto the commit-protocol skill. - Attach all ten orphaned skills to the roles their `when_to_use` names. All 23 authored skills now reach at least one role. - Aggregate the loader's per-name logging into one line per template. The old per-name spam is why this went unnoticed; a bound/unresolved count is noticeable. References with no authored skill are kept and listed — they record intent for skills not yet written. - Two regression tests: no authored skill may be orphaned, and every authored skill must be referenced by its exact name. Also clears the two standing clippy warnings: group `mint_team_from_template`'s eight positional args into `TeamMint`, and make `provider_alias_for` branch on `is_exact_provider_match` so the helper is live code and the two can't disagree about what counts as an exact family match. Co-Authored-By: Claude Opus 5 <[email protected]>
This commit is contained in:
co-authored by
Claude Opus 5
parent
95bd65540c
commit
2eb0880fc0
@@ -29,14 +29,15 @@ pub fn claw_alias(claw_id: Uuid) -> String {
|
||||
pub fn provider_alias_for(model: &str) -> &'static str {
|
||||
let m = model.trim().to_ascii_lowercase();
|
||||
// Prefix families first (covers claude-sonnet-5, claude-opus-4-8,
|
||||
// claude-haiku-4-5-*, etc.) then explicit aliases.
|
||||
if m.starts_with("claude") {
|
||||
return "anthropic.default";
|
||||
}
|
||||
if m.starts_with("gemini") {
|
||||
return "gemini.default";
|
||||
}
|
||||
if m.starts_with("llama") || m.starts_with("groq") {
|
||||
// claude-haiku-4-5-*, etc.) then explicit aliases. `is_exact_provider_match`
|
||||
// decides what "its own family" means, so the two can't drift apart.
|
||||
if is_exact_provider_match(&m) {
|
||||
if m.starts_with("claude") {
|
||||
return "anthropic.default";
|
||||
}
|
||||
if m.starts_with("gemini") {
|
||||
return "gemini.default";
|
||||
}
|
||||
return "groq.default";
|
||||
}
|
||||
match m.as_str() {
|
||||
@@ -69,12 +70,13 @@ pub fn provider_alias_for(model: &str) -> &'static str {
|
||||
}
|
||||
}
|
||||
|
||||
/// Whether `provider_alias_for` resolved this model to its own family, or
|
||||
/// substituted a different one.
|
||||
/// Whether `provider_alias_for` resolves this model to its own family, or
|
||||
/// substitutes a different one.
|
||||
///
|
||||
/// Callers that surface a model choice to a user can use this to say so rather
|
||||
/// than letting the substitution be discovered on an invoice. Kept alongside
|
||||
/// `provider_alias_for` so the two can't disagree about what counts as a match.
|
||||
/// `provider_alias_for` branches on this, so it is the single definition of
|
||||
/// "its own family". Also public for callers that surface a model choice to a
|
||||
/// user, so a substitution can be said out loud rather than discovered on an
|
||||
/// invoice.
|
||||
pub fn is_exact_provider_match(model: &str) -> bool {
|
||||
let m = model.trim().to_ascii_lowercase();
|
||||
m.starts_with("claude")
|
||||
@@ -350,7 +352,12 @@ mod tests {
|
||||
"{m} resolves to anthropic.default by substitution, not by family"
|
||||
);
|
||||
}
|
||||
for m in ["claude-sonnet-5", "gemini-2.5-flash", "groq-llama", "llama3"] {
|
||||
for m in [
|
||||
"claude-sonnet-5",
|
||||
"gemini-2.5-flash",
|
||||
"groq-llama",
|
||||
"llama3",
|
||||
] {
|
||||
assert!(
|
||||
super::is_exact_provider_match(m),
|
||||
"{m} should resolve to its own family"
|
||||
|
||||
Reference in New Issue
Block a user