Commit Graph
76 Commits
Author SHA1 Message Date
dependabot[bot]anddependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> 5048665d35 chore(deps): bump dompurify from 3.4.12 to 3.4.13 in /explorer (#872)
Bumps [dompurify](https://github.com/cure53/DOMPurify) from 3.4.12 to 3.4.13.
- [Release notes](https://github.com/cure53/DOMPurify/releases)
- [Commits](https://github.com/cure53/DOMPurify/compare/3.4.12...3.4.13)

---
updated-dependencies:
- dependency-name: dompurify
  dependency-version: 3.4.13
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-08-09 21:31:11 +05:30
KaifAhmad1 5cd4407e57 fix(explorer): review follow-ups for #830 render-loop fix
- Wire the Explorer frontend's node --test suites (test:graph-store,
  test:graph-workspace, and the new test:plugin-registry regression
  test) into CI. Previously only `npm run build` ran, so none of the
  frontend tests -- including this fix's own regression coverage --
  executed anywhere except a contributor's local machine.
- Broaden the diagnostics dedup's structureLayer comparison to also
  cover disabledReason/curveCount/bridgeCurveCount/backboneCurveCount,
  not just cacheKey/lastDrawAt/enabled, so a disabledReason-only
  transition doesn't leave the dev diagnostics panel stale.
2026-08-06 13:03:56 +05:30
Sameer6305 667e69a0c1 refactor: tighten comments across #830 changes for clarity
- pluginRegistryPredicates.ts: consolidate 8-line JSDoc to 5 lines,
  removing redundant detail that restated implementation mechanics
  already obvious from the code.

- GraphWorkspace.tsx: shorten the lastScrubberMsRef comment from 5 lines
  to 2; trim the handleDiagnosticsChange block comment by removing the
  'rather than bailing out' implementation-alternative sentence; tighten
  the distanceVisual inline comment.

- pluginRegistry.temporal.test.mjs: replace 17-line file-level JSDoc
  with 9 lines focused on the invariant rather than the root-cause
  narrative (already covered in pluginRegistryPredicates.ts); remove
  two tsx loader implementation-detail comments; tighten two test-level
  inline comments.

No logic, types, or test assertions changed. All 42 tests pass.
2026-08-05 17:52:21 +05:30
Sameer6305 80de3652cf fixed qodo findings
Two issues addressed:

1. Plugin-loading useEffect unnecessarily depended on temporalState.
   After the #830 fix, no shouldLoad predicate reads temporalState, but
   the effect's dep array still included it, causing extra re-runs on
   every scrubber update. Removed temporalState from the dep array and
   the shouldLoad call site. Made temporalState optional in the
   LazyPluginRegistryEntry shouldLoad context type to match.

2. Regression test imported a local copy of shouldLoad instead of the
   production predicate. Extracted all three shouldLoad predicates into
   pluginRegistryPredicates.ts (pure module, no React/DOM dependencies),
   wired GraphWorkspace.tsx to use the imported functions, and updated
   the test to import and exercise the real production code via tsx.
   Verified: introducing the old broken condition causes the test to fail;
   the correct implementation passes all 7 assertions.
2026-08-05 17:37:33 +05:30
Sameer6305 8d52281cdf chore(explorer): clean up #830 branch — remove #793 file, add regression test
temporalDiffState.ts belongs to feat/793-temporal-diff-ui and should not
appear in the #830 diff. Remove it from this branch's tracked files.

Add the pluginRegistry.temporal.test.mjs regression test that covers the
shouldLoad fix committed in the main #830 commit (it was never committed).

Add test:plugin-registry script to package.json so the regression test
can be run via npm run test:plugin-registry.
2026-08-05 16:26:24 +05:30
Sameer6305 6a0eecbe02 fix(explorer): resolve #830 — Maximum update depth exceeded on Temporal panel open
Two independent render loops were causing the Temporal panel to remain
stuck on 'Loading temporal...' in npm run dev:

Loop 1 — diagnostics state churn (GraphWorkspace.tsx):
  handleDiagnosticsChange unconditionally called setGraphDiagnosticsState
  with a new object on every invocation. buildEffectAvailability (called
  inside GraphCanvas's diagnostics useEffect) always returns a new object,
  so setGraphDiagnosticsState was called on every effect run, creating a
  cycle: setGraphDiagnosticsState  graphDiagnosticsState new
  diagnosticsSnapshot new  pluginContext new  handleInteractionStateChange
  new  GraphCanvas re-renders  diagnostics effect fires again.

  Fix: before calling setGraphDiagnosticsState, compare the incoming
  diagnostics field-by-field against the last accepted snapshot via a ref
  (lastDiagnosticsRef). All effectAvailability entries, edgeClasses.updatedAt,
  structureLayer.cacheKey/lastDrawAt/enabled, and distanceVisual identity
  must differ for a state update to proceed. The ref approach avoids
  scheduling a re-render at all, rather than bailing out inside a functional
  updater after the render has already been committed.

Loop 2 — scrubberTime churn (GraphWorkspace.tsx + GraphWorkspaceShell.tsx):
  TimelinePanel.tsx calls onTimeChange(defaultTime) whenever its useEffect
  re-runs. React 18 concurrent mode re-runs effects with structurally-new
  Date objects for the same timestamp when speculative renders discard
  useMemo caches, causing setScrubberTime to be called repeatedly with a
  new Date that has the same millisecond value — triggering temporalState
  churn, the diagnostics effect, and eventually the same loop.

  Fix: wrap setScrubberTime in an onTimeChange useCallback that compares the
  incoming time's millisecond value against the last sent value (via
  lastScrubberMsRef). Redundant calls with the same timestamp are dropped
  before reaching setScrubberTime. Stable useCallback identity also prevents
  TimelinePanel's useEffect from re-firing solely due to prop identity churn.

Both fixes applied to GraphWorkspace.tsx and identically to
GraphWorkspaceShell.tsx which has the same pattern.

Verified:
- npm run dev: 0 'Maximum update depth exceeded' errors
- Temporal panel renders with real data in dev mode
- Effects and Neighbors panels unaffected
- npm run build + preview: identical behavior, 0 errors
- All 42 frontend tests pass (34 graph-workspace, 1 graph-store, 7 plugin-registry)
2026-08-05 16:01:18 +05:30
Sameer6305 aa85535d47 fixed copilot review 2026-08-04 16:45:33 +05:30
Sameer6305 7d936d0f7c fix(explorer): write diff highlights to displayGraph as well as store graph
fixed qodo review

applyDiffHighlight/clearDiffHighlight were writing baseColor only to
graphStore.graph (the store singleton), but Sigma is constructed with
displayGraphRef.current and the nodeReducer reads attributes from that
instance. When the display graph is a derived copy (aggregated,
focused, or grouped view), the store write has no effect on the
currently-rendered frame -- sigma.scheduleRefresh() flushes the
reducer over the display graph, which did not receive the mutation.

Fix: introduce writeBaseColor(context, nodeId, color) which writes to
BOTH the store graph (so the color propagates into the next display
graph rebuild via aggregateDisplayGraph's shallow attribute copy) AND
context.displayGraph (the live Graph instance currently bound to
Sigma, so the change is visible in the current frame immediately).

The dg !== graph guard skips the display-graph write when they happen
to be the same object (non-aggregated full view), avoiding a redundant
double-write in that case.

Original baseColor is still captured from the store graph (the
authoritative source, since aggregateDisplayGraph copies from there),
so restore remains correct across all view modes.
2026-08-04 16:32:04 +05:30
Sameer6305 47531d8365 feat(explorer): add temporal diff comparison to the Temporal panel
Adds a Compare section to the existing Temporal Context panel
(temporalOverlayPlugin.tsx) that lets a user pick two ISO timestamps
and diff the graph's node set between them via the existing, previously
UI-less GET /api/temporal/diff backend route.

- New temporalDiffState.ts: typed fetch wrapper (fetchTemporalDiff)
  matching the route's added_nodes/removed_nodes response shape.
- Diff results recolor affected nodes via baseColor (not
  ringColor/haloColor -- traced and confirmed those are only read by
  the sigma reducer for hovered/selected/path-state nodes and are
  silently discarded for default-state nodes).
- Validates both timestamps are present, parseable, and from < to
  before firing a request.
- Distinct idle/loading/error/empty/success states -- an empty diff
  (no changes) is rendered as its own state, not as an error.
- Cancels any in-flight request via AbortController on re-submission
  and on unmount; restores each highlighted node's original baseColor
  (captured before overwrite, not cleared to a fallback default) on
  both paths.
- Reuses existing theme tokens (GRAPH_THEME.palette.semantic[2],
  ui.control.dangerText) and existing button/input/loading/error
  visual patterns already established in this same plugins directory
  and in GraphInspectorPanel.tsx, rather than introducing new styling.
2026-08-04 15:57:53 +05:30
KaifAhmad1 dcd936a9ab fix: restore error surfacing dropped by inlined mount-effect fetches
The set-state-in-effect refactor inlined each initial-fetch effect as a
standalone `fetchInitial`, duplicating the logic of the existing
reload/fetchOverview/fetchRegistry/loadVersions callbacks instead of
reusing them (required, since eslint-plugin-react-hooks v7 flags calling
an outside setState-touching function directly from an effect body, even
through an async gap - verified via a local lint probe). The duplicates
dropped the setError/flashMsg calls the originals had, so a failed
initial page load in AlignmentsTab, KGOverviewTab, OntologyManager, and
VersionsTab now failed silently instead of showing an error - a
regression of the exact bug #767/#790 fixed for these same files.

Also fixes LineageDiagram only clearing nodes/edges when the new
activeId was falsy, leaving the previous lineage view's stale diagram
on screen while switching directly between two ids.
2026-07-26 13:40:16 +05:30
KaifAhmad1 b663c6bbbf Merge branch 'main' into fix/769-lint-effect-setstate 2026-07-26 13:22:45 +05:30
dependabot[bot]anddependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> 8f09d4f57b chore(deps): bump dompurify from 3.4.11 to 3.4.12 in /explorer (#800)
Bumps [dompurify](https://github.com/cure53/DOMPurify) from 3.4.11 to 3.4.12.
- [Release notes](https://github.com/cure53/DOMPurify/releases)
- [Commits](https://github.com/cure53/DOMPurify/compare/3.4.11...3.4.12)

---
updated-dependencies:
- dependency-name: dompurify
  dependency-version: 3.4.12
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-25 16:36:25 +05:30
dependabot[bot]anddependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> 7e05f196b5 chore(deps): bump postcss from 8.5.10 to 8.5.23 in /explorer (#799)
Bumps [postcss](https://github.com/postcss/postcss) from 8.5.10 to 8.5.23.
- [Release notes](https://github.com/postcss/postcss/releases)
- [Changelog](https://github.com/postcss/postcss/blob/main/CHANGELOG.md)
- [Commits](https://github.com/postcss/postcss/compare/8.5.10...8.5.23)

---
updated-dependencies:
- dependency-name: postcss
  dependency-version: 8.5.23
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-25 16:33:19 +05:30
dependabot[bot]anddependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> 47c7f4adbe chore(deps): bump brace-expansion and eslint in /explorer (#797)
Bumps [brace-expansion](https://github.com/juliangruber/brace-expansion) to 5.0.8 and updates ancestor dependency [eslint](https://github.com/eslint/eslint). These dependencies need to be updated together.


Updates `brace-expansion` from 5.0.6 to 5.0.8
- [Release notes](https://github.com/juliangruber/brace-expansion/releases)
- [Commits](https://github.com/juliangruber/brace-expansion/compare/v5.0.6...v5.0.8)

Updates `eslint` from 9.39.4 to 10.8.0
- [Release notes](https://github.com/eslint/eslint/releases)
- [Commits](https://github.com/eslint/eslint/compare/v9.39.4...v10.8.0)

---
updated-dependencies:
- dependency-name: brace-expansion
  dependency-version: 5.0.8
  dependency-type: indirect
- dependency-name: eslint
  dependency-version: 10.8.0
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-25 16:31:43 +05:30
KaifAhmad1 33d8f806c2 Merge remote-tracking branch 'origin/main' into fix/768-error-boundaries-review
# Conflicts:
#	CHANGELOG.md
2026-07-25 16:11:15 +05:30
KaifAhmad1 530e297d17 fix(#768): reset ErrorBoundary retryCount only after a retry settles
Previously retryCount never reset on success (removed in adb4613 to
avoid resetting mid-Suspense-fallback), so unrelated transient errors
across a session could permanently exhaust the 3-retry budget even
though each prior retry had actually recovered. Now the counter resets
via a short settle timer after a retry stays error-free, avoiding both
the premature-reset and never-reset failure modes.
2026-07-25 16:09:07 +05:30
Sameer6305 495c2a2fbd fixes qodo reviews 2026-07-24 21:39:57 +05:30
Sameer6305 eb8156ddb3 Fix GraphWorkspace infinite render loop by tracking stringified open panel IDs 2026-07-24 21:19:54 +05:30
Sameer6305 1c3d2b949f Merge main to fix conflicts 2026-07-24 21:09:34 +05:30
Sameer6305 343d2bc418 Fix #769: Resolve all react-hooks/set-state-in-effect lint errors project-wide 2026-07-24 20:56:11 +05:30
KaifAhmad1 99b0a517fd Fix remaining silent-failure gaps flagged in review of #790
KGOverviewTab dropped the nodes-fetch 207 warning whenever stats also
returned 207; HealthTab and AlignmentsTab still had the exact
silent-swallow pattern this PR set out to fix elsewhere in the same
folder. Also documents all of #790's fixes in the changelog.
2026-07-24 16:25:21 +05:30
Sameer6305 adb46134c4 fix(#768): remove componentDidUpdate auto-reset to avoid premature reset on Suspense fallback 2026-07-24 16:15:34 +05:30
Sameer6305 d2d38a0509 fix(#768): ensure ErrorBoundary retryCount only resets on recovery transition 2026-07-24 16:11:14 +05:30
Sameer6305 9a21e523f0 fix(#768): add ErrorBoundary to workspace Suspense blocks 2026-07-24 15:53:33 +05:30
Sameer6305 e7696f462a fixing qodo findings 2026-07-24 00:38:49 +05:30
Sameer6305 d6c7154fa9 Fix #767: Harden workspaces against silent error swallowing and 207 statuses
Ensures network errors, API failures, and 207 Partial Success statuses are surfaced correctly to the user instead of failing silently in the frontend UI.
2026-07-24 00:16:46 +05:30
Zohaib Hassnain 21ddee94f7 Add Knowledge Explorer deployment templates 2026-06-23 13:37:25 +05:00
dependabot[bot]anddependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> aefa51baa5 chore(deps): bump dompurify from 3.4.10 to 3.4.11 in /explorer (#663)
Bumps [dompurify](https://github.com/cure53/DOMPurify) from 3.4.10 to 3.4.11.
- [Release notes](https://github.com/cure53/DOMPurify/releases)
- [Commits](https://github.com/cure53/DOMPurify/compare/3.4.10...3.4.11)

---
updated-dependencies:
- dependency-name: dompurify
  dependency-version: 3.4.11
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-06-20 22:35:54 +05:30
dependabot[bot]anddependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> 9c58b9df7c chore(deps-dev): bump @babel/core from 7.29.0 to 7.29.6 in /explorer (#640)
Bumps [@babel/core](https://github.com/babel/babel/tree/HEAD/packages/babel-core) from 7.29.0 to 7.29.6.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.29.6/packages/babel-core)

---
updated-dependencies:
- dependency-name: "@babel/core"
  dependency-version: 7.29.6
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-06-16 19:58:37 +05:30
dependabot[bot]anddependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> e3562daa89 chore(deps-dev): bump js-yaml from 4.1.1 to 4.2.0 in /explorer (#639)
Bumps [js-yaml](https://github.com/nodeca/js-yaml) from 4.1.1 to 4.2.0.
- [Changelog](https://github.com/nodeca/js-yaml/blob/master/CHANGELOG.md)
- [Commits](https://github.com/nodeca/js-yaml/commits)

---
updated-dependencies:
- dependency-name: js-yaml
  dependency-version: 4.2.0
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-06-16 19:57:13 +05:30
Mohd KaifandZohaib Hassnain 46447d1f3f fix(explorer): resolve blank dashboard UI and ship frontend bundle in wheel (#638)
* fix(explorer): resolve blank dashboard UI and ship frontend bundle in wheel

Fixes #631 — the Explorer server started successfully but the browser showed
a blank page because semantica/static/ was gitignored and never present after
a fresh install or clone.

Changes:
- ci.yml / release.yml: add Node 20 setup + npm ci && npm run build before
  python -m build so every wheel contains a CI-built frontend bundle
- pyproject.toml: add package-data patterns (static/*, static/assets/*) so
  setuptools includes the bundle in the wheel; add MANIFEST.in for sdist coverage
- app.py: replace silent empty-HTML fallback with a 200 page that clearly
  explains the missing bundle and links to /docs; fix CORS allow_credentials
  to default false, gated behind EXPLORER_CORS_CREDENTIALS env var to prevent
  credentialed cross-origin requests on unauthenticated endpoints
- __init__.py: warn at startup when --host is non-loopback (unauthenticated
  network exposure)
- explorer/README.md: full rewrite covering pip-install mode (primary path,
  no Node required) and dev-server mode (contributors), CLI flags, env vars,
  workspace table, troubleshooting for the blank-page symptom
- README.md: update Knowledge Explorer section with correct command and link
  to the new setup guide

* fix(explorer): set build.target esnext to fix esbuild CI failure

esbuild >=0.28 (forced via npm overrides) conflicts with Vite 6 defaults on
Linux CI — it tries to lower destructuring syntax for the implicit browser
target list but errors out. Explicit target: 'esnext' tells esbuild to emit
native syntax unchanged, bypassing the transpilation error entirely. Safe for
a developer tool that runs in modern browsers.

* test(explorer): verify packaged frontend bundle

---------

Co-authored-by: Zohaib Hassnain <109234410+ZohaibHassan16@users.noreply.github.com>
2026-06-16 14:38:24 +05:30
Mohd Kaif 6d9a690bcd security: force esbuild ^0.28.1; remove leaked Groq API keys from notebooks (#619)
- Add esbuild ^0.28.1 npm override in explorer/package.json (Dependabot #15,
  GHSA-gv7w-rqvm-qjhr); npm audit now reports 0 vulnerabilities
- Strip hardcoded GROQ_API_KEY values from 6 cookbook notebooks; fallback
  replaced with empty string (secret scanning alerts #1-#6)
  Affected: supply_chain/01, intelligence/01, cybersecurity/01 & 02,
  finance/01, blockchain/02
- CHANGELOG: document both fixes under [Unreleased] ### Security
2026-06-13 13:04:49 +05:30
Mohd Kaif c8519470bc security: fix 9 Dependabot/CodeQL alerts (DOMPurify, vite, uuid, workflow permissions) (#617)
* security: fix 9 Dependabot/CodeQL alerts — DOMPurify, vite, uuid, workflow permissions

- Add explicit permissions block to defender-for-devops.yml (CodeQL #25)
- Upgrade vite 5.4.x → 6.4.3; bundled esbuild 0.21.5 → 0.25.12 (Dependabot #2, #7)
- Force dompurify ^3.4.0 via npm overrides; resolves 6 DOMPurify XSS alerts (#4–#6, #8–#11)
- Force uuid ^13.0.1 via npm overrides; fixes buffer bounds check (Dependabot #12)

* fix(ci): exclude bandit from MSDO scan on windows-latest

bandit_runner.exe builds a per-file command line; on a large Python repo
the total command string exceeds the Windows CreateProcess limit and the
process fails to start (Win32 ERROR_FILENAME_EXCED_RANGE 206).
Exclude bandit via the tools param and retain checkov, eslint,
templateanalyzer, terrascan, and binskim.

* fix(ci): drop binskim (no binaries), enable Neptune audit logging

- Remove binskim from MSDO tools: repo has no compiled binaries so
  BinSkim raises AnalyzeArgumentNoValuesException and breaks the run
- Add EnableCloudwatchLogsExports: [audit] to NeptuneCluster to fix
  Checkov CKV_AWS_101 (the one error-level result breaking the build)
2026-06-13 12:40:15 +05:30
Zohaib Hassnain e891cd8685 fix(explorer): restore graph from cached summary (#584) 2026-06-05 15:24:12 +05:30
Zohaib Hassnain eb63d5dcb4 fix(explorer): auto-settle full graph layout (#583) 2026-06-05 15:11:57 +05:30
KaifAhmad1 470315d9cb Make favicon brain icon larger — reduce inner padding to fill more space 2026-05-24 18:42:26 +05:30
KaifAhmad1 058014272a Update branding to new Semantica logo
- Rename logo PNG to semantica-logo.png (lowercase, hyphenated)
- Update docs.json logo (light/dark) and favicon to reference new PNG
- Replace legacy purple favicon with new teal brain neural network icon
2026-05-24 18:37:51 +05:30
Zohaib Hassnain e14b372626 fix(ui): resolve explorer redesign merge blockers 2026-05-16 15:55:47 +05:00
KaifAhmad1 0efb018df0 fix(ontology): silent empty state for offline backend + fix SHACL crash
- OntologyManager: remove red error banner on HTTP 500; always fall back
  to empty state silently (error banners reserved for user actions only)
- AlignmentsTab: remove offline-backend warning when both registry and
  alignments requests fail; show empty form silently
- ShaclStudio: fix Monarch tokenizer crash — [@] character class prevents
  Monaco from misinterpreting @prefix/@base as language-property refs;
  wrap beforeMount in try/catch so any Monaco setup failure cannot crash
  the React tree
2026-05-16 15:15:37 +05:30
KaifAhmad1 aab7e23125 fix(explorer): address code review issues from PR #557
Decision workspace:
- Add AbortController per loadChain() call; abort previous request when a
  new decision is selected, preventing stale out-of-order chain responses
- Guard all setState calls with signal.aborted so unmounted component
  state updates are skipped; cancel in-flight request on unmount via a
  dedicated cleanup effect

SPARQL workspace:
- Guard results table on both result.rows && result.columns to prevent
  runtime crash when backend omits columns field
- Use (result.columns ?? []) inside rows.map() to satisfy TypeScript
  narrowing inside the closure
- Add .catch() to clipboard.writeText() — silently swallows permission
  errors (query remains visible in the editor as fallback)
- Fix CSV export anchor: append to body before click, remove after, to
  ensure cross-browser compatibility

Import/Export workspace:
- Fix download anchor: append to document.body before a.click() and
  remove afterwards, matching the standard compatible pattern

Lineage workspace:
- Replace 🔗 emoji empty-state icon with lucide-react Link2 for
  consistent theming and sizing

Diff & Merge workspace:
- Add "Sample preview" banner above the mock diff table so users know
  the displayed fields are illustrative until the backend is connected

OntologyManager:
- Restore non-blocking warning (flash message) when HTTP response is
  non-OK and not a 404; network errors (backend down) stay silent

AlignmentsTab:
- When both registry and alignments promises reject, surface a soft
  error banner so users know data is missing rather than just empty
2026-05-16 14:56:43 +05:30
KaifAhmad1 4809c16ed2 feat(explorer): redesign all workspace UIs with consistent design system
Introduces a shared CSS token system (--ws-* variables, .ws-* utility
classes) in App.tsx and applies it across every workspace tab to produce
a cohesive dark-themed Knowledge Explorer UI.

Changes per workspace:
- App.tsx: added full design-system block (:root tokens, .ws-btn,
  .ws-input, .ws-card, .ws-stat-grid, .ws-pill, .ws-sidebar, .ws-empty,
  animations); renamed "Network Explorer" -> "Semantica Explorer" app-wide;
  redesigned WelcomeScreen as a tech landing page (hero, metrics strip,
  workspace grid, capability band)
- ReasoningWorkspace: two-column layout, quick templates, monospace
  textareas, graph-write toggle, spinner run button
- SparqlWorkspace: template toolbar, copy button, styled Monaco editor,
  URI-coloured results table with CSV export
- DecisionWorkspace: ws-sidebar filter + list, ChainNode/RelEdge chain
  renderer, detail pane with outcome badge
- ImportExportWorkspace: drag-drop import zone, JSON/CSV export toggle,
  toast notifications with slide-up animation
- DiffMergeWorkspace: side-by-side diff table, amber diff pills, merge
  action with loading state
- KGOverviewTab: ws-stat-grid cards, TypeBar distribution charts,
  top-connected-nodes grid
- LineageDiagram: glassmorphism toolbar, ws-btn export actions, themed
  react-flow controls
- OntologyWorkspace/index: cleaned unused ComingSoonStub + dead style
  constants that caused babel-plugin-react-compiler compilation errors
- OntologyManager: graceful empty state instead of error banner when
  backend is unreachable
- HealthTab, ShaclStudio, AlignmentsTab: silence read-operation errors;
  keep errors only for user-triggered write actions
2026-05-16 14:45:20 +05:30
1861ca578c chore: resolve merge conflicts with origin/main
- Keep SequenceMatcher + Tuple imports; delegate Literal to typing_extensions
- Preserve both _ALIGNMENT_RELATIONS (subissue-520) and _INGEST_FORMAT_SUFFIXES (main)
- Keep our OntologyAlignment-typed _get_alignment_store; add main's _get_drafts,
  _get_proposals, _get_versions, _alignment_key, _coerce_alignment, _version_field
- Import OntologyEditor + VersionsTab (main) alongside ShaclStudio (subissue-520)
- All 14 subissue-3 tests pass post-resolution

Co-authored-by: KaifAhmad1 <mohammadk78600@gmail.com>
Co-authored-by: ZohaibHassan16 <zohaib@example.com>
2026-05-02 16:45:10 +05:30
63acc7a66e fix(ontology): address Qodo automated review findings from PR #524
Backend (semantica/explorer/routes/ontology.py):
- suggest-alignments: add TF-IDF character-ngram embeddings via sklearn
  (SimilarityCalculator-compatible cosine scoring) so embedding_similarity
  is populated in results; combined score = 0.4*label + 0.6*embedding when
  available, falling back to label-only when sklearn is absent
- suggest-alignments: add token-overlap prefilter before SequenceMatcher so
  zero-Jaccard pairs are skipped without computing full similarity; add
  _MAX_ENTITIES_PER_SIDE=500 per-ontology cap on top of the existing
  _MAX_ANALYSIS_NODES global cap
- suggest-alignments: remove dead try/except OntologyEngine.create_alignment
  block that always failed silently (no TripletStore configured); replace
  with a comment explaining the intentional ephemeral-only storage model
- health: replace O(alignments x entities) any() scans for alignment coverage
  with O(1) set membership checks via assessed_ids
- shacl/validate: run rdflib.Graph().parse(format='turtle') syntax check on
  the submitted Turtle before returning; invalid syntax now raises 422 instead
  of returning a misleading unavailable/success response

Frontend:
- AlignmentsTab: add pairwise alignment matrix section that groups recorded
  alignments by (source_ontology, target_ontology) pair; each cell shows
  color-coded relation badges per RELATION_COLORS; clicking a badge populates
  the create/edit form for quick editing; matrix is shown when at least two
  ontologies are loaded
- ShaclStudio: add selectedShapeId state and fullShacl ref; each shape row in
  the library is now a clickable button that extracts its Turtle block from
  the full SHACL and pre-populates the Monaco editor; a "View all" toggle
  restores the full SHACL; selected shape ID is shown in the editor header
- GraphWorkspace: fix viewMode race in external focus effect — call
  setSelectedNodeId directly instead of going through focusNode(), which
  captured a stale viewMode in its closure; remove focusNode from the
  dependency array since it is no longer called

Tests (14 passing, was 11):
- Add test_suggest_alignments_returns_embedding_similarity: asserts
  embedding_similarity is non-null when sklearn is available
- Add test_shacl_validate_rejects_invalid_turtle_syntax: asserts 422 on
  syntactically invalid Turtle
- Add test_health_alignment_coverage_uses_set_lookup: asserts alignment
  dimension score is non-zero after recording an alignment, verifying the
  O(1) set lookup path works correctly end-to-end

Co-authored-by: KaifAhmad1 <mohammadk78600@gmail.com>
Co-authored-by: ZohaibHassan16 <zohaib@hawksight.ai>
2026-05-02 16:38:09 +05:30
00ceb09960 fix(ontology): address review blockers from PR #524
Backend:
- Replace false conforms=True SHACL stub with status=unavailable always;
  live validation cannot be wired until OntologyEngine.validate_graph is
  connected to a data graph — a stub that returns conforms=True misleads
  users editing shapes
- Cap node/edge fetches in health, suggest-alignments, and SHACL generation
  at _MAX_ANALYSIS_NODES (5 000) with a logger.warning when the graph
  exceeds the limit; unbounded limit=999_999 fetches cause OOM on large graphs
- Set SHACL health dimension score to 0.0 (was 70.0) when status=unavailable;
  exclude unavailable dimensions from the total_score average so they neither
  inflate nor deflate the result
- Allow alignments to reference external/unloaded URIs (e.g. schema.org)
  without raising 404; label falls back to URI fragment or caller-supplied
  source_label/target_label fields added to OntologyAlignmentRequest
- Fix _alignment_id to use uuid.NAMESPACE_OID instead of NAMESPACE_URL;
  the composite key is not a URL
- Fix _summarize_shapes to normalise \r\n before splitting on .\n so shape
  parsing works correctly on Windows line endings

Frontend:
- Wrap handleSave/handleSuggest/handleRemove/handleAcceptSuggestion in
  useCallback in AlignmentsTab for consistency with sibling components
- Add ephemeral-storage banner in AlignmentsTab warning that alignments are
  session-memory-only and not persisted across restarts
- Fix exportReport in HealthTab to append/remove anchor from document before
  clicking and defer URL.revokeObjectURL to avoid Blob URL leak in some browsers
- Derive health dimension grid column count from health.dimensions.length
  instead of the hardcoded repeat(5, ...) that breaks if the backend adds
  or removes a dimension
- Add minimal Monarch tokenizer for the Monaco turtle language registration
  in ShaclStudio so prefix declarations, IRIs, SHACL properties, comments,
  and string literals are syntax-highlighted; previously the editor rendered
  as plain text despite theme rules being defined

Tests (11 passing, was 5):
- Rename test_shacl_validate_has_stable_contract to
  test_shacl_validate_returns_unavailable and assert status == unavailable
- Add test_shacl_validate_rejects_empty_turtle (expects 422)
- Add test_health_returns_404_for_unknown_ontology
- Add test_health_shacl_dimension_is_zero_when_unavailable with total_score check
- Add test_delete_unknown_alignment_returns_404
- Add test_alignment_upsert_is_idempotent (verifies ID stability and created_at
  preservation across updates)
- Add test_alignment_accepts_external_uri (verifies no 404 for schema.org URIs)
- Relax test_alignment_suggestions_are_ranked label assertions to substring
  checks so the test survives similarity algorithm changes

Co-authored-by: KaifAhmad1 <mohammadk78600@gmail.com>
Co-authored-by: ZohaibHassan16 <zohaib@hawksight.ai>
2026-05-02 15:53:47 +05:30
Zohaib Hassnain 9e916a82b5 fix(ontology): address hub endpoint review blockers 2026-05-02 00:02:06 +05:00
Zohaib Hassnain e8bf0e50d3 feat(ontology): add alignments health and shacl studio 2026-05-01 22:59:15 +05:00
KaifAhmad1 269fdaa9fb feat: implement Ontology Hub endpoints with Semantica module integration
- Add comprehensive ontology API endpoints (27 total)
- Integrate OntologyEngine for validation, SHACL, SKOS, alignments
- Integrate VersionManager for versioning and diffing
- Integrate ChangeLogEntry for audit trails
- Integrate OntologyIngestor for RDF parsing
- Add frontend components: OntologyEditor, ProposalReview, VersionsTab
- Update CHANGELOG with detailed feature documentation
- Add proper error handling and fallback mechanisms
- Fix import issues and dependencies
- All endpoints tested and verified working

Features implemented:
- Draft management with audit trails
- Change proposals with structured diffing
- Version comparison and publishing
- Ontology loading with multiple format support
- SKOS vocabulary management
- Cross-ontology alignments
- Visual ontology editor
- Registry and search functionality
2026-05-01 22:26:21 +05:30
KaifAhmad1 2a031f0225 fix(explorer): correct file upload format detection for xml/json extensions (#518)
Bug 4 — Upload format misdetected:
- Added xml→'xml' and json→'json-ld' to the extension→format map so
  .xml and .json files are no longer misidentified as turtle.
- Changed the fallback from '|| "turtle"' to '?? ""' (empty string for
  unknown extensions) so the backend _detect_format() runs instead of
  blindly assuming turtle for any unrecognised extension.
- Omit the format key entirely from the load request body when no format
  was detected, letting the backend auto-detect from content heuristics.
- Added .n3 to the file picker accept list and dropzone hint text.
2026-05-01 15:18:28 +05:30
KaifAhmad1 d04f2b3643 fix(explorer): address Qodo review findings for ontology hub (#518)
Bug 1 — Broken registry filters:
fetchRegistry no longer sends format/kind values (owl/skos/internal/external)
as the status query param; those filters are applied client-side via
filteredEntries which already had the correct logic. Only the text search
param q is delegated to the backend.

Bug 2 — Toggle/refresh URI corruption:
Removed removesuffix('/toggle') and removesuffix('/refresh') from
toggle_ontology and refresh_ontology. Starlette's route regex already
strips the literal suffix from the captured path param; the removesuffix
call was a no-op for normal URIs but corrupted any ontology URI that
legitimately ends with /toggle or /refresh.

Bug 3 — SSRF in URL fetch:
Added _validate_fetch_url() which rejects non-http/https schemes and
resolves the hostname to block private, loopback, link-local, reserved,
and multicast addresses before requests.get() is called. Applied to all
three fetch sites: preview, load, and refresh.

Bug 5 — Inconsistent XML hardening:
_parse_rdf_sync now calls _safe_parse_rdf() from
semantica/explorer/utils/rdf_parser.py instead of g.parse() directly,
applying the existing defusedxml-based XXE protection for RDF/XML inputs.

Bug 6 — Search scans whole graph:
search_entities now calls session.search(q, limit*6) which hits the
GraphSearchIndex instead of fetching up to 999,999 nodes and doing a
linear Python substring scan. Results are post-filtered by _SEARCHABLE_TYPES
and entity_type before being returned up to the requested limit.
2026-05-01 15:12:04 +05:30
KaifAhmad1 2811469071 feat(explorer): add Ontology Hub workspace — Registry, Loader, Entity Search & SKOS (closes #518)
Implements the first subissue of Ontology Hub (#517):

Frontend:
- New OntologyWorkspace with 6 tabs (Registry, Editor, Versions,
  Alignments, Health, SHACL); active tab persisted in ontologyTab URL param
- OntologyManager: full registry CRUD with status/format badges, stats,
  toggle/refresh/remove actions, search + filter toolbar, empty state CTA
- OntologyLoader: 3-tab modal — URL import with live preview, drag-and-drop
  file upload, and Create New (from scratch / data / text)
- OntologySearch: debounced entity search with type filters and detail panel
  showing superclasses, subclasses, domain/range, instance count
- SKOSVocabularyManager: recursive concept hierarchy tree, client-side
  filtering, full SKOS annotation + relation detail panel
- Editor/Versions (subissue 2) and Alignments/Health/SHACL (subissue 3)
  tabs render descriptive stub cards as placeholders

Backend:
- 12 new FastAPI endpoints under /api/ontology (registry, preview, load,
  create, search, entity detail, SKOS schemes + concept detail, toggle,
  refresh, remove)
- rdflib-based RDF parser supporting Turtle, RDF/XML, N-Triples, JSON-LD
- URL fetching via requests in asyncio.to_thread with 20 MB cap
- Registry stored in app.state.ontology_registry; route ordering prevents
  literal paths being shadowed by /{uri:path} wildcards

Also: add playwright dev dependency for screenshot testing
2026-05-01 13:08:45 +05:30