Hmbown/CodeWhale · error
refusing to trust skill outside Codewhale-owned roots
Error message
refusing to trust skill outside Codewhale-owned roots
What it means
trust_skill() refuses to mark a skill as trusted when its root does not pass skill.root.is_writable_owned(), i.e. the skill lives outside roots that Codewhale owns and can write. Trust records are bound to the skill's on-disk digest, so trusting a skill outside managed roots would create a trust attestation the library cannot enforce or update. This is a trust-boundary guard, checked before the managed-source check and digest verification.
Solutions
- Move or reinstall the skill into a Codewhale-owned root (project or global skills dir) before trusting it
- Check skill.root.is_writable_owned() before calling trust_skill
- Update the skills-root configuration so the skill's directory is registered as an owned, writable root
- Trust the skill manually via the UI/configuration if supported, accepting it stays outside managed roots
Example fix
// before ctx.trust_skill(skill_id, digest)?; // skill lives in ~/.my-skills // after // move the skill into the managed project skills dir first // ~/.codewhale/skills/<name> or .codewhale/skills/<name>, then: ctx.trust_skill(skill_id, digest)?;
Defensive patterns
Strategy: validation
Validate before calling
if !skill.root.is_writable_owned() { return Err(anyhow!("skill root is not owned; move it into a Codewhale skills dir")); } Type guard
fn trustable_root(s: &Skill) -> bool { s.root.is_writable_owned() && matches!(s.source_kind, SkillSourceKind::CodeWhaleManaged) } Prevention
- Keep all trusted skills inside configured Codewhale-owned roots
- Verify root ownership in UI before enabling trust actions
- Reinstall rather than symlink external skill directories into managed roots
When it happens
Trigger: Calling trust_skill (directly or via trust_writes_v2_digest_binding / execute_sync) with a skill_id whose skill.root is a non-owned (e.g. user home, external path, read-only mount) skill root.
Common situations: A user points Codewhale at skills stored in a shared or personal directory and then tries to trust one; or a symlink/config change moved a previously-owned skill outside managed roots.
Understand the failure class
Background: Permission denied / not authorized / 403 Forbidden: access-control rejections when the caller lacks the required role, grant, or ownership — this error's family across 18 libraries.
Related errors
- only CodeWhale managed skills can be trusted
- only Codewhale managed skills can be removed
- only Codewhale managed skills can be trusted
- agent profile may not request trust=true
- audited owned root does not match mutation target
AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22).
Data as JSON: /api/errors/f05ea47e09bee6a8.
Report an issue: GitHub.
Appendix: source
Thrown at crates/tui/src/skills/mutation.rs:975
Ok(SkillMutationReceipt {
action: SkillActionKind::Remove,
name: skill_id.canonical_name,
scope,
safe_target_path: safe_display_path(&path, Some(ctx.workspace), ctx.home),
before_digest: before,
after_digest: None,
outcome: SkillMutationOutcome::Removed,
})
}
fn trust_skill(
skill_id: AuditedSkillId,
expected_digest: String,
ctx: &MutationContext<'_>,
) -> Result<SkillMutationReceipt> {
let (skill, path) = find_audited_skill(ctx, &skill_id)?;
if !skill.root.is_writable_owned() {
bail!("refusing to trust skill outside Codewhale-owned roots");
}
if skill.source_kind != SkillSourceKind::CodeWhaleManaged {
bail!("only Codewhale managed skills can be trusted");
}
validate_owned_skill_path(ctx, &skill, &path)?;
let before = verify_expected_digest(&path, Some(&expected_digest))?;
validate_owned_skill_path(ctx, &skill, &path)?;
write_trust_v2(&path, &expected_digest)?;
let scope = match skill.root.kind {
SkillRootKind::CodeWhaleProject => SkillScope::Project,
SkillRootKind::CodeWhaleGlobal => SkillScope::Global,
_ => SkillScope::Logical,
};
Ok(SkillMutationReceipt {
action: SkillActionKind::Trust,
name: skill_id.canonical_name,
scope,
safe_target_path: safe_display_path(&path, Some(ctx.workspace), ctx.home),View on GitHub (pinned to 73e0f67d83)