Epistemic tiers and confidence¶
ZettelForge 2.8.0 records two different judgments on every memory note: an editorial tier and a numeric confidence value. The tier can decide whether a note enters synthesis. Confidence records your assessment of the note, but it does not remove the note from synthesis by itself.
Use these fields as policy inputs, not as proof that intelligence is true. The released model stores values that you assign; it does not validate the source or enforce the documented ranges.
Prerequisites: Read the Memory Manager API for note operations and the Configuration reference for the complete synthesis settings.
Two judgments answer two questions¶
Tier and confidence are intentionally separate:
| Field | Released default | Question it answers |
|---|---|---|
metadata.tier |
"B" on a plain Metadata object |
What editorial role does this source play? |
metadata.confidence |
1.0 |
How strongly do you assess this note? |
metadata.stix_confidence |
-1 |
What integer confidence did a STIX-oriented integration supply? -1 means unset. |
ZettelForge defines three editorial tiers in its default configuration:
| Tier | Meaning | Useful decision rule |
|---|---|---|
A |
Authoritative: high-confidence, verified sources | Reserve it for evidence your process has validated. |
B |
Operational: working knowledge with moderate confidence | Use it for intelligence that supports analysis but still needs corroboration. |
C |
Support: low-confidence, inferred, or speculative material | Keep it available for investigation without treating it as established fact. |
The letter does not calculate the number, and the number does not promote the
letter. ZettelForge also does not convert metadata.confidence to
metadata.stix_confidence. This separation lets you describe provenance and
certainty without collapsing them into one score.
Ingestion assigns a starting tier, not trust¶
The model default and the direct ingestion path use different starting values.
A standalone Metadata object starts at tier B. The NoteConstructor used by
the ordinary MemoryManager.remember() path creates every note at tier A,
regardless of source_type, domain, or text.
That A is an implementation default, not an automatic source assessment.
Review the source and rewrite the note metadata when the default does not match
your evidence policy. SQLite persists later changes to both tier and
stix_confidence.
Tier and confidence validation is in progress
ZettelForge 2.8.0 declares tier as a string, confidence as a float, and
stix_confidence as an integer without range constraints. The released
model accepts values such as tier D, confidence 1.5, and STIX confidence
101. Validate allowed tiers and numeric bounds in your ingestion layer
before you store a note.
Evolution applies one confidence cap¶
Calling increment_evolution() records a revision and sets confidence to the
lower of its current value and 0.95. A note at 1.0 therefore moves to
0.95 after its first evolution. A second call increases
evolution_count but leaves that confidence at 0.95; the method does not
apply repeated decay.
The built-in review predicate returns true when either condition holds:
metadata.confidenceis below0.5.metadata.evolution_countis greater than5.
The boundaries are strict. Confidence 0.5 is not flagged by the confidence
rule, and an evolution count of 5 is not flagged by the count rule.
This mechanism is a review signal, not a calibrated probability model. If your
workflow needs cumulative decay, corroboration weights, or conflict-aware
scoring, calculate that policy outside increment_evolution() and persist the
result explicitly.
Synthesis filters by tier only¶
The synthesis generator retrieves notes, removes duplicate IDs, and then keeps
notes whose metadata.tier appears in tier_filter. It does not compare
metadata.confidence with the generator's confidence_threshold. A tier B
note with confidence 0.1 still enters synthesis when B is allowed.
Observed ZettelForge 2.8.0 behavior is:
| Call behavior | Tiers admitted |
|---|---|
Omit tier_filter in a direct MemoryManager.synthesize() call |
A, B, and C |
Pass tier_filter=["A", "B"] |
A and B |
Pass tier_filter=["A"] |
A |
| Pass an empty list | A, B, and C |
The last row follows from the generator treating an empty list like a missing value. Pass an explicit non-empty list when you want a restriction.
The configured synthesis default is not wired to direct calls
config.default.yaml and SynthesisConfig default to tiers A and B,
but MemoryManager.synthesize() does not load that setting when
tier_filter is omitted. The generator uses all three tiers instead. Pass
the required filter at each direct call until config-to-runtime wiring is
implemented.
The operational model¶
Treat the fields as a small policy vocabulary:
- Tier expresses the source's role in your editorial process.
- Confidence expresses your current assessment of the note.
- Evolution count tells you how often later notes revised it.
- Your calling application validates values and decides what requires review.
- Synthesis uses only the explicit tier allowlist.
This division keeps ZettelForge flexible, but it leaves enforcement with you. The useful habit is simple: assign deliberately, validate before storage, and pass synthesis policy explicitly.
This page describes the self-hosted ZettelForge model. ThreatRecall.ai is the separate hosted SaaS and is outside this page's scope.