Overview
A contract (contract.yaml) declares what a strategy needs to run: its parameters, required tables with column schemas, graph dependencies, and optional discovery hints. Contracts are the interface between strategy authors and the data-staging layer — they describe what data is needed without specifying how to fetch it.
Contracts live alongside strategy code:
Contract Fields
Top-level
| Field | Type | Required | Description |
|---|---|---|---|
name | string | yes | Strategy identifier (e.g., "credential-stealer-hunt") |
version | string | no | Semantic version (e.g., "2.0.0") |
description | string | yes | Human-readable purpose |
tags | []string | yes | At least one tag for classification (e.g., [hunt, macos]) |
params | map | no | Input parameters the strategy accepts |
requires | object | no | Runtime dependencies (graph, tables, sources) |
pinned_backend | string | no | Constrain resolution to a specific backend (e.g., "elasticsearch") |
discovery | object | no | Pre-staging guidance for orchestrators |
params
Each key is a parameter name; the value is aParamSpec:
| Field | Type | Required | Description |
|---|---|---|---|
type | string | yes | "str", "int", "float", "bool", or "list" |
required | bool | no | Whether the caller must provide this parameter |
default | any | no | Default value if not provided |
description | string | no | Parameter purpose (shown in strategy_describe) |
requires
| Field | Type | Description |
|---|---|---|
graph | bool | Whether the strategy needs knowledge graph access |
duckdb | bool | Whether the strategy needs DuckDB (implied by tables) |
tables | map | Required staging tables with column schemas |
sources | []string | Advisory list of expected LogSource names |
requires.tables
Each key is a table name; the value is aTableSpec:
| Field | Type | Description |
|---|---|---|
description | string | What data this table holds |
optional | bool | Strategy works without this table if true |
volume_hint | string | Expected cardinality: "low", "medium", "high" |
columns | map | Column definitions (see below) |
Column definitions
Each key is a column name; the value is aColumnSpec:
| Field | Type | Description |
|---|---|---|
type | string | DuckDB type: VARCHAR, INT64, FLOAT64, BOOLEAN, TIMESTAMP |
semantic | string | Semantic type linking to the knowledge graph (e.g., "ip_address", "identity_arn") |
description | string | Column purpose |
discovery
Optional hints for orchestrators that auto-stage data:| Field | Type | Description |
|---|---|---|
description | string | Prose explanation of how to stage data |
mcp_hints | []object | Suggested MCP tools |
mcp_hint:
| Field | Type | Description |
|---|---|---|
tool | string | MCP tool name (e.g., "elasticsearch.search") |
purpose | string | Why this tool is needed |
stage_as | string | Table name to store results as |
Validation
The following are enforced at parse time:namemust be non-emptydescriptionmust be non-emptytagsmust contain at least one element

