Student Profiles
The student profile is the synthesis layer of the RTI loop. After the
Skill-Status Engine produces skill and domain
status for a student, the modules/profile module composes those statuses into
one educational profile per student per assessment window: a structured
object that drives the intervention recommendation and the teacher-facing
narrative.
Profiles are entirely developer-facing internal representations. The codes on this page (primary profile IDs, modifier keys, sub-flags) are identifiers in the system’s data model. They are never shown to students or families.
What a profile contains
A resolved profile has five layers, each more specific than the last.
| Layer | What it answers |
|---|---|
| Primary profile | Which broad instructional pattern best describes this student right now? |
| Access driver | For comprehension-adjacent profiles, is the bottleneck decoding, accuracy, or fluency? |
| Comprehension subprofile | If comprehension is the primary gap, is it literal, inferential, or mixed? |
| Modifier profiles (up to 5) | Which co-occurring patterns need to be layered onto the primary recommendation? |
| Sub-flags (up to 8) | Which fine-grained skill signals need to be surfaced to an educator reviewing the plan? |
Primary profiles
The primary profile is selected from a closed catalog of ~12 codes.
PR2-00 / DATA_INCOMPLETE is a system guard that indicates there is not yet
enough evidence to assign any instructional profile. It is never a “real”
educational profile and blocks the intervention recommendation path entirely.
When do_not_decide_yet is returned by the Skill-Status Engine (the tie-rule
sentinel described in The Decision Engine),
or when the student is in DATA_INCOMPLETE state, the profile module writes
no assignment row. It records a structured decline in the audit log and
the read endpoint returns the guard state with a 200 status. This is intentional:
the system has nothing meaningful to say yet, and honesty is preferable to a
placeholder guess.
Access driver
Refines reading-comprehension-adjacent primaries. Values: decoding_driven,
accuracy_driven, fluency_driven, mixed_access.
Comprehension subprofile
Further refines comprehension gap profiles. Values: literal_gap,
inferential_gap, mixed_comprehension_gap.
Modifier profiles
Up to 5 modifier profiles can co-occur with a primary. They represent secondary patterns that an intervention plan must address alongside the anchor:
| Modifier key | What it signals |
|---|---|
VOCAB_SYNTAX_MORPH_GAP | Vocabulary, syntax, or morphology weakness co-occurring with the primary |
ARABIC_ACCURACY_ONLY_MONITOR | Arabic-feature accuracy indicators need monitoring (not a standalone profile) |
WRITING_SPELLING_SUPPORT | Writing and spelling support layer needed |
LISTENING_LANGUAGE_SUPPORT | Listening/language comprehension support needed |
ON_TRACK_WITH_SKILL_ALERT | Generally on track but one or more skill alerts are open |
Sub-flags
The 8 fine-grained sub-flags are the most granular signal in the profile. They roll up into modifier profiles and drive intervention design analytics:
| Sub-flag | Scope constraint |
|---|---|
AR_MADD_FLAG | Written/visual items only; never derived from fluency probes |
AR_SHORT_VOWEL_FLAG | Written/visual items only |
AR_LETTER_CONFUSION_FLAG | Visual/orthographic confusion only (not auditory) |
AR_SHADDA_FLAG | Content/decodability tags only; opens no bundle or alert |
VOCAB_ALERT | Vocabulary signal |
SYNTAX_ALERT | Syntax signal |
MORPH_ALERT | Morphology signal |
WR_SP_ALERT | Writing and spelling signal |
Arabic-feature sub-flags (AR_MADD_FLAG, AR_SHORT_VOWEL_FLAG,
AR_LETTER_CONFUSION_FLAG, AR_SHADDA_FLAG) may only be derived from
written/visual assessment items, never from oral reading fluency (ORF) or CBM
probes. AR_LETTER_CONFUSION_FLAG is visual/orthographic only, not auditory.
Hamza is out of scope in the current phase.
Profile assignment lifecycle
Every profile assignment starts in pending_teacher_review. It becomes active
only when the teacher explicitly confirms it. This is the V-12 principle that
the teacher decides at every step. The lifecycle states are:
| Status | Meaning |
|---|---|
pending_teacher_review | Computed; awaiting teacher confirmation |
active | Teacher confirmed; drives intervention recommendation |
superseded | A recompute produced a newer assignment; this one is archived |
withdrawn | Teacher indicated more data is needed; no active assignment |
When a recompute runs, any prior active assignment moves to superseded and a
fresh pending_teacher_review row is written. The student has no active profile
until the teacher confirms the new one. The database enforces a partial unique
constraint on (org, student, window) WHERE status='active'.
Narratives
Each active profile produces a pre-written narrative rendered per audience.
The four supported audience values are teacher, parent, admin, and
student_tasks_only. Requesting audience=student returns a 422; no
student-facing copy is served through this endpoint.
Narratives are sourced from a library of 15 SPOT templates × 4 grade levels (60 rendered variants). They are rule-authored. No AI is in the narrative path. Every narrative string passes through the Language Safety filter before being written or returned. The parent-audience variant applies the stricter parent filter: no numeric scores, no internal label substrings, growth language only.
Profile narratives are developer-facing in the sense that they are returned by
the API, but their content is designed for educator and family audiences.
Never expose a teacher or admin narrative directly to a parent. Always
request audience=parent for parent-facing surfaces.
Determinism and replay
Profile resolution is fully deterministic (V-6): the same SSE snapshot +
the same pinned catalog version always produces the same profile assignment.
The admin replay endpoint (POST /api/admin/profile-replay) runs the entire
resolution dry (writing zero rows), so you can preview how a catalog version
change would affect existing assignments before publishing.
Key endpoints
The profile module exposes 6 routes, all teacher/admin only and never student-facing (FR-SPR-10).
| Endpoint | Purpose |
|---|---|
GET /api/profile/:studentId | Active or pending assignment, or the DATA_INCOMPLETE guard state |
GET /api/profile/:studentId/narrative | Filtered narrative (audience=teacher|parent|admin) |
GET /api/profiles/class/:classId | Class distribution (ClassTeacher-scoped) |
POST /api/profile/:studentId/review-resolution | Teacher confirms, withdraws, or maintains |
POST /api/admin/profile-catalog/publish | Publish a new catalog version (completeness gate) |
POST /api/admin/profile-replay | V-6 dry-run replay; writes nothing |
Connections
- Upstream: Skill-Status Engine: the 5-layer decision engine whose skill and domain status snapshots feed profile resolution.
- Downstream: Intervention Bundles: the active profile is the key that selects a bundle from the 21-row profile-to-bundle map.
- Workflow: Teacher Activation Workflow: the
teacher review step that moves a profile from
pending_teacher_reviewtoactive. - Language rules: Language Safety: the filter applied at every narrative write and render.