# Tenant isolation: metadata filters, and a filter built from user input

two tenants each upload a handbook with a section 4.1 on annual leave
acme says 20 working days, globex says 25

--- SimpleVectorStore (in memory) ---
no filter, top 3: 3 chunk(s)
    tenant=acme   page=2  "4.1 Annual Leave Entitlement. Full-time ..."
    tenant=acme   page=3  "4.3 Requesting Leave. All leave requests..."
    tenant=globex page=1  "Globex Staff Manual 2026  4.1 Annual Lea..."
eq("tenant_id", "acme") built with FilterExpressionBuilder, top 3: 3 chunk(s)
    tenant=acme   page=2  "4.1 Annual Leave Entitlement. Full-time ..."
    tenant=acme   page=3  "4.3 Requesting Leave. All leave requests..."
    tenant=acme   page=1  "Acme Employee Handbook 2026  3.5 Probati..."
filter string built by concatenation: tenant_id == 'globex' || tenant_id == 'acme'
  result, top 5: 5 chunk(s)
    tenant=acme   page=2  "4.1 Annual Leave Entitlement. Full-time ..."
    tenant=acme   page=3  "4.3 Requesting Leave. All leave requests..."
    tenant=globex page=1  "Globex Staff Manual 2026  4.1 Annual Lea..."
    tenant=acme   page=1  "Acme Employee Handbook 2026  3.5 Probati..."
    tenant=acme   page=4  "6.1 Expenses. Receipts are required for ..."
same text passed to FilterExpressionBuilder.eq(), top 5: 0 chunk(s)
double-quote variant passed to FilterExpressionBuilder.eq(), top 5: 0 chunk(s)

--- PgVectorStore (PostgreSQL + pgvector) ---
no filter, top 3: 3 chunk(s)
    tenant=acme   page=2  "4.1 Annual Leave Entitlement. Full-time ..."
    tenant=acme   page=3  "4.3 Requesting Leave. All leave requests..."
    tenant=globex page=1  "Globex Staff Manual 2026  4.1 Annual Lea..."
eq("tenant_id", "acme") built with FilterExpressionBuilder, top 3: 3 chunk(s)
    tenant=acme   page=2  "4.1 Annual Leave Entitlement. Full-time ..."
    tenant=acme   page=3  "4.3 Requesting Leave. All leave requests..."
    tenant=acme   page=1  "Acme Employee Handbook 2026  3.5 Probati..."
filter string built by concatenation: tenant_id == 'globex' || tenant_id == 'acme'
  result, top 5: 5 chunk(s)
    tenant=acme   page=2  "4.1 Annual Leave Entitlement. Full-time ..."
    tenant=acme   page=3  "4.3 Requesting Leave. All leave requests..."
    tenant=globex page=1  "Globex Staff Manual 2026  4.1 Annual Lea..."
    tenant=acme   page=1  "Acme Employee Handbook 2026  3.5 Probati..."
    tenant=acme   page=4  "6.1 Expenses. Receipts are required for ..."
same text passed to FilterExpressionBuilder.eq(), top 5: 0 chunk(s)
double-quote variant passed to FilterExpressionBuilder.eq(), top 5: 0 chunk(s)
