Skip to content

Every Field.user column reads as a bare id to a platform persona: the readable sys_user set is now the caller's own row (1 of 113, was 83) #82

Description

@os-sam

Measured while delivering #67 on claude/issue-67-employer-contact, base c3c6526. #67 fixes exactly
one column (ats_employer.owner) with a stored name mirror, because that mirror is only defensible
where the audience already holds the fact. The other five Field.user columns have no such mirror
and are unfixed; this card is the general case.

What was measured

One container, objectstack dev -p 4671, demo seed (818 rows, errored: 0), both drivers, counted
after [Seeder] Seed loading complete with hasMore == false and records.length == total asserted.

sys_user rows readable per persona — identical on the memory and the sqlite driver:

Persona sys_user readable of the 30 employer-staff rows
admin@platform.example 1 of 113 0
ops@platform.example 1 of 113 0
candidate01@mail.example 1 of 113 0
admin@objectos.ai (platform owner, no ATS position) 113 of 113 30

The one row each persona reads is its own. "Employer staff" is not a hand-written set: it is the 30
user values of ats_employer_member, read as the platform owner.

Consequence, as admin@platform.example, one request per row (populate on the field):

ats_candidate.user          -> ["usr_ats_c45","usr_ats_c08","usr_ats_c04"]
ats_interview.interviewers  -> [["usr_ats_swiftroute_r1"],["usr_ats_harborline_r1","usr_ats_harborline_admin"], …]
ats_offer.approved_by       -> ["usr_ats_cedarbrook_admin","usr_ats_cedarbrook_admin","usr_ats_summitridge_admin"]
ats_report.reporter         -> ["usr_ats_c06","usr_ats_brightmarket_r1","usr_ats_c61"]
ats_employer_member.user    -> ["usr_ats_lumenvale_r2","usr_ats_summitridge_r2","usr_ats_pixelforge_admin"]

Not one of them expands. ats_interview.interviewers is an authored grid column
(src/views/interview.view.ts), so a platform reviewer reads that queue as a column of raw ids —
the same defect #67 measured on ats_employer.owner, on a surface #67 does not touch.

Why this is a change and not the known state

#67's triage comment measured the same thing on 54cd69c and got 83 of 113 readable — 80
candidates, 2 platform staff, the dev owner — and recorded ats_candidate.user expanding correctly:

Avery Lindqvist   user = {"id":"usr_ats_c01","name": …}     <- expanded

Today that same field is a bare usr_ats_c45. The readable set has gone 83 -> 1 and a field that
resolved a name now does not. The merges between 54cd69c and c3c6526 that touch membership are
#38 and #79 (membershipPolicy invite-only). The cause was not traced — this card reports the
measurement and the interval, not a mechanism.

Why the #67 fix does not generalise

#67 stamps owner_name from sys_user.name because a platform reviewer already reads those same 12
names on ats_employer_member.display_name, so the mirror restates a fact rather than disclosing
one; the job-seeker set seals it for the audience that holds no such fact. Neither half of that
argument is available for ats_candidate.user or ats_interview.interviewers — there is no second
column already telling a platform reviewer those names. Mirroring them would be a new disclosure, so
the choice here is a real one: either a platform persona is allowed to resolve the users it already
governs, or these columns keep rendering ids.

Related: #67 (the one column with a mirror), #39, #30, #35.

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