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.

Surface: alpha Storage: extension-only Tables: 18 Fields: 405 Generated: 2026-07-27T19:27:08.396Z

Overview

18documented tables and read objects
405documented fields
16enum sets
15raw/API rules
No alias map: Analytics has no 1EdTech base. Every object below is a new Alpha extension object whose reason and behavior trace to the accepted Analytics architecture. Source rows remain owned by Events, Results, Curriculum, People and Orgs, or Ed-Fi; Analytics stores references plus derived facts.

Upstream Inputs

Analytics Alpha architecture

Accepted ITDs, table set, API axes, metric-check trace, no-alias extend-only storage.

Events Alpha data dictionary

Event source refs, close notifications, Caliper moment boundary, source imports.

Results Alpha data dictionary

XP ledger, mastery state, MAP score/growth/sitting rows, durable result evidence.

Curriculum Alpha data dictionary

KC, course, track, component, subject, and policy refs.

People and Orgs Alpha data dictionary

Student, school, enrollment, academic-session, and point-in-time identity refs.

Ed-Fi 1EdTech data dictionary

CalendarDate source behind alpha.school_calendar school-day denominator; missing coverage is a launch/repair state, not a report formula.

Metric-Check Trace

Metric CheckAnalytics ObjectDerived FactsITD
minutes|Caliper eventsalpha.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
XPalpha.analytics_xp_rollupxp_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 fallbackaitd-007-xp-rollups
mastery|student_kc_statealpha.analytics_mastery_deltagrade_levels_mastered (subject, grade, completed_on); per-state previous_value, new_value, delta_value, transition_kindaitd-008-mastery-and-grade-levels
RIT|GrowthX|MAP growth windowsalpha.analytics_map_growth_rolluprit, achievement_percentile, growth_percentile, growth_x (= observed / projected, ALPHA-2), growth_x_target, on_trackaitd-009-map-growth-rollups
MAP sittings/scoresalpha.analytics_map_growth_rolluptest_of_record summary plus sitting_count and retake_count for audit/report cellsaitd-009-map-growth-rollups
completion|curriculum refsalpha.analytics_completion_rollupxp_earned, xp_remaining, completion_percent, null_reason (NEVER a 1-if-active fallback)aitd-010-completion-rollups
Learning Report accuracyalpha.analytics_accuracycorrect_question_count, total_question_count, incorrect_question_count, accuracy_percent, null_reasonaitd-001-report-source-ingestion
Learning Report attemptsalpha.analytics_attempt_rollupattempt_count, max_attempt_ordinal, source_event_refs, policy_refaitd-001-report-source-ingestion
Learning Report response latencyalpha.analytics_response_latency_rollupresponse_count, response_time_ms_total, response_time_ms_avg, response_time_ms_min, response_time_ms_max, policy_refaitd-001-report-source-ingestion
Learning Report hint usagealpha.analytics_hint_usage_rolluphint_request_count, hint_view_count, hint_used_count, source_event_refs, policy_refaitd-001-report-source-ingestion
GOALS target dateanalytics.school_days_remaininginstructional_days_remaining, instructional_dates, xp_unit.*, effort.*aitd-018-goals-school-days-remaining
Accuracy (P7) is first-class: this dictionary documents the in-wave contract for 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.
Question interaction rollups are governed: attempts, response latency, and hint usage are stored in 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.
Stripe-style examples: every Analytics object section starts with an example JSON payload before lifecycle, raw DB rules, and field rows. Use Object Example Coverage to jump directly to any payload.

Completion Rollup Retention

Probe tenants are operational stores: 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.

tenanttotalRowscurrentRowssupersededRowscheckedAt
analytics-debug-debug-1781267631521454502026-07-03T23:33:00Z
analytics-live-debug-17812677289871250125002026-07-03T23:33:00Z
reviewer-analytics1606160602026-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.

adapterpanelsourceTablereportColumnsanalyticsObjectadapterContractitd
timeback-xp-time-accuracyXP Goal (P5), Time Commitment (P6), Accuracy (P7)reporting.processed_factsxp_earned, active_seconds, total_questions, correct_questions, subject, date, app, source, score_typealpha.analytics_xp_rollup, alpha.analytics_school_day_minutes, alpha.analytics_accuracyAccept 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-mapMAP Results (P3)reporting.hp_map_resultstestritscore, testpercentile, wintertowinterobservedgrowth, wintertowinterprojectedgrowth, typicalwintertowintergrowth, wintertowinterconditionalgrowthpercentile, termname, growthmeasureynalpha.analytics_map_growth_rollupAccept 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-masteryGrade Levels Mastered (P4)reporting.assessment_resultsstudent_sourced_id, score, score_status, score_date, learning_objective_set, assessment_line_item_sourced_idalpha.analytics_mastery_deltaAccept 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-completionCourse Completion (P2)reporting.processed_facts + reporting.courses + reporting.course_componentsxp_earned (earned) + course expected XP (remaining denominator)alpha.analytics_completion_rollupAccept 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
No literal fallback: if an expected source row is missing, Analytics writes a typed 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, and curriculum_scope_refs plus derived values such as active_seconds_total or growth_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

Active means your child was doing reportable school work. Inactive means the source says time passed but the student was idle, paused, or not meaningfully engaged. Waste means the source was classified as gaming, distraction, or anti-pattern work.

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

ValueCurrent SettingWhat It Means In A Report
eligible_event_tuplesTimeSpentEvent/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 ruleClosed 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 classifierForeground 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 tuplesEvent/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_seconds60After 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 rulePaused 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 ruleTimebackProfile 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 ladder1 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 roundingStore 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 FieldMeaningExample / Source
eligible_event_typesCaliper/TimebackProfile event types allowed to contribute seconds.["TimeSpentEvent", "ActivityEvent", "TimebackProfile.AntiPatternEvent"]
active_source_rulesRegistry 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_rulesPolicy-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_rulesPolicy-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_refThe 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

Reports ask for named windows. Analytics has already chosen the start and end dates, so a dashboard does not parse labels like Winter 2026.

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

ValueCurrent SettingWhat 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_dayMondayWeekly rollups start Monday in the school timezone.
timezonePeople 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 sourcePeople 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 FieldMeaningExample / Source
school_timezone_sourceWhere the school timezone comes from.People and Orgs school/org config
week_start_dayFirst day of the platform week.Monday
academic_session_sourceSource 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

Reports group by math, reading, language, science, vocabulary, and writing. Source labels such as FastMath, Vocab, ELA, or Science-notqced are normalized to a governed canonical subject or rejected before a row is reportable.

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

ValueCurrent SettingWhat It Means In A Report
canonical subject_id valuesmath, reading, language, science, vocabulary, writingAnalytics rows use these values only.
learning source-label normalizationFastMath->math; ELA/Language Arts->language; Vocab/Vocabulary->vocabulary; Science->science.These normalization happens before a derived fact is written.
MAP/report source-label normalizationFastMath->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 valueanalytics:adapter_rejected or quality_status=source_unlinked.A consumer never creates a new subject string to make a report work.

Required Config Fields

Config FieldMeaningExample / Source
canonical_valuesAllowed subject_id values.math, reading, language, science, vocabulary, writing
source_label_normalizationSource labels mapped at write time.FastMath->math, Vocab/Vocabulary->vocabulary, ELA/Language Arts->language
rejected_valuesOut-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.

Trace: aitd-011-policy-and-enum-normalization

School-Day Denominator

alpha.policy.school_day.v2026-06-10

This is the denominator for time commitment. The ratified rule is: count days the student was enrolled and the student's school was in session. Enrollment begin/end dates bound the count; the student's school calendar governs it; MAP testing days are excluded; and per-subject rows count only days with a subject assignment. The report reads the stored denominator and average from Analytics; if the calendar source is missing, that is a repair state, not a value a report can replace.

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

ValueCurrent SettingWhat It Means In A Report
launch/reportability requirementalpha.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 denominatordays 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_dayreason=instructional only.Every other Alpha reason is excluded unless a future accepted policy version explicitly maps a governed value to instructional.
excluded reasonsweekend, teacher_workshop, holiday_break, nwea_map_testing, other.NWEA MAP testing days are not school days for this time-commitment denominator.
MAP testing exclusion3 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 intersectionbegin_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 denominatorA 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 divergenceDocumented 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 fallbackprocessed_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 FieldMeaningExample / Source
calendar_sourceCalendar rows behind alpha.school_calendar.Ed-Fi CalendarDate.CalendarEvents, surfaced as the Alpha school calendar source for denominator materialization
reason_mapMapping from Ed-Fi CalendarEventDescriptor values to Alpha reasons.See the Calendar Code Map below.
enrollment_sourceEffective-dated People and Orgs membership/enrollment rows.begin_date/end_date point-in-time rule
subject_assignment_sourceCourse/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

Analytics tells you the XP total, goal, remaining XP, and uncapped XP goal percent to show. Goal, remaining XP, and XP percent use the same school-day denominator as time commitment, and the report reads those stored fields instead of multiplying days locally.

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

ValueCurrent SettingWhat It Means In A Report
report sourcetimeback-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_sourceResults 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 statusesok, 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=okInclude in positive_xp or negative_xp according to the signed XP value.Ordinary report rows include ok.
quality_status=correctedInclude 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=reversedInclude 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_rejectedExclude from display totals; expose through import/problem/audit reads.These statuses explain why no reportable XP total could be materialized.
positive_xpPositive contribution audit subtotal from the adapter/ledger refs.Nonnegative by definition; supports explanations but is not a client formula source.
negative_xpPenalty/reversal audit subtotal from the adapter/ledger refs.Kept zero-or-negative; never clamped away by a report.
xp_totalThe report-ready XP total the Learning Report renders.Non-null values require source_import_id provenance under aitd-004.
denominator sourcealpha.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 policyalpha.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 denominatordaily_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 remainingxp_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 aliasxp_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 statusreportable 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 FieldMeaningExample / Source
report_source_adapterNamed source adapter for report XP values.timeback-xp-time-accuracy over reporting.processed_facts
ledger_sourceCanonical source for awarded XP audit refs when present.Results alpha.xp_ledger
window_policy_refWindow policy used for grouping.alpha.policy.analytics.window.v2026-06-10
goal_policy_refPolicy/Curriculum source for daily XP goals and school-day denominator.alpha.policy.analytics.xp_goal_percent.v1 plus Curriculum expected_xp refs
include_reversalsWhether 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

This is the over-goal number parents see once the denominator exists. If a student earns more than the goal, the percent stays above 100 instead of being capped. While the shared school-day denominator is missing, the percent is unavailable rather than guessed.

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

ValueCurrent SettingWhat It Means In A Report
denominator sourceenrolled_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.
formulaxp_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 behavioruncapped 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 variantrejected.No field, website, implementation, report, or skill pack may define a captured/capped 0-to-100 XP percent variant for this tile.
null behaviornull_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 FieldMeaningExample / Source
daily_xp_goal_sourceSource of the daily XP target.alpha.policy.analytics.xp_goal_percent.v1 / Curriculum Policy
school_day_sourceSource of enrolled_school_days.alpha.policy.school_day.v2026-06-10
cap_behaviorWhether 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

For GOALS target dates, one XP means one expected minute of work. Sixty XP is one expected hour. GOALS reads this convention from Analytics instead of carrying an XP_PER_HOUR constant.

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

ValueCurrent SettingWhat It Means In A Report
xp_per_expected_minute11 XP equals 1 expected minute for GOALS and target-date effort reads.
xp_per_hour6060 XP equals one expected hour.
hours formulahours_remaining = expected_minutes_remaining / 60.Analytics returns the value; GOALS does not keep a private XP_PER_HOUR constant.
school-day pacing formularequired_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 formulaschool_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 FieldMeaningExample / Source
xp_per_expected_minuteHow many XP equal one expected minute.1
xp_per_hourHow many XP equal one expected hour.60
unit_ownerWhere the convention lives.alpha.policy.analytics.xp_expected_minute.v2026-06-14
applies_toFields 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

Accuracy (P7) is the percent-correct number parents see. This data dictionary makes Accuracy a first-class Analytics contract for the current wave: reports query alpha.analytics_accuracy or GET /alpha/analytics/v1/accuracy-rollups. The endpoint is served at this wave's implementation cell, so live materialization evidence belongs to the following implementation/integration cells; the report query shape is final here. Apps never divide raw source rows or decide which app/question rows count.

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

ValueCurrent SettingWhat It Means In A Report
report sourcetimeback-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.
formulaaccuracy_percent = correct_question_count / total_question_count x 100.Analytics stores the percent. Consumers read it and never recompute from processed_facts.
denominator zeroaccuracy_percent=null and null_reason=no_questions.A report shows unavailable/no attempts instead of pretending the student had 0% or 100% accuracy.
question filtersOnly rows accepted by the adapter under policy_ref count.Apps do not keep local app/source/score_type allowlists.
source provenanceNon-null values require source_import_id.The report can audit which source-shaped import produced the Accuracy row.

Required Config Fields

Config FieldMeaningExample / Source
report_source_adapterNamed source adapter for report Accuracy values.timeback-xp-time-accuracy over reporting.processed_facts
question_columnsSource-shaped columns the adapter accepts.total_questions, correct_questions, subject, date, app, source, score_type
include_source_rulesPolicy-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
roundingDisplay 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

Analytics shows what changed. Results still owns the current mastery state.

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

ValueCurrent SettingWhat It Means In A Report
state dimensionsinitial_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_refalpha.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_refalpha.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 ruleA 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 ruleA 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 ruleA 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 ruleA 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 ruleA 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 summaryResults 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 visibilitycurrent_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 transitiontransition_kind=blocked and quality_status/source null_reason explain missing evidence.No guessed mastery delta is written.

Required Config Fields

Config FieldMeaningExample / Source
state_sourceCurrent/state history source.Results alpha.student_kc_state
evidence_sourceResults/KC evidence refs explaining the transition.alpha.result_kc_evidence
blocked_transition_handlingHow 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

A report changes norms by changing norms_set. It may read/cache the surface's versioned norms and R90 tables, but it never ships a private norms table, picks retakes, or parses term strings.

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

ValueCurrent SettingWhat It Means In A Report
allowed norms_set2020, 2025.Every MAP row carries the selected norms family; reports regenerate under a different norms set by changing this filter.
growth_window valuesfall_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 windowUse 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 mappingRIT = 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 importAccept 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 groundingArchitecture 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 formulagrowth_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_target2.0000.Current Alpha commitment: twice typical growth.
on_track ruleon_track = growth_x >= growth_x_target when both values are present.Null growth_x or target yields on_track=null with null_reason.
norms sourceAnalytics 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 FieldMeaningExample / Source
test_of_record_sourceResults row that already applied the MAP test-of-record rule.alpha.map_score
report_source_adapterNamed source adapter for MAP report values.timeback-map over reporting.hp_map_results
learning_report_growth_windowWindow used by the parent Learning Report "Growth Percentile (vs 1yr ago)" panel.winter_to_winter
growth_x_targetTarget multiplier used by on_track.2.0000 under current Alpha commitment, read from policy
norms_setsAllowed 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

This is how GOALS turns "I want the 99th percentile" into a RIT and grade-level target. The table and the API live on the surface, so apps do not carry their own norms or R90 copy.

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

ValueCurrent SettingWhat It Means In A Report
serving homeanalytics/alpha.Per ruling R1, Analytics serves Alpha-side norms/R90 resources; NWEAMap 1EdTech remains the raw mirror and provenance source.
allowed norms_set2020, 2025.The same GOALS or Learning Report query can be rerun under either norms family by flipping norms_set.
current norms table_versionanalytics.norms.achievement.v2026-06-12The NWEA achievement norms table version used by current percentile<->RIT reads.
current R90 table_versionanalytics.rit_to_grade.powerpath.v2026-06-15The PowerPath RIT-to-grade table version required for current raw/API convergence; raw readers do not infer current by sorting names.
R90 one-version rulealpha.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 ruleRead 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 ruleUse 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 ruleRead 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 ruleR90 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 behaviorResponses 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 behaviorInvalid 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 FieldMeaningExample / Source
norms_resourceReadable NWEA achievement-status norms table.alpha.analytics_norms_achievement
r90_resourceReadable RIT50/RIT90/effective-grade table.alpha.analytics_r90_table
version_keyCache/reproducibility key.norms_set + table_version
percentile_rit_ruleHow 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_ruleHow 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

R90 is Alpha extrapolation, not an NWEA-published score. This policy tells a parent or app exactly which Alpha method produced the row it is reading, so no one keeps a private R90 copy or silently changes the method.

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

ValueCurrent SettingWhat It Means In A Report
serving homeanalytics/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_versionanalytics.rit_to_grade.powerpath.v2026-06-15Pinned by AITD-017 and echoed by /r90 plus /r90/table.
RIT50 handlingThe current R50/R90 serving follows the PowerPath RIT-to-grade table.The dictionary current path follows the served PowerPath mirror.
RIT90 handlingRows 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 behaviorFilter 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 behaviorAny 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 behaviorResponses 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 FieldMeaningExample / Source
source_resourceReadable surface resource using this method.alpha.analytics_r90_table
published_anchor_sourceSource of the current R90 grade-position rows.powerpath:/powerpath/rit-to-grade
owner_modulePlatform module that owns the PowerPath RIT-to-grade master.nweamap
extend_kindHonesty marker on R90 rows.alpha_extrapolation
version_boundaryWhen 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

Analytics preserves typed progress evidence for Results and audits. Learning Report and GOALS consumers read actual course and grade-level progress from Results course-progress and grade-level-progress. NWEA MAP/RIT/R90 can explain grade position, but it never computes actual course or grade-level progress.

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

ValueCurrent SettingWhat It Means In A Report
precedenceapp-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 denominatorcompletion_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 statusesok, corrected.Other quality statuses are audit/findings until repaired.
scope graincourse, subject, track, track_level, grade_level, segment.The scope controls what scope_id points to and what policy selected as expected work.
worked direct exampleA 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 exampleA 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 FieldMeaningExample / Source
event_sourceNamed Events extension source for direct course progress.TimebackProfile courseProgressPercent / percentComplete
report_source_adapterNamed source adapter for XP-remaining fallback.timeback-completion over reporting.processed_facts
denominator_policy_refWhich denominator policy was used for the scope.alpha.policy.analytics.course_progress.v2026-06-15
zero_denominator_behaviorHow 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

This is the XP fallback rule for Analytics evidence. Direct app-reported course percent remains the first source of evidence used by Results for actual course progress.

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

ValueCurrent SettingWhat It Means In A Report
accepted_report_source_shapesreporting.processed_facts rows linked to the requested completion scope.Each accepted row must resolve to a Curriculum denominator scope.
ordinary report statusesok, corrected.reversed/source_missing/source_unlinked/policy_pending/adapter_rejected do not increase xp_earned.
completion evidence ruleEarned 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 FieldMeaningExample / Source
accepted_report_source_shapesReport-source shapes allowed to count.reporting.processed_facts rows linked to scope and accepted by adapter policy
required_quality_statusQuality statuses allowed in ordinary completion reports.ok, corrected; exclude source_missing/source_unlinked/policy_pending/adapter_rejected
source_ref_matchHow 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

This is the main-course rule. It decides the grade-level progress denominator without asking a report to infer it from MAP/RIT/R90 or walk a Curriculum tree.

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

ValueCurrent SettingWhat It Means In A Report
included_course_rolemain.Only main courses count toward grade-level progress. Hole-filling and remediation do not.
denominator worked shapeTwo 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 traversalServer-side Curriculum reference expansion under denominator_policy_ref.Reports do not recursively query course_component or course_component_member.
student-specific filteringExpected 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 denominatorxp_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 FieldMeaningExample / Source
scope_ref_sourceCurriculum refs used for denominator membership.course_component, course_component_member, KC refs
included_course_roleCourse role that contributes to grade-level progress.main
excluded_course_rolesCourse roles excluded from grade-level progress.hole_filling, remediation, remedial, catalog, practice, review
zero_denominator_reasonThe 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

Current source status: 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.

statuscheckedByrowCountschoolDayRowsschoolCountdateRangereasonscontract
verified_availabledata dictionary attempt 1 using current read-only Node/Postgres persistence evidence plus operator reporting-probe settlement92385674142025-08-13 to 2027-06-06holiday_break, instructional, nwea_map_testing, other, weekendA 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.
alphaReasonedFiCalendarEventCodescountsAsSchoolDaymeaning
instructionalInstructional day,Make-up day,Student late arrival/early dismissalyesCounts in the denominator when it also intersects the student enrollment and, for subject rows, subject assignment.
teacher_workshopTeacher only daynoTeachers are working but students are not expected to produce learning minutes.
holiday_breakHolidaynoInstruction is cancelled for holiday or break; minutes are not divided by this date.
nwea_map_testingTenant-governed NWEA/MAP testing CalendarEventDescriptor valuesnoMAP testing days are excluded from the time-commitment denominator by alpha.policy.school_day.
otherEmergency day,Non-instructional day,Other,Strike,Weather day,tenant-governed uncovered valuesno unless policy explicitly maps the governed value to instructionalA 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)

Queryable pointer: read 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, with accuracy_percent=null and null_reason=no_questions when 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_accuracy current ok/corrected rows. Do not sum reporting.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.

PanelAnalytics ObjectRecipeRequired FieldsAPIRaw DB Rule
timeCommitment
Time 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.
xpGoals
XP 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.
accuracy
Accuracy (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.
masteryTransitions
Mastery / 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.
mapResults
MAP 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.
courseCompletion
Course 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.
goalsTargetDate
GOALS 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.
goalsAgeGradeStatus
GOALS 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.
fullLearningReport
End-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.

EndpointPanelRecipeReadsContract 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

  1. 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.
  2. 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.
  3. 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

  1. Resolve the student school by effective-dated People and Orgs enrollment, or pass a schoolId when the caller already has the governed school id.
  2. 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.
  3. 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.
  4. 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

  1. 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.
  2. Read working_grade and highest_mastered_grade from Results. Results owns the working-grade resolver; Analytics only compares returned grade positions.
  3. 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

  1. 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.
  2. Read the six Analytics tables/endpoints at their documented grains with the ordinary current-row filters.
  3. 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.

ObjectExample AnchorWhat 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

One source event became one signed time contribution. Reports normally read the rollups, but this table explains why minutes changed.

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

Kind: Alpha extension table
Grain: One source Event contribution per fact_kind, policy_ref, and calculation_version.
Primary key: id; unique report grain is (tenant_id, source_event_id, fact_kind, policy_ref, calculation_version) for current rows.
Metric checks: minutes|Caliper events
API: GET /alpha/analytics/v1/event-time-facts

Example 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
ValueMeaningSourceITD
active_secondsSeconds the policy classifies as productive engaged work for a closed source event.Alpha extension enumaitd-005-time-facts-and-windows, aitd-011-policy-and-enum-normalization
inactive_secondsSeconds the policy classifies as idle or not meaningfully engaged.Alpha extension enumaitd-005-time-facts-and-windows, aitd-011-policy-and-enum-normalization
waste_secondsSeconds the policy classifies as gaming, distraction, or otherwise counterproductive work.Alpha extension enumaitd-005-time-facts-and-windows, aitd-011-policy-and-enum-normalization
quality_status
ValueMeaningSourceITD
okThe row is the current reportable fact for its key and policy.Alpha extension enumaitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope, aitd-111-axis-privacy-retention
correctedThe row includes a correction contribution but remains reportable.Alpha extension enumaitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope, aitd-111-axis-privacy-retention
reversedThe row reverses a prior contribution and should be read as signed history.Alpha extension enumaitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope, aitd-111-axis-privacy-retention
source_missingA required source row was removed or unavailable before the fact could be finalized.Alpha extension enumaitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope, aitd-111-axis-privacy-retention
source_unlinkedThe source row exists but could not link to a required Event, Result, student, subject, KC, course, or policy ref.Alpha extension enumaitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope, aitd-111-axis-privacy-retention
policy_pendingA required policy configuration was missing or not yet active at materialization time.Alpha extension enumaitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope, aitd-111-axis-privacy-retention
adapter_rejectedThe source-shaped row was valid input but the server-side adapter rejected it with a typed Problem.Alpha extension enumaitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope, aitd-111-axis-privacy-retention

alpha.analytics_time_window

How much active, inactive, and waste time a student had in a day, week, term, school year, or named custom range.

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

Kind: Alpha extension rollup table
Grain: student_id x subject_id nullable x window_kind x window_start x window_end x policy_ref.
Primary key: id; unique current grain is (tenant_id, student_id, subject_id, window_kind, window_start, window_end, policy_ref, calculation_version).
Metric checks: minutes|Caliper events
API: GET /alpha/analytics/v1/time-windows

Example 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
ValueMeaningSourceITD
dayA calendar day in the school timezone, represented as a half-open date range.Alpha extension enumaitd-005-time-facts-and-windows, aitd-103-axis-query-model, aitd-011-policy-and-enum-normalization
weekA platform week under alpha.policy.analytics.window.Alpha extension enumaitd-005-time-facts-and-windows, aitd-103-axis-query-model, aitd-011-policy-and-enum-normalization
termAn academic term from the People and Orgs academic-session calendar.Alpha extension enumaitd-005-time-facts-and-windows, aitd-103-axis-query-model, aitd-011-policy-and-enum-normalization
school_yearA school-year window from the org academic-session calendar.Alpha extension enumaitd-005-time-facts-and-windows, aitd-103-axis-query-model, aitd-011-policy-and-enum-normalization
customA caller-requested or migration reconciliation range with explicit start and end dates.Alpha extension enumaitd-005-time-facts-and-windows, aitd-103-axis-query-model, aitd-011-policy-and-enum-normalization
quality_status
ValueMeaningSourceITD
okThe row is the current reportable fact for its key and policy.Alpha extension enumaitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope, aitd-111-axis-privacy-retention
correctedThe row includes a correction contribution but remains reportable.Alpha extension enumaitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope, aitd-111-axis-privacy-retention
reversedThe row reverses a prior contribution and should be read as signed history.Alpha extension enumaitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope, aitd-111-axis-privacy-retention
source_missingA required source row was removed or unavailable before the fact could be finalized.Alpha extension enumaitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope, aitd-111-axis-privacy-retention
source_unlinkedThe source row exists but could not link to a required Event, Result, student, subject, KC, course, or policy ref.Alpha extension enumaitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope, aitd-111-axis-privacy-retention
policy_pendingA required policy configuration was missing or not yet active at materialization time.Alpha extension enumaitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope, aitd-111-axis-privacy-retention
adapter_rejectedThe source-shaped row was valid input but the server-side adapter rejected it with a typed Problem.Alpha extension enumaitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope, aitd-111-axis-privacy-retention

alpha.analytics_school_day_minutes

The Learning Report time-commitment row: active minutes plus the materialized school-day denominator and report-ready minutes per enrolled school day.

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

Kind: Alpha extension rollup table
Grain: student_id x school_id x subject_id nullable x window_start x window_end x school_day_policy_ref.
Primary key: id; unique current grain is (tenant_id, student_id, school_id, subject_id, window_start, window_end, school_day_policy_ref, calculation_version).
Metric checks: minutes|Caliper events
API: GET /alpha/analytics/v1/school-day-minutes

Example 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
ValueMeaningSourceITD
okThe row is the current reportable fact for its key and policy.Alpha extension enumaitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope, aitd-111-axis-privacy-retention
correctedThe row includes a correction contribution but remains reportable.Alpha extension enumaitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope, aitd-111-axis-privacy-retention
reversedThe row reverses a prior contribution and should be read as signed history.Alpha extension enumaitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope, aitd-111-axis-privacy-retention
source_missingA required source row was removed or unavailable before the fact could be finalized.Alpha extension enumaitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope, aitd-111-axis-privacy-retention
source_unlinkedThe source row exists but could not link to a required Event, Result, student, subject, KC, course, or policy ref.Alpha extension enumaitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope, aitd-111-axis-privacy-retention
policy_pendingA required policy configuration was missing or not yet active at materialization time.Alpha extension enumaitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope, aitd-111-axis-privacy-retention
adapter_rejectedThe source-shaped row was valid input but the server-side adapter rejected it with a typed Problem.Alpha extension enumaitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope, aitd-111-axis-privacy-retention
null_reason
ValueMeaningSourceITD
noneNo null-producing condition applies.Alpha extension enumaitd-011-policy-and-enum-normalization
no_school_daysThe denominator window has zero enrolled school days after calendar and enrollment intersection.Alpha extension enumaitd-011-policy-and-enum-normalization
no_questionsThe window has zero reportable question attempts, so accuracy_percent is null rather than guessed as 0 or 100.Alpha extension enumaitd-011-policy-and-enum-normalization
no_enrollmentThe student has no time-locatable enrollment for the requested range.Alpha extension enumaitd-011-policy-and-enum-normalization
no_subject_assignmentThe student had no subject assignment/course/test membership for the subject denominator.Alpha extension enumaitd-011-policy-and-enum-normalization
source_missingRequired Event, Result, calendar, enrollment, or curriculum source evidence is missing.Alpha extension enumaitd-011-policy-and-enum-normalization
source_unlinkedSource evidence exists but cannot be linked to platform ids under the current policy.Alpha extension enumaitd-011-policy-and-enum-normalization
policy_pendingThe named policy needed to compute the measure is missing or not active.Alpha extension enumaitd-011-policy-and-enum-normalization
not_applicableThe metric does not apply at this grain, such as MAP growth for a non-MAP subject.Alpha extension enumaitd-011-policy-and-enum-normalization

alpha.analytics_xp_rollup

The XP Goal tile row: report-source XP total plus daily goal, stored school-day denominator, remaining XP, and uncapped XP goal percent.

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

Kind: Alpha extension rollup table
Grain: student_id x subject_id nullable x window_kind x window_start x window_end x policy_ref.
Primary key: id; unique current grain is (tenant_id, student_id, subject_id, window_kind, window_start, window_end, policy_ref, calculation_version).
Metric checks: XP
API: GET /alpha/analytics/v1/xp-rollups

Example 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
ValueMeaningSourceITD
dayA calendar day in the school timezone, represented as a half-open date range.Alpha extension enumaitd-005-time-facts-and-windows, aitd-103-axis-query-model, aitd-011-policy-and-enum-normalization
weekA platform week under alpha.policy.analytics.window.Alpha extension enumaitd-005-time-facts-and-windows, aitd-103-axis-query-model, aitd-011-policy-and-enum-normalization
termAn academic term from the People and Orgs academic-session calendar.Alpha extension enumaitd-005-time-facts-and-windows, aitd-103-axis-query-model, aitd-011-policy-and-enum-normalization
school_yearA school-year window from the org academic-session calendar.Alpha extension enumaitd-005-time-facts-and-windows, aitd-103-axis-query-model, aitd-011-policy-and-enum-normalization
customA caller-requested or migration reconciliation range with explicit start and end dates.Alpha extension enumaitd-005-time-facts-and-windows, aitd-103-axis-query-model, aitd-011-policy-and-enum-normalization
quality_status
ValueMeaningSourceITD
okThe row is the current reportable fact for its key and policy.Alpha extension enumaitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope, aitd-111-axis-privacy-retention
correctedThe row includes a correction contribution but remains reportable.Alpha extension enumaitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope, aitd-111-axis-privacy-retention
reversedThe row reverses a prior contribution and should be read as signed history.Alpha extension enumaitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope, aitd-111-axis-privacy-retention
source_missingA required source row was removed or unavailable before the fact could be finalized.Alpha extension enumaitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope, aitd-111-axis-privacy-retention
source_unlinkedThe source row exists but could not link to a required Event, Result, student, subject, KC, course, or policy ref.Alpha extension enumaitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope, aitd-111-axis-privacy-retention
policy_pendingA required policy configuration was missing or not yet active at materialization time.Alpha extension enumaitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope, aitd-111-axis-privacy-retention
adapter_rejectedThe source-shaped row was valid input but the server-side adapter rejected it with a typed Problem.Alpha extension enumaitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope, aitd-111-axis-privacy-retention
null_reason
ValueMeaningSourceITD
noneNo null-producing condition applies.Alpha extension enumaitd-011-policy-and-enum-normalization
no_school_daysThe denominator window has zero enrolled school days after calendar and enrollment intersection.Alpha extension enumaitd-011-policy-and-enum-normalization
no_questionsThe window has zero reportable question attempts, so accuracy_percent is null rather than guessed as 0 or 100.Alpha extension enumaitd-011-policy-and-enum-normalization
no_enrollmentThe student has no time-locatable enrollment for the requested range.Alpha extension enumaitd-011-policy-and-enum-normalization
no_subject_assignmentThe student had no subject assignment/course/test membership for the subject denominator.Alpha extension enumaitd-011-policy-and-enum-normalization
source_missingRequired Event, Result, calendar, enrollment, or curriculum source evidence is missing.Alpha extension enumaitd-011-policy-and-enum-normalization
source_unlinkedSource evidence exists but cannot be linked to platform ids under the current policy.Alpha extension enumaitd-011-policy-and-enum-normalization
policy_pendingThe named policy needed to compute the measure is missing or not active.Alpha extension enumaitd-011-policy-and-enum-normalization
not_applicableThe metric does not apply at this grain, such as MAP growth for a non-MAP subject.Alpha extension enumaitd-011-policy-and-enum-normalization

alpha.analytics_accuracy

The Learning Report Accuracy tile row: correct questions, total questions, incorrect questions, and percent correct with source-import provenance.

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

Kind: Alpha extension rollup table
Grain: student_id x subject_id nullable x window_kind x window_start x window_end x policy_ref.
Primary key: id; unique current grain is (tenant_id, student_id, subject_id, window_kind, window_start, window_end, policy_ref, calculation_version).
Metric checks: Learning Report accuracy
API: GET /alpha/analytics/v1/accuracy-rollups

Example 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
ValueMeaningSourceITD
dayA calendar day in the school timezone, represented as a half-open date range.Alpha extension enumaitd-005-time-facts-and-windows, aitd-103-axis-query-model, aitd-011-policy-and-enum-normalization
weekA platform week under alpha.policy.analytics.window.Alpha extension enumaitd-005-time-facts-and-windows, aitd-103-axis-query-model, aitd-011-policy-and-enum-normalization
termAn academic term from the People and Orgs academic-session calendar.Alpha extension enumaitd-005-time-facts-and-windows, aitd-103-axis-query-model, aitd-011-policy-and-enum-normalization
school_yearA school-year window from the org academic-session calendar.Alpha extension enumaitd-005-time-facts-and-windows, aitd-103-axis-query-model, aitd-011-policy-and-enum-normalization
customA caller-requested or migration reconciliation range with explicit start and end dates.Alpha extension enumaitd-005-time-facts-and-windows, aitd-103-axis-query-model, aitd-011-policy-and-enum-normalization
quality_status
ValueMeaningSourceITD
okThe row is the current reportable fact for its key and policy.Alpha extension enumaitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope, aitd-111-axis-privacy-retention
correctedThe row includes a correction contribution but remains reportable.Alpha extension enumaitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope, aitd-111-axis-privacy-retention
reversedThe row reverses a prior contribution and should be read as signed history.Alpha extension enumaitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope, aitd-111-axis-privacy-retention
source_missingA required source row was removed or unavailable before the fact could be finalized.Alpha extension enumaitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope, aitd-111-axis-privacy-retention
source_unlinkedThe source row exists but could not link to a required Event, Result, student, subject, KC, course, or policy ref.Alpha extension enumaitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope, aitd-111-axis-privacy-retention
policy_pendingA required policy configuration was missing or not yet active at materialization time.Alpha extension enumaitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope, aitd-111-axis-privacy-retention
adapter_rejectedThe source-shaped row was valid input but the server-side adapter rejected it with a typed Problem.Alpha extension enumaitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope, aitd-111-axis-privacy-retention
null_reason
ValueMeaningSourceITD
noneNo null-producing condition applies.Alpha extension enumaitd-011-policy-and-enum-normalization
no_school_daysThe denominator window has zero enrolled school days after calendar and enrollment intersection.Alpha extension enumaitd-011-policy-and-enum-normalization
no_questionsThe window has zero reportable question attempts, so accuracy_percent is null rather than guessed as 0 or 100.Alpha extension enumaitd-011-policy-and-enum-normalization
no_enrollmentThe student has no time-locatable enrollment for the requested range.Alpha extension enumaitd-011-policy-and-enum-normalization
no_subject_assignmentThe student had no subject assignment/course/test membership for the subject denominator.Alpha extension enumaitd-011-policy-and-enum-normalization
source_missingRequired Event, Result, calendar, enrollment, or curriculum source evidence is missing.Alpha extension enumaitd-011-policy-and-enum-normalization
source_unlinkedSource evidence exists but cannot be linked to platform ids under the current policy.Alpha extension enumaitd-011-policy-and-enum-normalization
policy_pendingThe named policy needed to compute the measure is missing or not active.Alpha extension enumaitd-011-policy-and-enum-normalization
not_applicableThe metric does not apply at this grain, such as MAP growth for a non-MAP subject.Alpha extension enumaitd-011-policy-and-enum-normalization

alpha.analytics_mastery_delta

Grade Levels Mastered plus KC mastery-state changes. It is not the current mastery state.

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

Kind: Alpha extension ledger table
Grain: One state transition per student_id, kc_id|grade_scope, state_dimension, effective_at, policy_ref, and calculation_version.
Primary key: id; unique source transition key is (tenant_id, source_state_ref, state_dimension, effective_at, policy_ref, calculation_version).
Metric checks: mastery|student_kc_state
API: GET /alpha/analytics/v1/mastery-deltas

Example 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
ValueMeaningSourceITD
mathMath subject rollups and MAP/math source-label normalization.Alpha/Curriculum governed enumaitd-011-policy-and-enum-normalization
readingReading subject rollups.Alpha/Curriculum governed enumaitd-011-policy-and-enum-normalization
languageLanguage / ELA subject rollups. Public reads keep vocabulary and writing as distinct canonical subjects.Alpha/Curriculum governed enumaitd-011-policy-and-enum-normalization
scienceScience subject rollups.Alpha/Curriculum governed enumaitd-011-policy-and-enum-normalization
vocabularyVocabulary activity rollups as the canonical vocabulary subject.Alpha/Curriculum governed enumaitd-011-policy-and-enum-normalization
writingWriting activity rollups as the canonical writing subject.Alpha/Curriculum governed enumaitd-011-policy-and-enum-normalization
state_dimension
ValueMeaningSourceITD
initial_masteryThe acquisition/mastery signal changed for the KC.Alpha extension enumaitd-008-mastery-and-grade-levels, aitd-011-policy-and-enum-normalization
current_retentionThe retained mastery value changed under the Results retention policy.Alpha extension enumaitd-008-mastery-and-grade-levels, aitd-011-policy-and-enum-normalization
durable_masteryThe durable mastery state changed.Alpha extension enumaitd-008-mastery-and-grade-levels, aitd-011-policy-and-enum-normalization
fluency_stateThe fluency/automaticity state changed.Alpha extension enumaitd-008-mastery-and-grade-levels, aitd-011-policy-and-enum-normalization
next_due_atThe next review or practice due date changed.Alpha extension enumaitd-008-mastery-and-grade-levels, aitd-011-policy-and-enum-normalization
transition_kind
ValueMeaningSourceITD
acquiredThe student crossed into mastery/acquisition for the KC.Alpha extension enumaitd-008-mastery-and-grade-levels, aitd-011-policy-and-enum-normalization
improvedThe state value increased but did not represent first acquisition.Alpha extension enumaitd-008-mastery-and-grade-levels, aitd-011-policy-and-enum-normalization
decayedThe value decreased under Results retention state.Alpha extension enumaitd-008-mastery-and-grade-levels, aitd-011-policy-and-enum-normalization
review_dueThe due-date dimension moved into a new due state.Alpha extension enumaitd-008-mastery-and-grade-levels, aitd-011-policy-and-enum-normalization
fluency_changedThe fluency dimension changed.Alpha extension enumaitd-008-mastery-and-grade-levels, aitd-011-policy-and-enum-normalization
correctedThe transition reflects a source correction or migration repair.Alpha extension enumaitd-008-mastery-and-grade-levels, aitd-011-policy-and-enum-normalization
blockedA required source or policy row was missing, so the state change is blocked.Alpha extension enumaitd-008-mastery-and-grade-levels, aitd-011-policy-and-enum-normalization
quality_status
ValueMeaningSourceITD
okThe row is the current reportable fact for its key and policy.Alpha extension enumaitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope, aitd-111-axis-privacy-retention
correctedThe row includes a correction contribution but remains reportable.Alpha extension enumaitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope, aitd-111-axis-privacy-retention
reversedThe row reverses a prior contribution and should be read as signed history.Alpha extension enumaitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope, aitd-111-axis-privacy-retention
source_missingA required source row was removed or unavailable before the fact could be finalized.Alpha extension enumaitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope, aitd-111-axis-privacy-retention
source_unlinkedThe source row exists but could not link to a required Event, Result, student, subject, KC, course, or policy ref.Alpha extension enumaitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope, aitd-111-axis-privacy-retention
policy_pendingA required policy configuration was missing or not yet active at materialization time.Alpha extension enumaitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope, aitd-111-axis-privacy-retention
adapter_rejectedThe source-shaped row was valid input but the server-side adapter rejected it with a typed Problem.Alpha extension enumaitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope, aitd-111-axis-privacy-retention

alpha.analytics_map_growth_rollup

The MAP result row the Learning Report renders: RIT, achievement percentile, growth percentile, Growth X, norms set, growth window, retakes, and on-track flag.

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

Kind: Alpha extension rollup table
Grain: student_id x subject_id x canonical_term_id x growth_window x norms_set x policy_ref.
Primary key: id; unique current grain is (tenant_id, student_id, subject_id, canonical_term_id, growth_window, norms_set, policy_ref, calculation_version).
Metric checks: RIT|GrowthX|MAP growth windows MAP sittings/scores
API: GET /alpha/analytics/v1/map-growth-rollups

Example 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
ValueMeaningSourceITD
fall_to_fallYear-over-year growth from fall of the prior school year to fall of the selected school year.Alpha extension enumaitd-009-map-growth-rollups, aitd-011-policy-and-enum-normalization
fall_to_winterObserved and projected growth from fall to winter.Alpha extension enumaitd-009-map-growth-rollups, aitd-011-policy-and-enum-normalization
winter_to_springObserved and projected growth from winter to spring.Alpha extension enumaitd-009-map-growth-rollups, aitd-011-policy-and-enum-normalization
fall_to_springObserved and projected growth from fall to spring.Alpha extension enumaitd-009-map-growth-rollups, aitd-011-policy-and-enum-normalization
winter_to_winterYear-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 enumaitd-009-map-growth-rollups, aitd-011-policy-and-enum-normalization
spring_to_springYear-over-year growth from spring of the prior school year to spring of the selected school year.Alpha extension enumaitd-009-map-growth-rollups, aitd-011-policy-and-enum-normalization
baseline_to_currentGrowth from the student baseline term to the current term.Alpha extension enumaitd-009-map-growth-rollups, aitd-011-policy-and-enum-normalization
termA single-term MAP observation with no paired growth delta.Alpha extension enumaitd-009-map-growth-rollups, aitd-011-policy-and-enum-normalization
customA named migration or report window whose dates are stored in policy/config.Alpha extension enumaitd-009-map-growth-rollups, aitd-011-policy-and-enum-normalization
norms_set
ValueMeaningSourceITD
2020NWEA 2020 norms, kept distinct for historical report reproduction.Alpha extension enumaitd-009-map-growth-rollups, aitd-015-norms-r90-readable-resources, aitd-016-scale-translation-apis, aitd-011-policy-and-enum-normalization
2025NWEA 2025 norms, the current norms family when requested by policy or caller.Alpha extension enumaitd-009-map-growth-rollups, aitd-015-norms-r90-readable-resources, aitd-016-scale-translation-apis, aitd-011-policy-and-enum-normalization
null_reason
ValueMeaningSourceITD
noneNo null-producing condition applies.Alpha extension enumaitd-011-policy-and-enum-normalization
no_school_daysThe denominator window has zero enrolled school days after calendar and enrollment intersection.Alpha extension enumaitd-011-policy-and-enum-normalization
no_questionsThe window has zero reportable question attempts, so accuracy_percent is null rather than guessed as 0 or 100.Alpha extension enumaitd-011-policy-and-enum-normalization
no_enrollmentThe student has no time-locatable enrollment for the requested range.Alpha extension enumaitd-011-policy-and-enum-normalization
no_subject_assignmentThe student had no subject assignment/course/test membership for the subject denominator.Alpha extension enumaitd-011-policy-and-enum-normalization
source_missingRequired Event, Result, calendar, enrollment, or curriculum source evidence is missing.Alpha extension enumaitd-011-policy-and-enum-normalization
source_unlinkedSource evidence exists but cannot be linked to platform ids under the current policy.Alpha extension enumaitd-011-policy-and-enum-normalization
policy_pendingThe named policy needed to compute the measure is missing or not active.Alpha extension enumaitd-011-policy-and-enum-normalization
not_applicableThe metric does not apply at this grain, such as MAP growth for a non-MAP subject.Alpha extension enumaitd-011-policy-and-enum-normalization
quality_status
ValueMeaningSourceITD
okThe row is the current reportable fact for its key and policy.Alpha extension enumaitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope, aitd-111-axis-privacy-retention
correctedThe row includes a correction contribution but remains reportable.Alpha extension enumaitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope, aitd-111-axis-privacy-retention
reversedThe row reverses a prior contribution and should be read as signed history.Alpha extension enumaitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope, aitd-111-axis-privacy-retention
source_missingA required source row was removed or unavailable before the fact could be finalized.Alpha extension enumaitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope, aitd-111-axis-privacy-retention
source_unlinkedThe source row exists but could not link to a required Event, Result, student, subject, KC, course, or policy ref.Alpha extension enumaitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope, aitd-111-axis-privacy-retention
policy_pendingA required policy configuration was missing or not yet active at materialization time.Alpha extension enumaitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope, aitd-111-axis-privacy-retention
adapter_rejectedThe source-shaped row was valid input but the server-side adapter rejected it with a typed Problem.Alpha extension enumaitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope, aitd-111-axis-privacy-retention

alpha.analytics_norms_achievement

The readable NWEA percentile-to-RIT reference table the surface ships by version, so apps can cache the platform table instead of maintaining their own norms copy.

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

Kind: Alpha readable reference table
Grain: norms_set x table_version x subject_id x role x grade_key x season.
Primary key: resource_id; unique published grain is (norms_set, table_version, subject_id, role, grade_key, season).
Metric checks: RIT|GrowthX|MAP windows GOALS percentile-to-RIT
API: GET /alpha/analytics/v1/norms, GET /alpha/analytics/v1/norms/table, GET /alpha/analytics/v1/norms/rit, and GET /alpha/analytics/v1/norms/percentile

Example 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
ValueMeaningSourceITD
2020NWEA 2020 norms, kept distinct for historical report reproduction.Alpha extension enumaitd-009-map-growth-rollups, aitd-015-norms-r90-readable-resources, aitd-016-scale-translation-apis, aitd-011-policy-and-enum-normalization
2025NWEA 2025 norms, the current norms family when requested by policy or caller.Alpha extension enumaitd-009-map-growth-rollups, aitd-015-norms-r90-readable-resources, aitd-016-scale-translation-apis, aitd-011-policy-and-enum-normalization
quality_status
ValueMeaningSourceITD
okThe row is the current reportable fact for its key and policy.Alpha extension enumaitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope, aitd-111-axis-privacy-retention
correctedThe row includes a correction contribution but remains reportable.Alpha extension enumaitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope, aitd-111-axis-privacy-retention
reversedThe row reverses a prior contribution and should be read as signed history.Alpha extension enumaitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope, aitd-111-axis-privacy-retention
source_missingA required source row was removed or unavailable before the fact could be finalized.Alpha extension enumaitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope, aitd-111-axis-privacy-retention
source_unlinkedThe source row exists but could not link to a required Event, Result, student, subject, KC, course, or policy ref.Alpha extension enumaitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope, aitd-111-axis-privacy-retention
policy_pendingA required policy configuration was missing or not yet active at materialization time.Alpha extension enumaitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope, aitd-111-axis-privacy-retention
adapter_rejectedThe source-shaped row was valid input but the server-side adapter rejected it with a typed Problem.Alpha extension enumaitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope, aitd-111-axis-privacy-retention

alpha.analytics_r90_table

The one readable R90/RIT-to-grade reference table the surface ships by version, with R90 marked as Alpha extrapolation where NWEA does not publish it.

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

Kind: Alpha readable reference table
Grain: table_version x table_subject_id x rit_score.
Primary key: resource_id; unique published grain is (table_version, table_subject_id, rit_score).
Metric checks: RIT|GrowthX|MAP windows GOALS RIT-to-grade/R90
API: GET /alpha/analytics/v1/r90/table and GET /alpha/analytics/v1/r90

Example 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
ValueMeaningSourceITD
2020NWEA 2020 norms, kept distinct for historical report reproduction.Alpha extension enumaitd-009-map-growth-rollups, aitd-015-norms-r90-readable-resources, aitd-016-scale-translation-apis, aitd-011-policy-and-enum-normalization
2025NWEA 2025 norms, the current norms family when requested by policy or caller.Alpha extension enumaitd-009-map-growth-rollups, aitd-015-norms-r90-readable-resources, aitd-016-scale-translation-apis, aitd-011-policy-and-enum-normalization
source_point_kind
ValueMeaningSourceITD
exactThe requested RIT exactly matched a PowerPath RIT-to-grade row in the current R90 table version.Alpha reference lookup enumaitd-015-norms-r90-readable-resources, aitd-016-scale-translation-apis, aitd-017-r90-version-supersession
source_missingNo 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 enumaitd-015-norms-r90-readable-resources, aitd-016-scale-translation-apis, aitd-017-r90-version-supersession
quality_status
ValueMeaningSourceITD
okThe row is the current reportable fact for its key and policy.Alpha extension enumaitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope, aitd-111-axis-privacy-retention
correctedThe row includes a correction contribution but remains reportable.Alpha extension enumaitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope, aitd-111-axis-privacy-retention
reversedThe row reverses a prior contribution and should be read as signed history.Alpha extension enumaitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope, aitd-111-axis-privacy-retention
source_missingA required source row was removed or unavailable before the fact could be finalized.Alpha extension enumaitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope, aitd-111-axis-privacy-retention
source_unlinkedThe source row exists but could not link to a required Event, Result, student, subject, KC, course, or policy ref.Alpha extension enumaitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope, aitd-111-axis-privacy-retention
policy_pendingA required policy configuration was missing or not yet active at materialization time.Alpha extension enumaitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope, aitd-111-axis-privacy-retention
adapter_rejectedThe source-shaped row was valid input but the server-side adapter rejected it with a typed Problem.Alpha extension enumaitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope, aitd-111-axis-privacy-retention

analytics.school_days_remaining

The GOALS endpoint response object: remaining instructional days and XP-to-time effort projections from the surface calendar and XP expected-minute policy.

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

Kind: Analytics endpoint response object; no storage table
Grain: One GOALS forward-calendar answer per student_id x school_id x half-open [as_of, end_date) request x school_day_policy_ref x XP expected-minute policy.
Primary key: No stored primary key. The deterministic request grain is student_id, school_id, as_of, end_date, school_day_policy_ref, and effort inputs.
Metric checks: GOALS target date GOALS school-days-remaining
API: GET /alpha/analytics/v1/school-days-remaining

Example 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

analytics.grade_level_status

The GOALS endpoint response object: P&O age grade plus Results working/HMG positions and the two named age-grade comparisons.

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

Kind: Analytics endpoint response object; no storage table
Grain: One student_id x subject_id x as_of_date answer assembled from People and Orgs age grade and Results grade positions.
Primary key: No stored primary key. The deterministic request grain is student_id, subject_id, and as_of_date.
Metric checks: GOALS age-grade status GOALS ahead/at/behind
API: GET /alpha/analytics/v1/grade-level-status

Example 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
ValueMeaningSourceITD
mathMath subject rollups and MAP/math source-label normalization.Alpha/Curriculum governed enumaitd-011-policy-and-enum-normalization
readingReading subject rollups.Alpha/Curriculum governed enumaitd-011-policy-and-enum-normalization
languageLanguage / ELA subject rollups. Public reads keep vocabulary and writing as distinct canonical subjects.Alpha/Curriculum governed enumaitd-011-policy-and-enum-normalization
scienceScience subject rollups.Alpha/Curriculum governed enumaitd-011-policy-and-enum-normalization
vocabularyVocabulary activity rollups as the canonical vocabulary subject.Alpha/Curriculum governed enumaitd-011-policy-and-enum-normalization
writingWriting activity rollups as the canonical writing subject.Alpha/Curriculum governed enumaitd-011-policy-and-enum-normalization

alpha.analytics_completion_rollup

Course and grade-level progress evidence: app-reported Caliper percent first, XP-remaining fallback second, and grade-level evidence across main courses only. Student-facing progress is served by Results.

Progress evidence for Results and Analytics audits without MAP/RIT/R90 inference, client-side Curriculum tree walking, or Results-row counting.

Retention: reviewer/debug probe tenants retain current rows only; superseded completion-rollup history is swept under 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

Kind: Alpha extension rollup table
Grain: student_id x completion_scope x scope_id x window_start x window_end x policy_ref.
Primary key: id; unique current grain is (tenant_id, student_id, completion_scope, scope_id, window_start, window_end, policy_ref, calculation_version).
Metric checks: completion|curriculum refs
API: GET /alpha/analytics/v1/completion-rollups

Example 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
ValueMeaningSourceITD
courseCompletion for one course.Alpha extension enumaitd-010-completion-rollups, aitd-011-policy-and-enum-normalization
subjectCompletion for all expected work in one subject.Alpha extension enumaitd-010-completion-rollups, aitd-011-policy-and-enum-normalization
trackCompletion for a full track.Alpha extension enumaitd-010-completion-rollups, aitd-011-policy-and-enum-normalization
track_levelCompletion for one level inside a track.Alpha extension enumaitd-010-completion-rollups, aitd-011-policy-and-enum-normalization
grade_levelProgress evidence across the main courses that make up one grade level; the student-facing answer is served by Results.Alpha extension enumaitd-010-completion-rollups, aitd-011-policy-and-enum-normalization
segmentCompletion for one curriculum segment.Alpha extension enumaitd-010-completion-rollups, aitd-011-policy-and-enum-normalization
null_reason
ValueMeaningSourceITD
noneNo null-producing condition applies.Alpha extension enumaitd-011-policy-and-enum-normalization
no_school_daysThe denominator window has zero enrolled school days after calendar and enrollment intersection.Alpha extension enumaitd-011-policy-and-enum-normalization
no_questionsThe window has zero reportable question attempts, so accuracy_percent is null rather than guessed as 0 or 100.Alpha extension enumaitd-011-policy-and-enum-normalization
no_enrollmentThe student has no time-locatable enrollment for the requested range.Alpha extension enumaitd-011-policy-and-enum-normalization
no_subject_assignmentThe student had no subject assignment/course/test membership for the subject denominator.Alpha extension enumaitd-011-policy-and-enum-normalization
source_missingRequired Event, Result, calendar, enrollment, or curriculum source evidence is missing.Alpha extension enumaitd-011-policy-and-enum-normalization
source_unlinkedSource evidence exists but cannot be linked to platform ids under the current policy.Alpha extension enumaitd-011-policy-and-enum-normalization
policy_pendingThe named policy needed to compute the measure is missing or not active.Alpha extension enumaitd-011-policy-and-enum-normalization
not_applicableThe metric does not apply at this grain, such as MAP growth for a non-MAP subject.Alpha extension enumaitd-011-policy-and-enum-normalization
quality_status
ValueMeaningSourceITD
okThe row is the current reportable fact for its key and policy.Alpha extension enumaitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope, aitd-111-axis-privacy-retention
correctedThe row includes a correction contribution but remains reportable.Alpha extension enumaitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope, aitd-111-axis-privacy-retention
reversedThe row reverses a prior contribution and should be read as signed history.Alpha extension enumaitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope, aitd-111-axis-privacy-retention
source_missingA required source row was removed or unavailable before the fact could be finalized.Alpha extension enumaitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope, aitd-111-axis-privacy-retention
source_unlinkedThe source row exists but could not link to a required Event, Result, student, subject, KC, course, or policy ref.Alpha extension enumaitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope, aitd-111-axis-privacy-retention
policy_pendingA required policy configuration was missing or not yet active at materialization time.Alpha extension enumaitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope, aitd-111-axis-privacy-retention
adapter_rejectedThe source-shaped row was valid input but the server-side adapter rejected it with a typed Problem.Alpha extension enumaitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope, aitd-111-axis-privacy-retention

alpha.analytics_source_import

The audit receipt for every named report-source adapter run and reconciliation replay.

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

Kind: Alpha extension provenance ledger
Grain: One named-adapter ingestion run from one report-source producer.
Primary key: import_id; idempotency key hash is unique per tenant for public imports.
Metric checks: all metric checks
API: POST /alpha/analytics/v1/source-imports/{adapter} and GET /alpha/analytics/v1/source-imports

Example 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
ValueMeaningSourceITD
timeback-xp-time-accuracyNamed report-source adapter for the Learning Report XP Goal, Time Commitment, and Accuracy panels from reporting.processed_facts.Alpha extension enumaitd-001-report-source-ingestion, aitd-101-axis-write-granularity
timeback-mapNamed 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 enumaitd-001-report-source-ingestion, aitd-101-axis-write-granularity
timeback-grade-masteryNamed report-source adapter for the Grade Levels Mastered panel from reporting.assessment_results.Alpha extension enumaitd-001-report-source-ingestion, aitd-101-axis-write-granularity
timeback-completionNamed report-source adapter for XP-remaining fallback course progress from reporting.processed_facts plus Curriculum expected-XP refs.Alpha extension enumaitd-001-report-source-ingestion, aitd-101-axis-write-granularity
event_close_replayA replay of Events close notifications into Analytics materializers.Alpha extension enumaitd-001-report-source-ingestion, aitd-101-axis-write-granularity
result_close_replayA replay of Results close/change notifications into Analytics materializers.Alpha extension enumaitd-001-report-source-ingestion, aitd-101-axis-write-granularity
migration_reconcileA migration gate rerun that imports source-shaped rows and checks metric reconciliation.Alpha extension enumaitd-001-report-source-ingestion, aitd-101-axis-write-granularity
import_status
ValueMeaningSourceITD
receivedThe batch envelope is recorded but not yet processed.Alpha extension enumaitd-001-report-source-ingestion, aitd-108-axis-error-envelope
runningThe adapter/materializer is processing the batch.Alpha extension enumaitd-001-report-source-ingestion, aitd-108-axis-error-envelope
materializedAccepted rows produced readable Analytics rows.Alpha extension enumaitd-001-report-source-ingestion, aitd-108-axis-error-envelope
partially_rejectedSome rows materialized and some rows produced typed Problems.Alpha extension enumaitd-001-report-source-ingestion, aitd-108-axis-error-envelope
rejectedNo rows materialized because the batch failed validation or adapter mapping.Alpha extension enumaitd-001-report-source-ingestion, aitd-108-axis-error-envelope
failedA platform failure interrupted processing after the batch was accepted.Alpha extension enumaitd-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

ValueMeaning
digits_correct_per_minuteCorrect units completed per elapsed minute; the initial governed fluency probe family.

performance_band

ValueMeaning
acquisitionrate_per_minute below 10.
fluency_buildingrate_per_minute at least 10 and below 20.
masteryrate_per_minute at least 20.

quality_status

ValueMeaning
okThe row is the current reportable fact for its key and policy.
correctedThe row includes a correction contribution but remains reportable.
reversedThe row reverses a prior contribution and should be read as signed history.
source_missingA required source row was removed or unavailable before the fact could be finalized.
source_unlinkedThe source row exists but could not link to a required Event, Result, student, subject, KC, course, or policy ref.
policy_pendingA required policy configuration was missing or not yet active at materialization time.
adapter_rejectedThe 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

FieldLogical TypePostgreSQL TypeNullabilityMeaningConstraintsRelationship / ProvenanceExample
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

ValueMeaning
ap_chemistryApplies the 16 completed hands-on lab requirement.
ap_environmental_scienceApplies the 25 percent hands-on active-time requirement.

null_reason

ValueMeaning
noneNo null-producing condition applies.
no_school_daysThe denominator window has zero enrolled school days after calendar and enrollment intersection.
no_questionsThe window has zero reportable question attempts, so accuracy_percent is null rather than guessed as 0 or 100.
no_enrollmentThe student has no time-locatable enrollment for the requested range.
no_subject_assignmentThe student had no subject assignment/course/test membership for the subject denominator.
source_missingRequired Event, Result, calendar, enrollment, or curriculum source evidence is missing.
source_unlinkedSource evidence exists but cannot be linked to platform ids under the current policy.
policy_pendingThe named policy needed to compute the measure is missing or not active.
not_applicableThe metric does not apply at this grain, such as MAP growth for a non-MAP subject.

quality_status

ValueMeaning
okThe row is the current reportable fact for its key and policy.
correctedThe row includes a correction contribution but remains reportable.
reversedThe row reverses a prior contribution and should be read as signed history.
source_missingA required source row was removed or unavailable before the fact could be finalized.
source_unlinkedThe source row exists but could not link to a required Event, Result, student, subject, KC, course, or policy ref.
policy_pendingA required policy configuration was missing or not yet active at materialization time.
adapter_rejectedThe 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

FieldLogical TypePostgreSQL TypeNullabilityMeaningConstraintsRelationship / ProvenanceExample
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.

Trace: aitd-012-corrections-and-reversals

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.

Trace: aitd-011-policy-and-enum-normalization

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.

Trace: aitd-008-mastery-and-grade-levels

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

Architecture-committed error contract: the stable Problem codes defined in this table are 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-

FieldTypeRequiredMeaning
typeURIrequiredStable deep link for this Analytics Problem code.
titleTEXTrequiredShort human-readable summary.
statusINTEGERrequiredHTTP status code; validation=400, adapter/policy normalization=422, conflict/not-ready=409, platform failure=500.
codeTEXTrequiredStable analytics:* code. Consumers switch on this, not title/detail text.
detailTEXTrequiredSpecific explanation safe to show to the caller.
requestIdTEXTrequiredPer-request id for support and audit correlation.
traceIdTEXTrequiredCross-service trace id for operator investigation.
fieldErrorsJSONB arrayoptionalPer-field validation failures for analytics:validation_failed.
sourceRefTEXToptionalOpaque source row/ref when a source-shaped row or close notification failed.
resolutionTEXTrequiredNext safe action: correct request, repair source mapping, seed policy, replay, or wait for source close.
links.dataDictionaryURIrequiredDeep 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"
  }
}
CodeHTTPMeaningWhen RaisedClient FixRaw DB EffectExampleTrace
analytics:validation_failed400The 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_parameter400A 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_rejected422A 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_conflict409The 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_failed500The 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_error500An 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_missing409Analytics 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_unlinked422The 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_pending422A 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
Validation and adapter failures are never reported as HTTP 200 with an error body. The import/read contract uses typed RFC 7807 Problem responses.

Allowed Values

subject_id

ValueMeaningSourceITD
mathMath subject rollups and MAP/math source-label normalization.Alpha/Curriculum governed enumaitd-011-policy-and-enum-normalization
readingReading subject rollups.Alpha/Curriculum governed enumaitd-011-policy-and-enum-normalization
languageLanguage / ELA subject rollups. Public reads keep vocabulary and writing as distinct canonical subjects.Alpha/Curriculum governed enumaitd-011-policy-and-enum-normalization
scienceScience subject rollups.Alpha/Curriculum governed enumaitd-011-policy-and-enum-normalization
vocabularyVocabulary activity rollups as the canonical vocabulary subject.Alpha/Curriculum governed enumaitd-011-policy-and-enum-normalization
writingWriting activity rollups as the canonical writing subject.Alpha/Curriculum governed enumaitd-011-policy-and-enum-normalization

fact_kind

ValueMeaningSourceITD
active_secondsSeconds the policy classifies as productive engaged work for a closed source event.Alpha extension enumaitd-005-time-facts-and-windows, aitd-011-policy-and-enum-normalization
inactive_secondsSeconds the policy classifies as idle or not meaningfully engaged.Alpha extension enumaitd-005-time-facts-and-windows, aitd-011-policy-and-enum-normalization
waste_secondsSeconds the policy classifies as gaming, distraction, or otherwise counterproductive work.Alpha extension enumaitd-005-time-facts-and-windows, aitd-011-policy-and-enum-normalization

window_kind

ValueMeaningSourceITD
dayA calendar day in the school timezone, represented as a half-open date range.Alpha extension enumaitd-005-time-facts-and-windows, aitd-103-axis-query-model, aitd-011-policy-and-enum-normalization
weekA platform week under alpha.policy.analytics.window.Alpha extension enumaitd-005-time-facts-and-windows, aitd-103-axis-query-model, aitd-011-policy-and-enum-normalization
termAn academic term from the People and Orgs academic-session calendar.Alpha extension enumaitd-005-time-facts-and-windows, aitd-103-axis-query-model, aitd-011-policy-and-enum-normalization
school_yearA school-year window from the org academic-session calendar.Alpha extension enumaitd-005-time-facts-and-windows, aitd-103-axis-query-model, aitd-011-policy-and-enum-normalization
customA caller-requested or migration reconciliation range with explicit start and end dates.Alpha extension enumaitd-005-time-facts-and-windows, aitd-103-axis-query-model, aitd-011-policy-and-enum-normalization

quality_status

ValueMeaningSourceITD
okThe row is the current reportable fact for its key and policy.Alpha extension enumaitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope, aitd-111-axis-privacy-retention
correctedThe row includes a correction contribution but remains reportable.Alpha extension enumaitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope, aitd-111-axis-privacy-retention
reversedThe row reverses a prior contribution and should be read as signed history.Alpha extension enumaitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope, aitd-111-axis-privacy-retention
source_missingA required source row was removed or unavailable before the fact could be finalized.Alpha extension enumaitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope, aitd-111-axis-privacy-retention
source_unlinkedThe source row exists but could not link to a required Event, Result, student, subject, KC, course, or policy ref.Alpha extension enumaitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope, aitd-111-axis-privacy-retention
policy_pendingA required policy configuration was missing or not yet active at materialization time.Alpha extension enumaitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope, aitd-111-axis-privacy-retention
adapter_rejectedThe source-shaped row was valid input but the server-side adapter rejected it with a typed Problem.Alpha extension enumaitd-011-policy-and-enum-normalization, aitd-108-axis-error-envelope, aitd-111-axis-privacy-retention

null_reason

ValueMeaningSourceITD
noneNo null-producing condition applies.Alpha extension enumaitd-011-policy-and-enum-normalization
no_school_daysThe denominator window has zero enrolled school days after calendar and enrollment intersection.Alpha extension enumaitd-011-policy-and-enum-normalization
no_questionsThe window has zero reportable question attempts, so accuracy_percent is null rather than guessed as 0 or 100.Alpha extension enumaitd-011-policy-and-enum-normalization
no_enrollmentThe student has no time-locatable enrollment for the requested range.Alpha extension enumaitd-011-policy-and-enum-normalization
no_subject_assignmentThe student had no subject assignment/course/test membership for the subject denominator.Alpha extension enumaitd-011-policy-and-enum-normalization
source_missingRequired Event, Result, calendar, enrollment, or curriculum source evidence is missing.Alpha extension enumaitd-011-policy-and-enum-normalization
source_unlinkedSource evidence exists but cannot be linked to platform ids under the current policy.Alpha extension enumaitd-011-policy-and-enum-normalization
policy_pendingThe named policy needed to compute the measure is missing or not active.Alpha extension enumaitd-011-policy-and-enum-normalization
not_applicableThe metric does not apply at this grain, such as MAP growth for a non-MAP subject.Alpha extension enumaitd-011-policy-and-enum-normalization

state_dimension

ValueMeaningSourceITD
initial_masteryThe acquisition/mastery signal changed for the KC.Alpha extension enumaitd-008-mastery-and-grade-levels, aitd-011-policy-and-enum-normalization
current_retentionThe retained mastery value changed under the Results retention policy.Alpha extension enumaitd-008-mastery-and-grade-levels, aitd-011-policy-and-enum-normalization
durable_masteryThe durable mastery state changed.Alpha extension enumaitd-008-mastery-and-grade-levels, aitd-011-policy-and-enum-normalization
fluency_stateThe fluency/automaticity state changed.Alpha extension enumaitd-008-mastery-and-grade-levels, aitd-011-policy-and-enum-normalization
next_due_atThe next review or practice due date changed.Alpha extension enumaitd-008-mastery-and-grade-levels, aitd-011-policy-and-enum-normalization

transition_kind

ValueMeaningSourceITD
acquiredThe student crossed into mastery/acquisition for the KC.Alpha extension enumaitd-008-mastery-and-grade-levels, aitd-011-policy-and-enum-normalization
improvedThe state value increased but did not represent first acquisition.Alpha extension enumaitd-008-mastery-and-grade-levels, aitd-011-policy-and-enum-normalization
decayedThe value decreased under Results retention state.Alpha extension enumaitd-008-mastery-and-grade-levels, aitd-011-policy-and-enum-normalization
review_dueThe due-date dimension moved into a new due state.Alpha extension enumaitd-008-mastery-and-grade-levels, aitd-011-policy-and-enum-normalization
fluency_changedThe fluency dimension changed.Alpha extension enumaitd-008-mastery-and-grade-levels, aitd-011-policy-and-enum-normalization
correctedThe transition reflects a source correction or migration repair.Alpha extension enumaitd-008-mastery-and-grade-levels, aitd-011-policy-and-enum-normalization
blockedA required source or policy row was missing, so the state change is blocked.Alpha extension enumaitd-008-mastery-and-grade-levels, aitd-011-policy-and-enum-normalization

norms_set

ValueMeaningSourceITD
2020NWEA 2020 norms, kept distinct for historical report reproduction.Alpha extension enumaitd-009-map-growth-rollups, aitd-015-norms-r90-readable-resources, aitd-016-scale-translation-apis, aitd-011-policy-and-enum-normalization
2025NWEA 2025 norms, the current norms family when requested by policy or caller.Alpha extension enumaitd-009-map-growth-rollups, aitd-015-norms-r90-readable-resources, aitd-016-scale-translation-apis, aitd-011-policy-and-enum-normalization

source_point_kind

ValueMeaningSourceITD
exactThe requested RIT exactly matched a PowerPath RIT-to-grade row in the current R90 table version.Alpha reference lookup enumaitd-015-norms-r90-readable-resources, aitd-016-scale-translation-apis, aitd-017-r90-version-supersession
source_missingNo 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 enumaitd-015-norms-r90-readable-resources, aitd-016-scale-translation-apis, aitd-017-r90-version-supersession

growth_window

ValueMeaningSourceITD
fall_to_fallYear-over-year growth from fall of the prior school year to fall of the selected school year.Alpha extension enumaitd-009-map-growth-rollups, aitd-011-policy-and-enum-normalization
fall_to_winterObserved and projected growth from fall to winter.Alpha extension enumaitd-009-map-growth-rollups, aitd-011-policy-and-enum-normalization
winter_to_springObserved and projected growth from winter to spring.Alpha extension enumaitd-009-map-growth-rollups, aitd-011-policy-and-enum-normalization
fall_to_springObserved and projected growth from fall to spring.Alpha extension enumaitd-009-map-growth-rollups, aitd-011-policy-and-enum-normalization
winter_to_winterYear-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 enumaitd-009-map-growth-rollups, aitd-011-policy-and-enum-normalization
spring_to_springYear-over-year growth from spring of the prior school year to spring of the selected school year.Alpha extension enumaitd-009-map-growth-rollups, aitd-011-policy-and-enum-normalization
baseline_to_currentGrowth from the student baseline term to the current term.Alpha extension enumaitd-009-map-growth-rollups, aitd-011-policy-and-enum-normalization
termA single-term MAP observation with no paired growth delta.Alpha extension enumaitd-009-map-growth-rollups, aitd-011-policy-and-enum-normalization
customA named migration or report window whose dates are stored in policy/config.Alpha extension enumaitd-009-map-growth-rollups, aitd-011-policy-and-enum-normalization

completion_scope

ValueMeaningSourceITD
courseCompletion for one course.Alpha extension enumaitd-010-completion-rollups, aitd-011-policy-and-enum-normalization
subjectCompletion for all expected work in one subject.Alpha extension enumaitd-010-completion-rollups, aitd-011-policy-and-enum-normalization
trackCompletion for a full track.Alpha extension enumaitd-010-completion-rollups, aitd-011-policy-and-enum-normalization
track_levelCompletion for one level inside a track.Alpha extension enumaitd-010-completion-rollups, aitd-011-policy-and-enum-normalization
grade_levelProgress evidence across the main courses that make up one grade level; the student-facing answer is served by Results.Alpha extension enumaitd-010-completion-rollups, aitd-011-policy-and-enum-normalization
segmentCompletion for one curriculum segment.Alpha extension enumaitd-010-completion-rollups, aitd-011-policy-and-enum-normalization

import_kind

ValueMeaningSourceITD
timeback-xp-time-accuracyNamed report-source adapter for the Learning Report XP Goal, Time Commitment, and Accuracy panels from reporting.processed_facts.Alpha extension enumaitd-001-report-source-ingestion, aitd-101-axis-write-granularity
timeback-mapNamed 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 enumaitd-001-report-source-ingestion, aitd-101-axis-write-granularity
timeback-grade-masteryNamed report-source adapter for the Grade Levels Mastered panel from reporting.assessment_results.Alpha extension enumaitd-001-report-source-ingestion, aitd-101-axis-write-granularity
timeback-completionNamed report-source adapter for XP-remaining fallback course progress from reporting.processed_facts plus Curriculum expected-XP refs.Alpha extension enumaitd-001-report-source-ingestion, aitd-101-axis-write-granularity
event_close_replayA replay of Events close notifications into Analytics materializers.Alpha extension enumaitd-001-report-source-ingestion, aitd-101-axis-write-granularity
result_close_replayA replay of Results close/change notifications into Analytics materializers.Alpha extension enumaitd-001-report-source-ingestion, aitd-101-axis-write-granularity
migration_reconcileA migration gate rerun that imports source-shaped rows and checks metric reconciliation.Alpha extension enumaitd-001-report-source-ingestion, aitd-101-axis-write-granularity

import_status

ValueMeaningSourceITD
receivedThe batch envelope is recorded but not yet processed.Alpha extension enumaitd-001-report-source-ingestion, aitd-108-axis-error-envelope
runningThe adapter/materializer is processing the batch.Alpha extension enumaitd-001-report-source-ingestion, aitd-108-axis-error-envelope
materializedAccepted rows produced readable Analytics rows.Alpha extension enumaitd-001-report-source-ingestion, aitd-108-axis-error-envelope
partially_rejectedSome rows materialized and some rows produced typed Problems.Alpha extension enumaitd-001-report-source-ingestion, aitd-108-axis-error-envelope
rejectedNo rows materialized because the batch failed validation or adapter mapping.Alpha extension enumaitd-001-report-source-ingestion, aitd-108-axis-error-envelope
failedA platform failure interrupted processing after the batch was accepted.Alpha extension enumaitd-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_namecolumn_namedata_type
assessment_resultssourced_idtext
assessment_resultsstatusUSER-DEFINED
assessment_resultsdate_last_modifiedtimestamp without time zone
assessment_resultsmetadatajsonb
assessment_resultsassessment_line_item_sourced_idtext
assessment_resultsstudent_sourced_idtext
assessment_resultsscorereal
assessment_resultstext_scoretext
assessment_resultsscore_datetimestamp without time zone
assessment_resultsscore_scale_sourced_idtext
assessment_resultsscore_percentilereal
assessment_resultsscore_statusUSER-DEFINED
assessment_resultscommenttext
assessment_resultslearning_objective_setjsonb
assessment_resultsin_progressboolean
assessment_resultsincompleteboolean
assessment_resultslateboolean
assessment_resultsmissingboolean
assessment_resultstenant_iduuid
assessment_resultsclient_app_iduuid
course_componentssourced_idtext
course_componentsstatusUSER-DEFINED
course_componentsdate_last_modifiedtimestamp without time zone
course_componentsmetadatajsonb
course_componentscourse_sourced_idtext
course_componentsparent_sourced_idtext
course_componentstitletext
course_componentssort_orderinteger
course_componentsprerequisitesARRAY
course_componentsprerequisite_criteriatext
course_componentsunlock_datetimestamp without time zone
course_componentstenant_iduuid
course_componentsclient_app_iduuid
coursessourced_idtext
coursesstatusUSER-DEFINED
coursesdate_last_modifiedtimestamp without time zone
coursesmetadatajsonb
coursestitletext
coursesschool_year_sourced_idtext
coursescourse_codetext

Fresh June 12 Reporting processed_facts Subject Aggregate

subjectnactive_secondsinactive_secondswaste_secondsxp_earned
Writing497471579160252.577.0801226124.18
Math4039603364972640.263822941.95452971.584434337.04
Language2219490158829436.14618341.92311330.74924056.48
FastMath202274870873766.86480024.938471840.11072054.64
Reading1805944180023835.5559883.94124753.452979423.42
Social Studies69955211529499.333501554.5162669.99358718.83
Science54639380107538.43837338.19611348.021571641.41
Vocabulary2699368276420.16198372.501081696.58
None38717718490.028109.9112310.90
(blank)13505000-24549
Other361365648.851237.93032202
Biology850000
Mathematics30000165
ELA300035

Fresh June 12 Reporting hp_map_results Window Aggregate

subjecttermnamenrit_rowswtw_observed_rowswtw_projected_rowswtw_cgp_rowsmin_ritmax_rit
ReadingWinter 2025-202654495449329313313136267
MathFall 2025-202652725272000104307
ReadingFall 2025-202647404740000123267
LanguageFall 2025-202646484648000136272
LanguageWinter 2025-202643924392227221221137267
MathWinter 2025-202639403940328312312123314
ReadingSpring 2025-202635523552000143278
LanguageSpring 2025-202630753075000140289
MathSpring 2025-202624992499000144323
ScienceWinter 2025-202621552155196196196159276
ScienceSpring 2025-202616101610000158282
ScienceFall 2025-2026861861000160271
MathSpring 2024-2025642642000127289
ReadingSpring 2024-2025580580000116260
LanguageSpring 2024-2025424424000154268
ScienceSpring 2024-2025369369000167254

Fresh June 12 Caliper Type/Action Aggregate

typeactionn
TimeSpentEventSpentTime13159747
ActivityEventCompleted4194050
EventCreated34481
ToolUseEventUsed3672
AnnotationEventTagged1586
AssessmentItemEventCompleted738
SessionEventLoggedIn270
SessionEventLoggedOut193
EventAchieved132
AssessmentItemEventSkipped119
AssessmentEventSubmitted18
EventUsed8
EventCompleted6
EventViewed4
FeedbackEventRanked2
FeedbackEventCommented2
GradeEventGraded1
AssessmentEventStarted1
AssessmentEventPaused1

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_countrows_with_total_questionsrows_with_correct_questionstotal_questions_sumcorrect_questions_sumaccuracy_percent
1666232929804432893838591676085139093686.857

Current School Calendar Persistence Evidence

tablerow_countschool_day_rowsschool_countmin_calendar_datemax_calendar_datereasonsinterpretation
alpha.school_calendar92385674142025-08-132027-06-06holiday_break,instructional,nwea_map_testing,other,weekendalpha.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.

attemptstatusevidence_pathrow_counttotal_questions_sumcorrect_questions_suminterpretation
1completedsource/evidence/attempt1-accuracy-source-aggregate-2026-06-13.json166623295916760851390936Attempt 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

namepurposeresultelapsed_seconds_before_cancelout_path_requested
processed_facts_accuracy_aggregateRefresh the PII-safe production value-space evidence for alpha.analytics_accuracy source numerator and denominator columns.completed5.17source/evidence/attempt1-accuracy-source-aggregate-2026-06-13.json

Attempt 2 Token-File Refresh Attempt

namepurposeresultelapsed_seconds_before_cancelout_path_requested
processed_facts_accuracy_aggregateConfirm 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_latency193source/evidence/attempt2-accuracy-source-aggregate-2026-06-13.json

Attempt 13 Token-File Refresh Attempt

namepurposeresultelapsed_seconds_before_cancelout_path_requested
bounded_processed_facts_accuracy_aggregateRefresh 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_latency220source/evidence/attempt13-accuracy-source-aggregate-2026-06-13.json

Historical Attempt 8 Source Refresh Audit

namepurposeresultelapsed_seconds_before_cancel
bounded_processed_facts_accuracy_aggregateRefresh 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_latency65

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.

namepurposeresultelapsed_seconds_before_cancel
processed_facts_full_accuracy_aggregateRefresh a full PII-safe aggregate for total_questions and correct_questions.cancelled_after_timeout120
processed_facts_bounded_accuracy_shape_probeRefresh a bounded PII-safe source-shape and range probe for total_questions and correct_questions.cancelled_after_timeout75

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_countrows_with_total_questionsrows_with_correct_questionstotal_questions_sumcorrect_questions_sumaccuracy_percent
1663875729762862889758590607505130021286.86
row_countrows_with_total_questionsrows_with_correct_questionstotal_questions_sumcorrect_questions_sumaccuracy_percent
1663875429762852889757590607055130017586.86
row_countrows_with_total_questionsrows_with_correct_questionstotal_questions_sumcorrect_questions_sumaccuracy_percent
1663875429762852889757590607055130017586.86
row_countrows_with_total_questionsrows_with_correct_questionstotal_questions_sumcorrect_questions_sumaccuracy_percent
1663874329762842889756590607005130017386.86
row_countrows_with_total_questionsrows_with_correct_questionstotal_questions_sumcorrect_questions_sumaccuracy_percent
1663868729762822889755590606575130014286.86
row_countrows_with_total_questionsrows_with_correct_questionstotal_questions_sumcorrect_questions_sumaccuracy_percent
298119029762782889752590606325130013086.86
row_countrows_with_total_questionsrows_with_correct_questionstotal_questions_sumcorrect_questions_sumaccuracy_percent
1663719929761282889603590566345129668686.86
row_countrows_with_total_questionsrows_with_correct_questionstotal_questions_sumcorrect_questions_sumaccuracy_percent
1663710329761112889586590554145129565986.86
row_countrows_with_total_questionsrows_with_correct_questionstotal_questions_sumcorrect_questions_sumaccuracy_percent
1663701629760642889539590528445129325186.86
row_countrows_with_total_questionsrows_with_correct_questionstotal_questions_sumcorrect_questions_sum
16636945297605128895265905208751292581
row_countrows_with_total_questionsrows_with_correct_questionstotal_questions_sumcorrect_questions_sum
16636865297604628895215905200751292532
rows_with_questionstotal_questions_sumcorrect_questions_sum
29760405905183351198540
row_countrows_with_total_questionsrows_with_correct_questionstotal_questions_sumcorrect_questions_sum
16636688297602928895045905159351292145

No rows available.

Approved Architecture Grounding

queriedWithqueriedAtreportingDbReachablexpNaiveMatchesmapNaiveMatchesreconciliationHeadlineconsequence
mcp danny-timeback query(database='reporting'); same value-space as scripts/timeback-query.mjs --token-file ~/Documents/timeback-danny-mcp-creds2026-06-10true1/6 subjects2/4 subjects for observed/typicalNaive 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

reportPanelreportingSourceanalyticsObjectrequiredFieldsprobeValue
Panel 3 MAP: Growth Percentile (vs 1yr ago), Growth X, RITtimeback-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 = wintertowinterprojectedgrowthalpha.analytics_map_growth_rollupsource_import_id, growth_window=winter_to_winter, rit_score, achievement_percentile, growth_percentile, observed_growth, projected_growth, typical_growth, growth_xMath 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 daytimeback-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_minutessource_import_id, active_seconds/active_minutes, enrolled_school_day_count, excluded_school_day_count, minutes_per_enrolled_school_day, null_reasonReport-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 Percenttimeback-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 existalpha.analytics_xp_rollupsource_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_reasonApproved 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.
Accuracytimeback-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_accuracysource_import_id, correct_question_count, total_question_count, incorrect_question_count, accuracy_percent, null_reasonCurrent 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 Masteredtimeback-grade-mastery over reporting.assessment_results passed gates; Results student_kc_state remains the canonical mastery state for KC deltasalpha.analytics_mastery_deltasource_import_id, grade_subject, grade_level, completed_on, state_dimension, transition_kind, source_result_refsApproved 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 denominatoralpha.analytics_completion_rollupsource_import_id, completion_scope, scope_id, grade_level, is_main_course, progress_source_kind, xp_earned, xp_remaining, completion_percent, denominator_policy_refDirect 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.

subjecttermnametestritscorewintertowinterprojectedgrowthwintertowinterobservedgrowthtypicalwintertowintergrowthwintertowinterconditionalgrowthpercentilegrowth_x_vs_projectedold_observed_over_typical_probe
LanguageWinter 2025-2026232232561.51.5
LanguageWinter 2025-2026232232561.51.5
MathWinter 2025-2026239762430.85713
MathWinter 2025-2026239762430.85713
ReadingWinter 2025-2026239232581.51.5
ReadingWinter 2025-2026239232581.51.5
ScienceWinter 2025-2026229322440.66671
ScienceWinter 2025-2026229322440.66671

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.

rowsactive_datesactive_secondsactive_minuteswaste_secondsxp_earnedmastered_unitstotal_questionscorrect_questions
203901931434663.1723911.05337241.8521371.73305310964392808
subjectrowsactive_datesactive_minuteswaste_secondsxp_earnedmastered_unitstotal_questionscorrect_questions
FastMath105847697.01737155563.757901566013409
Language23131554519.08304795.866271816816997
Math17481446242.8186.85406064954513995
Other110025000
Reading14061455573.850511621351583363
Science1174523173.60116314123741583
Vocabulary1033133460.73303195.624676105351938
Writing116571123243.9602452.516617791523

Mastery Visibility Source

course_subjectrowsmin_course_grademax_course_gradelatest_completion_date
FastMath1552025-11-03T15:21:29.287
Language1662025-12-10T16:54:14.73
Math1552025-12-16T17:45:35.393
Reading1882026-03-24T14:59:36.049
Science1552025-08-27T16:11:38.767
Social Studies1332025-03-07T03:00:00
Vocabulary110102026-05-01T15:40:27.617
Writing1552026-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

typeactionndeleted_n
TimeSpentEventSpentTime130451130
ActivityEventCompleted41371660
EventCreated344810
ToolUseEventUsed36720
AnnotationEventTagged15680
AssessmentItemEventCompleted7380
SessionEventLoggedIn2700
SessionEventLoggedOut1930
EventAchieved1320
AssessmentItemEventSkipped1190
AssessmentEventSubmitted180
EventUsed80
EventCompleted60
EventViewed40
FeedbackEventCommented20
FeedbackEventRanked20
AssessmentEventPaused10
AssessmentEventStarted10
GradeEventGraded10

Processed Facts Subject Values

subjectnactive_secondsinactive_secondswaste_secondsxp_earned
Writing494452678685082.017.0801215406.9
Math3984163361781553.963722875.12452971.584351580.04
Language2199666157274095.14618341.92311330.74886201.78
FastMath199300669638890.86480024.938169566.11054788.82
Reading1776985178347417.5559883.94124753.452929304.42
Social Studies69358711492725.783240114.11162669.99358558.43
Science54502379827954.43837338.19611348.021563132.41
Vocabulary2683928209617.16198372.501073697.11
None38702718394.028109.9112310.90
(blank)13444000-25179
Other361065648.851237.93032157
Biology850000
Mathematics30000165
ELA300035

Processed Facts App Values

appnactive_secondsinactive_secondswaste_secondsxp_earned
Alphawrite490905869303957.4700948123.15
TimeBack Dash232816925052400001834
AlphaMath Fluency145312055177283.51038169566.1827989.41
MobyMax119403390547053001977383
Zearn1033749118232419001264126
Lalilo71216152269000001393125
TeachTales671367786311000122692
AlphaLearn56324729538987.052125652.69235176.8116256.75
Math Academy460530105892772001230324
VocabLoco2741291027144000731223
DreamUp2722952410132480006043618.11
Math Raiders2618841186461400174559.75

Results Subject Values

subjectn
(null)1871757
Language1417902
Math1043040
FastMath1030579
Reading783905
Science-notqced627047
Vocabulary228333
Science197166
Writing61963
Social Studies54811
Math-notqced28140
None21671
Math-ISEE17642
Language-notqced11907
ELA8663
Reading-ISEE8194
Language-ISEE8074
Reading-notqced7813