Skip to content

v0.4.0

Choose a tag to compare

@github-actions github-actions released this 08 Apr 05:16
· 522 commits to main since this release

Semantica v0.4.0 β€” Release Notes

Released: 2026-04-08
PyPI: pip install semantica==0.4.0
Tag: v0.4.0
Full Changelog: CHANGELOG.md


v0.4.0 is the largest feature release to date. It ships a complete bi-temporal intelligence stack, a production-ready Knowledge Explorer API, first-class SHACL validation, SKOS vocabulary management, ontology alignment & diff, an Agno agentic framework integration, a Datalog reasoning engine, and a broad sweep of reliability, performance, and security fixes.

Test suite: 886 passed Β· 9 skipped Β· 0 failed


What's New

Temporal Intelligence

A full bi-temporal model is now baked into the core. Every entity, relationship, decision, and provenance record can carry valid time (when a fact was true in the world) and transaction time (when it was recorded in the system).

Core Temporal Data Model (PR #396)

  • New semantica.kg.temporal_model with shared parsing, normalization, and serialization helpers used across all temporal APIs
  • TemporalBound and BiTemporalFact exported from semantica.kg
  • valid, transaction, and both time-axis filtering in all temporal queries
  • TemporalValidationError raised consistently on invalid inputs β€” no silent coercions
  • History-preserving revisions in TemporalVersionManager.apply_revision() with supersession semantics

Temporal Query Engine: Point-in-Time Correctness (PR #397)

  • TemporalGraphQuery.reconstruct_at_time(graph, at_time) β€” builds a consistent point-in-time subgraph without mutating the source
  • query_at_time() uses reconstruction internally so returned subgraphs never contain dangling edges
  • TemporalConsistencyReport β€” detects inverted intervals, relationships outside entity lifetimes, missing endpoints, overlapping same-type relationships, and temporal gaps
  • validate_temporal_consistency(graph) available as a top-level module function
  • Sequence and cycle pattern detection with pattern_type, signature, frequency, and per-occurrence detail
  • Calendar-aligned temporal evolution bucketing via temporal_granularity
  • Causal ordering controls on find_temporal_paths() β€” enforce_causal_ordering, ordering_strategy (strict, overlap, loose)

Deterministic Temporal Reasoning Engine (PR #398)

  • New semantica.kg.temporal_reasoning β€” zero LLM calls, pure deterministic reasoning
  • Full Allen interval algebra via IntervalRelation β€” all 13 relations (before, meets, overlaps, starts, during, finishes, equals, and inverses)
  • TemporalReasoningEngine with helpers for interval merging, gap analysis, coverage calculation, timelines, and retroactive coverage
  • Circular import risk between semantica.reasoning and semantica.kg eliminated; semantica.reasoning access preserved via re-exports

Temporal Awareness in Context Graph (PR #399)

  • Decision dataclass carries valid_from / valid_until validity windows β€” superseded decisions remain in the graph (immutable history)
  • find_precedents_by_scenario(include_superseded=False, as_of=None) β€” defaults exclude expired decisions; as_of enables point-in-time queries
  • ContextGraph.state_at(timestamp) β€” serializable point-in-time snapshot; source graph never mutated
  • CausalChainAnalyzer.trace_at_time(event_id, at_time) β€” reconstructs causal chain using only edges recorded up to at_time
  • AgentContext.checkpoint(label), diff_checkpoints(label1, label2), flush_checkpoint(label) β€” named in-memory snapshots with structured diffs

Temporal Metadata Extraction from Text (PR #400)

  • extract_relations_llm(extract_temporal_bounds=True) β€” each returned Relation gains valid_from, valid_until, temporal_confidence (0.0–1.0), and temporal_source_text; default False is 100% backward-compatible
  • Calibrated confidence anchors baked into the prompt: 1.00 = full ISO date β†’ 0.00 = no temporal signal
  • New TemporalNormalizer β€” zero LLM calls, pure regex + dateutil:
    • normalize(value) β†’ (valid_from, valid_until) UTC datetime tuple or None
    • normalize_phrase(phrase) β†’ domain metadata dict or None
    • 13-domain default phrase map covering General/Policy, Healthcare, Cybersecurity, Supply Chain, Finance, and Energy
    • Ambiguous DD/MM/YYYY inputs issue TemporalAmbiguityWarning β€” never silently guesses locale
    • User-supplied phrase_map merged over defaults at construction

Temporal Provenance & Export (PR #401)

  • ProvenanceTracker.track_entity() auto-stamps recorded_at on every new record
  • query_recorded_between(start, end) β€” returns all provenance records within an inclusive time range
  • revision_history(fact_id) β€” complete revision chain ordered by recorded_at ascending
  • export_audit_log(fact_ids, format) β€” "json" (pretty-printed) or "csv" (with header row)
  • RDFExporter.export_to_rdf(include_temporal=True, time_axis="valid"|"transaction"|"both") β€” emits OWL-Time triples for all temporally-annotated relationships
  • create_snapshot() stamps "format_version": "1.0"; validate_snapshot() and migrate_snapshot() for stable snapshot lifecycle management

Temporal GraphRAG Integration (PR #402)

  • TemporalGraphRetriever β€” drop-in wrapper for any ContextRetriever; filters retrieved entities and relationships to a point in time; at_time=None is a true passthrough
  • ContextRetriever.query_with_reasoning(at_time=..., header_template=...) β€” structured temporal header prepended to LLM context; format-string injection guard via str.replace
  • TemporalQueryRewriter β€” extracts temporal_intent, at_time, start_time, end_time, and rewritten_query from natural language; regex-only by default, optional LLM-assisted mode

Ontology & Knowledge Representation

SHACL Shape Generation & Validation (PR #318)

  • SHACLGenerator derives SHACL node and property shapes from any Semantica ontology dict β€” zero hand-authoring required
  • Three quality tiers: "basic" (structure + cardinality), "standard" (adds sh:in, sh:pattern, inheritance), "strict" (adds sh:closed true + sh:ignoredProperties)
  • Output formats: Turtle, JSON-LD, N-Triples; iterative multi-level inheritance propagation, cycle-safe
  • OntologyEngine.to_shacl(), export_shacl(), and validate_graph(explain=True) β€” plain-English explanations for all 7 SHACL constraint types
  • SHACLValidationReport with conforms, violations, warnings, summary(), explain_violations(), to_dict()
  • Install: pip install semantica[shacl]

SKOS Vocabulary Module (PR #319)

  • TripletStore.add_skos_concept() β€” assembles and stores all required SKOS triples automatically via existing add_triplets() API
  • TripletStore.get_skos_concepts(scheme_uri=None) β€” SPARQL-backed retrieval with multi-value altLabel/broader/narrower collapsing
  • OntologyEngine.list_vocabularies(), list_concepts(scheme_uri), search_concepts(query, scheme_uri=None) β€” injection-safe SPARQL throughout
  • NamespaceManager.get_skos_uri(local_name) and build_concept_scheme_uri(name) namespace helpers

Ontology Alignment API (PR #361)

  • OntologyEngine.create_alignment(source_uri, target_uri, predicate) β€” stores triples using standard OWL/SKOS predicates (owl:equivalentClass, skos:exactMatch, skos:relatedMatch, etc.)
  • get_alignments(entity_uri) β€” bidirectional retrieval of all alignments for an entity
  • ReuseManager.suggest_alignments(target, source) β€” O(N+M) hashmap heuristic over exact label matches
  • QueryEngine.expand_entity_uri(uri, store, use_alignments=True) β€” SPARQL expansion to automatically include aligned equivalents in queries
  • SPARQL injection hardened in list_alignments and build_values_clause

Ontology Diff & Migration (PR #367)

  • VersionManager.diff_ontologies(base, target) β€” structured diff covering classes, properties, individuals, and axioms
  • ChangeLogAnalyzer.analyze(diff) β€” classifies impact: CRITICAL/BREAKING, HIGH/BREAKING, MEDIUM/POTENTIALLY_BREAKING, INFO/NON_BREAKING
  • ImpactReport and generate_change_report(diff) β€” structured output with summary, impact_classification, and recommendations
  • OntologyEngine.compare_versions(base_id, target_id, run_validation=True, graph_data=...) β€” end-to-end orchestrator with optional validation and graph-instance checks

Knowledge Explorer

A full FastAPI backend for the Semantica dashboard. Install with pip install semantica[explorer] and launch via semantica-explorer --graph my_graph.json.

Graph API (PR #384)

  • GET /api/graph/nodes|edges|stats β€” type/keyword filter, skip/limit pagination
  • GET /api/graph/node/{id}/neighbors β€” BFS traversal, configurable depth 1–5
  • GET /api/graph/node/{id}/path β€” BFS or Dijkstra, dispatched via algorithm param
  • POST /api/graph/search β€” full-text search across node content and metadata

Analytics, Decisions & Temporal (PR #384)

  • GET /api/analytics β€” centrality, community detection, connectivity (comma-separated metrics param)
  • GET /api/decisions/{id}/chain|precedents|compliance β€” causal chain BFS, ranked precedent retrieval, in-graph compliance edge scan
  • GET /api/temporal/snapshot|diff|patterns β€” point-in-time snapshots, node-set diffs between timestamps, pattern detection

Enrichment & Export (PR #384)

  • POST /api/enrich/extract|links|dedup|reason β€” NLP extraction, link prediction, deduplication, forward/backward inference
  • POST /api/export β€” 12 formats: JSON, Turtle, RDF-XML, N-Triples, CSV, GraphML, GEXF, OWL, Cypher, AQL, YAML; temp files always cleaned via try/finally
  • POST /api/import β€” JSON/JSON-LD multipart upload with WebSocket real-time progress events

SKOS Vocabulary REST API (PR #426)

  • GET /api/vocabulary/schemes β€” all skos:ConceptScheme nodes
  • GET /api/vocabulary/hierarchy?scheme=<uri> β€” full broader/narrower concept tree with cycle detection
  • POST /api/vocabulary/import β€” accepts .ttl, .rdf, .owl uploads; invalid files return HTTP 422

Infrastructure

  • Thread-safe GraphSession with 8 lazily-initialized analytics components under RLock (PR #385)
  • WebSocket ConnectionManager for real-time broadcast and per-client messaging
  • 28 Pydantic v2 request/response models; 99 integration tests, all passing

Integrations

Agno Agentic Framework (Issue #249)

Five components making Semantica the memory and knowledge layer for Agno agents. All degrade gracefully when agno is not installed.

  • AgnoContextStore β€” graph-backed agent memory implementing agno.memory.db.base.MemoryDb; supports full CRUD plus record_decision(), find_precedents(), retrieve()
  • AgnoKnowledgeGraph β€” multi-hop GraphRAG knowledge base implementing agno.knowledge.base.AgentKnowledge; ingests files, directories, URLs, and raw text via NER β†’ relation extraction β†’ graph β†’ vector index pipeline
  • AgnoDecisionKit β€” Agno Toolkit exposing 6 decision-intelligence tools: record_decision, find_precedents, trace_causal_chain, analyze_impact, check_policy, get_decision_summary
  • AgnoKGToolkit β€” Agno Toolkit exposing 7 KG pipeline tools: extract_entities, extract_relations, add_to_graph, query_graph, find_related, infer_facts, export_subgraph
  • AgnoSharedContext β€” team-level coordinator with a single shared ContextGraph; bind_agent(role) returns a role-scoped view with cross-agent memory visibility; thread-safe via RLock

Install: pip install semantica[agno]
Cookbooks: cookbook/integrations/agno_decision_intelligence.ipynb, agno_graphrag_context.ipynb, agno_multi_agent_shared_context.ipynb

Novita AI Provider (PR #374)

  • create_provider("novita") β€” OpenAI-compatible integration; default model deepseek/deepseek-v3.2; configured via NOVITA_API_KEY

Reasoning

Native Datalog Reasoning Engine (PR #371)

  • DatalogReasoner β€” pure-Python bottom-up semi-naive fixpoint engine with guaranteed termination on finite graphs
  • Supports recursive Horn clause rules (e.g. ancestor(X,Y) :- parent(X,Z), ancestor(Z,Y).) β€” handles cases that loop the existing forward/backward engine indefinitely
  • query("pred(?X, ?Y)") returns variable-binding dicts; bindings={"Y": "val"} for pre-bound verification
  • load_from_graph(ContextGraph) β€” one-call conversion of all graph edges and nodes to Datalog facts
  • O(1) delta-index lookup per iteration; derive_all() skips re-evaluation when inputs are unchanged
  • DatalogReasoner, DatalogFact, DatalogRule exported from semantica.reasoning

Pattern Matcher Restored (PR #387)

  • Dead code silently overwrote _match_pattern's full regex (pre-bound variable embedding, repeated-variable backreferences (?P=var)) with a simple re.escape pattern β€” breaking transitivity, symmetry, and self-join rules entirely
  • Removed; re.error exceptions now surfaced instead of swallowed

Performance & Reliability

ContextGraph O(N) β†’ O(limit) Pagination (PR #431)

  • find_nodes and find_edges now use generator expressions consumed via itertools.islice β€” on a 50k-node / 100k-edge graph, each paginated request previously allocated up to 2.5M dicts and caused 502 timeouts; now O(limit) in both time and space
  • Ghost-node fix: add_edges accepts both "source_id"/"target_id" and "source"/"target" key names β€” edges from find_edges no longer silently produce None β†’ None entries
  • Deterministic page boundaries: find_nodes and find_active_nodes call sorted() on index sets before iterating
  • stats() applies the same validity filters as find_nodes/find_edges so counts always match what pagination returns

ContextGraph Thread Safety (PR #385)

  • threading.RLock added to ContextGraph.__init__; all mutation and read/query paths protected
  • GraphSession lazy analytics properties initialized under RLock β€” no double-instantiation under concurrent FastAPI workers

ContextGraph Traversal Fallbacks (PR #386)

  • All 7 DecisionQuery methods and 4 DecisionRecorder methods have native ContextGraph fallback paths β€” in-memory usage no longer requires a graph database backend

Snapshot & Audit Trail (PRs #393, #394)

  • restore_snapshot() requires explicit confirmation before destructive restore β€” rollback protection
  • get_node_history() for per-entity audit inspection; diff() as a Git-like alias over version comparisons
  • Both nodes/edges and entities/relationships snapshot schemas accepted transparently

Named Graph Support (PR #432)

  • enable_named_graphs config flag correctly forwarded through TripletStore.execute_query()
  • Duplicate FROM <...> / FROM NAMED <...> clause prevention in QueryEngine.prepare_query()
  • default_graph_uri config alias added alongside existing default_graph
  • Graph URIs percent-encoded before SPARQL interpolation in version-pruning DROP SILENT GRAPH statements

Bug Fixes

  • OllamaProvider ignored base_url (PR #408) β€” all requests silently hit localhost:11434; fixed by instantiating ollama.Client(host=self.base_url) instead of assigning the raw module
  • CentralityCalculator crash β€” _build_adjacency() failed on ContextGraph edges (dataclass objects vs plain dicts); fixed to handle both shapes
  • find_path always used BFS (PR #384) β€” algorithm query param was parsed but never dispatched; now correctly routes to dijkstra_shortest_path or bfs_shortest_path
  • /api/enrich/links blocked the event loop (PR #385) β€” score_link scoring loop ran inline in async def; wrapped in asyncio.to_thread
  • Temp file leak in export_graph (PR #384) β€” file not deleted on exception; fixed with try/finally cleanup
  • spaCy NER crash β€” NERExtractor crashed in environments where spaCy is installed but broken at runtime; fallback now catches runtime initialization failures, not just missing-model errors
  • ChangeCategory enum typo (PR #367) β€” "potenitally_breaking" β†’ "potentially_breaking"

Security

  • CWE-312/359/532 β€” Sensitive data in logs β€” Removed debug print blocks in relation_extractor.py and triplet_extractor.py that wrote api_key values to stdout in verbose mode
  • CWE-20 β€” Incomplete URL sanitization β€” "url" in urls replaced with any(url == "url" for url in urls) β€” eliminates substring match that could match attacker-controlled URLs at arbitrary positions
  • Overpermissioned CI workflows β€” permissions: contents: read added to benchmark.yml and security.yml; both previously inherited repo-default (potentially read-write) permissions
  • SHACL path traversal β€” Replaced len < 500 and "\n" not in s path-vs-content heuristic with os.path.exists(); prevents attacker-controlled SHACL strings from being silently interpreted as file paths
  • SHACL inheritance mutation β€” _propagate_inheritance now uses dataclasses.replace() instead of appending parent PropertyShape objects by reference; child mutations no longer silently corrupt parent shapes
  • SPARQL injection β€” Hardened search_concepts, list_alignments, and build_values_clause with full character escaping and _sanitize_uri guards on all user-controlled inputs

Installation

pip install semantica==0.4.0

pip install semantica[shacl]      # SHACL validation (requires pyshacl)
pip install semantica[explorer]   # Knowledge Explorer API (requires FastAPI)
pip install semantica[agno]       # Agno framework integration
pip install semantica[llm-all]    # All LLM providers
pip install semantica[all]        # Everything

Contributors

@KaifAhmad1

  • Authored the full temporal intelligence stack β€” data model (#396), point-in-time query engine (#397), deterministic reasoning engine (#398), context graph temporal awareness (#399), text-to-temporal extraction + TemporalNormalizer (#400), provenance & OWL-Time export (#401), GraphRAG integration (#402)
  • Authored SHACL shape generation & validation (#318) and SKOS vocabulary module (#319)
  • Security hardening β€” CodeQL alert remediation, SPARQL injection fixes, context explainability output fixes
  • Review patches and follow-up fixes across all contributor PRs

@ZohaibHassan16

  • Knowledge Explorer API backend (#384), thread safety & pagination (#385), ContextGraph traversal fallbacks (#386)
  • SKOS vocabulary REST API (#426) and RDF parsing utility (#425)
  • ContextGraph pagination & edge integrity fixes (#431)
  • Snapshot schema compatibility (#393), audit trail & rollback protection (#394)
  • Ontology alignment API (#361), ontology diff & migration (#367)
  • Native Datalog reasoning engine (#371)

@Sameer6305

  • Named graph support (#432)

@Alex-wuhu

  • Novita AI provider integration (#374)

@AlexeyMyslin

  • OllamaProvider base_url fix (#408)

PyPI Β· GitHub Release Β· Documentation