import type { Check } from "../internals/verify.js"; import type { SkillShape } from "./shape.js"; /** Four-state install verdict (docs/security/skill-trust-gate.md). */ export type SkillVerdict = "GREEN" | "YELLOW" | "RED" | "UNKNOWN"; export interface SkillVerdictResult { verdict: SkillVerdict; reasons: string[]; } /** * Pure verdict engine: fold checks + shape + acquisition facts into one * GREEN/YELLOW/RED/UNKNOWN verdict. Rules, in priority order: * 1. any proven-dangerous FAIL (TRUST_DANGER_CODES) → RED * 2. not fetched / fetch-blocked, detector-unavailable evidence gaps * (optional gaps on non-first-party sources; required FAILs on all sources), * license missing, or an unpinned GitHub source → UNKNOWN * 3. any other FAIL, or a shape trigger (install scripts / * MCP config / full-codebase analysis) → YELLOW * 4. otherwise → GREEN * Every contributing rule pushes a human-readable reason, so a RED verdict * still lists its UNKNOWN/YELLOW contributors for the operator. * * First-party exemption: a FIRST-PARTY source (`opts.firstParty` — a local path * resolved UNDER the repo root, e.g. a bundled skill in `packs/`) is graded on * aih-native coverage, so an unavailable third-party deep detector * (skillspector/cisco) does NOT force UNKNOWN — those scanners guard UNTRUSTED * REMOTE fetches, while a repo-relative path is operator-controlled content whose * approval anchor is the human PR review + git history. Explicit enterprise * required-detector failures still force UNKNOWN on first-party sources; the * exemption is only for optional detector skips. The exemption is scoped to * repo-relative sources on purpose: a local path OUTSIDE the repo is treated like * any other unvetted source (still UNKNOWN without the detectors). Native rules * always apply: a malicious-code finding is still RED, a shape trigger is still * YELLOW, and a missing license is still UNKNOWN. When the deep detectors ARE * available they still run and still escalate on their findings. */ export declare function skillVerdict(checks: readonly Check[], shape: SkillShape, opts: { pinned: boolean; fetched: boolean; firstParty?: boolean; }): SkillVerdictResult;