Skip to content

Csf Strategy

csf_strategy — mvp.csf_strategy

Cluster: Safety & Alignment | Type: component | MCP Tools: 26

Overview

Strategy registry and execution block that manages named safety strategies: composable plans for how an agent should behave under specific conditions. Strategies are registered with strategy_register, retrieved with strategy_get, approved with strategy_approve in the MCP surface, and executed via strategy_run, which delegates to a StrategyRunner that optionally calls an LLM for adaptive plan generation. The returns library is used for railway-oriented error propagation through the dispatch chain.

Scope and production caveat

csf_strategy is a reliability harness and audit/trace layer, not a complete workflow automation engine. The built-in execution path uses EchoTool plus an optional LLM-backed tool, so it is useful for registering, approving, smoke-testing, tracing, comparing, and auditing strategy behavior, but domain-specific real-world actions require explicit tools to be registered and wired in. MCP strategy_run and strategy_run_node require approved strategies and available declared capabilities; use strategy_dry_run for no-side-effect smoke tests.

Approval asymmetry, source-op policy, and degradation contract

Approval gate (MCP-only). The approval gate is enforced only on the MCP surface (CSFStrategyMCPBlock, require_approval=True): strategy_run/strategy_run_node refuse any strategy whose status is not approved, before the execution graph is built. The base CSFStrategyBlock runs in permissive embedded / trusted-in-process mode (require_approval=False) and does not enforce approval. strategy_status discloses this honestly via approval_enforced (MCP true / base false) and approval_scope. The capability pre-flight (missing = required - available) runs on both surfaces.

Echo-stub / source-op policy. tool_register wires a stub EchoTool (maturity=stub, side_effect_class=none), not a concrete backend adapter; its response and the source_operations discovery surface mark it as a stub so callers never mistake it for a real backend. Real backend adapters declare typed SourceOperation descriptors (capability, input/output schema, side-effect class, permission requirement, idempotency, provenance, degradation modes). Mutating ops must carry a permission_requirement; an undeclared source op is blocked-escalated.

Degradation contract. Every public op surfaces the canonical envelope at the top level (completion_state ∈ {verified, qualified-draft, blocked-escalated}, warning_card, evidence, request_id, run_id) and persists it with the execution record. LLM fallback ([LLM unavailable], never fabricated) and stub execution are qualified-draft; approval/capability refusals, validation errors, and block exceptions are blocked-escalated with a stable G6_E_* code. Trace proposals are grounded in these persisted completion-state counts, not free text alone.

When to use:

  • Registering and running safety-aware behavioural strategies for an agent at runtime
  • Composing multi-step safety plans from reusable strategy primitives
  • Switching between pre-registered strategies based on current context or risk level
  • Capturing strategy execution traces, audit history, and simple before/after comparisons

Example:

from mvp.csf_strategy.strategy_mcp import CSFStrategyMCPBlock, MCPStrategyInput

block = CSFStrategyMCPBlock(db_path=":memory:")
block.infer(MCPStrategyInput(
    op="strategy_register",
    strategy_id="conservative",
    description="Check, execute, verify, and critique a task.",
    capabilities=["echo"],
))
block.infer(MCPStrategyInput(op="strategy_approve", strategy_id="conservative"))
result = block.infer(MCPStrategyInput(
    op="strategy_run",
    strategy_id="conservative",
    task="Check the generated summary for obvious omissions.",
))
# result.value.value -> {"run_id": ..., "success": ..., "nodes_executed": ...}

Works well with: csf, csf_cognitive, goal_engine

Public API

Node(ABC)

Base execution node in a strategy graph.

Constructor:

Parameter Type Default
name str required

Methods:

execute(context: dict[str, Any], tools: dict[str, Any]) -> dict[str, Any]

Execute this node, updating and returning the context.

PlannerNode(Node)

Decomposes a task into a plan (list of subtask strings).

Constructor:

Parameter Type Default
llm Callable[[str], str] \| None None

Methods:

execute(context: dict[str, Any], tools: dict[str, Any]) -> dict[str, Any]

ExecutorNode(Node)

Executes each step in the plan using available tools.

Methods:

execute(context: dict[str, Any], tools: dict[str, Any]) -> dict[str, Any]

VerifierNode(Node)

Verifies execution results for errors and completeness.

Methods:

execute(context: dict[str, Any], tools: dict[str, Any]) -> dict[str, Any]

CriticNode(Node)

Evaluates quality and suggests improvements.

Constructor:

Parameter Type Default
llm Callable[[str], str] \| None None

Methods:

execute(context: dict[str, Any], tools: dict[str, Any]) -> dict[str, Any]

ExecutionGraph

Ordered sequence of nodes executed in pipeline fashion.

Constructor:

Parameter Type Default
nodes list[Node] \| None None

Methods:

add_node(node: Node) -> None

run(task: str, tools: dict[str, Any]) -> dict[str, Any]

Execute all nodes sequentially, building up the context.

build_default(llm: Any = None) -> ExecutionGraph

Build the standard Planner->Executor->Verifier->Critic graph.

build_custom(node_names: list[str], llm: Any = None) -> ExecutionGraph

Build a graph from a list of node type names.

StrategyStats

Aggregate statistics for a strategy.

Field Type Default
strategy_id str ''
success_rate float 0.0
avg_duration float 0.0
total_runs int 0
failure_distribution dict[str, int] field(default_factory=dict)

TraceStore

In-memory trace storage.

Methods:

record(trace: dict[str, Any]) -> str

Store a trace and return its ID.

list_for_strategy(strategy_id: str, limit: int = 50) -> list[dict[str, Any]]

List traces for a given strategy.

get(trace_id: str) -> dict[str, Any] | None

Get a single trace by ID.

all_traces() -> list[dict[str, Any]]

Return all traces.

TraceLearner

Computes statistics and proposes recipe adjustments from traces.

Constructor:

Parameter Type Default
trace_store TraceStore required

Methods:

compute_stats(strategy_id: str) -> StrategyStats

Compute aggregate statistics for a strategy from traces.

propose_adjustments(strategy_id: str) -> list[dict[str, Any]]

Propose recipe adjustments based on trace analysis.

compare_strategies(strategy_a: str, strategy_b: str) -> dict[str, Any]

Compare two strategies' performance statistics.

ApprovalStatus(str, Enum)

RetryPolicy

Field Type Default
max_attempts int 3
backoff_factor float 1.0
retry_on tuple[str, ...] ('timeout', 'transient')

FailureMode

Field Type Default
name str required
description str required
severity str 'medium'
mitigation str ''

EvaluationMetric

Field Type Default
name str required
value float required
unit str ''
threshold float 0.0

StrategyModel

Field Type Default
id str required
version int 1
description str ''
policy str 'default'
status ApprovalStatus ApprovalStatus.DRAFT
capabilities list[str] field(default_factory=list)
recipes list[str] field(default_factory=list)
failure_modes list[FailureMode] field(default_factory=list)
retry_policy RetryPolicy field(default_factory=RetryPolicy)
created_by str ''
max_epsilon float 1.0
verification_method str 'union_bound'
metadata dict field(default_factory=dict)

Methods:

to_dict() -> dict[str, Any]

from_dict(d: dict[str, Any]) -> StrategyModel

StrategyRegistry

Thread-safe registry with versioning, audit trail, and optional SQLite persistence.

Constructor:

Parameter Type Default
db_path str \| None None

Methods:

register(model: StrategyModel) -> int

Register a strategy. Returns the assigned version number.

load(model: StrategyModel) -> None

Load a persisted strategy into memory without changing its metadata.

get(sid: str, version: int | None = None) -> StrategyModel | None

Get latest version or a specific version of a strategy.

approve(sid: str, reviewer: str | None = None) -> bool

Approve the latest version of a strategy with reviewer binding.

deprecate(sid: str) -> bool

Deprecate the latest version of a strategy.

list_all() -> list[dict[str, Any]]

List all registered strategies with summary metadata.

get_history(sid: str) -> list[dict[str, Any]]

Return all versions of a strategy.

get_audit_log() -> list[dict[str, Any]]

Return the full audit trail.

StrategyRunner

Executes strategies against tasks using the execution graph.

Constructor:

Parameter Type Default
registry StrategyRegistry required
tool_registry ToolRegistry required
llm Any None
require_approval bool True

Methods:

check_capabilities(strategy_id: str) -> dict[str, Any]

Pre-flight check: verify all required capabilities are available.

run(strategy_id: str, task: str) -> dict[str, Any]

Execute a strategy: build graph, run all nodes, return context.

dry_run(strategy_id: str, task: str) -> dict[str, Any]

Dry-run with EchoTools substituted for all tools.

run_node(strategy_id: str, node_name: str, task: str, context: dict[str, Any] | None = None) -> dict[str, Any]

Run a single named node.

StrategyInput(BaseModel)

Field Type Default
op Literal['strategy_register', 'strategy_get', 'strategy_run', 'strategy_list', 'strategy_status'] required
strategy_id str ''
description str ''
policy str 'default'
capabilities list[str] Field(default_factory=list)
recipes list[str] Field(default_factory=list)
created_by str ''
model_json str ''
task str ''

StrategyOutput(BaseModel)

Field Type Default
op str required
value Any None
error str ''
degraded bool False
degradation_reason str ''
completion_state str ''
warning_card dict[str, Any] Field(default_factory=dict)
evidence list[str] Field(default_factory=list)
request_id str ''
run_id str ''

CSFStrategyBlock(AIBlock[StrategyInput, StrategyOutput, dict])

Base strategy block with 5 core operations.

Field Type Default
name str 'csf_strategy'
state dict \| None None
resource_bounds ResourceBounds \| None None
usage ResourceUsage field(default_factory=ResourceUsage)

Methods:

infer(data: StrategyInput) -> Result[StrategyOutput]

SourceOperation

Typed descriptor for a backend-native source operation a tool can expose.

Field Type Default
name str required
capability str required
description str ''
input_schema dict[str, Any] field(default_factory=dict)
output_schema dict[str, Any] field(default_factory=dict)
side_effect_class str 'none'
permission_requirement str ''
idempotent bool True
provenance str ''
degradation_modes tuple[str, ...] ()
maturity str 'stub'

Methods:

compact() -> dict[str, Any]

SourceOperationResult

Structured result of a source-operation invocation.

Field Type Default
op_name str required
value Any None
completion_state str 'qualified-draft'
degraded bool False
degradation_reason str ''
side_effect_class str 'none'
provenance str ''

Methods:

compact() -> dict[str, Any]

Tool(ABC)

Abstract base class for strategy tools.

Constructor:

Parameter Type Default
name str required
capabilities list[str] \| None None

Methods:

execute(input_text: str) -> str

Execute the tool on the given input and return a string result.

source_operations() -> list[SourceOperation]

Describe the backend-native operations this tool exposes.

execute_operation(op_name: str, payload: dict[str, Any] | None = None, context: dict[str, Any] | None = None) -> SourceOperationResult

Execute a named source operation.

EchoTool(Tool)

Passes input through unchanged. Used for dry-run testing.

Constructor:

Parameter Type Default
name str 'echo'
capabilities list[str] \| None None

Methods:

execute(input_text: str) -> str

source_operations() -> list[SourceOperation]

LLMTool(Tool)

Calls the claude CLI subprocess for LLM-powered operations.

Constructor:

Parameter Type Default
name str 'llm'
capabilities list[str] \| None None
llm_fn Any None

Methods:

execute(input_text: str) -> str

ToolRegistry

Registry of named tools with capability lookup.

Methods:

register(tool: Tool) -> None

Register a tool by name.

get(name: str) -> Tool | None

Get a tool by name.

list_all() -> list[dict[str, Any]]

List all registered tools with metadata.

get_capabilities() -> list[str]

Return the union of all tool capabilities.

as_dict() -> dict[str, Tool]

Return tools as a name->Tool dict (for graph execution).

source_operations() -> list[dict[str, Any]]

Discover all backend-native source operations across registered tools.

find_by_source_operation(op_name: str) -> Tool | None

Return the first tool that declares a source operation named op_name.

find_by_capability(capability: str) -> list[Tool]

Return all tools whose capabilities include capability.

MCP Tools

Operation Source
strategy_register strategy_mcp
strategy_get strategy_mcp
strategy_approve strategy_mcp
strategy_deprecate strategy_mcp
strategy_list strategy_mcp
strategy_run strategy_mcp
strategy_dry_run strategy_mcp
strategy_check_capabilities strategy_mcp
strategy_run_node strategy_mcp
strategy_get_execution strategy_mcp
trace_record strategy_mcp
trace_stats strategy_mcp
trace_propose strategy_mcp
trace_list strategy_mcp
trace_compare strategy_mcp
graph_build strategy_mcp
graph_custom strategy_mcp
tool_register strategy_mcp
tool_list strategy_mcp
tool_get strategy_mcp
strategy_status strategy_mcp
strategy_audit strategy_mcp
strategy_history strategy_mcp
strategy_export strategy_mcp
strategy_import strategy_mcp
list_patterns strategy_mcp