Python API Reference¶
Top-level exports¶
foghorn
¶
foghorn - Decision staleness alerts for AI agents.
ActivityFrame(frame_id, application, site, t_start, t_end, input_volume, evidence_ptrs, frame_type='activity', row_count=0)
dataclass
¶
Compiled typed activity frame (deterministic, zero-model).
Bounded episode carrying application, site, timing, input volume, and evidence pointers back to raw rows - byte-identical and cacheable.
RawCaptureRow(row_id, timestamp, application, site='', input_kind='', meta=dict())
dataclass
¶
One raw capture stream row (pre-compile).
Attributes:
| Name | Type | Description |
|---|---|---|
row_id |
str
|
Stable id of the raw row (evidence pointer target). |
timestamp |
float
|
Unix seconds (or any monotonic clock). |
application |
str
|
Foreground application name. |
site |
str
|
Optional site/URL host (browser) or window title token. |
input_kind |
str
|
Optional input class ( |
meta |
dict[str, Any]
|
Optional extra fields (ignored by compile fingerprint except when callers pass them through explicitly). |
ClosedLoopError
¶
Bases: ValueError
Raised when the gate refuses empty, unusable, or misused worlds.
GateOutcome(ok, verdict, reason, exit_code, alerts=(), max_impact=0.0, stale_source_ids=(), oldest_age_seconds=None, source_count=0, human_required=False)
dataclass
¶
Result of a closed-loop read of a foghorn world or source-age gate.
Attributes:
| Name | Type | Description |
|---|---|---|
ok |
bool
|
True only when a pipeline may continue (no high-impact stale). |
verdict |
str
|
|
reason |
str
|
Human-readable explanation (always non-empty). |
exit_code |
int
|
0 PASS, 1 FAIL (stale), 2 FAIL_LOUD (empty/misuse). |
alerts |
tuple[StalenessAlert, ...]
|
Staleness alerts when scoring ran. |
max_impact |
float
|
Highest impact_score among alerts (0.0 if none). |
stale_source_ids |
tuple[str, ...]
|
Fact ids that exceeded max source age. |
oldest_age_seconds |
float | None
|
Age of the oldest examined source fact. |
source_count |
int
|
Number of source facts examined. |
human_required |
bool
|
True when refresh/re-retrieval needs a human or re-fetch. |
to_dict()
¶
Serialise for JSON reports (eagle-eyes dogfood, CI artifacts).
Source code in src/foghorn/closed_loop.py
EvidenceLink(feature_id, source_id, source_kind='evidence_link', detail='')
dataclass
¶
Provenance edge from a feature to a source artifact.
Attributes:
| Name | Type | Description |
|---|---|---|
feature_id |
str
|
Feature this evidence supports. |
source_id |
str
|
Id of source table row, fact, guideline, or raw capture. |
source_kind |
str
|
Class of source ( |
detail |
str
|
Optional free-text cite / path. |
FeatureRecord(feature_id, name='', kind='derived_feature', rubric_ok=True, value=None, meta=dict())
dataclass
¶
A derived/engineered feature that must carry evidence provenance.
Attributes:
| Name | Type | Description |
|---|---|---|
feature_id |
str
|
Stable id of the feature. |
name |
str
|
Human-readable feature name. |
kind |
str
|
Feature class ( |
rubric_ok |
bool
|
Whether rubric/structure checks passed (default True). |
value |
Any
|
Optional payload (not gated on content). |
meta |
dict[str, Any]
|
Optional extra fields. |
Decision(label, content, fact_ids=list(), recorded_at=time.time())
dataclass
¶
A named agent conclusion recorded alongside the facts it depended on.
Decisions are the nodes that foghorn watches for staleness. When any
Fact listed in fact_ids changes, this Decision is marked stale.
Attributes:
| Name | Type | Description |
|---|---|---|
id |
str
|
Content-addressed identifier - SHA-256[:16] of "{label}|{content}". |
label |
str
|
Short slug describing the decision (e.g. "chose-redis-for-rate-limiting"). |
content |
str
|
Full reasoning text or justification. |
fact_ids |
list[str]
|
IDs of the Facts this decision directly depended on. |
recorded_at |
float
|
Unix timestamp when this decision was recorded. |
Fact(subject, predicate, object, confidence=1.0, recorded_at=time.time())
dataclass
¶
An immutable, content-addressed triple that agents assert about the world.
Facts are the atoms of foghorn. Two Facts with the same subject, predicate, and object always have the same ID, regardless of when they were recorded.
Attributes:
| Name | Type | Description |
|---|---|---|
id |
str
|
Content-addressed identifier - SHA-256[:16] of "{subject}|{predicate}|{object}". |
subject |
str
|
The entity this fact is about (e.g. "Redis"). |
predicate |
str
|
The relationship being asserted (e.g. "is-appropriate-for"). |
object |
str
|
The value of the assertion (e.g. "rate-limiting"). |
confidence |
float
|
Belief weight in [0.0, 1.0]. Default 1.0 (certain). |
recorded_at |
float
|
Unix timestamp when this fact was committed. |
StalenessAlert(decision_id, decision_label, stale_fact_ids, impact_score)
dataclass
¶
Emitted when a Decision's upstream facts have changed.
Attributes:
| Name | Type | Description |
|---|---|---|
decision_id |
str
|
ID of the stale Decision. |
decision_label |
str
|
Human-readable label for display. |
stale_fact_ids |
list[str]
|
Which specific facts changed and triggered this alert. |
impact_score |
float
|
Confidence-weighted importance in [0.0, 1.0]. Higher = more confidence was placed in the now-changed facts. |
to_dict()
¶
Serialize to a JSON-compatible dict.
Source code in src/foghorn/fact.py
PropagationResult(changed_fact_ids, directly_stale=list(), transitively_stale=list(), propagation_depth=0, impact_summary='')
dataclass
¶
Result of propagating staleness from a set of changed facts.
Attributes:
| Name | Type | Description |
|---|---|---|
changed_fact_ids |
list[str]
|
The fact IDs that triggered the propagation. |
directly_stale |
list[str]
|
Labels of decisions that directly depend on changed facts. |
transitively_stale |
list[str]
|
Labels of decisions that depend on directly stale decisions (requires decisions to reference other decisions via their fact_ids - if the architecture only records fact→decision edges, this will be empty). |
propagation_depth |
int
|
Maximum depth reached in the propagation graph. |
impact_summary |
str
|
Human-readable summary of the propagation result. |
Recommendation(decision_label, reason, action, priority, stale_facts=list())
dataclass
¶
An actionable recommendation for a stale decision.
Attributes:
| Name | Type | Description |
|---|---|---|
decision_label |
str
|
The label of the stale decision. |
reason |
str
|
Why the decision is considered stale. |
action |
str
|
Recommended action: |
priority |
str
|
|
stale_facts |
list[str]
|
Subjects of the facts that triggered this recommendation. |
to_dict()
¶
Serialize to a plain dict.
WorldRepo(store)
¶
A foghorn repository: a versioned store of agent facts and decisions.
WorldRepo is the main user-facing API. It wraps WorldStore with the higher-level operations of a version-controlled knowledge base.
Typical workflow::
repo = WorldRepo.init(".foghorn")
repo.add_fact("Redis", "is-appropriate-for", "rate-limiting")
repo.decide("chose-redis", "Redis fits our rate-limiter needs",
depends_on=[...fact_ids...])
commit = repo.commit("Initial architecture decisions")
Attributes:
| Name | Type | Description |
|---|---|---|
store |
The underlying WorldStore. |
|
path |
Path to the repository database. |
Source code in src/foghorn/repo.py
init(path='.foghorn/world.db')
classmethod
¶
Create or open a WorldRepo at the given path.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
path
|
str | Path
|
Path to the SQLite database file. Parent directories are created automatically. |
'.foghorn/world.db'
|
Returns:
| Type | Description |
|---|---|
WorldRepo
|
A WorldRepo ready for use. |
Source code in src/foghorn/repo.py
add_fact(subject, predicate, obj, confidence=1.0)
¶
Stage a new Fact for the next commit.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
subject
|
str
|
The entity this fact is about. |
required |
predicate
|
str
|
The relationship being asserted. |
required |
obj
|
str
|
The value of the assertion. |
required |
confidence
|
float
|
Belief weight in [0.0, 1.0]. |
1.0
|
Returns:
| Type | Description |
|---|---|
Fact
|
The created (and staged) Fact. |
Source code in src/foghorn/repo.py
decide(label, content, depends_on=None)
¶
Stage a new Decision for the next commit.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
label
|
str
|
Short slug for this decision (e.g. "chose-redis-for-rate-limiting"). |
required |
content
|
str
|
Full reasoning text. |
required |
depends_on
|
list[str] | None
|
List of Fact IDs this decision relied on. |
None
|
Returns:
| Type | Description |
|---|---|
Decision
|
The created (and staged) Decision. |
Source code in src/foghorn/repo.py
commit(message)
¶
Commit all staged facts and decisions.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
message
|
str
|
Human-readable commit message. |
required |
Returns:
| Type | Description |
|---|---|
WorldCommit
|
The new WorldCommit. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If there is nothing staged to commit. |
Source code in src/foghorn/repo.py
retract_fact(fact_id)
¶
Stage a fact retraction so it is excluded from the next commit snapshot.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
fact_id
|
str
|
ID of the Fact to remove from the next snapshot. |
required |
stale(since=None)
¶
Return staleness alerts for decisions affected by recent fact changes.
Compares HEAD to since (or HEAD's parent if None) and finds all
Decisions whose upstream facts changed.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
since
|
WorldCommit | None
|
The base commit to diff against. Defaults to HEAD's parent. |
None
|
Returns:
| Type | Description |
|---|---|
list[StalenessAlert]
|
List of StalenessAlert sorted by impact_score descending. |
list[StalenessAlert]
|
Empty list if nothing has changed or there are no decisions. |
Source code in src/foghorn/repo.py
diff(commit_a=None, commit_b=None)
¶
Diff two commits (defaults to HEAD~1 vs HEAD).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
commit_a
|
WorldCommit | None
|
Base commit (None = empty state). |
None
|
commit_b
|
WorldCommit | None
|
Head commit (None = current HEAD). |
None
|
Returns:
| Type | Description |
|---|---|
DiffResult
|
DiffResult with added and removed facts. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If HEAD is empty and no commits are provided. |
Source code in src/foghorn/repo.py
log()
¶
export_json()
¶
Export the entire repository state as a JSON string.
Delegates to :func:foghorn.export.export_json.
Returns:
| Type | Description |
|---|---|
str
|
A JSON string with all facts, decisions, and commits. |
Source code in src/foghorn/repo.py
recommend()
¶
Generate actionable staleness recommendations.
Delegates to :func:foghorn.recommend.recommend.
Returns:
| Type | Description |
|---|---|
list[Recommendation]
|
Sorted list of :class: |
Source code in src/foghorn/repo.py
propagate(fact_ids)
¶
Propagate staleness from a set of changed facts.
Delegates to :func:foghorn.propagate.propagate_staleness.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
fact_ids
|
list[str]
|
IDs of facts that have changed. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
A |
PropagationResult
|
class: |
Source code in src/foghorn/repo.py
DiffResult(added_facts, removed_facts, changed_fact_ids, commit_a_id, commit_b_id)
dataclass
¶
Summary of changes between two world commits.
Attributes:
| Name | Type | Description |
|---|---|---|
added_facts |
list[Fact]
|
Facts present in |
removed_facts |
list[Fact]
|
Facts present in |
changed_fact_ids |
set[str]
|
Union of added and removed fact IDs (convenience set). |
commit_a_id |
str | None
|
ID of the base commit (or None for the empty state). |
commit_b_id |
str
|
ID of the head commit. |
WorldCommit(message, fact_ids=set(), decision_ids=set(), parent_id=None, timestamp=time.time())
dataclass
¶
A snapshot of world state at a point in time.
Attributes:
| Name | Type | Description |
|---|---|---|
id |
str
|
Content-addressed identifier. |
message |
str
|
Human-readable commit message. |
fact_ids |
set[str]
|
Set of Fact IDs in this snapshot. |
decision_ids |
set[str]
|
Set of Decision IDs in this snapshot. |
parent_id |
str | None
|
ID of the parent commit, or None for the initial commit. |
timestamp |
float
|
Unix timestamp of this commit. |
to_dict()
¶
Serialize to a JSON-compatible dict.
Source code in src/foghorn/store.py
from_dict(d)
classmethod
¶
Deserialize from a dict produced by to_dict().
Source code in src/foghorn/store.py
WorldStore(path)
¶
SQLite-backed persistence layer for foghorn.
All Facts, Decisions, and Commits are stored in a single SQLite database. Content-addressed IDs guarantee deduplication: storing the same fact twice is a no-op.
Attributes:
| Name | Type | Description |
|---|---|---|
path |
Path to the SQLite database file. |
Source code in src/foghorn/store.py
close()
¶
add_fact(fact)
¶
Store a Fact (no-op if already stored).
Source code in src/foghorn/store.py
get_fact(fact_id)
¶
Retrieve a Fact by ID, or None if not found.
Source code in src/foghorn/store.py
list_facts()
¶
Return all stored Facts ordered by recorded_at (oldest first).
D-FOGHORN warning: this is an append-oriented history view.
Do not use next(iter(list_facts())) or list_facts()[0] as
the "current" value of a subject/predicate - that is the oldest
fact and caused full pipeline recaptures in production (Pioneer
Content Foundry, 2026-07-22). Use :meth:latest_fact or
:meth:list_facts_for instead.
Source code in src/foghorn/store.py
list_facts_for(subject, predicate=None)
¶
Return facts for a subject (and optional predicate), oldest first.
Use this when you need the history of a key. For the single current
value of (subject, predicate), prefer :meth:latest_fact.
Source code in src/foghorn/store.py
latest_fact(subject, predicate)
¶
Return the most recently recorded fact for (subject, predicate).
Real-world case (Qdrant / farm_memory D-FOGHORN): Foundry modules treated
list_facts() as a LWW current-state map and took next(...) →
oldest object → false script_changed → wiped all frame dirs (~95 min
recapture). This method is the correct reader for "what is the current
value of this key in the append-only log?"
Note: Fact IDs are content-addressed on subject|predicate|object, so
changing the object creates a new row; "current" = max(recorded_at).
Source code in src/foghorn/store.py
current_fact_map()
¶
Map each (subject, predicate) to its latest recorded Fact.
Safe replacement for the anti-pattern of scanning list_facts() in
insertion order and treating the first hit as current.
Source code in src/foghorn/store.py
add_decision(decision)
¶
Store a Decision and its dependency edges (no-op if already stored).
Source code in src/foghorn/store.py
get_decision(decision_id)
¶
Retrieve a Decision by ID, or None if not found.
Source code in src/foghorn/store.py
list_decisions()
¶
Return all stored Decisions ordered by recorded_at.
Source code in src/foghorn/store.py
get_decisions_for_fact(fact_id)
¶
Return all Decisions that depend on a given Fact.
Source code in src/foghorn/store.py
retract_fact(fact_id)
¶
Stage a fact retraction so it is excluded from the next commit snapshot.
Source code in src/foghorn/store.py
commit(message)
¶
Create a new commit from staged facts and decisions.
Source code in src/foghorn/store.py
get_commit(commit_id)
¶
Retrieve a WorldCommit by ID, or None if not found.
Source code in src/foghorn/store.py
log()
¶
Return all commits from HEAD to root, newest first.
Source code in src/foghorn/store.py
head()
¶
activity_frame_fingerprint(*, application, site, t_start, t_end, evidence_ptrs, input_volume)
¶
Stable SHA-256 hex of the frame content (byte-identical across runs).
Source code in src/foghorn/activity.py
assert_activity_memory_ok(frames=None, **kwargs)
¶
Raise :class:ClosedLoopError unless :func:gate_activity_memory is ok.
Source code in src/foghorn/activity.py
compile_activity_frames(rows, *, gap_split_seconds=DEFAULT_GAP_SPLIT_SECONDS)
¶
Segment raw capture into typed activity frames (deterministic, zero-model).
Split rules (all mechanical - no LLM):
- Sort by
timestampascending (stable on equal timestamps byrow_id). - Start a new frame when application or site changes vs previous row.
- Start a new frame when the gap from previous row exceeds
gap_split_seconds(default 300s). input_volume= count of rows with non-emptyinput_kind.evidence_ptrs= orderedrow_idlist for rows in the frame.frame_id= :func:activity_frame_fingerprintof the content.
Empty input → empty list (caller may FAIL_LOUD via the gate).
Source code in src/foghorn/activity.py
frame_is_valid(frame)
¶
True when a compiled frame is load-bearing (evidence + timing).
Source code in src/foghorn/activity.py
gate_activity_memory(frames=None, *, memory_mode='compiled', raw_rows=None, require_frames=True, require_evidence=True, gap_split_seconds=DEFAULT_GAP_SPLIT_SECONDS, claimed_frame_ids=None)
¶
Refuse non-deterministic or evidence-free activity memory.
Activity Frames class (arXiv 2608.05784):
memory_mode="llm_summary"→ FAIL - LLM day-summary is not load-bearing memory (paper accuracy gap vs compiled frames).memory_mode="raw_uncompiled"→ FAIL - must compile first.memory_mode="compiled"with no frames when required → FAIL_LOUD.- Frame missing evidence pointers → FAIL_LOUD.
- Invalid timing (
t_end < t_start) → FAIL. claimed_frame_idsnot subset of compiled inventory → FAIL.- Valid compiled frames with evidence → PASS.
If raw_rows is provided and frames is None/empty under compiled mode,
frames are compiled in-process (deterministic) before gating.
Source code in src/foghorn/activity.py
299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 | |
assert_fresh(source, **kwargs)
¶
Gate staleness and raise :class:ClosedLoopError unless outcome is ok.
Source code in src/foghorn/closed_loop.py
assert_not_current_state_store()
¶
Explicit D-FOGHORN guard for integrators (always raises if called wrong).
Prefer calling :func:gate_staleness with mode='staleness' only.
Source code in src/foghorn/closed_loop.py
assert_sources_fresh(source, **kwargs)
¶
Raise :class:ClosedLoopError unless :func:gate_source_freshness is ok.
Source code in src/foghorn/closed_loop.py
gate_source_freshness(source, *, max_age_seconds=DEFAULT_MAX_SOURCE_AGE_SECONDS, now=None, predicates=None, subjects=None, require_source_facts=True, use_latest_only=True)
¶
Refuse decisions grounded on expired wiki/docs (Amazon Q stale-wiki class).
Public incident: Amazon Q / stale internal wiki - agents answer from
retrieved documentation that is no longer current. gate_staleness only
fires when fact ids change under a decision; it does not fail on
wall-clock age of an unchanging wiki page fact.
Rules:
- No source facts when
require_source_facts→ FAIL_LOUD - Any source fact with age >
max_age_seconds→ FAIL (human_required- re-retrieve or human review) - Fresh sources only → PASS
use_latest_only(default): apply D-FOGHORN - age the newest fact per (subject, predicate), not the oldest log row.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
source
|
WorldRepo | Sequence[Fact]
|
WorldRepo or sequence of Facts. |
required |
max_age_seconds
|
float
|
Maximum allowed age (default 7 days). |
DEFAULT_MAX_SOURCE_AGE_SECONDS
|
now
|
float | None
|
Reference time (default |
None
|
predicates
|
Iterable[str] | None
|
Override source predicate set (default wiki/doc set). |
None
|
subjects
|
Iterable[str] | None
|
If set, only examine these subjects. |
None
|
require_source_facts
|
bool
|
Empty source inventory → FAIL_LOUD. |
True
|
use_latest_only
|
bool
|
Deduplicate to latest per key before aging. |
True
|
Source code in src/foghorn/closed_loop.py
303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 | |
gate_staleness(source, *, mode='staleness', impact_threshold=0.5, require_decisions=True)
¶
Read a world, surface staleness, fail loudly on empty or D-FOGHORN misuse.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
source
|
WorldRepo | str | Path
|
Open :class: |
required |
mode
|
Mode
|
Must be |
'staleness'
|
impact_threshold
|
float
|
Max alert impact allowed for PASS (any alert at/above this impact → FAIL exit 1). |
0.5
|
require_decisions
|
bool
|
If True, a world with zero decisions is FAIL_LOUD (nothing load-bearing to gate). |
True
|
Returns:
| Type | Description |
|---|---|
GateOutcome
|
class: |
Source code in src/foghorn/closed_loop.py
162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 | |
is_source_predicate(predicate, *, extra=None)
¶
True if predicate marks wiki/doc/retrieval grounding.
Source code in src/foghorn/closed_loop.py
analyze_evidence_links(features=None, evidence_links=None, *, known_source_ids=None, min_links_per_feature=1)
¶
Summarize feature provenance coverage (does not gate).
Returns covered/unlinked feature ids, broken source pointers, and rubric
failures. Use :func:gate_evidence_links to refuse decision-grade use.
Source code in src/foghorn/evidence.py
assert_evidence_linked(features=None, evidence_links=None, **kwargs)
¶
Raise :class:ClosedLoopError unless :func:gate_evidence_links is ok.
Source code in src/foghorn/evidence.py
gate_evidence_links(features=None, evidence_links=None, *, known_source_ids=None, claim_decision_grade=False, require_features=True, min_links_per_feature=1, refuse_rubric_fail=True, refuse_broken_sources=True)
¶
Refuse decision-grade use of features without evidence provenance.
Public case: arXiv 2608.06366 Tracing the Heart: An Evidence-Linked Pipeline for Heart-Failure Feature Engineering. Derived features without structural integrity, rubric compliance, and provenance are not decision-grade. Foghorn already ages wiki sources and requires activity evidence_ptrs; this gate covers feature engineering provenance.
Rules:
claim_decision_gradewith zero features when required → FAIL_LOUD- Empty features + empty links (non-claim, require_features) → FAIL_LOUD
- Any feature with fewer than
min_links_per_featurelinks → FAIL (or FAIL_LOUD when claim_decision_grade and zero links total) - Evidence pointer with empty
source_id→ FAIL source_idnot inknown_source_ids(when provided) → FAILrubric_ok=Falsewhenrefuse_rubric_fail→ FAIL- Fully linked, rubric-ok features → PASS
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
features
|
Sequence[Any] | None
|
Feature records (dicts or :class: |
None
|
evidence_links
|
Sequence[Any] | None
|
Provenance edges (dicts or :class: |
None
|
known_source_ids
|
Sequence[str] | None
|
Optional inventory of valid source artifact ids. |
None
|
claim_decision_grade
|
bool
|
Features claimed ready for clinical/decision use. |
False
|
require_features
|
bool
|
Empty feature inventory → FAIL_LOUD when claiming or when True and no links either. |
True
|
min_links_per_feature
|
int
|
Minimum evidence edges per feature (default 1). |
1
|
refuse_rubric_fail
|
bool
|
Rubric non-compliance → FAIL. |
True
|
refuse_broken_sources
|
bool
|
Unknown source_id → FAIL when inventory given. |
True
|
Source code in src/foghorn/evidence.py
294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 | |
is_evidence_kind(kind, *, extra=None)
¶
True if kind marks a provenance/evidence edge.
Source code in src/foghorn/evidence.py
is_feature_kind(kind, *, extra=None)
¶
True if kind marks an engineered/derived feature.
Source code in src/foghorn/evidence.py
export_graphviz(repo)
¶
Export the fact → decision dependency graph in Graphviz DOT format.
Each fact and decision is a node; directed edges run from facts to the
decisions that depend on them. The resulting DOT string can be rendered
with dot -Tsvg graph.dot > graph.svg.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
repo
|
WorldRepo
|
The repository to graph. |
required |
Returns:
| Type | Description |
|---|---|
str
|
A Graphviz DOT string. |
Source code in src/foghorn/export.py
export_json(repo)
¶
Export the entire repository state as a JSON string.
Exports all facts, decisions, and commits currently known to the store.
The resulting JSON is suitable for archiving, migration, or seeding a
fresh repository via :func:import_json.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
repo
|
WorldRepo
|
The repository to export. |
required |
Returns:
| Type | Description |
|---|---|
str
|
A JSON string with keys |
Source code in src/foghorn/export.py
import_json(path_or_str, target_repo)
¶
Import a JSON export into a target repository.
Imports all facts and decisions from the export. Each unique fact and decision is staged and committed to the target repository as a single "import" commit. If there is nothing new to stage, no commit is created.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
path_or_str
|
str
|
Either a JSON string or a path to a JSON file. |
required |
target_repo
|
WorldRepo
|
The :class: |
required |
Returns:
| Type | Description |
|---|---|
int
|
The total number of items (facts + decisions) imported. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If the JSON is not a valid foghorn export. |
FileNotFoundError
|
If a path is given but does not exist. |
Source code in src/foghorn/export.py
propagate_staleness(repo, changed_fact_ids)
¶
Find all directly and transitively stale decisions for a set of changed facts.
The propagation graph is fact → decision. Decisions that share a common "fact"
edge with other decisions (i.e., decisions whose ID appears in another decision's
fact_ids list) are considered transitive dependents.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
repo
|
WorldRepo
|
The :class: |
required |
changed_fact_ids
|
list[str]
|
IDs of facts that have changed. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
A |
PropagationResult
|
class: |
Source code in src/foghorn/propagate.py
compute_staleness(store, changed_fact_ids)
¶
Given a set of changed fact IDs, return staleness alerts for affected decisions.
For each Decision that depends on at least one changed fact, emit a
StalenessAlert. The impact_score is the average confidence of the
changed facts that the decision depended on.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
store
|
WorldStore
|
The WorldStore to resolve Decisions from. |
required |
changed_fact_ids
|
set[str]
|
Set of Fact IDs that have been added or removed. |
required |
Returns:
| Type | Description |
|---|---|
list[StalenessAlert]
|
List of StalenessAlert, sorted by impact_score descending. |
Source code in src/foghorn/staleness.py
diff_commits(store, commit_a, commit_b)
¶
Compute the fact-level diff between two commits.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
store
|
WorldStore
|
The WorldStore to resolve Fact objects from. |
required |
commit_a
|
WorldCommit | None
|
The base commit (None = empty state). |
required |
commit_b
|
WorldCommit
|
The head commit to compare against. |
required |
Returns:
| Type | Description |
|---|---|
DiffResult
|
DiffResult with added/removed facts and the union of changed IDs. |