Analytics Alpha Data Dictionary
Analytics is the derived-facts layer: typed rollups computed from Events and Results, written when source events/results close, and read by reports without recomputing platform math.
Overview
Upstream Inputs
Accepted ITDs, table set, API axes, metric-check trace, no-alias extend-only storage.
Event source refs, close notifications, Caliper moment boundary, source imports.
XP ledger, mastery state, MAP score/growth/sitting rows, durable result evidence.
KC, course, track, component, subject, and policy refs.
Student, school, enrollment, academic-session, and point-in-time identity refs.
CalendarDate source behind alpha.school_calendar school-day denominator; missing coverage is a launch/repair state, not a report formula.
Metric-Check Trace
| Metric Check | Analytics Object | Derived Facts | ITD |
|---|---|---|---|
minutes|Caliper events | alpha.analytics_time_window (derived) + alpha.analytics_school_day_minutes (report tile) | active_seconds, inactive_seconds, waste_seconds (derived from Events); minutes_per_enrolled_school_day (report tile, ingested numerator / calendar denominator) | aitd-006-school-day-minutes |
XP | alpha.analytics_xp_rollup | xp_total, daily_xp_goal, enrolled_school_day_count, xp_goal (policy denominator), xp_remaining, xp_goal_percent (uncapped when populated), on_track, positive_xp, negative_xp, null_reason; source_missing is a repair state, not an app-side fallback | aitd-007-xp-rollups |
mastery|student_kc_state | alpha.analytics_mastery_delta | grade_levels_mastered (subject, grade, completed_on); per-state previous_value, new_value, delta_value, transition_kind | aitd-008-mastery-and-grade-levels |
RIT|GrowthX|MAP growth windows | alpha.analytics_map_growth_rollup | rit, achievement_percentile, growth_percentile, growth_x (= observed / projected, ALPHA-2), growth_x_target, on_track | aitd-009-map-growth-rollups |
MAP sittings/scores | alpha.analytics_map_growth_rollup | test_of_record summary plus sitting_count and retake_count for audit/report cells | aitd-009-map-growth-rollups |
completion|curriculum refs | alpha.analytics_completion_rollup | xp_earned, xp_remaining, completion_percent, null_reason (NEVER a 1-if-active fallback) | aitd-010-completion-rollups |
Learning Report accuracy | alpha.analytics_accuracy | correct_question_count, total_question_count, incorrect_question_count, accuracy_percent, null_reason | aitd-001-report-source-ingestion |
Learning Report attempts | alpha.analytics_attempt_rollup | attempt_count, max_attempt_ordinal, source_event_refs, policy_ref | aitd-001-report-source-ingestion |
Learning Report response latency | alpha.analytics_response_latency_rollup | response_count, response_time_ms_total, response_time_ms_avg, response_time_ms_min, response_time_ms_max, policy_ref | aitd-001-report-source-ingestion |
Learning Report hint usage | alpha.analytics_hint_usage_rollup | hint_request_count, hint_view_count, hint_used_count, source_event_refs, policy_ref | aitd-001-report-source-ingestion |
GOALS target date | analytics.school_days_remaining | instructional_days_remaining, instructional_dates, xp_unit.*, effort.* | aitd-018-goals-school-days-remaining |
alpha.analytics_accuracy, the Accuracy (P7) recipe, the raw SQL path, and GET /alpha/analytics/v1/accuracy-rollups. The endpoint is served at this wave's implementation cell; a report must not compute percent correct from reporting.processed_facts or any private app allowlist.
alpha.analytics_attempt_rollup, alpha.analytics_response_latency_rollup, and alpha.analytics_hint_usage_rollup. Read GET /alpha/analytics/v1/attempt-rollups, GET /alpha/analytics/v1/response-latency-rollups, and GET /alpha/analytics/v1/hint-usage-rollups; do not parse Events player extensions in reports.
Completion Rollup Retention
reviewer-analytics and analytics-*debug* retain current completion-rollup rows and sweep superseded rows under alpha.policy.analytics.completion_rollup_retention.v2026-07-03. Historical probe volume must not affect endpoint latency.
GET /alpha/analytics/v1/completion-rollups is a page-bounded current-row read. The API filters out rows with superseded_at or source_deleted_at before sorting or paging, accepts limit/cursor, and must not run an unbounded total-count query.
| tenant | totalRows | currentRows | supersededRows | checkedAt |
|---|---|---|---|---|
analytics-debug-debug-1781267631521 | 45 | 45 | 0 | 2026-07-03T23:33:00Z |
analytics-live-debug-1781267728987 | 1250 | 1250 | 0 | 2026-07-03T23:33:00Z |
reviewer-analytics | 1606 | 1606 | 0 | 2026-07-03T23:33:00Z |
Issue #286 retention bound: reviewer/debug total rows are bounded by current rollup-key cardinality plus transient in-flight page work. Repeated probe runs must not accumulate superseded completion-rollup history.
Report Source Adapters
These are the named server-side adapters pinned by the approved Analytics architecture. A Learning Report fact is report-grade only when Analytics ingests the named source shape, normalizes it on the server, and writes source_import_id provenance.
| adapter | panel | sourceTable | reportColumns | analyticsObject | adapterContract | itd |
|---|---|---|---|---|---|---|
| timeback-xp-time-accuracy | XP Goal (P5), Time Commitment (P6), Accuracy (P7) | reporting.processed_facts | xp_earned, active_seconds, total_questions, correct_questions, subject, date, app, source, score_type | alpha.analytics_xp_rollup, alpha.analytics_school_day_minutes, alpha.analytics_accuracy | Accept the source-shaped producer row for this adapter; normalize server-side and reject only missing required fields or unlinked governed refs. | aitd-007-xp-rollups |
| timeback-map | MAP Results (P3) | reporting.hp_map_results | testritscore, testpercentile, wintertowinterobservedgrowth, wintertowinterprojectedgrowth, typicalwintertowintergrowth, wintertowinterconditionalgrowthpercentile, termname, growthmeasureyn | alpha.analytics_map_growth_rollup | Accept the full source-shaped reporting.hp_map_results row, including wintertowinter*, fall/winter/spring window blocks, goal1..goal8 blocks, and any unknown extra columns. Unknown extra columns are ignored; missing required columns or unlinked identities produce typed Problems. | aitd-009-map-growth-rollups |
| timeback-grade-mastery | Grade Levels Mastered (P4) | reporting.assessment_results | student_sourced_id, score, score_status, score_date, learning_objective_set, assessment_line_item_sourced_id | alpha.analytics_mastery_delta | Accept the source-shaped producer row for this adapter; normalize server-side and reject only missing required fields or unlinked governed refs. | aitd-008-mastery-and-grade-levels |
| timeback-completion | Course Completion (P2) | reporting.processed_facts + reporting.courses + reporting.course_components | xp_earned (earned) + course expected XP (remaining denominator) | alpha.analytics_completion_rollup | Accept the source-shaped producer row for this adapter; normalize server-side and reject only missing required fields or unlinked governed refs. | aitd-010-completion-rollups |
null_reason=source_missing or an adapter Problem. It never hard-codes a target student's answer and never asks a skill pack to reproduce report math.
Storage Model
Alpha extension only. Analytics creates new alpha.analytics_* tables for derived facts and stores source references plus derived values. It never aliases a 1EdTech base table and never copies raw Events/Results source columns when a reference can be stored.
- Correct: store
source_event_id,source_state_ref,source_result_refs,source_ledger_refs,map_score_id, andcurriculum_scope_refsplus derived values such asactive_seconds_totalorgrowth_x. - Wrong: copy raw Caliper JSON, Results score rows, NWEA CDF fields, Curriculum trees, calendar payloads, or source app/student display strings into Analytics.
- Raw DB path: query
alpha.analytics_*tables at their documented grain. Do not drop into raw Events/Results tables and redo the math.
Primary ITDs: aitd-000-extend-only-storage, aitd-003-close-time-materialization, aitd-110-axis-conformance-evidence
Policy Reference
Every policy_ref named in a table below resolves here to the rule family it controls, the values an app must read from policy/config, and the raw-DB rule that keeps reports from doing the platform's work.
Time Classification
alpha.policy.analytics.time_classification.v2026-06-10
Answers: What makes a second active, inactive, or waste?
Controls: Classifies closed Events time into fact_kind rows before any report reads it.
Definitions
active_seconds- Seconds from a closed Event that resolves to a registered learning activity, a reportable subject or content/course ref, and no idle/waste override.
inactive_seconds- Seconds from a closed Event that are reportable as time present but not active learning work, such as idle gaps, paused/background activity, or missing engagement evidence under the policy.
waste_seconds- Seconds from a closed Event or TimebackProfile anti-pattern event that the policy classifies as gaming, cheating, distraction, or counterproductive work.
Current Effective Values
| Value | Current Setting | What It Means In A Report |
|---|---|---|
eligible_event_tuples | TimeSpentEvent/SpentTime; ActivityEvent/Completed; TimebackProfile.AntiPatternEvent/*. | Other Caliper tuples can still exist in Events, but they contribute zero Analytics seconds unless this policy adds them. Fresh evidence also shows Event/Created, ToolUseEvent/Used, AnnotationEvent/Tagged, AssessmentItemEvent/*, SessionEvent/*, AssessmentEvent/*, FeedbackEvent/*, and GradeEvent/* as observed non-time sources. |
active_seconds rule | Closed source event + resolved real student + reportable subject/content/course ref + foreground learning activity + no idle/waste override. | A source tuple alone is not enough; the row must also resolve to the school-language refs Analytics reports on. |
foreground classifier | Foreground means the source was the active learning app or activity at the event timestamp, not hidden/background/paused, and the event links to a content_id, course_id, kc_id, or subject_id accepted by policy. | A foreground TimeSpentEvent/SpentTime contributes its reported duration up to the idle threshold; an ActivityEvent/Completed contributes active seconds only through its linked time source, not by inventing duration from a point event. |
zero-contribution observed tuples | Event/Created; ToolUseEvent/Used; AnnotationEvent/Tagged; AssessmentItemEvent/Completed or Skipped; SessionEvent/LoggedIn or LoggedOut; AssessmentEvent/Started, Paused, or Submitted; FeedbackEvent/*; GradeEvent/Graded. | These tuples can be source evidence, result evidence, or audit context, but they do not add active/inactive/waste seconds unless a future accepted policy version explicitly makes them duration-bearing. |
idle_after_seconds | 60 | After 60 consecutive seconds with no foreground learning activity inside an open time source, additional seconds are inactive_seconds until activity resumes or the source closes. |
paused/background rule | Paused actions and browser/app visibility values hidden/background become inactive_seconds. | Inactive time is reportable as present-but-not-working; it is not active work and it is not gaming by default. |
waste_seconds rule | TimebackProfile anti-pattern kinds gaming, cheating, distraction, counterproductive_work. | Waste seconds stay separate from inactive seconds and can also feed negative XP evidence through Results. |
subject fallback ladder | 1 source subject_id if canonical; 2 linked Content/Curriculum subject from content_id/course_id/kc_id; 3 app/source source-label normalization; 4 MAP/report source-label normalization when the report asks for MAP proxy subject; 5 source_unlinked or adapter_rejected. | Reports never parse source app or subject strings; the materialized row either has a canonical subject_id or a typed rejection/null_reason. |
display rounding | Store seconds as NUMERIC(14,3); display minutes as seconds / 60 rounded to 3 decimal places. | Reports read display_active_minutes or active_minutes; they do not divide and round locally. |
Required Config Fields
| Config Field | Meaning | Example / Source |
|---|---|---|
eligible_event_types | Caliper/TimebackProfile event types allowed to contribute seconds. | ["TimeSpentEvent", "ActivityEvent", "TimebackProfile.AntiPatternEvent"] |
active_source_rules | Registry refs for apps/actions/content refs that qualify as active learning work. | ["caliper:TimeSpentEvent/SpentTime", "caliper:ActivityEvent/Completed"] with real-student, subject/content/course ref, and foreground checks |
inactive_rules | Policy-owned idle, paused, missing-engagement, and background rules. Values live in alpha.policy, not in reports. | {"idle_after_seconds":60, "paused_actions":["Paused"], "background_visibility":["hidden","background"]} |
waste_rules | Policy-owned anti-pattern/gaming rules that create waste_seconds or negative XP evidence. | {"event_profile":"TimebackProfile", "anti_pattern_types":["gaming", "cheating", "distraction", "counterproductive_work"]} |
subject_alias_policy_ref | The subject normalization policy used before a fact is written. | alpha.policy.analytics.subject_normalization.v2026-06-10 |
Raw DB rule: Use fact_kind and seconds_delta from alpha.analytics_event_time_fact or totals from alpha.analytics_time_window. Do not parse Caliper type/action or processed_facts app/subject strings in a report.
Trace: aitd-005-time-facts-and-windows, aitd-011-policy-and-enum-normalization, aitd-012-corrections-and-reversals
Window Boundaries
alpha.policy.analytics.window.v2026-06-10
Answers: Which dates belong in a day, week, term, school year, or custom window?
Controls: Defines half-open reporting windows and the school timezone used by time and XP rollups.
Definitions
half-open range- window_start is included and window_end is excluded.
school timezone- Calendar dates are interpreted in the school/org timezone named by policy.
custom window- An explicit policy-backed range used for reconciliation or a named report.
Current Effective Values
| Value | Current Setting | What It Means In A Report |
|---|---|---|
range convention | [window_start, window_end) | window_start is included; window_end is excluded for every day/week/term/school-year/custom rollup. |
week_start_day | Monday | Weekly rollups start Monday in the school timezone. |
timezone | People and Orgs school/org timezone; tenant default only if the school timezone is policy_pending. | A missing timezone does not authorize client-side timezone guessing. |
term/school_year source | People and Orgs academic-session rows. | Reports filter by canonical_term_id or stored window dates; they do not parse labels like Winter 2026. |
Required Config Fields
| Config Field | Meaning | Example / Source |
|---|---|---|
school_timezone_source | Where the school timezone comes from. | People and Orgs school/org config |
week_start_day | First day of the platform week. | Monday |
academic_session_source | Source of terms and school years. | People and Orgs academicSession rows |
Raw DB rule: Filter by window_kind, window_start, and window_end. Do not derive windows from modified_at, source_closed_at, or source term strings.
Trace: aitd-005-time-facts-and-windows, aitd-103-axis-query-model, aitd-011-policy-and-enum-normalization
Subject Normalization
alpha.policy.analytics.subject_normalization.v2026-06-10
Answers: How do source subject names become the canonical Alpha subject_id?
Controls: Normalization source subjects and app labels to the Alpha subject enum before Analytics writes a derived fact.
Definitions
canonical subject- The subject_id stored on Analytics rows after write-time source-label normalization.
proxy subject- A source value that maps to a reporting subject for MAP or learning-report purposes, such as fastmath to math.
adapter finding- A typed rejection or null_reason when a source subject cannot be safely mapped.
Current Effective Values
| Value | Current Setting | What It Means In A Report |
|---|---|---|
canonical subject_id values | math, reading, language, science, vocabulary, writing | Analytics rows use these values only. |
learning source-label normalization | FastMath->math; ELA/Language Arts->language; Vocab/Vocabulary->vocabulary; Science->science. | These normalization happens before a derived fact is written. |
MAP/report source-label normalization | FastMath->math; Vocab->language; Writing->language. | Used when a MAP/goal/report question needs the Brainlift proxy subject rules rather than the activity subject itself. |
unknown source value | analytics:adapter_rejected or quality_status=source_unlinked. | A consumer never creates a new subject string to make a report work. |
Required Config Fields
| Config Field | Meaning | Example / Source |
|---|---|---|
canonical_values | Allowed subject_id values. | math, reading, language, science, vocabulary, writing |
source_label_normalization | Source labels mapped at write time. | FastMath->math, Vocab/Vocabulary->vocabulary, ELA/Language Arts->language |
rejected_values | Out-of-scope or test values that must not become new subjects. | dev/screener junk, unknown source strings |
Raw DB rule: Use subject_id on alpha.analytics_* rows. Do not group by source subject/app strings or create local alias tables.
School-Day Denominator
alpha.policy.school_day.v2026-06-10
Answers: Which days count in minutes per enrolled school day?
Controls: Requires an Alpha school calendar over Ed-Fi CalendarDate plus effective-dated enrollment and optional subject assignment. The ratified denominator is days the student was enrolled and school was in session. A Learning Report row is reportable only when this denominator is materialized by Analytics.
Definitions
enrolled_school_day_count- Instructional calendar dates for the school that intersect a time-locatable student enrollment.
excluded_school_day_count- Calendar dates inside the requested range that are excluded by the school-day policy, such as weekend, holiday, workshop, or MAP-testing dates.
subject denominator- A date counts for a subject only when the student had a subject course, test, or assignment on that date.
MAP exclusion- NWEA MAP testing days are explicitly not school days for the time-commitment denominator.
documented legacy divergence- The legacy Learning Report time-commitment panel used an undocumented per-app/session filter. Its displayed values are not the reconciliation target because they cannot be reproduced from source rows under a consistent denominator. Source: loop/context/alpha-minutes-decision.md, Andy-ratified 2026-06-11.
source-missing repair state- If alpha.school_calendar coverage is unavailable for the requested school/range, Analytics writes null_reason=source_missing for repair/audit and the report must show the missing-source state rather than guess. This is not the ordinary report path.
Current Effective Values
| Value | Current Setting | What It Means In A Report |
|---|---|---|
launch/reportability requirement | alpha.school_calendar coverage must exist before Learning Report time-commitment rows are complete. | A source_missing row is a blocking repair signal. It is not a permanent answer and does not authorize client-side denominator math. |
ratified denominator | days the student was ENROLLED and school was IN SESSION. | Enrollment begin/end bound the denominator; the student's school calendar is authoritative; MAP testing days are excluded; per-subject rows count a day only if the student had a subject assignment that day. |
is_school_day | reason=instructional only. | Every other Alpha reason is excluded unless a future accepted policy version explicitly maps a governed value to instructional. |
excluded reasons | weekend, teacher_workshop, holiday_break, nwea_map_testing, other. | NWEA MAP testing days are not school days for this time-commitment denominator. |
MAP testing exclusion | 3 terms x 4 days = 12 excluded MAP days per school year when calendar coverage exists. | The actual dates come from alpha.school_calendar, not a hard-coded date list. |
enrollment intersection | begin_date NULL is excluded; end_date NULL remains active for dates on/after begin_date. | Same point-in-time rule as People and Orgs. |
subject denominator | A date counts for a subject only when the student has a subject course, test, or assignment on that date. | All-subject rows use subject_id null and do not require subject assignment. |
legacy panel divergence | Documented divergence, not the platform target. | Legacy values are not reproducible from source because the old panel applied an undocumented filter. Analytics exposes one source-backed denominator under alpha.policy.school_day.v2026-06-10. |
forbidden fallback | processed_facts active dates, attendance dates, and raw calendar-day counts are not school-day denominators. | If calendar coverage is missing, emit null/source_missing for repair/audit; do not fabricate enrolled_school_day_count or excluded_school_day_count. |
Required Config Fields
| Config Field | Meaning | Example / Source |
|---|---|---|
calendar_source | Calendar rows behind alpha.school_calendar. | Ed-Fi CalendarDate.CalendarEvents, surfaced as the Alpha school calendar source for denominator materialization |
reason_map | Mapping from Ed-Fi CalendarEventDescriptor values to Alpha reasons. | See the Calendar Code Map below. |
enrollment_source | Effective-dated People and Orgs membership/enrollment rows. | begin_date/end_date point-in-time rule |
subject_assignment_source | Course/test assignment evidence used for subject-specific denominators. | Curriculum/Results refs |
Raw DB rule: Read active_minutes, enrolled_school_day_count, excluded_school_day_count, minutes_per_enrolled_school_day, quality_status, and null_reason from alpha.analytics_school_day_minutes. Ordinary Learning Report rows use quality_status in (ok, corrected) and null_reason=none. If a row is source_missing, show the repair state and fix/replay the source; do not recalculate a calendar denominator in SQL.
Trace: aitd-006-school-day-minutes, aitd-011-policy-and-enum-normalization
XP Rollup
alpha.policy.analytics.xp_rollup.v2026-06-10
Answers: Which XP awards, penalties, goals, and remaining amounts are included in the Learning Report?
Controls: Ingests the report-grade XP value from reporting.processed_facts through the timeback-xp-time-accuracy adapter, preserves signed audit fields, resolves the daily goal from policy, and applies the uncapped XP goal percent rule using the stored school-day denominator.
Definitions
xp_total- The report-ready XP total for the student/subject/window after the report-source adapter applies source-label normalization, exclusions, corrections, and policy normalization.
positive_xp- Sum of nonnegative ledger awards in the window.
negative_xp- Sum of penalties and reversals, kept signed.
daily_xp_goal- The daily XP target under policy for this student, subject, and window. It may be known even when the school-day denominator is missing.
enrolled_school_day_count- The school-day denominator used for XP goal percent: days the student was enrolled and school was in session, with the same subject-assignment rule as time commitment.
xp_goal- The window XP target: daily_xp_goal multiplied by enrolled_school_day_count. Analytics stores it so consumers do not multiply locally.
xp_remaining- The report-ready remaining XP after xp_total is applied to xp_goal.
xp_goal_percent- How far through the XP goal the student is. It is intentionally uncapped, so values above 100 are valid.
xp_completion_percent- Deprecated compatibility alias for xp_goal_percent. It has no separate formula and must carry the same uncapped value until consumers migrate to xp_goal_percent.
Current Effective Values
| Value | Current Setting | What It Means In A Report |
|---|---|---|
report source | timeback-xp-time-accuracy adapter over reporting.processed_facts. | Naive SUM(processed_facts.xp_earned) reproduced only 1 of 6 report subjects in architecture grounding, so the adapter is the source of the report-grade value. |
ledger_source | Results alpha.xp_ledger for audit refs where a platform ledger row exists. | The Learning Report tile reads xp_total from Analytics, not a consumer ledger sum. |
included quality statuses | ok, corrected, reversed when signed into the net total. | source_missing, source_unlinked, policy_pending, and adapter_rejected are audit/findings, not ordinary display totals. |
quality_status=ok | Include in positive_xp or negative_xp according to the signed XP value. | Ordinary report rows include ok. |
quality_status=corrected | Include the current corrected signed value; exclude the superseded row by superseded_at/source_deleted_at current-row filters. | Corrections are reportable only through the current Analytics row. |
quality_status=reversed | Include only as a signed reversal contribution when the row carries reversal_count or a negative signed XP delta. | A reversal reduces net_xp; it does not erase the audit trail. |
quality_status source_missing/source_unlinked/policy_pending/adapter_rejected | Exclude from display totals; expose through import/problem/audit reads. | These statuses explain why no reportable XP total could be materialized. |
positive_xp | Positive contribution audit subtotal from the adapter/ledger refs. | Nonnegative by definition; supports explanations but is not a client formula source. |
negative_xp | Penalty/reversal audit subtotal from the adapter/ledger refs. | Kept zero-or-negative; never clamped away by a report. |
xp_total | The report-ready XP total the Learning Report renders. | Non-null values require source_import_id provenance under aitd-004. |
denominator source | alpha.analytics_school_day_minutes / alpha.school_calendar school-day denominator. | XP goal fields use the same materialized enrolled_school_day_count as time commitment; a source_missing denominator is a repair state, not an app-side fallback. |
canonical XP percent policy | alpha.policy.analytics.xp_goal_percent.v1. | There is one rule only: xp_goal_percent = total_xp_earned / (daily_xp_goal x enrolled_school_days) * 100. The result is uncapped when the denominator is present. |
XP denominator | daily_xp_goal x enrolled_school_day_count. | enrolled_school_day_count uses the ratified school-day rule: enrolled and school-in-session days, MAP days excluded, per-subject days only with a subject assignment. If that count is null/source_missing, xp_goal_percent is also null/source_missing. |
xp_goal and remaining | xp_goal = daily_xp_goal x enrolled_school_day_count; xp_remaining = max(xp_goal - xp_total, 0) only when xp_goal is present; xp_goal_percent is NOT capped by xp_remaining. | Over-goal rows are valid when the shared school-day denominator is present. The worked example is intentionally above 100% so readers do not cap the policy. |
deprecated alias | xp_completion_percent, when present for compatibility, equals xp_goal_percent exactly and is also uncapped. | It must never mean capped completion, captured percent, or ordinary 0-to-100 course completion. |
worked over-goal XP example status | reportable Analytics rows may exceed 100%. | The example row shows xp_goal_percent above 100 because the policy is uncapped. This is the canonical report path once the school-day denominator is materialized. |
Required Config Fields
| Config Field | Meaning | Example / Source |
|---|---|---|
report_source_adapter | Named source adapter for report XP values. | timeback-xp-time-accuracy over reporting.processed_facts |
ledger_source | Canonical source for awarded XP audit refs when present. | Results alpha.xp_ledger |
window_policy_ref | Window policy used for grouping. | alpha.policy.analytics.window.v2026-06-10 |
goal_policy_ref | Policy/Curriculum source for daily XP goals and school-day denominator. | alpha.policy.analytics.xp_goal_percent.v1 plus Curriculum expected_xp refs |
include_reversals | Whether signed reversal rows are included in ordinary net totals. | true under current Analytics policy |
Raw DB rule: Read alpha.analytics_xp_rollup.xp_total, daily_xp_goal, enrolled_school_day_count, xp_goal, xp_remaining, xp_goal_percent, and null_reason. Use Results xp_ledger or reporting.processed_facts only through authorized source refs, not as report math. If a row has null_reason=source_missing, repair/replay the school-day source; do not compute XP goal fields locally. If a legacy row still exposes xp_completion_percent, treat it only as the same uncapped value as xp_goal_percent.
Trace: aitd-007-xp-rollups, aitd-001-report-source-ingestion, aitd-004-provenance-no-literals, aitd-012-corrections-and-reversals
XP Goal Percent
alpha.policy.analytics.xp_goal_percent.v1
Answers: How is the Learning Report XP percent computed?
Controls: Defines the one uncapped XP percent rule used by Analytics XP rollups and Learning Report XP panels.
Definitions
total_xp_earned- The report-ready XP total in alpha.analytics_xp_rollup.xp_total.
daily_xp_goal- The policy-defined daily XP target for the student/subject/window.
enrolled_school_days- The ratified denominator: enrolled and school-in-session days, using the student's school calendar, excluding MAP testing days, and requiring subject assignment for subject rows.
xp_goal_percent- total_xp_earned / (daily_xp_goal x enrolled_school_days) x 100, with no cap.
Current Effective Values
| Value | Current Setting | What It Means In A Report |
|---|---|---|
denominator source | enrolled_school_day_count stored by Analytics under alpha.policy.school_day. | The same school-calendar denominator is used for time commitment and XP goal percent. Reports read it; they do not count active days, weekdays, or attendance rows. |
formula | xp_goal_percent = total_xp_earned / (daily_xp_goal x enrolled_school_days) x 100. | total_xp_earned is xp_total; the denominator is daily_xp_goal multiplied by enrolled_school_day_count. Apply only when enrolled_school_day_count is present. |
cap behavior | uncapped when populated. | Calendar-backed Analytics rows may legitimately remain above 100 instead of being capped. source_missing is only a repair state for uncovered school/window coverage, not the ordinary XP-goal report path. |
invalid capped variant | rejected. | No field, website, implementation, report, or skill pack may define a captured/capped 0-to-100 XP percent variant for this tile. |
null behavior | null_reason=policy_pending, source_missing, or no_school_days. | If daily_xp_goal or enrolled_school_day_count is missing, do not substitute active days or return 100%; treat the row as not reportable until repaired. |
Required Config Fields
| Config Field | Meaning | Example / Source |
|---|---|---|
daily_xp_goal_source | Source of the daily XP target. | alpha.policy.analytics.xp_goal_percent.v1 / Curriculum Policy |
school_day_source | Source of enrolled_school_days. | alpha.policy.school_day.v2026-06-10 |
cap_behavior | Whether the percent is capped. | uncapped |
Raw DB rule: Read xp_goal_percent and null_reason from alpha.analytics_xp_rollup. Do not clamp it, do not calculate a separate capped percent in SQL, and do not produce a private xp_goal_percent when enrolled_school_day_count is null/source_missing.
Trace: aitd-007-xp-rollups, aitd-006-school-day-minutes, aitd-011-policy-and-enum-normalization
XP Expected-Minute Unit
alpha.policy.analytics.xp_expected_minute.v2026-06-14
Answers: How does GOALS convert remaining XP into expected minutes and hours?
Controls: Defines the unit convention used by /school-days-remaining effort projections: expected XP is expected time, not a client-owned conversion constant.
Definitions
expected_xp- XP assigned by Curriculum/Policy as an expected amount of work. For GOALS effort projection, this is measured in expected minutes.
xp_per_expected_minute- The surface-owned unit conversion. Current value: 1.
xp_per_hour- The expected-hour conversion. Current value: 60.
expected_minutes_remaining- Remaining XP converted to expected minutes by dividing by xp_per_expected_minute.
hours_remaining- Expected minutes remaining divided by 60.
Current Effective Values
| Value | Current Setting | What It Means In A Report |
|---|---|---|
xp_per_expected_minute | 1 | 1 XP equals 1 expected minute for GOALS and target-date effort reads. |
xp_per_hour | 60 | 60 XP equals one expected hour. |
hours formula | hours_remaining = expected_minutes_remaining / 60. | Analytics returns the value; GOALS does not keep a private XP_PER_HOUR constant. |
school-day pacing formula | required_hours_per_school_day_to_target_date = hours_remaining / school_days_until_target_date. | Null when targetDate is absent or the target window has zero instructional days. |
finish-date formula | school_days_needed_at_hours_per_school_day = ceil(hours_remaining / hoursPerSchoolDay). | target_date_at_hours_per_school_day is the returned instructional date at that ordinal, or null when the requested endDate window is too short. |
Required Config Fields
| Config Field | Meaning | Example / Source |
|---|---|---|
xp_per_expected_minute | How many XP equal one expected minute. | 1 |
xp_per_hour | How many XP equal one expected hour. | 60 |
unit_owner | Where the convention lives. | alpha.policy.analytics.xp_expected_minute.v2026-06-14 |
applies_to | Fields that use this unit for GOALS effort projection. | expected_xp, daily_xp_goal, xp_remaining, xp_unit.*, effort.* |
Raw DB rule: Resolve alpha.policy.analytics.xp_expected_minute.v2026-06-14 before converting XP into expected minutes/hours. Do not hard-code XP_PER_HOUR in GOALS, the skill pack, or raw SQL; do not infer the unit from observed student actuals.
Trace: aitd-018-goals-school-days-remaining, aitd-007-xp-rollups, aitd-011-policy-and-enum-normalization
Accuracy (P7)
alpha.policy.analytics.accuracy.v2026-06-12
Answers: What percent of reportable questions did the student answer correctly?
Controls: Ingests report-grade question numerator and denominator fields from reporting.processed_facts through the timeback-xp-time-accuracy adapter and materializes the Learning Report Accuracy panel.
Definitions
correct_question_count- Reportable questions answered correctly in the window after server-side subject/app/source normalization.
total_question_count- Reportable question attempts in the same window and policy scope.
incorrect_question_count- total_question_count minus correct_question_count, retained for explanation and audit.
accuracy_percent- correct_question_count / total_question_count x 100, rounded by Analytics under policy_ref.
no_questions- Typed null state when the window has zero reportable question attempts.
Current Effective Values
| Value | Current Setting | What It Means In A Report |
|---|---|---|
report source | timeback-xp-time-accuracy adapter over reporting.processed_facts. | The same adapter that owns XP and Time Commitment also owns Accuracy because the live report source carries total_questions and correct_questions. |
formula | accuracy_percent = correct_question_count / total_question_count x 100. | Analytics stores the percent. Consumers read it and never recompute from processed_facts. |
denominator zero | accuracy_percent=null and null_reason=no_questions. | A report shows unavailable/no attempts instead of pretending the student had 0% or 100% accuracy. |
question filters | Only rows accepted by the adapter under policy_ref count. | Apps do not keep local app/source/score_type allowlists. |
source provenance | Non-null values require source_import_id. | The report can audit which source-shaped import produced the Accuracy row. |
Required Config Fields
| Config Field | Meaning | Example / Source |
|---|---|---|
report_source_adapter | Named source adapter for report Accuracy values. | timeback-xp-time-accuracy over reporting.processed_facts |
question_columns | Source-shaped columns the adapter accepts. | total_questions, correct_questions, subject, date, app, source, score_type |
include_source_rules | Policy-owned app/source/score_type rules for whether a processed_facts row contributes to Accuracy. | reportable learning work; test/dev/internal rows excluded by policy |
rounding | Display precision for the stored percent. | 3 decimal places |
Raw DB rule: Read correct_question_count, total_question_count, incorrect_question_count, and accuracy_percent from alpha.analytics_accuracy. Do not query reporting.processed_facts, divide totals locally, or maintain app/source/score_type allowlists in the report.
Trace: aitd-001-report-source-ingestion, aitd-004-provenance-no-literals, aitd-011-policy-and-enum-normalization
Mastery Delta
alpha.policy.results.mastery_state.v2026-06-10
Answers: Which mastery state changes are reportable?
Controls: Defines which Results state dimensions create Analytics delta rows and how null/blocked transitions are represented.
Definitions
state_dimension- The part of Results mastery state that changed, such as durable_mastery or next_due_at.
transition_kind- The report category for the change, such as acquired, improved, decayed, or blocked.
effective_at- The time the change counts for as-of reporting.
Current Effective Values
| Value | Current Setting | What It Means In A Report |
|---|---|---|
state dimensions | initial_mastery, current_retention, durable_mastery, fluency_state, next_due_at. | Closed list for this policy version; there is no "other per policy" dimension on Analytics rows. |
mastery_cutoff_ref | alpha.policy.mastery_cutoff:2026-06-03 = 89.5%, displayed as >=90%. | Owned by Results/Policy; Analytics records the delta created by that settled Results state. |
retention_model_ref | alpha.policy.retention_model:2026-06-03 = FIRe-style, exposed output next_due_at. | Results owns retention/decay math. Analytics shows previous_value, new_value, delta_value, transition_kind, and effective_at. |
initial_mastery rule | A Results state transition crossing the 89.5% acquisition cutoff writes state_dimension=initial_mastery and transition_kind=acquired. | Analytics records the transition; Results remains the source of truth for the state. |
durable_mastery rule | A durable Results mastery state change writes state_dimension=durable_mastery with previous_value, new_value, and delta_value. | Reports read the delta row instead of recomputing mastery from attempts. |
current_retention rule | A Results FIRe retention output change writes state_dimension=current_retention; decreases use transition_kind=decayed and increases use improved or corrected as appropriate. | The curve coefficients stay in Results/Policy; Analytics stores the observable change. |
next_due_at rule | A Results retention schedule change writes state_dimension=next_due_at with transition_kind=review_due when the due date becomes actionable. | A Learning Report can show what became due without running a retention scheduler. |
fluency_state rule | A Results fluency/automaticity state change writes state_dimension=fluency_state and transition_kind=fluency_changed. | Fluency remains a state output, not a client-side speed calculation. |
FIRe summary | Results policy emits current_retention and next_due_at from the FIRe-style retention model; Analytics materializes only the before/after values and transition kind. | The data dictionary intentionally does not publish curve coefficients as report logic. |
decay visibility | current_retention changes are materialized as state_dimension=current_retention; due-date changes as state_dimension=next_due_at. | A parent can see that retention decayed or a review became due without a skill pack running the decay curve. |
blocked transition | transition_kind=blocked and quality_status/source null_reason explain missing evidence. | No guessed mastery delta is written. |
Required Config Fields
| Config Field | Meaning | Example / Source |
|---|---|---|
state_source | Current/state history source. | Results alpha.student_kc_state |
evidence_source | Results/KC evidence refs explaining the transition. | alpha.result_kc_evidence |
blocked_transition_handling | How missing source/policy evidence is surfaced. | transition_kind=blocked plus quality_status/null_reason |
Raw DB rule: Read alpha.analytics_mastery_delta for changes between dates. Do not recompute mastery, decay, HMG, or review due dates from attempts.
Trace: aitd-008-mastery-and-grade-levels, aitd-011-policy-and-enum-normalization
MAP Growth
alpha.policy.analytics.map_growth.v2026-06-10
Answers: Which RIT, Growth X, norms set, and MAP window should the report show?
Controls: Ingests reporting.hp_map_results through timeback-map, applies test-of-record dedup, and exposes report-ready RIT, achievement percentile, growth percentile, projected growth, Growth X, sitting count, and retake count.
Definitions
rit_score- The report-ready Results MAP test-of-record RIT for the subject and term.
growth_percentile- The conditional growth percentile for the selected growth_window, such as winter-to-winter for the Learning Report "vs 1yr ago" panel.
projected_growth- The NWEA projected-growth denominator the Learning Report uses for Growth X.
typical_growth- The NWEA typical-growth context value, retained for audit and comparison but not the Learning Report Growth X denominator.
growth_x- Observed growth divided by projected_growth for the selected norms_set and growth_window.
on_track- Whether growth_x meets the policy target.
Current Effective Values
| Value | Current Setting | What It Means In A Report |
|---|---|---|
allowed norms_set | 2020, 2025. | Every MAP row carries the selected norms family; reports regenerate under a different norms set by changing this filter. |
growth_window values | fall_to_fall, fall_to_winter, winter_to_spring, fall_to_spring, winter_to_winter, spring_to_spring, baseline_to_current, term, custom. | Analytics stores the typed window; clients do not switch over NWEA wide columns. |
Learning Report MAP window | Use growth_window=winter_to_winter for "Growth Percentile (vs 1yr ago)". | The old fall_to_winter window is a within-year window and does not reproduce the report panel. |
Learning Report source mapping | RIT = testritscore; achievement_percentile = testpercentile; growth_percentile = wintertowinterconditionalgrowthpercentile; observed_growth = wintertowinterobservedgrowth; projected_growth = wintertowinterprojectedgrowth; typical_growth = typicalwintertowintergrowth; growth_x = observed_growth / projected_growth. | These source columns are normalized by the timeback-map adapter and materialized by Analytics; reports never read hp_map_results directly. |
timeback-map source-shaped import | Accept the FULL reporting.hp_map_results source row. | The adapter accepts all hp_map_results columns, including wintertowinter*, fall/winter/spring growth-window blocks and goal1..goal8 blocks. Unknown extra columns are ignored, not rejected; only missing required columns or unresolved identities produce typed Problems. |
Real report-source grounding | Architecture evidence found naive observed/typical reproduced only 2 of 4 subjects; observed/projected is the pinned Growth X rule. | Captured in source/evidence/report-source-grounding.json and enforced by AITD-009. |
Growth X formula | growth_x = observed_growth / projected_growth. | The surface stores the result. Consumers read growth_x; they do not ship the formula as report logic. |
growth_x_target | 2.0000. | Current Alpha commitment: twice typical growth. |
on_track rule | on_track = growth_x >= growth_x_target when both values are present. | Null growth_x or target yields on_track=null with null_reason. |
norms source | Analytics readable reference tables alpha.analytics_norms_achievement and alpha.analytics_r90_table, with provenance to NWEAMap NormsReferenceData. | No private norms/R90 table belongs in the skill pack or report. Apps call the surface or read the surface versioned resources. |
Required Config Fields
| Config Field | Meaning | Example / Source |
|---|---|---|
test_of_record_source | Results row that already applied the MAP test-of-record rule. | alpha.map_score |
report_source_adapter | Named source adapter for MAP report values. | timeback-map over reporting.hp_map_results |
learning_report_growth_window | Window used by the parent Learning Report "Growth Percentile (vs 1yr ago)" panel. | winter_to_winter |
growth_x_target | Target multiplier used by on_track. | 2.0000 under current Alpha commitment, read from policy |
norms_sets | Allowed NWEA norms families. | 2020, 2025 |
Raw DB rule: Read alpha.analytics_map_growth_rollup by canonical_term_id, growth_window, and norms_set. Do not compute Growth X or sitting dedupe in a report.
Trace: aitd-009-map-growth-rollups, aitd-011-policy-and-enum-normalization
MAP Scale Translation
alpha.policy.analytics.scale_translation.v2026-06-12
Answers: How does the surface translate percentile to RIT, RIT to percentile, and RIT to R90/grade?
Controls: Reads the versioned surface resources alpha.analytics_norms_achievement and alpha.analytics_r90_table. Percentile<->RIT uses the published mean_rit/sd_rit normal model; R90/grade uses current table_version analytics.rit_to_grade.powerpath.v2026-06-15 and the PowerPath RIT-to-grade lookup, so callers never extrapolate privately.
Definitions
readable resource- A versioned surface table an app may read/cache by table_version.
table_version- The immutable version id for a norms or R90 table. The current R90 table holds exactly one live PowerPath version.
calculator_version- The version of the translation calculation used by /norms/rit, /norms/percentile, or /r90.
source_point_kind- R90 lookup flag: exact or source_missing. exact means the surface used the PowerPath RIT-to-grade row for the requested score.
R90- Alpha extrapolated 90%-mastery threshold. NWEA does not publish it directly, so rows carry extend_kind=alpha_extrapolation.
Current Effective Values
| Value | Current Setting | What It Means In A Report |
|---|---|---|
serving home | analytics/alpha. | Per ruling R1, Analytics serves Alpha-side norms/R90 resources; NWEAMap 1EdTech remains the raw mirror and provenance source. |
allowed norms_set | 2020, 2025. | The same GOALS or Learning Report query can be rerun under either norms family by flipping norms_set. |
current norms table_version | analytics.norms.achievement.v2026-06-12 | The NWEA achievement norms table version used by current percentile<->RIT reads. |
current R90 table_version | analytics.rit_to_grade.powerpath.v2026-06-15 | The PowerPath RIT-to-grade table version required for current raw/API convergence; raw readers do not infer current by sorting names. |
R90 one-version rule | alpha.analytics_r90_table currently holds exactly one live observed RIT-to-grade table_version. | The only live observed-RIT version is analytics.rit_to_grade.powerpath.v2026-06-15; grade2rit.csv is forecast-only and is not a historical observed-RIT target. |
percentile_to_rit rule | Read mean_rit and sd_rit from alpha.analytics_norms_achievement, then convert percentile to a z-score and RIT under the surface calculator. | No app ships a norms table or private calculator. |
rit_to_percentile rule | Use the same alpha.analytics_norms_achievement row and normal model in reverse. | The response carries mean_rit, sd_rit, calculator_version, and norms_set so the answer is inspectable. |
rit_to_r90 rule | Read alpha.analytics_r90_table where table_version='analytics.rit_to_grade.powerpath.v2026-06-15' and table_subject_id matches the subject and rit_score equals the requested RIT. | This is the PowerPath observed RIT-to-grade lookup. Missing rows return source_missing instead of a fabricated grade. |
R90 honesty rule | R90 rows use extend_kind=alpha_extrapolation and r90_method_ref. | The row exposes that R90/effective-grade is an Alpha/PowerPath mapping, not an NWEA-published value. |
cache behavior | Responses include table_version; translation responses include calculator_version; HTTP cache-control is no-store. | Clients may cache by table_version as the cache key, but must not maintain or edit a private copy. |
missing table behavior | Invalid subjects/table parameters return analytics:validation_failed field codes; R90 requests with no PowerPath source row return source_missing. | A missing norms_set/table_version never falls back to a nearby version. |
Required Config Fields
| Config Field | Meaning | Example / Source |
|---|---|---|
norms_resource | Readable NWEA achievement-status norms table. | alpha.analytics_norms_achievement |
r90_resource | Readable RIT50/RIT90/effective-grade table. | alpha.analytics_r90_table |
version_key | Cache/reproducibility key. | norms_set + table_version |
percentile_rit_rule | How percentile<->RIT is answered. | Use the published mean_rit and sd_rit row for (norms_set, subject, grade, season, role) and the documented normal-model translation. |
rit_to_grade_lookup_rule | How RIT-to-grade requests are answered. | Filter to the current R90 table version, then use the PowerPath RIT-to-grade row for the requested RIT. If no such row exists, return source_missing; never use grade2rit.csv, interpolate, clamp upward, or extrapolate. |
Raw DB rule: Read alpha.analytics_norms_achievement by norms_set, table_version, subject_id, role, grade_key, and season, then apply the documented normal-model translation. Read alpha.analytics_r90_table with table_version='analytics.rit_to_grade.powerpath.v2026-06-15', table_subject_id, and rit_score equal to the requested RIT; row matches return source_point_kind=exact. Never read a private norms/R90 file, use grade2rit.csv as an observed-RIT inverse, infer current by sorting table_version strings, interpolate, clamp upward, or invent extrapolated values.
Trace: aitd-015-norms-r90-readable-resources, aitd-016-scale-translation-apis, aitd-017-r90-version-supersession, aitd-011-policy-and-enum-normalization
R90 Method
alpha.policy.analytics.r90_method.v2026-06-12
Answers: Which Alpha method produced each RIT90 and effective-grade row?
Controls: Versioned method reference for alpha.analytics_r90_table rows. The current R90 method is the PowerPath RIT-to-grade lookup named by AITD-017; a future legitimate method change would create a new table_version and policy_ref.
Definitions
PowerPath source row- The source row containing RIT, R50 grade, and R90 grade values.
R90 extrapolation- The Alpha 90%-mastery grade-position interpretation selected from the PowerPath RIT-to-grade source.
effective_grade- The grade-level interpretation attached to the R90 row for GOALS and Learning Report display.
method immutability- Rows produced under this policy are not edited in place; a revised method publishes a new r90_method_ref and table_version.
PowerPath lookup- For an observed input score, the surface chooses the matching PowerPath RIT-to-grade row.
Current Effective Values
| Value | Current Setting | What It Means In A Report |
|---|---|---|
serving home | analytics/alpha mirror; nweamap owner. | The Alpha-readable R90 table and API live on Analytics, but the PowerPath RIT-to-grade master source lives in NWEAMAP. |
current R90 table_version | analytics.rit_to_grade.powerpath.v2026-06-15 | Pinned by AITD-017 and echoed by /r90 plus /r90/table. |
RIT50 handling | The current R50/R90 serving follows the PowerPath RIT-to-grade table. | The dictionary current path follows the served PowerPath mirror. |
RIT90 handling | Rows carry extend_kind=alpha_extrapolation and r90_method_ref=alpha.policy.analytics.r90_method.v2026-06-12. | The field makes the Alpha-added method visible in raw DB reads and API responses. |
lookup behavior | Filter table_version='analytics.rit_to_grade.powerpath.v2026-06-15', then use the PowerPath row whose rit_score equals the requested RIT. | Exact matches return source_point_kind=exact; missing rows return source_missing. |
versioning behavior | Any legitimate future method change publishes a new table_version and r90_method_ref. | The prior production derivation is not a valid historical target; current reads use analytics.rit_to_grade.powerpath.v2026-06-15. |
cache behavior | Responses include table_version and calculator_version and use no-store for mutable HTTP caching. | Clients may cache by immutable table_version, but do not maintain a separate R90 table. |
Required Config Fields
| Config Field | Meaning | Example / Source |
|---|---|---|
source_resource | Readable surface resource using this method. | alpha.analytics_r90_table |
published_anchor_source | Source of the current R90 grade-position rows. | powerpath:/powerpath/rit-to-grade |
owner_module | Platform module that owns the PowerPath RIT-to-grade master. | nweamap |
extend_kind | Honesty marker on R90 rows. | alpha_extrapolation |
version_boundary | When this policy changes. | Any R90 calculation-method, anchor-source, step-floor, missing-row, or effective-grade rule change |
Raw DB rule: Resolve alpha.analytics_r90_table.r90_method_ref to this policy before rendering or caching a R90 answer. Current raw reads must filter alpha.analytics_r90_table.table_version='analytics.rit_to_grade.powerpath.v2026-06-15' and must not substitute scale_translation, a private method, or a table_version inferred from the version string.
Trace: aitd-015-norms-r90-readable-resources, aitd-016-scale-translation-apis, aitd-017-r90-version-supersession, aitd-011-policy-and-enum-normalization
Course Progress Evidence
alpha.policy.analytics.course_progress.v2026-06-15
Answers: What course-progress evidence has Analytics materialized for Results and audits?
Controls: Uses app-reported Caliper percent_complete first; when no direct percent exists, uses 1 - (XP remaining / total XP). Lesson counts are only a last source-adapter fallback when neither direct percent nor XP denominator evidence exists.
Definitions
app-reported percent- A Caliper course progress event field such as percent_complete, preserved by Events and materialized by Analytics.
xp_remaining fallback- When no direct percent exists, completion_percent = (1 - (xp_remaining / (xp_earned + xp_remaining))) * 100.
completion_percent- Materialized progress-evidence percent for the scope, expressed from 0 to 100 when reportable.
Current Effective Values
| Value | Current Setting | What It Means In A Report |
|---|---|---|
precedence | app-reported percent_complete; then 1 - (xp_remaining / total_xp); then lesson count only as last adapter fallback. | Analytics stores the computed percent and progress_source_kind; consumers read it. |
zero denominator | completion_percent=null with null_reason no_subject_assignment, no_enrollment, source_missing, source_unlinked, or not_applicable. | No report may divide by zero, return 1-if-active, or invent 0%. |
ordinary quality statuses | ok, corrected. | Other quality statuses are audit/findings until repaired. |
scope grain | course, subject, track, track_level, grade_level, segment. | The scope controls what scope_id points to and what policy selected as expected work. |
worked direct example | A course progress event with percent_complete=75 writes completion_percent=75.000 and progress_source_kind=app_reported_percent. | Direct app evidence wins over any fallback count or XP row. |
worked XP fallback example | A course scope with xp_earned=900 and xp_remaining=300 writes completion_percent=75.000 when no direct percent exists. | The remaining-XP denominator comes from Curriculum expected XP; the report does not walk the tree. |
Required Config Fields
| Config Field | Meaning | Example / Source |
|---|---|---|
event_source | Named Events extension source for direct course progress. | TimebackProfile courseProgressPercent / percentComplete |
report_source_adapter | Named source adapter for XP-remaining fallback. | timeback-completion over reporting.processed_facts |
denominator_policy_ref | Which denominator policy was used for the scope. | alpha.policy.analytics.course_progress.v2026-06-15 |
zero_denominator_behavior | How empty scopes appear. | completion_percent=null and null_reason=no_subject_assignment/no_enrollment/source_missing as applicable |
Raw DB rule: Read alpha.analytics_completion_rollup by completion_scope and scope_id for evidence and reconciliation. For the student-facing answer, read Results alpha.student_course_progress or alpha.student_grade_level_progress. Do not derive actual progress from MAP/RIT/R90, count Results rows, or walk course_component trees in a report.
Trace: aitd-010-completion-rollups, aitd-001-report-source-ingestion, aitd-004-provenance-no-literals, aitd-011-policy-and-enum-normalization
Completion XP Fallback
alpha.policy.analytics.course_progress.v2026-06-15
Answers: Which source evidence becomes xp_earned when course progress falls back to XP?
Controls: Selects report-source earned XP rows that count toward xp_earned only when no app-reported percent_complete exists for the scope.
Definitions
earned XP evidence- A report-source processed_facts row linked to the completion scope and accepted by the timeback-completion adapter.
blocked evidence- A Results row that cannot count because it is superseded, source-deleted, unlinked, or not accepted by the policy.
Current Effective Values
| Value | Current Setting | What It Means In A Report |
|---|---|---|
accepted_report_source_shapes | reporting.processed_facts rows linked to the requested completion scope. | Each accepted row must resolve to a Curriculum denominator scope. |
ordinary report statuses | ok, corrected. | reversed/source_missing/source_unlinked/policy_pending/adapter_rejected do not increase xp_earned. |
completion evidence rule | Earned XP is accumulated once per accepted source key under adapter policy. | Retries and corrections are already handled by source refs and quality_status. |
Required Config Fields
| Config Field | Meaning | Example / Source |
|---|---|---|
accepted_report_source_shapes | Report-source shapes allowed to count. | reporting.processed_facts rows linked to scope and accepted by adapter policy |
required_quality_status | Quality statuses allowed in ordinary completion reports. | ok, corrected; exclude source_missing/source_unlinked/policy_pending/adapter_rejected |
source_ref_match | How source evidence must link to Curriculum expected refs. | source course/activity/KC refs must resolve to denominator scope |
Raw DB rule: Read xp_earned from alpha.analytics_completion_rollup. Use source_import_id/sourceRefs only for authorized audits.
Trace: aitd-010-completion-rollups, aitd-011-policy-and-enum-normalization
Completion Denominator
alpha.policy.curriculum.main_course_grade_level.v2026-06-15
Answers: Which course refs count toward grade-level progress?
Controls: Selects main grade-level courses for grade_level progress and excludes remediation, hole-filling, catalog, review, and practice-only courses from the denominator.
Definitions
expected ref- A Curriculum scope ref whose expected XP contributes to xp_remaining under the scope and date window.
zero denominator- A scope with no earned or remaining XP denominator; completion_percent is null with a typed null_reason.
Current Effective Values
| Value | Current Setting | What It Means In A Report |
|---|---|---|
included_course_role | main. | Only main courses count toward grade-level progress. Hole-filling and remediation do not. |
denominator worked shape | Two main courses at 25% and 75% write grade_level completion_percent=50.000. | A 100% hole-filling course does not change that grade-level percent. |
scope traversal | Server-side Curriculum reference expansion under denominator_policy_ref. | Reports do not recursively query course_component or course_component_member. |
student-specific filtering | Expected refs must apply to the student, subject, track/level, enrollment window, and personalized course when present. | A shared course and a personalized course can have different xp_remaining values. |
zero denominator | xp_earned + xp_remaining = 0 and completion_percent=null with typed null_reason. | No client fallback to 0%, 100%, or hidden row. |
Required Config Fields
| Config Field | Meaning | Example / Source |
|---|---|---|
scope_ref_source | Curriculum refs used for denominator membership. | course_component, course_component_member, KC refs |
included_course_role | Course role that contributes to grade-level progress. | main |
excluded_course_roles | Course roles excluded from grade-level progress. | hole_filling, remediation, remedial, catalog, practice, review |
zero_denominator_reason | The null_reason to emit for empty/unlinked scopes. | no_subject_assignment, source_missing, source_unlinked, not_applicable |
Raw DB rule: Read grade_level, is_main_course, progress_source_kind, xp_remaining, and curriculum_scope_refs from alpha.analytics_completion_rollup. Do not recursively query Curriculum for the report denominator.
Trace: aitd-010-completion-rollups, aitd-011-policy-and-enum-normalization
Calendar Code Map
alpha.school_calendar is present in the shared DB and the latest operator settlement verified the reporting probe all-green for Time Commitment. The code map below is the active mapping from Ed-Fi CalendarDate to Alpha school-day reasons; source_missing remains an edge-case repair state for an uncovered school/window, not the ordinary report path.
The school-day denominator reads Ed-Fi CalendarDate.CalendarEvents through alpha.school_calendar and maps them to Alpha reasons under alpha.policy.school_day.
| status | checkedBy | rowCount | schoolDayRows | schoolCount | dateRange | reasons | contract |
|---|---|---|---|---|---|---|---|
| verified_available | data dictionary attempt 1 using current read-only Node/Postgres persistence evidence plus operator reporting-probe settlement | 9238 | 5674 | 14 | 2025-08-13 to 2027-06-06 | holiday_break, instructional, nwea_map_testing, other, weekend | A reportable Learning Report row carries a real enrolled_school_day_count from alpha.school_calendar over Ed-Fi CalendarDate intersected with enrollment and subject assignment. If a particular school/window lacks coverage, Analytics emits source_missing for repair/audit; consumers still never fabricate a denominator. |
| alphaReason | edFiCalendarEventCodes | countsAsSchoolDay | meaning |
|---|---|---|---|
| instructional | Instructional day,Make-up day,Student late arrival/early dismissal | yes | Counts in the denominator when it also intersects the student enrollment and, for subject rows, subject assignment. |
| teacher_workshop | Teacher only day | no | Teachers are working but students are not expected to produce learning minutes. |
| holiday_break | Holiday | no | Instruction is cancelled for holiday or break; minutes are not divided by this date. |
| nwea_map_testing | Tenant-governed NWEA/MAP testing CalendarEventDescriptor values | no | MAP testing days are excluded from the time-commitment denominator by alpha.policy.school_day. |
| other | Emergency day,Non-instructional day,Other,Strike,Weather day,tenant-governed uncovered values | no unless policy explicitly maps the governed value to instructional | A catch-all for non-instructional or locally-governed calendar codes; uncovered tenant values produce policy_pending/source_unlinked findings before they affect reports. |
Accuracy (P7)
alpha.analytics_accuracy directly, or call GET /alpha/analytics/v1/accuracy-rollups. The endpoint is served at this wave's implementation cell; this data dictionary pins the table, fields, formula, policy, raw query, and sample row now so the Learning Report can be built from alpha.analytics_* alone.
- Panel
- Accuracy (P7)
- Table
alpha.analytics_accuracy- Endpoint
GET /alpha/analytics/v1/accuracy-rollups- Formula
accuracy_percent = correct_question_count / total_question_count * 100, withaccuracy_percent=nullandnull_reason=no_questionswhen the denominator is zero.- Render Fields
correct_question_count,total_question_count,incorrect_question_count,accuracy_percent,source_import_id,policy_ref,quality_status,null_reason.- Policy
alpha.policy.analytics.accuracy.v2026-06-12- Raw Rule
- Query
alpha.analytics_accuracycurrentok/correctedrows. Do not sumreporting.processed_facts, keep private app allowlists, or divide and round locally.
Worked Example
{
"id": "aac_01HT8ACC_2026_SPRING_MATH",
"student_id": "student_01HT7G3YZV7QB5N4YKQ1K0Z9A9",
"subject_id": "math",
"window_kind": "term",
"window_start": "2026-01-01",
"window_end": "2026-06-01",
"correct_question_count": 480,
"total_question_count": 600,
"incorrect_question_count": 120,
"accuracy_percent": 80,
"policy_ref": "alpha.policy.analytics.accuracy.v2026-06-12",
"source_import_id": "imp_01HT8XPTIME_2026_SPRING",
"quality_status": "ok",
"null_reason": "none"
}
Same recipe as Accuracy (P7): Correct Questions Over Total Questions; same object payload as the alpha.analytics_accuracy object example.
Learning Report Panel Coverage
Every named Learning Report panel has one Analytics owner, one recipe, and a raw-table path that reads alpha.analytics_* only. This table is the quick check for skill-pack operators before writing a report.
| Panel | Analytics Object | Recipe | Required Fields | API | Raw DB Rule |
|---|---|---|---|---|---|
timeCommitmentTime Commitment |
alpha.analytics_school_day_minutes |
minutes-per-school-day |
active_minutes enrolled_school_day_count excluded_school_day_count minutes_per_enrolled_school_day null_reason |
GET /alpha/analytics/v1/school-day-minutes |
Read alpha.analytics_school_day_minutes current ok/corrected rows with null_reason=none; never recompute the calendar denominator in the report. source_missing rows are repair states, not replacement report values. |
xpGoalsXP Goals |
alpha.analytics_xp_rollup |
xp-total |
xp_total daily_xp_goal enrolled_school_day_count xp_goal xp_remaining xp_goal_percent on_track null_reason |
GET /alpha/analytics/v1/xp-rollups |
Read alpha.analytics_xp_rollup; never sum Results XP ledger or processed_facts in the report. |
accuracyAccuracy (P7) |
alpha.analytics_accuracy |
accuracy |
correct_question_count total_question_count incorrect_question_count accuracy_percent source_import_id null_reason |
GET /alpha/analytics/v1/accuracy-rollups |
Read alpha.analytics_accuracy; never sum reporting.processed_facts.total_questions/correct_questions, keep app allowlists, or divide and round locally. |
masteryTransitionsMastery / Grade Levels |
alpha.analytics_mastery_delta |
mastery-deltas |
kc_id state_dimension transition_kind previous_value new_value effective_at source_import_id/source_state_ref |
GET /alpha/analytics/v1/mastery-deltas |
Read alpha.analytics_mastery_delta; never recompute mastery, HMG, or decay from attempts in the report. |
mapResultsMAP Results |
alpha.analytics_map_growth_rollup |
map-growth |
rit_score achievement_percentile growth_percentile observed_growth projected_growth growth_x norms_set growth_window |
GET /alpha/analytics/v1/map-growth-rollups |
Read alpha.analytics_map_growth_rollup; never dedupe MAP sittings, parse term strings, or maintain norms locally. |
courseCompletionCourse Completion |
alpha.analytics_completion_rollup |
completion |
completion_scope scope_id xp_earned xp_remaining completion_percent denominator_policy_ref null_reason |
GET /alpha/analytics/v1/completion-rollups |
Read alpha.analytics_completion_rollup for Analytics evidence; course rows prefer app-reported Caliper percent, then XP remaining, and grade_level rows preserve main-course evidence only. Student-facing progress comes from Results course-progress and grade-level-progress. Never derive actual progress from MAP/RIT/R90, walk Curriculum trees, or count Results rows. |
goalsTargetDateGOALS Target Date |
analytics.school_days_remaining | school-days-remaining |
instructional_days_remaining instructional_dates xp_unit.xp_per_expected_minute xp_unit.xp_per_hour effort.* |
GET /alpha/analytics/v1/school-days-remaining |
Read alpha.school_calendar under alpha.policy.school_day through the documented raw path, then apply alpha.policy.analytics.xp_expected_minute.v2026-06-14; never count weekdays, parse school-period labels, or hard-code XP_PER_HOUR. |
goalsAgeGradeStatusGOALS Age-Grade Status |
analytics.grade_level_status | grade-level-status |
age_grade working_grade highest_mastered_grade working_age_grade_status mastered_age_grade_status working_age_grade_delta mastered_age_grade_delta |
GET /alpha/analytics/v1/grade-level-status |
Read People and Orgs alpha.age_grade_history and Results working_grade/HMG at the requested asOfDate; Analytics returns only the named comparisons and never infers age grade from MAP/RIT or course placement. |
fullLearningReportEnd-To-End Assembly |
six alpha.analytics_* report tables | learning-report-assembly |
All panel fields above including panels.accuracy.* |
six GET calls listed in the assembly recipe |
Assemble already-computed Analytics rows into JSON only; no minutes, XP, accuracy, mastery, MAP, or completion math runs in the report. |
Endpoint Catalog
These are the read endpoints a report or skill-pack operator calls instead of recomputing Analytics values. The JSON sidecar exposes the same list as endpoints and apiEndpoints.
| Endpoint | Panel | Recipe | Reads | Contract Status |
|---|---|---|---|---|
GET /alpha/analytics/v1/school-day-minutes |
timeCommitment |
minutes-per-school-day |
alpha.analytics_school_day_minutes |
documented Analytics read contract |
GET /alpha/analytics/v1/xp-rollups |
xpGoals |
xp-total |
alpha.analytics_xp_rollup |
documented Analytics read contract |
GET /alpha/analytics/v1/accuracy-rollups |
accuracy |
accuracy |
alpha.analytics_accuracy |
served at this wave's implementation cell; docs-first contract with live materializer evidence in implementation/integration |
GET /alpha/analytics/v1/mastery-deltas |
masteryTransitions |
mastery-deltas |
alpha.analytics_mastery_delta |
documented Analytics read contract |
GET /alpha/analytics/v1/map-growth-rollups |
mapResults |
map-growth |
alpha.analytics_map_growth_rollup |
documented Analytics read contract |
GET /alpha/analytics/v1/norms/rit |
goalsScaleTranslation |
scale-translation |
alpha.analytics_norms_achievement alpha.analytics_r90_table |
documented Analytics read contract |
GET /alpha/analytics/v1/r90 |
goalsScaleTranslation |
scale-translation |
alpha.analytics_norms_achievement alpha.analytics_r90_table |
documented Analytics read contract |
GET /alpha/analytics/v1/school-days-remaining |
goalsTargetDate |
school-days-remaining |
analytics.school_days_remaining alpha.school_calendar alpha.analytics_xp_rollup |
documented Analytics read contract |
GET /alpha/analytics/v1/grade-level-status |
goalsAgeGradeStatus |
grade-level-status |
analytics.grade_level_status |
documented Analytics read contract |
GET /alpha/analytics/v1/completion-rollups |
courseCompletion |
completion |
alpha.analytics_completion_rollup |
documented Analytics read contract; page-bounded and current-row scoped under completion-rollup retention |
Learning Report Query Recipes
These recipes show the exact API and raw-table paths for the report cells the customer eval names. The raw path queries Analytics only; it never recomputes Events, Results, NWEA norms, school calendars, or Curriculum trees.
Time Commitment: Minutes Per Enrolled School Day
Learning Report panel: timeCommitment
Question: Is the school-day denominator available, and if so how many active minutes per enrolled school day did this student average?
Table: alpha.analytics_school_day_minutes
API Path
GET /alpha/analytics/v1/school-day-minutes?studentId=student_01HT7G3YZV7QB5N4YKQ1K0Z9A9&subjectId=math&startDate=2026-01-01&endDate=2026-06-01
Raw DB Path
select active_minutes, enrolled_school_day_count, excluded_school_day_count, minutes_per_enrolled_school_day, school_day_policy_ref, quality_status, null_reason from alpha.analytics_school_day_minutes where tenant_id = :tenant_id and student_id = :student_id and subject_id = 'math' and window_start = date '2026-01-01' and window_end = date '2026-06-01' and quality_status in ('ok','corrected') and null_reason = 'none' and superseded_at is null and source_deleted_at is null;
Render these fields: active_minutes enrolled_school_day_count excluded_school_day_count minutes_per_enrolled_school_day school_day_policy_ref quality_status null_reason
XP: Earned, Goal Availability, And Uncapped Percent
Learning Report panel: xpGoals
Question: How much XP was earned, and are the goal, remaining, and uncapped percent fields available under the shared school-day denominator?
Table: alpha.analytics_xp_rollup
API Path
GET /alpha/analytics/v1/xp-rollups?studentId=student_01HT7G3YZV7QB5N4YKQ1K0Z9A9&subjectId=math&windowKind=term&startDate=2026-01-01&endDate=2026-06-01
Raw DB Path
select xp_total, daily_xp_goal, enrolled_school_day_count, xp_goal, xp_remaining, xp_goal_percent, on_track, positive_xp, negative_xp, award_count, reversal_count, source_import_id, policy_ref, null_reason from alpha.analytics_xp_rollup where tenant_id = :tenant_id and student_id = :student_id and subject_id = 'math' and window_kind = 'term' and window_start = date '2026-01-01' and window_end = date '2026-06-01' and quality_status in ('ok','corrected') and superseded_at is null and source_deleted_at is null;
Render these fields: xp_total daily_xp_goal enrolled_school_day_count xp_goal xp_remaining xp_goal_percent on_track positive_xp negative_xp award_count reversal_count source_import_id policy_ref null_reason
Accuracy (P7): Correct Questions Over Total Questions
Learning Report panel: accuracy
Question: What accuracy percent should the Learning Report show for this student and subject?
Table: alpha.analytics_accuracy
API Path
GET /alpha/analytics/v1/accuracy-rollups?studentId=student_01HT7G3YZV7QB5N4YKQ1K0Z9A9&subjectId=math&windowKind=term&startDate=2026-01-01&endDate=2026-06-01
Raw DB Path
select correct_question_count, total_question_count, incorrect_question_count, accuracy_percent, source_import_id, policy_ref, quality_status, null_reason from alpha.analytics_accuracy where tenant_id = :tenant_id and student_id = :student_id and subject_id = 'math' and window_kind = 'term' and window_start = date '2026-01-01' and window_end = date '2026-06-01' and quality_status in ('ok','corrected') and superseded_at is null and source_deleted_at is null;
Render these fields: correct_question_count total_question_count incorrect_question_count accuracy_percent source_import_id policy_ref quality_status null_reason
Example Report JSON
{
"id": "aac_01HT8ACC_2026_SPRING_MATH",
"student_id": "student_01HT7G3YZV7QB5N4YKQ1K0Z9A9",
"subject_id": "math",
"window_kind": "term",
"window_start": "2026-01-01",
"window_end": "2026-06-01",
"correct_question_count": 480,
"total_question_count": 600,
"incorrect_question_count": 120,
"accuracy_percent": 80,
"policy_ref": "alpha.policy.analytics.accuracy.v2026-06-12",
"source_import_id": "imp_01HT8XPTIME_2026_SPRING",
"quality_status": "ok",
"null_reason": "none"
}
Mastery: KC Changes During A Date Range
Learning Report panel: masteryTransitions
Question: Which Knowledge Components changed mastery state for this student?
Table: alpha.analytics_mastery_delta
API Path
GET /alpha/analytics/v1/mastery-deltas?studentId=student_01HT7G3YZV7QB5N4YKQ1K0Z9A9&startDate=2026-05-01&endDate=2026-06-01&stateDimension=durable_mastery
Raw DB Path
select kc_id, state_dimension, effective_at, previous_value, new_value, delta_value, transition_kind, policy_ref from alpha.analytics_mastery_delta where tenant_id = :tenant_id and student_id = :student_id and state_dimension = 'durable_mastery' and effective_at >= timestamptz '2026-05-01T00:00:00Z' and effective_at < timestamptz '2026-06-01T00:00:00Z' and quality_status in ('ok','corrected') and superseded_at is null and source_deleted_at is null order by effective_at, kc_id;
Render these fields: kc_id state_dimension effective_at previous_value new_value delta_value transition_kind
MAP Results: RIT And Growth X
Learning Report panel: mapResults
Question: What RIT and Growth X should the Learning Report show for this term?
Table: alpha.analytics_map_growth_rollup
API Path
GET /alpha/analytics/v1/map-growth-rollups?studentId=student_01HT7G3YZV7QB5N4YKQ1K0Z9A9&subjectId=math&termId=term_2026_winter&growthWindow=winter_to_winter&normsSet=2025
Raw DB Path
select rit_score, achievement_percentile, growth_percentile, observed_growth, projected_growth, typical_growth, growth_x, growth_x_target, on_track, sitting_count, retake_count, source_import_id from alpha.analytics_map_growth_rollup where tenant_id = :tenant_id and student_id = :student_id and subject_id = 'math' and canonical_term_id = 'term_2026_winter' and growth_window = 'winter_to_winter' and norms_set = '2025' and quality_status in ('ok','corrected') and superseded_at is null and source_deleted_at is null;
Render these fields: rit_score achievement_percentile growth_percentile observed_growth projected_growth typical_growth growth_x growth_x_target on_track sitting_count retake_count norms_set growth_window source_import_id
GOALS: Percentile To RIT And RIT To R90
Learning Report panel: goalsScaleTranslation
Question: What RIT is a target percentile, and what grade/R90 does a RIT map to?
Tables: alpha.analytics_norms_achievement alpha.analytics_r90_table
Assembly Steps
- Use the norms table_version pinned in the report and the current R90 table_version analytics.rit_to_grade.powerpath.v2026-06-15 unless the report explicitly asks to reproduce a historical R90 answer. HTTP responses are no-store; the version string is the cache key.
- For percentile-to-RIT, read mean_rit and sd_rit from the achievement norms row and apply the documented normal-model translation, or call /norms/rit.
- For RIT-to-R90, filter the current R90 table version and choose the PowerPath row whose rit_score equals the requested score. Exact matches return exact; missing rows return source_missing.
API Path
GET /alpha/analytics/v1/norms/rit?subjectId=math&gradeLevel=5&termName=winter&percentile=90&normsSet=2025 GET /alpha/analytics/v1/r90?subjectId=math&rit=239&normsSet=2025
Raw DB Path
with
norms_row as (
select mean_rit, sd_rit, table_version
from alpha.analytics_norms_achievement
where tenant_id is null
and norms_set = :norms_set
and table_version = :norms_table_version
and subject_id = :subject_id
and role = :role
and grade_key = :grade_key
and season = :season
and quality_status = 'ok'
limit 1
),
percentile_to_rit as (
select
mean_rit + (sd_rit * :z_score_for_requested_percentile) as rit_score,
mean_rit,
sd_rit,
table_version
from norms_row
),
r90 as (
select
r90_grade,
effective_grade,
r90_grade_level,
r90_percent_complete,
'exact' as source_point_kind,
table_version,
rit_score as table_rit_score
from alpha.analytics_r90_table
where tenant_id is null
and norms_set = :norms_set
and table_version = 'analytics.rit_to_grade.powerpath.v2026-06-15'
and table_subject_id = :subject_id
and rit_score = :input_rit
and quality_status = 'ok'
limit 1
)
select jsonb_build_object(
'percentileToRit', (select to_jsonb(percentile_to_rit) from percentile_to_rit),
'ritToR90', (select to_jsonb(r90) from r90)
) as scale_translation;
Render these fields: percentileToRit.rit_score percentileToRit.mean_rit percentileToRit.sd_rit ritToR90.r90_grade ritToR90.effective_grade ritToR90.r90_grade_level ritToR90.rit90_grade_band_percent ritToR90.r90_percent_complete ritToR90.source_point_kind ritToR90.table_rit_score ritToR90.table_version
Example Report JSON
{
"percentileToRit": {
"norms_set": "2025",
"table_version": "analytics.norms.achievement.v2026-06-12",
"calculator_version": "analytics.norms.translation.v2026-06-12",
"subject_id": "math",
"grade_key": "5",
"season": "winter",
"role": "student",
"percentile": 90,
"mean_rit": 214.2,
"sd_rit": 14.1,
"rit_score": 232.3
},
"ritToR90": {
"norms_set": "2025",
"table_version": "analytics.rit_to_grade.powerpath.v2026-06-15",
"table_subject_id": "math",
"input_rit": 239,
"table_rit_score": 239,
"r90_grade": 4.8,
"effective_grade": 5,
"r90_grade_level": 4,
"rit90_grade_band_percent": 80,
"r90_percent_complete": 80,
"extend_kind": "alpha_extrapolation",
"source_point_kind": "exact"
}
}
GOALS: School Days Remaining And Target-Date Effort
Learning Report panel: goalsTargetDate
Question: How many instructional days remain, and what daily effort is needed to finish by a target date?
Tables: analytics.school_days_remaining alpha.school_calendar alpha.analytics_xp_rollup
Assembly Steps
- Resolve the student school by effective-dated People and Orgs enrollment, or pass a schoolId when the caller already has the governed school id.
- Count only alpha.school_calendar rows that are instructional under alpha.policy.school_day inside the half-open [asOf, endDate) window; asOf is included and endDate is excluded.
- Use alpha.policy.analytics.xp_expected_minute.v2026-06-14: 1 XP = 1 expected minute, 60 XP = 1 expected hour. Do not keep XP_PER_HOUR or weekday math in GOALS.
- Render the returned fields. If the window has no instructional days, instructional_days_remaining is 0 and target-date effort fields that divide by days are null instead of guessed.
API Path
GET /alpha/analytics/v1/school-days-remaining?studentId=student_01HT7G3YZV7QB5N4YKQ1K0Z9A9&asOf=2026-06-14&endDate=2026-07-24&xpRemaining=600&hoursPerSchoolDay=1.5&targetDate=2026-07-24
Raw DB Path
with
student_school as (
select :school_id as school_id
-- If schoolId is omitted, resolve this from People and Orgs effective-dated enrollment
-- where begin_date is not null and :as_of falls inside [begin_date, end_date].
),
instructional_dates as (
select calendar_date
from alpha.school_calendar
where school_id = (select school_id from student_school)
and calendar_date >= :as_of::date
and calendar_date < :end_date::date
and is_school_day = true
and reason = 'instructional'
and policy_ref = 'alpha.policy.school_day.v2026-06-10'
order by calendar_date
),
effort as (
select
:xp_remaining::numeric as xp_remaining,
(:xp_remaining::numeric / 1.0) as expected_minutes_remaining,
(:xp_remaining::numeric / 60.0) as hours_remaining,
:hours_per_school_day::numeric as hours_per_school_day
),
target_window as (
select count(*)::integer as school_days_until_target_date
from instructional_dates
where calendar_date < :target_date::date
)
select jsonb_build_object(
'object', 'analytics.school_days_remaining',
'student_id', :student_id,
'school_id', (select school_id from student_school),
'as_of', :as_of,
'end_date', :end_date,
'school_day_policy_ref', 'alpha.policy.school_day.v2026-06-10',
'instructional_days_remaining', (select count(*) from instructional_dates),
'calendar_ref_count', (
select count(*) from alpha.school_calendar
where school_id = (select school_id from student_school)
and calendar_date >= :as_of::date
and calendar_date < :end_date::date
),
'first_instructional_date', (select min(calendar_date) from instructional_dates),
'last_instructional_date', (select max(calendar_date) from instructional_dates),
'instructional_dates', (select jsonb_agg(calendar_date order by calendar_date) from instructional_dates),
'xp_unit', jsonb_build_object(
'policy_ref', 'alpha.policy.analytics.xp_expected_minute.v2026-06-14',
'xp_per_expected_minute', 1,
'xp_per_hour', 60,
'meaning', '1 XP = 1 expected minute; 60 XP = 1 expected hour.'
),
'effort', jsonb_build_object(
'xp_remaining', (select xp_remaining from effort),
'expected_minutes_remaining', (select expected_minutes_remaining from effort),
'hours_remaining', (select hours_remaining from effort),
'target_date', :target_date,
'school_days_until_target_date', (select school_days_until_target_date from target_window),
'required_hours_per_school_day_to_target_date',
case when (select school_days_until_target_date from target_window) > 0
then (select hours_remaining from effort) / (select school_days_until_target_date from target_window)
else null end,
'hours_per_school_day', (select hours_per_school_day from effort),
'school_days_needed_at_hours_per_school_day',
case when (select hours_per_school_day from effort) > 0
then ceil((select hours_remaining from effort) / (select hours_per_school_day from effort))
else null end
)
) as school_days_remaining;
Render these fields: instructional_days_remaining calendar_ref_count first_instructional_date last_instructional_date instructional_dates[] xp_unit.policy_ref xp_unit.xp_per_expected_minute xp_unit.xp_per_hour effort.xp_remaining effort.expected_minutes_remaining effort.hours_remaining effort.school_days_until_target_date effort.required_hours_per_school_day_to_target_date effort.school_days_needed_at_hours_per_school_day effort.target_date_at_hours_per_school_day effort.can_finish_by_end_date_at_hours_per_school_day
Example Report JSON
{
"object": "analytics.school_days_remaining",
"student_id": "student_01HT7G3YZV7QB5N4YKQ1K0Z9A9",
"school_id": "school_alpha_austin",
"as_of": "2026-06-14",
"end_date": "2026-07-24",
"school_day_policy_ref": "alpha.policy.school_day.v2026-06-10",
"instructional_days_remaining": 29,
"calendar_ref_count": 40,
"first_instructional_date": "2026-06-15",
"last_instructional_date": "2026-07-23",
"instructional_dates": [
"2026-06-15",
"2026-06-16",
"2026-06-17"
],
"xp_unit": {
"policy_ref": "alpha.policy.analytics.xp_expected_minute.v2026-06-14",
"xp_per_expected_minute": 1,
"xp_per_hour": 60,
"meaning": "1 XP = 1 expected minute; 60 XP = 1 expected hour."
},
"effort": {
"xp_remaining": 600,
"expected_minutes_remaining": 600,
"hours_remaining": 10,
"target_date": "2026-07-24",
"school_days_until_target_date": 29,
"required_hours_per_school_day_to_target_date": 0.345,
"hours_per_school_day": 1.5,
"school_days_needed_at_hours_per_school_day": 7,
"target_date_at_hours_per_school_day": "2026-06-23",
"can_finish_by_end_date_at_hours_per_school_day": true
}
}
GOALS: Working And Mastered Age-Grade Status
Learning Report panel: goalsAgeGradeStatus
Question: Is the student working above, at, or behind their school-assigned age grade, and is strict mastery above, at, or behind age grade?
Table: analytics.grade_level_status
Assembly Steps
- Read age_grade from People and Orgs alpha.age_grade_history for the requested asOfDate. Do not infer it from birthdays, prior-year close, MAP/RIT, working grade, HMG, or course placement.
- Read working_grade and highest_mastered_grade from Results. Results owns the working-grade resolver; Analytics only compares returned grade positions.
- Return exactly two named comparisons: working_age_grade_status = working_grade - age_grade and mastered_age_grade_status = highest_mastered_grade - age_grade. Old generic status names, if present, are compatibility aliases only.
API Path
GET /alpha/analytics/v1/grade-level-status?studentId=b6fa7128-f641-4efd-9075-375411fd6c39&subject=math&asOfDate=2026-05-20
Raw DB Path
with
age_grade as (
select age_grade, begin_date, end_date
from alpha.age_grade_history
where tenant_id = :people_and_orgs_tenant_id
and person_id = :student_id
and is_time_locatable is true
and begin_date <= :as_of_date::date
and (end_date is null or :as_of_date::date < end_date)
and deleted_at is null
order by begin_date desc
limit 1
),
results_grade as (
select working_grade, highest_mastered_grade
from results.student_track_state
where tenant_id = :results_tenant_id
and student_id = :student_id
and subject_id = :subject_id
and as_of_date <= :as_of_date::date
order by as_of_date desc
limit 1
)
select jsonb_build_object(
'object', 'analytics.grade_level_status',
'student_id', :student_id,
'subject_id', :subject_id,
'as_of_date', :as_of_date,
'age_grade', (select age_grade from age_grade),
'working_grade', (select working_grade from results_grade),
'highest_mastered_grade', (select highest_mastered_grade from results_grade),
'working_age_grade_delta', (select working_grade from results_grade) - (select age_grade from age_grade),
'mastered_age_grade_delta', (select highest_mastered_grade from results_grade) - (select age_grade from age_grade)
) as grade_level_status;
Render these fields: age_grade working_grade highest_mastered_grade working_age_grade_status mastered_age_grade_status working_age_grade_delta mastered_age_grade_delta source_refs
Example Report JSON
{
"object": "analytics.grade_level_status",
"student_id": "b6fa7128-f641-4efd-9075-375411fd6c39",
"subject_id": "math",
"as_of_date": "2026-05-20",
"age_grade": 5,
"working_grade": 6,
"highest_mastered_grade": 5,
"working_age_grade_delta": 1,
"working_age_grade_status": "working_above_age_grade",
"mastered_age_grade_delta": 0,
"mastered_age_grade_status": "mastered_at_age_grade",
"source_refs": {
"age_grade": "people_and_orgs.alpha.age_grade_history",
"working_grade": "results.student_track_state.working_grade",
"highest_mastered_grade": "results.highest_mastered_grade"
},
"deprecated_aliases": {
"instructional_level_status": "working_age_grade_status",
"strict_mastery_status": "mastered_age_grade_status"
}
}
Course Progress Evidence: Completion Percent
Learning Report panel: courseCompletion
Question: What completion evidence did Analytics materialize for this course?
Table: alpha.analytics_completion_rollup
API Path
GET /alpha/analytics/v1/completion-rollups?studentId=student_01HT7G3YZV7QB5N4YKQ1K0Z9A9&completionScope=course&scopeId=course_math_grade_4_powerpath
Raw DB Path
select xp_earned, xp_remaining, completion_percent, denominator_policy_ref, source_import_id, null_reason from alpha.analytics_completion_rollup where tenant_id = :tenant_id and student_id = :student_id and completion_scope = 'course' and scope_id = 'course_math_grade_4_powerpath' and quality_status in ('ok','corrected') and superseded_at is null and source_deleted_at is null;
Render these fields: xp_earned xp_remaining completion_percent denominator_policy_ref source_import_id null_reason
End-To-End Learning Report Assembly
Learning Report panel: fullLearningReport
Question: How does one studentId + term become the Learning Report panels, including Accuracy?
Tables: alpha.analytics_school_day_minutes alpha.analytics_xp_rollup alpha.analytics_accuracy alpha.analytics_mastery_delta alpha.analytics_map_growth_rollup alpha.analytics_completion_rollup
Assembly Steps
- Resolve studentId, subjectId, canonicalTermId, term_start, term_end, normsSet, growthWindow=winter_to_winter for the "vs 1yr ago" MAP panel, completionScope, and scopeId from the report route or upstream Alpha surfaces.
- Read the six Analytics tables/endpoints at their documented grains with the ordinary current-row filters.
- Place returned fields into report panels. If a time-commitment row or XP goal row has null_reason=source_missing, it is a repair state and the report is incomplete until the source is fixed/replayed; do not substitute active dates, attendance days, or calendar-day counts. The only client work is shaping JSON for display; no minutes, XP, accuracy, mastery, MAP, or completion math runs in the report.
API Path
GET /alpha/analytics/v1/school-day-minutes?studentId=student_01HT7G3YZV7QB5N4YKQ1K0Z9A9&subjectId=math&startDate=2026-01-01&endDate=2026-06-01 GET /alpha/analytics/v1/xp-rollups?studentId=student_01HT7G3YZV7QB5N4YKQ1K0Z9A9&subjectId=math&windowKind=term&startDate=2026-01-01&endDate=2026-06-01 GET /alpha/analytics/v1/accuracy-rollups?studentId=student_01HT7G3YZV7QB5N4YKQ1K0Z9A9&subjectId=math&windowKind=term&startDate=2026-01-01&endDate=2026-06-01 GET /alpha/analytics/v1/mastery-deltas?studentId=student_01HT7G3YZV7QB5N4YKQ1K0Z9A9&startDate=2026-01-01&endDate=2026-06-01 GET /alpha/analytics/v1/map-growth-rollups?studentId=student_01HT7G3YZV7QB5N4YKQ1K0Z9A9&subjectId=math&termId=term_2026_winter&growthWindow=winter_to_winter&normsSet=2025 GET /alpha/analytics/v1/completion-rollups?studentId=student_01HT7G3YZV7QB5N4YKQ1K0Z9A9&completionScope=course&scopeId=course_math_grade_4_powerpath
Raw DB Path
with
time_commitment as (
select active_minutes, enrolled_school_day_count, excluded_school_day_count, minutes_per_enrolled_school_day, quality_status, null_reason
from alpha.analytics_school_day_minutes
where tenant_id = :tenant_id and student_id = :student_id and subject_id = :subject_id
and window_start = :term_start and window_end = :term_end
and quality_status in ('ok','corrected') and null_reason = 'none' and superseded_at is null and source_deleted_at is null
),
xp as (
select xp_total, net_xp, daily_xp_goal, enrolled_school_day_count, xp_goal, xp_remaining, xp_goal_percent, xp_completion_percent, on_track, positive_xp, negative_xp, award_count, reversal_count, source_import_id, null_reason
from alpha.analytics_xp_rollup
where tenant_id = :tenant_id and student_id = :student_id and subject_id = :subject_id
and window_kind = 'term' and window_start = :term_start and window_end = :term_end
and quality_status in ('ok','corrected') and superseded_at is null and source_deleted_at is null
),
accuracy as (
select correct_question_count, total_question_count, incorrect_question_count, accuracy_percent, source_import_id, null_reason
from alpha.analytics_accuracy
where tenant_id = :tenant_id and student_id = :student_id and subject_id = :subject_id
and window_kind = 'term' and window_start = :term_start and window_end = :term_end
and quality_status in ('ok','corrected') and superseded_at is null and source_deleted_at is null
),
mastery as (
select jsonb_agg(jsonb_build_object(
'kcId', kc_id,
'stateDimension', state_dimension,
'transition', transition_kind,
'previousValue', previous_value,
'newValue', new_value,
'effectiveAt', effective_at
) order by effective_at desc) as deltas
from alpha.analytics_mastery_delta
where tenant_id = :tenant_id and student_id = :student_id
and effective_at >= :term_start::timestamptz and effective_at < :term_end::timestamptz
and quality_status in ('ok','corrected') and superseded_at is null and source_deleted_at is null
),
map as (
select rit_score, achievement_percentile, growth_percentile, observed_growth, projected_growth, typical_growth, growth_x, growth_x_target, on_track,
sitting_count, retake_count, norms_set, growth_window, source_import_id
from alpha.analytics_map_growth_rollup
where tenant_id = :tenant_id and student_id = :student_id and subject_id = :subject_id
and canonical_term_id = :canonical_term_id and growth_window = :growth_window and norms_set = :norms_set
and quality_status in ('ok','corrected') and superseded_at is null and source_deleted_at is null
),
completion as (
select completion_scope, scope_id, xp_earned, xp_remaining, completion_percent, null_reason, source_import_id
from alpha.analytics_completion_rollup
where tenant_id = :tenant_id and student_id = :student_id
and completion_scope = :completion_scope and scope_id = :scope_id
and quality_status in ('ok','corrected') and superseded_at is null and source_deleted_at is null
)
select jsonb_build_object(
'studentId', :student_id,
'termId', :canonical_term_id,
'panels', jsonb_build_object(
'timeCommitment', (select to_jsonb(time_commitment) from time_commitment),
'xpGoals', (select to_jsonb(xp) from xp),
'accuracy', (select to_jsonb(accuracy) from accuracy),
'masteryTransitions', coalesce((select deltas from mastery), '[]'::jsonb),
'mapResults', (select to_jsonb(map) from map),
'courseCompletion', (select to_jsonb(completion) from completion)
)
) as learning_report_json;
Render these fields: panels.timeCommitment.active_minutes panels.timeCommitment.enrolled_school_day_count panels.timeCommitment.excluded_school_day_count panels.timeCommitment.minutes_per_enrolled_school_day panels.timeCommitment.null_reason panels.xpGoals.xp_total panels.xpGoals.net_xp panels.xpGoals.daily_xp_goal panels.xpGoals.enrolled_school_day_count panels.xpGoals.xp_remaining panels.xpGoals.xp_goal_percent panels.xpGoals.xp_completion_percent panels.xpGoals.source_import_id panels.xpGoals.null_reason panels.accuracy.correct_question_count panels.accuracy.total_question_count panels.accuracy.accuracy_percent panels.accuracy.source_import_id panels.masteryTransitions[] panels.mapResults.rit_score panels.mapResults.achievement_percentile panels.mapResults.growth_percentile panels.mapResults.observed_growth panels.mapResults.projected_growth panels.mapResults.typical_growth panels.mapResults.growth_x panels.mapResults.growth_x_target panels.mapResults.on_track panels.mapResults.sitting_count panels.mapResults.retake_count panels.mapResults.norms_set panels.mapResults.growth_window panels.mapResults.source_import_id panels.courseCompletion.completion_percent
Example Report JSON
{
"studentId": "student_01HT7G3YZV7QB5N4YKQ1K0Z9A9",
"termId": "term_2026_winter",
"panels": {
"timeCommitment": {
"active_minutes": 4860,
"enrolled_school_day_count": 90,
"excluded_school_day_count": 61,
"minutes_per_enrolled_school_day": 54,
"quality_status": "ok",
"null_reason": "none"
},
"xpGoals": {
"xp_total": 11800,
"positive_xp": 11850,
"negative_xp": -50,
"net_xp": 11800,
"daily_xp_goal": 100,
"enrolled_school_day_count": 90,
"xp_goal": 9000,
"xp_remaining": 0,
"xp_goal_percent": 131.111,
"xp_completion_percent": 131.111,
"on_track": true,
"source_import_id": "imp_01HT8XPTIME_2026_SPRING",
"null_reason": "none",
"award_count": 24,
"reversal_count": 1
},
"accuracy": {
"correct_question_count": 480,
"total_question_count": 600,
"incorrect_question_count": 120,
"accuracy_percent": 80,
"source_import_id": "imp_01HT8XPTIME_2026_SPRING",
"null_reason": "none"
},
"masteryTransitions": [
{
"kcId": "kc_math_fraction_addition_unlike_denominators",
"stateDimension": "durable_mastery",
"transition": "acquired",
"previousValue": {
"value": 0.82
},
"newValue": {
"value": 0.91
},
"effectiveAt": "2026-05-14T18:45:00Z"
}
],
"mapResults": {
"rit_score": 239,
"achievement_percentile": 91,
"growth_percentile": 43,
"observed_growth": 6,
"typical_growth": 2,
"projected_growth": 7,
"growth_x": 0.8571,
"growth_x_target": 2,
"on_track": false,
"sitting_count": 2,
"retake_count": 1,
"norms_set": "2025",
"growth_window": "winter_to_winter",
"source_import_id": "imp_01HT8MAP_2026_WINTER"
},
"courseCompletion": {
"completion_scope": "course",
"scope_id": "course_math_grade_4_powerpath",
"xp_earned": 900,
"xp_remaining": 300,
"completion_percent": 75,
"null_reason": "none"
}
}
}
Object Example Coverage
Each Analytics object below has a JSON payload at the top of its section, matching the Stripe reference pattern of showing a concrete object before the field list. Required fields are validated against these payloads during the build.
| Object | Example Anchor | What The Payload Proves |
|---|---|---|
alpha.analytics_event_time_fact |
Example payload | id tenant_id student_id source_event_id source_fact_key source_closed_at fact_kind seconds_delta + 9 more fields |
alpha.analytics_time_window |
Example payload | id tenant_id student_id subject_id window_kind window_start window_end active_seconds_total + 12 more fields |
alpha.analytics_school_day_minutes |
Example payload | id tenant_id student_id school_id subject_id school_day_policy_ref window_start window_end + 14 more fields |
alpha.analytics_xp_rollup |
Example payload | id tenant_id student_id subject_id policy_ref window_kind window_start window_end + 22 more fields |
alpha.analytics_accuracy |
Example payload | id tenant_id student_id subject_id policy_ref window_kind window_start window_end + 13 more fields |
alpha.analytics_mastery_delta |
Example payload | id tenant_id student_id kc_id grade_subject grade_level completed_on source_import_id + 15 more fields |
alpha.analytics_map_growth_rollup |
Example payload | id tenant_id student_id subject_id canonical_term_id growth_window norms_set map_score_id + 22 more fields |
alpha.analytics_norms_achievement |
Example payload | resource_id tenant_id norms_set table_version subject_id role grade_key season + 7 more fields |
alpha.analytics_r90_table |
Example payload | resource_id tenant_id norms_set table_version table_subject_id rit_score rit50_rit rit90_rit + 14 more fields |
analytics.school_days_remaining |
Example payload | object student_id school_id as_of end_date school_day_policy_ref instructional_days_remaining calendar_ref_count + 7 more fields |
analytics.grade_level_status |
Example payload | object student_id subject_id as_of_date age_grade working_grade highest_mastered_grade working_age_grade_delta + 5 more fields |
alpha.analytics_completion_rollup |
Example payload | id tenant_id student_id completion_scope scope_id subject_id grade_level is_main_course + 17 more fields |
alpha.analytics_source_import |
Example payload | import_id tenant_id import_kind adapter_name source_system source_table status idempotency_key_hash + 11 more fields |
alpha.analytics_event_time_fact
Stores signed active, inactive, and waste second contributions for the DERIVED Events axis, so reports can audit time-on-task without classifying raw Caliper events themselves.
Architecture trace: aitd-000-extend-only-storage, aitd-002-derived-events-complement, aitd-003-close-time-materialization, aitd-005-time-facts-and-windows, aitd-011-policy-and-enum-normalization, aitd-012-corrections-and-reversals
minutes|Caliper eventsGET /alpha/analytics/v1/event-time-factsExample Object Payload
Concrete reportable payload for this object. Required fields in the field list must appear here unless their nullability explicitly allows omission.
{
"id": "8e9c0ef2-bc75-4f53-8124-df77df49f25f",
"tenant_id": "7b0bb5d8-9a38-4a62-9fdc-9f8d2dc1a111",
"student_id": "student_01HT7G3YZV7QB5N4YKQ1K0Z9A9",
"source_event_id": "evt_alpha_000891",
"source_fact_key": "tenant:7b0b:event:evt_891:fact:active_seconds:policy:v2026-06-10:calc:1",
"source_closed_at": "2026-05-14T18:32:20Z",
"fact_kind": "active_seconds",
"seconds_delta": 420,
"subject_id": "math",
"application_ref": "app_math_academy",
"policy_ref": "alpha.policy.analytics.time_classification.v2026-06-10",
"quality_status": "ok",
"calculation_version": 1,
"computed_at": "2026-05-14T18:32:22Z",
"modified_at": "2026-05-14T18:32:22Z",
"superseded_at": null,
"source_deleted_at": null
}
Lifecycle
Written when an Event closes or when an event-close replay runs. Corrections write signed replacement/reversal rows.
Raw DB Rule
Raw readers query current rows by tenant_id/source_event_id/fact_kind/policy_ref and sum seconds_delta only at the documented grain; they do not inspect Caliper JSON. For the Learning Report Time Commitment tile, read analytics_school_day_minutes instead of substituting this derived audit axis.
Field Index
Fields
| Field | Type / Nullability | Meaning | Constraints / Range | Relationship | Invalid When | Example | Source / ITD |
|---|---|---|---|---|---|---|---|
id |
UUID required |
Analytics-owned stable row id for this derived fact. | Generated by the platform; globally unique within alpha.analytics_* objects. | Primary key for list/detail endpoints. | Provided by a public import client or reused across tenants. | 8e9c0ef2-bc75-4f53-8124-df77df49f25f |
Alpha extension aitd-000-extend-only-storage |
tenant_id |
UUID required |
Tenant boundary for the derived fact. | Set from the JWT tenant claim or internal materializer context; never accepted from request body/query. | All raw-path queries must filter by tenant_id before joining, sorting, paging, or counting. | Missing, caller-supplied in body/query, or mismatched with the JWT tenant claim. | 7b0bb5d8-9a38-4a62-9fdc-9f8d2dc1a111 |
Alpha extension aitd-109-axis-tenant-routing, aitd-106-axis-auth-shape |
student_id |
TEXT required |
Canonical Alpha student id the source Event or Result resolved to at materialization time. | Must resolve through People and Orgs as a real student for the source timestamp/effective date. | References People and Orgs student identity; see https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/data_dictionary. | Parsed from email/name/source payload instead of resolved by the Events/Results adapter. | student_01HT7G3YZV7QB5N4YKQ1K0Z9A9 |
Alpha extension reference aitd-003-close-time-materialization, aitd-106-axis-auth-shape, aitd-011-policy-and-enum-normalization |
source_event_id |
TEXT required |
Events Alpha event id this contribution derives from. | Must reference one closed Events row in the same tenant. | Many Analytics facts can reference one Events row; see https://platform3-andymontgomery-9773s-projects.vercel.app/events/alpha/data_dictionary#table-event. | Null, cross-tenant, or replaced by a copied Caliper payload column. | evt_alpha_000891 |
Alpha extension reference aitd-000-extend-only-storage, aitd-003-close-time-materialization, aitd-005-time-facts-and-windows |
source_fact_key |
TEXT required |
Deterministic idempotency key for the materialized source contribution or rollup. | Includes tenant, source ref, fact kind/scope, policy_ref, and calculation_version; max 512 bytes. | Unique per table where the row is a single materialized source contribution. | Generated from non-deterministic timestamps or caller-provided display labels. | tenant:7b0b:event:evt_891:fact:active_seconds:policy:v2026-06-10:calc:1 |
Alpha extension aitd-105-axis-idempotency |
source_closed_at |
TIMESTAMPTZ required |
When the source Event or Result became closed enough for Analytics to materialize from it. | Set by Events/Results close/import notifications; UTC timestamp. | Prevents reports from reading provisional source rows as final derived facts. | Null on a reportable row or copied from source payload without source close confirmation. | 2026-05-14T18:32:20Z |
Alpha extension aitd-003-close-time-materialization |
fact_kind |
TEXT enum required |
Tells whether this source event counted as active work, inactive time, or waste. Which time bucket this signed contribution belongs to. |
Allowed values: fact_kind enum. Set by the versioned time-classification policy named in policy_ref, for example alpha.policy.analytics.time_classification.v2026-06-10. | One source event can create up to one current row for each fact_kind under a policy. | A caller supplies the bucket or a report parses app names/actions to infer it. | active_seconds |
Alpha extension aitd-005-time-facts-and-windows, aitd-011-policy-and-enum-normalization |
seconds_delta |
NUMERIC(14,3) required |
The signed number of seconds this one event added or removed. Signed seconds contributed by this source event to the fact_kind bucket. |
May be negative for correction/reversal rows; ordinary display measures use rollup fields, not client-side clamping. | Feeds alpha.analytics_time_window totals. | Assumed nonnegative for corrections or recomputed from source duration by a report. | 420.000 |
Alpha extension aitd-005-time-facts-and-windows, aitd-012-corrections-and-reversals |
subject_id |
TEXT nullable where the row is all-subject or the source cannot validly resolve a subject |
Canonical Alpha subject used for reporting and grouping. | Closed Alpha subject enum after write-time source-label normalization; unknown source subject becomes an adapter finding or null_reason, not a new string. | References the Curriculum/Results subject vocabulary; see https://platform3-andymontgomery-9773s-projects.vercel.app/curriculum/alpha/data_dictionary and https://platform3-andymontgomery-9773s-projects.vercel.app/results/alpha/data_dictionary. | Copied from source strings such as FastMath, Vocabulary, Science-notqced, or ISEE variants without normalization. | math |
Alpha extension reference aitd-011-policy-and-enum-normalization |
application_ref |
TEXT nullable |
Application/activity-source reference resolved from the source event when available. | Reference only; application identity/lifecycle belongs to Applications. | Optional grouping key for app-level time evidence; not a user id. | Used as a credential, treated as a student, or copied from app display text without registry resolution. | app_math_academy |
Alpha extension reference aitd-011-policy-and-enum-normalization |
policy_ref |
TEXT required |
The rulebook version Analytics used; see Policy Reference on this page. Named policy/config version used to compute the measure or rollup. |
Must point at alpha.policy.analytics.* or an inherited Curriculum/Results policy active for the source effective date. | Many Analytics facts can share one policy row; changing policy creates new calculation versions or corrections. | A consumer hard-codes thresholds, school-day calendars, Growth X formulas, or completion denominators instead of using the policy ref. | alpha.policy.analytics.time_classification.v2026-06-10 |
Alpha extension reference aitd-011-policy-and-enum-normalization, aitd-003-close-time-materialization |
quality_status |
TEXT enum required |
Whether this row is reportable, corrected, reversed, blocked, or rejected. Current materialization quality state for this fact. |
Allowed values: quality_status enum. Ordinary report reads keep ok, corrected, and signed reversed rows according to the table rule; audit reads may include source_missing/source_unlinked/policy_pending/adapter_rejected. | Used by raw/API convergence filters and source-ref audit views. | Free-text status or hidden failures represented as HTTP 200 success. | ok |
Alpha extension aitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope, aitd-111-axis-privacy-retention |
calculation_version |
INTEGER required |
Materializer calculation version for this fact shape. | Positive integer; starts at 1 and increments when policy/materializer logic intentionally changes. | Part of deterministic source_fact_key/idempotency for materializer writes. | Omitted from replay keys or changed without a new policy/materializer decision. | 1 |
Alpha extension aitd-003-close-time-materialization, aitd-105-axis-idempotency, aitd-104-axis-concurrency |
computed_at |
TIMESTAMPTZ required |
When Analytics wrote this derived fact. | UTC timestamp with timezone; updated only by Analytics materializers. | Used for audit and source-ref subcollections, not for school-day grouping. | Used as a substitute for the source event time, result effective time, or window boundaries. | 2026-06-10T00:51:14Z |
Alpha extension aitd-003-close-time-materialization |
modified_at |
TIMESTAMPTZ required |
Last time the Analytics row changed for polling and modifiedSince queries. | UTC timestamp; list endpoints support modifiedSince against this field. | Supports poll plus modifiedSince eventing. | Client-supplied or used as the business effective date. | 2026-06-10T00:51:14Z |
Alpha extension aitd-107-axis-eventing, aitd-103-axis-query-model |
superseded_at |
TIMESTAMPTZ nullable |
When this row stopped being the current reportable version because of source correction, deletion, or recalculation. | Null means current; non-null rows are excluded from ordinary list reads unless includeSuperseded=true and authorized. | Preserves audit history without mutating source Events or Results. | Used to hard-delete old rows or omitted on a correction that replaces a prior fact. | null |
Alpha extension aitd-111-axis-privacy-retention, aitd-012-corrections-and-reversals |
source_deleted_at |
TIMESTAMPTZ nullable |
When the source Event/Result became deleted or invalidated. | Null for live source rows; set from source tombstone/correction notifications. | Ordinary reads exclude tombstoned facts unless includeSuperseded=true and authorized. | Used as a physical delete or ignored by raw-path report queries. | null |
Alpha extension aitd-111-axis-privacy-retention |
Enums Used Here
fact_kind | |||
|---|---|---|---|
| Value | Meaning | Source | ITD |
active_seconds | Seconds the policy classifies as productive engaged work for a closed source event. | Alpha extension enum | aitd-005-time-facts-and-windows, aitd-011-policy-and-enum-normalization |
inactive_seconds | Seconds the policy classifies as idle or not meaningfully engaged. | Alpha extension enum | aitd-005-time-facts-and-windows, aitd-011-policy-and-enum-normalization |
waste_seconds | Seconds the policy classifies as gaming, distraction, or otherwise counterproductive work. | Alpha extension enum | aitd-005-time-facts-and-windows, aitd-011-policy-and-enum-normalization |
quality_status | |||
|---|---|---|---|
| Value | Meaning | Source | ITD |
ok | The row is the current reportable fact for its key and policy. | Alpha extension enum | aitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope, aitd-111-axis-privacy-retention |
corrected | The row includes a correction contribution but remains reportable. | Alpha extension enum | aitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope, aitd-111-axis-privacy-retention |
reversed | The row reverses a prior contribution and should be read as signed history. | Alpha extension enum | aitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope, aitd-111-axis-privacy-retention |
source_missing | A required source row was removed or unavailable before the fact could be finalized. | Alpha extension enum | aitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope, aitd-111-axis-privacy-retention |
source_unlinked | The source row exists but could not link to a required Event, Result, student, subject, KC, course, or policy ref. | Alpha extension enum | aitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope, aitd-111-axis-privacy-retention |
policy_pending | A required policy configuration was missing or not yet active at materialization time. | Alpha extension enum | aitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope, aitd-111-axis-privacy-retention |
adapter_rejected | The source-shaped row was valid input but the server-side adapter rejected it with a typed Problem. | Alpha extension enum | aitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope, aitd-111-axis-privacy-retention |
alpha.analytics_time_window
Report-ready active, inactive, and waste time totals for the DERIVED Events axis. These complement the ingested Time Commitment tile and support audit/Waste views.
Architecture trace: aitd-005-time-facts-and-windows, aitd-002-derived-events-complement, aitd-003-close-time-materialization, aitd-011-policy-and-enum-normalization, aitd-112-axis-list-endpoints
minutes|Caliper eventsGET /alpha/analytics/v1/time-windowsExample Object Payload
Concrete reportable payload for this object. Required fields in the field list must appear here unless their nullability explicitly allows omission.
{
"id": "1b0d98de-8f58-4ec3-9f2b-5cfbfa3d0001",
"tenant_id": "7b0bb5d8-9a38-4a62-9fdc-9f8d2dc1a111",
"student_id": "student_01HT7G3YZV7QB5N4YKQ1K0Z9A9",
"subject_id": "math",
"window_kind": "day",
"window_start": "2026-05-14",
"window_end": "2026-05-15",
"active_seconds_total": 3240,
"inactive_seconds_total": 120,
"waste_seconds_total": 0,
"display_active_minutes": 54,
"source_fact_count": 12,
"source_fact_refs": [
"8e9c0ef2-bc75-4f53-8124-df77df49f25f"
],
"policy_ref": "alpha.policy.analytics.time_classification.v2026-06-10",
"quality_status": "ok",
"calculation_version": 1,
"computed_at": "2026-05-14T23:59:59Z",
"modified_at": "2026-05-14T23:59:59Z",
"superseded_at": null,
"source_deleted_at": null
}
Lifecycle
Refreshed idempotently after event-time facts close, replay, correct, or reverse.
Raw DB Rule
Raw readers use this table for active/inactive/waste totals by window and subject; they do not group raw Events by event_time or parse processed_facts. For minutes per enrolled school day, read analytics_school_day_minutes.
Field Index
Fields
| Field | Type / Nullability | Meaning | Constraints / Range | Relationship | Invalid When | Example | Source / ITD |
|---|---|---|---|---|---|---|---|
id |
UUID required |
Analytics-owned stable row id for this derived fact. | Generated by the platform; globally unique within alpha.analytics_* objects. | Primary key for list/detail endpoints. | Provided by a public import client or reused across tenants. | 8e9c0ef2-bc75-4f53-8124-df77df49f25f |
Alpha extension aitd-000-extend-only-storage |
tenant_id |
UUID required |
Tenant boundary for the derived fact. | Set from the JWT tenant claim or internal materializer context; never accepted from request body/query. | All raw-path queries must filter by tenant_id before joining, sorting, paging, or counting. | Missing, caller-supplied in body/query, or mismatched with the JWT tenant claim. | 7b0bb5d8-9a38-4a62-9fdc-9f8d2dc1a111 |
Alpha extension aitd-109-axis-tenant-routing, aitd-106-axis-auth-shape |
student_id |
TEXT required |
Canonical Alpha student id the source Event or Result resolved to at materialization time. | Must resolve through People and Orgs as a real student for the source timestamp/effective date. | References People and Orgs student identity; see https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/data_dictionary. | Parsed from email/name/source payload instead of resolved by the Events/Results adapter. | student_01HT7G3YZV7QB5N4YKQ1K0Z9A9 |
Alpha extension reference aitd-003-close-time-materialization, aitd-106-axis-auth-shape, aitd-011-policy-and-enum-normalization |
subject_id |
TEXT nullable where the row is all-subject or the source cannot validly resolve a subject |
Canonical Alpha subject used for reporting and grouping. | Closed Alpha subject enum after write-time source-label normalization; unknown source subject becomes an adapter finding or null_reason, not a new string. | References the Curriculum/Results subject vocabulary; see https://platform3-andymontgomery-9773s-projects.vercel.app/curriculum/alpha/data_dictionary and https://platform3-andymontgomery-9773s-projects.vercel.app/results/alpha/data_dictionary. | Copied from source strings such as FastMath, Vocabulary, Science-notqced, or ISEE variants without normalization. | math |
Alpha extension reference aitd-011-policy-and-enum-normalization |
window_kind |
TEXT enum required |
Named window family for this rollup. | Allowed values: window_kind enum; custom requires explicit policy/window metadata. | Part of the rollup grain and list filters. | Inferred by parsing term labels or source date strings in a consumer. | day |
Alpha extension aitd-005-time-facts-and-windows, aitd-011-policy-and-enum-normalization, aitd-103-axis-query-model |
window_start |
DATE required |
Inclusive start date of the reporting window in the school timezone. | Must be before window_end; ISO date. | Half-open range [window_start, window_end). | Computed from modified_at or source_closed_at instead of the policy window. | 2026-05-14 |
Alpha extension aitd-005-time-facts-and-windows |
window_end |
DATE required |
Exclusive end date of the reporting window in the school timezone. | Must be after window_start; ISO date. | Half-open range [window_start, window_end). | Treated as inclusive by raw-path queries. | 2026-05-15 |
Alpha extension aitd-005-time-facts-and-windows |
active_seconds_total |
NUMERIC(14,3) required |
Total active work time in this window before display rounding. Net active seconds from current event_time_fact rows in this window. |
Can include signed corrections; display fields apply policy presentation. | Numerator source for school-day minutes. | Recomputed by the app from source events. | 3240.000 |
Alpha extension aitd-005-time-facts-and-windows, aitd-012-corrections-and-reversals |
inactive_seconds_total |
NUMERIC(14,3) required |
Net inactive seconds from current event_time_fact rows in this window. | Can include signed corrections. | Report display/audit metric; not subtracted by consumers unless a named policy says so. | Derived by client idle-threshold logic. | 120.000 |
Alpha extension aitd-005-time-facts-and-windows, aitd-012-corrections-and-reversals |
waste_seconds_total |
NUMERIC(14,3) required |
Net waste/gaming seconds from current event_time_fact rows in this window. | Can be positive or negative after corrections. | Feeds closed-loop dashboards and XP penalty audits. | Modeled as an event category rather than an Analytics derived fact. | 0.000 |
Alpha extension aitd-005-time-facts-and-windows, aitd-012-corrections-and-reversals |
display_active_minutes |
NUMERIC(12,3) required |
The minutes number a report can show for this time window. Policy-defined active minutes shown in reports for this time window. |
Computed by Analytics from active_seconds_total under policy_ref; consumers read it directly. | Used by app/report display when the question asks for active minutes, not raw seconds. | Consumer divides seconds by 60 differently or clamps signed corrections locally. | 54.000 |
Alpha extension aitd-005-time-facts-and-windows, aitd-012-corrections-and-reversals |
source_fact_count |
INTEGER required |
Number of current event_time_fact rows contributing to this rollup. | Nonnegative integer. | Audit/provenance summary; detailed refs live in the authorized sourceRefs subcollection. | Used as a proxy for number of Events without applying fact_kind and correction rules. | 12 |
Alpha extension aitd-102-axis-read-shape |
source_fact_refs |
JSONB required |
Compact list or cursor descriptor for contributing analytics_event_time_fact ids. | Contains ids/hashes only, never raw Caliper payload or PII. | Supports /time-windows/{id}/source-refs for authorized audit users. | Stores source payload copies or student display names. | ["8e9c0ef2-bc75-4f53-8124-df77df49f25f"] |
Alpha extension aitd-000-extend-only-storage, aitd-102-axis-read-shape, aitd-111-axis-privacy-retention |
policy_ref |
TEXT required |
The rulebook version Analytics used; see Policy Reference on this page. Named policy/config version used to compute the measure or rollup. |
Must point at alpha.policy.analytics.* or an inherited Curriculum/Results policy active for the source effective date. | Many Analytics facts can share one policy row; changing policy creates new calculation versions or corrections. | A consumer hard-codes thresholds, school-day calendars, Growth X formulas, or completion denominators instead of using the policy ref. | alpha.policy.analytics.time_classification.v2026-06-10 |
Alpha extension reference aitd-011-policy-and-enum-normalization, aitd-003-close-time-materialization |
quality_status |
TEXT enum required |
Whether this row is reportable, corrected, reversed, blocked, or rejected. Current materialization quality state for this fact. |
Allowed values: quality_status enum. Ordinary report reads keep ok, corrected, and signed reversed rows according to the table rule; audit reads may include source_missing/source_unlinked/policy_pending/adapter_rejected. | Used by raw/API convergence filters and source-ref audit views. | Free-text status or hidden failures represented as HTTP 200 success. | ok |
Alpha extension aitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope, aitd-111-axis-privacy-retention |
calculation_version |
INTEGER required |
Materializer calculation version for this fact shape. | Positive integer; starts at 1 and increments when policy/materializer logic intentionally changes. | Part of deterministic source_fact_key/idempotency for materializer writes. | Omitted from replay keys or changed without a new policy/materializer decision. | 1 |
Alpha extension aitd-003-close-time-materialization, aitd-105-axis-idempotency, aitd-104-axis-concurrency |
computed_at |
TIMESTAMPTZ required |
When Analytics wrote this derived fact. | UTC timestamp with timezone; updated only by Analytics materializers. | Used for audit and source-ref subcollections, not for school-day grouping. | Used as a substitute for the source event time, result effective time, or window boundaries. | 2026-06-10T00:51:14Z |
Alpha extension aitd-003-close-time-materialization |
modified_at |
TIMESTAMPTZ required |
Last time the Analytics row changed for polling and modifiedSince queries. | UTC timestamp; list endpoints support modifiedSince against this field. | Supports poll plus modifiedSince eventing. | Client-supplied or used as the business effective date. | 2026-06-10T00:51:14Z |
Alpha extension aitd-107-axis-eventing, aitd-103-axis-query-model |
superseded_at |
TIMESTAMPTZ nullable |
When this row stopped being the current reportable version because of source correction, deletion, or recalculation. | Null means current; non-null rows are excluded from ordinary list reads unless includeSuperseded=true and authorized. | Preserves audit history without mutating source Events or Results. | Used to hard-delete old rows or omitted on a correction that replaces a prior fact. | null |
Alpha extension aitd-111-axis-privacy-retention, aitd-012-corrections-and-reversals |
source_deleted_at |
TIMESTAMPTZ nullable |
When the source Event/Result became deleted or invalidated. | Null for live source rows; set from source tombstone/correction notifications. | Ordinary reads exclude tombstoned facts unless includeSuperseded=true and authorized. | Used as a physical delete or ignored by raw-path report queries. | null |
Alpha extension aitd-111-axis-privacy-retention |
Enums Used Here
window_kind | |||
|---|---|---|---|
| Value | Meaning | Source | ITD |
day | A calendar day in the school timezone, represented as a half-open date range. | Alpha extension enum | aitd-005-time-facts-and-windows, aitd-103-axis-query-model, aitd-011-policy-and-enum-normalization |
week | A platform week under alpha.policy.analytics.window. | Alpha extension enum | aitd-005-time-facts-and-windows, aitd-103-axis-query-model, aitd-011-policy-and-enum-normalization |
term | An academic term from the People and Orgs academic-session calendar. | Alpha extension enum | aitd-005-time-facts-and-windows, aitd-103-axis-query-model, aitd-011-policy-and-enum-normalization |
school_year | A school-year window from the org academic-session calendar. | Alpha extension enum | aitd-005-time-facts-and-windows, aitd-103-axis-query-model, aitd-011-policy-and-enum-normalization |
custom | A caller-requested or migration reconciliation range with explicit start and end dates. | Alpha extension enum | aitd-005-time-facts-and-windows, aitd-103-axis-query-model, aitd-011-policy-and-enum-normalization |
quality_status | |||
|---|---|---|---|
| Value | Meaning | Source | ITD |
ok | The row is the current reportable fact for its key and policy. | Alpha extension enum | aitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope, aitd-111-axis-privacy-retention |
corrected | The row includes a correction contribution but remains reportable. | Alpha extension enum | aitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope, aitd-111-axis-privacy-retention |
reversed | The row reverses a prior contribution and should be read as signed history. | Alpha extension enum | aitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope, aitd-111-axis-privacy-retention |
source_missing | A required source row was removed or unavailable before the fact could be finalized. | Alpha extension enum | aitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope, aitd-111-axis-privacy-retention |
source_unlinked | The source row exists but could not link to a required Event, Result, student, subject, KC, course, or policy ref. | Alpha extension enum | aitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope, aitd-111-axis-privacy-retention |
policy_pending | A required policy configuration was missing or not yet active at materialization time. | Alpha extension enum | aitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope, aitd-111-axis-privacy-retention |
adapter_rejected | The source-shaped row was valid input but the server-side adapter rejected it with a typed Problem. | Alpha extension enum | aitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope, aitd-111-axis-privacy-retention |
alpha.analytics_school_day_minutes
Minutes per enrolled school day for the Time Commitment tile. Numerator is ingested from reporting.processed_facts.active_seconds; denominator is alpha.school_calendar intersected with enrollment/subject assignment, with MAP-day exclusion.
Architecture trace: aitd-006-school-day-minutes, aitd-001-report-source-ingestion, aitd-004-provenance-no-literals, aitd-005-time-facts-and-windows, aitd-011-policy-and-enum-normalization
minutes|Caliper eventsGET /alpha/analytics/v1/school-day-minutesExample Object Payload
Concrete reportable payload for this object. Required fields in the field list must appear here unless their nullability explicitly allows omission.
{
"id": "2d4b32cd-c4d8-4e45-8a3a-9de8ce3b0002",
"tenant_id": "7b0bb5d8-9a38-4a62-9fdc-9f8d2dc1a111",
"student_id": "student_01HT7G3YZV7QB5N4YKQ1K0Z9A9",
"school_id": "school_alpha_austin",
"subject_id": "math",
"school_day_policy_ref": "alpha.policy.school_day.v2026-06-10",
"window_start": "2026-01-01",
"window_end": "2026-06-01",
"active_minutes": 4860,
"source_import_id": "imp_01HT8XPTIME_2026_SPRING",
"enrolled_school_day_count": 90,
"excluded_school_day_count": 61,
"minutes_per_enrolled_school_day": 54,
"calendar_ref_count": 151,
"enrollment_ref_count": 1,
"null_reason": "none",
"quality_status": "ok",
"calculation_version": 1,
"computed_at": "2026-06-01T01:00:00Z",
"modified_at": "2026-06-01T01:00:00Z",
"superseded_at": null,
"source_deleted_at": null
}
Lifecycle
Materialized when the timeback-xp-time-accuracy adapter ingests reporting.processed_facts for the numerator and when alpha.school_calendar, enrollment windows, subject assignments, or school-day policy inputs change. If calendar coverage is missing, materialization writes an explanatory null/source_missing repair row rather than a guessed denominator; ordinary Learning Report rows are ok/corrected with null_reason=none.
Raw DB Rule
Raw readers use this table for school-day minutes; they do not intersect Events with calendars/enrollment/client-side. Ordinary reports require quality_status in ('ok','corrected') and null_reason='none'. If source_missing appears, treat it as a repair state and do not render a fabricated time-commitment number.
Formula
minutes_per_enrolled_school_day = round(active_minutes / enrolled_school_day_count, 3) when enrolled_school_day_count > 0 and null_reason = none. If the denominator source is unavailable, enrolled_school_day_count, excluded_school_day_count, and minutes_per_enrolled_school_day are null with null_reason=source_missing until repaired/replayed.
Field Index
Fields
| Field | Type / Nullability | Meaning | Constraints / Range | Relationship | Invalid When | Example | Source / ITD |
|---|---|---|---|---|---|---|---|
id |
UUID required |
Analytics-owned stable row id for this derived fact. | Generated by the platform; globally unique within alpha.analytics_* objects. | Primary key for list/detail endpoints. | Provided by a public import client or reused across tenants. | 8e9c0ef2-bc75-4f53-8124-df77df49f25f |
Alpha extension aitd-000-extend-only-storage |
tenant_id |
UUID required |
Tenant boundary for the derived fact. | Set from the JWT tenant claim or internal materializer context; never accepted from request body/query. | All raw-path queries must filter by tenant_id before joining, sorting, paging, or counting. | Missing, caller-supplied in body/query, or mismatched with the JWT tenant claim. | 7b0bb5d8-9a38-4a62-9fdc-9f8d2dc1a111 |
Alpha extension aitd-109-axis-tenant-routing, aitd-106-axis-auth-shape |
student_id |
TEXT required |
Canonical Alpha student id the source Event or Result resolved to at materialization time. | Must resolve through People and Orgs as a real student for the source timestamp/effective date. | References People and Orgs student identity; see https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/data_dictionary. | Parsed from email/name/source payload instead of resolved by the Events/Results adapter. | student_01HT7G3YZV7QB5N4YKQ1K0Z9A9 |
Alpha extension reference aitd-003-close-time-materialization, aitd-106-axis-auth-shape, aitd-011-policy-and-enum-normalization |
school_id |
TEXT required |
People and Orgs school whose calendar/enrollment intersection defines the denominator. | Must resolve as the student school for the effective range; no current-only shortcut. | References People and Orgs school identity; calendar source is alpha.school_calendar over Ed-Fi CalendarDate (https://platform3-andymontgomery-9773s-projects.vercel.app/ed_fi/1edtech/data_dictionary). | Copied from source campus_name or joined through current roster instead of effective-dated enrollment. | school_alpha_austin |
Alpha extension reference aitd-006-school-day-minutes |
subject_id |
TEXT nullable; null means all reportable subjects |
Canonical Alpha subject used for reporting and grouping. | Closed Alpha subject enum after write-time source-label normalization; unknown source subject becomes an adapter finding or null_reason, not a new string. | References the Curriculum/Results subject vocabulary; see https://platform3-andymontgomery-9773s-projects.vercel.app/curriculum/alpha/data_dictionary and https://platform3-andymontgomery-9773s-projects.vercel.app/results/alpha/data_dictionary. | Copied from source strings such as FastMath, Vocabulary, Science-notqced, or ISEE variants without normalization. | math |
Alpha extension reference aitd-011-policy-and-enum-normalization |
school_day_policy_ref |
TEXT required |
The rulebook version Analytics used; see Policy Reference on this page. Named policy/config version used to compute the measure or rollup. |
Must point at alpha.policy.analytics.* or an inherited Curriculum/Results policy active for the source effective date. | Many Analytics facts can share one policy row; changing policy creates new calculation versions or corrections. | A consumer hard-codes thresholds, school-day calendars, Growth X formulas, or completion denominators instead of using the policy ref. | alpha.policy.school_day.v2026-06-10 |
Alpha extension reference aitd-006-school-day-minutes, aitd-011-policy-and-enum-normalization |
window_start |
DATE required |
Inclusive start date for the denominator/numerator window. | ISO date; half-open range with window_end. | Used with school_id calendar and enrollment refs. | Parsed from report labels or MAP term strings. | 2026-05-01 |
Alpha extension aitd-006-school-day-minutes |
window_end |
DATE required |
Exclusive end date for the denominator/numerator window. | ISO date; must be after window_start. | Used with school_id calendar and enrollment refs. | Treated as inclusive by raw queries. | 2026-06-01 |
Alpha extension aitd-006-school-day-minutes |
enrolled_school_day_count |
INTEGER required when null_reason=none; nullable only for source_missing repair rows |
The number of real school days your child was enrolled for this report period. Denominator: school days intersecting the student effective-dated enrollment and subject assignment when subject_id is present. |
Nonnegative; excludes weekends, holidays, teacher-workshop days, MAP-testing days, and non-time-locatable enrollments. Null only with a typed repair reason such as source_missing. | Comes from alpha.school_calendar and People and Orgs enrollment windows. | Computed from processed_facts active dates, attendance days, raw calendar days, or current enrollment by a report. | 90 |
Alpha extension aitd-006-school-day-minutes |
excluded_school_day_count |
INTEGER required when null_reason=none; nullable only for source_missing repair rows |
The number of calendar dates excluded by the school-day policy. Calendar dates inside the requested window that the school-day policy excluded from the denominator. |
Nonnegative; includes weekend, holiday_break, teacher_workshop, nwea_map_testing, and governed other exclusions. Null only with a typed repair reason such as source_missing. | Same alpha.school_calendar source and enrollment/subject intersection pass as enrolled_school_day_count. | Guessed from weekends, hard-coded MAP dates, or attendance gaps without calendar rows. | 61 |
Alpha extension aitd-006-school-day-minutes |
active_minutes |
NUMERIC(12,3) required |
Policy-defined active minutes for the same window and subject grain. | Normalized by the timeback-xp-time-accuracy adapter from reporting.processed_facts.active_seconds, then stored as minutes under policy_ref. | Numerator for minutes_per_enrolled_school_day; analytics_time_window remains the derived Events audit complement. | A consumer sums raw event durations, divides processed_facts seconds, or substitutes derived audit seconds for the report tile. | 4860.000 |
Alpha extension aitd-006-school-day-minutes, aitd-001-report-source-ingestion, aitd-005-time-facts-and-windows |
minutes_per_enrolled_school_day |
NUMERIC(12,3) nullable when denominator is zero or policy/source is missing |
The time-commitment average shown on a Learning Report. Report-ready average active minutes per enrolled school day when the school-day denominator source is available. |
Formula: round(active_minutes / enrolled_school_day_count, 3) when enrolled_school_day_count > 0 and null_reason=none. Null requires null_reason other than none; consumers never recompute the denominator or substitute active days. | The value reports and skill packs read. A null/source_missing row is a repair state, not a normal rendered value. | Computed by a dashboard from active_minutes and a client-side day count. | 54.000 |
Alpha extension aitd-006-school-day-minutes |
calendar_ref_count |
INTEGER required when null_reason=none; nullable only for source_missing repair rows |
Count of school calendar rows used in the denominator calculation. | Nonnegative when populated; detailed ids available only to authorized audit reads. Null only when calendar coverage itself is source_missing. | Audit summary for alpha.school_calendar source coverage. | Treated as enrolled school day count without applying enrollment/subject filters. | 151 |
Alpha extension aitd-006-school-day-minutes, aitd-102-axis-read-shape |
enrollment_ref_count |
INTEGER required |
Count of People and Orgs enrollment/membership rows used for the point-in-time denominator. | Nonnegative; null begin_date memberships are excluded from denominator claims. | Audit summary for point-in-time roster source coverage. | Used to infer current school membership outside the requested date range. | 1 |
Alpha extension aitd-006-school-day-minutes |
quality_status |
TEXT enum required |
Whether this row is reportable, corrected, reversed, blocked, or rejected. Current materialization quality state for this school-day denominator row. |
Allowed values: quality_status enum. Ordinary Learning Report rows are ok or corrected; source_missing is a readable repair state when the calendar source is unavailable. | Used with null_reason so the API and raw path can expose repair states without letting reports guess. | A source_missing row is treated as a reportable time-commitment value. | ok |
Alpha extension aitd-006-school-day-minutes, aitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope |
null_reason |
TEXT enum required |
Why the report value is missing instead of asking an app to guess. Why minutes_per_enrolled_school_day and denominator counts are null or not reportable. |
Allowed values: null_reason enum. none means the metric is populated; source_missing means the required calendar source does not exist or is unavailable and the row is not reportable. | Prevents clients from guessing fallback denominator rules. | Null denominator fields with no typed reason, or a free-text explanation. | none |
Alpha extension enum aitd-006-school-day-minutes, aitd-011-policy-and-enum-normalization |
source_import_id |
TEXT required for report-tile rows; nullable for purely derived event-axis rows |
Analytics source-import receipt that proves which named report-source adapter produced this report-grade fact. | Must reference alpha.analytics_source_import for non-null Learning Report tile values; no literal or fixture value may be reportable without this provenance. | Many report-fact rows can reference one source import; detail/sourceRefs endpoints join here for adapter, source_table, and source_row_key_hashes. | Missing on a non-null report-tile value, or replaced by copied raw reporting-DB columns. | imp_01HT8XPTIME_2026_SPRING |
Alpha extension provenance reference aitd-001-report-source-ingestion, aitd-004-provenance-no-literals, aitd-006-school-day-minutes |
calculation_version |
INTEGER required |
Materializer calculation version for this fact shape. | Positive integer; starts at 1 and increments when policy/materializer logic intentionally changes. | Part of deterministic source_fact_key/idempotency for materializer writes. | Omitted from replay keys or changed without a new policy/materializer decision. | 1 |
Alpha extension aitd-003-close-time-materialization, aitd-105-axis-idempotency, aitd-104-axis-concurrency |
computed_at |
TIMESTAMPTZ required |
When Analytics wrote this derived fact. | UTC timestamp with timezone; updated only by Analytics materializers. | Used for audit and source-ref subcollections, not for school-day grouping. | Used as a substitute for the source event time, result effective time, or window boundaries. | 2026-06-10T00:51:14Z |
Alpha extension aitd-003-close-time-materialization |
modified_at |
TIMESTAMPTZ required |
Last time the Analytics row changed for polling and modifiedSince queries. | UTC timestamp; list endpoints support modifiedSince against this field. | Supports poll plus modifiedSince eventing. | Client-supplied or used as the business effective date. | 2026-06-10T00:51:14Z |
Alpha extension aitd-107-axis-eventing, aitd-103-axis-query-model |
superseded_at |
TIMESTAMPTZ nullable |
When this row stopped being the current reportable version because of source correction, deletion, or recalculation. | Null means current; non-null rows are excluded from ordinary list reads unless includeSuperseded=true and authorized. | Preserves audit history without mutating source Events or Results. | Used to hard-delete old rows or omitted on a correction that replaces a prior fact. | null |
Alpha extension aitd-111-axis-privacy-retention, aitd-012-corrections-and-reversals |
source_deleted_at |
TIMESTAMPTZ nullable |
When the source Event/Result became deleted or invalidated. | Null for live source rows; set from source tombstone/correction notifications. | Ordinary reads exclude tombstoned facts unless includeSuperseded=true and authorized. | Used as a physical delete or ignored by raw-path report queries. | null |
Alpha extension aitd-111-axis-privacy-retention |
Enums Used Here
quality_status | |||
|---|---|---|---|
| Value | Meaning | Source | ITD |
ok | The row is the current reportable fact for its key and policy. | Alpha extension enum | aitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope, aitd-111-axis-privacy-retention |
corrected | The row includes a correction contribution but remains reportable. | Alpha extension enum | aitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope, aitd-111-axis-privacy-retention |
reversed | The row reverses a prior contribution and should be read as signed history. | Alpha extension enum | aitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope, aitd-111-axis-privacy-retention |
source_missing | A required source row was removed or unavailable before the fact could be finalized. | Alpha extension enum | aitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope, aitd-111-axis-privacy-retention |
source_unlinked | The source row exists but could not link to a required Event, Result, student, subject, KC, course, or policy ref. | Alpha extension enum | aitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope, aitd-111-axis-privacy-retention |
policy_pending | A required policy configuration was missing or not yet active at materialization time. | Alpha extension enum | aitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope, aitd-111-axis-privacy-retention |
adapter_rejected | The source-shaped row was valid input but the server-side adapter rejected it with a typed Problem. | Alpha extension enum | aitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope, aitd-111-axis-privacy-retention |
null_reason | |||
|---|---|---|---|
| Value | Meaning | Source | ITD |
none | No null-producing condition applies. | Alpha extension enum | aitd-011-policy-and-enum-normalization |
no_school_days | The denominator window has zero enrolled school days after calendar and enrollment intersection. | Alpha extension enum | aitd-011-policy-and-enum-normalization |
no_questions | The window has zero reportable question attempts, so accuracy_percent is null rather than guessed as 0 or 100. | Alpha extension enum | aitd-011-policy-and-enum-normalization |
no_enrollment | The student has no time-locatable enrollment for the requested range. | Alpha extension enum | aitd-011-policy-and-enum-normalization |
no_subject_assignment | The student had no subject assignment/course/test membership for the subject denominator. | Alpha extension enum | aitd-011-policy-and-enum-normalization |
source_missing | Required Event, Result, calendar, enrollment, or curriculum source evidence is missing. | Alpha extension enum | aitd-011-policy-and-enum-normalization |
source_unlinked | Source evidence exists but cannot be linked to platform ids under the current policy. | Alpha extension enum | aitd-011-policy-and-enum-normalization |
policy_pending | The named policy needed to compute the measure is missing or not active. | Alpha extension enum | aitd-011-policy-and-enum-normalization |
not_applicable | The metric does not apply at this grain, such as MAP growth for a non-MAP subject. | Alpha extension enum | aitd-011-policy-and-enum-normalization |
alpha.analytics_xp_rollup
Report-ready XP total plus goal progress fields. The goal fields use the same materialized school-day denominator as time commitment.
Architecture trace: aitd-007-xp-rollups, aitd-001-report-source-ingestion, aitd-004-provenance-no-literals, aitd-003-close-time-materialization, aitd-012-corrections-and-reversals
XPGET /alpha/analytics/v1/xp-rollupsExample Object Payload
Concrete reportable payload for this object. Required fields in the field list must appear here unless their nullability explicitly allows omission.
{
"id": "3f2b79e1-6182-4e21-a0b6-7d6cf7530003",
"tenant_id": "7b0bb5d8-9a38-4a62-9fdc-9f8d2dc1a111",
"student_id": "student_01HT7G3YZV7QB5N4YKQ1K0Z9A9",
"subject_id": "math",
"policy_ref": "alpha.policy.analytics.xp_goal_percent.v1",
"window_kind": "term",
"window_start": "2026-01-01",
"window_end": "2026-06-01",
"positive_xp": 11850,
"negative_xp": -50,
"xp_total": 11800,
"net_xp": 11800,
"daily_xp_goal": 100,
"enrolled_school_day_count": 90,
"xp_goal": 9000,
"xp_remaining": 0,
"xp_goal_percent": 131.111,
"xp_completion_percent": 131.111,
"on_track": true,
"award_count": 24,
"reversal_count": 1,
"source_import_id": "imp_01HT8XPTIME_2026_SPRING",
"source_ledger_refs": [
"xp_award_01HT7K"
],
"quality_status": "ok",
"null_reason": "none",
"calculation_version": 1,
"computed_at": "2026-06-01T01:02:00Z",
"modified_at": "2026-06-01T01:02:00Z",
"superseded_at": null,
"source_deleted_at": null
}
Lifecycle
Materialized when the timeback-xp-time-accuracy adapter ingests reporting.processed_facts, and refreshed when linked Results-owned xp_ledger rows close, correct, reverse, or import.
API Read Rule
For windowKind=range, term, or school_year with startDate and endDate, both dates must exactly match a producer-materialized window; the read never substitutes an overlapping row or recomputes one. A miss returns data: [] with meta.null_reason=no_exact_window, the requested_window, and bounded available_windows hints for the same tenant and filters.
Raw DB Rule
Raw readers use this table for XP report totals and goal status; they do not sum processed_facts.xp_earned, sum xp_ledger, recompute XP from expected_xp/accuracy, or fabricate the school-day denominator. Ordinary report rows carry stored goal fields; source_missing means repair/replay is required before the XP goal panel is complete.
Field Index
Fields
| Field | Type / Nullability | Meaning | Constraints / Range | Relationship | Invalid When | Example | Source / ITD |
|---|---|---|---|---|---|---|---|
id |
UUID required |
Analytics-owned stable row id for this derived fact. | Generated by the platform; globally unique within alpha.analytics_* objects. | Primary key for list/detail endpoints. | Provided by a public import client or reused across tenants. | 8e9c0ef2-bc75-4f53-8124-df77df49f25f |
Alpha extension aitd-000-extend-only-storage |
tenant_id |
UUID required |
Tenant boundary for the derived fact. | Set from the JWT tenant claim or internal materializer context; never accepted from request body/query. | All raw-path queries must filter by tenant_id before joining, sorting, paging, or counting. | Missing, caller-supplied in body/query, or mismatched with the JWT tenant claim. | 7b0bb5d8-9a38-4a62-9fdc-9f8d2dc1a111 |
Alpha extension aitd-109-axis-tenant-routing, aitd-106-axis-auth-shape |
student_id |
TEXT required |
Canonical Alpha student id the source Event or Result resolved to at materialization time. | Must resolve through People and Orgs as a real student for the source timestamp/effective date. | References People and Orgs student identity; see https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/data_dictionary. | Parsed from email/name/source payload instead of resolved by the Events/Results adapter. | student_01HT7G3YZV7QB5N4YKQ1K0Z9A9 |
Alpha extension reference aitd-003-close-time-materialization, aitd-106-axis-auth-shape, aitd-011-policy-and-enum-normalization |
subject_id |
TEXT nullable where the row is all-subject or the source cannot validly resolve a subject |
Canonical Alpha subject used for reporting and grouping. | Closed Alpha subject enum after write-time source-label normalization; unknown source subject becomes an adapter finding or null_reason, not a new string. | References the Curriculum/Results subject vocabulary; see https://platform3-andymontgomery-9773s-projects.vercel.app/curriculum/alpha/data_dictionary and https://platform3-andymontgomery-9773s-projects.vercel.app/results/alpha/data_dictionary. | Copied from source strings such as FastMath, Vocabulary, Science-notqced, or ISEE variants without normalization. | math |
Alpha extension reference aitd-011-policy-and-enum-normalization |
policy_ref |
TEXT required |
The rulebook version Analytics used; see Policy Reference on this page. Named policy/config version used to compute the measure or rollup. |
Must point at alpha.policy.analytics.* or an inherited Curriculum/Results policy active for the source effective date. | Many Analytics facts can share one policy row; changing policy creates new calculation versions or corrections. | A consumer hard-codes thresholds, school-day calendars, Growth X formulas, or completion denominators instead of using the policy ref. | alpha.policy.analytics.xp_goal_percent.v1 |
Alpha extension reference aitd-007-xp-rollups, aitd-006-school-day-minutes, aitd-011-policy-and-enum-normalization |
window_kind |
TEXT enum required |
Named window family for the XP rollup. | Allowed values: window_kind enum. | Part of XP rollup grain and list filters. | Parsed from report title or term label. | term |
Alpha extension aitd-007-xp-rollups, aitd-103-axis-query-model |
window_start |
DATE required |
Inclusive start date for included XP ledger effective dates. | ISO date; half-open with window_end. | Defines XP reporting period. | Uses computed_at instead of ledger effective date. | 2026-01-01 |
Alpha extension aitd-007-xp-rollups |
window_end |
DATE required |
Exclusive end date for included XP ledger effective dates. | ISO date; must be after window_start. | Defines XP reporting period. | Treated as inclusive in raw queries. | 2026-06-01 |
Alpha extension aitd-007-xp-rollups |
positive_xp |
NUMERIC(14,3) required |
Positive XP contribution subtotal retained for audit/explanation. | Nonnegative; normalized by the adapter/materializer, with Results xp_ledger refs when available. | References Results XP ledger source for audit where present; see https://platform3-andymontgomery-9773s-projects.vercel.app/results/alpha/data_dictionary#table-alpha-xp-ledger. | Computed by apps from accuracy, effort, expected_xp, or raw source rows. | 11850.000 |
Alpha extension aitd-007-xp-rollups |
negative_xp |
NUMERIC(14,3) required |
Sum of negative XP penalties/reversals in this rollup. | Zero or negative; gaming/cheating signals and reversals stay signed. | Explains why net_xp may be lower than positive_xp. | Dropped from reports or clamped to zero by consumers. | -50.000 |
Alpha extension aitd-007-xp-rollups, aitd-012-corrections-and-reversals |
xp_total |
NUMERIC(14,3) required |
The XP total the Learning Report should show. Policy-defined report XP total after the report-source adapter applies subject normalization, exclusions, corrections, and signed contributions. |
Non-null values require source_import_id provenance; should equal the report value for this student/subject/window. | The XP value dashboards render. | Recomputed from processed_facts, xp_ledger, expected_xp, accuracy, or effort by a report. | 11800.000 |
Alpha extension aitd-007-xp-rollups, aitd-001-report-source-ingestion, aitd-004-provenance-no-literals |
net_xp |
NUMERIC(14,3) required |
The signed audit total that explains awards, penalties, and reversals. Signed audit total after positive and negative XP contributions; equal to xp_total for ordinary report rows under the current policy. |
positive_xp + negative_xp under policy_ref; retained for correction/reversal reconciliation. | Explains how signed contributions reconcile to xp_total. | Used by a consumer instead of xp_total when the two diverge under a future policy. | 11800.000 |
Alpha extension aitd-007-xp-rollups, aitd-012-corrections-and-reversals |
xp_goal |
NUMERIC(14,3) required when null_reason=none; nullable only when enrolled_school_day_count or XP goal policy is missing |
The XP target for this report window. Window XP target for this student, subject, and window, used by the Learning Report XP Remaining and XP Goal Percent panels. |
Nonnegative when populated; equals daily_xp_goal multiplied by enrolled_school_day_count when both are present. Null requires a typed repair reason such as source_missing or policy_pending. | Lets reports show XP remaining without reading Curriculum trees or goal policy directly. | A report computes the goal from Content expected_xp, active dates, attendance days, raw calendar days, or hard-coded course sizes. | 9000.000 |
Alpha extension aitd-007-xp-rollups, aitd-006-school-day-minutes, aitd-011-policy-and-enum-normalization |
daily_xp_goal |
NUMERIC(14,3) nullable when daily XP policy is missing |
Daily XP target used in the auditor-pinned XP goal percent denominator. | Nonnegative; read from alpha.policy.analytics.xp_goal_percent.v1 / Curriculum Policy, never from a consumer constant. | Multiplied by enrolled_school_day_count to produce xp_goal. | Hard-coded in a report, skill pack, or import caller. | 100.000 |
Alpha extension policy reference value aitd-007-xp-rollups, aitd-006-school-day-minutes, aitd-011-policy-and-enum-normalization |
enrolled_school_day_count |
INTEGER required when null_reason=none; nullable only when school-day denominator source is missing |
Number of days in the XP percent denominator: days the student was enrolled and school was in session. | Nonnegative integer when populated. Enrollment begin/end bound the count; the student's school calendar governs it; MAP testing days are excluded; per-subject rows count only days with a subject assignment. Null requires a typed repair reason such as source_missing. | Same ratified denominator policy as alpha.analytics_school_day_minutes, reused for xp_goal_percent. | Computed from active dates, attendance rows, weekdays, or a current-only enrollment shortcut. | 90 |
Alpha extension policy reference value aitd-007-xp-rollups, aitd-006-school-day-minutes, aitd-011-policy-and-enum-normalization |
xp_remaining |
NUMERIC(14,3) required when null_reason=none; nullable when xp_goal is null/source_missing |
The XP still left after earned XP is applied to the target. Report-ready remaining XP under policy_ref. |
max(xp_goal - xp_total, 0) under policy_ref when xp_goal is present; stored by Analytics so reports do not subtract locally. Null requires a typed repair reason. | Displayed as XP Remaining in the Learning Report. | Negative, or recomputed by a dashboard after reading net_xp. | 0.000 |
Alpha extension aitd-007-xp-rollups, aitd-011-policy-and-enum-normalization |
xp_goal_percent |
NUMERIC(9,3) nullable when daily_xp_goal or enrolled_school_day_count is null or zero |
The uncapped XP percent the Learning Report should show. Uncapped percent of the XP goal reached in this window when the school-day denominator is available. |
Formula under alpha.policy.analytics.xp_goal_percent.v1 when populated: xp_total / (daily_xp_goal x enrolled_school_day_count) x 100. Values above 100 are valid and must remain visible. Null requires a typed repair reason. | Canonical Learning Report XP percent; xp_completion_percent, if present, is only a deprecated compatibility alias with the same value. | Capped at 100, named as a captured percent, recomputed by a report, or divided by a locally computed goal. | 131.111 |
Alpha extension aitd-007-xp-rollups, aitd-006-school-day-minutes, aitd-011-policy-and-enum-normalization |
xp_completion_percent |
NUMERIC(9,3) deprecated compatibility alias; nullability matches xp_goal_percent |
Deprecated alias for xp_goal_percent; same value when present. Deprecated compatibility alias for xp_goal_percent. |
Must equal xp_goal_percent exactly and remains uncapped. It has no independent capped-completion meaning. Nullability matches xp_goal_percent. | Kept only so older deployed consumers can migrate; new reports use xp_goal_percent. | Different from xp_goal_percent, capped at 100, or treated as course completion percent. | 131.111 |
Alpha extension aitd-007-xp-rollups, aitd-006-school-day-minutes, aitd-011-policy-and-enum-normalization |
on_track |
BOOLEAN nullable when xp_goal_percent is null |
Whether the student is on track against the XP goal policy for this window. | Computed under policy_ref; null means the goal policy or denominator is missing. | Report flag for XP-goal intervention workflows. | Client compares XP to a local threshold. | true |
Alpha extension aitd-007-xp-rollups, aitd-011-policy-and-enum-normalization |
award_count |
INTEGER required |
Number of positive or neutral XP ledger rows contributing to this rollup. | Nonnegative; excludes superseded rows unless audit query requests them. | Provenance summary for Results xp_ledger source rows. | Used as a count of attempts or Events. | 24 |
Alpha extension aitd-007-xp-rollups, aitd-102-axis-read-shape |
reversal_count |
INTEGER required |
Number of reversal/correction XP ledger rows included. | Nonnegative. | Audit signal for signed corrections. | Ignored when reconciling old source totals to current reports. | 1 |
Alpha extension aitd-007-xp-rollups, aitd-012-corrections-and-reversals |
source_ledger_refs |
JSONB required |
Compact ids/cursor for contributing Results xp_ledger rows. | Stores refs/hashes only; never copies scores, content expected_xp, or event payloads. | Supports /xp-rollups/{id}/source-refs for authorized audits. | Stores raw Results columns that belong to Results. | ["xp_award_01HT7K"] |
Alpha extension reference list aitd-000-extend-only-storage, aitd-007-xp-rollups, aitd-102-axis-read-shape |
source_import_id |
TEXT required for report-tile rows; nullable for purely derived event-axis rows |
Analytics source-import receipt that proves which named report-source adapter produced this report-grade fact. | Must reference alpha.analytics_source_import for non-null Learning Report tile values; no literal or fixture value may be reportable without this provenance. | Many report-fact rows can reference one source import; detail/sourceRefs endpoints join here for adapter, source_table, and source_row_key_hashes. | Missing on a non-null report-tile value, or replaced by copied raw reporting-DB columns. | imp_01HT8XPTIME_2026_SPRING |
Alpha extension provenance reference aitd-001-report-source-ingestion, aitd-004-provenance-no-literals, aitd-007-xp-rollups |
quality_status |
TEXT enum required |
Whether this row is reportable, corrected, reversed, blocked, or rejected. Current materialization quality state for this fact. |
Allowed values: quality_status enum. Ordinary report reads keep ok, corrected, and signed reversed rows according to the table rule; audit reads may include source_missing/source_unlinked/policy_pending/adapter_rejected. | Used by raw/API convergence filters and source-ref audit views. | Free-text status or hidden failures represented as HTTP 200 success. | ok |
Alpha extension aitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope, aitd-111-axis-privacy-retention |
null_reason |
TEXT enum required |
Why the report value is missing instead of asking an app to guess. Why XP goal fields are null or unavailable while xp_total itself may still be reportable. |
Allowed values: null_reason enum. none means xp_goal, xp_remaining, xp_goal_percent, and on_track are populated; source_missing means the shared school-day denominator source is absent and the goal fields are not reportable. | Uses the same materialized school-day denominator as alpha.analytics_school_day_minutes. | XP goal fields are null with no typed reason, or a consumer computes them anyway. | none |
Alpha extension enum aitd-007-xp-rollups, aitd-006-school-day-minutes, aitd-011-policy-and-enum-normalization |
calculation_version |
INTEGER required |
Materializer calculation version for this fact shape. | Positive integer; starts at 1 and increments when policy/materializer logic intentionally changes. | Part of deterministic source_fact_key/idempotency for materializer writes. | Omitted from replay keys or changed without a new policy/materializer decision. | 1 |
Alpha extension aitd-003-close-time-materialization, aitd-105-axis-idempotency, aitd-104-axis-concurrency |
computed_at |
TIMESTAMPTZ required |
When Analytics wrote this derived fact. | UTC timestamp with timezone; updated only by Analytics materializers. | Used for audit and source-ref subcollections, not for school-day grouping. | Used as a substitute for the source event time, result effective time, or window boundaries. | 2026-06-10T00:51:14Z |
Alpha extension aitd-003-close-time-materialization |
modified_at |
TIMESTAMPTZ required |
Last time the Analytics row changed for polling and modifiedSince queries. | UTC timestamp; list endpoints support modifiedSince against this field. | Supports poll plus modifiedSince eventing. | Client-supplied or used as the business effective date. | 2026-06-10T00:51:14Z |
Alpha extension aitd-107-axis-eventing, aitd-103-axis-query-model |
superseded_at |
TIMESTAMPTZ nullable |
When this row stopped being the current reportable version because of source correction, deletion, or recalculation. | Null means current; non-null rows are excluded from ordinary list reads unless includeSuperseded=true and authorized. | Preserves audit history without mutating source Events or Results. | Used to hard-delete old rows or omitted on a correction that replaces a prior fact. | null |
Alpha extension aitd-111-axis-privacy-retention, aitd-012-corrections-and-reversals |
source_deleted_at |
TIMESTAMPTZ nullable |
When the source Event/Result became deleted or invalidated. | Null for live source rows; set from source tombstone/correction notifications. | Ordinary reads exclude tombstoned facts unless includeSuperseded=true and authorized. | Used as a physical delete or ignored by raw-path report queries. | null |
Alpha extension aitd-111-axis-privacy-retention |
Enums Used Here
window_kind | |||
|---|---|---|---|
| Value | Meaning | Source | ITD |
day | A calendar day in the school timezone, represented as a half-open date range. | Alpha extension enum | aitd-005-time-facts-and-windows, aitd-103-axis-query-model, aitd-011-policy-and-enum-normalization |
week | A platform week under alpha.policy.analytics.window. | Alpha extension enum | aitd-005-time-facts-and-windows, aitd-103-axis-query-model, aitd-011-policy-and-enum-normalization |
term | An academic term from the People and Orgs academic-session calendar. | Alpha extension enum | aitd-005-time-facts-and-windows, aitd-103-axis-query-model, aitd-011-policy-and-enum-normalization |
school_year | A school-year window from the org academic-session calendar. | Alpha extension enum | aitd-005-time-facts-and-windows, aitd-103-axis-query-model, aitd-011-policy-and-enum-normalization |
custom | A caller-requested or migration reconciliation range with explicit start and end dates. | Alpha extension enum | aitd-005-time-facts-and-windows, aitd-103-axis-query-model, aitd-011-policy-and-enum-normalization |
quality_status | |||
|---|---|---|---|
| Value | Meaning | Source | ITD |
ok | The row is the current reportable fact for its key and policy. | Alpha extension enum | aitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope, aitd-111-axis-privacy-retention |
corrected | The row includes a correction contribution but remains reportable. | Alpha extension enum | aitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope, aitd-111-axis-privacy-retention |
reversed | The row reverses a prior contribution and should be read as signed history. | Alpha extension enum | aitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope, aitd-111-axis-privacy-retention |
source_missing | A required source row was removed or unavailable before the fact could be finalized. | Alpha extension enum | aitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope, aitd-111-axis-privacy-retention |
source_unlinked | The source row exists but could not link to a required Event, Result, student, subject, KC, course, or policy ref. | Alpha extension enum | aitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope, aitd-111-axis-privacy-retention |
policy_pending | A required policy configuration was missing or not yet active at materialization time. | Alpha extension enum | aitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope, aitd-111-axis-privacy-retention |
adapter_rejected | The source-shaped row was valid input but the server-side adapter rejected it with a typed Problem. | Alpha extension enum | aitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope, aitd-111-axis-privacy-retention |
null_reason | |||
|---|---|---|---|
| Value | Meaning | Source | ITD |
none | No null-producing condition applies. | Alpha extension enum | aitd-011-policy-and-enum-normalization |
no_school_days | The denominator window has zero enrolled school days after calendar and enrollment intersection. | Alpha extension enum | aitd-011-policy-and-enum-normalization |
no_questions | The window has zero reportable question attempts, so accuracy_percent is null rather than guessed as 0 or 100. | Alpha extension enum | aitd-011-policy-and-enum-normalization |
no_enrollment | The student has no time-locatable enrollment for the requested range. | Alpha extension enum | aitd-011-policy-and-enum-normalization |
no_subject_assignment | The student had no subject assignment/course/test membership for the subject denominator. | Alpha extension enum | aitd-011-policy-and-enum-normalization |
source_missing | Required Event, Result, calendar, enrollment, or curriculum source evidence is missing. | Alpha extension enum | aitd-011-policy-and-enum-normalization |
source_unlinked | Source evidence exists but cannot be linked to platform ids under the current policy. | Alpha extension enum | aitd-011-policy-and-enum-normalization |
policy_pending | The named policy needed to compute the measure is missing or not active. | Alpha extension enum | aitd-011-policy-and-enum-normalization |
not_applicable | The metric does not apply at this grain, such as MAP growth for a non-MAP subject. | Alpha extension enum | aitd-011-policy-and-enum-normalization |
alpha.analytics_accuracy
Report-ready Accuracy panel facts: correct questions, total questions, incorrect questions, and percent correct without client-side processed_facts math.
Architecture trace: aitd-001-report-source-ingestion, aitd-004-provenance-no-literals, aitd-011-policy-and-enum-normalization, aitd-003-close-time-materialization, aitd-012-corrections-and-reversals
Learning Report accuracyGET /alpha/analytics/v1/accuracy-rollupsExample Object Payload
Concrete reportable payload for this object. Required fields in the field list must appear here unless their nullability explicitly allows omission.
{
"id": "9c3f3e4f-1fd8-4c28-8a72-cbbf2e6d0006",
"tenant_id": "7b0bb5d8-9a38-4a62-9fdc-9f8d2dc1a111",
"student_id": "student_01HT7G3YZV7QB5N4YKQ1K0Z9A9",
"subject_id": "math",
"policy_ref": "alpha.policy.analytics.accuracy.v2026-06-12",
"window_kind": "term",
"window_start": "2026-01-01",
"window_end": "2026-06-01",
"correct_question_count": 480,
"total_question_count": 600,
"incorrect_question_count": 120,
"accuracy_percent": 80,
"source_import_id": "imp_01HT8XPTIME_2026_SPRING",
"source_fact_refs": [
"processed_facts_hash_01HT7Q"
],
"quality_status": "ok",
"null_reason": "none",
"calculation_version": 1,
"computed_at": "2026-06-01T01:02:30Z",
"modified_at": "2026-06-01T01:02:30Z",
"superseded_at": null,
"source_deleted_at": null
}
Lifecycle
Docs-first contract for this wave: the implementation cell adds the materializer and /accuracy-rollups endpoint. Once live, rows are materialized when the timeback-xp-time-accuracy adapter ingests reporting.processed_facts and refreshed when accepted source rows correct, reverse, delete, or replay. The table, field, endpoint, and raw-query contract are final in this dictionary; live-render evidence belongs to the implementation/integration cells, not this preceding dictionary cell.
Raw DB Rule
Raw readers use this table for Accuracy panel values; they do not sum reporting.processed_facts.total_questions/correct_questions, maintain app/source allowlists, or divide locally.
Formula
accuracy_percent = round((correct_question_count / total_question_count) * 100, 3) when total_question_count > 0 and null_reason=none. If total_question_count is zero, accuracy_percent is null with null_reason=no_questions.
Field Index
Fields
| Field | Type / Nullability | Meaning | Constraints / Range | Relationship | Invalid When | Example | Source / ITD |
|---|---|---|---|---|---|---|---|
id |
UUID required |
Analytics-owned stable row id for this derived fact. | Generated by the platform; globally unique within alpha.analytics_* objects. | Primary key for list/detail endpoints. | Provided by a public import client or reused across tenants. | 8e9c0ef2-bc75-4f53-8124-df77df49f25f |
Alpha extension aitd-000-extend-only-storage |
tenant_id |
UUID required |
Tenant boundary for the derived fact. | Set from the JWT tenant claim or internal materializer context; never accepted from request body/query. | All raw-path queries must filter by tenant_id before joining, sorting, paging, or counting. | Missing, caller-supplied in body/query, or mismatched with the JWT tenant claim. | 7b0bb5d8-9a38-4a62-9fdc-9f8d2dc1a111 |
Alpha extension aitd-109-axis-tenant-routing, aitd-106-axis-auth-shape |
student_id |
TEXT required |
Canonical Alpha student id the source Event or Result resolved to at materialization time. | Must resolve through People and Orgs as a real student for the source timestamp/effective date. | References People and Orgs student identity; see https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/data_dictionary. | Parsed from email/name/source payload instead of resolved by the Events/Results adapter. | student_01HT7G3YZV7QB5N4YKQ1K0Z9A9 |
Alpha extension reference aitd-003-close-time-materialization, aitd-106-axis-auth-shape, aitd-011-policy-and-enum-normalization |
subject_id |
TEXT nullable where the row is all-subject or the source cannot validly resolve a subject |
Canonical Alpha subject used for reporting and grouping. | Closed Alpha subject enum after write-time source-label normalization; unknown source subject becomes an adapter finding or null_reason, not a new string. | References the Curriculum/Results subject vocabulary; see https://platform3-andymontgomery-9773s-projects.vercel.app/curriculum/alpha/data_dictionary and https://platform3-andymontgomery-9773s-projects.vercel.app/results/alpha/data_dictionary. | Copied from source strings such as FastMath, Vocabulary, Science-notqced, or ISEE variants without normalization. | math |
Alpha extension reference aitd-011-policy-and-enum-normalization |
policy_ref |
TEXT required |
The rulebook version Analytics used; see Policy Reference on this page. Named policy/config version used to compute the measure or rollup. |
Must point at alpha.policy.analytics.* or an inherited Curriculum/Results policy active for the source effective date. | Many Analytics facts can share one policy row; changing policy creates new calculation versions or corrections. | A consumer hard-codes thresholds, school-day calendars, Growth X formulas, or completion denominators instead of using the policy ref. | alpha.policy.analytics.accuracy.v2026-06-12 |
Alpha extension reference aitd-001-report-source-ingestion, aitd-011-policy-and-enum-normalization |
window_kind |
TEXT enum required |
Named window family for the Accuracy rollup. | Allowed values: window_kind enum. | Part of Accuracy rollup grain and list filters. | Parsed from report title or term label. | term |
Alpha extension aitd-103-axis-query-model, aitd-011-policy-and-enum-normalization |
window_start |
DATE required |
Inclusive start date for source question rows included in this rollup. | ISO date; half-open with window_end. | Defines the reporting period for the Accuracy panel. | Uses computed_at instead of the source/report effective date. | 2026-01-01 |
Alpha extension aitd-005-time-facts-and-windows, aitd-001-report-source-ingestion |
window_end |
DATE required |
Exclusive end date for source question rows included in this rollup. | ISO date; must be after window_start. | Defines the reporting period for the Accuracy panel. | Treated as inclusive in raw queries. | 2026-06-01 |
Alpha extension aitd-005-time-facts-and-windows, aitd-001-report-source-ingestion |
correct_question_count |
INTEGER required |
How many reportable questions your child answered correctly. Reportable correct-question numerator after the adapter applies subject, app/source, score_type, correction, and real-student rules. |
Nonnegative integer; cannot exceed total_question_count when total_question_count is present. Normalized from source-shaped reporting.processed_facts.correct_questions, not read by reports from the source table. | Numerator for accuracy_percent. | Summed by a consumer from reporting.processed_facts or copied as raw source rows without source_import_id provenance. | 480 |
Alpha extension derived rollup value aitd-001-report-source-ingestion, aitd-004-provenance-no-literals, aitd-011-policy-and-enum-normalization |
total_question_count |
INTEGER required |
How many reportable questions counted in the Accuracy denominator. Reportable question-attempt denominator after the adapter applies the same policy filters as correct_question_count. |
Nonnegative integer. Zero is allowed only with null_reason=no_questions and null accuracy_percent. | Denominator for accuracy_percent. | Computed by counting Events, QTI attempts, or processed_facts rows in a report. | 600 |
Alpha extension derived rollup value aitd-001-report-source-ingestion, aitd-004-provenance-no-literals, aitd-011-policy-and-enum-normalization |
incorrect_question_count |
INTEGER required |
How many reportable questions were not correct. Reportable incorrect-question count retained for explanations. |
Nonnegative integer; equals total_question_count - correct_question_count under the policy version. | Audit/explanation value for parent-facing Accuracy cards. | Calculated differently by the client or allowed to go negative. | 120 |
Alpha extension derived rollup value aitd-001-report-source-ingestion, aitd-011-policy-and-enum-normalization |
accuracy_percent |
NUMERIC(9,3) nullable when total_question_count is zero or source/policy is missing |
The percent-correct number the Learning Report should show. Report-ready percent of reportable questions answered correctly. |
0 through 100 when populated; null requires a typed null_reason. Formula and rounding are owned by Analytics under policy_ref. | The Learning Report Accuracy panel reads this value directly. | A dashboard divides correct_question_count by total_question_count itself, rounds differently, or substitutes 0/100 when there are no questions. | 80.000 |
Alpha extension derived measure aitd-001-report-source-ingestion, aitd-011-policy-and-enum-normalization |
source_import_id |
TEXT required for report-tile rows; nullable for purely derived event-axis rows |
Analytics source-import receipt that proves which named report-source adapter produced this report-grade fact. | Must reference alpha.analytics_source_import for non-null Learning Report tile values; no literal or fixture value may be reportable without this provenance. | Many report-fact rows can reference one source import; detail/sourceRefs endpoints join here for adapter, source_table, and source_row_key_hashes. | Missing on a non-null report-tile value, or replaced by copied raw reporting-DB columns. | imp_01HT8XPTIME_2026_SPRING |
Alpha extension provenance reference aitd-001-report-source-ingestion, aitd-004-provenance-no-literals |
source_fact_refs |
JSONB required |
Compact ids/hashes/cursor for source-shaped processed_facts rows accepted by the adapter. | Stores refs/hashes only; never copies raw processed_facts rows or student identifiers. | Supports /accuracy-rollups/{id}/source-refs for authorized audits. | Contains raw source table columns or enough payload to become a copied reporting table. | ["processed_facts_hash_01HT7Q"] |
Alpha extension reference list aitd-000-extend-only-storage, aitd-001-report-source-ingestion, aitd-102-axis-read-shape |
quality_status |
TEXT enum required |
Whether this row is reportable, corrected, reversed, blocked, or rejected. Current materialization quality state for this fact. |
Allowed values: quality_status enum. Ordinary report reads keep ok, corrected, and signed reversed rows according to the table rule; audit reads may include source_missing/source_unlinked/policy_pending/adapter_rejected. | Used by raw/API convergence filters and source-ref audit views. | Free-text status or hidden failures represented as HTTP 200 success. | ok |
Alpha extension aitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope, aitd-111-axis-privacy-retention |
null_reason |
TEXT enum required |
Why the report value is missing instead of asking an app to guess. Why accuracy_percent is null or not reportable. |
Allowed values: null_reason enum. no_questions means the source window had zero reportable question attempts; none means the metric is populated. | Prevents clients from turning no attempts into 0% or 100%. | Null accuracy_percent with no typed reason, or a free-text explanation. | none |
Alpha extension enum aitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope |
calculation_version |
INTEGER required |
Materializer calculation version for this fact shape. | Positive integer; starts at 1 and increments when policy/materializer logic intentionally changes. | Part of deterministic source_fact_key/idempotency for materializer writes. | Omitted from replay keys or changed without a new policy/materializer decision. | 1 |
Alpha extension aitd-003-close-time-materialization, aitd-105-axis-idempotency, aitd-104-axis-concurrency |
computed_at |
TIMESTAMPTZ required |
When Analytics wrote this derived fact. | UTC timestamp with timezone; updated only by Analytics materializers. | Used for audit and source-ref subcollections, not for school-day grouping. | Used as a substitute for the source event time, result effective time, or window boundaries. | 2026-06-10T00:51:14Z |
Alpha extension aitd-003-close-time-materialization |
modified_at |
TIMESTAMPTZ required |
Last time the Analytics row changed for polling and modifiedSince queries. | UTC timestamp; list endpoints support modifiedSince against this field. | Supports poll plus modifiedSince eventing. | Client-supplied or used as the business effective date. | 2026-06-10T00:51:14Z |
Alpha extension aitd-107-axis-eventing, aitd-103-axis-query-model |
superseded_at |
TIMESTAMPTZ nullable |
When this row stopped being the current reportable version because of source correction, deletion, or recalculation. | Null means current; non-null rows are excluded from ordinary list reads unless includeSuperseded=true and authorized. | Preserves audit history without mutating source Events or Results. | Used to hard-delete old rows or omitted on a correction that replaces a prior fact. | null |
Alpha extension aitd-111-axis-privacy-retention, aitd-012-corrections-and-reversals |
source_deleted_at |
TIMESTAMPTZ nullable |
When the source Event/Result became deleted or invalidated. | Null for live source rows; set from source tombstone/correction notifications. | Ordinary reads exclude tombstoned facts unless includeSuperseded=true and authorized. | Used as a physical delete or ignored by raw-path report queries. | null |
Alpha extension aitd-111-axis-privacy-retention |
Enums Used Here
window_kind | |||
|---|---|---|---|
| Value | Meaning | Source | ITD |
day | A calendar day in the school timezone, represented as a half-open date range. | Alpha extension enum | aitd-005-time-facts-and-windows, aitd-103-axis-query-model, aitd-011-policy-and-enum-normalization |
week | A platform week under alpha.policy.analytics.window. | Alpha extension enum | aitd-005-time-facts-and-windows, aitd-103-axis-query-model, aitd-011-policy-and-enum-normalization |
term | An academic term from the People and Orgs academic-session calendar. | Alpha extension enum | aitd-005-time-facts-and-windows, aitd-103-axis-query-model, aitd-011-policy-and-enum-normalization |
school_year | A school-year window from the org academic-session calendar. | Alpha extension enum | aitd-005-time-facts-and-windows, aitd-103-axis-query-model, aitd-011-policy-and-enum-normalization |
custom | A caller-requested or migration reconciliation range with explicit start and end dates. | Alpha extension enum | aitd-005-time-facts-and-windows, aitd-103-axis-query-model, aitd-011-policy-and-enum-normalization |
quality_status | |||
|---|---|---|---|
| Value | Meaning | Source | ITD |
ok | The row is the current reportable fact for its key and policy. | Alpha extension enum | aitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope, aitd-111-axis-privacy-retention |
corrected | The row includes a correction contribution but remains reportable. | Alpha extension enum | aitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope, aitd-111-axis-privacy-retention |
reversed | The row reverses a prior contribution and should be read as signed history. | Alpha extension enum | aitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope, aitd-111-axis-privacy-retention |
source_missing | A required source row was removed or unavailable before the fact could be finalized. | Alpha extension enum | aitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope, aitd-111-axis-privacy-retention |
source_unlinked | The source row exists but could not link to a required Event, Result, student, subject, KC, course, or policy ref. | Alpha extension enum | aitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope, aitd-111-axis-privacy-retention |
policy_pending | A required policy configuration was missing or not yet active at materialization time. | Alpha extension enum | aitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope, aitd-111-axis-privacy-retention |
adapter_rejected | The source-shaped row was valid input but the server-side adapter rejected it with a typed Problem. | Alpha extension enum | aitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope, aitd-111-axis-privacy-retention |
null_reason | |||
|---|---|---|---|
| Value | Meaning | Source | ITD |
none | No null-producing condition applies. | Alpha extension enum | aitd-011-policy-and-enum-normalization |
no_school_days | The denominator window has zero enrolled school days after calendar and enrollment intersection. | Alpha extension enum | aitd-011-policy-and-enum-normalization |
no_questions | The window has zero reportable question attempts, so accuracy_percent is null rather than guessed as 0 or 100. | Alpha extension enum | aitd-011-policy-and-enum-normalization |
no_enrollment | The student has no time-locatable enrollment for the requested range. | Alpha extension enum | aitd-011-policy-and-enum-normalization |
no_subject_assignment | The student had no subject assignment/course/test membership for the subject denominator. | Alpha extension enum | aitd-011-policy-and-enum-normalization |
source_missing | Required Event, Result, calendar, enrollment, or curriculum source evidence is missing. | Alpha extension enum | aitd-011-policy-and-enum-normalization |
source_unlinked | Source evidence exists but cannot be linked to platform ids under the current policy. | Alpha extension enum | aitd-011-policy-and-enum-normalization |
policy_pending | The named policy needed to compute the measure is missing or not active. | Alpha extension enum | aitd-011-policy-and-enum-normalization |
not_applicable | The metric does not apply at this grain, such as MAP growth for a non-MAP subject. | Alpha extension enum | aitd-011-policy-and-enum-normalization |
alpha.analytics_mastery_delta
Grade Levels Mastered facts for the Learning Report plus a typed change log of mastery state movements; Results remains the current mastery state of record.
Architecture trace: aitd-008-mastery-and-grade-levels, aitd-001-report-source-ingestion, aitd-004-provenance-no-literals, aitd-003-close-time-materialization, aitd-011-policy-and-enum-normalization
mastery|student_kc_stateGET /alpha/analytics/v1/mastery-deltasExample Object Payload
Concrete reportable payload for this object. Required fields in the field list must appear here unless their nullability explicitly allows omission.
{
"id": "4e9268b7-e76a-46d9-9b6e-899aa2df0004",
"tenant_id": "7b0bb5d8-9a38-4a62-9fdc-9f8d2dc1a111",
"student_id": "student_01HT7G3YZV7QB5N4YKQ1K0Z9A9",
"kc_id": "kc_math_fraction_addition_unlike_denominators",
"grade_subject": "math",
"grade_level": 5,
"completed_on": "2026-05-14",
"source_import_id": "imp_01HT8GRADE_2026_SPRING",
"source_state_ref": "student_kc_state_01HT7K7S9Q",
"source_result_refs": [
"result_01HT7K8BR3",
"result_kc_evidence_01HT7K8BR3_KC"
],
"state_dimension": "durable_mastery",
"effective_at": "2026-05-14T18:45:00Z",
"previous_value": {
"value": 0.82
},
"new_value": {
"value": 0.91
},
"delta_value": 0.09,
"transition_kind": "acquired",
"policy_ref": "alpha.policy.results.mastery_state.v2026-06-10",
"quality_status": "ok",
"calculation_version": 1,
"computed_at": "2026-05-14T18:45:04Z",
"modified_at": "2026-05-14T18:45:04Z",
"superseded_at": null,
"source_deleted_at": null
}
Lifecycle
Written when the timeback-grade-mastery adapter ingests reporting.assessment_results passed gates, or when Results student_kc_state changes or historical mastery evidence is imported/replayed.
Raw DB Rule
Raw readers query mastery_delta by effective_at/state_dimension; they do not recompute mastery, decay, HMG, or due dates from attempts.
Field Index
Fields
| Field | Type / Nullability | Meaning | Constraints / Range | Relationship | Invalid When | Example | Source / ITD |
|---|---|---|---|---|---|---|---|
id |
UUID required |
Analytics-owned stable row id for this derived fact. | Generated by the platform; globally unique within alpha.analytics_* objects. | Primary key for list/detail endpoints. | Provided by a public import client or reused across tenants. | 8e9c0ef2-bc75-4f53-8124-df77df49f25f |
Alpha extension aitd-000-extend-only-storage |
tenant_id |
UUID required |
Tenant boundary for the derived fact. | Set from the JWT tenant claim or internal materializer context; never accepted from request body/query. | All raw-path queries must filter by tenant_id before joining, sorting, paging, or counting. | Missing, caller-supplied in body/query, or mismatched with the JWT tenant claim. | 7b0bb5d8-9a38-4a62-9fdc-9f8d2dc1a111 |
Alpha extension aitd-109-axis-tenant-routing, aitd-106-axis-auth-shape |
student_id |
TEXT required |
Canonical Alpha student id the source Event or Result resolved to at materialization time. | Must resolve through People and Orgs as a real student for the source timestamp/effective date. | References People and Orgs student identity; see https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/data_dictionary. | Parsed from email/name/source payload instead of resolved by the Events/Results adapter. | student_01HT7G3YZV7QB5N4YKQ1K0Z9A9 |
Alpha extension reference aitd-003-close-time-materialization, aitd-106-axis-auth-shape, aitd-011-policy-and-enum-normalization |
kc_id |
TEXT nullable when the row is a grade-level mastered fact without a single KC |
Knowledge Component whose student state changed. | Must reference a Curriculum KC; never a standard or lesson id. | References Curriculum KC tree; see https://platform3-andymontgomery-9773s-projects.vercel.app/curriculum/alpha/data_dictionary. | Points to a standard, lesson, content item, or parsed source course string. | kc_math_fraction_addition_unlike_denominators |
Alpha extension reference aitd-008-mastery-and-grade-levels |
grade_subject |
TEXT enum nullable except grade-level mastered rows |
Subject for a Grade Levels Mastered row shown in the Learning Report. | Closed Alpha subject enum after write-time normalization; required when grade_level/completed_on are populated. | Ingested from reporting.assessment_results through the timeback-grade-mastery adapter. | Parsed by a report from assessment names or display text. | math |
Alpha extension aitd-008-mastery-and-grade-levels, aitd-001-report-source-ingestion, aitd-011-policy-and-enum-normalization |
grade_level |
INTEGER nullable except grade-level mastered rows |
Grade level the student has mastered in the subject. | Positive integer; set by the grade-mastery adapter from passed gate/assessment evidence. | Learning Report Grade Levels Mastered tile reads this field with grade_subject and completed_on. | Computed by a dashboard from current grade, MAP RIT, or a course name. | 5 |
Alpha extension aitd-008-mastery-and-grade-levels, aitd-001-report-source-ingestion |
completed_on |
DATE nullable except grade-level mastered rows |
Date the grade-level mastery fact became effective for reporting. | ISO date derived from the source assessment/gate completion date. | Used to order Grade Levels Mastered entries in Learning Reports. | Filled from Analytics computed_at or import time. | 2026-05-14 |
Alpha extension aitd-008-mastery-and-grade-levels, aitd-001-report-source-ingestion |
source_state_ref |
TEXT nullable for grade-level mastered rows; required for Results state-delta rows |
Results student_kc_state row/version this delta derives from. | Must reference Results state or ledger evidence in same tenant. | References Results current state/history; see https://platform3-andymontgomery-9773s-projects.vercel.app/results/alpha/data_dictionary#table-alpha-student-kc-state. | Analytics becomes the authoritative mastery state or stores state without source ref. | student_kc_state_01HT7K7S9Q |
Alpha extension reference aitd-000-extend-only-storage, aitd-008-mastery-and-grade-levels |
source_result_refs |
JSONB required |
Result/evidence ids that caused or explain the state transition or grade-level mastery fact. | Stores ids/hashes only; no raw scored payload copies. | Links back to result_record/result_kc_evidence or imported assessment_results source refs for audit. | Contains copied response bodies, raw attempts, or mastery math inputs for client recomputation. | ["result_01HT7K8BR3"] |
Alpha extension reference list aitd-000-extend-only-storage, aitd-008-mastery-and-grade-levels, aitd-102-axis-read-shape |
state_dimension |
TEXT enum required |
Which Results mastery-state dimension changed. | Allowed values: state_dimension enum. | Part of the delta grain and filter model. | Free-text state labels or dashboard-specific columns. | durable_mastery |
Alpha extension aitd-008-mastery-and-grade-levels, aitd-011-policy-and-enum-normalization |
effective_at |
TIMESTAMPTZ required |
When the state transition is effective for as-of reporting. | UTC timestamp; comes from Results state transition, not Analytics computed_at. | Raw/API answer to "what changed between A and B" filters this field. | Substituted with computed_at or source import time. | 2026-05-14T18:45:00Z |
Alpha extension aitd-008-mastery-and-grade-levels |
previous_value |
JSONB nullable |
Typed previous value for the changed state dimension. | JSON shape must match state_dimension; null allowed for first known state. | Used for report explanations; not for recomputing Results state. | Unstructured notes or mixed units without state_dimension shape. | {"value":0.82} |
Alpha extension aitd-008-mastery-and-grade-levels |
new_value |
JSONB required |
Typed new value for the changed state dimension. | JSON shape must match state_dimension. | Report-ready delta endpoint output. | Consumer has to fetch Results and calculate the value itself. | {"value":0.91} |
Alpha extension aitd-008-mastery-and-grade-levels |
delta_value |
NUMERIC(12,6) nullable |
Numeric difference where the state dimension has a numeric value. | Null for non-numeric dimensions such as next_due_at or fluency_state. | Used for sorting and report summaries. | Invented for categorical dimensions without policy meaning. | 0.090000 |
Alpha extension aitd-008-mastery-and-grade-levels |
transition_kind |
TEXT enum required |
A plain category for what changed in mastery. Human-readable category of the state transition. |
Allowed values: acquired, improved, decayed, review_due, fluency_changed, corrected, blocked. Set by Results/Analytics materializer policy; reports group by this value instead of classifying attempts. | Lets reports group deltas without client-side classifiers. | Classified by a dashboard from score percentages or attempt names. | acquired |
Alpha extension aitd-008-mastery-and-grade-levels, aitd-011-policy-and-enum-normalization |
source_import_id |
TEXT required for report-tile rows; nullable for purely derived event-axis rows |
Analytics source-import receipt that proves which named report-source adapter produced this report-grade fact. | Must reference alpha.analytics_source_import for non-null Learning Report tile values; no literal or fixture value may be reportable without this provenance. | Many report-fact rows can reference one source import; detail/sourceRefs endpoints join here for adapter, source_table, and source_row_key_hashes. | Missing on a non-null report-tile value, or replaced by copied raw reporting-DB columns. | imp_01HT8GRADE_2026_SPRING |
Alpha extension provenance reference aitd-001-report-source-ingestion, aitd-004-provenance-no-literals, aitd-008-mastery-and-grade-levels |
policy_ref |
TEXT required |
The rulebook version Analytics used; see Policy Reference on this page. Named policy/config version used to compute the measure or rollup. |
Must point at alpha.policy.analytics.* or an inherited Curriculum/Results policy active for the source effective date. | Many Analytics facts can share one policy row; changing policy creates new calculation versions or corrections. | A consumer hard-codes thresholds, school-day calendars, Growth X formulas, or completion denominators instead of using the policy ref. | alpha.policy.results.mastery_state.v2026-06-10 |
Alpha extension reference aitd-008-mastery-and-grade-levels, aitd-011-policy-and-enum-normalization |
quality_status |
TEXT enum required |
Whether this row is reportable, corrected, reversed, blocked, or rejected. Current materialization quality state for this fact. |
Allowed values: quality_status enum. Ordinary report reads keep ok, corrected, and signed reversed rows according to the table rule; audit reads may include source_missing/source_unlinked/policy_pending/adapter_rejected. | Used by raw/API convergence filters and source-ref audit views. | Free-text status or hidden failures represented as HTTP 200 success. | ok |
Alpha extension aitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope, aitd-111-axis-privacy-retention |
calculation_version |
INTEGER required |
Materializer calculation version for this fact shape. | Positive integer; starts at 1 and increments when policy/materializer logic intentionally changes. | Part of deterministic source_fact_key/idempotency for materializer writes. | Omitted from replay keys or changed without a new policy/materializer decision. | 1 |
Alpha extension aitd-003-close-time-materialization, aitd-105-axis-idempotency, aitd-104-axis-concurrency |
computed_at |
TIMESTAMPTZ required |
When Analytics wrote this derived fact. | UTC timestamp with timezone; updated only by Analytics materializers. | Used for audit and source-ref subcollections, not for school-day grouping. | Used as a substitute for the source event time, result effective time, or window boundaries. | 2026-06-10T00:51:14Z |
Alpha extension aitd-003-close-time-materialization |
modified_at |
TIMESTAMPTZ required |
Last time the Analytics row changed for polling and modifiedSince queries. | UTC timestamp; list endpoints support modifiedSince against this field. | Supports poll plus modifiedSince eventing. | Client-supplied or used as the business effective date. | 2026-06-10T00:51:14Z |
Alpha extension aitd-107-axis-eventing, aitd-103-axis-query-model |
superseded_at |
TIMESTAMPTZ nullable |
When this row stopped being the current reportable version because of source correction, deletion, or recalculation. | Null means current; non-null rows are excluded from ordinary list reads unless includeSuperseded=true and authorized. | Preserves audit history without mutating source Events or Results. | Used to hard-delete old rows or omitted on a correction that replaces a prior fact. | null |
Alpha extension aitd-111-axis-privacy-retention, aitd-012-corrections-and-reversals |
source_deleted_at |
TIMESTAMPTZ nullable |
When the source Event/Result became deleted or invalidated. | Null for live source rows; set from source tombstone/correction notifications. | Ordinary reads exclude tombstoned facts unless includeSuperseded=true and authorized. | Used as a physical delete or ignored by raw-path report queries. | null |
Alpha extension aitd-111-axis-privacy-retention |
Enums Used Here
subject_id | |||
|---|---|---|---|
| Value | Meaning | Source | ITD |
math | Math subject rollups and MAP/math source-label normalization. | Alpha/Curriculum governed enum | aitd-011-policy-and-enum-normalization |
reading | Reading subject rollups. | Alpha/Curriculum governed enum | aitd-011-policy-and-enum-normalization |
language | Language / ELA subject rollups. Public reads keep vocabulary and writing as distinct canonical subjects. | Alpha/Curriculum governed enum | aitd-011-policy-and-enum-normalization |
science | Science subject rollups. | Alpha/Curriculum governed enum | aitd-011-policy-and-enum-normalization |
vocabulary | Vocabulary activity rollups as the canonical vocabulary subject. | Alpha/Curriculum governed enum | aitd-011-policy-and-enum-normalization |
writing | Writing activity rollups as the canonical writing subject. | Alpha/Curriculum governed enum | aitd-011-policy-and-enum-normalization |
state_dimension | |||
|---|---|---|---|
| Value | Meaning | Source | ITD |
initial_mastery | The acquisition/mastery signal changed for the KC. | Alpha extension enum | aitd-008-mastery-and-grade-levels, aitd-011-policy-and-enum-normalization |
current_retention | The retained mastery value changed under the Results retention policy. | Alpha extension enum | aitd-008-mastery-and-grade-levels, aitd-011-policy-and-enum-normalization |
durable_mastery | The durable mastery state changed. | Alpha extension enum | aitd-008-mastery-and-grade-levels, aitd-011-policy-and-enum-normalization |
fluency_state | The fluency/automaticity state changed. | Alpha extension enum | aitd-008-mastery-and-grade-levels, aitd-011-policy-and-enum-normalization |
next_due_at | The next review or practice due date changed. | Alpha extension enum | aitd-008-mastery-and-grade-levels, aitd-011-policy-and-enum-normalization |
transition_kind | |||
|---|---|---|---|
| Value | Meaning | Source | ITD |
acquired | The student crossed into mastery/acquisition for the KC. | Alpha extension enum | aitd-008-mastery-and-grade-levels, aitd-011-policy-and-enum-normalization |
improved | The state value increased but did not represent first acquisition. | Alpha extension enum | aitd-008-mastery-and-grade-levels, aitd-011-policy-and-enum-normalization |
decayed | The value decreased under Results retention state. | Alpha extension enum | aitd-008-mastery-and-grade-levels, aitd-011-policy-and-enum-normalization |
review_due | The due-date dimension moved into a new due state. | Alpha extension enum | aitd-008-mastery-and-grade-levels, aitd-011-policy-and-enum-normalization |
fluency_changed | The fluency dimension changed. | Alpha extension enum | aitd-008-mastery-and-grade-levels, aitd-011-policy-and-enum-normalization |
corrected | The transition reflects a source correction or migration repair. | Alpha extension enum | aitd-008-mastery-and-grade-levels, aitd-011-policy-and-enum-normalization |
blocked | A required source or policy row was missing, so the state change is blocked. | Alpha extension enum | aitd-008-mastery-and-grade-levels, aitd-011-policy-and-enum-normalization |
quality_status | |||
|---|---|---|---|
| Value | Meaning | Source | ITD |
ok | The row is the current reportable fact for its key and policy. | Alpha extension enum | aitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope, aitd-111-axis-privacy-retention |
corrected | The row includes a correction contribution but remains reportable. | Alpha extension enum | aitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope, aitd-111-axis-privacy-retention |
reversed | The row reverses a prior contribution and should be read as signed history. | Alpha extension enum | aitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope, aitd-111-axis-privacy-retention |
source_missing | A required source row was removed or unavailable before the fact could be finalized. | Alpha extension enum | aitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope, aitd-111-axis-privacy-retention |
source_unlinked | The source row exists but could not link to a required Event, Result, student, subject, KC, course, or policy ref. | Alpha extension enum | aitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope, aitd-111-axis-privacy-retention |
policy_pending | A required policy configuration was missing or not yet active at materialization time. | Alpha extension enum | aitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope, aitd-111-axis-privacy-retention |
adapter_rejected | The source-shaped row was valid input but the server-side adapter rejected it with a typed Problem. | Alpha extension enum | aitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope, aitd-111-axis-privacy-retention |
alpha.analytics_map_growth_rollup
Report-ready RIT, achievement percentile, growth percentile, Growth X, MAP window, sitting-count, retake, and on-track facts without client-side norms tables, sitting selection, or term parsing.
Architecture trace: aitd-009-map-growth-rollups, aitd-001-report-source-ingestion, aitd-004-provenance-no-literals, aitd-003-close-time-materialization, aitd-011-policy-and-enum-normalization
RIT|GrowthX|MAP growth windows MAP sittings/scoresGET /alpha/analytics/v1/map-growth-rollupsExample Object Payload
Concrete reportable payload for this object. Required fields in the field list must appear here unless their nullability explicitly allows omission.
{
"id": "5a41fb2a-5d08-45fd-a62b-58a518060005",
"tenant_id": "7b0bb5d8-9a38-4a62-9fdc-9f8d2dc1a111",
"student_id": "student_01HT7G3YZV7QB5N4YKQ1K0Z9A9",
"subject_id": "math",
"canonical_term_id": "term_2026_winter",
"growth_window": "winter_to_winter",
"norms_set": "2025",
"map_score_id": "map_score_01HT7N0T9Q",
"map_growth_window_ref": "map_growth_01HT7N5YDG",
"source_import_id": "imp_01HT8MAP_2026_WINTER",
"rit_score": 239,
"achievement_percentile": 91,
"growth_percentile": 43,
"observed_growth": 6,
"typical_growth": 2,
"projected_growth": 7,
"growth_x": 0.8571,
"growth_x_target": 2,
"on_track": false,
"sitting_count": 2,
"retake_count": 1,
"map_sitting_refs": [
"map_sitting_01HT7N",
"map_sitting_01HT7P"
],
"policy_ref": "alpha.policy.analytics.map_growth.v2026-06-10",
"null_reason": "none",
"quality_status": "ok",
"calculation_version": 1,
"computed_at": "2026-05-14T19:00:00Z",
"modified_at": "2026-05-14T19:00:00Z",
"superseded_at": null,
"source_deleted_at": null
}
Lifecycle
Materialized when the timeback-map adapter ingests reporting.hp_map_results, or when Results/NWEAMap MAP score/growth/sitting refs close, correct, or replay.
Raw DB Rule
Raw readers use this table by canonical_term_id/growth_window/norms_set; they do not choose test-of-record, parse NWEA term strings, read hp_map_results directly, or compute Growth X.
Field Index
Fields
| Field | Type / Nullability | Meaning | Constraints / Range | Relationship | Invalid When | Example | Source / ITD |
|---|---|---|---|---|---|---|---|
id |
UUID required |
Analytics-owned stable row id for this derived fact. | Generated by the platform; globally unique within alpha.analytics_* objects. | Primary key for list/detail endpoints. | Provided by a public import client or reused across tenants. | 8e9c0ef2-bc75-4f53-8124-df77df49f25f |
Alpha extension aitd-000-extend-only-storage |
tenant_id |
UUID required |
Tenant boundary for the derived fact. | Set from the JWT tenant claim or internal materializer context; never accepted from request body/query. | All raw-path queries must filter by tenant_id before joining, sorting, paging, or counting. | Missing, caller-supplied in body/query, or mismatched with the JWT tenant claim. | 7b0bb5d8-9a38-4a62-9fdc-9f8d2dc1a111 |
Alpha extension aitd-109-axis-tenant-routing, aitd-106-axis-auth-shape |
student_id |
TEXT required |
Canonical Alpha student id the source Event or Result resolved to at materialization time. | Must resolve through People and Orgs as a real student for the source timestamp/effective date. | References People and Orgs student identity; see https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/data_dictionary. | Parsed from email/name/source payload instead of resolved by the Events/Results adapter. | student_01HT7G3YZV7QB5N4YKQ1K0Z9A9 |
Alpha extension reference aitd-003-close-time-materialization, aitd-106-axis-auth-shape, aitd-011-policy-and-enum-normalization |
subject_id |
TEXT required for MAP rollups |
Canonical Alpha subject used for reporting and grouping. | Closed Alpha subject enum after write-time source-label normalization; unknown source subject becomes an adapter finding or null_reason, not a new string. | References the Curriculum/Results subject vocabulary; see https://platform3-andymontgomery-9773s-projects.vercel.app/curriculum/alpha/data_dictionary and https://platform3-andymontgomery-9773s-projects.vercel.app/results/alpha/data_dictionary. | Copied from source strings such as FastMath, Vocabulary, Science-notqced, or ISEE variants without normalization. | math |
Alpha extension reference aitd-009-map-growth-rollups, aitd-011-policy-and-enum-normalization |
canonical_term_id |
TEXT required |
Alpha canonical term id for the MAP observation/window. | Set by Results/NWEAMap term normalization; not parsed by Analytics clients. | References People and Orgs academic-session term. | A report parses source strings like Winter 2026 or growth-window columns. | term_2026_winter |
Alpha extension reference aitd-009-map-growth-rollups, aitd-011-policy-and-enum-normalization |
growth_window |
TEXT enum required |
MAP growth interval represented by this row. | Allowed values: growth_window enum. | Part of the MAP rollup grain. | A client switches over NWEA wide growth-window columns. | winter_to_winter |
Alpha extension aitd-009-map-growth-rollups, aitd-011-policy-and-enum-normalization |
norms_set |
TEXT enum required |
NWEA norms family used for projected growth and normed outputs. | Allowed values: norms_set enum; the same report can be regenerated by changing this filter. | Prevents mixed-norm calculations. | A report ships its own norms table or combines 2020 and 2025 values. | 2025 |
Alpha extension aitd-009-map-growth-rollups, aitd-011-policy-and-enum-normalization |
map_score_id |
TEXT required |
Results MAP score/test-of-record row this report fact derives from. | Same tenant; Results owns test-of-record and raw sitting decisions. | References Results MAP score; see https://platform3-andymontgomery-9773s-projects.vercel.app/results/alpha/data_dictionary#table-alpha-map-score. | Analytics selects the highest RIT itself or copies raw sitting fields. | map_score_01HT7N0T9Q |
Alpha extension reference aitd-000-extend-only-storage, aitd-009-map-growth-rollups |
map_growth_window_ref |
TEXT nullable for single-term observations |
Results MAP growth-window row used for projected/observed growth. | Required when growth_window is not term. | References Results MAP growth window; see https://platform3-andymontgomery-9773s-projects.vercel.app/results/alpha/data_dictionary#table-alpha-map-growth-window. | Client computes projected growth or window pairing. | map_growth_01HT7N5YDG |
Alpha extension reference aitd-000-extend-only-storage, aitd-009-map-growth-rollups |
rit_score |
NUMERIC(6,2) required |
The MAP score the report should show for this term. Report-ready RIT value from Results MAP test-of-record for this subject/term. |
Positive numeric; no local test-of-record choice in Analytics clients. | Displayed in MAP reports and used with Growth X fields. | Selected from raw sittings by the consumer. | 239.00 |
Alpha extension aitd-009-map-growth-rollups |
growth_percentile |
NUMERIC(6,2) nullable when the selected growth_window has no conditional growth percentile |
Conditional growth percentile for the selected MAP window; the Learning Report "vs 1yr ago" panel reads this from the winter_to_winter row. | 0 to 100 when present; null requires null_reason for report windows that should have growth. | For winter_to_winter, normalized from Results/NWEAMap wintertowinterconditionalgrowthpercentile source evidence. | Filled from fall_to_winter for a one-year-growth report panel. | 43.00 |
Alpha extension aitd-009-map-growth-rollups, aitd-011-policy-and-enum-normalization |
achievement_percentile |
NUMERIC(6,2) nullable when the MAP source row has no achievement percentile |
The MAP achievement percentile from the test-of-record sitting. Achievement percentile for the test-of-record sitting. |
0 to 100 when present; for hp_map_results this is normalized from testpercentile. | Displayed beside RIT in MAP report panels. | Filled from conditional growth percentile or mixed with growth_percentile. | 91.00 |
Alpha extension aitd-009-map-growth-rollups, aitd-011-policy-and-enum-normalization |
observed_growth |
NUMERIC(7,3) nullable when no paired window exists |
Actual RIT growth for the growth_window. | Null for term-only observations; otherwise computed by Results MAP views. | Numerator for Growth X. | Computed by subtracting RIT values in a report. | 6.000 |
Alpha extension aitd-009-map-growth-rollups |
typical_growth |
NUMERIC(7,3) nullable when the selected growth_window has no typical-growth value |
NWEA typical-growth context value for the selected growth window. | Comes from normalized Results/NWEAMap typical*growth columns; retained for audit and comparison. | For winter_to_winter, normalized from typicalwintertowintergrowth. | Used as the Learning Report Growth X denominator; the approved architecture pins projected_growth for Growth X. | 2.000 |
Alpha extension aitd-009-map-growth-rollups, aitd-011-policy-and-enum-normalization |
projected_growth |
NUMERIC(7,3) nullable when no projected growth exists |
NWEA projected-growth value for the selected window. | Must be greater than 0 when growth_x is present; comes from Results/NWEAMap normalized projections and never from a client norms table. | The pinned Learning Report Growth X denominator under AITD-009. | Copied from a skill pack or dashboard constants file. | 7.000 |
Alpha extension aitd-009-map-growth-rollups, aitd-011-policy-and-enum-normalization |
growth_x |
NUMERIC(8,4) nullable when observed or projected growth is unavailable |
Observed growth divided by projected growth for this MAP window. Observed growth divided by projected_growth, using the named norms_set and growth_window. |
Null requires null_reason; target comparisons use growth_x_target. | The report-ready Alpha growth measure. | Computed by a consumer from exported RIT/projection fields, or computed with typical_growth as the denominator. | 0.8571 |
Alpha extension aitd-009-map-growth-rollups |
growth_x_target |
NUMERIC(8,4) required |
Alpha target Growth X for intervention/on-track decisions. | Normally 2 under current Alpha policy, but read from policy_ref. | Feeds on_track flag and GOALS-style reports. | Hard-coded in a report or skill pack. | 2.0000 |
Alpha extension aitd-009-map-growth-rollups, aitd-011-policy-and-enum-normalization |
on_track |
BOOLEAN nullable when growth_x or target is null |
Whether Growth X meets the Alpha target in the named policy. Whether the student is meeting the Growth X target for this row. |
Computed under policy_ref; null requires null_reason. | Report flag for intervention workflows. | Client compares growth_x to a local threshold. | true |
Alpha extension aitd-009-map-growth-rollups |
sitting_count |
INTEGER required |
Number of MAP sittings Results observed for this subject/term before test-of-record selection. | Nonnegative; includes source-visible sittings according to Results policy. | Retake/audit display; not a dedupe instruction for clients. | Consumer counts raw NWEA rows itself. | 2 |
Alpha extension aitd-009-map-growth-rollups |
retake_count |
INTEGER required |
Number of non-test-of-record sittings represented by the sitting_count. | Nonnegative; computed by Results/NWEAMap policy. | Retake audit metric. | Client infers retakes from source term strings or GrowthMeasureYN flags. | 1 |
Alpha extension aitd-009-map-growth-rollups |
map_sitting_refs |
JSONB required |
Compact ids/cursor for Results MAP sitting rows used in the rollup. | Refs/hashes only; no raw NWEA row copy. | Authorized audit sourceRefs subcollection. | Stores raw CDF fields or lets consumers dedupe. | ["map_sitting_01HT7N", "map_sitting_01HT7P"] |
Alpha extension reference list aitd-000-extend-only-storage, aitd-009-map-growth-rollups, aitd-102-axis-read-shape |
source_import_id |
TEXT required for report-tile rows; nullable for purely derived event-axis rows |
Analytics source-import receipt that proves which named report-source adapter produced this report-grade fact. | Must reference alpha.analytics_source_import for non-null Learning Report tile values; no literal or fixture value may be reportable without this provenance. | Many report-fact rows can reference one source import; detail/sourceRefs endpoints join here for adapter, source_table, and source_row_key_hashes. | Missing on a non-null report-tile value, or replaced by copied raw reporting-DB columns. | imp_01HT8MAP_2026_WINTER |
Alpha extension provenance reference aitd-001-report-source-ingestion, aitd-004-provenance-no-literals, aitd-009-map-growth-rollups |
policy_ref |
TEXT required |
The rulebook version Analytics used; see Policy Reference on this page. Named policy/config version used to compute the measure or rollup. |
Must point at alpha.policy.analytics.* or an inherited Curriculum/Results policy active for the source effective date. | Many Analytics facts can share one policy row; changing policy creates new calculation versions or corrections. | A consumer hard-codes thresholds, school-day calendars, Growth X formulas, or completion denominators instead of using the policy ref. | alpha.policy.analytics.map_growth.v2026-06-10 |
Alpha extension reference aitd-009-map-growth-rollups, aitd-011-policy-and-enum-normalization |
null_reason |
TEXT enum required |
Why the report value is missing instead of asking an app to guess. Why a MAP rollup value is null or not applicable. |
Allowed values: null_reason enum; none means core report fields are populated. | Prevents client fallback term/norm math. | Null growth fields without a typed reason. | none |
Alpha extension aitd-009-map-growth-rollups, aitd-011-policy-and-enum-normalization |
quality_status |
TEXT enum required |
Whether this row is reportable, corrected, reversed, blocked, or rejected. Current materialization quality state for this fact. |
Allowed values: quality_status enum. Ordinary report reads keep ok, corrected, and signed reversed rows according to the table rule; audit reads may include source_missing/source_unlinked/policy_pending/adapter_rejected. | Used by raw/API convergence filters and source-ref audit views. | Free-text status or hidden failures represented as HTTP 200 success. | ok |
Alpha extension aitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope, aitd-111-axis-privacy-retention |
calculation_version |
INTEGER required |
Materializer calculation version for this fact shape. | Positive integer; starts at 1 and increments when policy/materializer logic intentionally changes. | Part of deterministic source_fact_key/idempotency for materializer writes. | Omitted from replay keys or changed without a new policy/materializer decision. | 1 |
Alpha extension aitd-003-close-time-materialization, aitd-105-axis-idempotency, aitd-104-axis-concurrency |
computed_at |
TIMESTAMPTZ required |
When Analytics wrote this derived fact. | UTC timestamp with timezone; updated only by Analytics materializers. | Used for audit and source-ref subcollections, not for school-day grouping. | Used as a substitute for the source event time, result effective time, or window boundaries. | 2026-06-10T00:51:14Z |
Alpha extension aitd-003-close-time-materialization |
modified_at |
TIMESTAMPTZ required |
Last time the Analytics row changed for polling and modifiedSince queries. | UTC timestamp; list endpoints support modifiedSince against this field. | Supports poll plus modifiedSince eventing. | Client-supplied or used as the business effective date. | 2026-06-10T00:51:14Z |
Alpha extension aitd-107-axis-eventing, aitd-103-axis-query-model |
superseded_at |
TIMESTAMPTZ nullable |
When this row stopped being the current reportable version because of source correction, deletion, or recalculation. | Null means current; non-null rows are excluded from ordinary list reads unless includeSuperseded=true and authorized. | Preserves audit history without mutating source Events or Results. | Used to hard-delete old rows or omitted on a correction that replaces a prior fact. | null |
Alpha extension aitd-111-axis-privacy-retention, aitd-012-corrections-and-reversals |
source_deleted_at |
TIMESTAMPTZ nullable |
When the source Event/Result became deleted or invalidated. | Null for live source rows; set from source tombstone/correction notifications. | Ordinary reads exclude tombstoned facts unless includeSuperseded=true and authorized. | Used as a physical delete or ignored by raw-path report queries. | null |
Alpha extension aitd-111-axis-privacy-retention |
Enums Used Here
growth_window | |||
|---|---|---|---|
| Value | Meaning | Source | ITD |
fall_to_fall | Year-over-year growth from fall of the prior school year to fall of the selected school year. | Alpha extension enum | aitd-009-map-growth-rollups, aitd-011-policy-and-enum-normalization |
fall_to_winter | Observed and projected growth from fall to winter. | Alpha extension enum | aitd-009-map-growth-rollups, aitd-011-policy-and-enum-normalization |
winter_to_spring | Observed and projected growth from winter to spring. | Alpha extension enum | aitd-009-map-growth-rollups, aitd-011-policy-and-enum-normalization |
fall_to_spring | Observed and projected growth from fall to spring. | Alpha extension enum | aitd-009-map-growth-rollups, aitd-011-policy-and-enum-normalization |
winter_to_winter | Year-over-year growth from winter of the prior school year to winter of the selected school year. This is the Learning Report "vs 1yr ago" MAP window. | Alpha extension enum | aitd-009-map-growth-rollups, aitd-011-policy-and-enum-normalization |
spring_to_spring | Year-over-year growth from spring of the prior school year to spring of the selected school year. | Alpha extension enum | aitd-009-map-growth-rollups, aitd-011-policy-and-enum-normalization |
baseline_to_current | Growth from the student baseline term to the current term. | Alpha extension enum | aitd-009-map-growth-rollups, aitd-011-policy-and-enum-normalization |
term | A single-term MAP observation with no paired growth delta. | Alpha extension enum | aitd-009-map-growth-rollups, aitd-011-policy-and-enum-normalization |
custom | A named migration or report window whose dates are stored in policy/config. | Alpha extension enum | aitd-009-map-growth-rollups, aitd-011-policy-and-enum-normalization |
norms_set | |||
|---|---|---|---|
| Value | Meaning | Source | ITD |
2020 | NWEA 2020 norms, kept distinct for historical report reproduction. | Alpha extension enum | aitd-009-map-growth-rollups, aitd-015-norms-r90-readable-resources, aitd-016-scale-translation-apis, aitd-011-policy-and-enum-normalization |
2025 | NWEA 2025 norms, the current norms family when requested by policy or caller. | Alpha extension enum | aitd-009-map-growth-rollups, aitd-015-norms-r90-readable-resources, aitd-016-scale-translation-apis, aitd-011-policy-and-enum-normalization |
null_reason | |||
|---|---|---|---|
| Value | Meaning | Source | ITD |
none | No null-producing condition applies. | Alpha extension enum | aitd-011-policy-and-enum-normalization |
no_school_days | The denominator window has zero enrolled school days after calendar and enrollment intersection. | Alpha extension enum | aitd-011-policy-and-enum-normalization |
no_questions | The window has zero reportable question attempts, so accuracy_percent is null rather than guessed as 0 or 100. | Alpha extension enum | aitd-011-policy-and-enum-normalization |
no_enrollment | The student has no time-locatable enrollment for the requested range. | Alpha extension enum | aitd-011-policy-and-enum-normalization |
no_subject_assignment | The student had no subject assignment/course/test membership for the subject denominator. | Alpha extension enum | aitd-011-policy-and-enum-normalization |
source_missing | Required Event, Result, calendar, enrollment, or curriculum source evidence is missing. | Alpha extension enum | aitd-011-policy-and-enum-normalization |
source_unlinked | Source evidence exists but cannot be linked to platform ids under the current policy. | Alpha extension enum | aitd-011-policy-and-enum-normalization |
policy_pending | The named policy needed to compute the measure is missing or not active. | Alpha extension enum | aitd-011-policy-and-enum-normalization |
not_applicable | The metric does not apply at this grain, such as MAP growth for a non-MAP subject. | Alpha extension enum | aitd-011-policy-and-enum-normalization |
quality_status | |||
|---|---|---|---|
| Value | Meaning | Source | ITD |
ok | The row is the current reportable fact for its key and policy. | Alpha extension enum | aitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope, aitd-111-axis-privacy-retention |
corrected | The row includes a correction contribution but remains reportable. | Alpha extension enum | aitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope, aitd-111-axis-privacy-retention |
reversed | The row reverses a prior contribution and should be read as signed history. | Alpha extension enum | aitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope, aitd-111-axis-privacy-retention |
source_missing | A required source row was removed or unavailable before the fact could be finalized. | Alpha extension enum | aitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope, aitd-111-axis-privacy-retention |
source_unlinked | The source row exists but could not link to a required Event, Result, student, subject, KC, course, or policy ref. | Alpha extension enum | aitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope, aitd-111-axis-privacy-retention |
policy_pending | A required policy configuration was missing or not yet active at materialization time. | Alpha extension enum | aitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope, aitd-111-axis-privacy-retention |
adapter_rejected | The source-shaped row was valid input but the server-side adapter rejected it with a typed Problem. | Alpha extension enum | aitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope, aitd-111-axis-privacy-retention |
alpha.analytics_norms_achievement
Readable NWEA achievement-status norms table for percentile-to-RIT and RIT-to-percentile translation. Apps may read/cache this surface table by table_version or call /norms/rit and /norms/percentile; they never maintain their own norms table.
Architecture trace: aitd-015-norms-r90-readable-resources, aitd-016-scale-translation-apis, aitd-009-map-growth-rollups, aitd-011-policy-and-enum-normalization, aitd-112-axis-list-endpoints
RIT|GrowthX|MAP windows GOALS percentile-to-RITGET /alpha/analytics/v1/norms, GET /alpha/analytics/v1/norms/table, GET /alpha/analytics/v1/norms/rit, and GET /alpha/analytics/v1/norms/percentileExample Object Payload
Concrete reportable payload for this object. Required fields in the field list must appear here unless their nullability explicitly allows omission.
{
"resource_id": "norms_2025_math_g5_winter_student",
"tenant_id": null,
"norms_set": "2025",
"table_version": "analytics.norms.achievement.v2026-06-12",
"subject_id": "math",
"role": "student",
"grade_key": "5",
"season": "winter",
"mean_rit": 214.2,
"sd_rit": 14.1,
"source_ref": "nweamap:NormsReferenceData:2025:math:5:winter:student",
"source_publication": "NWEA MAP Growth achievement status norms, 2025",
"is_current_version": true,
"published_at": "2026-06-12T00:00:00Z",
"quality_status": "ok"
}
Lifecycle
Seeded when Analytics publishes a NWEA achievement-status norms table version from the NWEAMap 1EdTech raw mirror. Versions are immutable: a new NWEA publication or correction creates a new table_version instead of editing rows in place.
Raw DB Rule
Raw readers may query this table by norms_set, table_version, subject_id, role, grade_key, and season. Percentile-to-RIT uses rit_score = mean_rit + sd_rit * inverse_normal_cdf(percentile / 100); RIT-to-percentile applies the same normal model in reverse. Missing subject/table points return analytics:validation_failed field codes, not a private fallback table.
Formula
percentile_to_rit: rit_score = mean_rit + (sd_rit * z(percentile/100)). rit_to_percentile: percentile = normal_cdf((rit_score - mean_rit) / sd_rit) * 100. The API returns calculator_version, mean_rit, sd_rit, norms_set, and table_version.
Field Index
Fields
| Field | Type / Nullability | Meaning | Constraints / Range | Relationship | Invalid When | Example | Source / ITD |
|---|---|---|---|---|---|---|---|
resource_id |
TEXT required |
Stable Analytics id for this norms reference row. | Generated by Analytics when the versioned table is published; unique across achievement norms rows. | Primary key for raw reads and /norms row paging. | Caller-supplied, tenant-specific, or reused across table_version values. | norms_2025_math_g5_winter_student |
Alpha readable reference id aitd-015-norms-r90-readable-resources |
tenant_id |
UUID nullable; must be null for platform-global reference rows |
Tenant scope marker. Achievement norms rows are platform-global reference data, so tenant_id is null by design. | Apps still authenticate with a tenant-scoped JWT, but raw reference rows use tenant_id IS NULL; tenant overrides are forbidden because ALPHA-8 requires one canonical copy. | Separates global reference data from student-specific Analytics facts. | A tenant-specific norms row exists or a raw query joins norms rows by student tenant to create a fork. | null |
Alpha readable reference scope aitd-015-norms-r90-readable-resources, aitd-109-axis-tenant-routing |
norms_set |
TEXT enum required |
NWEA norms family this achievement norms row belongs to. | Allowed values: norms_set enum. A table version belongs to exactly one norms_set. | Required input for /norms, /norms/rit, and /norms/percentile; prevents mixed-norm reports. | A row omits norms_set, uses free-text labels, or mixes 2020 and 2025 values in one table_version. | 2025 |
Alpha readable reference dimension aitd-015-norms-r90-readable-resources, aitd-016-scale-translation-apis, aitd-011-policy-and-enum-normalization |
table_version |
TEXT required |
The version of the surface norms table this row belongs to; HTTP reads are no-store and the version string is the reproducibility key. Immutable version id of the published achievement norms table. |
Stable, cacheable identifier; new source publication or correction creates a new version. Maximum 128 characters. | Part of every raw/API lookup. HTTP responses are cache-control: no-store; table_version is the reproducibility key. | Rows are edited in place under the same version or a client caches without version. | analytics.norms.achievement.v2026-06-12 |
Alpha readable reference version aitd-015-norms-r90-readable-resources |
subject_id |
TEXT required |
Canonical Alpha subject for this achievement norms row. | Must be one of the MAP-supported Alpha subject values for the table version. | Part of percentile/RIT lookup grain. | A source label such as Math K-12 or Language Usage is stored without write-time subject normalization. | math |
Alpha extension reference aitd-015-norms-r90-readable-resources, aitd-011-policy-and-enum-normalization |
role |
TEXT required |
NWEA role/population label for the norms row. | Governed by the published norms table. Current public student translations use role=student unless a future NWEA publication distinguishes another role. | Part of the achievement norms lookup grain. | Dropped by a raw query, causing population-specific rows to be mixed if NWEA publishes them. | student |
Alpha readable reference dimension aitd-015-norms-r90-readable-resources, aitd-016-scale-translation-apis |
grade_key |
TEXT required |
NWEA grade key for this achievement norms row. | Governed grade label from the published norms table; examples include K and 1 through 12. | Used with subject_id and season for achievement-status lookup. | Inferred from a student current grade or Alpha level tag instead of the published norms row. | 5 |
Alpha readable reference dimension aitd-015-norms-r90-readable-resources, aitd-016-scale-translation-apis |
season |
TEXT required |
MAP testing season for this achievement norms row. | Governed values for the table version: fall, winter, spring, or another NWEA-published season label. | Used by percentile-to-RIT and RIT-to-percentile translations. | Parsed from report prose or mapped by a client-side term switch statement. | winter |
Alpha readable reference dimension aitd-015-norms-r90-readable-resources, aitd-016-scale-translation-apis, aitd-011-policy-and-enum-normalization |
mean_rit |
NUMERIC(7,2) required |
The NWEA-published mean RIT used by percentile<->RIT translations. Published mean RIT for this subject/role/grade/season row. |
Positive numeric RIT value from the NWEA-published achievement-status norms; never estimated by a client. | Used by /norms/rit and /norms/percentile normal-model translations. | Rounded differently per app or copied from an app-private norms table. | 214.20 |
Alpha readable reference value aitd-015-norms-r90-readable-resources, aitd-016-scale-translation-apis |
sd_rit |
NUMERIC(6,3) required |
The NWEA-published RIT standard deviation used by percentile<->RIT translations. Published standard deviation of RIT for this subject/role/grade/season row. |
Must be positive. It is the denominator for RIT-to-percentile and multiplier for percentile-to-RIT. | Used by the normal-model translation APIs and raw-DB twin formula. | Blank, zero, averaged from adjacent rows, or copied from a different norms_set. | 14.100 |
Alpha readable reference value aitd-015-norms-r90-readable-resources, aitd-016-scale-translation-apis |
source_ref |
TEXT required |
Opaque provenance pointer to the NWEA-published norms row in the NWEAMap 1EdTech raw mirror. | Must identify the source publication/row without copying a private app table. | References the NWEAMAP-owned PowerPath RIT-to-grade master; see https://platform3-andymontgomery-9773s-projects.vercel.app/nweamap/1edtech/data_dictionary. | Points at a skill pack file, production app constant, or unversioned spreadsheet export. | nweamap:NormsReferenceData:2025:math:5:winter:student |
Alpha readable reference provenance aitd-015-norms-r90-readable-resources |
source_publication |
TEXT required |
Human-readable source publication name for the norms table. | Names the NWEA publication behind source_ref; maximum 256 characters. | Lets parent/LLM readers understand where the table came from without source code. | Blank, generic, or says Alpha extrapolation for an NWEA-published norms point. | NWEA MAP Growth achievement status norms, 2025 |
Alpha readable reference provenance aitd-015-norms-r90-readable-resources |
is_current_version |
BOOLEAN required |
Whether this table_version is the current default for its norms_set. | At most one current version per norms_set and table; historical versions remain readable. | Allows callers to request latest without losing reproducibility for pinned historical reports. | Old versions are hidden/deleted or multiple versions are current for one norms_set. | true |
Alpha readable reference version metadata aitd-015-norms-r90-readable-resources |
published_at |
TIMESTAMPTZ required |
When Analytics published this readable table version. | UTC timestamp; not a student test date. | Resource lifecycle/audit metadata. | Used as a MAP term date or modified in place for corrections. | 2026-06-12T00:00:00Z |
Alpha readable reference lifecycle metadata aitd-015-norms-r90-readable-resources |
quality_status |
TEXT enum required |
Whether this row is reportable, corrected, reversed, blocked, or rejected. Publication quality state for this reference row. |
Current public rows use ok. Unpublished or failed rows are not returned by ordinary /norms reads. | Keeps reference publication failures visible to operators without fabricating translations. | A row with policy_pending/source_missing is used in a translation response. | ok |
Alpha extension aitd-015-norms-r90-readable-resources, aitd-108-axis-error-envelope |
Enums Used Here
norms_set | |||
|---|---|---|---|
| Value | Meaning | Source | ITD |
2020 | NWEA 2020 norms, kept distinct for historical report reproduction. | Alpha extension enum | aitd-009-map-growth-rollups, aitd-015-norms-r90-readable-resources, aitd-016-scale-translation-apis, aitd-011-policy-and-enum-normalization |
2025 | NWEA 2025 norms, the current norms family when requested by policy or caller. | Alpha extension enum | aitd-009-map-growth-rollups, aitd-015-norms-r90-readable-resources, aitd-016-scale-translation-apis, aitd-011-policy-and-enum-normalization |
quality_status | |||
|---|---|---|---|
| Value | Meaning | Source | ITD |
ok | The row is the current reportable fact for its key and policy. | Alpha extension enum | aitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope, aitd-111-axis-privacy-retention |
corrected | The row includes a correction contribution but remains reportable. | Alpha extension enum | aitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope, aitd-111-axis-privacy-retention |
reversed | The row reverses a prior contribution and should be read as signed history. | Alpha extension enum | aitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope, aitd-111-axis-privacy-retention |
source_missing | A required source row was removed or unavailable before the fact could be finalized. | Alpha extension enum | aitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope, aitd-111-axis-privacy-retention |
source_unlinked | The source row exists but could not link to a required Event, Result, student, subject, KC, course, or policy ref. | Alpha extension enum | aitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope, aitd-111-axis-privacy-retention |
policy_pending | A required policy configuration was missing or not yet active at materialization time. | Alpha extension enum | aitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope, aitd-111-axis-privacy-retention |
adapter_rejected | The source-shaped row was valid input but the server-side adapter rejected it with a typed Problem. | Alpha extension enum | aitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope, aitd-111-axis-privacy-retention |
alpha.analytics_r90_table
Readable R90 / RIT-to-grade reference for GOALS target conversion, Learning Report grade-position display, and screener starting-grade hints. Final PowerPath placement comes from bottom-up grade-level mastery tests, not this table, and actual course or grade-level progress comes from Results course-progress and grade-level-progress backed by Analytics evidence. The current version mirrors powerpath:/powerpath/rit-to-grade; observed RIT-to-grade uses the PowerPath row for the requested score.
Architecture trace: aitd-015-norms-r90-readable-resources, aitd-016-scale-translation-apis, aitd-017-r90-version-supersession, aitd-009-map-growth-rollups, aitd-011-policy-and-enum-normalization, aitd-112-axis-list-endpoints
RIT|GrowthX|MAP windows GOALS RIT-to-grade/R90GET /alpha/analytics/v1/r90/table and GET /alpha/analytics/v1/r90Example Object Payload
Concrete reportable payload for this object. Required fields in the field list must appear here unless their nullability explicitly allows omission.
{
"resource_id": "r90_2025_math_239",
"tenant_id": null,
"norms_set": "2025",
"table_version": "analytics.rit_to_grade.powerpath.v2026-06-15",
"table_subject_id": "math",
"rit_score": 239,
"rit50_rit": 239,
"rit90_rit": 239,
"r90_grade": 4.8,
"effective_grade": 5,
"r90_grade_level": 4,
"r90_percent_complete": 80,
"alpha_min_rit": null,
"alpha_predicted_rit": 239,
"extend_kind": "alpha_extrapolation",
"r90_method_ref": "alpha.policy.analytics.r90_method.v2026-06-12",
"source_norms_refs": [
"powerpath:/powerpath/rit-to-grade",
"powerpath:2026-06-15:Math:RIT:239"
],
"exact_nwea_point": false,
"source_point_kind": "exact",
"is_current_version": true,
"published_at": "2026-06-14T00:00:00Z",
"quality_status": "ok"
}
Lifecycle
Seeded as the single Alpha mirror of the NWEAMAP-owned R90/RIT-to-grade resource. The live R90 table_version is analytics.rit_to_grade.powerpath.v2026-06-15; grade2rit.csv is forecast-only and is not used as an observed-RIT inverse.
Raw DB Rule
Raw readers query this table with table_version='analytics.rit_to_grade.powerpath.v2026-06-15' and table_subject_id. For an input RIT, read that rit_score row. If no row exists for the requested RIT, return source_missing; never use grade2rit.csv as an observed-RIT inverse, interpolate, clamp upward, extrapolate, or infer the current table_version by sorting strings.
Formula
RIT-to-R90 current method: filter table_version='analytics.rit_to_grade.powerpath.v2026-06-15', then choose the PowerPath row whose rit_score equals the requested RIT. R90 values are Alpha/PowerPath extrapolations and must carry extend_kind=alpha_extrapolation plus AITD-017 provenance.
Field Index
Fields
| Field | Type / Nullability | Meaning | Constraints / Range | Relationship | Invalid When | Example | Source / ITD |
|---|---|---|---|---|---|---|---|
resource_id |
TEXT required |
Stable Analytics id for this R90 reference row. | Generated by Analytics when the R90 table version is published; unique across R90 rows. | Primary key for raw reads and /r90 row paging. | Caller-supplied or reused across table_version values. | r90_2025_math_239 |
Alpha readable reference id aitd-015-norms-r90-readable-resources |
tenant_id |
UUID nullable; must be null for platform-global reference rows |
Tenant scope marker. R90 rows are platform-global reference data, so tenant_id is null by design. | Apps authenticate with a tenant-scoped JWT, but the raw row itself is global. Tenant-specific R90 forks are forbidden. | Enforces the one-canonical-R90-copy decision. | A tenant-local R90 table or row exists. | null |
Alpha readable reference scope aitd-015-norms-r90-readable-resources, aitd-109-axis-tenant-routing |
norms_set |
TEXT enum required |
NWEA norms family the R90 table version is tied to. | Allowed values: norms_set enum. | Required input for /r90/table and /r90. | An R90 row is used without stating whether it belongs to the 2020 or 2025 norms. | 2025 |
Alpha readable reference dimension aitd-015-norms-r90-readable-resources, aitd-016-scale-translation-apis, aitd-011-policy-and-enum-normalization |
table_version |
TEXT required |
Immutable version id of the published R90 table. | Stable, cacheable identifier; current reads use analytics.rit_to_grade.powerpath.v2026-06-15; a method or source change creates a new version. | Part of every raw/API lookup. HTTP responses are cache-control: no-store; table_version is the reproducibility key. | Two different R90 methods share one version id, or a current raw read omits the current-version filter. | analytics.rit_to_grade.powerpath.v2026-06-15 |
Alpha readable reference version aitd-015-norms-r90-readable-resources, aitd-017-r90-version-supersession |
table_subject_id |
TEXT required |
Canonical table subject for this R90 row. | Must be one of the supported MAP/GOALS subject values for the table version. | Part of RIT-to-grade/R90 lookup grain. | A report maps subject labels locally before looking up R90. | math |
Alpha readable reference dimension aitd-015-norms-r90-readable-resources, aitd-011-policy-and-enum-normalization |
rit_score |
NUMERIC(7,2) required |
Observed RIT score from the PowerPath source row represented by this R90/grade row. | Unique within (table_version, table_subject_id); current raw/API lookups use this as the exact key. | Exact lookup key for /rit-to-grade and legacy /r90. | Duplicated within a subject/version, or a report uses grade2rit.csv as an observed-RIT inverse. | 239.00 |
Alpha readable reference dimension aitd-015-norms-r90-readable-resources, aitd-016-scale-translation-apis, aitd-017-r90-version-supersession |
rit50_rit |
NUMERIC(7,2) required |
Compatibility anchor for older RIT50/RIT90 reports; in the current PowerPath version this equals the observed RIT source row. | Current version uses the PowerPath RIT value. Apps must not use this field to reconstruct the current lookup method. | Retained so older report templates that require the headline RIT50/RIT90 fields still receive a surfaced value. | Recomputed or rounded differently by an app. | 239.00 |
Alpha readable reference compatibility value aitd-015-norms-r90-readable-resources, aitd-016-scale-translation-apis, aitd-017-r90-version-supersession |
rit90_rit |
NUMERIC(7,2) required |
The Alpha R90 target RIT for this row. Compatibility anchor for older RIT90-facing consumers; in the current PowerPath version this equals the selected observed RIT row, while the report-grade output is r90_grade/effective_grade. |
Must be produced by r90_method_ref; because NWEA does not publish R90 directly, rows carry extend_kind=alpha_extrapolation. | Returned with the readable table for consumers that need the headline RIT90 field; /r90 exposes r90_grade/effective_grade for target conversion and starting-grade hints, never final PowerPath placement. | Copied from a private app table or undocumented production constant. | 239.00 |
Alpha readable reference compatibility value aitd-015-norms-r90-readable-resources, aitd-016-scale-translation-apis, aitd-017-r90-version-supersession |
r90_grade |
NUMERIC(8,3) required |
The grade-position value GOALS can show for this RIT. Grade-position value from the selected PowerPath row. |
Governed display/ordering value from the R90 table version; must be reproducible from the same row. | Returned by /r90 and read by GOALS when converting a RIT target to grade progress. | Computed by a consumer from a private RIT-to-grade table. | 4.800 |
Alpha readable reference value aitd-015-norms-r90-readable-resources, aitd-016-scale-translation-apis, aitd-017-r90-version-supersession |
effective_grade |
INTEGER required |
The grade-level label reports and GOALS can show for this RIT. Plain report-ready grade/effective-grade label produced by the R90 method. |
Governed display label; must be reproducible from the same row and method version. | Used by Learning Report placement/progress and GOALS. | Derived client-side from a local RIT-to-grade table. | 5 |
Alpha readable reference value aitd-015-norms-r90-readable-resources, aitd-016-scale-translation-apis, aitd-017-r90-version-supersession |
r90_grade_level |
INTEGER required |
Governed grade-level bucket for this R90 row. | Integer floor of r90_grade under the current PowerPath method. | Supports GOALS and Learning Report grouping without parsing effective_grade text. | Derived by splitting display text client-side. | 4 |
Alpha readable reference value aitd-015-norms-r90-readable-resources, aitd-016-scale-translation-apis, aitd-017-r90-version-supersession |
r90_percent_complete |
NUMERIC(7,3) required |
MAP-inferred percent through the R90 grade band represented by this RIT row. | Usually 0 through 100 inside a grade band; computed by the documented R90 method and immutable for the table_version. | Used by GOALS to describe grade-band position. It is not actual work progress and must not populate course or grade-level completion. | Calculated in GOALS or Learning Report code from a private table, or treated as actual course/grade-level progress. | 80.000 |
Alpha readable reference value aitd-015-norms-r90-readable-resources, aitd-016-scale-translation-apis, aitd-017-r90-version-supersession |
alpha_min_rit |
NUMERIC(7,2) nullable when the Alpha minimum rule does not apply to the row |
Alpha Minimum RIT associated with this R90/effective-grade band. | Nullable in the current PowerPath version; no app-side override. | Feeds GOALS and progress predictions. | Hard-coded in GOALS or Learning Report code. | null |
Alpha readable reference value aitd-015-norms-r90-readable-resources, aitd-016-scale-translation-apis |
alpha_predicted_rit |
NUMERIC(7,2) nullable when no Alpha predicted value is published for the row |
Alpha predicted RIT associated with this band under the current R90 method. | Set by the documented Alpha method and table_version; current PowerPath version uses the selected observed RIT. | Used for GOALS/prediction workflows as a surface value. | Computed by a consumer from private expected-growth assumptions. | 239.00 |
Alpha readable reference value aitd-015-norms-r90-readable-resources, aitd-016-scale-translation-apis, aitd-017-r90-version-supersession |
extend_kind |
TEXT required |
Makes clear that R90 is Alpha extrapolation, not a NWEA-published field. Honest source classification for this row. |
Allowed value for R90-derived rows: alpha_extrapolation. NWEA-published 50%-correct points may be represented through exact_nwea_point=true. | Makes the ALPHA-4 tension visible: R90 is not an NWEA-published field. | R90 rows are presented as NWEA-published facts. | alpha_extrapolation |
Alpha readable reference provenance aitd-015-norms-r90-readable-resources |
r90_method_ref |
TEXT required |
The versioned rule that produced the R90 values. Named method/policy version that produced R90, effective_grade, alpha_min_rit, and alpha_predicted_rit. |
Stable versioned R90 method policy reference, for example alpha.policy.analytics.r90_method.v2026-06-12; changing the method creates a new table_version. | Lets raw readers reproduce why a row is Alpha extrapolation rather than NWEA pass-through. | Blank, unversioned, or stored only in app code. | alpha.policy.analytics.r90_method.v2026-06-12 |
Alpha readable reference method aitd-015-norms-r90-readable-resources, aitd-016-scale-translation-apis, aitd-017-r90-version-supersession |
source_norms_refs |
JSONB required |
Published/source refs that anchor this Alpha R90 extrapolation. | Array of opaque refs/hashes; no raw private app table data. | References the NWEAMap 1EdTech raw mirror; see https://platform3-andymontgomery-9773s-projects.vercel.app/nweamap/1edtech/data_dictionary. | Points at an app-owned R90 file or has no provenance. | ["powerpath:/powerpath/rit-to-grade", "powerpath:2026-06-15:Math:RIT:239"] |
Alpha readable reference provenance aitd-015-norms-r90-readable-resources, aitd-017-r90-version-supersession |
exact_nwea_point |
BOOLEAN required |
Whether the row value being referenced is an exact NWEA-published point. | false for Alpha R90 extrapolations; true only for values reproduced directly from NWEA-published data. | Lets apps and parents distinguish NWEA pass-through from Alpha extrapolation. | true on a rit90_rit value that NWEA did not publish. | false |
Alpha readable reference provenance aitd-015-norms-r90-readable-resources |
source_point_kind |
TEXT enum required |
Whether the R90 answer is exact from PowerPath or source_missing. How the /r90 lookup should describe the source point for this row or translated response. |
Allowed values: source_point_kind enum. Stored current-version rows use exact; API responses can return source_missing when no PowerPath row exists for the input. | Carries the step-floor behavior promised by AITD-016/AITD-017 instead of forcing apps to extrapolate. | Missing on a translation response or replaced with a silent nearest-value lookup. | exact |
Alpha readable reference lookup metadata aitd-015-norms-r90-readable-resources, aitd-016-scale-translation-apis, aitd-017-r90-version-supersession |
is_current_version |
BOOLEAN required |
Whether this table_version is the current default for its norms_set. | At most one current R90 version per norms_set; current is analytics.rit_to_grade.powerpath.v2026-06-15. | Supports latest reads while preserving historical reproducibility. | Historical versions are deleted or multiple current versions exist. | true |
Alpha readable reference version metadata aitd-015-norms-r90-readable-resources, aitd-017-r90-version-supersession |
published_at |
TIMESTAMPTZ required |
When Analytics published this R90 table version. | UTC timestamp; not a student result date. | Resource lifecycle/audit metadata. | Used as a MAP term date. | 2026-06-14T00:00:00Z |
Alpha readable reference lifecycle metadata aitd-015-norms-r90-readable-resources, aitd-017-r90-version-supersession |
quality_status |
TEXT enum required |
Whether this row is reportable, corrected, reversed, blocked, or rejected. Publication quality state for this R90 reference row. |
Current public rows use ok. Failed or unpublished rows are not returned by ordinary /r90/table or /r90 reads. | Keeps reference publication failures visible to operators without fabricating translations. | A non-ok row is used to answer a report or GOALS translation. | ok |
Alpha extension aitd-015-norms-r90-readable-resources, aitd-108-axis-error-envelope |
Enums Used Here
norms_set | |||
|---|---|---|---|
| Value | Meaning | Source | ITD |
2020 | NWEA 2020 norms, kept distinct for historical report reproduction. | Alpha extension enum | aitd-009-map-growth-rollups, aitd-015-norms-r90-readable-resources, aitd-016-scale-translation-apis, aitd-011-policy-and-enum-normalization |
2025 | NWEA 2025 norms, the current norms family when requested by policy or caller. | Alpha extension enum | aitd-009-map-growth-rollups, aitd-015-norms-r90-readable-resources, aitd-016-scale-translation-apis, aitd-011-policy-and-enum-normalization |
source_point_kind | |||
|---|---|---|---|
| Value | Meaning | Source | ITD |
exact | The requested RIT exactly matched a PowerPath RIT-to-grade row in the current R90 table version. | Alpha reference lookup enum | aitd-015-norms-r90-readable-resources, aitd-016-scale-translation-apis, aitd-017-r90-version-supersession |
source_missing | No PowerPath RIT-to-grade source row exists for the requested RIT and subject, so the surface returns a typed missing answer instead of extrapolating. | Alpha reference lookup enum | aitd-015-norms-r90-readable-resources, aitd-016-scale-translation-apis, aitd-017-r90-version-supersession |
quality_status | |||
|---|---|---|---|
| Value | Meaning | Source | ITD |
ok | The row is the current reportable fact for its key and policy. | Alpha extension enum | aitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope, aitd-111-axis-privacy-retention |
corrected | The row includes a correction contribution but remains reportable. | Alpha extension enum | aitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope, aitd-111-axis-privacy-retention |
reversed | The row reverses a prior contribution and should be read as signed history. | Alpha extension enum | aitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope, aitd-111-axis-privacy-retention |
source_missing | A required source row was removed or unavailable before the fact could be finalized. | Alpha extension enum | aitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope, aitd-111-axis-privacy-retention |
source_unlinked | The source row exists but could not link to a required Event, Result, student, subject, KC, course, or policy ref. | Alpha extension enum | aitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope, aitd-111-axis-privacy-retention |
policy_pending | A required policy configuration was missing or not yet active at materialization time. | Alpha extension enum | aitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope, aitd-111-axis-privacy-retention |
adapter_rejected | The source-shaped row was valid input but the server-side adapter rejected it with a typed Problem. | Alpha extension enum | aitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope, aitd-111-axis-privacy-retention |
analytics.school_days_remaining
Forward instructional-day count and XP-to-time effort projection for GOALS target-date columns. Apps call this endpoint or follow this raw path instead of counting weekdays, excluding MAP days, or carrying XP-hour constants locally.
Architecture trace: aitd-018-goals-school-days-remaining, aitd-006-school-day-minutes, aitd-007-xp-rollups, aitd-016-scale-translation-apis, aitd-011-policy-and-enum-normalization
GOALS target date GOALS school-days-remainingGET /alpha/analytics/v1/school-days-remainingExample Object Payload
Concrete reportable payload for this object. Required fields in the field list must appear here unless their nullability explicitly allows omission.
{
"object": "analytics.school_days_remaining",
"student_id": "student_01HT7G3YZV7QB5N4YKQ1K0Z9A9",
"school_id": "school_alpha_austin",
"as_of": "2026-06-14",
"end_date": "2026-07-24",
"school_day_policy_ref": "alpha.policy.school_day.v2026-06-10",
"instructional_days_remaining": 29,
"calendar_ref_count": 40,
"first_instructional_date": "2026-06-15",
"last_instructional_date": "2026-07-23",
"instructional_dates": [
"2026-06-15",
"2026-06-16",
"2026-06-17"
],
"xp_unit": {
"policy_ref": "alpha.policy.analytics.xp_expected_minute.v2026-06-14",
"xp_per_expected_minute": 1,
"xp_per_hour": 60,
"meaning": "1 XP = 1 expected minute; 60 XP = 1 expected hour."
},
"effort": {
"xp_remaining": 600,
"expected_minutes_remaining": 600,
"hours_remaining": 10,
"target_date": "2026-07-24",
"school_days_until_target_date": 29,
"required_hours_per_school_day_to_target_date": 0.345,
"hours_per_school_day": 1.5,
"school_days_needed_at_hours_per_school_day": 7,
"target_date_at_hours_per_school_day": "2026-06-23",
"can_finish_by_end_date_at_hours_per_school_day": true
},
"provenance": {
"source": "alpha.school_calendar over ed_fi.CalendarDate plus People and Orgs enrollment",
"source_ref_sample": [
"calendar_date:school_alpha_austin:2026-06-15"
],
"policy_ref": "alpha.policy.school_day.v2026-06-10",
"xp_unit_policy_ref": "alpha.policy.analytics.xp_expected_minute.v2026-06-14"
},
"links": {
"self": "/alpha/analytics/v1/school-days-remaining?studentId=student_01HT7G3YZV7QB5N4YKQ1K0Z9A9&asOf=2026-06-14&endDate=2026-07-24&xpRemaining=600&hoursPerSchoolDay=1.5&targetDate=2026-07-24",
"schoolDayMinutes": "/alpha/analytics/v1/school-day-minutes?studentId=student_01HT7G3YZV7QB5N4YKQ1K0Z9A9&windowKind=school_year",
"xpRollups": "/alpha/analytics/v1/xp-rollups?studentId=student_01HT7G3YZV7QB5N4YKQ1K0Z9A9&windowKind=school_year"
}
}
Lifecycle
Read-time response assembled from alpha.school_calendar, People and Orgs enrollment, alpha.policy.school_day, and the XP expected-minute policy. It does not copy calendar rows into Analytics storage; it returns the surface-owned answer GOALS needs.
Raw DB Rule
Raw readers resolve the student's effective-dated school enrollment, read alpha.school_calendar for that school where calendar_date >= :asOf and calendar_date < :endDate, apply alpha.policy.school_day.v2026-06-10 so only instructional days count and MAP-testing days are excluded, then apply alpha.policy.analytics.xp_expected_minute.v2026-06-14 for effort fields. The raw path may return the same instructional_dates array the surface returns; it must not count weekdays, infer summer gaps, use attendance days, or hard-code XP_PER_HOUR.
Formula
instructional_days_remaining = count(instructional_dates). expected_minutes_remaining = xp_remaining / xp_per_expected_minute when xpRemaining is supplied. hours_remaining = expected_minutes_remaining / 60. required_hours_per_school_day_to_target_date = hours_remaining / school_days_until_target_date when targetDate is supplied and the target window has instructional days. school_days_needed_at_hours_per_school_day = ceil(hours_remaining / hoursPerSchoolDay) when hoursPerSchoolDay is supplied.
Field Index
Fields
| Field | Type / Nullability | Meaning | Constraints / Range | Relationship | Invalid When | Example | Source / ITD |
|---|---|---|---|---|---|---|---|
object |
TEXT required |
Response object discriminator for this endpoint. | Always analytics.school_days_remaining. | Lets docs, skill packs, and contract checks identify the response shape. | Missing or replaced with a generic list object. | analytics.school_days_remaining |
Analytics response metadata aitd-018-goals-school-days-remaining |
student_id |
TEXT required |
Canonical Alpha student id whose enrolled school calendar is used for the forward count. | Must resolve through People and Orgs as a real student for as_of/end_date. If schoolId is omitted, Analytics resolves the student school point-in-time. | References People and Orgs student identity; see https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/data_dictionary. | GOALS supplies a name/email or a current-only student lookup. | student_01HT7G3YZV7QB5N4YKQ1K0Z9A9 |
Alpha extension reference aitd-018-goals-school-days-remaining, aitd-006-school-day-minutes, aitd-106-axis-auth-shape |
school_id |
TEXT required |
School whose alpha.school_calendar rows were read for the forward window. | Resolved from request schoolId or the student effective-dated enrollment. Must be one real People and Orgs school. | References People and Orgs school identity; calendar source is alpha.school_calendar over Ed-Fi CalendarDate (https://platform3-andymontgomery-9773s-projects.vercel.app/ed_fi/1edtech/data_dictionary). | Inferred from a display campus string or current-only school assignment outside the requested date. | school_alpha_austin |
Alpha reference aitd-018-goals-school-days-remaining, aitd-006-school-day-minutes |
as_of |
DATE required |
Inclusive start date for the forward school-day count. | ISO date. The response uses the half-open window [as_of, end_date). | Alias of the asOf request parameter. | Treated as exclusive or defaulted to server time without request provenance. | 2026-06-14 |
Request-derived response field aitd-018-goals-school-days-remaining |
end_date |
DATE required |
Exclusive end date for the forward school-day count. | ISO date; must be after as_of. If omitted by request, Analytics uses the policy-defined GOALS school-year end. | Alias of endDate/schoolYearEnd request parameter. | Treated as inclusive, or guessed by a client from a local school-year calendar. | 2026-07-24 |
Request/policy-derived response field aitd-018-goals-school-days-remaining, aitd-006-school-day-minutes |
school_day_policy_ref |
TEXT required |
The rulebook version Analytics used; see Policy Reference on this page. Policy ref used to decide which calendar rows count as instructional school days. |
Current value: alpha.policy.school_day.v2026-06-10. The policy excludes MAP-testing days. | Same policy family as alpha.analytics_school_day_minutes.school_day_policy_ref. | Blank, unversioned, or replaced by local weekday filtering. | alpha.policy.school_day.v2026-06-10 |
Policy reference aitd-018-goals-school-days-remaining, aitd-006-school-day-minutes |
instructional_days_remaining |
INTEGER required |
Count of remaining instructional school days in [as_of, end_date) after calendar, enrollment, and MAP-day exclusion rules. | Nonnegative integer. Zero is valid and means no instructional days remain in the requested window. | GOALS target-date denominator. | Computed from weekdays, attendance days, active dates, or private school-period bounds. | 29 |
Derived response value aitd-018-goals-school-days-remaining, aitd-006-school-day-minutes |
calendar_ref_count |
INTEGER required |
Count of alpha.school_calendar rows inspected for the requested window before instructional-day filtering. | Nonnegative; not the same as instructional_days_remaining. | Audit summary for calendar coverage. | Rendered as school days remaining or computed from raw date span length. | 40 |
Audit response value aitd-018-goals-school-days-remaining, aitd-006-school-day-minutes, aitd-102-axis-read-shape |
first_instructional_date |
DATE nullable when instructional_days_remaining=0 |
First counted instructional date in the requested window. | Must be one of instructional_dates when present. | GOALS display and audit field. | A non-null date appears while instructional_days_remaining=0. | 2026-06-15 |
Derived response value aitd-018-goals-school-days-remaining, aitd-006-school-day-minutes |
last_instructional_date |
DATE nullable when instructional_days_remaining=0 |
Last counted instructional date in the requested window. | Must be one of instructional_dates when present and must be before end_date. | GOALS display and audit field. | Equals end_date when end_date is exclusive, unless end_date itself is not counted and this is a prior date. | 2026-07-23 |
Derived response value aitd-018-goals-school-days-remaining, aitd-006-school-day-minutes |
instructional_dates |
DATE[] required |
The counted instructional dates returned by the surface for this request. | Array length must equal instructional_days_remaining. Values are ISO dates, sorted ascending, and all satisfy the school-day policy. | GOALS may render or cache the returned dates by request, but must not recreate them from a private calendar. | Unsorted, includes MAP-testing/non-school dates, includes end_date, or differs in length from instructional_days_remaining. | ["2026-06-15","2026-06-16","2026-06-17"] |
Derived response value aitd-018-goals-school-days-remaining, aitd-006-school-day-minutes |
xp_unit.policy_ref |
TEXT required |
Versioned policy that defines XP-to-expected-minute conversion. | Current value: alpha.policy.analytics.xp_expected_minute.v2026-06-14. | Resolves to the XP Expected-Minute Unit policy on this page. | Omitted while effort fields are returned, or replaced by a client constant. | alpha.policy.analytics.xp_expected_minute.v2026-06-14 |
Policy reference aitd-018-goals-school-days-remaining, aitd-007-xp-rollups |
xp_unit.xp_per_expected_minute |
NUMERIC(8,3) required |
How many XP equal one expected minute. | Current value is 1.000. It is policy, not a client constant. | Used to compute effort.expected_minutes_remaining. | GOALS hard-codes a different value or infers it from observed student actuals. | 1.000 |
Policy response value aitd-018-goals-school-days-remaining, aitd-007-xp-rollups, aitd-011-policy-and-enum-normalization |
xp_unit.xp_per_hour |
NUMERIC(8,3) required |
How many XP equal one expected hour. | Current value is 60.000. Derived from 1 XP per expected minute and 60 minutes per hour. | Used to compute effort.hours_remaining. | Hard-coded in a skill pack or GOALS client instead of read from the surface. | 60.000 |
Policy response value aitd-018-goals-school-days-remaining, aitd-007-xp-rollups, aitd-011-policy-and-enum-normalization |
xp_unit.meaning |
TEXT required |
Plain-language statement of the XP expected-minute convention. | Must state 1 XP = 1 expected minute and 60 XP = 1 expected hour. | Allows parent-readable docs and skill packs to explain the conversion without source code. | Absent or inconsistent with xp_per_expected_minute/xp_per_hour. | 1 XP = 1 expected minute; 60 XP = 1 expected hour. |
Policy response text aitd-018-goals-school-days-remaining, aitd-007-xp-rollups |
effort.xp_remaining |
NUMERIC(14,3) nullable unless request supplies xpRemaining |
Remaining XP supplied by the caller or read from related XP rollup flow for effort projection. | Nonnegative when present. Mutually exclusive request inputs xpRemaining, minutesRemaining, and hoursRemaining collapse to expected_minutes_remaining. | Same XP unit convention as alpha.analytics_xp_rollup.xp_remaining. | Negative, or derived by GOALS from a private XP goal formula. | 600.000 |
Request-derived effort value aitd-018-goals-school-days-remaining, aitd-007-xp-rollups |
effort.expected_minutes_remaining |
NUMERIC(14,3) nullable unless any effort input is supplied |
Remaining effort normalized to expected minutes under the XP expected-minute policy. | Nonnegative when present. | Source for hours_remaining and pacing fields. | Computed locally with a private XP_PER_HOUR constant. | 600.000 |
Derived response value aitd-018-goals-school-days-remaining, aitd-007-xp-rollups |
effort.hours_remaining |
NUMERIC(14,3) nullable unless any effort input is supplied |
Remaining effort in expected hours. | expected_minutes_remaining / 60 under xp_unit.xp_per_hour. | GOALS hours-to-target-date display. | Computed locally or rounded differently from the surface. | 10.000 |
Derived response value aitd-018-goals-school-days-remaining, aitd-007-xp-rollups |
effort.target_date |
DATE nullable unless targetDate is supplied |
Requested target date for required-hours-per-school-day projection. | Must be after as_of and on or before end_date when supplied. | Alias of request targetDate. | Before/as_of or after the requested end_date. | 2026-07-24 |
Request-derived response field aitd-018-goals-school-days-remaining |
effort.school_days_until_target_date |
INTEGER nullable unless targetDate is supplied |
Instructional days from as_of through the target-date window according to the same school-day policy. | Nonnegative; uses the same half-open counting convention against targetDate as the endpoint documents. | Denominator for required_hours_per_school_day_to_target_date. | Counts calendar days, weekdays, or dates outside instructional_dates. | 29 |
Derived response value aitd-018-goals-school-days-remaining, aitd-006-school-day-minutes |
effort.required_hours_per_school_day_to_target_date |
NUMERIC(12,3) nullable unless targetDate and effort are supplied and target window has school days |
Expected hours per remaining instructional day needed to finish by targetDate. | hours_remaining / school_days_until_target_date; null when school_days_until_target_date=0. | GOALS target-date pacing value. | Computed over calendar days or rounded in client code. | 0.345 |
Derived response value aitd-018-goals-school-days-remaining, aitd-007-xp-rollups |
effort.hours_per_school_day |
NUMERIC(12,3) nullable unless request supplies hoursPerSchoolDay |
Caller-supplied planned expected hours per instructional day. | Must be positive when supplied. | Input for school_days_needed_at_hours_per_school_day. | Zero, negative, or interpreted as clock-hours available on non-school days. | 1.500 |
Request-derived effort value aitd-018-goals-school-days-remaining |
effort.school_days_needed_at_hours_per_school_day |
INTEGER nullable unless hoursPerSchoolDay and effort are supplied |
Instructional-day count needed to finish at the supplied pace. | ceil(hours_remaining / hoursPerSchoolDay). | GOALS date-at-pace calculation. | Counts weekdays or rounds down. | 7 |
Derived response value aitd-018-goals-school-days-remaining, aitd-007-xp-rollups |
effort.target_date_at_hours_per_school_day |
DATE nullable unless the supplied pace finishes inside the requested window |
Instructional date reached at the supplied pace. | Must be one of instructional_dates when present; null when the window is too short. | GOALS predicted finish date at the supplied pace. | Falls on a non-school/MAP day or after end_date without null/false finish status. | 2026-06-23 |
Derived response value aitd-018-goals-school-days-remaining, aitd-006-school-day-minutes, aitd-007-xp-rollups |
effort.can_finish_by_end_date_at_hours_per_school_day |
BOOLEAN nullable unless hoursPerSchoolDay and effort are supplied |
Whether the supplied pace finishes within the requested forward window. | True only when school_days_needed_at_hours_per_school_day <= instructional_days_remaining. | GOALS finishability flag. | True while target_date_at_hours_per_school_day is null. | true |
Derived response value aitd-018-goals-school-days-remaining, aitd-007-xp-rollups |
provenance.source |
TEXT required |
Plain source statement for the calendar/enrollment rows behind the response. | Must name alpha.school_calendar over Ed-Fi CalendarDate and People and Orgs enrollment. | Points readers to the raw-DB path without exposing PII payloads. | Claims weekday math or a private GOALS school-period table as the source. | alpha.school_calendar over ed_fi.CalendarDate plus People and Orgs enrollment |
Provenance response field aitd-018-goals-school-days-remaining, aitd-006-school-day-minutes |
provenance.source_ref_sample |
TEXT[] nullable |
Opaque sample refs for calendar rows used by the read. | May include refs/hashes only; no raw calendar payload or student PII. | Audit pointer for operators. | Contains raw source rows or student names/emails. | ["calendar_date:school_alpha_austin:2026-06-15"] |
Provenance response field aitd-018-goals-school-days-remaining, aitd-111-axis-privacy-retention |
provenance.policy_ref |
TEXT required |
School-day policy ref used for the calendar count. | Must match school_day_policy_ref. | Audit-friendly duplicate for the provenance block. | Differs from school_day_policy_ref. | alpha.policy.school_day.v2026-06-10 |
Policy provenance field aitd-018-goals-school-days-remaining, aitd-006-school-day-minutes |
provenance.xp_unit_policy_ref |
TEXT required |
The rulebook version Analytics used; see Policy Reference on this page. XP expected-minute policy ref used for effort projection. |
Must match alpha.policy.analytics.xp_expected_minute.v2026-06-14. | Audit-friendly pointer to the XP unit policy. | Missing while effort or xp_unit fields are returned. | alpha.policy.analytics.xp_expected_minute.v2026-06-14 |
Policy provenance field aitd-018-goals-school-days-remaining, aitd-007-xp-rollups |
links.self |
URL required |
The request URL for this read. | Must preserve the effective query parameters used to produce the answer. | Useful for skill-pack reproduction and support. | Missing or points at a stale/non-equivalent query. | /alpha/analytics/v1/school-days-remaining?studentId=student_01HT7G3YZV7QB5N4YKQ1K0Z9A9&asOf=2026-06-14&endDate=2026-07-24 |
Response link aitd-018-goals-school-days-remaining, aitd-102-axis-read-shape |
links.schoolDayMinutes |
URL required |
Related consumed-day rollup endpoint for past Time Commitment rows. | This is a related link, not the source for future-day counts. | Points to alpha.analytics_school_day_minutes when a report also needs consumed days. | Used to answer future school-days remaining when no consumed-day row exists. | /alpha/analytics/v1/school-day-minutes?studentId=student_01HT7G3YZV7QB5N4YKQ1K0Z9A9&windowKind=school_year |
Response link aitd-018-goals-school-days-remaining, aitd-006-school-day-minutes |
links.xpRollups |
URL required |
Related XP rollup endpoint for XP total/remaining/goal rows. | GOALS may use the rollup to obtain xp_remaining, then pass it into this endpoint for effort projection. | Points to alpha.analytics_xp_rollup. | Used as permission to calculate XP goal fields locally. | /alpha/analytics/v1/xp-rollups?studentId=student_01HT7G3YZV7QB5N4YKQ1K0Z9A9&windowKind=school_year |
Response link aitd-018-goals-school-days-remaining, aitd-007-xp-rollups |
analytics.grade_level_status
GOALS age-grade status without local comparison logic: exactly two named comparisons, working vs age grade and mastered vs age grade.
Architecture trace: aitd-102-axis-read-shape, aitd-008-mastery-and-grade-levels, aitd-011-policy-and-enum-normalization, aitd-112-axis-list-endpoints
GOALS age-grade status GOALS ahead/at/behindGET /alpha/analytics/v1/grade-level-statusExample Object Payload
Concrete reportable payload for this object. Required fields in the field list must appear here unless their nullability explicitly allows omission.
{
"object": "analytics.grade_level_status",
"student_id": "b6fa7128-f641-4efd-9075-375411fd6c39",
"subject_id": "math",
"as_of_date": "2026-05-20",
"age_grade": 5,
"working_grade": 6,
"highest_mastered_grade": 5,
"working_age_grade_delta": 1,
"working_age_grade_status": "working_above_age_grade",
"mastered_age_grade_delta": 0,
"mastered_age_grade_status": "mastered_at_age_grade",
"source_refs": {
"age_grade": "people_and_orgs.alpha.age_grade_history",
"working_grade": "results.student_track_state.working_grade",
"highest_mastered_grade": "results.highest_mastered_grade"
},
"deprecated_aliases": {
"instructional_level_status": "working_age_grade_status",
"strict_mastery_status": "mastered_age_grade_status"
}
}
Lifecycle
Read-time response assembled from People and Orgs alpha.age_grade_history plus Results working_grade and highest_mastered_grade. Analytics returns the comparison labels; it does not store roster age grade or own the Results grade state.
Raw DB Rule
Read age_grade from People and Orgs alpha.age_grade_history where begin_date <= :asOfDate and (:asOfDate < end_date or end_date is null). Read working_grade and highest_mastered_grade from Results for the same student/subject/asOfDate. Compute only the two named deltas and labels. Never infer age grade from birthdays, prior-year close, MAP/RIT/R90, working grade, HMG, or course placement.
Formula
working_age_grade_delta = working_grade - age_grade. mastered_age_grade_delta = highest_mastered_grade - age_grade. Positive deltas map to *_above_age_grade, zero maps to *_at_age_grade, negative maps to *_behind_age_grade. Null inputs return unknown status and null delta.
Field Index
Fields
| Field | Type / Nullability | Meaning | Constraints / Range | Relationship | Invalid When | Example | Source / ITD |
|---|---|---|---|---|---|---|---|
object |
TEXT required |
Response object discriminator for this endpoint. | Always analytics.grade_level_status. | Lets docs, skill packs, and contract checks identify the response shape. | Missing or replaced by a generic status object. | analytics.grade_level_status |
Analytics response metadata aitd-102-axis-read-shape |
student_id |
TEXT required |
Canonical Alpha student id used to read P&O age grade and Results grade positions. | Must resolve to the same student across People and Orgs and Results source tenants. | References People and Orgs identity (https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/data_dictionary) and Results student state (https://platform3-andymontgomery-9773s-projects.vercel.app/results/alpha/data_dictionary). | Name/email/local app id is used directly. | b6fa7128-f641-4efd-9075-375411fd6c39 |
Alpha extension reference aitd-102-axis-read-shape, aitd-109-axis-tenant-routing |
subject_id |
TEXT enum required |
Canonical subject for Results working grade and HMG lookup. | Use Analytics/Results governed subject ids; subject aliases normalize at the platform boundary. | Same governed subject id family as other Analytics report endpoints. | Parsed from MAP test names or course titles by a client. | math |
Request-derived response field aitd-011-policy-and-enum-normalization |
as_of_date |
DATE required |
Date used for the point-in-time P&O age-grade row and Results state read. | ISO date. The response does not default age grade from a current-only scalar. | Drives the effective-dated age-grade and Results state reads. | Ignored or replaced by server-now without provenance. | 2026-05-20 |
Request-derived response field aitd-102-axis-read-shape |
age_grade |
INTEGER nullable when P&O has no active age-grade history row |
Student's school-assigned cohort grade for school-year reporting as of as_of_date. | Source of truth is People and Orgs alpha.age_grade_history. Never infer from MAP/RIT, birthday, working grade, HMG, course placement, or current-only alpha.person.age_grade. | Owned by People and Orgs alpha.age_grade_history; see https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/data_dictionary#table-alpha-age-grade-history. | Computed from achievement, parsed from labels, or copied into Results. | 5 |
People and Orgs source fact aitd-102-axis-read-shape, aitd-011-policy-and-enum-normalization |
working_grade |
INTEGER nullable when Results has no working-grade state |
Results-owned working grade for the subject and as_of_date. | Read from Results; Analytics does not recompute the working-grade resolver. | Owned by Results student track state; see https://platform3-andymontgomery-9773s-projects.vercel.app/results/alpha/data_dictionary. | Derived from MAP/RIT/R90 or duplicated into P&O. | 6 |
Results source fact aitd-008-mastery-and-grade-levels, aitd-102-axis-read-shape |
highest_mastered_grade |
INTEGER nullable when Results has no HMG state |
Results-owned highest mastered grade for the subject and as_of_date. | Read from Results; strict mastery-vs-age status uses this field directly. | Owned by Results highest-mastered state; see https://platform3-andymontgomery-9773s-projects.vercel.app/results/alpha/data_dictionary. | Inferred from working grade without Results provenance. | 5 |
Results source fact aitd-008-mastery-and-grade-levels, aitd-102-axis-read-shape |
working_age_grade_delta |
INTEGER nullable when age_grade or working_grade is missing |
Signed difference between working_grade and age_grade. | Formula: working_grade - age_grade. | Drives working_age_grade_status. | Computed against HMG or MAP-inferred grade position. | 1 |
Derived response value aitd-102-axis-read-shape |
working_age_grade_status |
TEXT enum required |
Named working-vs-age status. | Allowed values: working_behind_age_grade, working_at_age_grade, working_above_age_grade, unknown. | Preferred GOALS ahead/at/behind status field. | Replaced by generic ahead/at/behind or instructional_level_status as preferred public contract. | working_above_age_grade |
Derived response label aitd-102-axis-read-shape, aitd-011-policy-and-enum-normalization |
mastered_age_grade_delta |
INTEGER nullable when age_grade or highest_mastered_grade is missing |
Signed difference between highest_mastered_grade and age_grade. | Formula: highest_mastered_grade - age_grade. | Drives mastered_age_grade_status. | Computed from working grade or MAP-inferred grade position. | 0 |
Derived response value aitd-102-axis-read-shape |
mastered_age_grade_status |
TEXT enum required |
Named strict mastery-vs-age status. | Allowed values: mastered_behind_age_grade, mastered_at_age_grade, mastered_above_age_grade, unknown. | Separate qualified read from working_age_grade_status. | Used as the default GOALS working status or hidden under generic mastery_level_status. | mastered_at_age_grade |
Derived response label aitd-102-axis-read-shape, aitd-011-policy-and-enum-normalization |
source_refs |
JSON object required |
Machine-readable owner pointers for the facts used by the response. | Must name P&O for age grade and Results for working/HMG. | Prevents clients and doers from moving ownership into Analytics. | Missing, names Analytics as the owner of age_grade/HMG, or points at MAP/RIT. | {"age_grade":"people_and_orgs.alpha.age_grade_history","working_grade":"results.student_track_state.working_grade","highest_mastered_grade":"results.highest_mastered_grade"} |
Provenance response field aitd-004-provenance-no-literals, aitd-102-axis-read-shape |
deprecated_aliases |
JSON object nullable compatibility block |
Compatibility mapping for old field names; not the preferred public contract. | If served, instructional_level_status delegates to working_age_grade_status and strict_mastery_status delegates to mastered_age_grade_status. | Allows old consumers to migrate without reintroducing generic status terminology. | Documented as preferred or computed with different formulas. | {"instructional_level_status":"working_age_grade_status","strict_mastery_status":"mastered_age_grade_status"} |
Compatibility metadata aitd-102-axis-read-shape, aitd-011-policy-and-enum-normalization |
Enums Used Here
subject_id | |||
|---|---|---|---|
| Value | Meaning | Source | ITD |
math | Math subject rollups and MAP/math source-label normalization. | Alpha/Curriculum governed enum | aitd-011-policy-and-enum-normalization |
reading | Reading subject rollups. | Alpha/Curriculum governed enum | aitd-011-policy-and-enum-normalization |
language | Language / ELA subject rollups. Public reads keep vocabulary and writing as distinct canonical subjects. | Alpha/Curriculum governed enum | aitd-011-policy-and-enum-normalization |
science | Science subject rollups. | Alpha/Curriculum governed enum | aitd-011-policy-and-enum-normalization |
vocabulary | Vocabulary activity rollups as the canonical vocabulary subject. | Alpha/Curriculum governed enum | aitd-011-policy-and-enum-normalization |
writing | Writing activity rollups as the canonical writing subject. | Alpha/Curriculum governed enum | aitd-011-policy-and-enum-normalization |
alpha.analytics_completion_rollup
Progress evidence for Results and Analytics audits without MAP/RIT/R90 inference, client-side Curriculum tree walking, or Results-row counting.
alpha.policy.analytics.completion_rollup_retention.v2026-07-03. Current readback: reviewer-analytics has 1606 current rows and 0 superseded rows.Architecture trace: aitd-010-completion-rollups, aitd-001-report-source-ingestion, aitd-004-provenance-no-literals, aitd-003-close-time-materialization, aitd-011-policy-and-enum-normalization
completion|curriculum refsGET /alpha/analytics/v1/completion-rollupsExample Object Payload
Concrete reportable payload for this object. Required fields in the field list must appear here unless their nullability explicitly allows omission.
{
"id": "6d7d3b01-6b70-44ce-90dd-e7cf2f690006",
"tenant_id": "7b0bb5d8-9a38-4a62-9fdc-9f8d2dc1a111",
"student_id": "student_01HT7G3YZV7QB5N4YKQ1K0Z9A9",
"completion_scope": "course",
"scope_id": "course_math_grade_4_powerpath",
"subject_id": "math",
"grade_level": 4,
"is_main_course": true,
"progress_source_kind": "app_reported_percent",
"window_start": "2026-01-01",
"window_end": "2026-06-01",
"xp_earned": null,
"xp_remaining": null,
"completion_percent": 75,
"denominator_policy_ref": "alpha.policy.analytics.course_progress.v2026-06-15",
"source_import_id": "imp_01HT8COMPLETION_2026_SPRING",
"curriculum_scope_refs": [
"course_component_01HT8ROOT",
"progress_source:app_reported_percent",
"course_role:main",
"grade_level:4"
],
"policy_ref": "alpha.policy.analytics.course_progress.v2026-06-15",
"null_reason": "none",
"quality_status": "ok",
"calculation_version": 1,
"computed_at": "2026-06-01T01:03:00Z",
"modified_at": "2026-06-01T01:03:00Z",
"superseded_at": null,
"source_deleted_at": null
}
Lifecycle
Materialized when Events preserves app-reported course progress percent, or when the timeback-completion adapter ingests XP/remaining-XP fallback rows. Grade-level rows are derived from main-course course rows only.
Raw DB Rule
Raw readers use this table for progress evidence and reconciliation. Course rows prefer app-reported Caliper percent_complete, then XP remaining; grade_level rows preserve main-course evidence only. Student-facing progress reads come from Results. Raw readers do not derive actual progress from MAP/RIT/R90, count result rows, walk course components, or invent a percent from activity evidence.
Field Index
Fields
| Field | Type / Nullability | Meaning | Constraints / Range | Relationship | Invalid When | Example | Source / ITD |
|---|---|---|---|---|---|---|---|
id |
UUID required |
Analytics-owned stable row id for this derived fact. | Generated by the platform; globally unique within alpha.analytics_* objects. | Primary key for list/detail endpoints. | Provided by a public import client or reused across tenants. | 8e9c0ef2-bc75-4f53-8124-df77df49f25f |
Alpha extension aitd-000-extend-only-storage |
tenant_id |
UUID required |
Tenant boundary for the derived fact. | Set from the JWT tenant claim or internal materializer context; never accepted from request body/query. | All raw-path queries must filter by tenant_id before joining, sorting, paging, or counting. | Missing, caller-supplied in body/query, or mismatched with the JWT tenant claim. | 7b0bb5d8-9a38-4a62-9fdc-9f8d2dc1a111 |
Alpha extension aitd-109-axis-tenant-routing, aitd-106-axis-auth-shape |
student_id |
TEXT required |
Canonical Alpha student id the source Event or Result resolved to at materialization time. | Must resolve through People and Orgs as a real student for the source timestamp/effective date. | References People and Orgs student identity; see https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/data_dictionary. | Parsed from email/name/source payload instead of resolved by the Events/Results adapter. | student_01HT7G3YZV7QB5N4YKQ1K0Z9A9 |
Alpha extension reference aitd-003-close-time-materialization, aitd-106-axis-auth-shape, aitd-011-policy-and-enum-normalization |
completion_scope |
TEXT enum required |
Curriculum/reporting scope for this completion measure. | Allowed values: completion_scope enum. | Determines what scope_id points to. | A consumer invents separate columns per course/track/segment instead of using the typed scope. | course |
Alpha extension aitd-010-completion-rollups, aitd-011-policy-and-enum-normalization |
scope_id |
TEXT required |
Identifier of the Curriculum or subject scope being measured. | Must match completion_scope: course id for course, subject id for subject, track id for track, etc. | References Curriculum scope refs; see https://platform3-andymontgomery-9773s-projects.vercel.app/curriculum/alpha/data_dictionary. | A report walks the course tree and generates its own scope id. | course_math_grade_4_powerpath |
Alpha extension reference aitd-000-extend-only-storage, aitd-010-completion-rollups |
subject_id |
TEXT nullable; required when completion_scope=subject or the scope resolves to one subject |
Canonical Alpha subject used for reporting and grouping. | Closed Alpha subject enum after write-time source-label normalization; unknown source subject becomes an adapter finding or null_reason, not a new string. | References the Curriculum/Results subject vocabulary; see https://platform3-andymontgomery-9773s-projects.vercel.app/curriculum/alpha/data_dictionary and https://platform3-andymontgomery-9773s-projects.vercel.app/results/alpha/data_dictionary. | Copied from source strings such as FastMath, Vocabulary, Science-notqced, or ISEE variants without normalization. | math |
Alpha extension reference aitd-011-policy-and-enum-normalization |
grade_level |
INTEGER nullable for non-grade-level scopes without a course grade |
Working grade level associated with the course progress row, or the grade represented by a grade_level aggregate. | Must come from the course/Caliper/Curriculum scope metadata, not from MAP/RIT/R90. | GOALS filters grade-level progress by this typed field. | Derived from RIT, R90, effective_grade, or a private placement table. | 4 |
Alpha extension aitd-010-completion-rollups, aitd-011-policy-and-enum-normalization |
is_main_course |
BOOLEAN nullable when not applicable; true for main course and grade_level aggregate rows |
Whether the course row counts toward grade-level progress. | Main grade-level courses count; remediation, hole-filling, catalog, practice, and review courses do not. | Defines the denominator for completion_scope=grade_level rows. | Unset on a course row that contributes to grade-level progress, or true for a hole-filling/remediation/catalog course. | true |
Alpha extension aitd-010-completion-rollups, aitd-011-policy-and-enum-normalization |
progress_source_kind |
TEXT enum required for reportable progress rows |
Which evidence source produced completion_percent. | Allowed values include app_reported_percent, xp_remaining, lesson_count, subject_aggregate, and main_course_aggregate. | Explains whether a row came directly from the app, an XP fallback, or an Analytics aggregate. | Missing on a reportable completion row or used to hide MAP/RIT/R90-derived progress. | app_reported_percent |
Alpha extension enum aitd-010-completion-rollups, aitd-011-policy-and-enum-normalization |
window_start |
DATE required |
Inclusive start date for Results evidence included in completion. | ISO date; half-open with window_end. | Defines the report interval. | Uses source import time or current term label. | 2026-01-01 |
Alpha extension aitd-010-completion-rollups |
window_end |
DATE required |
Exclusive end date for Results evidence included in completion. | ISO date; must be after window_start. | Defines the report interval. | Treated as inclusive in raw queries. | 2026-06-01 |
Alpha extension aitd-010-completion-rollups |
xp_earned |
NUMERIC(14,3) nullable when progress_source_kind is app_reported_percent or an aggregate without XP evidence |
Earned XP that counts toward this course or scope. Earned XP for this completion scope when the row uses the XP fallback. |
Nonnegative when present; source corrections are reflected through quality_status/corrections before this value is reportable. | Fallback numerator for completion_percent; direct app percent rows may leave XP fields null. | Computed by a consumer from active days, activity flags, passed result counts, or processed_facts rows. | null |
Alpha extension aitd-010-completion-rollups, aitd-001-report-source-ingestion |
xp_remaining |
NUMERIC(14,3) nullable when progress_source_kind is app_reported_percent or an aggregate without XP evidence |
Expected XP still remaining in this course or scope. Remaining expected XP for this completion scope when the row uses the XP fallback. |
Nonnegative when present; computed from Curriculum expected XP refs under denominator_policy_ref. | Fallback denominator complement for completion_percent. Direct app percent rows may leave XP fields null. | A report walks Curriculum trees or hard-codes expected XP locally. | null |
Alpha extension aitd-010-completion-rollups |
completion_percent |
NUMERIC(7,3) nullable when no direct percent, XP denominator, lesson denominator, or source/policy is available |
The Analytics progress-evidence percent; student-facing reports should use Results course-progress or grade-level-progress for the final answer. Report-ready completion measure for the scope. |
Direct app percent wins. If absent, fallback formula is xp_earned / (xp_earned + xp_remaining) * 100. Normally 0 to 100; null requires null_reason. | The value dashboards and skill packs render. | Consumer divides local counts, treats any activity as complete, returns 1-if-active, or derives progress from MAP/RIT/R90. | 75.000 |
Alpha extension aitd-010-completion-rollups |
denominator_policy_ref |
TEXT required |
The rulebook version Analytics used; see Policy Reference on this page. Policy that decides which Curriculum expected-XP refs belong in the remaining-XP denominator. |
Named versioned progress policy, for example alpha.policy.analytics.course_progress.v2026-06-15 or alpha.policy.curriculum.main_course_grade_level.v2026-06-15, or inherited Curriculum policy. | Keeps Curriculum scope decisions on the surface. | A report carries its own course tree filter or expected-XP lookup table. | alpha.policy.analytics.course_progress.v2026-06-15 |
Alpha extension reference aitd-010-completion-rollups, aitd-011-policy-and-enum-normalization |
curriculum_scope_refs |
JSONB required |
Compact ids/cursor for Curriculum refs used to form the denominator. | Refs/hashes only; never copies Curriculum trees or Content rows. | Authorized sourceRefs audit view. | Duplicates course_component hierarchy in Analytics. | ["course_component_01HT8ROOT", "kc_math_fraction_addition"] |
Alpha extension reference list aitd-000-extend-only-storage, aitd-010-completion-rollups, aitd-102-axis-read-shape |
source_import_id |
TEXT required for report-tile rows; nullable for purely derived event-axis rows |
Analytics source-import receipt that proves which named report-source adapter produced this report-grade fact. | Must reference alpha.analytics_source_import for non-null Learning Report tile values; no literal or fixture value may be reportable without this provenance. | Many report-fact rows can reference one source import; detail/sourceRefs endpoints join here for adapter, source_table, and source_row_key_hashes. | Missing on a non-null report-tile value, or replaced by copied raw reporting-DB columns. | imp_01HT8COMPLETION_2026_SPRING |
Alpha extension provenance reference aitd-001-report-source-ingestion, aitd-004-provenance-no-literals, aitd-010-completion-rollups |
null_reason |
TEXT enum required |
Why the report value is missing instead of asking an app to guess. Why completion_percent is null or not reportable. |
Allowed values: null_reason enum; none means the metric is populated. | Prevents client fallback completion math. | Null completion_percent with no typed explanation. | none |
Alpha extension aitd-010-completion-rollups, aitd-011-policy-and-enum-normalization |
policy_ref |
TEXT required |
The rulebook version Analytics used; see Policy Reference on this page. Named policy/config version used to compute the measure or rollup. |
Must point at alpha.policy.analytics.* or an inherited Curriculum/Results policy active for the source effective date. | Many Analytics facts can share one policy row; changing policy creates new calculation versions or corrections. | A consumer hard-codes thresholds, school-day calendars, Growth X formulas, or completion denominators instead of using the policy ref. | alpha.policy.analytics.course_progress.v2026-06-15 |
Alpha extension reference aitd-010-completion-rollups, aitd-011-policy-and-enum-normalization |
quality_status |
TEXT enum required |
Whether this row is reportable, corrected, reversed, blocked, or rejected. Current materialization quality state for this fact. |
Allowed values: quality_status enum. Ordinary report reads keep ok, corrected, and signed reversed rows according to the table rule; audit reads may include source_missing/source_unlinked/policy_pending/adapter_rejected. | Used by raw/API convergence filters and source-ref audit views. | Free-text status or hidden failures represented as HTTP 200 success. | ok |
Alpha extension aitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope, aitd-111-axis-privacy-retention |
calculation_version |
INTEGER required |
Materializer calculation version for this fact shape. | Positive integer; starts at 1 and increments when policy/materializer logic intentionally changes. | Part of deterministic source_fact_key/idempotency for materializer writes. | Omitted from replay keys or changed without a new policy/materializer decision. | 1 |
Alpha extension aitd-003-close-time-materialization, aitd-105-axis-idempotency, aitd-104-axis-concurrency |
computed_at |
TIMESTAMPTZ required |
When Analytics wrote this derived fact. | UTC timestamp with timezone; updated only by Analytics materializers. | Used for audit and source-ref subcollections, not for school-day grouping. | Used as a substitute for the source event time, result effective time, or window boundaries. | 2026-06-10T00:51:14Z |
Alpha extension aitd-003-close-time-materialization |
modified_at |
TIMESTAMPTZ required |
Last time the Analytics row changed for polling and modifiedSince queries. | UTC timestamp; list endpoints support modifiedSince against this field. | Supports poll plus modifiedSince eventing. | Client-supplied or used as the business effective date. | 2026-06-10T00:51:14Z |
Alpha extension aitd-107-axis-eventing, aitd-103-axis-query-model |
superseded_at |
TIMESTAMPTZ nullable |
When this row stopped being the current reportable version because of source correction, deletion, or recalculation. | Null means current; non-null rows are excluded from ordinary list reads unless includeSuperseded=true and authorized. | Preserves audit history without mutating source Events or Results. | Used to hard-delete old rows or omitted on a correction that replaces a prior fact. | null |
Alpha extension aitd-111-axis-privacy-retention, aitd-012-corrections-and-reversals |
source_deleted_at |
TIMESTAMPTZ nullable |
When the source Event/Result became deleted or invalidated. | Null for live source rows; set from source tombstone/correction notifications. | Ordinary reads exclude tombstoned facts unless includeSuperseded=true and authorized. | Used as a physical delete or ignored by raw-path report queries. | null |
Alpha extension aitd-111-axis-privacy-retention |
Enums Used Here
completion_scope | |||
|---|---|---|---|
| Value | Meaning | Source | ITD |
course | Completion for one course. | Alpha extension enum | aitd-010-completion-rollups, aitd-011-policy-and-enum-normalization |
subject | Completion for all expected work in one subject. | Alpha extension enum | aitd-010-completion-rollups, aitd-011-policy-and-enum-normalization |
track | Completion for a full track. | Alpha extension enum | aitd-010-completion-rollups, aitd-011-policy-and-enum-normalization |
track_level | Completion for one level inside a track. | Alpha extension enum | aitd-010-completion-rollups, aitd-011-policy-and-enum-normalization |
grade_level | Progress evidence across the main courses that make up one grade level; the student-facing answer is served by Results. | Alpha extension enum | aitd-010-completion-rollups, aitd-011-policy-and-enum-normalization |
segment | Completion for one curriculum segment. | Alpha extension enum | aitd-010-completion-rollups, aitd-011-policy-and-enum-normalization |
null_reason | |||
|---|---|---|---|
| Value | Meaning | Source | ITD |
none | No null-producing condition applies. | Alpha extension enum | aitd-011-policy-and-enum-normalization |
no_school_days | The denominator window has zero enrolled school days after calendar and enrollment intersection. | Alpha extension enum | aitd-011-policy-and-enum-normalization |
no_questions | The window has zero reportable question attempts, so accuracy_percent is null rather than guessed as 0 or 100. | Alpha extension enum | aitd-011-policy-and-enum-normalization |
no_enrollment | The student has no time-locatable enrollment for the requested range. | Alpha extension enum | aitd-011-policy-and-enum-normalization |
no_subject_assignment | The student had no subject assignment/course/test membership for the subject denominator. | Alpha extension enum | aitd-011-policy-and-enum-normalization |
source_missing | Required Event, Result, calendar, enrollment, or curriculum source evidence is missing. | Alpha extension enum | aitd-011-policy-and-enum-normalization |
source_unlinked | Source evidence exists but cannot be linked to platform ids under the current policy. | Alpha extension enum | aitd-011-policy-and-enum-normalization |
policy_pending | The named policy needed to compute the measure is missing or not active. | Alpha extension enum | aitd-011-policy-and-enum-normalization |
not_applicable | The metric does not apply at this grain, such as MAP growth for a non-MAP subject. | Alpha extension enum | aitd-011-policy-and-enum-normalization |
quality_status | |||
|---|---|---|---|
| Value | Meaning | Source | ITD |
ok | The row is the current reportable fact for its key and policy. | Alpha extension enum | aitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope, aitd-111-axis-privacy-retention |
corrected | The row includes a correction contribution but remains reportable. | Alpha extension enum | aitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope, aitd-111-axis-privacy-retention |
reversed | The row reverses a prior contribution and should be read as signed history. | Alpha extension enum | aitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope, aitd-111-axis-privacy-retention |
source_missing | A required source row was removed or unavailable before the fact could be finalized. | Alpha extension enum | aitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope, aitd-111-axis-privacy-retention |
source_unlinked | The source row exists but could not link to a required Event, Result, student, subject, KC, course, or policy ref. | Alpha extension enum | aitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope, aitd-111-axis-privacy-retention |
policy_pending | A required policy configuration was missing or not yet active at materialization time. | Alpha extension enum | aitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope, aitd-111-axis-privacy-retention |
adapter_rejected | The source-shaped row was valid input but the server-side adapter rejected it with a typed Problem. | Alpha extension enum | aitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope, aitd-111-axis-privacy-retention |
alpha.analytics_source_import
Provenance spine for every ingested report-grade fact: adapter, source system/table, idempotency key, source-row natural-key/hash set, materialized counts, and per-row Problem summaries.
Architecture trace: aitd-001-report-source-ingestion, aitd-004-provenance-no-literals, aitd-101-axis-write-granularity, aitd-105-axis-idempotency, aitd-108-axis-error-envelope
all metric checksPOST /alpha/analytics/v1/source-imports/{adapter} and GET /alpha/analytics/v1/source-importsExample Object Payload
Concrete reportable payload for this object. Required fields in the field list must appear here unless their nullability explicitly allows omission.
{
"import_id": "imp_01HT8ANALYTICS",
"tenant_id": "7b0bb5d8-9a38-4a62-9fdc-9f8d2dc1a111",
"import_kind": "timeback-xp-time-accuracy",
"adapter_name": "timeback-xp-time-accuracy",
"source_system": "reporting",
"source_table": "processed_facts",
"status": "materialized",
"idempotency_key_hash": "sha256:4b463adfe0...",
"source_batch_ref": "migration-2026-06-10-reporting-processed-facts-001",
"source_payload_hash": "sha256:91f25d7371...",
"source_row_key_hashes": [
"sha256:rowkey001...",
"sha256:rowkey002..."
],
"submitted_row_count": 5000,
"accepted_row_count": 4970,
"materialized_row_count": 4970,
"rejected_row_count": 30,
"problem_counts": {
"analytics:adapter_rejected": 30
},
"received_at": "2026-06-10T00:55:00Z",
"completed_at": "2026-06-10T00:56:12Z",
"modified_at": "2026-06-10T00:56:12Z"
}
Lifecycle
Created by POST /source-imports/{adapter} for timeback-xp-time-accuracy, timeback-map, timeback-grade-mastery, or timeback-completion, or by internal event/result replay jobs; completed when rows are materialized or rejected with typed Problems.
Raw DB Rule
Raw migration checks count materialized Analytics rows plus source_import provenance, not submitted source rows. HTTP 200/202 means accepted processing only as documented; validation and adapter rejection use typed Problems.
Field Index
Fields
| Field | Type / Nullability | Meaning | Constraints / Range | Relationship | Invalid When | Example | Source / ITD |
|---|---|---|---|---|---|---|---|
import_id |
TEXT required |
Stable id for this source import request. | Generated by platform; unique per tenant. | Primary key and detail endpoint id. | Caller-supplied to overwrite a prior import. | imp_01HT8ANALYTICS |
Alpha extension aitd-001-report-source-ingestion |
tenant_id |
UUID required |
Tenant boundary for the derived fact. | Set from the JWT tenant claim or internal materializer context; never accepted from request body/query. | All raw-path queries must filter by tenant_id before joining, sorting, paging, or counting. | Missing, caller-supplied in body/query, or mismatched with the JWT tenant claim. | 7b0bb5d8-9a38-4a62-9fdc-9f8d2dc1a111 |
Alpha extension aitd-109-axis-tenant-routing, aitd-106-axis-auth-shape |
import_kind |
TEXT enum required |
Which source/replay contract this batch follows. | Allowed values: import_kind enum. | Selects the server-side adapter/materializer. | Generic upload with caller-provided normalized metric rows. | timeback-xp-time-accuracy |
Alpha extension aitd-001-report-source-ingestion, aitd-101-axis-write-granularity |
adapter_name |
TEXT required |
Named server-side adapter that normalized this source batch. | Must match one approved adapter: timeback-xp-time-accuracy, timeback-map, timeback-grade-mastery, or timeback-completion, plus internal replay kinds where applicable. | Selects the source-table contract and normalization rules; no client-computed metric values are accepted. | Generic import, free-text adapter names, or client-chosen formulas. | timeback-xp-time-accuracy |
Alpha extension aitd-001-report-source-ingestion, aitd-101-axis-write-granularity |
source_system |
TEXT required |
Producer system the adapter read from. | Closed governed values for approved adapters: reporting, events, results, migration_reconcile. | Audits whether a fact came from report-source ingestion or internal derived replay. | Raw database URL, credentials, or ungoverned free text. | reporting |
Alpha extension aitd-001-report-source-ingestion, aitd-004-provenance-no-literals |
source_table |
TEXT required for report-source adapters |
Report-source table or producer collection read by the adapter. | For the four public report adapters: processed_facts, hp_map_results, assessment_results, or processed_facts+courses+course_components. For timeback-map, source_table=hp_map_results means the adapter accepts the full source-shaped row and ignores unknown extra columns. | Explains which approved upstream source produced the report-grade fact without exposing raw rows. | A source table is missing for a non-null report tile value. | processed_facts |
Alpha extension provenance reference aitd-001-report-source-ingestion, aitd-004-provenance-no-literals |
status |
TEXT enum required |
Processing state of the source import. | Allowed values: import_status enum. | A status of materialized or partially_rejected can be followed by reads of created Analytics facts. | A validation or adapter rejection is represented as success without Problem details. | materialized |
Alpha extension aitd-001-report-source-ingestion, aitd-108-axis-error-envelope |
idempotency_key_hash |
TEXT required for public POST imports |
Hash of the Idempotency-Key header used for replay safety. | Stores a hash, never the raw key; replay with same hash and same body is a no-op, different body is analytics:idempotency_conflict. | Unique with tenant_id for source import writes. | Missing on public writes or stored as plaintext secret material. | sha256:4b463adfe0... |
Alpha extension aitd-105-axis-idempotency |
source_batch_ref |
TEXT nullable |
Operator/source identifier for the imported file, replay, or reconciliation run. | Opaque reference; no PII or raw row contents. | Audit linkage to migration/reconciliation artifacts. | Contains raw source rows, emails, or credentials. | migration-2026-06-10-processed-facts-001 |
Alpha extension aitd-001-report-source-ingestion, aitd-111-axis-privacy-retention |
source_payload_hash |
TEXT required |
Hash of the submitted source-shaped payload or replay source set. | SHA-256 or stronger; no raw payload copy in this table. | Supports idempotency and audit without storing PII rows. | Raw processed_facts rows are stored here. | sha256:91f25d7371... |
Alpha extension aitd-001-report-source-ingestion, aitd-111-axis-privacy-retention |
source_row_key_hashes |
JSONB required |
Hashes of natural source-row keys included in the import. | Hashes/opaque keys only; no student names, emails, credentials, or raw source payloads. | Allows a non-null report value to prove it came from a resolvable source row while keeping public reads PII-safe. | Missing on a report-source import that produced materialized rows, or stores raw source records. | ["sha256:rowkey001...", "sha256:rowkey002..."] |
Alpha extension provenance reference aitd-004-provenance-no-literals, aitd-111-axis-privacy-retention |
submitted_row_count |
INTEGER required |
Number of source-shaped rows submitted in the batch. | Nonnegative. | Top-level import audit, not a materialized-fact count. | Used as proof that Analytics rows exist. | 5000 |
Alpha extension aitd-001-report-source-ingestion |
accepted_row_count |
INTEGER required |
Rows accepted by request validation and adapter mapping. | Nonnegative and not greater than submitted_row_count. | Accepted rows should materialize or have a documented source_missing or policy_pending state. | Returned with HTTP 200 while validation actually failed. | 4970 |
Alpha extension aitd-001-report-source-ingestion, aitd-108-axis-error-envelope |
materialized_row_count |
INTEGER required |
How many imported source rows produced readable Analytics facts. Rows that produced readable Analytics facts. |
Nonnegative; successful nonempty imports must produce readable rows unless status explains otherwise. | Migration gate checks this count against the public Analytics reads. | Zero after a claimed successful import of rows that should materialize. | 4970 |
Alpha extension aitd-001-report-source-ingestion, aitd-110-axis-conformance-evidence |
rejected_row_count |
INTEGER required |
Rows rejected by validation or adapter mapping. | Nonnegative; submitted = accepted + rejected for completed imports. | Problem details summarize why rows could not materialize. | Hidden in a success body without typed Problem codes. | 30 |
Alpha extension aitd-001-report-source-ingestion, aitd-108-axis-error-envelope |
problem_counts |
JSONB required |
Counts of typed Problem codes produced by the import. | Keys must be stable analytics:* codes; values nonnegative integers. | Summarizes analytics:validation_failed, analytics:adapter_rejected, analytics:source_missing, analytics:policy_pending, and related errors. | Free-text error blobs or HTTP 200 with embedded failure status. | {"analytics:adapter_rejected":30} |
Alpha extension aitd-108-axis-error-envelope, aitd-001-report-source-ingestion |
received_at |
TIMESTAMPTZ required |
When the import request was received. | UTC timestamp. | Import audit timeline. | Used as a business effective date for metrics. | 2026-06-10T00:55:00Z |
Alpha extension aitd-001-report-source-ingestion |
completed_at |
TIMESTAMPTZ nullable until processing completes |
When import processing reached a terminal status. | UTC timestamp; null while status is received/running. | Import audit timeline. | Set before materialization/rejection summary is final. | 2026-06-10T00:56:12Z |
Alpha extension aitd-001-report-source-ingestion |
modified_at |
TIMESTAMPTZ required |
Last time the Analytics row changed for polling and modifiedSince queries. | UTC timestamp; list endpoints support modifiedSince against this field. | Supports poll plus modifiedSince eventing. | Client-supplied or used as the business effective date. | 2026-06-10T00:51:14Z |
Alpha extension aitd-107-axis-eventing, aitd-103-axis-query-model |
Enums Used Here
import_kind | |||
|---|---|---|---|
| Value | Meaning | Source | ITD |
timeback-xp-time-accuracy | Named report-source adapter for the Learning Report XP Goal, Time Commitment, and Accuracy panels from reporting.processed_facts. | Alpha extension enum | aitd-001-report-source-ingestion, aitd-101-axis-write-granularity |
timeback-map | Named report-source adapter for the MAP Results panel from reporting.hp_map_results. It accepts the full source-shaped hp_map_results row, including every wintertowinter* and goal* column; unknown extra columns are ignored, never rejected. | Alpha extension enum | aitd-001-report-source-ingestion, aitd-101-axis-write-granularity |
timeback-grade-mastery | Named report-source adapter for the Grade Levels Mastered panel from reporting.assessment_results. | Alpha extension enum | aitd-001-report-source-ingestion, aitd-101-axis-write-granularity |
timeback-completion | Named report-source adapter for XP-remaining fallback course progress from reporting.processed_facts plus Curriculum expected-XP refs. | Alpha extension enum | aitd-001-report-source-ingestion, aitd-101-axis-write-granularity |
event_close_replay | A replay of Events close notifications into Analytics materializers. | Alpha extension enum | aitd-001-report-source-ingestion, aitd-101-axis-write-granularity |
result_close_replay | A replay of Results close/change notifications into Analytics materializers. | Alpha extension enum | aitd-001-report-source-ingestion, aitd-101-axis-write-granularity |
migration_reconcile | A migration gate rerun that imports source-shaped rows and checks metric reconciliation. | Alpha extension enum | aitd-001-report-source-ingestion, aitd-101-axis-write-granularity |
import_status | |||
|---|---|---|---|
| Value | Meaning | Source | ITD |
received | The batch envelope is recorded but not yet processed. | Alpha extension enum | aitd-001-report-source-ingestion, aitd-108-axis-error-envelope |
running | The adapter/materializer is processing the batch. | Alpha extension enum | aitd-001-report-source-ingestion, aitd-108-axis-error-envelope |
materialized | Accepted rows produced readable Analytics rows. | Alpha extension enum | aitd-001-report-source-ingestion, aitd-108-axis-error-envelope |
partially_rejected | Some rows materialized and some rows produced typed Problems. | Alpha extension enum | aitd-001-report-source-ingestion, aitd-108-axis-error-envelope |
rejected | No rows materialized because the batch failed validation or adapter mapping. | Alpha extension enum | aitd-001-report-source-ingestion, aitd-108-axis-error-envelope |
failed | A platform failure interrupted processing after the batch was accepted. | Alpha extension enum | aitd-001-report-source-ingestion, aitd-108-axis-error-envelope |
alpha.analytics_fluency_probe · Fluency Probe
Publishes the dictionary-owned digits-correct-per-minute calculation and band without renderer or BFF recomputation.
Grain
One accepted Events fluency_probe_completed fact per tenant_id and source_event_id.
Primary Key
(tenant_id, id); source fact uniqueness is (tenant_id, source_event_id).
Lifecycle
Materialized from an accepted Events fluency_probe_completed fact and recalculated only through governed replay/correction.
Retention And Current Rows
Inherits Events authorization and retention; source deletion/tombstone and superseded rows remain auditable under AITD-111.
Ordinary reads require superseded_at IS NULL and source_deleted_at IS NULL; modifiedSince polls modified_at.
Provenance And Source Relationships
Events owns the immutable source fact; Analytics owns DCPM, performance_band, policy_ref, and materialization timestamps.
- Events fluency_probe_completed via source_event_id
- Curriculum course via course_id
- Curriculum KC via kc_id
- People and Orgs student via student_id
Public Endpoint And Query Axes
GET /alpha/analytics/v1/fluency-probes
modifiedSince sort limit cursor studentId courseId kcId performanceBand startDate endDate
Applicable Enums
probe_kind
| Value | Meaning |
|---|---|
digits_correct_per_minute | Correct units completed per elapsed minute; the initial governed fluency probe family. |
performance_band
| Value | Meaning |
|---|---|
acquisition | rate_per_minute below 10. |
fluency_building | rate_per_minute at least 10 and below 20. |
mastery | rate_per_minute at least 20. |
quality_status
| Value | Meaning |
|---|---|
ok | The row is the current reportable fact for its key and policy. |
corrected | The row includes a correction contribution but remains reportable. |
reversed | The row reverses a prior contribution and should be read as signed history. |
source_missing | A required source row was removed or unavailable before the fact could be finalized. |
source_unlinked | The source row exists but could not link to a required Event, Result, student, subject, KC, course, or policy ref. |
policy_pending | A required policy configuration was missing or not yet active at materialization time. |
adapter_rejected | The source-shaped row was valid input but the server-side adapter rejected it with a typed Problem. |
Raw DB Rule
Filter tenant_id and current rows, then read the stored rate_per_minute and performance_band. Never recalculate DCPM or bands from Events in a consumer query.
Example
{
"id": "fluency_probe_7f3a",
"tenant_id": "reviewer-analytics",
"student_id": "student-ada-001",
"course_id": "ap-chemistry",
"kc_id": "kc_chem_formula_fluency",
"source_event_id": "events:fluency_probe_001",
"occurred_at": "2026-07-18T14:30:00.000Z",
"probe_kind": "digits_correct_per_minute",
"correct_units": 18,
"elapsed_ms": 60000,
"rate_per_minute": 18,
"performance_band": "fluency_building",
"policy_ref": "alpha.policy.analytics.fluency_probe.v2026-07-18.issue-1128",
"quality_status": "ok",
"calculation_version": 1,
"computed_at": "2026-07-18T14:30:01.000Z",
"modified_at": "2026-07-18T14:30:01.000Z",
"superseded_at": null,
"source_deleted_at": null
}
Fields
| Field | Logical Type | PostgreSQL Type | Nullability | Meaning | Constraints | Relationship / Provenance | Example |
|---|---|---|---|---|---|---|---|
id |
TEXT | TEXT |
required | Analytics-owned stable fluency-probe row id. | Unique with tenant_id. | Primary key component for the public collection. Analytics materializer output governed by loop/context/ap-one-platform-capabilities-decision.md. |
fluency_probe_7f3a |
tenant_id |
TEXT | TEXT |
required | Tenant boundary taken from the authenticated materializer context. | Never accepted from public query or source extensions. | All reads filter tenant_id before other predicates. Analytics materializer output governed by loop/context/ap-one-platform-capabilities-decision.md. |
reviewer-analytics |
student_id |
TEXT | TEXT |
required | Canonical student whose accepted probe event was measured. | Resolved from the Events fact, not a display name or email. | References People and Orgs identity through the source Event. Analytics materializer output governed by loop/context/ap-one-platform-capabilities-decision.md. |
student-ada-001 |
course_id |
TEXT | TEXT |
required | Governed Curriculum course id carried by the accepted Events extension. | Must be present on the fluency_probe_completed source event. | References the Curriculum course containing the KC. Analytics materializer output governed by loop/context/ap-one-platform-capabilities-decision.md. |
ap-chemistry |
kc_id |
TEXT | TEXT |
required | Curriculum Knowledge Component measured by the probe. | Must resolve at the source event grain. | References the smallest durable Curriculum mastery target. Analytics materializer output governed by loop/context/ap-one-platform-capabilities-decision.md. |
kc_chem_formula_fluency |
source_event_id |
TEXT | TEXT |
required | Immutable Events fluency_probe_completed fact id. | Unique with tenant_id for this table. | One Analytics fluency row derives from one accepted Events fact. Analytics materializer output governed by loop/context/ap-one-platform-capabilities-decision.md. |
events:fluency_probe_001 |
occurred_at |
TIMESTAMPTZ | TIMESTAMPTZ |
required | UTC timestamp when the fluency probe occurred. | ISO 8601 timestamp with timezone; this is not a date-only field. | Copies the governed Events happened_at instant for temporal filtering. Analytics materializer output governed by loop/context/ap-one-platform-capabilities-decision.md. |
2026-07-18T14:30:00.000Z |
probe_kind |
TEXT enum | TEXT |
required | Typed measurement family for the probe. | Allowed values: probe_kind enum. | Selects the dictionary-owned formula and units. Analytics materializer output governed by loop/context/ap-one-platform-capabilities-decision.md. |
digits_correct_per_minute |
correct_units |
INTEGER | INTEGER |
required | Number of correct units completed during the probe. | Nonnegative integer from the accepted Events extension. | Numerator of rate_per_minute. Analytics materializer output governed by loop/context/ap-one-platform-capabilities-decision.md. |
18 |
elapsed_ms |
INTEGER | INTEGER |
required | Positive elapsed milliseconds for the probe. | Positive integer from the accepted Events extension. | Denominator of rate_per_minute. Analytics materializer output governed by loop/context/ap-one-platform-capabilities-decision.md. |
60000 |
rate_per_minute |
NUMERIC(10,3) | NUMERIC(10,3) |
required | Analytics-owned correct units per minute. | rate_per_minute = correct_units * 60000 / elapsed_ms, rounded to 3 decimals. | Stored calculation used to assign performance_band. Analytics materializer output governed by loop/context/ap-one-platform-capabilities-decision.md. |
18 |
performance_band |
TEXT enum | TEXT |
required | Policy-owned fluency band for the calculated rate. | Allowed values: performance_band enum; acquisition <10, fluency_building >=10 and <20, mastery >=20. | Derived only by the named fluency policy. Analytics materializer output governed by loop/context/ap-one-platform-capabilities-decision.md. |
fluency_building |
policy_ref |
TEXT | TEXT |
required | Exact fluency calculation and band policy version. | Must equal the active dictionary-referenced policy for this row. | Resolves formula and thresholds without client recomputation. Analytics materializer output governed by loop/context/ap-one-platform-capabilities-decision.md. |
alpha.policy.analytics.fluency_probe.v2026-07-18.issue-1128 |
quality_status |
TEXT enum | TEXT |
required | Current materialization quality state. | Allowed values: quality_status enum; this table writes ok, corrected, or source_missing as applicable. | Used with current-row timestamps for ordinary reads. Analytics materializer output governed by loop/context/ap-one-platform-capabilities-decision.md. |
ok |
calculation_version |
INTEGER | INTEGER |
required | Materializer calculation version for this row shape. | Positive integer; corrections preserve traceable versions. | Supports deterministic replay and audit. Analytics materializer output governed by loop/context/ap-one-platform-capabilities-decision.md. |
1 |
computed_at |
TIMESTAMPTZ | TIMESTAMPTZ |
required | UTC timestamp when Analytics calculated the row. | ISO 8601 timestamp with timezone. | Materialization audit timestamp. Analytics materializer output governed by loop/context/ap-one-platform-capabilities-decision.md. |
2026-07-18T14:30:01.000Z |
modified_at |
TIMESTAMPTZ | TIMESTAMPTZ |
required | UTC timestamp of the last row change. | Supports modifiedSince polling. | Public eventing cursor timestamp. Analytics materializer output governed by loop/context/ap-one-platform-capabilities-decision.md. |
2026-07-18T14:30:01.000Z |
superseded_at |
TIMESTAMPTZ | TIMESTAMPTZ |
nullable | When a correction made this row non-current. | Null on current rows. | Ordinary reads require superseded_at is null. Analytics materializer output governed by loop/context/ap-one-platform-capabilities-decision.md. |
null |
source_deleted_at |
TIMESTAMPTZ | TIMESTAMPTZ |
nullable | When the source Events fact was deleted or invalidated. | Null while the source is current. | Ordinary reads require source_deleted_at is null. Analytics materializer output governed by loop/context/ap-one-platform-capabilities-decision.md. |
null |
alpha.analytics_lab_progress · AP Lab Progress
Publishes AP Chemistry completed-lab and AP Environmental Science hands-on-time requirements without client-side event counting or threshold math.
Grain
One current row per tenant_id, student_id, course_id, and resolved policy_profile over the stored activity window.
Primary Key
(tenant_id, id); id is deterministic from student_id, course_id, and the resolved profile.
Lifecycle
Refreshed from governed lab_completed and course-scoped active-duration Events facts when the public collection is read or replayed.
Retention And Current Rows
Inherits Events authorization and retention; source deletion/tombstone and superseded rows remain auditable under AITD-111.
Ordinary reads require superseded_at IS NULL and source_deleted_at IS NULL; modifiedSince polls modified_at.
Provenance And Source Relationships
Events owns lab/activity facts, Curriculum owns policy_profile, and Analytics owns counts, percentages, thresholds, verdict, and null reason.
- Events lab_completed and course activity via source_event_refs
- Curriculum course via course_id
- Curriculum AP policy via policy_profile
- People and Orgs student via student_id
Public Endpoint And Query Axes
GET /alpha/analytics/v1/lab-progress
modifiedSince sort limit cursor studentId courseId policyProfile startDate endDate
Applicable Enums
policy_profile
| Value | Meaning |
|---|---|
ap_chemistry | Applies the 16 completed hands-on lab requirement. |
ap_environmental_science | Applies the 25 percent hands-on active-time requirement. |
null_reason
| Value | Meaning |
|---|---|
none | No null-producing condition applies. |
no_school_days | The denominator window has zero enrolled school days after calendar and enrollment intersection. |
no_questions | The window has zero reportable question attempts, so accuracy_percent is null rather than guessed as 0 or 100. |
no_enrollment | The student has no time-locatable enrollment for the requested range. |
no_subject_assignment | The student had no subject assignment/course/test membership for the subject denominator. |
source_missing | Required Event, Result, calendar, enrollment, or curriculum source evidence is missing. |
source_unlinked | Source evidence exists but cannot be linked to platform ids under the current policy. |
policy_pending | The named policy needed to compute the measure is missing or not active. |
not_applicable | The metric does not apply at this grain, such as MAP growth for a non-MAP subject. |
quality_status
| Value | Meaning |
|---|---|
ok | The row is the current reportable fact for its key and policy. |
corrected | The row includes a correction contribution but remains reportable. |
reversed | The row reverses a prior contribution and should be read as signed history. |
source_missing | A required source row was removed or unavailable before the fact could be finalized. |
source_unlinked | The source row exists but could not link to a required Event, Result, student, subject, KC, course, or policy ref. |
policy_pending | A required policy configuration was missing or not yet active at materialization time. |
adapter_rejected | The source-shaped row was valid input but the server-side adapter rejected it with a typed Problem. |
Raw DB Rule
Filter tenant_id and current rows and render the stored counts, percentage, requirement thresholds, verdict, and null_reason. Do not count Events or apply AP thresholds in a report.
Example
{
"id": "lab_progress_a8d1",
"tenant_id": "reviewer-analytics",
"student_id": "student-ada-001",
"course_id": "ap-chemistry",
"policy_profile": "ap_chemistry",
"window_start": "2026-01-01",
"window_end": "2026-07-19",
"completed_hands_on_lab_count": 16,
"hands_on_minutes": 720,
"total_course_active_minutes": 900,
"hands_on_percent": 80,
"required_lab_count": 16,
"required_hands_on_percent": null,
"meets_course_requirement": true,
"source_event_refs": [
"events:lab_completed_001",
"events:lab_completed_016"
],
"null_reason": "none",
"policy_ref": "alpha.policy.analytics.ap_lab_progress.v2026-07-18.issue-1128",
"quality_status": "ok",
"calculation_version": 1,
"computed_at": "2026-07-19T00:00:01.000Z",
"modified_at": "2026-07-19T00:00:01.000Z",
"superseded_at": null,
"source_deleted_at": null
}
Fields
| Field | Logical Type | PostgreSQL Type | Nullability | Meaning | Constraints | Relationship / Provenance | Example |
|---|---|---|---|---|---|---|---|
id |
TEXT | TEXT |
required | Analytics-owned stable lab-progress row id. | Unique with tenant_id. | Primary key component for the public collection. Analytics materializer output governed by loop/context/ap-one-platform-capabilities-decision.md. |
lab_progress_a8d1 |
tenant_id |
TEXT | TEXT |
required | Tenant boundary taken from the authenticated materializer context. | Never accepted from query or Events extensions. | All reads filter tenant_id first. Analytics materializer output governed by loop/context/ap-one-platform-capabilities-decision.md. |
reviewer-analytics |
student_id |
TEXT | TEXT |
required | Canonical student whose course lab evidence is aggregated. | Resolved through accepted Events facts. | References People and Orgs identity through Events. Analytics materializer output governed by loop/context/ap-one-platform-capabilities-decision.md. |
student-ada-001 |
course_id |
TEXT | TEXT |
required | Governed Curriculum course whose lab evidence is aggregated. | Required on contributing course-scoped Events facts. | References the Curriculum course and its policy profile. Analytics materializer output governed by loop/context/ap-one-platform-capabilities-decision.md. |
ap-chemistry |
policy_profile |
TEXT enum | TEXT |
nullable when Events do not resolve exactly one governed profile | Curriculum policy profile selecting the applicable AP requirement. | Allowed values: policy_profile enum. | AP Chemistry selects the 16-lab floor; AP Environmental Science selects the 25% hands-on floor. Analytics materializer output governed by loop/context/ap-one-platform-capabilities-decision.md. |
ap_chemistry |
window_start |
DATE | DATE |
required | Inclusive first course-activity date represented by the rollup. | ISO YYYY-MM-DD date-only value; never a timestamp. | Lower bound for contributing governed Events facts. Analytics materializer output governed by loop/context/ap-one-platform-capabilities-decision.md. |
2026-01-01 |
window_end |
DATE | DATE |
required | Exclusive date after the last course activity represented by the rollup. | ISO YYYY-MM-DD date-only value; never a timestamp. | Upper bound for contributing governed Events facts. Analytics materializer output governed by loop/context/ap-one-platform-capabilities-decision.md. |
2026-07-19 |
completed_hands_on_lab_count |
INTEGER | INTEGER |
required | Distinct accepted hands-on lab sessions completed in the window. | Nonnegative; counts lab_completed with hands_on=true and a lab_session_id. | AP Chemistry requirement numerator. Analytics materializer output governed by loop/context/ap-one-platform-capabilities-decision.md. |
16 |
hands_on_minutes |
NUMERIC(12,3) | NUMERIC(12,3) |
required | Accepted active minutes attached to hands-on lab completion facts. | Nonnegative and no greater than total_course_active_minutes. | Numerator of hands_on_percent. Analytics materializer output governed by loop/context/ap-one-platform-capabilities-decision.md. |
720 |
total_course_active_minutes |
NUMERIC(12,3) | NUMERIC(12,3) |
required | Governed active minutes for the course in the same window. | Nonnegative course-scoped denominator. | Denominator of hands_on_percent. Analytics materializer output governed by loop/context/ap-one-platform-capabilities-decision.md. |
900 |
hands_on_percent |
NUMERIC(7,3) | NUMERIC(7,3) |
nullable when the denominator is unavailable or zero | Percent of course active minutes that were hands-on lab minutes. | 0 through 100; hands_on_minutes / total_course_active_minutes * 100. | AP Environmental Science requirement numerator. Analytics materializer output governed by loop/context/ap-one-platform-capabilities-decision.md. |
80 |
required_lab_count |
INTEGER | INTEGER |
nullable when policy_profile is not ap_chemistry | Policy-required completed hands-on lab count. | 16 for ap_chemistry; otherwise null. | Threshold used by meets_course_requirement. Analytics materializer output governed by loop/context/ap-one-platform-capabilities-decision.md. |
16 |
required_hands_on_percent |
NUMERIC(7,3) | NUMERIC(7,3) |
nullable when policy_profile is not ap_environmental_science | Policy-required hands-on share of active course time. | 25 for ap_environmental_science; otherwise null. | Threshold used by meets_course_requirement. Analytics materializer output governed by loop/context/ap-one-platform-capabilities-decision.md. |
null |
meets_course_requirement |
BOOLEAN | BOOLEAN |
nullable when no supported policy profile or usable denominator applies | Stored verdict for the profile-specific AP lab requirement. | Chemistry compares completed labs to 16; Environmental Science compares hands_on_percent to 25. | Consumers render this value and do not recompute thresholds. Analytics materializer output governed by loop/context/ap-one-platform-capabilities-decision.md. |
true |
source_event_refs |
JSONB | JSONB |
required | Authorized contributing Events fact ids. | JSON array of opaque source ids; no copied event payloads. | Provenance link to lab_completed and course activity facts. Analytics materializer output governed by loop/context/ap-one-platform-capabilities-decision.md. |
["events:lab_completed_001","events:lab_completed_016"] |
null_reason |
TEXT enum | TEXT |
required | Typed explanation when the denominator or applicable profile is unavailable. | Allowed values: null_reason enum; this table uses none, source_missing, and not_applicable. | Explains nullable percentage, threshold, and verdict fields. Analytics materializer output governed by loop/context/ap-one-platform-capabilities-decision.md. |
none |
policy_ref |
TEXT | TEXT |
required | Exact AP lab-progress calculation policy version. | Must resolve to the dictionary-referenced policy. | Resolves formulas and thresholds without client recomputation. Analytics materializer output governed by loop/context/ap-one-platform-capabilities-decision.md. |
alpha.policy.analytics.ap_lab_progress.v2026-07-18.issue-1128 |
quality_status |
TEXT enum | TEXT |
required | Current materialization quality state. | Allowed values: quality_status enum; source_missing marks unavailable required evidence. | Used with null_reason and current-row timestamps. Analytics materializer output governed by loop/context/ap-one-platform-capabilities-decision.md. |
ok |
calculation_version |
INTEGER | INTEGER |
required | Materializer calculation version for this row shape. | Positive integer. | Supports deterministic replay and audit. Analytics materializer output governed by loop/context/ap-one-platform-capabilities-decision.md. |
1 |
computed_at |
TIMESTAMPTZ | TIMESTAMPTZ |
required | UTC timestamp when Analytics calculated the row. | ISO 8601 timestamp with timezone. | Materialization audit timestamp. Analytics materializer output governed by loop/context/ap-one-platform-capabilities-decision.md. |
2026-07-19T00:00:01.000Z |
modified_at |
TIMESTAMPTZ | TIMESTAMPTZ |
required | UTC timestamp of the last row change. | Supports modifiedSince polling. | Public eventing cursor timestamp. Analytics materializer output governed by loop/context/ap-one-platform-capabilities-decision.md. |
2026-07-19T00:00:01.000Z |
superseded_at |
TIMESTAMPTZ | TIMESTAMPTZ |
nullable | When a replacement made this row non-current. | Null on current rows. | Ordinary reads require superseded_at is null. Analytics materializer output governed by loop/context/ap-one-platform-capabilities-decision.md. |
null |
source_deleted_at |
TIMESTAMPTZ | TIMESTAMPTZ |
nullable | When contributing source evidence was deleted or invalidated. | Null while source evidence remains current. | Ordinary reads require source_deleted_at is null. Analytics materializer output governed by loop/context/ap-one-platform-capabilities-decision.md. |
null |
Raw/API Convergence Rules
These are dictionary rules, not implementation hints. A raw database query and an API call must reach the same answer by following them.
tenant_scope · Which rows belong to this tenant?
API Path
The API takes tenant_id only from the JWT claim; tenantId in URL/query/body is rejected or ignored according to the endpoint contract.
Raw DB Path
Every raw query must filter alpha.analytics_* by tenant_id before joins, windows, counts, sorting, or paging.
Failure mode: A raw report mixes demo/reviewer/production tenants and returns plausible but wrong totals.
Trace: aitd-109-axis-tenant-routing, aitd-106-axis-auth-shape
all_learning_report_metrics · How should a report answer a metric question?
API Path
Reports call the named Analytics endpoint for the metric.
Raw DB Path
Raw readers query the matching alpha.analytics_* table. They do not recompute from Events, Results, processed_facts, Curriculum trees, calendars, or private norms/R90 tables; for scale questions they read alpha.analytics_norms_achievement and the alpha.analytics_r90_table mirror sourced from the NWEAMAP-owned PowerPath RIT-to-grade master.
Failure mode: Client-side math leaks platform-owned logic into skill packs and fails three-way convergence.
Trace: aitd-003-close-time-materialization, aitd-110-axis-conformance-evidence
storage_model · How do I audit a derived fact?
API Path
Detail/sourceRefs subcollections expose authorized source ids and provenance summaries.
Raw DB Path
Join through source_event_id, source_state_ref, source_result_refs, source_ledger_refs, map refs, or curriculum_scope_refs; do not expect copied source columns in Analytics tables.
Failure mode: A raw query looks for Caliper payload, NWEA raw fields, Results scores, or Curriculum trees duplicated in Analytics.
Trace: aitd-000-extend-only-storage, aitd-102-axis-read-shape
corrections_and_tombstones · Which derived rows are reportable by default?
API Path
Ordinary list/detail endpoints exclude superseded/tombstoned rows unless includeSuperseded=true and the caller is authorized.
Raw DB Path
Filter superseded_at IS NULL AND source_deleted_at IS NULL for ordinary reports, then apply table-specific quality_status rules.
Failure mode: A raw report double-counts corrections or invalidated source rows.
Trace: aitd-111-axis-privacy-retention, aitd-012-corrections-and-reversals
signed_corrections · How do corrections affect totals?
API Path
Analytics exposes signed source contributions and report-ready net/display totals.
Raw DB Path
Use signed seconds_delta/negative_xp/net fields exactly as documented; do not clamp, drop, or recompute corrections locally.
Failure mode: A report silently removes negative gaming XP or reversal seconds and stops reconciling.
subject_normalization · How are source subjects handled?
API Path
Materializers write canonical subject_id or typed null_reason/adapter Problem at write time.
Raw DB Path
Filter/group by subject_id, not source strings such as FastMath, Vocabulary, Science-notqced, ELA, or ISEE variants.
Failure mode: A raw report creates extra subjects or mixes MAP proxy subjects after policy changes.
minutes_per_enrolled_school_day · Is the school-day denominator available, and if so how many active minutes per enrolled school day did this student have?
API Path
GET /school-day-minutes returns active_minutes, enrolled_school_day_count, excluded_school_day_count, minutes_per_enrolled_school_day, quality_status, and null_reason at the report grain.
Raw DB Path
Query alpha.analytics_school_day_minutes at the documented grain with quality_status in ('ok','corrected') and null_reason='none' for ordinary reports. source_missing rows are repair states; do not intersect Events with alpha.school_calendar, enrollment windows, processed_facts active dates, or attendance dates in the consumer.
Failure mode: A raw path returns an empty list for a known student, includes weekends/MAP testing days/current-only school assignment, fabricates a denominator from active dates, or renders a source_missing repair row as a completed time-commitment value.
Trace: aitd-006-school-day-minutes
xp_totals · How much XP did a student earn, how much remains, and what percent of the XP goal is complete?
API Path
GET /xp-rollups returns xp_total, daily_xp_goal, enrolled_school_day_count, xp_goal, xp_remaining, xp_goal_percent, on_track, signed audit subtotals, source_import provenance, and null_reason.
Raw DB Path
Query alpha.analytics_xp_rollup; use reporting.processed_facts and Results xp_ledger only through authorized source refs, not for report totals, remaining XP, or XP goal percent. Ordinary report rows carry stored denominator-derived goal fields; source_missing means repair/replay is required. Never cap xp_goal_percent at 100 when it is populated.
Failure mode: A client sums TimeBack processed_facts.xp_earned or xp_ledger, then computes goals, remaining XP, or a capped percent locally.
Trace: aitd-007-xp-rollups, aitd-001-report-source-ingestion, aitd-004-provenance-no-literals
accuracy_percent · What percent of reportable questions did the student answer correctly?
API Path
GET /accuracy-rollups returns correct_question_count, total_question_count, incorrect_question_count, accuracy_percent, source_import_id, quality_status, and null_reason at the documented student/subject/window grain.
Raw DB Path
Query alpha.analytics_accuracy; use reporting.processed_facts only through source_import/source-ref audit views, never as report math. If total_question_count is zero, read null_reason=no_questions and do not substitute 0% or 100%.
Failure mode: A report computes accuracy by summing raw processed_facts, counting QTI/Events attempts, keeping a private app/source allowlist, or dividing and rounding locally.
Trace: aitd-001-report-source-ingestion, aitd-004-provenance-no-literals, aitd-011-policy-and-enum-normalization
mastery_delta · Which KCs changed between dates?
API Path
GET /mastery-deltas filters by effective_at and state_dimension.
Raw DB Path
Query alpha.analytics_mastery_delta; current state remains Results student_kc_state and mastery math remains Results/Policy.
Failure mode: A report rebuilds mastery/decay/HMG from attempts or treats Analytics as current state of record.
rit_growthx_map_windows · What RIT and Growth X did the student have under a norms set?
API Path
GET /map-growth-rollups accepts typed normsSet/growthWindow/term filters and returns report-ready values; the Learning Report "vs 1yr ago" panel requests growthWindow=winter_to_winter.
Raw DB Path
Query alpha.analytics_map_growth_rollup by canonical_term_id, growth_window, and norms_set; for the Learning Report MAP panel read growth_percentile and growth_x from growth_window=winter_to_winter, not fall_to_winter. Do not parse terms, choose retakes, maintain a private norms table, or compute Growth X as observed/typical.
Failure mode: A raw report mixes 2020/2025 norms, selects fall_to_winter for a one-year panel, computes observed/typical, ships a private norms/R90 table, or disagrees with Results/NWEAMap test-of-record.
Trace: aitd-009-map-growth-rollups, aitd-001-report-source-ingestion
percentile_rit_r90_translation · What RIT maps to a percentile, and what R90/effective grade maps to a RIT?
API Path
GET /norms and /r90/table return versioned readable resources; GET /norms/rit, /norms/percentile, and /r90 return translated values with norms_set, table_version, calculator_version, and source_point_kind where applicable.
Raw DB Path
Read alpha.analytics_norms_achievement by norms_set/table_version/subject_id/role/grade_key/season and apply the documented normal model. Read alpha.analytics_r90_table by table_version='analytics.rit_to_grade.powerpath.v2026-06-15' and table_subject_id, then choose the row whose rit_score equals the requested RIT. Missing subjects/table points and missing RIT rows return typed source_missing behavior rather than interpolation, step-flooring, upward clamping, or extrapolation.
Failure mode: GOALS, Learning Report, and skill-pack examples disagree because one app cached a private norms table or R90 copy, silently changed versions, chose a nearest row, interpolated, step-floored, or skipped the current table_version filter.
Trace: aitd-015-norms-r90-readable-resources, aitd-016-scale-translation-apis, aitd-017-r90-version-supersession
goals_target_date_school_days · How many instructional days remain, and what daily effort is needed to finish by the target date?
API Path
GET /school-days-remaining returns analytics.school_days_remaining with instructional_days_remaining, instructional_dates, xp_unit.*, effort.*, provenance.*, and links.*. The endpoint uses the half-open [asOf,endDate) window and alpha.policy.analytics.xp_expected_minute.v2026-06-14.
Raw DB Path
Resolve the student's school through People and Orgs effective-dated enrollment, read alpha.school_calendar where calendar_date >= :asOf and calendar_date < :endDate, filter to instructional school days under alpha.policy.school_day.v2026-06-10, exclude MAP-testing days by policy, and apply alpha.policy.analytics.xp_expected_minute.v2026-06-14: 1 XP = 1 expected minute and 60 XP = 1 expected hour. Do not read consumed-day rollups for future dates, count weekdays, use attendance days, parse school_period labels, or hard-code XP_PER_HOUR.
Failure mode: GOALS or a skill pack computes a different target date because it counts weekdays/summer gaps locally, includes MAP days, uses current-only enrollment, treats endDate as inclusive, or carries a private XP_PER_HOUR constant.
Trace: aitd-018-goals-school-days-remaining, aitd-006-school-day-minutes, aitd-007-xp-rollups
completion_percent · What progress evidence exists for a course/subject/track?
API Path
GET /completion-rollups returns xp_earned, xp_remaining, completion_percent, source_import_id, and null_reason as Analytics evidence.
Raw DB Path
Query alpha.analytics_completion_rollup by completion_scope and scope_id for evidence. Course rows prefer app-reported Caliper percent, then XP remaining; grade_level rows preserve main-course evidence only. Student-facing progress reads come from Results. Do not derive progress from MAP/RIT/R90, walk Curriculum trees, count Results client-side, or use activity flags.
Failure mode: The raw path diverges when a client treats Analytics evidence as the final app-facing answer, treats RIT grade-band percent as actual progress, includes hole-filling courses in grade-level progress, or invents 1-if-active completion.
Trace: aitd-010-completion-rollups, aitd-001-report-source-ingestion, aitd-004-provenance-no-literals
source_shaped_imports · Did source-shaped import materialize rows?
API Path
POST /source-imports/{adapter} accepts only named adapters; timeback-map accepts full source-shaped hp_map_results rows and ignores unknown extra columns; validation failures return analytics:validation_failed with HTTP 400; adapter rejections return analytics:adapter_rejected with HTTP 422; successful imports report accepted/materialized counts.
Raw DB Path
Migration checks count readable alpha.analytics_* rows plus analytics_source_import.materialized_row_count, not submitted source rows or Problem bodies.
Failure mode: A lying HTTP 200 with zero readable rows, or a timeback-map rejection caused only by unknown extra hp_map_results columns, recreates the migration failure Analytics exists to fix.
Trace: aitd-001-report-source-ingestion, aitd-108-axis-error-envelope, aitd-110-axis-conformance-evidence
Problem Codes
analytics:validation_failed (400), analytics:unsupported_parameter (400), analytics:adapter_rejected (422), analytics:idempotency_conflict (409), analytics:schema_migration_failed (500), analytics:server_error (500), analytics:source_missing (409), analytics:source_unlinked (422), analytics:policy_pending (422).
Consumers switch on code, never on titles or legacy aliases.
Problem Envelope
Analytics errors use application/problem+json. A validation, adapter, policy, source, or schema failure is never returned as HTTP 200 with a hidden error body.
Type URI prefix: https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/data_dictionary#problem-
| Field | Type | Required | Meaning |
|---|---|---|---|
type | URI | required | Stable deep link for this Analytics Problem code. |
title | TEXT | required | Short human-readable summary. |
status | INTEGER | required | HTTP status code; validation=400, adapter/policy normalization=422, conflict/not-ready=409, platform failure=500. |
code | TEXT | required | Stable analytics:* code. Consumers switch on this, not title/detail text. |
detail | TEXT | required | Specific explanation safe to show to the caller. |
requestId | TEXT | required | Per-request id for support and audit correlation. |
traceId | TEXT | required | Cross-service trace id for operator investigation. |
fieldErrors | JSONB array | optional | Per-field validation failures for analytics:validation_failed. |
sourceRef | TEXT | optional | Opaque source row/ref when a source-shaped row or close notification failed. |
resolution | TEXT | required | Next safe action: correct request, repair source mapping, seed policy, replay, or wait for source close. |
links.dataDictionary | URI | required | Deep link to the table, field, or Problem-code section that explains the rule. |
Example Problem Payload
{
"type": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/data_dictionary#problem-analytics-policy-pending",
"title": "Analytics policy pending",
"status": 422,
"code": "analytics:policy_pending",
"detail": "alpha.policy.school_day.v2026-06-10 has no active reason mapping for CalendarEventDescriptor=District MAP testing.",
"requestId": "req_01J0ANALYTICS",
"traceId": "trace_01J0ANALYTICS",
"sourceRef": "calendar_date:school_alpha_austin:2026-05-15",
"resolution": "Seed or activate the governed alpha.policy.school_day reason mapping, then replay the affected materializer window.",
"links": {
"dataDictionary": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/data_dictionary#policy-school-day"
}
}
| Code | HTTP | Meaning | When Raised | Client Fix | Raw DB Effect | Example | Trace |
|---|---|---|---|---|---|---|---|
analytics:validation_failed | 400 | The request envelope, query string, dates, enum values, or required fields are invalid before an adapter/materializer can run. Carries field-level codes, including the norms/R90 reference codes norms_subject_not_found, r90_subject_not_found, norms_point_not_found, r90_point_not_found (aitd-015/016). Also the status carrier for 401/403/404/405/415 envelope errors. | The API envelope, query filter, enum value, date range, required field, or JSON shape is invalid before Analytics can normalize source rows. For timeback-map, unknown extra columns in a full hp_map_results row are not validation failures. | Correct the request shape or query parameter. Do not retry the same body under a new idempotency key. | No new alpha.analytics_* row is written. analytics_source_import, when present, records status=rejected and materialized_row_count=0. | normsSet=2026, completionScope=course_component, window_end before window_start, or tenantId supplied in the query string. | aitd-103-axis-query-model, aitd-108-axis-error-envelope |
analytics:unsupported_parameter | 400 | A query parameter is not part of the typed query model (Vercel routing params such as path are stripped before validation). | A request includes a filter or sort parameter outside the typed query model. | Use only documented filters from the table grain and endpoint contract; strip routing params before validation. | No raw-path equivalent exists for the unsupported filter; adding ad hoc WHERE clauses breaks convergence. | Filtering completion-rollups by raw course_component_kind instead of completion_scope/scope_id. | aitd-103-axis-query-model, aitd-108-axis-error-envelope |
analytics:adapter_rejected | 422 | A valid source-shaped row cannot be normalized, OR an expected report-source row is missing — a reconciliation error, never a silent default. | The source-shaped row is syntactically valid but cannot resolve to required Events, Results, student, subject, KC, course, calendar, or policy refs. A full hp_map_results row with additional unknown columns is accepted by timeback-map and those extra columns are ignored. | Repair the source mapping or upstream row, then replay the same source-shaped row idempotently. | Rejected rows appear only as typed import findings; reportable tables do not get fake partial facts. | A processed_facts row names an unknown subject, or a completion row points at a course the Curriculum surface cannot resolve. | aitd-001-report-source-ingestion, aitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope |
analytics:idempotency_conflict | 409 | The same Idempotency-Key or source_fact_key was replayed with different content. | The same Idempotency-Key or deterministic source_fact_key is replayed with different content. | Use the original body for replay, or submit a correction through the correction/reversal pathway. | Existing materialized rows remain unchanged; no duplicate or replacement row is written. | A migration replay keeps the same source_fact_key but changes active_seconds from 300 to 360. | aitd-105-axis-idempotency, aitd-012-corrections-and-reversals |
analytics:schema_migration_failed | 500 | The Postgres schema-readiness path could not complete the version-gated migration or schema sentinel check. | Raised only by Analytics schema initialization/readiness before a route can safely use the Postgres repository. | Retry after the platform operator resolves the schema/readiness incident; do not treat it as an adapter or import-row failure. | No report should treat this Problem as a materialized Analytics fact. | A cold-start schema sentinel check or idempotent migration fails before the import handler starts writing source rows. | aitd-108-axis-error-envelope |
analytics:server_error | 500 | An unexpected runtime failure outside the typed validation, adapter, policy, source, idempotency, and schema-readiness paths. | Raised by the generic Analytics error envelope for uncaught runtime errors such as import-write statement timeouts. | Capture requestId and traceId for operator support; retry only after checking idempotency and whether the platform incident has cleared. | The request failed before Analytics could guarantee the intended write/read result. Idempotent replays must use the same body and key. | A source-import write is canceled by Postgres statement_timeout after the schema was already ready. | aitd-108-axis-error-envelope |
analytics:source_missing | 409 | Analytics expected an Event, Result, calendar, enrollment, or Curriculum source row, but it was not available or not closed. | A materializer or read-side source-ref audit cannot finish because a required upstream row is absent, tombstoned before materialization, or still open. | Wait for the source close/import to finish or repair the upstream source row, then replay the affected source/window. For school-day minutes, the fix is to surface the upstream Alpha calendar source and replay the window. | No numeric denominator is fabricated. School-day minutes may expose a current explanatory row with quality_status=source_missing or null_reason=source_missing so reports show unavailable instead of returning an empty list; other tables expose source_missing through audit/import reads until replay succeeds. | A TimeSpentEvent close notification references an event id that Events has already tombstoned. | aitd-003-close-time-materialization, aitd-111-axis-privacy-retention, aitd-108-axis-error-envelope |
analytics:source_unlinked | 422 | The source row exists, but Analytics cannot link it to the required Alpha student, subject, KC, course, school calendar, or policy ref. | Server-side normalization sees a source-shaped row whose identity or relationship keys do not resolve under the current tenant and policy value-space. | Fix the upstream id mapping or governed alias/policy row. Do not supply a caller-normalized replacement id just for this import. | The finding is visible through import/problem counts or quality_status=source_unlinked; report queries exclude it. | A processed_facts row has subject=Science-notqced and no accepted subject normalization. | aitd-011-policy-and-enum-normalization, aitd-001-report-source-ingestion, aitd-108-axis-error-envelope |
analytics:policy_pending | 422 | A required alpha.policy.* row is missing, inactive for the effective date, or lacks a governed value needed to compute the fact. | Analytics cannot classify time, count school days, roll up XP, interpret MAP norms, or count completion because the named policy/config value is unavailable. | Seed or activate the policy row and replay. Reports and skill packs must not hard-code the missing value. | Rows may carry quality_status=policy_pending or null_reason=policy_pending for audit, but ordinary report queries exclude them. | alpha.policy.school_day has no reason mapping for a real Ed-Fi CalendarEventDescriptor. | aitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope |
Allowed Values
subject_id
| Value | Meaning | Source | ITD |
|---|---|---|---|
math | Math subject rollups and MAP/math source-label normalization. | Alpha/Curriculum governed enum | aitd-011-policy-and-enum-normalization |
reading | Reading subject rollups. | Alpha/Curriculum governed enum | aitd-011-policy-and-enum-normalization |
language | Language / ELA subject rollups. Public reads keep vocabulary and writing as distinct canonical subjects. | Alpha/Curriculum governed enum | aitd-011-policy-and-enum-normalization |
science | Science subject rollups. | Alpha/Curriculum governed enum | aitd-011-policy-and-enum-normalization |
vocabulary | Vocabulary activity rollups as the canonical vocabulary subject. | Alpha/Curriculum governed enum | aitd-011-policy-and-enum-normalization |
writing | Writing activity rollups as the canonical writing subject. | Alpha/Curriculum governed enum | aitd-011-policy-and-enum-normalization |
fact_kind
| Value | Meaning | Source | ITD |
|---|---|---|---|
active_seconds | Seconds the policy classifies as productive engaged work for a closed source event. | Alpha extension enum | aitd-005-time-facts-and-windows, aitd-011-policy-and-enum-normalization |
inactive_seconds | Seconds the policy classifies as idle or not meaningfully engaged. | Alpha extension enum | aitd-005-time-facts-and-windows, aitd-011-policy-and-enum-normalization |
waste_seconds | Seconds the policy classifies as gaming, distraction, or otherwise counterproductive work. | Alpha extension enum | aitd-005-time-facts-and-windows, aitd-011-policy-and-enum-normalization |
window_kind
| Value | Meaning | Source | ITD |
|---|---|---|---|
day | A calendar day in the school timezone, represented as a half-open date range. | Alpha extension enum | aitd-005-time-facts-and-windows, aitd-103-axis-query-model, aitd-011-policy-and-enum-normalization |
week | A platform week under alpha.policy.analytics.window. | Alpha extension enum | aitd-005-time-facts-and-windows, aitd-103-axis-query-model, aitd-011-policy-and-enum-normalization |
term | An academic term from the People and Orgs academic-session calendar. | Alpha extension enum | aitd-005-time-facts-and-windows, aitd-103-axis-query-model, aitd-011-policy-and-enum-normalization |
school_year | A school-year window from the org academic-session calendar. | Alpha extension enum | aitd-005-time-facts-and-windows, aitd-103-axis-query-model, aitd-011-policy-and-enum-normalization |
custom | A caller-requested or migration reconciliation range with explicit start and end dates. | Alpha extension enum | aitd-005-time-facts-and-windows, aitd-103-axis-query-model, aitd-011-policy-and-enum-normalization |
quality_status
| Value | Meaning | Source | ITD |
|---|---|---|---|
ok | The row is the current reportable fact for its key and policy. | Alpha extension enum | aitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope, aitd-111-axis-privacy-retention |
corrected | The row includes a correction contribution but remains reportable. | Alpha extension enum | aitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope, aitd-111-axis-privacy-retention |
reversed | The row reverses a prior contribution and should be read as signed history. | Alpha extension enum | aitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope, aitd-111-axis-privacy-retention |
source_missing | A required source row was removed or unavailable before the fact could be finalized. | Alpha extension enum | aitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope, aitd-111-axis-privacy-retention |
source_unlinked | The source row exists but could not link to a required Event, Result, student, subject, KC, course, or policy ref. | Alpha extension enum | aitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope, aitd-111-axis-privacy-retention |
policy_pending | A required policy configuration was missing or not yet active at materialization time. | Alpha extension enum | aitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope, aitd-111-axis-privacy-retention |
adapter_rejected | The source-shaped row was valid input but the server-side adapter rejected it with a typed Problem. | Alpha extension enum | aitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope, aitd-111-axis-privacy-retention |
null_reason
| Value | Meaning | Source | ITD |
|---|---|---|---|
none | No null-producing condition applies. | Alpha extension enum | aitd-011-policy-and-enum-normalization |
no_school_days | The denominator window has zero enrolled school days after calendar and enrollment intersection. | Alpha extension enum | aitd-011-policy-and-enum-normalization |
no_questions | The window has zero reportable question attempts, so accuracy_percent is null rather than guessed as 0 or 100. | Alpha extension enum | aitd-011-policy-and-enum-normalization |
no_enrollment | The student has no time-locatable enrollment for the requested range. | Alpha extension enum | aitd-011-policy-and-enum-normalization |
no_subject_assignment | The student had no subject assignment/course/test membership for the subject denominator. | Alpha extension enum | aitd-011-policy-and-enum-normalization |
source_missing | Required Event, Result, calendar, enrollment, or curriculum source evidence is missing. | Alpha extension enum | aitd-011-policy-and-enum-normalization |
source_unlinked | Source evidence exists but cannot be linked to platform ids under the current policy. | Alpha extension enum | aitd-011-policy-and-enum-normalization |
policy_pending | The named policy needed to compute the measure is missing or not active. | Alpha extension enum | aitd-011-policy-and-enum-normalization |
not_applicable | The metric does not apply at this grain, such as MAP growth for a non-MAP subject. | Alpha extension enum | aitd-011-policy-and-enum-normalization |
state_dimension
| Value | Meaning | Source | ITD |
|---|---|---|---|
initial_mastery | The acquisition/mastery signal changed for the KC. | Alpha extension enum | aitd-008-mastery-and-grade-levels, aitd-011-policy-and-enum-normalization |
current_retention | The retained mastery value changed under the Results retention policy. | Alpha extension enum | aitd-008-mastery-and-grade-levels, aitd-011-policy-and-enum-normalization |
durable_mastery | The durable mastery state changed. | Alpha extension enum | aitd-008-mastery-and-grade-levels, aitd-011-policy-and-enum-normalization |
fluency_state | The fluency/automaticity state changed. | Alpha extension enum | aitd-008-mastery-and-grade-levels, aitd-011-policy-and-enum-normalization |
next_due_at | The next review or practice due date changed. | Alpha extension enum | aitd-008-mastery-and-grade-levels, aitd-011-policy-and-enum-normalization |
transition_kind
| Value | Meaning | Source | ITD |
|---|---|---|---|
acquired | The student crossed into mastery/acquisition for the KC. | Alpha extension enum | aitd-008-mastery-and-grade-levels, aitd-011-policy-and-enum-normalization |
improved | The state value increased but did not represent first acquisition. | Alpha extension enum | aitd-008-mastery-and-grade-levels, aitd-011-policy-and-enum-normalization |
decayed | The value decreased under Results retention state. | Alpha extension enum | aitd-008-mastery-and-grade-levels, aitd-011-policy-and-enum-normalization |
review_due | The due-date dimension moved into a new due state. | Alpha extension enum | aitd-008-mastery-and-grade-levels, aitd-011-policy-and-enum-normalization |
fluency_changed | The fluency dimension changed. | Alpha extension enum | aitd-008-mastery-and-grade-levels, aitd-011-policy-and-enum-normalization |
corrected | The transition reflects a source correction or migration repair. | Alpha extension enum | aitd-008-mastery-and-grade-levels, aitd-011-policy-and-enum-normalization |
blocked | A required source or policy row was missing, so the state change is blocked. | Alpha extension enum | aitd-008-mastery-and-grade-levels, aitd-011-policy-and-enum-normalization |
norms_set
| Value | Meaning | Source | ITD |
|---|---|---|---|
2020 | NWEA 2020 norms, kept distinct for historical report reproduction. | Alpha extension enum | aitd-009-map-growth-rollups, aitd-015-norms-r90-readable-resources, aitd-016-scale-translation-apis, aitd-011-policy-and-enum-normalization |
2025 | NWEA 2025 norms, the current norms family when requested by policy or caller. | Alpha extension enum | aitd-009-map-growth-rollups, aitd-015-norms-r90-readable-resources, aitd-016-scale-translation-apis, aitd-011-policy-and-enum-normalization |
source_point_kind
| Value | Meaning | Source | ITD |
|---|---|---|---|
exact | The requested RIT exactly matched a PowerPath RIT-to-grade row in the current R90 table version. | Alpha reference lookup enum | aitd-015-norms-r90-readable-resources, aitd-016-scale-translation-apis, aitd-017-r90-version-supersession |
source_missing | No PowerPath RIT-to-grade source row exists for the requested RIT and subject, so the surface returns a typed missing answer instead of extrapolating. | Alpha reference lookup enum | aitd-015-norms-r90-readable-resources, aitd-016-scale-translation-apis, aitd-017-r90-version-supersession |
growth_window
| Value | Meaning | Source | ITD |
|---|---|---|---|
fall_to_fall | Year-over-year growth from fall of the prior school year to fall of the selected school year. | Alpha extension enum | aitd-009-map-growth-rollups, aitd-011-policy-and-enum-normalization |
fall_to_winter | Observed and projected growth from fall to winter. | Alpha extension enum | aitd-009-map-growth-rollups, aitd-011-policy-and-enum-normalization |
winter_to_spring | Observed and projected growth from winter to spring. | Alpha extension enum | aitd-009-map-growth-rollups, aitd-011-policy-and-enum-normalization |
fall_to_spring | Observed and projected growth from fall to spring. | Alpha extension enum | aitd-009-map-growth-rollups, aitd-011-policy-and-enum-normalization |
winter_to_winter | Year-over-year growth from winter of the prior school year to winter of the selected school year. This is the Learning Report "vs 1yr ago" MAP window. | Alpha extension enum | aitd-009-map-growth-rollups, aitd-011-policy-and-enum-normalization |
spring_to_spring | Year-over-year growth from spring of the prior school year to spring of the selected school year. | Alpha extension enum | aitd-009-map-growth-rollups, aitd-011-policy-and-enum-normalization |
baseline_to_current | Growth from the student baseline term to the current term. | Alpha extension enum | aitd-009-map-growth-rollups, aitd-011-policy-and-enum-normalization |
term | A single-term MAP observation with no paired growth delta. | Alpha extension enum | aitd-009-map-growth-rollups, aitd-011-policy-and-enum-normalization |
custom | A named migration or report window whose dates are stored in policy/config. | Alpha extension enum | aitd-009-map-growth-rollups, aitd-011-policy-and-enum-normalization |
completion_scope
| Value | Meaning | Source | ITD |
|---|---|---|---|
course | Completion for one course. | Alpha extension enum | aitd-010-completion-rollups, aitd-011-policy-and-enum-normalization |
subject | Completion for all expected work in one subject. | Alpha extension enum | aitd-010-completion-rollups, aitd-011-policy-and-enum-normalization |
track | Completion for a full track. | Alpha extension enum | aitd-010-completion-rollups, aitd-011-policy-and-enum-normalization |
track_level | Completion for one level inside a track. | Alpha extension enum | aitd-010-completion-rollups, aitd-011-policy-and-enum-normalization |
grade_level | Progress evidence across the main courses that make up one grade level; the student-facing answer is served by Results. | Alpha extension enum | aitd-010-completion-rollups, aitd-011-policy-and-enum-normalization |
segment | Completion for one curriculum segment. | Alpha extension enum | aitd-010-completion-rollups, aitd-011-policy-and-enum-normalization |
import_kind
| Value | Meaning | Source | ITD |
|---|---|---|---|
timeback-xp-time-accuracy | Named report-source adapter for the Learning Report XP Goal, Time Commitment, and Accuracy panels from reporting.processed_facts. | Alpha extension enum | aitd-001-report-source-ingestion, aitd-101-axis-write-granularity |
timeback-map | Named report-source adapter for the MAP Results panel from reporting.hp_map_results. It accepts the full source-shaped hp_map_results row, including every wintertowinter* and goal* column; unknown extra columns are ignored, never rejected. | Alpha extension enum | aitd-001-report-source-ingestion, aitd-101-axis-write-granularity |
timeback-grade-mastery | Named report-source adapter for the Grade Levels Mastered panel from reporting.assessment_results. | Alpha extension enum | aitd-001-report-source-ingestion, aitd-101-axis-write-granularity |
timeback-completion | Named report-source adapter for XP-remaining fallback course progress from reporting.processed_facts plus Curriculum expected-XP refs. | Alpha extension enum | aitd-001-report-source-ingestion, aitd-101-axis-write-granularity |
event_close_replay | A replay of Events close notifications into Analytics materializers. | Alpha extension enum | aitd-001-report-source-ingestion, aitd-101-axis-write-granularity |
result_close_replay | A replay of Results close/change notifications into Analytics materializers. | Alpha extension enum | aitd-001-report-source-ingestion, aitd-101-axis-write-granularity |
migration_reconcile | A migration gate rerun that imports source-shaped rows and checks metric reconciliation. | Alpha extension enum | aitd-001-report-source-ingestion, aitd-101-axis-write-granularity |
import_status
| Value | Meaning | Source | ITD |
|---|---|---|---|
received | The batch envelope is recorded but not yet processed. | Alpha extension enum | aitd-001-report-source-ingestion, aitd-108-axis-error-envelope |
running | The adapter/materializer is processing the batch. | Alpha extension enum | aitd-001-report-source-ingestion, aitd-108-axis-error-envelope |
materialized | Accepted rows produced readable Analytics rows. | Alpha extension enum | aitd-001-report-source-ingestion, aitd-108-axis-error-envelope |
partially_rejected | Some rows materialized and some rows produced typed Problems. | Alpha extension enum | aitd-001-report-source-ingestion, aitd-108-axis-error-envelope |
rejected | No rows materialized because the batch failed validation or adapter mapping. | Alpha extension enum | aitd-001-report-source-ingestion, aitd-108-axis-error-envelope |
failed | A platform failure interrupted processing after the batch was accepted. | Alpha extension enum | aitd-001-report-source-ingestion, aitd-108-axis-error-envelope |
Production Source Evidence
Analytics field and enum rules are grounded in aggregate-only production evidence. This rebuild fetched the approved upstream pages and ran bounded read-only probes through the required Danny token-file path. The evidence below is schema or aggregate-only: no raw student rows, names, emails, or identifiers are published.
Fresh query path: This artifact trail fetched approved upstream pages and ran bounded read-only aggregate/schema probes through node loop/nweamap/vendor/skill-pack-baseline/nwea-map-analysis/scripts/timeback-query.mjs --token-file ~/Documents/timeback-danny-mcp-creds against TimeBack report-source tables and caliper. The current stored accuracy evidence is source/evidence/attempt1-accuracy-source-aggregate-2026-06-13.json, a bounded processed_facts aggregate through that token-file path against the MCP-visible public.processed_facts source-shaped table. Attempt 1 uses that completed PII-safe aggregate evidence instead of inventing values or querying raw source rows in the report. The current school-calendar evidence is source/evidence/current-school-calendar-persistence-2026-06-13.json, a read-only persistence check showing alpha.school_calendar has 9,238 rows. This attempt applies the operator settlement that the reporting probe is green for Time Commitment; source_missing remains only an uncovered-school/window repair state.
Fresh June 12 Reporting Schema Probe
| table_name | column_name | data_type |
|---|---|---|
| assessment_results | sourced_id | text |
| assessment_results | status | USER-DEFINED |
| assessment_results | date_last_modified | timestamp without time zone |
| assessment_results | metadata | jsonb |
| assessment_results | assessment_line_item_sourced_id | text |
| assessment_results | student_sourced_id | text |
| assessment_results | score | real |
| assessment_results | text_score | text |
| assessment_results | score_date | timestamp without time zone |
| assessment_results | score_scale_sourced_id | text |
| assessment_results | score_percentile | real |
| assessment_results | score_status | USER-DEFINED |
| assessment_results | comment | text |
| assessment_results | learning_objective_set | jsonb |
| assessment_results | in_progress | boolean |
| assessment_results | incomplete | boolean |
| assessment_results | late | boolean |
| assessment_results | missing | boolean |
| assessment_results | tenant_id | uuid |
| assessment_results | client_app_id | uuid |
| course_components | sourced_id | text |
| course_components | status | USER-DEFINED |
| course_components | date_last_modified | timestamp without time zone |
| course_components | metadata | jsonb |
| course_components | course_sourced_id | text |
| course_components | parent_sourced_id | text |
| course_components | title | text |
| course_components | sort_order | integer |
| course_components | prerequisites | ARRAY |
| course_components | prerequisite_criteria | text |
| course_components | unlock_date | timestamp without time zone |
| course_components | tenant_id | uuid |
| course_components | client_app_id | uuid |
| courses | sourced_id | text |
| courses | status | USER-DEFINED |
| courses | date_last_modified | timestamp without time zone |
| courses | metadata | jsonb |
| courses | title | text |
| courses | school_year_sourced_id | text |
| courses | course_code | text |
Fresh June 12 Reporting processed_facts Subject Aggregate
| subject | n | active_seconds | inactive_seconds | waste_seconds | xp_earned |
|---|---|---|---|---|---|
| Writing | 4974715 | 79160252.57 | 7.08 | 0 | 1226124.18 |
| Math | 4039603 | 364972640.26 | 3822941.95 | 452971.58 | 4434337.04 |
| Language | 2219490 | 158829436.14 | 618341.92 | 311330.7 | 4924056.48 |
| FastMath | 2022748 | 70873766.86 | 480024.9 | 38471840.1 | 1072054.64 |
| Reading | 1805944 | 180023835.5 | 559883.94 | 124753.45 | 2979423.42 |
| Social Studies | 699552 | 11529499.33 | 3501554.5 | 162669.99 | 358718.83 |
| Science | 546393 | 80107538.43 | 837338.19 | 611348.02 | 1571641.41 |
| Vocabulary | 269936 | 8276420.16 | 198372.5 | 0 | 1081696.58 |
| None | 38717 | 718490.02 | 8109.91 | 12310.9 | 0 |
| (blank) | 13505 | 0 | 0 | 0 | -24549 |
| Other | 3613 | 65648.85 | 1237.93 | 0 | 32202 |
| Biology | 85 | 0 | 0 | 0 | 0 |
| Mathematics | 30 | 0 | 0 | 0 | 165 |
| ELA | 3 | 0 | 0 | 0 | 35 |
Fresh June 12 Reporting hp_map_results Window Aggregate
| subject | termname | n | rit_rows | wtw_observed_rows | wtw_projected_rows | wtw_cgp_rows | min_rit | max_rit |
|---|---|---|---|---|---|---|---|---|
| Reading | Winter 2025-2026 | 5449 | 5449 | 329 | 313 | 313 | 136 | 267 |
| Math | Fall 2025-2026 | 5272 | 5272 | 0 | 0 | 0 | 104 | 307 |
| Reading | Fall 2025-2026 | 4740 | 4740 | 0 | 0 | 0 | 123 | 267 |
| Language | Fall 2025-2026 | 4648 | 4648 | 0 | 0 | 0 | 136 | 272 |
| Language | Winter 2025-2026 | 4392 | 4392 | 227 | 221 | 221 | 137 | 267 |
| Math | Winter 2025-2026 | 3940 | 3940 | 328 | 312 | 312 | 123 | 314 |
| Reading | Spring 2025-2026 | 3552 | 3552 | 0 | 0 | 0 | 143 | 278 |
| Language | Spring 2025-2026 | 3075 | 3075 | 0 | 0 | 0 | 140 | 289 |
| Math | Spring 2025-2026 | 2499 | 2499 | 0 | 0 | 0 | 144 | 323 |
| Science | Winter 2025-2026 | 2155 | 2155 | 196 | 196 | 196 | 159 | 276 |
| Science | Spring 2025-2026 | 1610 | 1610 | 0 | 0 | 0 | 158 | 282 |
| Science | Fall 2025-2026 | 861 | 861 | 0 | 0 | 0 | 160 | 271 |
| Math | Spring 2024-2025 | 642 | 642 | 0 | 0 | 0 | 127 | 289 |
| Reading | Spring 2024-2025 | 580 | 580 | 0 | 0 | 0 | 116 | 260 |
| Language | Spring 2024-2025 | 424 | 424 | 0 | 0 | 0 | 154 | 268 |
| Science | Spring 2024-2025 | 369 | 369 | 0 | 0 | 0 | 167 | 254 |
Fresh June 12 Caliper Type/Action Aggregate
| type | action | n |
|---|---|---|
| TimeSpentEvent | SpentTime | 13159747 |
| ActivityEvent | Completed | 4194050 |
| Event | Created | 34481 |
| ToolUseEvent | Used | 3672 |
| AnnotationEvent | Tagged | 1586 |
| AssessmentItemEvent | Completed | 738 |
| SessionEvent | LoggedIn | 270 |
| SessionEvent | LoggedOut | 193 |
| Event | Achieved | 132 |
| AssessmentItemEvent | Skipped | 119 |
| AssessmentEvent | Submitted | 18 |
| Event | Used | 8 |
| Event | Completed | 6 |
| Event | Viewed | 4 |
| FeedbackEvent | Ranked | 2 |
| FeedbackEvent | Commented | 2 |
| GradeEvent | Graded | 1 |
| AssessmentEvent | Started | 1 |
| AssessmentEvent | Paused | 1 |
Current Accuracy Aggregate Evidence
Attempt 1 uses completed PII-safe Accuracy source evidence from the required token-file helper and the current persistence check for alpha.school_calendar. The aggregate proves the source-shaped processed_facts table carries the question numerator and denominator that Analytics materializes into alpha.analytics_accuracy; the calendar check proves the Time Commitment denominator source remains available and names the live raw columns.
| row_count | rows_with_total_questions | rows_with_correct_questions | total_questions_sum | correct_questions_sum | accuracy_percent |
|---|---|---|---|---|---|
| 16662329 | 2980443 | 2893838 | 59167608 | 51390936 | 86.857 |
Current School Calendar Persistence Evidence
| table | row_count | school_day_rows | school_count | min_calendar_date | max_calendar_date | reasons | interpretation |
|---|---|---|---|---|---|---|---|
| alpha.school_calendar | 9238 | 5674 | 14 | 2025-08-13 | 2027-06-06 | holiday_break,instructional,nwea_map_testing,other,weekend | alpha.school_calendar remains present in the shared DB; Time Commitment examples should use reportable rows and keep source_missing as repair behavior only. |
Attempt 1 Source Refresh Audit
Attempt 1 records the current evidence path used for the Accuracy contract. If an attempt-specific aggregate exists, the dictionary uses it; otherwise it carries forward the latest current aggregate and says so explicitly instead of inventing replacement values.
| attempt | status | evidence_path | row_count | total_questions_sum | correct_questions_sum | interpretation |
|---|---|---|---|---|---|---|
| 1 | completed | source/evidence/attempt1-accuracy-source-aggregate-2026-06-13.json | 16662329 | 59167608 | 51390936 | Attempt 1 uses completed PII-safe aggregate evidence from the required token-file helper path; no raw source rows or student identifiers are published. |
Attempt 1 Token-File Refresh Attempt
| name | purpose | result | elapsed_seconds_before_cancel | out_path_requested |
|---|---|---|---|---|
| processed_facts_accuracy_aggregate | Refresh the PII-safe production value-space evidence for alpha.analytics_accuracy source numerator and denominator columns. | completed | 5.17 | source/evidence/attempt1-accuracy-source-aggregate-2026-06-13.json |
Attempt 2 Token-File Refresh Attempt
| name | purpose | result | elapsed_seconds_before_cancel | out_path_requested |
|---|---|---|---|---|
| processed_facts_accuracy_aggregate | Confirm current production source-shaped total_questions and correct_questions availability for alpha.analytics_accuracy without publishing student identifiers or raw source rows. | cancelled_after_helper_latency | 193 | source/evidence/attempt2-accuracy-source-aggregate-2026-06-13.json |
Attempt 13 Token-File Refresh Attempt
| name | purpose | result | elapsed_seconds_before_cancel | out_path_requested |
|---|---|---|---|---|
| bounded_processed_facts_accuracy_aggregate | Refresh PII-safe current-attempt evidence that the source-shaped public.processed_facts table carries total_questions and correct_questions for alpha.analytics_accuracy. | cancelled_after_helper_latency | 220 | source/evidence/attempt13-accuracy-source-aggregate-2026-06-13.json |
Historical Attempt 8 Source Refresh Audit
| name | purpose | result | elapsed_seconds_before_cancel |
|---|---|---|---|
| bounded_processed_facts_accuracy_aggregate | Refresh PII-safe current-attempt evidence that the source-shaped processed_facts table carries total_questions and correct_questions for alpha.analytics_accuracy. | cancelled_after_helper_latency | 65 |
Historical Attempt 3 Source Refresh Audit
Earlier full and bounded accuracy probes were also cancelled after helper latency; that older audit remains below for traceability.
| name | purpose | result | elapsed_seconds_before_cancel |
|---|---|---|---|
| processed_facts_full_accuracy_aggregate | Refresh a full PII-safe aggregate for total_questions and correct_questions. | cancelled_after_timeout | 120 |
| processed_facts_bounded_accuracy_shape_probe | Refresh a bounded PII-safe source-shape and range probe for total_questions and correct_questions. | cancelled_after_timeout | 75 |
Earlier Accuracy Probe Trail
The attempt-23, attempt-22, attempt-21, attempt-20, attempt-19, attempt-18, attempt-15, attempt-14, attempt-12, attempt-11, attempt-10, attempt-9, attempt-8, and attempt-6 token-file queries are retained for audit. Attempt 6 returned no visible aggregate rows; source/evidence/attempt1-accuracy-source-aggregate-2026-06-13.json is the current attempt accuracy-source evidence used by this rebuild, while the older fresh/attempt files remain as comparison points.
| row_count | rows_with_total_questions | rows_with_correct_questions | total_questions_sum | correct_questions_sum | accuracy_percent |
|---|---|---|---|---|---|
| 16638757 | 2976286 | 2889758 | 59060750 | 51300212 | 86.86 |
| row_count | rows_with_total_questions | rows_with_correct_questions | total_questions_sum | correct_questions_sum | accuracy_percent |
|---|---|---|---|---|---|
| 16638754 | 2976285 | 2889757 | 59060705 | 51300175 | 86.86 |
| row_count | rows_with_total_questions | rows_with_correct_questions | total_questions_sum | correct_questions_sum | accuracy_percent |
|---|---|---|---|---|---|
| 16638754 | 2976285 | 2889757 | 59060705 | 51300175 | 86.86 |
| row_count | rows_with_total_questions | rows_with_correct_questions | total_questions_sum | correct_questions_sum | accuracy_percent |
|---|---|---|---|---|---|
| 16638743 | 2976284 | 2889756 | 59060700 | 51300173 | 86.86 |
| row_count | rows_with_total_questions | rows_with_correct_questions | total_questions_sum | correct_questions_sum | accuracy_percent |
|---|---|---|---|---|---|
| 16638687 | 2976282 | 2889755 | 59060657 | 51300142 | 86.86 |
| row_count | rows_with_total_questions | rows_with_correct_questions | total_questions_sum | correct_questions_sum | accuracy_percent |
|---|---|---|---|---|---|
| 2981190 | 2976278 | 2889752 | 59060632 | 51300130 | 86.86 |
| row_count | rows_with_total_questions | rows_with_correct_questions | total_questions_sum | correct_questions_sum | accuracy_percent |
|---|---|---|---|---|---|
| 16637199 | 2976128 | 2889603 | 59056634 | 51296686 | 86.86 |
| row_count | rows_with_total_questions | rows_with_correct_questions | total_questions_sum | correct_questions_sum | accuracy_percent |
|---|---|---|---|---|---|
| 16637103 | 2976111 | 2889586 | 59055414 | 51295659 | 86.86 |
| row_count | rows_with_total_questions | rows_with_correct_questions | total_questions_sum | correct_questions_sum | accuracy_percent |
|---|---|---|---|---|---|
| 16637016 | 2976064 | 2889539 | 59052844 | 51293251 | 86.86 |
| row_count | rows_with_total_questions | rows_with_correct_questions | total_questions_sum | correct_questions_sum |
|---|---|---|---|---|
| 16636945 | 2976051 | 2889526 | 59052087 | 51292581 |
| row_count | rows_with_total_questions | rows_with_correct_questions | total_questions_sum | correct_questions_sum |
|---|---|---|---|---|
| 16636865 | 2976046 | 2889521 | 59052007 | 51292532 |
| rows_with_questions | total_questions_sum | correct_questions_sum |
|---|---|---|
| 2976040 | 59051833 | 51198540 |
| row_count | rows_with_total_questions | rows_with_correct_questions | total_questions_sum | correct_questions_sum |
|---|---|---|---|---|
| 16636688 | 2976029 | 2889504 | 59051593 | 51292145 |
No rows available.
Approved Architecture Grounding
| queriedWith | queriedAt | reportingDbReachable | xpNaiveMatches | mapNaiveMatches | reconciliationHeadline | consequence |
|---|---|---|---|---|---|---|
| mcp danny-timeback query(database='reporting'); same value-space as scripts/timeback-query.mjs --token-file ~/Documents/timeback-danny-mcp-creds | 2026-06-10 | true | 1/6 subjects | 2/4 subjects for observed/typical | Naive re-derivation from raw source rows produces wrong-but-plausible values for MOST report tiles. The report applies per-subject normalization (source-label normalization, test-app exclusion, daily caps, norms-referenced growth) that only the report pipeline knows. Therefore report-grade facts must be INGESTED from the report source, never re-derived. | aitd-001 (report-source ingestion) + aitd-004 (provenance, no literals): each report tile is ingested by one named adapter from the table above, normalized server-side under the report's documented rule, written with full provenance to alpha.analytics_source_import, and returns null_reason=source_missing rather than a literal/guess when the source row is absent. Derived-from-events facts (aitd-002/005) complement but never substitute for the ingested tile. |
Earlier hp_map_results Probe Trail
The earlier bounded token-file probes for hp_map_results are retained for audit. The fresh aggregate probes above now provide the current source-shape evidence for this attempt.
No rows available.
No rows available.
Learning Report Grounding
The rollback feedback required each Learning Report metric to be grounded in the real reporting database for the named target student. This public section names source columns, rollup fields, and aggregate/probe values; raw rows and identity stay in local evidence files.
Reporting query path: mcp danny-timeback query(database='reporting'); same value-space as scripts/timeback-query.mjs --token-file ~/Documents/timeback-danny-mcp-creds
| reportPanel | reportingSource | analyticsObject | requiredFields | probeValue |
|---|---|---|---|---|
| Panel 3 MAP: Growth Percentile (vs 1yr ago), Growth X, RIT | timeback-map over full source-shaped reporting.hp_map_results Winter 2025-2026 rows; RIT = testritscore; achievement percentile = testpercentile; growth percentile = wintertowinterconditionalgrowthpercentile; observed = wintertowinterobservedgrowth; Growth X denominator = wintertowinterprojectedgrowth | alpha.analytics_map_growth_rollup | source_import_id, growth_window=winter_to_winter, rit_score, achievement_percentile, growth_percentile, observed_growth, projected_growth, typical_growth, growth_x | Math source evidence: rit_score=239, growth_percentile=43, observed_growth=6, projected_growth=7, typical_growth=2; pinned Growth X is 0.8571 from observed/projected, while the old observed/typical probe was only diagnostic evidence. Full-row import contract: accept all hp_map_results columns, including wintertowinter* and unknown extras; ignore extras rather than rejecting. |
| Time Commitment / minutes per enrolled school day | timeback-xp-time-accuracy over reporting.processed_facts active_seconds, inactive_seconds, waste_seconds by student/date/subject for the numerator; the denominator is alpha.school_calendar over Ed-Fi CalendarDate intersected with enrollment and subject assignment. | alpha.analytics_event_time_fact + alpha.analytics_school_day_minutes | source_import_id, active_seconds/active_minutes, enrolled_school_day_count, excluded_school_day_count, minutes_per_enrolled_school_day, null_reason | Report-period processed_facts evidence: 20,390 rows, 193 active dates, active_seconds=1,434,663.17, active_minutes=23,911.053. Those active dates are explicitly not the school-day denominator; the reportable denominator must be the materialized Analytics calendar/enrollment intersection. |
| XP Earned / XP Remaining / XP Goal Percent | timeback-xp-time-accuracy over reporting.processed_facts plus XP-goal policy and Curriculum expected-XP refs; Results xp_ledger remains the audit source where platform ledger rows exist | alpha.analytics_xp_rollup | source_import_id, xp_total, daily_xp_goal, enrolled_school_day_count, xp_goal, xp_remaining, xp_goal_percent, on_track, positive_xp, negative_xp, award_count, reversal_count, null_reason | Approved architecture evidence found naive SUM(processed_facts.xp_earned) reproduced only 1/6 report subjects, so xp_total is an ingested report-ready value with provenance, not a raw SQL sum. XP percent follows alpha.policy.analytics.xp_goal_percent.v1, uses the stored enrolled_school_day_count, and remains uncapped when populated. |
| Accuracy | timeback-xp-time-accuracy over reporting.processed_facts total_questions and correct_questions by student/date/subject, after the adapter applies reportable app/source/score_type filters. | alpha.analytics_accuracy | source_import_id, correct_question_count, total_question_count, incorrect_question_count, accuracy_percent, null_reason | Current token-file evidence confirms the source-shaped processed_facts table carries integer total_questions and correct_questions. The aggregate probe found 2,980,443 rows with total_questions, 59,167,608 total questions, and 51,390,936 correct questions. Attempt 1 documents the Analytics contract for the in-wave implementation family; reports will read alpha.analytics_accuracy and never divide raw source rows or keep private app allowlists. |
| Knowledge Grade / Grade Levels Mastered | timeback-grade-mastery over reporting.assessment_results passed gates; Results student_kc_state remains the canonical mastery state for KC deltas | alpha.analytics_mastery_delta | source_import_id, grade_subject, grade_level, completed_on, state_dimension, transition_kind, source_result_refs | Approved architecture evidence pins assessment_results as the report source for Grade Levels Mastered; old visibility aggregates remain diagnostic only. |
| Course / subject completion % | Events app-reported course percent first; timeback-completion XP remaining fallback second; Curriculum main-course refs define grade-level denominator | alpha.analytics_completion_rollup | source_import_id, completion_scope, scope_id, grade_level, is_main_course, progress_source_kind, xp_earned, xp_remaining, completion_percent, denominator_policy_ref | Direct app-reported percent_complete wins as evidence; if absent, use XP remaining fallback evidence. Results owns grade-level progress and applies main-course active-path semantics. total_questions/correct_questions evidence belongs to Accuracy, not Course Completion. |
Winter 2025-2026 MAP Projection Columns
This table is the MAP fix in one place: winter-to-winter is a separate row/window, wintertowinterprojectedgrowth is the pinned Growth X denominator, and the old observed-over-typical probe remains diagnostic evidence only.
| subject | termname | testritscore | wintertowinterprojectedgrowth | wintertowinterobservedgrowth | typicalwintertowintergrowth | wintertowinterconditionalgrowthpercentile | growth_x_vs_projected | old_observed_over_typical_probe |
|---|---|---|---|---|---|---|---|---|
| Language | Winter 2025-2026 | 232 | 2 | 3 | 2 | 56 | 1.5 | 1.5 |
| Language | Winter 2025-2026 | 232 | 2 | 3 | 2 | 56 | 1.5 | 1.5 |
| Math | Winter 2025-2026 | 239 | 7 | 6 | 2 | 43 | 0.8571 | 3 |
| Math | Winter 2025-2026 | 239 | 7 | 6 | 2 | 43 | 0.8571 | 3 |
| Reading | Winter 2025-2026 | 239 | 2 | 3 | 2 | 58 | 1.5 | 1.5 |
| Reading | Winter 2025-2026 | 239 | 2 | 3 | 2 | 58 | 1.5 | 1.5 |
| Science | Winter 2025-2026 | 229 | 3 | 2 | 2 | 44 | 0.6667 | 1 |
| Science | Winter 2025-2026 | 229 | 3 | 2 | 2 | 44 | 0.6667 | 1 |
Report-Period Processed Facts
These aggregates explain why source-shaped migration rows must carry processed_facts time, XP, mastery, question, score, course, and activity columns into server-side Analytics materializers.
| rows | active_dates | active_seconds | active_minutes | waste_seconds | xp_earned | mastered_units | total_questions | correct_questions |
|---|---|---|---|---|---|---|---|---|
| 20390 | 193 | 1434663.17 | 23911.053 | 37241.85 | 21371.73 | 3053 | 109643 | 92808 |
| subject | rows | active_dates | active_minutes | waste_seconds | xp_earned | mastered_units | total_questions | correct_questions |
|---|---|---|---|---|---|---|---|---|
| FastMath | 1058 | 47 | 697.017 | 37155 | 563.75 | 790 | 15660 | 13409 |
| Language | 2313 | 155 | 4519.083 | 0 | 4795.86 | 627 | 18168 | 16997 |
| Math | 1748 | 144 | 6242.81 | 86.85 | 4060 | 649 | 5451 | 3995 |
| Other | 1 | 1 | 0 | 0 | 25 | 0 | 0 | 0 |
| Reading | 1406 | 145 | 5573.85 | 0 | 5116 | 213 | 5158 | 3363 |
| Science | 1174 | 52 | 3173.6 | 0 | 1163 | 141 | 2374 | 1583 |
| Vocabulary | 1033 | 133 | 460.733 | 0 | 3195.62 | 467 | 61053 | 51938 |
| Writing | 11657 | 112 | 3243.96 | 0 | 2452.5 | 166 | 1779 | 1523 |
Mastery Visibility Source
| course_subject | rows | min_course_grade | max_course_grade | latest_completion_date |
|---|---|---|---|---|
| FastMath | 1 | 5 | 5 | 2025-11-03T15:21:29.287 |
| Language | 1 | 6 | 6 | 2025-12-10T16:54:14.73 |
| Math | 1 | 5 | 5 | 2025-12-16T17:45:35.393 |
| Reading | 1 | 8 | 8 | 2026-03-24T14:59:36.049 |
| Science | 1 | 5 | 5 | 2025-08-27T16:11:38.767 |
| Social Studies | 1 | 3 | 3 | 2025-03-07T03:00:00 |
| Vocabulary | 1 | 10 | 10 | 2026-05-01T15:40:27.617 |
| Writing | 1 | 5 | 5 | 2026-04-10T18:29:51.149 |
General Value-Space Evidence
Fresh processed_facts columns
id email date datetime username user_grade user_family_name user_given_name user_id subject app course_id course_name campus_id campus_name enrollment_id activity_id activity_name total_questions correct_questions xp_earned mastered_units active_seconds inactive_seconds waste_seconds source alpha_level generated_at send_time sensor event_type year month day day_of_week session_id source_system score_type max_score original_event_type original_event_id action score_given object_type parent_object_id
Fresh Caliper type/action distribution
| type | action | n | deleted_n |
|---|---|---|---|
| TimeSpentEvent | SpentTime | 13045113 | 0 |
| ActivityEvent | Completed | 4137166 | 0 |
| Event | Created | 34481 | 0 |
| ToolUseEvent | Used | 3672 | 0 |
| AnnotationEvent | Tagged | 1568 | 0 |
| AssessmentItemEvent | Completed | 738 | 0 |
| SessionEvent | LoggedIn | 270 | 0 |
| SessionEvent | LoggedOut | 193 | 0 |
| Event | Achieved | 132 | 0 |
| AssessmentItemEvent | Skipped | 119 | 0 |
| AssessmentEvent | Submitted | 18 | 0 |
| Event | Used | 8 | 0 |
| Event | Completed | 6 | 0 |
| Event | Viewed | 4 | 0 |
| FeedbackEvent | Commented | 2 | 0 |
| FeedbackEvent | Ranked | 2 | 0 |
| AssessmentEvent | Paused | 1 | 0 |
| AssessmentEvent | Started | 1 | 0 |
| GradeEvent | Graded | 1 | 0 |
Processed Facts Subject Values
| subject | n | active_seconds | inactive_seconds | waste_seconds | xp_earned |
|---|---|---|---|---|---|
| Writing | 4944526 | 78685082.01 | 7.08 | 0 | 1215406.9 |
| Math | 3984163 | 361781553.96 | 3722875.12 | 452971.58 | 4351580.04 |
| Language | 2199666 | 157274095.14 | 618341.92 | 311330.7 | 4886201.78 |
| FastMath | 1993006 | 69638890.86 | 480024.9 | 38169566.1 | 1054788.82 |
| Reading | 1776985 | 178347417.5 | 559883.94 | 124753.45 | 2929304.42 |
| Social Studies | 693587 | 11492725.78 | 3240114.11 | 162669.99 | 358558.43 |
| Science | 545023 | 79827954.43 | 837338.19 | 611348.02 | 1563132.41 |
| Vocabulary | 268392 | 8209617.16 | 198372.5 | 0 | 1073697.11 |
| None | 38702 | 718394.02 | 8109.91 | 12310.9 | 0 |
| (blank) | 13444 | 0 | 0 | 0 | -25179 |
| Other | 3610 | 65648.85 | 1237.93 | 0 | 32157 |
| Biology | 85 | 0 | 0 | 0 | 0 |
| Mathematics | 30 | 0 | 0 | 0 | 165 |
| ELA | 3 | 0 | 0 | 0 | 35 |
Processed Facts App Values
| app | n | active_seconds | inactive_seconds | waste_seconds | xp_earned |
|---|---|---|---|---|---|
| Alphawrite | 4909058 | 69303957.47 | 0 | 0 | 948123.15 |
| TimeBack Dash | 2328169 | 25052400 | 0 | 0 | 1834 |
| AlphaMath Fluency | 1453120 | 55177283.51 | 0 | 38169566.1 | 827989.41 |
| MobyMax | 1194033 | 90547053 | 0 | 0 | 1977383 |
| Zearn | 1033749 | 118232419 | 0 | 0 | 1264126 |
| Lalilo | 712161 | 52269000 | 0 | 0 | 1393125 |
| TeachTales | 671367 | 7863110 | 0 | 0 | 122692 |
| AlphaLearn | 563247 | 29538987.05 | 2125652.69 | 235176.8 | 116256.75 |
| Math Academy | 460530 | 105892772 | 0 | 0 | 1230324 |
| VocabLoco | 274129 | 10271440 | 0 | 0 | 731223 |
| DreamUp | 272295 | 2410132 | 480006 | 0 | 43618.11 |
| Math Raiders | 261884 | 11864614 | 0 | 0 | 174559.75 |
Results Subject Values
| subject | n |
|---|---|
| (null) | 1871757 |
| Language | 1417902 |
| Math | 1043040 |
| FastMath | 1030579 |
| Reading | 783905 |
| Science-notqced | 627047 |
| Vocabulary | 228333 |
| Science | 197166 |
| Writing | 61963 |
| Social Studies | 54811 |
| Math-notqced | 28140 |
| None | 21671 |
| Math-ISEE | 17642 |
| Language-notqced | 11907 |
| ELA | 8663 |
| Reading-ISEE | 8194 |
| Language-ISEE | 8074 |
| Reading-notqced | 7813 |