Metadata-Version: 2.5
Name: albok
Version: 0.1.10
Summary: 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/).
Author: Vuong Hoang
License: Proprietary
License-File: LICENSE
Requires-Python: >=3.11
Requires-Dist: chromadb>=0.5
Requires-Dist: gitpython>=3.1
Requires-Dist: httpx>=0.27
Requires-Dist: pydantic>=2.7
Requires-Dist: python-frontmatter>=1.1
Requires-Dist: pyyaml>=6.0
Requires-Dist: rank-bm25>=0.2.2
Requires-Dist: sentence-transformers>=3.0
Requires-Dist: torch>=2.0
Description-Content-Type: text/markdown

# 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.yaml` sidecar 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
  `albok` CLI or the `albok-mcp` server; 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

```bash
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`) pins `albok==0.1.0` (0.1.1 is a drop-in; its three additive keywords default to 0.1.0 behaviour) from
  `https://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.
