- module
- people_and_orgs
- surface
- alpha
- deliverable
- customer_website
- generatedAt
- 2026-06-19T15:21:39Z
- benchmarkUrl
- https://docs.stripe.com/api
- implementationBaseUrl
- https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/implementation/api
- architectureUrl
- https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/architecture
- dataDictionaryUrl
- https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/data_dictionary
- oneRosterDictionaryUrl
- https://platform3-andymontgomery-9773s-projects.vercel.app/oneroster/1edtech/data_dictionary
- edFiDictionaryUrl
- https://platform3-andymontgomery-9773s-projects.vercel.app/ed_fi/1edtech/data_dictionary
- endpointCount
- 82
- tableCount
- 17
- fieldCount
- 154
- problemTypeBase
- https://platform3-andymontgomery-9773s-projects.vercel.app/problems/people-orgs/
sourceArtifacts
{
"architecture": "loop/people_and_orgs/artifacts/alpha/architecture/site/people-and-orgs-alpha-architecture.json",
"dataDictionary": "loop/people_and_orgs/artifacts/alpha/data_dictionary/site/people-and-orgs-alpha-data-dictionary.json",
"aliasMap": "loop/people_and_orgs/artifacts/alpha/architecture/site/alpha-alias-map.json"
}tables
[
{
"name": "alpha.person",
"title": "Person",
"apiCollection": "/people",
"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.",
"changeType": "rename + extend",
"upstream": "oneroster.users",
"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.",
"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."
},
"fieldCount": 20
},
{
"name": "alpha.place",
"title": "Place",
"apiCollection": "/places",
"purpose": "A district, school, level, department, or other roster place. For NWEA, district means exactly one Brand x Modality account.",
"changeType": "rename + restrict + extend",
"upstream": "oneroster.orgs",
"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.",
"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."
},
"fieldCount": 14
},
{
"name": "alpha.person_ext",
"title": "Person Extension Storage",
"apiCollection": "storage-only; written through /people extension fields",
"purpose": "The storage row that lets Alpha add person lifecycle, age-grade, and reality context to a person without copying OneRoster user columns.",
"changeType": "extend",
"upstream": "None; logical FK to alpha.person_base",
"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.",
"storageContract": null,
"fieldCount": 5
},
{
"name": "alpha.place_ext",
"title": "Place Extension Storage",
"apiCollection": "storage-only; written through /places extension fields",
"purpose": "The storage row that lets Alpha attach the NWEA account id and reality classification to a place without copying OneRoster org columns.",
"changeType": "extend",
"upstream": "None; logical FK to alpha.place_base",
"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.",
"storageContract": null,
"fieldCount": 4
},
{
"name": "alpha.alpha_level_history",
"title": "Alpha Level History",
"apiCollection": "/alpha_level_history",
"purpose": "The over-time answer for alphaLevel(student, date). It keeps Alpha level history instead of replacing old context with one mutable current value.",
"changeType": "extend",
"upstream": "None; logical FK to alpha.person_base and source classification",
"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.",
"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."
},
"fieldCount": 7
},
{
"name": "alpha.age_grade_history",
"title": "Age Grade History",
"apiCollection": "/age_grade_history",
"purpose": "The over-time answer for ageGrade(student, date). It keeps age-grade history instead of replacing old context with one mutable current value.",
"changeType": "extend",
"upstream": "None; logical FK to alpha.person_base and source grade classification",
"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.",
"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."
},
"fieldCount": 7
},
{
"name": "alpha.place_membership",
"title": "Place Membership",
"apiCollection": "/place_memberships",
"purpose": "A dated relationship saying what one person is in one place, such as parent, guardian, guide, student, administrator, or staff.",
"changeType": "rename + restrict",
"upstream": "oneroster.roles",
"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.",
"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."
},
"fieldCount": 10
},
{
"name": "alpha.class_membership",
"title": "Class Membership",
"apiCollection": "/class_memberships",
"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.",
"changeType": "rename + restrict",
"upstream": "oneroster.enrollments",
"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.",
"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."
},
"fieldCount": 10
},
{
"name": "alpha.school_period",
"title": "School Period",
"apiCollection": "/school_periods",
"purpose": "A school year, term, semester, or grading period used to answer roster questions as of a date.",
"changeType": "rename + restrict",
"upstream": "oneroster.academic_sessions",
"storage": "Public view alpha.school_period selects from alpha.school_period_base over oneroster.academic_sessions. No Alpha table stores academic-session fields.",
"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."
},
"fieldCount": 10
},
{
"name": "alpha.person_sensitive_profile",
"title": "Person Sensitive Profile",
"apiCollection": "/person_sensitive_profiles",
"purpose": "Sensitive demographic facts kept out of ordinary roster lists and returned only through authorized self, guardian, or administrative views.",
"changeType": "restrict",
"upstream": "oneroster.demographics",
"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.",
"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."
},
"fieldCount": 7
},
{
"name": "alpha.guardian_view",
"title": "Guardian",
"apiCollection": "/guardians",
"purpose": "A parent, guardian, emergency contact, or family contact for a student.",
"changeType": "rename + restrict",
"upstream": "edfi.canonical_record(resource_name=Contact)",
"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.",
"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."
},
"fieldCount": 9
},
{
"name": "alpha.guardian_relationship_view",
"title": "Guardian Relationship",
"apiCollection": "/guardian_relationships",
"purpose": "The relationship between one student and one guardian/contact.",
"changeType": "rename + restrict",
"upstream": "edfi.canonical_record(resource_name=StudentContactAssociation)",
"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.",
"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."
},
"fieldCount": 11
},
{
"name": "alpha.staff_assignment_view",
"title": "Staff Assignment",
"apiCollection": "/staff_assignments",
"purpose": "A staff member's assignment to a school, district, department, or other education organization beyond the role rows OneRoster already carries.",
"changeType": "rename + restrict",
"upstream": "edfi.canonical_record(resource_name=StaffEducationOrganizationAssignmentAssociation)",
"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.",
"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."
},
"fieldCount": 11
},
{
"name": "alpha.program_participation_view",
"title": "Program Participation",
"apiCollection": "/program_participations",
"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.",
"changeType": "rename + restrict",
"upstream": "edfi.canonical_record(resource_name in GeneralStudentProgramAssociation, StudentProgramAssociation, and specializations)",
"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.",
"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."
},
"fieldCount": 12
},
{
"name": "alpha.app_credential",
"title": "App Credential",
"apiCollection": "/app_credentials",
"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.",
"changeType": "extend",
"upstream": "None",
"storage": "Alpha extension for operational secret references; no 1EdTech source table.",
"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."
},
"fieldCount": 6
},
{
"name": "alpha.tag_definition",
"title": "Tag Definition",
"apiCollection": "/tag_definitions",
"purpose": "Governed tag registry for low-cardinality roster reporting dimensions that do not belong as enforced relationship columns.",
"changeType": "extend",
"upstream": "None",
"storage": "Alpha extension for governed low-cardinality reporting dimensions.",
"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."
},
"fieldCount": 6
},
{
"name": "alpha.object_tag",
"title": "Object Tag",
"apiCollection": "/object_tags",
"purpose": "A governed tag assignment for report slicing only. It is never used for relationships, joins to live rows, or secrets.",
"changeType": "extend",
"upstream": "None",
"storage": "Alpha extension for governed tag assignments.",
"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."
},
"fieldCount": 5
}
]workflows
[
{
"title": "List currently-enrolled students at a school filtered by level",
"text": "For the Brownsville Lower Elementary job: filter schools by typed level, narrow by campus name because place.name is display-only, then ask the selected place for active student memberships using only asOfDate and roleKind on the relationship route.",
"calls": [
"GET /places?filter=placeKind==school AND level==LL",
"GET /places/{brownsvillePlaceId}/people?asOfDate=2026-06-13&roleKind=student"
],
"traces": [
"paitd-003-place-nwea-boundary",
"paitd-004-point-in-time-memberships",
"paitd-006-tag-registry"
]
},
{
"title": "Find a student's school context",
"text": "Read the person, then ask for memberships at an asOfDate. Do not assume the latest membership row is current.",
"calls": [
"GET /people/{personId}",
"GET /people/{personId}/memberships?asOfDate=YYYY-MM-DD"
],
"traces": [
"paitd-002-person-vocabulary",
"paitd-004-point-in-time-memberships"
]
},
{
"title": "Build a teacher roster",
"text": "Start from a place or learning group. On /places/{placeId}/people, pass asOfDate and optional roleKind only; use /class_memberships when the job needs a pageable filtered collection scan.",
"calls": [
"GET /places/{placeId}/people?asOfDate=YYYY-MM-DD&roleKind=student",
"GET /class_memberships?filter=learningGroupId==group_demo AND roleKind==student&asOfDate=YYYY-MM-DD"
],
"traces": [
"paitd-004-point-in-time-memberships",
"paitd-103-query-model"
]
},
{
"title": "Reconcile NWEA account boundaries",
"text": "Read district places where place_kind=district. The district row owns nwea_district_id, brand, and modality. Schools point to it through parent_place_id.",
"calls": [
"GET /places?filter=placeKind==district",
"GET /places/{districtPlaceId}/schools"
],
"traces": [
"paitd-003-place-nwea-boundary",
"paitd-006-tag-registry"
]
},
{
"title": "Check app credential status",
"text": "Read credential existence and last rotation. The API never returns the secret value and never stores it on person or tags.",
"calls": [
"GET /app_credentials?filter=studentSourcedId==person_ada_lovelace",
"PATCH /app_credentials/{studentSourcedId}/{appId}"
],
"traces": [
"paitd-008-app-credentials",
"paitd-111-privacy-retention"
]
},
{
"title": "Read sensitive profile data lawfully",
"text": "Use the sensitive profile endpoint only with self, guardian, or administrative scope. Ordinary people lists never include demographics.",
"calls": [
"GET /person_sensitive_profiles/{personId}"
],
"traces": [
"paitd-009-sensitive-profile-privacy",
"paitd-111-privacy-retention"
]
},
{
"title": "Find a student's guardians",
"text": "Ask the relationship route instead of joining Ed-Fi Contact records or shipping relation descriptor maps in the client.",
"calls": [
"GET /people/{personId}/guardians",
"GET /guardian_relationships?filter=studentPersonId=={personId}"
],
"traces": [
"paitd-012-edfi-second-upstream",
"paitd-013-guardian-views"
]
},
{
"title": "Find active staff assignments",
"text": "Use the place staff-assignment route with asOfDate; staff classifications are already descriptor-resolved by the surface.",
"calls": [
"GET /places/{placeId}/staff_assignments?asOfDate=YYYY-MM-DD",
"GET /staff_assignments?filter=placeId=={placeId} AND staffClassification==Teacher&asOfDate=YYYY-MM-DD"
],
"traces": [
"paitd-012-edfi-second-upstream",
"paitd-014-staff-assignment-views"
]
},
{
"title": "Find a student's active programs",
"text": "Program participation is belonging, not a Results score or Policy calculation. The surface filters date ranges and resolves program descriptors.",
"calls": [
"GET /people/{personId}/program_participations?asOfDate=YYYY-MM-DD",
"GET /program_participations?filter=studentPersonId=={personId} AND programType==Special%20Education&asOfDate=YYYY-MM-DD"
],
"traces": [
"paitd-012-edfi-second-upstream",
"paitd-015-program-participation-views"
]
},
{
"title": "Poll for roster changes",
"text": "Use modifiedSince, limit, and cursor on collection list endpoints such as /people, /places, /place_memberships, and /class_memberships. Relationship reads publish their own smaller query contracts.",
"calls": [
"GET /people?modifiedSince=2026-09-01T00:00:00Z&limit=100",
"GET /places?cursor=<opaque>"
],
"traces": [
"paitd-103-query-model",
"paitd-107-eventing-model"
]
}
]boundaryRules
[
{
"title": "This is the roster, not the gradebook",
"text": "People & Orgs answers who someone is and where they belong as of a date. Results owns MAP, mastery, working grade, advancement, report-card outcomes, and gradebook rollups.",
"traces": [
"paitd-001-module-boundary"
]
},
{
"title": "Point-in-time is mandatory",
"text": "Membership rows with begin_date null are excluded from every asOfDate computation. end_date null means still active after begin_date. Consumers use is_time_locatable instead of guessing from nulls.",
"traces": [
"paitd-004-point-in-time-memberships"
]
},
{
"title": "Relationships are columns",
"text": "person_id, place_id, parent_place_id, learning_group_id, family_or_agent_person_ids, and membership ids are real relationships. Tags are only governed report slices.",
"traces": [
"paitd-006-tag-registry"
]
},
{
"title": "Secrets never leave the vault",
"text": "The Alpha surface cuts OneRoster password fields. app_credential.secret_ref points at a vault and ordinary APIs expose only existence and last rotation.",
"traces": [
"paitd-008-app-credentials"
]
},
{
"title": "Alpha roster objects are views",
"text": "person, place, memberships, school periods, sensitive profiles, guardian views, staff assignments, and program participation are public views over OneRoster or Ed-Fi base records. Only person_ext, place_ext, app_credential, tag_definition, object_tag, alpha_level_history, and age_grade_history are Alpha-owned extension tables.",
"traces": [
"paitd-011-storage-model"
]
},
{
"title": "Ed-Fi facts are view-only here",
"text": "Guardian, staff-assignment, and program-participation rows come from Ed-Fi canonical records. Alpha resolves descriptors and joins roster ids, but it does not copy or own those administrative records.",
"traces": [
"paitd-012-edfi-second-upstream",
"paitd-013-guardian-views",
"paitd-014-staff-assignment-views",
"paitd-015-program-participation-views"
]
}
]calendarEffortHandoff
{
"id": "school-calendar-effort",
"title": "People & Orgs serves the school-day calendar reads",
"dateColumn": "The GOALS Date column is bidirectional: done by <date> turns into hours per school day, and X hrs/day turns into a completion date. That date-to-effort-per-day arithmetic uses People & Orgs school-calendar reads over alpha.school_calendar, a view over Ed-Fi CalendarDate. school_period still gives academic-session boundaries; it is not a substitute for enumerated school-day facts.",
"peopleAndOrgsOwns": [
"student stable id",
"school and place membership",
"locked school level",
"tenure inputs",
"dated memberships",
"school_period start/end boundaries",
"school-day list",
"is-school-day",
"days-between",
"days-remaining",
"next-school-year-start"
],
"forbiddenClientWorkarounds": [
"weekday counting from school_period boundaries",
"holiday or break inference",
"summer-gap skip heuristics",
"local holiday lists",
"recreated rpt2_calendar logic"
],
"productionExample": {
"schoolDays": 204,
"startDate": "2025-08-13",
"endDate": "2026-07-24",
"remainingDaysExample": 31,
"meaning": "An enumerated policy/read-model answer, not a formula a roster client derives from weekdays."
},
"xpUnit": {
"statement": "1 XP ≈ 1 expected minute for expected work; equivalently, 1 expected XP ≈ 1 expected minute. Expected XP is student-independent, set by speed-running or approved calibration, and denominates expected minutes rather than active seconds or awarded-XP history.",
"plannedHoursFormula": "expected_xp / 60 before school-day pacing policy is applied",
"doNotInferFrom": "production defaults such as default_xp_goal == default_minutes_goal",
"canonicalDefinitionSites": [
"GET /api/policy_config/alpha.policy.expected_xp_minute_convention",
"https://platform3-andymontgomery-9773s-projects.vercel.app/content/alpha/customer_website#xp",
"https://platform3-andymontgomery-9773s-projects.vercel.app/content/alpha/data_dictionary#content-item-expected-xp",
"https://platform3-andymontgomery-9773s-projects.vercel.app/results/alpha/data_dictionary#table-alpha-xp-ledger"
]
},
"servingEndpoints": [
"GET /api/places/{placeId}/school_calendar/{date}",
"GET /api/places/{placeId}/school_calendar?startDate=YYYY-MM-DD&endDate=YYYY-MM-DD",
"GET /api/places/{placeId}/school_days_between?startDate=YYYY-MM-DD&endDate=YYYY-MM-DD",
"GET /api/places/{placeId}/school_days_remaining?asOfDate=YYYY-MM-DD",
"GET /api/places/{placeId}/next_school_year_start?asOfDate=YYYY-MM-DD"
],
"owningSurfaceWhenNeeded": "People & Orgs serves these school-calendar reads. The storage truth is Ed-Fi CalendarDate; alpha.school_calendar is a view, not an Alpha base table. If the view lacks a complete date range, the API fails closed instead of filling gaps with weekday math.",
"traces": [
"paitd-004-point-in-time-memberships",
"paitd-005-school-periods",
"paitd-007-tenure-and-grade-context"
]
}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."
}
]
}problemTitles
{
"people_orgs:unsupported_query_parameter": "Remove the unsupported query parameter",
"people_orgs:validation_failed": "Check the request",
"people_orgs:tenant_forbidden": "This token cannot do that",
"people_orgs:sensitive_scope_required": "Request a narrower trusted token",
"people_orgs:not_found": "We could not find that record",
"people_orgs:idempotency_conflict": "This retry key conflicts with the original request",
"people_orgs:precondition_required": "Send the current version"
}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"
}
]
}
]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.level_alias_folds",
"type": "alias-fold config",
"owner": "People & Orgs setup import",
"meaning": "Maps live source school-level labels to the locked place.level enum at write time.",
"requiredBy": "place.level and school-level report slices.",
"invalidWhen": "A consumer parses school level from source tables, place names, campus labels, or local dashboard lists 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-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.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."
}
]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"
}
]
}
]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."
}
]