Skip to content

symfonic.capabilities.governance.stages.metacognition_policy

metacognition_policy

The deterministic evidence policy used before calling the reflector.

This is deliberately a governance-local translation of the legacy selective gate. It does not import the legacy middleware: callers hand governance the facts that middleware once had, and this policy names which fact fired.

ConfidenceOnlyMetacognitionPolicy

ConfidenceOnlyMetacognitionPolicy(*, confidence_floor: float = 0.6, sensitive_terms: Sequence[str] = ())

The pre-FP-1 capability policy, retained as an explicit cost opt-out.

It intentionally does not preserve the legacy selective hard floors. A deployment choosing it accepts that numbers, tool actions, recalled tags, findings, and intent do not by themselves request reflection.

Source code in src/symfonic/capabilities/governance/stages/metacognition_policy.py
def __init__(
    self, *, confidence_floor: float = 0.6, sensitive_terms: Sequence[str] = ()
) -> None:
    self._floor = validate_floor(confidence_floor)
    self._sensitive_terms = frozenset(term.lower() for term in sensitive_terms if term)

SelectiveMetacognitionPolicy

SelectiveMetacognitionPolicy(*, confidence_floor: float = 0.6, sensitive_terms: Sequence[str] = (), sensitive_tags: Sequence[str] = (), read_only_tools: Sequence[str] = (), trivial_ack_patterns: Sequence[str] = ())

Preserve the legacy selective gate's hard floors on the capability path.

A scalar confidence is supplemental evidence. It can never stand in for claims, actions, detector findings, or recall-time sensitivity.

Source code in src/symfonic/capabilities/governance/stages/metacognition_policy.py
def __init__(
    self,
    *,
    confidence_floor: float = 0.6,
    sensitive_terms: Sequence[str] = (),
    sensitive_tags: Sequence[str] = (),
    read_only_tools: Sequence[str] = (),
    trivial_ack_patterns: Sequence[str] = (),
) -> None:
    self._floor = validate_floor(confidence_floor)
    self._sensitive_terms = frozenset(term.lower() for term in sensitive_terms if term)
    self._sensitive_tags = frozenset(tag.lower() for tag in sensitive_tags if tag)
    self._read_only = frozenset(read_only_tools)
    self._ack_patterns = tuple(trivial_ack_patterns) or _ACK_PATTERNS

trigger

trigger(subject: GovernanceSubject, context: GovernanceContext, confidence: float | None) -> str | None

Return a stable trigger name, or None for a trivial ack.

Source code in src/symfonic/capabilities/governance/stages/metacognition_policy.py
def trigger(
    self,
    subject: GovernanceSubject,
    context: GovernanceContext,
    confidence: float | None,
) -> str | None:
    """Return a stable trigger name, or ``None`` for a trivial ack."""
    draft = subject.draft
    lowered = draft.lower()
    term = next((term for term in self._sensitive_terms if term in lowered), None)
    if term is not None:
        return f"sensitive_term:{term}"
    tag = self._recalled_tag(subject)
    if tag is not None:
        return f"recalled_sensitive_tag:{tag}"
    if self._findings(context):
        return "fabrication_finding"
    if any(call.name not in self._read_only for call in subject.tool_calls):
        return "mutating_tool"
    if getattr(context.intent, "label", None) in {"action", "ambiguous"}:
        return f"intent:{context.intent.label}"
    if any(pattern.search(draft) for pattern in _CLAIM_PATTERNS):
        return "draft_claim"
    if self._is_trivial_ack(draft):
        return None
    if confidence is not None:
        return "confidence_below_floor" if confidence < self._floor else "substantive_draft"
    return "substantive_draft"