vigiles API reference
    Preparing search index...

    Interface HarnessDialect

    interface HarnessDialect {
        builtinAgentTools: readonly string[];
        eventCapabilities?: EventCapabilityTable;
        hookEvents: readonly string[];
        hookEventVocabulary?: HarnessVocabulary;
        instructionBudget?: InstructionBudget;
        instructionTargets: readonly string[];
        knownMcpServers?: readonly string[];
        mcpToolPattern: RegExp;
        name: string;
        neverAvailableTools: readonly string[];
        noEffectHookEvents?: readonly string[];
        permissionDecisionHookEvents?: readonly string[];
        pluginRootToken: string;
        sideEffectingTools?: readonly string[];
        skillFrontmatterKeys: readonly string[];
        subagentToolVocabulary?: HarnessVocabulary;
    }
    Index

    Properties

    builtinAgentTools: readonly string[]

    Built-in tools a subagent may list in its tools: contract.

    eventCapabilities?: EventCapabilityTable

    What each hook event CARRIES and HONOURS — EventCapabilityTable.

    The single table three flat lists had been approximating: hookEvents (membership), noEffectHookEvents (blocks ignored) and permissionDecisionHookEvents (deny needs a field) all ask about an event, none relate it to its PAYLOAD, and the fourth — injectableEvents — sits on a different port entirely. A list per question cannot answer a question about a PAIR, which is what "is this role legal on this event?" is.

    Optional (additive, non-breaking): absent ⇒ the flat lists still decide, and the (role, event) compatibility check does not run for that adapter. Present ⇒ it is the source the derived lists are read from, so the two cannot drift.

    hookEvents: readonly string[]

    Hook event names the harness fires.

    hookEventVocabulary?: HarnessVocabulary

    The hook-event catalog as a HarnessVocabulary — a status and a recorded vendor capture per term, rather than bare membership in hookEvents. When present it is what verifyHookEvents classifies against, so a name the catalog doesn't hold produces an unrecognised ADVISORY (naming vigiles's capture as the possibly-stale party) instead of the old behaviour, where an unknown name drew an accusation or silence depending on its edit distance to the list.

    Optional (additive, non-breaking). Absent ⇒ one is synthesised from hookEvents via vocabularyFromLists, so a legacy adapter keeps working and its unknowns become advisories rather than silence.

    instructionBudget?: InstructionBudget

    What this harness loads WITHOUT being asked, how it MEASURES that, and what it does when there is too much — InstructionBudget.

    On the dialect because it is a FORMAT fact (which files, counted in which unit), and because the browser engine is handed a dialect. Optional: absent ⇒ the weight report does not run for that adapter, which is the honest answer for a harness whose limits nobody has read.

    instructionTargets: readonly string[]

    Instruction-file targets the harness reads (also the h1 heading).

    knownMcpServers?: readonly string[]

    MCP servers the harness provides itself, available to a contract WITHOUT the plugin declaring them — e.g. Claude Code's built-in ide integration (mcp__ide__getDiagnostics). The mcp-tool-resolves check allowlists these so a reference to a built-in server is never flagged as an undeclared one. Optional (additive, non-breaking for existing adapters) — defaults to none.

    mcpToolPattern: RegExp

    Matches an MCP tool reference, e.g. mcp__server__tool.

    name: string

    Stable identifier, e.g. "claude-code".

    neverAvailableTools: readonly string[]

    Tools the platform never exposes to a subagent (a listed one is dead).

    noEffectHookEvents?: readonly string[]

    The subset of hookEvents where a block decision (exit 2 / a deny field) is SILENTLY IGNORED ENTIRELY — no veto AND no model feedback (Claude Code's SessionStart / SessionEnd / Notification / PreCompact: exit 2 there writes stderr only to the user). The basis for the hook-block-ineffective "wrong-event" check, which fires ONLY on these (so it stays FP-safe and never cries wolf on a PostToolUse feedback/nudge hook). Optional (additive, non-breaking) — absent ⇒ the harness's block semantics are undeclared and the check does not run for it.

    Superseded by eventCapabilities, from which this list is now DERIVED (blockIneffectiveEvents) and against which it is asserted. Kept because removing a public port field breaks third-party adapters; it will go in the next major.

    🔴 THE NAME IS WRONG AND THAT MATTERED. "No effect" reads as "a hook here does nothing", but it MEANS "no effect OF A BLOCK" — Claude Code's SessionStart is in this list and injects context perfectly well; exit 2 is the only thing it ignores. Deriving the list caught this: the obvious predicate (honours === []) silently dropped SessionStart and would have changed what hook-block-ineffective flags.

    permissionDecisionHookEvents?: readonly string[]

    The subset of blocking events whose deny REQUIRES the structured permissionDecision field (e.g. Claude Code's PreToolUse), where the legacy top-level decision field is silently ignored. The basis for the hook-block-ineffective "wrong-field" check. Optional (additive). *

    Superseded by eventCapabilities (denyShape: "permission-decision"), from which this list is derived and against which it is asserted. Kept for third-party adapters; goes in the next major.

    pluginRootToken: string

    The env token expanded to the plugin root in hook commands.

    sideEffectingTools?: readonly string[]

    Tools that PRODUCE side effects (write, exec, network, spawn) — the complement of read-only within builtinAgentTools. The basis for effect-surface analysis and the pure: contract: a tool here is denied to a pure skill and counts toward a harness's side-effect surface. Bash is listed (undecidable at the tool-name level → conservatively side-effecting); an MCP tool not classifiable from the name is treated as unknown-effect. Optional (additive, non-breaking) — absent ⇒ no tool is known-side-effecting.

    skillFrontmatterKeys: readonly string[]

    The SKILL.md frontmatter keys this harness READS. The compiler emits a key iff it is listed here, so a harness that reads only the cross-tool shape declares ["name", "description"] and the CC-only keys are omitted from its output rather than written as inert noise.

    Conformance requires name and description (a SKILL.md without them has no identity) and refuses a key outside RENDERABLE_SKILL_FRONTMATTER_KEYS — a key the compiler cannot render is a declaration nothing acts on.

    subagentToolVocabulary?: HarnessVocabulary

    The subagent-tool catalog as a HarnessVocabulary. Same contract as hookEventVocabulary; absent ⇒ synthesised from builtinAgentTools (available) + neverAvailableTools (withheld).

    The third status is why this exists: the vendor removes Agent only at the spawn depth limit and ExitPlanMode only outside plan mode, and removes most built-ins from a background subagent but not a foreground one — so "available to a subagent" is not a property of the name, and a two-way split had to encode one of those conditions as an unconditional fact.