Platform3 · people_and_orgs · alpha · data_dictionary

People & Orgs Alpha Data Dictionary

Field-level contract served verbatim from the tracked owning data dictionary JSON. Every value on this page is reflected mechanically from that source.

17 tables156 fieldsgenerated 2026-06-12T01:38:33Z

Contract overview

title
People & Orgs Alpha Data Dictionary
surface
alpha
module
people_and_orgs
deliverable
data_dictionary
generatedAt
2026-06-12T01:38:33Z
canonicalUrl
https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/data_dictionary/
architectureUrl
https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture
upstreamDictionaryUrl
https://platform3-andymontgomery-9773s-projects.vercel.app/oneroster/1edtech/data_dictionary
edFiDictionaryUrl
https://platform3-andymontgomery-9773s-projects.vercel.app/ed_fi/1edtech/data_dictionary
benchmarkUrl
https://platform3-24kpiksyo-andymontgomery-9773s-projects.vercel.app/data_dictionary
sourceSummary
Generated from the approved People & Orgs Alpha architecture alias map, the approved OneRoster and Ed-Fi 1EdTech data dictionaries, and the Wave 2 over-time/reality decision; #70 closed enums were validated against live TimeBack production source values.
audience
students, parents, teachers, and app-builder LLMs
moduleBoundary
Belongs here if it says who someone is and where they belong, as of a date.

Tables and fields

alpha.person · Person

objectName
person
apiCollection
/people
storage
Public view alpha.person joins alpha.person_base over oneroster.users to alpha.person_ext. Only admission_date, exit_date, age_grade, and reality live in alpha.person_ext; sourced OneRoster fields are never copied.
changeType
rename + extend
upstream
oneroster.users
primaryKey
(tenant_id, person_id)
purpose
One human in the roster: student, parent, guardian, guide, staff member, or administrator. A person's roles are dated memberships, not columns hidden inside the person row.
lifecycle
Created from the OneRoster user row or by an Alpha per-resource person command. Deleting a person is logical: keep the id for history, hide disallowed PII, and let memberships answer as-of-date questions.
auth
Ordinary roster scopes can read non-sensitive fields. Contact fields require role-scoped visibility. Sensitive demographics use alpha.person_sensitive_profile.
sourceType
1edtech_alias_view_with_extension_join
publicSurface
alpha.person
baseView
alpha.person_base
baseSource
oneroster.users
coreWriteRoute
Route sourced-field writes to the OneRoster 1EdTech users surface.
extensionWriteRoute
Write only admission_date, exit_date, age_grade, and reality to alpha.person_ext after the base person exists.
anchor
table-alpha-person
fieldCount
21
sourceAnchor
https://platform3-andymontgomery-9773s-projects.vercel.app/oneroster/1edtech/data_dictionary/#table-oneroster-users
filters
[
  "personId",
  "email",
  "isEnabled",
  "reality",
  "roleKind via membership",
  "placeId via membership",
  "schoolId via class_membership",
  "ageGrade",
  "gradeLevel",
  "modifiedSince"
]
sortKeys
[
  "last_name",
  "first_name",
  "person_id",
  "source_updated_at"
]
extensionTables
[
  "alpha.person_ext"
]
storageContract
{
  "alphaObject": "person",
  "publicSurface": "alpha.person",
  "upstreamModule": "oneroster/1edtech",
  "baseSource": "oneroster.users",
  "baseView": "alpha.person_base",
  "extensionTables": [
    "alpha.person_ext"
  ],
  "coreWriteRoute": "Route sourced-field writes to the OneRoster 1EdTech users surface.",
  "extensionWriteRoute": "Write only admission_date, exit_date, age_grade, and reality to alpha.person_ext after the base person exists.",
  "requiredShape": "CREATE VIEW over the OneRoster 1EdTech base; no Alpha table may store sourced OneRoster columns."
}
example
{
  "person_id": "person_ada_lovelace",
  "source_status": "active",
  "source_updated_at": "2026-08-15T13:45:30.000Z",
  "reality": "real",
  "is_enabled": true,
  "username": "ada.lovelace",
  "first_name": "Ada",
  "last_name": "Lovelace",
  "middle_name": "Byron",
  "preferred_first_name": "Ada",
  "preferred_last_name": "Lovelace",
  "email": "ada@example.edu",
  "sms": "+15550101010",
  "phone": "+15550101010",
  "family_or_agent_person_ids": [
    "person_grace_hopper"
  ],
  "grade_levels": [
    7
  ],
  "primary_place_id": "place_north_valley_school",
  "admission_date": "2025-08-18",
  "age_grade": 7,
  "exit_date": null
}

Fields (21)

tenant_id

title
Tenant Id
type
UUID
publicApi
Hidden in ordinary Alpha responses; selected from the verified JWT.
nullability
Required on every stored row.
required
Yes
range
Valid PostgreSQL UUID.
meaning
The tenant boundary that owns this People & Orgs row.
constraints
Must equal the verified JWT tenant_id or tenantId claim. Never accept a tenant header or body field as source of truth.
relationship
Belongs to one platform.tenant. One tenant owns many People & Orgs rows.
invalidWhen
Missing, malformed, points to another tenant, or is supplied by an unverified request body.
edgeCases
Demo token minting may accept tenantId=demo, but stored rows still use the resolved tenant id.
example
0d4ce2f4-1c42-4f3c-9f0d-03fb7f5271d3
pii
No
allowedValues
[]
provenance
{
  "changeType": "inherited",
  "sourceType": "platform_shared",
  "source": "platform.tenant",
  "sourceAnchor": null,
  "aliasMapField": null,
  "label": "Alpha inherited",
  "note": "Inherited platform tenant routing field, not a OneRoster alias.",
  "itds": [
    {
      "id": "paitd-109-tenant-routing",
      "title": "API Axis: Tenant Routing",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-109-tenant-routing"
    }
  ]
}
storage
{
  "kind": "platform_inherited_column",
  "source": "platform.tenant / verified JWT tenant claim",
  "storageRule": "Inherited platform tenant key. It scopes base rows, extension rows, and views; it is not copied from OneRoster or Ed-Fi.",
  "writeRoute": "Resolved from the verified JWT tenant claim by the platform layer."
}

person_id

title
Person Id
type
TEXT
publicApi
string
nullability
Required.
required
Yes
range
1 to 255 printable characters, unique within (tenant_id, alpha.person).
meaning
Stable TimeBack person id for one roster human.
constraints
Must remain stable across imports and writes. Use this id for relationships instead of parsing names or emails.
relationship
Referenced by place_membership.person_id, class_membership.person_id, person_sensitive_profile.person_id, app_credential.student_sourced_id, and app-visible relationship claims.
invalidWhen
Blank, reused for another person in the same tenant, changed to fix a display-name issue, or derived from email at read time.
edgeCases
A person may have no active membership as of a date; the identity still exists for historical references.
example
person_ada_lovelace
pii
Identifier
allowedValues
[]
provenance
{
  "changeType": "rename",
  "sourceType": "1edtech_alias",
  "source": "oneroster.users.sourced_id",
  "sourceAnchor": "https://platform3-andymontgomery-9773s-projects.vercel.app/oneroster/1edtech/data_dictionary/#field-oneroster-users-sourced-id",
  "aliasMapField": "person.person_id",
  "label": "Alpha rename",
  "note": "Tenant-scoped person id.",
  "itds": [
    {
      "id": "paitd-002-person-vocabulary",
      "title": "Person Is The Plain Alias For OneRoster User",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-002-person-vocabulary"
    },
    {
      "id": "paitd-010-alias-map-contract",
      "title": "Alias Map Is A Generated Architecture Artifact",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-010-alias-map-contract"
    }
  ]
}
storage
{
  "kind": "oneedtech_view_column",
  "source": "oneroster.users.sourced_id",
  "storageRule": "Selected by alpha.person_base from oneroster.users; public alpha.person does not store a copy of this 1EdTech field.",
  "writeRoute": "Route sourced-field writes to the OneRoster 1EdTech users surface."
}

source_status

title
Source Status
type
TEXT enum
publicApi
string enum
nullability
Nullable in bulk-origin rows; required when the source sends delta status.
required
Conditional
range
active or tobedeleted.
meaning
OneRoster lifecycle marker preserved for provenance.
constraints
Do not use this as the active-as-of answer. Membership dates answer that question.
relationship
No direct foreign key.
invalidWhen
Any value other than active or tobedeleted, or using tobedeleted to erase historical Results, Events, or memberships.
edgeCases
Bulk OneRoster rows intentionally omit status; Alpha may show null rather than inventing active.
example
active
pii
No
allowedValues
[
  {
    "value": "active",
    "meaning": "The delta row is current and should be inserted or updated.",
    "useWhen": "Use only in delta row status fields. Alpha keeps this only as source provenance; ordinary active-as-of queries still use dated memberships.",
    "invalidWhen": "Invalid in bulk rows or when the row should be deleted."
  },
  {
    "value": "tobedeleted",
    "meaning": "The delta row indicates the source wants this object deleted or retired.",
    "useWhen": "Use only in delta row status fields. Alpha keeps this only as source provenance; ordinary active-as-of queries still use dated memberships.",
    "invalidWhen": "Invalid in bulk rows or when the source object remains active."
  }
]
provenance
{
  "changeType": "rename",
  "sourceType": "1edtech_alias",
  "source": "oneroster.users.status",
  "sourceAnchor": "https://platform3-andymontgomery-9773s-projects.vercel.app/oneroster/1edtech/data_dictionary/#field-oneroster-users-status",
  "aliasMapField": "person.source_status",
  "label": "Alpha rename",
  "note": "OneRoster lifecycle state, preserved for provenance.",
  "itds": [
    {
      "id": "paitd-002-person-vocabulary",
      "title": "Person Is The Plain Alias For OneRoster User",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-002-person-vocabulary"
    },
    {
      "id": "paitd-111-privacy-retention",
      "title": "API Axis: Privacy / Retention",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-111-privacy-retention"
    }
  ]
}
storage
{
  "kind": "oneedtech_view_column",
  "source": "oneroster.users.status",
  "storageRule": "Selected by alpha.person_base from oneroster.users; public alpha.person does not store a copy of this 1EdTech field.",
  "writeRoute": "Route sourced-field writes to the OneRoster 1EdTech users surface."
}

source_updated_at

title
Source Updated At
type
TIMESTAMPTZ
publicApi
ISO 8601 datetime
nullability
Nullable in bulk-origin rows; required when the source sends delta status.
required
Conditional
range
ISO 8601 UTC datetime.
meaning
Source-system modified timestamp for modifiedSince scans.
constraints
Must be parsed and stored as a timestamp. Do not parse display text at read time.
relationship
Used by modifiedSince list scans for source-origin rows.
invalidWhen
Malformed timestamp, supplied in bulk mode when source contract forbids it, or older than the previous accepted delta for the same source row.
edgeCases
Per-resource Alpha writes may also update platform updated_at; the endpoint documents which clock powers modifiedSince.
example
2026-08-15T13:45:30.000Z
pii
No
allowedValues
[]
provenance
{
  "changeType": "rename",
  "sourceType": "1edtech_alias",
  "source": "oneroster.users.date_last_modified",
  "sourceAnchor": "https://platform3-andymontgomery-9773s-projects.vercel.app/oneroster/1edtech/data_dictionary/#field-oneroster-users-date-last-modified",
  "aliasMapField": "person.source_updated_at",
  "label": "Alpha rename",
  "note": "Source-system modified timestamp for delta rows.",
  "itds": [
    {
      "id": "paitd-002-person-vocabulary",
      "title": "Person Is The Plain Alias For OneRoster User",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-002-person-vocabulary"
    },
    {
      "id": "paitd-103-query-model",
      "title": "API Axis: Query Model",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-103-query-model"
    }
  ]
}
storage
{
  "kind": "oneedtech_view_column",
  "source": "oneroster.users.date_last_modified",
  "storageRule": "Selected by alpha.person_base from oneroster.users; public alpha.person does not store a copy of this 1EdTech field.",
  "writeRoute": "Route sourced-field writes to the OneRoster 1EdTech users surface."
}

reality

title
Reality
type
TEXT enum
publicApi
real | test | synthetic
nullability
Required for reportable person rows after the PAITD-017 write boundary; historical pre-backfill rows fail report reads until classified.
required
Yes
range
Closed values: real, test, synthetic.
meaning
Typed reality classification for this person. Ordinary reports default to reality=real so test and synthetic people never enter customer answers.
constraints
Set at write time from authoritative SIS or TimeBack source classification. Never infer from name, email, campus, username, or an exclude-list in a consumer.
relationship
No foreign key; it is a first-class filter on person and must agree with joined place reality for school reports.
invalidWhen
Missing on a reportable person, any value outside real/test/synthetic, inferred by string matching, or omitted from a real-student report query.
edgeCases
A test user can have valid memberships and still be excluded from default reports because reality is not real.
example
real
pii
No
allowedValues
[
  {
    "value": "real",
    "meaning": "A production student, person, school, district, or roster place that belongs in ordinary customer reports.",
    "useWhen": "Use for real TimeBack people and places after the write boundary has verified the source classification.",
    "invalidWhen": "Invalid for QA accounts, AI-agent test rows, generated fixtures, or demo-only entities."
  },
  {
    "value": "test",
    "meaning": "A QA, staff-test, integration-test, or AI-agent test entity that must be excluded from ordinary reports.",
    "useWhen": "Use for entities intentionally created to test the surface or another app.",
    "invalidWhen": "Invalid for production students or schools even if their display name looks unusual."
  },
  {
    "value": "synthetic",
    "meaning": "Generated, seeded, anonymized, or fixture data that is useful for demos or development but not a real customer row.",
    "useWhen": "Use for generated seed rows, local fixtures, and anonymized examples.",
    "invalidWhen": "Invalid for a row imported from the authoritative SIS or TimeBack production source as a real entity."
  }
]
provenance
{
  "changeType": "extend",
  "sourceType": "alpha_extend_table",
  "source": "alpha.person_ext.reality",
  "sourceAnchor": null,
  "aliasMapField": "person.reality",
  "label": "Alpha extend",
  "note": "PAITD-017 reality decision: first-class Alpha extension field on person.",
  "itds": [
    {
      "id": "paitd-017-reality-flag",
      "title": "Reality Is A Typed Closed Flag On Person And Place, Set At Write Time",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-017-reality-flag"
    },
    {
      "id": "paitd-103-query-model",
      "title": "API Axis: Query Model",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-103-query-model"
    },
    {
      "id": "paitd-111-privacy-retention",
      "title": "API Axis: Privacy / Retention",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-111-privacy-retention"
    },
    {
      "id": "paitd-011-storage-model",
      "title": "Alpha Storage Is Views Over OneRoster Plus Extension Tables",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-011-storage-model"
    }
  ]
}
storage
{
  "kind": "alpha_extend_table",
  "source": "alpha.person_ext.reality",
  "storageRule": "Stored only in alpha.person_ext; allowed because real/test/synthetic classification is an Alpha reporting guardrail, not a OneRoster field copy.",
  "writeRoute": "Write through the Alpha person extension path from authoritative source classification; never infer from names, emails, or campus labels."
}

is_enabled

title
Is Enabled
type
BOOLEAN
publicApi
boolean
nullability
Required.
required
Yes
range
true or false.
meaning
Whether the source system says this person's account is enabled.
constraints
Store as a boolean, not text. It does not delete the person or erase history.
relationship
May be used by auth and roster UIs, but it is not a membership relationship.
invalidWhen
Missing, not boolean, or used to cascade-delete results, events, memberships, or credentials.
edgeCases
A disabled person can still appear in historical membership and Results records.
example
true
pii
No
allowedValues
[
  {
    "value": "true",
    "meaning": "The fact is asserted by the source or by the Alpha surface.",
    "useWhen": "Use only when the field's own constraints say the fact is true.",
    "invalidWhen": "Invalid when guessed from names, labels, dates, tags, or another field."
  },
  {
    "value": "false",
    "meaning": "The fact is explicitly not asserted.",
    "useWhen": "Use only when the source or surface stores an explicit false value.",
    "invalidWhen": "Invalid when a missing value should remain unknown."
  }
]
provenance
{
  "changeType": "rename",
  "sourceType": "1edtech_alias",
  "source": "oneroster.users.enabled_user",
  "sourceAnchor": "https://platform3-andymontgomery-9773s-projects.vercel.app/oneroster/1edtech/data_dictionary/#field-oneroster-users-enabled-user",
  "aliasMapField": "person.is_enabled",
  "label": "Alpha rename",
  "note": "Whether the source system says the account is enabled.",
  "itds": [
    {
      "id": "paitd-002-person-vocabulary",
      "title": "Person Is The Plain Alias For OneRoster User",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-002-person-vocabulary"
    }
  ]
}
storage
{
  "kind": "oneedtech_view_column",
  "source": "oneroster.users.enabled_user",
  "storageRule": "Selected by alpha.person_base from oneroster.users; public alpha.person does not store a copy of this 1EdTech field.",
  "writeRoute": "Route sourced-field writes to the OneRoster 1EdTech users surface."
}

username

title
Username
type
TEXT
publicApi
string
nullability
Required by OneRoster source; may be hidden by auth policy.
required
Yes
range
1 to 255 visible characters. It is not a password.
meaning
Roster username for the person.
constraints
Treat as credential-adjacent PII. Never store or return a password in this field.
relationship
No relationship. Use person_id for joins.
invalidWhen
Blank, used as the primary key, logged in public evidence, or mixed with password/secret values.
edgeCases
Some source systems use email-like usernames; visibility still follows privacy policy.
example
ada.lovelace
pii
Credential-adjacent
allowedValues
[]
provenance
{
  "changeType": "rename",
  "sourceType": "1edtech_alias",
  "source": "oneroster.users.username",
  "sourceAnchor": "https://platform3-andymontgomery-9773s-projects.vercel.app/oneroster/1edtech/data_dictionary/#field-oneroster-users-username",
  "aliasMapField": "person.username",
  "label": "Alpha rename",
  "note": "Roster username, never a password.",
  "itds": [
    {
      "id": "paitd-002-person-vocabulary",
      "title": "Person Is The Plain Alias For OneRoster User",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-002-person-vocabulary"
    },
    {
      "id": "paitd-009-sensitive-profile-privacy",
      "title": "Sensitive Profiles Are Restricted, Not Default Roster Fields",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-009-sensitive-profile-privacy"
    }
  ]
}
storage
{
  "kind": "oneedtech_view_column",
  "source": "oneroster.users.username",
  "storageRule": "Selected by alpha.person_base from oneroster.users; public alpha.person does not store a copy of this 1EdTech field.",
  "writeRoute": "Route sourced-field writes to the OneRoster 1EdTech users surface."
}

first_name

title
First Name
type
TEXT
publicApi
string
nullability
Required.
required
Yes
range
1 to 200 visible characters.
meaning
Legal or source first name.
constraints
Store what the source supplies; do not infer roles, grade, sex, or ethnicity from names.
relationship
No relationship. Use person_id for joins.
invalidWhen
Blank, over range, contains control characters, or used as an identifier.
edgeCases
Preferred names are separate fields so legal/source names remain traceable.
example
Ada
pii
Yes
allowedValues
[]
provenance
{
  "changeType": "rename",
  "sourceType": "1edtech_alias",
  "source": "oneroster.users.given_name",
  "sourceAnchor": "https://platform3-andymontgomery-9773s-projects.vercel.app/oneroster/1edtech/data_dictionary/#field-oneroster-users-given-name",
  "aliasMapField": "person.first_name",
  "label": "Alpha rename",
  "note": "Legal or source first name.",
  "itds": [
    {
      "id": "paitd-002-person-vocabulary",
      "title": "Person Is The Plain Alias For OneRoster User",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-002-person-vocabulary"
    }
  ]
}
storage
{
  "kind": "oneedtech_view_column",
  "source": "oneroster.users.given_name",
  "storageRule": "Selected by alpha.person_base from oneroster.users; public alpha.person does not store a copy of this 1EdTech field.",
  "writeRoute": "Route sourced-field writes to the OneRoster 1EdTech users surface."
}

last_name

title
Last Name
type
TEXT
publicApi
string
nullability
Required.
required
Yes
range
1 to 200 visible characters.
meaning
Legal or source family name.
constraints
Store what the source supplies; do not sort by parsed particles unless the source writes a separate typed field.
relationship
No relationship. Use person_id for joins.
invalidWhen
Blank, over range, contains control characters, or used as an identifier.
edgeCases
Display ordering is a UI concern; the stored field remains the source family name.
example
Lovelace
pii
Yes
allowedValues
[]
provenance
{
  "changeType": "rename",
  "sourceType": "1edtech_alias",
  "source": "oneroster.users.family_name",
  "sourceAnchor": "https://platform3-andymontgomery-9773s-projects.vercel.app/oneroster/1edtech/data_dictionary/#field-oneroster-users-family-name",
  "aliasMapField": "person.last_name",
  "label": "Alpha rename",
  "note": "Legal or source family name.",
  "itds": [
    {
      "id": "paitd-002-person-vocabulary",
      "title": "Person Is The Plain Alias For OneRoster User",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-002-person-vocabulary"
    }
  ]
}
storage
{
  "kind": "oneedtech_view_column",
  "source": "oneroster.users.family_name",
  "storageRule": "Selected by alpha.person_base from oneroster.users; public alpha.person does not store a copy of this 1EdTech field.",
  "writeRoute": "Route sourced-field writes to the OneRoster 1EdTech users surface."
}

middle_name

title
Middle Name
type
TEXT
publicApi
string
nullability
Optional.
required
No
range
0 to 200 visible characters.
meaning
Legal or source middle name.
constraints
Optional. Preserve source spelling when supplied.
relationship
No relationship.
invalidWhen
Over range, contains control characters, or used for identity matching.
edgeCases
Multiple middle names may be space-separated by the source.
example
Byron
pii
Yes
allowedValues
[]
provenance
{
  "changeType": "rename",
  "sourceType": "1edtech_alias",
  "source": "oneroster.users.middle_name",
  "sourceAnchor": "https://platform3-andymontgomery-9773s-projects.vercel.app/oneroster/1edtech/data_dictionary/#field-oneroster-users-middle-name",
  "aliasMapField": "person.middle_name",
  "label": "Alpha rename",
  "note": "Legal or source middle name.",
  "itds": [
    {
      "id": "paitd-002-person-vocabulary",
      "title": "Person Is The Plain Alias For OneRoster User",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-002-person-vocabulary"
    }
  ]
}
storage
{
  "kind": "oneedtech_view_column",
  "source": "oneroster.users.middle_name",
  "storageRule": "Selected by alpha.person_base from oneroster.users; public alpha.person does not store a copy of this 1EdTech field.",
  "writeRoute": "Route sourced-field writes to the OneRoster 1EdTech users surface."
}

preferred_first_name

title
Preferred First Name
type
TEXT
publicApi
string
nullability
Optional.
required
No
range
0 to 200 visible characters.
meaning
Preferred first name.
constraints
Store separately from first_name; do not overwrite legal/source name.
relationship
No relationship.
invalidWhen
Over range, contains control characters, or used to infer any protected attribute.
edgeCases
Null means no source value, not that the preferred name equals first_name.
example
Ada
pii
Yes
allowedValues
[]
provenance
{
  "changeType": "rename",
  "sourceType": "1edtech_alias",
  "source": "oneroster.users.preferred_given_name",
  "sourceAnchor": "https://platform3-andymontgomery-9773s-projects.vercel.app/oneroster/1edtech/data_dictionary/#field-oneroster-users-preferred-given-name",
  "aliasMapField": "person.preferred_first_name",
  "label": "Alpha rename",
  "note": "Preferred first name.",
  "itds": [
    {
      "id": "paitd-002-person-vocabulary",
      "title": "Person Is The Plain Alias For OneRoster User",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-002-person-vocabulary"
    }
  ]
}
storage
{
  "kind": "oneedtech_view_column",
  "source": "oneroster.users.preferred_given_name",
  "storageRule": "Selected by alpha.person_base from oneroster.users; public alpha.person does not store a copy of this 1EdTech field.",
  "writeRoute": "Route sourced-field writes to the OneRoster 1EdTech users surface."
}

preferred_last_name

title
Preferred Last Name
type
TEXT
publicApi
string
nullability
Optional.
required
No
range
0 to 200 visible characters.
meaning
Preferred family name.
constraints
Store separately from last_name; do not overwrite legal/source name.
relationship
No relationship.
invalidWhen
Over range, contains control characters, or used to infer any protected attribute.
edgeCases
Null means no source value, not that the preferred name equals last_name.
example
Lovelace
pii
Yes
allowedValues
[]
provenance
{
  "changeType": "rename",
  "sourceType": "1edtech_alias",
  "source": "oneroster.users.preferred_family_name",
  "sourceAnchor": "https://platform3-andymontgomery-9773s-projects.vercel.app/oneroster/1edtech/data_dictionary/#field-oneroster-users-preferred-family-name",
  "aliasMapField": "person.preferred_last_name",
  "label": "Alpha rename",
  "note": "Preferred last name.",
  "itds": [
    {
      "id": "paitd-002-person-vocabulary",
      "title": "Person Is The Plain Alias For OneRoster User",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-002-person-vocabulary"
    }
  ]
}
storage
{
  "kind": "oneedtech_view_column",
  "source": "oneroster.users.preferred_family_name",
  "storageRule": "Selected by alpha.person_base from oneroster.users; public alpha.person does not store a copy of this 1EdTech field.",
  "writeRoute": "Route sourced-field writes to the OneRoster 1EdTech users surface."
}

email

title
Email
type
TEXT
publicApi
email string
nullability
Optional.
required
No
range
0 to 320 characters, parseable as email when supplied.
meaning
Contact email visible only to scopes allowed for this relationship.
constraints
Do not use as primary key; email can change and may be shared in family contexts.
relationship
No relationship. Use person_id for joins.
invalidWhen
Malformed, used for tenant routing, exposed without role-scoped authorization, or used to infer identity when person_id is present.
edgeCases
Some students may not have email; parent/guardian contact visibility depends on agentOf and scope claims.
example
ada@example.edu
pii
Yes
allowedValues
[]
provenance
{
  "changeType": "rename",
  "sourceType": "1edtech_alias",
  "source": "oneroster.users.email",
  "sourceAnchor": "https://platform3-andymontgomery-9773s-projects.vercel.app/oneroster/1edtech/data_dictionary/#field-oneroster-users-email",
  "aliasMapField": "person.email",
  "label": "Alpha rename",
  "note": "Contact email, subject to role-scoped privacy rules.",
  "itds": [
    {
      "id": "paitd-002-person-vocabulary",
      "title": "Person Is The Plain Alias For OneRoster User",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-002-person-vocabulary"
    },
    {
      "id": "paitd-009-sensitive-profile-privacy",
      "title": "Sensitive Profiles Are Restricted, Not Default Roster Fields",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-009-sensitive-profile-privacy"
    }
  ]
}
storage
{
  "kind": "oneedtech_view_column",
  "source": "oneroster.users.email",
  "storageRule": "Selected by alpha.person_base from oneroster.users; public alpha.person does not store a copy of this 1EdTech field.",
  "writeRoute": "Route sourced-field writes to the OneRoster 1EdTech users surface."
}

sms

title
Sms
type
TEXT
publicApi
string
nullability
Optional.
required
No
range
0 to 80 visible characters.
meaning
SMS contact address supplied by the source.
constraints
Treat as contact PII and normalize only at write time if the profile defines a canonical format.
relationship
No relationship.
invalidWhen
Used for authorization, logged in public evidence, or guessed from phone.
edgeCases
May be blank even when phone is present.
example
+15550101010
pii
Yes
allowedValues
[]
provenance
{
  "changeType": "rename",
  "sourceType": "1edtech_alias",
  "source": "oneroster.users.sms",
  "sourceAnchor": "https://platform3-andymontgomery-9773s-projects.vercel.app/oneroster/1edtech/data_dictionary/#field-oneroster-users-sms",
  "aliasMapField": "person.sms",
  "label": "Alpha rename",
  "note": "SMS contact address.",
  "itds": [
    {
      "id": "paitd-002-person-vocabulary",
      "title": "Person Is The Plain Alias For OneRoster User",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-002-person-vocabulary"
    },
    {
      "id": "paitd-009-sensitive-profile-privacy",
      "title": "Sensitive Profiles Are Restricted, Not Default Roster Fields",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-009-sensitive-profile-privacy"
    }
  ]
}
storage
{
  "kind": "oneedtech_view_column",
  "source": "oneroster.users.sms",
  "storageRule": "Selected by alpha.person_base from oneroster.users; public alpha.person does not store a copy of this 1EdTech field.",
  "writeRoute": "Route sourced-field writes to the OneRoster 1EdTech users surface."
}

phone

title
Phone
type
TEXT
publicApi
string
nullability
Optional.
required
No
range
0 to 80 visible characters.
meaning
Phone contact supplied by the source.
constraints
Treat as contact PII and normalize only at write time if the profile defines a canonical format.
relationship
No relationship.
invalidWhen
Used for authorization, logged in public evidence, or guessed from sms.
edgeCases
May be blank even when sms is present.
example
+15550101010
pii
Yes
allowedValues
[]
provenance
{
  "changeType": "rename",
  "sourceType": "1edtech_alias",
  "source": "oneroster.users.phone",
  "sourceAnchor": "https://platform3-andymontgomery-9773s-projects.vercel.app/oneroster/1edtech/data_dictionary/#field-oneroster-users-phone",
  "aliasMapField": "person.phone",
  "label": "Alpha rename",
  "note": "Phone contact.",
  "itds": [
    {
      "id": "paitd-002-person-vocabulary",
      "title": "Person Is The Plain Alias For OneRoster User",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-002-person-vocabulary"
    },
    {
      "id": "paitd-009-sensitive-profile-privacy",
      "title": "Sensitive Profiles Are Restricted, Not Default Roster Fields",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-009-sensitive-profile-privacy"
    }
  ]
}
storage
{
  "kind": "oneedtech_view_column",
  "source": "oneroster.users.phone",
  "storageRule": "Selected by alpha.person_base from oneroster.users; public alpha.person does not store a copy of this 1EdTech field.",
  "writeRoute": "Route sourced-field writes to the OneRoster 1EdTech users surface."
}

family_or_agent_person_ids

title
Family Or Agent Person Ids
type
TEXT[]
publicApi
array of person ids
nullability
Optional; empty array means no source relationship in this field.
required
No
range
Each id is 1 to 255 printable characters and must reference a person in the same tenant when supplied.
meaning
Explicit OneRoster agent relationships such as parent or guardian links.
constraints
Relationships are real ids, never tags. The target person must exist in the same tenant.
relationship
Many-to-many person relationship folded from OneRoster agent_sourced_ids. A person can list many family/agent people.
invalidWhen
Contains an id missing from alpha.person, references another tenant, or is replaced by a free-form tag.
edgeCases
Membership role_kind still states what the family/agent is; this field only links people.
pii
Identifier
example
[
  "person_grace_hopper"
]
allowedValues
[]
provenance
{
  "changeType": "rename",
  "sourceType": "1edtech_alias",
  "source": "oneroster.users.agent_sourced_ids",
  "sourceAnchor": "https://platform3-andymontgomery-9773s-projects.vercel.app/oneroster/1edtech/data_dictionary/#field-oneroster-users-agent-sourced-ids",
  "aliasMapField": "person.family_or_agent_person_ids",
  "label": "Alpha rename",
  "note": "Explicit OneRoster agent relationships such as parent or guardian links.",
  "itds": [
    {
      "id": "paitd-002-person-vocabulary",
      "title": "Person Is The Plain Alias For OneRoster User",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-002-person-vocabulary"
    },
    {
      "id": "paitd-006-tag-registry",
      "title": "Governed Tags Are Report Slices Only",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-006-tag-registry"
    }
  ]
}
storage
{
  "kind": "oneedtech_view_column",
  "source": "oneroster.users.agent_sourced_ids",
  "storageRule": "Selected by alpha.person_base from oneroster.users; public alpha.person does not store a copy of this 1EdTech field.",
  "writeRoute": "Route sourced-field writes to the OneRoster 1EdTech users surface."
}

grade_levels

title
Grade Levels
type
INTEGER[] closed enum
publicApi
array of grade_level integers
nullability
Optional.
required
No
range
Closed grade_level values: -1 for PreK, 0 for K, and 1 through 12. Live aliases PK->-1, K->0, 4TH_GRADE/Grade_4->4 fold at write time.
meaning
Source grade values folded to the Alpha grade_level closed enum at write time.
constraints
Do not parse grades from class names or test titles. Write boundary canonicalizes source aliases into integer grade_level values and rejects unreconciled values such as observed source grade 13.
relationship
No relationship; student Results and working grade live in Results.
invalidWhen
Parsed from a title, used as mastery, mixed with age_grade without alias-fold evidence, left as unknown free text, or includes a value outside -1, 0, and 1..12.
edgeCases
A multi-grade student may have multiple grade_levels; age_grade is the single age-grade context when present. Production validation on 2026-06-09 found source grade 13 on 112 rows; that is a reconciliation finding, not a canonical value.
pii
Yes
example
[
  7
]
allowedValues
[
  {
    "value": "-1",
    "meaning": "PreK. Live source aliases validated 2026-06-09: -1 and PK fold here.",
    "useWhen": "Use for pre-kindergarten age-grade or enrolled-grade context.",
    "invalidWhen": "Invalid for kindergarten or any student grade 1 through 12."
  },
  {
    "value": "0",
    "meaning": "Kindergarten. Live source aliases validated 2026-06-09: 0 and K fold here.",
    "useWhen": "Use for kindergarten age-grade or enrolled-grade context.",
    "invalidWhen": "Invalid for PreK or any numbered grade."
  },
  {
    "value": "1",
    "meaning": "Grade 1.",
    "useWhen": "Use for grade 1 age-grade, enrolled-grade, or course grade-level context.",
    "invalidWhen": "Invalid when parsed from names, class titles, test labels, or free text at read time."
  },
  {
    "value": "2",
    "meaning": "Grade 2.",
    "useWhen": "Use for grade 2 age-grade, enrolled-grade, or course grade-level context.",
    "invalidWhen": "Invalid when parsed from names, class titles, test labels, or free text at read time."
  },
  {
    "value": "3",
    "meaning": "Grade 3.",
    "useWhen": "Use for grade 3 age-grade, enrolled-grade, or course grade-level context.",
    "invalidWhen": "Invalid when parsed from names, class titles, test labels, or free text at read time."
  },
  {
    "value": "4",
    "meaning": "Grade 4. Live source aliases validated 2026-06-09: 4, 4TH_GRADE, and Grade_4 fold here.",
    "useWhen": "Use for grade 4 age-grade, enrolled-grade, or course grade-level context.",
    "invalidWhen": "Invalid when parsed from names, class titles, test labels, or free text at read time."
  },
  {
    "value": "5",
    "meaning": "Grade 5.",
    "useWhen": "Use for grade 5 age-grade, enrolled-grade, or course grade-level context.",
    "invalidWhen": "Invalid when parsed from names, class titles, test labels, or free text at read time."
  },
  {
    "value": "6",
    "meaning": "Grade 6.",
    "useWhen": "Use for grade 6 age-grade, enrolled-grade, or course grade-level context.",
    "invalidWhen": "Invalid when parsed from names, class titles, test labels, or free text at read time."
  },
  {
    "value": "7",
    "meaning": "Grade 7.",
    "useWhen": "Use for grade 7 age-grade, enrolled-grade, or course grade-level context.",
    "invalidWhen": "Invalid when parsed from names, class titles, test labels, or free text at read time."
  },
  {
    "value": "8",
    "meaning": "Grade 8.",
    "useWhen": "Use for grade 8 age-grade, enrolled-grade, or course grade-level context.",
    "invalidWhen": "Invalid when parsed from names, class titles, test labels, or free text at read time."
  },
  {
    "value": "9",
    "meaning": "Grade 9.",
    "useWhen": "Use for grade 9 age-grade, enrolled-grade, or course grade-level context.",
    "invalidWhen": "Invalid when parsed from names, class titles, test labels, or free text at read time."
  },
  {
    "value": "10",
    "meaning": "Grade 10.",
    "useWhen": "Use for grade 10 age-grade, enrolled-grade, or course grade-level context.",
    "invalidWhen": "Invalid when parsed from names, class titles, test labels, or free text at read time."
  },
  {
    "value": "11",
    "meaning": "Grade 11.",
    "useWhen": "Use for grade 11 age-grade, enrolled-grade, or course grade-level context.",
    "invalidWhen": "Invalid when parsed from names, class titles, test labels, or free text at read time."
  },
  {
    "value": "12",
    "meaning": "Grade 12.",
    "useWhen": "Use for grade 12 age-grade, enrolled-grade, or course grade-level context.",
    "invalidWhen": "Invalid when parsed from names, class titles, test labels, or free text at read time."
  }
]
provenance
{
  "changeType": "rename+restrict",
  "sourceType": "1edtech_alias",
  "source": "oneroster.users.grades",
  "sourceAnchor": "https://platform3-andymontgomery-9773s-projects.vercel.app/oneroster/1edtech/data_dictionary/#field-oneroster-users-grades",
  "aliasMapField": "person.grade_levels",
  "label": "Alpha rename+restrict",
  "note": "Source grade values folded to the Alpha canonical grade vocabulary at write time.",
  "itds": [
    {
      "id": "paitd-002-person-vocabulary",
      "title": "Person Is The Plain Alias For OneRoster User",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-002-person-vocabulary"
    },
    {
      "id": "paitd-007-tenure-and-grade-context",
      "title": "Tenure And Grade Context Are Typed Inputs, Not Dashboard Math",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-007-tenure-and-grade-context"
    }
  ]
}
storage
{
  "kind": "oneedtech_view_column",
  "source": "oneroster.users.grades",
  "storageRule": "Selected by alpha.person_base from oneroster.users; public alpha.person does not store a copy of this 1EdTech field.",
  "writeRoute": "Route sourced-field writes to the OneRoster 1EdTech users surface."
}

primary_place_id

title
Primary Place Id
type
TEXT
publicApi
place id
nullability
Optional.
required
No
range
1 to 255 printable characters when supplied.
meaning
Source primary organization for the person, expressed as an Alpha place id.
constraints
Must reference alpha.place.place_id in the same tenant when supplied. It is a relationship column, never a tag.
relationship
Optionally references one alpha.place. Many people can share a primary place.
invalidWhen
Referenced place is missing, belongs to another tenant, or is stored only as a tag.
edgeCases
Point-in-time membership still determines active belonging; this is a source primary hint.
example
place_north_valley_school
pii
Identifier
allowedValues
[]
provenance
{
  "changeType": "rename",
  "sourceType": "1edtech_alias",
  "source": "oneroster.users.primary_org_sourced_id",
  "sourceAnchor": "https://platform3-andymontgomery-9773s-projects.vercel.app/oneroster/1edtech/data_dictionary/#field-oneroster-users-primary-org-sourced-id",
  "aliasMapField": "person.primary_place_id",
  "label": "Alpha rename",
  "note": "Source primary organization for the person.",
  "itds": [
    {
      "id": "paitd-002-person-vocabulary",
      "title": "Person Is The Plain Alias For OneRoster User",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-002-person-vocabulary"
    },
    {
      "id": "paitd-006-tag-registry",
      "title": "Governed Tags Are Report Slices Only",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-006-tag-registry"
    }
  ]
}
storage
{
  "kind": "oneedtech_view_column",
  "source": "oneroster.users.primary_org_sourced_id",
  "storageRule": "Selected by alpha.person_base from oneroster.users; public alpha.person does not store a copy of this 1EdTech field.",
  "writeRoute": "Route sourced-field writes to the OneRoster 1EdTech users surface."
}

admission_date

title
Admission Date
type
DATE
publicApi
date
nullability
Optional except where student-tenure reports require it.
required
Conditional
range
ISO 8601 date YYYY-MM-DD.
meaning
Date the student joined the school or program for tenure calculations.
constraints
Set at write time. Tenure bucket is computed by the surface from this date and asOfDate using alpha.policy.tenure_buckets.
relationship
No foreign key; consumed by surface policy computation.
invalidWhen
Parsed from a cohort name, later than asOfDate for a current-tenure request, or hardcoded into a dashboard.
edgeCases
A non-student person may have null admission_date. Null admission_date means tenure is unknown, not zero.
example
2025-08-18
pii
Yes
allowedValues
[]
provenance
{
  "changeType": "extend",
  "sourceType": "alpha_extend_table",
  "source": "alpha.person_ext.admission_date",
  "sourceAnchor": null,
  "aliasMapField": "person.admission_date",
  "label": "Alpha extend",
  "note": "Alpha extension required for tenure bands.",
  "itds": [
    {
      "id": "paitd-007-tenure-and-grade-context",
      "title": "Tenure And Grade Context Are Typed Inputs, Not Dashboard Math",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-007-tenure-and-grade-context"
    }
  ]
}
storage
{
  "kind": "alpha_extend_table",
  "source": "alpha.person_ext.admission_date",
  "storageRule": "Stored only in alpha.person_ext.admission_date; allowed because it is a true Alpha extension and not a copied 1EdTech field.",
  "writeRoute": "Write only admission_date, exit_date, age_grade, and reality to alpha.person_ext after the base person exists."
}

exit_date

title
Admission Date
type
DATE
publicApi
date
nullability
Optional except where student-tenure reports require it.
required
Conditional
range
ISO 8601 date YYYY-MM-DD.
meaning
Exclusive date the person stopped being admitted/enrolled in the school or program. Null means the person lifecycle remains open after admission_date.
constraints
Set at write time. Tenure bucket is computed by the surface from this date and asOfDate using alpha.policy.tenure_buckets.
relationship
No foreign key; consumed by lifecycle and tenure policy checks. Membership begin_date/end_date rows remain separate relationship intervals.
invalidWhen
Parsed from a cohort name, later than asOfDate for a current-tenure request, or hardcoded into a dashboard.
edgeCases
Do not derive exit_date from place_membership.end_date or class_membership.end_date; a person can change memberships without exiting the school/program. Null means no known person-level exit date, not a membership interval.
example
2025-08-18
pii
Yes
allowedValues
[]
provenance
{
  "changeType": "extend",
  "sourceType": "alpha_extend_table",
  "source": "alpha.person_ext.admission_date",
  "sourceAnchor": null,
  "aliasMapField": "person.admission_date",
  "label": "Alpha extend",
  "note": "Alpha extension required for tenure bands.",
  "itds": [
    {
      "id": "paitd-007-tenure-and-grade-context",
      "title": "Tenure And Grade Context Are Typed Inputs, Not Dashboard Math",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-007-tenure-and-grade-context"
    }
  ]
}
storage
{
  "kind": "alpha_extend_table",
  "source": "alpha.person_ext.exit_date",
  "storageRule": "Stored only in alpha.person_ext.exit_date; allowed because it is a true Alpha person-lifecycle extension and not a copied 1EdTech field.",
  "writeRoute": "Write only admission_date, exit_date, age_grade, and reality to alpha.person_ext after the base person exists."
}

age_grade

title
Age Grade
type
INTEGER closed enum
publicApi
grade_level integer
nullability
Optional except where age-grade cohort reports require it.
required
Conditional
range
Closed grade_level values: -1 for PreK, 0 for K, and 1 through 12.
meaning
Canonical age-grade context folded at write time from source grade aliases.
constraints
Never parse age_grade from a test name, class name, or display string. Alias folds are maintained by the surface and the canonical value is the grade_level integer.
relationship
No foreign key; Results owns working grade and advancement.
invalidWhen
Free text, parsed at read time, used as working grade/mastery, or outside -1, 0, and 1..12.
edgeCases
age_grade can differ from Results working grade; that difference is expected for advanced or remediating students. Source grade 13 is a live reconciliation finding and is not accepted as age_grade. Historical age-grade reads use alpha.age_grade_history.
example
7
pii
Yes
allowedValues
[
  {
    "value": "-1",
    "meaning": "PreK. Live source aliases validated 2026-06-09: -1 and PK fold here.",
    "useWhen": "Use for pre-kindergarten age-grade or enrolled-grade context.",
    "invalidWhen": "Invalid for kindergarten or any student grade 1 through 12."
  },
  {
    "value": "0",
    "meaning": "Kindergarten. Live source aliases validated 2026-06-09: 0 and K fold here.",
    "useWhen": "Use for kindergarten age-grade or enrolled-grade context.",
    "invalidWhen": "Invalid for PreK or any numbered grade."
  },
  {
    "value": "1",
    "meaning": "Grade 1.",
    "useWhen": "Use for grade 1 age-grade, enrolled-grade, or course grade-level context.",
    "invalidWhen": "Invalid when parsed from names, class titles, test labels, or free text at read time."
  },
  {
    "value": "2",
    "meaning": "Grade 2.",
    "useWhen": "Use for grade 2 age-grade, enrolled-grade, or course grade-level context.",
    "invalidWhen": "Invalid when parsed from names, class titles, test labels, or free text at read time."
  },
  {
    "value": "3",
    "meaning": "Grade 3.",
    "useWhen": "Use for grade 3 age-grade, enrolled-grade, or course grade-level context.",
    "invalidWhen": "Invalid when parsed from names, class titles, test labels, or free text at read time."
  },
  {
    "value": "4",
    "meaning": "Grade 4. Live source aliases validated 2026-06-09: 4, 4TH_GRADE, and Grade_4 fold here.",
    "useWhen": "Use for grade 4 age-grade, enrolled-grade, or course grade-level context.",
    "invalidWhen": "Invalid when parsed from names, class titles, test labels, or free text at read time."
  },
  {
    "value": "5",
    "meaning": "Grade 5.",
    "useWhen": "Use for grade 5 age-grade, enrolled-grade, or course grade-level context.",
    "invalidWhen": "Invalid when parsed from names, class titles, test labels, or free text at read time."
  },
  {
    "value": "6",
    "meaning": "Grade 6.",
    "useWhen": "Use for grade 6 age-grade, enrolled-grade, or course grade-level context.",
    "invalidWhen": "Invalid when parsed from names, class titles, test labels, or free text at read time."
  },
  {
    "value": "7",
    "meaning": "Grade 7.",
    "useWhen": "Use for grade 7 age-grade, enrolled-grade, or course grade-level context.",
    "invalidWhen": "Invalid when parsed from names, class titles, test labels, or free text at read time."
  },
  {
    "value": "8",
    "meaning": "Grade 8.",
    "useWhen": "Use for grade 8 age-grade, enrolled-grade, or course grade-level context.",
    "invalidWhen": "Invalid when parsed from names, class titles, test labels, or free text at read time."
  },
  {
    "value": "9",
    "meaning": "Grade 9.",
    "useWhen": "Use for grade 9 age-grade, enrolled-grade, or course grade-level context.",
    "invalidWhen": "Invalid when parsed from names, class titles, test labels, or free text at read time."
  },
  {
    "value": "10",
    "meaning": "Grade 10.",
    "useWhen": "Use for grade 10 age-grade, enrolled-grade, or course grade-level context.",
    "invalidWhen": "Invalid when parsed from names, class titles, test labels, or free text at read time."
  },
  {
    "value": "11",
    "meaning": "Grade 11.",
    "useWhen": "Use for grade 11 age-grade, enrolled-grade, or course grade-level context.",
    "invalidWhen": "Invalid when parsed from names, class titles, test labels, or free text at read time."
  },
  {
    "value": "12",
    "meaning": "Grade 12.",
    "useWhen": "Use for grade 12 age-grade, enrolled-grade, or course grade-level context.",
    "invalidWhen": "Invalid when parsed from names, class titles, test labels, or free text at read time."
  }
]
provenance
{
  "changeType": "extend",
  "sourceType": "alpha_extend_table",
  "source": "alpha.person_ext.age_grade",
  "sourceAnchor": null,
  "aliasMapField": "person.age_grade",
  "label": "Alpha extend",
  "note": "Current convenience value; alpha.age_grade_history is the point-in-time system of record.",
  "itds": [
    {
      "id": "paitd-018-over-time-history",
      "title": "Alpha Level And Age Grade Keep Effective-Dated History, Read By AsOfDate",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-018-over-time-history"
    },
    {
      "id": "paitd-007-tenure-and-grade-context",
      "title": "Tenure And Grade Context Are Typed Inputs, Not Dashboard Math",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-007-tenure-and-grade-context"
    }
  ]
}
storage
{
  "kind": "alpha_extend_table",
  "source": "alpha.person_ext.age_grade",
  "storageRule": "Stored only in alpha.person_ext.age_grade; allowed because it is a true Alpha extension and not a copied 1EdTech field.",
  "writeRoute": "Write only admission_date, exit_date, age_grade, and reality to alpha.person_ext after the base person exists."
}

alpha.place · Place

objectName
place
apiCollection
/places
storage
Public view alpha.place joins alpha.place_base over oneroster.orgs to alpha.place_ext and governed alpha.object_tag projections. Only nwea_district_id, reality, and report-slice tags are Alpha storage.
changeType
rename + restrict + extend
upstream
oneroster.orgs
primaryKey
(tenant_id, place_id)
purpose
A district, school, level, department, or other roster place. For NWEA, district means exactly one Brand x Modality account.
lifecycle
Created from OneRoster org rows or Alpha place commands. Schools link to their district parent through parent_place_id; a school does not duplicate its NWEA account id.
auth
Readable to roster scopes narrowed by placeIds or schoolIds claims. NWEA-account fields require school/district visibility.
sourceType
1edtech_alias_view_with_extension_join
publicSurface
alpha.place
baseView
alpha.place_base
baseSource
oneroster.orgs
coreWriteRoute
Route sourced-field writes to the OneRoster 1EdTech orgs surface.
extensionWriteRoute
Write nwea_district_id and reality to alpha.place_ext and report-slice tags to alpha.object_tag only.
anchor
table-alpha-place
fieldCount
14
sourceAnchor
https://platform3-andymontgomery-9773s-projects.vercel.app/oneroster/1edtech/data_dictionary/#table-oneroster-orgs
filters
[
  "placeKind",
  "parentPlaceId",
  "brand",
  "modality",
  "segment",
  "level",
  "reality",
  "nweaDistrictId",
  "modifiedSince"
]
sortKeys
[
  "name",
  "place_kind",
  "source_updated_at",
  "place_id"
]
extensionTables
[
  "alpha.place_ext",
  "alpha.object_tag"
]
storageContract
{
  "alphaObject": "place",
  "publicSurface": "alpha.place",
  "upstreamModule": "oneroster/1edtech",
  "baseSource": "oneroster.orgs",
  "baseView": "alpha.place_base",
  "extensionTables": [
    "alpha.place_ext",
    "alpha.object_tag"
  ],
  "coreWriteRoute": "Route sourced-field writes to the OneRoster 1EdTech orgs surface.",
  "extensionWriteRoute": "Write nwea_district_id and reality to alpha.place_ext and report-slice tags to alpha.object_tag only.",
  "requiredShape": "CREATE VIEW over the OneRoster 1EdTech base; no Alpha table may store sourced OneRoster columns."
}
example
{
  "place_id": "place_timeback_physical_district",
  "source_status": "active",
  "source_updated_at": "2026-08-15T13:45:30.000Z",
  "reality": "real",
  "name": "TimeBack Academy - Physical",
  "place_kind": "district",
  "public_identifier": "NCES-123456",
  "parent_place_id": "place_timeback_physical_district",
  "nwea_district_id": "nwea-district-physical-001",
  "brand": "alpha",
  "modality": "physical",
  "segment": "private",
  "level": "MS"
}

Fields (14)

tenant_id

title
Tenant Id
type
UUID
publicApi
Hidden in ordinary Alpha responses; selected from the verified JWT.
nullability
Required on every stored row.
required
Yes
range
Valid PostgreSQL UUID.
meaning
The tenant boundary that owns this People & Orgs row.
constraints
Must equal the verified JWT tenant_id or tenantId claim. Never accept a tenant header or body field as source of truth.
relationship
Belongs to one platform.tenant. One tenant owns many People & Orgs rows.
invalidWhen
Missing, malformed, points to another tenant, or is supplied by an unverified request body.
edgeCases
Demo token minting may accept tenantId=demo, but stored rows still use the resolved tenant id.
example
0d4ce2f4-1c42-4f3c-9f0d-03fb7f5271d3
pii
No
allowedValues
[]
provenance
{
  "changeType": "inherited",
  "sourceType": "platform_shared",
  "source": "platform.tenant",
  "sourceAnchor": null,
  "aliasMapField": null,
  "label": "Alpha inherited",
  "note": "Inherited platform tenant routing field, not a OneRoster alias.",
  "itds": [
    {
      "id": "paitd-109-tenant-routing",
      "title": "API Axis: Tenant Routing",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-109-tenant-routing"
    }
  ]
}
storage
{
  "kind": "platform_inherited_column",
  "source": "platform.tenant / verified JWT tenant claim",
  "storageRule": "Inherited platform tenant key. It scopes base rows, extension rows, and views; it is not copied from OneRoster or Ed-Fi.",
  "writeRoute": "Resolved from the verified JWT tenant claim by the platform layer."
}

place_id

title
Place Id
type
TEXT
publicApi
string
nullability
Required.
required
Yes
range
1 to 255 printable characters, unique within (tenant_id, alpha.place).
meaning
Stable place id for a school, district, level, department, or NWEA account.
constraints
Use this for relationships. Do not parse school or district ids from names.
relationship
Referenced by person.primary_place_id, place.parent_place_id, place_membership.place_id, and class_membership.school_id.
invalidWhen
Blank, reused for another place, changed because a school display name changes, or replaced by a tag.
edgeCases
District place rows representing NWEA accounts also carry nwea_district_id.
example
place_timeback_physical_district
pii
No
allowedValues
[]
provenance
{
  "changeType": "rename",
  "sourceType": "1edtech_alias",
  "source": "oneroster.orgs.sourced_id",
  "sourceAnchor": "https://platform3-andymontgomery-9773s-projects.vercel.app/oneroster/1edtech/data_dictionary/#field-oneroster-orgs-sourced-id",
  "aliasMapField": "place.place_id",
  "label": "Alpha rename",
  "note": "Tenant-scoped place id.",
  "itds": [
    {
      "id": "paitd-003-place-nwea-boundary",
      "title": "Place Is The Plain Alias For OneRoster Org And District Is The NWEA Account",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-003-place-nwea-boundary"
    },
    {
      "id": "paitd-010-alias-map-contract",
      "title": "Alias Map Is A Generated Architecture Artifact",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-010-alias-map-contract"
    }
  ]
}
storage
{
  "kind": "oneedtech_view_column",
  "source": "oneroster.orgs.sourced_id",
  "storageRule": "Selected by alpha.place_base from oneroster.orgs; public alpha.place does not store a copy of this 1EdTech field.",
  "writeRoute": "Route sourced-field writes to the OneRoster 1EdTech orgs surface."
}

source_status

title
Source Status
type
TEXT enum
publicApi
string enum
nullability
Nullable in bulk-origin rows; required when the source sends delta status.
required
Conditional
range
active or tobedeleted.
meaning
OneRoster lifecycle marker preserved for provenance.
constraints
Does not erase child schools or historical memberships by itself.
relationship
No direct foreign key.
invalidWhen
Any value other than active or tobedeleted, or used to hide history.
edgeCases
Bulk OneRoster rows intentionally omit status.
example
active
pii
No
allowedValues
[
  {
    "value": "active",
    "meaning": "The delta row is current and should be inserted or updated.",
    "useWhen": "Use only in delta row status fields. Alpha keeps this only as source provenance; ordinary active-as-of queries still use dated memberships.",
    "invalidWhen": "Invalid in bulk rows or when the row should be deleted."
  },
  {
    "value": "tobedeleted",
    "meaning": "The delta row indicates the source wants this object deleted or retired.",
    "useWhen": "Use only in delta row status fields. Alpha keeps this only as source provenance; ordinary active-as-of queries still use dated memberships.",
    "invalidWhen": "Invalid in bulk rows or when the source object remains active."
  }
]
provenance
{
  "changeType": "rename",
  "sourceType": "1edtech_alias",
  "source": "oneroster.orgs.status",
  "sourceAnchor": "https://platform3-andymontgomery-9773s-projects.vercel.app/oneroster/1edtech/data_dictionary/#field-oneroster-orgs-status",
  "aliasMapField": "place.source_status",
  "label": "Alpha rename",
  "note": "OneRoster lifecycle state.",
  "itds": [
    {
      "id": "paitd-003-place-nwea-boundary",
      "title": "Place Is The Plain Alias For OneRoster Org And District Is The NWEA Account",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-003-place-nwea-boundary"
    },
    {
      "id": "paitd-111-privacy-retention",
      "title": "API Axis: Privacy / Retention",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-111-privacy-retention"
    }
  ]
}
storage
{
  "kind": "oneedtech_view_column",
  "source": "oneroster.orgs.status",
  "storageRule": "Selected by alpha.place_base from oneroster.orgs; public alpha.place does not store a copy of this 1EdTech field.",
  "writeRoute": "Route sourced-field writes to the OneRoster 1EdTech orgs surface."
}

source_updated_at

title
Source Updated At
type
TIMESTAMPTZ
publicApi
ISO 8601 datetime
nullability
Nullable in bulk-origin rows; required when the source sends delta status.
required
Conditional
range
ISO 8601 UTC datetime.
meaning
Source-system modified timestamp for modifiedSince scans.
constraints
Must be parsed and stored as a timestamp.
relationship
Used by modifiedSince list scans for source-origin rows.
invalidWhen
Malformed, supplied where source contract forbids it, or older than the prior accepted delta for the same row.
edgeCases
Per-resource Alpha writes may also update platform updated_at.
example
2026-08-15T13:45:30.000Z
pii
No
allowedValues
[]
provenance
{
  "changeType": "rename",
  "sourceType": "1edtech_alias",
  "source": "oneroster.orgs.date_last_modified",
  "sourceAnchor": "https://platform3-andymontgomery-9773s-projects.vercel.app/oneroster/1edtech/data_dictionary/#field-oneroster-orgs-date-last-modified",
  "aliasMapField": "place.source_updated_at",
  "label": "Alpha rename",
  "note": "Source-system modified timestamp for delta rows.",
  "itds": [
    {
      "id": "paitd-003-place-nwea-boundary",
      "title": "Place Is The Plain Alias For OneRoster Org And District Is The NWEA Account",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-003-place-nwea-boundary"
    },
    {
      "id": "paitd-103-query-model",
      "title": "API Axis: Query Model",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-103-query-model"
    }
  ]
}
storage
{
  "kind": "oneedtech_view_column",
  "source": "oneroster.orgs.date_last_modified",
  "storageRule": "Selected by alpha.place_base from oneroster.orgs; public alpha.place does not store a copy of this 1EdTech field.",
  "writeRoute": "Route sourced-field writes to the OneRoster 1EdTech orgs surface."
}

reality

title
Reality
type
TEXT enum
publicApi
real | test | synthetic
nullability
Required for reportable place rows after the PAITD-017 write boundary; historical pre-backfill rows fail report reads until classified.
required
Yes
range
Closed values: real, test, synthetic.
meaning
Typed reality classification for this place. Ordinary reports default to reality=real so test and synthetic schools or districts never enter customer answers.
constraints
Set at write time from authoritative SIS or TimeBack source classification. Never infer from place name, campus label, brand, modality, segment, or a consumer-maintained exclude-list.
relationship
No foreign key; it is a first-class filter on place and must agree with joined person reality for roster reports.
invalidWhen
Missing on a reportable school/district, any value outside real/test/synthetic, inferred by string matching, or omitted from a real-school report query.
edgeCases
A test campus can have valid memberships and still be excluded from default reports because reality is not real.
example
real
pii
No
allowedValues
[
  {
    "value": "real",
    "meaning": "A production student, person, school, district, or roster place that belongs in ordinary customer reports.",
    "useWhen": "Use for real TimeBack people and places after the write boundary has verified the source classification.",
    "invalidWhen": "Invalid for QA accounts, AI-agent test rows, generated fixtures, or demo-only entities."
  },
  {
    "value": "test",
    "meaning": "A QA, staff-test, integration-test, or AI-agent test entity that must be excluded from ordinary reports.",
    "useWhen": "Use for entities intentionally created to test the surface or another app.",
    "invalidWhen": "Invalid for production students or schools even if their display name looks unusual."
  },
  {
    "value": "synthetic",
    "meaning": "Generated, seeded, anonymized, or fixture data that is useful for demos or development but not a real customer row.",
    "useWhen": "Use for generated seed rows, local fixtures, and anonymized examples.",
    "invalidWhen": "Invalid for a row imported from the authoritative SIS or TimeBack production source as a real entity."
  }
]
provenance
{
  "changeType": "extend",
  "sourceType": "alpha_extend_table",
  "source": "alpha.place_ext.reality",
  "sourceAnchor": null,
  "aliasMapField": "place.reality",
  "label": "Alpha extend",
  "note": "PAITD-017 reality decision: first-class Alpha extension field on place.",
  "itds": [
    {
      "id": "paitd-017-reality-flag",
      "title": "Reality Is A Typed Closed Flag On Person And Place, Set At Write Time",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-017-reality-flag"
    },
    {
      "id": "paitd-103-query-model",
      "title": "API Axis: Query Model",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-103-query-model"
    },
    {
      "id": "paitd-111-privacy-retention",
      "title": "API Axis: Privacy / Retention",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-111-privacy-retention"
    },
    {
      "id": "paitd-011-storage-model",
      "title": "Alpha Storage Is Views Over OneRoster Plus Extension Tables",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-011-storage-model"
    }
  ]
}
storage
{
  "kind": "alpha_extend_table",
  "source": "alpha.place_ext.reality",
  "storageRule": "Stored only in alpha.place_ext; allowed because real/test/synthetic classification is an Alpha reporting guardrail, not a OneRoster org field copy.",
  "writeRoute": "Write through the Alpha place extension path from authoritative source classification; never infer from place names or campus labels."
}

name

title
Name
type
TEXT
publicApi
string
nullability
Required.
required
Yes
range
1 to 255 visible characters.
meaning
Human-readable place name.
constraints
Display only. Do not parse brand, modality, segment, level, or school year from the name.
relationship
No relationship. Use place_id and parent_place_id for joins.
invalidWhen
Blank, used as a primary key, or parsed to compute brand/modality/segment/level.
edgeCases
Names may change without changing place_id.
example
TimeBack Academy - Physical
pii
No
allowedValues
[]
provenance
{
  "changeType": "rename",
  "sourceType": "1edtech_alias",
  "source": "oneroster.orgs.name",
  "sourceAnchor": "https://platform3-andymontgomery-9773s-projects.vercel.app/oneroster/1edtech/data_dictionary/#field-oneroster-orgs-name",
  "aliasMapField": "place.name",
  "label": "Alpha rename",
  "note": "Place name.",
  "itds": [
    {
      "id": "paitd-003-place-nwea-boundary",
      "title": "Place Is The Plain Alias For OneRoster Org And District Is The NWEA Account",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-003-place-nwea-boundary"
    },
    {
      "id": "paitd-006-tag-registry",
      "title": "Governed Tags Are Report Slices Only",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-006-tag-registry"
    }
  ]
}
storage
{
  "kind": "oneedtech_view_column",
  "source": "oneroster.orgs.name",
  "storageRule": "Selected by alpha.place_base from oneroster.orgs; public alpha.place does not store a copy of this 1EdTech field.",
  "writeRoute": "Route sourced-field writes to the OneRoster 1EdTech orgs surface."
}

place_kind

title
Place Kind
type
TEXT enum
publicApi
string enum
nullability
Required.
required
Yes
range
One of the allowed place_kind values.
meaning
Canonical place type. District and school are structural; tags refine them but never override them.
constraints
Must be set at write time. district rows may represent Brand x Modality NWEA accounts; school rows anchor enrollments.
relationship
Controls which relationships the row can satisfy. parent_place_id links the hierarchy.
invalidWhen
Free text, parsed from name, or contradicted by brand/modality tags.
edgeCases
local, state, and national remain source-compatible hierarchy values but do not replace the district=Brand x Modality NWEA boundary.
example
district
pii
No
allowedValues
[
  {
    "value": "department",
    "meaning": "Department-level organization, usually below a school or district.",
    "useWhen": "Use for academic/administrative departments that can own courses or roles but should not satisfy school_sourced_id references.",
    "invalidWhen": "Invalid as the target of classes.school_sourced_id or enrollments.school_sourced_id."
  },
  {
    "value": "school",
    "meaning": "School/building organization and the required org type for school-scoped class, enrollment, and line-item references.",
    "useWhen": "Use when a row can be referenced by classes.school_sourced_id, enrollments.school_sourced_id, or line_items.school_sourced_id.",
    "invalidWhen": "Invalid for district or department rows that should only be hierarchy parents."
  },
  {
    "value": "district",
    "meaning": "District organization that commonly parents school rows.",
    "useWhen": "Use as parent_sourced_id for schools or for district-level roles/courses where the source sends them.",
    "invalidWhen": "Invalid as a class/enrollment school_sourced_id target."
  },
  {
    "value": "local",
    "meaning": "Local education authority or local-level organization.",
    "useWhen": "Use when the source models an LEA/local authority distinct from a district.",
    "invalidWhen": "Invalid as a school_sourced_id target unless the source profile explicitly says local rows are schools."
  },
  {
    "value": "state",
    "meaning": "State-level education agency or authority.",
    "useWhen": "Use as a hierarchy ancestor or role scope when supplied by the source.",
    "invalidWhen": "Invalid as a class/enrollment school_sourced_id target."
  },
  {
    "value": "national",
    "meaning": "National-level education agency or authority.",
    "useWhen": "Use only for national hierarchy/role contexts supplied by the source.",
    "invalidWhen": "Invalid as a school_sourced_id target or ordinary school parent when a district/local row exists."
  }
]
provenance
{
  "changeType": "rename+restrict",
  "sourceType": "1edtech_alias",
  "source": "oneroster.orgs.type",
  "sourceAnchor": "https://platform3-andymontgomery-9773s-projects.vercel.app/oneroster/1edtech/data_dictionary/#field-oneroster-orgs-type",
  "aliasMapField": "place.place_kind",
  "label": "Alpha rename+restrict",
  "note": "Canonical place type. District and school are structural; tags may refine but never override type.",
  "itds": [
    {
      "id": "paitd-003-place-nwea-boundary",
      "title": "Place Is The Plain Alias For OneRoster Org And District Is The NWEA Account",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-003-place-nwea-boundary"
    }
  ]
}
storage
{
  "kind": "oneedtech_view_column",
  "source": "oneroster.orgs.type",
  "storageRule": "Selected by alpha.place_base from oneroster.orgs; public alpha.place does not store a copy of this 1EdTech field.",
  "writeRoute": "Route sourced-field writes to the OneRoster 1EdTech orgs surface."
}

public_identifier

title
Public Identifier
type
TEXT
publicApi
string
nullability
Optional.
required
No
range
0 to 255 visible characters.
meaning
Human-readable public identifier such as NCES id.
constraints
Do not use for joins, tenant routing, or authorization.
relationship
No relationship; place_id remains the relationship key.
invalidWhen
Used as the primary key, conflicts with place_id, or contains a secret.
edgeCases
A place can have no public identifier.
example
NCES-123456
pii
No
allowedValues
[]
provenance
{
  "changeType": "rename",
  "sourceType": "1edtech_alias",
  "source": "oneroster.orgs.identifier",
  "sourceAnchor": "https://platform3-andymontgomery-9773s-projects.vercel.app/oneroster/1edtech/data_dictionary/#field-oneroster-orgs-identifier",
  "aliasMapField": "place.public_identifier",
  "label": "Alpha rename",
  "note": "Human-readable public identifier such as NCES id.",
  "itds": [
    {
      "id": "paitd-003-place-nwea-boundary",
      "title": "Place Is The Plain Alias For OneRoster Org And District Is The NWEA Account",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-003-place-nwea-boundary"
    }
  ]
}
storage
{
  "kind": "oneedtech_view_column",
  "source": "oneroster.orgs.identifier",
  "storageRule": "Selected by alpha.place_base from oneroster.orgs; public alpha.place does not store a copy of this 1EdTech field.",
  "writeRoute": "Route sourced-field writes to the OneRoster 1EdTech orgs surface."
}

parent_place_id

title
Parent Place Id
type
TEXT
publicApi
place id
nullability
Optional. Required for schools that belong to a district account in NWEA reports.
required
Conditional
range
1 to 255 printable characters when supplied.
meaning
Parent place in the stock OneRoster tree.
constraints
Must reference alpha.place.place_id in the same tenant. A school's NWEA account is read from this parent district, never duplicated on the school.
relationship
Self-reference: one parent place can have many child places.
invalidWhen
References a missing place, crosses tenant, creates a cycle, or is replaced by a tag.
edgeCases
Top-level district or state rows can have null parent_place_id.
example
place_timeback_physical_district
pii
No
allowedValues
[]
provenance
{
  "changeType": "rename",
  "sourceType": "1edtech_alias",
  "source": "oneroster.orgs.parent_sourced_id",
  "sourceAnchor": "https://platform3-andymontgomery-9773s-projects.vercel.app/oneroster/1edtech/data_dictionary/#field-oneroster-orgs-parent-sourced-id",
  "aliasMapField": "place.parent_place_id",
  "label": "Alpha rename",
  "note": "Parent place in the stock OneRoster tree.",
  "itds": [
    {
      "id": "paitd-003-place-nwea-boundary",
      "title": "Place Is The Plain Alias For OneRoster Org And District Is The NWEA Account",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-003-place-nwea-boundary"
    },
    {
      "id": "paitd-006-tag-registry",
      "title": "Governed Tags Are Report Slices Only",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-006-tag-registry"
    }
  ]
}
storage
{
  "kind": "oneedtech_view_column",
  "source": "oneroster.orgs.parent_sourced_id",
  "storageRule": "Selected by alpha.place_base from oneroster.orgs; public alpha.place does not store a copy of this 1EdTech field.",
  "writeRoute": "Route sourced-field writes to the OneRoster 1EdTech orgs surface."
}

nwea_district_id

title
Nwea District Id
type
TEXT
publicApi
string
nullability
Required when place_kind=district and this place is the Brand x Modality NWEA account; invalid on school rows.
required
Conditional
range
NWEA account/district id supplied by the NWEA account setup.
meaning
The NWEA district/account id for exactly one Brand x Modality account.
constraints
Must be a real column on the district place. Schools read it through parent_place_id; they do not carry a second copy.
relationship
Used by NWEAMap ingest and Results reports to select the account boundary through the OneRoster org tree.
invalidWhen
Missing on an NWEA district account, present on a school row, duplicated across two Brand x Modality districts, or stored as a tag.
edgeCases
The Brand x Modality account boundary uses the closed brand and modality lists published in this data dictionary. Production org rows without typed brand/segment require reconciliation before they become NWEA-account rows.
example
nwea-district-physical-001
pii
No
allowedValues
[]
provenance
{
  "changeType": "extend",
  "sourceType": "alpha_extend_table",
  "source": "alpha.place_ext.nwea_district_id",
  "sourceAnchor": null,
  "aliasMapField": "place.nwea_district_id",
  "label": "Alpha extend",
  "note": "Alpha extension required by cross-cutting rule 7.",
  "itds": [
    {
      "id": "paitd-003-place-nwea-boundary",
      "title": "Place Is The Plain Alias For OneRoster Org And District Is The NWEA Account",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-003-place-nwea-boundary"
    }
  ]
}
storage
{
  "kind": "alpha_extend_table",
  "source": "alpha.place_ext.nwea_district_id",
  "storageRule": "Stored only in alpha.place_ext.nwea_district_id; allowed because it is a true Alpha extension and not a copied 1EdTech field.",
  "writeRoute": "Write nwea_district_id and reality to alpha.place_ext and report-slice tags to alpha.object_tag only."
}

brand

title
Brand
type
TEXT enum
publicApi
string enum
nullability
Required for NWEA-account district rows and typed school rows; optional elsewhere only if a registered tag allows it.
required
Conditional
range
Closed values: 100for100, alpha, gt, limitless_education, montessorium, nextgen, nova_academy, novatio, sw_sales, texas_sports_academy, towermath, unbound, waypoint.
meaning
Locked reporting tag for the brand half of the Brand x Modality NWEA account boundary.
constraints
It is a governed tag projection, not a relationship, secret, or computed input. Setup seeds and locks the closed value list published here; source aliases fold at write time.
relationship
Pairs with modality and segment on the same place. Does not replace parent_place_id or place_kind.
invalidWhen
Free text, unregistered value, attached at the wrong grain, parsed from a name at read time, or used for joins outside the tag registry.
edgeCases
Validated against live active production org rows on 2026-06-09. Unmatched active orgs are reconciliation findings; they do not create an unknown brand value.
example
alpha
pii
No
allowedValues
[
  {
    "value": "100for100",
    "meaning": "100for100 brand. Live active org validation found this brand in the campus taxonomy intersected with production org rows.",
    "useWhen": "Use for NWEA-account district and school rows whose typed brand is 100for100.",
    "invalidWhen": "Invalid as a fallback for Alpha, GT, Texas Sports Academy, or partner brands."
  },
  {
    "value": "alpha",
    "meaning": "Alpha School brand. Live source aliases include Alpha, Alpha School, Alpha Anywhere, Alpha School campus names, and 2 Hour Learning legacy names.",
    "useWhen": "Use for Alpha School physical and virtual NWEA-account rows.",
    "invalidWhen": "Invalid for GT School, Texas Sports Academy, or non-Alpha partner schools."
  },
  {
    "value": "gt",
    "meaning": "GT School brand. Live aliases include GT School and GT Anywhere.",
    "useWhen": "Use for GT physical or virtual NWEA-account rows.",
    "invalidWhen": "Invalid for Alpha or partner school rows."
  },
  {
    "value": "limitless_education",
    "meaning": "Limitless Education brand observed in live active org rows.",
    "useWhen": "Use for schools whose typed brand is Limitless Education.",
    "invalidWhen": "Invalid for generic partner rows without that brand assignment."
  },
  {
    "value": "montessorium",
    "meaning": "Montessorium brand observed in live active org rows.",
    "useWhen": "Use for Montessorium school rows.",
    "invalidWhen": "Invalid for Alpha, GT, or Texas Sports Academy rows."
  },
  {
    "value": "nextgen",
    "meaning": "NextGen brand observed in live active org rows.",
    "useWhen": "Use for NextGen Academy or NextGen tutoring rows.",
    "invalidWhen": "Invalid for unrelated partner schools."
  },
  {
    "value": "nova_academy",
    "meaning": "Nova Academy brand observed in live active org rows.",
    "useWhen": "Use for Nova Academy campuses.",
    "invalidWhen": "Invalid for Novatio; that is a separate brand value."
  },
  {
    "value": "novatio",
    "meaning": "Novatio brand observed in live active org rows.",
    "useWhen": "Use for Novatio rows.",
    "invalidWhen": "Invalid for Nova Academy rows."
  },
  {
    "value": "sw_sales",
    "meaning": "SW Sales segment/brand value observed across Allendale and similar live active org rows.",
    "useWhen": "Use when the production taxonomy classifies the school as SW Sales.",
    "invalidWhen": "Invalid for Alpha-owned campuses or Texas Sports Academy rows."
  },
  {
    "value": "texas_sports_academy",
    "meaning": "Texas Sports Academy brand. Live aliases include Texas Sports Academy, TSA, TSA Online, and TSA sport/prep campus names.",
    "useWhen": "Use for Texas Sports Academy physical and virtual accounts.",
    "invalidWhen": "Invalid for Alpha, GT, or non-TSA partner rows."
  },
  {
    "value": "towermath",
    "meaning": "TowerMath brand observed in live active org rows.",
    "useWhen": "Use for TowerMath rows.",
    "invalidWhen": "Invalid for Alpha math products unless the typed brand is TowerMath."
  },
  {
    "value": "unbound",
    "meaning": "Unbound brand observed in live active org rows.",
    "useWhen": "Use for Unbound Academy rows.",
    "invalidWhen": "Invalid for other partner schools."
  },
  {
    "value": "waypoint",
    "meaning": "Waypoint brand observed in live active org rows.",
    "useWhen": "Use for Waypoint Academy rows.",
    "invalidWhen": "Invalid for other partner schools."
  }
]
provenance
{
  "changeType": "extend",
  "sourceType": "alpha_extend_table",
  "source": "alpha.object_tag(tag_key=brand)",
  "sourceAnchor": null,
  "aliasMapField": "place.brand",
  "label": "Alpha extend",
  "note": "Alpha governed tag projection.",
  "itds": [
    {
      "id": "paitd-003-place-nwea-boundary",
      "title": "Place Is The Plain Alias For OneRoster Org And District Is The NWEA Account",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-003-place-nwea-boundary"
    },
    {
      "id": "paitd-006-tag-registry",
      "title": "Governed Tags Are Report Slices Only",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-006-tag-registry"
    }
  ]
}
storage
{
  "kind": "alpha_extend_table",
  "source": "alpha.object_tag(tag_key=brand)",
  "storageRule": "Stored only in alpha.object_tag(tag_key=brand); allowed because it is a true Alpha extension and not a copied 1EdTech field.",
  "writeRoute": "Write nwea_district_id and reality to alpha.place_ext and report-slice tags to alpha.object_tag only."
}

modality

title
Modality
type
TEXT enum
publicApi
physical | virtual
nullability
Required for NWEA-account district rows and typed school rows; invalid for hybrid.
required
Conditional
range
physical or virtual only.
meaning
Locked reporting tag for the modality half of the Brand x Modality NWEA account boundary.
constraints
Must be one of physical or virtual. Hybrid is invalid by architecture.
relationship
Pairs with brand and segment on the same place.
invalidWhen
hybrid, mixed, unregistered free text, school-level copy, or absent from an NWEA-account district.
edgeCases
Physical and virtual are the same academic program but different motivational models, so they remain separate NWEA accounts.
example
physical
pii
No
allowedValues
[
  {
    "value": "physical",
    "meaning": "The NWEA account is for the physical-school modality of a brand. Live source aliases validated 2026-06-09: Physical folds here.",
    "useWhen": "Use for the district or school place row representing the physical NWEA account or child school.",
    "invalidWhen": "Invalid for virtual accounts or for a mixed/hybrid account."
  },
  {
    "value": "virtual",
    "meaning": "The NWEA account is for the virtual-school modality of a brand. Live source aliases validated 2026-06-09: Virtual folds here.",
    "useWhen": "Use for the district or school place row representing the virtual NWEA account or child school.",
    "invalidWhen": "Invalid for physical accounts or for a mixed/hybrid account."
  }
]
provenance
{
  "changeType": "extend",
  "sourceType": "alpha_extend_table",
  "source": "alpha.object_tag(tag_key=modality)",
  "sourceAnchor": null,
  "aliasMapField": "place.modality",
  "label": "Alpha extend",
  "note": "Alpha governed tag projection.",
  "itds": [
    {
      "id": "paitd-003-place-nwea-boundary",
      "title": "Place Is The Plain Alias For OneRoster Org And District Is The NWEA Account",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-003-place-nwea-boundary"
    },
    {
      "id": "paitd-006-tag-registry",
      "title": "Governed Tags Are Report Slices Only",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-006-tag-registry"
    }
  ]
}
storage
{
  "kind": "alpha_extend_table",
  "source": "alpha.object_tag(tag_key=modality)",
  "storageRule": "Stored only in alpha.object_tag(tag_key=modality); allowed because it is a true Alpha extension and not a copied 1EdTech field.",
  "writeRoute": "Write nwea_district_id and reality to alpha.place_ext and report-slice tags to alpha.object_tag only."
}

segment

title
Segment
type
TEXT enum
publicApi
string enum
nullability
Required for typed district and school rows once the #70 write boundary is active; district rows spanning segments use mixed.
required
Conditional
range
Closed values: charter, private, sw_sales, virtual, mixed.
meaning
Closed reporting segment for school and district grouping.
constraints
Set at write time from the typed org source or governed setup import. Consumers never parse it from place.name, campusId, or a dashboard list. A district spanning segments uses segment=mixed.
relationship
Pairs with brand and modality on the same place; it is a report slice, not a parent-child relationship.
invalidWhen
Free text, null on a typed school/district row, parsed from names, used for secrets, or used to replace parent_place_id.
edgeCases
mixed is reserved for multi-segment district/account rows and was not observed as an active school segment in the 2026-06-09 validation.
example
private
pii
No
allowedValues
[
  {
    "value": "charter",
    "meaning": "Charter-school segment observed in live active org rows.",
    "useWhen": "Use for schools whose typed segment is charter.",
    "invalidWhen": "Invalid for private, virtual, or SW Sales rows."
  },
  {
    "value": "private",
    "meaning": "Private-school segment observed in live active org rows.",
    "useWhen": "Use for private school campuses and district accounts.",
    "invalidWhen": "Invalid for virtual-only, charter, or SW Sales rows."
  },
  {
    "value": "sw_sales",
    "meaning": "SW Sales segment observed in live active org rows.",
    "useWhen": "Use for schools typed into the SW Sales segment.",
    "invalidWhen": "Invalid for Alpha private/virtual rows unless the write boundary explicitly assigns SW Sales."
  },
  {
    "value": "virtual",
    "meaning": "Virtual segment observed in live active org rows.",
    "useWhen": "Use for schools or accounts whose segment is virtual.",
    "invalidWhen": "Invalid for physical private or charter segment rows; modality still remains physical or virtual separately."
  },
  {
    "value": "mixed",
    "meaning": "District/account rollup reserved for a district spanning multiple segments.",
    "useWhen": "Use only on a district/account row that intentionally spans more than one segment.",
    "invalidWhen": "Invalid on an ordinary school row or as a substitute for unknown."
  }
]
provenance
{
  "changeType": "extend",
  "sourceType": "alpha_extend_table",
  "source": "alpha.object_tag(tag_key=segment)",
  "sourceAnchor": null,
  "aliasMapField": "place.segment",
  "label": "Alpha extend",
  "note": "Alpha governed tag projection added by the #70 closed-enum feedback.",
  "itds": [
    {
      "id": "paitd-003-place-nwea-boundary",
      "title": "Place Is The Plain Alias For OneRoster Org And District Is The NWEA Account",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-003-place-nwea-boundary"
    },
    {
      "id": "paitd-006-tag-registry",
      "title": "Governed Tags Are Report Slices Only",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-006-tag-registry"
    }
  ]
}
storage
{
  "kind": "alpha_extend_table",
  "source": "alpha.object_tag(tag_key=segment)",
  "storageRule": "Stored only in alpha.object_tag with tag_key=segment; allowed because it is a true Alpha reporting-slice extension and not a copied OneRoster field.",
  "writeRoute": "Route sourced place writes to the OneRoster 1EdTech orgs surface; write segment through alpha.object_tag only after the place exists."
}

level

title
Level
type
TEXT closed enum
publicApi
WL | LL | L1 | L2 | MS | HS
nullability
Optional except where a school-level report requires it.
required
Conditional
range
Closed locked school-level values: WL, LL, L1, L2, MS, HS. The list is seeded in alpha.tag_definition where tag_key=level and anchor=school.
meaning
Locked school-level reporting tag for school and program cohort slices.
constraints
Setup seeds and locks the closed WL/LL/L1/L2/MS/HS list. Consumers filter by these tokens only and never parse school level from place.name, campus labels, segment, modality, or grade strings.
relationship
No relationship; tag registry validates tag_key=level at the school anchor. This tag does not replace place_kind, parent_place_id, or age/working grade.
invalidWhen
Free text, prose level labels, used as a foreign key, used to compute placement, or used to override place_kind.
edgeCases
School level is a locked report slice, not an open runtime registry. A new school-level token requires an explicit controlled setup/migration change, not an app-local value.
example
MS
pii
No
allowedValues
[
  {
    "value": "WL",
    "meaning": "WonderLab, the pre-K Alpha level. Live source alias validated 2026-06-09: PKBY folds here.",
    "useWhen": "Use for the pre-K Alpha level, point-in-time as of the roster date.",
    "invalidWhen": "Invalid for kindergarten, LearningLab, or any grade-level placement."
  },
  {
    "value": "LL",
    "meaning": "LearningLab, the K-1 Alpha level. Live source alias validated 2026-06-09: Linc folds here.",
    "useWhen": "Use for K-1 Alpha-level grouping, point-in-time as of the roster date.",
    "invalidWhen": "Invalid for WonderLab or numbered upper levels."
  },
  {
    "value": "L1",
    "meaning": "Level 1, the grade 2-3 Alpha level after live cohort confirmation.",
    "useWhen": "Use for the Alpha level spanning grade 2 through grade 3.",
    "invalidWhen": "Invalid for grade 4+ cohorts or for MAP working-grade state."
  },
  {
    "value": "L2",
    "meaning": "Level 2, the grade 4-5 Alpha level after live cohort confirmation.",
    "useWhen": "Use for the Alpha level spanning grade 4 through grade 5.",
    "invalidWhen": "Invalid for grade 2-3, middle school, high school, or Results working-grade state."
  },
  {
    "value": "MS",
    "meaning": "Middle School, the grade 6-8 Alpha level. Live source aliases validated 2026-06-09: Middle School and L3 fold here.",
    "useWhen": "Use for middle-school Alpha-level grouping.",
    "invalidWhen": "Invalid for high school or elementary level rows."
  },
  {
    "value": "HS",
    "meaning": "High School, the grade 9-12 Alpha level. Live source aliases validated 2026-06-09: High School, L4.1, L4.2, and L4.3 fold here.",
    "useWhen": "Use for high-school Alpha-level grouping.",
    "invalidWhen": "Invalid for middle-school or elementary level rows."
  }
]
provenance
{
  "changeType": "extend",
  "sourceType": "alpha_extend_table",
  "source": "alpha.object_tag(tag_key=level)",
  "sourceAnchor": null,
  "aliasMapField": "place.level",
  "label": "Alpha extend",
  "note": "Alpha locked governed tag projection for the school levels named once by the brainlift.",
  "itds": [
    {
      "id": "paitd-006-tag-registry",
      "title": "Governed Tags Are Report Slices Only",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-006-tag-registry"
    },
    {
      "id": "paitd-003-place-nwea-boundary",
      "title": "Place Is The Plain Alias For OneRoster Org And District Is The NWEA Account",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-003-place-nwea-boundary"
    }
  ]
}
storage
{
  "kind": "alpha_extend_table",
  "source": "alpha.object_tag(tag_key=level)",
  "storageRule": "Stored only in alpha.object_tag with tag_key=level; allowed because it is a locked Alpha school-level reporting tag and not a copied OneRoster field.",
  "writeRoute": "Route sourced place writes to the OneRoster 1EdTech orgs surface; seed the locked level tag_definition at setup, then write level through alpha.object_tag only after the place exists."
}

alpha.person_ext · Person Extension Storage

objectName
person_ext
apiCollection
storage-only; written through /people extension fields
storage
Alpha-owned extension table for person facts that OneRoster does not carry. It decorates alpha.person_base by tenant_id/person_id and is read through alpha.person.
changeType
extend
upstream
None; logical FK to alpha.person_base
baseView
alpha.person_base
coreWriteRoute
None. Sourced person fields route to the OneRoster 1EdTech users surface.
extensionWriteRoute
Write only person_id, admission_date, exit_date, age_grade, and reality to alpha.person_ext after the alpha.person_base row exists.
primaryKey
(tenant_id, person_id)
purpose
The storage row that lets Alpha add person lifecycle, age-grade, and reality context to a person without copying OneRoster user columns.
lifecycle
Created after the base person exists. Updated when admission_date, exit_date, age_grade, or reality changes at the Alpha write boundary. Removing extension context deletes or nulls this row without deleting the base person.
auth
Not exposed as an ordinary roster collection. Reads appear through alpha.person; direct migration writes require schema/admin scope.
sourceType
alpha_extend
publicSurface
alpha.person_ext
baseSource
storageContract
anchor
table-alpha-person-ext
fieldCount
6
sourceAnchor
extensionTables
[
  "alpha.person_ext"
]
filters
[
  "personId",
  "reality",
  "tenantId"
]
sortKeys
[
  "person_id"
]
example
{
  "person_id": "person_ada_lovelace",
  "admission_date": "2025-08-18",
  "age_grade": 7,
  "reality": "real",
  "exit_date": null
}

Fields (6)

tenant_id

title
Tenant Id
type
UUID
publicApi
Hidden in ordinary Alpha responses; selected from the verified JWT.
nullability
Required on every stored row.
required
Yes
range
Valid PostgreSQL UUID.
meaning
The tenant boundary that owns this People & Orgs row.
constraints
Must equal the verified JWT tenant_id or tenantId claim. Never accept a tenant header or body field as source of truth.
relationship
Belongs to one platform.tenant. One tenant owns many People & Orgs rows.
invalidWhen
Missing, malformed, points to another tenant, or is supplied by an unverified request body.
edgeCases
Demo token minting may accept tenantId=demo, but stored rows still use the resolved tenant id.
example
0d4ce2f4-1c42-4f3c-9f0d-03fb7f5271d3
pii
No
allowedValues
[]
provenance
{
  "changeType": "inherited",
  "sourceType": "platform_shared",
  "source": "platform.tenant",
  "sourceAnchor": null,
  "aliasMapField": null,
  "label": "Alpha inherited",
  "note": "Inherited platform tenant routing field, not a OneRoster alias.",
  "itds": [
    {
      "id": "paitd-109-tenant-routing",
      "title": "API Axis: Tenant Routing",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-109-tenant-routing"
    }
  ]
}
storage
{
  "kind": "platform_inherited_column",
  "source": "platform.tenant / verified JWT tenant claim",
  "storageRule": "Inherited platform tenant key. It scopes base rows, extension rows, and views; it is not copied from OneRoster or Ed-Fi.",
  "writeRoute": "Resolved from the verified JWT tenant claim by the platform layer."
}

person_id

title
Person Id
type
TEXT
publicApi
storage foreign key; appears as person_id on alpha.person
nullability
Required.
required
Yes
range
1 to 255 printable characters.
meaning
The base person row this extension decorates.
constraints
Must match one alpha.person_base row in the same tenant before the extension row is written. One extension row per base person.
relationship
Logical foreign key to alpha.person_base(tenant_id, person_id); the physical database may enforce the same relationship against the underlying OneRoster base key.
invalidWhen
Missing, references a non-existent base person, crosses tenant, or is treated as the source of person identity.
edgeCases
A person can exist without a person_ext row; then admission_date, exit_date, and age_grade surface as null on alpha.person.
example
person_ada_lovelace
pii
Identifier
allowedValues
[]
provenance
{
  "changeType": "extend",
  "sourceType": "alpha_extend_table",
  "source": "alpha.person_ext.person_id",
  "sourceAnchor": null,
  "aliasMapField": "person_ext.person_id",
  "label": "Alpha extend",
  "note": "Base-row reference allowed by PAITD-011.",
  "itds": [
    {
      "id": "paitd-007-tenure-and-grade-context",
      "title": "Tenure And Grade Context Are Typed Inputs, Not Dashboard Math",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-007-tenure-and-grade-context"
    },
    {
      "id": "paitd-011-storage-model",
      "title": "Alpha Storage Is Views Over OneRoster Plus Extension Tables",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-011-storage-model"
    }
  ]
}
storage
{
  "kind": "alpha_extend_table",
  "source": "alpha.person_ext.person_id",
  "storageRule": "Stored only as the base-row reference for alpha.person_ext; it points at alpha.person_base and does not copy any OneRoster person attribute.",
  "writeRoute": "Write only after the matching alpha.person_base row exists; sourced person fields still route to the OneRoster 1EdTech users surface."
}

admission_date

title
Admission Date
type
DATE
publicApi
date on alpha.person.admission_date
nullability
Optional except where student-tenure reports require it.
required
Conditional
range
ISO 8601 date YYYY-MM-DD.
meaning
Date the student joined the school or program for tenure calculations.
constraints
Set at write time. Tenure bucket is computed by the surface from this date and asOfDate using alpha.policy.tenure_buckets.
relationship
Belongs to exactly one person_ext row and surfaces through alpha.person.
invalidWhen
Parsed from a cohort name, later than asOfDate for a current-tenure request, or hardcoded into a dashboard.
edgeCases
A non-student person may have null admission_date. Null means tenure is unknown, not zero.
example
2025-08-18
pii
Yes
allowedValues
[]
provenance
{
  "changeType": "extend",
  "sourceType": "alpha_extend_table",
  "source": "alpha.person_ext.admission_date",
  "sourceAnchor": null,
  "aliasMapField": "person_ext.admission_date",
  "label": "Alpha extend",
  "note": "Alpha extension required for tenure bands.",
  "itds": [
    {
      "id": "paitd-007-tenure-and-grade-context",
      "title": "Tenure And Grade Context Are Typed Inputs, Not Dashboard Math",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-007-tenure-and-grade-context"
    },
    {
      "id": "paitd-011-storage-model",
      "title": "Alpha Storage Is Views Over OneRoster Plus Extension Tables",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-011-storage-model"
    }
  ]
}
storage
{
  "kind": "alpha_extend_table",
  "source": "alpha.person_ext.admission_date",
  "storageRule": "Stored only in alpha.person_ext; allowed because admission date is an Alpha tenure-context extension, not a OneRoster field copy.",
  "writeRoute": "Write through the Alpha person extension path after the base person exists."
}

exit_date

title
Admission Date
type
DATE
publicApi
date on alpha.person.exit_date
nullability
Optional except where student-tenure reports require it.
required
Conditional
range
ISO 8601 date YYYY-MM-DD.
meaning
Exclusive person-level lifecycle close date for the school/program. Null means still active/open after admission_date when the source has not recorded an exit.
constraints
Set at write time. Tenure bucket is computed by the surface from this date and asOfDate using alpha.policy.tenure_buckets.
relationship
Belongs to exactly one person_ext row and surfaces through alpha.person. It is not the same fact as a membership end_date.
invalidWhen
Parsed from a cohort name, later than asOfDate for a current-tenure request, or hardcoded into a dashboard.
edgeCases
A person may have ended memberships without an exit_date; do not infer person exit from role/enrollment intervals. exit_date must be after admission_date when both are present.
example
2025-08-18
pii
Yes
allowedValues
[]
provenance
{
  "changeType": "extend",
  "sourceType": "alpha_extend_table",
  "source": "alpha.person_ext.admission_date",
  "sourceAnchor": null,
  "aliasMapField": "person_ext.admission_date",
  "label": "Alpha extend",
  "note": "Alpha extension required for tenure bands.",
  "itds": [
    {
      "id": "paitd-007-tenure-and-grade-context",
      "title": "Tenure And Grade Context Are Typed Inputs, Not Dashboard Math",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-007-tenure-and-grade-context"
    },
    {
      "id": "paitd-011-storage-model",
      "title": "Alpha Storage Is Views Over OneRoster Plus Extension Tables",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-011-storage-model"
    }
  ]
}
storage
{
  "kind": "alpha_extend_table",
  "source": "alpha.person_ext.exit_date",
  "storageRule": "Stored only in alpha.person_ext; allowed because exit date is an Alpha person-lifecycle extension, not a OneRoster field copy.",
  "writeRoute": "Write through the Alpha person extension path after the base person exists."
}

age_grade

title
Age Grade
type
INTEGER closed enum
publicApi
grade_level integer on alpha.person.age_grade
nullability
Optional except where age-grade cohort reports require it.
required
Conditional
range
Closed grade_level values: -1 for PreK, 0 for K, and 1 through 12.
meaning
Canonical age-grade context folded at write time from source grade aliases.
constraints
Never parse age_grade from a test name, class name, or display string. Alias folds are maintained by the surface and the canonical value is the grade_level integer.
relationship
Belongs to exactly one person_ext row and surfaces through alpha.person. Results owns working grade and advancement.
invalidWhen
Free text, parsed at read time, used as working grade/mastery, or outside -1, 0, and 1..12.
edgeCases
age_grade can differ from Results working grade. Source grade 13 is a live reconciliation finding and is not accepted as age_grade. Use alpha.age_grade_history for as-of-date age-grade questions.
example
7
pii
Yes
allowedValues
[
  {
    "value": "-1",
    "meaning": "PreK. Live source aliases validated 2026-06-09: -1 and PK fold here.",
    "useWhen": "Use for pre-kindergarten age-grade or enrolled-grade context.",
    "invalidWhen": "Invalid for kindergarten or any student grade 1 through 12."
  },
  {
    "value": "0",
    "meaning": "Kindergarten. Live source aliases validated 2026-06-09: 0 and K fold here.",
    "useWhen": "Use for kindergarten age-grade or enrolled-grade context.",
    "invalidWhen": "Invalid for PreK or any numbered grade."
  },
  {
    "value": "1",
    "meaning": "Grade 1.",
    "useWhen": "Use for grade 1 age-grade, enrolled-grade, or course grade-level context.",
    "invalidWhen": "Invalid when parsed from names, class titles, test labels, or free text at read time."
  },
  {
    "value": "2",
    "meaning": "Grade 2.",
    "useWhen": "Use for grade 2 age-grade, enrolled-grade, or course grade-level context.",
    "invalidWhen": "Invalid when parsed from names, class titles, test labels, or free text at read time."
  },
  {
    "value": "3",
    "meaning": "Grade 3.",
    "useWhen": "Use for grade 3 age-grade, enrolled-grade, or course grade-level context.",
    "invalidWhen": "Invalid when parsed from names, class titles, test labels, or free text at read time."
  },
  {
    "value": "4",
    "meaning": "Grade 4. Live source aliases validated 2026-06-09: 4, 4TH_GRADE, and Grade_4 fold here.",
    "useWhen": "Use for grade 4 age-grade, enrolled-grade, or course grade-level context.",
    "invalidWhen": "Invalid when parsed from names, class titles, test labels, or free text at read time."
  },
  {
    "value": "5",
    "meaning": "Grade 5.",
    "useWhen": "Use for grade 5 age-grade, enrolled-grade, or course grade-level context.",
    "invalidWhen": "Invalid when parsed from names, class titles, test labels, or free text at read time."
  },
  {
    "value": "6",
    "meaning": "Grade 6.",
    "useWhen": "Use for grade 6 age-grade, enrolled-grade, or course grade-level context.",
    "invalidWhen": "Invalid when parsed from names, class titles, test labels, or free text at read time."
  },
  {
    "value": "7",
    "meaning": "Grade 7.",
    "useWhen": "Use for grade 7 age-grade, enrolled-grade, or course grade-level context.",
    "invalidWhen": "Invalid when parsed from names, class titles, test labels, or free text at read time."
  },
  {
    "value": "8",
    "meaning": "Grade 8.",
    "useWhen": "Use for grade 8 age-grade, enrolled-grade, or course grade-level context.",
    "invalidWhen": "Invalid when parsed from names, class titles, test labels, or free text at read time."
  },
  {
    "value": "9",
    "meaning": "Grade 9.",
    "useWhen": "Use for grade 9 age-grade, enrolled-grade, or course grade-level context.",
    "invalidWhen": "Invalid when parsed from names, class titles, test labels, or free text at read time."
  },
  {
    "value": "10",
    "meaning": "Grade 10.",
    "useWhen": "Use for grade 10 age-grade, enrolled-grade, or course grade-level context.",
    "invalidWhen": "Invalid when parsed from names, class titles, test labels, or free text at read time."
  },
  {
    "value": "11",
    "meaning": "Grade 11.",
    "useWhen": "Use for grade 11 age-grade, enrolled-grade, or course grade-level context.",
    "invalidWhen": "Invalid when parsed from names, class titles, test labels, or free text at read time."
  },
  {
    "value": "12",
    "meaning": "Grade 12.",
    "useWhen": "Use for grade 12 age-grade, enrolled-grade, or course grade-level context.",
    "invalidWhen": "Invalid when parsed from names, class titles, test labels, or free text at read time."
  }
]
provenance
{
  "changeType": "extend",
  "sourceType": "alpha_extend_table",
  "source": "alpha.person_ext.age_grade",
  "sourceAnchor": null,
  "aliasMapField": "person_ext.age_grade",
  "label": "Alpha extend",
  "note": "Current convenience value; alpha.age_grade_history is the point-in-time system of record.",
  "itds": [
    {
      "id": "paitd-018-over-time-history",
      "title": "Alpha Level And Age Grade Keep Effective-Dated History, Read By AsOfDate",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-018-over-time-history"
    },
    {
      "id": "paitd-007-tenure-and-grade-context",
      "title": "Tenure And Grade Context Are Typed Inputs, Not Dashboard Math",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-007-tenure-and-grade-context"
    },
    {
      "id": "paitd-011-storage-model",
      "title": "Alpha Storage Is Views Over OneRoster Plus Extension Tables",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-011-storage-model"
    }
  ]
}
storage
{
  "kind": "alpha_extend_table",
  "source": "alpha.person_ext.age_grade",
  "storageRule": "Stored only in alpha.person_ext; allowed because canonical age-grade context is an Alpha extension, not a OneRoster field copy.",
  "writeRoute": "Write through the Alpha person extension path after the base person exists."
}

reality

title
Reality
type
TEXT enum
publicApi
real | test | synthetic on alpha.person.reality
nullability
Required for reportable person rows after the PAITD-017 write boundary.
required
Yes
range
Closed values: real, test, synthetic.
meaning
Typed reality classification surfaced through alpha.person.
constraints
Write from authoritative source classification only. The write boundary rejects missing or unclassified report rows instead of letting consumers infer from names.
relationship
Belongs to exactly one person_ext row and surfaces through alpha.person.
invalidWhen
Free text, inferred from names/emails, omitted from default report filters, or any value outside real/test/synthetic.
edgeCases
Synthetic demo fixtures stay synthetic even when they look like plausible students.
example
real
pii
No
allowedValues
[
  {
    "value": "real",
    "meaning": "A production student, person, school, district, or roster place that belongs in ordinary customer reports.",
    "useWhen": "Use for real TimeBack people and places after the write boundary has verified the source classification.",
    "invalidWhen": "Invalid for QA accounts, AI-agent test rows, generated fixtures, or demo-only entities."
  },
  {
    "value": "test",
    "meaning": "A QA, staff-test, integration-test, or AI-agent test entity that must be excluded from ordinary reports.",
    "useWhen": "Use for entities intentionally created to test the surface or another app.",
    "invalidWhen": "Invalid for production students or schools even if their display name looks unusual."
  },
  {
    "value": "synthetic",
    "meaning": "Generated, seeded, anonymized, or fixture data that is useful for demos or development but not a real customer row.",
    "useWhen": "Use for generated seed rows, local fixtures, and anonymized examples.",
    "invalidWhen": "Invalid for a row imported from the authoritative SIS or TimeBack production source as a real entity."
  }
]
provenance
{
  "changeType": "extend",
  "sourceType": "alpha_extend_table",
  "source": "alpha.person_ext.reality",
  "sourceAnchor": null,
  "aliasMapField": "person_ext.reality",
  "label": "Alpha extend",
  "note": "PAITD-017 Alpha extension required for real-only report defaults.",
  "itds": [
    {
      "id": "paitd-017-reality-flag",
      "title": "Reality Is A Typed Closed Flag On Person And Place, Set At Write Time",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-017-reality-flag"
    },
    {
      "id": "paitd-103-query-model",
      "title": "API Axis: Query Model",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-103-query-model"
    },
    {
      "id": "paitd-111-privacy-retention",
      "title": "API Axis: Privacy / Retention",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-111-privacy-retention"
    },
    {
      "id": "paitd-011-storage-model",
      "title": "Alpha Storage Is Views Over OneRoster Plus Extension Tables",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-011-storage-model"
    }
  ]
}
storage
{
  "kind": "alpha_extend_table",
  "source": "alpha.person_ext.reality",
  "storageRule": "Stored only in alpha.person_ext; allowed because real/test/synthetic classification is an Alpha reporting guardrail, not a OneRoster field copy.",
  "writeRoute": "Write through the Alpha person extension path from authoritative source classification; never infer from names, emails, or campus labels."
}

alpha.place_ext · Place Extension Storage

objectName
place_ext
apiCollection
storage-only; written through /places extension fields
storage
Alpha-owned extension table for place facts that OneRoster does not carry. It decorates alpha.place_base by tenant_id/place_id and is read through alpha.place.
changeType
extend
upstream
None; logical FK to alpha.place_base
baseView
alpha.place_base
coreWriteRoute
None. Sourced place fields route to the OneRoster 1EdTech orgs surface.
extensionWriteRoute
Write only place_id, nwea_district_id, and reality to alpha.place_ext after the alpha.place_base row exists.
primaryKey
(tenant_id, place_id)
purpose
The storage row that lets Alpha attach the NWEA account id and reality classification to a place without copying OneRoster org columns.
lifecycle
Created after the base place exists and only for places that need Alpha-owned place context. Updated when the NWEA account id or reality classification is corrected. Deleting the extension row removes Alpha account context but does not delete the base place.
auth
Not exposed as an ordinary roster collection. Reads appear through alpha.place; direct migration writes require schema/admin scope.
sourceType
alpha_extend
publicSurface
alpha.place_ext
baseSource
storageContract
anchor
table-alpha-place-ext
fieldCount
4
sourceAnchor
extensionTables
[
  "alpha.place_ext"
]
filters
[
  "placeId",
  "nweaDistrictId",
  "reality",
  "tenantId"
]
sortKeys
[
  "place_id",
  "nwea_district_id"
]
example
{
  "place_id": "place_timeback_physical_district",
  "nwea_district_id": "nwea-district-physical-001",
  "reality": "real"
}

Fields (4)

tenant_id

title
Tenant Id
type
UUID
publicApi
Hidden in ordinary Alpha responses; selected from the verified JWT.
nullability
Required on every stored row.
required
Yes
range
Valid PostgreSQL UUID.
meaning
The tenant boundary that owns this People & Orgs row.
constraints
Must equal the verified JWT tenant_id or tenantId claim. Never accept a tenant header or body field as source of truth.
relationship
Belongs to one platform.tenant. One tenant owns many People & Orgs rows.
invalidWhen
Missing, malformed, points to another tenant, or is supplied by an unverified request body.
edgeCases
Demo token minting may accept tenantId=demo, but stored rows still use the resolved tenant id.
example
0d4ce2f4-1c42-4f3c-9f0d-03fb7f5271d3
pii
No
allowedValues
[]
provenance
{
  "changeType": "inherited",
  "sourceType": "platform_shared",
  "source": "platform.tenant",
  "sourceAnchor": null,
  "aliasMapField": null,
  "label": "Alpha inherited",
  "note": "Inherited platform tenant routing field, not a OneRoster alias.",
  "itds": [
    {
      "id": "paitd-109-tenant-routing",
      "title": "API Axis: Tenant Routing",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-109-tenant-routing"
    }
  ]
}
storage
{
  "kind": "platform_inherited_column",
  "source": "platform.tenant / verified JWT tenant claim",
  "storageRule": "Inherited platform tenant key. It scopes base rows, extension rows, and views; it is not copied from OneRoster or Ed-Fi.",
  "writeRoute": "Resolved from the verified JWT tenant claim by the platform layer."
}

place_id

title
Place Id
type
TEXT
publicApi
storage foreign key; appears as place_id on alpha.place
nullability
Required.
required
Yes
range
1 to 255 printable characters.
meaning
The base place row this extension decorates.
constraints
Must match one alpha.place_base row in the same tenant before the extension row is written. One extension row per base place.
relationship
Logical foreign key to alpha.place_base(tenant_id, place_id); the physical database may enforce the same relationship against the underlying OneRoster base key.
invalidWhen
Missing, references a non-existent base place, crosses tenant, or is treated as the source of place identity.
edgeCases
A place can exist without a place_ext row; then nwea_district_id surfaces as null on alpha.place.
example
place_timeback_physical_district
pii
Identifier
allowedValues
[]
provenance
{
  "changeType": "extend",
  "sourceType": "alpha_extend_table",
  "source": "alpha.place_ext.place_id",
  "sourceAnchor": null,
  "aliasMapField": "place_ext.place_id",
  "label": "Alpha extend",
  "note": "Base-row reference allowed by PAITD-011.",
  "itds": [
    {
      "id": "paitd-003-place-nwea-boundary",
      "title": "Place Is The Plain Alias For OneRoster Org And District Is The NWEA Account",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-003-place-nwea-boundary"
    },
    {
      "id": "paitd-011-storage-model",
      "title": "Alpha Storage Is Views Over OneRoster Plus Extension Tables",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-011-storage-model"
    }
  ]
}
storage
{
  "kind": "alpha_extend_table",
  "source": "alpha.place_ext.place_id",
  "storageRule": "Stored only as the base-row reference for alpha.place_ext; it points at alpha.place_base and does not copy any OneRoster place attribute.",
  "writeRoute": "Write only after the matching alpha.place_base row exists; sourced place fields still route to the OneRoster 1EdTech orgs surface."
}

nwea_district_id

title
Nwea District Id
type
TEXT
publicApi
string on alpha.place.nwea_district_id
nullability
Required when place_kind=district and this place is the Brand x Modality NWEA account; invalid on school rows.
required
Conditional
range
NWEA account/district id supplied by NWEA account setup.
meaning
The NWEA district/account id for exactly one Brand x Modality account.
constraints
Must be stored on the district place extension row. Schools read it through parent_place_id; they do not carry a second copy.
relationship
Belongs to exactly one place_ext row and surfaces through alpha.place. NWEAMap ingest reads this through the OneRoster org tree.
invalidWhen
Missing on an NWEA district account, present for a school row, duplicated across two Brand x Modality district places, or stored as a tag.
edgeCases
Production org rows without typed brand/segment require reconciliation before they become NWEA-account rows.
example
nwea-district-physical-001
pii
No
allowedValues
[]
provenance
{
  "changeType": "extend",
  "sourceType": "alpha_extend_table",
  "source": "alpha.place_ext.nwea_district_id",
  "sourceAnchor": null,
  "aliasMapField": "place_ext.nwea_district_id",
  "label": "Alpha extend",
  "note": "Alpha extension required by the NWEA account boundary.",
  "itds": [
    {
      "id": "paitd-003-place-nwea-boundary",
      "title": "Place Is The Plain Alias For OneRoster Org And District Is The NWEA Account",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-003-place-nwea-boundary"
    },
    {
      "id": "paitd-011-storage-model",
      "title": "Alpha Storage Is Views Over OneRoster Plus Extension Tables",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-011-storage-model"
    }
  ]
}
storage
{
  "kind": "alpha_extend_table",
  "source": "alpha.place_ext.nwea_district_id",
  "storageRule": "Stored only in alpha.place_ext; allowed because the NWEA district/account id is an Alpha roster extension required for Brand x Modality reporting.",
  "writeRoute": "Write through the Alpha place extension path after the base place exists and place_kind is district."
}

reality

title
Reality
type
TEXT enum
publicApi
real | test | synthetic on alpha.place.reality
nullability
Required for reportable place rows after the PAITD-017 write boundary.
required
Yes
range
Closed values: real, test, synthetic.
meaning
Typed reality classification surfaced through alpha.place.
constraints
Write from authoritative source classification only. The write boundary rejects missing or unclassified report rows instead of letting consumers infer from names.
relationship
Belongs to exactly one place_ext row and surfaces through alpha.place.
invalidWhen
Free text, inferred from place names, omitted from default report filters, or any value outside real/test/synthetic.
edgeCases
A test campus can remain connected to a real district tree but ordinary reports still exclude it by reality.
example
real
pii
No
allowedValues
[
  {
    "value": "real",
    "meaning": "A production student, person, school, district, or roster place that belongs in ordinary customer reports.",
    "useWhen": "Use for real TimeBack people and places after the write boundary has verified the source classification.",
    "invalidWhen": "Invalid for QA accounts, AI-agent test rows, generated fixtures, or demo-only entities."
  },
  {
    "value": "test",
    "meaning": "A QA, staff-test, integration-test, or AI-agent test entity that must be excluded from ordinary reports.",
    "useWhen": "Use for entities intentionally created to test the surface or another app.",
    "invalidWhen": "Invalid for production students or schools even if their display name looks unusual."
  },
  {
    "value": "synthetic",
    "meaning": "Generated, seeded, anonymized, or fixture data that is useful for demos or development but not a real customer row.",
    "useWhen": "Use for generated seed rows, local fixtures, and anonymized examples.",
    "invalidWhen": "Invalid for a row imported from the authoritative SIS or TimeBack production source as a real entity."
  }
]
provenance
{
  "changeType": "extend",
  "sourceType": "alpha_extend_table",
  "source": "alpha.place_ext.reality",
  "sourceAnchor": null,
  "aliasMapField": "place_ext.reality",
  "label": "Alpha extend",
  "note": "PAITD-017 Alpha extension required for real-only report defaults.",
  "itds": [
    {
      "id": "paitd-017-reality-flag",
      "title": "Reality Is A Typed Closed Flag On Person And Place, Set At Write Time",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-017-reality-flag"
    },
    {
      "id": "paitd-103-query-model",
      "title": "API Axis: Query Model",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-103-query-model"
    },
    {
      "id": "paitd-111-privacy-retention",
      "title": "API Axis: Privacy / Retention",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-111-privacy-retention"
    },
    {
      "id": "paitd-011-storage-model",
      "title": "Alpha Storage Is Views Over OneRoster Plus Extension Tables",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-011-storage-model"
    }
  ]
}
storage
{
  "kind": "alpha_extend_table",
  "source": "alpha.place_ext.reality",
  "storageRule": "Stored only in alpha.place_ext; allowed because real/test/synthetic classification is an Alpha reporting guardrail, not a OneRoster org field copy.",
  "writeRoute": "Write through the Alpha place extension path from authoritative source classification; never infer from place names or campus labels."
}

alpha.alpha_level_history · Alpha Level History

objectName
alpha_level_history
apiCollection
/alpha_level_history
storage
Alpha-owned effective-dated history table for a student's Alpha level. It references alpha.person_base and does not copy OneRoster user fields.
changeType
extend
upstream
None; logical FK to alpha.person_base and source classification
baseView
coreWriteRoute
None.
extensionWriteRoute
Write effective-dated alpha.alpha_level_history rows with a person_id foreign key to the base person, after the base person exists. No OneRoster or Ed-Fi column is copied.
primaryKey
(tenant_id, history_id)
purpose
The over-time answer for alphaLevel(student, date). It keeps Alpha level history instead of replacing old context with one mutable current value.
lifecycle
Created when the source says a student's Alpha level interval starts. Closing an interval sets end_date; it does not delete history. Corrections update the interval with audit outside this dictionary.
auth
Readable to roster scopes allowed to see the student. Ordinary reports also require alpha.person.reality=real unless explicitly including test/synthetic rows.
sourceType
alpha_extend
publicSurface
alpha.alpha_level_history
baseSource
anchor
table-alpha-alpha-level-history
fieldCount
7
sourceAnchor
https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-018-over-time-history
extensionTables
[
  "alpha.alpha_level_history"
]
filters
[
  "personId",
  "alphaLevel",
  "asOfDate",
  "isTimeLocatable"
]
sortKeys
[
  "person_id",
  "begin_date",
  "end_date",
  "alpha_level"
]
storageContract
{
  "alphaObject": "alpha_level_history",
  "publicSurface": "alpha.alpha_level_history",
  "upstreamModule": "oneroster/1edtech",
  "baseSource": null,
  "baseView": null,
  "extensionTables": [
    "alpha.alpha_level_history"
  ],
  "coreWriteRoute": "None.",
  "extensionWriteRoute": "Write effective-dated alpha.alpha_level_history rows with a person_id foreign key to the base person, after the base person exists. No OneRoster or Ed-Fi column is copied.",
  "requiredShape": "CREATE TABLE is allowed because this is a pure Alpha extension."
}
example
{
  "history_id": "alpha_level_hist_ada_2026_ms",
  "person_id": "person_ada_lovelace",
  "alpha_level": "MS",
  "begin_date": "2026-08-15",
  "end_date": "2027-06-01",
  "is_time_locatable": true
}

Fields (7)

tenant_id

title
Tenant Id
type
UUID
publicApi
Hidden in ordinary Alpha responses; selected from the verified JWT.
nullability
Required on every stored row.
required
Yes
range
Valid PostgreSQL UUID.
meaning
The tenant boundary that owns this People & Orgs row.
constraints
Must equal the verified JWT tenant_id or tenantId claim. Never accept a tenant header or body field as source of truth.
relationship
Belongs to one platform.tenant. One tenant owns many People & Orgs rows.
invalidWhen
Missing, malformed, points to another tenant, or is supplied by an unverified request body.
edgeCases
Demo token minting may accept tenantId=demo, but stored rows still use the resolved tenant id.
example
0d4ce2f4-1c42-4f3c-9f0d-03fb7f5271d3
pii
No
allowedValues
[]
provenance
{
  "changeType": "inherited",
  "sourceType": "platform_shared",
  "source": "platform.tenant",
  "sourceAnchor": null,
  "aliasMapField": null,
  "label": "Alpha inherited",
  "note": "Inherited platform tenant routing field, not a OneRoster alias.",
  "itds": [
    {
      "id": "paitd-109-tenant-routing",
      "title": "API Axis: Tenant Routing",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-109-tenant-routing"
    }
  ]
}
storage
{
  "kind": "platform_inherited_column",
  "source": "platform.tenant / verified JWT tenant claim",
  "storageRule": "Inherited platform tenant key. It scopes base rows, extension rows, and views; it is not copied from OneRoster or Ed-Fi.",
  "writeRoute": "Resolved from the verified JWT tenant claim by the platform layer."
}

history_id

title
History Id
type
TEXT
publicApi
string
nullability
Required.
required
Yes
range
1 to 255 printable characters, unique within tenant.
meaning
Stable id for one Alpha-level history interval.
constraints
Must not be derived from the student's display name. Keep stable across corrections to the same interval.
relationship
Primary identifier for this Alpha-owned history row.
invalidWhen
Blank, reused for another interval, crosses tenant, or treated as a person id.
edgeCases
A person can have multiple non-overlapping Alpha-level intervals over time.
example
alpha_level_hist_ada_2026_ms
pii
Identifier
allowedValues
[]
provenance
{
  "changeType": "extend",
  "sourceType": "alpha_extend_table",
  "source": "alpha.alpha_level_history.history_id",
  "sourceAnchor": null,
  "aliasMapField": "alpha_level_history.history_id",
  "label": "Alpha extend",
  "note": "PAITD-018 over-time extension row id.",
  "itds": [
    {
      "id": "paitd-018-over-time-history",
      "title": "Alpha Level And Age Grade Keep Effective-Dated History, Read By AsOfDate",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-018-over-time-history"
    },
    {
      "id": "paitd-004-point-in-time-memberships",
      "title": "Memberships Are Effective-Dated And Answered By AsOfDate",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-004-point-in-time-memberships"
    },
    {
      "id": "paitd-007-tenure-and-grade-context",
      "title": "Tenure And Grade Context Are Typed Inputs, Not Dashboard Math",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-007-tenure-and-grade-context"
    },
    {
      "id": "paitd-011-storage-model",
      "title": "Alpha Storage Is Views Over OneRoster Plus Extension Tables",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-011-storage-model"
    }
  ]
}
storage
{
  "kind": "alpha_extend_table",
  "source": "alpha.alpha_level_history.history_id",
  "storageRule": "Stored only as the Alpha-owned history row id; it does not copy OneRoster or Ed-Fi state.",
  "writeRoute": "Write when the source classification says a student's Alpha level changed."
}

person_id

title
Person Id
type
TEXT
publicApi
person id
nullability
Required.
required
Yes
range
1 to 255 printable characters.
meaning
The student person whose Alpha level this interval describes.
constraints
Must reference alpha.person.person_id in the same tenant and that person must be reportable as a student for student-level reports.
relationship
Many Alpha-level history rows can belong to one person.
invalidWhen
Missing, references another tenant, points at a deleted/nonexistent person, or is stored as a tag.
edgeCases
The relationship can exist before a student has active membership on the requested asOfDate; report queries still apply the membership and reality filters separately.
example
person_ada_lovelace
pii
Identifier
allowedValues
[]
provenance
{
  "changeType": "extend",
  "sourceType": "alpha_extend_table",
  "source": "alpha.alpha_level_history.person_id",
  "sourceAnchor": null,
  "aliasMapField": "alpha_level_history.person_id",
  "label": "Alpha extend",
  "note": "Base-row reference allowed by PAITD-011 and PAITD-018.",
  "itds": [
    {
      "id": "paitd-018-over-time-history",
      "title": "Alpha Level And Age Grade Keep Effective-Dated History, Read By AsOfDate",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-018-over-time-history"
    },
    {
      "id": "paitd-002-person-vocabulary",
      "title": "Person Is The Plain Alias For OneRoster User",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-002-person-vocabulary"
    },
    {
      "id": "paitd-004-point-in-time-memberships",
      "title": "Memberships Are Effective-Dated And Answered By AsOfDate",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-004-point-in-time-memberships"
    },
    {
      "id": "paitd-011-storage-model",
      "title": "Alpha Storage Is Views Over OneRoster Plus Extension Tables",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-011-storage-model"
    }
  ]
}
storage
{
  "kind": "alpha_extend_table",
  "source": "alpha.alpha_level_history.person_id",
  "storageRule": "Stored only as a same-tenant reference to the base person row.",
  "writeRoute": "Write only after the matching alpha.person_base row exists."
}

alpha_level

title
Alpha Level
type
TEXT closed enum
publicApi
WL | LL | L1 | L2 | MS | HS
nullability
Required.
required
Yes
range
Closed values: WL, LL, L1, L2, MS, HS.
meaning
Canonical Alpha level for this student's effective-dated interval.
constraints
Fold source labels through alpha.policy.alpha_level_alias_folds at write time. Do not parse Alpha level from school, class, or cohort names at read time.
relationship
No foreign key; it is a governed cohort field for People & Orgs reports.
invalidWhen
Free text, null, outside the closed enum, parsed at read time, or used as Results mastery state.
edgeCases
A student's Alpha level can change without changing age_grade or working grade.
example
MS
pii
Yes
allowedValues
[
  {
    "value": "WL",
    "meaning": "WonderLab, the pre-K Alpha level. Live source alias validated 2026-06-09: PKBY folds here.",
    "useWhen": "Use for the pre-K Alpha level, point-in-time as of the roster date.",
    "invalidWhen": "Invalid for kindergarten, LearningLab, or any grade-level placement."
  },
  {
    "value": "LL",
    "meaning": "LearningLab, the K-1 Alpha level. Live source alias validated 2026-06-09: Linc folds here.",
    "useWhen": "Use for K-1 Alpha-level grouping, point-in-time as of the roster date.",
    "invalidWhen": "Invalid for WonderLab or numbered upper levels."
  },
  {
    "value": "L1",
    "meaning": "Level 1, the grade 2-3 Alpha level after live cohort confirmation.",
    "useWhen": "Use for the Alpha level spanning grade 2 through grade 3.",
    "invalidWhen": "Invalid for grade 4+ cohorts or for MAP working-grade state."
  },
  {
    "value": "L2",
    "meaning": "Level 2, the grade 4-5 Alpha level after live cohort confirmation.",
    "useWhen": "Use for the Alpha level spanning grade 4 through grade 5.",
    "invalidWhen": "Invalid for grade 2-3, middle school, high school, or Results working-grade state."
  },
  {
    "value": "MS",
    "meaning": "Middle School, the grade 6-8 Alpha level. Live source aliases validated 2026-06-09: Middle School and L3 fold here.",
    "useWhen": "Use for middle-school Alpha-level grouping.",
    "invalidWhen": "Invalid for high school or elementary level rows."
  },
  {
    "value": "HS",
    "meaning": "High School, the grade 9-12 Alpha level. Live source aliases validated 2026-06-09: High School, L4.1, L4.2, and L4.3 fold here.",
    "useWhen": "Use for high-school Alpha-level grouping.",
    "invalidWhen": "Invalid for middle-school or elementary level rows."
  }
]
provenance
{
  "changeType": "extend",
  "sourceType": "alpha_extend_table",
  "source": "alpha.alpha_level_history.alpha_level",
  "sourceAnchor": null,
  "aliasMapField": "alpha_level_history.alpha_level",
  "label": "Alpha extend",
  "note": "PAITD-018 alpha-level over-time decision.",
  "itds": [
    {
      "id": "paitd-018-over-time-history",
      "title": "Alpha Level And Age Grade Keep Effective-Dated History, Read By AsOfDate",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-018-over-time-history"
    },
    {
      "id": "paitd-007-tenure-and-grade-context",
      "title": "Tenure And Grade Context Are Typed Inputs, Not Dashboard Math",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-007-tenure-and-grade-context"
    },
    {
      "id": "paitd-103-query-model",
      "title": "API Axis: Query Model",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-103-query-model"
    }
  ]
}
storage
{
  "kind": "alpha_extend_table",
  "source": "alpha.alpha_level_history.alpha_level",
  "storageRule": "Stored only as the canonical Alpha level for this effective-dated interval.",
  "writeRoute": "Fold source labels through alpha.policy.alpha_level_alias_folds at write time."
}

begin_date

title
Begin Date
type
DATE
publicApi
date
nullability
Nullable storage, but begin_date null means not time-locatable and excluded from every point-in-time computation.
required
No
range
ISO 8601 date YYYY-MM-DD.
meaning
Inclusive date when this Alpha-level interval becomes locatable.
constraints
begin_date NULL => the row has no locatable start and is EXCLUDED from every point-in-time computation. Active-as-of requires begin_date <= asOfDate.
relationship
No foreign key; used by alphaLevel(student, date).
invalidWhen
Malformed, after end_date when end_date is present, or ignored by a current-only shortcut.
edgeCases
begin_date null plus end_date present is still excluded from point-in-time computations.
example
2026-08-15
pii
No
allowedValues
[]
provenance
{
  "changeType": "extend",
  "sourceType": "alpha_extend_table",
  "source": "alpha.alpha_level_history.begin_date",
  "sourceAnchor": null,
  "aliasMapField": "alpha_level_history.begin_date",
  "label": "Alpha extend",
  "note": "Same null rule as membership rows.",
  "itds": [
    {
      "id": "paitd-018-over-time-history",
      "title": "Alpha Level And Age Grade Keep Effective-Dated History, Read By AsOfDate",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-018-over-time-history"
    },
    {
      "id": "paitd-004-point-in-time-memberships",
      "title": "Memberships Are Effective-Dated And Answered By AsOfDate",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-004-point-in-time-memberships"
    },
    {
      "id": "paitd-103-query-model",
      "title": "API Axis: Query Model",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-103-query-model"
    }
  ]
}
storage
{
  "kind": "alpha_extend_table",
  "source": "alpha.alpha_level_history.begin_date",
  "storageRule": "Stored only as the effective-dated interval start for the Alpha level row.",
  "writeRoute": "Write from the authoritative source interval; null makes the row not time-locatable."
}

end_date

title
End Date
type
DATE
publicApi
date
nullability
Optional. Null means still active for dates on or after begin_date.
required
No
range
ISO 8601 date YYYY-MM-DD.
meaning
Exclusive date when this Alpha-level interval stops being active.
constraints
end_date NULL => still active, included for any asOfDate >= begin_date. Both begin_date and end_date NULL => always excluded.
relationship
No foreign key; used by alphaLevel(student, date).
invalidWhen
Malformed, on/before begin_date for the same interval, or treated as inclusive.
edgeCases
A closed interval remains queryable historically; do not delete it to make a current report work.
example
2027-06-01
pii
No
allowedValues
[]
provenance
{
  "changeType": "extend",
  "sourceType": "alpha_extend_table",
  "source": "alpha.alpha_level_history.end_date",
  "sourceAnchor": null,
  "aliasMapField": "alpha_level_history.end_date",
  "label": "Alpha extend",
  "note": "Same null rule as membership rows.",
  "itds": [
    {
      "id": "paitd-018-over-time-history",
      "title": "Alpha Level And Age Grade Keep Effective-Dated History, Read By AsOfDate",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-018-over-time-history"
    },
    {
      "id": "paitd-004-point-in-time-memberships",
      "title": "Memberships Are Effective-Dated And Answered By AsOfDate",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-004-point-in-time-memberships"
    },
    {
      "id": "paitd-103-query-model",
      "title": "API Axis: Query Model",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-103-query-model"
    }
  ]
}
storage
{
  "kind": "alpha_extend_table",
  "source": "alpha.alpha_level_history.end_date",
  "storageRule": "Stored only as the effective-dated interval end for the Alpha level row.",
  "writeRoute": "Write null only when the interval is still active after begin_date."
}

is_time_locatable

title
Is Time Locatable
type
BOOLEAN
publicApi
boolean
nullability
Required derived field.
required
Yes
range
true or false.
meaning
True only when begin_date is non-null; consumers filter on this instead of guessing from nulls.
constraints
Derived by the surface from begin_date. Do not let consumers recompute a different null rule.
relationship
No foreign key; query input to alphaLevel(student, date).
invalidWhen
True when begin_date is null, false when begin_date is present, or omitted from history responses.
edgeCases
end_date null does not make the row unlocatable; begin_date is the only locatability switch.
example
true
pii
No
allowedValues
[
  {
    "value": "true",
    "meaning": "The fact is asserted by the source or by the Alpha surface.",
    "useWhen": "Use only when the field's own constraints say the fact is true.",
    "invalidWhen": "Invalid when guessed from names, labels, dates, tags, or another field."
  },
  {
    "value": "false",
    "meaning": "The fact is explicitly not asserted.",
    "useWhen": "Use only when the source or surface stores an explicit false value.",
    "invalidWhen": "Invalid when a missing value should remain unknown."
  }
]
provenance
{
  "changeType": "restrict",
  "sourceType": "view_expression",
  "source": "view expression: alpha.alpha_level_history.begin_date IS NOT NULL",
  "sourceAnchor": null,
  "aliasMapField": "alpha_level_history.is_time_locatable",
  "label": "Alpha derived view field",
  "note": "PAITD-018 over-time derived field. No Alpha table stores it.",
  "itds": [
    {
      "id": "paitd-018-over-time-history",
      "title": "Alpha Level And Age Grade Keep Effective-Dated History, Read By AsOfDate",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-018-over-time-history"
    },
    {
      "id": "paitd-004-point-in-time-memberships",
      "title": "Memberships Are Effective-Dated And Answered By AsOfDate",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-004-point-in-time-memberships"
    },
    {
      "id": "paitd-103-query-model",
      "title": "API Axis: Query Model",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-103-query-model"
    }
  ]
}
storage
{
  "kind": "view_derived",
  "source": "view expression: alpha.alpha_level_history.begin_date IS NOT NULL",
  "storageRule": "Derived by the public view from begin_date; no separate Alpha column stores a second truth.",
  "writeRoute": "Not writable; recomputed by the view from begin_date."
}

alpha.age_grade_history · Age Grade History

objectName
age_grade_history
apiCollection
/age_grade_history
storage
Alpha-owned effective-dated history table for a student's age-grade context. It references alpha.person_base and does not copy OneRoster user fields.
changeType
extend
upstream
None; logical FK to alpha.person_base and source grade classification
baseView
coreWriteRoute
None.
extensionWriteRoute
Write effective-dated alpha.age_grade_history rows with a person_id foreign key to the base person, after the base person exists. No OneRoster or Ed-Fi column is copied.
primaryKey
(tenant_id, history_id)
purpose
The over-time answer for ageGrade(student, date). It keeps age-grade history instead of replacing old context with one mutable current value.
lifecycle
Created when the source says a student's age-grade interval starts. Closing an interval sets end_date; it does not delete history.
auth
Readable to roster scopes allowed to see the student. Ordinary reports also require alpha.person.reality=real unless explicitly including test/synthetic rows.
sourceType
alpha_extend
publicSurface
alpha.age_grade_history
baseSource
anchor
table-alpha-age-grade-history
fieldCount
7
sourceAnchor
https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-018-over-time-history
extensionTables
[
  "alpha.age_grade_history"
]
filters
[
  "personId",
  "ageGrade",
  "asOfDate",
  "isTimeLocatable"
]
sortKeys
[
  "person_id",
  "begin_date",
  "end_date",
  "age_grade"
]
storageContract
{
  "alphaObject": "age_grade_history",
  "publicSurface": "alpha.age_grade_history",
  "upstreamModule": "oneroster/1edtech",
  "baseSource": null,
  "baseView": null,
  "extensionTables": [
    "alpha.age_grade_history"
  ],
  "coreWriteRoute": "None.",
  "extensionWriteRoute": "Write effective-dated alpha.age_grade_history rows with a person_id foreign key to the base person, after the base person exists. No OneRoster or Ed-Fi column is copied.",
  "requiredShape": "CREATE TABLE is allowed because this is a pure Alpha extension."
}
example
{
  "history_id": "age_grade_hist_ada_2026_7",
  "person_id": "person_ada_lovelace",
  "age_grade": 7,
  "begin_date": "2026-08-15",
  "end_date": "2027-06-01",
  "is_time_locatable": true
}

Fields (7)

tenant_id

title
Tenant Id
type
UUID
publicApi
Hidden in ordinary Alpha responses; selected from the verified JWT.
nullability
Required on every stored row.
required
Yes
range
Valid PostgreSQL UUID.
meaning
The tenant boundary that owns this People & Orgs row.
constraints
Must equal the verified JWT tenant_id or tenantId claim. Never accept a tenant header or body field as source of truth.
relationship
Belongs to one platform.tenant. One tenant owns many People & Orgs rows.
invalidWhen
Missing, malformed, points to another tenant, or is supplied by an unverified request body.
edgeCases
Demo token minting may accept tenantId=demo, but stored rows still use the resolved tenant id.
example
0d4ce2f4-1c42-4f3c-9f0d-03fb7f5271d3
pii
No
allowedValues
[]
provenance
{
  "changeType": "inherited",
  "sourceType": "platform_shared",
  "source": "platform.tenant",
  "sourceAnchor": null,
  "aliasMapField": null,
  "label": "Alpha inherited",
  "note": "Inherited platform tenant routing field, not a OneRoster alias.",
  "itds": [
    {
      "id": "paitd-109-tenant-routing",
      "title": "API Axis: Tenant Routing",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-109-tenant-routing"
    }
  ]
}
storage
{
  "kind": "platform_inherited_column",
  "source": "platform.tenant / verified JWT tenant claim",
  "storageRule": "Inherited platform tenant key. It scopes base rows, extension rows, and views; it is not copied from OneRoster or Ed-Fi.",
  "writeRoute": "Resolved from the verified JWT tenant claim by the platform layer."
}

history_id

title
History Id
type
TEXT
publicApi
string
nullability
Required.
required
Yes
range
1 to 255 printable characters, unique within tenant.
meaning
Stable id for one age-grade history interval.
constraints
Must not be derived from the student's display name. Keep stable across corrections to the same interval.
relationship
Primary identifier for this Alpha-owned history row.
invalidWhen
Blank, reused for another interval, crosses tenant, or treated as a person id.
edgeCases
A person can have multiple non-overlapping age-grade intervals over time.
example
age_grade_hist_ada_2026_7
pii
Identifier
allowedValues
[]
provenance
{
  "changeType": "extend",
  "sourceType": "alpha_extend_table",
  "source": "alpha.age_grade_history.history_id",
  "sourceAnchor": null,
  "aliasMapField": "age_grade_history.history_id",
  "label": "Alpha extend",
  "note": "PAITD-018 age-grade history extension row id.",
  "itds": [
    {
      "id": "paitd-018-over-time-history",
      "title": "Alpha Level And Age Grade Keep Effective-Dated History, Read By AsOfDate",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-018-over-time-history"
    },
    {
      "id": "paitd-004-point-in-time-memberships",
      "title": "Memberships Are Effective-Dated And Answered By AsOfDate",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-004-point-in-time-memberships"
    },
    {
      "id": "paitd-007-tenure-and-grade-context",
      "title": "Tenure And Grade Context Are Typed Inputs, Not Dashboard Math",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-007-tenure-and-grade-context"
    },
    {
      "id": "paitd-011-storage-model",
      "title": "Alpha Storage Is Views Over OneRoster Plus Extension Tables",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-011-storage-model"
    }
  ]
}
storage
{
  "kind": "alpha_extend_table",
  "source": "alpha.age_grade_history.history_id",
  "storageRule": "Stored only as the Alpha-owned history row id; it does not copy OneRoster or Ed-Fi state.",
  "writeRoute": "Write when the source classification says a student's age-grade context changed."
}

person_id

title
Person Id
type
TEXT
publicApi
person id
nullability
Required.
required
Yes
range
1 to 255 printable characters.
meaning
The student person whose age-grade context this interval describes.
constraints
Must reference alpha.person.person_id in the same tenant and that person must be reportable as a student for student-level reports.
relationship
Many age-grade history rows can belong to one person.
invalidWhen
Missing, references another tenant, points at a deleted/nonexistent person, or is stored as a tag.
edgeCases
The relationship can exist before a student has active membership on the requested asOfDate; report queries still apply the membership and reality filters separately.
example
person_ada_lovelace
pii
Identifier
allowedValues
[]
provenance
{
  "changeType": "extend",
  "sourceType": "alpha_extend_table",
  "source": "alpha.age_grade_history.person_id",
  "sourceAnchor": null,
  "aliasMapField": "age_grade_history.person_id",
  "label": "Alpha extend",
  "note": "Base-row reference allowed by PAITD-011 and PAITD-018.",
  "itds": [
    {
      "id": "paitd-018-over-time-history",
      "title": "Alpha Level And Age Grade Keep Effective-Dated History, Read By AsOfDate",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-018-over-time-history"
    },
    {
      "id": "paitd-002-person-vocabulary",
      "title": "Person Is The Plain Alias For OneRoster User",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-002-person-vocabulary"
    },
    {
      "id": "paitd-004-point-in-time-memberships",
      "title": "Memberships Are Effective-Dated And Answered By AsOfDate",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-004-point-in-time-memberships"
    },
    {
      "id": "paitd-011-storage-model",
      "title": "Alpha Storage Is Views Over OneRoster Plus Extension Tables",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-011-storage-model"
    }
  ]
}
storage
{
  "kind": "alpha_extend_table",
  "source": "alpha.age_grade_history.person_id",
  "storageRule": "Stored only as a same-tenant reference to the base person row.",
  "writeRoute": "Write only after the matching alpha.person_base row exists."
}

age_grade

title
Age Grade
type
INTEGER closed enum
publicApi
grade_level integer
nullability
Required.
required
Yes
range
Closed grade_level values: -1 for PreK, 0 for K, and 1 through 12.
meaning
Canonical age-grade context for this student's effective-dated interval.
constraints
Fold source grade labels through alpha.policy.grade_alias_folds at write time. Never parse age_grade from test names, class names, or display strings at read time.
relationship
No foreign key; Results owns working grade and advancement.
invalidWhen
Free text, null, parsed at read time, used as working grade/mastery, or outside -1, 0, and 1..12.
edgeCases
age_grade can differ from Results working grade and can change over time independently from Alpha level.
example
7
pii
Yes
allowedValues
[
  {
    "value": "-1",
    "meaning": "PreK. Live source aliases validated 2026-06-09: -1 and PK fold here.",
    "useWhen": "Use for pre-kindergarten age-grade or enrolled-grade context.",
    "invalidWhen": "Invalid for kindergarten or any student grade 1 through 12."
  },
  {
    "value": "0",
    "meaning": "Kindergarten. Live source aliases validated 2026-06-09: 0 and K fold here.",
    "useWhen": "Use for kindergarten age-grade or enrolled-grade context.",
    "invalidWhen": "Invalid for PreK or any numbered grade."
  },
  {
    "value": "1",
    "meaning": "Grade 1.",
    "useWhen": "Use for grade 1 age-grade, enrolled-grade, or course grade-level context.",
    "invalidWhen": "Invalid when parsed from names, class titles, test labels, or free text at read time."
  },
  {
    "value": "2",
    "meaning": "Grade 2.",
    "useWhen": "Use for grade 2 age-grade, enrolled-grade, or course grade-level context.",
    "invalidWhen": "Invalid when parsed from names, class titles, test labels, or free text at read time."
  },
  {
    "value": "3",
    "meaning": "Grade 3.",
    "useWhen": "Use for grade 3 age-grade, enrolled-grade, or course grade-level context.",
    "invalidWhen": "Invalid when parsed from names, class titles, test labels, or free text at read time."
  },
  {
    "value": "4",
    "meaning": "Grade 4. Live source aliases validated 2026-06-09: 4, 4TH_GRADE, and Grade_4 fold here.",
    "useWhen": "Use for grade 4 age-grade, enrolled-grade, or course grade-level context.",
    "invalidWhen": "Invalid when parsed from names, class titles, test labels, or free text at read time."
  },
  {
    "value": "5",
    "meaning": "Grade 5.",
    "useWhen": "Use for grade 5 age-grade, enrolled-grade, or course grade-level context.",
    "invalidWhen": "Invalid when parsed from names, class titles, test labels, or free text at read time."
  },
  {
    "value": "6",
    "meaning": "Grade 6.",
    "useWhen": "Use for grade 6 age-grade, enrolled-grade, or course grade-level context.",
    "invalidWhen": "Invalid when parsed from names, class titles, test labels, or free text at read time."
  },
  {
    "value": "7",
    "meaning": "Grade 7.",
    "useWhen": "Use for grade 7 age-grade, enrolled-grade, or course grade-level context.",
    "invalidWhen": "Invalid when parsed from names, class titles, test labels, or free text at read time."
  },
  {
    "value": "8",
    "meaning": "Grade 8.",
    "useWhen": "Use for grade 8 age-grade, enrolled-grade, or course grade-level context.",
    "invalidWhen": "Invalid when parsed from names, class titles, test labels, or free text at read time."
  },
  {
    "value": "9",
    "meaning": "Grade 9.",
    "useWhen": "Use for grade 9 age-grade, enrolled-grade, or course grade-level context.",
    "invalidWhen": "Invalid when parsed from names, class titles, test labels, or free text at read time."
  },
  {
    "value": "10",
    "meaning": "Grade 10.",
    "useWhen": "Use for grade 10 age-grade, enrolled-grade, or course grade-level context.",
    "invalidWhen": "Invalid when parsed from names, class titles, test labels, or free text at read time."
  },
  {
    "value": "11",
    "meaning": "Grade 11.",
    "useWhen": "Use for grade 11 age-grade, enrolled-grade, or course grade-level context.",
    "invalidWhen": "Invalid when parsed from names, class titles, test labels, or free text at read time."
  },
  {
    "value": "12",
    "meaning": "Grade 12.",
    "useWhen": "Use for grade 12 age-grade, enrolled-grade, or course grade-level context.",
    "invalidWhen": "Invalid when parsed from names, class titles, test labels, or free text at read time."
  }
]
provenance
{
  "changeType": "extend",
  "sourceType": "alpha_extend_table",
  "source": "alpha.age_grade_history.age_grade",
  "sourceAnchor": null,
  "aliasMapField": "age_grade_history.age_grade",
  "label": "Alpha extend",
  "note": "PAITD-018 age-grade history decision.",
  "itds": [
    {
      "id": "paitd-018-over-time-history",
      "title": "Alpha Level And Age Grade Keep Effective-Dated History, Read By AsOfDate",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-018-over-time-history"
    },
    {
      "id": "paitd-007-tenure-and-grade-context",
      "title": "Tenure And Grade Context Are Typed Inputs, Not Dashboard Math",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-007-tenure-and-grade-context"
    },
    {
      "id": "paitd-103-query-model",
      "title": "API Axis: Query Model",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-103-query-model"
    }
  ]
}
storage
{
  "kind": "alpha_extend_table",
  "source": "alpha.age_grade_history.age_grade",
  "storageRule": "Stored only as the canonical age grade for this effective-dated interval.",
  "writeRoute": "Fold source grade labels through alpha.policy.grade_alias_folds at write time."
}

begin_date

title
Begin Date
type
DATE
publicApi
date
nullability
Nullable storage, but begin_date null means not time-locatable and excluded from every point-in-time computation.
required
No
range
ISO 8601 date YYYY-MM-DD.
meaning
Inclusive date when this age-grade interval becomes locatable.
constraints
begin_date NULL => the row has no locatable start and is EXCLUDED from every point-in-time computation. Active-as-of requires begin_date <= asOfDate.
relationship
No foreign key; used by ageGrade(student, date).
invalidWhen
Malformed, after end_date when end_date is present, or ignored by a current-only shortcut.
edgeCases
begin_date null plus end_date present is still excluded from point-in-time computations.
example
2026-08-15
pii
No
allowedValues
[]
provenance
{
  "changeType": "extend",
  "sourceType": "alpha_extend_table",
  "source": "alpha.age_grade_history.begin_date",
  "sourceAnchor": null,
  "aliasMapField": "age_grade_history.begin_date",
  "label": "Alpha extend",
  "note": "Same null rule as membership rows.",
  "itds": [
    {
      "id": "paitd-018-over-time-history",
      "title": "Alpha Level And Age Grade Keep Effective-Dated History, Read By AsOfDate",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-018-over-time-history"
    },
    {
      "id": "paitd-004-point-in-time-memberships",
      "title": "Memberships Are Effective-Dated And Answered By AsOfDate",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-004-point-in-time-memberships"
    },
    {
      "id": "paitd-103-query-model",
      "title": "API Axis: Query Model",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-103-query-model"
    }
  ]
}
storage
{
  "kind": "alpha_extend_table",
  "source": "alpha.age_grade_history.begin_date",
  "storageRule": "Stored only as the effective-dated interval start for the age-grade row.",
  "writeRoute": "Write from the authoritative source interval; null makes the row not time-locatable."
}

end_date

title
End Date
type
DATE
publicApi
date
nullability
Optional. Null means still active for dates on or after begin_date.
required
No
range
ISO 8601 date YYYY-MM-DD.
meaning
Exclusive date when this age-grade interval stops being active.
constraints
end_date NULL => still active, included for any asOfDate >= begin_date. Both begin_date and end_date NULL => always excluded.
relationship
No foreign key; used by ageGrade(student, date).
invalidWhen
Malformed, on/before begin_date for the same interval, or treated as inclusive.
edgeCases
A closed interval remains queryable historically; do not delete it to make a current report work.
example
2027-06-01
pii
No
allowedValues
[]
provenance
{
  "changeType": "extend",
  "sourceType": "alpha_extend_table",
  "source": "alpha.age_grade_history.end_date",
  "sourceAnchor": null,
  "aliasMapField": "age_grade_history.end_date",
  "label": "Alpha extend",
  "note": "Same null rule as membership rows.",
  "itds": [
    {
      "id": "paitd-018-over-time-history",
      "title": "Alpha Level And Age Grade Keep Effective-Dated History, Read By AsOfDate",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-018-over-time-history"
    },
    {
      "id": "paitd-004-point-in-time-memberships",
      "title": "Memberships Are Effective-Dated And Answered By AsOfDate",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-004-point-in-time-memberships"
    },
    {
      "id": "paitd-103-query-model",
      "title": "API Axis: Query Model",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-103-query-model"
    }
  ]
}
storage
{
  "kind": "alpha_extend_table",
  "source": "alpha.age_grade_history.end_date",
  "storageRule": "Stored only as the effective-dated interval end for the age-grade row.",
  "writeRoute": "Write null only when the interval is still active after begin_date."
}

is_time_locatable

title
Is Time Locatable
type
BOOLEAN
publicApi
boolean
nullability
Required derived field.
required
Yes
range
true or false.
meaning
True only when begin_date is non-null; consumers filter on this instead of guessing from nulls.
constraints
Derived by the surface from begin_date. Do not let consumers recompute a different null rule.
relationship
No foreign key; query input to ageGrade(student, date).
invalidWhen
True when begin_date is null, false when begin_date is present, or omitted from history responses.
edgeCases
end_date null does not make the row unlocatable; begin_date is the only locatability switch.
example
true
pii
No
allowedValues
[
  {
    "value": "true",
    "meaning": "The fact is asserted by the source or by the Alpha surface.",
    "useWhen": "Use only when the field's own constraints say the fact is true.",
    "invalidWhen": "Invalid when guessed from names, labels, dates, tags, or another field."
  },
  {
    "value": "false",
    "meaning": "The fact is explicitly not asserted.",
    "useWhen": "Use only when the source or surface stores an explicit false value.",
    "invalidWhen": "Invalid when a missing value should remain unknown."
  }
]
provenance
{
  "changeType": "restrict",
  "sourceType": "view_expression",
  "source": "view expression: alpha.age_grade_history.begin_date IS NOT NULL",
  "sourceAnchor": null,
  "aliasMapField": "age_grade_history.is_time_locatable",
  "label": "Alpha derived view field",
  "note": "PAITD-018 over-time derived field. No Alpha table stores it.",
  "itds": [
    {
      "id": "paitd-018-over-time-history",
      "title": "Alpha Level And Age Grade Keep Effective-Dated History, Read By AsOfDate",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-018-over-time-history"
    },
    {
      "id": "paitd-004-point-in-time-memberships",
      "title": "Memberships Are Effective-Dated And Answered By AsOfDate",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-004-point-in-time-memberships"
    },
    {
      "id": "paitd-103-query-model",
      "title": "API Axis: Query Model",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-103-query-model"
    }
  ]
}
storage
{
  "kind": "view_derived",
  "source": "view expression: alpha.age_grade_history.begin_date IS NOT NULL",
  "storageRule": "Derived by the public view from begin_date; no separate Alpha column stores a second truth.",
  "writeRoute": "Not writable; recomputed by the view from begin_date."
}

alpha.place_membership · Place Membership

objectName
place_membership
apiCollection
/place_memberships
storage
Public view alpha.place_membership selects from alpha.place_membership_base over oneroster.roles. is_time_locatable is a view expression; this object has no Alpha table.
changeType
rename + restrict
upstream
oneroster.roles
primaryKey
(tenant_id, membership_id)
purpose
A dated relationship saying what one person is in one place, such as parent, guardian, guide, student, administrator, or staff.
lifecycle
Created from OneRoster role rows or Alpha membership commands. Active roster questions are always answered by asOfDate and the begin/end date null rule.
auth
Readable to scopes that can see the person and place. Family relationships require relationship-scoped claims.
sourceType
1edtech_alias_view
publicSurface
alpha.place_membership
baseView
alpha.place_membership_base
baseSource
oneroster.roles
coreWriteRoute
Route all writes to the OneRoster 1EdTech roles surface.
extensionWriteRoute
None. is_time_locatable is a view expression, not stored Alpha state.
anchor
table-alpha-place-membership
fieldCount
10
sourceAnchor
https://platform3-andymontgomery-9773s-projects.vercel.app/oneroster/1edtech/data_dictionary/#table-oneroster-roles
filters
[
  "personId",
  "placeId",
  "roleKind",
  "rolePriority",
  "asOfDate",
  "isTimeLocatable",
  "modifiedSince"
]
sortKeys
[
  "person_id",
  "place_id",
  "role_kind",
  "begin_date",
  "end_date"
]
extensionTables
[]
storageContract
{
  "alphaObject": "place_membership",
  "publicSurface": "alpha.place_membership",
  "upstreamModule": "oneroster/1edtech",
  "baseSource": "oneroster.roles",
  "baseView": "alpha.place_membership_base",
  "extensionTables": [],
  "coreWriteRoute": "Route all writes to the OneRoster 1EdTech roles surface.",
  "extensionWriteRoute": "None. is_time_locatable is a view expression, not stored Alpha state.",
  "requiredShape": "CREATE VIEW over the OneRoster 1EdTech base; no Alpha table may store sourced OneRoster columns."
}
example
{
  "membership_id": "pm_person_ada_place_school_student_2026",
  "person_id": "person_ada_lovelace",
  "place_id": "place_timeback_school",
  "role_kind": "guide",
  "role_priority": "primary",
  "begin_date": "2026-08-15",
  "end_date": "2027-06-01",
  "is_time_locatable": true,
  "profile_id": "profile_canvas_001"
}

Fields (10)

tenant_id

title
Tenant Id
type
UUID
publicApi
Hidden in ordinary Alpha responses; selected from the verified JWT.
nullability
Required on every stored row.
required
Yes
range
Valid PostgreSQL UUID.
meaning
The tenant boundary that owns this People & Orgs row.
constraints
Must equal the verified JWT tenant_id or tenantId claim. Never accept a tenant header or body field as source of truth.
relationship
Belongs to one platform.tenant. One tenant owns many People & Orgs rows.
invalidWhen
Missing, malformed, points to another tenant, or is supplied by an unverified request body.
edgeCases
Demo token minting may accept tenantId=demo, but stored rows still use the resolved tenant id.
example
0d4ce2f4-1c42-4f3c-9f0d-03fb7f5271d3
pii
No
allowedValues
[]
provenance
{
  "changeType": "inherited",
  "sourceType": "platform_shared",
  "source": "platform.tenant",
  "sourceAnchor": null,
  "aliasMapField": null,
  "label": "Alpha inherited",
  "note": "Inherited platform tenant routing field, not a OneRoster alias.",
  "itds": [
    {
      "id": "paitd-109-tenant-routing",
      "title": "API Axis: Tenant Routing",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-109-tenant-routing"
    }
  ]
}
storage
{
  "kind": "platform_inherited_column",
  "source": "platform.tenant / verified JWT tenant claim",
  "storageRule": "Inherited platform tenant key. It scopes base rows, extension rows, and views; it is not copied from OneRoster or Ed-Fi.",
  "writeRoute": "Resolved from the verified JWT tenant claim by the platform layer."
}

membership_id

title
Membership Id
type
TEXT
publicApi
string
nullability
Required.
required
Yes
range
1 to 255 printable characters, unique within (tenant_id, alpha.place_membership).
meaning
Stable id for one person's dated role in one place.
constraints
Must remain stable across source updates and per-resource writes.
relationship
Primary identifier for this relationship row.
invalidWhen
Blank, reused for another person/place/role window, or derived from display names.
edgeCases
One person can have several place memberships across places and date windows.
example
pm_person_ada_place_school_student_2026
pii
Identifier
allowedValues
[]
provenance
{
  "changeType": "rename",
  "sourceType": "1edtech_alias",
  "source": "oneroster.roles.sourced_id",
  "sourceAnchor": "https://platform3-andymontgomery-9773s-projects.vercel.app/oneroster/1edtech/data_dictionary/#field-oneroster-roles-sourced-id",
  "aliasMapField": "place_membership.membership_id",
  "label": "Alpha rename",
  "note": "Tenant-scoped membership id.",
  "itds": [
    {
      "id": "paitd-004-point-in-time-memberships",
      "title": "Memberships Are Effective-Dated And Answered By AsOfDate",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-004-point-in-time-memberships"
    },
    {
      "id": "paitd-010-alias-map-contract",
      "title": "Alias Map Is A Generated Architecture Artifact",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-010-alias-map-contract"
    }
  ]
}
storage
{
  "kind": "oneedtech_view_column",
  "source": "oneroster.roles.sourced_id",
  "storageRule": "Selected by alpha.place_membership_base from oneroster.roles; public alpha.place_membership does not store a copy of this 1EdTech field.",
  "writeRoute": "Route all writes to the OneRoster 1EdTech roles surface."
}

person_id

title
Person Id
type
TEXT
publicApi
person id
nullability
Required.
required
Yes
range
1 to 255 printable characters.
meaning
Person who holds the role.
constraints
Must reference alpha.person.person_id in the same tenant. Relationships are columns, never tags.
relationship
Many place memberships belong to one person.
invalidWhen
Missing, references a missing person, crosses tenant, or is replaced by a tag.
edgeCases
A disabled person can still have historical memberships.
example
person_ada_lovelace
pii
Identifier
allowedValues
[]
provenance
{
  "changeType": "rename",
  "sourceType": "1edtech_alias",
  "source": "oneroster.roles.user_sourced_id",
  "sourceAnchor": "https://platform3-andymontgomery-9773s-projects.vercel.app/oneroster/1edtech/data_dictionary/#field-oneroster-roles-user-sourced-id",
  "aliasMapField": "place_membership.person_id",
  "label": "Alpha rename",
  "note": "Person who holds the role.",
  "itds": [
    {
      "id": "paitd-004-point-in-time-memberships",
      "title": "Memberships Are Effective-Dated And Answered By AsOfDate",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-004-point-in-time-memberships"
    },
    {
      "id": "paitd-006-tag-registry",
      "title": "Governed Tags Are Report Slices Only",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-006-tag-registry"
    }
  ]
}
storage
{
  "kind": "oneedtech_view_column",
  "source": "oneroster.roles.user_sourced_id",
  "storageRule": "Selected by alpha.place_membership_base from oneroster.roles; public alpha.place_membership does not store a copy of this 1EdTech field.",
  "writeRoute": "Route all writes to the OneRoster 1EdTech roles surface."
}

place_id

title
Place Id
type
TEXT
publicApi
place id
nullability
Required.
required
Yes
range
1 to 255 printable characters.
meaning
Place where the role applies.
constraints
Must reference alpha.place.place_id in the same tenant. Do not encode place in role text.
relationship
Many place memberships belong to one place.
invalidWhen
Missing, references a missing place, crosses tenant, or is stored as a tag.
edgeCases
District-level and school-level memberships can coexist for the same person with different rows.
example
place_timeback_school
pii
Identifier
allowedValues
[]
provenance
{
  "changeType": "rename",
  "sourceType": "1edtech_alias",
  "source": "oneroster.roles.org_sourced_id",
  "sourceAnchor": "https://platform3-andymontgomery-9773s-projects.vercel.app/oneroster/1edtech/data_dictionary/#field-oneroster-roles-org-sourced-id",
  "aliasMapField": "place_membership.place_id",
  "label": "Alpha rename",
  "note": "Place where the role applies.",
  "itds": [
    {
      "id": "paitd-004-point-in-time-memberships",
      "title": "Memberships Are Effective-Dated And Answered By AsOfDate",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-004-point-in-time-memberships"
    },
    {
      "id": "paitd-006-tag-registry",
      "title": "Governed Tags Are Report Slices Only",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-006-tag-registry"
    }
  ]
}
storage
{
  "kind": "oneedtech_view_column",
  "source": "oneroster.roles.org_sourced_id",
  "storageRule": "Selected by alpha.place_membership_base from oneroster.roles; public alpha.place_membership does not store a copy of this 1EdTech field.",
  "writeRoute": "Route all writes to the OneRoster 1EdTech roles surface."
}

role_kind

title
Role Kind
type
TEXT enum
publicApi
string enum
nullability
Required.
required
Yes
range
One of the canonical role_kind values.
meaning
Canonical role enum with a maintained alias fold; never parsed from names or titles.
constraints
Fold source OneRoster role values to canonical Alpha role_kind at write time. Keep the source value in provenance.
relationship
No foreign key. Used for filtering memberships and role-specific person views.
invalidWhen
Free text, parsed from a title, or used to store class-level role when class_membership is the correct home.
edgeCases
teacher source rows usually fold to guide; administrator-like source roles fold to administrator.
example
guide
pii
Yes
allowedValues
[
  {
    "value": "student",
    "meaning": "A learner whose roster context may feed Results and Events, but whose mastery and scores never live in People & Orgs.",
    "useWhen": "Use for source roles/enrollments that say student.",
    "invalidWhen": "Invalid for parents, guardians, staff, guides, or administrators."
  },
  {
    "value": "parent",
    "meaning": "A parent relationship for a student or school context.",
    "useWhen": "Use for the OneRoster parent role or a maintained source alias that folds to parent.",
    "invalidWhen": "Invalid for guardian when the source distinguishes guardian from parent."
  },
  {
    "value": "guardian",
    "meaning": "A guardian relationship for a student or school context.",
    "useWhen": "Use for the OneRoster guardian role or a maintained source alias that folds to guardian.",
    "invalidWhen": "Invalid for parent when the source distinguishes parent from guardian."
  },
  {
    "value": "relative",
    "meaning": "A family relationship that is not parent or guardian.",
    "useWhen": "Use for the OneRoster relative role.",
    "invalidWhen": "Invalid as a generic fallback for unknown family data."
  },
  {
    "value": "guide",
    "meaning": "A teacher or guide who works directly with students.",
    "useWhen": "Use for teacher source roles and approved aliases that TimeBack treats as instructional guides.",
    "invalidWhen": "Invalid for administrative-only or family relationship roles."
  },
  {
    "value": "staff",
    "meaning": "School staff who are not the student's primary instructional guide in this row.",
    "useWhen": "Use for aide, counselor, proctor, or similar staff roles when the source does not make them the guide.",
    "invalidWhen": "Invalid when the source role is teacher and the row should be guide."
  },
  {
    "value": "administrator",
    "meaning": "A district, site, system, or school administrator.",
    "useWhen": "Use for districtAdministrator, siteAdministrator, systemAdministrator, principal, or administrator source roles.",
    "invalidWhen": "Invalid for teachers, students, parents, or guardians."
  }
]
provenance
{
  "changeType": "rename+restrict",
  "sourceType": "1edtech_alias",
  "source": "oneroster.roles.role",
  "sourceAnchor": "https://platform3-andymontgomery-9773s-projects.vercel.app/oneroster/1edtech/data_dictionary/#field-oneroster-roles-role",
  "aliasMapField": "place_membership.role_kind",
  "label": "Alpha rename+restrict",
  "note": "Canonical role enum with a maintained alias fold; never parsed from names or titles.",
  "itds": [
    {
      "id": "paitd-002-person-vocabulary",
      "title": "Person Is The Plain Alias For OneRoster User",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-002-person-vocabulary"
    },
    {
      "id": "paitd-004-point-in-time-memberships",
      "title": "Memberships Are Effective-Dated And Answered By AsOfDate",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-004-point-in-time-memberships"
    }
  ]
}
storage
{
  "kind": "oneedtech_view_column",
  "source": "oneroster.roles.role",
  "storageRule": "Selected by alpha.place_membership_base from oneroster.roles; public alpha.place_membership does not store a copy of this 1EdTech field.",
  "writeRoute": "Route all writes to the OneRoster 1EdTech roles surface."
}

role_priority

title
Role Priority
type
TEXT enum
publicApi
primary | secondary
nullability
Optional where the source does not mark priority.
required
No
range
primary or secondary.
meaning
Primary or secondary role marker.
constraints
At most one active primary role should exist for the same person/place/date window when local policy requires a primary.
relationship
No foreign key.
invalidWhen
Any value outside primary/secondary or used to select a primary guide for a class; class_membership.is_primary_guide owns class guide primacy.
edgeCases
Null means no priority supplied, not secondary.
example
primary
pii
No
allowedValues
[
  {
    "value": "primary",
    "meaning": "This is the user's primary role in the organization/date window.",
    "useWhen": "Use when one role should be treated as the main role for org-scoped lookups.",
    "invalidWhen": "Invalid if another role is already primary for the same user/org/window under the local profile."
  },
  {
    "value": "secondary",
    "meaning": "This is an additional non-primary role in the organization/date window.",
    "useWhen": "Use when the user has more than one org role.",
    "invalidWhen": "Invalid if the source intends the role to be primary."
  }
]
provenance
{
  "changeType": "rename",
  "sourceType": "1edtech_alias",
  "source": "oneroster.roles.role_type",
  "sourceAnchor": "https://platform3-andymontgomery-9773s-projects.vercel.app/oneroster/1edtech/data_dictionary/#field-oneroster-roles-role-type",
  "aliasMapField": "place_membership.role_priority",
  "label": "Alpha rename",
  "note": "Primary or secondary role marker.",
  "itds": [
    {
      "id": "paitd-004-point-in-time-memberships",
      "title": "Memberships Are Effective-Dated And Answered By AsOfDate",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-004-point-in-time-memberships"
    }
  ]
}
storage
{
  "kind": "oneedtech_view_column",
  "source": "oneroster.roles.role_type",
  "storageRule": "Selected by alpha.place_membership_base from oneroster.roles; public alpha.place_membership does not store a copy of this 1EdTech field.",
  "writeRoute": "Route all writes to the OneRoster 1EdTech roles surface."
}

begin_date

title
Begin Date
type
DATE
publicApi
date
nullability
Nullable storage, but begin_date null means not time-locatable and excluded from every point-in-time computation.
required
No
range
ISO 8601 date YYYY-MM-DD.
meaning
Inclusive date when the membership becomes locatable.
constraints
Set is_time_locatable=false when null. Active-as-of requires begin_date <= asOfDate.
relationship
No foreign key; used by point-in-time computations.
invalidWhen
Malformed, after end_date when end_date is present, or ignored by a current-only shortcut.
edgeCases
begin_date null plus end_date present is still excluded from point-in-time computations.
example
2026-08-15
pii
No
allowedValues
[]
provenance
{
  "changeType": "rename",
  "sourceType": "1edtech_alias",
  "source": "oneroster.roles.begin_date",
  "sourceAnchor": "https://platform3-andymontgomery-9773s-projects.vercel.app/oneroster/1edtech/data_dictionary/#field-oneroster-roles-begin-date",
  "aliasMapField": "place_membership.begin_date",
  "label": "Alpha rename",
  "note": "Inclusive date when the membership becomes locatable.",
  "itds": [
    {
      "id": "paitd-004-point-in-time-memberships",
      "title": "Memberships Are Effective-Dated And Answered By AsOfDate",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-004-point-in-time-memberships"
    }
  ]
}
storage
{
  "kind": "oneedtech_view_column",
  "source": "oneroster.roles.begin_date",
  "storageRule": "Selected by alpha.place_membership_base from oneroster.roles; public alpha.place_membership does not store a copy of this 1EdTech field.",
  "writeRoute": "Route all writes to the OneRoster 1EdTech roles surface."
}

end_date

title
End Date
type
DATE
publicApi
date
nullability
Optional. Null means still active for dates on or after begin_date.
required
No
range
ISO 8601 date YYYY-MM-DD.
meaning
Exclusive date when the membership stops being active.
constraints
Active-as-of includes the row when begin_date is not null, asOfDate >= begin_date, and end_date is null or asOfDate < end_date.
relationship
No foreign key; used by point-in-time computations.
invalidWhen
Malformed, on/before begin_date for the same row, or treated as inclusive.
edgeCases
Both begin_date and end_date null means always excluded from point-in-time computations.
example
2027-06-01
pii
No
allowedValues
[]
provenance
{
  "changeType": "rename",
  "sourceType": "1edtech_alias",
  "source": "oneroster.roles.end_date",
  "sourceAnchor": "https://platform3-andymontgomery-9773s-projects.vercel.app/oneroster/1edtech/data_dictionary/#field-oneroster-roles-end-date",
  "aliasMapField": "place_membership.end_date",
  "label": "Alpha rename",
  "note": "Exclusive date when the membership stops being active; null means still active after begin_date.",
  "itds": [
    {
      "id": "paitd-004-point-in-time-memberships",
      "title": "Memberships Are Effective-Dated And Answered By AsOfDate",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-004-point-in-time-memberships"
    }
  ]
}
storage
{
  "kind": "oneedtech_view_column",
  "source": "oneroster.roles.end_date",
  "storageRule": "Selected by alpha.place_membership_base from oneroster.roles; public alpha.place_membership does not store a copy of this 1EdTech field.",
  "writeRoute": "Route all writes to the OneRoster 1EdTech roles surface."
}

is_time_locatable

title
Is Time Locatable
type
BOOLEAN
publicApi
boolean
nullability
Required derived field.
required
Yes
range
true or false.
meaning
True only when begin_date is non-null; consumers filter on this instead of guessing from nulls.
constraints
Derived by the surface from begin_date. Do not let consumers recompute the null rule.
relationship
No foreign key; query input to active-as-of views.
invalidWhen
True when begin_date is null, false when begin_date is present, or omitted from membership responses.
edgeCases
end_date null does not make the row unlocatable; begin_date is the only locatability switch.
example
true
pii
No
allowedValues
[
  {
    "value": "true",
    "meaning": "The fact is asserted by the source or by the Alpha surface.",
    "useWhen": "Use only when the field's own constraints say the fact is true.",
    "invalidWhen": "Invalid when guessed from names, labels, dates, tags, or another field."
  },
  {
    "value": "false",
    "meaning": "The fact is explicitly not asserted.",
    "useWhen": "Use only when the source or surface stores an explicit false value.",
    "invalidWhen": "Invalid when a missing value should remain unknown."
  }
]
provenance
{
  "changeType": "restrict",
  "sourceType": "view_expression",
  "source": "view expression: begin_date is not null",
  "sourceAnchor": null,
  "aliasMapField": "place_membership.is_time_locatable",
  "label": "Alpha derived view field",
  "note": "Alpha derived field required by the point-in-time rule. No Alpha table stores it.",
  "itds": [
    {
      "id": "paitd-004-point-in-time-memberships",
      "title": "Memberships Are Effective-Dated And Answered By AsOfDate",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-004-point-in-time-memberships"
    }
  ]
}
storage
{
  "kind": "view_derived",
  "source": "view expression: begin_date is not null",
  "storageRule": "Computed in alpha.place_membership as a view expression; no Alpha table column stores it.",
  "writeRoute": "Not writable; recomputed by the view from sourced fields."
}

profile_id

title
Profile Id
type
TEXT
publicApi
string
nullability
Optional.
required
No
range
1 to 255 printable characters when supplied.
meaning
Optional non-secret profile reference.
constraints
May reference restricted OneRoster user profile metadata, but must never expose profile password or secret values.
relationship
Optional reference to an upstream user profile in the same tenant.
invalidWhen
References a missing profile, leaks a credential, or is used instead of app_credential.secret_ref for operational secrets.
edgeCases
Profile details require explicit scopes; ordinary membership reads may show only this non-secret reference or omit it.
example
profile_canvas_001
pii
Identifier
allowedValues
[]
provenance
{
  "changeType": "rename+restrict",
  "sourceType": "1edtech_alias",
  "source": "oneroster.roles.user_profile_sourced_id",
  "sourceAnchor": "https://platform3-andymontgomery-9773s-projects.vercel.app/oneroster/1edtech/data_dictionary/#field-oneroster-roles-user-profile-sourced-id",
  "aliasMapField": "place_membership.profile_id",
  "label": "Alpha rename+restrict",
  "note": "Optional non-secret profile reference.",
  "itds": [
    {
      "id": "paitd-008-app-credentials",
      "title": "App Credentials Use Vault References, Never Roster Password Fields",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-008-app-credentials"
    },
    {
      "id": "paitd-009-sensitive-profile-privacy",
      "title": "Sensitive Profiles Are Restricted, Not Default Roster Fields",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-009-sensitive-profile-privacy"
    }
  ]
}
storage
{
  "kind": "oneedtech_view_column",
  "source": "oneroster.roles.user_profile_sourced_id",
  "storageRule": "Selected by alpha.place_membership_base from oneroster.roles; public alpha.place_membership does not store a copy of this 1EdTech field.",
  "writeRoute": "Route all writes to the OneRoster 1EdTech roles surface."
}

alpha.class_membership · Class Membership

objectName
class_membership
apiCollection
/class_memberships
storage
Public view alpha.class_membership selects from alpha.class_membership_base over oneroster.enrollments. is_time_locatable is a view expression; this object has no Alpha table.
changeType
rename + restrict
upstream
oneroster.enrollments
primaryKey
(tenant_id, membership_id)
purpose
A dated relationship saying that one person belongs to one learning group at one school. It is the source for student<->guide association and studentsForGuide(guide, date); the detailed class/course object is not re-owned by this module.
lifecycle
Created from OneRoster enrollment rows or Alpha commands. Active learning-group rosters, guide rosters, and student enrollment anchors are always answered by asOfDate and the begin/end date null rule.
auth
Readable to school/class scoped claims. Student records remain roster context; Results owns outcomes.
sourceType
1edtech_alias_view
publicSurface
alpha.class_membership
baseView
alpha.class_membership_base
baseSource
oneroster.enrollments
coreWriteRoute
Route all writes to the OneRoster 1EdTech enrollments surface.
extensionWriteRoute
None. is_time_locatable is a view expression, not stored Alpha state.
anchor
table-alpha-class-membership
fieldCount
10
sourceAnchor
https://platform3-andymontgomery-9773s-projects.vercel.app/oneroster/1edtech/data_dictionary/#table-oneroster-enrollments
filters
[
  "personId",
  "schoolId",
  "learningGroupId",
  "roleKind",
  "isPrimaryGuide",
  "guidePersonId via studentsForGuide",
  "asOfDate",
  "isTimeLocatable",
  "modifiedSince"
]
sortKeys
[
  "school_id",
  "learning_group_id",
  "person_id",
  "role_kind",
  "begin_date"
]
extensionTables
[]
storageContract
{
  "alphaObject": "class_membership",
  "publicSurface": "alpha.class_membership",
  "upstreamModule": "oneroster/1edtech",
  "baseSource": "oneroster.enrollments",
  "baseView": "alpha.class_membership_base",
  "extensionTables": [],
  "coreWriteRoute": "Route all writes to the OneRoster 1EdTech enrollments surface.",
  "extensionWriteRoute": "None. is_time_locatable is a view expression, not stored Alpha state.",
  "requiredShape": "CREATE VIEW over the OneRoster 1EdTech base; no Alpha table may store sourced OneRoster columns."
}
example
{
  "membership_id": "cm_alg1_ada_student_2026",
  "person_id": "person_ada_lovelace",
  "school_id": "place_timeback_school",
  "learning_group_id": "class_algebra_1_a",
  "role_kind": "student",
  "is_primary_guide": "false",
  "begin_date": "2026-08-15",
  "end_date": "2027-06-01",
  "is_time_locatable": true
}

Fields (10)

tenant_id

title
Tenant Id
type
UUID
publicApi
Hidden in ordinary Alpha responses; selected from the verified JWT.
nullability
Required on every stored row.
required
Yes
range
Valid PostgreSQL UUID.
meaning
The tenant boundary that owns this People & Orgs row.
constraints
Must equal the verified JWT tenant_id or tenantId claim. Never accept a tenant header or body field as source of truth.
relationship
Belongs to one platform.tenant. One tenant owns many People & Orgs rows.
invalidWhen
Missing, malformed, points to another tenant, or is supplied by an unverified request body.
edgeCases
Demo token minting may accept tenantId=demo, but stored rows still use the resolved tenant id.
example
0d4ce2f4-1c42-4f3c-9f0d-03fb7f5271d3
pii
No
allowedValues
[]
provenance
{
  "changeType": "inherited",
  "sourceType": "platform_shared",
  "source": "platform.tenant",
  "sourceAnchor": null,
  "aliasMapField": null,
  "label": "Alpha inherited",
  "note": "Inherited platform tenant routing field, not a OneRoster alias.",
  "itds": [
    {
      "id": "paitd-109-tenant-routing",
      "title": "API Axis: Tenant Routing",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-109-tenant-routing"
    }
  ]
}
storage
{
  "kind": "platform_inherited_column",
  "source": "platform.tenant / verified JWT tenant claim",
  "storageRule": "Inherited platform tenant key. It scopes base rows, extension rows, and views; it is not copied from OneRoster or Ed-Fi.",
  "writeRoute": "Resolved from the verified JWT tenant claim by the platform layer."
}

membership_id

title
Membership Id
type
TEXT
publicApi
string
nullability
Required.
required
Yes
range
1 to 255 printable characters, unique within (tenant_id, alpha.class_membership).
meaning
Stable id for one person's dated membership in one learning group.
constraints
Must remain stable across source updates and per-resource writes.
relationship
Primary identifier for this class membership row.
invalidWhen
Blank, reused for another person/class/date window, or derived from names.
edgeCases
A person can have multiple learning-group memberships at the same school.
example
cm_alg1_ada_student_2026
pii
Identifier
allowedValues
[]
provenance
{
  "changeType": "rename",
  "sourceType": "1edtech_alias",
  "source": "oneroster.enrollments.sourced_id",
  "sourceAnchor": "https://platform3-andymontgomery-9773s-projects.vercel.app/oneroster/1edtech/data_dictionary/#field-oneroster-enrollments-sourced-id",
  "aliasMapField": "class_membership.membership_id",
  "label": "Alpha rename",
  "note": "Tenant-scoped class membership id.",
  "itds": [
    {
      "id": "paitd-004-point-in-time-memberships",
      "title": "Memberships Are Effective-Dated And Answered By AsOfDate",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-004-point-in-time-memberships"
    },
    {
      "id": "paitd-010-alias-map-contract",
      "title": "Alias Map Is A Generated Architecture Artifact",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-010-alias-map-contract"
    }
  ]
}
storage
{
  "kind": "oneedtech_view_column",
  "source": "oneroster.enrollments.sourced_id",
  "storageRule": "Selected by alpha.class_membership_base from oneroster.enrollments; public alpha.class_membership does not store a copy of this 1EdTech field.",
  "writeRoute": "Route all writes to the OneRoster 1EdTech enrollments surface."
}

person_id

title
Person Id
type
TEXT
publicApi
person id
nullability
Required.
required
Yes
range
1 to 255 printable characters.
meaning
Person in the learning group.
constraints
Must reference alpha.person.person_id in the same tenant.
relationship
Many class memberships belong to one person.
invalidWhen
Missing, references a missing person, crosses tenant, or is stored as a tag.
edgeCases
The same person can have guide and student roles in different groups only if source policy allows it.
example
person_ada_lovelace
pii
Identifier
allowedValues
[]
provenance
{
  "changeType": "rename",
  "sourceType": "1edtech_alias",
  "source": "oneroster.enrollments.user_sourced_id",
  "sourceAnchor": "https://platform3-andymontgomery-9773s-projects.vercel.app/oneroster/1edtech/data_dictionary/#field-oneroster-enrollments-user-sourced-id",
  "aliasMapField": "class_membership.person_id",
  "label": "Alpha rename",
  "note": "Person in the learning group.",
  "itds": [
    {
      "id": "paitd-004-point-in-time-memberships",
      "title": "Memberships Are Effective-Dated And Answered By AsOfDate",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-004-point-in-time-memberships"
    },
    {
      "id": "paitd-006-tag-registry",
      "title": "Governed Tags Are Report Slices Only",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-006-tag-registry"
    }
  ]
}
storage
{
  "kind": "oneedtech_view_column",
  "source": "oneroster.enrollments.user_sourced_id",
  "storageRule": "Selected by alpha.class_membership_base from oneroster.enrollments; public alpha.class_membership does not store a copy of this 1EdTech field.",
  "writeRoute": "Route all writes to the OneRoster 1EdTech enrollments surface."
}

school_id

title
School Id
type
TEXT
publicApi
place id
nullability
Required.
required
Yes
range
1 to 255 printable characters.
meaning
School place for the membership.
constraints
Must reference an alpha.place row whose place_kind is school. NWEA account comes from that school's parent district.
relationship
Many class memberships belong to one school place.
invalidWhen
Missing, references a non-school place, crosses tenant, or duplicates NWEA district id on the school row.
edgeCases
If a source sends district-level class enrollments, architecture must decide whether to ship before Alpha accepts them.
example
place_timeback_school
pii
Identifier
allowedValues
[]
provenance
{
  "changeType": "rename+restrict",
  "sourceType": "1edtech_alias",
  "source": "oneroster.enrollments.school_sourced_id",
  "sourceAnchor": "https://platform3-andymontgomery-9773s-projects.vercel.app/oneroster/1edtech/data_dictionary/#field-oneroster-enrollments-school-sourced-id",
  "aliasMapField": "class_membership.school_id",
  "label": "Alpha rename+restrict",
  "note": "School place for the membership.",
  "itds": [
    {
      "id": "paitd-003-place-nwea-boundary",
      "title": "Place Is The Plain Alias For OneRoster Org And District Is The NWEA Account",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-003-place-nwea-boundary"
    },
    {
      "id": "paitd-004-point-in-time-memberships",
      "title": "Memberships Are Effective-Dated And Answered By AsOfDate",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-004-point-in-time-memberships"
    }
  ]
}
storage
{
  "kind": "oneedtech_view_column",
  "source": "oneroster.enrollments.school_sourced_id",
  "storageRule": "Selected by alpha.class_membership_base from oneroster.enrollments; public alpha.class_membership does not store a copy of this 1EdTech field.",
  "writeRoute": "Route all writes to the OneRoster 1EdTech enrollments surface."
}

learning_group_id

title
Learning Group Id
type
TEXT
publicApi
string
nullability
Required.
required
Yes
range
1 to 255 printable characters.
meaning
OneRoster class id retained as a real relationship column.
constraints
Must reference the same-tenant learning group/class source row. People & Orgs owns the membership, not the detailed class/course definition.
relationship
Many memberships can point at one learning group. The learning group details stay outside this Alpha module.
invalidWhen
Missing, references a missing class, crosses tenant, or is stored as a tag.
edgeCases
Downstream modules may use this id for authorization context without importing class details into People & Orgs.
example
class_algebra_1_a
pii
Identifier
allowedValues
[]
provenance
{
  "changeType": "rename",
  "sourceType": "1edtech_alias",
  "source": "oneroster.enrollments.class_sourced_id",
  "sourceAnchor": "https://platform3-andymontgomery-9773s-projects.vercel.app/oneroster/1edtech/data_dictionary/#field-oneroster-enrollments-class-sourced-id",
  "aliasMapField": "class_membership.learning_group_id",
  "label": "Alpha rename",
  "note": "OneRoster class id retained as a real relationship column.",
  "itds": [
    {
      "id": "paitd-004-point-in-time-memberships",
      "title": "Memberships Are Effective-Dated And Answered By AsOfDate",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-004-point-in-time-memberships"
    },
    {
      "id": "paitd-006-tag-registry",
      "title": "Governed Tags Are Report Slices Only",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-006-tag-registry"
    }
  ]
}
storage
{
  "kind": "oneedtech_view_column",
  "source": "oneroster.enrollments.class_sourced_id",
  "storageRule": "Selected by alpha.class_membership_base from oneroster.enrollments; public alpha.class_membership does not store a copy of this 1EdTech field.",
  "writeRoute": "Route all writes to the OneRoster 1EdTech enrollments surface."
}

role_kind

title
Role Kind
type
TEXT enum
publicApi
string enum
nullability
Required.
required
Yes
range
student, guide, proctor, or administrator.
meaning
Canonical enrollment role: student, guide, proctor, or administrator.
constraints
Fold source teacher to guide at write time. Do not use place role_kind values that do not belong to class membership.
relationship
No foreign key; used for filtering class rosters.
invalidWhen
Free text, parsed from class title, or used to store parent/guardian relationships.
edgeCases
Parents and guardians can see class context through claims, not through class_membership rows.
example
student
pii
Yes
allowedValues
[
  {
    "value": "student",
    "meaning": "The person participates in the learning group as a learner.",
    "useWhen": "Use for source enrollments.role=student.",
    "invalidWhen": "Invalid for guide, proctor, or administrator rows."
  },
  {
    "value": "guide",
    "meaning": "The person teaches or guides the learning group.",
    "useWhen": "Use for source enrollments.role=teacher.",
    "invalidWhen": "Invalid for learners or non-instructional administrative access."
  },
  {
    "value": "proctor",
    "meaning": "The person supervises an assessment or activity context without being the guide.",
    "useWhen": "Use for source enrollments.role=proctor.",
    "invalidWhen": "Invalid as a substitute for guide when the source says teacher."
  },
  {
    "value": "administrator",
    "meaning": "The person has administrative participation in the learning group.",
    "useWhen": "Use for source enrollments.role=administrator.",
    "invalidWhen": "Invalid for students or guides."
  }
]
provenance
{
  "changeType": "rename+restrict",
  "sourceType": "1edtech_alias",
  "source": "oneroster.enrollments.role",
  "sourceAnchor": "https://platform3-andymontgomery-9773s-projects.vercel.app/oneroster/1edtech/data_dictionary/#field-oneroster-enrollments-role",
  "aliasMapField": "class_membership.role_kind",
  "label": "Alpha rename+restrict",
  "note": "Canonical enrollment role: student, teacher, proctor, or administrator.",
  "itds": [
    {
      "id": "paitd-002-person-vocabulary",
      "title": "Person Is The Plain Alias For OneRoster User",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-002-person-vocabulary"
    },
    {
      "id": "paitd-004-point-in-time-memberships",
      "title": "Memberships Are Effective-Dated And Answered By AsOfDate",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-004-point-in-time-memberships"
    }
  ]
}
storage
{
  "kind": "oneedtech_view_column",
  "source": "oneroster.enrollments.role",
  "storageRule": "Selected by alpha.class_membership_base from oneroster.enrollments; public alpha.class_membership does not store a copy of this 1EdTech field.",
  "writeRoute": "Route all writes to the OneRoster 1EdTech enrollments surface."
}

is_primary_guide

title
Is Primary Guide
type
BOOLEAN
publicApi
boolean
nullability
Optional; meaningful only when role_kind=guide.
required
No
range
true, false, or null.
meaning
Primary-teacher marker, valid only for guide rows.
constraints
Only role_kind=guide may be true. At most one active primary guide should exist for the same learning_group_id/asOfDate under local policy.
relationship
No foreign key.
invalidWhen
True for student/proctor/administrator, multiple active primary guides when policy forbids it, or used for place-level role priority.
edgeCases
Null means the source did not supply primary status; false means explicit non-primary when supplied.
example
false
pii
No
allowedValues
[
  {
    "value": "true",
    "meaning": "The fact is asserted by the source or by the Alpha surface.",
    "useWhen": "Use only when the field's own constraints say the fact is true.",
    "invalidWhen": "Invalid when guessed from names, labels, dates, tags, or another field."
  },
  {
    "value": "false",
    "meaning": "The fact is explicitly not asserted.",
    "useWhen": "Use only when the source or surface stores an explicit false value.",
    "invalidWhen": "Invalid when a missing value should remain unknown."
  }
]
provenance
{
  "changeType": "rename+restrict",
  "sourceType": "1edtech_alias",
  "source": "oneroster.enrollments.primary",
  "sourceAnchor": "https://platform3-andymontgomery-9773s-projects.vercel.app/oneroster/1edtech/data_dictionary/#field-oneroster-enrollments-primary",
  "aliasMapField": "class_membership.is_primary_guide",
  "label": "Alpha rename+restrict",
  "note": "Primary-teacher marker, valid only for guide/teacher rows.",
  "itds": [
    {
      "id": "paitd-004-point-in-time-memberships",
      "title": "Memberships Are Effective-Dated And Answered By AsOfDate",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-004-point-in-time-memberships"
    }
  ]
}
storage
{
  "kind": "oneedtech_view_column",
  "source": "oneroster.enrollments.primary",
  "storageRule": "Selected by alpha.class_membership_base from oneroster.enrollments; public alpha.class_membership does not store a copy of this 1EdTech field.",
  "writeRoute": "Route all writes to the OneRoster 1EdTech enrollments surface."
}

begin_date

title
Begin Date
type
DATE
publicApi
date
nullability
Nullable storage, but begin_date null means not time-locatable and excluded from every point-in-time computation.
required
No
range
ISO 8601 date YYYY-MM-DD.
meaning
Inclusive date when the membership becomes locatable.
constraints
Set is_time_locatable=false when null. Active-as-of requires begin_date <= asOfDate.
relationship
No foreign key; used by point-in-time computations.
invalidWhen
Malformed, after end_date when end_date is present, or ignored by a current-only shortcut.
edgeCases
begin_date null plus end_date present is still excluded from point-in-time computations.
example
2026-08-15
pii
No
allowedValues
[]
provenance
{
  "changeType": "rename",
  "sourceType": "1edtech_alias",
  "source": "oneroster.enrollments.begin_date",
  "sourceAnchor": "https://platform3-andymontgomery-9773s-projects.vercel.app/oneroster/1edtech/data_dictionary/#field-oneroster-enrollments-begin-date",
  "aliasMapField": "class_membership.begin_date",
  "label": "Alpha rename",
  "note": "Inclusive date when the membership becomes locatable.",
  "itds": [
    {
      "id": "paitd-004-point-in-time-memberships",
      "title": "Memberships Are Effective-Dated And Answered By AsOfDate",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-004-point-in-time-memberships"
    }
  ]
}
storage
{
  "kind": "oneedtech_view_column",
  "source": "oneroster.enrollments.begin_date",
  "storageRule": "Selected by alpha.class_membership_base from oneroster.enrollments; public alpha.class_membership does not store a copy of this 1EdTech field.",
  "writeRoute": "Route all writes to the OneRoster 1EdTech enrollments surface."
}

end_date

title
End Date
type
DATE
publicApi
date
nullability
Optional. Null means still active for dates on or after begin_date.
required
No
range
ISO 8601 date YYYY-MM-DD.
meaning
Exclusive date when the membership stops being active.
constraints
Active-as-of includes the row when begin_date is not null, asOfDate >= begin_date, and end_date is null or asOfDate < end_date.
relationship
No foreign key; used by point-in-time computations.
invalidWhen
Malformed, on/before begin_date for the same row, or treated as inclusive.
edgeCases
Both begin_date and end_date null means always excluded from point-in-time computations.
example
2027-06-01
pii
No
allowedValues
[]
provenance
{
  "changeType": "rename",
  "sourceType": "1edtech_alias",
  "source": "oneroster.enrollments.end_date",
  "sourceAnchor": "https://platform3-andymontgomery-9773s-projects.vercel.app/oneroster/1edtech/data_dictionary/#field-oneroster-enrollments-end-date",
  "aliasMapField": "class_membership.end_date",
  "label": "Alpha rename",
  "note": "Exclusive date when the membership stops being active; null means still active after begin_date.",
  "itds": [
    {
      "id": "paitd-004-point-in-time-memberships",
      "title": "Memberships Are Effective-Dated And Answered By AsOfDate",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-004-point-in-time-memberships"
    }
  ]
}
storage
{
  "kind": "oneedtech_view_column",
  "source": "oneroster.enrollments.end_date",
  "storageRule": "Selected by alpha.class_membership_base from oneroster.enrollments; public alpha.class_membership does not store a copy of this 1EdTech field.",
  "writeRoute": "Route all writes to the OneRoster 1EdTech enrollments surface."
}

is_time_locatable

title
Is Time Locatable
type
BOOLEAN
publicApi
boolean
nullability
Required derived field.
required
Yes
range
true or false.
meaning
True only when begin_date is non-null.
constraints
Derived by the surface from begin_date. Consumers filter on this field instead of guessing at nulls.
relationship
No foreign key; query input to active-as-of views.
invalidWhen
True when begin_date is null, false when begin_date is present, or omitted from membership responses.
edgeCases
end_date null means still active only after begin_date; it does not make an undated row locatable.
example
true
pii
No
allowedValues
[
  {
    "value": "true",
    "meaning": "The fact is asserted by the source or by the Alpha surface.",
    "useWhen": "Use only when the field's own constraints say the fact is true.",
    "invalidWhen": "Invalid when guessed from names, labels, dates, tags, or another field."
  },
  {
    "value": "false",
    "meaning": "The fact is explicitly not asserted.",
    "useWhen": "Use only when the source or surface stores an explicit false value.",
    "invalidWhen": "Invalid when a missing value should remain unknown."
  }
]
provenance
{
  "changeType": "restrict",
  "sourceType": "view_expression",
  "source": "view expression: begin_date is not null",
  "sourceAnchor": null,
  "aliasMapField": "class_membership.is_time_locatable",
  "label": "Alpha derived view field",
  "note": "Alpha derived field required by the point-in-time rule. No Alpha table stores it.",
  "itds": [
    {
      "id": "paitd-004-point-in-time-memberships",
      "title": "Memberships Are Effective-Dated And Answered By AsOfDate",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-004-point-in-time-memberships"
    }
  ]
}
storage
{
  "kind": "view_derived",
  "source": "view expression: begin_date is not null",
  "storageRule": "Computed in alpha.class_membership as a view expression; no Alpha table column stores it.",
  "writeRoute": "Not writable; recomputed by the view from sourced fields."
}

alpha.school_period · School Period

objectName
school_period
apiCollection
/school_periods
storage
Public view alpha.school_period selects from alpha.school_period_base over oneroster.academic_sessions. No Alpha table stores academic-session fields.
changeType
rename + restrict
upstream
oneroster.academic_sessions
primaryKey
(tenant_id, period_id)
purpose
A school year, term, semester, or grading period used to answer roster questions as of a date.
lifecycle
Created from OneRoster academicSession rows or Alpha commands. Period title is display text; typed period_kind and dates drive computations.
auth
Readable to roster scopes; it contains no student outcomes.
sourceType
1edtech_alias_view
publicSurface
alpha.school_period
baseView
alpha.school_period_base
baseSource
oneroster.academic_sessions
coreWriteRoute
Route all writes to the OneRoster 1EdTech academic_sessions surface.
extensionWriteRoute
None.
anchor
table-alpha-school-period
fieldCount
10
sourceAnchor
https://platform3-andymontgomery-9773s-projects.vercel.app/oneroster/1edtech/data_dictionary/#table-oneroster-academic-sessions
filters
[
  "periodKind",
  "schoolYear",
  "asOfDate",
  "parentPeriodId",
  "modifiedSince"
]
sortKeys
[
  "school_year",
  "start_date",
  "end_date",
  "period_kind",
  "title"
]
extensionTables
[]
storageContract
{
  "alphaObject": "school_period",
  "publicSurface": "alpha.school_period",
  "upstreamModule": "oneroster/1edtech",
  "baseSource": "oneroster.academic_sessions",
  "baseView": "alpha.school_period_base",
  "extensionTables": [],
  "coreWriteRoute": "Route all writes to the OneRoster 1EdTech academic_sessions surface.",
  "extensionWriteRoute": "None.",
  "requiredShape": "CREATE VIEW over the OneRoster 1EdTech base; no Alpha table may store sourced OneRoster columns."
}
example
{
  "period_id": "period_2026_2027_school_year",
  "source_status": "active",
  "source_updated_at": "2026-08-15T13:45:30.000Z",
  "title": "2026-2027 School Year",
  "period_kind": "school_year",
  "start_date": "2026-08-15",
  "end_date": "2027-06-01",
  "parent_period_id": "period_2026_2027_school_year",
  "school_year": 2027
}

Fields (10)

tenant_id

title
Tenant Id
type
UUID
publicApi
Hidden in ordinary Alpha responses; selected from the verified JWT.
nullability
Required on every stored row.
required
Yes
range
Valid PostgreSQL UUID.
meaning
The tenant boundary that owns this People & Orgs row.
constraints
Must equal the verified JWT tenant_id or tenantId claim. Never accept a tenant header or body field as source of truth.
relationship
Belongs to one platform.tenant. One tenant owns many People & Orgs rows.
invalidWhen
Missing, malformed, points to another tenant, or is supplied by an unverified request body.
edgeCases
Demo token minting may accept tenantId=demo, but stored rows still use the resolved tenant id.
example
0d4ce2f4-1c42-4f3c-9f0d-03fb7f5271d3
pii
No
allowedValues
[]
provenance
{
  "changeType": "inherited",
  "sourceType": "platform_shared",
  "source": "platform.tenant",
  "sourceAnchor": null,
  "aliasMapField": null,
  "label": "Alpha inherited",
  "note": "Inherited platform tenant routing field, not a OneRoster alias.",
  "itds": [
    {
      "id": "paitd-109-tenant-routing",
      "title": "API Axis: Tenant Routing",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-109-tenant-routing"
    }
  ]
}
storage
{
  "kind": "platform_inherited_column",
  "source": "platform.tenant / verified JWT tenant claim",
  "storageRule": "Inherited platform tenant key. It scopes base rows, extension rows, and views; it is not copied from OneRoster or Ed-Fi.",
  "writeRoute": "Resolved from the verified JWT tenant claim by the platform layer."
}

period_id

title
Period Id
type
TEXT
publicApi
string
nullability
Required.
required
Yes
range
1 to 255 printable characters, unique within (tenant_id, alpha.school_period).
meaning
Stable school period id.
constraints
Use this for relationships; do not parse period ids from titles.
relationship
Referenced by parent_period_id and downstream modules that need school-calendar context.
invalidWhen
Blank, reused for another period, or changed because title changes.
edgeCases
A period may be a grading period, term, semester, or whole school year.
example
period_2026_2027_school_year
pii
No
allowedValues
[]
provenance
{
  "changeType": "rename",
  "sourceType": "1edtech_alias",
  "source": "oneroster.academic_sessions.sourced_id",
  "sourceAnchor": "https://platform3-andymontgomery-9773s-projects.vercel.app/oneroster/1edtech/data_dictionary/#field-oneroster-academic-sessions-sourced-id",
  "aliasMapField": "school_period.period_id",
  "label": "Alpha rename",
  "note": "Tenant-scoped school period id.",
  "itds": [
    {
      "id": "paitd-005-school-periods",
      "title": "School Period Is The Plain Alias For Academic Session",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-005-school-periods"
    },
    {
      "id": "paitd-010-alias-map-contract",
      "title": "Alias Map Is A Generated Architecture Artifact",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-010-alias-map-contract"
    }
  ]
}
storage
{
  "kind": "oneedtech_view_column",
  "source": "oneroster.academic_sessions.sourced_id",
  "storageRule": "Selected by alpha.school_period_base from oneroster.academic_sessions; public alpha.school_period does not store a copy of this 1EdTech field.",
  "writeRoute": "Route all writes to the OneRoster 1EdTech academic_sessions surface."
}

source_status

title
Source Status
type
TEXT enum
publicApi
string enum
nullability
Nullable in bulk-origin rows; required when the source sends delta status.
required
Conditional
range
active or tobedeleted.
meaning
OneRoster lifecycle marker preserved for provenance.
constraints
Does not delete downstream historical references by itself.
relationship
No direct foreign key.
invalidWhen
Any value other than active or tobedeleted, or used to erase history.
edgeCases
Bulk OneRoster rows intentionally omit status.
example
active
pii
No
allowedValues
[
  {
    "value": "active",
    "meaning": "The delta row is current and should be inserted or updated.",
    "useWhen": "Use only in delta row status fields. Alpha keeps this only as source provenance; ordinary active-as-of queries still use dated memberships.",
    "invalidWhen": "Invalid in bulk rows or when the row should be deleted."
  },
  {
    "value": "tobedeleted",
    "meaning": "The delta row indicates the source wants this object deleted or retired.",
    "useWhen": "Use only in delta row status fields. Alpha keeps this only as source provenance; ordinary active-as-of queries still use dated memberships.",
    "invalidWhen": "Invalid in bulk rows or when the source object remains active."
  }
]
provenance
{
  "changeType": "rename",
  "sourceType": "1edtech_alias",
  "source": "oneroster.academic_sessions.status",
  "sourceAnchor": "https://platform3-andymontgomery-9773s-projects.vercel.app/oneroster/1edtech/data_dictionary/#field-oneroster-academic-sessions-status",
  "aliasMapField": "school_period.source_status",
  "label": "Alpha rename",
  "note": "OneRoster lifecycle state.",
  "itds": [
    {
      "id": "paitd-005-school-periods",
      "title": "School Period Is The Plain Alias For Academic Session",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-005-school-periods"
    },
    {
      "id": "paitd-111-privacy-retention",
      "title": "API Axis: Privacy / Retention",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-111-privacy-retention"
    }
  ]
}
storage
{
  "kind": "oneedtech_view_column",
  "source": "oneroster.academic_sessions.status",
  "storageRule": "Selected by alpha.school_period_base from oneroster.academic_sessions; public alpha.school_period does not store a copy of this 1EdTech field.",
  "writeRoute": "Route all writes to the OneRoster 1EdTech academic_sessions surface."
}

source_updated_at

title
Source Updated At
type
TIMESTAMPTZ
publicApi
ISO 8601 datetime
nullability
Nullable in bulk-origin rows; required when the source sends delta status.
required
Conditional
range
ISO 8601 UTC datetime.
meaning
Source-system modified timestamp for modifiedSince scans.
constraints
Must be parsed and stored as a timestamp.
relationship
Used by modifiedSince list scans.
invalidWhen
Malformed, supplied where source contract forbids it, or older than a previous accepted delta for the same period.
edgeCases
Per-resource Alpha writes may also update platform updated_at.
example
2026-08-15T13:45:30.000Z
pii
No
allowedValues
[]
provenance
{
  "changeType": "rename",
  "sourceType": "1edtech_alias",
  "source": "oneroster.academic_sessions.date_last_modified",
  "sourceAnchor": "https://platform3-andymontgomery-9773s-projects.vercel.app/oneroster/1edtech/data_dictionary/#field-oneroster-academic-sessions-date-last-modified",
  "aliasMapField": "school_period.source_updated_at",
  "label": "Alpha rename",
  "note": "Source-system modified timestamp for delta rows.",
  "itds": [
    {
      "id": "paitd-005-school-periods",
      "title": "School Period Is The Plain Alias For Academic Session",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-005-school-periods"
    },
    {
      "id": "paitd-103-query-model",
      "title": "API Axis: Query Model",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-103-query-model"
    }
  ]
}
storage
{
  "kind": "oneedtech_view_column",
  "source": "oneroster.academic_sessions.date_last_modified",
  "storageRule": "Selected by alpha.school_period_base from oneroster.academic_sessions; public alpha.school_period does not store a copy of this 1EdTech field.",
  "writeRoute": "Route all writes to the OneRoster 1EdTech academic_sessions surface."
}

title

title
Title
type
TEXT
publicApi
string
nullability
Required.
required
Yes
range
1 to 255 visible characters.
meaning
Human title for the period.
constraints
Display only. Consumers must not parse season or school year from title.
relationship
No relationship.
invalidWhen
Blank, used as period_kind, or parsed to compute dates.
edgeCases
A title may include local naming conventions; period_kind and school_year stay typed.
example
2026-2027 School Year
pii
No
allowedValues
[]
provenance
{
  "changeType": "rename",
  "sourceType": "1edtech_alias",
  "source": "oneroster.academic_sessions.title",
  "sourceAnchor": "https://platform3-andymontgomery-9773s-projects.vercel.app/oneroster/1edtech/data_dictionary/#field-oneroster-academic-sessions-title",
  "aliasMapField": "school_period.title",
  "label": "Alpha rename",
  "note": "Human title for the period.",
  "itds": [
    {
      "id": "paitd-005-school-periods",
      "title": "School Period Is The Plain Alias For Academic Session",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-005-school-periods"
    }
  ]
}
storage
{
  "kind": "oneedtech_view_column",
  "source": "oneroster.academic_sessions.title",
  "storageRule": "Selected by alpha.school_period_base from oneroster.academic_sessions; public alpha.school_period does not store a copy of this 1EdTech field.",
  "writeRoute": "Route all writes to the OneRoster 1EdTech academic_sessions surface."
}

period_kind

title
Period Kind
type
TEXT enum
publicApi
string enum
nullability
Required.
required
Yes
range
school_year, semester, term, or grading_period.
meaning
Canonical period type; consumers never parse the title.
constraints
Fold OneRoster schoolYear and gradingPeriod to Alpha school_year and grading_period at write time.
relationship
No foreign key; controls period filtering.
invalidWhen
Free text, source spelling leaked into Alpha, or inferred from title.
edgeCases
Downstream gradebook rollups can use grading_period, but Results owns rollups.
example
school_year
pii
No
allowedValues
[
  {
    "value": "school_year",
    "meaning": "Whole school-year calendar window. Source alias: OneRoster schoolYear.",
    "useWhen": "Use when the period spans the school year and school_year is the ending year.",
    "invalidWhen": "Invalid for semester, term, or grading-period windows."
  },
  {
    "value": "semester",
    "meaning": "A semester within a school year. Source alias: OneRoster semester.",
    "useWhen": "Use when the school calendar is semester-based.",
    "invalidWhen": "Invalid for shorter terms or grading periods."
  },
  {
    "value": "term",
    "meaning": "A term that is not a semester. Source alias: OneRoster term.",
    "useWhen": "Use for quarter, trimester, or local term windows represented by OneRoster term.",
    "invalidWhen": "Invalid for a whole school year."
  },
  {
    "value": "grading_period",
    "meaning": "A reporting period used for gradebook context. Source alias: OneRoster gradingPeriod.",
    "useWhen": "Use when a downstream gradebook or Results rollup needs the grading-period context.",
    "invalidWhen": "Invalid when the period is only a semester or whole school year."
  }
]
provenance
{
  "changeType": "rename+restrict",
  "sourceType": "1edtech_alias",
  "source": "oneroster.academic_sessions.type",
  "sourceAnchor": "https://platform3-andymontgomery-9773s-projects.vercel.app/oneroster/1edtech/data_dictionary/#field-oneroster-academic-sessions-type",
  "aliasMapField": "school_period.period_kind",
  "label": "Alpha rename+restrict",
  "note": "Canonical period type; consumers never parse the title.",
  "itds": [
    {
      "id": "paitd-005-school-periods",
      "title": "School Period Is The Plain Alias For Academic Session",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-005-school-periods"
    }
  ]
}
storage
{
  "kind": "oneedtech_view_column",
  "source": "oneroster.academic_sessions.type",
  "storageRule": "Selected by alpha.school_period_base from oneroster.academic_sessions; public alpha.school_period does not store a copy of this 1EdTech field.",
  "writeRoute": "Route all writes to the OneRoster 1EdTech academic_sessions surface."
}

start_date

title
Start Date
type
DATE
publicApi
date
nullability
Required.
required
Yes
range
ISO 8601 date YYYY-MM-DD.
meaning
Inclusive period start date.
constraints
Must be on or before end_date. Use this typed date, not the title, for date-window queries.
relationship
No foreign key.
invalidWhen
Malformed, after end_date, or parsed from title at read time.
edgeCases
A period can start before the calendar year named by school_year.
example
2026-08-15
pii
No
allowedValues
[]
provenance
{
  "changeType": "rename",
  "sourceType": "1edtech_alias",
  "source": "oneroster.academic_sessions.start_date",
  "sourceAnchor": "https://platform3-andymontgomery-9773s-projects.vercel.app/oneroster/1edtech/data_dictionary/#field-oneroster-academic-sessions-start-date",
  "aliasMapField": "school_period.start_date",
  "label": "Alpha rename",
  "note": "Inclusive period start date.",
  "itds": [
    {
      "id": "paitd-005-school-periods",
      "title": "School Period Is The Plain Alias For Academic Session",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-005-school-periods"
    }
  ]
}
storage
{
  "kind": "oneedtech_view_column",
  "source": "oneroster.academic_sessions.start_date",
  "storageRule": "Selected by alpha.school_period_base from oneroster.academic_sessions; public alpha.school_period does not store a copy of this 1EdTech field.",
  "writeRoute": "Route all writes to the OneRoster 1EdTech academic_sessions surface."
}

end_date

title
End Date
type
DATE
publicApi
date
nullability
Required.
required
Yes
range
ISO 8601 date YYYY-MM-DD.
meaning
Exclusive period end date.
constraints
Must be after start_date. Treat as exclusive for point-in-time and period containment checks.
relationship
No foreign key.
invalidWhen
Malformed, on/before start_date, or treated as inclusive without a surface policy.
edgeCases
A school year ending in June 2027 may carry school_year=2027.
example
2027-06-01
pii
No
allowedValues
[]
provenance
{
  "changeType": "rename",
  "sourceType": "1edtech_alias",
  "source": "oneroster.academic_sessions.end_date",
  "sourceAnchor": "https://platform3-andymontgomery-9773s-projects.vercel.app/oneroster/1edtech/data_dictionary/#field-oneroster-academic-sessions-end-date",
  "aliasMapField": "school_period.end_date",
  "label": "Alpha rename",
  "note": "Exclusive period end date.",
  "itds": [
    {
      "id": "paitd-005-school-periods",
      "title": "School Period Is The Plain Alias For Academic Session",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-005-school-periods"
    }
  ]
}
storage
{
  "kind": "oneedtech_view_column",
  "source": "oneroster.academic_sessions.end_date",
  "storageRule": "Selected by alpha.school_period_base from oneroster.academic_sessions; public alpha.school_period does not store a copy of this 1EdTech field.",
  "writeRoute": "Route all writes to the OneRoster 1EdTech academic_sessions surface."
}

parent_period_id

title
Parent Period Id
type
TEXT
publicApi
period id
nullability
Optional.
required
No
range
1 to 255 printable characters when supplied.
meaning
Parent period relationship.
constraints
Must reference alpha.school_period.period_id in the same tenant when supplied.
relationship
Self-reference: one parent period can contain many child periods.
invalidWhen
References a missing period, crosses tenant, creates a cycle, or is stored as free text.
edgeCases
Whole school-year periods normally have no parent.
example
period_2026_2027_school_year
pii
No
allowedValues
[]
provenance
{
  "changeType": "rename",
  "sourceType": "1edtech_alias",
  "source": "oneroster.academic_sessions.parent_sourced_id",
  "sourceAnchor": "https://platform3-andymontgomery-9773s-projects.vercel.app/oneroster/1edtech/data_dictionary/#field-oneroster-academic-sessions-parent-sourced-id",
  "aliasMapField": "school_period.parent_period_id",
  "label": "Alpha rename",
  "note": "Parent period relationship.",
  "itds": [
    {
      "id": "paitd-005-school-periods",
      "title": "School Period Is The Plain Alias For Academic Session",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-005-school-periods"
    }
  ]
}
storage
{
  "kind": "oneedtech_view_column",
  "source": "oneroster.academic_sessions.parent_sourced_id",
  "storageRule": "Selected by alpha.school_period_base from oneroster.academic_sessions; public alpha.school_period does not store a copy of this 1EdTech field.",
  "writeRoute": "Route all writes to the OneRoster 1EdTech academic_sessions surface."
}

school_year

title
School Year
type
INTEGER
publicApi
integer
nullability
Required.
required
Yes
range
Four-digit ending year, such as 2027.
meaning
Typed school-year value, not a string parsed from title.
constraints
Must be the year in which the school year ends unless an architecture-superseding policy says otherwise.
relationship
No foreign key; consumed by policy and downstream reports.
invalidWhen
Non-integer, parsed from title, mixed with season text, or outside reasonable school-year range.
edgeCases
For 2026-2027, school_year is 2027.
example
2027
pii
No
allowedValues
[]
provenance
{
  "changeType": "rename",
  "sourceType": "1edtech_alias",
  "source": "oneroster.academic_sessions.school_year",
  "sourceAnchor": "https://platform3-andymontgomery-9773s-projects.vercel.app/oneroster/1edtech/data_dictionary/#field-oneroster-academic-sessions-school-year",
  "aliasMapField": "school_period.school_year",
  "label": "Alpha rename",
  "note": "Typed school-year value, not a string parsed from title.",
  "itds": [
    {
      "id": "paitd-005-school-periods",
      "title": "School Period Is The Plain Alias For Academic Session",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-005-school-periods"
    }
  ]
}
storage
{
  "kind": "oneedtech_view_column",
  "source": "oneroster.academic_sessions.school_year",
  "storageRule": "Selected by alpha.school_period_base from oneroster.academic_sessions; public alpha.school_period does not store a copy of this 1EdTech field.",
  "writeRoute": "Route all writes to the OneRoster 1EdTech academic_sessions surface."
}

alpha.person_sensitive_profile · Person Sensitive Profile

objectName
person_sensitive_profile
apiCollection
/person_sensitive_profiles
storage
Restricted public view alpha.person_sensitive_profile selects from alpha.person_sensitive_profile_base over oneroster.demographics. Authorization and redaction are API/view restrictions, not copied storage.
changeType
restrict
upstream
oneroster.demographics
primaryKey
(tenant_id, person_id)
purpose
Sensitive demographic facts kept out of ordinary roster lists and returned only through authorized self, guardian, or administrative views.
lifecycle
Created from OneRoster demographics rows after the person exists. Reads are audited and redacted from public examples.
auth
Requires explicit sensitive-profile scope plus self, guardian, or administrative relationship checks. Every read writes an audit row.
sourceType
1edtech_restricted_view
publicSurface
alpha.person_sensitive_profile
baseView
alpha.person_sensitive_profile_base
baseSource
oneroster.demographics
coreWriteRoute
Route sourced-field writes to the OneRoster 1EdTech demographics surface.
extensionWriteRoute
None. Authorization and redaction are API/view restrictions, not copied storage.
anchor
table-alpha-person-sensitive-profile
fieldCount
7
sourceAnchor
https://platform3-andymontgomery-9773s-projects.vercel.app/oneroster/1edtech/data_dictionary/#table-oneroster-demographics
filters
[
  "personId",
  "modifiedSince"
]
sortKeys
[
  "person_id"
]
extensionTables
[]
storageContract
{
  "alphaObject": "person_sensitive_profile",
  "publicSurface": "alpha.person_sensitive_profile",
  "upstreamModule": "oneroster/1edtech",
  "baseSource": "oneroster.demographics",
  "baseView": "alpha.person_sensitive_profile_base",
  "extensionTables": [],
  "coreWriteRoute": "Route sourced-field writes to the OneRoster 1EdTech demographics surface.",
  "extensionWriteRoute": "None. Authorization and redaction are API/view restrictions, not copied storage.",
  "requiredShape": "CREATE VIEW over the OneRoster 1EdTech base; no Alpha table may store sourced OneRoster columns."
}
example
{
  "person_id": "person_ada_lovelace",
  "birth_date": "2012-04-23",
  "sex": "unspecified",
  "race_ethnicity_flags": {
    "asian": true,
    "hispanic_or_latino_ethnicity": false
  },
  "birth_place_fields": {
    "country_of_birth_code": "US",
    "state_of_birth_abbreviation": "CA"
  },
  "residence_status": "resident"
}

Fields (7)

tenant_id

title
Tenant Id
type
UUID
publicApi
Hidden in ordinary Alpha responses; selected from the verified JWT.
nullability
Required on every stored row.
required
Yes
range
Valid PostgreSQL UUID.
meaning
The tenant boundary that owns this People & Orgs row.
constraints
Must equal the verified JWT tenant_id or tenantId claim. Never accept a tenant header or body field as source of truth.
relationship
Belongs to one platform.tenant. One tenant owns many People & Orgs rows.
invalidWhen
Missing, malformed, points to another tenant, or is supplied by an unverified request body.
edgeCases
Demo token minting may accept tenantId=demo, but stored rows still use the resolved tenant id.
example
0d4ce2f4-1c42-4f3c-9f0d-03fb7f5271d3
pii
No
allowedValues
[]
provenance
{
  "changeType": "inherited",
  "sourceType": "platform_shared",
  "source": "platform.tenant",
  "sourceAnchor": null,
  "aliasMapField": null,
  "label": "Alpha inherited",
  "note": "Inherited platform tenant routing field, not a OneRoster alias.",
  "itds": [
    {
      "id": "paitd-109-tenant-routing",
      "title": "API Axis: Tenant Routing",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-109-tenant-routing"
    }
  ]
}
storage
{
  "kind": "platform_inherited_column",
  "source": "platform.tenant / verified JWT tenant claim",
  "storageRule": "Inherited platform tenant key. It scopes base rows, extension rows, and views; it is not copied from OneRoster or Ed-Fi.",
  "writeRoute": "Resolved from the verified JWT tenant claim by the platform layer."
}

person_id

title
Person Id
type
TEXT
publicApi
person id
nullability
Required.
required
Yes
range
1 to 255 printable characters.
meaning
Person whose sensitive profile is described.
constraints
Must reference alpha.person.person_id in the same tenant.
relationship
One sensitive profile belongs to one person.
invalidWhen
References a missing person, crosses tenant, or is returned to an unauthorized caller.
edgeCases
A person can exist without a sensitive profile.
example
person_ada_lovelace
pii
Identifier
allowedValues
[]
provenance
{
  "changeType": "restrict",
  "sourceType": "1edtech_alias",
  "source": "oneroster.demographics.sourced_id",
  "sourceAnchor": "https://platform3-andymontgomery-9773s-projects.vercel.app/oneroster/1edtech/data_dictionary/#field-oneroster-demographics-sourced-id",
  "aliasMapField": "person_sensitive_profile.person_id",
  "label": "Alpha restrict",
  "note": "Person whose sensitive profile is described.",
  "itds": [
    {
      "id": "paitd-009-sensitive-profile-privacy",
      "title": "Sensitive Profiles Are Restricted, Not Default Roster Fields",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-009-sensitive-profile-privacy"
    },
    {
      "id": "paitd-111-privacy-retention",
      "title": "API Axis: Privacy / Retention",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-111-privacy-retention"
    }
  ]
}
storage
{
  "kind": "oneedtech_view_column",
  "source": "oneroster.demographics.sourced_id",
  "storageRule": "Selected by alpha.person_sensitive_profile_base from oneroster.demographics; public alpha.person_sensitive_profile does not store a copy of this 1EdTech field.",
  "writeRoute": "Route sourced-field writes to the OneRoster 1EdTech demographics surface."
}

birth_date

title
Birth Date
type
DATE
publicApi
date
nullability
Optional.
required
No
range
ISO 8601 date YYYY-MM-DD.
meaning
Date of birth when lawfully supplied.
constraints
Sensitive PII. Do not expose in ordinary person lists, Problems, logs, or public examples.
relationship
No relationship.
invalidWhen
Malformed, guessed, or returned without sensitive-profile authorization.
edgeCases
Null means no source value, not unknown age computed by the surface.
example
2012-04-23
pii
Sensitive PII
allowedValues
[]
provenance
{
  "changeType": "restrict",
  "sourceType": "1edtech_alias",
  "source": "oneroster.demographics.birth_date",
  "sourceAnchor": "https://platform3-andymontgomery-9773s-projects.vercel.app/oneroster/1edtech/data_dictionary/#field-oneroster-demographics-birth-date",
  "aliasMapField": "person_sensitive_profile.birth_date",
  "label": "Alpha restrict",
  "note": "Date of birth when lawfully supplied.",
  "itds": [
    {
      "id": "paitd-009-sensitive-profile-privacy",
      "title": "Sensitive Profiles Are Restricted, Not Default Roster Fields",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-009-sensitive-profile-privacy"
    },
    {
      "id": "paitd-111-privacy-retention",
      "title": "API Axis: Privacy / Retention",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-111-privacy-retention"
    }
  ]
}
storage
{
  "kind": "oneedtech_view_column",
  "source": "oneroster.demographics.birth_date",
  "storageRule": "Selected by alpha.person_sensitive_profile_base from oneroster.demographics; public alpha.person_sensitive_profile does not store a copy of this 1EdTech field.",
  "writeRoute": "Route sourced-field writes to the OneRoster 1EdTech demographics surface."
}

sex

title
Sex
type
TEXT enum
publicApi
string enum
nullability
Optional.
required
No
range
male, female, unspecified, or other.
meaning
Source demographic sex value.
constraints
Sensitive demographic exchange value. Preserve source value; never infer it.
relationship
No relationship.
invalidWhen
Guessed, used for placement without policy, or returned without sensitive-profile authorization.
edgeCases
unspecified is a deliberate source value and must not be collapsed into null.
example
unspecified
pii
Sensitive PII
allowedValues
[
  {
    "value": "male",
    "meaning": "Demographic sex value supplied by the source system.",
    "useWhen": "Use only when the source system lawfully provides this value.",
    "invalidWhen": "Invalid if copied to logs or used outside OneRoster demographic exchange."
  },
  {
    "value": "female",
    "meaning": "Demographic sex value supplied by the source system.",
    "useWhen": "Use only when the source system lawfully provides this value.",
    "invalidWhen": "Invalid if copied to logs or used outside OneRoster demographic exchange."
  },
  {
    "value": "unspecified",
    "meaning": "The source system did not specify a male/female/other value.",
    "useWhen": "Use when the demographic value is intentionally unspecified.",
    "invalidWhen": "Invalid if used to guess or erase a known source value."
  },
  {
    "value": "other",
    "meaning": "The source system supplied a demographic sex value outside male/female/unspecified.",
    "useWhen": "Use only when that is the source-system value.",
    "invalidWhen": "Invalid if used as a catch-all for missing data."
  }
]
provenance
{
  "changeType": "restrict",
  "sourceType": "1edtech_alias",
  "source": "oneroster.demographics.sex",
  "sourceAnchor": "https://platform3-andymontgomery-9773s-projects.vercel.app/oneroster/1edtech/data_dictionary/#field-oneroster-demographics-sex",
  "aliasMapField": "person_sensitive_profile.sex",
  "label": "Alpha restrict",
  "note": "Source demographic sex value.",
  "itds": [
    {
      "id": "paitd-009-sensitive-profile-privacy",
      "title": "Sensitive Profiles Are Restricted, Not Default Roster Fields",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-009-sensitive-profile-privacy"
    },
    {
      "id": "paitd-111-privacy-retention",
      "title": "API Axis: Privacy / Retention",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-111-privacy-retention"
    }
  ]
}
storage
{
  "kind": "oneedtech_view_column",
  "source": "oneroster.demographics.sex",
  "storageRule": "Selected by alpha.person_sensitive_profile_base from oneroster.demographics; public alpha.person_sensitive_profile does not store a copy of this 1EdTech field.",
  "writeRoute": "Route sourced-field writes to the OneRoster 1EdTech demographics surface."
}

race_ethnicity_flags

title
Race Ethnicity Flags
type
JSONB object
publicApi
object of boolean flags
nullability
Optional object; keys may be absent when the source omits them.
required
No
range
Allowed keys listed below; each present value is true or false.
meaning
Independent source race and ethnicity flags; never inferred from names or places.
constraints
The flags are independent. Do not collapse them into one display label unless a downstream compliance report owns that transformation.
relationship
No relationship.
invalidWhen
Inferred, normalized into a single race value, logged, or returned without sensitive-profile authorization.
edgeCases
Multiple race flags may be true at the same time; hispanic_or_latino_ethnicity is independent of race.
pii
Sensitive PII
example
{
  "asian": true,
  "hispanic_or_latino_ethnicity": false
}
allowedValues
[
  {
    "value": "american_indian_or_alaska_native",
    "meaning": "Source-supplied race flag. It may be true at the same time as another race flag.",
    "useWhen": "Use only when the source demographics row supplies the value.",
    "invalidWhen": "Invalid if inferred from name, language, place, or another demographic field."
  },
  {
    "value": "asian",
    "meaning": "Source-supplied race flag. It may be true at the same time as another race flag.",
    "useWhen": "Use only when the source demographics row supplies the value.",
    "invalidWhen": "Invalid if inferred from name, language, place, or another demographic field."
  },
  {
    "value": "black_or_african_american",
    "meaning": "Source-supplied race flag. It may be true at the same time as another race flag.",
    "useWhen": "Use only when the source demographics row supplies the value.",
    "invalidWhen": "Invalid if inferred from name, language, place, or another demographic field."
  },
  {
    "value": "native_hawaiian_or_other_pacific_islander",
    "meaning": "Source-supplied race flag. It may be true at the same time as another race flag.",
    "useWhen": "Use only when the source demographics row supplies the value.",
    "invalidWhen": "Invalid if inferred from name, language, place, or another demographic field."
  },
  {
    "value": "white",
    "meaning": "Source-supplied race flag. It may be true at the same time as another race flag.",
    "useWhen": "Use only when the source demographics row supplies the value.",
    "invalidWhen": "Invalid if inferred from name, language, place, or another demographic field."
  },
  {
    "value": "two_or_more_races",
    "meaning": "Source-supplied indicator that the source reports two or more races.",
    "useWhen": "Use only when the source sends demographic_race_two_or_more_races.",
    "invalidWhen": "Invalid if computed by counting other flags at read time."
  },
  {
    "value": "hispanic_or_latino_ethnicity",
    "meaning": "Source-supplied ethnicity flag. It is independent of race flags.",
    "useWhen": "Use only when the source demographics row supplies the value.",
    "invalidWhen": "Invalid if inferred from name, language, place, or another demographic field."
  }
]
provenance
{
  "changeType": "restrict",
  "sourceType": "1edtech_alias",
  "source": "oneroster.demographics.american_indian_or_alaska_native",
  "sourceAnchor": "https://platform3-andymontgomery-9773s-projects.vercel.app/oneroster/1edtech/data_dictionary/#field-oneroster-demographics-american-indian-or-alaska-native",
  "aliasMapField": null,
  "label": "Alpha restrict",
  "note": "Independent source flags; never inferred from names or places.",
  "itds": [
    {
      "id": "paitd-009-sensitive-profile-privacy",
      "title": "Sensitive Profiles Are Restricted, Not Default Roster Fields",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-009-sensitive-profile-privacy"
    },
    {
      "id": "paitd-111-privacy-retention",
      "title": "API Axis: Privacy / Retention",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-111-privacy-retention"
    }
  ]
}
storage
{
  "kind": "oneedtech_view_column",
  "source": "oneroster.demographics.race/ethnicity fields",
  "storageRule": "Selected by alpha.person_sensitive_profile_base from oneroster.demographics; public alpha.person_sensitive_profile does not store a copy of this 1EdTech field.",
  "writeRoute": "Route sourced-field writes to the OneRoster 1EdTech demographics surface."
}

birth_place_fields

title
Birth Place Fields
type
JSONB object
publicApi
object
nullability
Optional object; keys may be absent when the source omits them.
required
No
range
Allowed keys listed below; text values preserve source format.
meaning
Optional source-supplied birth location details.
constraints
Sensitive PII. Never infer from address, language, or current school.
relationship
No relationship.
invalidWhen
Guessed, parsed from another field, logged, or returned without sensitive-profile authorization.
edgeCases
A country code can be present without state or city.
pii
Sensitive PII
example
{
  "country_of_birth_code": "US",
  "state_of_birth_abbreviation": "CA"
}
allowedValues
[
  {
    "value": "country_of_birth_code",
    "meaning": "Country of birth code from OneRoster demographics.",
    "useWhen": "Use only when lawfully supplied by the source.",
    "invalidWhen": "Invalid if guessed from current address, language, or school."
  },
  {
    "value": "state_of_birth_abbreviation",
    "meaning": "State or province of birth abbreviation from OneRoster demographics.",
    "useWhen": "Use only when lawfully supplied by the source.",
    "invalidWhen": "Invalid if guessed or normalized without a source value."
  },
  {
    "value": "city_of_birth",
    "meaning": "City of birth text from OneRoster demographics.",
    "useWhen": "Use only when lawfully supplied by the source.",
    "invalidWhen": "Invalid if logged, exposed publicly, or inferred."
  }
]
provenance
{
  "changeType": "restrict",
  "sourceType": "1edtech_alias",
  "source": "oneroster.demographics.country_of_birth_code",
  "sourceAnchor": "https://platform3-andymontgomery-9773s-projects.vercel.app/oneroster/1edtech/data_dictionary/#field-oneroster-demographics-country-of-birth-code",
  "aliasMapField": null,
  "label": "Alpha restrict",
  "note": "Optional source-supplied birth location details.",
  "itds": [
    {
      "id": "paitd-009-sensitive-profile-privacy",
      "title": "Sensitive Profiles Are Restricted, Not Default Roster Fields",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-009-sensitive-profile-privacy"
    },
    {
      "id": "paitd-111-privacy-retention",
      "title": "API Axis: Privacy / Retention",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-111-privacy-retention"
    }
  ]
}
storage
{
  "kind": "oneedtech_view_column",
  "source": "oneroster.demographics.country/state/city of birth",
  "storageRule": "Selected by alpha.person_sensitive_profile_base from oneroster.demographics; public alpha.person_sensitive_profile does not store a copy of this 1EdTech field.",
  "writeRoute": "Route sourced-field writes to the OneRoster 1EdTech demographics surface."
}

residence_status

title
Residence Status
type
TEXT
publicApi
string
nullability
Optional.
required
No
range
0 to 255 visible characters supplied by the source.
meaning
Source legal-residence status.
constraints
Sensitive demographic/legal context. Do not infer or expose outside authorized views.
relationship
No relationship.
invalidWhen
Free-form value not supplied by source, used for authorization, logged publicly, or returned without scope.
edgeCases
Blank means no source value.
example
resident
pii
Sensitive PII
allowedValues
[]
provenance
{
  "changeType": "restrict",
  "sourceType": "1edtech_alias",
  "source": "oneroster.demographics.public_school_residence_status",
  "sourceAnchor": "https://platform3-andymontgomery-9773s-projects.vercel.app/oneroster/1edtech/data_dictionary/#field-oneroster-demographics-public-school-residence-status",
  "aliasMapField": "person_sensitive_profile.residence_status",
  "label": "Alpha restrict",
  "note": "Source legal-residence status.",
  "itds": [
    {
      "id": "paitd-009-sensitive-profile-privacy",
      "title": "Sensitive Profiles Are Restricted, Not Default Roster Fields",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-009-sensitive-profile-privacy"
    },
    {
      "id": "paitd-111-privacy-retention",
      "title": "API Axis: Privacy / Retention",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-111-privacy-retention"
    }
  ]
}
storage
{
  "kind": "oneedtech_view_column",
  "source": "oneroster.demographics.public_school_residence_status",
  "storageRule": "Selected by alpha.person_sensitive_profile_base from oneroster.demographics; public alpha.person_sensitive_profile does not store a copy of this 1EdTech field.",
  "writeRoute": "Route sourced-field writes to the OneRoster 1EdTech demographics surface."
}

alpha.guardian_view · Guardian

objectName
guardian
apiCollection
/guardians
storage
Public view alpha.guardian_view selects canonical, non-deleted Ed-Fi Contact records from edfi.canonical_record. It has no Alpha-owned table and stores no copied Ed-Fi columns.
changeType
rename + restrict
upstream
edfi.canonical_record(resource_name=Contact)
primaryKey
(tenant_id, guardian_id)
purpose
A parent, guardian, emergency contact, or family contact for a student.
lifecycle
Created and corrected through the Ed-Fi 1EdTech Contact surface. Ordinary Alpha reads expose only canonical, non-deleted contacts; draft and deleted records stay on Ed-Fi admin/audit paths.
auth
Readable only to relationship-scoped guardian/student/school/admin claims. Contact details follow PAITD-013 privacy rules.
sourceType
edfi_alias_view
publicSurface
alpha.guardian_view
baseView
alpha.guardian_base_view
baseSource
edfi.canonical_record(resource_name=Contact)
coreWriteRoute
Route all sourced-field writes to the Ed-Fi 1EdTech Contact collection; Alpha exposes only canonical, non-deleted Contact records.
extensionWriteRoute
None. Guardian facts that originate in Ed-Fi stay in edfi.canonical_record and descriptor_code-backed views.
anchor
table-alpha-guardian-view
fieldCount
9
sourceAnchor
https://platform3-andymontgomery-9773s-projects.vercel.app/ed_fi/1edtech/data_dictionary/#entry-contact-4d61009a458d
filters
[
  "guardianId",
  "contactUniqueId",
  "studentPersonId via guardian_relationship",
  "modifiedSince"
]
sortKeys
[
  "full_name",
  "guardian_id",
  "source_updated_at"
]
extensionTables
[]
storageContract
{
  "alphaObject": "guardian",
  "publicSurface": "alpha.guardian_view",
  "upstreamModule": "ed_fi/1edtech",
  "baseSource": "edfi.canonical_record(resource_name=Contact)",
  "baseView": "alpha.guardian_base_view",
  "extensionTables": [],
  "coreWriteRoute": "Route all sourced-field writes to the Ed-Fi 1EdTech Contact collection; Alpha exposes only canonical, non-deleted Contact records.",
  "extensionWriteRoute": "None. Guardian facts that originate in Ed-Fi stay in edfi.canonical_record and descriptor_code-backed views.",
  "requiredShape": "CREATE VIEW over edfi.canonical_record; filter resource_name/collection_route, tenant_id, is_deleted=false, canonical state, descriptor_code resolution, and OneRoster sourcedId joins. No Alpha table may store sourced Ed-Fi columns."
}
example
{
  "guardian_id": "guardian_contact_001",
  "contact_unique_id": "contact-ada-family-001",
  "full_name": "Grace Hopper",
  "email": "grace.hopper@example.edu",
  "phone": "+15550101010",
  "language_codes": [
    "en",
    "es"
  ],
  "source_updated_at": "2026-08-15T13:45:30.000Z",
  "is_deleted": false
}

Fields (9)

tenant_id

title
Tenant Id
type
UUID
publicApi
Hidden in ordinary Alpha responses; selected from the verified JWT.
nullability
Required on every stored row.
required
Yes
range
Valid PostgreSQL UUID.
meaning
The tenant boundary that owns this People & Orgs row.
constraints
Must equal the verified JWT tenant_id or tenantId claim. Never accept a tenant header or body field as source of truth.
relationship
Belongs to one platform.tenant. One tenant owns many People & Orgs rows.
invalidWhen
Missing, malformed, points to another tenant, or is supplied by an unverified request body.
edgeCases
Demo token minting may accept tenantId=demo, but stored rows still use the resolved tenant id.
example
0d4ce2f4-1c42-4f3c-9f0d-03fb7f5271d3
pii
No
allowedValues
[]
provenance
{
  "changeType": "inherited",
  "sourceType": "platform_shared",
  "source": "platform.tenant",
  "sourceAnchor": null,
  "aliasMapField": null,
  "label": "Alpha inherited",
  "note": "Inherited platform tenant routing field, not a OneRoster alias.",
  "itds": [
    {
      "id": "paitd-109-tenant-routing",
      "title": "API Axis: Tenant Routing",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-109-tenant-routing"
    }
  ]
}
storage
{
  "kind": "platform_inherited_column",
  "source": "platform.tenant / verified JWT tenant claim",
  "storageRule": "Inherited platform tenant key. It scopes base rows, extension rows, and views; it is not copied from OneRoster or Ed-Fi.",
  "writeRoute": "Resolved from the verified JWT tenant claim by the platform layer."
}

guardian_id

title
Guardian Id
type
TEXT
publicApi
string
nullability
Required.
required
Yes
range
Tenant-scoped Ed-Fi local id, 1 to 255 printable characters.
meaning
Tenant-scoped Ed-Fi local id for the canonical Contact record.
constraints
Must identify one edfi.canonical_record Contact row in the same tenant; never mint an Alpha copy.
relationship
Referenced by alpha.guardian_relationship_view.guardian_id.
invalidWhen
Blank, cross-tenant, draft, or deleted in an ordinary read.
edgeCases
Older Parent naming must be normalized by the Ed-Fi surface before Alpha exposes it.
example
guardian_contact_001
pii
Identifier
allowedValues
[]
provenance
{
  "changeType": "rename+restrict",
  "sourceType": "edfi_alias_view",
  "source": "edfi.canonical_record.edfi_local_id",
  "sourceAnchor": "https://platform3-andymontgomery-9773s-projects.vercel.app/ed_fi/1edtech/data_dictionary/#entry-contact-4d61009a458d",
  "aliasMapField": "guardian.guardian_id",
  "label": "Alpha Ed-Fi view",
  "note": "Tenant-scoped Ed-Fi local id for the canonical Contact record.",
  "itds": [
    {
      "id": "paitd-012-edfi-second-upstream",
      "title": "Ed-Fi Administrative Records Are A Second View-Only Upstream",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-012-edfi-second-upstream"
    },
    {
      "id": "paitd-013-guardian-views",
      "title": "Guardians Come From Ed-Fi Contact And StudentContactAssociation Views",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-013-guardian-views"
    }
  ]
}
storage
{
  "kind": "edfi_canonical_record_view_column",
  "source": "edfi.canonical_record.edfi_local_id",
  "storageRule": "Selected by alpha.guardian_base_view from edfi.canonical_record(resource_name=Contact); public alpha.guardian_view does not store a copy of this Ed-Fi field.",
  "writeRoute": "Route all sourced-field writes to the Ed-Fi 1EdTech Contact collection; Alpha exposes only canonical, non-deleted Contact records."
}

contact_unique_id

title
Contact Unique Id
type
TEXT
publicApi
string
nullability
Conditional.
required
Conditional
range
Ed-Fi ContactUniqueId string.
meaning
Ed-Fi contact unique id.
constraints
Use only as source provenance or to resolve association rows; do not use for tenant routing.
relationship
May resolve guardian_relationship.guardian_id when the association payload supplies Contact.ContactUniqueId.
invalidWhen
Missing when source-required, changed outside Ed-Fi, or used cross-tenant.
edgeCases
guardian_id remains the Alpha join key.
example
contact-ada-family-001
pii
Identifier
allowedValues
[]
provenance
{
  "changeType": "rename+restrict",
  "sourceType": "edfi_alias_view",
  "source": "edfi.canonical_record.payload_json.ContactUniqueId",
  "sourceAnchor": "https://platform3-andymontgomery-9773s-projects.vercel.app/ed_fi/1edtech/data_dictionary/#entry-contact-4d61009a458d",
  "aliasMapField": "guardian.contact_unique_id",
  "label": "Alpha Ed-Fi view",
  "note": "Ed-Fi contact unique id.",
  "itds": [
    {
      "id": "paitd-012-edfi-second-upstream",
      "title": "Ed-Fi Administrative Records Are A Second View-Only Upstream",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-012-edfi-second-upstream"
    },
    {
      "id": "paitd-013-guardian-views",
      "title": "Guardians Come From Ed-Fi Contact And StudentContactAssociation Views",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-013-guardian-views"
    }
  ]
}
storage
{
  "kind": "edfi_canonical_record_view_column",
  "source": "edfi.canonical_record.payload_json.ContactUniqueId",
  "storageRule": "Selected by alpha.guardian_base_view from edfi.canonical_record(resource_name=Contact); public alpha.guardian_view does not store a copy of this Ed-Fi field.",
  "writeRoute": "Route all sourced-field writes to the Ed-Fi 1EdTech Contact collection; Alpha exposes only canonical, non-deleted Contact records."
}

full_name

title
Full Name
type
TEXT
publicApi
string
nullability
Conditional.
required
Conditional
range
1 to 240 visible characters when supplied.
meaning
Full legal name supplied by Ed-Fi Contact.
constraints
Display only; do not parse relationship, language, priority, or legal status from the name.
relationship
No relationship. Use guardian_id and guardian_relationship rows for joins.
invalidWhen
Used as a key or parsed into relationship facts.
edgeCases
Structured upstream names are flattened by the Ed-Fi surface into this plain display field.
example
Grace Hopper
pii
Yes
allowedValues
[]
provenance
{
  "changeType": "rename+restrict",
  "sourceType": "edfi_alias_view",
  "source": "edfi.canonical_record.payload_json.Name",
  "sourceAnchor": "https://platform3-andymontgomery-9773s-projects.vercel.app/ed_fi/1edtech/data_dictionary/#entry-contact-4d61009a458d",
  "aliasMapField": "guardian.full_name",
  "label": "Alpha Ed-Fi view",
  "note": "Full legal name supplied by Ed-Fi Contact.",
  "itds": [
    {
      "id": "paitd-013-guardian-views",
      "title": "Guardians Come From Ed-Fi Contact And StudentContactAssociation Views",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-013-guardian-views"
    },
    {
      "id": "paitd-111-privacy-retention",
      "title": "API Axis: Privacy / Retention",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-111-privacy-retention"
    }
  ]
}
storage
{
  "kind": "edfi_canonical_record_view_column",
  "source": "edfi.canonical_record.payload_json.Name",
  "storageRule": "Selected by alpha.guardian_base_view from edfi.canonical_record(resource_name=Contact); public alpha.guardian_view does not store a copy of this Ed-Fi field.",
  "writeRoute": "Route all sourced-field writes to the Ed-Fi 1EdTech Contact collection; Alpha exposes only canonical, non-deleted Contact records."
}

email

title
Email
type
TEXT
publicApi
email string
nullability
Optional.
required
No
range
0 to 320 characters, parseable as email when supplied.
meaning
Contact email, redacted by relationship-scoped authorization when required.
constraints
Redact when caller lacks contact-detail scope; do not use as a primary key.
relationship
No relationship. Visibility is controlled by guardian_relationship and claims.
invalidWhen
Malformed, exposed to an unrelated caller, logged in public evidence, or used for tenant routing.
edgeCases
A guardian can exist with phone but no email.
example
grace.hopper@example.edu
pii
Yes
allowedValues
[]
provenance
{
  "changeType": "rename+restrict",
  "sourceType": "edfi_alias_view",
  "source": "edfi.canonical_record.payload_json.ElectronicMail",
  "sourceAnchor": "https://platform3-andymontgomery-9773s-projects.vercel.app/ed_fi/1edtech/data_dictionary/#entry-contact-4d61009a458d",
  "aliasMapField": "guardian.email",
  "label": "Alpha Ed-Fi view",
  "note": "Contact email, redacted by relationship-scoped authorization when required.",
  "itds": [
    {
      "id": "paitd-013-guardian-views",
      "title": "Guardians Come From Ed-Fi Contact And StudentContactAssociation Views",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-013-guardian-views"
    },
    {
      "id": "paitd-111-privacy-retention",
      "title": "API Axis: Privacy / Retention",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-111-privacy-retention"
    }
  ]
}
storage
{
  "kind": "edfi_canonical_record_view_column",
  "source": "edfi.canonical_record.payload_json.ElectronicMail",
  "storageRule": "Selected by alpha.guardian_base_view from edfi.canonical_record(resource_name=Contact); public alpha.guardian_view does not store a copy of this Ed-Fi field.",
  "writeRoute": "Route all sourced-field writes to the Ed-Fi 1EdTech Contact collection; Alpha exposes only canonical, non-deleted Contact records."
}

phone

title
Phone
type
TEXT
publicApi
string
nullability
Optional.
required
No
range
0 to 80 visible characters.
meaning
Contact phone, redacted by relationship-scoped authorization when required.
constraints
Treat as contact PII and redact when caller lacks contact-detail scope.
relationship
No relationship.
invalidWhen
Exposed to an unrelated caller, logged in public evidence, or guessed from another field.
edgeCases
A guardian can have multiple upstream phone entries; this is the documented contact projection.
example
+15550101010
pii
Yes
allowedValues
[]
provenance
{
  "changeType": "rename+restrict",
  "sourceType": "edfi_alias_view",
  "source": "edfi.canonical_record.payload_json.Telephone",
  "sourceAnchor": "https://platform3-andymontgomery-9773s-projects.vercel.app/ed_fi/1edtech/data_dictionary/#entry-contact-4d61009a458d",
  "aliasMapField": "guardian.phone",
  "label": "Alpha Ed-Fi view",
  "note": "Contact phone, redacted by relationship-scoped authorization when required.",
  "itds": [
    {
      "id": "paitd-013-guardian-views",
      "title": "Guardians Come From Ed-Fi Contact And StudentContactAssociation Views",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-013-guardian-views"
    },
    {
      "id": "paitd-111-privacy-retention",
      "title": "API Axis: Privacy / Retention",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-111-privacy-retention"
    }
  ]
}
storage
{
  "kind": "edfi_canonical_record_view_column",
  "source": "edfi.canonical_record.payload_json.Telephone",
  "storageRule": "Selected by alpha.guardian_base_view from edfi.canonical_record(resource_name=Contact); public alpha.guardian_view does not store a copy of this Ed-Fi field.",
  "writeRoute": "Route all sourced-field writes to the Ed-Fi 1EdTech Contact collection; Alpha exposes only canonical, non-deleted Contact records."
}

language_codes

title
Language Codes
type
TEXT[]
publicApi
array of strings
nullability
Optional; empty array means no source language supplied.
required
No
range
Source language codes or descriptors normalized by Ed-Fi.
meaning
Communication languages from the Ed-Fi Contact payload.
constraints
Do not infer from name, ethnicity, place, or school.
relationship
No relationship.
invalidWhen
Guessed, parsed at read time, or used as a sensitive demographic substitute.
edgeCases
Instructional language facts belong in their Ed-Fi or policy context; this is contact communication context.
pii
Sensitive
example
[
  "en",
  "es"
]
allowedValues
[]
provenance
{
  "changeType": "rename+restrict",
  "sourceType": "edfi_alias_view",
  "source": "edfi.canonical_record.payload_json.Language",
  "sourceAnchor": "https://platform3-andymontgomery-9773s-projects.vercel.app/ed_fi/1edtech/data_dictionary/#entry-contact-4d61009a458d",
  "aliasMapField": "guardian.language_codes",
  "label": "Alpha Ed-Fi view",
  "note": "Communication languages from the Ed-Fi Contact payload.",
  "itds": [
    {
      "id": "paitd-012-edfi-second-upstream",
      "title": "Ed-Fi Administrative Records Are A Second View-Only Upstream",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-012-edfi-second-upstream"
    },
    {
      "id": "paitd-013-guardian-views",
      "title": "Guardians Come From Ed-Fi Contact And StudentContactAssociation Views",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-013-guardian-views"
    }
  ]
}
storage
{
  "kind": "edfi_canonical_record_view_column",
  "source": "edfi.canonical_record.payload_json.Language",
  "storageRule": "Selected by alpha.guardian_base_view from edfi.canonical_record(resource_name=Contact); public alpha.guardian_view does not store a copy of this Ed-Fi field.",
  "writeRoute": "Route all sourced-field writes to the Ed-Fi 1EdTech Contact collection; Alpha exposes only canonical, non-deleted Contact records."
}

source_updated_at

title
Source Updated At
type
TIMESTAMPTZ
publicApi
ISO 8601 datetime
nullability
Required.
required
Yes
range
ISO 8601 UTC datetime.
meaning
Canonical Ed-Fi record updated timestamp.
constraints
Read from edfi.canonical_record.updated_at; do not parse timestamps from payload text.
relationship
Used by modifiedSince list scans.
invalidWhen
Missing, malformed, client-supplied on Alpha writes, or older than the accepted canonical update.
edgeCases
A payload change can update this even when the Alpha projection stays the same.
example
2026-08-15T13:45:30.000Z
pii
No
allowedValues
[]
provenance
{
  "changeType": "rename+restrict",
  "sourceType": "edfi_alias_view",
  "source": "edfi.canonical_record.updated_at",
  "sourceAnchor": "https://platform3-andymontgomery-9773s-projects.vercel.app/ed_fi/1edtech/data_dictionary/#entry-contact-4d61009a458d",
  "aliasMapField": "guardian.source_updated_at",
  "label": "Alpha Ed-Fi view",
  "note": "Canonical Ed-Fi record updated timestamp.",
  "itds": [
    {
      "id": "paitd-012-edfi-second-upstream",
      "title": "Ed-Fi Administrative Records Are A Second View-Only Upstream",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-012-edfi-second-upstream"
    },
    {
      "id": "paitd-103-query-model",
      "title": "API Axis: Query Model",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-103-query-model"
    }
  ]
}
storage
{
  "kind": "edfi_canonical_record_view_column",
  "source": "edfi.canonical_record.updated_at",
  "storageRule": "Selected by alpha.guardian_base_view from edfi.canonical_record(resource_name=Contact); public alpha.guardian_view does not store a copy of this Ed-Fi field.",
  "writeRoute": "Route all sourced-field writes to the Ed-Fi 1EdTech Contact collection; Alpha exposes only canonical, non-deleted Contact records."
}

is_deleted

title
Is Deleted
type
BOOLEAN
publicApi
boolean
nullability
Required.
required
Yes
range
false in ordinary Alpha reads; true only on authorized audit paths.
meaning
Always false in ordinary Alpha views; deleted contacts are visible only to authorized audit paths.
constraints
Ordinary guardian_view reads filter is_deleted=false.
relationship
No relationship.
invalidWhen
True in an ordinary roster response, omitted from an audit query, or used to hard-delete history.
edgeCases
Soft-deleted contacts remain in Ed-Fi retention history after ordinary Alpha hides them.
example
false
pii
No
allowedValues
[
  {
    "value": "true",
    "meaning": "The fact is asserted by the source or by the Alpha surface.",
    "useWhen": "Use only when the field's own constraints say the fact is true.",
    "invalidWhen": "Invalid when guessed from names, labels, dates, tags, or another field."
  },
  {
    "value": "false",
    "meaning": "The fact is explicitly not asserted.",
    "useWhen": "Use only when the source or surface stores an explicit false value.",
    "invalidWhen": "Invalid when a missing value should remain unknown."
  }
]
provenance
{
  "changeType": "rename+restrict",
  "sourceType": "edfi_alias_view",
  "source": "edfi.canonical_record.is_deleted",
  "sourceAnchor": "https://platform3-andymontgomery-9773s-projects.vercel.app/ed_fi/1edtech/data_dictionary/#entry-contact-4d61009a458d",
  "aliasMapField": "guardian.is_deleted",
  "label": "Alpha Ed-Fi view",
  "note": "Always false in ordinary Alpha views; deleted contacts are visible only to authorized audit paths.",
  "itds": [
    {
      "id": "paitd-012-edfi-second-upstream",
      "title": "Ed-Fi Administrative Records Are A Second View-Only Upstream",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-012-edfi-second-upstream"
    },
    {
      "id": "paitd-013-guardian-views",
      "title": "Guardians Come From Ed-Fi Contact And StudentContactAssociation Views",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-013-guardian-views"
    },
    {
      "id": "paitd-111-privacy-retention",
      "title": "API Axis: Privacy / Retention",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-111-privacy-retention"
    }
  ]
}
storage
{
  "kind": "edfi_canonical_record_view_column",
  "source": "edfi.canonical_record.is_deleted",
  "storageRule": "Selected by alpha.guardian_base_view from edfi.canonical_record(resource_name=Contact); public alpha.guardian_view does not store a copy of this Ed-Fi field.",
  "writeRoute": "Route all sourced-field writes to the Ed-Fi 1EdTech Contact collection; Alpha exposes only canonical, non-deleted Contact records."
}

alpha.guardian_relationship_view · Guardian Relationship

objectName
guardian_relationship
apiCollection
/guardian_relationships
storage
Public view alpha.guardian_relationship_view selects canonical, non-deleted Ed-Fi StudentContactAssociation records and resolves descriptors through edfi.descriptor_code. It has no Alpha-owned table.
changeType
rename + restrict
upstream
edfi.canonical_record(resource_name=StudentContactAssociation)
primaryKey
(tenant_id, guardian_relationship_id)
purpose
The relationship between one student and one guardian/contact.
lifecycle
Created and corrected through the Ed-Fi 1EdTech StudentContactAssociation surface. Ordinary Alpha reads expose canonical, non-deleted relationships only.
auth
Readable only to self, guardian, school, or administrative scopes with relationship evidence.
sourceType
edfi_alias_view
publicSurface
alpha.guardian_relationship_view
baseView
alpha.guardian_relationship_base_view
baseSource
edfi.canonical_record(resource_name=StudentContactAssociation)
coreWriteRoute
Route all sourced-field writes to the Ed-Fi 1EdTech StudentContactAssociation collection; Alpha joins to OneRoster users only by platform3 sourcedId references.
extensionWriteRoute
None. Relationship descriptors and flags remain Ed-Fi canonical data.
anchor
table-alpha-guardian-relationship-view
fieldCount
11
sourceAnchor
https://platform3-andymontgomery-9773s-projects.vercel.app/ed_fi/1edtech/data_dictionary/#entry-studentcontactassociation-32667f508a41
filters
[
  "studentPersonId",
  "guardianId",
  "relationshipKind",
  "isLegalGuardian",
  "isPrimaryContact",
  "isEmergencyContact",
  "modifiedSince"
]
sortKeys
[
  "student_person_id",
  "contact_priority",
  "relationship_kind",
  "guardian_id"
]
extensionTables
[]
storageContract
{
  "alphaObject": "guardian_relationship",
  "publicSurface": "alpha.guardian_relationship_view",
  "upstreamModule": "ed_fi/1edtech",
  "baseSource": "edfi.canonical_record(resource_name=StudentContactAssociation)",
  "baseView": "alpha.guardian_relationship_base_view",
  "extensionTables": [],
  "coreWriteRoute": "Route all sourced-field writes to the Ed-Fi 1EdTech StudentContactAssociation collection; Alpha joins to OneRoster users only by platform3 sourcedId references.",
  "extensionWriteRoute": "None. Relationship descriptors and flags remain Ed-Fi canonical data.",
  "requiredShape": "CREATE VIEW over edfi.canonical_record; filter resource_name/collection_route, tenant_id, is_deleted=false, canonical state, descriptor_code resolution, and OneRoster sourcedId joins. No Alpha table may store sourced Ed-Fi columns."
}
example
{
  "guardian_relationship_id": "guardian_rel_001",
  "student_person_id": "person_ada_lovelace",
  "guardian_id": "guardian_contact_001",
  "relationship_kind": "guardian",
  "is_primary_contact": true,
  "is_legal_guardian": true,
  "lives_with_student": false,
  "is_emergency_contact": true,
  "contact_priority": 1,
  "contact_restrictions": [
    "do_not_release_address"
  ]
}

Fields (11)

tenant_id

title
Tenant Id
type
UUID
publicApi
Hidden in ordinary Alpha responses; selected from the verified JWT.
nullability
Required on every stored row.
required
Yes
range
Valid PostgreSQL UUID.
meaning
The tenant boundary that owns this People & Orgs row.
constraints
Must equal the verified JWT tenant_id or tenantId claim. Never accept a tenant header or body field as source of truth.
relationship
Belongs to one platform.tenant. One tenant owns many People & Orgs rows.
invalidWhen
Missing, malformed, points to another tenant, or is supplied by an unverified request body.
edgeCases
Demo token minting may accept tenantId=demo, but stored rows still use the resolved tenant id.
example
0d4ce2f4-1c42-4f3c-9f0d-03fb7f5271d3
pii
No
allowedValues
[]
provenance
{
  "changeType": "inherited",
  "sourceType": "platform_shared",
  "source": "platform.tenant",
  "sourceAnchor": null,
  "aliasMapField": null,
  "label": "Alpha inherited",
  "note": "Inherited platform tenant routing field, not a OneRoster alias.",
  "itds": [
    {
      "id": "paitd-109-tenant-routing",
      "title": "API Axis: Tenant Routing",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-109-tenant-routing"
    }
  ]
}
storage
{
  "kind": "platform_inherited_column",
  "source": "platform.tenant / verified JWT tenant claim",
  "storageRule": "Inherited platform tenant key. It scopes base rows, extension rows, and views; it is not copied from OneRoster or Ed-Fi.",
  "writeRoute": "Resolved from the verified JWT tenant claim by the platform layer."
}

guardian_relationship_id

title
Guardian Relationship Id
type
TEXT
publicApi
string
nullability
Required.
required
Yes
range
Tenant-scoped Ed-Fi local id, 1 to 255 printable characters.
meaning
Tenant-scoped Ed-Fi local id for the StudentContactAssociation record.
constraints
Must identify one same-tenant canonical association row; never mint an Alpha relationship table.
relationship
Primary identifier for this student-contact relationship.
invalidWhen
Blank, cross-tenant, draft, or deleted in ordinary reads.
edgeCases
Older StudentParentAssociation naming must be normalized by Ed-Fi before Alpha exposes it.
example
guardian_rel_001
pii
Identifier
allowedValues
[]
provenance
{
  "changeType": "rename+restrict",
  "sourceType": "edfi_alias_view",
  "source": "edfi.canonical_record.edfi_local_id",
  "sourceAnchor": "https://platform3-andymontgomery-9773s-projects.vercel.app/ed_fi/1edtech/data_dictionary/#entry-studentcontactassociation-32667f508a41",
  "aliasMapField": "guardian_relationship.guardian_relationship_id",
  "label": "Alpha Ed-Fi view",
  "note": "Tenant-scoped Ed-Fi local id for the StudentContactAssociation record.",
  "itds": [
    {
      "id": "paitd-012-edfi-second-upstream",
      "title": "Ed-Fi Administrative Records Are A Second View-Only Upstream",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-012-edfi-second-upstream"
    },
    {
      "id": "paitd-013-guardian-views",
      "title": "Guardians Come From Ed-Fi Contact And StudentContactAssociation Views",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-013-guardian-views"
    }
  ]
}
storage
{
  "kind": "edfi_canonical_record_view_column",
  "source": "edfi.canonical_record.edfi_local_id",
  "storageRule": "Selected by alpha.guardian_relationship_base_view from edfi.canonical_record(resource_name=StudentContactAssociation); public alpha.guardian_relationship_view does not store a copy of this Ed-Fi field.",
  "writeRoute": "Route all sourced-field writes to the Ed-Fi 1EdTech StudentContactAssociation collection; Alpha joins to OneRoster users only by platform3 sourcedId references."
}

student_person_id

title
Student Person Id
type
TEXT
publicApi
person id
nullability
Required.
required
Yes
range
1 to 255 printable characters.
meaning
Student person id resolved through the platform3 sourcedId boundary.
constraints
Must join to alpha.person.person_id in the same tenant; do not reconcile ids in client code.
relationship
Many guardian relationships belong to one student person.
invalidWhen
Missing, non-student for a student association, cross-tenant, or resolved by parsing names.
edgeCases
A student can have several guardian relationships with different priority and legal flags.
example
person_ada_lovelace
pii
Identifier
allowedValues
[]
provenance
{
  "changeType": "rename+restrict",
  "sourceType": "edfi_alias_view",
  "source": "join oneroster.users.sourced_id via edfi.canonical_record.student_sourced_id",
  "sourceAnchor": "https://platform3-andymontgomery-9773s-projects.vercel.app/ed_fi/1edtech/data_dictionary/#entry-studentcontactassociation-32667f508a41",
  "aliasMapField": "guardian_relationship.student_person_id",
  "label": "Alpha Ed-Fi view",
  "note": "Student person id resolved through the platform3 sourcedId boundary.",
  "itds": [
    {
      "id": "paitd-012-edfi-second-upstream",
      "title": "Ed-Fi Administrative Records Are A Second View-Only Upstream",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-012-edfi-second-upstream"
    },
    {
      "id": "paitd-013-guardian-views",
      "title": "Guardians Come From Ed-Fi Contact And StudentContactAssociation Views",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-013-guardian-views"
    }
  ]
}
storage
{
  "kind": "roster_fk_view_column",
  "source": "join oneroster.users.sourced_id via edfi.canonical_record.student_sourced_id",
  "storageRule": "Resolved in alpha.guardian_relationship_view by joining Ed-Fi canonical records to OneRoster sourcedId boundaries; no Alpha table copies the source ids.",
  "writeRoute": "Route all sourced-field writes to the Ed-Fi 1EdTech StudentContactAssociation collection; Alpha joins to OneRoster users only by platform3 sourcedId references."
}

guardian_id

title
Guardian Id
type
TEXT
publicApi
guardian id
nullability
Required.
required
Yes
range
1 to 255 printable characters.
meaning
Contact id from the StudentContactAssociation payload, resolved to alpha.guardian_view when present.
constraints
Must reference the same-tenant guardian contact after Ed-Fi resolution; do not store the relationship as a tag.
relationship
Many guardian relationships can reference one alpha.guardian_view row.
invalidWhen
Missing, references a missing guardian, crosses tenant, or is stored as free text.
edgeCases
Ordinary reads should surface resolved canonical relationships only.
example
guardian_contact_001
pii
Identifier
allowedValues
[]
provenance
{
  "changeType": "rename+restrict",
  "sourceType": "edfi_alias_view",
  "source": "edfi.canonical_record.payload_json.Contact.ContactUniqueId",
  "sourceAnchor": "https://platform3-andymontgomery-9773s-projects.vercel.app/ed_fi/1edtech/data_dictionary/#entry-studentcontactassociation-32667f508a41",
  "aliasMapField": "guardian_relationship.guardian_id",
  "label": "Alpha Ed-Fi view",
  "note": "Contact id from the StudentContactAssociation payload, resolved to alpha.guardian_view when present.",
  "itds": [
    {
      "id": "paitd-012-edfi-second-upstream",
      "title": "Ed-Fi Administrative Records Are A Second View-Only Upstream",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-012-edfi-second-upstream"
    },
    {
      "id": "paitd-013-guardian-views",
      "title": "Guardians Come From Ed-Fi Contact And StudentContactAssociation Views",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-013-guardian-views"
    }
  ]
}
storage
{
  "kind": "edfi_canonical_record_view_column",
  "source": "edfi.canonical_record.payload_json.Contact.ContactUniqueId",
  "storageRule": "Selected by alpha.guardian_relationship_base_view from edfi.canonical_record(resource_name=StudentContactAssociation); public alpha.guardian_relationship_view does not store a copy of this Ed-Fi field.",
  "writeRoute": "Route all sourced-field writes to the Ed-Fi 1EdTech StudentContactAssociation collection; Alpha joins to OneRoster users only by platform3 sourcedId references."
}

relationship_kind

title
Relationship Kind
type
TEXT governed descriptor
publicApi
string
nullability
Conditional.
required
Conditional
range
Resolved Ed-Fi Relation descriptor value; open governed code list.
meaning
Governed Ed-Fi relation descriptor resolved to a stable plain value.
constraints
Descriptor resolution happens on the surface; consumers must not ship local descriptor tables or parse relation text.
relationship
No Alpha foreign key; governed by Ed-Fi.
invalidWhen
Free text, unresolved descriptor id, guessed from name, or stored in alpha.object_tag.
edgeCases
District-specific descriptor values can appear through edfi.descriptor_code without changing Alpha schema.
example
guardian
pii
Sensitive relationship
allowedValues
[]
provenance
{
  "changeType": "rename+restrict",
  "sourceType": "edfi_alias_view",
  "source": "edfi.descriptor_code(Relation)",
  "sourceAnchor": "https://platform3-andymontgomery-9773s-projects.vercel.app/ed_fi/1edtech/data_dictionary/#entry-studentcontactassociation-32667f508a41",
  "aliasMapField": "guardian_relationship.relationship_kind",
  "label": "Alpha Ed-Fi view",
  "note": "Governed Ed-Fi relation descriptor resolved to a stable plain value.",
  "itds": [
    {
      "id": "paitd-012-edfi-second-upstream",
      "title": "Ed-Fi Administrative Records Are A Second View-Only Upstream",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-012-edfi-second-upstream"
    },
    {
      "id": "paitd-013-guardian-views",
      "title": "Guardians Come From Ed-Fi Contact And StudentContactAssociation Views",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-013-guardian-views"
    }
  ]
}
storage
{
  "kind": "edfi_descriptor_resolved_view",
  "source": "edfi.descriptor_code(Relation)",
  "storageRule": "Resolved in alpha.guardian_relationship_view from edfi.descriptor_code; no Alpha tag or descriptor table stores a copy.",
  "writeRoute": "Route all sourced-field writes to the Ed-Fi 1EdTech StudentContactAssociation collection; Alpha joins to OneRoster users only by platform3 sourcedId references."
}

is_primary_contact

title
Is Primary Contact
type
BOOLEAN
publicApi
boolean
nullability
Optional when unknown.
required
No
range
true, false, or null.
meaning
Whether Ed-Fi marks this contact as primary.
constraints
Use the source flag only; do not infer from contact_priority unless a future ITD ships that policy.
relationship
No relationship.
invalidWhen
Guessed, parsed from relationship_kind, or used to hide other legal contacts.
edgeCases
Primary does not imply legal guardian.
example
true
pii
Sensitive relationship
allowedValues
[
  {
    "value": "true",
    "meaning": "The fact is asserted by the source or by the Alpha surface.",
    "useWhen": "Use only when the field's own constraints say the fact is true.",
    "invalidWhen": "Invalid when guessed from names, labels, dates, tags, or another field."
  },
  {
    "value": "false",
    "meaning": "The fact is explicitly not asserted.",
    "useWhen": "Use only when the source or surface stores an explicit false value.",
    "invalidWhen": "Invalid when a missing value should remain unknown."
  }
]
provenance
{
  "changeType": "rename+restrict",
  "sourceType": "edfi_alias_view",
  "source": "edfi.canonical_record.payload_json.PrimaryContactStatus",
  "sourceAnchor": "https://platform3-andymontgomery-9773s-projects.vercel.app/ed_fi/1edtech/data_dictionary/#entry-studentcontactassociation-32667f508a41",
  "aliasMapField": "guardian_relationship.is_primary_contact",
  "label": "Alpha Ed-Fi view",
  "note": "Whether Ed-Fi marks this contact as primary.",
  "itds": [
    {
      "id": "paitd-013-guardian-views",
      "title": "Guardians Come From Ed-Fi Contact And StudentContactAssociation Views",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-013-guardian-views"
    }
  ]
}
storage
{
  "kind": "edfi_canonical_record_view_column",
  "source": "edfi.canonical_record.payload_json.PrimaryContactStatus",
  "storageRule": "Selected by alpha.guardian_relationship_base_view from edfi.canonical_record(resource_name=StudentContactAssociation); public alpha.guardian_relationship_view does not store a copy of this Ed-Fi field.",
  "writeRoute": "Route all sourced-field writes to the Ed-Fi 1EdTech StudentContactAssociation collection; Alpha joins to OneRoster users only by platform3 sourcedId references."
}

lives_with_student

title
Lives With Student
type
BOOLEAN
publicApi
boolean
nullability
Optional when unknown.
required
No
range
true, false, or null.
meaning
Whether the student lives with the contact.
constraints
Use only the Ed-Fi canonical flag and hide from callers without relationship scope.
relationship
No relationship.
invalidWhen
Guessed from address, defaulted from relation, or exposed without authorization.
edgeCases
Lives-with can change independently of legal guardian status.
example
false
pii
Sensitive relationship
allowedValues
[
  {
    "value": "true",
    "meaning": "The fact is asserted by the source or by the Alpha surface.",
    "useWhen": "Use only when the field's own constraints say the fact is true.",
    "invalidWhen": "Invalid when guessed from names, labels, dates, tags, or another field."
  },
  {
    "value": "false",
    "meaning": "The fact is explicitly not asserted.",
    "useWhen": "Use only when the source or surface stores an explicit false value.",
    "invalidWhen": "Invalid when a missing value should remain unknown."
  }
]
provenance
{
  "changeType": "rename+restrict",
  "sourceType": "edfi_alias_view",
  "source": "edfi.canonical_record.payload_json.LivesWith",
  "sourceAnchor": "https://platform3-andymontgomery-9773s-projects.vercel.app/ed_fi/1edtech/data_dictionary/#entry-studentcontactassociation-32667f508a41",
  "aliasMapField": "guardian_relationship.lives_with_student",
  "label": "Alpha Ed-Fi view",
  "note": "Whether the student lives with the contact.",
  "itds": [
    {
      "id": "paitd-013-guardian-views",
      "title": "Guardians Come From Ed-Fi Contact And StudentContactAssociation Views",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-013-guardian-views"
    },
    {
      "id": "paitd-111-privacy-retention",
      "title": "API Axis: Privacy / Retention",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-111-privacy-retention"
    }
  ]
}
storage
{
  "kind": "edfi_canonical_record_view_column",
  "source": "edfi.canonical_record.payload_json.LivesWith",
  "storageRule": "Selected by alpha.guardian_relationship_base_view from edfi.canonical_record(resource_name=StudentContactAssociation); public alpha.guardian_relationship_view does not store a copy of this Ed-Fi field.",
  "writeRoute": "Route all sourced-field writes to the Ed-Fi 1EdTech StudentContactAssociation collection; Alpha joins to OneRoster users only by platform3 sourcedId references."
}

is_emergency_contact

title
Is Emergency Contact
type
BOOLEAN
publicApi
boolean
nullability
Optional when unknown.
required
No
range
true, false, or null.
meaning
Whether the contact is an emergency contact.
constraints
Use only the Ed-Fi canonical flag; do not infer from priority or relationship kind.
relationship
No relationship; used by emergency-contact workflows.
invalidWhen
Guessed, omitted from emergency-contact queries, or exposed to unrelated callers.
edgeCases
Emergency contact does not imply legal guardian.
example
true
pii
Sensitive relationship
allowedValues
[
  {
    "value": "true",
    "meaning": "The fact is asserted by the source or by the Alpha surface.",
    "useWhen": "Use only when the field's own constraints say the fact is true.",
    "invalidWhen": "Invalid when guessed from names, labels, dates, tags, or another field."
  },
  {
    "value": "false",
    "meaning": "The fact is explicitly not asserted.",
    "useWhen": "Use only when the source or surface stores an explicit false value.",
    "invalidWhen": "Invalid when a missing value should remain unknown."
  }
]
provenance
{
  "changeType": "rename+restrict",
  "sourceType": "edfi_alias_view",
  "source": "edfi.canonical_record.payload_json.EmergencyContactStatus",
  "sourceAnchor": "https://platform3-andymontgomery-9773s-projects.vercel.app/ed_fi/1edtech/data_dictionary/#entry-studentcontactassociation-32667f508a41",
  "aliasMapField": "guardian_relationship.is_emergency_contact",
  "label": "Alpha Ed-Fi view",
  "note": "Whether the contact is an emergency contact.",
  "itds": [
    {
      "id": "paitd-013-guardian-views",
      "title": "Guardians Come From Ed-Fi Contact And StudentContactAssociation Views",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-013-guardian-views"
    },
    {
      "id": "paitd-111-privacy-retention",
      "title": "API Axis: Privacy / Retention",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-111-privacy-retention"
    }
  ]
}
storage
{
  "kind": "edfi_canonical_record_view_column",
  "source": "edfi.canonical_record.payload_json.EmergencyContactStatus",
  "storageRule": "Selected by alpha.guardian_relationship_base_view from edfi.canonical_record(resource_name=StudentContactAssociation); public alpha.guardian_relationship_view does not store a copy of this Ed-Fi field.",
  "writeRoute": "Route all sourced-field writes to the Ed-Fi 1EdTech StudentContactAssociation collection; Alpha joins to OneRoster users only by platform3 sourcedId references."
}

contact_priority

title
Contact Priority
type
INTEGER
publicApi
integer
nullability
Optional.
required
No
range
Positive integer when supplied.
meaning
Preferred contact order.
constraints
Use for ordering only; do not infer legal guardian or primary contact from it.
relationship
No relationship.
invalidWhen
Negative, non-integer, or inferred from list position.
edgeCases
Use stable secondary sort by guardian_id when priorities tie.
example
1
pii
Sensitive relationship
allowedValues
[]
provenance
{
  "changeType": "rename+restrict",
  "sourceType": "edfi_alias_view",
  "source": "edfi.canonical_record.payload_json.ContactPriority",
  "sourceAnchor": "https://platform3-andymontgomery-9773s-projects.vercel.app/ed_fi/1edtech/data_dictionary/#entry-studentcontactassociation-32667f508a41",
  "aliasMapField": "guardian_relationship.contact_priority",
  "label": "Alpha Ed-Fi view",
  "note": "Preferred contact order.",
  "itds": [
    {
      "id": "paitd-013-guardian-views",
      "title": "Guardians Come From Ed-Fi Contact And StudentContactAssociation Views",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-013-guardian-views"
    }
  ]
}
storage
{
  "kind": "edfi_canonical_record_view_column",
  "source": "edfi.canonical_record.payload_json.ContactPriority",
  "storageRule": "Selected by alpha.guardian_relationship_base_view from edfi.canonical_record(resource_name=StudentContactAssociation); public alpha.guardian_relationship_view does not store a copy of this Ed-Fi field.",
  "writeRoute": "Route all sourced-field writes to the Ed-Fi 1EdTech StudentContactAssociation collection; Alpha joins to OneRoster users only by platform3 sourcedId references."
}

contact_restrictions

title
Contact Restrictions
type
TEXT[]
publicApi
array of strings, redacted when unauthorized
nullability
Optional; empty array means no source restriction in this projection.
required
No
range
Restriction text or descriptor values after privacy filtering.
meaning
Contact restrictions; restricted/redacted by privacy rules.
constraints
Treat as sensitive relationship data; ordinary reads must redact or omit without scope.
relationship
No relationship.
invalidWhen
Logged publicly, exposed to unrelated callers, stored as a tag, or ignored by contact workflows.
edgeCases
A restriction may prevent showing phone/email even when relationship exists.
pii
Sensitive
example
[
  "do_not_release_address"
]
allowedValues
[]
provenance
{
  "changeType": "rename+restrict",
  "sourceType": "edfi_alias_view",
  "source": "edfi.canonical_record.payload_json.ContactRestrictions",
  "sourceAnchor": "https://platform3-andymontgomery-9773s-projects.vercel.app/ed_fi/1edtech/data_dictionary/#entry-studentcontactassociation-32667f508a41",
  "aliasMapField": "guardian_relationship.contact_restrictions",
  "label": "Alpha Ed-Fi view",
  "note": "Contact restrictions; restricted/redacted by privacy rules.",
  "itds": [
    {
      "id": "paitd-013-guardian-views",
      "title": "Guardians Come From Ed-Fi Contact And StudentContactAssociation Views",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-013-guardian-views"
    },
    {
      "id": "paitd-111-privacy-retention",
      "title": "API Axis: Privacy / Retention",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-111-privacy-retention"
    }
  ]
}
storage
{
  "kind": "edfi_canonical_record_view_column",
  "source": "edfi.canonical_record.payload_json.ContactRestrictions",
  "storageRule": "Selected by alpha.guardian_relationship_base_view from edfi.canonical_record(resource_name=StudentContactAssociation); public alpha.guardian_relationship_view does not store a copy of this Ed-Fi field.",
  "writeRoute": "Route all sourced-field writes to the Ed-Fi 1EdTech StudentContactAssociation collection; Alpha joins to OneRoster users only by platform3 sourcedId references."
}

alpha.staff_assignment_view · Staff Assignment

objectName
staff_assignment
apiCollection
/staff_assignments
storage
Public view alpha.staff_assignment_view selects canonical, non-deleted Ed-Fi StaffEducationOrganizationAssignmentAssociation records and resolves StaffClassification through edfi.descriptor_code. It has no Alpha-owned table.
changeType
rename + restrict
upstream
edfi.canonical_record(resource_name=StaffEducationOrganizationAssignmentAssociation)
primaryKey
(tenant_id, staff_assignment_id)
purpose
A staff member's assignment to a school, district, department, or other education organization beyond the role rows OneRoster already carries.
lifecycle
Created and corrected through Ed-Fi. Active assignment questions use asOfDate and the begin/end null rule.
auth
Readable to school/district staff scopes. HR-only facts outside assignment context stay on Ed-Fi and are cut from Alpha.
sourceType
edfi_alias_view
publicSurface
alpha.staff_assignment_view
baseView
alpha.staff_assignment_base_view
baseSource
edfi.canonical_record(resource_name=StaffEducationOrganizationAssignmentAssociation)
coreWriteRoute
Route all sourced-field writes to the Ed-Fi 1EdTech StaffEducationOrganizationAssignmentAssociation collection; OneRoster users and orgs remain the roster identity boundary.
extensionWriteRoute
None. Staff assignment facts from Ed-Fi stay in edfi.canonical_record and descriptor_code-backed views.
anchor
table-alpha-staff-assignment-view
fieldCount
11
sourceAnchor
https://platform3-andymontgomery-9773s-projects.vercel.app/ed_fi/1edtech/data_dictionary/#entry-staffeducationorganizationassignmentassociation-e92aa18ecc7f
filters
[
  "staffPersonId",
  "placeId",
  "staffClassification",
  "asOfDate",
  "isTimeLocatable",
  "modifiedSince"
]
sortKeys
[
  "place_id",
  "staff_person_id",
  "staff_classification",
  "begin_date",
  "assignment_order"
]
extensionTables
[]
storageContract
{
  "alphaObject": "staff_assignment",
  "publicSurface": "alpha.staff_assignment_view",
  "upstreamModule": "ed_fi/1edtech",
  "baseSource": "edfi.canonical_record(resource_name=StaffEducationOrganizationAssignmentAssociation)",
  "baseView": "alpha.staff_assignment_base_view",
  "extensionTables": [],
  "coreWriteRoute": "Route all sourced-field writes to the Ed-Fi 1EdTech StaffEducationOrganizationAssignmentAssociation collection; OneRoster users and orgs remain the roster identity boundary.",
  "extensionWriteRoute": "None. Staff assignment facts from Ed-Fi stay in edfi.canonical_record and descriptor_code-backed views.",
  "requiredShape": "CREATE VIEW over edfi.canonical_record; filter resource_name/collection_route, tenant_id, is_deleted=false, canonical state, descriptor_code resolution, and OneRoster sourcedId joins. No Alpha table may store sourced Ed-Fi columns."
}
example
{
  "staff_assignment_id": "staff_assignment_001",
  "staff_person_id": "person_grace_hopper",
  "place_id": "place_timeback_school",
  "staff_classification": "Teacher",
  "position_title": "Middle School Math Guide",
  "begin_date": "2026-08-15",
  "end_date": "2027-06-01",
  "is_time_locatable": true,
  "assignment_order": 1,
  "full_time_equivalency": 1
}

Fields (11)

tenant_id

title
Tenant Id
type
UUID
publicApi
Hidden in ordinary Alpha responses; selected from the verified JWT.
nullability
Required on every stored row.
required
Yes
range
Valid PostgreSQL UUID.
meaning
The tenant boundary that owns this People & Orgs row.
constraints
Must equal the verified JWT tenant_id or tenantId claim. Never accept a tenant header or body field as source of truth.
relationship
Belongs to one platform.tenant. One tenant owns many People & Orgs rows.
invalidWhen
Missing, malformed, points to another tenant, or is supplied by an unverified request body.
edgeCases
Demo token minting may accept tenantId=demo, but stored rows still use the resolved tenant id.
example
0d4ce2f4-1c42-4f3c-9f0d-03fb7f5271d3
pii
No
allowedValues
[]
provenance
{
  "changeType": "inherited",
  "sourceType": "platform_shared",
  "source": "platform.tenant",
  "sourceAnchor": null,
  "aliasMapField": null,
  "label": "Alpha inherited",
  "note": "Inherited platform tenant routing field, not a OneRoster alias.",
  "itds": [
    {
      "id": "paitd-109-tenant-routing",
      "title": "API Axis: Tenant Routing",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-109-tenant-routing"
    }
  ]
}
storage
{
  "kind": "platform_inherited_column",
  "source": "platform.tenant / verified JWT tenant claim",
  "storageRule": "Inherited platform tenant key. It scopes base rows, extension rows, and views; it is not copied from OneRoster or Ed-Fi.",
  "writeRoute": "Resolved from the verified JWT tenant claim by the platform layer."
}

staff_assignment_id

title
Staff Assignment Id
type
TEXT
publicApi
string
nullability
Required.
required
Yes
range
Tenant-scoped Ed-Fi local id, 1 to 255 printable characters.
meaning
Tenant-scoped Ed-Fi local id for the staff assignment.
constraints
Must identify one same-tenant canonical assignment row; never mint a copied Alpha table.
relationship
Primary identifier for this assignment row.
invalidWhen
Blank, cross-tenant, draft, or deleted in ordinary reads.
edgeCases
A staff member can have several assignments.
example
staff_assignment_001
pii
Identifier
allowedValues
[]
provenance
{
  "changeType": "rename+restrict",
  "sourceType": "edfi_alias_view",
  "source": "edfi.canonical_record.edfi_local_id",
  "sourceAnchor": "https://platform3-andymontgomery-9773s-projects.vercel.app/ed_fi/1edtech/data_dictionary/#entry-staffeducationorganizationassignmentassociation-e92aa18ecc7f",
  "aliasMapField": "staff_assignment.staff_assignment_id",
  "label": "Alpha Ed-Fi view",
  "note": "Tenant-scoped Ed-Fi local id for the staff assignment.",
  "itds": [
    {
      "id": "paitd-012-edfi-second-upstream",
      "title": "Ed-Fi Administrative Records Are A Second View-Only Upstream",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-012-edfi-second-upstream"
    },
    {
      "id": "paitd-014-staff-assignment-views",
      "title": "Staff Assignments Come From Ed-Fi Assignment Views Beyond OneRoster Roles",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-014-staff-assignment-views"
    }
  ]
}
storage
{
  "kind": "edfi_canonical_record_view_column",
  "source": "edfi.canonical_record.edfi_local_id",
  "storageRule": "Selected by alpha.staff_assignment_base_view from edfi.canonical_record(resource_name=StaffEducationOrganizationAssignmentAssociation); public alpha.staff_assignment_view does not store a copy of this Ed-Fi field.",
  "writeRoute": "Route all sourced-field writes to the Ed-Fi 1EdTech StaffEducationOrganizationAssignmentAssociation collection; OneRoster users and orgs remain the roster identity boundary."
}

staff_person_id

title
Staff Person Id
type
TEXT
publicApi
person id
nullability
Required.
required
Yes
range
1 to 255 printable characters.
meaning
Staff person id resolved through the platform3 sourcedId boundary.
constraints
Must join to alpha.person.person_id in the same tenant; do not reconcile staff ids in client code.
relationship
Many staff assignments belong to one person.
invalidWhen
Missing, references a missing person, crosses tenant, or is resolved by parsing names/emails.
edgeCases
The person may also have OneRoster guide/admin memberships; this row carries Ed-Fi assignment detail.
example
person_grace_hopper
pii
Identifier
allowedValues
[]
provenance
{
  "changeType": "rename+restrict",
  "sourceType": "edfi_alias_view",
  "source": "join oneroster.users.sourced_id via edfi.canonical_record.staff_sourced_id",
  "sourceAnchor": "https://platform3-andymontgomery-9773s-projects.vercel.app/ed_fi/1edtech/data_dictionary/#entry-staffeducationorganizationassignmentassociation-e92aa18ecc7f",
  "aliasMapField": "staff_assignment.staff_person_id",
  "label": "Alpha Ed-Fi view",
  "note": "Staff person id resolved through the platform3 sourcedId boundary.",
  "itds": [
    {
      "id": "paitd-012-edfi-second-upstream",
      "title": "Ed-Fi Administrative Records Are A Second View-Only Upstream",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-012-edfi-second-upstream"
    },
    {
      "id": "paitd-014-staff-assignment-views",
      "title": "Staff Assignments Come From Ed-Fi Assignment Views Beyond OneRoster Roles",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-014-staff-assignment-views"
    }
  ]
}
storage
{
  "kind": "roster_fk_view_column",
  "source": "join oneroster.users.sourced_id via edfi.canonical_record.staff_sourced_id",
  "storageRule": "Resolved in alpha.staff_assignment_view by joining Ed-Fi canonical records to OneRoster sourcedId boundaries; no Alpha table copies the source ids.",
  "writeRoute": "Route all sourced-field writes to the Ed-Fi 1EdTech StaffEducationOrganizationAssignmentAssociation collection; OneRoster users and orgs remain the roster identity boundary."
}

place_id

title
Place Id
type
TEXT
publicApi
place id
nullability
Required.
required
Yes
range
1 to 255 printable characters.
meaning
School or education organization place id resolved through OneRoster.
constraints
Must join to alpha.place.place_id in the same tenant. Relationships are columns, never tags.
relationship
Many staff assignments can belong to one place.
invalidWhen
Missing, references a missing place, crosses tenant, or is stored as a tag.
edgeCases
Ed-Fi education-organization ids resolve to platform3 OneRoster place ids.
example
place_timeback_school
pii
Identifier
allowedValues
[]
provenance
{
  "changeType": "rename+restrict",
  "sourceType": "edfi_alias_view",
  "source": "join oneroster.orgs.sourced_id via edfi.canonical_record.school_sourced_id",
  "sourceAnchor": "https://platform3-andymontgomery-9773s-projects.vercel.app/ed_fi/1edtech/data_dictionary/#entry-staffeducationorganizationassignmentassociation-e92aa18ecc7f",
  "aliasMapField": "staff_assignment.place_id",
  "label": "Alpha Ed-Fi view",
  "note": "School or education organization place id resolved through OneRoster.",
  "itds": [
    {
      "id": "paitd-012-edfi-second-upstream",
      "title": "Ed-Fi Administrative Records Are A Second View-Only Upstream",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-012-edfi-second-upstream"
    },
    {
      "id": "paitd-014-staff-assignment-views",
      "title": "Staff Assignments Come From Ed-Fi Assignment Views Beyond OneRoster Roles",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-014-staff-assignment-views"
    }
  ]
}
storage
{
  "kind": "roster_fk_view_column",
  "source": "join oneroster.orgs.sourced_id via edfi.canonical_record.school_sourced_id",
  "storageRule": "Resolved in alpha.staff_assignment_view by joining Ed-Fi canonical records to OneRoster sourcedId boundaries; no Alpha table copies the source ids.",
  "writeRoute": "Route all sourced-field writes to the Ed-Fi 1EdTech StaffEducationOrganizationAssignmentAssociation collection; OneRoster users and orgs remain the roster identity boundary."
}

staff_classification

title
Staff Classification
type
TEXT governed descriptor
publicApi
string
nullability
Conditional.
required
Conditional
range
Resolved Ed-Fi StaffClassification descriptor value; open governed code list.
meaning
Governed staff-classification descriptor.
constraints
Descriptor resolution happens on the surface; consumers must not ship descriptor tables or parse titles.
relationship
No Alpha foreign key; governed by Ed-Fi descriptor_code.
invalidWhen
Free text, unresolved descriptor id, parsed from title, or stored in alpha.object_tag.
edgeCases
District-specific descriptors can appear through edfi.descriptor_code without schema changes.
example
Teacher
pii
Yes
allowedValues
[]
provenance
{
  "changeType": "rename+restrict",
  "sourceType": "edfi_alias_view",
  "source": "edfi.descriptor_code(StaffClassification)",
  "sourceAnchor": "https://platform3-andymontgomery-9773s-projects.vercel.app/ed_fi/1edtech/data_dictionary/#entry-staffeducationorganizationassignmentassociation-e92aa18ecc7f",
  "aliasMapField": "staff_assignment.staff_classification",
  "label": "Alpha Ed-Fi view",
  "note": "Governed staff-classification descriptor.",
  "itds": [
    {
      "id": "paitd-012-edfi-second-upstream",
      "title": "Ed-Fi Administrative Records Are A Second View-Only Upstream",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-012-edfi-second-upstream"
    },
    {
      "id": "paitd-014-staff-assignment-views",
      "title": "Staff Assignments Come From Ed-Fi Assignment Views Beyond OneRoster Roles",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-014-staff-assignment-views"
    }
  ]
}
storage
{
  "kind": "edfi_descriptor_resolved_view",
  "source": "edfi.descriptor_code(StaffClassification)",
  "storageRule": "Resolved in alpha.staff_assignment_view from edfi.descriptor_code; no Alpha tag or descriptor table stores a copy.",
  "writeRoute": "Route all sourced-field writes to the Ed-Fi 1EdTech StaffEducationOrganizationAssignmentAssociation collection; OneRoster users and orgs remain the roster identity boundary."
}

position_title

title
Position Title
type
TEXT
publicApi
string
nullability
Optional.
required
No
range
0 to 200 visible characters.
meaning
Human staff position title.
constraints
Display only. Do not parse classification, role_kind, or authorization from this title.
relationship
No relationship.
invalidWhen
Used as a descriptor, parsed to compute staff_classification, or exposed beyond authorized staff contexts.
edgeCases
Two assignments can share the same title but differ by classification or dates.
example
Middle School Math Guide
pii
Yes
allowedValues
[]
provenance
{
  "changeType": "rename+restrict",
  "sourceType": "edfi_alias_view",
  "source": "edfi.canonical_record.payload_json.PositionTitle",
  "sourceAnchor": "https://platform3-andymontgomery-9773s-projects.vercel.app/ed_fi/1edtech/data_dictionary/#entry-staffeducationorganizationassignmentassociation-e92aa18ecc7f",
  "aliasMapField": "staff_assignment.position_title",
  "label": "Alpha Ed-Fi view",
  "note": "Human staff position title.",
  "itds": [
    {
      "id": "paitd-014-staff-assignment-views",
      "title": "Staff Assignments Come From Ed-Fi Assignment Views Beyond OneRoster Roles",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-014-staff-assignment-views"
    },
    {
      "id": "paitd-111-privacy-retention",
      "title": "API Axis: Privacy / Retention",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-111-privacy-retention"
    }
  ]
}
storage
{
  "kind": "edfi_canonical_record_view_column",
  "source": "edfi.canonical_record.payload_json.PositionTitle",
  "storageRule": "Selected by alpha.staff_assignment_base_view from edfi.canonical_record(resource_name=StaffEducationOrganizationAssignmentAssociation); public alpha.staff_assignment_view does not store a copy of this Ed-Fi field.",
  "writeRoute": "Route all sourced-field writes to the Ed-Fi 1EdTech StaffEducationOrganizationAssignmentAssociation collection; OneRoster users and orgs remain the roster identity boundary."
}

begin_date

title
Begin Date
type
DATE
publicApi
date
nullability
Nullable storage, but begin_date null means not time-locatable.
required
No
range
ISO 8601 date YYYY-MM-DD.
meaning
Inclusive date the assignment becomes locatable.
constraints
Active-as-of requires begin_date <= asOfDate and is_time_locatable=true.
relationship
No foreign key; used by point-in-time computations.
invalidWhen
Malformed, after end_date, or ignored by a current-only shortcut.
edgeCases
begin_date null plus end_date present is still excluded from point-in-time computations.
example
2026-08-15
pii
No
allowedValues
[]
provenance
{
  "changeType": "rename+restrict",
  "sourceType": "edfi_alias_view",
  "source": "edfi.canonical_record.payload_json.BeginDate",
  "sourceAnchor": "https://platform3-andymontgomery-9773s-projects.vercel.app/ed_fi/1edtech/data_dictionary/#entry-staffeducationorganizationassignmentassociation-e92aa18ecc7f",
  "aliasMapField": "staff_assignment.begin_date",
  "label": "Alpha Ed-Fi view",
  "note": "Inclusive date the assignment becomes locatable.",
  "itds": [
    {
      "id": "paitd-004-point-in-time-memberships",
      "title": "Memberships Are Effective-Dated And Answered By AsOfDate",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-004-point-in-time-memberships"
    },
    {
      "id": "paitd-014-staff-assignment-views",
      "title": "Staff Assignments Come From Ed-Fi Assignment Views Beyond OneRoster Roles",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-014-staff-assignment-views"
    }
  ]
}
storage
{
  "kind": "edfi_canonical_record_view_column",
  "source": "edfi.canonical_record.payload_json.BeginDate",
  "storageRule": "Selected by alpha.staff_assignment_base_view from edfi.canonical_record(resource_name=StaffEducationOrganizationAssignmentAssociation); public alpha.staff_assignment_view does not store a copy of this Ed-Fi field.",
  "writeRoute": "Route all sourced-field writes to the Ed-Fi 1EdTech StaffEducationOrganizationAssignmentAssociation collection; OneRoster users and orgs remain the roster identity boundary."
}

end_date

title
End Date
type
DATE
publicApi
date
nullability
Optional. Null means active after begin_date.
required
No
range
ISO 8601 date YYYY-MM-DD.
meaning
Date the assignment ends; null means active after begin_date.
constraints
Active-as-of includes the row when end_date is null or asOfDate < end_date.
relationship
No foreign key; used by point-in-time computations.
invalidWhen
Malformed, on/before begin_date, or treated as inclusive.
edgeCases
Both begin_date and end_date null means always excluded.
example
2027-06-01
pii
No
allowedValues
[]
provenance
{
  "changeType": "rename+restrict",
  "sourceType": "edfi_alias_view",
  "source": "edfi.canonical_record.payload_json.EndDate",
  "sourceAnchor": "https://platform3-andymontgomery-9773s-projects.vercel.app/ed_fi/1edtech/data_dictionary/#entry-staffeducationorganizationassignmentassociation-e92aa18ecc7f",
  "aliasMapField": "staff_assignment.end_date",
  "label": "Alpha Ed-Fi view",
  "note": "Date the assignment ends; null means active after begin_date.",
  "itds": [
    {
      "id": "paitd-004-point-in-time-memberships",
      "title": "Memberships Are Effective-Dated And Answered By AsOfDate",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-004-point-in-time-memberships"
    },
    {
      "id": "paitd-014-staff-assignment-views",
      "title": "Staff Assignments Come From Ed-Fi Assignment Views Beyond OneRoster Roles",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-014-staff-assignment-views"
    }
  ]
}
storage
{
  "kind": "edfi_canonical_record_view_column",
  "source": "edfi.canonical_record.payload_json.EndDate",
  "storageRule": "Selected by alpha.staff_assignment_base_view from edfi.canonical_record(resource_name=StaffEducationOrganizationAssignmentAssociation); public alpha.staff_assignment_view does not store a copy of this Ed-Fi field.",
  "writeRoute": "Route all sourced-field writes to the Ed-Fi 1EdTech StaffEducationOrganizationAssignmentAssociation collection; OneRoster users and orgs remain the roster identity boundary."
}

is_time_locatable

title
Is Time Locatable
type
BOOLEAN
publicApi
boolean
nullability
Required derived field.
required
Yes
range
true or false.
meaning
True only when begin_date is present; consumers do not infer from nulls.
constraints
Derived by the view from BeginDate; consumers filter on this instead of guessing from nulls.
relationship
No relationship; query input to active-as-of views.
invalidWhen
True when begin_date is null, false when begin_date is present, or omitted.
edgeCases
end_date null does not make the row unlocatable.
example
true
pii
No
allowedValues
[
  {
    "value": "true",
    "meaning": "The fact is asserted by the source or by the Alpha surface.",
    "useWhen": "Use only when the field's own constraints say the fact is true.",
    "invalidWhen": "Invalid when guessed from names, labels, dates, tags, or another field."
  },
  {
    "value": "false",
    "meaning": "The fact is explicitly not asserted.",
    "useWhen": "Use only when the source or surface stores an explicit false value.",
    "invalidWhen": "Invalid when a missing value should remain unknown."
  }
]
provenance
{
  "changeType": "restrict",
  "sourceType": "view_expression",
  "source": "view expression: payload_json.BeginDate is not null",
  "sourceAnchor": null,
  "aliasMapField": "staff_assignment.is_time_locatable",
  "label": "Alpha derived view field",
  "note": "True only when begin_date is present; consumers do not infer from nulls. No Alpha table stores it.",
  "itds": [
    {
      "id": "paitd-004-point-in-time-memberships",
      "title": "Memberships Are Effective-Dated And Answered By AsOfDate",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-004-point-in-time-memberships"
    },
    {
      "id": "paitd-014-staff-assignment-views",
      "title": "Staff Assignments Come From Ed-Fi Assignment Views Beyond OneRoster Roles",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-014-staff-assignment-views"
    }
  ]
}
storage
{
  "kind": "view_derived",
  "source": "view expression: payload_json.BeginDate is not null",
  "storageRule": "Computed in alpha.staff_assignment_view as a view expression; no Alpha table column stores it.",
  "writeRoute": "Not writable; recomputed by the view from sourced fields."
}

assignment_order

title
Assignment Order
type
INTEGER
publicApi
integer
nullability
Optional.
required
No
range
Positive integer when supplied.
meaning
Primary/secondary assignment order when supplied.
constraints
Use only for ordering within a staff member's assignments.
relationship
No relationship.
invalidWhen
Negative, non-integer, or inferred from row order.
edgeCases
Null means the source did not provide assignment order.
example
1
pii
No
allowedValues
[]
provenance
{
  "changeType": "rename+restrict",
  "sourceType": "edfi_alias_view",
  "source": "edfi.canonical_record.payload_json.OrderOfAssignment",
  "sourceAnchor": "https://platform3-andymontgomery-9773s-projects.vercel.app/ed_fi/1edtech/data_dictionary/#entry-staffeducationorganizationassignmentassociation-e92aa18ecc7f",
  "aliasMapField": "staff_assignment.assignment_order",
  "label": "Alpha Ed-Fi view",
  "note": "Primary/secondary assignment order when supplied.",
  "itds": [
    {
      "id": "paitd-014-staff-assignment-views",
      "title": "Staff Assignments Come From Ed-Fi Assignment Views Beyond OneRoster Roles",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-014-staff-assignment-views"
    }
  ]
}
storage
{
  "kind": "edfi_canonical_record_view_column",
  "source": "edfi.canonical_record.payload_json.OrderOfAssignment",
  "storageRule": "Selected by alpha.staff_assignment_base_view from edfi.canonical_record(resource_name=StaffEducationOrganizationAssignmentAssociation); public alpha.staff_assignment_view does not store a copy of this Ed-Fi field.",
  "writeRoute": "Route all sourced-field writes to the Ed-Fi 1EdTech StaffEducationOrganizationAssignmentAssociation collection; OneRoster users and orgs remain the roster identity boundary."
}

full_time_equivalency

title
Full Time Equivalency
type
NUMERIC
publicApi
number
nullability
Optional.
required
No
range
0.0 to 1.0 unless source policy documents another bound.
meaning
Ratio of expected work time for the assignment.
constraints
Use only the source-supplied value; do not compute from minutes, schedule, or title in a consumer.
relationship
No relationship.
invalidWhen
Negative, over source maximum, parsed from title, or used as attendance/service minutes.
edgeCases
Multiple part-time assignments can sum to a reporting question outside this field.
example
1
pii
No
allowedValues
[]
provenance
{
  "changeType": "rename+restrict",
  "sourceType": "edfi_alias_view",
  "source": "edfi.canonical_record.payload_json.FullTimeEquivalency",
  "sourceAnchor": "https://platform3-andymontgomery-9773s-projects.vercel.app/ed_fi/1edtech/data_dictionary/#entry-staffeducationorganizationassignmentassociation-e92aa18ecc7f",
  "aliasMapField": "staff_assignment.full_time_equivalency",
  "label": "Alpha Ed-Fi view",
  "note": "Ratio of expected work time for the assignment.",
  "itds": [
    {
      "id": "paitd-014-staff-assignment-views",
      "title": "Staff Assignments Come From Ed-Fi Assignment Views Beyond OneRoster Roles",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-014-staff-assignment-views"
    }
  ]
}
storage
{
  "kind": "edfi_canonical_record_view_column",
  "source": "edfi.canonical_record.payload_json.FullTimeEquivalency",
  "storageRule": "Selected by alpha.staff_assignment_base_view from edfi.canonical_record(resource_name=StaffEducationOrganizationAssignmentAssociation); public alpha.staff_assignment_view does not store a copy of this Ed-Fi field.",
  "writeRoute": "Route all sourced-field writes to the Ed-Fi 1EdTech StaffEducationOrganizationAssignmentAssociation collection; OneRoster users and orgs remain the roster identity boundary."
}

alpha.program_participation_view · Program Participation

objectName
program_participation
apiCollection
/program_participations
storage
Public view alpha.program_participation_view selects canonical, non-deleted Ed-Fi program association records and resolves ProgramType and ProgramParticipationStatus through edfi.descriptor_code. It has no Alpha-owned table.
changeType
rename + restrict
upstream
edfi.canonical_record(resource_name in GeneralStudentProgramAssociation, StudentProgramAssociation, and specializations)
primaryKey
(tenant_id, program_participation_id)
purpose
A student's participation in an administrative program such as Special Education, Title I, English Learner, Section 504, food service, or another Ed-Fi program association.
lifecycle
Created and corrected through Ed-Fi. Active program questions use asOfDate and the begin/end null rule.
auth
Readable only to student/guardian/school/admin scopes allowed to see program participation. Outcomes and eligibility logic live outside People & Orgs.
sourceType
edfi_alias_view
publicSurface
alpha.program_participation_view
baseView
alpha.program_participation_base_view
baseSource
edfi.canonical_record(resource_name in GeneralStudentProgramAssociation, StudentProgramAssociation, and specializations)
coreWriteRoute
Route all sourced-field writes to the Ed-Fi 1EdTech Program and StudentProgramAssociation-family collections; Alpha joins student and place ids through OneRoster sourcedIds.
extensionWriteRoute
None. Program participation facts from Ed-Fi stay in edfi.canonical_record and descriptor_code-backed views.
anchor
table-alpha-program-participation-view
fieldCount
12
sourceAnchor
https://platform3-andymontgomery-9773s-projects.vercel.app/ed_fi/1edtech/data_dictionary/#entry-generalstudentprogramassociation-b50a12920f64
filters
[
  "studentPersonId",
  "placeId",
  "programId",
  "programType",
  "participationStatus",
  "sourceProgramResource",
  "asOfDate",
  "isTimeLocatable",
  "modifiedSince"
]
sortKeys
[
  "student_person_id",
  "program_type",
  "program_name",
  "begin_date"
]
extensionTables
[]
storageContract
{
  "alphaObject": "program_participation",
  "publicSurface": "alpha.program_participation_view",
  "upstreamModule": "ed_fi/1edtech",
  "baseSource": "edfi.canonical_record(resource_name in GeneralStudentProgramAssociation, StudentProgramAssociation, and specializations)",
  "baseView": "alpha.program_participation_base_view",
  "extensionTables": [],
  "coreWriteRoute": "Route all sourced-field writes to the Ed-Fi 1EdTech Program and StudentProgramAssociation-family collections; Alpha joins student and place ids through OneRoster sourcedIds.",
  "extensionWriteRoute": "None. Program participation facts from Ed-Fi stay in edfi.canonical_record and descriptor_code-backed views.",
  "requiredShape": "CREATE VIEW over edfi.canonical_record; filter resource_name/collection_route, tenant_id, is_deleted=false, canonical state, descriptor_code resolution, and OneRoster sourcedId joins. No Alpha table may store sourced Ed-Fi columns."
}
example
{
  "program_participation_id": "program_participation_001",
  "student_person_id": "person_ada_lovelace",
  "place_id": "place_timeback_school",
  "program_id": "program-special-education",
  "program_name": "Special Education",
  "program_type": "Special Education",
  "participation_status": "Participating",
  "begin_date": "2026-08-15",
  "end_date": "2027-06-01",
  "is_time_locatable": true,
  "source_program_resource": "GeneralStudentProgramAssociation"
}

Fields (12)

tenant_id

title
Tenant Id
type
UUID
publicApi
Hidden in ordinary Alpha responses; selected from the verified JWT.
nullability
Required on every stored row.
required
Yes
range
Valid PostgreSQL UUID.
meaning
The tenant boundary that owns this People & Orgs row.
constraints
Must equal the verified JWT tenant_id or tenantId claim. Never accept a tenant header or body field as source of truth.
relationship
Belongs to one platform.tenant. One tenant owns many People & Orgs rows.
invalidWhen
Missing, malformed, points to another tenant, or is supplied by an unverified request body.
edgeCases
Demo token minting may accept tenantId=demo, but stored rows still use the resolved tenant id.
example
0d4ce2f4-1c42-4f3c-9f0d-03fb7f5271d3
pii
No
allowedValues
[]
provenance
{
  "changeType": "inherited",
  "sourceType": "platform_shared",
  "source": "platform.tenant",
  "sourceAnchor": null,
  "aliasMapField": null,
  "label": "Alpha inherited",
  "note": "Inherited platform tenant routing field, not a OneRoster alias.",
  "itds": [
    {
      "id": "paitd-109-tenant-routing",
      "title": "API Axis: Tenant Routing",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-109-tenant-routing"
    }
  ]
}
storage
{
  "kind": "platform_inherited_column",
  "source": "platform.tenant / verified JWT tenant claim",
  "storageRule": "Inherited platform tenant key. It scopes base rows, extension rows, and views; it is not copied from OneRoster or Ed-Fi.",
  "writeRoute": "Resolved from the verified JWT tenant claim by the platform layer."
}

program_participation_id

title
Program Participation Id
type
TEXT
publicApi
string
nullability
Required.
required
Yes
range
Tenant-scoped Ed-Fi local id, 1 to 255 printable characters.
meaning
Tenant-scoped Ed-Fi local id for the program association.
constraints
Must identify one same-tenant canonical program association; never mint a copied Alpha table.
relationship
Primary identifier for this program participation row.
invalidWhen
Blank, cross-tenant, draft, or deleted in ordinary reads.
edgeCases
Specialized Ed-Fi associations share this shape when they pass the People & Orgs boundary test.
example
program_participation_001
pii
Identifier
allowedValues
[]
provenance
{
  "changeType": "rename+restrict",
  "sourceType": "edfi_alias_view",
  "source": "edfi.canonical_record.edfi_local_id",
  "sourceAnchor": "https://platform3-andymontgomery-9773s-projects.vercel.app/ed_fi/1edtech/data_dictionary/#entry-generalstudentprogramassociation-b50a12920f64",
  "aliasMapField": "program_participation.program_participation_id",
  "label": "Alpha Ed-Fi view",
  "note": "Tenant-scoped Ed-Fi local id for the program association.",
  "itds": [
    {
      "id": "paitd-012-edfi-second-upstream",
      "title": "Ed-Fi Administrative Records Are A Second View-Only Upstream",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-012-edfi-second-upstream"
    },
    {
      "id": "paitd-015-program-participation-views",
      "title": "Program Participation Is A People & Orgs Belonging View, Not Results Or Policy",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-015-program-participation-views"
    }
  ]
}
storage
{
  "kind": "edfi_canonical_record_view_column",
  "source": "edfi.canonical_record.edfi_local_id",
  "storageRule": "Selected by alpha.program_participation_base_view from edfi.canonical_record(resource_name in GeneralStudentProgramAssociation, StudentProgramAssociation, and specializations); public alpha.program_participation_view does not store a copy of this Ed-Fi field.",
  "writeRoute": "Route all sourced-field writes to the Ed-Fi 1EdTech Program and StudentProgramAssociation-family collections; Alpha joins student and place ids through OneRoster sourcedIds."
}

student_person_id

title
Student Person Id
type
TEXT
publicApi
person id
nullability
Required.
required
Yes
range
1 to 255 printable characters.
meaning
Student person id resolved through the platform3 sourcedId boundary.
constraints
Must join to alpha.person.person_id in the same tenant; do not reconcile ids in client code.
relationship
Many program participation rows can belong to one student person.
invalidWhen
Missing, references a missing student, crosses tenant, or is resolved by parsing names.
edgeCases
Student status still requires dated membership when the job asks for active students at a place.
example
person_ada_lovelace
pii
Identifier
allowedValues
[]
provenance
{
  "changeType": "rename+restrict",
  "sourceType": "edfi_alias_view",
  "source": "join oneroster.users.sourced_id via edfi.canonical_record.student_sourced_id",
  "sourceAnchor": "https://platform3-andymontgomery-9773s-projects.vercel.app/ed_fi/1edtech/data_dictionary/#entry-generalstudentprogramassociation-b50a12920f64",
  "aliasMapField": "program_participation.student_person_id",
  "label": "Alpha Ed-Fi view",
  "note": "Student person id resolved through the platform3 sourcedId boundary.",
  "itds": [
    {
      "id": "paitd-012-edfi-second-upstream",
      "title": "Ed-Fi Administrative Records Are A Second View-Only Upstream",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-012-edfi-second-upstream"
    },
    {
      "id": "paitd-015-program-participation-views",
      "title": "Program Participation Is A People & Orgs Belonging View, Not Results Or Policy",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-015-program-participation-views"
    }
  ]
}
storage
{
  "kind": "roster_fk_view_column",
  "source": "join oneroster.users.sourced_id via edfi.canonical_record.student_sourced_id",
  "storageRule": "Resolved in alpha.program_participation_view by joining Ed-Fi canonical records to OneRoster sourcedId boundaries; no Alpha table copies the source ids.",
  "writeRoute": "Route all sourced-field writes to the Ed-Fi 1EdTech Program and StudentProgramAssociation-family collections; Alpha joins student and place ids through OneRoster sourcedIds."
}

place_id

title
Place Id
type
TEXT
publicApi
place id
nullability
Conditional.
required
Conditional
range
1 to 255 printable characters when supplied.
meaning
School or education organization place id resolved through OneRoster.
constraints
Must join to alpha.place.place_id in the same tenant when supplied; relationships are columns, never tags.
relationship
Many program participation rows can belong to one place.
invalidWhen
References a missing place, crosses tenant, or is stored as a tag.
edgeCases
Some program associations are district-level; place_kind clarifies the grain.
example
place_timeback_school
pii
Identifier
allowedValues
[]
provenance
{
  "changeType": "rename+restrict",
  "sourceType": "edfi_alias_view",
  "source": "join oneroster.orgs.sourced_id via edfi.canonical_record.school_sourced_id",
  "sourceAnchor": "https://platform3-andymontgomery-9773s-projects.vercel.app/ed_fi/1edtech/data_dictionary/#entry-generalstudentprogramassociation-b50a12920f64",
  "aliasMapField": "program_participation.place_id",
  "label": "Alpha Ed-Fi view",
  "note": "School or education organization place id resolved through OneRoster.",
  "itds": [
    {
      "id": "paitd-012-edfi-second-upstream",
      "title": "Ed-Fi Administrative Records Are A Second View-Only Upstream",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-012-edfi-second-upstream"
    },
    {
      "id": "paitd-015-program-participation-views",
      "title": "Program Participation Is A People & Orgs Belonging View, Not Results Or Policy",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-015-program-participation-views"
    }
  ]
}
storage
{
  "kind": "roster_fk_view_column",
  "source": "join oneroster.orgs.sourced_id via edfi.canonical_record.school_sourced_id",
  "storageRule": "Resolved in alpha.program_participation_view by joining Ed-Fi canonical records to OneRoster sourcedId boundaries; no Alpha table copies the source ids.",
  "writeRoute": "Route all sourced-field writes to the Ed-Fi 1EdTech Program and StudentProgramAssociation-family collections; Alpha joins student and place ids through OneRoster sourcedIds."
}

program_id

title
Program Id
type
TEXT
publicApi
string
nullability
Conditional.
required
Conditional
range
Ed-Fi ProgramId from the canonical payload.
meaning
Program identifier from the linked Ed-Fi Program payload when present.
constraints
Use for program relationship joins only; do not parse program_name or use object_tag for program membership.
relationship
References an Ed-Fi Program canonical record when the source supplies one.
invalidWhen
Missing when source-required, crosses tenant, or replaced by a tag.
edgeCases
Some specialized associations may expose program_type without a separate program_id.
example
program-special-education
pii
Identifier
allowedValues
[]
provenance
{
  "changeType": "rename+restrict",
  "sourceType": "edfi_alias_view",
  "source": "edfi.canonical_record.payload_json.Program.ProgramId",
  "sourceAnchor": "https://platform3-andymontgomery-9773s-projects.vercel.app/ed_fi/1edtech/data_dictionary/#entry-generalstudentprogramassociation-b50a12920f64",
  "aliasMapField": "program_participation.program_id",
  "label": "Alpha Ed-Fi view",
  "note": "Program identifier from the linked Ed-Fi Program payload when present.",
  "itds": [
    {
      "id": "paitd-015-program-participation-views",
      "title": "Program Participation Is A People & Orgs Belonging View, Not Results Or Policy",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-015-program-participation-views"
    }
  ]
}
storage
{
  "kind": "edfi_canonical_record_view_column",
  "source": "edfi.canonical_record.payload_json.Program.ProgramId",
  "storageRule": "Selected by alpha.program_participation_base_view from edfi.canonical_record(resource_name in GeneralStudentProgramAssociation, StudentProgramAssociation, and specializations); public alpha.program_participation_view does not store a copy of this Ed-Fi field.",
  "writeRoute": "Route all sourced-field writes to the Ed-Fi 1EdTech Program and StudentProgramAssociation-family collections; Alpha joins student and place ids through OneRoster sourcedIds."
}

program_name

title
Program Name
type
TEXT
publicApi
string
nullability
Optional.
required
No
range
0 to 240 visible characters.
meaning
Plain program name.
constraints
Display only. Do not parse type, eligibility, or outcome from the name.
relationship
No relationship. Use program_id and program_type for joins/filtering.
invalidWhen
Used as the primary key, parsed for program_type, or used to store outcome/status.
edgeCases
Program display names can vary by district while program_type remains governed.
example
Special Education
pii
Sensitive education program
allowedValues
[]
provenance
{
  "changeType": "rename+restrict",
  "sourceType": "edfi_alias_view",
  "source": "edfi.canonical_record.payload_json.Program.ProgramName",
  "sourceAnchor": "https://platform3-andymontgomery-9773s-projects.vercel.app/ed_fi/1edtech/data_dictionary/#entry-generalstudentprogramassociation-b50a12920f64",
  "aliasMapField": "program_participation.program_name",
  "label": "Alpha Ed-Fi view",
  "note": "Plain program name.",
  "itds": [
    {
      "id": "paitd-015-program-participation-views",
      "title": "Program Participation Is A People & Orgs Belonging View, Not Results Or Policy",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-015-program-participation-views"
    },
    {
      "id": "paitd-111-privacy-retention",
      "title": "API Axis: Privacy / Retention",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-111-privacy-retention"
    }
  ]
}
storage
{
  "kind": "edfi_canonical_record_view_column",
  "source": "edfi.canonical_record.payload_json.Program.ProgramName",
  "storageRule": "Selected by alpha.program_participation_base_view from edfi.canonical_record(resource_name in GeneralStudentProgramAssociation, StudentProgramAssociation, and specializations); public alpha.program_participation_view does not store a copy of this Ed-Fi field.",
  "writeRoute": "Route all sourced-field writes to the Ed-Fi 1EdTech Program and StudentProgramAssociation-family collections; Alpha joins student and place ids through OneRoster sourcedIds."
}

program_type

title
Program Type
type
TEXT governed descriptor
publicApi
string
nullability
Conditional.
required
Conditional
range
Resolved Ed-Fi ProgramType descriptor value; open governed code list.
meaning
Governed Ed-Fi program-type descriptor.
constraints
Descriptor resolution happens on the surface; consumers must not ship descriptor tables or parse names.
relationship
No Alpha foreign key; governed by Ed-Fi descriptor_code.
invalidWhen
Free text, unresolved descriptor id, parsed from program_name, or stored in alpha.object_tag.
edgeCases
District-specific program types can appear through edfi.descriptor_code without schema changes.
example
Special Education
pii
Sensitive education program
allowedValues
[]
provenance
{
  "changeType": "rename+restrict",
  "sourceType": "edfi_alias_view",
  "source": "edfi.descriptor_code(ProgramType)",
  "sourceAnchor": "https://platform3-andymontgomery-9773s-projects.vercel.app/ed_fi/1edtech/data_dictionary/#entry-generalstudentprogramassociation-b50a12920f64",
  "aliasMapField": "program_participation.program_type",
  "label": "Alpha Ed-Fi view",
  "note": "Governed Ed-Fi program-type descriptor.",
  "itds": [
    {
      "id": "paitd-012-edfi-second-upstream",
      "title": "Ed-Fi Administrative Records Are A Second View-Only Upstream",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-012-edfi-second-upstream"
    },
    {
      "id": "paitd-015-program-participation-views",
      "title": "Program Participation Is A People & Orgs Belonging View, Not Results Or Policy",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-015-program-participation-views"
    }
  ]
}
storage
{
  "kind": "edfi_descriptor_resolved_view",
  "source": "edfi.descriptor_code(ProgramType)",
  "storageRule": "Resolved in alpha.program_participation_view from edfi.descriptor_code; no Alpha tag or descriptor table stores a copy.",
  "writeRoute": "Route all sourced-field writes to the Ed-Fi 1EdTech Program and StudentProgramAssociation-family collections; Alpha joins student and place ids through OneRoster sourcedIds."
}

participation_status

title
Participation Status
type
TEXT governed descriptor
publicApi
string
nullability
Optional.
required
No
range
Resolved Ed-Fi ProgramParticipationStatus descriptor value; open governed code list.
meaning
Governed participation-status descriptor.
constraints
Descriptor resolution happens on the surface; do not compute eligibility, service intensity, or outcome from this field.
relationship
No Alpha foreign key; governed by Ed-Fi descriptor_code.
invalidWhen
Free text, unresolved descriptor id, parsed from dates, or used as a Results outcome.
edgeCases
Active-as-of still uses begin/end dates; status is source participation status.
example
Participating
pii
Sensitive education program
allowedValues
[]
provenance
{
  "changeType": "rename+restrict",
  "sourceType": "edfi_alias_view",
  "source": "edfi.descriptor_code(ProgramParticipationStatus)",
  "sourceAnchor": "https://platform3-andymontgomery-9773s-projects.vercel.app/ed_fi/1edtech/data_dictionary/#entry-generalstudentprogramassociation-b50a12920f64",
  "aliasMapField": "program_participation.participation_status",
  "label": "Alpha Ed-Fi view",
  "note": "Governed participation-status descriptor.",
  "itds": [
    {
      "id": "paitd-012-edfi-second-upstream",
      "title": "Ed-Fi Administrative Records Are A Second View-Only Upstream",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-012-edfi-second-upstream"
    },
    {
      "id": "paitd-015-program-participation-views",
      "title": "Program Participation Is A People & Orgs Belonging View, Not Results Or Policy",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-015-program-participation-views"
    }
  ]
}
storage
{
  "kind": "edfi_descriptor_resolved_view",
  "source": "edfi.descriptor_code(ProgramParticipationStatus)",
  "storageRule": "Resolved in alpha.program_participation_view from edfi.descriptor_code; no Alpha tag or descriptor table stores a copy.",
  "writeRoute": "Route all sourced-field writes to the Ed-Fi 1EdTech Program and StudentProgramAssociation-family collections; Alpha joins student and place ids through OneRoster sourcedIds."
}

begin_date

title
Begin Date
type
DATE
publicApi
date
nullability
Nullable storage, but begin_date null means not time-locatable.
required
No
range
ISO 8601 date YYYY-MM-DD.
meaning
Inclusive date the student becomes involved with the program.
constraints
Active-as-of requires begin_date <= asOfDate and is_time_locatable=true.
relationship
No foreign key; used by point-in-time computations.
invalidWhen
Malformed, after end_date, or ignored by a current-only shortcut.
edgeCases
begin_date null plus end_date present is still excluded from point-in-time computations.
example
2026-08-15
pii
Sensitive education program
allowedValues
[]
provenance
{
  "changeType": "rename+restrict",
  "sourceType": "edfi_alias_view",
  "source": "edfi.canonical_record.payload_json.BeginDate",
  "sourceAnchor": "https://platform3-andymontgomery-9773s-projects.vercel.app/ed_fi/1edtech/data_dictionary/#entry-generalstudentprogramassociation-b50a12920f64",
  "aliasMapField": "program_participation.begin_date",
  "label": "Alpha Ed-Fi view",
  "note": "Inclusive date the student becomes involved with the program.",
  "itds": [
    {
      "id": "paitd-004-point-in-time-memberships",
      "title": "Memberships Are Effective-Dated And Answered By AsOfDate",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-004-point-in-time-memberships"
    },
    {
      "id": "paitd-015-program-participation-views",
      "title": "Program Participation Is A People & Orgs Belonging View, Not Results Or Policy",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-015-program-participation-views"
    }
  ]
}
storage
{
  "kind": "edfi_canonical_record_view_column",
  "source": "edfi.canonical_record.payload_json.BeginDate",
  "storageRule": "Selected by alpha.program_participation_base_view from edfi.canonical_record(resource_name in GeneralStudentProgramAssociation, StudentProgramAssociation, and specializations); public alpha.program_participation_view does not store a copy of this Ed-Fi field.",
  "writeRoute": "Route all sourced-field writes to the Ed-Fi 1EdTech Program and StudentProgramAssociation-family collections; Alpha joins student and place ids through OneRoster sourcedIds."
}

end_date

title
End Date
type
DATE
publicApi
date
nullability
Optional. Null means active after begin_date.
required
No
range
ISO 8601 date YYYY-MM-DD.
meaning
Date the student exits the program; null means active after begin_date.
constraints
Active-as-of includes the row when end_date is null or asOfDate < end_date.
relationship
No foreign key; used by point-in-time computations.
invalidWhen
Malformed, on/before begin_date, or treated as inclusive.
edgeCases
Both begin_date and end_date null means always excluded.
example
2027-06-01
pii
Sensitive education program
allowedValues
[]
provenance
{
  "changeType": "rename+restrict",
  "sourceType": "edfi_alias_view",
  "source": "edfi.canonical_record.payload_json.EndDate",
  "sourceAnchor": "https://platform3-andymontgomery-9773s-projects.vercel.app/ed_fi/1edtech/data_dictionary/#entry-generalstudentprogramassociation-b50a12920f64",
  "aliasMapField": "program_participation.end_date",
  "label": "Alpha Ed-Fi view",
  "note": "Date the student exits the program; null means active after begin_date.",
  "itds": [
    {
      "id": "paitd-004-point-in-time-memberships",
      "title": "Memberships Are Effective-Dated And Answered By AsOfDate",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-004-point-in-time-memberships"
    },
    {
      "id": "paitd-015-program-participation-views",
      "title": "Program Participation Is A People & Orgs Belonging View, Not Results Or Policy",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-015-program-participation-views"
    }
  ]
}
storage
{
  "kind": "edfi_canonical_record_view_column",
  "source": "edfi.canonical_record.payload_json.EndDate",
  "storageRule": "Selected by alpha.program_participation_base_view from edfi.canonical_record(resource_name in GeneralStudentProgramAssociation, StudentProgramAssociation, and specializations); public alpha.program_participation_view does not store a copy of this Ed-Fi field.",
  "writeRoute": "Route all sourced-field writes to the Ed-Fi 1EdTech Program and StudentProgramAssociation-family collections; Alpha joins student and place ids through OneRoster sourcedIds."
}

is_time_locatable

title
Is Time Locatable
type
BOOLEAN
publicApi
boolean
nullability
Required derived field.
required
Yes
range
true or false.
meaning
True only when begin_date is present.
constraints
Derived by the view from BeginDate; consumers filter on this instead of guessing from nulls.
relationship
No relationship; query input to active-as-of views.
invalidWhen
True when begin_date is null, false when begin_date is present, or omitted.
edgeCases
end_date null does not make the row unlocatable.
example
true
pii
No
allowedValues
[
  {
    "value": "true",
    "meaning": "The fact is asserted by the source or by the Alpha surface.",
    "useWhen": "Use only when the field's own constraints say the fact is true.",
    "invalidWhen": "Invalid when guessed from names, labels, dates, tags, or another field."
  },
  {
    "value": "false",
    "meaning": "The fact is explicitly not asserted.",
    "useWhen": "Use only when the source or surface stores an explicit false value.",
    "invalidWhen": "Invalid when a missing value should remain unknown."
  }
]
provenance
{
  "changeType": "restrict",
  "sourceType": "view_expression",
  "source": "view expression: payload_json.BeginDate is not null",
  "sourceAnchor": null,
  "aliasMapField": "program_participation.is_time_locatable",
  "label": "Alpha derived view field",
  "note": "True only when begin_date is present. No Alpha table stores it.",
  "itds": [
    {
      "id": "paitd-004-point-in-time-memberships",
      "title": "Memberships Are Effective-Dated And Answered By AsOfDate",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-004-point-in-time-memberships"
    },
    {
      "id": "paitd-015-program-participation-views",
      "title": "Program Participation Is A People & Orgs Belonging View, Not Results Or Policy",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-015-program-participation-views"
    }
  ]
}
storage
{
  "kind": "view_derived",
  "source": "view expression: payload_json.BeginDate is not null",
  "storageRule": "Computed in alpha.program_participation_view as a view expression; no Alpha table column stores it.",
  "writeRoute": "Not writable; recomputed by the view from sourced fields."
}

source_program_resource

title
Source Program Resource
type
TEXT enum
publicApi
string enum
nullability
Required.
required
Yes
range
One of the Ed-Fi program-association resources exposed by PAITD-015.
meaning
Exact Ed-Fi association/specialization that produced the row.
constraints
Use for provenance and debugging only; do not branch business logic on a client-side switch statement.
relationship
No relationship; points back to the Ed-Fi canonical resource family.
invalidWhen
Free text, missing, or used by a skill pack to reimplement Ed-Fi routing.
edgeCases
The list can expand only through an architecture update that proves the source remains a People & Orgs belonging fact.
example
GeneralStudentProgramAssociation
pii
No
allowedValues
[
  {
    "value": "GeneralStudentProgramAssociation",
    "meaning": "Generic Ed-Fi student-program association.",
    "useWhen": "Use when the canonical record comes from GeneralStudentProgramAssociation.",
    "invalidWhen": "Invalid for specialized associations that the Ed-Fi surface names more specifically."
  },
  {
    "value": "StudentProgramAssociation",
    "meaning": "Ed-Fi student-program association family record.",
    "useWhen": "Use when the canonical record comes from StudentProgramAssociation or a direct equivalent.",
    "invalidWhen": "Invalid for unrelated attendance, discipline, transcript, or intervention-outcome records."
  },
  {
    "value": "SpecialEducationProgramAssociation",
    "meaning": "Special Education participation specialization when the Ed-Fi surface exposes it as a canonical program association.",
    "useWhen": "Use only for the Special Education program association.",
    "invalidWhen": "Invalid for outcomes, services effectiveness, or eligibility formulas."
  },
  {
    "value": "TitleIPartAProgramAssociation",
    "meaning": "Title I participation specialization when present in the Ed-Fi source.",
    "useWhen": "Use only for the Title I program association.",
    "invalidWhen": "Invalid for general program rows or outcome records."
  },
  {
    "value": "EnglishLearnerProgramAssociation",
    "meaning": "English Learner participation specialization when present in the Ed-Fi source.",
    "useWhen": "Use only for the English Learner program association.",
    "invalidWhen": "Invalid for language preference fields or test results."
  },
  {
    "value": "Section504ProgramAssociation",
    "meaning": "Section 504 participation specialization when present in the Ed-Fi source.",
    "useWhen": "Use only for the Section 504 program association.",
    "invalidWhen": "Invalid for service details or policy thresholds."
  },
  {
    "value": "FoodServiceProgramAssociation",
    "meaning": "Food service participation specialization when present in the Ed-Fi source.",
    "useWhen": "Use only for the Food Service program association.",
    "invalidWhen": "Invalid for finance records or eligibility calculations."
  }
]
provenance
{
  "changeType": "rename+restrict",
  "sourceType": "edfi_alias_view",
  "source": "edfi.canonical_record.resource_name",
  "sourceAnchor": "https://platform3-andymontgomery-9773s-projects.vercel.app/ed_fi/1edtech/data_dictionary/#entry-generalstudentprogramassociation-b50a12920f64",
  "aliasMapField": "program_participation.source_program_resource",
  "label": "Alpha Ed-Fi view",
  "note": "Exact Ed-Fi association/specialization that produced the row.",
  "itds": [
    {
      "id": "paitd-015-program-participation-views",
      "title": "Program Participation Is A People & Orgs Belonging View, Not Results Or Policy",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-015-program-participation-views"
    }
  ]
}
storage
{
  "kind": "edfi_canonical_record_view_column",
  "source": "edfi.canonical_record.resource_name",
  "storageRule": "Selected by alpha.program_participation_base_view from edfi.canonical_record(resource_name in GeneralStudentProgramAssociation, StudentProgramAssociation, and specializations); public alpha.program_participation_view does not store a copy of this Ed-Fi field.",
  "writeRoute": "Route all sourced-field writes to the Ed-Fi 1EdTech Program and StudentProgramAssociation-family collections; Alpha joins student and place ids through OneRoster sourcedIds."
}

alpha.app_credential · App Credential

objectName
app_credential
apiCollection
/app_credentials
storage
Alpha extension for operational secret references; no 1EdTech source table.
changeType
extend
upstream
None
primaryKey
(tenant_id, student_sourced_id, app_id)
purpose
A first-class operational secret reference for a student's login to a third-party learning app. The secret value is never stored in a roster field, tag, log, or API response.
lifecycle
Created when an operator links a student to an app credential in the vault. Rotation updates last_rotated_at and secret_ref. Ordinary reads expose existence and rotation metadata only.
auth
Requires credential-status scope for existence reads and a stronger operator scope for rotation. Secret values are never returned.
sourceType
alpha_extend
publicSurface
alpha.app_credential
baseView
baseSource
coreWriteRoute
None.
extensionWriteRoute
Write alpha.app_credential rows with a student_sourced_id foreign key to oneroster.users.
anchor
table-alpha-app-credential
fieldCount
6
sourceAnchor
https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-008-app-credentials
filters
[
  "studentSourcedId",
  "appId",
  "hasCredential",
  "lastRotatedBefore"
]
sortKeys
[
  "student_sourced_id",
  "app_id",
  "last_rotated_at"
]
extensionTables
[
  "alpha.app_credential"
]
storageContract
{
  "alphaObject": "app_credential",
  "publicSurface": "alpha.app_credential",
  "upstreamModule": "oneroster/1edtech",
  "baseSource": null,
  "baseView": null,
  "extensionTables": [
    "alpha.app_credential"
  ],
  "coreWriteRoute": "None.",
  "extensionWriteRoute": "Write alpha.app_credential rows with a student_sourced_id foreign key to oneroster.users.",
  "requiredShape": "CREATE TABLE is allowed because this is a pure Alpha extension."
}
example
{
  "student_sourced_id": "person_ada_lovelace",
  "app_id": "ixl_math",
  "secret_ref": "vault://learning-apps/ixl_math/person_ada_lovelace",
  "created_at": "2026-08-15T13:45:30.000Z",
  "last_rotated_at": "2026-11-01T09:00:00.000Z"
}

Fields (6)

tenant_id

title
Tenant Id
type
UUID
publicApi
Hidden in ordinary Alpha responses; selected from the verified JWT.
nullability
Required on every stored row.
required
Yes
range
Valid PostgreSQL UUID.
meaning
The tenant boundary that owns this People & Orgs row.
constraints
Must equal the verified JWT tenant_id or tenantId claim. Never accept a tenant header or body field as source of truth.
relationship
Belongs to one platform.tenant. One tenant owns many People & Orgs rows.
invalidWhen
Missing, malformed, points to another tenant, or is supplied by an unverified request body.
edgeCases
Demo token minting may accept tenantId=demo, but stored rows still use the resolved tenant id.
example
0d4ce2f4-1c42-4f3c-9f0d-03fb7f5271d3
pii
No
allowedValues
[]
provenance
{
  "changeType": "inherited",
  "sourceType": "platform_shared",
  "source": "platform.tenant",
  "sourceAnchor": null,
  "aliasMapField": null,
  "label": "Alpha inherited",
  "note": "Inherited platform tenant routing field, not a OneRoster alias.",
  "itds": [
    {
      "id": "paitd-109-tenant-routing",
      "title": "API Axis: Tenant Routing",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-109-tenant-routing"
    }
  ]
}
storage
{
  "kind": "platform_inherited_column",
  "source": "platform.tenant / verified JWT tenant claim",
  "storageRule": "Inherited platform tenant key. It scopes base rows, extension rows, and views; it is not copied from OneRoster or Ed-Fi.",
  "writeRoute": "Resolved from the verified JWT tenant claim by the platform layer."
}

student_sourced_id

title
Student Sourced Id
type
TEXT
publicApi
person id
nullability
Required.
required
Yes
range
1 to 255 printable characters.
meaning
Student person id that owns the credential.
constraints
Must reference alpha.person.person_id in the same tenant and the person must have an active student membership for credential use.
relationship
Many app credentials can belong to one student person.
invalidWhen
References a missing/non-student person, crosses tenant, or stores an app username instead of person id.
edgeCases
Historical credentials can remain for audit after a student leaves, but existence reads remain scoped.
example
person_ada_lovelace
pii
Identifier
allowedValues
[]
provenance
{
  "changeType": "extend",
  "sourceType": "alpha_extend_table",
  "source": "alpha.app_credential.student_sourced_id",
  "sourceAnchor": null,
  "aliasMapField": "app_credential.student_sourced_id",
  "label": "Alpha extend",
  "note": "",
  "itds": [
    {
      "id": "paitd-008-app-credentials",
      "title": "App Credentials Use Vault References, Never Roster Password Fields",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-008-app-credentials"
    }
  ]
}
storage
{
  "kind": "alpha_extend_table",
  "source": "alpha.app_credential.student_sourced_id",
  "storageRule": "Stored only in alpha.app_credential.student_sourced_id; allowed because it is a true Alpha extension and not a copied 1EdTech field.",
  "writeRoute": "Write alpha.app_credential rows with a student_sourced_id foreign key to oneroster.users."
}

app_id

title
App Id
type
TEXT
publicApi
string
nullability
Required.
required
Yes
range
1 to 120 lowercase letters, digits, hyphens, underscores, or dots.
meaning
Learning app identifier.
constraints
Must identify the external app whose credential is referenced. It is not a secret.
relationship
Pairs with student_sourced_id to identify one credential reference.
invalidWhen
Blank, contains a secret, or changes to rotate a credential.
edgeCases
The app catalog itself can live outside People & Orgs; this module stores only the credential reference by app id.
example
ixl_math
pii
No
allowedValues
[]
provenance
{
  "changeType": "extend",
  "sourceType": "alpha_extend_table",
  "source": "alpha.app_credential.app_id",
  "sourceAnchor": null,
  "aliasMapField": "app_credential.app_id",
  "label": "Alpha extend",
  "note": "",
  "itds": [
    {
      "id": "paitd-008-app-credentials",
      "title": "App Credentials Use Vault References, Never Roster Password Fields",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-008-app-credentials"
    }
  ]
}
storage
{
  "kind": "alpha_extend_table",
  "source": "alpha.app_credential.app_id",
  "storageRule": "Stored only in alpha.app_credential.app_id; allowed because it is a true Alpha extension and not a copied 1EdTech field.",
  "writeRoute": "Write alpha.app_credential rows with a student_sourced_id foreign key to oneroster.users."
}

secret_ref

title
Secret Ref
type
TEXT vault reference
publicApi
redacted reference status
nullability
Required in storage; never returned raw from ordinary APIs.
required
Yes
range
Managed-vault reference URI or key accepted by the security-approved vault.
meaning
Reference to a managed secrets vault, never plaintext.
constraints
Must point to a vault-managed secret. Never store plaintext, tags, passwords, or copied secrets in People & Orgs.
relationship
Operational reference to the vault; no database foreign key to secret material.
invalidWhen
Plaintext password, API key, token, or any value returned to a normal API caller.
edgeCases
A privileged rotation workflow may replace secret_ref; audit the operation without logging the value.
example
vault://learning-apps/ixl_math/person_ada_lovelace
pii
Secret reference
allowedValues
[]
provenance
{
  "changeType": "extend",
  "sourceType": "alpha_extend_table",
  "source": "alpha.app_credential.secret_ref",
  "sourceAnchor": null,
  "aliasMapField": "app_credential.secret_ref",
  "label": "Alpha extend",
  "note": "",
  "itds": [
    {
      "id": "paitd-008-app-credentials",
      "title": "App Credentials Use Vault References, Never Roster Password Fields",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-008-app-credentials"
    },
    {
      "id": "paitd-111-privacy-retention",
      "title": "API Axis: Privacy / Retention",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-111-privacy-retention"
    }
  ]
}
storage
{
  "kind": "alpha_extend_table",
  "source": "alpha.app_credential.secret_ref",
  "storageRule": "Stored only in alpha.app_credential.secret_ref; allowed because it is a true Alpha extension and not a copied 1EdTech field.",
  "writeRoute": "Write alpha.app_credential rows with a student_sourced_id foreign key to oneroster.users."
}

created_at

title
Created At
type
TIMESTAMPTZ
publicApi
ISO 8601 datetime
nullability
Required.
required
Yes
range
ISO 8601 UTC datetime.
meaning
Credential reference creation time.
constraints
Set by the surface when the reference is created.
relationship
No relationship.
invalidWhen
Client-supplied in a way that rewrites audit history or earlier than the tenant creation time.
edgeCases
Recreating a deleted credential reference creates a new created_at and audit trail.
example
2026-08-15T13:45:30.000Z
pii
No
allowedValues
[]
provenance
{
  "changeType": "extend",
  "sourceType": "alpha_extend_table",
  "source": "alpha.app_credential.created_at",
  "sourceAnchor": null,
  "aliasMapField": "app_credential.created_at",
  "label": "Alpha extend",
  "note": "",
  "itds": [
    {
      "id": "paitd-008-app-credentials",
      "title": "App Credentials Use Vault References, Never Roster Password Fields",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-008-app-credentials"
    }
  ]
}
storage
{
  "kind": "alpha_extend_table",
  "source": "alpha.app_credential.created_at",
  "storageRule": "Stored only in alpha.app_credential.created_at; allowed because it is a true Alpha extension and not a copied 1EdTech field.",
  "writeRoute": "Write alpha.app_credential rows with a student_sourced_id foreign key to oneroster.users."
}

last_rotated_at

title
Last Rotated At
type
TIMESTAMPTZ
publicApi
ISO 8601 datetime or null
nullability
Optional until the first rotation after creation.
required
No
range
ISO 8601 UTC datetime when supplied.
meaning
Last rotation time surfaced for audit and operations.
constraints
Updated by the rotation workflow. Consumers use it to decide whether a credential is stale; they never see the secret.
relationship
No relationship.
invalidWhen
Earlier than created_at, client-supplied without a rotation, or used as proof of password value.
edgeCases
Null can mean never rotated after creation.
example
2026-11-01T09:00:00.000Z
pii
No
allowedValues
[]
provenance
{
  "changeType": "extend",
  "sourceType": "alpha_extend_table",
  "source": "alpha.app_credential.last_rotated_at",
  "sourceAnchor": null,
  "aliasMapField": "app_credential.last_rotated_at",
  "label": "Alpha extend",
  "note": "",
  "itds": [
    {
      "id": "paitd-008-app-credentials",
      "title": "App Credentials Use Vault References, Never Roster Password Fields",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-008-app-credentials"
    }
  ]
}
storage
{
  "kind": "alpha_extend_table",
  "source": "alpha.app_credential.last_rotated_at",
  "storageRule": "Stored only in alpha.app_credential.last_rotated_at; allowed because it is a true Alpha extension and not a copied 1EdTech field.",
  "writeRoute": "Write alpha.app_credential rows with a student_sourced_id foreign key to oneroster.users."
}

alpha.tag_definition · Tag Definition

objectName
tag_definition
apiCollection
/tag_definitions
storage
Alpha extension for governed low-cardinality reporting dimensions.
changeType
extend
upstream
None
primaryKey
(tenant_id, tag_key, anchor)
purpose
Governed tag registry for low-cardinality roster reporting dimensions that do not belong as enforced relationship columns.
lifecycle
Seeded at tenant setup for locked values such as brand, modality, segment, level, alpha_level, and grade_level. Non-locked reporting dimensions can be added through governed configuration.
auth
Readable to roster integrators; writable only by configuration/admin scopes.
sourceType
alpha_extend
publicSurface
alpha.tag_definition
baseView
baseSource
coreWriteRoute
None.
extensionWriteRoute
Write alpha.tag_definition rows only; no 1EdTech columns are copied.
anchor
table-alpha-tag-definition
fieldCount
6
sourceAnchor
https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-006-tag-registry
filters
[
  "tagKey",
  "anchor",
  "isLocked"
]
sortKeys
[
  "tag_key",
  "anchor"
]
extensionTables
[
  "alpha.tag_definition"
]
storageContract
{
  "alphaObject": "tag_definition",
  "publicSurface": "alpha.tag_definition",
  "upstreamModule": "oneroster/1edtech",
  "baseSource": null,
  "baseView": null,
  "extensionTables": [
    "alpha.tag_definition"
  ],
  "coreWriteRoute": "None.",
  "extensionWriteRoute": "Write alpha.tag_definition rows only; no 1EdTech columns are copied.",
  "requiredShape": "CREATE TABLE is allowed because this is a pure Alpha extension."
}
example
{
  "tag_key": "level",
  "anchor": "school",
  "allowed_values": [
    "WL",
    "LL",
    "L1",
    "L2",
    "MS",
    "HS"
  ],
  "value_type": "string",
  "is_locked": true
}

Fields (6)

tenant_id

title
Tenant Id
type
UUID
publicApi
Hidden in ordinary Alpha responses; selected from the verified JWT.
nullability
Required on every stored row.
required
Yes
range
Valid PostgreSQL UUID.
meaning
The tenant boundary that owns this People & Orgs row.
constraints
Must equal the verified JWT tenant_id or tenantId claim. Never accept a tenant header or body field as source of truth.
relationship
Belongs to one platform.tenant. One tenant owns many People & Orgs rows.
invalidWhen
Missing, malformed, points to another tenant, or is supplied by an unverified request body.
edgeCases
Demo token minting may accept tenantId=demo, but stored rows still use the resolved tenant id.
example
0d4ce2f4-1c42-4f3c-9f0d-03fb7f5271d3
pii
No
allowedValues
[]
provenance
{
  "changeType": "inherited",
  "sourceType": "platform_shared",
  "source": "platform.tenant",
  "sourceAnchor": null,
  "aliasMapField": null,
  "label": "Alpha inherited",
  "note": "Inherited platform tenant routing field, not a OneRoster alias.",
  "itds": [
    {
      "id": "paitd-109-tenant-routing",
      "title": "API Axis: Tenant Routing",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-109-tenant-routing"
    }
  ]
}
storage
{
  "kind": "platform_inherited_column",
  "source": "platform.tenant / verified JWT tenant claim",
  "storageRule": "Inherited platform tenant key. It scopes base rows, extension rows, and views; it is not copied from OneRoster or Ed-Fi.",
  "writeRoute": "Resolved from the verified JWT tenant claim by the platform layer."
}

tag_key

title
Tag Key
type
TEXT
publicApi
string
nullability
Required.
required
Yes
range
1 to 80 lowercase letters, digits, underscores, or dots.
meaning
Stable tag key.
constraints
Must be unique with anchor in the tenant. Use readable keys such as brand, modality, segment, alpha_level, grade_level, or level.
relationship
Referenced by alpha.object_tag.tag_key.
invalidWhen
Blank, free-form display label, contains a secret, or duplicates a real column's job.
edgeCases
Promotion to a real column is one-way when a tag becomes a join target, constraint key, or computed input.
example
level
pii
No
allowedValues
[]
provenance
{
  "changeType": "extend",
  "sourceType": "alpha_extend_table",
  "source": "alpha.tag_definition.tag_key",
  "sourceAnchor": null,
  "aliasMapField": "tag_definition.tag_key",
  "label": "Alpha extend",
  "note": "",
  "itds": [
    {
      "id": "paitd-006-tag-registry",
      "title": "Governed Tags Are Report Slices Only",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-006-tag-registry"
    }
  ]
}
storage
{
  "kind": "alpha_extend_table",
  "source": "alpha.tag_definition.tag_key",
  "storageRule": "Stored only in alpha.tag_definition.tag_key; allowed because it is a true Alpha extension and not a copied 1EdTech field.",
  "writeRoute": "Write alpha.tag_definition rows only; no 1EdTech columns are copied."
}

anchor

title
Anchor
type
TEXT enum
publicApi
string enum
nullability
Required.
required
Yes
range
One of the allowed anchors.
meaning
The grain the tag is allowed to attach to, such as nwea_account or school.
constraints
Must name a supported object grain. Brand and modality use anchor=nwea_account; school level uses anchor=school.
relationship
Constrained by object_tag.object_kind and object_id.
invalidWhen
Used for a relationship, foreign key, secret, or computed input.
edgeCases
nwea_account means a district place with nwea_district_id, not any district-like string. school means a place row whose place_kind is school.
example
school
pii
No
allowedValues
[
  {
    "value": "nwea_account",
    "meaning": "The tag applies to a place whose place_kind is district and which carries nwea_district_id.",
    "useWhen": "Use for locked brand and modality tags.",
    "invalidWhen": "Invalid on school rows or non-NWEA-account places."
  },
  {
    "value": "school",
    "meaning": "The tag applies to a place whose place_kind is school.",
    "useWhen": "Use for school-level report slicing dimensions such as level.",
    "invalidWhen": "Invalid for a relationship, foreign key, secret, or computed input."
  },
  {
    "value": "person",
    "meaning": "The tag applies to a person for reporting only.",
    "useWhen": "Use only for low-cardinality slices that are not relationships or sensitive secrets.",
    "invalidWhen": "Invalid for parent/guardian links, credentials, mastery, or policy formulas."
  }
]
provenance
{
  "changeType": "extend",
  "sourceType": "alpha_extend_table",
  "source": "alpha.tag_definition.anchor",
  "sourceAnchor": null,
  "aliasMapField": "tag_definition.anchor",
  "label": "Alpha extend",
  "note": "",
  "itds": [
    {
      "id": "paitd-006-tag-registry",
      "title": "Governed Tags Are Report Slices Only",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-006-tag-registry"
    },
    {
      "id": "paitd-003-place-nwea-boundary",
      "title": "Place Is The Plain Alias For OneRoster Org And District Is The NWEA Account",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-003-place-nwea-boundary"
    }
  ]
}
storage
{
  "kind": "alpha_extend_table",
  "source": "alpha.tag_definition.anchor",
  "storageRule": "Stored only in alpha.tag_definition.anchor; allowed because it is a true Alpha extension and not a copied 1EdTech field.",
  "writeRoute": "Write alpha.tag_definition rows only; no 1EdTech columns are copied."
}

allowed_values

title
Allowed Values
type
JSONB array
publicApi
array of strings
nullability
Required; may be empty only before activation in setup workflow.
required
Yes
range
Array of governed scalar values; each value must fit the tag value_type.
meaning
Governed allowed value list.
constraints
object_tag.tag_value must be one of these values. No free-form tags. For #70 and school-level reporting-blocking keys, the closed lists are published in the enum catalog: brand, modality, segment, level, alpha_level, and grade_level.
relationship
Defines valid alpha.object_tag.tag_value rows.
invalidWhen
Missing for an active tag, contains secrets, contains ids that should be foreign keys, mixes value types, or omits a live-validated canonical value.
edgeCases
Brand, segment, and level values are no longer deferred to runtime registry text; this dictionary publishes their closed lists and live validation evidence.
pii
No
example
[
  "WL",
  "LL",
  "L1",
  "L2",
  "MS",
  "HS"
]
allowedValues
[]
provenance
{
  "changeType": "extend",
  "sourceType": "alpha_extend_table",
  "source": "alpha.tag_definition.allowed_values",
  "sourceAnchor": null,
  "aliasMapField": "tag_definition.allowed_values",
  "label": "Alpha extend",
  "note": "",
  "itds": [
    {
      "id": "paitd-006-tag-registry",
      "title": "Governed Tags Are Report Slices Only",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-006-tag-registry"
    }
  ]
}
storage
{
  "kind": "alpha_extend_table",
  "source": "alpha.tag_definition.allowed_values",
  "storageRule": "Stored only in alpha.tag_definition.allowed_values; allowed because it is a true Alpha extension and not a copied 1EdTech field.",
  "writeRoute": "Write alpha.tag_definition rows only; no 1EdTech columns are copied."
}

value_type

title
Value Type
type
TEXT enum
publicApi
string enum
nullability
Required.
required
Yes
range
string, integer, boolean, or date.
meaning
Typed value class.
constraints
Every allowed value must parse as this type.
relationship
Controls validation of object_tag.tag_value.
invalidWhen
Free text type, changed without migrating existing tag values, or used to store JSON blobs.
edgeCases
Most People & Orgs tags are string enums.
example
string
pii
No
allowedValues
[
  {
    "value": "string",
    "meaning": "Allowed values are strings.",
    "useWhen": "Use for brand, modality, level, and similar labels.",
    "invalidWhen": "Invalid for dates or numeric bands."
  },
  {
    "value": "integer",
    "meaning": "Allowed values are integers.",
    "useWhen": "Use for a governed numeric slice.",
    "invalidWhen": "Invalid when values need decimal precision or units."
  },
  {
    "value": "boolean",
    "meaning": "Allowed values are true/false.",
    "useWhen": "Use for a governed reporting switch.",
    "invalidWhen": "Invalid when missing and false have different meanings."
  },
  {
    "value": "date",
    "meaning": "Allowed values are ISO dates.",
    "useWhen": "Use only for a report slice, not for point-in-time membership computations.",
    "invalidWhen": "Invalid when the date must be a real computed input column."
  }
]
provenance
{
  "changeType": "extend",
  "sourceType": "alpha_extend_table",
  "source": "alpha.tag_definition.value_type",
  "sourceAnchor": null,
  "aliasMapField": "tag_definition.value_type",
  "label": "Alpha extend",
  "note": "",
  "itds": [
    {
      "id": "paitd-006-tag-registry",
      "title": "Governed Tags Are Report Slices Only",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-006-tag-registry"
    }
  ]
}
storage
{
  "kind": "alpha_extend_table",
  "source": "alpha.tag_definition.value_type",
  "storageRule": "Stored only in alpha.tag_definition.value_type; allowed because it is a true Alpha extension and not a copied 1EdTech field.",
  "writeRoute": "Write alpha.tag_definition rows only; no 1EdTech columns are copied."
}

is_locked

title
Is Locked
type
BOOLEAN
publicApi
boolean
nullability
Required.
required
Yes
range
true or false.
meaning
True when setup seeds and locks the tag, as with brand, modality, segment, and level.
constraints
Locked tags cannot add or remove values without a controlled setup/migration step.
relationship
No relationship.
invalidWhen
False for any setup-locked reporting tag: brand, modality, segment, level, alpha_level, or grade_level; or used to bypass tag governance.
edgeCases
A locked tag can still be read and filtered by consumers.
example
true
pii
No
allowedValues
[
  {
    "value": "true",
    "meaning": "The fact is asserted by the source or by the Alpha surface.",
    "useWhen": "Use only when the field's own constraints say the fact is true.",
    "invalidWhen": "Invalid when guessed from names, labels, dates, tags, or another field."
  },
  {
    "value": "false",
    "meaning": "The fact is explicitly not asserted.",
    "useWhen": "Use only when the source or surface stores an explicit false value.",
    "invalidWhen": "Invalid when a missing value should remain unknown."
  }
]
provenance
{
  "changeType": "extend",
  "sourceType": "alpha_extend_table",
  "source": "alpha.tag_definition.is_locked",
  "sourceAnchor": null,
  "aliasMapField": "tag_definition.is_locked",
  "label": "Alpha extend",
  "note": "",
  "itds": [
    {
      "id": "paitd-006-tag-registry",
      "title": "Governed Tags Are Report Slices Only",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-006-tag-registry"
    },
    {
      "id": "paitd-003-place-nwea-boundary",
      "title": "Place Is The Plain Alias For OneRoster Org And District Is The NWEA Account",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-003-place-nwea-boundary"
    }
  ]
}
storage
{
  "kind": "alpha_extend_table",
  "source": "alpha.tag_definition.is_locked",
  "storageRule": "Stored only in alpha.tag_definition.is_locked; allowed because it is a true Alpha extension and not a copied 1EdTech field.",
  "writeRoute": "Write alpha.tag_definition rows only; no 1EdTech columns are copied."
}

alpha.object_tag · Object Tag

objectName
object_tag
apiCollection
/object_tags
storage
Alpha extension for governed tag assignments.
changeType
extend
upstream
None
primaryKey
(tenant_id, object_kind, object_id, tag_key)
purpose
A governed tag assignment for report slicing only. It is never used for relationships, joins to live rows, or secrets.
lifecycle
Created only after tag_definition exists for the same tenant and anchor. Deleted when a reporting assignment is no longer valid; historical reports use their own evidence snapshots if needed.
auth
Readable to roster report scopes; writable only by configuration/admin scopes.
sourceType
alpha_extend
publicSurface
alpha.object_tag
baseView
baseSource
coreWriteRoute
None.
extensionWriteRoute
Write alpha.object_tag rows only; object_id is a relationship reference to a live public object, not a copied 1EdTech field.
anchor
table-alpha-object-tag
fieldCount
5
sourceAnchor
https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-006-tag-registry
filters
[
  "objectKind",
  "objectId",
  "tagKey",
  "tagValue"
]
sortKeys
[
  "object_kind",
  "tag_key",
  "tag_value"
]
extensionTables
[
  "alpha.object_tag"
]
storageContract
{
  "alphaObject": "object_tag",
  "publicSurface": "alpha.object_tag",
  "upstreamModule": "oneroster/1edtech",
  "baseSource": null,
  "baseView": null,
  "extensionTables": [
    "alpha.object_tag"
  ],
  "coreWriteRoute": "None.",
  "extensionWriteRoute": "Write alpha.object_tag rows only; object_id is a relationship reference to a live public object, not a copied 1EdTech field.",
  "requiredShape": "CREATE TABLE is allowed because this is a pure Alpha extension."
}
example
{
  "object_kind": "place",
  "object_id": "place_alpha_ms",
  "tag_key": "level",
  "tag_value": "MS"
}

Fields (5)

tenant_id

title
Tenant Id
type
UUID
publicApi
Hidden in ordinary Alpha responses; selected from the verified JWT.
nullability
Required on every stored row.
required
Yes
range
Valid PostgreSQL UUID.
meaning
The tenant boundary that owns this People & Orgs row.
constraints
Must equal the verified JWT tenant_id or tenantId claim. Never accept a tenant header or body field as source of truth.
relationship
Belongs to one platform.tenant. One tenant owns many People & Orgs rows.
invalidWhen
Missing, malformed, points to another tenant, or is supplied by an unverified request body.
edgeCases
Demo token minting may accept tenantId=demo, but stored rows still use the resolved tenant id.
example
0d4ce2f4-1c42-4f3c-9f0d-03fb7f5271d3
pii
No
allowedValues
[]
provenance
{
  "changeType": "inherited",
  "sourceType": "platform_shared",
  "source": "platform.tenant",
  "sourceAnchor": null,
  "aliasMapField": null,
  "label": "Alpha inherited",
  "note": "Inherited platform tenant routing field, not a OneRoster alias.",
  "itds": [
    {
      "id": "paitd-109-tenant-routing",
      "title": "API Axis: Tenant Routing",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-109-tenant-routing"
    }
  ]
}
storage
{
  "kind": "platform_inherited_column",
  "source": "platform.tenant / verified JWT tenant claim",
  "storageRule": "Inherited platform tenant key. It scopes base rows, extension rows, and views; it is not copied from OneRoster or Ed-Fi.",
  "writeRoute": "Resolved from the verified JWT tenant claim by the platform layer."
}

object_kind

title
Object Kind
type
TEXT enum
publicApi
string enum
nullability
Required.
required
Yes
range
One of the allowed object kinds.
meaning
Tagged Alpha object kind.
constraints
Must be compatible with tag_definition.anchor. For brand/modality, object_kind is place and the place must be an NWEA-account district; for level, object_kind is place and the place must be a school.
relationship
Together with object_id points to the tagged object.
invalidWhen
Unknown object kind, mismatched tag anchor, or used for a relationship field.
edgeCases
The same object can hold multiple different tag_keys.
example
place
pii
No
allowedValues
[
  {
    "value": "person",
    "meaning": "The tag attaches to alpha.person.",
    "useWhen": "Use only when tag_definition.anchor allows person.",
    "invalidWhen": "Invalid when the tag describes a place or membership relationship."
  },
  {
    "value": "place",
    "meaning": "The tag attaches to alpha.place.",
    "useWhen": "Use for school, district, NWEA-account, brand, modality, or level slices when registered.",
    "invalidWhen": "Invalid when the tag value should be a real parent_place_id or nwea_district_id column."
  },
  {
    "value": "school_period",
    "meaning": "The tag attaches to alpha.school_period.",
    "useWhen": "Use for reporting slices only, not term math.",
    "invalidWhen": "Invalid when the period value is a computed input."
  },
  {
    "value": "place_membership",
    "meaning": "The tag attaches to alpha.place_membership.",
    "useWhen": "Use only for low-cardinality reporting dimensions registered for memberships.",
    "invalidWhen": "Invalid for person_id, place_id, begin_date, end_date, or role_kind."
  },
  {
    "value": "class_membership",
    "meaning": "The tag attaches to alpha.class_membership.",
    "useWhen": "Use only for low-cardinality reporting dimensions registered for class memberships.",
    "invalidWhen": "Invalid for class, school, person, date, or role relationships."
  }
]
provenance
{
  "changeType": "extend",
  "sourceType": "alpha_extend_table",
  "source": "alpha.object_tag.object_kind",
  "sourceAnchor": null,
  "aliasMapField": "object_tag.object_kind",
  "label": "Alpha extend",
  "note": "",
  "itds": [
    {
      "id": "paitd-006-tag-registry",
      "title": "Governed Tags Are Report Slices Only",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-006-tag-registry"
    }
  ]
}
storage
{
  "kind": "alpha_extend_table",
  "source": "alpha.object_tag.object_kind",
  "storageRule": "Stored only in alpha.object_tag.object_kind; allowed because it is a true Alpha extension and not a copied 1EdTech field.",
  "writeRoute": "Write alpha.object_tag rows only; object_id is a relationship reference to a live public object, not a copied 1EdTech field."
}

object_id

title
Object Id
type
TEXT
publicApi
string
nullability
Required.
required
Yes
range
1 to 255 printable characters.
meaning
Tagged object id.
constraints
Must reference the object named by object_kind in the same tenant.
relationship
Polymorphic relationship constrained by object_kind and tag_definition.anchor.
invalidWhen
References a missing object, crosses tenant, or points at a value that should be a real foreign key.
edgeCases
For anchor=nwea_account, object_id must identify a district place with nwea_district_id. For anchor=school, object_id must identify a school place.
example
place_alpha_ms
pii
Identifier
allowedValues
[]
provenance
{
  "changeType": "extend",
  "sourceType": "alpha_extend_table",
  "source": "alpha.object_tag.object_id",
  "sourceAnchor": null,
  "aliasMapField": "object_tag.object_id",
  "label": "Alpha extend",
  "note": "",
  "itds": [
    {
      "id": "paitd-006-tag-registry",
      "title": "Governed Tags Are Report Slices Only",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-006-tag-registry"
    },
    {
      "id": "paitd-003-place-nwea-boundary",
      "title": "Place Is The Plain Alias For OneRoster Org And District Is The NWEA Account",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-003-place-nwea-boundary"
    }
  ]
}
storage
{
  "kind": "alpha_extend_table",
  "source": "alpha.object_tag.object_id",
  "storageRule": "Stored only in alpha.object_tag.object_id; allowed because it is a true Alpha extension and not a copied 1EdTech field.",
  "writeRoute": "Write alpha.object_tag rows only; object_id is a relationship reference to a live public object, not a copied 1EdTech field."
}

tag_key

title
Tag Key
type
TEXT
publicApi
string
nullability
Required.
required
Yes
range
Existing tag_definition.tag_key for this tenant and compatible anchor.
meaning
Registered tag key.
constraints
Must have a tag_definition row before assignment.
relationship
References alpha.tag_definition.tag_key with the compatible anchor.
invalidWhen
Unregistered, misspelled, or used to create a free-form metadata bag.
edgeCases
A tag_key can be legal for one anchor and illegal for another.
example
level
pii
No
allowedValues
[]
provenance
{
  "changeType": "extend",
  "sourceType": "alpha_extend_table",
  "source": "alpha.object_tag.tag_key",
  "sourceAnchor": null,
  "aliasMapField": "object_tag.tag_key",
  "label": "Alpha extend",
  "note": "",
  "itds": [
    {
      "id": "paitd-006-tag-registry",
      "title": "Governed Tags Are Report Slices Only",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-006-tag-registry"
    }
  ]
}
storage
{
  "kind": "alpha_extend_table",
  "source": "alpha.object_tag.tag_key",
  "storageRule": "Stored only in alpha.object_tag.tag_key; allowed because it is a true Alpha extension and not a copied 1EdTech field.",
  "writeRoute": "Write alpha.object_tag rows only; object_id is a relationship reference to a live public object, not a copied 1EdTech field."
}

tag_value

title
Tag Value
type
TEXT
publicApi
string
nullability
Required.
required
Yes
range
One of tag_definition.allowed_values for the tag_key and anchor.
meaning
Allowed value from tag_definition.
constraints
Must exactly match a governed allowed value. It cannot be a secret, foreign key, or computed input.
relationship
Validated against alpha.tag_definition.allowed_values.
invalidWhen
Free text, unregistered value, contains secret material, or used as a relationship target.
edgeCases
For modality, only physical and virtual are valid; hybrid is invalid. For brand, segment, and level, use the closed values published in this dictionary's enum catalog.
example
MS
pii
No
allowedValues
[]
provenance
{
  "changeType": "extend",
  "sourceType": "alpha_extend_table",
  "source": "alpha.object_tag.tag_value",
  "sourceAnchor": null,
  "aliasMapField": "object_tag.tag_value",
  "label": "Alpha extend",
  "note": "",
  "itds": [
    {
      "id": "paitd-006-tag-registry",
      "title": "Governed Tags Are Report Slices Only",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-006-tag-registry"
    },
    {
      "id": "paitd-003-place-nwea-boundary",
      "title": "Place Is The Plain Alias For OneRoster Org And District Is The NWEA Account",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-003-place-nwea-boundary"
    }
  ]
}
storage
{
  "kind": "alpha_extend_table",
  "source": "alpha.object_tag.tag_value",
  "storageRule": "Stored only in alpha.object_tag.tag_value; allowed because it is a true Alpha extension and not a copied 1EdTech field.",
  "writeRoute": "Write alpha.object_tag rows only; object_id is a relationship reference to a live public object, not a copied 1EdTech field."
}

Additional contract data

conventions
[
  "Every public Alpha field is a rename, restriction, extension, inherited platform field, or explicit cut against the approved OneRoster or Ed-Fi 1EdTech data dictionaries.",
  "Alpha renamed/cut/restricted objects are public views over the 1EdTech base; only Alpha extension fields get Alpha tables.",
  "No alpha table column may carry a OneRoster or Ed-Fi source. If a field maps to either upstream, it must be documented as a view column.",
  "Relationships are real columns and ids, never tags.",
  "Reporting-blocking enums reality, alpha_level, grade_level, brand, segment, modality, and level are closed value sets published here with write-time alias folds and live production validation evidence.",
  "Every ordinary report read defaults to reality=real for both people and places unless the caller explicitly asks for test or synthetic data.",
  "Point-in-time membership, staff-assignment, program-participation, alpha-level history, and age-grade history reads require asOfDate and use the begin_date/end_date/is_time_locatable rule.",
  "Ed-Fi-backed views select canonical records only, hide is_deleted rows by default, exclude drafts, resolve descriptors through edfi.descriptor_code, and join person/place references through OneRoster sourcedIds.",
  "Secrets never appear in roster fields, tags, logs, public examples, or Problem details.",
  "Role-specific views such as students, guides, and staff are filters over person plus memberships; guardian, staff-assignment, and program-participation facts are Ed-Fi-backed views, not Alpha storage tables.",
  "Mastery, test scores, gradebook rollups, activity events, content effectiveness, and curriculum graph facts are out of module."
]
storageModel
{
  "rule": "Alpha is views over the OneRoster and Ed-Fi 1EdTech bases for rename/cut/restrict changes; only extend changes add Alpha-owned tables containing new Alpha fields plus foreign keys to base rows.",
  "itd": {
    "id": "paitd-011-storage-model",
    "title": "Alpha Storage Is Views Over OneRoster Plus Extension Tables",
    "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-011-storage-model"
  },
  "forbiddenAlphaTables": [
    "alpha.person",
    "alpha.place",
    "alpha.place_membership",
    "alpha.class_membership",
    "alpha.school_period",
    "alpha.person_sensitive_profile",
    "alpha.guardian_view",
    "alpha.guardian_relationship_view",
    "alpha.staff_assignment_view",
    "alpha.program_participation_view"
  ],
  "forbiddenTables": [
    "alpha.person",
    "alpha.place",
    "alpha.place_membership",
    "alpha.class_membership",
    "alpha.school_period",
    "alpha.person_sensitive_profile",
    "alpha.guardian_view",
    "alpha.guardian_relationship_view",
    "alpha.staff_assignment_view",
    "alpha.program_participation_view"
  ],
  "allowedExtensionTables": [
    "alpha.person_ext",
    "alpha.place_ext",
    "alpha.app_credential",
    "alpha.tag_definition",
    "alpha.object_tag",
    "alpha.alpha_level_history",
    "alpha.age_grade_history"
  ],
  "storageContract": [
    {
      "alphaObject": "person",
      "publicSurface": "alpha.person",
      "upstreamModule": "oneroster/1edtech",
      "baseSource": "oneroster.users",
      "baseView": "alpha.person_base",
      "extensionTables": [
        "alpha.person_ext"
      ],
      "coreWriteRoute": "Route sourced-field writes to the OneRoster 1EdTech users surface.",
      "extensionWriteRoute": "Write admission_date, exit_date, age_grade, and reality to alpha.person_ext after the base person exists.",
      "requiredShape": "CREATE VIEW over the OneRoster 1EdTech base; no Alpha table may store sourced OneRoster columns. Wave 2 adds reality as an Alpha extension field, not a copied OneRoster column."
    },
    {
      "alphaObject": "place",
      "publicSurface": "alpha.place",
      "upstreamModule": "oneroster/1edtech",
      "baseSource": "oneroster.orgs",
      "baseView": "alpha.place_base",
      "extensionTables": [
        "alpha.place_ext",
        "alpha.object_tag"
      ],
      "coreWriteRoute": "Route sourced-field writes to the OneRoster 1EdTech orgs surface.",
      "extensionWriteRoute": "Write nwea_district_id and reality to alpha.place_ext, and report-slice tags to alpha.object_tag, after the base place exists.",
      "requiredShape": "CREATE VIEW over the OneRoster 1EdTech base; no Alpha table may store sourced OneRoster columns. Wave 2 adds reality as an Alpha extension field, not a copied OneRoster column."
    },
    {
      "alphaObject": "place_membership",
      "publicSurface": "alpha.place_membership",
      "upstreamModule": "oneroster/1edtech",
      "baseSource": "oneroster.roles",
      "baseView": "alpha.place_membership_base",
      "extensionTables": [],
      "coreWriteRoute": "Route all writes to the OneRoster 1EdTech roles surface.",
      "extensionWriteRoute": "None. is_time_locatable is a view expression, not stored Alpha state.",
      "requiredShape": "CREATE VIEW over the OneRoster 1EdTech base; no Alpha table may store sourced OneRoster columns."
    },
    {
      "alphaObject": "class_membership",
      "publicSurface": "alpha.class_membership",
      "upstreamModule": "oneroster/1edtech",
      "baseSource": "oneroster.enrollments",
      "baseView": "alpha.class_membership_base",
      "extensionTables": [],
      "coreWriteRoute": "Route all writes to the OneRoster 1EdTech enrollments surface.",
      "extensionWriteRoute": "None. is_time_locatable is a view expression, not stored Alpha state.",
      "requiredShape": "CREATE VIEW over the OneRoster 1EdTech base; no Alpha table may store sourced OneRoster columns."
    },
    {
      "alphaObject": "school_period",
      "publicSurface": "alpha.school_period",
      "upstreamModule": "oneroster/1edtech",
      "baseSource": "oneroster.academic_sessions",
      "baseView": "alpha.school_period_base",
      "extensionTables": [],
      "coreWriteRoute": "Route all writes to the OneRoster 1EdTech academic_sessions surface.",
      "extensionWriteRoute": "None.",
      "requiredShape": "CREATE VIEW over the OneRoster 1EdTech base; no Alpha table may store sourced OneRoster columns."
    },
    {
      "alphaObject": "person_sensitive_profile",
      "publicSurface": "alpha.person_sensitive_profile",
      "upstreamModule": "oneroster/1edtech",
      "baseSource": "oneroster.demographics",
      "baseView": "alpha.person_sensitive_profile_base",
      "extensionTables": [],
      "coreWriteRoute": "Route sourced-field writes to the OneRoster 1EdTech demographics surface.",
      "extensionWriteRoute": "None. Authorization and redaction are API/view restrictions, not copied storage.",
      "requiredShape": "CREATE VIEW over the OneRoster 1EdTech base; no Alpha table may store sourced OneRoster columns."
    },
    {
      "alphaObject": "guardian",
      "publicSurface": "alpha.guardian_view",
      "upstreamModule": "ed_fi/1edtech",
      "baseSource": "edfi.canonical_record(resource_name=Contact)",
      "baseView": "alpha.guardian_base_view",
      "extensionTables": [],
      "coreWriteRoute": "Route all sourced-field writes to the Ed-Fi 1EdTech Contact collection; Alpha exposes only canonical, non-deleted Contact records.",
      "extensionWriteRoute": "None. Guardian facts that originate in Ed-Fi stay in edfi.canonical_record and descriptor_code-backed views.",
      "requiredShape": "CREATE VIEW over edfi.canonical_record; filter resource_name/collection_route, tenant_id, is_deleted=false, canonical state, descriptor_code resolution, and OneRoster sourcedId joins. No Alpha table may store sourced Ed-Fi columns."
    },
    {
      "alphaObject": "guardian_relationship",
      "publicSurface": "alpha.guardian_relationship_view",
      "upstreamModule": "ed_fi/1edtech",
      "baseSource": "edfi.canonical_record(resource_name=StudentContactAssociation)",
      "baseView": "alpha.guardian_relationship_base_view",
      "extensionTables": [],
      "coreWriteRoute": "Route all sourced-field writes to the Ed-Fi 1EdTech StudentContactAssociation collection; Alpha joins to OneRoster users only by platform3 sourcedId references.",
      "extensionWriteRoute": "None. Relationship descriptors and flags remain Ed-Fi canonical data.",
      "requiredShape": "CREATE VIEW over edfi.canonical_record; filter resource_name/collection_route, tenant_id, is_deleted=false, canonical state, descriptor_code resolution, and OneRoster sourcedId joins. No Alpha table may store sourced Ed-Fi columns."
    },
    {
      "alphaObject": "staff_assignment",
      "publicSurface": "alpha.staff_assignment_view",
      "upstreamModule": "ed_fi/1edtech",
      "baseSource": "edfi.canonical_record(resource_name=StaffEducationOrganizationAssignmentAssociation)",
      "baseView": "alpha.staff_assignment_base_view",
      "extensionTables": [],
      "coreWriteRoute": "Route all sourced-field writes to the Ed-Fi 1EdTech StaffEducationOrganizationAssignmentAssociation collection; OneRoster users and orgs remain the roster identity boundary.",
      "extensionWriteRoute": "None. Staff assignment facts from Ed-Fi stay in edfi.canonical_record and descriptor_code-backed views.",
      "requiredShape": "CREATE VIEW over edfi.canonical_record; filter resource_name/collection_route, tenant_id, is_deleted=false, canonical state, descriptor_code resolution, and OneRoster sourcedId joins. No Alpha table may store sourced Ed-Fi columns."
    },
    {
      "alphaObject": "program_participation",
      "publicSurface": "alpha.program_participation_view",
      "upstreamModule": "ed_fi/1edtech",
      "baseSource": "edfi.canonical_record(resource_name in GeneralStudentProgramAssociation, StudentProgramAssociation, and specializations)",
      "baseView": "alpha.program_participation_base_view",
      "extensionTables": [],
      "coreWriteRoute": "Route all sourced-field writes to the Ed-Fi 1EdTech Program and StudentProgramAssociation-family collections; Alpha joins student and place ids through OneRoster sourcedIds.",
      "extensionWriteRoute": "None. Program participation facts from Ed-Fi stay in edfi.canonical_record and descriptor_code-backed views.",
      "requiredShape": "CREATE VIEW over edfi.canonical_record; filter resource_name/collection_route, tenant_id, is_deleted=false, canonical state, descriptor_code resolution, and OneRoster sourcedId joins. No Alpha table may store sourced Ed-Fi columns."
    },
    {
      "alphaObject": "app_credential",
      "publicSurface": "alpha.app_credential",
      "upstreamModule": "oneroster/1edtech",
      "baseSource": null,
      "baseView": null,
      "extensionTables": [
        "alpha.app_credential"
      ],
      "coreWriteRoute": "None.",
      "extensionWriteRoute": "Write alpha.app_credential rows with a student_sourced_id foreign key to oneroster.users.",
      "requiredShape": "CREATE TABLE is allowed because this is a pure Alpha extension."
    },
    {
      "alphaObject": "tag_definition",
      "publicSurface": "alpha.tag_definition",
      "upstreamModule": "oneroster/1edtech",
      "baseSource": null,
      "baseView": null,
      "extensionTables": [
        "alpha.tag_definition"
      ],
      "coreWriteRoute": "None.",
      "extensionWriteRoute": "Write alpha.tag_definition rows only; no 1EdTech columns are copied.",
      "requiredShape": "CREATE TABLE is allowed because this is a pure Alpha extension."
    },
    {
      "alphaObject": "object_tag",
      "publicSurface": "alpha.object_tag",
      "upstreamModule": "oneroster/1edtech",
      "baseSource": null,
      "baseView": null,
      "extensionTables": [
        "alpha.object_tag"
      ],
      "coreWriteRoute": "None.",
      "extensionWriteRoute": "Write alpha.object_tag rows only; object_id is a relationship reference to a live public object, not a copied 1EdTech field.",
      "requiredShape": "CREATE TABLE is allowed because this is a pure Alpha extension."
    },
    {
      "alphaObject": "alpha_level_history",
      "publicSurface": "alpha.alpha_level_history",
      "upstreamModule": "oneroster/1edtech",
      "baseSource": null,
      "baseView": null,
      "extensionTables": [
        "alpha.alpha_level_history"
      ],
      "coreWriteRoute": "None.",
      "extensionWriteRoute": "Write effective-dated alpha.alpha_level_history rows with a person_id foreign key to the base person, after the base person exists. No OneRoster or Ed-Fi column is copied.",
      "requiredShape": "CREATE TABLE is allowed because this is a pure Alpha extension."
    },
    {
      "alphaObject": "age_grade_history",
      "publicSurface": "alpha.age_grade_history",
      "upstreamModule": "oneroster/1edtech",
      "baseSource": null,
      "baseView": null,
      "extensionTables": [
        "alpha.age_grade_history"
      ],
      "coreWriteRoute": "None.",
      "extensionWriteRoute": "Write effective-dated alpha.age_grade_history rows with a person_id foreign key to the base person, after the base person exists. No OneRoster or Ed-Fi column is copied.",
      "requiredShape": "CREATE TABLE is allowed because this is a pure Alpha extension."
    }
  ]
}
cutsAndRestrictions
[
  {
    "source": "oneroster.users.password",
    "alphaDisposition": "cut",
    "reason": "Secrets are never roster fields or tags. Alpha uses alpha.app_credential.secret_ref instead.",
    "itd": {
      "id": "paitd-008-app-credentials",
      "title": "App Credentials Use Vault References, Never Roster Password Fields",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-008-app-credentials"
    },
    "invalidIf": "Any Alpha person response, tag, log, example, or Problem contains a password or plaintext secret."
  },
  {
    "source": "oneroster.user_profiles.password",
    "alphaDisposition": "cut",
    "reason": "User profile credentials are operational secrets, not roster facts.",
    "itd": {
      "id": "paitd-008-app-credentials",
      "title": "App Credentials Use Vault References, Never Roster Password Fields",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-008-app-credentials"
    },
    "invalidIf": "The value appears outside the managed vault or is exposed through an Alpha API."
  },
  {
    "source": "oneroster.user_profiles.*",
    "alphaDisposition": "restrict",
    "reason": "Profile context can exist in OneRoster provenance, but ordinary Alpha roster reads expose only non-secret profile references and app credential status.",
    "itd": {
      "id": "paitd-009-sensitive-profile-privacy",
      "title": "Sensitive Profiles Are Restricted, Not Default Roster Fields",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-009-sensitive-profile-privacy"
    },
    "invalidIf": "Vendor username, credential type, or profile description leaks into ordinary person or membership list responses."
  },
  {
    "source": "oneroster.demographics.*",
    "alphaDisposition": "restrict",
    "reason": "Sensitive demographic fields move behind alpha.person_sensitive_profile with explicit scopes and audit.",
    "itd": {
      "id": "paitd-009-sensitive-profile-privacy",
      "title": "Sensitive Profiles Are Restricted, Not Default Roster Fields",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-009-sensitive-profile-privacy"
    },
    "invalidIf": "Birth date, sex, race/ethnicity, birth location, or residence status appears in ordinary people lists."
  },
  {
    "source": "oneroster.users.user_ids / identifier / user_master_identifier",
    "alphaDisposition": "cut from ordinary person",
    "reason": "Alpha identity is the plain TimeBack person_id plus authorized contact fields. Extra external identifiers stay in the 1EdTech surface unless a future Alpha ITD ships them.",
    "itd": {
      "id": "paitd-002-person-vocabulary",
      "title": "Person Is The Plain Alias For OneRoster User",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-002-person-vocabulary"
    },
    "invalidIf": "A consumer has to choose between competing person identifiers for ordinary Alpha joins."
  },
  {
    "source": "oneroster.users.preferred_middle_name / pronouns",
    "alphaDisposition": "not public in this attempt",
    "reason": "The approved alias map does not publish these as public Alpha fields. They remain available in the 1EdTech surface until a future People & Orgs architecture ITD adds a privacy-scoped Alpha alias.",
    "itd": {
      "id": "paitd-010-alias-map-contract",
      "title": "Alias Map Is A Generated Architecture Artifact",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-010-alias-map-contract"
    },
    "invalidIf": "A downstream artifact exposes an unmapped public Alpha field."
  },
  {
    "source": "oneroster.users.import_batch_id",
    "alphaDisposition": "cut from Alpha public view",
    "reason": "Import batch provenance stays on the 1EdTech OneRoster ingest rows. Alpha exposes person source_updated_at and platform collection sync controls; consumers must not join roster answers by import batch.",
    "itd": {
      "id": "paitd-010-alias-map-contract",
      "title": "Alias Map Is A Generated Architecture Artifact",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-010-alias-map-contract"
    },
    "invalidIf": "A raw Alpha person query requires import_batch_id or treats one import batch as the roster truth for an as-of-date answer."
  },
  {
    "source": "oneroster.orgs.import_batch_id",
    "alphaDisposition": "cut from Alpha public view",
    "reason": "Import batch provenance stays on the 1EdTech OneRoster ingest rows. Alpha exposes place source_updated_at and platform collection sync controls; consumers must not group schools or districts by ingest batch.",
    "itd": {
      "id": "paitd-010-alias-map-contract",
      "title": "Alias Map Is A Generated Architecture Artifact",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-010-alias-map-contract"
    },
    "invalidIf": "A raw Alpha place query requires import_batch_id or uses it as a tenant, district, brand, modality, or school-period boundary."
  },
  {
    "source": "oneroster.roles.import_batch_id",
    "alphaDisposition": "cut from Alpha public view",
    "reason": "Import batch provenance stays on the 1EdTech role ingest rows. Alpha place_membership answers use person_id, place_id, role_kind, begin_date, end_date, and is_time_locatable instead.",
    "itd": {
      "id": "paitd-004-point-in-time-memberships",
      "title": "Memberships Are Effective-Dated And Answered By AsOfDate",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-004-point-in-time-memberships"
    },
    "invalidIf": "A raw Alpha place-membership query filters by import_batch_id instead of the documented point-in-time membership rule."
  },
  {
    "source": "oneroster.enrollments.import_batch_id",
    "alphaDisposition": "cut from Alpha public view",
    "reason": "Import batch provenance stays on the 1EdTech enrollment ingest rows. Alpha class_membership answers use person_id, school_id, learning_group_id, role_kind, begin_date, end_date, and is_time_locatable instead.",
    "itd": {
      "id": "paitd-004-point-in-time-memberships",
      "title": "Memberships Are Effective-Dated And Answered By AsOfDate",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-004-point-in-time-memberships"
    },
    "invalidIf": "A raw Alpha class-membership query filters by import_batch_id instead of tenant, school, learning_group, role, and as-of-date."
  },
  {
    "source": "oneroster.academic_sessions.import_batch_id",
    "alphaDisposition": "cut from Alpha public view",
    "reason": "Import batch provenance stays on the 1EdTech academic-session ingest rows. Alpha school_period exposes typed period fields and source_updated_at for sync.",
    "itd": {
      "id": "paitd-005-school-periods",
      "title": "School Period Is The Plain Alias For Academic Session",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-005-school-periods"
    },
    "invalidIf": "A raw Alpha school-period query uses import_batch_id to infer school-year or term membership."
  },
  {
    "source": "oneroster.demographics.import_batch_id",
    "alphaDisposition": "cut from Alpha public view",
    "reason": "Import batch provenance stays on the 1EdTech demographics ingest rows. Alpha sensitive-profile access is scope-gated and must not expose ingest-batch identifiers.",
    "itd": {
      "id": "paitd-009-sensitive-profile-privacy",
      "title": "Sensitive Profiles Are Restricted, Not Default Roster Fields",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-009-sensitive-profile-privacy"
    },
    "invalidIf": "An Alpha sensitive-profile read or migration exposes import_batch_id outside an authorized 1EdTech audit path."
  },
  {
    "source": "oneroster.user_profiles.import_batch_id",
    "alphaDisposition": "cut from Alpha public view",
    "reason": "Import batch provenance stays on the 1EdTech user-profile ingest rows. Alpha cuts profile secrets and exposes only app_credential secret references.",
    "itd": {
      "id": "paitd-008-app-credentials",
      "title": "App Credentials Use Vault References, Never Roster Password Fields",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-008-app-credentials"
    },
    "invalidIf": "An Alpha app credential or profile query requires OneRoster user_profile import_batch_id."
  },
  {
    "source": "oneroster.roles.status",
    "alphaDisposition": "cut",
    "reason": "The approved alias map does not publish role-row lifecycle status on alpha.place_membership. Alpha answers active membership from begin_date, end_date, and is_time_locatable; OneRoster delta lifecycle remains on the 1EdTech roles surface for audit.",
    "itd": {
      "id": "paitd-004-point-in-time-memberships",
      "title": "Memberships Are Effective-Dated And Answered By AsOfDate",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-004-point-in-time-memberships"
    },
    "invalidIf": "A raw Alpha roster query treats role status as the active-as-of rule or a downstream artifact exposes an unmapped place_membership source_status field."
  },
  {
    "source": "oneroster.roles.date_last_modified",
    "alphaDisposition": "cut",
    "reason": "The approved alias map does not publish a roles modified timestamp on alpha.place_membership. Consumers use documented membership date windows for as-of answers and platform/API collection clocks for sync.",
    "itd": {
      "id": "paitd-103-query-model",
      "title": "API Axis: Query Model",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-103-query-model"
    },
    "invalidIf": "A downstream artifact requires alpha.place_membership.source_updated_at without a new architecture alias-map decision."
  },
  {
    "source": "oneroster.enrollments.status",
    "alphaDisposition": "cut",
    "reason": "The approved alias map does not publish enrollment-row lifecycle status on alpha.class_membership. Alpha answers active class membership from begin_date, end_date, and is_time_locatable; OneRoster delta lifecycle remains on the 1EdTech enrollments surface for audit.",
    "itd": {
      "id": "paitd-004-point-in-time-memberships",
      "title": "Memberships Are Effective-Dated And Answered By AsOfDate",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-004-point-in-time-memberships"
    },
    "invalidIf": "A raw Alpha class roster query treats enrollment status as the active-as-of rule or a downstream artifact exposes an unmapped class_membership source_status field."
  },
  {
    "source": "oneroster.enrollments.date_last_modified",
    "alphaDisposition": "cut",
    "reason": "The approved alias map does not publish an enrollments modified timestamp on alpha.class_membership. Consumers use documented membership date windows for as-of answers and platform/API collection clocks for sync.",
    "itd": {
      "id": "paitd-103-query-model",
      "title": "API Axis: Query Model",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-103-query-model"
    },
    "invalidIf": "A downstream artifact requires alpha.class_membership.source_updated_at without a new architecture alias-map decision."
  },
  {
    "source": "OneRoster classes, courses, resources, lineItems, results, categories, scoreScales",
    "alphaDisposition": "cut by module boundary",
    "reason": "People & Orgs owns who, where, and as-of-date belonging. Content, Results, Curriculum, and Events own the adjacent facts.",
    "itd": {
      "id": "paitd-001-module-boundary",
      "title": "People & Orgs Owns Who, Where, And As-Of-Date Belonging",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-001-module-boundary"
    },
    "invalidIf": "This module stores mastery, test scores, activity events, content effectiveness, curriculum graph, or gradebook rollups."
  },
  {
    "source": "Ed-Fi attendance, discipline, transcripts, health, finance, credentials, evaluation, and full HR/employment records",
    "alphaDisposition": "cut by module boundary",
    "reason": "Only Ed-Fi records that say who someone is or where they belong are exposed here: guardian, guardian_relationship, staff_assignment, and program_participation. Other Ed-Fi domains remain on Ed-Fi, Results, Policy, or other owning surfaces.",
    "itd": {
      "id": "paitd-012-edfi-second-upstream",
      "title": "Ed-Fi Administrative Records Are A Second View-Only Upstream",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-012-edfi-second-upstream"
    },
    "invalidIf": "A People & Orgs row stores attendance, discipline, transcript, staff evaluation, finance, service effectiveness, eligibility, or outcome facts."
  },
  {
    "source": "edfi.draft_record and edfi.canonical_record.is_deleted=true",
    "alphaDisposition": "restrict from ordinary Alpha reads",
    "reason": "Drafts are UI-recovery state and deleted canonical records are audit/retention history. Ordinary Alpha views expose only canonical, non-deleted Ed-Fi facts.",
    "itd": {
      "id": "paitd-012-edfi-second-upstream",
      "title": "Ed-Fi Administrative Records Are A Second View-Only Upstream",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-012-edfi-second-upstream"
    },
    "invalidIf": "A normal guardian, staff_assignment, or program_participation query returns draft records or is_deleted=true rows without an authorized audit/admin path."
  },
  {
    "source": "Ed-Fi descriptor tables for Relation, StaffClassification, ProgramType, and ProgramParticipationStatus",
    "alphaDisposition": "restrict to resolved descriptor values",
    "reason": "The surface resolves descriptors through edfi.descriptor_code so consumers never ship descriptor maps, parse titles, or use free-form tags.",
    "itd": {
      "id": "paitd-012-edfi-second-upstream",
      "title": "Ed-Fi Administrative Records Are A Second View-Only Upstream",
      "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-012-edfi-second-upstream"
    },
    "invalidIf": "A skill pack or raw-query recipe carries its own descriptor table or parses descriptor names in client code."
  }
]
apiControls
{
  "queryParameters": [
    {
      "name": "asOfDate",
      "type": "ISO 8601 date",
      "required": "Required for active-as-of membership views; optional on raw historical scans.",
      "meaning": "The date the caller wants the roster answer for.",
      "constraints": "Membership rows are active when begin_date is not null, asOfDate >= begin_date, and end_date is null or asOfDate < end_date.",
      "invalidWhen": "Missing from active membership views, malformed, or replaced by currentOnly.",
      "itds": [
        {
          "id": "paitd-004-point-in-time-memberships",
          "title": "Memberships Are Effective-Dated And Answered By AsOfDate",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-004-point-in-time-memberships"
        },
        {
          "id": "paitd-103-query-model",
          "title": "API Axis: Query Model",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-103-query-model"
        }
      ]
    },
    {
      "name": "modifiedSince",
      "type": "ISO 8601 datetime",
      "required": "Optional",
      "meaning": "Requests rows changed after the supplied instant for polling-based sync.",
      "constraints": "Uses the collection's documented source_updated_at, edfi.canonical_record.updated_at, or platform updated_at clock. Unsupported clocks return a typed 400 Problem.",
      "invalidWhen": "Malformed or combined with a cursor in a way the endpoint does not document.",
      "itds": [
        {
          "id": "paitd-103-query-model",
          "title": "API Axis: Query Model",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-103-query-model"
        },
        {
          "id": "paitd-107-eventing-model",
          "title": "API Axis: Eventing Model",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-107-eventing-model"
        }
      ]
    },
    {
      "name": "includeDeleted",
      "type": "boolean",
      "required": "No; ordinary callers cannot set it.",
      "meaning": "Requests Ed-Fi soft-deleted canonical records for an authorized audit/admin path.",
      "constraints": "Only valid for privileged Ed-Fi-backed guardian, guardian_relationship, staff_assignment, and program_participation audit reads. Ordinary Alpha reads behave as includeDeleted=false.",
      "invalidWhen": "Used without audit/admin scope, used on OneRoster-backed collections, or used to bypass privacy retention rules.",
      "itds": [
        {
          "id": "paitd-012-edfi-second-upstream",
          "title": "Ed-Fi Administrative Records Are A Second View-Only Upstream",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-012-edfi-second-upstream"
        },
        {
          "id": "paitd-111-privacy-retention",
          "title": "API Axis: Privacy / Retention",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-111-privacy-retention"
        }
      ]
    },
    {
      "name": "filter",
      "type": "string",
      "required": "Optional",
      "meaning": "Narrows a list to the documented filters named on each table.",
      "constraints": "Unsupported fields or operators return people_orgs:unsupported_query_parameter.",
      "invalidWhen": "The parameter silently does nothing or accepts undocumented field names.",
      "itds": [
        {
          "id": "paitd-103-query-model",
          "title": "API Axis: Query Model",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-103-query-model"
        },
        {
          "id": "paitd-108-error-envelope",
          "title": "API Axis: Error Envelope",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-108-error-envelope"
        }
      ]
    },
    {
      "name": "reality",
      "type": "real | test | synthetic",
      "required": "Optional; defaults to real on ordinary report reads.",
      "meaning": "Explicitly selects which reality classification to include. Omit it for default customer reports, which include real rows only.",
      "constraints": "Supported on people, places, active-student, history, enrollment-anchor, and guide-inverse reads. Including test or synthetic rows requires an authorized report/debug scope.",
      "invalidWhen": "Missing from a raw SQL report filter, set to an unsupported value, or implemented as name/campus string matching.",
      "itds": [
        {
          "id": "paitd-017-reality-flag",
          "title": "Reality Is A Typed Closed Flag On Person And Place, Set At Write Time",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-017-reality-flag"
        },
        {
          "id": "paitd-103-query-model",
          "title": "API Axis: Query Model",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-103-query-model"
        },
        {
          "id": "paitd-111-privacy-retention",
          "title": "API Axis: Privacy / Retention",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-111-privacy-retention"
        }
      ]
    },
    {
      "name": "sort",
      "type": "string",
      "required": "Optional",
      "meaning": "Orders list results by the documented sort keys named on each table.",
      "constraints": "Unsupported sort keys return a typed 400 Problem.",
      "invalidWhen": "Sorts by a field not documented as sortable.",
      "itds": [
        {
          "id": "paitd-103-query-model",
          "title": "API Axis: Query Model",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-103-query-model"
        }
      ]
    },
    {
      "name": "cursor",
      "type": "opaque string",
      "required": "Optional",
      "meaning": "Continues a paged list from a server-provided token.",
      "constraints": "Opaque, tenant-scoped, and not client-generated.",
      "invalidWhen": "Parsed by the client or reused across tenants.",
      "itds": [
        {
          "id": "paitd-103-query-model",
          "title": "API Axis: Query Model",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-103-query-model"
        }
      ]
    },
    {
      "name": "limit",
      "type": "integer",
      "required": "Optional",
      "meaning": "Caps returned rows.",
      "constraints": "Positive integer within the endpoint maximum.",
      "invalidWhen": "Zero, negative, non-integer, or above maximum.",
      "itds": [
        {
          "id": "paitd-103-query-model",
          "title": "API Axis: Query Model",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-103-query-model"
        }
      ]
    }
  ],
  "headers": [
    {
      "name": "Authorization",
      "type": "Bearer JWT",
      "required": "Required except demo token mint.",
      "meaning": "Authenticates the caller and supplies tenant and relationship-scoped claims.",
      "constraints": "JWT must include tenant_id or tenantId, role/scopes, and relationship claims where needed.",
      "invalidWhen": "Missing, expired, wrong tenant, or too broad for sensitive profile/credential reads.",
      "itds": [
        {
          "id": "paitd-106-auth-shape",
          "title": "API Axis: Auth Shape",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-106-auth-shape"
        },
        {
          "id": "paitd-109-tenant-routing",
          "title": "API Axis: Tenant Routing",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-109-tenant-routing"
        }
      ]
    },
    {
      "name": "Idempotency-Key",
      "type": "ASCII string",
      "required": "Required on retryable writes.",
      "meaning": "Scopes replay protection for create, update, delete, and rotation commands.",
      "constraints": "Same key and same canonical request hash replays; same key and different request hash returns 409.",
      "invalidWhen": "Missing on retryable writes or reused for a different request body.",
      "itds": [
        {
          "id": "paitd-105-idempotency-model",
          "title": "API Axis: Idempotency Model",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-105-idempotency-model"
        }
      ]
    },
    {
      "name": "ETag",
      "type": "HTTP entity tag",
      "required": "Returned on mutable resource reads.",
      "meaning": "Validator the client stores before update or delete.",
      "constraints": "Changes when the customer-visible representation changes.",
      "invalidWhen": "Missing from mutable reads.",
      "itds": [
        {
          "id": "paitd-104-concurrency-model",
          "title": "API Axis: Concurrency Model",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-104-concurrency-model"
        }
      ]
    },
    {
      "name": "If-Match",
      "type": "HTTP entity tag",
      "required": "Required on PUT, PATCH, and DELETE that can overwrite state.",
      "meaning": "Prevents lost updates.",
      "constraints": "Missing precondition returns 428; stale validators return 412 or a documented conflict Problem.",
      "invalidWhen": "Mutation proceeds without a required matching validator.",
      "itds": [
        {
          "id": "paitd-104-concurrency-model",
          "title": "API Axis: Concurrency Model",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-104-concurrency-model"
        }
      ]
    }
  ],
  "namedQueries": [
    {
      "name": "alphaLevel(student, date)",
      "endpoint": "/people/{personId}/alpha_level?asOfDate=YYYY-MM-DD",
      "resultShape": "{ person_id, alpha_level, begin_date, end_date, is_time_locatable }",
      "rawDbRule": "Read alpha.alpha_level_history for the person with is_time_locatable=true, begin_date <= :as_of_date, and (end_date is null or :as_of_date < end_date), then join alpha.person and require p.reality='real' for ordinary reports.",
      "invalidWhen": "Answered from one mutable current alpha_level field, parsed from place/class names, or returned without the begin/end null rule.",
      "itds": [
        {
          "id": "paitd-018-over-time-history",
          "title": "Alpha Level And Age Grade Keep Effective-Dated History, Read By AsOfDate",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-018-over-time-history"
        },
        {
          "id": "paitd-017-reality-flag",
          "title": "Reality Is A Typed Closed Flag On Person And Place, Set At Write Time",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-017-reality-flag"
        },
        {
          "id": "paitd-004-point-in-time-memberships",
          "title": "Memberships Are Effective-Dated And Answered By AsOfDate",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-004-point-in-time-memberships"
        },
        {
          "id": "paitd-007-tenure-and-grade-context",
          "title": "Tenure And Grade Context Are Typed Inputs, Not Dashboard Math",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-007-tenure-and-grade-context"
        },
        {
          "id": "paitd-103-query-model",
          "title": "API Axis: Query Model",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-103-query-model"
        }
      ]
    },
    {
      "name": "ageGrade(student, date)",
      "endpoint": "/people/{personId}/age_grade?asOfDate=YYYY-MM-DD",
      "resultShape": "{ person_id, age_grade, begin_date, end_date, is_time_locatable }",
      "rawDbRule": "Read alpha.age_grade_history for the person with is_time_locatable=true, begin_date <= :as_of_date, and (end_date is null or :as_of_date < end_date), then join alpha.person and require p.reality='real' for ordinary reports.",
      "invalidWhen": "Answered only from alpha.person.age_grade when the caller asked for a historical date, parsed from class/test labels, or mixed with Results working grade.",
      "itds": [
        {
          "id": "paitd-018-over-time-history",
          "title": "Alpha Level And Age Grade Keep Effective-Dated History, Read By AsOfDate",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-018-over-time-history"
        },
        {
          "id": "paitd-017-reality-flag",
          "title": "Reality Is A Typed Closed Flag On Person And Place, Set At Write Time",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-017-reality-flag"
        },
        {
          "id": "paitd-004-point-in-time-memberships",
          "title": "Memberships Are Effective-Dated And Answered By AsOfDate",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-004-point-in-time-memberships"
        },
        {
          "id": "paitd-007-tenure-and-grade-context",
          "title": "Tenure And Grade Context Are Typed Inputs, Not Dashboard Math",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-007-tenure-and-grade-context"
        },
        {
          "id": "paitd-103-query-model",
          "title": "API Axis: Query Model",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-103-query-model"
        }
      ]
    },
    {
      "name": "firstEnrolledCourseGrade(student, subject)",
      "endpoint": "/people/{personId}/enrollment_anchors/first_enrolled_course_grade?subject=math",
      "resultShape": "{ person_id, subject, grade_level, first_enrolled_course_grade_level, grade_levels, course_grade_mode, first_enrolled_course_begin_date, evidence_membership_id }",
      "rawDbRule": "Public People & Orgs subject query values are the canonical lowercase Alpha subject ids: math, reading, language, science, vocabulary, writing. Display/source aliases such as Math or Mathematics are folded only at import/write boundaries and are validation errors on public reads. Use the surface-owned query/read function so the subject, course_grade_mode, and course_grade_levels come from Curriculum's typed learning-group/course context and the enrollment date comes from alpha.class_membership. The raw path must not parse subject or grade from class names.",
      "invalidWhen": "Computed by parsing course titles, using the single-grade-only anchor as the general first-course answer, treating multi-grade courses as single-grade, using display/source aliases such as subject=Math on public reads, ignoring begin_date null rows, or selecting a test/synthetic person/place by default.",
      "itds": [
        {
          "id": "paitd-004-point-in-time-memberships",
          "title": "Memberships Are Effective-Dated And Answered By AsOfDate",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-004-point-in-time-memberships"
        },
        {
          "id": "paitd-007-tenure-and-grade-context",
          "title": "Tenure And Grade Context Are Typed Inputs, Not Dashboard Math",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-007-tenure-and-grade-context"
        },
        {
          "id": "paitd-103-query-model",
          "title": "API Axis: Query Model",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-103-query-model"
        }
      ]
    },
    {
      "name": "firstSingleGradeEnrollmentDate(student, subject)",
      "endpoint": "/people/{personId}/enrollment_anchors/first_single_grade?subject=math",
      "resultShape": "{ person_id, subject, grade_level, first_single_grade_enrollment_date, evidence_membership_id }",
      "rawDbRule": "Public People & Orgs subject query values are the canonical lowercase Alpha subject ids: math, reading, language, science, vocabulary, writing. Display/source aliases such as Math or Mathematics are folded only at import/write boundaries and are validation errors on public reads. Use the surface-owned query/read function so the subject and single-grade classification come from Curriculum's typed learning-group/course context and the enrollment dates come from alpha.class_membership. The raw path must not parse subject or grade from class names.",
      "invalidWhen": "Computed by parsing course titles, treating multi-grade courses as single-grade, using display/source aliases such as subject=Math on public reads, ignoring begin_date null rows, or selecting a test/synthetic person/place by default.",
      "itds": [
        {
          "id": "paitd-004-point-in-time-memberships",
          "title": "Memberships Are Effective-Dated And Answered By AsOfDate",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-004-point-in-time-memberships"
        },
        {
          "id": "paitd-007-tenure-and-grade-context",
          "title": "Tenure And Grade Context Are Typed Inputs, Not Dashboard Math",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-007-tenure-and-grade-context"
        },
        {
          "id": "paitd-103-query-model",
          "title": "API Axis: Query Model",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-103-query-model"
        }
      ]
    },
    {
      "name": "studentsForGuide(guide, date)",
      "endpoint": "/guides/{guidePersonId}/students?asOfDate=YYYY-MM-DD",
      "resultShape": "{ guide_person_id, student_person_id, learning_group_id, school_id, begin_date, end_date }[]",
      "rawDbRule": "Join active guide class_membership rows to active student class_membership rows on tenant_id, school_id, and learning_group_id for the same asOfDate; join alpha.person for both sides and alpha.place for the school; require all joined person/place reality values to be real unless explicitly including test/synthetic rows.",
      "invalidWhen": "Implemented as an undocumented two-hop in the client, inferred from staff titles, missing asOfDate, or returning test/synthetic students in ordinary reports.",
      "itds": [
        {
          "id": "paitd-004-point-in-time-memberships",
          "title": "Memberships Are Effective-Dated And Answered By AsOfDate",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-004-point-in-time-memberships"
        },
        {
          "id": "paitd-102-read-shape",
          "title": "API Axis: Read Shape",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-102-read-shape"
        },
        {
          "id": "paitd-103-query-model",
          "title": "API Axis: Query Model",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-103-query-model"
        },
        {
          "id": "paitd-106-auth-shape",
          "title": "API Axis: Auth Shape",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-106-auth-shape"
        }
      ]
    }
  ],
  "problemCategories": [
    {
      "code": "people_orgs:unsupported_query_parameter",
      "status": 400,
      "callerFix": "Remove or replace the query parameter with a documented filter, sort, cursor, limit, modifiedSince, or asOfDate parameter.",
      "itds": [
        {
          "id": "paitd-108-error-envelope",
          "title": "API Axis: Error Envelope",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-108-error-envelope"
        }
      ]
    },
    {
      "code": "people_orgs:validation_failed",
      "status": 400,
      "callerFix": "Fix field type, range, requiredness, enum, or relationship errors named in fieldErrors.",
      "itds": [
        {
          "id": "paitd-108-error-envelope",
          "title": "API Axis: Error Envelope",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-108-error-envelope"
        }
      ]
    },
    {
      "code": "people_orgs:tenant_forbidden",
      "status": 403,
      "callerFix": "Use a token scoped to the tenant and relationship being read.",
      "itds": [
        {
          "id": "paitd-108-error-envelope",
          "title": "API Axis: Error Envelope",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-108-error-envelope"
        }
      ]
    },
    {
      "code": "people_orgs:sensitive_scope_required",
      "status": 403,
      "callerFix": "Request a token with sensitive-profile or credential-status scope and the required relationship claim.",
      "itds": [
        {
          "id": "paitd-108-error-envelope",
          "title": "API Axis: Error Envelope",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-108-error-envelope"
        }
      ]
    },
    {
      "code": "people_orgs:not_found",
      "status": 404,
      "callerFix": "Check tenant scope and id. The response does not reveal cross-tenant existence.",
      "itds": [
        {
          "id": "paitd-108-error-envelope",
          "title": "API Axis: Error Envelope",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-108-error-envelope"
        }
      ]
    },
    {
      "code": "people_orgs:idempotency_conflict",
      "status": 409,
      "callerFix": "Replay the exact original request with the same key or use a new key for a different write.",
      "itds": [
        {
          "id": "paitd-108-error-envelope",
          "title": "API Axis: Error Envelope",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-108-error-envelope"
        }
      ]
    },
    {
      "code": "people_orgs:precondition_required",
      "status": 428,
      "callerFix": "Refetch the resource, keep its ETag, and send If-Match.",
      "itds": [
        {
          "id": "paitd-108-error-envelope",
          "title": "API Axis: Error Envelope",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-108-error-envelope"
        }
      ]
    }
  ]
}
namedQueries
[
  {
    "name": "personLifecycleDates(person)",
    "endpoint": "/people and /people/{personId}",
    "resultShape": "{ person_id, admission_date, exit_date }",
    "rawDbRule": "alpha.person.admission_date and alpha.person.exit_date come only from alpha.person_ext. admission_date is the person-level lifecycle open date; exit_date is the exclusive person-level lifecycle close date; null exit_date means still active/open after admission_date. Membership begin_date/end_date and school_period start_date/end_date are separate interval facts.",
    "invalidWhen": "A consumer or doer treats membership end_date as person exit_date, uses school_period start_date as admission_date, or advertises a generic start_date for person lifecycle.",
    "itds": [
      {
        "id": "paitd-002-person-vocabulary",
        "title": "Person Vocabulary",
        "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture/#paitd-002-person-vocabulary"
      },
      {
        "id": "paitd-007-tenure-and-grade-context",
        "title": "Tenure And Grade Context",
        "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture/#paitd-007-tenure-and-grade-context"
      },
      {
        "id": "paitd-011-storage-model",
        "title": "Storage Model",
        "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture/#paitd-011-storage-model"
      }
    ]
  },
  {
    "name": "alphaLevel(student, date)",
    "endpoint": "/people/{personId}/alpha_level?asOfDate=YYYY-MM-DD",
    "resultShape": "{ person_id, alpha_level, begin_date, end_date, is_time_locatable }",
    "rawDbRule": "Read alpha.alpha_level_history for the person with is_time_locatable=true, begin_date <= :as_of_date, and (end_date is null or :as_of_date < end_date), then join alpha.person and require p.reality='real' for ordinary reports.",
    "invalidWhen": "Answered from one mutable current alpha_level field, parsed from place/class names, or returned without the begin/end null rule.",
    "itds": [
      {
        "id": "paitd-018-over-time-history",
        "title": "Alpha Level And Age Grade Keep Effective-Dated History, Read By AsOfDate",
        "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-018-over-time-history"
      },
      {
        "id": "paitd-017-reality-flag",
        "title": "Reality Is A Typed Closed Flag On Person And Place, Set At Write Time",
        "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-017-reality-flag"
      },
      {
        "id": "paitd-004-point-in-time-memberships",
        "title": "Memberships Are Effective-Dated And Answered By AsOfDate",
        "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-004-point-in-time-memberships"
      },
      {
        "id": "paitd-007-tenure-and-grade-context",
        "title": "Tenure And Grade Context Are Typed Inputs, Not Dashboard Math",
        "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-007-tenure-and-grade-context"
      },
      {
        "id": "paitd-103-query-model",
        "title": "API Axis: Query Model",
        "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-103-query-model"
      }
    ]
  },
  {
    "name": "ageGrade(student, date)",
    "endpoint": "/people/{personId}/age_grade?asOfDate=YYYY-MM-DD",
    "resultShape": "{ person_id, age_grade, begin_date, end_date, is_time_locatable }",
    "rawDbRule": "Read alpha.age_grade_history for the person with is_time_locatable=true, begin_date <= :as_of_date, and (end_date is null or :as_of_date < end_date), then join alpha.person and require p.reality='real' for ordinary reports.",
    "invalidWhen": "Answered only from alpha.person.age_grade when the caller asked for a historical date, parsed from class/test labels, or mixed with Results working grade.",
    "itds": [
      {
        "id": "paitd-018-over-time-history",
        "title": "Alpha Level And Age Grade Keep Effective-Dated History, Read By AsOfDate",
        "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-018-over-time-history"
      },
      {
        "id": "paitd-017-reality-flag",
        "title": "Reality Is A Typed Closed Flag On Person And Place, Set At Write Time",
        "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-017-reality-flag"
      },
      {
        "id": "paitd-004-point-in-time-memberships",
        "title": "Memberships Are Effective-Dated And Answered By AsOfDate",
        "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-004-point-in-time-memberships"
      },
      {
        "id": "paitd-007-tenure-and-grade-context",
        "title": "Tenure And Grade Context Are Typed Inputs, Not Dashboard Math",
        "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-007-tenure-and-grade-context"
      },
      {
        "id": "paitd-103-query-model",
        "title": "API Axis: Query Model",
        "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-103-query-model"
      }
    ]
  },
  {
    "name": "activePersonalizedCourseBindings(student, date)",
    "endpoint": "/people/{personId}/active_course_bindings?asOfDate=YYYY-MM-DD&reality=real",
    "resultShape": "{ person_id, asOfDate, reality, data[{ course_id, source_course_ref, subject_id, course_grade_mode, course_grade_levels[], student_id, next_lesson_path, evidence_memberships[] }], count, links }",
    "rawDbRule": "Start from active alpha.class_membership rows for the exact real student and date using begin_date <= :as_of_date and (:as_of_date < end_date or end_date is null). Join the exact OneRoster class course_sourced_id to alpha.curriculum_courses.source_refs. Return only non-retired published personalized static course roots whose stored alpha.student_id exactly equals the requested person. subject_id is the eight-value authoring registry id owned by loop/context/authoring-subject-registry.json; explicit machine subject codes outrank display labels and unsupported machine codes fail closed. A source_course_ref resolving to multiple active roots is a typed conflict across all active learning groups. The separate enrolled_grade and enrollment-anchor reads remain exact-six reporting contracts.",
    "invalidWhen": "A client composes subject-specific reads, parses course or class labels, infers student ownership from a name, omits asOfDate, admits shared/draft/dynamic/wrong-owner roots, treats malformed or timed-out dependency data as absence, or expands the exact-six reporting registry.",
    "itds": [
      {
        "id": "paitd-004-point-in-time-memberships",
        "title": "Memberships Are Effective-Dated And Answered By AsOfDate",
        "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-004-point-in-time-memberships"
      },
      {
        "id": "paitd-103-query-model",
        "title": "API Axis: Query Model",
        "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-103-query-model"
      },
      {
        "id": "paitd-106-auth-shape",
        "title": "API Axis: Auth Shape",
        "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-106-auth-shape"
      }
    ]
  },
  {
    "name": "enrolledGradeInSubject(student, subject, date)",
    "endpoint": "/people/{personId}/enrolled_grade?subject=math&asOfDate=YYYY-MM-DD",
    "resultShape": "{ person_id, subject, asOfDate, grade_level, grade_levels, enrolled_grade_mode, curriculum_course_bindings[], evidence_memberships[] }",
    "rawDbRule": "Public People & Orgs subject query values are the canonical lowercase Alpha subject ids: math, reading, language, science, vocabulary, writing. Display/source aliases such as Math or Mathematics are folded only at import/write boundaries and are validation errors on public reads. Use the surface-owned query/read function so the subject and grade context come from imported typed OneRoster class/course context for the active learning_group_id, and the date window comes from active alpha.class_membership rows with is_time_locatable=true, begin_date <= :as_of_date, and (end_date is null or :as_of_date < end_date). OneRoster subjects is multi-valued: every canonical subject declared by the exact class/course row materializes independently without duplicating the class or membership. curriculum_course_bindings[].course_id is resolved only by exact source_course_ref/source_refs over alpha.curriculum_courses; that same exact course binds each of its declared canonical source subjects even when Curriculum records one primary subject_id. The returned id is for Curriculum GET /alpha/curriculum/v1/courses/{courseId}/next-lesson. Untyped or unsupported source subjects such as FastMath remain absence; non-404 upstream/storage errors are not absence. Join alpha.person and alpha.place and require real student/school rows for ordinary reports.",
    "invalidWhen": "Computed by parsing course titles, answered from age_grade or Results working grade, using display/source aliases such as subject=Math on public reads, ignoring begin_date null rows, missing asOfDate, or selecting a test/synthetic person/place by default.",
    "itds": [
      {
        "id": "paitd-004-point-in-time-memberships",
        "title": "Memberships Are Effective-Dated And Answered By AsOfDate",
        "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-004-point-in-time-memberships"
      },
      {
        "id": "paitd-007-tenure-and-grade-context",
        "title": "Tenure And Grade Context Are Typed Inputs, Not Dashboard Math",
        "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-007-tenure-and-grade-context"
      },
      {
        "id": "paitd-103-query-model",
        "title": "API Axis: Query Model",
        "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-103-query-model"
      }
    ]
  },
  {
    "name": "firstEnrolledCourseGrade(student, subject)",
    "endpoint": "/people/{personId}/enrollment_anchors/first_enrolled_course_grade?subject=math",
    "resultShape": "{ person_id, subject, grade_level, first_enrolled_course_grade_level, grade_levels, course_grade_mode, first_enrolled_course_begin_date, evidence_membership_id }",
    "rawDbRule": "Public People & Orgs subject query values are the canonical lowercase Alpha subject ids: math, reading, language, science, vocabulary, writing. Display/source aliases such as Math or Mathematics are folded only at import/write boundaries and are validation errors on public reads. Use the surface-owned query/read function so the subject, course_grade_mode, and course_grade_levels come from Curriculum's typed learning-group/course context and the enrollment date comes from alpha.class_membership. The raw path must not parse subject or grade from class names.",
    "invalidWhen": "Computed by parsing course titles, using the single-grade-only anchor as the general first-course answer, treating multi-grade courses as single-grade, using display/source aliases such as subject=Math on public reads, ignoring begin_date null rows, or selecting a test/synthetic person/place by default.",
    "itds": [
      {
        "id": "paitd-004-point-in-time-memberships",
        "title": "Memberships Are Effective-Dated And Answered By AsOfDate",
        "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-004-point-in-time-memberships"
      },
      {
        "id": "paitd-007-tenure-and-grade-context",
        "title": "Tenure And Grade Context Are Typed Inputs, Not Dashboard Math",
        "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-007-tenure-and-grade-context"
      },
      {
        "id": "paitd-103-query-model",
        "title": "API Axis: Query Model",
        "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-103-query-model"
      }
    ]
  },
  {
    "name": "firstSingleGradeEnrollmentDate(student, subject)",
    "endpoint": "/people/{personId}/enrollment_anchors/first_single_grade?subject=math",
    "resultShape": "{ person_id, subject, grade_level, first_single_grade_enrollment_date, evidence_membership_id }",
    "rawDbRule": "Public People & Orgs subject query values are the canonical lowercase Alpha subject ids: math, reading, language, science, vocabulary, writing. Display/source aliases such as Math or Mathematics are folded only at import/write boundaries and are validation errors on public reads. Use the surface-owned query/read function so the subject and single-grade classification come from Curriculum's typed learning-group/course context and the enrollment dates come from alpha.class_membership. The raw path must not parse subject or grade from class names.",
    "invalidWhen": "Computed by parsing course titles, treating multi-grade courses as single-grade, using display/source aliases such as subject=Math on public reads, ignoring begin_date null rows, or selecting a test/synthetic person/place by default.",
    "itds": [
      {
        "id": "paitd-004-point-in-time-memberships",
        "title": "Memberships Are Effective-Dated And Answered By AsOfDate",
        "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-004-point-in-time-memberships"
      },
      {
        "id": "paitd-007-tenure-and-grade-context",
        "title": "Tenure And Grade Context Are Typed Inputs, Not Dashboard Math",
        "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-007-tenure-and-grade-context"
      },
      {
        "id": "paitd-103-query-model",
        "title": "API Axis: Query Model",
        "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-103-query-model"
      }
    ]
  },
  {
    "name": "studentsForGuide(guide, date)",
    "endpoint": "/guides/{guidePersonId}/students?asOfDate=YYYY-MM-DD",
    "resultShape": "{ guide_person_id, student_person_id, learning_group_id, school_id, begin_date, end_date }[]",
    "rawDbRule": "Join active guide class_membership rows to active student class_membership rows on tenant_id, school_id, and learning_group_id for the same asOfDate; join alpha.person for both sides and alpha.place for the school; require all joined person/place reality values to be real unless explicitly including test/synthetic rows.",
    "invalidWhen": "Implemented as an undocumented two-hop in the client, inferred from staff titles, missing asOfDate, or returning test/synthetic students in ordinary reports.",
    "itds": [
      {
        "id": "paitd-004-point-in-time-memberships",
        "title": "Memberships Are Effective-Dated And Answered By AsOfDate",
        "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-004-point-in-time-memberships"
      },
      {
        "id": "paitd-102-read-shape",
        "title": "API Axis: Read Shape",
        "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-102-read-shape"
      },
      {
        "id": "paitd-103-query-model",
        "title": "API Axis: Query Model",
        "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-103-query-model"
      },
      {
        "id": "paitd-106-auth-shape",
        "title": "API Axis: Auth Shape",
        "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-106-auth-shape"
      }
    ]
  }
]
policyConfig
[
  {
    "key": "alpha.policy.reality_source_mapping",
    "type": "write-boundary source mapping",
    "owner": "People & Orgs surface config",
    "meaning": "Maps authoritative SIS and TimeBack source classifications to the closed reality enum without parsing names or campus labels.",
    "requiredBy": "person.reality, place.reality, default real-only report reads, migration backfill, and deployed smoke tests that exclude test data.",
    "invalidWhen": "A report ships an exclude-list, regexes campus/person names, or treats missing reality as real.",
    "example": {
      "authoritative_real": "real",
      "qa_or_agent_test": "test",
      "generated_fixture": "synthetic"
    },
    "itds": [
      {
        "id": "paitd-103-query-model",
        "title": "API Axis: Query Model",
        "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-103-query-model"
      },
      {
        "id": "paitd-111-privacy-retention",
        "title": "API Axis: Privacy / Retention",
        "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-111-privacy-retention"
      }
    ]
  },
  {
    "key": "alpha.policy.tenure_buckets",
    "type": "ordered bucket config",
    "owner": "People & Orgs surface config",
    "meaning": "Defines tenure bands computed from person.admission_date and asOfDate.",
    "requiredBy": "Tenure reports and cohort filters.",
    "invalidWhen": "A dashboard or skill pack hardcodes bucket edges instead of calling the surface.",
    "example": [
      {
        "label": "0-0.5 year",
        "min_days": 0,
        "max_days": 182
      },
      {
        "label": "0.5-1 year",
        "min_days": 183,
        "max_days": 365
      },
      {
        "label": "1-2 years",
        "min_days": 366,
        "max_days": 730
      },
      {
        "label": "2-3 years",
        "min_days": 731,
        "max_days": 1095
      },
      {
        "label": "3+ years",
        "min_days": 1096,
        "max_days": null
      }
    ],
    "itds": [
      {
        "id": "paitd-007-tenure-and-grade-context",
        "title": "Tenure And Grade Context Are Typed Inputs, Not Dashboard Math",
        "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-007-tenure-and-grade-context"
      }
    ]
  },
  {
    "key": "alpha.policy.grade_alias_folds",
    "type": "alias-fold config",
    "owner": "People & Orgs surface config",
    "meaning": "Maps source grade aliases to the closed grade_level enum at write time.",
    "requiredBy": "person.grade_levels and person.age_grade.",
    "invalidWhen": "A consumer parses grade strings from users.grades, class names, or test names at read time.",
    "example": {
      "0": 0,
      "7": 7,
      "13": "reject_or_reconcile",
      "PK": -1,
      "-1": -1,
      "K": 0,
      "4TH_GRADE": 4,
      "Grade_4": 4
    },
    "itds": [
      {
        "id": "paitd-007-tenure-and-grade-context",
        "title": "Tenure And Grade Context Are Typed Inputs, Not Dashboard Math",
        "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-007-tenure-and-grade-context"
      }
    ]
  },
  {
    "key": "alpha.policy.alpha_level_alias_folds",
    "type": "alias-fold config",
    "owner": "People & Orgs surface config",
    "meaning": "Maps live source alpha-level labels to the closed alpha_level enum at write time.",
    "requiredBy": "alpha_level reporting and point-in-time cohort slices.",
    "invalidWhen": "A consumer parses level labels from users_visibility.user_alpha_level or place names at read time.",
    "example": {
      "PKBY": "WL",
      "WL": "WL",
      "Linc": "LL",
      "LL": "LL",
      "L3": "MS",
      "Middle School": "MS",
      "L4.1": "HS",
      "L4.2": "HS",
      "L4.3": "HS",
      "High School": "HS"
    },
    "itds": [
      {
        "id": "paitd-007-tenure-and-grade-context",
        "title": "Tenure And Grade Context Are Typed Inputs, Not Dashboard Math",
        "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-007-tenure-and-grade-context"
      },
      {
        "id": "paitd-006-tag-registry",
        "title": "Governed Tags Are Report Slices Only",
        "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-006-tag-registry"
      }
    ]
  },
  {
    "key": "alpha.policy.brand_alias_folds",
    "type": "alias-fold config",
    "owner": "People & Orgs setup import",
    "meaning": "Maps live org labels and campus-taxonomy aliases to the closed brand enum at write time.",
    "requiredBy": "place.brand and NWEA Brand x Modality account grouping.",
    "invalidWhen": "A report groups by parsed school names or maintains its own campus taxonomy.",
    "example": {
      "Alpha School": "alpha",
      "Alpha Anywhere": "alpha",
      "GT School": "gt",
      "GT Anywhere": "gt",
      "TSA Online": "texas_sports_academy",
      "Texas Sports Academy": "texas_sports_academy"
    },
    "itds": [
      {
        "id": "paitd-003-place-nwea-boundary",
        "title": "Place Is The Plain Alias For OneRoster Org And District Is The NWEA Account",
        "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-003-place-nwea-boundary"
      },
      {
        "id": "paitd-006-tag-registry",
        "title": "Governed Tags Are Report Slices Only",
        "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-006-tag-registry"
      }
    ]
  },
  {
    "key": "alpha.policy.segment_alias_folds",
    "type": "alias-fold config",
    "owner": "People & Orgs setup import",
    "meaning": "Maps live org labels and campus-taxonomy aliases to the closed segment enum at write time.",
    "requiredBy": "place.segment and reporting slices.",
    "invalidWhen": "A dashboard parses segment from place.name, campusId, or a stale local list.",
    "example": {
      "Private": "private",
      "Virtual": "virtual",
      "SW Sales": "sw_sales",
      "Charter": "charter",
      "multi-segment district": "mixed"
    },
    "itds": [
      {
        "id": "paitd-003-place-nwea-boundary",
        "title": "Place Is The Plain Alias For OneRoster Org And District Is The NWEA Account",
        "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-003-place-nwea-boundary"
      },
      {
        "id": "paitd-006-tag-registry",
        "title": "Governed Tags Are Report Slices Only",
        "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-006-tag-registry"
      }
    ]
  },
  {
    "key": "alpha.policy.school_year_boundaries",
    "type": "date-boundary config",
    "owner": "Surface config shared with school_period reads",
    "meaning": "Defines the school-year boundary used by policy computations that need a year start/end.",
    "requiredBy": "asOfDate reports that align roster context to school-year windows.",
    "invalidWhen": "A report hardcodes start/end dates or parses them from school_period.title.",
    "example": {
      "start_month": 8,
      "start_day": 1,
      "end_month": 7,
      "end_day": 31
    },
    "itds": [
      {
        "id": "paitd-005-school-periods",
        "title": "School Period Is The Plain Alias For Academic Session",
        "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-005-school-periods"
      },
      {
        "id": "paitd-007-tenure-and-grade-context",
        "title": "Tenure And Grade Context Are Typed Inputs, Not Dashboard Math",
        "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-007-tenure-and-grade-context"
      }
    ]
  },
  {
    "key": "alpha.policy.school_day",
    "type": "enumerable school-day calendar",
    "owner": "People & Orgs calendar reads over Ed-Fi CalendarDate",
    "meaning": "Defines school-day answers from alpha.school_calendar, a view over Ed-Fi CalendarDate records keyed by school. Consumers call the surface for is-school-day, school-days-in-range, school-days-between, school-days-remaining, and next-school-year-start instead of counting weekdays or carrying holiday tables.",
    "requiredBy": "GOALS date-to-effort arithmetic, within-grade pacing, minutes-per-school-day denominators, and school-day reports.",
    "invalidWhen": "A client counts weekdays, skips summer gaps locally, stores local holidays, or parses school_period start/end dates as a school-day list.",
    "example": {
      "source_view": "alpha.school_calendar",
      "source_truth": "ed_fi.CalendarDate",
      "reason_values": [
        "instructional",
        "weekend",
        "teacher_workshop",
        "holiday_break",
        "nwea_map_testing",
        "other"
      ],
      "range_inclusive": true,
      "regression": {
        "school_id": "place_north_valley_school",
        "start_date": "2025-08-13",
        "end_date": "2026-07-24",
        "school_days_between": 204
      }
    },
    "itds": [
      {
        "id": "paitd-005-school-periods",
        "title": "School Period Is The Plain Alias For Academic Session",
        "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-005-school-periods"
      },
      {
        "id": "paitd-103-query-model",
        "title": "API Axis: Query Model",
        "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-103-query-model"
      }
    ]
  },
  {
    "key": "alpha.policy.expected_xp_minute_convention",
    "type": "effort unit convention",
    "owner": "Cross-module policy surfaced here for roster-calendar consumers",
    "meaning": "1 expected XP is approximately 1 expected minute. Convert expected_xp to planned hours with expected_xp / 60 before applying school-day pacing.",
    "requiredBy": "GOALS effort-per-school-day calculations and any report that turns expected XP into time.",
    "invalidWhen": "A consumer learns the XP-minute relationship from production defaults such as default_xp_goal == default_minutes_goal or applies awarded XP history as expected effort.",
    "example": {
      "expected_xp": 360,
      "expected_minutes": 360,
      "planned_hours_before_calendar_pacing": 6
    },
    "itds": [
      {
        "id": "paitd-007-tenure-and-grade-context",
        "title": "Tenure And Grade Context Are Typed Inputs, Not Dashboard Math",
        "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-007-tenure-and-grade-context"
      }
    ]
  }
]
roleViews
[
  {
    "name": "students",
    "definition": "Filter alpha.person to people with an active place_membership or class_membership where role_kind=student at asOfDate.",
    "notStorage": "Not a new table; person plus memberships remain the storage contract.",
    "invalidWhen": "A student row stores mastery, working grade, MAP result, or advancement. Those facts live in Results."
  },
  {
    "name": "parents_and_guardians",
    "definition": "Use alpha.guardian_view plus alpha.guardian_relationship_view for Ed-Fi guardian/contact facts, and alpha.person family_or_agent_person_ids only for thin OneRoster agent links.",
    "notStorage": "Guardian/contact facts are Ed-Fi-backed views, not Alpha tables; OneRoster family links remain real ids, never tags.",
    "invalidWhen": "A parent/guardian relationship is stored as a free-form tag or copied into an Alpha own-table."
  },
  {
    "name": "guides",
    "definition": "Filter alpha.person to people with role_kind=guide or class_membership.role_kind=guide at asOfDate. The inverse studentsForGuide(guide, date) joins active guide and student class_membership rows on learning_group_id and school_id.",
    "notStorage": "Not a new table; guide assignment is a dated membership and the inverse is a first-class query over those memberships.",
    "invalidWhen": "A guide is inferred by parsing a class title or email domain, or studentsForGuide is rebuilt as an undocumented client-side two-hop."
  },
  {
    "name": "staff_and_administrators",
    "definition": "Filter alpha.person to people with active staff/admin memberships for simple roster roles; use alpha.staff_assignment_view for Ed-Fi assignment-specific facts such as staff classification, title, assignment order, and full-time equivalency.",
    "notStorage": "Not a new table; staff/admin roles are dated memberships and assignment detail is an Ed-Fi-backed view.",
    "invalidWhen": "An admin list bypasses asOfDate, ignores relationship-scoped auth, or parses titles instead of using staff_classification."
  },
  {
    "name": "program_participants",
    "definition": "Use alpha.program_participation_view to answer which administrative programs a student belongs to at a place as of a date.",
    "notStorage": "Not a tag and not a Results object; it is an Ed-Fi-backed relationship view.",
    "invalidWhen": "Program participation is stored as a tag, mixed with outcomes/eligibility formulas, or queried without the begin/end date rule."
  }
]
quickExamples
[
  {
    "title": "Query: active students in one school on one date",
    "job": "Use this when a teacher, parent report, or app-builder LLM asks for the roster of real students for a school as of a date.",
    "setup": "export PEOPLE_ORGS_BASE_URL=\"$BASE_URL\"\nexport PEOPLE_ORGS_JWT=\"$JWT\"\nexport AS_OF_DATE=\"2026-09-15\"\nexport SCHOOL_ID=\"place_north_valley_school\"\nexport TENANT_ID=\"0d4ce2f4-1c42-4f3c-9f0d-03fb7f5271d3\"",
    "api": "curl -sS \"$PEOPLE_ORGS_BASE_URL/people?asOfDate=$AS_OF_DATE&reality=real&filter=roleKind:eq:student,schoolId:eq:$SCHOOL_ID&sort=last_name,first_name\" \\\n  -H \"Authorization: Bearer $PEOPLE_ORGS_JWT\"",
    "sql": "WITH active_students AS (\n  -- Row grain: one active class-membership row per student per learning group.\n  -- DISTINCT below intentionally folds this to one person row for the people list;\n  -- it is not a substitute for tenant_id, school_id, role_kind, or asOfDate joins.\n  SELECT DISTINCT cm.tenant_id, cm.person_id\n  FROM alpha.class_membership cm\n  WHERE cm.tenant_id = :'tenant_id'\n    AND cm.school_id = :'school_id'\n    AND cm.role_kind = 'student'\n    AND cm.is_time_locatable IS TRUE\n    AND cm.begin_date <= :'as_of_date'::date\n    AND (cm.end_date IS NULL OR :'as_of_date'::date < cm.end_date)\n)\nSELECT p.person_id, p.first_name, p.last_name, p.email, p.age_grade\nFROM alpha.person p\nJOIN active_students s\n  ON s.tenant_id = p.tenant_id\n AND s.person_id = p.person_id\nJOIN alpha.place school\n  ON school.tenant_id = s.tenant_id\n AND school.place_id = :'school_id'\nWHERE p.tenant_id = :'tenant_id'\n  AND p.reality = 'real'\n  AND school.reality = 'real'\n  AND COALESCE(p.source_status, 'active') <> 'tobedeleted'\n  AND COALESCE(school.source_status, 'active') <> 'tobedeleted'\nORDER BY p.last_name, p.first_name, p.person_id;",
    "sameAnswerRule": "The API and raw SQL must return the same person ids in the same order. If they diverge, check tenant scope, person/place reality=real, source_status tombstones, role_kind=student, school_id, the asOfDate membership rule, and the stated row grain before changing consumer code.",
    "itds": [
      {
        "id": "paitd-017-reality-flag",
        "title": "Reality Is A Typed Closed Flag On Person And Place, Set At Write Time",
        "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-017-reality-flag"
      },
      {
        "id": "paitd-004-point-in-time-memberships",
        "title": "Memberships Are Effective-Dated And Answered By AsOfDate",
        "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-004-point-in-time-memberships"
      },
      {
        "id": "paitd-103-query-model",
        "title": "API Axis: Query Model",
        "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-103-query-model"
      },
      {
        "id": "paitd-106-auth-shape",
        "title": "API Axis: Auth Shape",
        "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-106-auth-shape"
      },
      {
        "id": "paitd-109-tenant-routing",
        "title": "API Axis: Tenant Routing",
        "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-109-tenant-routing"
      },
      {
        "id": "paitd-111-privacy-retention",
        "title": "API Axis: Privacy / Retention",
        "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-111-privacy-retention"
      }
    ]
  },
  {
    "title": "Query: alpha level and age grade for a student on one date",
    "job": "Use this when a progress report asks what Alpha level or age grade was true on a historical date.",
    "setup": "export PEOPLE_ORGS_BASE_URL=\"$BASE_URL\"\nexport PEOPLE_ORGS_JWT=\"$JWT\"\nexport AS_OF_DATE=\"2026-09-15\"\nexport STUDENT_PERSON_ID=\"person_ada_lovelace\"\nexport TENANT_ID=\"0d4ce2f4-1c42-4f3c-9f0d-03fb7f5271d3\"",
    "api": "curl -sS \"$PEOPLE_ORGS_BASE_URL/people/$STUDENT_PERSON_ID/alpha_level?asOfDate=$AS_OF_DATE&reality=real\" \\\n  -H \"Authorization: Bearer $PEOPLE_ORGS_JWT\"\n\ncurl -sS \"$PEOPLE_ORGS_BASE_URL/people/$STUDENT_PERSON_ID/age_grade?asOfDate=$AS_OF_DATE&reality=real\" \\\n  -H \"Authorization: Bearer $PEOPLE_ORGS_JWT\"",
    "sql": "SELECT\n  p.person_id,\n  al.alpha_level,\n  ag.age_grade\nFROM alpha.person p\nLEFT JOIN alpha.alpha_level_history al\n  ON al.tenant_id = p.tenant_id\n AND al.person_id = p.person_id\n AND al.is_time_locatable IS TRUE\n AND al.begin_date <= :'as_of_date'::date\n AND (al.end_date IS NULL OR :'as_of_date'::date < al.end_date)\nLEFT JOIN alpha.age_grade_history ag\n  ON ag.tenant_id = p.tenant_id\n AND ag.person_id = p.person_id\n AND ag.is_time_locatable IS TRUE\n AND ag.begin_date <= :'as_of_date'::date\n AND (ag.end_date IS NULL OR :'as_of_date'::date < ag.end_date)\nWHERE p.tenant_id = :'tenant_id'\n  AND p.person_id = :'student_person_id'\n  AND p.reality = 'real'\n  AND COALESCE(p.source_status, 'active') <> 'tobedeleted';",
    "sameAnswerRule": "The API and raw SQL must return the same alpha_level and age_grade for the same asOfDate. If they diverge, check reality=real, duplicate overlapping history rows, and the begin_date/end_date/is_time_locatable null rule before changing consumer code.",
    "itds": [
      {
        "id": "paitd-018-over-time-history",
        "title": "Alpha Level And Age Grade Keep Effective-Dated History, Read By AsOfDate",
        "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-018-over-time-history"
      },
      {
        "id": "paitd-017-reality-flag",
        "title": "Reality Is A Typed Closed Flag On Person And Place, Set At Write Time",
        "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-017-reality-flag"
      },
      {
        "id": "paitd-004-point-in-time-memberships",
        "title": "Memberships Are Effective-Dated And Answered By AsOfDate",
        "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-004-point-in-time-memberships"
      },
      {
        "id": "paitd-007-tenure-and-grade-context",
        "title": "Tenure And Grade Context Are Typed Inputs, Not Dashboard Math",
        "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-007-tenure-and-grade-context"
      },
      {
        "id": "paitd-103-query-model",
        "title": "API Axis: Query Model",
        "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-103-query-model"
      },
      {
        "id": "paitd-111-privacy-retention",
        "title": "API Axis: Privacy / Retention",
        "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-111-privacy-retention"
      }
    ]
  },
  {
    "title": "Query: students for one guide on one date",
    "job": "Use this when a guide dashboard asks which real students a guide serves as of a date.",
    "setup": "export PEOPLE_ORGS_BASE_URL=\"$BASE_URL\"\nexport PEOPLE_ORGS_JWT=\"$JWT\"\nexport AS_OF_DATE=\"2026-09-15\"\nexport GUIDE_PERSON_ID=\"person_katherine_johnson\"\nexport TENANT_ID=\"0d4ce2f4-1c42-4f3c-9f0d-03fb7f5271d3\"",
    "api": "curl -sS \"$PEOPLE_ORGS_BASE_URL/guides/$GUIDE_PERSON_ID/students?asOfDate=$AS_OF_DATE&reality=real\" \\\n  -H \"Authorization: Bearer $PEOPLE_ORGS_JWT\"",
    "sql": "WITH active_guide_groups AS (\n  SELECT tenant_id, school_id, learning_group_id, begin_date, end_date\n  FROM alpha.class_membership\n  WHERE tenant_id = :'tenant_id'\n    AND person_id = :'guide_person_id'\n    AND role_kind = 'guide'\n    AND is_time_locatable IS TRUE\n    AND begin_date <= :'as_of_date'::date\n    AND (end_date IS NULL OR :'as_of_date'::date < end_date)\n),\nactive_student_groups AS (\n  SELECT cm.tenant_id, cm.person_id, cm.school_id, cm.learning_group_id, cm.begin_date, cm.end_date\n  FROM alpha.class_membership cm\n  JOIN active_guide_groups gg\n    ON gg.tenant_id = cm.tenant_id\n   AND gg.school_id = cm.school_id\n   AND gg.learning_group_id = cm.learning_group_id\n  WHERE cm.role_kind = 'student'\n    AND cm.is_time_locatable IS TRUE\n    AND cm.begin_date <= :'as_of_date'::date\n    AND (cm.end_date IS NULL OR :'as_of_date'::date < cm.end_date)\n)\nSELECT DISTINCT\n  -- Row grain: one row per guide/student/school/learning_group after the active\n  -- membership join. DISTINCT only removes duplicate overlapping evidence for\n  -- the same returned person row; it must never hide a missing join predicate.\n  :'guide_person_id' AS guide_person_id,\n  student.person_id AS student_person_id,\n  student.first_name,\n  student.last_name,\n  sg.school_id,\n  sg.learning_group_id\nFROM active_student_groups sg\nJOIN alpha.person student\n  ON student.tenant_id = sg.tenant_id\n AND student.person_id = sg.person_id\nJOIN alpha.person guide\n  ON guide.tenant_id = sg.tenant_id\n AND guide.person_id = :'guide_person_id'\nJOIN alpha.place school\n  ON school.tenant_id = sg.tenant_id\n AND school.place_id = sg.school_id\nWHERE student.reality = 'real'\n  AND guide.reality = 'real'\n  AND school.reality = 'real'\nORDER BY student.last_name, student.first_name, student.person_id;",
    "sameAnswerRule": "The API and raw SQL must return the same student ids for the guide/date. If they diverge, check the guide role, shared tenant_id/school_id/learning_group_id, asOfDate windows, tenant scope, row grain, and real-only filters before rebuilding a two-hop client query.",
    "itds": [
      {
        "id": "paitd-004-point-in-time-memberships",
        "title": "Memberships Are Effective-Dated And Answered By AsOfDate",
        "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-004-point-in-time-memberships"
      },
      {
        "id": "paitd-102-read-shape",
        "title": "API Axis: Read Shape",
        "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-102-read-shape"
      },
      {
        "id": "paitd-103-query-model",
        "title": "API Axis: Query Model",
        "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-103-query-model"
      },
      {
        "id": "paitd-106-auth-shape",
        "title": "API Axis: Auth Shape",
        "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-106-auth-shape"
      }
    ]
  },
  {
    "title": "Query: first single-grade enrollment date in a subject",
    "job": "Use this when a school-year-start anchor or growth report needs the first date a real student entered a single-grade learning group for a subject.",
    "setup": "export PEOPLE_ORGS_BASE_URL=\"$BASE_URL\"\nexport PEOPLE_ORGS_JWT=\"$JWT\"\nexport STUDENT_PERSON_ID=\"person_ada_lovelace\"\nexport SUBJECT=\"Math\"\nexport TENANT_ID=\"0d4ce2f4-1c42-4f3c-9f0d-03fb7f5271d3\"",
    "api": "curl -sS \"$PEOPLE_ORGS_BASE_URL/people/$STUDENT_PERSON_ID/enrollment_anchors/first_single_grade?subject=$SUBJECT&reality=real\" \\\n  -H \"Authorization: Bearer $PEOPLE_ORGS_JWT\"",
    "sql": "SELECT *\nFROM alpha.first_single_grade_enrollment_date(\n  tenant_id => :'tenant_id'::uuid,\n  student_person_id => :'student_person_id',\n  subject => :'subject',\n  reality => 'real'\n);",
    "sameAnswerRule": "The API and raw SQL function must return the same first_single_grade_enrollment_date and evidence_membership_id. The function owns the Curriculum subject/single-grade join and the People & Orgs begin/end null rule so consumers do not parse class names or keep subject maps.",
    "itds": [
      {
        "id": "paitd-004-point-in-time-memberships",
        "title": "Memberships Are Effective-Dated And Answered By AsOfDate",
        "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-004-point-in-time-memberships"
      },
      {
        "id": "paitd-007-tenure-and-grade-context",
        "title": "Tenure And Grade Context Are Typed Inputs, Not Dashboard Math",
        "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-007-tenure-and-grade-context"
      },
      {
        "id": "paitd-103-query-model",
        "title": "API Axis: Query Model",
        "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-103-query-model"
      }
    ]
  },
  {
    "title": "Query: legal guardians and primary contacts for one student",
    "job": "Use this when a parent portal, guide dashboard, or app-builder LLM asks who may act for or contact a student.",
    "setup": "export PEOPLE_ORGS_BASE_URL=\"$BASE_URL\"\nexport PEOPLE_ORGS_JWT=\"$JWT\"\nexport STUDENT_PERSON_ID=\"person_ada_lovelace\"\nexport TENANT_ID=\"0d4ce2f4-1c42-4f3c-9f0d-03fb7f5271d3\"",
    "api": "curl -sS \"$PEOPLE_ORGS_BASE_URL/guardian_relationships?filter=studentPersonId:eq:$STUDENT_PERSON_ID&sort=contact_priority,guardian_id\" \\\n  -H \"Authorization: Bearer $PEOPLE_ORGS_JWT\"",
    "sql": "SELECT\n  gr.guardian_relationship_id,\n  gr.student_person_id,\n  gr.guardian_id,\n  g.full_name,\n  gr.relationship_kind,\n  gr.is_legal_guardian,\n  gr.is_primary_contact,\n  gr.is_emergency_contact,\n  gr.contact_priority\nFROM alpha.guardian_relationship_view gr\nJOIN alpha.guardian_view g\n  ON g.tenant_id = gr.tenant_id\n AND g.guardian_id = gr.guardian_id\nWHERE gr.tenant_id = :'tenant_id'\n  AND gr.student_person_id = :'student_person_id'\n  AND COALESCE(g.is_deleted, false) IS FALSE\nORDER BY gr.contact_priority NULLS LAST, gr.guardian_id;",
    "sameAnswerRule": "The API and raw SQL must return the same guardian_relationship ids. If they diverge, check tenant scope, Ed-Fi canonical-only state, is_deleted=false, descriptor_code resolution, and OneRoster sourcedId joins before changing consumer code.",
    "itds": [
      {
        "id": "paitd-012-edfi-second-upstream",
        "title": "Ed-Fi Administrative Records Are A Second View-Only Upstream",
        "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-012-edfi-second-upstream"
      },
      {
        "id": "paitd-013-guardian-views",
        "title": "Guardians Come From Ed-Fi Contact And StudentContactAssociation Views",
        "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-013-guardian-views"
      },
      {
        "id": "paitd-103-query-model",
        "title": "API Axis: Query Model",
        "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-103-query-model"
      },
      {
        "id": "paitd-106-auth-shape",
        "title": "API Axis: Auth Shape",
        "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-106-auth-shape"
      },
      {
        "id": "paitd-111-privacy-retention",
        "title": "API Axis: Privacy / Retention",
        "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-111-privacy-retention"
      }
    ]
  },
  {
    "title": "Migration: backfill person_ext and place_ext without copying base rows",
    "job": "Use this when a migration needs to add Alpha-owned tenure, age-grade, or NWEA-account context after OneRoster people and places already exist.",
    "setup": "-- psql variables expected:\n--   :tenant_id\n-- This migration writes only allowed Alpha extension tables.\n-- It validates every row against alpha.person_base or alpha.place_base first.",
    "api": "# API-equivalent per-resource writes route sourced fields to OneRoster\n# and extension fields to the owning Alpha extension table.\ncurl -sS -X PATCH \"$PEOPLE_ORGS_BASE_URL/people/person_ada_lovelace\" \\\n  -H \"Authorization: Bearer $PEOPLE_ORGS_JWT\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"admissionDate\":\"2025-08-18\",\"exitDate\":null,\"ageGrade\":7,\"reality\":\"real\"}'\n\ncurl -sS -X PATCH \"$PEOPLE_ORGS_BASE_URL/places/place_timeback_physical_district\" \\\n  -H \"Authorization: Bearer $PEOPLE_ORGS_JWT\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"nweaDistrictId\":\"nwea-district-physical-001\",\"reality\":\"real\"}'",
    "sql": "BEGIN;\n\nWITH incoming_person_ext(tenant_id, person_id, admission_date, exit_date, age_grade, reality) AS (\n  VALUES\n    (:'tenant_id'::uuid, 'person_ada_lovelace', DATE '2025-08-18', NULL::date, 7, 'real')\n),\nvalidated_person_ext AS (\n  SELECT i.*\n  FROM incoming_person_ext i\n  JOIN alpha.person_base pb\n    ON pb.tenant_id = i.tenant_id\n   AND pb.person_id = i.person_id\n)\nINSERT INTO alpha.person_ext (\n  tenant_id, person_id, admission_date, exit_date, age_grade, reality\n)\nSELECT tenant_id, person_id, admission_date, exit_date, age_grade, reality\nFROM validated_person_ext\nON CONFLICT (tenant_id, person_id) DO UPDATE\nSET admission_date = EXCLUDED.admission_date,\n    exit_date = EXCLUDED.exit_date,\n    age_grade = EXCLUDED.age_grade,\n    reality = EXCLUDED.reality;\n\nWITH incoming_place_ext(tenant_id, place_id, nwea_district_id, reality) AS (\n  VALUES\n    (:'tenant_id'::uuid, 'place_timeback_physical_district', 'nwea-district-physical-001', 'real')\n),\nvalidated_place_ext AS (\n  SELECT i.*\n  FROM incoming_place_ext i\n  JOIN alpha.place_base pb\n    ON pb.tenant_id = i.tenant_id\n   AND pb.place_id = i.place_id\n  WHERE pb.place_kind = 'district'\n)\nINSERT INTO alpha.place_ext (\n  tenant_id, place_id, nwea_district_id, reality\n)\nSELECT tenant_id, place_id, nwea_district_id, reality\nFROM validated_place_ext\nON CONFLICT (tenant_id, place_id) DO UPDATE\nSET nwea_district_id = EXCLUDED.nwea_district_id,\n    reality = EXCLUDED.reality;\n\nCOMMIT;",
    "sameAnswerRule": "This is valid because alpha.person_ext and alpha.place_ext are allowed extension tables, and every row is validated against the base view before insert. The migration must classify reality from authoritative source data; it must not create or populate alpha.person, alpha.place, alpha.place_membership, alpha.class_membership, or alpha.school_period as tables.",
    "itds": [
      {
        "id": "paitd-003-place-nwea-boundary",
        "title": "Place Is The Plain Alias For OneRoster Org And District Is The NWEA Account",
        "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-003-place-nwea-boundary"
      },
      {
        "id": "paitd-007-tenure-and-grade-context",
        "title": "Tenure And Grade Context Are Typed Inputs, Not Dashboard Math",
        "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-007-tenure-and-grade-context"
      },
      {
        "id": "paitd-011-storage-model",
        "title": "Alpha Storage Is Views Over OneRoster Plus Extension Tables",
        "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-011-storage-model"
      },
      {
        "id": "paitd-101-write-granularity",
        "title": "API Axis: Write Granularity",
        "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-101-write-granularity"
      }
    ]
  },
  {
    "title": "Migration: add a governed reporting tag without copying roster fields",
    "job": "Use this as the storage-gate pattern for a migration that adds a report slice over a real Alpha extension table.",
    "setup": "-- psql variables expected:\n--   :tenant_id\n-- This migration touches only allowed Alpha extension tables.\n-- It does not CREATE TABLE alpha.person or copy from oneroster.users.",
    "api": "# There is no client-side computation here. After this migration,\n# callers filter /places by level through the Alpha surface.",
    "sql": "BEGIN;\n\nINSERT INTO alpha.tag_definition (\n  tenant_id, tag_key, anchor, allowed_values, value_type, is_locked\n) VALUES (\n  :'tenant_id',\n  'level',\n  'school',\n  '[\"WL\",\"LL\",\"L1\",\"L2\",\"MS\",\"HS\"]'::jsonb,\n  'string',\n  true\n) ON CONFLICT (tenant_id, tag_key, anchor) DO UPDATE\nSET allowed_values = EXCLUDED.allowed_values,\n    value_type = EXCLUDED.value_type,\n    is_locked = EXCLUDED.is_locked;\n\nCREATE INDEX IF NOT EXISTS object_tag_tenant_key_value_idx\n  ON alpha.object_tag (tenant_id, tag_key, tag_value);\n\nCOMMIT;",
    "sameAnswerRule": "This is valid because alpha.tag_definition and alpha.object_tag are allowed extension tables, and level is a locked school-level tag using the same WL/LL/L1/L2/MS/HS glossary as alpha_level. A migration that creates alpha.person, alpha.place, or any other renamed object as a table fails PAITD-011.",
    "itds": [
      {
        "id": "paitd-006-tag-registry",
        "title": "Governed Tags Are Report Slices Only",
        "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-006-tag-registry"
      },
      {
        "id": "paitd-011-storage-model",
        "title": "Alpha Storage Is Views Over OneRoster Plus Extension Tables",
        "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-011-storage-model"
      }
    ]
  }
]
convergenceRules
[
  {
    "name": "Tenant scope",
    "apiRule": "The API reads tenant_id or tenantId only from the verified bearer token.",
    "rawDbRule": "Every raw query includes tenant_id = :tenant_id on the public Alpha view and on every joined extension table. Do not read tenant ids from request headers, body fields, or display names.",
    "wrongPlausibleAnswer": "Rows from another school network appear valid because ids are only unique inside a tenant.",
    "exampleWhere": "p.tenant_id = :'tenant_id' AND cm.tenant_id = p.tenant_id",
    "itds": [
      {
        "id": "paitd-106-auth-shape",
        "title": "API Axis: Auth Shape",
        "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-106-auth-shape"
      },
      {
        "id": "paitd-109-tenant-routing",
        "title": "API Axis: Tenant Routing",
        "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-109-tenant-routing"
      }
    ]
  },
  {
    "name": "Join grain before de-duplication",
    "apiRule": "List endpoints choose the response grain before joining: people lists return one row per person, membership lists return one row per membership, and guide/student inverse reads return one row per guide-student-learning_group-school relationship.",
    "rawDbRule": "Every raw query states its row grain before it joins. Join membership rows on tenant_id plus the documented relationship keys: place membership uses person_id/place_id/role_kind/date window, class membership uses person_id/school_id/learning_group_id/role_kind/date window, guide inverse joins guide and student rows on tenant_id, school_id, and learning_group_id, and place account joins use parent_place_id. Use DISTINCT only after projecting the documented response grain, never to hide a missing join key or date predicate.",
    "wrongPlausibleAnswer": "A query returns duplicate students, loses a valid multi-school membership, or silently hides a cross-school join mistake because DISTINCT cleaned up rows after the wrong join.",
    "exampleWhere": "student_cm.tenant_id = guide_cm.tenant_id AND student_cm.school_id = guide_cm.school_id AND student_cm.learning_group_id = guide_cm.learning_group_id -- then SELECT DISTINCT only at the documented response grain",
    "itds": [
      {
        "id": "paitd-004-point-in-time-memberships",
        "title": "Memberships Are Effective-Dated And Answered By AsOfDate",
        "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-004-point-in-time-memberships"
      },
      {
        "id": "paitd-102-read-shape",
        "title": "API Axis: Read Shape",
        "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-102-read-shape"
      },
      {
        "id": "paitd-103-query-model",
        "title": "API Axis: Query Model",
        "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-103-query-model"
      }
    ]
  },
  {
    "name": "Real student, not every person",
    "apiRule": "Student list endpoints use dated role membership plus reality=real by default, not a person table shortcut.",
    "rawDbRule": "A real student answer joins alpha.person to alpha.place_membership or alpha.class_membership with p.reality='real', role_kind='student', is_time_locatable=true, begin_date <= :asOfDate, and end_date null or after :asOfDate. If a school/place is in the query, the joined place must also have reality='real'.",
    "wrongPlausibleAnswer": "Parents, guides, inactive students, test users, synthetic rows, or undated rows enter a student report because the query filtered person.grade_levels or a name string instead of membership and reality.",
    "exampleWhere": "p.reality = 'real' AND school.reality = 'real' AND cm.role_kind = 'student' AND cm.is_time_locatable IS TRUE AND cm.begin_date <= :'as_of_date'::date AND (cm.end_date IS NULL OR :'as_of_date'::date < cm.end_date)",
    "itds": [
      {
        "id": "paitd-017-reality-flag",
        "title": "Reality Is A Typed Closed Flag On Person And Place, Set At Write Time",
        "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-017-reality-flag"
      },
      {
        "id": "paitd-002-person-vocabulary",
        "title": "Person Is The Plain Alias For OneRoster User",
        "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-002-person-vocabulary"
      },
      {
        "id": "paitd-004-point-in-time-memberships",
        "title": "Memberships Are Effective-Dated And Answered By AsOfDate",
        "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-004-point-in-time-memberships"
      },
      {
        "id": "paitd-103-query-model",
        "title": "API Axis: Query Model",
        "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-103-query-model"
      },
      {
        "id": "paitd-111-privacy-retention",
        "title": "API Axis: Privacy / Retention",
        "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-111-privacy-retention"
      }
    ]
  },
  {
    "name": "Reality filter",
    "apiRule": "Ordinary report endpoints default to reality=real for both person and place. Including test or synthetic data is explicit and scope-gated.",
    "rawDbRule": "Every ordinary raw report query over alpha.person or alpha.place includes reality = 'real' on each joined person/place role. Do not infer reality from names, campus labels, email domains, tenant names, or local exclude-lists.",
    "wrongPlausibleAnswer": "A test campus or AI-agent test user has valid memberships and therefore appears in production reports.",
    "exampleWhere": "p.reality = 'real' AND school.reality = 'real'",
    "itds": [
      {
        "id": "paitd-017-reality-flag",
        "title": "Reality Is A Typed Closed Flag On Person And Place, Set At Write Time",
        "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-017-reality-flag"
      },
      {
        "id": "paitd-103-query-model",
        "title": "API Axis: Query Model",
        "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-103-query-model"
      },
      {
        "id": "paitd-111-privacy-retention",
        "title": "API Axis: Privacy / Retention",
        "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-111-privacy-retention"
      }
    ]
  },
  {
    "name": "Point-in-time belonging rows",
    "apiRule": "Active membership, staff-assignment, program-participation, alpha-level, and age-grade routes require asOfDate and never offer a currentOnly shortcut.",
    "rawDbRule": "For alpha.place_membership, alpha.class_membership, alpha.staff_assignment_view, alpha.program_participation_view, alpha.alpha_level_history, and alpha.age_grade_history: begin_date null means excluded from every point-in-time computation. end_date null means still active for asOfDate on or after begin_date. Both null means excluded.",
    "wrongPlausibleAnswer": "A membership, staff assignment, program participation, alpha-level row, or age-grade row with no begin date looks active forever, or an ended row remains active after its end date.",
    "exampleWhere": "m.is_time_locatable IS TRUE AND m.begin_date <= :'as_of_date'::date AND (m.end_date IS NULL OR :'as_of_date'::date < m.end_date)",
    "itds": [
      {
        "id": "paitd-018-over-time-history",
        "title": "Alpha Level And Age Grade Keep Effective-Dated History, Read By AsOfDate",
        "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-018-over-time-history"
      },
      {
        "id": "paitd-004-point-in-time-memberships",
        "title": "Memberships Are Effective-Dated And Answered By AsOfDate",
        "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-004-point-in-time-memberships"
      },
      {
        "id": "paitd-014-staff-assignment-views",
        "title": "Staff Assignments Come From Ed-Fi Assignment Views Beyond OneRoster Roles",
        "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-014-staff-assignment-views"
      },
      {
        "id": "paitd-015-program-participation-views",
        "title": "Program Participation Is A People & Orgs Belonging View, Not Results Or Policy",
        "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-015-program-participation-views"
      },
      {
        "id": "paitd-103-query-model",
        "title": "API Axis: Query Model",
        "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-103-query-model"
      }
    ]
  },
  {
    "name": "Enrollment anchor and guide inverse",
    "apiRule": "firstEnrolledCourseGrade(student, subject), firstSingleGradeEnrollmentDate(student, subject), and studentsForGuide(guide, date) are first-class reads so consumers do not reconstruct them in app code.",
    "rawDbRule": "The enrollment-anchor raw paths use the surface-owned function/query for Curriculum subject, course_grade_mode, course_grade_levels, and single-grade context plus alpha.class_membership begin/end windows. The guide inverse raw path joins guide and student class_membership rows on tenant_id, school_id, and learning_group_id with the same asOfDate and reality=real filters.",
    "wrongPlausibleAnswer": "A report chooses the wrong school-year start date by parsing class names, treating multi-grade groups as single-grade, or doing an undocumented two-hop for guide rosters.",
    "exampleWhere": "guide_cm.role_kind = 'guide' AND student_cm.role_kind = 'student' AND guide_cm.learning_group_id = student_cm.learning_group_id AND student.reality = 'real'",
    "itds": [
      {
        "id": "paitd-004-point-in-time-memberships",
        "title": "Memberships Are Effective-Dated And Answered By AsOfDate",
        "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-004-point-in-time-memberships"
      },
      {
        "id": "paitd-102-read-shape",
        "title": "API Axis: Read Shape",
        "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-102-read-shape"
      },
      {
        "id": "paitd-103-query-model",
        "title": "API Axis: Query Model",
        "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-103-query-model"
      }
    ]
  },
  {
    "name": "Soft-delete, logical-delete, and tombstone hygiene",
    "apiRule": "Ordinary roster reads hide source_status = 'tobedeleted' and Ed-Fi is_deleted=true rows unless the caller requests an authorized audit or retention workflow.",
    "rawDbRule": "Ordinary raw roster queries add COALESCE(source_status, 'active') <> 'tobedeleted' for OneRoster-backed views and is_deleted=false for Ed-Fi-backed views. Historical audit queries may include tombstones or soft-deleted rows only when the job explicitly asks for retained delete history.",
    "wrongPlausibleAnswer": "A soft-deleted contact, deleted person, or retired place remains in a live roster because the raw query ignored the source lifecycle marker instead of matching the API hygiene filter.",
    "exampleWhere": "COALESCE(p.source_status, 'active') <> 'tobedeleted'",
    "itds": [
      {
        "id": "paitd-111-privacy-retention",
        "title": "API Axis: Privacy / Retention",
        "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-111-privacy-retention"
      }
    ]
  },
  {
    "name": "Sensitive profile scope",
    "apiRule": "Ordinary person and place lists do not include birth date, race or ethnicity, birth location, residence status, vendor profile usernames, or credential details.",
    "rawDbRule": "Do not join alpha.person_sensitive_profile or alpha.app_credential in ordinary roster queries. Query those objects only for a job that has explicit sensitive-profile or credential-status scope and relationship evidence.",
    "wrongPlausibleAnswer": "A raw query returns sensitive PII that the public API would correctly redact.",
    "exampleWhere": "Use alpha.person_sensitive_profile only in a privileged query path; ordinary alpha.person queries must not join it.",
    "itds": [
      {
        "id": "paitd-008-app-credentials",
        "title": "App Credentials Use Vault References, Never Roster Password Fields",
        "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-008-app-credentials"
      },
      {
        "id": "paitd-009-sensitive-profile-privacy",
        "title": "Sensitive Profiles Are Restricted, Not Default Roster Fields",
        "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-009-sensitive-profile-privacy"
      },
      {
        "id": "paitd-106-auth-shape",
        "title": "API Axis: Auth Shape",
        "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-106-auth-shape"
      }
    ]
  },
  {
    "name": "NWEA account grain",
    "apiRule": "For MAP reporting, a district place row is exactly one Brand x Modality NWEA account; a school reads its account through parent_place_id.",
    "rawDbRule": "Find a school's NWEA account by joining the school place to its parent district place, then read the parent's nwea_district_id plus locked brand and modality tags. Segment is a closed report slice on the place, with mixed reserved for multi-segment district rows. Never store or query a second school-level nwea_district_id.",
    "wrongPlausibleAnswer": "Physical and virtual schools combine in one NWEA account report because the raw query grouped by school name or a school-level tag.",
    "exampleWhere": "school.parent_place_id = district.place_id AND district.place_kind = 'district' AND district.nwea_district_id IS NOT NULL",
    "itds": [
      {
        "id": "paitd-003-place-nwea-boundary",
        "title": "Place Is The Plain Alias For OneRoster Org And District Is The NWEA Account",
        "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-003-place-nwea-boundary"
      },
      {
        "id": "paitd-006-tag-registry",
        "title": "Governed Tags Are Report Slices Only",
        "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-006-tag-registry"
      }
    ]
  },
  {
    "name": "Closed reporting enums",
    "apiRule": "Writes canonicalize alpha_level, grade_level, brand, segment, modality, and level aliases at the boundary and reject unreconciled live values instead of passing free text through.",
    "rawDbRule": "Raw migrations seed alpha.tag_definition and extension fields with only the closed values published in the enum catalog. The school level tag is locked to WL, LL, L1, L2, MS, and HS. Alias folds such as PK->-1, K->0, L3->MS, L4.*->HS, Physical->physical, and GT School->gt are write-time normalization rules, not read-time parsing recipes.",
    "wrongPlausibleAnswer": "A report silently splits Alpha School/alpha, GT School/gt, PK/-1, or L4.1/HS into separate cohorts because the consumer grouped on raw source labels.",
    "exampleWhere": "brand IN ('100for100','alpha','gt','limitless_education','montessorium','nextgen','nova_academy','novatio','sw_sales','texas_sports_academy','towermath','unbound','waypoint') AND modality IN ('physical','virtual') AND level IN ('WL','LL','L1','L2','MS','HS')",
    "itds": [
      {
        "id": "paitd-003-place-nwea-boundary",
        "title": "Place Is The Plain Alias For OneRoster Org And District Is The NWEA Account",
        "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-003-place-nwea-boundary"
      },
      {
        "id": "paitd-006-tag-registry",
        "title": "Governed Tags Are Report Slices Only",
        "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-006-tag-registry"
      },
      {
        "id": "paitd-007-tenure-and-grade-context",
        "title": "Tenure And Grade Context Are Typed Inputs, Not Dashboard Math",
        "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-007-tenure-and-grade-context"
      }
    ]
  },
  {
    "name": "Ed-Fi canonical view guardrail",
    "apiRule": "Guardian, guardian_relationship, staff_assignment, and program_participation endpoints read only canonical Ed-Fi records for the documented resource family, hide is_deleted=true rows by default, exclude drafts, resolve descriptors through edfi.descriptor_code, and join person/place ids through OneRoster sourcedId boundaries.",
    "rawDbRule": "Raw queries must use the documented alpha.*_view objects, or if auditing the underlying Ed-Fi tables directly, filter tenant_id, resource_name/collection_route, canonical state, is_deleted=false for ordinary reads, join descriptor fields through edfi.descriptor_code, and join student/staff/place references to OneRoster sourcedIds.",
    "wrongPlausibleAnswer": "A raw report includes deleted contacts, draft program rows, unresolved descriptor ids, or cross-system student ids that the API would correctly hide or resolve.",
    "exampleWhere": "FROM alpha.guardian_relationship_view gr JOIN alpha.guardian_view g ON g.tenant_id = gr.tenant_id AND g.guardian_id = gr.guardian_id WHERE gr.tenant_id = :'tenant_id' AND COALESCE(g.is_deleted, false) IS FALSE",
    "itds": [
      {
        "id": "paitd-012-edfi-second-upstream",
        "title": "Ed-Fi Administrative Records Are A Second View-Only Upstream",
        "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-012-edfi-second-upstream"
      },
      {
        "id": "paitd-013-guardian-views",
        "title": "Guardians Come From Ed-Fi Contact And StudentContactAssociation Views",
        "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-013-guardian-views"
      },
      {
        "id": "paitd-014-staff-assignment-views",
        "title": "Staff Assignments Come From Ed-Fi Assignment Views Beyond OneRoster Roles",
        "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-014-staff-assignment-views"
      },
      {
        "id": "paitd-015-program-participation-views",
        "title": "Program Participation Is A People & Orgs Belonging View, Not Results Or Policy",
        "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture#paitd-015-program-participation-views"
      }
    ]
  }
]
acronymGlossary
[
  {
    "term": "Alpha",
    "expansion": "The plain-language TimeBack surface for students, parents, teachers, and app-builder LLMs.",
    "use": "Use Alpha names such as person, place, and school_period instead of OneRoster jargon in this data dictionary."
  },
  {
    "term": "API",
    "expansion": "Application programming interface.",
    "use": "The HTTP surface that validates auth, filters, pagination, and writes."
  },
  {
    "term": "DB",
    "expansion": "Database.",
    "use": "The raw SQL path over documented Alpha views and extension tables."
  },
  {
    "term": "Ed-Fi",
    "expansion": "A standards-backed administrative student information model.",
    "use": "People & Orgs uses Ed-Fi only for guardian, staff-assignment, and program-participation who/where facts."
  },
  {
    "term": "ETag",
    "expansion": "HTTP entity tag.",
    "use": "The version validator returned on mutable reads and supplied through If-Match on updates."
  },
  {
    "term": "GDPR",
    "expansion": "General Data Protection Regulation style privacy and erasure handling.",
    "use": "The privacy model for redaction, audit, tombstones, and erasure."
  },
  {
    "term": "ITD",
    "expansion": "Important Technical Decision.",
    "use": "A pinned architecture decision that every dictionary field and rule traces to."
  },
  {
    "term": "JWT",
    "expansion": "JSON Web Token.",
    "use": "The signed bearer token that supplies tenant and relationship-scoped claims."
  },
  {
    "term": "LLM",
    "expansion": "Large language model.",
    "use": "An AI agent building apps or reports from these docs."
  },
  {
    "term": "MAP",
    "expansion": "Measures of Academic Progress.",
    "use": "NWEA MAP Growth test results live in Results/NWEAMap; People & Orgs supplies the student and place context."
  },
  {
    "term": "NWEA",
    "expansion": "Northwest Evaluation Association.",
    "use": "The organization behind MAP Growth; in this roster surface it appears only as the district account boundary."
  },
  {
    "term": "PII",
    "expansion": "Personally identifiable information.",
    "use": "Data that can identify or contact a person and must follow privacy scopes."
  },
  {
    "term": "SQL",
    "expansion": "Structured Query Language.",
    "use": "The raw database query language used by the first-class raw-DB path."
  },
  {
    "term": "UUID",
    "expansion": "Universally unique identifier.",
    "use": "The tenant key format inherited from platform.tenant."
  }
]
enumCatalog
[
  {
    "table": "alpha.canonical_enums",
    "field": "reality",
    "anchor": "enum-alpha-canonical-enums-reality",
    "type": "TEXT closed enum",
    "values": [
      {
        "value": "real",
        "meaning": "A production student, person, school, district, or roster place that belongs in ordinary customer reports.",
        "useWhen": "Use for real TimeBack people and places after the write boundary has verified the source classification.",
        "invalidWhen": "Invalid for QA accounts, AI-agent test rows, generated fixtures, or demo-only entities."
      },
      {
        "value": "test",
        "meaning": "A QA, staff-test, integration-test, or AI-agent test entity that must be excluded from ordinary reports.",
        "useWhen": "Use for entities intentionally created to test the surface or another app.",
        "invalidWhen": "Invalid for production students or schools even if their display name looks unusual."
      },
      {
        "value": "synthetic",
        "meaning": "Generated, seeded, anonymized, or fixture data that is useful for demos or development but not a real customer row.",
        "useWhen": "Use for generated seed rows, local fixtures, and anonymized examples.",
        "invalidWhen": "Invalid for a row imported from the authoritative SIS or TimeBack production source as a real entity."
      }
    ],
    "sourceEvidence": {
      "sourceTables": [
        "SIS school/person classification",
        "TimeBack production test/demo markers"
      ],
      "note": "Wave 2 decision: reality is set at the write boundary from authoritative source classification. Consumers never infer it from person names, campus names, email domains, or hand-maintained exclusion lists.",
      "values": [
        "real",
        "test",
        "synthetic"
      ]
    }
  },
  {
    "table": "alpha.canonical_enums",
    "field": "alpha_level",
    "anchor": "enum-alpha-canonical-enums-alpha-level",
    "type": "TEXT closed enum",
    "values": [
      {
        "value": "WL",
        "meaning": "WonderLab, the pre-K Alpha level. Live source alias validated 2026-06-09: PKBY folds here.",
        "useWhen": "Use for the pre-K Alpha level, point-in-time as of the roster date.",
        "invalidWhen": "Invalid for kindergarten, LearningLab, or any grade-level placement."
      },
      {
        "value": "LL",
        "meaning": "LearningLab, the K-1 Alpha level. Live source alias validated 2026-06-09: Linc folds here.",
        "useWhen": "Use for K-1 Alpha-level grouping, point-in-time as of the roster date.",
        "invalidWhen": "Invalid for WonderLab or numbered upper levels."
      },
      {
        "value": "L1",
        "meaning": "Level 1, the grade 2-3 Alpha level after live cohort confirmation.",
        "useWhen": "Use for the Alpha level spanning grade 2 through grade 3.",
        "invalidWhen": "Invalid for grade 4+ cohorts or for MAP working-grade state."
      },
      {
        "value": "L2",
        "meaning": "Level 2, the grade 4-5 Alpha level after live cohort confirmation.",
        "useWhen": "Use for the Alpha level spanning grade 4 through grade 5.",
        "invalidWhen": "Invalid for grade 2-3, middle school, high school, or Results working-grade state."
      },
      {
        "value": "MS",
        "meaning": "Middle School, the grade 6-8 Alpha level. Live source aliases validated 2026-06-09: Middle School and L3 fold here.",
        "useWhen": "Use for middle-school Alpha-level grouping.",
        "invalidWhen": "Invalid for high school or elementary level rows."
      },
      {
        "value": "HS",
        "meaning": "High School, the grade 9-12 Alpha level. Live source aliases validated 2026-06-09: High School, L4.1, L4.2, and L4.3 fold here.",
        "useWhen": "Use for high-school Alpha-level grouping.",
        "invalidWhen": "Invalid for middle-school or elementary level rows."
      }
    ],
    "sourceEvidence": {
      "sourceTable": "public.users_visibility.user_alpha_level",
      "observedAliases": {
        "WL": [
          "WL",
          "PKBY"
        ],
        "LL": [
          "LL",
          "Linc"
        ],
        "L1": [
          "L1"
        ],
        "L2": [
          "L2"
        ],
        "MS": [
          "MS",
          "Middle School",
          "L3"
        ],
        "HS": [
          "HS",
          "High School",
          "L4.1",
          "L4.2",
          "L4.3"
        ]
      },
      "nullCount": 24577,
      "uncoveredValues": []
    }
  },
  {
    "table": "alpha.canonical_enums",
    "field": "grade_level",
    "anchor": "enum-alpha-canonical-enums-grade-level",
    "type": "INTEGER closed enum",
    "values": [
      {
        "value": "-1",
        "meaning": "PreK. Live source aliases validated 2026-06-09: -1 and PK fold here.",
        "useWhen": "Use for pre-kindergarten age-grade or enrolled-grade context.",
        "invalidWhen": "Invalid for kindergarten or any student grade 1 through 12."
      },
      {
        "value": "0",
        "meaning": "Kindergarten. Live source aliases validated 2026-06-09: 0 and K fold here.",
        "useWhen": "Use for kindergarten age-grade or enrolled-grade context.",
        "invalidWhen": "Invalid for PreK or any numbered grade."
      },
      {
        "value": "1",
        "meaning": "Grade 1.",
        "useWhen": "Use for grade 1 age-grade, enrolled-grade, or course grade-level context.",
        "invalidWhen": "Invalid when parsed from names, class titles, test labels, or free text at read time."
      },
      {
        "value": "2",
        "meaning": "Grade 2.",
        "useWhen": "Use for grade 2 age-grade, enrolled-grade, or course grade-level context.",
        "invalidWhen": "Invalid when parsed from names, class titles, test labels, or free text at read time."
      },
      {
        "value": "3",
        "meaning": "Grade 3.",
        "useWhen": "Use for grade 3 age-grade, enrolled-grade, or course grade-level context.",
        "invalidWhen": "Invalid when parsed from names, class titles, test labels, or free text at read time."
      },
      {
        "value": "4",
        "meaning": "Grade 4. Live source aliases validated 2026-06-09: 4, 4TH_GRADE, and Grade_4 fold here.",
        "useWhen": "Use for grade 4 age-grade, enrolled-grade, or course grade-level context.",
        "invalidWhen": "Invalid when parsed from names, class titles, test labels, or free text at read time."
      },
      {
        "value": "5",
        "meaning": "Grade 5.",
        "useWhen": "Use for grade 5 age-grade, enrolled-grade, or course grade-level context.",
        "invalidWhen": "Invalid when parsed from names, class titles, test labels, or free text at read time."
      },
      {
        "value": "6",
        "meaning": "Grade 6.",
        "useWhen": "Use for grade 6 age-grade, enrolled-grade, or course grade-level context.",
        "invalidWhen": "Invalid when parsed from names, class titles, test labels, or free text at read time."
      },
      {
        "value": "7",
        "meaning": "Grade 7.",
        "useWhen": "Use for grade 7 age-grade, enrolled-grade, or course grade-level context.",
        "invalidWhen": "Invalid when parsed from names, class titles, test labels, or free text at read time."
      },
      {
        "value": "8",
        "meaning": "Grade 8.",
        "useWhen": "Use for grade 8 age-grade, enrolled-grade, or course grade-level context.",
        "invalidWhen": "Invalid when parsed from names, class titles, test labels, or free text at read time."
      },
      {
        "value": "9",
        "meaning": "Grade 9.",
        "useWhen": "Use for grade 9 age-grade, enrolled-grade, or course grade-level context.",
        "invalidWhen": "Invalid when parsed from names, class titles, test labels, or free text at read time."
      },
      {
        "value": "10",
        "meaning": "Grade 10.",
        "useWhen": "Use for grade 10 age-grade, enrolled-grade, or course grade-level context.",
        "invalidWhen": "Invalid when parsed from names, class titles, test labels, or free text at read time."
      },
      {
        "value": "11",
        "meaning": "Grade 11.",
        "useWhen": "Use for grade 11 age-grade, enrolled-grade, or course grade-level context.",
        "invalidWhen": "Invalid when parsed from names, class titles, test labels, or free text at read time."
      },
      {
        "value": "12",
        "meaning": "Grade 12.",
        "useWhen": "Use for grade 12 age-grade, enrolled-grade, or course grade-level context.",
        "invalidWhen": "Invalid when parsed from names, class titles, test labels, or free text at read time."
      }
    ],
    "sourceEvidence": {
      "sourceTable": "public.users.grades",
      "observedAliases": {
        "0": [
          "0",
          "K"
        ],
        "4": [
          "4",
          "4TH_GRADE",
          "Grade_4"
        ],
        "-1": [
          "-1",
          "PK"
        ]
      },
      "uncoveredValues": [
        {
          "value": "13",
          "count": 112,
          "action": "Reject or reconcile at the write boundary; do not publish as canonical K-12 grade_level."
        }
      ]
    }
  },
  {
    "table": "alpha.canonical_enums",
    "field": "brand",
    "anchor": "enum-alpha-canonical-enums-brand",
    "type": "TEXT closed enum",
    "values": [
      {
        "value": "100for100",
        "meaning": "100for100 brand. Live active org validation found this brand in the campus taxonomy intersected with production org rows.",
        "useWhen": "Use for NWEA-account district and school rows whose typed brand is 100for100.",
        "invalidWhen": "Invalid as a fallback for Alpha, GT, Texas Sports Academy, or partner brands."
      },
      {
        "value": "alpha",
        "meaning": "Alpha School brand. Live source aliases include Alpha, Alpha School, Alpha Anywhere, Alpha School campus names, and 2 Hour Learning legacy names.",
        "useWhen": "Use for Alpha School physical and virtual NWEA-account rows.",
        "invalidWhen": "Invalid for GT School, Texas Sports Academy, or non-Alpha partner schools."
      },
      {
        "value": "gt",
        "meaning": "GT School brand. Live aliases include GT School and GT Anywhere.",
        "useWhen": "Use for GT physical or virtual NWEA-account rows.",
        "invalidWhen": "Invalid for Alpha or partner school rows."
      },
      {
        "value": "limitless_education",
        "meaning": "Limitless Education brand observed in live active org rows.",
        "useWhen": "Use for schools whose typed brand is Limitless Education.",
        "invalidWhen": "Invalid for generic partner rows without that brand assignment."
      },
      {
        "value": "montessorium",
        "meaning": "Montessorium brand observed in live active org rows.",
        "useWhen": "Use for Montessorium school rows.",
        "invalidWhen": "Invalid for Alpha, GT, or Texas Sports Academy rows."
      },
      {
        "value": "nextgen",
        "meaning": "NextGen brand observed in live active org rows.",
        "useWhen": "Use for NextGen Academy or NextGen tutoring rows.",
        "invalidWhen": "Invalid for unrelated partner schools."
      },
      {
        "value": "nova_academy",
        "meaning": "Nova Academy brand observed in live active org rows.",
        "useWhen": "Use for Nova Academy campuses.",
        "invalidWhen": "Invalid for Novatio; that is a separate brand value."
      },
      {
        "value": "novatio",
        "meaning": "Novatio brand observed in live active org rows.",
        "useWhen": "Use for Novatio rows.",
        "invalidWhen": "Invalid for Nova Academy rows."
      },
      {
        "value": "sw_sales",
        "meaning": "SW Sales segment/brand value observed across Allendale and similar live active org rows.",
        "useWhen": "Use when the production taxonomy classifies the school as SW Sales.",
        "invalidWhen": "Invalid for Alpha-owned campuses or Texas Sports Academy rows."
      },
      {
        "value": "texas_sports_academy",
        "meaning": "Texas Sports Academy brand. Live aliases include Texas Sports Academy, TSA, TSA Online, and TSA sport/prep campus names.",
        "useWhen": "Use for Texas Sports Academy physical and virtual accounts.",
        "invalidWhen": "Invalid for Alpha, GT, or non-TSA partner rows."
      },
      {
        "value": "towermath",
        "meaning": "TowerMath brand observed in live active org rows.",
        "useWhen": "Use for TowerMath rows.",
        "invalidWhen": "Invalid for Alpha math products unless the typed brand is TowerMath."
      },
      {
        "value": "unbound",
        "meaning": "Unbound brand observed in live active org rows.",
        "useWhen": "Use for Unbound Academy rows.",
        "invalidWhen": "Invalid for other partner schools."
      },
      {
        "value": "waypoint",
        "meaning": "Waypoint brand observed in live active org rows.",
        "useWhen": "Use for Waypoint Academy rows.",
        "invalidWhen": "Invalid for other partner schools."
      }
    ],
    "sourceEvidence": {
      "sourceTable": "public.orgs",
      "activeOrgRows": 162,
      "taxonomyMatchedRows": 118,
      "taxonomyUnmatchedRows": 44,
      "brandValues": [
        "100for100",
        "alpha",
        "gt",
        "limitless_education",
        "montessorium",
        "nextgen",
        "nova_academy",
        "novatio",
        "sw_sales",
        "texas_sports_academy",
        "towermath",
        "unbound",
        "waypoint"
      ],
      "segmentValues": [
        "charter",
        "private",
        "sw_sales",
        "virtual",
        "mixed"
      ],
      "modalityValues": [
        "physical",
        "virtual"
      ],
      "note": "Production orgs do not yet store typed brand/segment columns. The closed lists were validated by intersecting live active org rows with the existing TimeBack campus taxonomy, then freezing write-boundary canonical values. Unmatched active orgs require reconciliation; they do not create an unknown enum value."
    }
  },
  {
    "table": "alpha.canonical_enums",
    "field": "segment",
    "anchor": "enum-alpha-canonical-enums-segment",
    "type": "TEXT closed enum",
    "values": [
      {
        "value": "charter",
        "meaning": "Charter-school segment observed in live active org rows.",
        "useWhen": "Use for schools whose typed segment is charter.",
        "invalidWhen": "Invalid for private, virtual, or SW Sales rows."
      },
      {
        "value": "private",
        "meaning": "Private-school segment observed in live active org rows.",
        "useWhen": "Use for private school campuses and district accounts.",
        "invalidWhen": "Invalid for virtual-only, charter, or SW Sales rows."
      },
      {
        "value": "sw_sales",
        "meaning": "SW Sales segment observed in live active org rows.",
        "useWhen": "Use for schools typed into the SW Sales segment.",
        "invalidWhen": "Invalid for Alpha private/virtual rows unless the write boundary explicitly assigns SW Sales."
      },
      {
        "value": "virtual",
        "meaning": "Virtual segment observed in live active org rows.",
        "useWhen": "Use for schools or accounts whose segment is virtual.",
        "invalidWhen": "Invalid for physical private or charter segment rows; modality still remains physical or virtual separately."
      },
      {
        "value": "mixed",
        "meaning": "District/account rollup reserved for a district spanning multiple segments.",
        "useWhen": "Use only on a district/account row that intentionally spans more than one segment.",
        "invalidWhen": "Invalid on an ordinary school row or as a substitute for unknown."
      }
    ],
    "sourceEvidence": {
      "sourceTable": "public.orgs",
      "activeOrgRows": 162,
      "taxonomyMatchedRows": 118,
      "taxonomyUnmatchedRows": 44,
      "brandValues": [
        "100for100",
        "alpha",
        "gt",
        "limitless_education",
        "montessorium",
        "nextgen",
        "nova_academy",
        "novatio",
        "sw_sales",
        "texas_sports_academy",
        "towermath",
        "unbound",
        "waypoint"
      ],
      "segmentValues": [
        "charter",
        "private",
        "sw_sales",
        "virtual",
        "mixed"
      ],
      "modalityValues": [
        "physical",
        "virtual"
      ],
      "note": "Production orgs do not yet store typed brand/segment columns. The closed lists were validated by intersecting live active org rows with the existing TimeBack campus taxonomy, then freezing write-boundary canonical values. Unmatched active orgs require reconciliation; they do not create an unknown enum value."
    }
  },
  {
    "table": "alpha.canonical_enums",
    "field": "modality",
    "anchor": "enum-alpha-canonical-enums-modality",
    "type": "TEXT closed enum",
    "values": [
      {
        "value": "physical",
        "meaning": "The NWEA account is for the physical-school modality of a brand. Live source aliases validated 2026-06-09: Physical folds here.",
        "useWhen": "Use for the district or school place row representing the physical NWEA account or child school.",
        "invalidWhen": "Invalid for virtual accounts or for a mixed/hybrid account."
      },
      {
        "value": "virtual",
        "meaning": "The NWEA account is for the virtual-school modality of a brand. Live source aliases validated 2026-06-09: Virtual folds here.",
        "useWhen": "Use for the district or school place row representing the virtual NWEA account or child school.",
        "invalidWhen": "Invalid for physical accounts or for a mixed/hybrid account."
      }
    ],
    "sourceEvidence": {
      "sourceTable": "public.orgs",
      "activeOrgRows": 162,
      "taxonomyMatchedRows": 118,
      "taxonomyUnmatchedRows": 44,
      "brandValues": [
        "100for100",
        "alpha",
        "gt",
        "limitless_education",
        "montessorium",
        "nextgen",
        "nova_academy",
        "novatio",
        "sw_sales",
        "texas_sports_academy",
        "towermath",
        "unbound",
        "waypoint"
      ],
      "segmentValues": [
        "charter",
        "private",
        "sw_sales",
        "virtual",
        "mixed"
      ],
      "modalityValues": [
        "physical",
        "virtual"
      ],
      "note": "Production orgs do not yet store typed brand/segment columns. The closed lists were validated by intersecting live active org rows with the existing TimeBack campus taxonomy, then freezing write-boundary canonical values. Unmatched active orgs require reconciliation; they do not create an unknown enum value."
    }
  },
  {
    "table": "alpha.canonical_enums",
    "field": "level",
    "anchor": "enum-alpha-canonical-enums-level",
    "type": "TEXT closed enum",
    "values": [
      {
        "value": "WL",
        "meaning": "WonderLab, the pre-K Alpha level. Live source alias validated 2026-06-09: PKBY folds here.",
        "useWhen": "Use for the pre-K Alpha level, point-in-time as of the roster date.",
        "invalidWhen": "Invalid for kindergarten, LearningLab, or any grade-level placement."
      },
      {
        "value": "LL",
        "meaning": "LearningLab, the K-1 Alpha level. Live source alias validated 2026-06-09: Linc folds here.",
        "useWhen": "Use for K-1 Alpha-level grouping, point-in-time as of the roster date.",
        "invalidWhen": "Invalid for WonderLab or numbered upper levels."
      },
      {
        "value": "L1",
        "meaning": "Level 1, the grade 2-3 Alpha level after live cohort confirmation.",
        "useWhen": "Use for the Alpha level spanning grade 2 through grade 3.",
        "invalidWhen": "Invalid for grade 4+ cohorts or for MAP working-grade state."
      },
      {
        "value": "L2",
        "meaning": "Level 2, the grade 4-5 Alpha level after live cohort confirmation.",
        "useWhen": "Use for the Alpha level spanning grade 4 through grade 5.",
        "invalidWhen": "Invalid for grade 2-3, middle school, high school, or Results working-grade state."
      },
      {
        "value": "MS",
        "meaning": "Middle School, the grade 6-8 Alpha level. Live source aliases validated 2026-06-09: Middle School and L3 fold here.",
        "useWhen": "Use for middle-school Alpha-level grouping.",
        "invalidWhen": "Invalid for high school or elementary level rows."
      },
      {
        "value": "HS",
        "meaning": "High School, the grade 9-12 Alpha level. Live source aliases validated 2026-06-09: High School, L4.1, L4.2, and L4.3 fold here.",
        "useWhen": "Use for high-school Alpha-level grouping.",
        "invalidWhen": "Invalid for middle-school or elementary level rows."
      }
    ],
    "sourceEvidence": {
      "sourceTable": "public.users_visibility.user_alpha_level",
      "observedAliases": {
        "WL": [
          "WL",
          "PKBY"
        ],
        "LL": [
          "LL",
          "Linc"
        ],
        "L1": [
          "L1"
        ],
        "L2": [
          "L2"
        ],
        "MS": [
          "MS",
          "Middle School",
          "L3"
        ],
        "HS": [
          "HS",
          "High School",
          "L4.1",
          "L4.2",
          "L4.3"
        ]
      },
      "nullCount": 24577,
      "uncoveredValues": []
    }
  },
  {
    "table": "alpha.person",
    "field": "source_status",
    "anchor": "field-alpha-person-source-status",
    "type": "TEXT enum",
    "values": [
      {
        "value": "active",
        "meaning": "The delta row is current and should be inserted or updated.",
        "useWhen": "Use only in delta row status fields. Alpha keeps this only as source provenance; ordinary active-as-of queries still use dated memberships.",
        "invalidWhen": "Invalid in bulk rows or when the row should be deleted."
      },
      {
        "value": "tobedeleted",
        "meaning": "The delta row indicates the source wants this object deleted or retired.",
        "useWhen": "Use only in delta row status fields. Alpha keeps this only as source provenance; ordinary active-as-of queries still use dated memberships.",
        "invalidWhen": "Invalid in bulk rows or when the source object remains active."
      }
    ]
  },
  {
    "table": "alpha.person",
    "field": "reality",
    "anchor": "field-alpha-person-reality",
    "type": "TEXT enum",
    "values": [
      {
        "value": "real",
        "meaning": "A production student, person, school, district, or roster place that belongs in ordinary customer reports.",
        "useWhen": "Use for real TimeBack people and places after the write boundary has verified the source classification.",
        "invalidWhen": "Invalid for QA accounts, AI-agent test rows, generated fixtures, or demo-only entities."
      },
      {
        "value": "test",
        "meaning": "A QA, staff-test, integration-test, or AI-agent test entity that must be excluded from ordinary reports.",
        "useWhen": "Use for entities intentionally created to test the surface or another app.",
        "invalidWhen": "Invalid for production students or schools even if their display name looks unusual."
      },
      {
        "value": "synthetic",
        "meaning": "Generated, seeded, anonymized, or fixture data that is useful for demos or development but not a real customer row.",
        "useWhen": "Use for generated seed rows, local fixtures, and anonymized examples.",
        "invalidWhen": "Invalid for a row imported from the authoritative SIS or TimeBack production source as a real entity."
      }
    ]
  },
  {
    "table": "alpha.person",
    "field": "is_enabled",
    "anchor": "field-alpha-person-is-enabled",
    "type": "BOOLEAN",
    "values": [
      {
        "value": "true",
        "meaning": "The fact is asserted by the source or by the Alpha surface.",
        "useWhen": "Use only when the field's own constraints say the fact is true.",
        "invalidWhen": "Invalid when guessed from names, labels, dates, tags, or another field."
      },
      {
        "value": "false",
        "meaning": "The fact is explicitly not asserted.",
        "useWhen": "Use only when the source or surface stores an explicit false value.",
        "invalidWhen": "Invalid when a missing value should remain unknown."
      }
    ]
  },
  {
    "table": "alpha.person",
    "field": "grade_levels",
    "anchor": "field-alpha-person-grade-levels",
    "type": "INTEGER[] closed enum",
    "values": [
      {
        "value": "-1",
        "meaning": "PreK. Live source aliases validated 2026-06-09: -1 and PK fold here.",
        "useWhen": "Use for pre-kindergarten age-grade or enrolled-grade context.",
        "invalidWhen": "Invalid for kindergarten or any student grade 1 through 12."
      },
      {
        "value": "0",
        "meaning": "Kindergarten. Live source aliases validated 2026-06-09: 0 and K fold here.",
        "useWhen": "Use for kindergarten age-grade or enrolled-grade context.",
        "invalidWhen": "Invalid for PreK or any numbered grade."
      },
      {
        "value": "1",
        "meaning": "Grade 1.",
        "useWhen": "Use for grade 1 age-grade, enrolled-grade, or course grade-level context.",
        "invalidWhen": "Invalid when parsed from names, class titles, test labels, or free text at read time."
      },
      {
        "value": "2",
        "meaning": "Grade 2.",
        "useWhen": "Use for grade 2 age-grade, enrolled-grade, or course grade-level context.",
        "invalidWhen": "Invalid when parsed from names, class titles, test labels, or free text at read time."
      },
      {
        "value": "3",
        "meaning": "Grade 3.",
        "useWhen": "Use for grade 3 age-grade, enrolled-grade, or course grade-level context.",
        "invalidWhen": "Invalid when parsed from names, class titles, test labels, or free text at read time."
      },
      {
        "value": "4",
        "meaning": "Grade 4. Live source aliases validated 2026-06-09: 4, 4TH_GRADE, and Grade_4 fold here.",
        "useWhen": "Use for grade 4 age-grade, enrolled-grade, or course grade-level context.",
        "invalidWhen": "Invalid when parsed from names, class titles, test labels, or free text at read time."
      },
      {
        "value": "5",
        "meaning": "Grade 5.",
        "useWhen": "Use for grade 5 age-grade, enrolled-grade, or course grade-level context.",
        "invalidWhen": "Invalid when parsed from names, class titles, test labels, or free text at read time."
      },
      {
        "value": "6",
        "meaning": "Grade 6.",
        "useWhen": "Use for grade 6 age-grade, enrolled-grade, or course grade-level context.",
        "invalidWhen": "Invalid when parsed from names, class titles, test labels, or free text at read time."
      },
      {
        "value": "7",
        "meaning": "Grade 7.",
        "useWhen": "Use for grade 7 age-grade, enrolled-grade, or course grade-level context.",
        "invalidWhen": "Invalid when parsed from names, class titles, test labels, or free text at read time."
      },
      {
        "value": "8",
        "meaning": "Grade 8.",
        "useWhen": "Use for grade 8 age-grade, enrolled-grade, or course grade-level context.",
        "invalidWhen": "Invalid when parsed from names, class titles, test labels, or free text at read time."
      },
      {
        "value": "9",
        "meaning": "Grade 9.",
        "useWhen": "Use for grade 9 age-grade, enrolled-grade, or course grade-level context.",
        "invalidWhen": "Invalid when parsed from names, class titles, test labels, or free text at read time."
      },
      {
        "value": "10",
        "meaning": "Grade 10.",
        "useWhen": "Use for grade 10 age-grade, enrolled-grade, or course grade-level context.",
        "invalidWhen": "Invalid when parsed from names, class titles, test labels, or free text at read time."
      },
      {
        "value": "11",
        "meaning": "Grade 11.",
        "useWhen": "Use for grade 11 age-grade, enrolled-grade, or course grade-level context.",
        "invalidWhen": "Invalid when parsed from names, class titles, test labels, or free text at read time."
      },
      {
        "value": "12",
        "meaning": "Grade 12.",
        "useWhen": "Use for grade 12 age-grade, enrolled-grade, or course grade-level context.",
        "invalidWhen": "Invalid when parsed from names, class titles, test labels, or free text at read time."
      }
    ]
  },
  {
    "table": "alpha.person",
    "field": "age_grade",
    "anchor": "field-alpha-person-age-grade",
    "type": "INTEGER closed enum",
    "values": [
      {
        "value": "-1",
        "meaning": "PreK. Live source aliases validated 2026-06-09: -1 and PK fold here.",
        "useWhen": "Use for pre-kindergarten age-grade or enrolled-grade context.",
        "invalidWhen": "Invalid for kindergarten or any student grade 1 through 12."
      },
      {
        "value": "0",
        "meaning": "Kindergarten. Live source aliases validated 2026-06-09: 0 and K fold here.",
        "useWhen": "Use for kindergarten age-grade or enrolled-grade context.",
        "invalidWhen": "Invalid for PreK or any numbered grade."
      },
      {
        "value": "1",
        "meaning": "Grade 1.",
        "useWhen": "Use for grade 1 age-grade, enrolled-grade, or course grade-level context.",
        "invalidWhen": "Invalid when parsed from names, class titles, test labels, or free text at read time."
      },
      {
        "value": "2",
        "meaning": "Grade 2.",
        "useWhen": "Use for grade 2 age-grade, enrolled-grade, or course grade-level context.",
        "invalidWhen": "Invalid when parsed from names, class titles, test labels, or free text at read time."
      },
      {
        "value": "3",
        "meaning": "Grade 3.",
        "useWhen": "Use for grade 3 age-grade, enrolled-grade, or course grade-level context.",
        "invalidWhen": "Invalid when parsed from names, class titles, test labels, or free text at read time."
      },
      {
        "value": "4",
        "meaning": "Grade 4. Live source aliases validated 2026-06-09: 4, 4TH_GRADE, and Grade_4 fold here.",
        "useWhen": "Use for grade 4 age-grade, enrolled-grade, or course grade-level context.",
        "invalidWhen": "Invalid when parsed from names, class titles, test labels, or free text at read time."
      },
      {
        "value": "5",
        "meaning": "Grade 5.",
        "useWhen": "Use for grade 5 age-grade, enrolled-grade, or course grade-level context.",
        "invalidWhen": "Invalid when parsed from names, class titles, test labels, or free text at read time."
      },
      {
        "value": "6",
        "meaning": "Grade 6.",
        "useWhen": "Use for grade 6 age-grade, enrolled-grade, or course grade-level context.",
        "invalidWhen": "Invalid when parsed from names, class titles, test labels, or free text at read time."
      },
      {
        "value": "7",
        "meaning": "Grade 7.",
        "useWhen": "Use for grade 7 age-grade, enrolled-grade, or course grade-level context.",
        "invalidWhen": "Invalid when parsed from names, class titles, test labels, or free text at read time."
      },
      {
        "value": "8",
        "meaning": "Grade 8.",
        "useWhen": "Use for grade 8 age-grade, enrolled-grade, or course grade-level context.",
        "invalidWhen": "Invalid when parsed from names, class titles, test labels, or free text at read time."
      },
      {
        "value": "9",
        "meaning": "Grade 9.",
        "useWhen": "Use for grade 9 age-grade, enrolled-grade, or course grade-level context.",
        "invalidWhen": "Invalid when parsed from names, class titles, test labels, or free text at read time."
      },
      {
        "value": "10",
        "meaning": "Grade 10.",
        "useWhen": "Use for grade 10 age-grade, enrolled-grade, or course grade-level context.",
        "invalidWhen": "Invalid when parsed from names, class titles, test labels, or free text at read time."
      },
      {
        "value": "11",
        "meaning": "Grade 11.",
        "useWhen": "Use for grade 11 age-grade, enrolled-grade, or course grade-level context.",
        "invalidWhen": "Invalid when parsed from names, class titles, test labels, or free text at read time."
      },
      {
        "value": "12",
        "meaning": "Grade 12.",
        "useWhen": "Use for grade 12 age-grade, enrolled-grade, or course grade-level context.",
        "invalidWhen": "Invalid when parsed from names, class titles, test labels, or free text at read time."
      }
    ]
  },
  {
    "table": "alpha.place",
    "field": "source_status",
    "anchor": "field-alpha-place-source-status",
    "type": "TEXT enum",
    "values": [
      {
        "value": "active",
        "meaning": "The delta row is current and should be inserted or updated.",
        "useWhen": "Use only in delta row status fields. Alpha keeps this only as source provenance; ordinary active-as-of queries still use dated memberships.",
        "invalidWhen": "Invalid in bulk rows or when the row should be deleted."
      },
      {
        "value": "tobedeleted",
        "meaning": "The delta row indicates the source wants this object deleted or retired.",
        "useWhen": "Use only in delta row status fields. Alpha keeps this only as source provenance; ordinary active-as-of queries still use dated memberships.",
        "invalidWhen": "Invalid in bulk rows or when the source object remains active."
      }
    ]
  },
  {
    "table": "alpha.place",
    "field": "reality",
    "anchor": "field-alpha-place-reality",
    "type": "TEXT enum",
    "values": [
      {
        "value": "real",
        "meaning": "A production student, person, school, district, or roster place that belongs in ordinary customer reports.",
        "useWhen": "Use for real TimeBack people and places after the write boundary has verified the source classification.",
        "invalidWhen": "Invalid for QA accounts, AI-agent test rows, generated fixtures, or demo-only entities."
      },
      {
        "value": "test",
        "meaning": "A QA, staff-test, integration-test, or AI-agent test entity that must be excluded from ordinary reports.",
        "useWhen": "Use for entities intentionally created to test the surface or another app.",
        "invalidWhen": "Invalid for production students or schools even if their display name looks unusual."
      },
      {
        "value": "synthetic",
        "meaning": "Generated, seeded, anonymized, or fixture data that is useful for demos or development but not a real customer row.",
        "useWhen": "Use for generated seed rows, local fixtures, and anonymized examples.",
        "invalidWhen": "Invalid for a row imported from the authoritative SIS or TimeBack production source as a real entity."
      }
    ]
  },
  {
    "table": "alpha.place",
    "field": "place_kind",
    "anchor": "field-alpha-place-place-kind",
    "type": "TEXT enum",
    "values": [
      {
        "value": "department",
        "meaning": "Department-level organization, usually below a school or district.",
        "useWhen": "Use for academic/administrative departments that can own courses or roles but should not satisfy school_sourced_id references.",
        "invalidWhen": "Invalid as the target of classes.school_sourced_id or enrollments.school_sourced_id."
      },
      {
        "value": "school",
        "meaning": "School/building organization and the required org type for school-scoped class, enrollment, and line-item references.",
        "useWhen": "Use when a row can be referenced by classes.school_sourced_id, enrollments.school_sourced_id, or line_items.school_sourced_id.",
        "invalidWhen": "Invalid for district or department rows that should only be hierarchy parents."
      },
      {
        "value": "district",
        "meaning": "District organization that commonly parents school rows.",
        "useWhen": "Use as parent_sourced_id for schools or for district-level roles/courses where the source sends them.",
        "invalidWhen": "Invalid as a class/enrollment school_sourced_id target."
      },
      {
        "value": "local",
        "meaning": "Local education authority or local-level organization.",
        "useWhen": "Use when the source models an LEA/local authority distinct from a district.",
        "invalidWhen": "Invalid as a school_sourced_id target unless the source profile explicitly says local rows are schools."
      },
      {
        "value": "state",
        "meaning": "State-level education agency or authority.",
        "useWhen": "Use as a hierarchy ancestor or role scope when supplied by the source.",
        "invalidWhen": "Invalid as a class/enrollment school_sourced_id target."
      },
      {
        "value": "national",
        "meaning": "National-level education agency or authority.",
        "useWhen": "Use only for national hierarchy/role contexts supplied by the source.",
        "invalidWhen": "Invalid as a school_sourced_id target or ordinary school parent when a district/local row exists."
      }
    ]
  },
  {
    "table": "alpha.place",
    "field": "brand",
    "anchor": "field-alpha-place-brand",
    "type": "TEXT enum",
    "values": [
      {
        "value": "100for100",
        "meaning": "100for100 brand. Live active org validation found this brand in the campus taxonomy intersected with production org rows.",
        "useWhen": "Use for NWEA-account district and school rows whose typed brand is 100for100.",
        "invalidWhen": "Invalid as a fallback for Alpha, GT, Texas Sports Academy, or partner brands."
      },
      {
        "value": "alpha",
        "meaning": "Alpha School brand. Live source aliases include Alpha, Alpha School, Alpha Anywhere, Alpha School campus names, and 2 Hour Learning legacy names.",
        "useWhen": "Use for Alpha School physical and virtual NWEA-account rows.",
        "invalidWhen": "Invalid for GT School, Texas Sports Academy, or non-Alpha partner schools."
      },
      {
        "value": "gt",
        "meaning": "GT School brand. Live aliases include GT School and GT Anywhere.",
        "useWhen": "Use for GT physical or virtual NWEA-account rows.",
        "invalidWhen": "Invalid for Alpha or partner school rows."
      },
      {
        "value": "limitless_education",
        "meaning": "Limitless Education brand observed in live active org rows.",
        "useWhen": "Use for schools whose typed brand is Limitless Education.",
        "invalidWhen": "Invalid for generic partner rows without that brand assignment."
      },
      {
        "value": "montessorium",
        "meaning": "Montessorium brand observed in live active org rows.",
        "useWhen": "Use for Montessorium school rows.",
        "invalidWhen": "Invalid for Alpha, GT, or Texas Sports Academy rows."
      },
      {
        "value": "nextgen",
        "meaning": "NextGen brand observed in live active org rows.",
        "useWhen": "Use for NextGen Academy or NextGen tutoring rows.",
        "invalidWhen": "Invalid for unrelated partner schools."
      },
      {
        "value": "nova_academy",
        "meaning": "Nova Academy brand observed in live active org rows.",
        "useWhen": "Use for Nova Academy campuses.",
        "invalidWhen": "Invalid for Novatio; that is a separate brand value."
      },
      {
        "value": "novatio",
        "meaning": "Novatio brand observed in live active org rows.",
        "useWhen": "Use for Novatio rows.",
        "invalidWhen": "Invalid for Nova Academy rows."
      },
      {
        "value": "sw_sales",
        "meaning": "SW Sales segment/brand value observed across Allendale and similar live active org rows.",
        "useWhen": "Use when the production taxonomy classifies the school as SW Sales.",
        "invalidWhen": "Invalid for Alpha-owned campuses or Texas Sports Academy rows."
      },
      {
        "value": "texas_sports_academy",
        "meaning": "Texas Sports Academy brand. Live aliases include Texas Sports Academy, TSA, TSA Online, and TSA sport/prep campus names.",
        "useWhen": "Use for Texas Sports Academy physical and virtual accounts.",
        "invalidWhen": "Invalid for Alpha, GT, or non-TSA partner rows."
      },
      {
        "value": "towermath",
        "meaning": "TowerMath brand observed in live active org rows.",
        "useWhen": "Use for TowerMath rows.",
        "invalidWhen": "Invalid for Alpha math products unless the typed brand is TowerMath."
      },
      {
        "value": "unbound",
        "meaning": "Unbound brand observed in live active org rows.",
        "useWhen": "Use for Unbound Academy rows.",
        "invalidWhen": "Invalid for other partner schools."
      },
      {
        "value": "waypoint",
        "meaning": "Waypoint brand observed in live active org rows.",
        "useWhen": "Use for Waypoint Academy rows.",
        "invalidWhen": "Invalid for other partner schools."
      }
    ]
  },
  {
    "table": "alpha.place",
    "field": "modality",
    "anchor": "field-alpha-place-modality",
    "type": "TEXT enum",
    "values": [
      {
        "value": "physical",
        "meaning": "The NWEA account is for the physical-school modality of a brand. Live source aliases validated 2026-06-09: Physical folds here.",
        "useWhen": "Use for the district or school place row representing the physical NWEA account or child school.",
        "invalidWhen": "Invalid for virtual accounts or for a mixed/hybrid account."
      },
      {
        "value": "virtual",
        "meaning": "The NWEA account is for the virtual-school modality of a brand. Live source aliases validated 2026-06-09: Virtual folds here.",
        "useWhen": "Use for the district or school place row representing the virtual NWEA account or child school.",
        "invalidWhen": "Invalid for physical accounts or for a mixed/hybrid account."
      }
    ]
  },
  {
    "table": "alpha.place",
    "field": "segment",
    "anchor": "field-alpha-place-segment",
    "type": "TEXT enum",
    "values": [
      {
        "value": "charter",
        "meaning": "Charter-school segment observed in live active org rows.",
        "useWhen": "Use for schools whose typed segment is charter.",
        "invalidWhen": "Invalid for private, virtual, or SW Sales rows."
      },
      {
        "value": "private",
        "meaning": "Private-school segment observed in live active org rows.",
        "useWhen": "Use for private school campuses and district accounts.",
        "invalidWhen": "Invalid for virtual-only, charter, or SW Sales rows."
      },
      {
        "value": "sw_sales",
        "meaning": "SW Sales segment observed in live active org rows.",
        "useWhen": "Use for schools typed into the SW Sales segment.",
        "invalidWhen": "Invalid for Alpha private/virtual rows unless the write boundary explicitly assigns SW Sales."
      },
      {
        "value": "virtual",
        "meaning": "Virtual segment observed in live active org rows.",
        "useWhen": "Use for schools or accounts whose segment is virtual.",
        "invalidWhen": "Invalid for physical private or charter segment rows; modality still remains physical or virtual separately."
      },
      {
        "value": "mixed",
        "meaning": "District/account rollup reserved for a district spanning multiple segments.",
        "useWhen": "Use only on a district/account row that intentionally spans more than one segment.",
        "invalidWhen": "Invalid on an ordinary school row or as a substitute for unknown."
      }
    ]
  },
  {
    "table": "alpha.place",
    "field": "level",
    "anchor": "field-alpha-place-level",
    "type": "TEXT closed enum",
    "values": [
      {
        "value": "WL",
        "meaning": "WonderLab, the pre-K Alpha level. Live source alias validated 2026-06-09: PKBY folds here.",
        "useWhen": "Use for the pre-K Alpha level, point-in-time as of the roster date.",
        "invalidWhen": "Invalid for kindergarten, LearningLab, or any grade-level placement."
      },
      {
        "value": "LL",
        "meaning": "LearningLab, the K-1 Alpha level. Live source alias validated 2026-06-09: Linc folds here.",
        "useWhen": "Use for K-1 Alpha-level grouping, point-in-time as of the roster date.",
        "invalidWhen": "Invalid for WonderLab or numbered upper levels."
      },
      {
        "value": "L1",
        "meaning": "Level 1, the grade 2-3 Alpha level after live cohort confirmation.",
        "useWhen": "Use for the Alpha level spanning grade 2 through grade 3.",
        "invalidWhen": "Invalid for grade 4+ cohorts or for MAP working-grade state."
      },
      {
        "value": "L2",
        "meaning": "Level 2, the grade 4-5 Alpha level after live cohort confirmation.",
        "useWhen": "Use for the Alpha level spanning grade 4 through grade 5.",
        "invalidWhen": "Invalid for grade 2-3, middle school, high school, or Results working-grade state."
      },
      {
        "value": "MS",
        "meaning": "Middle School, the grade 6-8 Alpha level. Live source aliases validated 2026-06-09: Middle School and L3 fold here.",
        "useWhen": "Use for middle-school Alpha-level grouping.",
        "invalidWhen": "Invalid for high school or elementary level rows."
      },
      {
        "value": "HS",
        "meaning": "High School, the grade 9-12 Alpha level. Live source aliases validated 2026-06-09: High School, L4.1, L4.2, and L4.3 fold here.",
        "useWhen": "Use for high-school Alpha-level grouping.",
        "invalidWhen": "Invalid for middle-school or elementary level rows."
      }
    ]
  },
  {
    "table": "alpha.person_ext",
    "field": "age_grade",
    "anchor": "field-alpha-person-ext-age-grade",
    "type": "INTEGER closed enum",
    "values": [
      {
        "value": "-1",
        "meaning": "PreK. Live source aliases validated 2026-06-09: -1 and PK fold here.",
        "useWhen": "Use for pre-kindergarten age-grade or enrolled-grade context.",
        "invalidWhen": "Invalid for kindergarten or any student grade 1 through 12."
      },
      {
        "value": "0",
        "meaning": "Kindergarten. Live source aliases validated 2026-06-09: 0 and K fold here.",
        "useWhen": "Use for kindergarten age-grade or enrolled-grade context.",
        "invalidWhen": "Invalid for PreK or any numbered grade."
      },
      {
        "value": "1",
        "meaning": "Grade 1.",
        "useWhen": "Use for grade 1 age-grade, enrolled-grade, or course grade-level context.",
        "invalidWhen": "Invalid when parsed from names, class titles, test labels, or free text at read time."
      },
      {
        "value": "2",
        "meaning": "Grade 2.",
        "useWhen": "Use for grade 2 age-grade, enrolled-grade, or course grade-level context.",
        "invalidWhen": "Invalid when parsed from names, class titles, test labels, or free text at read time."
      },
      {
        "value": "3",
        "meaning": "Grade 3.",
        "useWhen": "Use for grade 3 age-grade, enrolled-grade, or course grade-level context.",
        "invalidWhen": "Invalid when parsed from names, class titles, test labels, or free text at read time."
      },
      {
        "value": "4",
        "meaning": "Grade 4. Live source aliases validated 2026-06-09: 4, 4TH_GRADE, and Grade_4 fold here.",
        "useWhen": "Use for grade 4 age-grade, enrolled-grade, or course grade-level context.",
        "invalidWhen": "Invalid when parsed from names, class titles, test labels, or free text at read time."
      },
      {
        "value": "5",
        "meaning": "Grade 5.",
        "useWhen": "Use for grade 5 age-grade, enrolled-grade, or course grade-level context.",
        "invalidWhen": "Invalid when parsed from names, class titles, test labels, or free text at read time."
      },
      {
        "value": "6",
        "meaning": "Grade 6.",
        "useWhen": "Use for grade 6 age-grade, enrolled-grade, or course grade-level context.",
        "invalidWhen": "Invalid when parsed from names, class titles, test labels, or free text at read time."
      },
      {
        "value": "7",
        "meaning": "Grade 7.",
        "useWhen": "Use for grade 7 age-grade, enrolled-grade, or course grade-level context.",
        "invalidWhen": "Invalid when parsed from names, class titles, test labels, or free text at read time."
      },
      {
        "value": "8",
        "meaning": "Grade 8.",
        "useWhen": "Use for grade 8 age-grade, enrolled-grade, or course grade-level context.",
        "invalidWhen": "Invalid when parsed from names, class titles, test labels, or free text at read time."
      },
      {
        "value": "9",
        "meaning": "Grade 9.",
        "useWhen": "Use for grade 9 age-grade, enrolled-grade, or course grade-level context.",
        "invalidWhen": "Invalid when parsed from names, class titles, test labels, or free text at read time."
      },
      {
        "value": "10",
        "meaning": "Grade 10.",
        "useWhen": "Use for grade 10 age-grade, enrolled-grade, or course grade-level context.",
        "invalidWhen": "Invalid when parsed from names, class titles, test labels, or free text at read time."
      },
      {
        "value": "11",
        "meaning": "Grade 11.",
        "useWhen": "Use for grade 11 age-grade, enrolled-grade, or course grade-level context.",
        "invalidWhen": "Invalid when parsed from names, class titles, test labels, or free text at read time."
      },
      {
        "value": "12",
        "meaning": "Grade 12.",
        "useWhen": "Use for grade 12 age-grade, enrolled-grade, or course grade-level context.",
        "invalidWhen": "Invalid when parsed from names, class titles, test labels, or free text at read time."
      }
    ]
  },
  {
    "table": "alpha.person_ext",
    "field": "reality",
    "anchor": "field-alpha-person-ext-reality",
    "type": "TEXT enum",
    "values": [
      {
        "value": "real",
        "meaning": "A production student, person, school, district, or roster place that belongs in ordinary customer reports.",
        "useWhen": "Use for real TimeBack people and places after the write boundary has verified the source classification.",
        "invalidWhen": "Invalid for QA accounts, AI-agent test rows, generated fixtures, or demo-only entities."
      },
      {
        "value": "test",
        "meaning": "A QA, staff-test, integration-test, or AI-agent test entity that must be excluded from ordinary reports.",
        "useWhen": "Use for entities intentionally created to test the surface or another app.",
        "invalidWhen": "Invalid for production students or schools even if their display name looks unusual."
      },
      {
        "value": "synthetic",
        "meaning": "Generated, seeded, anonymized, or fixture data that is useful for demos or development but not a real customer row.",
        "useWhen": "Use for generated seed rows, local fixtures, and anonymized examples.",
        "invalidWhen": "Invalid for a row imported from the authoritative SIS or TimeBack production source as a real entity."
      }
    ]
  },
  {
    "table": "alpha.place_ext",
    "field": "reality",
    "anchor": "field-alpha-place-ext-reality",
    "type": "TEXT enum",
    "values": [
      {
        "value": "real",
        "meaning": "A production student, person, school, district, or roster place that belongs in ordinary customer reports.",
        "useWhen": "Use for real TimeBack people and places after the write boundary has verified the source classification.",
        "invalidWhen": "Invalid for QA accounts, AI-agent test rows, generated fixtures, or demo-only entities."
      },
      {
        "value": "test",
        "meaning": "A QA, staff-test, integration-test, or AI-agent test entity that must be excluded from ordinary reports.",
        "useWhen": "Use for entities intentionally created to test the surface or another app.",
        "invalidWhen": "Invalid for production students or schools even if their display name looks unusual."
      },
      {
        "value": "synthetic",
        "meaning": "Generated, seeded, anonymized, or fixture data that is useful for demos or development but not a real customer row.",
        "useWhen": "Use for generated seed rows, local fixtures, and anonymized examples.",
        "invalidWhen": "Invalid for a row imported from the authoritative SIS or TimeBack production source as a real entity."
      }
    ]
  },
  {
    "table": "alpha.alpha_level_history",
    "field": "alpha_level",
    "anchor": "field-alpha-alpha-level-history-alpha-level",
    "type": "TEXT closed enum",
    "values": [
      {
        "value": "WL",
        "meaning": "WonderLab, the pre-K Alpha level. Live source alias validated 2026-06-09: PKBY folds here.",
        "useWhen": "Use for the pre-K Alpha level, point-in-time as of the roster date.",
        "invalidWhen": "Invalid for kindergarten, LearningLab, or any grade-level placement."
      },
      {
        "value": "LL",
        "meaning": "LearningLab, the K-1 Alpha level. Live source alias validated 2026-06-09: Linc folds here.",
        "useWhen": "Use for K-1 Alpha-level grouping, point-in-time as of the roster date.",
        "invalidWhen": "Invalid for WonderLab or numbered upper levels."
      },
      {
        "value": "L1",
        "meaning": "Level 1, the grade 2-3 Alpha level after live cohort confirmation.",
        "useWhen": "Use for the Alpha level spanning grade 2 through grade 3.",
        "invalidWhen": "Invalid for grade 4+ cohorts or for MAP working-grade state."
      },
      {
        "value": "L2",
        "meaning": "Level 2, the grade 4-5 Alpha level after live cohort confirmation.",
        "useWhen": "Use for the Alpha level spanning grade 4 through grade 5.",
        "invalidWhen": "Invalid for grade 2-3, middle school, high school, or Results working-grade state."
      },
      {
        "value": "MS",
        "meaning": "Middle School, the grade 6-8 Alpha level. Live source aliases validated 2026-06-09: Middle School and L3 fold here.",
        "useWhen": "Use for middle-school Alpha-level grouping.",
        "invalidWhen": "Invalid for high school or elementary level rows."
      },
      {
        "value": "HS",
        "meaning": "High School, the grade 9-12 Alpha level. Live source aliases validated 2026-06-09: High School, L4.1, L4.2, and L4.3 fold here.",
        "useWhen": "Use for high-school Alpha-level grouping.",
        "invalidWhen": "Invalid for middle-school or elementary level rows."
      }
    ]
  },
  {
    "table": "alpha.alpha_level_history",
    "field": "is_time_locatable",
    "anchor": "field-alpha-alpha-level-history-is-time-locatable",
    "type": "BOOLEAN",
    "values": [
      {
        "value": "true",
        "meaning": "The fact is asserted by the source or by the Alpha surface.",
        "useWhen": "Use only when the field's own constraints say the fact is true.",
        "invalidWhen": "Invalid when guessed from names, labels, dates, tags, or another field."
      },
      {
        "value": "false",
        "meaning": "The fact is explicitly not asserted.",
        "useWhen": "Use only when the source or surface stores an explicit false value.",
        "invalidWhen": "Invalid when a missing value should remain unknown."
      }
    ]
  },
  {
    "table": "alpha.age_grade_history",
    "field": "age_grade",
    "anchor": "field-alpha-age-grade-history-age-grade",
    "type": "INTEGER closed enum",
    "values": [
      {
        "value": "-1",
        "meaning": "PreK. Live source aliases validated 2026-06-09: -1 and PK fold here.",
        "useWhen": "Use for pre-kindergarten age-grade or enrolled-grade context.",
        "invalidWhen": "Invalid for kindergarten or any student grade 1 through 12."
      },
      {
        "value": "0",
        "meaning": "Kindergarten. Live source aliases validated 2026-06-09: 0 and K fold here.",
        "useWhen": "Use for kindergarten age-grade or enrolled-grade context.",
        "invalidWhen": "Invalid for PreK or any numbered grade."
      },
      {
        "value": "1",
        "meaning": "Grade 1.",
        "useWhen": "Use for grade 1 age-grade, enrolled-grade, or course grade-level context.",
        "invalidWhen": "Invalid when parsed from names, class titles, test labels, or free text at read time."
      },
      {
        "value": "2",
        "meaning": "Grade 2.",
        "useWhen": "Use for grade 2 age-grade, enrolled-grade, or course grade-level context.",
        "invalidWhen": "Invalid when parsed from names, class titles, test labels, or free text at read time."
      },
      {
        "value": "3",
        "meaning": "Grade 3.",
        "useWhen": "Use for grade 3 age-grade, enrolled-grade, or course grade-level context.",
        "invalidWhen": "Invalid when parsed from names, class titles, test labels, or free text at read time."
      },
      {
        "value": "4",
        "meaning": "Grade 4. Live source aliases validated 2026-06-09: 4, 4TH_GRADE, and Grade_4 fold here.",
        "useWhen": "Use for grade 4 age-grade, enrolled-grade, or course grade-level context.",
        "invalidWhen": "Invalid when parsed from names, class titles, test labels, or free text at read time."
      },
      {
        "value": "5",
        "meaning": "Grade 5.",
        "useWhen": "Use for grade 5 age-grade, enrolled-grade, or course grade-level context.",
        "invalidWhen": "Invalid when parsed from names, class titles, test labels, or free text at read time."
      },
      {
        "value": "6",
        "meaning": "Grade 6.",
        "useWhen": "Use for grade 6 age-grade, enrolled-grade, or course grade-level context.",
        "invalidWhen": "Invalid when parsed from names, class titles, test labels, or free text at read time."
      },
      {
        "value": "7",
        "meaning": "Grade 7.",
        "useWhen": "Use for grade 7 age-grade, enrolled-grade, or course grade-level context.",
        "invalidWhen": "Invalid when parsed from names, class titles, test labels, or free text at read time."
      },
      {
        "value": "8",
        "meaning": "Grade 8.",
        "useWhen": "Use for grade 8 age-grade, enrolled-grade, or course grade-level context.",
        "invalidWhen": "Invalid when parsed from names, class titles, test labels, or free text at read time."
      },
      {
        "value": "9",
        "meaning": "Grade 9.",
        "useWhen": "Use for grade 9 age-grade, enrolled-grade, or course grade-level context.",
        "invalidWhen": "Invalid when parsed from names, class titles, test labels, or free text at read time."
      },
      {
        "value": "10",
        "meaning": "Grade 10.",
        "useWhen": "Use for grade 10 age-grade, enrolled-grade, or course grade-level context.",
        "invalidWhen": "Invalid when parsed from names, class titles, test labels, or free text at read time."
      },
      {
        "value": "11",
        "meaning": "Grade 11.",
        "useWhen": "Use for grade 11 age-grade, enrolled-grade, or course grade-level context.",
        "invalidWhen": "Invalid when parsed from names, class titles, test labels, or free text at read time."
      },
      {
        "value": "12",
        "meaning": "Grade 12.",
        "useWhen": "Use for grade 12 age-grade, enrolled-grade, or course grade-level context.",
        "invalidWhen": "Invalid when parsed from names, class titles, test labels, or free text at read time."
      }
    ]
  },
  {
    "table": "alpha.age_grade_history",
    "field": "is_time_locatable",
    "anchor": "field-alpha-age-grade-history-is-time-locatable",
    "type": "BOOLEAN",
    "values": [
      {
        "value": "true",
        "meaning": "The fact is asserted by the source or by the Alpha surface.",
        "useWhen": "Use only when the field's own constraints say the fact is true.",
        "invalidWhen": "Invalid when guessed from names, labels, dates, tags, or another field."
      },
      {
        "value": "false",
        "meaning": "The fact is explicitly not asserted.",
        "useWhen": "Use only when the source or surface stores an explicit false value.",
        "invalidWhen": "Invalid when a missing value should remain unknown."
      }
    ]
  },
  {
    "table": "alpha.place_membership",
    "field": "role_kind",
    "anchor": "field-alpha-place-membership-role-kind",
    "type": "TEXT enum",
    "values": [
      {
        "value": "student",
        "meaning": "A learner whose roster context may feed Results and Events, but whose mastery and scores never live in People & Orgs.",
        "useWhen": "Use for source roles/enrollments that say student.",
        "invalidWhen": "Invalid for parents, guardians, staff, guides, or administrators."
      },
      {
        "value": "parent",
        "meaning": "A parent relationship for a student or school context.",
        "useWhen": "Use for the OneRoster parent role or a maintained source alias that folds to parent.",
        "invalidWhen": "Invalid for guardian when the source distinguishes guardian from parent."
      },
      {
        "value": "guardian",
        "meaning": "A guardian relationship for a student or school context.",
        "useWhen": "Use for the OneRoster guardian role or a maintained source alias that folds to guardian.",
        "invalidWhen": "Invalid for parent when the source distinguishes parent from guardian."
      },
      {
        "value": "relative",
        "meaning": "A family relationship that is not parent or guardian.",
        "useWhen": "Use for the OneRoster relative role.",
        "invalidWhen": "Invalid as a generic fallback for unknown family data."
      },
      {
        "value": "guide",
        "meaning": "A teacher or guide who works directly with students.",
        "useWhen": "Use for teacher source roles and approved aliases that TimeBack treats as instructional guides.",
        "invalidWhen": "Invalid for administrative-only or family relationship roles."
      },
      {
        "value": "staff",
        "meaning": "School staff who are not the student's primary instructional guide in this row.",
        "useWhen": "Use for aide, counselor, proctor, or similar staff roles when the source does not make them the guide.",
        "invalidWhen": "Invalid when the source role is teacher and the row should be guide."
      },
      {
        "value": "administrator",
        "meaning": "A district, site, system, or school administrator.",
        "useWhen": "Use for districtAdministrator, siteAdministrator, systemAdministrator, principal, or administrator source roles.",
        "invalidWhen": "Invalid for teachers, students, parents, or guardians."
      }
    ]
  },
  {
    "table": "alpha.place_membership",
    "field": "role_priority",
    "anchor": "field-alpha-place-membership-role-priority",
    "type": "TEXT enum",
    "values": [
      {
        "value": "primary",
        "meaning": "This is the user's primary role in the organization/date window.",
        "useWhen": "Use when one role should be treated as the main role for org-scoped lookups.",
        "invalidWhen": "Invalid if another role is already primary for the same user/org/window under the local profile."
      },
      {
        "value": "secondary",
        "meaning": "This is an additional non-primary role in the organization/date window.",
        "useWhen": "Use when the user has more than one org role.",
        "invalidWhen": "Invalid if the source intends the role to be primary."
      }
    ]
  },
  {
    "table": "alpha.place_membership",
    "field": "is_time_locatable",
    "anchor": "field-alpha-place-membership-is-time-locatable",
    "type": "BOOLEAN",
    "values": [
      {
        "value": "true",
        "meaning": "The fact is asserted by the source or by the Alpha surface.",
        "useWhen": "Use only when the field's own constraints say the fact is true.",
        "invalidWhen": "Invalid when guessed from names, labels, dates, tags, or another field."
      },
      {
        "value": "false",
        "meaning": "The fact is explicitly not asserted.",
        "useWhen": "Use only when the source or surface stores an explicit false value.",
        "invalidWhen": "Invalid when a missing value should remain unknown."
      }
    ]
  },
  {
    "table": "alpha.class_membership",
    "field": "role_kind",
    "anchor": "field-alpha-class-membership-role-kind",
    "type": "TEXT enum",
    "values": [
      {
        "value": "student",
        "meaning": "The person participates in the learning group as a learner.",
        "useWhen": "Use for source enrollments.role=student.",
        "invalidWhen": "Invalid for guide, proctor, or administrator rows."
      },
      {
        "value": "guide",
        "meaning": "The person teaches or guides the learning group.",
        "useWhen": "Use for source enrollments.role=teacher.",
        "invalidWhen": "Invalid for learners or non-instructional administrative access."
      },
      {
        "value": "proctor",
        "meaning": "The person supervises an assessment or activity context without being the guide.",
        "useWhen": "Use for source enrollments.role=proctor.",
        "invalidWhen": "Invalid as a substitute for guide when the source says teacher."
      },
      {
        "value": "administrator",
        "meaning": "The person has administrative participation in the learning group.",
        "useWhen": "Use for source enrollments.role=administrator.",
        "invalidWhen": "Invalid for students or guides."
      }
    ]
  },
  {
    "table": "alpha.class_membership",
    "field": "is_primary_guide",
    "anchor": "field-alpha-class-membership-is-primary-guide",
    "type": "BOOLEAN",
    "values": [
      {
        "value": "true",
        "meaning": "The fact is asserted by the source or by the Alpha surface.",
        "useWhen": "Use only when the field's own constraints say the fact is true.",
        "invalidWhen": "Invalid when guessed from names, labels, dates, tags, or another field."
      },
      {
        "value": "false",
        "meaning": "The fact is explicitly not asserted.",
        "useWhen": "Use only when the source or surface stores an explicit false value.",
        "invalidWhen": "Invalid when a missing value should remain unknown."
      }
    ]
  },
  {
    "table": "alpha.class_membership",
    "field": "is_time_locatable",
    "anchor": "field-alpha-class-membership-is-time-locatable",
    "type": "BOOLEAN",
    "values": [
      {
        "value": "true",
        "meaning": "The fact is asserted by the source or by the Alpha surface.",
        "useWhen": "Use only when the field's own constraints say the fact is true.",
        "invalidWhen": "Invalid when guessed from names, labels, dates, tags, or another field."
      },
      {
        "value": "false",
        "meaning": "The fact is explicitly not asserted.",
        "useWhen": "Use only when the source or surface stores an explicit false value.",
        "invalidWhen": "Invalid when a missing value should remain unknown."
      }
    ]
  },
  {
    "table": "alpha.school_period",
    "field": "source_status",
    "anchor": "field-alpha-school-period-source-status",
    "type": "TEXT enum",
    "values": [
      {
        "value": "active",
        "meaning": "The delta row is current and should be inserted or updated.",
        "useWhen": "Use only in delta row status fields. Alpha keeps this only as source provenance; ordinary active-as-of queries still use dated memberships.",
        "invalidWhen": "Invalid in bulk rows or when the row should be deleted."
      },
      {
        "value": "tobedeleted",
        "meaning": "The delta row indicates the source wants this object deleted or retired.",
        "useWhen": "Use only in delta row status fields. Alpha keeps this only as source provenance; ordinary active-as-of queries still use dated memberships.",
        "invalidWhen": "Invalid in bulk rows or when the source object remains active."
      }
    ]
  },
  {
    "table": "alpha.school_period",
    "field": "period_kind",
    "anchor": "field-alpha-school-period-period-kind",
    "type": "TEXT enum",
    "values": [
      {
        "value": "school_year",
        "meaning": "Whole school-year calendar window. Source alias: OneRoster schoolYear.",
        "useWhen": "Use when the period spans the school year and school_year is the ending year.",
        "invalidWhen": "Invalid for semester, term, or grading-period windows."
      },
      {
        "value": "semester",
        "meaning": "A semester within a school year. Source alias: OneRoster semester.",
        "useWhen": "Use when the school calendar is semester-based.",
        "invalidWhen": "Invalid for shorter terms or grading periods."
      },
      {
        "value": "term",
        "meaning": "A term that is not a semester. Source alias: OneRoster term.",
        "useWhen": "Use for quarter, trimester, or local term windows represented by OneRoster term.",
        "invalidWhen": "Invalid for a whole school year."
      },
      {
        "value": "grading_period",
        "meaning": "A reporting period used for gradebook context. Source alias: OneRoster gradingPeriod.",
        "useWhen": "Use when a downstream gradebook or Results rollup needs the grading-period context.",
        "invalidWhen": "Invalid when the period is only a semester or whole school year."
      }
    ]
  },
  {
    "table": "alpha.person_sensitive_profile",
    "field": "sex",
    "anchor": "field-alpha-person-sensitive-profile-sex",
    "type": "TEXT enum",
    "values": [
      {
        "value": "male",
        "meaning": "Demographic sex value supplied by the source system.",
        "useWhen": "Use only when the source system lawfully provides this value.",
        "invalidWhen": "Invalid if copied to logs or used outside OneRoster demographic exchange."
      },
      {
        "value": "female",
        "meaning": "Demographic sex value supplied by the source system.",
        "useWhen": "Use only when the source system lawfully provides this value.",
        "invalidWhen": "Invalid if copied to logs or used outside OneRoster demographic exchange."
      },
      {
        "value": "unspecified",
        "meaning": "The source system did not specify a male/female/other value.",
        "useWhen": "Use when the demographic value is intentionally unspecified.",
        "invalidWhen": "Invalid if used to guess or erase a known source value."
      },
      {
        "value": "other",
        "meaning": "The source system supplied a demographic sex value outside male/female/unspecified.",
        "useWhen": "Use only when that is the source-system value.",
        "invalidWhen": "Invalid if used as a catch-all for missing data."
      }
    ]
  },
  {
    "table": "alpha.person_sensitive_profile",
    "field": "race_ethnicity_flags",
    "anchor": "field-alpha-person-sensitive-profile-race-ethnicity-flags",
    "type": "JSONB object",
    "values": [
      {
        "value": "american_indian_or_alaska_native",
        "meaning": "Source-supplied race flag. It may be true at the same time as another race flag.",
        "useWhen": "Use only when the source demographics row supplies the value.",
        "invalidWhen": "Invalid if inferred from name, language, place, or another demographic field."
      },
      {
        "value": "asian",
        "meaning": "Source-supplied race flag. It may be true at the same time as another race flag.",
        "useWhen": "Use only when the source demographics row supplies the value.",
        "invalidWhen": "Invalid if inferred from name, language, place, or another demographic field."
      },
      {
        "value": "black_or_african_american",
        "meaning": "Source-supplied race flag. It may be true at the same time as another race flag.",
        "useWhen": "Use only when the source demographics row supplies the value.",
        "invalidWhen": "Invalid if inferred from name, language, place, or another demographic field."
      },
      {
        "value": "native_hawaiian_or_other_pacific_islander",
        "meaning": "Source-supplied race flag. It may be true at the same time as another race flag.",
        "useWhen": "Use only when the source demographics row supplies the value.",
        "invalidWhen": "Invalid if inferred from name, language, place, or another demographic field."
      },
      {
        "value": "white",
        "meaning": "Source-supplied race flag. It may be true at the same time as another race flag.",
        "useWhen": "Use only when the source demographics row supplies the value.",
        "invalidWhen": "Invalid if inferred from name, language, place, or another demographic field."
      },
      {
        "value": "two_or_more_races",
        "meaning": "Source-supplied indicator that the source reports two or more races.",
        "useWhen": "Use only when the source sends demographic_race_two_or_more_races.",
        "invalidWhen": "Invalid if computed by counting other flags at read time."
      },
      {
        "value": "hispanic_or_latino_ethnicity",
        "meaning": "Source-supplied ethnicity flag. It is independent of race flags.",
        "useWhen": "Use only when the source demographics row supplies the value.",
        "invalidWhen": "Invalid if inferred from name, language, place, or another demographic field."
      }
    ]
  },
  {
    "table": "alpha.person_sensitive_profile",
    "field": "birth_place_fields",
    "anchor": "field-alpha-person-sensitive-profile-birth-place-fields",
    "type": "JSONB object",
    "values": [
      {
        "value": "country_of_birth_code",
        "meaning": "Country of birth code from OneRoster demographics.",
        "useWhen": "Use only when lawfully supplied by the source.",
        "invalidWhen": "Invalid if guessed from current address, language, or school."
      },
      {
        "value": "state_of_birth_abbreviation",
        "meaning": "State or province of birth abbreviation from OneRoster demographics.",
        "useWhen": "Use only when lawfully supplied by the source.",
        "invalidWhen": "Invalid if guessed or normalized without a source value."
      },
      {
        "value": "city_of_birth",
        "meaning": "City of birth text from OneRoster demographics.",
        "useWhen": "Use only when lawfully supplied by the source.",
        "invalidWhen": "Invalid if logged, exposed publicly, or inferred."
      }
    ]
  },
  {
    "table": "alpha.guardian_view",
    "field": "is_deleted",
    "anchor": "field-alpha-guardian-view-is-deleted",
    "type": "BOOLEAN",
    "values": [
      {
        "value": "true",
        "meaning": "The fact is asserted by the source or by the Alpha surface.",
        "useWhen": "Use only when the field's own constraints say the fact is true.",
        "invalidWhen": "Invalid when guessed from names, labels, dates, tags, or another field."
      },
      {
        "value": "false",
        "meaning": "The fact is explicitly not asserted.",
        "useWhen": "Use only when the source or surface stores an explicit false value.",
        "invalidWhen": "Invalid when a missing value should remain unknown."
      }
    ]
  },
  {
    "table": "alpha.guardian_relationship_view",
    "field": "is_primary_contact",
    "anchor": "field-alpha-guardian-relationship-view-is-primary-contact",
    "type": "BOOLEAN",
    "values": [
      {
        "value": "true",
        "meaning": "The fact is asserted by the source or by the Alpha surface.",
        "useWhen": "Use only when the field's own constraints say the fact is true.",
        "invalidWhen": "Invalid when guessed from names, labels, dates, tags, or another field."
      },
      {
        "value": "false",
        "meaning": "The fact is explicitly not asserted.",
        "useWhen": "Use only when the source or surface stores an explicit false value.",
        "invalidWhen": "Invalid when a missing value should remain unknown."
      }
    ]
  },
  {
    "table": "alpha.guardian_relationship_view",
    "field": "is_legal_guardian",
    "anchor": "field-alpha-guardian-relationship-view-is-legal-guardian",
    "type": "BOOLEAN",
    "values": [
      {
        "value": "true",
        "meaning": "The fact is asserted by the source or by the Alpha surface.",
        "useWhen": "Use only when the field's own constraints say the fact is true.",
        "invalidWhen": "Invalid when guessed from names, labels, dates, tags, or another field."
      },
      {
        "value": "false",
        "meaning": "The fact is explicitly not asserted.",
        "useWhen": "Use only when the source or surface stores an explicit false value.",
        "invalidWhen": "Invalid when a missing value should remain unknown."
      }
    ]
  },
  {
    "table": "alpha.guardian_relationship_view",
    "field": "lives_with_student",
    "anchor": "field-alpha-guardian-relationship-view-lives-with-student",
    "type": "BOOLEAN",
    "values": [
      {
        "value": "true",
        "meaning": "The fact is asserted by the source or by the Alpha surface.",
        "useWhen": "Use only when the field's own constraints say the fact is true.",
        "invalidWhen": "Invalid when guessed from names, labels, dates, tags, or another field."
      },
      {
        "value": "false",
        "meaning": "The fact is explicitly not asserted.",
        "useWhen": "Use only when the source or surface stores an explicit false value.",
        "invalidWhen": "Invalid when a missing value should remain unknown."
      }
    ]
  },
  {
    "table": "alpha.guardian_relationship_view",
    "field": "is_emergency_contact",
    "anchor": "field-alpha-guardian-relationship-view-is-emergency-contact",
    "type": "BOOLEAN",
    "values": [
      {
        "value": "true",
        "meaning": "The fact is asserted by the source or by the Alpha surface.",
        "useWhen": "Use only when the field's own constraints say the fact is true.",
        "invalidWhen": "Invalid when guessed from names, labels, dates, tags, or another field."
      },
      {
        "value": "false",
        "meaning": "The fact is explicitly not asserted.",
        "useWhen": "Use only when the source or surface stores an explicit false value.",
        "invalidWhen": "Invalid when a missing value should remain unknown."
      }
    ]
  },
  {
    "table": "alpha.staff_assignment_view",
    "field": "is_time_locatable",
    "anchor": "field-alpha-staff-assignment-view-is-time-locatable",
    "type": "BOOLEAN",
    "values": [
      {
        "value": "true",
        "meaning": "The fact is asserted by the source or by the Alpha surface.",
        "useWhen": "Use only when the field's own constraints say the fact is true.",
        "invalidWhen": "Invalid when guessed from names, labels, dates, tags, or another field."
      },
      {
        "value": "false",
        "meaning": "The fact is explicitly not asserted.",
        "useWhen": "Use only when the source or surface stores an explicit false value.",
        "invalidWhen": "Invalid when a missing value should remain unknown."
      }
    ]
  },
  {
    "table": "alpha.program_participation_view",
    "field": "is_time_locatable",
    "anchor": "field-alpha-program-participation-view-is-time-locatable",
    "type": "BOOLEAN",
    "values": [
      {
        "value": "true",
        "meaning": "The fact is asserted by the source or by the Alpha surface.",
        "useWhen": "Use only when the field's own constraints say the fact is true.",
        "invalidWhen": "Invalid when guessed from names, labels, dates, tags, or another field."
      },
      {
        "value": "false",
        "meaning": "The fact is explicitly not asserted.",
        "useWhen": "Use only when the source or surface stores an explicit false value.",
        "invalidWhen": "Invalid when a missing value should remain unknown."
      }
    ]
  },
  {
    "table": "alpha.program_participation_view",
    "field": "source_program_resource",
    "anchor": "field-alpha-program-participation-view-source-program-resource",
    "type": "TEXT enum",
    "values": [
      {
        "value": "GeneralStudentProgramAssociation",
        "meaning": "Generic Ed-Fi student-program association.",
        "useWhen": "Use when the canonical record comes from GeneralStudentProgramAssociation.",
        "invalidWhen": "Invalid for specialized associations that the Ed-Fi surface names more specifically."
      },
      {
        "value": "StudentProgramAssociation",
        "meaning": "Ed-Fi student-program association family record.",
        "useWhen": "Use when the canonical record comes from StudentProgramAssociation or a direct equivalent.",
        "invalidWhen": "Invalid for unrelated attendance, discipline, transcript, or intervention-outcome records."
      },
      {
        "value": "SpecialEducationProgramAssociation",
        "meaning": "Special Education participation specialization when the Ed-Fi surface exposes it as a canonical program association.",
        "useWhen": "Use only for the Special Education program association.",
        "invalidWhen": "Invalid for outcomes, services effectiveness, or eligibility formulas."
      },
      {
        "value": "TitleIPartAProgramAssociation",
        "meaning": "Title I participation specialization when present in the Ed-Fi source.",
        "useWhen": "Use only for the Title I program association.",
        "invalidWhen": "Invalid for general program rows or outcome records."
      },
      {
        "value": "EnglishLearnerProgramAssociation",
        "meaning": "English Learner participation specialization when present in the Ed-Fi source.",
        "useWhen": "Use only for the English Learner program association.",
        "invalidWhen": "Invalid for language preference fields or test results."
      },
      {
        "value": "Section504ProgramAssociation",
        "meaning": "Section 504 participation specialization when present in the Ed-Fi source.",
        "useWhen": "Use only for the Section 504 program association.",
        "invalidWhen": "Invalid for service details or policy thresholds."
      },
      {
        "value": "FoodServiceProgramAssociation",
        "meaning": "Food service participation specialization when present in the Ed-Fi source.",
        "useWhen": "Use only for the Food Service program association.",
        "invalidWhen": "Invalid for finance records or eligibility calculations."
      }
    ]
  },
  {
    "table": "alpha.tag_definition",
    "field": "anchor",
    "anchor": "field-alpha-tag-definition-anchor",
    "type": "TEXT enum",
    "values": [
      {
        "value": "nwea_account",
        "meaning": "The tag applies to a place whose place_kind is district and which carries nwea_district_id.",
        "useWhen": "Use for locked brand and modality tags.",
        "invalidWhen": "Invalid on school rows or non-NWEA-account places."
      },
      {
        "value": "school",
        "meaning": "The tag applies to a place whose place_kind is school.",
        "useWhen": "Use for school-level report slicing dimensions such as level.",
        "invalidWhen": "Invalid for a relationship, foreign key, secret, or computed input."
      },
      {
        "value": "person",
        "meaning": "The tag applies to a person for reporting only.",
        "useWhen": "Use only for low-cardinality slices that are not relationships or sensitive secrets.",
        "invalidWhen": "Invalid for parent/guardian links, credentials, mastery, or policy formulas."
      }
    ]
  },
  {
    "table": "alpha.tag_definition",
    "field": "value_type",
    "anchor": "field-alpha-tag-definition-value-type",
    "type": "TEXT enum",
    "values": [
      {
        "value": "string",
        "meaning": "Allowed values are strings.",
        "useWhen": "Use for brand, modality, level, and similar labels.",
        "invalidWhen": "Invalid for dates or numeric bands."
      },
      {
        "value": "integer",
        "meaning": "Allowed values are integers.",
        "useWhen": "Use for a governed numeric slice.",
        "invalidWhen": "Invalid when values need decimal precision or units."
      },
      {
        "value": "boolean",
        "meaning": "Allowed values are true/false.",
        "useWhen": "Use for a governed reporting switch.",
        "invalidWhen": "Invalid when missing and false have different meanings."
      },
      {
        "value": "date",
        "meaning": "Allowed values are ISO dates.",
        "useWhen": "Use only for a report slice, not for point-in-time membership computations.",
        "invalidWhen": "Invalid when the date must be a real computed input column."
      }
    ]
  },
  {
    "table": "alpha.tag_definition",
    "field": "is_locked",
    "anchor": "field-alpha-tag-definition-is-locked",
    "type": "BOOLEAN",
    "values": [
      {
        "value": "true",
        "meaning": "The fact is asserted by the source or by the Alpha surface.",
        "useWhen": "Use only when the field's own constraints say the fact is true.",
        "invalidWhen": "Invalid when guessed from names, labels, dates, tags, or another field."
      },
      {
        "value": "false",
        "meaning": "The fact is explicitly not asserted.",
        "useWhen": "Use only when the source or surface stores an explicit false value.",
        "invalidWhen": "Invalid when a missing value should remain unknown."
      }
    ]
  },
  {
    "table": "alpha.object_tag",
    "field": "object_kind",
    "anchor": "field-alpha-object-tag-object-kind",
    "type": "TEXT enum",
    "values": [
      {
        "value": "person",
        "meaning": "The tag attaches to alpha.person.",
        "useWhen": "Use only when tag_definition.anchor allows person.",
        "invalidWhen": "Invalid when the tag describes a place or membership relationship."
      },
      {
        "value": "place",
        "meaning": "The tag attaches to alpha.place.",
        "useWhen": "Use for school, district, NWEA-account, brand, modality, or level slices when registered.",
        "invalidWhen": "Invalid when the tag value should be a real parent_place_id or nwea_district_id column."
      },
      {
        "value": "school_period",
        "meaning": "The tag attaches to alpha.school_period.",
        "useWhen": "Use for reporting slices only, not term math.",
        "invalidWhen": "Invalid when the period value is a computed input."
      },
      {
        "value": "place_membership",
        "meaning": "The tag attaches to alpha.place_membership.",
        "useWhen": "Use only for low-cardinality reporting dimensions registered for memberships.",
        "invalidWhen": "Invalid for person_id, place_id, begin_date, end_date, or role_kind."
      },
      {
        "value": "class_membership",
        "meaning": "The tag attaches to alpha.class_membership.",
        "useWhen": "Use only for low-cardinality reporting dimensions registered for class memberships.",
        "invalidWhen": "Invalid for class, school, person, date, or role relationships."
      }
    ]
  }
]
liveEnumEvidence
{
  "queriedAt": "2026-06-09T20:28:00Z",
  "queryTool": "node loop/nweamap/vendor/skill-pack-baseline/nwea-map-analysis/scripts/timeback-query.mjs --token-file ~/Documents/timeback-danny-mcp-creds",
  "productionDatabase": "app",
  "orgEvidence": {
    "sourceTable": "public.orgs",
    "activeOrgRows": 162,
    "taxonomyMatchedRows": 118,
    "taxonomyUnmatchedRows": 44,
    "brandValues": [
      "100for100",
      "alpha",
      "gt",
      "limitless_education",
      "montessorium",
      "nextgen",
      "nova_academy",
      "novatio",
      "sw_sales",
      "texas_sports_academy",
      "towermath",
      "unbound",
      "waypoint"
    ],
    "segmentValues": [
      "charter",
      "private",
      "sw_sales",
      "virtual",
      "mixed"
    ],
    "modalityValues": [
      "physical",
      "virtual"
    ],
    "note": "Production orgs do not yet store typed brand/segment columns. The closed lists were validated by intersecting live active org rows with the existing TimeBack campus taxonomy, then freezing write-boundary canonical values. Unmatched active orgs require reconciliation; they do not create an unknown enum value."
  },
  "alphaLevelEvidence": {
    "sourceTable": "public.users_visibility.user_alpha_level",
    "observedAliases": {
      "WL": [
        "WL",
        "PKBY"
      ],
      "LL": [
        "LL",
        "Linc"
      ],
      "L1": [
        "L1"
      ],
      "L2": [
        "L2"
      ],
      "MS": [
        "MS",
        "Middle School",
        "L3"
      ],
      "HS": [
        "HS",
        "High School",
        "L4.1",
        "L4.2",
        "L4.3"
      ]
    },
    "nullCount": 24577,
    "uncoveredValues": []
  },
  "gradeLevelEvidence": {
    "sourceTable": "public.users.grades",
    "observedAliases": {
      "0": [
        "0",
        "K"
      ],
      "4": [
        "4",
        "4TH_GRADE",
        "Grade_4"
      ],
      "-1": [
        "-1",
        "PK"
      ]
    },
    "uncoveredValues": [
      {
        "value": "13",
        "count": 112,
        "action": "Reject or reconcile at the write boundary; do not publish as canonical K-12 grade_level."
      }
    ]
  },
  "realityEvidence": {
    "sourceTables": [
      "SIS school/person classification",
      "TimeBack production test/demo markers"
    ],
    "note": "Wave 2 decision: reality is set at the write boundary from authoritative source classification. Consumers never infer it from person names, campus names, email domains, or hand-maintained exclusion lists.",
    "values": [
      "real",
      "test",
      "synthetic"
    ]
  }
}
aliasMap
{
  "generatedAt": "2026-06-11T00:00:00Z",
  "canonicalUrl": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture/",
  "upstream": {
    "rules": {
      "upstream_module": "oneroster+ed_fi"
    },
    "upstreamDictionaryUrl": "https://platform3-andymontgomery-9773s-projects.vercel.app/oneroster/1edtech/data_dictionary/",
    "edFiDictionaryUrl": "https://platform3-andymontgomery-9773s-projects.vercel.app/ed_fi/1edtech/data_dictionary/"
  },
  "aliasMap": [
    {
      "alphaObject": "person",
      "changeType": "rename+extend",
      "sourceType": "1edtech_alias_view_with_extension_join",
      "oneEdTechSource": "oneroster.users",
      "sourceAnchor": "https://platform3-andymontgomery-9773s-projects.vercel.app/oneroster/1edtech/data_dictionary/#table-oneroster-users",
      "baseView": "alpha.person_base",
      "surfaceView": "alpha.person",
      "extensionTables": [
        "alpha.person_ext"
      ],
      "coreWriteRoute": "Route sourced-field writes to the OneRoster 1EdTech users surface.",
      "extensionWriteRoute": "Write only admission_date, exit_date, age_grade, and reality to alpha.person_ext after the base person exists.",
      "meaning": "One human in the roster: student, parent or guardian, guide, staff member, or administrator. A person's roles are separate memberships, not hidden inside the person row.",
      "fields": [
        {
          "alphaField": "person_id",
          "sourceField": "sourced_id",
          "meaning": "Tenant-scoped person id.",
          "storageKind": "oneedtech_view_column"
        },
        {
          "alphaField": "source_status",
          "sourceField": "status",
          "meaning": "OneRoster lifecycle state, preserved for provenance.",
          "storageKind": "oneedtech_view_column"
        },
        {
          "alphaField": "source_updated_at",
          "sourceField": "date_last_modified",
          "meaning": "Source-system modified timestamp for delta rows.",
          "storageKind": "oneedtech_view_column"
        },
        {
          "alphaField": "is_enabled",
          "sourceField": "enabled_user",
          "meaning": "Whether the source system says the account is enabled.",
          "storageKind": "oneedtech_view_column"
        },
        {
          "alphaField": "username",
          "sourceField": "username",
          "meaning": "Roster username, never a password.",
          "storageKind": "oneedtech_view_column"
        },
        {
          "alphaField": "first_name",
          "sourceField": "given_name",
          "meaning": "Legal or source first name.",
          "storageKind": "oneedtech_view_column"
        },
        {
          "alphaField": "last_name",
          "sourceField": "family_name",
          "meaning": "Legal or source family name.",
          "storageKind": "oneedtech_view_column"
        },
        {
          "alphaField": "middle_name",
          "sourceField": "middle_name",
          "meaning": "Legal or source middle name.",
          "storageKind": "oneedtech_view_column"
        },
        {
          "alphaField": "preferred_first_name",
          "sourceField": "preferred_given_name",
          "meaning": "Preferred first name.",
          "storageKind": "oneedtech_view_column"
        },
        {
          "alphaField": "preferred_last_name",
          "sourceField": "preferred_family_name",
          "meaning": "Preferred last name.",
          "storageKind": "oneedtech_view_column"
        },
        {
          "alphaField": "email",
          "sourceField": "email",
          "meaning": "Contact email, subject to role-scoped privacy rules.",
          "storageKind": "oneedtech_view_column"
        },
        {
          "alphaField": "sms",
          "sourceField": "sms",
          "meaning": "SMS contact address.",
          "storageKind": "oneedtech_view_column"
        },
        {
          "alphaField": "phone",
          "sourceField": "phone",
          "meaning": "Phone contact.",
          "storageKind": "oneedtech_view_column"
        },
        {
          "alphaField": "family_or_agent_person_ids",
          "sourceField": "agent_sourced_ids",
          "meaning": "Explicit OneRoster agent relationships such as parent or guardian links.",
          "storageKind": "oneedtech_view_column"
        },
        {
          "alphaField": "grade_levels",
          "sourceField": "grades",
          "meaning": "Source grade values folded to the Alpha canonical grade vocabulary at write time.",
          "storageKind": "oneedtech_view_column"
        },
        {
          "alphaField": "primary_place_id",
          "sourceField": "primary_org_sourced_id",
          "meaning": "Source primary organization for the person.",
          "storageKind": "oneedtech_view_column"
        },
        {
          "alphaField": "admission_date",
          "sourceField": "alpha.person_ext.admission_date",
          "meaning": "Admission date used with asOfDate to compute tenure buckets.",
          "storageKind": "alpha_extend_table"
        },
        {
          "alphaField": "age_grade",
          "sourceField": "alpha.person_ext.age_grade",
          "meaning": "Canonical age-grade value set by the Alpha boundary; not parsed from names or test titles. Current convenience value; dated history lives in alpha.age_grade_history (PAITD-018).",
          "storageKind": "alpha_extend_table"
        },
        {
          "alphaField": "reality",
          "sourceField": "alpha.person_ext.reality",
          "meaning": "Typed closed reality flag: real, test, or synthetic. Set at write time from authoritative source classification; ordinary reports default to real (PAITD-017).",
          "storageKind": "alpha_extend_table"
        }
      ]
    },
    {
      "alphaObject": "place",
      "changeType": "rename+restrict+extend",
      "sourceType": "1edtech_alias_view_with_extension_join",
      "oneEdTechSource": "oneroster.orgs",
      "sourceAnchor": "https://platform3-andymontgomery-9773s-projects.vercel.app/oneroster/1edtech/data_dictionary/#table-oneroster-orgs",
      "baseView": "alpha.place_base",
      "surfaceView": "alpha.place",
      "extensionTables": [
        "alpha.place_ext",
        "alpha.object_tag"
      ],
      "coreWriteRoute": "Route sourced-field writes to the OneRoster 1EdTech orgs surface.",
      "extensionWriteRoute": "Write nwea_district_id and reality to alpha.place_ext and report-slice tags to alpha.object_tag only.",
      "meaning": "A district, school, level, department, or other roster place. For NWEA, district means exactly one Brand x Modality NWEA account.",
      "fields": [
        {
          "alphaField": "place_id",
          "sourceField": "sourced_id",
          "meaning": "Tenant-scoped place id.",
          "storageKind": "oneedtech_view_column"
        },
        {
          "alphaField": "source_status",
          "sourceField": "status",
          "meaning": "OneRoster lifecycle state.",
          "storageKind": "oneedtech_view_column"
        },
        {
          "alphaField": "source_updated_at",
          "sourceField": "date_last_modified",
          "meaning": "Source-system modified timestamp for delta rows.",
          "storageKind": "oneedtech_view_column"
        },
        {
          "alphaField": "name",
          "sourceField": "name",
          "meaning": "Place name.",
          "storageKind": "oneedtech_view_column"
        },
        {
          "alphaField": "place_kind",
          "sourceField": "type",
          "meaning": "Canonical place type. District and school are structural; tags may refine but never override type.",
          "storageKind": "oneedtech_view_column"
        },
        {
          "alphaField": "public_identifier",
          "sourceField": "identifier",
          "meaning": "Human-readable public identifier such as NCES id.",
          "storageKind": "oneedtech_view_column"
        },
        {
          "alphaField": "parent_place_id",
          "sourceField": "parent_sourced_id",
          "meaning": "Parent place in the stock OneRoster tree.",
          "storageKind": "oneedtech_view_column"
        },
        {
          "alphaField": "nwea_district_id",
          "sourceField": "alpha.place_ext.nwea_district_id",
          "meaning": "Required only when place_kind=district and the row is a Brand x Modality NWEA account.",
          "storageKind": "alpha_extend_table"
        },
        {
          "alphaField": "brand",
          "sourceField": "alpha.object_tag(tag_key=brand)",
          "meaning": "Locked registry tag anchored at nwea_account.",
          "storageKind": "alpha_extend_table"
        },
        {
          "alphaField": "modality",
          "sourceField": "alpha.object_tag(tag_key=modality)",
          "meaning": "Locked registry tag anchored at nwea_account; allowed values physical or virtual.",
          "storageKind": "alpha_extend_table"
        },
        {
          "alphaField": "level",
          "sourceField": "alpha.object_tag(tag_key=level)",
          "meaning": "Low-cardinality reporting dimension for school or program level.",
          "storageKind": "alpha_extend_table"
        },
        {
          "alphaField": "segment",
          "sourceField": "alpha.object_tag(tag_key=segment)",
          "meaning": "Closed governed reporting tag for the operating segment of a school or district; allowed values are seeded at setup and a place spanning more than one segment carries segment=mixed.",
          "storageKind": "alpha_extend_table"
        },
        {
          "alphaField": "reality",
          "sourceField": "alpha.place_ext.reality",
          "meaning": "Typed closed reality flag: real, test, or synthetic. Set at write time from authoritative source classification; ordinary reports default to real (PAITD-017).",
          "storageKind": "alpha_extend_table"
        }
      ]
    },
    {
      "alphaObject": "place_membership",
      "changeType": "rename+restrict",
      "sourceType": "1edtech_alias_view",
      "oneEdTechSource": "oneroster.roles",
      "sourceAnchor": "https://platform3-andymontgomery-9773s-projects.vercel.app/oneroster/1edtech/data_dictionary/#table-oneroster-roles",
      "baseView": "alpha.place_membership_base",
      "surfaceView": "alpha.place_membership",
      "extensionTables": [],
      "coreWriteRoute": "Route all writes to the OneRoster 1EdTech roles surface.",
      "extensionWriteRoute": "None. is_time_locatable is a view expression, not stored Alpha state.",
      "meaning": "A dated relationship saying what one person is in one place, such as parent, guardian, guide, student, administrator, or staff.",
      "fields": [
        {
          "alphaField": "membership_id",
          "sourceField": "sourced_id",
          "meaning": "Tenant-scoped membership id.",
          "storageKind": "oneedtech_view_column"
        },
        {
          "alphaField": "person_id",
          "sourceField": "user_sourced_id",
          "meaning": "Person who holds the role.",
          "storageKind": "oneedtech_view_column"
        },
        {
          "alphaField": "place_id",
          "sourceField": "org_sourced_id",
          "meaning": "Place where the role applies.",
          "storageKind": "oneedtech_view_column"
        },
        {
          "alphaField": "role_kind",
          "sourceField": "role",
          "meaning": "Canonical role enum with a maintained alias fold; never parsed from names or titles.",
          "storageKind": "oneedtech_view_column"
        },
        {
          "alphaField": "role_priority",
          "sourceField": "role_type",
          "meaning": "Primary or secondary role marker.",
          "storageKind": "oneedtech_view_column"
        },
        {
          "alphaField": "begin_date",
          "sourceField": "begin_date",
          "meaning": "Inclusive date when the membership becomes locatable.",
          "storageKind": "oneedtech_view_column"
        },
        {
          "alphaField": "end_date",
          "sourceField": "end_date",
          "meaning": "Exclusive date when the membership stops being active; null means still active after begin_date.",
          "storageKind": "oneedtech_view_column"
        },
        {
          "alphaField": "is_time_locatable",
          "sourceField": "view expression: begin_date is not null",
          "meaning": "True only when begin_date is non-null; consumers filter on this field instead of guessing at nulls.",
          "storageKind": "view_derived"
        },
        {
          "alphaField": "profile_id",
          "sourceField": "user_profile_sourced_id",
          "meaning": "Optional non-secret profile reference.",
          "storageKind": "oneedtech_view_column"
        }
      ]
    },
    {
      "alphaObject": "class_membership",
      "changeType": "rename+restrict",
      "sourceType": "1edtech_alias_view",
      "oneEdTechSource": "oneroster.enrollments",
      "sourceAnchor": "https://platform3-andymontgomery-9773s-projects.vercel.app/oneroster/1edtech/data_dictionary/#table-oneroster-enrollments",
      "baseView": "alpha.class_membership_base",
      "surfaceView": "alpha.class_membership",
      "extensionTables": [],
      "coreWriteRoute": "Route all writes to the OneRoster 1EdTech enrollments surface.",
      "extensionWriteRoute": "None. is_time_locatable is a view expression, not stored Alpha state.",
      "meaning": "A dated relationship saying that one person belongs to one learning group at one school. The detailed class/course object is not re-owned by this module.",
      "fields": [
        {
          "alphaField": "membership_id",
          "sourceField": "sourced_id",
          "meaning": "Tenant-scoped class membership id.",
          "storageKind": "oneedtech_view_column"
        },
        {
          "alphaField": "person_id",
          "sourceField": "user_sourced_id",
          "meaning": "Person in the learning group.",
          "storageKind": "oneedtech_view_column"
        },
        {
          "alphaField": "school_id",
          "sourceField": "school_sourced_id",
          "meaning": "School place for the membership.",
          "storageKind": "oneedtech_view_column"
        },
        {
          "alphaField": "learning_group_id",
          "sourceField": "class_sourced_id",
          "meaning": "OneRoster class id retained as a real relationship column.",
          "storageKind": "oneedtech_view_column"
        },
        {
          "alphaField": "role_kind",
          "sourceField": "role",
          "meaning": "Canonical enrollment role: student, teacher, proctor, or administrator.",
          "storageKind": "oneedtech_view_column"
        },
        {
          "alphaField": "is_primary_guide",
          "sourceField": "primary",
          "meaning": "Primary-teacher marker, valid only for guide/teacher rows.",
          "storageKind": "oneedtech_view_column"
        },
        {
          "alphaField": "begin_date",
          "sourceField": "begin_date",
          "meaning": "Inclusive date when the membership becomes locatable.",
          "storageKind": "oneedtech_view_column"
        },
        {
          "alphaField": "end_date",
          "sourceField": "end_date",
          "meaning": "Exclusive date when the membership stops being active; null means still active after begin_date.",
          "storageKind": "oneedtech_view_column"
        },
        {
          "alphaField": "is_time_locatable",
          "sourceField": "view expression: begin_date is not null",
          "meaning": "True only when begin_date is non-null.",
          "storageKind": "view_derived"
        }
      ]
    },
    {
      "alphaObject": "school_period",
      "changeType": "rename+restrict",
      "sourceType": "1edtech_alias_view",
      "oneEdTechSource": "oneroster.academic_sessions",
      "sourceAnchor": "https://platform3-andymontgomery-9773s-projects.vercel.app/oneroster/1edtech/data_dictionary/#table-oneroster-academic-sessions",
      "baseView": "alpha.school_period_base",
      "surfaceView": "alpha.school_period",
      "extensionTables": [],
      "coreWriteRoute": "Route all writes to the OneRoster 1EdTech academic_sessions surface.",
      "extensionWriteRoute": "None.",
      "meaning": "A school year, term, semester, or grading period used to answer roster questions as of a date.",
      "fields": [
        {
          "alphaField": "period_id",
          "sourceField": "sourced_id",
          "meaning": "Tenant-scoped school period id.",
          "storageKind": "oneedtech_view_column"
        },
        {
          "alphaField": "source_status",
          "sourceField": "status",
          "meaning": "OneRoster lifecycle state.",
          "storageKind": "oneedtech_view_column"
        },
        {
          "alphaField": "source_updated_at",
          "sourceField": "date_last_modified",
          "meaning": "Source-system modified timestamp for delta rows.",
          "storageKind": "oneedtech_view_column"
        },
        {
          "alphaField": "title",
          "sourceField": "title",
          "meaning": "Human title for the period.",
          "storageKind": "oneedtech_view_column"
        },
        {
          "alphaField": "period_kind",
          "sourceField": "type",
          "meaning": "Canonical period type; consumers never parse the title.",
          "storageKind": "oneedtech_view_column"
        },
        {
          "alphaField": "start_date",
          "sourceField": "start_date",
          "meaning": "Inclusive period start date.",
          "storageKind": "oneedtech_view_column"
        },
        {
          "alphaField": "end_date",
          "sourceField": "end_date",
          "meaning": "Exclusive period end date.",
          "storageKind": "oneedtech_view_column"
        },
        {
          "alphaField": "parent_period_id",
          "sourceField": "parent_sourced_id",
          "meaning": "Parent period relationship.",
          "storageKind": "oneedtech_view_column"
        },
        {
          "alphaField": "school_year",
          "sourceField": "school_year",
          "meaning": "Typed school-year value, not a string parsed from title.",
          "storageKind": "oneedtech_view_column"
        }
      ]
    },
    {
      "alphaObject": "person_sensitive_profile",
      "changeType": "restrict",
      "sourceType": "1edtech_restricted_view",
      "oneEdTechSource": "oneroster.demographics",
      "sourceAnchor": "https://platform3-andymontgomery-9773s-projects.vercel.app/oneroster/1edtech/data_dictionary/#table-oneroster-demographics",
      "baseView": "alpha.person_sensitive_profile_base",
      "surfaceView": "alpha.person_sensitive_profile",
      "extensionTables": [],
      "coreWriteRoute": "Route sourced-field writes to the OneRoster 1EdTech demographics surface.",
      "extensionWriteRoute": "None. Authorization and redaction are API/view restrictions, not copied storage.",
      "meaning": "Sensitive demographic facts kept out of ordinary roster lists and returned only through authorized self, guardian, or administrative views.",
      "fields": [
        {
          "alphaField": "person_id",
          "sourceField": "sourced_id",
          "meaning": "Person whose sensitive profile is described.",
          "storageKind": "oneedtech_view_column"
        },
        {
          "alphaField": "birth_date",
          "sourceField": "birth_date",
          "meaning": "Date of birth when lawfully supplied.",
          "storageKind": "oneedtech_view_column"
        },
        {
          "alphaField": "sex",
          "sourceField": "sex",
          "meaning": "Source demographic sex value.",
          "storageKind": "oneedtech_view_column"
        },
        {
          "alphaField": "race_ethnicity_flags",
          "sourceField": "race/ethnicity fields",
          "meaning": "Independent source flags; never inferred from names or places.",
          "storageKind": "oneedtech_view_column"
        },
        {
          "alphaField": "birth_place_fields",
          "sourceField": "country/state/city of birth",
          "meaning": "Optional source-supplied birth location details.",
          "storageKind": "oneedtech_view_column"
        },
        {
          "alphaField": "residence_status",
          "sourceField": "public_school_residence_status",
          "meaning": "Source legal-residence status.",
          "storageKind": "oneedtech_view_column"
        }
      ]
    },
    {
      "alphaObject": "guardian",
      "changeType": "rename+restrict",
      "sourceType": "edfi_alias_view",
      "upstreamModule": "ed_fi/1edtech",
      "oneEdTechSource": "edfi.canonical_record(resource_name=Contact)",
      "sourceAnchor": "https://platform3-andymontgomery-9773s-projects.vercel.app/ed_fi/1edtech/data_dictionary/#entry-contact-4d61009a458d",
      "baseView": "alpha.guardian_base_view",
      "surfaceView": "alpha.guardian_view",
      "extensionTables": [],
      "coreWriteRoute": "Route all sourced-field writes to the Ed-Fi 1EdTech Contact collection; Alpha exposes only canonical, non-deleted Contact records.",
      "extensionWriteRoute": "None. Guardian facts that originate in Ed-Fi stay in edfi.canonical_record and descriptor_code-backed views.",
      "meaning": "A parent, guardian, emergency contact, or family contact for a student. The person exists because Ed-Fi administrative records know the contact even when OneRoster only has a thin agent reference.",
      "fields": [
        {
          "alphaField": "guardian_id",
          "sourceField": "edfi.canonical_record.edfi_local_id",
          "meaning": "Tenant-scoped Ed-Fi local id for the canonical Contact record.",
          "storageKind": "edfi_canonical_record_view_column"
        },
        {
          "alphaField": "contact_unique_id",
          "sourceField": "edfi.canonical_record.payload_json.ContactUniqueId",
          "meaning": "Ed-Fi contact unique id.",
          "storageKind": "edfi_canonical_record_view_column"
        },
        {
          "alphaField": "full_name",
          "sourceField": "edfi.canonical_record.payload_json.Name",
          "meaning": "Full legal name supplied by Ed-Fi Contact.",
          "storageKind": "edfi_canonical_record_view_column"
        },
        {
          "alphaField": "email",
          "sourceField": "edfi.canonical_record.payload_json.ElectronicMail",
          "meaning": "Contact email, redacted by relationship-scoped authorization when required.",
          "storageKind": "edfi_canonical_record_view_column"
        },
        {
          "alphaField": "phone",
          "sourceField": "edfi.canonical_record.payload_json.Telephone",
          "meaning": "Contact phone, redacted by relationship-scoped authorization when required.",
          "storageKind": "edfi_canonical_record_view_column"
        },
        {
          "alphaField": "language_codes",
          "sourceField": "edfi.canonical_record.payload_json.Language",
          "meaning": "Communication languages from the Ed-Fi Contact payload.",
          "storageKind": "edfi_canonical_record_view_column"
        },
        {
          "alphaField": "source_updated_at",
          "sourceField": "edfi.canonical_record.updated_at",
          "meaning": "Canonical Ed-Fi record updated timestamp.",
          "storageKind": "edfi_canonical_record_view_column"
        },
        {
          "alphaField": "is_deleted",
          "sourceField": "edfi.canonical_record.is_deleted",
          "meaning": "Always false in ordinary Alpha views; deleted contacts are visible only to authorized audit paths.",
          "storageKind": "edfi_canonical_record_view_column"
        }
      ]
    },
    {
      "alphaObject": "guardian_relationship",
      "changeType": "rename+restrict",
      "sourceType": "edfi_alias_view",
      "upstreamModule": "ed_fi/1edtech",
      "oneEdTechSource": "edfi.canonical_record(resource_name=StudentContactAssociation)",
      "sourceAnchor": "https://platform3-andymontgomery-9773s-projects.vercel.app/ed_fi/1edtech/data_dictionary/#entry-studentcontactassociation-32667f508a41",
      "baseView": "alpha.guardian_relationship_base_view",
      "surfaceView": "alpha.guardian_relationship_view",
      "extensionTables": [],
      "coreWriteRoute": "Route all sourced-field writes to the Ed-Fi 1EdTech StudentContactAssociation collection; Alpha joins to OneRoster users only by platform3 sourcedId references.",
      "extensionWriteRoute": "None. Relationship descriptors and flags remain Ed-Fi canonical data.",
      "meaning": "The dated or active relationship between one student and one guardian/contact, including relation, priority, legal-guardian, lives-with, and emergency-contact facts.",
      "fields": [
        {
          "alphaField": "guardian_relationship_id",
          "sourceField": "edfi.canonical_record.edfi_local_id",
          "meaning": "Tenant-scoped Ed-Fi local id for the StudentContactAssociation record.",
          "storageKind": "edfi_canonical_record_view_column"
        },
        {
          "alphaField": "student_person_id",
          "sourceField": "join oneroster.users.sourced_id via edfi.canonical_record.student_sourced_id",
          "meaning": "Student person id resolved through the platform3 sourcedId boundary.",
          "storageKind": "roster_fk_view_column"
        },
        {
          "alphaField": "guardian_id",
          "sourceField": "edfi.canonical_record.payload_json.Contact.ContactUniqueId",
          "meaning": "Contact id from the StudentContactAssociation payload, resolved to alpha.guardian_view when present.",
          "storageKind": "edfi_canonical_record_view_column"
        },
        {
          "alphaField": "relationship_kind",
          "sourceField": "edfi.descriptor_code(Relation)",
          "meaning": "Governed Ed-Fi relation descriptor resolved to a stable plain value.",
          "storageKind": "edfi_descriptor_resolved_view"
        },
        {
          "alphaField": "is_primary_contact",
          "sourceField": "edfi.canonical_record.payload_json.PrimaryContactStatus",
          "meaning": "Whether Ed-Fi marks this contact as primary.",
          "storageKind": "edfi_canonical_record_view_column"
        },
        {
          "alphaField": "is_legal_guardian",
          "sourceField": "edfi.canonical_record.payload_json.LegalGuardian",
          "meaning": "Whether Ed-Fi marks this contact as a legal guardian.",
          "storageKind": "edfi_canonical_record_view_column"
        },
        {
          "alphaField": "lives_with_student",
          "sourceField": "edfi.canonical_record.payload_json.LivesWith",
          "meaning": "Whether the student lives with the contact.",
          "storageKind": "edfi_canonical_record_view_column"
        },
        {
          "alphaField": "is_emergency_contact",
          "sourceField": "edfi.canonical_record.payload_json.EmergencyContactStatus",
          "meaning": "Whether the contact is an emergency contact.",
          "storageKind": "edfi_canonical_record_view_column"
        },
        {
          "alphaField": "contact_priority",
          "sourceField": "edfi.canonical_record.payload_json.ContactPriority",
          "meaning": "Preferred contact order.",
          "storageKind": "edfi_canonical_record_view_column"
        },
        {
          "alphaField": "contact_restrictions",
          "sourceField": "edfi.canonical_record.payload_json.ContactRestrictions",
          "meaning": "Contact restrictions; restricted/redacted by privacy rules.",
          "storageKind": "edfi_canonical_record_view_column"
        }
      ]
    },
    {
      "alphaObject": "staff_assignment",
      "changeType": "rename+restrict",
      "sourceType": "edfi_alias_view",
      "upstreamModule": "ed_fi/1edtech",
      "oneEdTechSource": "edfi.canonical_record(resource_name=StaffEducationOrganizationAssignmentAssociation)",
      "sourceAnchor": "https://platform3-andymontgomery-9773s-projects.vercel.app/ed_fi/1edtech/data_dictionary/#entry-staffeducationorganizationassignmentassociation-e92aa18ecc7f",
      "baseView": "alpha.staff_assignment_base_view",
      "surfaceView": "alpha.staff_assignment_view",
      "extensionTables": [],
      "coreWriteRoute": "Route all sourced-field writes to the Ed-Fi 1EdTech StaffEducationOrganizationAssignmentAssociation collection; OneRoster users and orgs remain the roster identity boundary.",
      "extensionWriteRoute": "None. Staff assignment facts from Ed-Fi stay in edfi.canonical_record and descriptor_code-backed views.",
      "meaning": "A staff member's assignment to a school, district, department, or other education organization beyond the role rows OneRoster already carries.",
      "fields": [
        {
          "alphaField": "staff_assignment_id",
          "sourceField": "edfi.canonical_record.edfi_local_id",
          "meaning": "Tenant-scoped Ed-Fi local id for the staff assignment.",
          "storageKind": "edfi_canonical_record_view_column"
        },
        {
          "alphaField": "staff_person_id",
          "sourceField": "join oneroster.users.sourced_id via edfi.canonical_record.staff_sourced_id",
          "meaning": "Staff person id resolved through the platform3 sourcedId boundary.",
          "storageKind": "roster_fk_view_column"
        },
        {
          "alphaField": "place_id",
          "sourceField": "join oneroster.orgs.sourced_id via edfi.canonical_record.school_sourced_id",
          "meaning": "School or education organization place id resolved through OneRoster.",
          "storageKind": "roster_fk_view_column"
        },
        {
          "alphaField": "staff_classification",
          "sourceField": "edfi.descriptor_code(StaffClassification)",
          "meaning": "Governed staff-classification descriptor.",
          "storageKind": "edfi_descriptor_resolved_view"
        },
        {
          "alphaField": "position_title",
          "sourceField": "edfi.canonical_record.payload_json.PositionTitle",
          "meaning": "Human staff position title.",
          "storageKind": "edfi_canonical_record_view_column"
        },
        {
          "alphaField": "begin_date",
          "sourceField": "edfi.canonical_record.payload_json.BeginDate",
          "meaning": "Inclusive date the assignment becomes locatable.",
          "storageKind": "edfi_canonical_record_view_column"
        },
        {
          "alphaField": "end_date",
          "sourceField": "edfi.canonical_record.payload_json.EndDate",
          "meaning": "Date the assignment ends; null means active after begin_date.",
          "storageKind": "edfi_canonical_record_view_column"
        },
        {
          "alphaField": "is_time_locatable",
          "sourceField": "view expression: payload_json.BeginDate is not null",
          "meaning": "True only when begin_date is present; consumers do not infer from nulls.",
          "storageKind": "view_derived"
        },
        {
          "alphaField": "assignment_order",
          "sourceField": "edfi.canonical_record.payload_json.OrderOfAssignment",
          "meaning": "Primary/secondary assignment order when supplied.",
          "storageKind": "edfi_canonical_record_view_column"
        },
        {
          "alphaField": "full_time_equivalency",
          "sourceField": "edfi.canonical_record.payload_json.FullTimeEquivalency",
          "meaning": "Ratio of expected work time for the assignment.",
          "storageKind": "edfi_canonical_record_view_column"
        }
      ]
    },
    {
      "alphaObject": "program_participation",
      "changeType": "rename+restrict",
      "sourceType": "edfi_alias_view",
      "upstreamModule": "ed_fi/1edtech",
      "oneEdTechSource": "edfi.canonical_record(resource_name in GeneralStudentProgramAssociation, StudentProgramAssociation, and specializations)",
      "sourceAnchor": "https://platform3-andymontgomery-9773s-projects.vercel.app/ed_fi/1edtech/data_dictionary/#entry-generalstudentprogramassociation-b50a12920f64",
      "baseView": "alpha.program_participation_base_view",
      "surfaceView": "alpha.program_participation_view",
      "extensionTables": [],
      "coreWriteRoute": "Route all sourced-field writes to the Ed-Fi 1EdTech Program and StudentProgramAssociation-family collections; Alpha joins student and place ids through OneRoster sourcedIds.",
      "extensionWriteRoute": "None. Program participation facts from Ed-Fi stay in edfi.canonical_record and descriptor_code-backed views.",
      "meaning": "A student's participation in an administrative program such as Special Education, Title I, English Learner, Section 504, food service, or another Ed-Fi program association. This records membership in the program, not outcomes or services effectiveness.",
      "fields": [
        {
          "alphaField": "program_participation_id",
          "sourceField": "edfi.canonical_record.edfi_local_id",
          "meaning": "Tenant-scoped Ed-Fi local id for the program association.",
          "storageKind": "edfi_canonical_record_view_column"
        },
        {
          "alphaField": "student_person_id",
          "sourceField": "join oneroster.users.sourced_id via edfi.canonical_record.student_sourced_id",
          "meaning": "Student person id resolved through the platform3 sourcedId boundary.",
          "storageKind": "roster_fk_view_column"
        },
        {
          "alphaField": "place_id",
          "sourceField": "join oneroster.orgs.sourced_id via edfi.canonical_record.school_sourced_id",
          "meaning": "School or education organization place id resolved through OneRoster.",
          "storageKind": "roster_fk_view_column"
        },
        {
          "alphaField": "program_id",
          "sourceField": "edfi.canonical_record.payload_json.Program.ProgramId",
          "meaning": "Program identifier from the linked Ed-Fi Program payload when present.",
          "storageKind": "edfi_canonical_record_view_column"
        },
        {
          "alphaField": "program_name",
          "sourceField": "edfi.canonical_record.payload_json.Program.ProgramName",
          "meaning": "Plain program name.",
          "storageKind": "edfi_canonical_record_view_column"
        },
        {
          "alphaField": "program_type",
          "sourceField": "edfi.descriptor_code(ProgramType)",
          "meaning": "Governed Ed-Fi program-type descriptor.",
          "storageKind": "edfi_descriptor_resolved_view"
        },
        {
          "alphaField": "participation_status",
          "sourceField": "edfi.descriptor_code(ProgramParticipationStatus)",
          "meaning": "Governed participation-status descriptor.",
          "storageKind": "edfi_descriptor_resolved_view"
        },
        {
          "alphaField": "begin_date",
          "sourceField": "edfi.canonical_record.payload_json.BeginDate",
          "meaning": "Inclusive date the student becomes involved with the program.",
          "storageKind": "edfi_canonical_record_view_column"
        },
        {
          "alphaField": "end_date",
          "sourceField": "edfi.canonical_record.payload_json.EndDate",
          "meaning": "Date the student exits the program; null means active after begin_date.",
          "storageKind": "edfi_canonical_record_view_column"
        },
        {
          "alphaField": "is_time_locatable",
          "sourceField": "view expression: payload_json.BeginDate is not null",
          "meaning": "True only when begin_date is present.",
          "storageKind": "view_derived"
        },
        {
          "alphaField": "source_program_resource",
          "sourceField": "edfi.canonical_record.resource_name",
          "meaning": "Exact Ed-Fi association/specialization that produced the row.",
          "storageKind": "edfi_canonical_record_view_column"
        }
      ]
    },
    {
      "alphaObject": "app_credential",
      "changeType": "extend",
      "sourceType": "alpha_extend",
      "oneEdTechSource": null,
      "sourceAnchor": "#paitd-008-app-credentials",
      "baseView": null,
      "surfaceView": "alpha.app_credential",
      "extensionTables": [
        "alpha.app_credential"
      ],
      "coreWriteRoute": "None.",
      "extensionWriteRoute": "Write alpha.app_credential rows with a student_sourced_id foreign key to oneroster.users.",
      "meaning": "A first-class operational secret reference for a student's login to a third-party learning app. The secret value is never stored in a roster field, tag, log, or API response.",
      "fields": [
        {
          "alphaField": "student_sourced_id",
          "sourceField": "alpha.app_credential.student_sourced_id",
          "meaning": "Student person id foreign key that owns the credential; named to match the required app_credential contract.",
          "storageKind": "alpha_extend_table"
        },
        {
          "alphaField": "app_id",
          "sourceField": "alpha.app_credential.app_id",
          "meaning": "Learning app identifier.",
          "storageKind": "alpha_extend_table"
        },
        {
          "alphaField": "secret_ref",
          "sourceField": "alpha.app_credential.secret_ref",
          "meaning": "Reference to a managed secrets vault, never plaintext.",
          "storageKind": "alpha_extend_table"
        },
        {
          "alphaField": "created_at",
          "sourceField": "alpha.app_credential.created_at",
          "meaning": "Credential reference creation time.",
          "storageKind": "alpha_extend_table"
        },
        {
          "alphaField": "last_rotated_at",
          "sourceField": "alpha.app_credential.last_rotated_at",
          "meaning": "Last rotation time surfaced for audit and operations.",
          "storageKind": "alpha_extend_table"
        }
      ]
    },
    {
      "alphaObject": "tag_definition",
      "changeType": "extend",
      "sourceType": "alpha_extend",
      "oneEdTechSource": null,
      "sourceAnchor": "#paitd-006-tag-registry",
      "baseView": null,
      "surfaceView": "alpha.tag_definition",
      "extensionTables": [
        "alpha.tag_definition"
      ],
      "coreWriteRoute": "None.",
      "extensionWriteRoute": "Write alpha.tag_definition rows only; no 1EdTech columns are copied.",
      "meaning": "Governed tag registry for low-cardinality roster reporting dimensions that do not belong as enforced relationship columns.",
      "fields": [
        {
          "alphaField": "tag_key",
          "sourceField": "alpha.tag_definition.tag_key",
          "meaning": "Stable tag key.",
          "storageKind": "alpha_extend_table"
        },
        {
          "alphaField": "anchor",
          "sourceField": "alpha.tag_definition.anchor",
          "meaning": "The grain the tag is allowed to attach to, such as nwea_account or school.",
          "storageKind": "alpha_extend_table"
        },
        {
          "alphaField": "allowed_values",
          "sourceField": "alpha.tag_definition.allowed_values",
          "meaning": "Governed allowed value list.",
          "storageKind": "alpha_extend_table"
        },
        {
          "alphaField": "value_type",
          "sourceField": "alpha.tag_definition.value_type",
          "meaning": "Typed value class.",
          "storageKind": "alpha_extend_table"
        },
        {
          "alphaField": "is_locked",
          "sourceField": "alpha.tag_definition.is_locked",
          "meaning": "True when setup seeds and locks the tag, as with brand and modality.",
          "storageKind": "alpha_extend_table"
        }
      ]
    },
    {
      "alphaObject": "object_tag",
      "changeType": "extend",
      "sourceType": "alpha_extend",
      "oneEdTechSource": null,
      "sourceAnchor": "#paitd-006-tag-registry",
      "baseView": null,
      "surfaceView": "alpha.object_tag",
      "extensionTables": [
        "alpha.object_tag"
      ],
      "coreWriteRoute": "None.",
      "extensionWriteRoute": "Write alpha.object_tag rows only; object_id is a relationship reference to a live public object, not a copied 1EdTech field.",
      "meaning": "A governed tag assignment for report slicing only. It is never used for relationships, joins to live rows, or secrets.",
      "fields": [
        {
          "alphaField": "object_kind",
          "sourceField": "alpha.object_tag.object_kind",
          "meaning": "Tagged Alpha object kind.",
          "storageKind": "alpha_extend_table"
        },
        {
          "alphaField": "object_id",
          "sourceField": "alpha.object_tag.object_id",
          "meaning": "Tagged object id.",
          "storageKind": "alpha_extend_table"
        },
        {
          "alphaField": "tag_key",
          "sourceField": "alpha.object_tag.tag_key",
          "meaning": "Registered tag key.",
          "storageKind": "alpha_extend_table"
        },
        {
          "alphaField": "tag_value",
          "sourceField": "alpha.object_tag.tag_value",
          "meaning": "Allowed value from tag_definition.",
          "storageKind": "alpha_extend_table"
        }
      ]
    },
    {
      "alphaObject": "alpha_level_history",
      "changeType": "extend",
      "sourceType": "alpha_extend",
      "oneEdTechSource": null,
      "sourceAnchor": "#paitd-018-over-time-history",
      "baseView": null,
      "surfaceView": "alpha.alpha_level_history",
      "extensionTables": [
        "alpha.alpha_level_history"
      ],
      "coreWriteRoute": "None.",
      "extensionWriteRoute": "Write effective-dated alpha.alpha_level_history rows with a person_id foreign key to the base person, after the base person exists. No OneRoster or Ed-Fi column is copied.",
      "meaning": "Effective-dated history of a student's Alpha level. Answers alphaLevel(person, asOfDate) for current and past dates; the dated table is the system of record so no level change overwrites history.",
      "fields": [
        {
          "alphaField": "history_id",
          "sourceField": "alpha.alpha_level_history.history_id",
          "meaning": "Tenant-scoped Alpha-owned history row id; not a OneRoster sourcedId.",
          "storageKind": "alpha_extend_table"
        },
        {
          "alphaField": "person_id",
          "sourceField": "alpha.alpha_level_history.person_id",
          "meaning": "Foreign key to the base person row; the only reference this extension table holds.",
          "storageKind": "alpha_extend_table"
        },
        {
          "alphaField": "alpha_level",
          "sourceField": "alpha.alpha_level_history.alpha_level",
          "meaning": "Canonical Alpha level for this interval; source labels are folded through alpha.policy.alpha_level_alias_folds at write time.",
          "storageKind": "alpha_extend_table"
        },
        {
          "alphaField": "begin_date",
          "sourceField": "alpha.alpha_level_history.begin_date",
          "meaning": "Inclusive date the level becomes effective; null excludes the row from point-in-time reads.",
          "storageKind": "alpha_extend_table"
        },
        {
          "alphaField": "end_date",
          "sourceField": "alpha.alpha_level_history.end_date",
          "meaning": "Exclusive date the level ends; null means still active for dates on or after begin_date.",
          "storageKind": "alpha_extend_table"
        },
        {
          "alphaField": "is_time_locatable",
          "sourceField": "view expression: begin_date is not null",
          "meaning": "True only when begin_date is non-null; consumers filter on this field instead of guessing at nulls.",
          "storageKind": "view_derived"
        }
      ]
    },
    {
      "alphaObject": "age_grade_history",
      "changeType": "extend",
      "sourceType": "alpha_extend",
      "oneEdTechSource": null,
      "sourceAnchor": "#paitd-018-over-time-history",
      "baseView": null,
      "surfaceView": "alpha.age_grade_history",
      "extensionTables": [
        "alpha.age_grade_history"
      ],
      "coreWriteRoute": "None.",
      "extensionWriteRoute": "Write effective-dated alpha.age_grade_history rows with a person_id foreign key to the base person, after the base person exists. No OneRoster or Ed-Fi column is copied.",
      "meaning": "Effective-dated history of a student's canonical age grade. Answers ageGrade(person, asOfDate) for current and past dates; the dated table is the system of record so no grade change overwrites history.",
      "fields": [
        {
          "alphaField": "history_id",
          "sourceField": "alpha.age_grade_history.history_id",
          "meaning": "Tenant-scoped Alpha-owned history row id; not a OneRoster sourcedId.",
          "storageKind": "alpha_extend_table"
        },
        {
          "alphaField": "person_id",
          "sourceField": "alpha.age_grade_history.person_id",
          "meaning": "Foreign key to the base person row; the only reference this extension table holds.",
          "storageKind": "alpha_extend_table"
        },
        {
          "alphaField": "age_grade",
          "sourceField": "alpha.age_grade_history.age_grade",
          "meaning": "Canonical age grade for this interval; source labels are folded through alpha.policy.grade_alias_folds at write time and never parsed from names.",
          "storageKind": "alpha_extend_table"
        },
        {
          "alphaField": "begin_date",
          "sourceField": "alpha.age_grade_history.begin_date",
          "meaning": "Inclusive date the age grade becomes effective; null excludes the row from point-in-time reads.",
          "storageKind": "alpha_extend_table"
        },
        {
          "alphaField": "end_date",
          "sourceField": "alpha.age_grade_history.end_date",
          "meaning": "Exclusive date the age grade ends; null means still active for dates on or after begin_date.",
          "storageKind": "alpha_extend_table"
        },
        {
          "alphaField": "is_time_locatable",
          "sourceField": "view expression: begin_date is not null",
          "meaning": "True only when begin_date is non-null; consumers filter on this field instead of guessing at nulls.",
          "storageKind": "view_derived"
        }
      ]
    }
  ],
  "storageContract": [
    {
      "alphaObject": "person",
      "publicSurface": "alpha.person",
      "upstreamModule": "oneroster/1edtech",
      "baseSource": "oneroster.users",
      "baseView": "alpha.person_base",
      "extensionTables": [
        "alpha.person_ext"
      ],
      "coreWriteRoute": "Route sourced-field writes to the OneRoster 1EdTech users surface.",
      "extensionWriteRoute": "Write only admission_date, exit_date, age_grade, and reality to alpha.person_ext after the base person exists.",
      "requiredShape": "CREATE VIEW over the OneRoster 1EdTech base; no Alpha table may store sourced OneRoster columns."
    },
    {
      "alphaObject": "place",
      "publicSurface": "alpha.place",
      "upstreamModule": "oneroster/1edtech",
      "baseSource": "oneroster.orgs",
      "baseView": "alpha.place_base",
      "extensionTables": [
        "alpha.place_ext",
        "alpha.object_tag"
      ],
      "coreWriteRoute": "Route sourced-field writes to the OneRoster 1EdTech orgs surface.",
      "extensionWriteRoute": "Write nwea_district_id and reality to alpha.place_ext and report-slice tags to alpha.object_tag only.",
      "requiredShape": "CREATE VIEW over the OneRoster 1EdTech base; no Alpha table may store sourced OneRoster columns."
    },
    {
      "alphaObject": "place_membership",
      "publicSurface": "alpha.place_membership",
      "upstreamModule": "oneroster/1edtech",
      "baseSource": "oneroster.roles",
      "baseView": "alpha.place_membership_base",
      "extensionTables": [],
      "coreWriteRoute": "Route all writes to the OneRoster 1EdTech roles surface.",
      "extensionWriteRoute": "None. is_time_locatable is a view expression, not stored Alpha state.",
      "requiredShape": "CREATE VIEW over the OneRoster 1EdTech base; no Alpha table may store sourced OneRoster columns."
    },
    {
      "alphaObject": "class_membership",
      "publicSurface": "alpha.class_membership",
      "upstreamModule": "oneroster/1edtech",
      "baseSource": "oneroster.enrollments",
      "baseView": "alpha.class_membership_base",
      "extensionTables": [],
      "coreWriteRoute": "Route all writes to the OneRoster 1EdTech enrollments surface.",
      "extensionWriteRoute": "None. is_time_locatable is a view expression, not stored Alpha state.",
      "requiredShape": "CREATE VIEW over the OneRoster 1EdTech base; no Alpha table may store sourced OneRoster columns."
    },
    {
      "alphaObject": "school_period",
      "publicSurface": "alpha.school_period",
      "upstreamModule": "oneroster/1edtech",
      "baseSource": "oneroster.academic_sessions",
      "baseView": "alpha.school_period_base",
      "extensionTables": [],
      "coreWriteRoute": "Route all writes to the OneRoster 1EdTech academic_sessions surface.",
      "extensionWriteRoute": "None.",
      "requiredShape": "CREATE VIEW over the OneRoster 1EdTech base; no Alpha table may store sourced OneRoster columns."
    },
    {
      "alphaObject": "person_sensitive_profile",
      "publicSurface": "alpha.person_sensitive_profile",
      "upstreamModule": "oneroster/1edtech",
      "baseSource": "oneroster.demographics",
      "baseView": "alpha.person_sensitive_profile_base",
      "extensionTables": [],
      "coreWriteRoute": "Route sourced-field writes to the OneRoster 1EdTech demographics surface.",
      "extensionWriteRoute": "None. Authorization and redaction are API/view restrictions, not copied storage.",
      "requiredShape": "CREATE VIEW over the OneRoster 1EdTech base; no Alpha table may store sourced OneRoster columns."
    },
    {
      "alphaObject": "guardian",
      "publicSurface": "alpha.guardian_view",
      "upstreamModule": "ed_fi/1edtech",
      "baseSource": "edfi.canonical_record(resource_name=Contact)",
      "baseView": "alpha.guardian_base_view",
      "extensionTables": [],
      "coreWriteRoute": "Route all sourced-field writes to the Ed-Fi 1EdTech Contact collection; Alpha exposes only canonical, non-deleted Contact records.",
      "extensionWriteRoute": "None. Guardian facts that originate in Ed-Fi stay in edfi.canonical_record and descriptor_code-backed views.",
      "requiredShape": "CREATE VIEW over edfi.canonical_record; filter resource_name/collection_route, tenant_id, is_deleted=false, canonical state, descriptor_code resolution, and OneRoster sourcedId joins. No Alpha table may store sourced Ed-Fi columns."
    },
    {
      "alphaObject": "guardian_relationship",
      "publicSurface": "alpha.guardian_relationship_view",
      "upstreamModule": "ed_fi/1edtech",
      "baseSource": "edfi.canonical_record(resource_name=StudentContactAssociation)",
      "baseView": "alpha.guardian_relationship_base_view",
      "extensionTables": [],
      "coreWriteRoute": "Route all sourced-field writes to the Ed-Fi 1EdTech StudentContactAssociation collection; Alpha joins to OneRoster users only by platform3 sourcedId references.",
      "extensionWriteRoute": "None. Relationship descriptors and flags remain Ed-Fi canonical data.",
      "requiredShape": "CREATE VIEW over edfi.canonical_record; filter resource_name/collection_route, tenant_id, is_deleted=false, canonical state, descriptor_code resolution, and OneRoster sourcedId joins. No Alpha table may store sourced Ed-Fi columns."
    },
    {
      "alphaObject": "staff_assignment",
      "publicSurface": "alpha.staff_assignment_view",
      "upstreamModule": "ed_fi/1edtech",
      "baseSource": "edfi.canonical_record(resource_name=StaffEducationOrganizationAssignmentAssociation)",
      "baseView": "alpha.staff_assignment_base_view",
      "extensionTables": [],
      "coreWriteRoute": "Route all sourced-field writes to the Ed-Fi 1EdTech StaffEducationOrganizationAssignmentAssociation collection; OneRoster users and orgs remain the roster identity boundary.",
      "extensionWriteRoute": "None. Staff assignment facts from Ed-Fi stay in edfi.canonical_record and descriptor_code-backed views.",
      "requiredShape": "CREATE VIEW over edfi.canonical_record; filter resource_name/collection_route, tenant_id, is_deleted=false, canonical state, descriptor_code resolution, and OneRoster sourcedId joins. No Alpha table may store sourced Ed-Fi columns."
    },
    {
      "alphaObject": "program_participation",
      "publicSurface": "alpha.program_participation_view",
      "upstreamModule": "ed_fi/1edtech",
      "baseSource": "edfi.canonical_record(resource_name in GeneralStudentProgramAssociation, StudentProgramAssociation, and specializations)",
      "baseView": "alpha.program_participation_base_view",
      "extensionTables": [],
      "coreWriteRoute": "Route all sourced-field writes to the Ed-Fi 1EdTech Program and StudentProgramAssociation-family collections; Alpha joins student and place ids through OneRoster sourcedIds.",
      "extensionWriteRoute": "None. Program participation facts from Ed-Fi stay in edfi.canonical_record and descriptor_code-backed views.",
      "requiredShape": "CREATE VIEW over edfi.canonical_record; filter resource_name/collection_route, tenant_id, is_deleted=false, canonical state, descriptor_code resolution, and OneRoster sourcedId joins. No Alpha table may store sourced Ed-Fi columns."
    },
    {
      "alphaObject": "app_credential",
      "publicSurface": "alpha.app_credential",
      "upstreamModule": "oneroster/1edtech",
      "baseSource": null,
      "baseView": null,
      "extensionTables": [
        "alpha.app_credential"
      ],
      "coreWriteRoute": "None.",
      "extensionWriteRoute": "Write alpha.app_credential rows with a student_sourced_id foreign key to oneroster.users.",
      "requiredShape": "CREATE TABLE is allowed because this is a pure Alpha extension."
    },
    {
      "alphaObject": "tag_definition",
      "publicSurface": "alpha.tag_definition",
      "upstreamModule": "oneroster/1edtech",
      "baseSource": null,
      "baseView": null,
      "extensionTables": [
        "alpha.tag_definition"
      ],
      "coreWriteRoute": "None.",
      "extensionWriteRoute": "Write alpha.tag_definition rows only; no 1EdTech columns are copied.",
      "requiredShape": "CREATE TABLE is allowed because this is a pure Alpha extension."
    },
    {
      "alphaObject": "object_tag",
      "publicSurface": "alpha.object_tag",
      "upstreamModule": "oneroster/1edtech",
      "baseSource": null,
      "baseView": null,
      "extensionTables": [
        "alpha.object_tag"
      ],
      "coreWriteRoute": "None.",
      "extensionWriteRoute": "Write alpha.object_tag rows only; object_id is a relationship reference to a live public object, not a copied 1EdTech field.",
      "requiredShape": "CREATE TABLE is allowed because this is a pure Alpha extension."
    },
    {
      "alphaObject": "alpha_level_history",
      "publicSurface": "alpha.alpha_level_history",
      "upstreamModule": "oneroster/1edtech",
      "baseSource": null,
      "baseView": null,
      "extensionTables": [
        "alpha.alpha_level_history"
      ],
      "coreWriteRoute": "None.",
      "extensionWriteRoute": "Write effective-dated alpha.alpha_level_history rows with a person_id foreign key to the base person, after the base person exists. No OneRoster or Ed-Fi column is copied.",
      "requiredShape": "CREATE TABLE is allowed because this is a pure Alpha extension."
    },
    {
      "alphaObject": "age_grade_history",
      "publicSurface": "alpha.age_grade_history",
      "upstreamModule": "oneroster/1edtech",
      "baseSource": null,
      "baseView": null,
      "extensionTables": [
        "alpha.age_grade_history"
      ],
      "coreWriteRoute": "None.",
      "extensionWriteRoute": "Write effective-dated alpha.age_grade_history rows with a person_id foreign key to the base person, after the base person exists. No OneRoster or Ed-Fi column is copied.",
      "requiredShape": "CREATE TABLE is allowed because this is a pure Alpha extension."
    }
  ],
  "forbiddenAlphaTables": [
    "alpha.person",
    "alpha.place",
    "alpha.place_membership",
    "alpha.class_membership",
    "alpha.school_period",
    "alpha.person_sensitive_profile",
    "alpha.guardian_view",
    "alpha.guardian_relationship_view",
    "alpha.staff_assignment_view",
    "alpha.program_participation_view"
  ],
  "allowedExtensionTables": [
    "alpha.person_ext",
    "alpha.place_ext",
    "alpha.app_credential",
    "alpha.tag_definition",
    "alpha.object_tag",
    "alpha.alpha_level_history",
    "alpha.age_grade_history"
  ]
}
modulePlacement
[
  {
    "fact": "person identity and contact",
    "home": "People & Orgs",
    "reason": "It says who someone is."
  },
  {
    "fact": "guardian and student-guardian relationship",
    "home": "People & Orgs",
    "reason": "It says who may act for or contact a student, with the relationship tied to one student."
  },
  {
    "fact": "place, school, district, NWEA account boundary",
    "home": "People & Orgs",
    "reason": "It says where people belong and how places nest."
  },
  {
    "fact": "roles and enrollments with dates",
    "home": "People & Orgs",
    "reason": "They link a person to a place or learning group over time."
  },
  {
    "fact": "staff assignment to an education organization",
    "home": "People & Orgs",
    "reason": "It says where a staff person serves and in what capacity as of a date."
  },
  {
    "fact": "student program participation",
    "home": "People & Orgs",
    "reason": "It says a student belongs to an administrative program at a place for a date range."
  },
  {
    "fact": "Alpha level over time and age grade over time",
    "home": "People & Orgs",
    "reason": "They say what level or grade a student is as of a date - who someone is over time - kept as dated history, not student outcomes."
  },
  {
    "fact": "real / test / synthetic classification of a person or place",
    "home": "People & Orgs",
    "reason": "It says what kind of roster entity this is so reports include only real people and places; it is identity context, not an outcome."
  },
  {
    "fact": "highest mastered grade as of a date",
    "home": "Results",
    "reason": "It reads the mastery ledger as of a date; the dated knowledge state is a durable statement about how a student is doing, not roster belonging."
  },
  {
    "fact": "student mastery, decay, working grade, MAP result, report-card outcome",
    "home": "Results",
    "reason": "It is a durable statement about how a specific student is doing."
  },
  {
    "fact": "program outcomes, intervention effect, eligibility formulas, thresholds",
    "home": "Results / Policy",
    "reason": "They are settled outcomes or policy decisions, not roster belonging facts."
  },
  {
    "fact": "curriculum graph and knowledge components",
    "home": "Curriculum",
    "reason": "It is the shared map of what there is to learn."
  },
  {
    "fact": "questions, lessons, videos, articles, tests",
    "home": "Content",
    "reason": "They are things students touch."
  },
  {
    "fact": "views, submissions, hint requests, video scrubs",
    "home": "Events",
    "reason": "They are records that something happened."
  }
]
crossCuttingRules
[
  {
    "rule": "Tag registry vs. real column",
    "handling": "Relationships, computed inputs, constraints, sort keys, and durable structural fields are real columns. On Alpha, sourced columns are view expressions over OneRoster or Ed-Fi canonical records; only new Alpha-owned facts live in extension tables. Brand, modality, segment, and level are governed registry tags only when used as report slices, with brand/modality locked at the NWEA-account grain and segment a closed list (a place spanning more than one segment is tagged segment=mixed). Ed-Fi descriptors resolve through edfi.descriptor_code, not free tags."
  },
  {
    "rule": "Point-in-time is default",
    "handling": "Roles, enrollments, school assignments, guide assignments, guardian relationships, staff assignments, program participation, Alpha level, age grade, and campus facts answer by entity plus asOfDate. begin_date null means excluded; end_date null means active after begin_date; both null means excluded. is_time_locatable is exposed. Alpha level and age grade keep dated history (alpha.alpha_level_history, alpha.age_grade_history) instead of a single overwritten current column."
  },
  {
    "rule": "Typed, never parsed",
    "handling": "role_kind, place_kind, period_kind, age_grade, school_year, season, brand, modality, segment, level, relationship_kind, staff_classification, program_type, and participation_status are typed at write time or descriptor-resolution time with maintained alias folds. Consumers never parse names, titles, URLs, or free strings."
  },
  {
    "rule": "Policy in alpha.policy.*",
    "handling": "Tenure buckets and school-year boundaries are named policy config; no dashboard or skill pack hardcodes them."
  },
  {
    "rule": "Event/result/gradebook split",
    "handling": "This module owns roster facts only. Interaction events live in Events; scored outcomes and gradebook rollups live in Results."
  },
  {
    "rule": "Two graphs, two homes",
    "handling": "The shared curriculum graph lives in Curriculum, and per-student mastery state lives in Results. Mastery is never a field on person."
  },
  {
    "rule": "NWEA account is district",
    "handling": "Each Brand x Modality NWEA account is exactly one place with place_kind=district, required nwea_district_id, locked brand/modality tags, and school children linked by parent_place_id."
  },
  {
    "rule": "Secrets are not roster fields",
    "handling": "OneRoster password fields and user_profile passwords are cut from Alpha. Student app credentials use app_credential.secret_ref to a vault and never return secret values."
  },
  {
    "rule": "Tenure bands are config",
    "handling": "Tenure derives from person.admission_date and alpha.policy.tenure_buckets at asOfDate."
  },
  {
    "rule": "Ed-Fi view guardrails are raw-DB rules",
    "handling": "Guardian, guardian_relationship, staff_assignment, and program_participation views select only edfi.canonical_record rows for the named resource, scoped by tenant_id, ordinary reads filter is_deleted=false, drafts in edfi.draft_record never appear as canonical facts, descriptor fields join edfi.descriptor_code, and student/staff/place references join OneRoster via platform3 sourcedId columns."
  },
  {
    "rule": "Content effectiveness belongs to Content",
    "handling": "No person or place counter stores validated_by_count, failed_by_count, or effectiveness rate."
  },
  {
    "rule": "Real-only is the reporting default",
    "handling": "Person and place carry a typed closed reality enum (real, test, synthetic) set at the write boundary from authoritative source classification. Ordinary reports default to reality=real; including test or synthetic is an explicit documented parameter. No consumer hand-maintains a name/email/campus exclusion list, and reality is never inferred from display strings."
  },
  {
    "rule": "External results use ingest adapters",
    "handling": "People & Orgs supplies canonical student ids and place context only; MAP, AP, and other results normalize in Results/NWEAMap adapters."
  },
  {
    "rule": "Test type is on Content",
    "handling": "No People & Orgs field classifies tests or gates by parsing names."
  },
  {
    "rule": "K-8 advancement is surface-owned",
    "handling": "People & Orgs supplies identity, school, grade, and tenure inputs; advancement is computed by the Results surface metric."
  }
]