{"id":13504648,"url":"https://github.com/sirixdb/sirix","last_synced_at":"2026-06-04T00:00:40.850Z","repository":{"id":3544170,"uuid":"4604367","full_name":"sirixdb/sirix","owner":"sirixdb","description":"SirixDB is an an embeddable, bitemporal, append-only database system and event store, storing immutable lightweight snapshots. It keeps the full history of each resource. Every commit stores a space-efficient snapshot through structural sharing. It is log-structured and never overwrites data. SirixDB uses a novel page-level versioning approach.","archived":false,"fork":false,"pushed_at":"2026-05-29T21:35:11.000Z","size":254037,"stargazers_count":1186,"open_issues_count":113,"forks_count":247,"subscribers_count":29,"default_branch":"main","last_synced_at":"2026-05-29T22:20:51.824Z","etag":null,"topics":["comparison","coroutines","diff","diff-algorithm","diffing","hacktoberfest","hashing","java","json","jsoniq","keycloak","kotlin","snapshot","ssd","storage","temporal-data","versioning","vertx","xml","xquery"],"latest_commit_sha":null,"homepage":"https://sirix.io","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":"praveenvijayan/grunt-html-validation","license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/sirixdb.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":"ROADMAP.md","authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null},"funding":{"github":null,"patreon":null,"open_collective":null,"ko_fi":null,"tidelift":null,"community_bridge":null,"liberapay":null,"issuehunt":null,"otechie":null,"custom":["https://www.paypal.me/jojolichtenberger"]}},"created_at":"2012-06-09T02:22:14.000Z","updated_at":"2026-05-29T21:35:16.000Z","dependencies_parsed_at":"2023-10-11T21:10:52.572Z","dependency_job_id":"df4de8de-a74e-4bd3-b860-f70f5a93a28b","html_url":"https://github.com/sirixdb/sirix","commit_stats":{"total_commits":3003,"total_committers":75,"mean_commits":40.04,"dds":0.6593406593406593,"last_synced_commit":"de5611e8e43e49694568af2a10dc2ded245fe63d"},"previous_names":[],"tags_count":24,"template":false,"template_full_name":null,"purl":"pkg:github/sirixdb/sirix","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sirixdb%2Fsirix","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sirixdb%2Fsirix/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sirixdb%2Fsirix/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sirixdb%2Fsirix/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sirixdb","download_url":"https://codeload.github.com/sirixdb/sirix/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sirixdb%2Fsirix/sbom","scorecard":{"id":670082,"data":{"date":"2025-08-11","repo":{"name":"github.com/sirixdb/sirix","commit":"c67af5d5105675e724c99637f3d1e514a885f101"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":4.8,"checks":[{"name":"Code-Review","score":2,"reason":"Found 3/11 approved changesets -- score normalized to 2","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Maintained","score":10,"reason":"14 commit(s) and 1 issue activity found in the last 90 days -- score normalized to 10","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: no topLevel permission defined: .github/workflows/gradle.yml:1","Warn: no topLevel permission defined: .github/workflows/sonarqube.yml:1","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"CII-Best-Practices","score":2,"reason":"badge detected: InProgress","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: BSD 3-Clause \"New\" or \"Revised\" License: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Binary-Artifacts","score":8,"reason":"binaries present in source code","details":["Warn: binary detected: bundles/sirix-distributed/gradle/wrapper/gradle-wrapper.jar:1","Warn: binary detected: gradle/wrapper/gradle-wrapper.jar:1"],"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'main'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Packaging","score":10,"reason":"packaging workflow detected","details":["Info: Project packages its releases by way of GitHub Actions.: .github/workflows/gradle.yml:62"],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 22 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Pinned-Dependencies","score":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/gradle.yml:22: update your workflow using https://app.stepsecurity.io/secureworkflow/sirixdb/sirix/gradle.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/gradle.yml:24: update your workflow using https://app.stepsecurity.io/secureworkflow/sirixdb/sirix/gradle.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/gradle.yml:28: update your workflow using https://app.stepsecurity.io/secureworkflow/sirixdb/sirix/gradle.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/gradle.yml:43: update your workflow using https://app.stepsecurity.io/secureworkflow/sirixdb/sirix/gradle.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/gradle.yml:48: update your workflow using https://app.stepsecurity.io/secureworkflow/sirixdb/sirix/gradle.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/gradle.yml:72: update your workflow using https://app.stepsecurity.io/secureworkflow/sirixdb/sirix/gradle.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/gradle.yml:74: update your workflow using https://app.stepsecurity.io/secureworkflow/sirixdb/sirix/gradle.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/gradle.yml:81: update your workflow using https://app.stepsecurity.io/secureworkflow/sirixdb/sirix/gradle.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/sonarqube.yml:12: update your workflow using https://app.stepsecurity.io/secureworkflow/sirixdb/sirix/sonarqube.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/sonarqube.yml:16: update your workflow using https://app.stepsecurity.io/secureworkflow/sirixdb/sirix/sonarqube.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/sonarqube.yml:21: update your workflow using https://app.stepsecurity.io/secureworkflow/sirixdb/sirix/sonarqube.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/sonarqube.yml:27: update your workflow using https://app.stepsecurity.io/secureworkflow/sirixdb/sirix/sonarqube.yml/main?enable=pin","Warn: containerImage not pinned by hash: Dockerfile:3","Warn: containerImage not pinned by hash: Dockerfile:14","Warn: containerImage not pinned by hash: bundles/sirix-distributed/src/main/docker/Dockerfile.jvm:17: pin your Docker image by updating fabric8/java-alpine-openjdk8-jre:1.6.5 to fabric8/java-alpine-openjdk8-jre:1.6.5@sha256:0c8081607b985031195e7de1678128169f8b71722ac21c3038210dbe01758c5c","Warn: containerImage not pinned by hash: bundles/sirix-distributed/src/main/docker/Dockerfile.native:17: pin your Docker image by updating registry.access.redhat.com/ubi8/ubi-minimal to registry.access.redhat.com/ubi8/ubi-minimal@sha256:395dec18e7ba913157b1ecf2fd696d701ef834fd77054fffdb7eb678f864eb9e","Warn: pipCommand not pinned by hash: .github/workflows/gradle.yml:55","Warn: pipCommand not pinned by hash: .github/workflows/gradle.yml:56","Info:   0 out of  11 GitHub-owned GitHubAction dependencies pinned","Info:   0 out of   1 third-party GitHubAction dependencies pinned","Info:   0 out of   4 containerImage dependencies pinned","Info:   0 out of   2 pipCommand dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}}]},"last_synced_at":"2025-08-21T19:40:32.139Z","repository_id":3544170,"created_at":"2025-08-21T19:40:32.139Z","updated_at":"2025-08-21T19:40:32.139Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33884734,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-03T02:00:06.370Z","response_time":59,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["comparison","coroutines","diff","diff-algorithm","diffing","hacktoberfest","hashing","java","json","jsoniq","keycloak","kotlin","snapshot","ssd","storage","temporal-data","versioning","vertx","xml","xquery"],"created_at":"2024-08-01T00:00:48.783Z","updated_at":"2026-06-04T00:00:40.840Z","avatar_url":"https://github.com/sirixdb.png","language":"Java","funding_links":["https://www.paypal.me/jojolichtenberger","https://opencollective.com/sirixdb/"],"categories":["Kotlin","Roff","Java","数据库","hacktoberfest"],"sub_categories":["Misc"],"readme":"\u003cp align=\"center\"\u003e\u003cimg src=\"Circuit%20Technology%20Logo.png\" width=\"320\" alt=\"SirixDB\"/\u003e\u003c/p\u003e\n\n\u003ch1 align=\"center\"\u003eSirixDB - The Bitemporal Database System\u003c/h1\u003e\n\u003ch3 align=\"center\"\u003eQuery any revision as fast as the latest\u003c/h3\u003e\n\n\u003cp align=\"center\"\u003e\n\u003ca href=\"https://github.com/sirixdb/sirix/actions\"\u003e\u003cimg src=\"https://github.com/sirixdb/sirix/workflows/Java%20CI%20with%20Gradle/badge.svg\" alt=\"CI Build Status\"/\u003e\u003c/a\u003e\n\u003ca href=\"https://search.maven.org/search?q=g:io.sirix\"\u003e\u003cimg src=\"https://img.shields.io/maven-central/v/io.sirix/sirix-core.svg\" alt=\"Maven Central\"/\u003e\u003c/a\u003e\n\u003ca href=\"http://makeapullrequest.com\"\u003e\u003cimg src=\"https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square\" alt=\"PRs Welcome\"/\u003e\u003c/a\u003e\n\u003ca href=\"#contributors-\"\u003e\u003cimg src=\"https://img.shields.io/badge/all_contributors-23-orange.svg?style=flat-square\" alt=\"All Contributors\"/\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n\u003ca href=\"docs/README.md\"\u003e\u003cb\u003eDocs\u003c/b\u003e\u003c/a\u003e · \u003ca href=\"https://sirix.io\"\u003e\u003cb\u003eWebsite\u003c/b\u003e\u003c/a\u003e · \u003ca href=\"https://discord.gg/yC33wVpv7t\"\u003e\u003cb\u003eDiscord\u003c/b\u003e\u003c/a\u003e · \u003ca href=\"https://sirix.discourse.group/\"\u003e\u003cb\u003eForum\u003c/b\u003e\u003c/a\u003e · \u003ca href=\"https://github.com/sirixdb/sirixdb-web-gui\"\u003e\u003cb\u003eWeb UI\u003c/b\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\u003ci\u003eStatus: \u003cb\u003e1.0.0-alpha\u003c/b\u003e — usable today and actively developed. The on-disk format and public APIs are stabilizing toward a 1.0 release; feedback from real use is exactly what we're looking for.\u003c/i\u003e\u003c/p\u003e\n\n---\n\n## The Problem\n\nYou update a row in your database. The old value is gone.\n\nTo get history, you bolt on audit tables, change-data-capture, or event sourcing. Now you have two systems: one for current state, one for history. Querying the past means replaying events or scanning logs. Your \"simple\" audit requirement just became an infrastructure project.\n\nGit solves this for files—but you can't query a Git repository. Event sourcing preserves history—but reconstructing past state means replaying from the beginning.\n\n## The Solution\n\nSirixDB is a database where **every revision is a first-class citizen**. Not an afterthought. Not a log you replay.\n\n```java\n// Query revision 1 - instant, not reconstructed\nsession.beginNodeReadOnlyTrx(1)\n\n// Query by timestamp - which revision was current at 3am last Tuesday?\nsession.beginNodeReadOnlyTrx(Instant.parse(\"2024-01-15T03:00:00Z\"))\n\n// Both return the same thing: a readable snapshot, as fast as querying \"now\"\n```\n\nThis works because SirixDB uses **structural sharing**: when you modify data, only changed pages are written. Unchanged data is shared between revisions via copy-on-write. Revision 1000 doesn't store 1000 copies—it stores the current state plus pointers to shared history.\n\n**The result:**\n- Storage: O(changes per revision), not O(total size × revisions)\n- Read any page from any revision: O(N) page fragment reads, where N is the configurable snapshot window (default 3)\n- No event replay, no log scanning—direct page access\n\n## Bitemporal: Two Kinds of Time\n\nMost databases (if they version at all) track one timeline: when data was written. SirixDB tracks two:\n\n- **Transaction time**: When was this committed? (system-managed)\n- **Valid time**: When was this true in the real world? (user-managed)\n\nWhy does this matter?\n\n```\nJanuary 15: You record \"Price = $100, valid from January 1\"\nJanuary 20: You discover the price was actually $95 on January 1\n\nAfter correction, you can ask:\n  \"What did we THINK the price was on Jan 16?\"  →  $100 (transaction time)\n  \"What WAS the price on Jan 1?\"                →  $95  (valid time)\n```\n\nBoth questions have correct, different answers. Without bitemporal support, the correction destroys the audit trail.\n\n## Core Properties\n\n- **Append-only storage**: Data is never overwritten. New revisions write to new locations.\n- **Structural sharing**: Unchanged pages and nodes are referenced between revisions via copy-on-write.\n- **Snapshot isolation**: Readers see a consistent view; one writer per resource.\n- **Embeddable**: Single JAR, no external dependencies. Or run as REST server.\n\n## How Versioning Works\n\n\u003cp align=\"center\"\u003e\n\u003cimg src=\"images/sirix-revisions.png\" alt=\"Logical page structure of a resource with 3 revisions\" width=\"800\"/\u003e\n\u003cbr/\u003e\n\u003cem\u003eLogical page structure of a resource with 3 revisions — read-only transactions (RTX) can open any revision, while a single write transaction (WTX) appends to the latest.\u003c/em\u003e\n\u003c/p\u003e\n\nSirixDB stores data in a persistent tree structure where revisions share unchanged pages and nodes. Traditional databases overwrite data in place and use write-ahead logs for recovery. SirixDB takes a different approach:\n\n### Physical Storage: Append-Only Log\n\nAll data is written sequentially to an append-only log. Nothing is ever overwritten.\n\n```\nPhysical Log (append-only, sequential writes)\n┌────────────────────────────────────────────────────────────────────────┐\n│ [R1:Root] [R1:P1] [R1:P2] [R2:Root] [R2:P1'] [R3:Root] [R3:P2'] ...    │\n└────────────────────────────────────────────────────────────────────────┘\n     t=0      t=1     t=2      t=3      t=4       t=5       t=6    → time\n```\n\n### Logical Structure: Persistent Trie\n\nEach revision has a root node in a trie. Unchanged pages are shared via references.\n\n```\nRevision Roots                    Page Trie (persistent, copy-on-write)\n      │\n      ▼\n   [Rev 3] ─────────────────┬─────────────────┐\n      │                     │                 │\n   [Rev 2] ────────┬────────┤                 │\n      │            │        │                 │\n   [Rev 1] ───┐    │        │                 │\n              │    │        │                 │\n              ▼    ▼        ▼                 ▼\n           [Root₁][Root₂][Root₃]          [Pages...]\n              │      │      │\n              ▼      ▼      ▼\n            ┌───────────────────────────────────────┐\n            │           Shared Page Pool            │\n            │  ┌─────┐ ┌─────┐ ┌─────┐ ┌─────┐      │\n            │  │ P1  │ │ P1' │ │ P2  │ │ P2' │ ...  │\n            │  └──▲──┘ └──▲──┘ └──▲──┘ └──▲──┘      │\n            │     │      │       │       │          │\n            │   R1,R2    R3    R1,R3    R2          │\n            │  (shared)       (shared)              │\n            └───────────────────────────────────────┘\n```\n\n### Page Versioning Strategies\n\nSirixDB supports multiple strategies for storing page versions, configurable per resource:\n\n```\n┌──────────────────────────────────────────────────────────────────────────────┐\n│ FULL: Each page stores complete data                                         │\n│                                                                              │\n│   Rev1: [████████]  Rev2: [████████]  Rev3: [████████]                       │\n│         (full)            (full)            (full)                           │\n│                                                                              │\n│   + Fast reads (no reconstruction)                                           │\n│   - High storage cost                                                        │\n├──────────────────────────────────────────────────────────────────────────────┤\n│ INCREMENTAL: Diffs from previous revision + periodic full snapshots          │\n│                                                                              │\n│   Rev1: [████████]  Rev2: [Δ←1]  Rev3: [Δ←2]  Rev4: [████████]               │\n│         (full)       (diff)       (diff)       (full snapshot)               │\n│                                                                              │\n│   Rev5: [Δ←4]  Rev6: [Δ←5]  Rev7: [████████]  ...                            │\n│         (diff)       (diff)       (full snapshot)                            │\n│                                                                              │\n│   Full snapshot written every N revisions (N = configurable window)          │\n│   + Bounded read cost (max N-1 diffs between full snapshots)                 │\n│   + Compact diffs (each diff is against previous revision only)              │\n│   - Read cost grows linearly within each window                              │\n├──────────────────────────────────────────────────────────────────────────────┤\n│ DIFFERENTIAL: Diffs from reference snapshot + periodic full snapshots        │\n│                                                                              │\n│   Rev1: [████████]  Rev2: [Δ←1]  Rev3: [████████]  Rev4: [Δ←3]               │\n│         (full)       (diff)       (full snapshot)    (diff)                  │\n│                                                                              │\n│   Rev5: [Δ←3]  Rev6: [████████]  Rev7: [Δ←6]  ...                            │\n│         (diff)       (full snapshot)    (diff)                               │\n│                                                                              │\n│   Full snapshot every N revisions; diffs reference the last snapshot         │\n│   + Bounded read cost (max 1 diff to apply)                                  │\n│   - Diffs grow larger as they diverge from last snapshot                     │\n├──────────────────────────────────────────────────────────────────────────────┤\n│ SLIDING SNAPSHOT: Incremental diffs within a sliding window of size N        │\n│                                                                              │\n│   Rev1: [████████]  Rev2: [Δ←1]  Rev3: [Δ←2]  Rev4: [Δ←3 + R1 copy]          │\n│         (full)       (diff)       (diff)       (diff + out-of-window         │\n│                                                 records from Rev1)           │\n│         ◄──────── window N=3 ──────────►                                     │\n│                      ◄──────── window N=3 ──────────►                        │\n│                                                                              │\n│   As the window slides forward, records from pages that fall out of          │\n│   the window are copied into the newest diff page, ensuring any              │\n│   revision can be reconstructed from at most N page fragments.               │\n│                                                                              │\n│   + Bounded read cost (max N page fragments to combine)                      │\n│   + No unbounded diff growth (out-of-window data is always rescued)          │\n│   = Best balance of storage vs read performance                              │\n└──────────────────────────────────────────────────────────────────────────────┘\n```\n\nWhen you modify data:\n1. Only the affected pages are copied and modified (copy-on-write)\n2. Unchanged pages are referenced from the new revision\n3. The old revision remains intact and queryable\n\n**Storage cost**: O(changed pages) per revision, not O(total document size).\n\n**Read performance**: Opening a revision is O(1) by revision number or O(log R) by timestamp (binary search over R revisions). Each page read requires combining at most N page fragments, where N is the snapshot window size (configurable, default 3). Tree traversal to locate a node is O(log nodes), same as querying the latest revision.\n\n## Quick Start\n\n### Using the CLI (Native Binaries)\n\nSirixDB provides two CLI tools, both available as instant-startup native binaries:\n\n| Binary | Module | Description |\n|--------|--------|-------------|\n| `sirix-cli` | sirix-kotlin-cli | Full-featured CLI for database operations |\n| `sirix-shell` | sirix-query | Interactive JSONiq/XQuery shell |\n\nBuild native binaries with GraalVM:\n\n```bash\n# Build both CLIs as native binaries (requires GraalVM with native-image)\n./gradlew :sirix-kotlin-cli:nativeCompile  # produces: sirix-cli\n./gradlew :sirix-query:nativeCompile       # produces: sirix-shell\n\n# Or run via JAR\n./gradlew :sirix-kotlin-cli:run --args=\"-l /tmp/mydb create\"\n```\n\n#### sirix-cli: Database Operations\n\nThe `-l` option specifies the database path. Each database can contain multiple resources.\n\n**Create a database and store JSON:**\n```bash\nsirix-cli -l /tmp/mydb create json -r myresource -d '{\"name\": \"Alice\", \"role\": \"admin\"}'\n```\n\n**Query your data:**\n```bash\nsirix-cli -l /tmp/mydb query -r myresource\n```\n\n**Run a JSONiq query:**\n```bash\n# The context is set to the document root, so access fields directly\nsirix-cli -l /tmp/mydb query -r myresource '.name'\n```\n\n**Update and create a new revision:**\n```bash\nsirix-cli -l /tmp/mydb update -r myresource '{\"role\": \"superadmin\"}' -im as-first-child\n```\n\n**Query a previous revision:**\n```bash\nsirix-cli -l /tmp/mydb query -r myresource -rev 1\n```\n\n**View revision history:**\n```bash\nsirix-cli -l /tmp/mydb resource-history myresource\n```\n\n#### sirix-shell: Interactive Query Shell\n\nThe interactive shell provides a REPL for JSONiq/XQuery queries:\n\n```bash\nsirix-shell\n\u003e 1 + 1\n2\n\u003e jn:store('mydb','resource','{\"key\": \"value\"}')\n\u003e jn:doc('mydb','resource').key\n\"value\"\n```\n\n### Using the REST API\n\nStart SirixDB and its bundled OAuth2 provider (Keycloak) with Docker:\n\n```bash\ngit clone https://github.com/sirixdb/sirix.git\ncd sirix\ndocker compose up\n```\n\nThis starts two services: the SirixDB REST server on `https://localhost:9443` (self-signed\ncert, so use `curl -k` for local testing) and a Keycloak instance that is auto-seeded with two\ndemo users — `admin/admin` (full access) and `viewer/viewer` (read-only).\n\nCheck the server is up (this endpoint needs no auth):\n\n```bash\ncurl -k https://localhost:9443/health   # -\u003e {\"status\":\"UP\"}\n```\n\nAll endpoints are OAuth2-protected. Obtain a bearer token from the server's `/token` endpoint,\nthen use it on subsequent requests:\n\n```bash\n# 1. Get an access token (the server proxies to Keycloak)\nTOKEN=$(curl -k -s -X POST https://localhost:9443/token \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"username\":\"admin\",\"password\":\"admin\"}' | jq -r .access_token)\n\n# 2. Store a JSON resource\ncurl -k -X PUT https://localhost:9443/mydb/myresource \\\n  -H \"Authorization: Bearer $TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"name\":\"Alice\",\"role\":\"admin\"}'\n\n# 3. Read it back\ncurl -k https://localhost:9443/mydb/myresource \\\n  -H \"Authorization: Bearer $TOKEN\" \\\n  -H \"Accept: application/json\"\n```\n\nSee the [REST API documentation](https://sirix.io/docs/rest-api.html) for the full endpoint reference.\n\n\u003e **Security note:** The bundled Keycloak realm, demo users, client secret, and the self-signed\n\u003e TLS certificate under `bundles/sirix-rest-api/src/main/resources/` are for **local development\n\u003e only**. Before any public deployment, generate your own certificate, rotate the client secret,\n\u003e and create real users with strong passwords. See [`docs/operations.md`](docs/operations.md).\n\n### Using the MCP Server (for AI Agents)\n\nSirixDB ships a native [Model Context Protocol](https://modelcontextprotocol.io) server, so AI\nagents (Claude, Cursor, Windsurf, or any MCP client) can talk to it directly. Because every\nrevision is copy-on-write, agents get **O(1) disposable snapshots**, **time-travel reads**, and\n**structural diffs** for free — branch, experiment, then discard or promote, with a human-reviewable\ndiff. It is read-only by default and includes access control, output sanitization, and an audit log.\n\n```bash\n# Build a self-contained launcher (creates build/install/sirix-mcp/bin/sirix-mcp)\n./gradlew :sirix-mcp:installDist\n```\n\nRegister it with your MCP client (e.g. Claude Desktop / Cursor `mcp_servers.json`):\n\n```json\n{\n  \"mcpServers\": {\n    \"sirixdb\": {\n      \"command\": \"/path/to/sirix/bundles/sirix-mcp/build/install/sirix-mcp/bin/sirix-mcp\",\n      \"args\": [\"--database-path\", \"/path/to/data\"]\n    }\n  }\n}\n```\n\nAdd `--read-write` to the `args` to allow mutations (read-only is the default). See [`docs/MCP_SERVER_DESIGN.md`](docs/MCP_SERVER_DESIGN.md) for the full tool reference.\n\n### As an Embedded Library\n\n```xml\n\u003cdependency\u003e\n  \u003cgroupId\u003eio.sirix\u003c/groupId\u003e\n  \u003cartifactId\u003esirix-core\u003c/artifactId\u003e\n  \u003cversion\u003e1.0.0-alpha10\u003c/version\u003e\n\u003c/dependency\u003e\n```\n\n```gradle\n// Gradle (Kotlin DSL)\nimplementation(\"io.sirix:sirix-core:1.0.0-alpha10\")\n```\n\n```java\nvar dbPath = Path.of(\"/tmp/mydb\");\n\n// Create database and resource\nDatabases.createJsonDatabase(new DatabaseConfiguration(dbPath));\ntry (var database = Databases.openJsonDatabase(dbPath)) {\n    database.createResource(ResourceConfiguration.newBuilder(\"myresource\").build());\n\n    // Insert JSON data (creates revision 1)\n    try (var session = database.beginResourceSession(\"myresource\");\n         var wtx = session.beginNodeTrx()) {\n        wtx.insertSubtreeAsFirstChild(JsonShredder.createStringReader(\"{\\\"key\\\": \\\"value\\\"}\"));\n        wtx.commit();\n    }\n\n    // Update creates revision 2 (revision 1 remains unchanged)\n    try (var session = database.beginResourceSession(\"myresource\");\n         var wtx = session.beginNodeTrx()) {\n        wtx.moveTo(2);  // Move to the \"key\" node\n        wtx.setStringValue(\"updated value\");\n        wtx.commit();\n    }\n\n    // Read from revision 1 - still accessible\n    try (var session = database.beginResourceSession(\"myresource\");\n         var rtx = session.beginNodeReadOnlyTrx(1)) {\n        rtx.moveTo(2);\n        System.out.println(rtx.getValue());  // Prints: value\n    }\n}\n```\n\n## Time-Travel Queries\n\nSirixDB extends JSONiq/XQuery (via [Brackit](https://github.com/sirixdb/brackit)) with temporal axis and functions.\n\n### Access by Revision Number or Timestamp\n\n```xquery\n(: Open specific revision :)\njn:doc('mydb','myresource', 5)\n\n(: Open by timestamp - returns revision valid at that instant :)\njn:open('mydb','myresource', xs:dateTime('2024-01-15T10:30:00Z'))\n```\n\n### Temporal Axis Functions\n\nNavigate a node's history across revisions:\n\n```xquery\n(: Single-step navigation :)\njn:previous($node)       (: same node in the previous revision :)\njn:next($node)           (: same node in the next revision :)\n\n(: Boundary access :)\njn:first($node)          (: node in the first revision :)\njn:last($node)           (: node in the most recent revision :)\njn:first-existing($node) (: revision where this node first appeared :)\njn:last-existing($node)  (: revision where this node last existed :)\n\n(: Range navigation - returns sequences :)\njn:past($node)           (: node in all past revisions :)\njn:future($node)         (: node in all future revisions :)\njn:all-times($node)      (: node across all revisions :)\n\n(: With includeSelf parameter :)\njn:past($node, true())   (: include current revision :)\njn:future($node, true()) (: include current revision :)\n```\n\nExample: iterate through all versions of a node:\n```xquery\nfor $version in jn:all-times(jn:doc('mydb','myresource').users[0])\nreturn {\"rev\": sdb:revision($version), \"data\": $version}\n```\n\n### Diff Between Revisions\n\n```xquery\n(: Structured diff between any two revisions :)\njn:diff('mydb','myresource', 1, 5)\n\n(: Diff with optional parameters: startNodeKey, maxLevel :)\njn:diff('mydb','myresource', 1, 5, $nodeKey, 3)\n```\n\nFor adjacent revisions, `jn:diff` reads directly from stored change tracking files. For non-adjacent revisions it computes the diff.\n\nIf hashes are enabled, you can also detect changes via hash comparison:\n```xquery\n(: Find which revisions changed a specific node - requires hashes enabled :)\nlet $node := jn:doc('mydb','myresource').config\nfor $v in jn:all-times($node)\nlet $prev := jn:previous($v)\nwhere empty($prev) or sdb:hash($v) ne sdb:hash($prev)\nreturn sdb:revision($v)\n```\n\n### Bitemporal Queries\n\nQuery both time dimensions (see [Bitemporal: Two Kinds of Time](#bitemporal-two-kinds-of-time) above for why this matters).\n\n#### Configuring Valid Time Support\n\nConfigure a resource with valid time paths to enable automatic indexing and dedicated query functions:\n\n```java\n// Configure resource with valid time paths\nvar resourceConfig = ResourceConfiguration.newBuilder(\"employees\")\n    .validTimePaths(\"validFrom\", \"validTo\")  // specify your JSON field names\n    .buildPathSummary(true)\n    .build();\n\ndatabase.createResource(resourceConfig);\n\n// Or use conventional field names (_validFrom, _validTo)\nvar resourceConfig = ResourceConfiguration.newBuilder(\"employees\")\n    .useConventionalValidTimePaths()\n    .build();\n```\n\nVia REST API, use query parameters when creating a resource:\n\n```bash\n# Custom valid time field names\ncurl -X PUT \"https://localhost:9443/database/resource?validFromPath=validFrom\u0026validToPath=validTo\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '[{\"name\": \"Alice\", \"validFrom\": \"2024-01-01T00:00:00Z\", \"validTo\": \"2024-12-31T23:59:59Z\"}]'\n\n# Use conventional _validFrom/_validTo fields\ncurl -X PUT \"https://localhost:9443/database/resource?useConventionalValidTime=true\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '[{\"name\": \"Bob\", \"_validFrom\": \"2024-01-01T00:00:00Z\", \"_validTo\": \"2024-12-31T23:59:59Z\"}]'\n```\n\nWhen valid time paths are configured, SirixDB automatically creates CAS indexes on the valid time fields for optimal query performance.\n\n#### Valid Time Query Functions\n\n```xquery\n(: Get records valid at a specific point in time :)\njn:valid-at('mydb','myresource', xs:dateTime('2024-07-15T12:00:00Z'))\n\n(: True bitemporal query: combine transaction time and valid time :)\n(: \"What records were known on Jan 20 and valid on July 15?\" :)\njn:open-bitemporal('mydb','myresource',\n    xs:dateTime('2024-01-20T10:00:00Z'),   (: transaction time - opens revision :)\n    xs:dateTime('2024-07-15T12:00:00Z'))   (: valid time - filters via index :)\n\n(: Extract valid time bounds from a node :)\nlet $record := jn:doc('mydb','myresource')[0]\nreturn {\n  \"validFrom\": sdb:valid-from($record),\n  \"validTo\": sdb:valid-to($record)\n}\n```\n\n#### Transaction Time Functions\n\n```xquery\n(: Transaction time: what did the database look like at a point in time? :)\njn:open('mydb','myresource', xs:dateTime('2024-01-15T10:30:00Z'))\n\n(: Get the commit timestamp of current revision :)\nsdb:timestamp(jn:doc('mydb','myresource'))\n\n(: Open all revisions within a transaction time range :)\njn:open-revisions('mydb','myresource',\n        xs:dateTime('2024-01-01T00:00:00Z'),\n        xs:dateTime('2024-06-01T00:00:00Z'))\n```\n\n### Revision Metadata Functions\n\n```xquery\n(: Get revision number and timestamp :)\nsdb:revision($node)              (: revision number of this node :)\nsdb:timestamp($node)             (: commit timestamp as xs:dateTime :)\nsdb:most-recent-revision($node)  (: latest revision number in resource :)\n\n(: Get history of changes to a specific node :)\nsdb:item-history($node)          (: all revisions where this node changed :)\nsdb:is-deleted($node)            (: true if node was deleted in a later revision :)\n\n(: Author tracking (if set during commit) :)\nsdb:author-name($node)\nsdb:author-id($node)\n\n(: Commit with metadata :)\nsdb:commit($doc)\nsdb:commit($doc, \"commit message\")\nsdb:commit($doc, \"commit message\", xs:dateTime('2024-01-15T10:30:00Z'))\n```\n\n### Merkle Hash Verification (Optional)\n\nWhen enabled in resource configuration, SirixDB stores a hash for each node computed from its content and descendants. Use this for:\n- Tamper detection\n- Efficient change detection (compare subtree hashes instead of traversing)\n- Data integrity verification\n\n```xquery\nsdb:hash(jn:doc('mydb','myresource'))           (: root hash :)\nsdb:hash(jn:doc('mydb','myresource').users[0])  (: subtree hash :)\n```\n\nSee [Query documentation](https://sirix.io/docs/jsoniq.html) for the full API.\n\n## Web Interface\n\nThe [SirixDB Web GUI](https://github.com/sirixdb/sirixdb-web-gui) provides visualization of revision history and diffs:\n\n```bash\ngit clone https://github.com/sirixdb/sirixdb-web-gui.git\ncd sirixdb-web-gui\ndocker compose -f docker-compose.demo.yml up\n```\n\nOpen `http://localhost:3000` (login: `admin`/`admin`)\n\n## Architecture\n\n### JSON Tree Encoding\n\nSirixDB shreds JSON into a typed node tree where each node has a stable key across revisions:\n\n\u003cp align=\"center\"\u003e\n\u003cimg src=\"images/sirix-json-tree-encoding.png\" alt=\"How JSON is encoded as a node tree\" width=\"700\"/\u003e\n\u003cbr/\u003e\n\u003cem\u003eA JSON document and its internal tree representation — each node carries a stable key (nodeKey) for identity tracking across revisions.\u003c/em\u003e\n\u003c/p\u003e\n\n### Document Storage and Path Summary\n\nWhen JSON is stored, SirixDB also builds a **path summary** — a compact trie capturing all unique paths in the document. This powers the path and CAS indexes:\n\n\u003cp align=\"center\"\u003e\n\u003cimg src=\"images/sirix-doc-storage-and-path-summary.png\" alt=\"Document tree and path summary\" width=\"700\"/\u003e\n\u003cbr/\u003e\n\u003cem\u003eLeft: the document tree. Right: the path summary trie with stable path class records (PCR) used for indexing.\u003c/em\u003e\n\u003c/p\u003e\n\n### On-Device Layout\n\n\u003cp align=\"center\"\u003e\n\u003cimg src=\"images/sirix-on-device-layout.png\" alt=\"Logical device layout of a resource\" width=\"700\"/\u003e\n\u003cbr/\u003e\n\u003cem\u003ePhysical layout on disk — data is split across two logical devices (LD₀ for metadata offsets, LD₁ for page data), written sequentially per revision.\u003c/em\u003e\n\u003c/p\u003e\n\n### Storage Model\n\n```\nDatabase (directory)\n└── Resource (single JSON or XML document with revision history)\n    └── Revisions (numbered 1, 2, 3, ...)\n        └── Pages (variable-size blocks containing node data)\n```\n\n- **Database**: Directory containing multiple resources\n- **Resource**: One logical document with its complete revision history\n- **Page**: Unit of I/O and versioning. Variable-size, immutable once written.\n\n### Key Design Decisions\n\n| Aspect | Design | Trade-off |\n|--------|--------|-----------|\n| Write pattern | Append-only | No in-place updates; simpler recovery; larger storage footprint |\n| Consistency | Single writer per resource | No write conflicts; readers never blocked |\n| Index updates | Synchronous | Queries always see current indexes |\n| Node IDs | Stable across revisions | Enables tracking node identity through time |\n\n### Indexes\n\n- **Path index**: Index specific JSON paths for faster navigation\n- **CAS index** (Content-and-Structure): Index values with type awareness\n- **Name index**: Index object keys\n\n## Correctness \u0026 Formal Verification\n\nA versioned storage engine is only useful if old revisions are *exactly* what was written. We take\ncorrectness seriously and treat it as a first-class, reviewable artifact:\n\n- **An invariant catalog** — [`docs/formal-verification.md`](docs/formal-verification.md) states the\n  load-bearing invariants of the engine (temporal arithmetic, DeweyID encoding, page-fragment\n  reconstruction, checksums, the HOT index) as precise pre/post-conditions, each with a proof sketch\n  tight enough to falsify by reading and a pointer to the test that discharges it.\n- **Executable verification tests** that fail CI if an invariant breaks — e.g. `DeweyIDEncodingVerificationTest`,\n  `ChecksumVerificationTest`, `FragmentCacheVerificationTest`, and the `HOTFormalModelTest` /\n  `HOTFormalVerificationTest` model-based suite (a formal model checked against the implementation).\n- **Property-based \u0026 fuzz testing** — a SQLite-`fuzzcheck`-style random JSON round-trip property test,\n  plus a long-running [bitemporal soak stress test](.github/workflows/stress.yml).\n\nThe aim isn't Coq-grade proof; it's that every behavioral claim about the storage engine is stated\nprecisely and guarded by a test.\n\n## Comparison with Alternatives\n\n| Feature | SirixDB | Postgres + Audit | Git + JSON | Event Sourcing | Datomic |\n|---------|---------|------------------|------------|----------------|---------|\n| Query past state | Direct page access | Scan audit log | Checkout + parse | Replay events | Direct segment access |\n| Storage overhead | O(changes) | O(all writes) | O(file × revs) | O(all events) | O(changes) |\n| Granularity | Node-level | Row-level | File-level | Event-level | Fact-level |\n| Bitemporal | Built-in | Manual | No | Manual | Built-in |\n| Embeddable | Yes | No | Yes | Varies | No |\n| Query language | JSONiq/XQuery | SQL | None | Varies | Datalog |\n\n## Building from Source\n\n```bash\ngit clone https://github.com/sirixdb/sirix.git\ncd sirix\n./gradlew build -x test\n```\n\n**Requirements:**\n- Java 25+\n- Gradle 9.1+ (or use included wrapper)\n\n**JVM flags** (required for running):\n```\n--enable-preview\n--add-exports=java.base/jdk.internal.ref=ALL-UNNAMED\n--add-exports=java.base/sun.nio.ch=ALL-UNNAMED\n--add-exports=jdk.unsupported/sun.misc=ALL-UNNAMED\n--add-opens=java.base/java.lang=ALL-UNNAMED\n--add-opens=java.base/java.lang.reflect=ALL-UNNAMED\n--add-opens=java.base/java.io=ALL-UNNAMED\n--add-opens=java.base/java.util=ALL-UNNAMED\n```\n\n**Build native binaries** (requires GraalVM):\n```bash\n./gradlew :sirix-kotlin-cli:nativeCompile  # sirix-cli\n./gradlew :sirix-query:nativeCompile       # sirix-shell\n./gradlew :sirix-rest-api:nativeCompile    # REST API server\n```\n\n## Project Structure\n\n```\nbundles/\n├── sirix-core/          # Core storage engine and versioning\n├── sirix-query/         # Brackit JSONiq/XQuery integration + sirix-shell\n├── sirix-rest-api/      # Vert.x REST server\n├── sirix-kotlin-cli/    # Command-line interface (sirix-cli)\n├── sirix-kotlin-api/    # Kotlin coroutine-based API\n├── sirix-mcp/           # Model Context Protocol server for AI agents\n├── sirix-examples/      # Runnable usage examples\n└── sirix-benchmarks/    # JMH and scale benchmarks\n```\n\n## Use Cases\n\n- **Audit trails**: Regulatory requirements for complete data history (finance, healthcare)\n- **Document versioning**: Track changes to configuration, contracts, or content\n- **Debugging**: Query production state at the time a bug occurred\n- **Temporal analytics**: Analyze how data evolved over time windows\n- **Undo/restore**: Revert to or query any historical state\n\n## Community\n\n- **[Discord](https://discord.gg/yC33wVpv7t)** — Quick questions and chat\n- **[Forum](https://sirix.discourse.group/)** — Discussions and support\n- **[GitHub Issues](https://github.com/sirixdb/sirix/issues)** — Bug reports and feature requests\n\n## Contributing\n\nContributions welcome! See [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines, and please review our [Code of Conduct](CODE_OF_CONDUCT.md).\n\nFor security vulnerabilities, see [SECURITY.md](SECURITY.md).\n\n## Contributors\n\nSirixDB is maintained by Johannes Lichtenberger and the open source community.\n\nThe project originated from Treetank, a university research project by Dr. Marc Kramis, Dr. Sebastian Graf and many students.\n\n\u003c!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section --\u003e\n\u003c!-- prettier-ignore-start --\u003e\n\u003c!-- markdownlint-disable --\u003e\n\u003ctable\u003e\n  \u003ctr\u003e\n    \u003ctd align=\"center\"\u003e\u003ca href=\"https://github.com/yiss\"\u003e\u003cimg src=\"https://avatars1.githubusercontent.com/u/12660796?v=4?s=100\" width=\"100px;\" alt=\"\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eIlias YAHIA\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"https://github.com/sirixdb/sirix/commits?author=yiss\" title=\"Code\"\u003e💻\u003c/a\u003e\u003c/td\u003e\n    \u003ctd align=\"center\"\u003e\u003ca href=\"https://github.com/BirokratskaZila\"\u003e\u003cimg src=\"https://avatars1.githubusercontent.com/u/24469472?v=4?s=100\" width=\"100px;\" alt=\"\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eBirokratskaZila\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"https://github.com/sirixdb/sirix/commits?author=BirokratskaZila\" title=\"Documentation\"\u003e📖\u003c/a\u003e\u003c/td\u003e\n    \u003ctd align=\"center\"\u003e\u003ca href=\"https://mrbuggysan.github.io/\"\u003e\u003cimg src=\"https://avatars0.githubusercontent.com/u/9119360?v=4?s=100\" width=\"100px;\" alt=\"\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eAndrei Buiza\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"https://github.com/sirixdb/sirix/commits?author=MrBuggySan\" title=\"Code\"\u003e💻\u003c/a\u003e\u003c/td\u003e\n    \u003ctd align=\"center\"\u003e\u003ca href=\"https://www.linkedin.com/in/dmytro-bondar-330804103/\"\u003e\u003cimg src=\"https://avatars0.githubusercontent.com/u/11942950?v=4?s=100\" width=\"100px;\" alt=\"\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eBondar Dmytro\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"https://github.com/sirixdb/sirix/commits?author=Loniks\" title=\"Code\"\u003e💻\u003c/a\u003e\u003c/td\u003e\n    \u003ctd align=\"center\"\u003e\u003ca href=\"https://github.com/santoshkumarkannur\"\u003e\u003cimg src=\"https://avatars3.githubusercontent.com/u/56201023?v=4?s=100\" width=\"100px;\" alt=\"\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003esantoshkumarkannur\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"https://github.com/sirixdb/sirix/commits?author=santoshkumarkannur\" title=\"Documentation\"\u003e📖\u003c/a\u003e\u003c/td\u003e\n    \u003ctd align=\"center\"\u003e\u003ca href=\"https://github.com/LarsEckart\"\u003e\u003cimg src=\"https://avatars1.githubusercontent.com/u/4414802?v=4?s=100\" width=\"100px;\" alt=\"\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eLars Eckart\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"https://github.com/sirixdb/sirix/commits?author=LarsEckart\" title=\"Code\"\u003e💻\u003c/a\u003e\u003c/td\u003e\n    \u003ctd align=\"center\"\u003e\u003ca href=\"http://www.hackingpalace.net\"\u003e\u003cimg src=\"https://avatars1.githubusercontent.com/u/6793260?v=4?s=100\" width=\"100px;\" alt=\"\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eJayadeep K M\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"#projectManagement-kmjayadeep\" title=\"Project Management\"\u003e📆\u003c/a\u003e\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd align=\"center\"\u003e\u003ca href=\"http://keithkim.org\"\u003e\u003cimg src=\"https://avatars0.githubusercontent.com/u/318225?v=4?s=100\" width=\"100px;\" alt=\"\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eKeith Kim\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"#design-karmakaze\" title=\"Design\"\u003e🎨\u003c/a\u003e\u003c/td\u003e\n    \u003ctd align=\"center\"\u003e\u003ca href=\"https://github.com/theodesp\"\u003e\u003cimg src=\"https://avatars0.githubusercontent.com/u/328805?v=4?s=100\" width=\"100px;\" alt=\"\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eTheofanis Despoudis\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"https://github.com/sirixdb/sirix/commits?author=theodesp\" title=\"Documentation\"\u003e📖\u003c/a\u003e\u003c/td\u003e\n    \u003ctd align=\"center\"\u003e\u003ca href=\"https://github.com/Mrexsp\"\u003e\u003cimg src=\"https://avatars3.githubusercontent.com/u/23698645?v=4?s=100\" width=\"100px;\" alt=\"\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eMario Iglesias Alarcón\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"#design-Mrexsp\" title=\"Design\"\u003e🎨\u003c/a\u003e\u003c/td\u003e\n    \u003ctd align=\"center\"\u003e\u003ca href=\"https://twitter.com/_anmonteiro\"\u003e\u003cimg src=\"https://avatars2.githubusercontent.com/u/661909?v=4?s=100\" width=\"100px;\" alt=\"\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eAntonio Nuno Monteiro\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"#projectManagement-anmonteiro\" title=\"Project Management\"\u003e📆\u003c/a\u003e\u003c/td\u003e\n    \u003ctd align=\"center\"\u003e\u003ca href=\"http://fultonbrowne.github.io\"\u003e\u003cimg src=\"https://avatars1.githubusercontent.com/u/50185337?v=4?s=100\" width=\"100px;\" alt=\"\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eFulton Browne\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"https://github.com/sirixdb/sirix/commits?author=FultonBrowne\" title=\"Documentation\"\u003e📖\u003c/a\u003e\u003c/td\u003e\n    \u003ctd align=\"center\"\u003e\u003ca href=\"https://twitter.com/felixrabe\"\u003e\u003cimg src=\"https://avatars3.githubusercontent.com/u/400795?v=4?s=100\" width=\"100px;\" alt=\"\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eFelix Rabe\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"https://github.com/sirixdb/sirix/commits?author=felixrabe\" title=\"Documentation\"\u003e📖\u003c/a\u003e\u003c/td\u003e\n    \u003ctd align=\"center\"\u003e\u003ca href=\"https://twitter.com/ELWillis10\"\u003e\u003cimg src=\"https://avatars3.githubusercontent.com/u/182492?v=4?s=100\" width=\"100px;\" alt=\"\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eEthan Willis\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"https://github.com/sirixdb/sirix/commits?author=ethanwillis\" title=\"Documentation\"\u003e📖\u003c/a\u003e\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd align=\"center\"\u003e\u003ca href=\"https://github.com/bark\"\u003e\u003cimg src=\"https://avatars1.githubusercontent.com/u/223964?v=4?s=100\" width=\"100px;\" alt=\"\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eErik Axelsson\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"https://github.com/sirixdb/sirix/commits?author=bark\" title=\"Code\"\u003e💻\u003c/a\u003e\u003c/td\u003e\n    \u003ctd align=\"center\"\u003e\u003ca href=\"https://se.rg.io/\"\u003e\u003cimg src=\"https://avatars1.githubusercontent.com/u/976915?v=4?s=100\" width=\"100px;\" alt=\"\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eSérgio Batista\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"https://github.com/sirixdb/sirix/commits?author=batista\" title=\"Documentation\"\u003e📖\u003c/a\u003e\u003c/td\u003e\n    \u003ctd align=\"center\"\u003e\u003ca href=\"https://github.com/chaensel\"\u003e\u003cimg src=\"https://avatars2.githubusercontent.com/u/2786041?v=4?s=100\" width=\"100px;\" alt=\"\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003echaensel\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"https://github.com/sirixdb/sirix/commits?author=chaensel\" title=\"Documentation\"\u003e📖\u003c/a\u003e\u003c/td\u003e\n    \u003ctd align=\"center\"\u003e\u003ca href=\"https://github.com/balajiv113\"\u003e\u003cimg src=\"https://avatars1.githubusercontent.com/u/13016475?v=4?s=100\" width=\"100px;\" alt=\"\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eBalaji Vijayakumar\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"https://github.com/sirixdb/sirix/commits?author=balajiv113\" title=\"Code\"\u003e💻\u003c/a\u003e\u003c/td\u003e\n    \u003ctd align=\"center\"\u003e\u003ca href=\"https://github.com/FernandaCG\"\u003e\u003cimg src=\"https://avatars3.githubusercontent.com/u/28972973?v=4?s=100\" width=\"100px;\" alt=\"\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eFernanda Campos\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"https://github.com/sirixdb/sirix/commits?author=FernandaCG\" title=\"Code\"\u003e💻\u003c/a\u003e\u003c/td\u003e\n    \u003ctd align=\"center\"\u003e\u003ca href=\"https://joellau.github.io/\"\u003e\u003cimg src=\"https://avatars3.githubusercontent.com/u/29514264?v=4?s=100\" width=\"100px;\" alt=\"\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eJoel Lau\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"https://github.com/sirixdb/sirix/commits?author=JoelLau\" title=\"Code\"\u003e💻\u003c/a\u003e\u003c/td\u003e\n    \u003ctd align=\"center\"\u003e\u003ca href=\"https://github.com/add09\"\u003e\u003cimg src=\"https://avatars3.githubusercontent.com/u/38160880?v=4?s=100\" width=\"100px;\" alt=\"\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eadd09\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"https://github.com/sirixdb/sirix/commits?author=add09\" title=\"Code\"\u003e💻\u003c/a\u003e\u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd align=\"center\"\u003e\u003ca href=\"https://github.com/EmilGedda\"\u003e\u003cimg src=\"https://avatars2.githubusercontent.com/u/4695818?v=4?s=100\" width=\"100px;\" alt=\"\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eEmil Gedda\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"https://github.com/sirixdb/sirix/commits?author=EmilGedda\" title=\"Code\"\u003e💻\u003c/a\u003e\u003c/td\u003e\n    \u003ctd align=\"center\"\u003e\u003ca href=\"https://github.com/arohlen\"\u003e\u003cimg src=\"https://avatars1.githubusercontent.com/u/49123208?v=4?s=100\" width=\"100px;\" alt=\"\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eAndreas Rohlén\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"https://github.com/sirixdb/sirix/commits?author=arohlen\" title=\"Code\"\u003e💻\u003c/a\u003e\u003c/td\u003e\n    \u003ctd align=\"center\"\u003e\u003ca href=\"https://github.com/marcinbieleckiLLL\"\u003e\u003cimg src=\"https://avatars3.githubusercontent.com/u/26444765?v=4?s=100\" width=\"100px;\" alt=\"\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eMarcin Bielecki\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"https://github.com/sirixdb/sirix/commits?author=marcinbieleckiLLL\" title=\"Code\"\u003e💻\u003c/a\u003e\u003c/td\u003e\n    \u003ctd align=\"center\"\u003e\u003ca href=\"https://github.com/ManfredNentwig\"\u003e\u003cimg src=\"https://avatars1.githubusercontent.com/u/164948?v=4?s=100\" width=\"100px;\" alt=\"\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eManfred Nentwig\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"https://github.com/sirixdb/sirix/commits?author=ManfredNentwig\" title=\"Code\"\u003e💻\u003c/a\u003e\u003c/td\u003e\n    \u003ctd align=\"center\"\u003e\u003ca href=\"https://github.com/Raj-Datta-Manohar\"\u003e\u003cimg src=\"https://avatars0.githubusercontent.com/u/25588557?v=4?s=100\" width=\"100px;\" alt=\"\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eRaj\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"https://github.com/sirixdb/sirix/commits?author=Raj-Datta-Manohar\" title=\"Code\"\u003e💻\u003c/a\u003e\u003c/td\u003e\n    \u003ctd align=\"center\"\u003e\u003ca href=\"https://github.com/mosheduminer\"\u003e\u003cimg src=\"https://avatars.githubusercontent.com/u/47164590?v=4?s=100\" width=\"100px;\" alt=\"\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eMoshe Uminer\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"https://github.com/sirixdb/sirix/commits?author=mosheduminer\" title=\"Code\"\u003e💻\u003c/a\u003e\u003c/td\u003e\n  \u003c/tr\u003e\n\u003c/table\u003e\n\n\u003c!-- markdownlint-restore --\u003e\n\u003c!-- prettier-ignore-end --\u003e\n\n\u003c!-- ALL-CONTRIBUTORS-LIST:END --\u003e\n\n## Sponsors\n\nSupport SirixDB development on [Open Collective](https://opencollective.com/sirixdb/).\n\n## License\n\n[BSD 3-Clause License](LICENSE)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsirixdb%2Fsirix","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsirixdb%2Fsirix","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsirixdb%2Fsirix/lists"}