|
Entropic 2.11.1
Local-first agentic inference engine
|
Post-generation constitutional compliance validator. More...
#include <entropic/core/constitutional_validator.h>
Public Member Functions | |
| ConstitutionalValidator (const ConstitutionalValidationConfig &config, const std::string &constitution_text) | |
| Construct validator with config and constitution text. | |
| entropic_error_t | attach (HookInterface *hook_iface, InferenceInterface *inference) |
| Register this validator as a POST_GENERATE hook. | |
| void | detach (HookInterface *hook_iface) |
| Deregister the POST_GENERATE hook. | |
| bool | should_validate (const std::string &identity_name) const |
| Check if validation is enabled for a given identity. | |
| void | set_identity_validation (const std::string &identity_name, bool enabled) |
| Set per-identity validation override. | |
| void | set_tier_rules (const std::string &identity_name, const std::vector< std::string > &rules) |
| Set per-identity validation rules from frontmatter. | |
| void | set_global_enabled (bool enabled) |
| Toggle the global validation gate at runtime. | |
| void | set_marker_resolver (std::function< std::pair< std::string, std::string >(const std::string &)> resolver) |
| Register a per-tier reasoning-delimiter resolver (gh#108). | |
| ValidationResult | validate (const std::string &content, const std::string &tier, const char *messages_json) |
| Run the validation pipeline on generated content. | |
| ValidationResult | last_result () const |
| Get the last validation result. | |
| void | set_auto_retry (bool enabled) |
| Enable or disable automatic revision after rejection. | |
| bool | auto_retry_enabled () const |
| Whether auto-revision is currently enabled. | |
| entropic_error_t | resume_retry () |
| Resume the revision pass after a paused validation. | |
| entropic_error_t | accept_last () |
| Finalize the cached attempt as the validation result. | |
| void | set_attempt_boundary_cb (void(*cb)(int attempt_n, void *user_data), void *user_data) |
| Register the attempt-boundary callback. | |
| void | set_critique_callbacks (void(*start_cb)(void *user_data), void(*end_cb)(void *user_data), void *user_data) |
| Register the critique start/end callback pair (gh#50). | |
| const ConstitutionalValidationConfig & | config () const |
| Get the config (read-only after construction). | |
| std::string | build_critique_prompt (const std::string &content) const |
| Build the critique prompt (exposed for testing). | |
Static Public Member Functions | |
| static int | hook_callback (entropic_hook_point_t hook_point, const char *context_json, char **modified_json, void *user_data) |
| POST_GENERATE hook callback for constitutional validation. | |
| static CritiqueResult | parse_critique (const std::string &json_str) |
| Parse critique JSON into structured result (exposed for testing). | |
Post-generation constitutional compliance validator.
Evaluates engine output against constitutional rules using a grammar-constrained critique generation pass, parses a structured JSON verdict, and optionally re-generates with feedback when violations are found.
Definition at line 84 of file constitutional_validator.h.
| entropic::ConstitutionalValidator::ConstitutionalValidator | ( | const ConstitutionalValidationConfig & | config, |
| const std::string & | constitution_text | ||
| ) |
Construct validator with config and constitution text.
| config | Validation pipeline configuration. |
| constitution_text | Full constitution text (from PromptManager). |
| config | Validation pipeline configuration. |
| constitution_text | Full constitution text. |
Definition at line 38 of file constitutional_validator.cpp.
| entropic_error_t entropic::ConstitutionalValidator::accept_last | ( | ) |
Finalize the cached attempt as the validation result.
Finalize the paused attempt as the consumer-accepted answer.
Used after set_auto_retry(false) paused validation: marks the paused attempt as the consumer-accepted answer (verdict becomes passed_consumer_override) and clears the cached pending state.
Marks verdict as passed_consumer_override and clears pending state. Returns INVALID_STATE if no pending state exists.
Definition at line 202 of file constitutional_validator.cpp.
| entropic_error_t entropic::ConstitutionalValidator::attach | ( | HookInterface * | hook_iface, |
| InferenceInterface * | inference | ||
| ) |
Register this validator as a POST_GENERATE hook.
Register as POST_GENERATE hook via the HookRegistry C API.
| hook_iface | HookInterface for registration (via fire_post). |
| inference | InferenceInterface for critique generation. |
| hook_iface | HookInterface with registry pointer. |
| inference | InferenceInterface for critique generation. |
Definition at line 56 of file constitutional_validator.cpp.
| bool entropic::ConstitutionalValidator::auto_retry_enabled | ( | ) | const |
Whether auto-revision is currently enabled.
Read auto-revision flag.
Definition at line 157 of file constitutional_validator.cpp.
| std::string entropic::ConstitutionalValidator::build_critique_prompt | ( | const std::string & | content | ) | const |
Build the critique prompt (exposed for testing).
Build the critique prompt string.
| content | Text to critique. |
When per-tier validation_rules exist (from identity frontmatter), those are the PRIMARY evaluation criteria and the constitution is included as background context. This prevents the validator from citing global constitution rule numbers ("Rule 2: Tool calls are mandatory") when the tier has its own specific compliance criteria.
When no validation_rules exist, falls back to the constitution as the sole rubric (pre-v2.0.8 behavior).
Prepends a tool call manifest (from current_tool_context_) when available so the validator can distinguish grounded claims from ungrounded assertions.
| content | Text to critique (think blocks already stripped). |
Definition at line 441 of file constitutional_validator.cpp.
|
inline |
Get the config (read-only after construction).
Definition at line 317 of file constitutional_validator.h.
| void entropic::ConstitutionalValidator::detach | ( | HookInterface * | hook_iface | ) |
Deregister the POST_GENERATE hook.
| hook_iface | HookInterface for deregistration. @req REQ-HOOK-002 |
| hook_iface | HookInterface with registry pointer. @req REQ-HOOK-002 |
Definition at line 80 of file constitutional_validator.cpp.
|
static |
POST_GENERATE hook callback for constitutional validation.
POST_GENERATE hook callback.
Static function registered with HookRegistry. Extracts ValidationContext from user_data, runs the validation pipeline, and writes modified_json if content was revised.
| hook_point | Hook point (POST_GENERATE). |
| context_json | JSON context from engine. |
| modified_json | Output: revised JSON or NULL. |
| user_data | ValidationContext pointer. |
| hook_point | Hook point (POST_GENERATE). |
| context_json | JSON context from engine. |
| modified_json | Output: revised JSON or NULL. |
| user_data | ValidationContext pointer. |
Definition at line 404 of file constitutional_validator.cpp.
| ValidationResult entropic::ConstitutionalValidator::last_result | ( | ) | const |
Get the last validation result.
Definition at line 387 of file constitutional_validator.cpp.
|
static |
Parse critique JSON into structured result (exposed for testing).
Parse critique JSON into CritiqueResult.
| json_str | Raw JSON string from grammar-constrained generation. |
| json_str | Raw JSON from grammar-constrained generation. |
Definition at line 503 of file constitutional_validator.cpp.
| entropic_error_t entropic::ConstitutionalValidator::resume_retry | ( | ) |
Resume the revision pass after a paused validation.
Resume the revision loop after a paused validation.
Re-enters apply_revisions() using the state cached by the most recent validate() call that paused on a critique failure. Runs synchronously and updates last_result_. Returns ENTROPIC_ERROR_INVALID_STATE if no validation is paused.
Pops the cached pending state, runs apply_revisions() against it ignoring the auto_retry_enabled_ flag for this call, and stores the final result. Returns INVALID_STATE if no pending state exists.
Definition at line 172 of file constitutional_validator.cpp.
| void entropic::ConstitutionalValidator::set_attempt_boundary_cb | ( | void(*)(int attempt_n, void *user_data) | cb, |
| void * | user_data | ||
| ) |
Register the attempt-boundary callback.
Fires immediately before each revision attempt starts. Used by consumers to split rendered output between attempts.
| cb | Callback (nullable clears). |
| user_data | Forwarded to cb. @req REQ-VALID-003 |
| cb | Callback fn pointer. |
| user_data | Forwarded to cb. @req REQ-VALID-003 |
Definition at line 227 of file constitutional_validator.cpp.
| void entropic::ConstitutionalValidator::set_auto_retry | ( | bool | enabled | ) |
Enable or disable automatic revision after rejection.
Toggle auto-revision.
When disabled, validate() returns immediately on the first failing critique with verdict paused_pending_consumer and caches enough state for resume_retry() to continue the revision loop later. Default: true (preserves pre-2.1.5 behavior).
| enabled | Whether auto-revision is enabled. @req REQ-VALID-003 |
| enabled | True to enable auto-revision. @req REQ-VALID-003 |
Definition at line 147 of file constitutional_validator.cpp.
| void entropic::ConstitutionalValidator::set_critique_callbacks | ( | void(*)(void *user_data) | start_cb, |
| void(*)(void *user_data) | end_cb, | ||
| void * | user_data | ||
| ) |
Register the critique start/end callback pair (gh#50).
Register critique start/end callbacks (gh#50, v2.1.12).
Fires immediately before and after the synchronous inference_->generate() call inside run_critique(). Gives consumer UIs a visible signal for the 20-30s critique window that previously left AgentState parked at EXECUTING with no observable transition. Both callbacks take only the user_data pointer — consumer correlates timing themselves.
Persistent-slot pattern: outlives set_callbacks() shuffles (validator owns its own slot, no entanglement with EngineCallbacks). Same survival contract as set_attempt_boundary_cb and the v2.1.10 state observer.
start_cb and end_cb are nullable independently; passing nullptr for both clears the slot.
| start_cb | Fires before the critique generate begins. |
| end_cb | Fires after the critique generate returns. |
| user_data | Forwarded to both callbacks. @threadsafety Thread-safe (guarded by critique_cbs_mutex_). @req REQ-VALID-003 |
Stored under critique_cbs_mutex_ so a consumer reassigning the slot cannot race with the firing site in run_critique(). Either callback pointer may be nullptr independently — only the non-null ones fire.
| start_cb | Pre-generate hook. |
| end_cb | Post-generate hook. |
| user_data | Forwarded to both. @req REQ-VALID-003 |
Definition at line 248 of file constitutional_validator.cpp.
| void entropic::ConstitutionalValidator::set_global_enabled | ( | bool | enabled | ) |
Toggle the global validation gate at runtime.
Per-identity overrides set via set_identity_validation() still take precedence; this only changes the fallback value used when no per-identity override exists.
| enabled | true to enable validation globally, false to disable. @req REQ-VALID-001 |
| enabled | New global enable state. @req REQ-VALID-001 |
Definition at line 121 of file constitutional_validator.cpp.
| void entropic::ConstitutionalValidator::set_identity_validation | ( | const std::string & | identity_name, |
| bool | enabled | ||
| ) |
Set per-identity validation override.
| identity_name | Identity name. |
| enabled | Whether validation is enabled for this identity. @req REQ-VALID-001 |
| identity_name | Identity name. |
| enabled | Whether validation is enabled. @req REQ-VALID-001 |
Definition at line 265 of file constitutional_validator.cpp.
| void entropic::ConstitutionalValidator::set_marker_resolver | ( | std::function< std::pair< std::string, std::string >(const std::string &)> | resolver | ) |
Register a per-tier reasoning-delimiter resolver (gh#108).
One validator serves every tier, but thinking format is per-family: Qwen/Nemotron use <think>…</think>, Gemma-4 QAT uses <|channel>…<channel|>. A single fixed pair would be wrong for any config mixing families, so the delimiters are resolved per call from the tier name validate() already receives.
The facade supplies the lambda (it can see ChatAdapter); the callback trades in plain strings so core keeps no dependency on inference. Unset, the <think> default applies.
| resolver | Maps tier name → {open, close}. @req REQ-VALID-001 |
| resolver | Maps tier name → {open, close}. @req REQ-VALID-001 |
Definition at line 132 of file constitutional_validator.cpp.
| void entropic::ConstitutionalValidator::set_tier_rules | ( | const std::string & | identity_name, |
| const std::vector< std::string > & | rules | ||
| ) |
Set per-identity validation rules from frontmatter.
| identity_name | Identity/tier name. |
| rules | Validation rules specific to this identity. |
| identity_name | Identity/tier name. |
| rules | Validation rules for this identity. @dg_internal |
Definition at line 278 of file constitutional_validator.cpp.
| bool entropic::ConstitutionalValidator::should_validate | ( | const std::string & | identity_name | ) | const |
Check if validation is enabled for a given identity.
Returns false if the tier is in config_.skip_tiers (e.g. "lead"). Per-identity overrides (set_identity_validation) take precedence.
| identity_name | Identity name to check. |
Returns false if the tier is in config_.skip_tiers (e.g. "lead", which streams output before the POST_GENERATE hook fires). Per-identity overrides take precedence over skip_tiers.
| identity_name | Identity name to check. |
Definition at line 101 of file constitutional_validator.cpp.
| ValidationResult entropic::ConstitutionalValidator::validate | ( | const std::string & | content, |
| const std::string & | tier, | ||
| const char * | messages_json | ||
| ) |
Run the validation pipeline on generated content.
Run the full validation pipeline on generated content.
| content | The generated text to validate. |
| tier | The tier/identity that produced the content. |
| messages_json | The conversation context (for revision). |
Called from the POST_GENERATE hook callback. Flow:
@req REQ-VALID-001 @req REQ-VALID-002
When called from handle_hook(), current_tool_context_ and current_system_prompt_ are set before this call so that build_critique_prompt() and inject_feedback_into_messages() have the per-turn context they need.
| content | The generated text to validate. |
| tier | The tier/identity that produced the content. |
| messages_json | Original conversation context. |
Definition at line 301 of file constitutional_validator.cpp.