symfonic.capabilities.governance.stages¶
stages ¶
The seven governed concerns, one module each (T3.4.4).
BudgetLimits
dataclass
¶
None measures without capping; a number caps.
Zero is refused rather than read as "unlimited": a deployment that
typed 0 meant "nothing", and silently reading that as "everything"
is the most expensive possible misreading.
BudgetStage ¶
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
CredentialHygieneStage ¶
Drop credential-shaped keys before any other stage observes them.
Source code in src/symfonic/capabilities/governance/stages/credentials.py
FabricationStage ¶
FabricationStage(detector: FabricationDetector | None, *, min_confidence: float = 0.6, refuse_min_confidence: float | None = 0.9)
Scan the draft, cross-check the intent, and report what is unsupported.
Source code in src/symfonic/capabilities/governance/stages/fabrication.py
IntentFilterStage ¶
MetacognitionStage ¶
MetacognitionStage(reflector: Reflector | None, *, confidence_floor: float = 0.6, sensitive_terms: Sequence[str] = (), sensitive_tags: Sequence[str] = (), read_only_tools: Sequence[str] = (), trivial_ack_patterns: Sequence[str] = (), confidence: ConfidenceReporter | None = None, trigger_policy: MetacognitionTriggerPolicy | None = None)
Reflect on the draft when, and only when, the gate fires.
Source code in src/symfonic/capabilities/governance/stages/metacognition.py
ObjectionSweep
dataclass
¶
ObjectionSweep(findings: tuple[Finding, ...] = (), checked: int = 0, degraded: tuple[str, ...] = ())
What every objector said about every call, and which ones broke.
amendments
property
¶
The findings that name a rule which rewrote a call.
objections
property
¶
The findings that mean this call is not admissible.
Separate from amendments because a stage steers on one and not
the other: a rule that fixed the call did not object to it, and a
stage that steered on a successful repair would refuse the very call
the repair made admissible.
PolicySteeringStage ¶
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
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
ToolPreconditionStage ¶
check_reporter ¶
The reporter, or a refusal raised where nothing will contain it.
This stage is FAIL_OPEN: the pipeline catches whatever apply
raises and allows the turn. So a per-turn refusal cannot protect a
composed caller -- it produces the disabled gate :func:_validated
exists to prevent, recorded in degraded_stages and nowhere a caller
is obliged to look. A port that can never work is knowable before any
turn runs, and construction happens outside the containment boundary, so
that is where it is refused.
An async reporter is the mistake worth naming: :class:Reflector sits
beside this port and is async, and runtime_checkable cannot tell
them apart because it only checks that the method exists. Left to run, it
returns an un-awaited coroutine every turn -- a warning, a leak, and a
gate that quietly stopped guarding.
Source code in src/symfonic/capabilities/governance/stages/metacognition_validation.py
compile_credential_pattern ¶
None -> the default set; [] -> disabled; otherwise a replacement.
An invalid fragment raises re.error here, at construction, rather
than at scrub time: a misconfigured pattern list must fail while the
deployment is being built, not while a secret is passing through it.
Source code in src/symfonic/capabilities/governance/stages/credentials.py
sweep ¶
sweep(objectors: Sequence[Objector], calls: Sequence[ToolCall], subject: GovernanceSubject, *, kind: str) -> ObjectionSweep
Ask each applicable objector about each call.
tool_name on the objector scopes it to one tool; an objector that
omits the attribute is asked about every call. An objector that raises
is skipped for that call and named in degraded โ the finding it
might have produced is unknowable, and pretending otherwise in either
direction (admit silently, or refuse) would be a guess.