Use cases

Worked scenarios, end to end

Five concrete builds, each showing the whole loop: the scenario, the ingestion setup, the scoping setup, and the agent interaction. Every command matches a real Verity route or tool. Assume a running server (verity-cli dev), $VERITY, $TENANT, and $VERITY_ADMIN_TOKEN in the environment.

1 · A support agent that answers from live CRM + docs without leaking other customers

Scenario. A support agent for Acme should answer from Acme's live CRM state and the shared docs Acme is allowed to see — and must never surface another customer's data or Acme's restricted pricing.

Ingestion setup

bash
# live CRM via CDC (mirrored) — one field update, queryable in ~31ms
curl -s -X POST "$VERITY/v1/ingest/debezium?tenant_id=$TENANT" \
  -H "authorization: Bearer $VERITY_ADMIN_TOKEN" -H 'content-type: application/json' \
  -d '{"payload":{"after":{"id":"opp-1","amount":84000,"stage":"negotiation"},
       "source":{"connector":"postgresql","db":"crm","table":"opportunities","ts_ms":1752000000000},"op":"u"}}'

# a shared runbook, visible to the support group (token 12), tagged to Acme
HANDLE=$(curl -s -X POST "$VERITY/v1/scopes" \
  -d '{"tenant_id":"'"$TENANT"'","principals":[12],"entity_scope":["account:acme"]}' | jq -r .scope_handle)
curl -s -X POST "$VERITY/v1/files" -F "scope_handle=$HANDLE" \
  -F "entities=account:acme" -F "file=@acme-runbook.md"

Scoping setup

The agent's session clamps pricing out with a purpose pack and binds to Acme only:

bash
SUPPORT=$(curl -s -X POST "$VERITY/v1/scopes" -d '{
  "tenant_id":"'"$TENANT"'","principals":[12],"entity_scope":["account:acme"],
  "purpose":"support_conversation","actor_azp":"agent:support-bot"}' | jq -r .scope_handle)

Agent interaction

bash
# answers from live CRM + the runbook
curl -s -X POST "$VERITY/v1/recall" -d "{\"scope_handle\":\"$SUPPORT\",\"text\":\"what stage is the Acme deal in?\"}"

# restricted pricing is filtered out by the purpose clamp
curl -s -X POST "$VERITY/v1/recall" -d "{\"scope_handle\":\"$SUPPORT\",\"text\":\"exact renewal quote amount\"}" | jq length
# → 0

# another customer's data is simply not in scope — 0 results, never a refusal message
curl -s -X POST "$VERITY/v1/recall" -d "{\"scope_handle\":\"$SUPPORT\",\"text\":\"globex account details\"}" | jq length
# → 0
what carries the guarantee Entity scope removes every non-Acme chunk in the index; the support_conversation purpose lowers the confidentiality ceiling below restricted so pricing is filtered too. The model never receives the excluded data, so no prompt can coax it out.

2 · Two agents sharing one account's memory with cross-agent activity awareness

Scenario. A sales-bot and a prep-bot both work Acme. They should share semantic memory and see each other's actions so neither repeats work — but the sharing must stay inside Acme.

Scoping setup

bash
mint() { curl -s -X POST "$VERITY/v1/scopes" -d "$1" | jq -r .scope_handle; }
SALES=$(mint '{"tenant_id":"'"$TENANT"'","principals":[7,11],"entity_scope":["account:acme"],"actor_azp":"agent:sales-bot"}')
PREP=$(mint  '{"tenant_id":"'"$TENANT"'","principals":[7,11],"entity_scope":["account:acme"],"actor_azp":"agent:prep-bot"}')

Agent interaction

bash
# sales-bot records an action AND a shared note
curl -s -X POST "$VERITY/v1/actions" -d "{\"scope_handle\":\"$SALES\",\"action_id\":\"q1\",
  \"action_type\":\"quote.issued\",\"summary\":\"Issued renewal quote at \$84,000.\",
  \"outcome\":\"succeeded\",\"occurred_at\":\"2026-07-10T17:41:02Z\"}"
curl -s -X POST "$VERITY/v1/episodes" -d "{\"scope_handle\":\"$SALES\",
  \"observation\":\"Acme's renewal decision moves to their Q4 board meeting.\",\"entities\":[\"account:acme\"]}"

# prep-bot checks activity BEFORE acting (so it won't re-issue the quote)…
curl -s "$VERITY/v1/activity?scope_handle=$PREP&entity=account:acme&action_types=quote.*" \
  | jq '.[] | {who:.actor_azp, what:.action_type}'
# → { "who":"agent:sales-bot", "what":"quote.issued" }

# …and recalls sales-bot's shared note
curl -s -X POST "$VERITY/v1/recall" -d "{\"scope_handle\":\"$PREP\",\"text\":\"when is Acme deciding on renewal?\",\"k\":1}" \
  | jq -r '.[0].content'
# → "Acme's renewal decision moves to their Q4 board meeting."

An MCP agent would use memory_activity before acting, memory_record_action after, and memory_poll_changes between turns to notice the other agent's writes with a cursor.

3 · A HubSpot + Google Drive knowledge base with ACL inheritance

Scenario. Connect a CRM and a document store so agents answer from both — with Drive's real file permissions inherited so a caller only sees the files they'd see in Drive.

Ingestion setup (BYOT, two connectors)

sh
# Google Drive — service account (tier A, mirrored ACLs). ACL-before-content.
export GOOGLE_APPLICATION_CREDENTIALS=/path/to/service-account.json
python -m verity_ingest.connectors.gdrive --once

# HubSpot — private-app token (tier C, no per-record ACL API → admin-assigned visibility)
export HUBSPOT_PRIVATE_APP_TOKEN=pat-na1-...
python -m verity_ingest.connectors.hubspot --once --visibility 12   # the "support" group token

Drive documents arrive with mirrored provenance: each file's permissions.list is mapped to canonical principals (user:*, group:*), and nested groups are resolved through SpiceDB via the Admin SDK directory sync. HubSpot, having no ACL API, arrives with admin-assigned visibility from the --visibility policy.

Scoping setup & interaction

bash
# resolve a real user to their principals (user + group closure) via ReBAC
ALICE=$(curl -s -X POST "$VERITY/v1/scopes" -d '{
  "tenant_id":"'"$TENANT"'","subject":"user:alice@corp.example"}' | jq -r .scope_handle)

# alice sees exactly the Drive files her Drive permissions allow, plus HubSpot content
# her support-group token can read — a single recall spanning both sources
curl -s -X POST "$VERITY/v1/recall" -d "{\"scope_handle\":\"$ALICE\",\"text\":\"acme onboarding plan\"}" \
  | jq '.[] | {source:.source, provenance:.acl_provenance}'
# → mixed hits: {"source":"gdrive","provenance":"mirrored"} … {"source":"hubspot","provenance":"admin-assigned"}
the point A file Alice cannot open in Drive never appears in her recall — the Drive ACL is the in-index pre-filter. Revoke her from a Drive group and a revocation tombstone hides those files on her next read, ahead of any bitmap rebuild.

4 · Org-wide learning via the knowledge layer without cross-customer leakage

Scenario. Sales agents keep hitting the same DPA objection with healthcare customers. You want that lesson available org-wide — without any single customer's specifics crossing scopes.

Agents propose (as hypotheses)

bash
# each scoped agent proposes from its own single-customer view (n=1, unpublishable alone)
curl -s -X POST "$VERITY/v1/knowledge" -d "{\"scope_handle\":\"$ACME_SCOPE\",
  \"statement\":\"Healthcare-segment customers require DPA redlines before security review; budget ~2 extra weeks.\",
  \"categories\":[\"industry:healthcare\",\"objection:dpa\"],\"evidence\":[\"$EPISODE_ID\"]}"
# a similar proposal from a DIFFERENT customer's agent accrues support onto the same candidate

The de-identification gate screens each statement against the entity lexicon, quoted spans, and identifying values; anything naming a customer is rejected back to scoped memory. The consolidation worker clusters similar proposals across entities.

A human publishes past k-support

bash
# review the queue (admin) — support must span ≥3 distinct entities and ≥2 writers
curl -s "$VERITY/v1/knowledge?tenant_id=$TENANT&status=candidate" \
  -H "authorization: Bearer $VERITY_ADMIN_TOKEN" | jq '.items[] | {statement, support_tier, distinct_entities}'

# publish with broad visibility; k_min is clamped to ≥3 server-side
curl -s -X POST "$VERITY/v1/knowledge/$ID/publish" -H "authorization: Bearer $VERITY_ADMIN_TOKEN" \
  -d '{"tenant_id":"'"$TENANT"'","visibility":[1],"k_min":3}'

Any scoped agent now benefits — the §7g carve-out

bash
# an agent scoped to a NEW healthcare customer retrieves the published lesson
# (entity-free, kind:knowledge) alongside its own account's tagged content — and nothing else
curl -s -X POST "$VERITY/v1/recall" -d "{\"scope_handle\":\"$NEWCO_SCOPE\",\"text\":\"what slows down healthcare security review?\"}"

Between propose and publish, the item passes through an eligible status once support crosses k across distinct entities and writers — nothing an agent reads ever triggers a publish, and auto-publish is off by default. Agents that recall the published item see a bucketed support tier (emerging / established / extensive), never an exact customer count.

safe by construction The published item is retrievable in an entity-bound scope only because it is positively verified entity-free, keyed on status: published. Erase a supporting episode and a recount runs; if support drops below k, the item auto-invalidates. Full treatment — the three roles, the four gates, the merge cascade with measured precision/recall, and the acceptability controls — on the knowledge layer page; the carve-out itself in Permissions.

5 · A webhook from an internal system as a memory source in 60 seconds

Scenario. An internal deployment system should drop a note into shared memory whenever it ships — no connector, no OAuth.

Mint → POST → recall

bash
# 1. mint a scoped URL (admin) — token shown once
URL=$(curl -s -X POST "$VERITY/v1/webhooks" -H "authorization: Bearer $VERITY_ADMIN_TOKEN" \
  -d '{"tenant_id":"'"$TENANT"'","name":"deploys","visibility":[1]}' | jq -r .url)

# 2. the internal system POSTs its native note (from CI, a cron, anywhere)
curl -s -X POST "$VERITY$URL" -H 'content-type: application/json' \
  -d '{"content":"Deployed api v2.4.1 to prod at 14:02 UTC; migration 0042 applied."}'
# → 200 { "episode_id":"...", "chunks_indexed":1, "facts_written":0 }

# 3. an agent recalls it seconds later
curl -s -X POST "$VERITY/v1/recall" -d "{\"scope_handle\":\"$ANY_ORG_HANDLE\",\"text\":\"latest prod deploy\",\"k\":1}" \
  | jq -r '.[0].content'
# → "Deployed api v2.4.1 to prod at 14:02 UTC; migration 0042 applied."

If the internal system sends a vendor-specific shape Verity doesn't recognize, the delivery returns 202 {"quarantined":true} and the raw payload waits in verity-cli tail for review — you then either adjust the sender to the native shape or bind a source manifest to map it. Either way, nothing ambiguous is ever indexed permissively.

from here Ready to go deeper? Revisit Ingestion for every entry point, Permissions for the full guarantee, or the API reference for exact routes and tools.