{"record":{"id":"7dc31545ee1941d7","repo":"Hmbown/CodeWhale","slug":"only-codewhale-managed-skills-can-be-trusted","errorCode":null,"errorMessage":"only CodeWhale managed skills can be trusted","messagePattern":"only CodeWhale managed skills can be trusted","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/tui/src/skills/mutation.rs","lineNumber":978,"sourceCode":"        scope,\n        safe_target_path: safe_display_path(&path, Some(ctx.workspace), ctx.home),\n        before_digest: before,\n        after_digest: None,\n        outcome: SkillMutationOutcome::Removed,\n    })\n}\n\nfn trust_skill(\n    skill_id: AuditedSkillId,\n    expected_digest: String,\n    ctx: &MutationContext<'_>,\n) -> Result<SkillMutationReceipt> {\n    let (skill, path) = find_audited_skill(ctx, &skill_id)?;\n    if !skill.root.is_writable_owned() {\n        bail!(\"refusing to trust skill outside CodeWhale-owned roots\");\n    }\n    if skill.source_kind != SkillSourceKind::CodeWhaleManaged {\n        bail!(\"only CodeWhale managed skills can be trusted\");\n    }\n    validate_owned_skill_path(ctx, &skill, &path)?;\n    let before = verify_expected_digest(&path, Some(&expected_digest))?;\n    validate_owned_skill_path(ctx, &skill, &path)?;\n    write_trust_v2(&path, &expected_digest)?;\n    let scope = match skill.root.kind {\n        SkillRootKind::CodeWhaleProject => SkillScope::Project,\n        SkillRootKind::CodeWhaleGlobal => SkillScope::Global,\n        _ => SkillScope::Logical,\n    };\n    Ok(SkillMutationReceipt {\n        action: SkillActionKind::Trust,\n        name: skill_id.canonical_name,\n        scope,\n        safe_target_path: safe_display_path(&path, Some(ctx.workspace), ctx.home),\n        before_digest: before.clone(),\n        after_digest: before,\n        outcome: SkillMutationOutcome::Trusted,","sourceCodeStart":960,"sourceCodeEnd":996,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/0c42157ee52f9d55af2b506d71b46249910f77d3/crates/tui/src/skills/mutation.rs#L960-L996","documentation":"Thrown by trust_skill in the skill-mutation API when asked to write a trust receipt (trust v2) for a skill whose source_kind is not SkillSourceKind::CodeWhaleManaged. Trust receipts pin a content digest and are only meaningful for skills installed and owned by CodeWhale roots; third-party, vendored, or user-imported skills are rejected so their trust state cannot be silently rewritten. The check runs after the writable-owned root check, so the skill is on a CodeWhale root but was not placed there by the managed installer.","triggerScenarios":"Calling the trust mutation with a skill id that resolves to a skill copied manually into a CodeWhale root, synced from another machine, or registered through a non-managed source; any trust request where find_audited_skill returns a record with source_kind != CodeWhaleManaged.","commonSituations":"Re-registering skills after restoring a backup or dotfile sync into ~/.codewhale or .codewhale/skills; hand-editing skill directories; migrating skills between projects; scripts that trust every audited skill in a loop without filtering by source.","solutions":["Reinstall the skill through CodeWhale's managed skill install path so it is recorded as CodeWhaleManaged, then retry the trust mutation.","Verify what you are trusting first: list audited skills with their source_kind and skip non-managed ones instead of trusting all ids blindly.","If the skill content is correct and you want it managed, remove the manually placed copy and install it via the managed installer rather than editing trust state by hand."],"exampleFix":"// before\nfor skill in audited_skills {\n    trust_skill(skill.id, skill.digest, &ctx)?; // bails on non-managed skills\n}\n\n// after\nfor skill in audited_skills {\n    if skill.source_kind == SkillSourceKind::CodeWhaleManaged {\n        trust_skill(skill.id, skill.digest, &ctx)?;\n    }\n}","handlingStrategy":"validation","validationCode":"use codewhale_tui::skills::{audit_skills, SkillSourceKind};\n\nfn is_trustable(ctx: &MutationContext<'_>, skill_id: &AuditedSkillId) -> bool {\n    match find_audited_skill(ctx, skill_id) {\n        Ok((skill, _)) => skill.source_kind == SkillSourceKind::CodeWhaleManaged\n            && skill.root.is_writable_owned(),\n        Err(_) => false,\n    }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Filter audited skills by source_kind == CodeWhaleManaged before batch trust operations.","Install skills through the managed installer instead of copying directories into CodeWhale roots.","Treat backup/dotfile-synced skill directories as unmanaged: reinstall before trusting."],"tags":["skills","trust","filesystem","permissions","rust"],"backgroundTag":"operation-not-supported","analyzedSha":"0c42157ee52f9d55af2b506d71b46249910f77d3","analyzedAt":"2026-08-20T21:50:45.477Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}