albok (0.1.10)
Installation
pip install --index-url https://gitea.phasefinal.com/api/packages/vh/pypi/simple/ --extra-index-url https://pypi.org/simple albokAbout this package
Albok — the fleet knowledgebase engine: the LLM-free knowledge store and retrieval package, plus the service that owns the store. Extracted from Worldtree (#412 follow-on; design record in docs/design/albok/).
albok — the fleet knowledgebase engine
Albok ("all-book", from the Icelandic alfræðibók) is the Corviduo fleet's
knowledge store and retrieval engine: an LLM-free Python package plus
the HTTP service that owns the store. It was extracted from Worldtree's
core/library, core/docstore, core/vector_store, core/bm25,
core/hybrid_search, core/text_chunker, core/reranker, core/kb_audit,
core/graph_store and the rule-based half of core/keywords (unit 1,
2026-10-02). Everything that calls an LLM stays with its caller.
What it is, in one screen
- Truth is pristine bytes plus a sidecar plus git: every ingested object
is stored verbatim beside a
.albok.yamlsidecar carrying its provenance, in a per-wing git repository. Nothing is ever stamped into a source. - Index is derived and rebuildable: a facet table over the sidecars, Chroma embeddings, BM25, the graph store. Losing it costs a rebuild.
- Division is two-level: buildings for the big divisions (
fleet,personal, one per organisation), wings inside them. Default-deny access at both levels; a wing may be encrypted at rest. - Writes go through the Albok process only. Ingesters (the fleet memory walker, Muninn) are clients submitting finished object sets for a commit id.
- Reads are authenticated per althing handle. Agents reach it through the
albokCLI or thealbok-mcpserver; nothing talks to the store directly. - Never a boot dependency: consumers degrade to "knowledge unavailable".
Status
| Unit | State |
|---|---|
| 1. Package split | shipped — albok 0.1.0 on the Gitea PyPI index (vh); Worldtree pins it through core/knowledge.py |
| 2. The service (read + ingest + tokens + layout) | shipped and in production — albok-service 0.1.8 at packages/albok-service on its own VM, nh3-albok on nh3-pve-2 (albok.nh3.internal:8392), albok 0.1.4; contract rev 1.9 |
| 3. Clients (ingester, CLI, MCP) | shipped — albok-nemi 0.1.1 (Nemi, hourly timer on nh3-dev), albok-client 0.1.0 (albok, albok-mcp); three wings ingested and tagged; contract docs/contracts/unit3_clients.contract.md |
| 4–6. Notes CRUD / graph / cut-over | per ROADMAP.md |
Layout
| Path | Purpose |
|---|---|
packages/albok-service/ |
the service (unit 2): config, layout, auth, journal, objects, facets, search, ingest, export, health, app; its own tests under service_tests/; Dockerfile; albok.example.yaml |
packages/albok-client/ |
the read clients (unit 3): the albok CLI and the albok-mcp stdio server, stdlib-only; tests under client_tests/ |
packages/albok-nemi/ |
Nemi, the fleet ingester (unit 3): walk, sticky identity, gen-small tagging, sidecars, batches, evals; nemi.example.yaml; tests under nemi_tests/ |
src/albok/ |
the package: library/ (wings, search, reconcile, lease), docstore.py, vector_store/, bm25.py, hybrid_search.py, text_chunker.py, reranker/, kb_audit.py + kb_audit_canary/, graph_store/, keywords.py (rule-based), r_target/ (facet and parser vocabulary), metrics.py (the injected sink protocol) |
tests/ |
the moved suite plus test_boundary.py, which builds the wheel, installs it in a fresh venv and proves core.llm never loads |
docs/design/albok/ |
the durable design record: every operator ruling, the scope survey, the storage/write-guard addendum, the blast radius, the ingestion design |
docs/contracts/ |
the unit contracts (unit1_package_split, unit2_service, unit3_clients; each records its revisions in its frontmatter) and the canonical contract format |
scripts/albok-check |
the operator's one-screen check of the live Albok: /health and the served version against this repo's, the wings a token can read, a search with a positive control, Nemi's newest walk (age, outcomes, a re-update storm), the timer, the container. ./scripts/albok-check; exit 1 on any FAIL |
scripts/albok-search |
search the live Albok by hand: scripts/albok-search <query> (--wing, --top-k, --facet, --json), scripts/albok-search read <object id> for the bytes; the address and token are wired up the same way as albok-check |
.gitea/workflows/ci.yml |
tests + boundary test on every push; wheel build and publish to the Gitea PyPI index on a vX.Y.Z tag |
Development
uv sync --group dev
uv run pytest -q --deselect tests/test_boundary.py # unit tests
uv run pytest -q tests/test_boundary.py # the LLM-free boundary (builds the wheel)
The package reads no configuration file, no environment variable and nothing
relative to its own files: every value arrives resolved from the caller, and
metrics go out through an injected MetricsSink that is required, never
optional. Tests set KB_PATH / WORLDTREE_DATA_PATH only for their own
scratch roots.
Consumers
- Worldtree (
vh/Worldtree) pinsalbok==0.1.0(0.1.1 is a drop-in; its three additive keywords default to 0.1.0 behaviour) fromhttps://gitea.phasefinal.com/api/packages/vh/pypi/simple/and imports it through one seam,core/knowledge.py, until unit 4 turns those callers into HTTP clients (unit 2 owns only the new buildings root, so no interval has two writers). - SVOS lands its read-only knowledge verbs (U14) on the unit 2 service.
- The fleet reaches it through the unit 3 clients.
Conventions
CLAUDE.md carries the working conventions; PRINCIPLES.md the four
engineering principles; persistent-memory.md the dated decisions and
in-flight state; ROADMAP.md the build order. Versioning follows
docs/VERSIONING-POLICY.md; releases are tagged, dev commits are not.