Commit Graph
215 Commits
Author SHA1 Message Date
KaifAhmad1andClaude Sonnet 4.6 e78ad7f819 fix(visualization): accept KnowledgeGraph objects in all visualize_* methods (closes #458)
KGVisualizer.visualize_network() (and sibling methods) only accepted a raw
dict. Passing a KnowledgeGraph object — the natural output of
GraphBuilder.build() — silently returned without rendering.

Added _normalize_graph() which duck-types the input: dicts pass through
unchanged; any object exposing .entities / .relationships attributes is
converted to the canonical dict form; anything else raises a clear
ProcessingError naming the offending type.

_normalize_graph() is called as the first statement in visualize_network(),
visualize_communities(), visualize_centrality(), visualize_entity_types(),
and visualize_relationship_matrix().

Also adds 21 tests in tests/visualization/test_kg_visualizer_normalize_graph.py
covering the helper directly, the end-to-end regression for #458, and
a guard that every public method routes through _normalize_graph.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-14 11:04:25 +05:30
Mohd Kaif e00bdfe8d4 Merge branch 'main' into feat/explorer-vocab-ui 2026-04-11 18:01:45 +05:30
KaifAhmad1 9d0744e20e fix(triplet-store): coerce non-string IDs and guard known vocabulary prefixes in _resolve_iri
Bug 1 — non-string IDs crash store():
_resolve_iri() called .startswith() directly on local, causing AttributeError
when upstream graph builders emit integer entity/relationship IDs. Fixed by
coercing local to str() at entry; None/empty returns a safe urn: sentinel.

Bug 2 — prefixed W3C terms mis-resolved under base_uri:
Values like 'owl:Thing' and 'xsd:date' were not recognised as absolute IRIs
and with base_uri set were rewritten to e.g. https://example.com/owl:Thing,
corrupting standard OWL/XSD IRIs in stored triples. Fixed by adding a known-
prefix expansion table (xsd/rdf/rdfs/owl/skos/semantica) that is checked before
base_uri is applied, matching the same prefix map already used in blazegraph_store.

Added 5 regression tests covering both bugs: integer IDs with/without base_uri,
owl:Thing domain/range, xsd:date range, and rdfs:/skos: parent class expansion.
2026-04-11 16:51:39 +05:30
KaifAhmad1 0b52b715dc fix(triplet-store): resolve entity/class/property IRIs against ontology namespace base_uri (Fixes #447)
store() was minting urn:entity:, urn:class:, and urn:property: URIs for every
bare local name, even when the ontology carried a namespace.base_uri. This made
instance data and ontology class data irreconcilable in SPARQL joins.

- Extract base_uri from ontology.namespace.base_uri (or ontology.uri as fallback)
- Introduce _resolve_iri(local, kind) closure that appends the local name to
  base_uri when present, keeping urn: fallback only when no base URI is known
- Apply _resolve_iri consistently for entity URIs, entity types, relationship
  predicates, ontology class URIs, parent class URIs, property URIs, and
  property domain/range URIs
- Explicit entity.uri values are never overridden
- Added 9 regression tests in TestTripletStoreOntologyNamespace covering all
  IRI expansion paths, urn: fallback, explicit URI passthrough, top-level uri
  key fallback, and trailing-slash safety
2026-04-11 15:47:42 +05:30
KaifAhmad1 2e2dae558f fix(blazegraph): expand prefixed datatypes and validate lang/datatype metadata
- Added _resolve_datatype_iri() to expand known prefixes (xsd/rdf/rdfs/owl/skos)
  to full IRIs instead of blindly wrapping in <...>, fixing invalid SPARQL like
  <xsd:integer>
- Validated language tags against RFC 5646 regex to prevent SPARQL injection
  via metadata["lang"] values containing whitespace or punctuation
- Validated datatype IRIs for whitespace/special characters before interpolation
- Extended test suite from 7 to 15 cases covering prefix expansion, injection
  rejection, and all accepted input forms
2026-04-11 15:16:15 +05:30
KaifAhmad1 3a1a798107 Fix Blazegraph literal serialization in bulk loader (Fixes #448) 2026-04-11 14:58:51 +05:30
KaifAhmad1 9366f07239 test(ontology): assert ontology uri prefix is used for generated IRIs 2026-04-11 13:52:04 +05:30
Mohd Kaif 61676fb321 Merge branch 'main' into ontology 2026-04-11 13:39:10 +05:30
KaifAhmad1 d2c20d410c fix(ontology): address #446 follow-up review findings\n\n- prefer label over name for generated IRIs\n- fix datatype range list handling in rdflib path\n- align generated IRIs with ontology uri namespace\n- resolve local subclassOf names to class IRIs\n- expand regression coverage and update changelog 2026-04-11 13:02:49 +05:30
KaifAhmad1 67a8ab1a8e fix(ontology): preserve user-facing schema fields in OWL generation\n\nFixes #446 2026-04-11 12:39:46 +05:30
Zohaib Hassnain dfd7785cc1 feat: overhaul graph explorer visuals and loading flow 2026-04-11 03:19:28 +05:00
Mohd KaifandCopilot Autofix powered by AI <223894421+github-code-quality[bot]@users.noreply.github.com> c77690129d Potential fix for pull request finding 'Imprecise assert'
Co-authored-by: Copilot Autofix powered by AI <223894421+github-code-quality[bot]@users.noreply.github.com>
2026-04-07 17:53:26 +05:30
KaifAhmad1andClaude Sonnet 4.6 655a24b77e fix: correct three test failures in unreleased changelog test suite
- Remove orphaned unclosed parenthesis (syntax error) in
  test_unreleased_changelog_comprehensive.py (OllamaProvider block)
- Fix test_invalid_json_returns_error to assert compliant=False and
  non-empty violations instead of missing "error" key — aligns with
  check_policy() return schema
- Fix test_as_of_filters_future_decisions to extract scenario via
  p["decision"]["scenario"] (correct nesting) and pass
  similarity_threshold=0.0 so word-overlap doesn't filter out Bob's
  decision below the 0.5 default

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-07 17:42:08 +05:30
Zohaib Hassnain 38b766298e feat(explorer): harden knowledge explorer backend and frontend, polish dashboard UX 2026-04-07 02:04:17 +05:00
Mohd KaifandCopilot Autofix powered by AI <223894421+github-code-quality[bot]@users.noreply.github.com> 4747d403bc Potential fix for pull request finding 'Syntax error'
Co-authored-by: Copilot Autofix powered by AI <223894421+github-code-quality[bot]@users.noreply.github.com>
2026-04-02 20:41:33 +05:30
Mohd Kaif 8348df63be Merge branch 'main' into utils 2026-04-02 20:37:10 +05:30
KaifAhmad1andClaude Sonnet 4.6 68b8b370d6 fix: address PR #434 code-quality review findings
- add_decision: pass valid_from/valid_until through kwargs path so
  temporal bounds are not silently dropped into metadata (Codex P1)
- add_decision: raise ValueError when Decision object and kwargs are
  both provided, instead of silently ignoring the kwargs (Codex P2)
- fix guard condition to exclude decision_maker (non-None default)
  to avoid false-positive ValueError on plain add_decision(obj) calls
- test_395: remove unused `import time`; strengthen as_of test with
  concrete assertions on scenarios list (github-code-quality)
- test_unreleased: remove unused `import time`; drop unused `snap =`
  assignment; drop unused `provider =` assignment (github-code-quality)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-02 20:34:59 +05:30
KaifAhmad1andClaude Sonnet 4.6 f8ec5ac010 test: cover add_decision kwargs form and VectorStore inmemory backend
- test_add_decision_kwargs_form: verifies add_decision() accepts kwargs
  directly (category, scenario, reasoning, outcome, confidence) without
  requiring a Decision object
- test_add_decision_kwargs_and_object_both_return_id: verifies both call
  forms return a non-empty string ID
- test_agent_context_inmemory_store_and_retrieve: verifies AgentContext
  with VectorStore(backend="inmemory") stores memories without faiss-cpu

Closes #433

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-02 20:25:34 +05:30
KaifAhmad1andSameer6305 a51542ce40 fix: address named-graph review findings
- honor enable_named_graphs flag when forwarding support

- prevent duplicate FROM/FROM NAMED clauses for same graph

- add default_graph_uri compatibility alias

- harden graph URI sanitization in prune DROP GRAPH path

- add regression tests for all fixes

Co-authored-by: Sameer6305 <sskadam6305@gmail.com>

Co-authored-by: KaifAhmad1 <kaifahmad087@gmail.com>
2026-04-02 18:10:11 +05:30
Sameer6305 ce01067009 test: add graph isolation tests 2026-04-02 15:46:41 +05:30
KaifAhmad1andClaude Sonnet 4.6 1d88c06cbb fix(security): resolve CodeQL alerts for logging, URL sanitization, and workflow permissions
- Remove api_key debug print blocks from relation_extractor.py and triplet_extractor.py (CWE-532 clear-text logging)
- Replace URL substring check with exact equality in test_web_ingestor.py (CWE-20 incomplete sanitization)
- Add `permissions: contents: read` to benchmark.yml and security.yml workflows (least-privilege)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-30 19:46:30 +05:30
KaifAhmad1andClaude Sonnet 4.6 f677b638e2 fix(explorer): resolve test crash, import error handling, cycle safety, and missing utils package
- test_vocabulary.py: remove sys.modules['spacy'] = MagicMock() — caused
  ValueError in pytest collection when transformers called
  importlib.util.find_spec('spacy') on a MagicMock without __spec__;
  add setup_function() reset_mock() to prevent cross-test state pollution;
  expand from 3 to 16 tests covering narrower edges, topConceptOf,
  hasTopConcept, flat scheme, empty scheme, missing param, cycle safety,
  .rdf/.owl format path, invalid file 422, and metadata envelope fallback
- vocabulary.py: /import returned HTTP 200 with {"status":"error"} on parse
  failure — now raises HTTPException(422) so clients get a proper error code;
  replace bare except with ValueError-specific catch, move add_nodes/add_edges
  outside the try block
- vocabulary.py: get_hierarchy tree assembly had no cycle detection — cyclic
  broader/narrower edges in real-world SKOS data would cause infinite recursion
  during Pydantic serialization; replaced inline loop with recursive
  _attach_children() that carries a visited set
- semantica/explorer/utils/: branch was based on main and missing rdf_parser.py
  and __init__.py (introduced in #425); copied from ebd2be3 so vocabulary.py
  import resolves correctly
- tests/explorer/test_rdf_parser.py: carried forward from #425 (32 tests)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-30 19:02:24 +05:30
ZohaibHassan16 2537976e8f feat(explorer): implement SKOS vocabulary routes and integration tests 2026-03-30 17:01:11 +05:00
Mohd KaifandClaude Sonnet 4.6 e30ef6cb76 Kg Context Explainability Output Fixes (#419)
* feat(#401): temporal provenance, OWL-Time export, stable snapshot schema

- ProvenanceTracker: auto-attach recorded_at (UTC) to every new record;
  add query_recorded_between(), revision_history(), export_audit_log()
- RDFExporter.export_to_rdf: add include_temporal + time_axis params;
  emit OWL-Time triples (time:Interval, time:Instant, inXSDDateTimeStamp)
  for relationships with valid_from/valid_until; TemporalBound.OPEN
  represented via semantica:openEndedInterval instead of time:hasEnd
- TemporalVersionManager.create_snapshot: stamp format_version "1.0"
  on every snapshot; add validate_snapshot() and migrate_snapshot()
- New: semantica/kg/schemas/temporal_snapshot_v1.json (JSON Schema draft-2020)
- Tests: 28 new tests covering all acceptance criteria (451 passing, 0 failed)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs(#401): add changelog entry for temporal provenance & export

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(#402): Temporal GraphRAG Integration — TemporalGraphRetriever & TemporalQueryRewriter

- Add TemporalGraphRetriever to context_retriever.py (no new file per project convention)
  - Drop-in wrapper for ContextRetriever; filters related_entities/related_relationships
    via reconstruct_at_time(); at_time=None is a true passthrough
  - Returns new RetrievedContext objects (no in-place mutation)
  - Graceful ImportError if temporal modules unavailable

- Add at_time + header_template to ContextRetriever._generate_reasoned_response()
  and query_with_reasoning()
  - Temporal header prepended to LLM context block only when at_time is set
  - Naive datetimes normalised to UTC before formatting
  - Header built with str.replace (not .format) to prevent format-string injection

- Add TemporalQueryRewriter + TemporalQueryResult to semantica/kg/
  - Regex-only (default) and LLM-assisted extraction modes
  - Resolves temporal phrases via TemporalNormalizer (deterministic, zero LLM)
  - Word-boundary guards on intent keywords; year fallback for noun-phrase dates
  - Never calls reconstruct_at_time — extraction only

- Export TemporalGraphRetriever from semantica.context
- Export TemporalQueryRewriter, TemporalQueryResult from semantica.kg

- Add 99 tests across two new test files
  - tests/context/test_temporal_retriever.py (56 tests)
  - tests/kg/test_temporal_query_rewriter.py (43 tests)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs(#402): add changelog entry for Temporal GraphRAG Integration

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs: rewrite and polish documentation site (#413)

- Rewrote index.md to match README (tagline, badges, Problem/Solution text)
- Improved getting-started, concepts, quickstart, installation, faq, use-cases, contributing, glossary, learning-more, examples, modules, architecture, cookbook, deep-dive pages: tighter prose, fixed headings/bullets, removed inconsistencies and duplicate sections
- Removed overuse of emojis from headings in integration pages (docling, snowflake)
- Fixed change_management reference page: closed unclosed JSON code block that broke the right TOC, demoted noisy sub-headings to bold text
- CSS layout: widened content area (max-width 1440px grid, left sidebar 11rem, right TOC narrowed to 11rem for broader content), tightened TOC spacing and font size, fixed word-wrap/overflow on TOC links
- Added mkdocs_local.yml for local serving without mkdocs-jupyter plugin

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(#318): SHACL Shape Generation & Validation (Phase 1 + Phase 2)

Phase 1 — Generation:
- Add SHACLGenerator, SHACLGraph, NodeShape, PropertyShape to ontology_generator.py
- 6-stage pipeline: class index → node shapes → property shapes → inheritance propagation → quality tier → serialization
- Three output formats: Turtle, JSON-LD, N-Triples
- Three quality tiers: basic / standard (default) / strict (sh:closed)
- 3-level+ inheritance propagation, cycle-safe, no duplicate shapes
- No-domain properties attach to all node shapes
- OntologyEngine.to_shacl(), export_shacl() added to engine.py
- RDFExporter.export_shacl() added to rdf_exporter.py

Phase 2 — Runtime Validation:
- Add SHACLViolation, SHACLValidationReport, _run_pyshacl to ontology_validator.py
- OntologyEngine.validate_graph() with shacl= or ontology= arguments
- explain_violations(): rule-based plain-English explanations for all 7 SHACL constraint types
- summary(), to_dict() on SHACLValidationReport for pipeline and LLM consumers
- pyshacl/rdflib are optional deferred imports (pip install semantica[shacl])

Security & reliability fixes:
- Replace path-heuristic (len/newline) with os.path.exists() in validate_graph
- Add shacl_format parameter to validate_graph and _run_pyshacl; thread format through correctly
- Fix validate_output format alias map in to_shacl (json-ld, n-triples aliases)
- Deep-copy PropertyShape in _propagate_inheritance (dataclasses.replace) — no shared mutable refs
- Deterministic Turtle prefix output via sorted(graph.prefixes.items())
- Use full rdf:type URI in sh:ignoredProperties — no prefix dependency

Tests & docs:
- Add TestSHACLGeneration (16 tests) to test_ontology_comprehensive.py
- Add TestSHACLHierarchicalAndValidation (18 tests) to test_ontology_advanced.py
- 34 new tests, 0 failures, 0 regressions across 1111-test suite
- Update README: Unreleased section, Features, Modules table, Ontology code block, Installation

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs(#318): add CHANGELOG entry for SHACL Shape Generation & Validation

Covers Phase 1 (generation), Phase 2 (runtime validation), all 5
security/reliability fixes, test results, and README updates.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(#319): SKOS Vocabulary Module — namespace helpers, store helpers, OntologyEngine APIs, tests, docs

Extends the existing ontology and triplet-store stack with first-class
SKOS support without adding any new top-level packages.

### semantica/ontology/namespace_manager.py
- `get_skos_uri(local_name)` — build full skos:core# URI from local name
- `build_concept_scheme_uri(name)` — slug a human name into a stable
  ConceptScheme URI anchored at the configured base URI

### semantica/triplet_store/triplet_store.py
- `add_skos_concept(concept_uri, scheme_uri, pref_label, ...)` — asserts
  ConceptScheme + Concept triples, prefLabel, altLabel, broader, narrower,
  related, definition, notation via existing `add_triplets()` API
- `get_skos_concepts(scheme_uri=None)` — SPARQL SELECT via `execute_query()`,
  collapses multi-valued bindings into concept dicts

### semantica/ontology/engine.py
- `list_vocabularies()` — list all skos:ConceptScheme instances
- `list_concepts(scheme_uri)` — list concepts in a scheme with alt labels
- `search_concepts(query, scheme_uri=None)` — case-insensitive substring
  search over prefLabel + altLabel; sanitises user input against SPARQL injection

### tests
- `TestSKOSOntologyEngine` (14 tests) in test_ontology_comprehensive.py
- `TestSKOSTripletStore` (6 tests) in test_triplet_store.py
- All 1162 existing + new tests pass, 0 failures

### docs/reference/ontology.md
- New "SKOS Vocabulary Management" section: data-model table, import
  examples (add_skos_concept + rdflib bulk), list/search API, NamespaceManager helpers

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs(#319): add CHANGELOG entry for SKOS Vocabulary Module

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* test: add comprehensive test suites for Temporal Semantics (#395) and all Unreleased changelog features

- tests/test_395_temporal_semantics_comprehensive.py — 113 tests covering
  #396–#399: bitemporal model, temporal consistency validation, query
  time-range aggregation, ContextGraph.state_at(), causal chain trace_at_time()
- tests/test_unreleased_changelog_comprehensive.py — 92 tests covering all
  unreleased changelog gaps: AgentContext checkpoints (#399), audit trail /
  named tags / rollback protection (#394), snapshot schema compatibility (#393),
  ContextGraph pagination & min_weight & thread safety (#385), SKOS helpers
  (#319), SHACL quality tiers & export (#318), OllamaProvider base_url (#408),
  DatalogReasoner multi-hop & graph load (#371)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix: Context Explainability Output Fixes — regression tests and centrality fix

- Fixed CentralityCalculator._build_adjacency() to handle ContextGraph edges
  (ContextEdge dataclass objects with source_id/target_id) so degree centrality
  and related algorithms return correct results instead of empty dicts
- Added 23 regression tests in tests/context/test_context_explainability_regression.py
  covering readable decision text preservation, enriched causal/path outputs,
  PolicyEngine consistent metadata across Cypher and fallback branches,
  EntityLinker similarity payloads, and KG consumer compatibility
- Updated CHANGELOG.md [Unreleased] to reflect the bug fix and test additions

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-29 13:03:52 +05:30
Mohd KaifandClaude Sonnet 4.6 cf7a78fa10 test: add comprehensive test suites for Temporal Semantics (#395) and all Unreleased changelog features (#417)
- tests/test_395_temporal_semantics_comprehensive.py — 113 tests covering
  #396–#399: bitemporal model, temporal consistency validation, query
  time-range aggregation, ContextGraph.state_at(), causal chain trace_at_time()
- tests/test_unreleased_changelog_comprehensive.py — 92 tests covering all
  unreleased changelog gaps: AgentContext checkpoints (#399), audit trail /
  named tags / rollback protection (#394), snapshot schema compatibility (#393),
  ContextGraph pagination & min_weight & thread safety (#385), SKOS helpers
  (#319), SHACL quality tiers & export (#318), OllamaProvider base_url (#408),
  DatalogReasoner multi-hop & graph load (#371)

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-28 18:48:04 +05:30
KaifAhmad1andClaude Sonnet 4.6 4f0cf282a1 test: add comprehensive test suites for Temporal Semantics (#395) and all Unreleased changelog features
- tests/test_395_temporal_semantics_comprehensive.py — 113 tests covering
  #396–#399: bitemporal model, temporal consistency validation, query
  time-range aggregation, ContextGraph.state_at(), causal chain trace_at_time()
- tests/test_unreleased_changelog_comprehensive.py — 92 tests covering all
  unreleased changelog gaps: AgentContext checkpoints (#399), audit trail /
  named tags / rollback protection (#394), snapshot schema compatibility (#393),
  ContextGraph pagination & min_weight & thread safety (#385), SKOS helpers
  (#319), SHACL quality tiers & export (#318), OllamaProvider base_url (#408),
  DatalogReasoner multi-hop & graph load (#371)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-28 18:44:03 +05:30
KaifAhmad1andClaude Sonnet 4.6 71d037f581 feat(#319): SKOS Vocabulary Module — namespace helpers, store helpers, OntologyEngine APIs, tests, docs
Extends the existing ontology and triplet-store stack with first-class
SKOS support without adding any new top-level packages.

### semantica/ontology/namespace_manager.py
- `get_skos_uri(local_name)` — build full skos:core# URI from local name
- `build_concept_scheme_uri(name)` — slug a human name into a stable
  ConceptScheme URI anchored at the configured base URI

### semantica/triplet_store/triplet_store.py
- `add_skos_concept(concept_uri, scheme_uri, pref_label, ...)` — asserts
  ConceptScheme + Concept triples, prefLabel, altLabel, broader, narrower,
  related, definition, notation via existing `add_triplets()` API
- `get_skos_concepts(scheme_uri=None)` — SPARQL SELECT via `execute_query()`,
  collapses multi-valued bindings into concept dicts

### semantica/ontology/engine.py
- `list_vocabularies()` — list all skos:ConceptScheme instances
- `list_concepts(scheme_uri)` — list concepts in a scheme with alt labels
- `search_concepts(query, scheme_uri=None)` — case-insensitive substring
  search over prefLabel + altLabel; sanitises user input against SPARQL injection

### tests
- `TestSKOSOntologyEngine` (14 tests) in test_ontology_comprehensive.py
- `TestSKOSTripletStore` (6 tests) in test_triplet_store.py
- All 1162 existing + new tests pass, 0 failures

### docs/reference/ontology.md
- New "SKOS Vocabulary Management" section: data-model table, import
  examples (add_skos_concept + rdflib bulk), list/search API, NamespaceManager helpers

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-28 13:59:23 +05:30
KaifAhmad1andClaude Sonnet 4.6 dae368532c feat(#318): SHACL Shape Generation & Validation (Phase 1 + Phase 2)
Phase 1 — Generation:
- Add SHACLGenerator, SHACLGraph, NodeShape, PropertyShape to ontology_generator.py
- 6-stage pipeline: class index → node shapes → property shapes → inheritance propagation → quality tier → serialization
- Three output formats: Turtle, JSON-LD, N-Triples
- Three quality tiers: basic / standard (default) / strict (sh:closed)
- 3-level+ inheritance propagation, cycle-safe, no duplicate shapes
- No-domain properties attach to all node shapes
- OntologyEngine.to_shacl(), export_shacl() added to engine.py
- RDFExporter.export_shacl() added to rdf_exporter.py

Phase 2 — Runtime Validation:
- Add SHACLViolation, SHACLValidationReport, _run_pyshacl to ontology_validator.py
- OntologyEngine.validate_graph() with shacl= or ontology= arguments
- explain_violations(): rule-based plain-English explanations for all 7 SHACL constraint types
- summary(), to_dict() on SHACLValidationReport for pipeline and LLM consumers
- pyshacl/rdflib are optional deferred imports (pip install semantica[shacl])

Security & reliability fixes:
- Replace path-heuristic (len/newline) with os.path.exists() in validate_graph
- Add shacl_format parameter to validate_graph and _run_pyshacl; thread format through correctly
- Fix validate_output format alias map in to_shacl (json-ld, n-triples aliases)
- Deep-copy PropertyShape in _propagate_inheritance (dataclasses.replace) — no shared mutable refs
- Deterministic Turtle prefix output via sorted(graph.prefixes.items())
- Use full rdf:type URI in sh:ignoredProperties — no prefix dependency

Tests & docs:
- Add TestSHACLGeneration (16 tests) to test_ontology_comprehensive.py
- Add TestSHACLHierarchicalAndValidation (18 tests) to test_ontology_advanced.py
- 34 new tests, 0 failures, 0 regressions across 1111-test suite
- Update README: Unreleased section, Features, Modules table, Ontology code block, Installation

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-27 17:42:46 +05:30
KaifAhmad1andClaude Sonnet 4.6 0f0800f109 feat(#402): Temporal GraphRAG Integration — TemporalGraphRetriever & TemporalQueryRewriter
- Add TemporalGraphRetriever to context_retriever.py (no new file per project convention)
  - Drop-in wrapper for ContextRetriever; filters related_entities/related_relationships
    via reconstruct_at_time(); at_time=None is a true passthrough
  - Returns new RetrievedContext objects (no in-place mutation)
  - Graceful ImportError if temporal modules unavailable

- Add at_time + header_template to ContextRetriever._generate_reasoned_response()
  and query_with_reasoning()
  - Temporal header prepended to LLM context block only when at_time is set
  - Naive datetimes normalised to UTC before formatting
  - Header built with str.replace (not .format) to prevent format-string injection

- Add TemporalQueryRewriter + TemporalQueryResult to semantica/kg/
  - Regex-only (default) and LLM-assisted extraction modes
  - Resolves temporal phrases via TemporalNormalizer (deterministic, zero LLM)
  - Word-boundary guards on intent keywords; year fallback for noun-phrase dates
  - Never calls reconstruct_at_time — extraction only

- Export TemporalGraphRetriever from semantica.context
- Export TemporalQueryRewriter, TemporalQueryResult from semantica.kg

- Add 99 tests across two new test files
  - tests/context/test_temporal_retriever.py (56 tests)
  - tests/kg/test_temporal_query_rewriter.py (43 tests)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-26 14:20:38 +05:30
Mohd KaifandClaude Sonnet 4.6 9e68266563 feat(#401): Temporal Provenance & Export (#411)
* feat(#401): temporal provenance, OWL-Time export, stable snapshot schema

- ProvenanceTracker: auto-attach recorded_at (UTC) to every new record;
  add query_recorded_between(), revision_history(), export_audit_log()
- RDFExporter.export_to_rdf: add include_temporal + time_axis params;
  emit OWL-Time triples (time:Interval, time:Instant, inXSDDateTimeStamp)
  for relationships with valid_from/valid_until; TemporalBound.OPEN
  represented via semantica:openEndedInterval instead of time:hasEnd
- TemporalVersionManager.create_snapshot: stamp format_version "1.0"
  on every snapshot; add validate_snapshot() and migrate_snapshot()
- New: semantica/kg/schemas/temporal_snapshot_v1.json (JSON Schema draft-2020)
- Tests: 28 new tests covering all acceptance criteria (451 passing, 0 failed)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs(#401): add changelog entry for temporal provenance & export

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-26 12:38:24 +05:30
KaifAhmad1andClaude Sonnet 4.6 b9af181625 feat(semantic-extract): temporal metadata extraction from text (#400)
- Add `extract_temporal_bounds: bool = False` to `extract_relations_llm()`.
  When True the LLM prompt is extended with a calibrated confidence scale
  and four few-shot examples; each returned Relation gains valid_from,
  valid_until, temporal_confidence, and temporal_source_text in metadata.
  Low confidence (<0.5) with non-null dates logs a WARNING. Default False
  preserves 100% backward compatibility.

- Add `RelationWithTemporalOut` / `RelationsWithTemporalResponse` Pydantic
  schemas so the four temporal fields are captured from structured LLM
  output (separate from RelationOut which uses extra="ignore").

- New `semantica/kg/temporal_normalizer.py` — `TemporalNormalizer` class
  (zero LLM calls, pure regex + dateutil arithmetic):
    * normalize(value) → (start, end) UTC datetimes or None
    * Resolution order: ISO 8601 → partial dates (year/month/Q) →
      ambiguity detection → domain phrase map → relative phrases
    * normalize_phrase(phrase) → metadata dict or None
    * Default phrase map covers 13 domains: General, Policy, Healthcare,
      Drug Discovery, Cybersecurity, Supply Chain, Finance, Energy
    * TemporalAmbiguityWarning for DD/MM/YYYY-style ambiguous inputs
    * Custom phrase_map at construction (merged over defaults)

- Add `TemporalAmbiguityWarning(UserWarning)` to exceptions.py.
- Export `TemporalNormalizer` from `semantica/kg/__init__.py`.
- Propagate `extract_temporal_bounds` through `_extract_relations_chunked`
  and add flag to cache key to prevent cross-mode cache pollution.

- 53 new tests in tests/semantic_extract/test_temporal_extraction.py;
  zero real LLM calls, suite runs in ~3.5s. 873 existing tests unaffected.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-25 21:42:57 +05:30
KaifAhmad1andClaude Sonnet 4.6 19665b9db2 fix(semantic-extract): pass base_url as host when initialising OllamaProvider client
Closes #408

Previously `_init_client` assigned the raw `ollama` module to
`self.client`, so the `base_url` parameter was silently ignored and
every request hit the default localhost:11434. Now an `ollama.Client`
instance is created with `host=self.base_url`, so remote Ollama servers
are reachable.

Three regression tests added to prevent recurrence:
- default base_url is forwarded as host
- custom base_url (e.g. http://192.168.1.3:11434) is forwarded as host
- self.client is never the raw module

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-24 19:36:22 +05:30
KaifAhmad1andClaude Sonnet 4.6 01ba7d113b feat(context): add temporal awareness to ContextGraph and AgentContext
- Add valid_from/valid_until fields to Decision dataclass and record_decision()
- Add include_superseded and as_of filters to find_precedents_by_scenario()
- Add _decision_matches_temporal_filters() and _normalize_temporal_input() helpers
- Add ContextGraph.state_at(timestamp) for point-in-time graph snapshots
- Stamp recorded_at on causal relationship edges
- Add CausalChainAnalyzer.trace_at_time() for transaction-time causal chain tracing
- Add AgentContext.checkpoint(), diff_checkpoints(), flush_checkpoint() for named context snapshots
- 93 tests passing (33 context_graph, 36 causal_analyzer, 24 agent_context)

Closes #399

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-24 12:18:25 +05:30
KaifAhmad1 a3a0848577 Fix semantic extract spaCy fallback review issues 2026-03-23 23:31:01 +05:30
Mohd Kaif eeda5f5b80 Merge branch 'main' into semantic-extract 2026-03-23 23:16:19 +05:30
KaifAhmad1 62b03d4fa5 Harden spaCy NER fallback in semantic extract 2026-03-23 23:12:48 +05:30
KaifAhmad1 8de7cc1b6d Fix temporal reasoning review issues 2026-03-23 19:43:12 +05:30
KaifAhmad1 c6dc9d87aa Add deterministic temporal reasoning engine 2026-03-23 19:12:18 +05:30
KaifAhmad1 b2b823a5c3 Fix temporal query review follow-ups 2026-03-23 17:13:02 +05:30
KaifAhmad1 3c863e860e Implement temporal point-in-time correctness (#397) 2026-03-23 16:39:49 +05:30
KaifAhmad1 8be16f782e Fix temporal revision integrity follow-ups 2026-03-23 16:12:29 +05:30
KaifAhmad1 9faa5661f8 Core temporal data model overhaul (#396) 2026-03-23 15:53:13 +05:30
OpenAI CodexandKaifAhmad1 e13ea740cd merge: resolve main conflicts for PR #394
Co-authored-by: KaifAhmad1 <kaifahmad087@gmail.com>
2026-03-22 20:12:01 +05:30
OpenAI CodexandKaifAhmad1 e2b79ada9a fix(change-management): preserve snapshot compatibility and audit integrity
Co-authored-by: KaifAhmad1 <kaifahmad087@gmail.com>
2026-03-22 19:45:58 +05:30
Mohd Kaif 4147f0ca3b Merge branch 'main' into fix/snapshot-key-mismatch 2026-03-22 17:42:32 +05:30
OpenAI Codex adac6f7a7b fix(change-management): preserve snapshot schema compatibility 2026-03-22 17:26:07 +05:30
Mohd Kaif ca8a916373 Merge branch 'main' into fix/issue-379-decision-query-fallback 2026-03-21 17:10:52 +05:30
KaifAhmad1andClaude Sonnet 4.6 13eed9cf6d fix(context): fix isinstance regression, hoist BFS find_edges, expand tests
- Replace isinstance(graph_store, ContextGraph) with type() is ContextGraph
  in all 12 guards across decision_query.py and decision_recorder.py.
  Fixes 2 regressions where Mock(spec=ContextGraph) triggered fallback
  paths, causing TypeError on iteration of mock return values.

- Hoist find_edges() calls out of the BFS while-loop in trace_decision_path
  so edges are fetched once per call instead of once per visited node,
  eliminating O(nodes * total_edges) repeated full-graph fetches.

- Expand test_decision_query_fallback.py: keep the original integration
  test and add 13 targeted unit tests covering all 7 DecisionQuery and
  4 DecisionRecorder ContextGraph fallback methods, including tz-aware/naive
  datetime mixing and Mock guard validation.

Result: 353 passed, 0 failed (was 338 passed, 2 failed on this branch)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-21 17:08:44 +05:30
KaifAhmad1andClaude Sonnet 4.6 ac047f917a fix(explorer): resolve merge-artifact syntax errors and clean up all route files
app.py:
- Fix unclosed '(' in generic_error_handler (two implementations were merged,
  leaving the return JSONResponse( call with no closing paren)
- Remove duplicate 'from fastapi import FastAPI, Request' import
- Remove unused 'import traceback'
- Remove duplicate static file mount (was mounted twice: once conditionally,
  once unconditionally creating the dir — FastAPI raises on duplicate mounts)

decisions.py:
- Remove stub 'return ComplianceResponse(compliant=True)' with unclosed '('
  that was left in front of the real edge-scan implementation

temporal.py:
- Remove blocking get_nodes/get_edges calls (without asyncio.to_thread) that
  were left as dead code above the correct async versions
- Fix empty 'except Exception:' clause before 'except ImportError:' that
  caused a SyntaxError

tests/explorer/test_explorer_api.py:
- Remove all merge-artifact duplicate class definitions (TestAnalytics x2,
  TestReasoning x2, TestAnnotations x2) — Python silently used the second
  definition, hiding the first; collapsed into single canonical classes
- Fix test_snapshot_at referencing undefined 'body' (no request was made);
  merged its assertions into test_snapshot_now
- Fix test_compliance asserting isinstance(body, list) on a dict response;
  the displaced precedents-check code is now in test_precedents where it
  belongs
- Fix test_compliance_with_violation using wrong session reference
- Remove duplicate node-lookup and duplicate assertions throughout
- Add test_search_content_populated: asserts search results carry non-empty
  content (regression guard for the to_dict envelope fix)
- Add test_import_edge_metadata_preserved: asserts edge metadata survives the
  import round-trip (regression guard for the properties/metadata fallback fix)

All 51 tests pass.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-20 00:18:08 +05:30
Mohd Kaif a0e7e9a1c9 Merge branch 'main' into fix/cg-thpag 2026-03-19 23:39:20 +05:30