Skip to content

Governance controls

ZettelForge 2.8.0 validates memory writes and recall queries before they reach storage or retrieval. Use this reference to confirm the implemented content limit, prompt-injection guard, optional PII handling, recall timeout behavior, and write-time anomaly gate.

Prerequisites: Install ZettelForge with the Quickstart, then use the Configuration reference to locate your active config.yaml.

In progress: three configured controls do not fully enforce their intent

governance.enabled and governance.min_content_length exist in the configuration dataclass, but the ZettelForge 2.8.0 write path does not pass them into GovernanceValidator. Setting enabled: false does not disable the implemented checks, and min_content_length does not reject short or empty strings.

governance.limits.recall_timeout_seconds detects an overrun and changes the result to an empty list. The current executor waits for the retrieval worker to finish before returning control, so this setting is not a hard wall-clock latency cap.

Direct write path

The default mm.remember(content) path applies controls in this order:

  1. Structural validation rejects values that are neither strings nor objects with a content attribute. The public remember() signature declares content as a string.
  2. Content length rejects content above governance.limits.max_content_length when the value is greater than zero.
  3. Prompt-injection detection rejects the first matching hostile pattern.
  4. PII handling runs when governance.pii.enabled is true and the optional analyzer is available.
  5. Note construction builds the memory note from the accepted or redacted content.
  6. Memory anomaly evaluation compares the note with recent same-domain reference notes.
  7. Storage and indexing write the note and then update the vector index.

Content-limit, prompt-injection, and blocking PII failures raise GovernanceViolationError before note construction. A flagged anomaly raises MemoryAnomalyError in block or quarantine mode. An unexpected anomaly evaluation error is logged and the write continues.

Recall path

mm.recall(query) checks the query with the same prompt-injection guard before retrieval. A match raises PromptInjectionError immediately.

When recall_timeout_seconds is greater than zero, recall runs in a worker. An overrun records recall_timed_out and discards the worker result by returning an empty list after the worker finishes. A value of 0 runs retrieval without the timeout wrapper.

Configuration reference

All keys live under the governance block in config.yaml.

Top-level keys

Key Default Environment variable Runtime state
enabled true none Defined but not wired into the 2.8.0 validator or write path.
min_content_length 1 none Defined but not enforced by the 2.8.0 validator.

governance.limits

Key Default Environment variable Runtime behavior
max_content_length 52428800 ZETTELFORGE_LIMITS_MAX_CONTENT_LENGTH Rejects remember() content when len(content) exceeds the value. 0 disables the check. The current exception text says “bytes,” but the implementation counts Python string characters.
recall_timeout_seconds 30.0 ZETTELFORGE_LIMITS_RECALL_TIMEOUT Marks an overrun and returns [] after the retrieval worker finishes. 0 disables the wrapper.

governance.pii

PII detection is disabled by default. It requires the pii optional extra, which installs Microsoft Presidio and spaCy support. If you enable PII handling without a usable analyzer, validation logs pii_validation_skipped and stores the original content.

Key Default Environment variable Runtime behavior
enabled false ZETTELFORGE_PII_ENABLED Enables PII analysis before storage.
action "log" ZETTELFORGE_PII_ACTION Selects log, redact, or block.
redact_placeholder "[REDACTED]" none Replaces every selected PII span in redact mode.
entities [] none Detects every supported type except the CTI allowlist. A non-empty list requests exactly those types.
language "en" none Sets the Presidio language.
nlp_model "en_core_web_sm" none Sets the spaCy model used by Presidio.

The detect-all CTI allowlist excludes IP_ADDRESS, URL, and DOMAIN_NAME because those values are common threat indicators. An explicit entities list is not filtered through that allowlist.

Action Result
log Logs entity types and confidence scores without detected text, then stores the original content.
redact Replaces detected spans with redact_placeholder, then stores the processed content.
block Raises GovernanceViolationError at the validator boundary before storage.

governance.memory_defense

The memory anomaly gate compares a candidate with recent same-domain notes before a direct write. The default audit mode logs a flagged decision and allows the write. block rejects the write. quarantine writes a JSONL forensic record and then rejects the write.

Key Default Environment variable Runtime behavior
enabled true ZETTELFORGE_MEMORY_DEFENSE_ENABLED Enables anomaly evaluation.
mode "audit" ZETTELFORGE_MEMORY_DEFENSE_MODE Selects audit, block, or quarantine. An unknown value falls back to audit.
min_calibration_notes 50 ZETTELFORGE_MEMORY_DEFENSE_MIN_CALIBRATION Requires this many valid reference notes before scoring.
max_reference_notes 50 none Caps valid reference notes used per evaluation.
kappa 2.0 ZETTELFORGE_MEMORY_DEFENSE_KAPPA Multiplies calibration standard deviation in the threshold.
lexical_weight 0.25 none Weights character n-gram Jensen-Shannon divergence.
ngram_size 3 none Sets the character n-gram size.
monitored_domains [] none Evaluates every domain when empty; otherwise evaluates listed domains only.
quarantine_path "" none Resolves an empty value to <data_dir>/quarantine/memory_anomalies.jsonl.
quarantine_raw_content true none Includes raw content in quarantine records. Set it to false when the record must omit content.

Anomaly scoring

The embedding term is 0.5 × maximum cosine similarity + 0.5 × mean cosine similarity. The final score adds lexical_weight × lexical Jensen-Shannon divergence over character n-grams.

Calibration scores each reference note against the other reference notes. The threshold is calibration mean + kappa × calibration standard deviation. A candidate is flagged only when its score is greater than that threshold.

The gate returns without scoring in these cases:

Condition Action reason
enabled=false allow disabled
Domain not listed in monitored_domains allow domain_not_monitored
Candidate embedding missing or all-zero audit candidate_embedding_unavailable
Too few valid reference notes audit calibration_insufficient
Leave-one-out calibration produces no scores audit calibration_unscorable

Prompt-injection patterns

ZettelForge normalizes control characters and whitespace, then evaluates six deterministic regular-expression patterns in order. The guard returns the first matching code and raises PromptInjectionError.

Code Pattern intent
instruction_override Ignore, disregard, forget, bypass, or override earlier instructions or rules.
role_rewrite Replace the model role or activate admin, root, jailbreak, or developer-mode framing.
secret_exfiltration Reveal, print, dump, show, exfiltrate, leak, or return hidden prompts, credentials, or secrets.
tool_or_network_command Call, invoke, use, run, or execute a tool, shell, HTTP request, or webhook.
prompt_boundary_marker Insert a begin/end marker for a system, developer, assistant, or tool prompt or message.
memory_poisoning_intent Store content as a system, developer, or highest-priority instruction or memory.

remember() wraps this error as GovernanceViolationError. Recall and other direct guard call sites expose PromptInjectionError.

Exceptions

Exception Module When raised
GovernanceViolationError zettelforge.governance_validator Structural validation, content length, prompt-injection, or PII validation rejects a write.
PromptInjectionError zettelforge.prompt_injection_guard A direct prompt guard call finds one of the six pattern codes.
PIIBlockedError zettelforge.pii_validator The raw PII validator finds PII in block mode; the governance boundary wraps it.
MemoryAnomalyError zettelforge.memory_defense A candidate is flagged in block or quarantine mode. The exception carries its MemoryAnomalyDecision.

Minimal hardening configuration

Enable PII redaction and switch the anomaly gate to block only after the store has at least min_calibration_notes clean same-domain references:

governance:
  limits:
    max_content_length: 1048576
    recall_timeout_seconds: 15.0
  pii:
    enabled: true
    action: redact
  memory_defense:
    enabled: true
    mode: block
    kappa: 2.0

Set the environment-backed subset with:

export ZETTELFORGE_PII_ENABLED=true
export ZETTELFORGE_PII_ACTION=redact
export ZETTELFORGE_MEMORY_DEFENSE_MODE=block
export ZETTELFORGE_LIMITS_MAX_CONTENT_LENGTH=1048576

block mode does not reject a candidate before calibration exists. Until the gate has enough valid reference notes, it returns calibration_insufficient and allows the write.