Skip to content

Custom policies silently receive empty ctx.paramspolicyParams config is ignored for them #585

Description

@chhhee10

Summary

PolicyContext exposes params, and policies-config.json has a policyParams map, so a custom policy appears configurable from config. It is not — custom policies always receive params: {}, silently.

Cause

POLICY_PARAMS_MAP is built only from BUILTIN_POLICIES entries that declare a params schema:

https://github.com/FailproofAI/failproofai/blob/main/src/hooks/policy-evaluator.ts#L31-L35

A CustomHook has no params schema (CustomHook in policy-types.ts:68-75 declares only name/description/match/fn), so lookup misses and it falls to the else-branch:

// policy-evaluator.ts:104-105
// Custom hooks and policies without schema get empty params
ctx = { ...baseCtx, params: {} };

Impact

Adding this to policies-config.json does nothing, with no warning:

{ "policyParams": { "my-custom-policy": { "threshold": 10 } } }

The failure is silent in both directions — the config key is accepted, and ctx.params is a valid empty object rather than undefined, so a policy reading ctx.params.threshold gets undefined and typically falls through to its default. Users have no signal that the value never arrived.

The comment at :104 reads as deliberate, so this may be intended. If so the gap is documentation plus a warning; if not, custom policies need a params channel.

Workaround

Hardcode values as module constants in the policy file, or read config/env directly inside fn.

Possible fixes

  1. Let CustomHook declare an optional params schema, and resolve it the same way builtins are.
  2. Pass config.policyParams[<custom name>] through unresolved (no schema, no defaults) — smaller change, no type addition.
  3. Keep current behavior, but warn at load time when policyParams names a policy that is not a builtin, and document the limitation.

Found while building a policy-authoring skill; it was a genuine surprise that survived reading the public types.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions