Skip to content

On the sqlite driver, tenant-scoped objects (ats_employer, ats_interview, ats_offer) return 0 rows to platform admins holding viewAllRecords; the memory driver returns all of them #39

Description

@os-sam

Found while verifying #27 on claude/issue-27-signable-personas at 48568f9, and reproduced on origin/main at 7e76ffe — so it is pre-existing and not attributable to that PR (which touches no object or tenancy setting).

Measured

Same artifact, same OS_PLATFORM_OWNER_EMAIL=admin@objectos.ai, --fresh, fresh sign-in per account, GET /api/v1/data/OBJECT?limit=1 read as that user. Seed loaded 801 rows, 0 errored, on both drivers.

account driver ats_employer ats_interview ats_offer ats_job ats_application ats_candidate
platform owner (admin_full_access + config standing) memory 12 40 14 40 200 80
platform owner sqlite (default) 0 0 0 40 200 80
platform_admin persona (ats_platform_admin, viewAllRecords) memory 12 40 14 40 200 80
platform_admin persona sqlite (default) 0 0 0 40 200 80
job seeker persona memory 9 (verified) 0 0 22 1 1
job seeker persona sqlite (default) 0 0 0 22 1 1

Baseline on origin/main 7e76ffe, sqlite, signed in as the runtime-minted dev admin with owner standing: ats_employer 0 · ats_interview 0 · ats_offer 0 · ats_job 40 · ats_application 200. Identical split.

The three objects that read 0 are exactly the ones that stay inside the Layer 0 tenant wall under the 2026-09-07 split contract (ats_employer, ats_employer_member, ats_interview, ats_offer carry organization_id); the objects that read fine are the platform-global ones (tenancy: { enabled: false }). So the SQL driver appears to apply an organization filter on organization_id that the memory driver does not — the seeded rows carry org_ats_* while every platform session's active organization is the Default Organization. DESIGN.md §03 says the wall produces null under the single posture, which is what the memory driver does; the sqlite path does not match that. I did not run a debug-level boot to read the tenancy or RLS lines, so the mechanism is a hypothesis, not a finding.

What it does to the demo

The literal pnpm dev (sqlite is the default driver) serves the Platform group's Employers Pending queue empty to every platform persona, while pnpm dev --database-driver memory shows its 2 rows. The README's demo path on #27's branch therefore only shows employer data on the memory driver.

Suggested next step

Boot with --log-level debug on sqlite, read as admin@platform.example, and capture the [RLS] / tenancy lines for one ats_employer find; then decide whether this is an upstream driver defect (relay to objectstack-ai/objectstack) or a posture the app must declare. #18 is about accessible_org_ids on the employer side and is a different mechanism — this one hits viewAllRecords holders.

Filed without a label for triage.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions