.. title:: How-to :description: One task at a time: name a workspace, pin a set, read a date, retire a claim, and turn the dense scorer on. Each section is one task. Every command finds the writer on ``127.0.0.1:8761`` with nothing set; ``PACKSET_URL`` points it elsewhere and ``packset ensure`` prints the address it started. Name the workspace once ======================= A workspace is the git remote of the directory you stand in, or ``default``. Set ``PACKSET_WORKSPACE`` to pin one for a shell: .. code:: console $ export PACKSET_WORKSPACE=seat $ packset status Every verb also takes the workspace as its last argument, and the writers take ``--workspace WS``. Pin a set ========= A set is a named slice of a workspace with its own cards. Pinning one scopes reads and deduplication to it. .. code:: console $ packset pin review {"instructions":"","set":"review","workspace":"demo"} $ packset pin {"instructions":"","set":"review","workspace":"demo"} The binary prints a JSON object with ``workspace``, ``set``, and ``instructions``. Ask what was live on a date =========================== A closed claim keeps its window. ``packset atoms --as-of TS`` lists every claim live at ``TS``; ``packset search --as-of TS QUERY`` ranks those same claims. Live-now search drops the closed window. .. code:: console $ packset atoms --as-of 2026-08-01T00:00:00Z seat $ packset search --as-of 2026-08-01T00:00:00Z --workspace seat fusion ``GET /v1/search`` with ``as_of`` is the same window. A stamp the pack will not parse is refused. Retire a claim ============== The pack tombstones; it does not erase. The record stays readable and stops being recalled. .. code:: console $ curl -s $PACKSET_URL/v1/atoms/delete -d '{"workspace":"seat","id":"3f9c...","why":"deed-review-2026-09"}' ``why`` names the deed that showed the claim wrong. The seat's ``ljos forget`` does this with the same field. Follow the citations ==================== A claim that names a deed accession (``deed-...`` or ``sha256:...``) is joined to the deed store by that id and nothing else. .. code:: console $ packset accessions seat | deedar evidence - # the bytes are intact $ packset accessions seat | deedar current - # still the tip $ packset citers deed-file-note seat # the claims standing on one deed Choose the panel ================ The writer fuses its ballots with a named panel. Set the three slots in the writer's environment, not in a client: ===================== ================================================================================================================== =========== Variable Values Default ===================== ================================================================================================================== =========== ``PACKSET_FUSE`` ``combmnz``, ``combsum``, ``rrf``, ``borda``, ``dowdall``, ``copeland``, ``schulze``, ``ranked-pairs``, ``kemeny`` ``combmnz`` ``PACKSET_DIVERSIFY`` ``mmr``, ``dpp``, ``none`` ``mmr`` ``PACKSET_DECAY`` ``off``, ``on``, ``fsrs`` ``fsrs`` ===================== ================================================================================================================== =========== ``fsrs`` scales a score by the claim's retrievability from its review clock; ``on`` is a fourteen-day half-life on age. :doc:`Explanation ` says what each was measured against. See what a task involves ======================== Islands are the natural clusters of the link graph; a cue activates one. On a seat's own pack of thirty claims: .. code:: text $ packset islands 9 The org to rst exporter fails with stringp nil on a src block with no language. Every begin_sr 7 Trust rows live in the pack as trust atoms and reach the settle through ljos consensus. One le 1 ljos pins packset-client to one git commit in its lock file. A client change needs cargo updat $ packset island settle a vote with learned trust 1.000 seed 1bd8ee9e370dc5d1b6eb86aca804b15a Trust rows live in the pack as trust atoms and reach 0.888 seed e7574b841812abff43b3c83e6a704d5e A trust graph with rows into only some voters makes 0.810 seed a34d89130f030ea528b5d70a3d0a22c9 The tracker verb takes --trust JSON rows laid over the con 0.732 seed 5a779f5aee06da68e95edc90c1bf3cf6 Trust rows over static trust config for the seat's c The first column is activation relative to the strongest; ``seed`` marks a claim search found itself, the rest were reached along links. Add ``--fire`` when the seat goes on to use the island: the strongest eight fire together and their links gain weight, so the next such cue walks a heavier path. .. code:: console $ packset island --fire settle a vote with learned trust $ packset fire 1bd8ee9e... e7574b84... # or name the claims yourself Turn on the dense scorer ======================== The dense ballot needs the ``packset-embed`` binary beside ``packsetd`` or on ``PATH``, and a model it can load. The default build links Open Neural Network Exchange (ONNX) Runtime that you compiled, or a distro ``libonnxruntime`` of 1.24 or newer that ``pkg-config`` can see. The runtime this ``ort`` publishes as a prebuilt is 1.28.0, and that is the version to compile. The prebuilt download from cdn.pyke.io is ``--features download-binaries``, off unless named. ``ORT_SKIP_DOWNLOAD=1``, ``ORT_OFFLINE=1`` or ``CARGO_NET_OFFLINE=1`` refuse that download even with the feature on. .. code:: console $ crates/packset-embed/build-onnxruntime.sh "$HOME/onnxruntime" $ ORT_LIB_PATH=$HOME/onnxruntime/lib ORT_PREFER_DYNAMIC_LINK=1 cargo build --release -p packset-embed $ export LD_LIBRARY_PATH=$HOME/onnxruntime/lib ``pkg-config`` is tried first. A ``libonnxruntime`` it reports at 1.24 or newer is the one that is linked. ``ORT_LIB_PATH`` is the directory used when that probe does not succeed: ``libonnxruntime.so`` for a shared build, or ``libonnxruntime.a`` for a static one. ``ORT_LIB_LOCATION`` is the same variable. ``ORT_PREFER_DYNAMIC_LINK=1`` selects the shared library; leave it unset to link the static archive. Point ``PKG_CONFIG_PATH`` at a prefix that provides ``libonnxruntime.pc`` when that is the library you want. A build with none of these, and neither feature, stops within the first minute with this recipe, instead of at the linker once everything else has compiled. ``PACKSET_EMBED_NO_ORT_CHECK=1`` skips that check. A runtime load does not link at build time: .. code:: console $ cargo build --release -p packset-embed --features load-dynamic $ ORT_DYLIB_PATH=$HOME/onnxruntime/lib/libonnxruntime.so packset-embed The default model is bge-small-en-v1.5. A hub checkout of it, with ``onnx/model.onnx``, ``tokenizer.json``, ``config.json``, ``special_tokens_map.json`` and ``tokenizer_config.json``, is the model. The first run does not fetch when those files are present. .. code:: console $ PACKSET_EMBED_MODEL_PATH=$HOME/models/bge-small-en-v1.5 packset-embed Without that variable the same files under ``$PACKSET_EMBED_CACHE/user/bge-small/`` are used. The cache is ``$XDG_CACHE_HOME/packset/embed`` unless ``PACKSET_EMBED_CACHE`` names another directory. A directory that is missing a file is an error. An absent directory is the Hugging Face fetch for a model the runtime knows. ``HF_HUB_OFFLINE=1`` refuses that fetch. ``e5-large-v2`` has no fetch; it is files only, under ``user/e5-large-v2/``. The pack stays on the lexical ballots without the model files or the binary. ``/v1/status`` then reads ``embedder.available`` false. A sitting still opens: doctor reads that status, and recall, island and search run on the lexical ballots. .. code:: console $ packset stop && packset ensure $ packset status seat | jq .embedder The published binary remains ``cargo binstall packset-embed`` for a seat that does not compile the runtime. Run the second stage on one question ==================================== The cross-encoder rerank is measured and off by default. Ask for it per query with ``packset search --rerank``, ``GET /v1/search?rerank=1``, or set ``PACKSET_RERANK=1`` on the writer. The stage is a forward pass over the top 20. An absent or broken ``packset-embed`` leaves the first-stage order and reports ``rerank: absent``. A lone hit reports ``rerank: settled``: one candidate cannot be reordered, so the stage answers without a model call. .. code:: console $ packset search --rerank --workspace seat fusion $ curl -s "$PACKSET_URL/v1/search?workspace=seat&q=fusion&rerank=1" | jq '.rerank' Export for a handover, import from one ====================================== .. code:: console $ packset export --into bag/data/atoms seat | deedar export --into bag/data/deeds - Import is one POST per line of the ``.jsonl``; the seat's ``ljos receive`` with ``--import`` does that after checking the bag. Trust rows travel the same way. Serve many agents ================= One writer serves every client on the seat. The worker pool is the balance: ``PACKSET_WORKERS`` sets it (default 4, at most 8), and one logical write runs at a time so two identical claims arriving together are stored once. A burst waits in a queue of ``PACKSET_QUEUE`` connections (default 128) rather than becoming threads. Past that a request is answered 503 with ``Retry-After: 1``. Searches and writes that a worker has read but cannot yet run are bounded the same way. ``packset-client`` asks a busy writer again after 50, 150 and 450 ms. Health, status, the workspace list and the listing without vectors that a status line reads keep one worker, so a search does not hold the last one. ``/health`` still answers. Reads share one parsed snapshot per write. The encoder runs before the write lock and is warmed at start. .. code:: console $ PACKSET_WORKERS=8 packsetd --port 8761 $ PACKSET_URL=http://127.0.0.1:8761 cargo run --release -p packset-daemon --example hammer -- 32 100 The example prints requests per second and latency percentiles for remember and search under 32 clients; the README carries the measured table. A second host is not a second writer: it is a client over the network, or its own pack. Run the retrieval benchmark =========================== .. code:: console $ curl -sSLO https://raw.githubusercontent.com/snap-research/locomo/main/data/locomo10.json $ cargo run --release -p packset-daemon --example locomo -- locomo10.json ``PACKSET_LOCOMO_CONVERSATIONS=3`` scores three conversations for a quick run; the numbers are then comparable to each other and not to a full run.