{
  "component_id": "src_policy.rs",
  "name": "Policy Engine",
  "description": "Deterministic policy engine for AI agent tool call evaluation. Loads YAML policy rules, compiles regex patterns, evaluates tool calls against conditions (regex, parameter checks, vault queries), and returns Allow/Deny/Ask/Gate/Ensure decisions. First-match-wins evaluation. No NLP, no network. Includes self-protection rules that prevent AI from tampering with policy infrastructure.",
  "version": 1,
  "types": [
    {
      "name": "Decision",
      "kind": "enum",
      "fields": [],
      "item_type": "",
      "variants": [
        "Allow",
        "Deny",
        "Ask",
        "Gate",
        "Ensure"
      ],
      "inner_types": [],
      "description": "Policy evaluation decision enum with lowercase conversion method",
      "owner_component": ""
    },
    {
      "name": "GateConfig",
      "kind": "struct",
      "fields": [
        {
          "name": "requires_prior",
          "type_ref": "String",
          "required": true,
          "default": "",
          "description": "Tool name or detail pattern to search for in action log. Pipe-delimited OR supported (e.g., 'EnterPlanMode|TaskCreate')",
          "validators": []
        },
        {
          "name": "within",
          "type_ref": "u32",
          "required": true,
          "default": "50",
          "description": "Look back this many recent allowed actions",
          "validators": []
        }
      ],
      "item_type": "",
      "variants": [],
      "inner_types": [],
      "description": "Configuration for Gate action: requires a prior allowed action within N recent actions",
      "owner_component": ""
    },
    {
      "name": "EnsureConfig",
      "kind": "struct",
      "fields": [
        {
          "name": "check",
          "type_ref": "String",
          "required": true,
          "default": "",
          "description": "Script name in .signet/checks/ to execute",
          "validators": []
        },
        {
          "name": "timeout",
          "type_ref": "u32",
          "required": true,
          "default": "5",
          "description": "Execution timeout in seconds",
          "validators": []
        },
        {
          "name": "message",
          "type_ref": "String",
          "required": true,
          "default": "\"\"",
          "description": "User-facing message if check fails",
          "validators": []
        }
      ],
      "item_type": "",
      "variants": [],
      "inner_types": [],
      "description": "Configuration for Ensure action: run a check script before allowing",
      "owner_component": ""
    },
    {
      "name": "PolicyRule",
      "kind": "struct",
      "fields": [
        {
          "name": "name",
          "type_ref": "String",
          "required": true,
          "default": "",
          "description": "Rule identifier",
          "validators": []
        },
        {
          "name": "tool_pattern",
          "type_ref": "String",
          "required": true,
          "default": "",
          "description": "Regex pattern matching tool names",
          "validators": []
        },
        {
          "name": "conditions",
          "type_ref": "Vec<String>",
          "required": true,
          "default": "[]",
          "description": "List of condition expressions (all must pass)",
          "validators": []
        },
        {
          "name": "action",
          "type_ref": "Decision",
          "required": true,
          "default": "",
          "description": "Action to take if rule matches",
          "validators": []
        },
        {
          "name": "reason",
          "type_ref": "Option<String>",
          "required": true,
          "default": "None",
          "description": "Human-readable reason for the action",
          "validators": []
        },
        {
          "name": "alternative",
          "type_ref": "Option<String>",
          "required": true,
          "default": "None",
          "description": "Suggested alternative if denied",
          "validators": []
        },
        {
          "name": "locked",
          "type_ref": "bool",
          "required": true,
          "default": "false",
          "description": "If true, rule protects policy infrastructure and cannot be bypassed",
          "validators": []
        },
        {
          "name": "gate",
          "type_ref": "Option<GateConfig>",
          "required": true,
          "default": "None",
          "description": "Gate configuration (required if action=Gate)",
          "validators": []
        },
        {
          "name": "ensure",
          "type_ref": "Option<EnsureConfig>",
          "required": true,
          "default": "None",
          "description": "Ensure configuration (required if action=Ensure)",
          "validators": []
        }
      ],
      "item_type": "",
      "variants": [],
      "inner_types": [],
      "description": "Single policy rule: regex pattern + conditions + action + metadata",
      "owner_component": ""
    },
    {
      "name": "PolicyConfig",
      "kind": "struct",
      "fields": [
        {
          "name": "version",
          "type_ref": "u32",
          "required": true,
          "default": "1",
          "description": "Policy schema version",
          "validators": []
        },
        {
          "name": "rules",
          "type_ref": "Vec<PolicyRule>",
          "required": true,
          "default": "[]",
          "description": "Ordered list of policy rules",
          "validators": []
        },
        {
          "name": "default_action",
          "type_ref": "Decision",
          "required": true,
          "default": "Decision::Allow",
          "description": "Action when no rules match",
          "validators": []
        }
      ],
      "item_type": "",
      "variants": [],
      "inner_types": [],
      "description": "Top-level policy configuration loaded from YAML",
      "owner_component": ""
    },
    {
      "name": "CompiledRule",
      "kind": "struct",
      "fields": [
        {
          "name": "name",
          "type_ref": "String",
          "required": true,
          "default": "",
          "description": "",
          "validators": []
        },
        {
          "name": "tool_regex",
          "type_ref": "Regex",
          "required": true,
          "default": "",
          "description": "Compiled regex from tool_pattern",
          "validators": []
        },
        {
          "name": "conditions",
          "type_ref": "Vec<String>",
          "required": true,
          "default": "",
          "description": "",
          "validators": []
        },
        {
          "name": "action",
          "type_ref": "Decision",
          "required": true,
          "default": "",
          "description": "",
          "validators": []
        },
        {
          "name": "reason",
          "type_ref": "Option<String>",
          "required": true,
          "default": "",
          "description": "",
          "validators": []
        },
        {
          "name": "alternative",
          "type_ref": "Option<String>",
          "required": true,
          "default": "",
          "description": "",
          "validators": []
        },
        {
          "name": "locked",
          "type_ref": "bool",
          "required": true,
          "default": "",
          "description": "",
          "validators": []
        },
        {
          "name": "gate",
          "type_ref": "Option<GateConfig>",
          "required": true,
          "default": "",
          "description": "",
          "validators": []
        },
        {
          "name": "ensure",
          "type_ref": "Option<EnsureConfig>",
          "required": true,
          "default": "",
          "description": "",
          "validators": []
        }
      ],
      "item_type": "",
      "variants": [],
      "inner_types": [],
      "description": "Policy rule with compiled regex for runtime evaluation",
      "owner_component": ""
    },
    {
      "name": "CompiledPolicy",
      "kind": "struct",
      "fields": [
        {
          "name": "rules",
          "type_ref": "Vec<CompiledRule>",
          "required": true,
          "default": "",
          "description": "Compiled rules in evaluation order",
          "validators": []
        },
        {
          "name": "default_action",
          "type_ref": "Decision",
          "required": true,
          "default": "",
          "description": "",
          "validators": []
        }
      ],
      "item_type": "",
      "variants": [],
      "inner_types": [],
      "description": "Runtime policy with all rules compiled",
      "owner_component": ""
    },
    {
      "name": "EvaluationResult",
      "kind": "struct",
      "fields": [
        {
          "name": "decision",
          "type_ref": "Decision",
          "required": true,
          "default": "",
          "description": "Final decision (Allow/Deny/Ask/Gate/Ensure)",
          "validators": []
        },
        {
          "name": "matched_rule",
          "type_ref": "Option<String>",
          "required": true,
          "default": "",
          "description": "Name of the rule that matched (None if default action used)",
          "validators": []
        },
        {
          "name": "matched_locked",
          "type_ref": "bool",
          "required": true,
          "default": "",
          "description": "True if the matched rule is a locked self-protection rule",
          "validators": []
        },
        {
          "name": "reason",
          "type_ref": "Option<String>",
          "required": true,
          "default": "",
          "description": "Human-readable reason for the decision",
          "validators": []
        },
        {
          "name": "evaluation_time_us",
          "type_ref": "u64",
          "required": true,
          "default": "",
          "description": "Evaluation duration in microseconds",
          "validators": []
        },
        {
          "name": "ensure_config",
          "type_ref": "Option<EnsureConfig>",
          "required": true,
          "default": "",
          "description": "Ensure configuration if decision=Ensure",
          "validators": []
        }
      ],
      "item_type": "",
      "variants": [],
      "inner_types": [],
      "description": "Result of evaluating a tool call against policy",
      "owner_component": ""
    },
    {
      "name": "ToolCall",
      "kind": "struct",
      "fields": [
        {
          "name": "tool_name",
          "type_ref": "String",
          "required": true,
          "default": "",
          "description": "Name of the tool being invoked",
          "validators": []
        },
        {
          "name": "parameters",
          "type_ref": "serde_json::Value",
          "required": true,
          "default": "",
          "description": "JSON object of tool parameters",
          "validators": []
        }
      ],
      "item_type": "",
      "variants": [],
      "inner_types": [],
      "description": "Tool call being evaluated: name + JSON parameters",
      "owner_component": ""
    }
  ],
  "functions": [
    {
      "name": "as_lowercase",
      "description": "Convert Decision enum variant to lowercase string representation",
      "inputs": [
        {
          "name": "self",
          "type_ref": "&Decision",
          "required": true,
          "default": "",
          "description": "",
          "validators": []
        }
      ],
      "output_type": "&'static str",
      "error_cases": [],
      "preconditions": [],
      "postconditions": [
        "Returns lowercase string matching enum variant name"
      ],
      "idempotent": false,
      "is_async": false,
      "side_effects": [],
      "structured_side_effects": [],
      "performance_budget": null
    },
    {
      "name": "default_gate_within",
      "description": "Default value for GateConfig.within field (serde default)",
      "inputs": [],
      "output_type": "u32",
      "error_cases": [],
      "preconditions": [],
      "postconditions": [
        "Returns 50"
      ],
      "idempotent": false,
      "is_async": false,
      "side_effects": [],
      "structured_side_effects": [],
      "performance_budget": null
    },
    {
      "name": "default_ensure_timeout",
      "description": "Default value for EnsureConfig.timeout field (serde default)",
      "inputs": [],
      "output_type": "u32",
      "error_cases": [],
      "preconditions": [],
      "postconditions": [
        "Returns 5"
      ],
      "idempotent": false,
      "is_async": false,
      "side_effects": [],
      "structured_side_effects": [],
      "performance_budget": null
    },
    {
      "name": "default_version",
      "description": "Default value for PolicyConfig.version field (serde default)",
      "inputs": [],
      "output_type": "u32",
      "error_cases": [],
      "preconditions": [],
      "postconditions": [
        "Returns 1"
      ],
      "idempotent": false,
      "is_async": false,
      "side_effects": [],
      "structured_side_effects": [],
      "performance_budget": null
    },
    {
      "name": "default_allow",
      "description": "Default value for PolicyConfig.default_action field (serde default)",
      "inputs": [],
      "output_type": "Decision",
      "error_cases": [],
      "preconditions": [],
      "postconditions": [
        "Returns Decision::Allow"
      ],
      "idempotent": false,
      "is_async": false,
      "side_effects": [],
      "structured_side_effects": [],
      "performance_budget": null
    },
    {
      "name": "from_config",
      "description": "Compile PolicyConfig into CompiledPolicy by compiling all rule regexes. Rules with invalid regexes are silently skipped.",
      "inputs": [
        {
          "name": "config",
          "type_ref": "&PolicyConfig",
          "required": true,
          "default": "",
          "description": "",
          "validators": []
        }
      ],
      "output_type": "CompiledPolicy",
      "error_cases": [],
      "preconditions": [],
      "postconditions": [
        "Returns CompiledPolicy with successfully compiled rules only",
        "Rules with invalid regex patterns are filtered out",
        "Rule order from config is preserved"
      ],
      "idempotent": false,
      "is_async": false,
      "side_effects": [],
      "structured_side_effects": [],
      "performance_budget": null
    },
    {
      "name": "evaluate_condition",
      "description": "Evaluate a single condition expression against a tool call. Supports: contains(), param_eq(), param_gt(), param_lt(), param_ne(), param_contains(), matches(), spend_gt(), spend_plus_amount_gt(), has_credential(), has_recent_action(), not(), or(), true, false, any_of(), contains_word(). Returns Ok(true) if condition passes, Ok(false) if fails, Err if invalid syntax or regex error.",
      "inputs": [
        {
          "name": "condition",
          "type_ref": "&str",
          "required": true,
          "default": "",
          "description": "Condition expression string",
          "validators": []
        },
        {
          "name": "call",
          "type_ref": "&ToolCall",
          "required": true,
          "default": "",
          "description": "Tool call being evaluated",
          "validators": []
        },
        {
          "name": "vault",
          "type_ref": "Option<&Vault>",
          "required": true,
          "default": "",
          "description": "Optional vault for spend/credential/action queries",
          "validators": []
        }
      ],
      "output_type": "Result<bool, String>",
      "error_cases": [
        {
          "name": "unknown_condition",
          "condition": "Condition function name not in KNOWN_CONDITION_FNS",
          "error_type": "String",
          "error_data": {}
        },
        {
          "name": "regex_compile_error",
          "condition": "Invalid regex pattern in matches() condition",
          "error_type": "String",
          "error_data": {}
        },
        {
          "name": "parse_error",
          "condition": "Cannot parse numeric threshold in param_gt/param_lt/spend_gt",
          "error_type": "String",
          "error_data": {}
        }
      ],
      "preconditions": [],
      "postconditions": [
        "Returns Ok(true) if all checks in condition pass",
        "Returns Ok(false) if any check fails",
        "Returns Err for unknown function names, invalid regex in matches(), parse errors"
      ],
      "idempotent": false,
      "is_async": false,
      "side_effects": [
        "Queries vault if condition uses spend_gt, spend_plus_amount_gt, has_credential, or has_recent_action"
      ],
      "structured_side_effects": [],
      "performance_budget": null
    },
    {
      "name": "evaluate",
      "description": "Evaluate a tool call against compiled policy. First-match-wins: iterates rules in order, returns on first match. Gate actions are resolved inline by querying vault. Ensure actions return decision=Ensure with config for caller to execute. Returns EvaluationResult with decision, matched rule, timing.",
      "inputs": [
        {
          "name": "call",
          "type_ref": "&ToolCall",
          "required": true,
          "default": "",
          "description": "",
          "validators": []
        },
        {
          "name": "policy",
          "type_ref": "&CompiledPolicy",
          "required": true,
          "default": "",
          "description": "",
          "validators": []
        },
        {
          "name": "vault",
          "type_ref": "Option<&Vault>",
          "required": true,
          "default": "",
          "description": "Optional vault for Gate resolution and condition evaluation",
          "validators": []
        }
      ],
      "output_type": "EvaluationResult",
      "error_cases": [],
      "preconditions": [],
      "postconditions": [
        "Returns first matched rule's action, or default_action if no match",
        "Gate actions are resolved to Allow or Deny based on vault query",
        "Ensure actions return decision=Ensure with ensure_config populated",
        "evaluation_time_us is always populated with microsecond-precision timing",
        "Condition evaluation errors cause the rule to not match (fall through to next rule)"
      ],
      "idempotent": false,
      "is_async": false,
      "side_effects": [
        "Queries vault for Gate resolution and condition evaluation (read-only)"
      ],
      "structured_side_effects": [],
      "performance_budget": null
    },
    {
      "name": "resolve_gate",
      "description": "Resolve a Gate action by checking vault's action log for the required prior action. Fails closed: returns false if vault is None.",
      "inputs": [
        {
          "name": "config",
          "type_ref": "&GateConfig",
          "required": true,
          "default": "",
          "description": "",
          "validators": []
        },
        {
          "name": "vault",
          "type_ref": "Option<&Vault>",
          "required": true,
          "default": "",
          "description": "",
          "validators": []
        }
      ],
      "output_type": "bool",
      "error_cases": [],
      "preconditions": [],
      "postconditions": [
        "Returns true if vault.has_recent_allowed_action() finds the requires_prior pattern within the specified window",
        "Returns false if vault is None (fail-closed)",
        "Returns false if no matching action found in vault"
      ],
      "idempotent": false,
      "is_async": false,
      "side_effects": [
        "Queries vault action log (read-only)"
      ],
      "structured_side_effects": [],
      "performance_budget": null
    },
    {
      "name": "load_policy",
      "description": "Load policy from YAML file. Falls back to default_policy() if file read or parse fails. Never panics.",
      "inputs": [
        {
          "name": "path",
          "type_ref": "&Path",
          "required": true,
          "default": "",
          "description": "",
          "validators": []
        }
      ],
      "output_type": "CompiledPolicy",
      "error_cases": [],
      "preconditions": [],
      "postconditions": [
        "Returns compiled policy from file if read and parse succeed",
        "Returns default_policy() if file cannot be read or YAML parse fails",
        "Never returns an error or panics"
      ],
      "idempotent": false,
      "is_async": false,
      "side_effects": [
        "Reads YAML file from filesystem"
      ],
      "structured_side_effects": [],
      "performance_budget": null
    },
    {
      "name": "load_policy_config",
      "description": "Load raw PolicyConfig from YAML file. Returns error if file cannot be read or YAML is invalid.",
      "inputs": [
        {
          "name": "path",
          "type_ref": "&Path",
          "required": true,
          "default": "",
          "description": "",
          "validators": []
        }
      ],
      "output_type": "Result<PolicyConfig, String>",
      "error_cases": [
        {
          "name": "file_read_error",
          "condition": "Cannot read file at path",
          "error_type": "String",
          "error_data": {}
        },
        {
          "name": "yaml_parse_error",
          "condition": "YAML deserialization fails",
          "error_type": "String",
          "error_data": {}
        }
      ],
      "preconditions": [],
      "postconditions": [
        "Returns parsed PolicyConfig on success"
      ],
      "idempotent": false,
      "is_async": false,
      "side_effects": [
        "Reads YAML file from filesystem"
      ],
      "structured_side_effects": [],
      "performance_budget": null
    },
    {
      "name": "validate_policy",
      "description": "Validate a PolicyConfig: check regex patterns compile, condition functions are known, Gate/Ensure configs are present and valid. Returns list of error strings (empty = valid).",
      "inputs": [
        {
          "name": "config",
          "type_ref": "&PolicyConfig",
          "required": true,
          "default": "",
          "description": "",
          "validators": []
        }
      ],
      "output_type": "Vec<String>",
      "error_cases": [],
      "preconditions": [],
      "postconditions": [
        "Returns empty Vec if policy is valid",
        "Returns Vec of error messages for: invalid regex, unknown condition functions, missing/invalid Gate config, missing/invalid Ensure config, out-of-range gate.within or ensure.timeout"
      ],
      "idempotent": false,
      "is_async": false,
      "side_effects": [],
      "structured_side_effects": [],
      "performance_budget": null
    },
    {
      "name": "validate_ensure_check_name",
      "description": "Validate that a check script name is safe: no slashes, no .., no null bytes, no control chars, not empty.",
      "inputs": [
        {
          "name": "name",
          "type_ref": "&str",
          "required": true,
          "default": "",
          "description": "",
          "validators": []
        }
      ],
      "output_type": "Result<(), String>",
      "error_cases": [
        {
          "name": "empty_name",
          "condition": "name.is_empty()",
          "error_type": "String",
          "error_data": {}
        },
        {
          "name": "path_separator",
          "condition": "name contains '/' or '\\\\'",
          "error_type": "String",
          "error_data": {}
        },
        {
          "name": "path_traversal",
          "condition": "name contains '..'",
          "error_type": "String",
          "error_data": {}
        },
        {
          "name": "null_byte",
          "condition": "name contains null byte",
          "error_type": "String",
          "error_data": {}
        },
        {
          "name": "control_char",
          "condition": "name contains control characters (< 0x20, except tab)",
          "error_type": "String",
          "error_data": {}
        }
      ],
      "preconditions": [],
      "postconditions": [
        "Returns Ok(()) if name is safe"
      ],
      "idempotent": false,
      "is_async": false,
      "side_effects": [],
      "structured_side_effects": [],
      "performance_budget": null
    },
    {
      "name": "resolve_ensure_script_path",
      "description": "Resolve and validate the full path for an ensure check script in .signet/checks/. Returns canonicalized path if valid, error if path escapes checks directory or cannot be resolved.",
      "inputs": [
        {
          "name": "check_name",
          "type_ref": "&str",
          "required": true,
          "default": "",
          "description": "",
          "validators": []
        }
      ],
      "output_type": "Result<std::path::PathBuf, String>",
      "error_cases": [
        {
          "name": "invalid_name",
          "condition": "check_name fails validate_ensure_check_name()",
          "error_type": "String",
          "error_data": {}
        },
        {
          "name": "cannot_resolve",
          "condition": "canonicalize() fails (file not found or permission error)",
          "error_type": "String",
          "error_data": {}
        },
        {
          "name": "path_escape",
          "condition": "Canonical path is not within checks directory",
          "error_type": "String",
          "error_data": {}
        }
      ],
      "preconditions": [
        "check_name passes validate_ensure_check_name()"
      ],
      "postconditions": [
        "Returns canonicalized path if script exists and is within checks directory",
        "Path is guaranteed to be within .signet/checks/"
      ],
      "idempotent": false,
      "is_async": false,
      "side_effects": [
        "Calls canonicalize() which accesses filesystem metadata"
      ],
      "structured_side_effects": [],
      "performance_budget": null
    },
    {
      "name": "self_protection_rules",
      "description": "Generate locked self-protection rules that prevent AI from tampering with policy infrastructure. Returns 8 locked rules: protect_checks_dir (highest priority), protect_signet_dir, protect_signet_binary, protect_hook_config, protect_signet_symlink, protect_signet_process, protect_preflight_storage, github_identity_guard.",
      "inputs": [],
      "output_type": "Vec<PolicyRule>",
      "error_cases": [],
      "preconditions": [],
      "postconditions": [
        "Returns exactly 8 PolicyRule instances",
        "All rules have locked=true",
        "First rule is protect_checks_dir (must be evaluated before all others)",
        "Rules protect: .signet/checks/, .signet/, signet-eval binary, settings.json, symlinks to signet, kill/pkill/killall signet, preflight DB, git remote operations"
      ],
      "idempotent": false,
      "is_async": false,
      "side_effects": [],
      "structured_side_effects": [],
      "performance_budget": null
    },
    {
      "name": "default_policy",
      "description": "Generate the default policy: self_protection_rules() + standard safety rules (plan-before-code, protect core files, block rm/force-push/piped-exec/credential-writes/chmod-777, etc). Default action is Allow.",
      "inputs": [],
      "output_type": "CompiledPolicy",
      "error_cases": [],
      "preconditions": [],
      "postconditions": [
        "Returns compiled policy with 8 locked rules + ~8 standard rules",
        "Self-protection rules are first in evaluation order",
        "Default action is Decision::Allow"
      ],
      "idempotent": false,
      "is_async": false,
      "side_effects": [],
      "structured_side_effects": [],
      "performance_budget": null
    },
    {
      "name": "split_at_top_level",
      "description": "Split string at first occurrence of separator where parenthesis depth is 0. Returns Some((left, right)) if found, None otherwise. Used for parsing or() conditions.",
      "inputs": [
        {
          "name": "s",
          "type_ref": "&str",
          "required": true,
          "default": "",
          "description": "",
          "validators": []
        },
        {
          "name": "separator",
          "type_ref": "&str",
          "required": true,
          "default": "",
          "description": "",
          "validators": []
        }
      ],
      "output_type": "Option<(&str, &str)>",
      "error_cases": [],
      "preconditions": [],
      "postconditions": [
        "Returns Some((before_sep, after_sep)) if separator found at depth 0",
        "Returns None if separator not found at depth 0 or separator is empty",
        "Tracks parenthesis depth correctly: '(' increments, ')' decrements (saturating)"
      ],
      "idempotent": false,
      "is_async": false,
      "side_effects": [],
      "structured_side_effects": [],
      "performance_budget": null
    },
    {
      "name": "strip_fn",
      "description": "Extract arguments from a function call string. If s matches 'name(args)', returns Some(args). Returns None otherwise.",
      "inputs": [
        {
          "name": "s",
          "type_ref": "&str",
          "required": true,
          "default": "",
          "description": "",
          "validators": []
        },
        {
          "name": "name",
          "type_ref": "&str",
          "required": true,
          "default": "",
          "description": "",
          "validators": []
        }
      ],
      "output_type": "Option<&str>",
      "error_cases": [],
      "preconditions": [],
      "postconditions": [
        "Returns Some(args) if s is 'name(args)' with matching parentheses",
        "Returns None if s does not start with name or lacks matching parens"
      ],
      "idempotent": false,
      "is_async": false,
      "side_effects": [],
      "structured_side_effects": [],
      "performance_budget": null
    },
    {
      "name": "extract_quoted",
      "description": "Extract string content from single or double quoted string. Returns Some(unquoted_string) if s is quoted, None otherwise.",
      "inputs": [
        {
          "name": "s",
          "type_ref": "&str",
          "required": true,
          "default": "",
          "description": "",
          "validators": []
        }
      ],
      "output_type": "Option<String>",
      "error_cases": [],
      "preconditions": [],
      "postconditions": [
        "Returns Some(content) if s is wrapped in matching single or double quotes",
        "Returns None if s is not quoted"
      ],
      "idempotent": false,
      "is_async": false,
      "side_effects": [],
      "structured_side_effects": [],
      "performance_budget": null
    },
    {
      "name": "param_str",
      "description": "Extract string parameter value from JSON parameters object. Returns empty string if field not found or not a string.",
      "inputs": [
        {
          "name": "params",
          "type_ref": "&serde_json::Value",
          "required": true,
          "default": "",
          "description": "",
          "validators": []
        },
        {
          "name": "field",
          "type_ref": "&str",
          "required": true,
          "default": "",
          "description": "",
          "validators": []
        }
      ],
      "output_type": "String",
      "error_cases": [],
      "preconditions": [],
      "postconditions": [
        "Returns field value as String if present and is string type",
        "Returns empty string if field not found or not a string"
      ],
      "idempotent": false,
      "is_async": false,
      "side_effects": [],
      "structured_side_effects": [],
      "performance_budget": null
    },
    {
      "name": "param_f64",
      "description": "Extract numeric parameter value from JSON parameters object. Tries as_f64() first, then parses as string. Returns 0.0 if field not found or not numeric.",
      "inputs": [
        {
          "name": "params",
          "type_ref": "&serde_json::Value",
          "required": true,
          "default": "",
          "description": "",
          "validators": []
        },
        {
          "name": "field",
          "type_ref": "&str",
          "required": true,
          "default": "",
          "description": "",
          "validators": []
        }
      ],
      "output_type": "f64",
      "error_cases": [],
      "preconditions": [],
      "postconditions": [
        "Returns field value as f64 if present and numeric or parseable string",
        "Returns 0.0 if field not found or cannot be parsed as number"
      ],
      "idempotent": false,
      "is_async": false,
      "side_effects": [],
      "structured_side_effects": [],
      "performance_budget": null
    }
  ],
  "dependencies": [
    "regex",
    "serde",
    "serde_yaml",
    "serde_json",
    "std::path",
    "std::time",
    "crate::vault"
  ],
  "dependency_contracts": {},
  "invariants": [
    "KNOWN_CONDITION_FNS: List of valid condition function names for validation",
    "First-match-wins rule evaluation order is always preserved",
    "Self-protection rules are always first in default_policy() evaluation order",
    "protect_checks_dir is always the first rule in self_protection_rules()",
    "All self-protection rules have locked=true",
    "Gate actions without vault fail closed (deny)",
    "Condition evaluation errors cause rule to not match (fail-safe)",
    "Invalid regexes in PolicyConfig are silently filtered during compilation",
    "default_gate_within() = 50",
    "default_ensure_timeout() = 5",
    "default_version() = 1",
    "default_allow() = Decision::Allow"
  ],
  "requires": [
    "Vault component must provide: session_spend(category), credential_exists(name), has_recent_allowed_action(search, within)",
    "Vault component must provide: log_action() for testing",
    "crate::vault::signet_dir() must return base directory path"
  ],
  "processing_register": "",
  "data_access": {
    "reads": [],
    "writes": [],
    "rationale": "",
    "side_effects": []
  },
  "authority": {
    "domains": [],
    "rationale": null
  }
}