AkurAI Build
Menu

AkurAI-Build

public

Latest change 0cf28150faedd8c150474a4f16be4c9922c04f56 - feat: add Ponytail UI design system by Olafur Bui

{% extends "layouts/docs.html" %} {% block title %}SQLite and vectors · Bunfork
docs{% endblock %} {% block description %}Use Bunfork's SQLCipher-encrypted
SQLite database, exact migrations, tenant/model-scoped vector CLI, and
authenticated vector API.{% endblock %} {% block breadcrumb %}SQLite &
vectors{% endblock %} {% block docs_title %}SQLite & vectors{% endblock %}
{% block docs_summary %}Bunfork keeps one narrow data model: encrypted vector
records, exact embedded migrations, and bounded exhaustive cosine search.{%
endblock %} {% block docs_content %}
<section class="doc-section" aria-labelledby="encrypted-sqlite">
  <h2 id="encrypted-sqlite">Encrypted SQLite</h2>
  <p>
    The bundled SQLCipher build encrypts the database at rest. Bunfork validates
    the application ID, user version, complete migration ledger, exact
    table/index SQL, and absence of unexpected schema objects.
  </p>
  <pre><code>./target/release/bunfork keygen
./target/release/bunfork migrate</code></pre>
  <p>
    The key must decode to 32 random bytes represented by 64 hexadecimal
    characters. Keep the key outside the page and public directories and outside
    the deployment release.
  </p>
</section>

<section class="doc-section" aria-labelledby="vector-cli">
  <h2 id="vector-cli">Vector CLI</h2>
  <p>
    Global <code>--tenant</code> and <code>--model</code> values define the
    record scope. Put reads content from a UTF-8 file; embeddings are
    comma-separated finite <code>f32</code> values.
  </p>
  <pre><code>./target/release/bunfork \
  --tenant acme --model notes \
  vector put note-1 \
  --content-file note.txt \
  --embedding 1,0,0

./target/release/bunfork \
  --tenant acme --model notes \
  vector search --embedding 0.9,0.1,0 --limit 5

./target/release/bunfork \
  --tenant acme --model notes \
  vector delete note-1</code></pre>
  <p>
    Search returns deterministic JSON matches ordered by cosine similarity. It
    considers only records with the query's dimension in the selected
    tenant/model scope.
  </p>
</section>

<section class="doc-section" aria-labelledby="vector-api">
  <h2 id="vector-api">Authenticated HTTP API</h2>
  <p>
    Vector endpoints require
    <code>Authorization: Bearer &lt;API_TOKEN&gt;</code>. For browser requests
    carrying an <code>Origin</code> header, the origin must match the configured
    public origin (or the request host when no public origin is configured).
  </p>
  <pre><code>curl --request PUT http://localhost:3100/api/vectors/note-1 \
  --header "Authorization: Bearer $API_TOKEN" \
  --header "Content-Type: application/json" \
  --data '{"id":"note-1","content":"hello","embedding":[1,0,0]}'

curl --request POST http://localhost:3100/api/vectors/search \
  --header "Authorization: Bearer $API_TOKEN" \
  --header "Content-Type: application/json" \
  --data '{"embedding":[1,0,0],"limit":5}'

curl --request DELETE http://localhost:3100/api/vectors/note-1 \
  --header "Authorization: Bearer $API_TOKEN"</code></pre>
  <aside class="doc-note">
    <strong>ID consistency:</strong> on PUT, the path ID and JSON
    <code>id</code> must be identical.
  </aside>
</section>

<section class="doc-section" aria-labelledby="hard-limits">
  <h2 id="hard-limits">Hard limits</h2>
  <div class="table-wrap">
    <table>
      <thead>
        <tr>
          <th>Input</th>
          <th>Limit</th>
        </tr>
      </thead>
      <tbody>
        <tr>
          <td>Embedding dimensions</td>
          <td>1–4,096</td>
        </tr>
        <tr>
          <td>Search candidates</td>
          <td>At most 10,000</td>
        </tr>
        <tr>
          <td>Search work</td>
          <td>At most 10,000,000 multiply-adds</td>
        </tr>
        <tr>
          <td>Results</td>
          <td>1–25</td>
        </tr>
        <tr>
          <td>Record content</td>
          <td>64 KiB</td>
        </tr>
        <tr>
          <td>JSON request body</td>
          <td>1 MiB</td>
        </tr>
      </tbody>
    </table>
  </div>
  <p>
    A single in-process gate permits one HTTP vector search at a time;
    concurrent searches receive <code>429</code>. Invalid IDs, dimensions,
    norms, limits, or budgets are client errors rather than server errors.
  </p>
</section>

<aside class="doc-callout" aria-labelledby="vector-boundary">
  <h2 id="vector-boundary">Deliberately exhaustive</h2>
  <p>
    Bunfork does not load SQLite extensions and does not claim ANN or full-text
    search. The bounded exhaustive scan is suitable for a small encrypted
    corpus. Move search to a dedicated system when that ceiling is measurable.
  </p>
</aside>

<nav class="docs-pagination" aria-label="Documentation pagination">
  <a href="/docs/cli"
    ><small>Previous</small><span aria-hidden="true">←</span> CLI &amp;
    operations</a
  >
  <a href="/docs/deployment"
    ><small>Next</small>Deploy &amp; recover
    <span aria-hidden="true">→</span></a
  >
</nav>
{% endblock %}