suchi

module
v0.1.0-beta.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 8, 2026 License: AGPL-3.0

README

suchi

suchi

A document-management system as a single Go binary.
Sanskrit सूची — "an index, a catalog, a list"; pronounced SOO-chee, like kimchi.

Homepage

Suchi combines SQLite, content-addressed storage, a Svelte interface, and an integration-friendly HTTP API. It needs no database server, queue, cache, or telemetry service.

Status: v0.1.0-beta.2, suitable for evaluation but not yet critical archives. The API and storage layout are stabilising but not frozen.

Container images · Releases · Actions

  • Reproducible size and startup measurements live under hack/bench/latest-published/.
  • No built-in outbound connection is made until an operator enables or uses an integration. Operator scripts are outside Suchi's egress inventory.
  • Static, CGO_ENABLED=0 Go binary with multi-user ACLs and scoped tokens.
  • AGPL-3.0.

Capabilities

  • PDF and image OCR, thumbnails, barcodes, encrypted PDFs, and ZUGFeRD invoices.
  • EPUB, Office, OpenDocument, RTF, CSV, DjVu, HEIC/HEIF, EML, and Outlook MSG.
  • Full-text search, Johnny.Decimal filing, custom fields, saved views, and rendered filesystem views.
  • Browser uploads, watched folders, IMAP intake, portable import/export, and versioned documents.
  • Automations, human approval workflows, selective rescans, and optional OpenAI-compatible classification, grounded archive research, and reviewed date intelligence with Calendar.
  • Groups, object ACLs, OIDC, share links, audit events, backups, and restore tooling.
  • Svelte SPA, a documented scoped HTTP API, and MCP over stdio or HTTP.

The feature comparison and architecture describe the detailed scope and tradeoffs.

Quick Start

The unsuffixed image is the recommended standard build:

docker volume create suchi-data
docker run -d --name suchi --restart unless-stopped \
  -p 8000:8000 \
  -e PUBLIC_URL=http://127.0.0.1:8000 \
  -v suchi-data:/data \
  ghcr.io/johnnybravo-xyz/suchi:beta
docker logs suchi 2>&1 | grep token_minted

Open http://127.0.0.1:8000, enter the one-time setup token, and create the first admin account. The token expires after 24 hours; attempting to use an expired token writes a replacement to the server log. A minimal compose.yaml is also provided for operators who want editable mounts, networks, and image pins. See Getting started for direct binary, reverse-proxy, NAS, and production deployment paths.

Images

  • v0.1.0-beta.2 / beta / beta-standard: Alpine. Supports all listed formats and indexes scanned PDFs with Tesseract. The beta channel tags resolve to the current beta's standard image.
  • v0.1.0-beta.2-full / beta-full: Debian. Adds OCRmyPDF so downloaded scanned PDFs can retain a searchable text layer.

Both images include anydoc, DjVu, HEIC/HEIF, and Outlook MSG support. The full image changes only the scanned-PDF archive behavior. See Supported file types for the exact routing and bare-metal dependencies.

Development

The workspace requires Go 1.27.0 or newer; plugin-api remains compatible with Go 1.24. SPA and documentation development require Bun.

git clone https://github.com/johnnybravo-xyz/suchi.git
cd suchi
make install-hooks
make check
make run

make run uses /tmp/suchi-dev and listens on http://127.0.0.1:8000. Useful verification commands:

make test
make lint
make ui-check
make smoke
make smoke-ingest
./hack/smoke-anydoc-docx.sh
make smoke-mail

The ci workflow runs formatting, vet, tests, static analysis, and the SPA build. The smoke workflow boots both images and verifies real PDF OCR and Outlook MSG ingestion.

Repository

plugin-api/   shared extension interfaces and types
core/         API, database, ingest pipeline, jobs, auth, and embedded UI
plugins/      local auth, OIDC, and LLM classifier modules
distro/       shipped suchi and suchi-mcp entry points
ui/           Svelte SPA source
deploy/       self-hosting templates and mail intake sidecar
docs/         published documentation source
hack/         fixtures, benchmarks, smoke tests, and developer tools

The root module contains the shipped application; plugin-api stays separate for external plugins and the utilities under hack/ keep isolated dependency graphs. The empty ui module keeps Go tooling out of frontend dependencies. make build produces dist/suchi; suchi doctor inventories configured egress, pipeline tools, schema and taxonomy state, data-directory writability, and selected job, backup, audit, upload-limit, and CAS indicators.

Documentation

Works with Johnny.Decimal, a trademark of Coruscade Pty Ltd. Suchi is independent and not endorsed by them.

License

Suchi is made available under the GNU Affero General Public License v3.0 beginning with its first public release. Before that release, its repository and container images were private development artifacts and were not distributed to any third party.

Directories

Path Synopsis
core
api
Package api owns the JSON HTTP surface — endpoints under /api/*.
Package api owns the JSON HTTP surface — endpoints under /api/*.
approvals
Package approvals is suchi's state-machine engine for routing docs through review/approval chains, sign-offs with deadlines, and timeout-driven escalation.
Package approvals is suchi's state-machine engine for routing docs through review/approval chains, sign-offs with deadlines, and timeout-driven escalation.
audit
Package audit writes append-only audit_events rows.
Package audit writes append-only audit_events rows.
auth
Package auth is the authenticator chain.
Package auth is the authenticator chain.
authz
Package authz owns the decision layer: "may this user do X to this object?" The interface lives here so wiring stays boring, and so downstream builds can swap the implementation without touching handlers.
Package authz owns the decision layer: "may this user do X to this object?" The interface lives here so wiring stays boring, and so downstream builds can swap the implementation without touching handlers.
automations
Package automations is the trigger→conditions→actions engine.
Package automations is the trigger→conditions→actions engine.
backup
Package backup owns the periodic VACUUM INTO snapshot loop.
Package backup owns the periodic VACUUM INTO snapshot loop.
blob
Package blob is the content-addressed store.
Package blob is the content-addressed store.
config
Package config is the env-var-first config loader.
Package config is the env-var-first config loader.
crypto
Package crypto is the small AEAD envelope suchi uses to seal operator-supplied secrets (password-manager style) before they land in SQLite.
Package crypto is the small AEAD envelope suchi uses to seal operator-supplied secrets (password-manager style) before they land in SQLite.
customfield
Package customfield is the per-type dispatch layer for document_custom_field_values.
Package customfield is the per-type dispatch layer for document_custom_field_values.
db
Package db is suchi's SQLite bootstrap.
Package db is suchi's SQLite bootstrap.
db/migrations
Package migrations embeds the database schema migrations.
Package migrations embeds the database schema migrations.
emailaccounts
Package emailaccounts is the CRUD + secret-sealing surface for the `email_accounts` table.
Package emailaccounts is the CRUD + secret-sealing surface for the `email_accounts` table.
gc
Package gc is the blob mark-and-sweep for the CAS.
Package gc is the blob mark-and-sweep for the CAS.
httpx
Package httpx is the HTTP layer glue: middleware stack, security headers, request-id, auth wiring, rate limiting.
Package httpx is the HTTP layer glue: middleware stack, security headers, request-id, auth wiring, rate limiting.
i18n
Package i18n loads the server-rendered UI string catalogs.
Package i18n loads the server-rendered UI string catalogs.
importer/bundle
Package bundle imports an export bundle from an existing DMS.
Package bundle imports an export bundle from an existing DMS.
ingest
Package ingest contains the small contracts shared by ingest producers.
Package ingest contains the small contracts shared by ingest producers.
ingest/emailwatch
Package emailwatch is the third canonical ingest path (design principle 9): IMAP polling for "forward it, forget it" archival.
Package emailwatch is the third canonical ingest path (design principle 9): IMAP polling for "forward it, forget it" archival.
ingest/emailwatch/oauth
Package oauth wraps Microsoft's MSAL-Go PublicClient for the IMAP device-code flow.
Package oauth wraps Microsoft's MSAL-Go PublicClient for the IMAP device-code flow.
ingest/fswatch
Package fswatch is the filesystem-watching ingest producer.
Package fswatch is the filesystem-watching ingest producer.
ingest/sidecar
Package sidecar is the JSON sidecar spec every ingest producer (fs-watch, email-ingest, third-party scanners, cron scripts) can target.
Package sidecar is the JSON sidecar spec every ingest producer (fs-watch, email-ingest, third-party scanners, cron scripts) can target.
intelligence
Package intelligence defines validated, reviewable facts extracted from documents.
Package intelligence defines validated, reviewable facts extracted from documents.
jd
Package jd owns the Johnny.Decimal taxonomy: the neutral first-boot baseline, the legacy importer starter tree, and the inbox-category invariant.
Package jd owns the Johnny.Decimal taxonomy: the neutral first-boot baseline, the legacy importer starter tree, and the inbox-category invariant.
jd/importer
Package importer applies a parsed suchi-taxonomy/v1 file to the DB.
Package importer applies a parsed suchi-taxonomy/v1 file to the DB.
jd/presetfile
Package presetfile is the parser + validator for suchi-taxonomy/v1 files: importable taxonomy presets in HuML, TOML, or YAML.
Package presetfile is the parser + validator for suchi-taxonomy/v1 files: importable taxonomy presets in HuML, TOML, or YAML.
jobs
Package jobs is the durable outbox dispatcher.
Package jobs is the durable outbox dispatcher.
logx
Package logx configures the process-wide slog handler.
Package logx configures the process-wide slog handler.
mimeutil
Package mimeutil refines generic MIME types using content and filename hints.
Package mimeutil refines generic MIME types using content and filename hints.
netutil
Package netutil contains shared network-boundary checks.
Package netutil contains shared network-boundary checks.
pipeline/anydoc
Package anydoc extracts EPUB and office documents through the anydoc CLI.
Package anydoc extracts EPUB and office documents through the anydoc CLI.
pipeline/barcode
Package barcode extracts QR, DataMatrix, and Aztec values from images.
Package barcode extracts QR, DataMatrix, and Aztec values from images.
pipeline/djvu
Package djvu extracts text from DjVu files via djvutxt (from djvulibre-bin on Debian).
Package djvu extracts text from DjVu files via djvutxt (from djvulibre-bin on Debian).
pipeline/docsplit
Package docsplit finds separator pages in a scanned PDF and returns the page ranges that make up each sub-document.
Package docsplit finds separator pages in a scanned PDF and returns the page ranges that make up each sub-document.
pipeline/eml
Package eml parses RFC 5322 email messages (message/rfc822) for the ingest pipeline.
Package eml parses RFC 5322 email messages (message/rfc822) for the ingest pipeline.
pipeline/imgpdf
Package imgpdf wraps raster images in a PDF so the standard OCR path can extract text.
Package imgpdf wraps raster images in a PDF so the standard OCR path can extract text.
pipeline/msg
Package msg converts Outlook .msg files to RFC 822 bytes via msgconvert.
Package msg converts Outlook .msg files to RFC 822 bytes via msgconvert.
pipeline/ocrmypdf
Package ocrmypdf wraps the ocrmypdf CLI for the ingest pipeline.
Package ocrmypdf wraps the ocrmypdf CLI for the ingest pipeline.
pipeline/pageanalyze
Package pageanalyze rasterizes a PDF's pages to greyscale and computes a per-page whiteness score.
Package pageanalyze rasterizes a PDF's pages to greyscale and computes a per-page whiteness score.
pipeline/pdfinspector
Package pdfinspector routes a PDF between the "text-native shortcut" and the "scanned → OCR" paths.
Package pdfinspector routes a PDF between the "text-native shortcut" and the "scanned → OCR" paths.
pipeline/pipeconfig
Package pipeconfig holds tiny helpers that read pipeline knobs from the process environment.
Package pipeconfig holds tiny helpers that read pipeline knobs from the process environment.
pipeline/pipefile
Package pipefile holds small filesystem helpers shared by pipeline stages.
Package pipefile holds small filesystem helpers shared by pipeline stages.
pipeline/postingest
Package postingest runs extraction, classification, and rendering after a document lands.
Package postingest runs extraction, classification, and rendering after a document lands.
pipeline/preconsume
Package preconsume runs an optional operator script before built-in ingest.
Package preconsume runs an optional operator script before built-in ingest.
pipeline/qpdf
Package qpdf is the PDF normalization pre-step.
Package qpdf is the PDF normalization pre-step.
pipeline/tessocr
Package tessocr is the lightweight OCR path: pdftoppm rasterizes each page to a PGM, tesseract reads it back as text, we concatenate.
Package tessocr is the lightweight OCR path: pdftoppm rasterizes each page to a PGM, tesseract reads it back as text, we concatenate.
pipeline/zugferd
Package zugferd extracts structured invoice data from ZUGFeRD / Factur-X / XRechnung PDF/A-3 files.
Package zugferd extracts structured invoice data from ZUGFeRD / Factur-X / XRechnung PDF/A-3 files.
render/paths
Package paths renders bounded storage-path templates.
Package paths renders bounded storage-path templates.
render/view
Package view is the rendered-view projection: the human-browsable file tree at $DATA_DIR/rendered/...
Package view is the rendered-view projection: the human-browsable file tree at $DATA_DIR/rendered/...
sandbox
Package sandbox is the shared subprocess-invocation wrapper.
Package sandbox is the shared subprocess-invocation wrapper.
settings
Package settings is a thin typed wrapper over the settings key-value table.
Package settings is a thin typed wrapper over the settings key-value table.
slug
Package slug provides canonical slugs for taxonomy rows.
Package slug provides canonical slugs for taxonomy rows.
taxonomy
Package taxonomy is admin tooling over the reference tables — tags, correspondents, document_types.
Package taxonomy is admin tooling over the reference tables — tags, correspondents, document_types.
trash
Package trash owns permanent document deletion and fixed retention.
Package trash owns permanent document deletion and fixed retention.
ui
Package ui is the small browser-side glue the SPA depends on: form-based cookie login, first-boot bootstrap, direct-URL blob serving (preview + download), and a static /assets mount for the login/bootstrap chrome.
Package ui is the small browser-side glue the SPA depends on: form-based cookie login, first-boot bootstrap, direct-URL blob serving (preview + download), and a static /assets mount for the login/bootstrap chrome.
distro
cmd/suchi command
Command suchi is the single-binary entry point.
Command suchi is the single-binary entry point.
demo
Demo-mode reset ticker removes expired visitor records, never CAS bytes.
Demo-mode reset ticker removes expired visitor records, never CAS bytes.
plugin-api module
plugins
llm-classifier
Package llmclassifier is the optional AI-driven classifier that covers what the deterministic rules engine can't.
Package llmclassifier is the optional AI-driven classifier that covers what the deterministic rules engine can't.
local-auth
Package localauth is the built-in Authenticator plugin.
Package localauth is the built-in Authenticator plugin.
oidc
Package oidcauth is the generic OpenID Connect authenticator plugin.
Package oidcauth is the generic OpenID Connect authenticator plugin.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL