{
  "module": "analytics",
  "surface": "alpha",
  "deliverable": "data_dictionary",
  "attempt": 1,
  "generatedAt": "2026-07-27T19:27:08.396Z",
  "benchmarkUrl": "https://platform3-24kpiksyo-andymontgomery-9773s-projects.vercel.app/data_dictionary",
  "architectureUrl": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture",
  "upstream": [
    {
      "title": "AP One Platform Capability Contract",
      "url": "loop/context/ap-one-platform-capabilities-decision.md",
      "usedFor": "Issue #1128 lab/fluency event facts, DCPM formula and bands, hands-on calculations, and AP course threshold policy."
    },
    {
      "title": "Analytics Alpha architecture",
      "url": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture",
      "usedFor": "Accepted ITDs, table set, API axes, metric-check trace, no-alias extend-only storage."
    },
    {
      "title": "Events Alpha data dictionary",
      "url": "https://platform3-andymontgomery-9773s-projects.vercel.app/events/alpha/data_dictionary",
      "usedFor": "Event source refs, close notifications, Caliper moment boundary, source imports."
    },
    {
      "title": "Results Alpha data dictionary",
      "url": "https://platform3-andymontgomery-9773s-projects.vercel.app/results/alpha/data_dictionary",
      "usedFor": "XP ledger, mastery state, MAP score/growth/sitting rows, durable result evidence."
    },
    {
      "title": "Curriculum Alpha data dictionary",
      "url": "https://platform3-andymontgomery-9773s-projects.vercel.app/curriculum/alpha/data_dictionary",
      "usedFor": "KC, course, track, component, subject, and policy refs."
    },
    {
      "title": "People and Orgs Alpha data dictionary",
      "url": "https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/data_dictionary",
      "usedFor": "Student, school, enrollment, academic-session, and point-in-time identity refs."
    },
    {
      "title": "Ed-Fi 1EdTech data dictionary",
      "url": "https://platform3-andymontgomery-9773s-projects.vercel.app/ed_fi/1edtech/data_dictionary",
      "usedFor": "CalendarDate source behind alpha.school_calendar school-day denominator; missing coverage is a launch/repair state, not a report formula."
    }
  ],
  "storageModel": {
    "label": "Alpha extension only",
    "noOneEdTechBase": true,
    "noAliasMap": true,
    "rule": "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."
  },
  "tables": [
    {
      "name": "alpha.analytics_event_time_fact",
      "title": "Event Time Fact",
      "kind": "Alpha extension table",
      "grain": "One source Event contribution per fact_kind, policy_ref, and calculation_version.",
      "primaryKey": "id; unique report grain is (tenant_id, source_event_id, fact_kind, policy_ref, calculation_version) for current rows.",
      "lifecycle": "Written when an Event closes or when an event-close replay runs. Corrections write signed replacement/reversal rows.",
      "purpose": "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.",
      "metricChecks": [
        "minutes|Caliper events"
      ],
      "architecture": [
        {
          "id": "aitd-000-extend-only-storage",
          "title": "Analytics Is New Extend-Only Alpha Storage",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-000-extend-only-storage"
        },
        {
          "id": "aitd-002-derived-events-complement",
          "title": "Derived-From-Events Facts Complement, Never Substitute For, Ingested Tiles",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-002-derived-events-complement"
        },
        {
          "id": "aitd-003-close-time-materialization",
          "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
        },
        {
          "id": "aitd-005-time-facts-and-windows",
          "title": "Active, Inactive, And Waste Seconds Are Typed Derived Time Facts",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-005-time-facts-and-windows"
        },
        {
          "id": "aitd-011-policy-and-enum-normalization",
          "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
        },
        {
          "id": "aitd-012-corrections-and-reversals",
          "title": "Corrections Are Signed Facts With Provenance",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-012-corrections-and-reversals"
        }
      ],
      "api": "GET /alpha/analytics/v1/event-time-facts",
      "rawRule": "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.",
      "example": {
        "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
      },
      "fields": [
        {
          "name": "id",
          "type": "UUID",
          "nullability": "required",
          "meaning": "Analytics-owned stable row id for this derived fact.",
          "constraints": "Generated by the platform; globally unique within alpha.analytics_* objects.",
          "relationship": "Primary key for list/detail endpoints.",
          "invalidWhen": "Provided by a public import client or reused across tenants.",
          "example": "8e9c0ef2-bc75-4f53-8124-df77df49f25f",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-000-extend-only-storage",
              "title": "Analytics Is New Extend-Only Alpha Storage",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-000-extend-only-storage"
            }
          ]
        },
        {
          "name": "tenant_id",
          "type": "UUID",
          "nullability": "required",
          "meaning": "Tenant boundary for the derived fact.",
          "constraints": "Set from the JWT tenant claim or internal materializer context; never accepted from request body/query.",
          "relationship": "All raw-path queries must filter by tenant_id before joining, sorting, paging, or counting.",
          "invalidWhen": "Missing, caller-supplied in body/query, or mismatched with the JWT tenant claim.",
          "example": "7b0bb5d8-9a38-4a62-9fdc-9f8d2dc1a111",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-109-axis-tenant-routing",
              "title": "API Axis: Tenant Routing",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-109-axis-tenant-routing"
            },
            {
              "id": "aitd-106-axis-auth-shape",
              "title": "API Axis: Auth Shape",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-106-axis-auth-shape"
            }
          ]
        },
        {
          "name": "student_id",
          "type": "TEXT",
          "nullability": "required",
          "meaning": "Canonical Alpha student id the source Event or Result resolved to at materialization time.",
          "constraints": "Must resolve through People and Orgs as a real student for the source timestamp/effective date.",
          "relationship": "References People and Orgs student identity; see https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/data_dictionary.",
          "invalidWhen": "Parsed from email/name/source payload instead of resolved by the Events/Results adapter.",
          "example": "student_01HT7G3YZV7QB5N4YKQ1K0Z9A9",
          "sourceClass": "Alpha extension reference",
          "itds": [
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            },
            {
              "id": "aitd-106-axis-auth-shape",
              "title": "API Axis: Auth Shape",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-106-axis-auth-shape"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "source_event_id",
          "type": "TEXT",
          "nullability": "required",
          "meaning": "Events Alpha event id this contribution derives from.",
          "constraints": "Must reference one closed Events row in the same tenant.",
          "relationship": "Many Analytics facts can reference one Events row; see https://platform3-andymontgomery-9773s-projects.vercel.app/events/alpha/data_dictionary#table-event.",
          "invalidWhen": "Null, cross-tenant, or replaced by a copied Caliper payload column.",
          "example": "evt_alpha_000891",
          "sourceClass": "Alpha extension reference",
          "itds": [
            {
              "id": "aitd-000-extend-only-storage",
              "title": "Analytics Is New Extend-Only Alpha Storage",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-000-extend-only-storage"
            },
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            },
            {
              "id": "aitd-005-time-facts-and-windows",
              "title": "Active, Inactive, And Waste Seconds Are Typed Derived Time Facts",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-005-time-facts-and-windows"
            }
          ]
        },
        {
          "name": "source_fact_key",
          "type": "TEXT",
          "nullability": "required",
          "meaning": "Deterministic idempotency key for the materialized source contribution or rollup.",
          "constraints": "Includes tenant, source ref, fact kind/scope, policy_ref, and calculation_version; max 512 bytes.",
          "relationship": "Unique per table where the row is a single materialized source contribution.",
          "invalidWhen": "Generated from non-deterministic timestamps or caller-provided display labels.",
          "example": "tenant:7b0b:event:evt_891:fact:active_seconds:policy:v2026-06-10:calc:1",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-105-axis-idempotency",
              "title": "API Axis: Idempotency Model",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-105-axis-idempotency"
            }
          ]
        },
        {
          "name": "source_closed_at",
          "type": "TIMESTAMPTZ",
          "nullability": "required",
          "meaning": "When the source Event or Result became closed enough for Analytics to materialize from it.",
          "constraints": "Set by Events/Results close/import notifications; UTC timestamp.",
          "relationship": "Prevents reports from reading provisional source rows as final derived facts.",
          "invalidWhen": "Null on a reportable row or copied from source payload without source close confirmation.",
          "example": "2026-05-14T18:32:20Z",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            }
          ]
        },
        {
          "name": "fact_kind",
          "type": "TEXT enum",
          "nullability": "required",
          "meaning": "Which time bucket this signed contribution belongs to.",
          "constraints": "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.",
          "relationship": "One source event can create up to one current row for each fact_kind under a policy.",
          "invalidWhen": "A caller supplies the bucket or a report parses app names/actions to infer it.",
          "example": "active_seconds",
          "enum": "fact_kind",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-005-time-facts-and-windows",
              "title": "Active, Inactive, And Waste Seconds Are Typed Derived Time Facts",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-005-time-facts-and-windows"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "seconds_delta",
          "type": "NUMERIC(14,3)",
          "nullability": "required",
          "meaning": "Signed seconds contributed by this source event to the fact_kind bucket.",
          "constraints": "May be negative for correction/reversal rows; ordinary display measures use rollup fields, not client-side clamping.",
          "relationship": "Feeds alpha.analytics_time_window totals.",
          "invalidWhen": "Assumed nonnegative for corrections or recomputed from source duration by a report.",
          "example": "420.000",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-005-time-facts-and-windows",
              "title": "Active, Inactive, And Waste Seconds Are Typed Derived Time Facts",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-005-time-facts-and-windows"
            },
            {
              "id": "aitd-012-corrections-and-reversals",
              "title": "Corrections Are Signed Facts With Provenance",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-012-corrections-and-reversals"
            }
          ]
        },
        {
          "name": "subject_id",
          "type": "TEXT",
          "nullability": "nullable where the row is all-subject or the source cannot validly resolve a subject",
          "meaning": "Canonical Alpha subject used for reporting and grouping.",
          "constraints": "Closed Alpha subject enum after write-time source-label normalization; unknown source subject becomes an adapter finding or null_reason, not a new string.",
          "relationship": "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.",
          "invalidWhen": "Copied from source strings such as FastMath, Vocabulary, Science-notqced, or ISEE variants without normalization.",
          "example": "math",
          "sourceClass": "Alpha extension reference",
          "itds": [
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "application_ref",
          "type": "TEXT",
          "nullability": "nullable",
          "meaning": "Application/activity-source reference resolved from the source event when available.",
          "constraints": "Reference only; application identity/lifecycle belongs to Applications.",
          "relationship": "Optional grouping key for app-level time evidence; not a user id.",
          "invalidWhen": "Used as a credential, treated as a student, or copied from app display text without registry resolution.",
          "example": "app_math_academy",
          "sourceClass": "Alpha extension reference",
          "itds": [
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "policy_ref",
          "type": "TEXT",
          "nullability": "required",
          "meaning": "Named policy/config version used to compute the measure or rollup.",
          "constraints": "Must point at alpha.policy.analytics.* or an inherited Curriculum/Results policy active for the source effective date.",
          "relationship": "Many Analytics facts can share one policy row; changing policy creates new calculation versions or corrections.",
          "invalidWhen": "A consumer hard-codes thresholds, school-day calendars, Growth X formulas, or completion denominators instead of using the policy ref.",
          "example": "alpha.policy.analytics.time_classification.v2026-06-10",
          "sourceClass": "Alpha extension reference",
          "itds": [
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            },
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            }
          ]
        },
        {
          "name": "quality_status",
          "type": "TEXT enum",
          "nullability": "required",
          "meaning": "Current materialization quality state for this fact.",
          "constraints": "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.",
          "relationship": "Used by raw/API convergence filters and source-ref audit views.",
          "invalidWhen": "Free-text status or hidden failures represented as HTTP 200 success.",
          "example": "ok",
          "enum": "quality_status",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            },
            {
              "id": "aitd-108-axis-error-envelope",
              "title": "API Axis: Error Envelope",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-108-axis-error-envelope"
            },
            {
              "id": "aitd-111-axis-privacy-retention",
              "title": "API Axis: Privacy And Retention",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-111-axis-privacy-retention"
            }
          ]
        },
        {
          "name": "calculation_version",
          "type": "INTEGER",
          "nullability": "required",
          "meaning": "Materializer calculation version for this fact shape.",
          "constraints": "Positive integer; starts at 1 and increments when policy/materializer logic intentionally changes.",
          "relationship": "Part of deterministic source_fact_key/idempotency for materializer writes.",
          "invalidWhen": "Omitted from replay keys or changed without a new policy/materializer decision.",
          "example": "1",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            },
            {
              "id": "aitd-105-axis-idempotency",
              "title": "API Axis: Idempotency Model",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-105-axis-idempotency"
            },
            {
              "id": "aitd-104-axis-concurrency",
              "title": "API Axis: Concurrency Model",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-104-axis-concurrency"
            }
          ]
        },
        {
          "name": "computed_at",
          "type": "TIMESTAMPTZ",
          "nullability": "required",
          "meaning": "When Analytics wrote this derived fact.",
          "constraints": "UTC timestamp with timezone; updated only by Analytics materializers.",
          "relationship": "Used for audit and source-ref subcollections, not for school-day grouping.",
          "invalidWhen": "Used as a substitute for the source event time, result effective time, or window boundaries.",
          "example": "2026-06-10T00:51:14Z",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            }
          ]
        },
        {
          "name": "modified_at",
          "type": "TIMESTAMPTZ",
          "nullability": "required",
          "meaning": "Last time the Analytics row changed for polling and modifiedSince queries.",
          "constraints": "UTC timestamp; list endpoints support modifiedSince against this field.",
          "relationship": "Supports poll plus modifiedSince eventing.",
          "invalidWhen": "Client-supplied or used as the business effective date.",
          "example": "2026-06-10T00:51:14Z",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-107-axis-eventing",
              "title": "API Axis: Eventing Model",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-107-axis-eventing"
            },
            {
              "id": "aitd-103-axis-query-model",
              "title": "API Axis: Query Model",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-103-axis-query-model"
            }
          ]
        },
        {
          "name": "superseded_at",
          "type": "TIMESTAMPTZ",
          "nullability": "nullable",
          "meaning": "When this row stopped being the current reportable version because of source correction, deletion, or recalculation.",
          "constraints": "Null means current; non-null rows are excluded from ordinary list reads unless includeSuperseded=true and authorized.",
          "relationship": "Preserves audit history without mutating source Events or Results.",
          "invalidWhen": "Used to hard-delete old rows or omitted on a correction that replaces a prior fact.",
          "example": "null",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-111-axis-privacy-retention",
              "title": "API Axis: Privacy And Retention",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-111-axis-privacy-retention"
            },
            {
              "id": "aitd-012-corrections-and-reversals",
              "title": "Corrections Are Signed Facts With Provenance",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-012-corrections-and-reversals"
            }
          ]
        },
        {
          "name": "source_deleted_at",
          "type": "TIMESTAMPTZ",
          "nullability": "nullable",
          "meaning": "When the source Event/Result became deleted or invalidated.",
          "constraints": "Null for live source rows; set from source tombstone/correction notifications.",
          "relationship": "Ordinary reads exclude tombstoned facts unless includeSuperseded=true and authorized.",
          "invalidWhen": "Used as a physical delete or ignored by raw-path report queries.",
          "example": "null",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-111-axis-privacy-retention",
              "title": "API Axis: Privacy And Retention",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-111-axis-privacy-retention"
            }
          ]
        }
      ],
      "plainLanguage": "One source event became one signed time contribution. Reports normally read the rollups, but this table explains why minutes changed."
    },
    {
      "name": "alpha.analytics_time_window",
      "title": "Time Window",
      "kind": "Alpha extension rollup table",
      "grain": "student_id x subject_id nullable x window_kind x window_start x window_end x policy_ref.",
      "primaryKey": "id; unique current grain is (tenant_id, student_id, subject_id, window_kind, window_start, window_end, policy_ref, calculation_version).",
      "lifecycle": "Refreshed idempotently after event-time facts close, replay, correct, or reverse.",
      "purpose": "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.",
      "metricChecks": [
        "minutes|Caliper events"
      ],
      "architecture": [
        {
          "id": "aitd-005-time-facts-and-windows",
          "title": "Active, Inactive, And Waste Seconds Are Typed Derived Time Facts",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-005-time-facts-and-windows"
        },
        {
          "id": "aitd-002-derived-events-complement",
          "title": "Derived-From-Events Facts Complement, Never Substitute For, Ingested Tiles",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-002-derived-events-complement"
        },
        {
          "id": "aitd-003-close-time-materialization",
          "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
        },
        {
          "id": "aitd-011-policy-and-enum-normalization",
          "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
        },
        {
          "id": "aitd-112-axis-list-endpoints",
          "title": "API Axis: List Endpoints",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-112-axis-list-endpoints"
        }
      ],
      "api": "GET /alpha/analytics/v1/time-windows",
      "rawRule": "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.",
      "example": {
        "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
      },
      "fields": [
        {
          "name": "id",
          "type": "UUID",
          "nullability": "required",
          "meaning": "Analytics-owned stable row id for this derived fact.",
          "constraints": "Generated by the platform; globally unique within alpha.analytics_* objects.",
          "relationship": "Primary key for list/detail endpoints.",
          "invalidWhen": "Provided by a public import client or reused across tenants.",
          "example": "8e9c0ef2-bc75-4f53-8124-df77df49f25f",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-000-extend-only-storage",
              "title": "Analytics Is New Extend-Only Alpha Storage",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-000-extend-only-storage"
            }
          ]
        },
        {
          "name": "tenant_id",
          "type": "UUID",
          "nullability": "required",
          "meaning": "Tenant boundary for the derived fact.",
          "constraints": "Set from the JWT tenant claim or internal materializer context; never accepted from request body/query.",
          "relationship": "All raw-path queries must filter by tenant_id before joining, sorting, paging, or counting.",
          "invalidWhen": "Missing, caller-supplied in body/query, or mismatched with the JWT tenant claim.",
          "example": "7b0bb5d8-9a38-4a62-9fdc-9f8d2dc1a111",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-109-axis-tenant-routing",
              "title": "API Axis: Tenant Routing",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-109-axis-tenant-routing"
            },
            {
              "id": "aitd-106-axis-auth-shape",
              "title": "API Axis: Auth Shape",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-106-axis-auth-shape"
            }
          ]
        },
        {
          "name": "student_id",
          "type": "TEXT",
          "nullability": "required",
          "meaning": "Canonical Alpha student id the source Event or Result resolved to at materialization time.",
          "constraints": "Must resolve through People and Orgs as a real student for the source timestamp/effective date.",
          "relationship": "References People and Orgs student identity; see https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/data_dictionary.",
          "invalidWhen": "Parsed from email/name/source payload instead of resolved by the Events/Results adapter.",
          "example": "student_01HT7G3YZV7QB5N4YKQ1K0Z9A9",
          "sourceClass": "Alpha extension reference",
          "itds": [
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            },
            {
              "id": "aitd-106-axis-auth-shape",
              "title": "API Axis: Auth Shape",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-106-axis-auth-shape"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "subject_id",
          "type": "TEXT",
          "nullability": "nullable where the row is all-subject or the source cannot validly resolve a subject",
          "meaning": "Canonical Alpha subject used for reporting and grouping.",
          "constraints": "Closed Alpha subject enum after write-time source-label normalization; unknown source subject becomes an adapter finding or null_reason, not a new string.",
          "relationship": "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.",
          "invalidWhen": "Copied from source strings such as FastMath, Vocabulary, Science-notqced, or ISEE variants without normalization.",
          "example": "math",
          "sourceClass": "Alpha extension reference",
          "itds": [
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "window_kind",
          "type": "TEXT enum",
          "nullability": "required",
          "meaning": "Named window family for this rollup.",
          "constraints": "Allowed values: window_kind enum; custom requires explicit policy/window metadata.",
          "relationship": "Part of the rollup grain and list filters.",
          "invalidWhen": "Inferred by parsing term labels or source date strings in a consumer.",
          "example": "day",
          "enum": "window_kind",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-005-time-facts-and-windows",
              "title": "Active, Inactive, And Waste Seconds Are Typed Derived Time Facts",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-005-time-facts-and-windows"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            },
            {
              "id": "aitd-103-axis-query-model",
              "title": "API Axis: Query Model",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-103-axis-query-model"
            }
          ]
        },
        {
          "name": "window_start",
          "type": "DATE",
          "nullability": "required",
          "meaning": "Inclusive start date of the reporting window in the school timezone.",
          "constraints": "Must be before window_end; ISO date.",
          "relationship": "Half-open range [window_start, window_end).",
          "invalidWhen": "Computed from modified_at or source_closed_at instead of the policy window.",
          "example": "2026-05-14",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-005-time-facts-and-windows",
              "title": "Active, Inactive, And Waste Seconds Are Typed Derived Time Facts",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-005-time-facts-and-windows"
            }
          ]
        },
        {
          "name": "window_end",
          "type": "DATE",
          "nullability": "required",
          "meaning": "Exclusive end date of the reporting window in the school timezone.",
          "constraints": "Must be after window_start; ISO date.",
          "relationship": "Half-open range [window_start, window_end).",
          "invalidWhen": "Treated as inclusive by raw-path queries.",
          "example": "2026-05-15",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-005-time-facts-and-windows",
              "title": "Active, Inactive, And Waste Seconds Are Typed Derived Time Facts",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-005-time-facts-and-windows"
            }
          ]
        },
        {
          "name": "active_seconds_total",
          "type": "NUMERIC(14,3)",
          "nullability": "required",
          "meaning": "Net active seconds from current event_time_fact rows in this window.",
          "constraints": "Can include signed corrections; display fields apply policy presentation.",
          "relationship": "Numerator source for school-day minutes.",
          "invalidWhen": "Recomputed by the app from source events.",
          "example": "3240.000",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-005-time-facts-and-windows",
              "title": "Active, Inactive, And Waste Seconds Are Typed Derived Time Facts",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-005-time-facts-and-windows"
            },
            {
              "id": "aitd-012-corrections-and-reversals",
              "title": "Corrections Are Signed Facts With Provenance",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-012-corrections-and-reversals"
            }
          ]
        },
        {
          "name": "inactive_seconds_total",
          "type": "NUMERIC(14,3)",
          "nullability": "required",
          "meaning": "Net inactive seconds from current event_time_fact rows in this window.",
          "constraints": "Can include signed corrections.",
          "relationship": "Report display/audit metric; not subtracted by consumers unless a named policy says so.",
          "invalidWhen": "Derived by client idle-threshold logic.",
          "example": "120.000",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-005-time-facts-and-windows",
              "title": "Active, Inactive, And Waste Seconds Are Typed Derived Time Facts",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-005-time-facts-and-windows"
            },
            {
              "id": "aitd-012-corrections-and-reversals",
              "title": "Corrections Are Signed Facts With Provenance",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-012-corrections-and-reversals"
            }
          ]
        },
        {
          "name": "waste_seconds_total",
          "type": "NUMERIC(14,3)",
          "nullability": "required",
          "meaning": "Net waste/gaming seconds from current event_time_fact rows in this window.",
          "constraints": "Can be positive or negative after corrections.",
          "relationship": "Feeds closed-loop dashboards and XP penalty audits.",
          "invalidWhen": "Modeled as an event category rather than an Analytics derived fact.",
          "example": "0.000",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-005-time-facts-and-windows",
              "title": "Active, Inactive, And Waste Seconds Are Typed Derived Time Facts",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-005-time-facts-and-windows"
            },
            {
              "id": "aitd-012-corrections-and-reversals",
              "title": "Corrections Are Signed Facts With Provenance",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-012-corrections-and-reversals"
            }
          ]
        },
        {
          "name": "display_active_minutes",
          "type": "NUMERIC(12,3)",
          "nullability": "required",
          "meaning": "Policy-defined active minutes shown in reports for this time window.",
          "constraints": "Computed by Analytics from active_seconds_total under policy_ref; consumers read it directly.",
          "relationship": "Used by app/report display when the question asks for active minutes, not raw seconds.",
          "invalidWhen": "Consumer divides seconds by 60 differently or clamps signed corrections locally.",
          "example": "54.000",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-005-time-facts-and-windows",
              "title": "Active, Inactive, And Waste Seconds Are Typed Derived Time Facts",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-005-time-facts-and-windows"
            },
            {
              "id": "aitd-012-corrections-and-reversals",
              "title": "Corrections Are Signed Facts With Provenance",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-012-corrections-and-reversals"
            }
          ]
        },
        {
          "name": "source_fact_count",
          "type": "INTEGER",
          "nullability": "required",
          "meaning": "Number of current event_time_fact rows contributing to this rollup.",
          "constraints": "Nonnegative integer.",
          "relationship": "Audit/provenance summary; detailed refs live in the authorized sourceRefs subcollection.",
          "invalidWhen": "Used as a proxy for number of Events without applying fact_kind and correction rules.",
          "example": "12",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-102-axis-read-shape",
              "title": "API Axis: Read Shape",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-102-axis-read-shape"
            }
          ]
        },
        {
          "name": "source_fact_refs",
          "type": "JSONB",
          "nullability": "required",
          "meaning": "Compact list or cursor descriptor for contributing analytics_event_time_fact ids.",
          "constraints": "Contains ids/hashes only, never raw Caliper payload or PII.",
          "relationship": "Supports /time-windows/{id}/source-refs for authorized audit users.",
          "invalidWhen": "Stores source payload copies or student display names.",
          "example": "[\"8e9c0ef2-bc75-4f53-8124-df77df49f25f\"]",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-000-extend-only-storage",
              "title": "Analytics Is New Extend-Only Alpha Storage",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-000-extend-only-storage"
            },
            {
              "id": "aitd-102-axis-read-shape",
              "title": "API Axis: Read Shape",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-102-axis-read-shape"
            },
            {
              "id": "aitd-111-axis-privacy-retention",
              "title": "API Axis: Privacy And Retention",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-111-axis-privacy-retention"
            }
          ]
        },
        {
          "name": "policy_ref",
          "type": "TEXT",
          "nullability": "required",
          "meaning": "Named policy/config version used to compute the measure or rollup.",
          "constraints": "Must point at alpha.policy.analytics.* or an inherited Curriculum/Results policy active for the source effective date.",
          "relationship": "Many Analytics facts can share one policy row; changing policy creates new calculation versions or corrections.",
          "invalidWhen": "A consumer hard-codes thresholds, school-day calendars, Growth X formulas, or completion denominators instead of using the policy ref.",
          "example": "alpha.policy.analytics.time_classification.v2026-06-10",
          "sourceClass": "Alpha extension reference",
          "itds": [
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            },
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            }
          ]
        },
        {
          "name": "quality_status",
          "type": "TEXT enum",
          "nullability": "required",
          "meaning": "Current materialization quality state for this fact.",
          "constraints": "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.",
          "relationship": "Used by raw/API convergence filters and source-ref audit views.",
          "invalidWhen": "Free-text status or hidden failures represented as HTTP 200 success.",
          "example": "ok",
          "enum": "quality_status",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            },
            {
              "id": "aitd-108-axis-error-envelope",
              "title": "API Axis: Error Envelope",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-108-axis-error-envelope"
            },
            {
              "id": "aitd-111-axis-privacy-retention",
              "title": "API Axis: Privacy And Retention",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-111-axis-privacy-retention"
            }
          ]
        },
        {
          "name": "calculation_version",
          "type": "INTEGER",
          "nullability": "required",
          "meaning": "Materializer calculation version for this fact shape.",
          "constraints": "Positive integer; starts at 1 and increments when policy/materializer logic intentionally changes.",
          "relationship": "Part of deterministic source_fact_key/idempotency for materializer writes.",
          "invalidWhen": "Omitted from replay keys or changed without a new policy/materializer decision.",
          "example": "1",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            },
            {
              "id": "aitd-105-axis-idempotency",
              "title": "API Axis: Idempotency Model",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-105-axis-idempotency"
            },
            {
              "id": "aitd-104-axis-concurrency",
              "title": "API Axis: Concurrency Model",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-104-axis-concurrency"
            }
          ]
        },
        {
          "name": "computed_at",
          "type": "TIMESTAMPTZ",
          "nullability": "required",
          "meaning": "When Analytics wrote this derived fact.",
          "constraints": "UTC timestamp with timezone; updated only by Analytics materializers.",
          "relationship": "Used for audit and source-ref subcollections, not for school-day grouping.",
          "invalidWhen": "Used as a substitute for the source event time, result effective time, or window boundaries.",
          "example": "2026-06-10T00:51:14Z",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            }
          ]
        },
        {
          "name": "modified_at",
          "type": "TIMESTAMPTZ",
          "nullability": "required",
          "meaning": "Last time the Analytics row changed for polling and modifiedSince queries.",
          "constraints": "UTC timestamp; list endpoints support modifiedSince against this field.",
          "relationship": "Supports poll plus modifiedSince eventing.",
          "invalidWhen": "Client-supplied or used as the business effective date.",
          "example": "2026-06-10T00:51:14Z",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-107-axis-eventing",
              "title": "API Axis: Eventing Model",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-107-axis-eventing"
            },
            {
              "id": "aitd-103-axis-query-model",
              "title": "API Axis: Query Model",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-103-axis-query-model"
            }
          ]
        },
        {
          "name": "superseded_at",
          "type": "TIMESTAMPTZ",
          "nullability": "nullable",
          "meaning": "When this row stopped being the current reportable version because of source correction, deletion, or recalculation.",
          "constraints": "Null means current; non-null rows are excluded from ordinary list reads unless includeSuperseded=true and authorized.",
          "relationship": "Preserves audit history without mutating source Events or Results.",
          "invalidWhen": "Used to hard-delete old rows or omitted on a correction that replaces a prior fact.",
          "example": "null",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-111-axis-privacy-retention",
              "title": "API Axis: Privacy And Retention",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-111-axis-privacy-retention"
            },
            {
              "id": "aitd-012-corrections-and-reversals",
              "title": "Corrections Are Signed Facts With Provenance",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-012-corrections-and-reversals"
            }
          ]
        },
        {
          "name": "source_deleted_at",
          "type": "TIMESTAMPTZ",
          "nullability": "nullable",
          "meaning": "When the source Event/Result became deleted or invalidated.",
          "constraints": "Null for live source rows; set from source tombstone/correction notifications.",
          "relationship": "Ordinary reads exclude tombstoned facts unless includeSuperseded=true and authorized.",
          "invalidWhen": "Used as a physical delete or ignored by raw-path report queries.",
          "example": "null",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-111-axis-privacy-retention",
              "title": "API Axis: Privacy And Retention",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-111-axis-privacy-retention"
            }
          ]
        }
      ],
      "plainLanguage": "How much active, inactive, and waste time a student had in a day, week, term, school year, or named custom range."
    },
    {
      "name": "alpha.analytics_school_day_minutes",
      "title": "School-Day Minutes",
      "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.",
      "primaryKey": "id; unique current grain is (tenant_id, student_id, school_id, subject_id, window_start, window_end, school_day_policy_ref, calculation_version).",
      "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.",
      "purpose": "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.",
      "metricChecks": [
        "minutes|Caliper events"
      ],
      "architecture": [
        {
          "id": "aitd-006-school-day-minutes",
          "title": "Minutes Per Enrolled School Day Uses The Alpha School Calendar",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-006-school-day-minutes"
        },
        {
          "id": "aitd-001-report-source-ingestion",
          "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
        },
        {
          "id": "aitd-004-provenance-no-literals",
          "title": "Every Report Value Traces To An Ingested Source Row, Or Reads Null",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-004-provenance-no-literals"
        },
        {
          "id": "aitd-005-time-facts-and-windows",
          "title": "Active, Inactive, And Waste Seconds Are Typed Derived Time Facts",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-005-time-facts-and-windows"
        },
        {
          "id": "aitd-011-policy-and-enum-normalization",
          "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
        }
      ],
      "api": "GET /alpha/analytics/v1/school-day-minutes",
      "rawRule": "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.",
      "example": {
        "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
      },
      "fields": [
        {
          "name": "id",
          "type": "UUID",
          "nullability": "required",
          "meaning": "Analytics-owned stable row id for this derived fact.",
          "constraints": "Generated by the platform; globally unique within alpha.analytics_* objects.",
          "relationship": "Primary key for list/detail endpoints.",
          "invalidWhen": "Provided by a public import client or reused across tenants.",
          "example": "8e9c0ef2-bc75-4f53-8124-df77df49f25f",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-000-extend-only-storage",
              "title": "Analytics Is New Extend-Only Alpha Storage",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-000-extend-only-storage"
            }
          ]
        },
        {
          "name": "tenant_id",
          "type": "UUID",
          "nullability": "required",
          "meaning": "Tenant boundary for the derived fact.",
          "constraints": "Set from the JWT tenant claim or internal materializer context; never accepted from request body/query.",
          "relationship": "All raw-path queries must filter by tenant_id before joining, sorting, paging, or counting.",
          "invalidWhen": "Missing, caller-supplied in body/query, or mismatched with the JWT tenant claim.",
          "example": "7b0bb5d8-9a38-4a62-9fdc-9f8d2dc1a111",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-109-axis-tenant-routing",
              "title": "API Axis: Tenant Routing",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-109-axis-tenant-routing"
            },
            {
              "id": "aitd-106-axis-auth-shape",
              "title": "API Axis: Auth Shape",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-106-axis-auth-shape"
            }
          ]
        },
        {
          "name": "student_id",
          "type": "TEXT",
          "nullability": "required",
          "meaning": "Canonical Alpha student id the source Event or Result resolved to at materialization time.",
          "constraints": "Must resolve through People and Orgs as a real student for the source timestamp/effective date.",
          "relationship": "References People and Orgs student identity; see https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/data_dictionary.",
          "invalidWhen": "Parsed from email/name/source payload instead of resolved by the Events/Results adapter.",
          "example": "student_01HT7G3YZV7QB5N4YKQ1K0Z9A9",
          "sourceClass": "Alpha extension reference",
          "itds": [
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            },
            {
              "id": "aitd-106-axis-auth-shape",
              "title": "API Axis: Auth Shape",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-106-axis-auth-shape"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "school_id",
          "type": "TEXT",
          "nullability": "required",
          "meaning": "People and Orgs school whose calendar/enrollment intersection defines the denominator.",
          "constraints": "Must resolve as the student school for the effective range; no current-only shortcut.",
          "relationship": "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).",
          "invalidWhen": "Copied from source campus_name or joined through current roster instead of effective-dated enrollment.",
          "example": "school_alpha_austin",
          "sourceClass": "Alpha extension reference",
          "itds": [
            {
              "id": "aitd-006-school-day-minutes",
              "title": "Minutes Per Enrolled School Day Uses The Alpha School Calendar",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-006-school-day-minutes"
            }
          ]
        },
        {
          "name": "subject_id",
          "type": "TEXT",
          "nullability": "nullable; null means all reportable subjects",
          "meaning": "Canonical Alpha subject used for reporting and grouping.",
          "constraints": "Closed Alpha subject enum after write-time source-label normalization; unknown source subject becomes an adapter finding or null_reason, not a new string.",
          "relationship": "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.",
          "invalidWhen": "Copied from source strings such as FastMath, Vocabulary, Science-notqced, or ISEE variants without normalization.",
          "example": "math",
          "sourceClass": "Alpha extension reference",
          "itds": [
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "school_day_policy_ref",
          "type": "TEXT",
          "nullability": "required",
          "meaning": "Named policy/config version used to compute the measure or rollup.",
          "constraints": "Must point at alpha.policy.analytics.* or an inherited Curriculum/Results policy active for the source effective date.",
          "relationship": "Many Analytics facts can share one policy row; changing policy creates new calculation versions or corrections.",
          "invalidWhen": "A consumer hard-codes thresholds, school-day calendars, Growth X formulas, or completion denominators instead of using the policy ref.",
          "example": "alpha.policy.school_day.v2026-06-10",
          "sourceClass": "Alpha extension reference",
          "itds": [
            {
              "id": "aitd-006-school-day-minutes",
              "title": "Minutes Per Enrolled School Day Uses The Alpha School Calendar",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-006-school-day-minutes"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "window_start",
          "type": "DATE",
          "nullability": "required",
          "meaning": "Inclusive start date for the denominator/numerator window.",
          "constraints": "ISO date; half-open range with window_end.",
          "relationship": "Used with school_id calendar and enrollment refs.",
          "invalidWhen": "Parsed from report labels or MAP term strings.",
          "example": "2026-05-01",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-006-school-day-minutes",
              "title": "Minutes Per Enrolled School Day Uses The Alpha School Calendar",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-006-school-day-minutes"
            }
          ]
        },
        {
          "name": "window_end",
          "type": "DATE",
          "nullability": "required",
          "meaning": "Exclusive end date for the denominator/numerator window.",
          "constraints": "ISO date; must be after window_start.",
          "relationship": "Used with school_id calendar and enrollment refs.",
          "invalidWhen": "Treated as inclusive by raw queries.",
          "example": "2026-06-01",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-006-school-day-minutes",
              "title": "Minutes Per Enrolled School Day Uses The Alpha School Calendar",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-006-school-day-minutes"
            }
          ]
        },
        {
          "name": "enrolled_school_day_count",
          "type": "INTEGER",
          "nullability": "required when null_reason=none; nullable only for source_missing repair rows",
          "meaning": "Denominator: school days intersecting the student effective-dated enrollment and subject assignment when subject_id is present.",
          "constraints": "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.",
          "relationship": "Comes from alpha.school_calendar and People and Orgs enrollment windows.",
          "invalidWhen": "Computed from processed_facts active dates, attendance days, raw calendar days, or current enrollment by a report.",
          "example": "90",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-006-school-day-minutes",
              "title": "Minutes Per Enrolled School Day Uses The Alpha School Calendar",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-006-school-day-minutes"
            }
          ]
        },
        {
          "name": "excluded_school_day_count",
          "type": "INTEGER",
          "nullability": "required when null_reason=none; nullable only for source_missing repair rows",
          "meaning": "Calendar dates inside the requested window that the school-day policy excluded from the denominator.",
          "constraints": "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.",
          "relationship": "Same alpha.school_calendar source and enrollment/subject intersection pass as enrolled_school_day_count.",
          "invalidWhen": "Guessed from weekends, hard-coded MAP dates, or attendance gaps without calendar rows.",
          "example": "61",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-006-school-day-minutes",
              "title": "Minutes Per Enrolled School Day Uses The Alpha School Calendar",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-006-school-day-minutes"
            }
          ]
        },
        {
          "name": "active_minutes",
          "type": "NUMERIC(12,3)",
          "nullability": "required",
          "meaning": "Policy-defined active minutes for the same window and subject grain.",
          "constraints": "Normalized by the timeback-xp-time-accuracy adapter from reporting.processed_facts.active_seconds, then stored as minutes under policy_ref.",
          "relationship": "Numerator for minutes_per_enrolled_school_day; analytics_time_window remains the derived Events audit complement.",
          "invalidWhen": "A consumer sums raw event durations, divides processed_facts seconds, or substitutes derived audit seconds for the report tile.",
          "example": "4860.000",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-006-school-day-minutes",
              "title": "Minutes Per Enrolled School Day Uses The Alpha School Calendar",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-006-school-day-minutes"
            },
            {
              "id": "aitd-001-report-source-ingestion",
              "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
            },
            {
              "id": "aitd-005-time-facts-and-windows",
              "title": "Active, Inactive, And Waste Seconds Are Typed Derived Time Facts",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-005-time-facts-and-windows"
            }
          ]
        },
        {
          "name": "minutes_per_enrolled_school_day",
          "type": "NUMERIC(12,3)",
          "nullability": "nullable when denominator is zero or policy/source is missing",
          "meaning": "Report-ready average active minutes per enrolled school day when the school-day denominator source is available.",
          "constraints": "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.",
          "relationship": "The value reports and skill packs read. A null/source_missing row is a repair state, not a normal rendered value.",
          "invalidWhen": "Computed by a dashboard from active_minutes and a client-side day count.",
          "example": "54.000",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-006-school-day-minutes",
              "title": "Minutes Per Enrolled School Day Uses The Alpha School Calendar",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-006-school-day-minutes"
            }
          ]
        },
        {
          "name": "calendar_ref_count",
          "type": "INTEGER",
          "nullability": "required when null_reason=none; nullable only for source_missing repair rows",
          "meaning": "Count of school calendar rows used in the denominator calculation.",
          "constraints": "Nonnegative when populated; detailed ids available only to authorized audit reads. Null only when calendar coverage itself is source_missing.",
          "relationship": "Audit summary for alpha.school_calendar source coverage.",
          "invalidWhen": "Treated as enrolled school day count without applying enrollment/subject filters.",
          "example": "151",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-006-school-day-minutes",
              "title": "Minutes Per Enrolled School Day Uses The Alpha School Calendar",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-006-school-day-minutes"
            },
            {
              "id": "aitd-102-axis-read-shape",
              "title": "API Axis: Read Shape",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-102-axis-read-shape"
            }
          ]
        },
        {
          "name": "enrollment_ref_count",
          "type": "INTEGER",
          "nullability": "required",
          "meaning": "Count of People and Orgs enrollment/membership rows used for the point-in-time denominator.",
          "constraints": "Nonnegative; null begin_date memberships are excluded from denominator claims.",
          "relationship": "Audit summary for point-in-time roster source coverage.",
          "invalidWhen": "Used to infer current school membership outside the requested date range.",
          "example": "1",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-006-school-day-minutes",
              "title": "Minutes Per Enrolled School Day Uses The Alpha School Calendar",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-006-school-day-minutes"
            }
          ]
        },
        {
          "name": "quality_status",
          "type": "TEXT enum",
          "nullability": "required",
          "meaning": "Current materialization quality state for this school-day denominator row.",
          "constraints": "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.",
          "relationship": "Used with null_reason so the API and raw path can expose repair states without letting reports guess.",
          "invalidWhen": "A source_missing row is treated as a reportable time-commitment value.",
          "example": "ok",
          "enum": "quality_status",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-006-school-day-minutes",
              "title": "Minutes Per Enrolled School Day Uses The Alpha School Calendar",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-006-school-day-minutes"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            },
            {
              "id": "aitd-108-axis-error-envelope",
              "title": "API Axis: Error Envelope",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-108-axis-error-envelope"
            }
          ]
        },
        {
          "name": "null_reason",
          "type": "TEXT enum",
          "nullability": "required",
          "meaning": "Why minutes_per_enrolled_school_day and denominator counts are null or not reportable.",
          "constraints": "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.",
          "relationship": "Prevents clients from guessing fallback denominator rules.",
          "invalidWhen": "Null denominator fields with no typed reason, or a free-text explanation.",
          "example": "none",
          "enum": "null_reason",
          "sourceClass": "Alpha extension enum",
          "itds": [
            {
              "id": "aitd-006-school-day-minutes",
              "title": "Minutes Per Enrolled School Day Uses The Alpha School Calendar",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-006-school-day-minutes"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "source_import_id",
          "type": "TEXT",
          "nullability": "required for report-tile rows; nullable for purely derived event-axis rows",
          "meaning": "Analytics source-import receipt that proves which named report-source adapter produced this report-grade fact.",
          "constraints": "Must reference alpha.analytics_source_import for non-null Learning Report tile values; no literal or fixture value may be reportable without this provenance.",
          "relationship": "Many report-fact rows can reference one source import; detail/sourceRefs endpoints join here for adapter, source_table, and source_row_key_hashes.",
          "invalidWhen": "Missing on a non-null report-tile value, or replaced by copied raw reporting-DB columns.",
          "example": "imp_01HT8XPTIME_2026_SPRING",
          "sourceClass": "Alpha extension provenance reference",
          "itds": [
            {
              "id": "aitd-001-report-source-ingestion",
              "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
            },
            {
              "id": "aitd-004-provenance-no-literals",
              "title": "Every Report Value Traces To An Ingested Source Row, Or Reads Null",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-004-provenance-no-literals"
            },
            {
              "id": "aitd-006-school-day-minutes",
              "title": "Minutes Per Enrolled School Day Uses The Alpha School Calendar",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-006-school-day-minutes"
            }
          ]
        },
        {
          "name": "calculation_version",
          "type": "INTEGER",
          "nullability": "required",
          "meaning": "Materializer calculation version for this fact shape.",
          "constraints": "Positive integer; starts at 1 and increments when policy/materializer logic intentionally changes.",
          "relationship": "Part of deterministic source_fact_key/idempotency for materializer writes.",
          "invalidWhen": "Omitted from replay keys or changed without a new policy/materializer decision.",
          "example": "1",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            },
            {
              "id": "aitd-105-axis-idempotency",
              "title": "API Axis: Idempotency Model",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-105-axis-idempotency"
            },
            {
              "id": "aitd-104-axis-concurrency",
              "title": "API Axis: Concurrency Model",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-104-axis-concurrency"
            }
          ]
        },
        {
          "name": "computed_at",
          "type": "TIMESTAMPTZ",
          "nullability": "required",
          "meaning": "When Analytics wrote this derived fact.",
          "constraints": "UTC timestamp with timezone; updated only by Analytics materializers.",
          "relationship": "Used for audit and source-ref subcollections, not for school-day grouping.",
          "invalidWhen": "Used as a substitute for the source event time, result effective time, or window boundaries.",
          "example": "2026-06-10T00:51:14Z",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            }
          ]
        },
        {
          "name": "modified_at",
          "type": "TIMESTAMPTZ",
          "nullability": "required",
          "meaning": "Last time the Analytics row changed for polling and modifiedSince queries.",
          "constraints": "UTC timestamp; list endpoints support modifiedSince against this field.",
          "relationship": "Supports poll plus modifiedSince eventing.",
          "invalidWhen": "Client-supplied or used as the business effective date.",
          "example": "2026-06-10T00:51:14Z",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-107-axis-eventing",
              "title": "API Axis: Eventing Model",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-107-axis-eventing"
            },
            {
              "id": "aitd-103-axis-query-model",
              "title": "API Axis: Query Model",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-103-axis-query-model"
            }
          ]
        },
        {
          "name": "superseded_at",
          "type": "TIMESTAMPTZ",
          "nullability": "nullable",
          "meaning": "When this row stopped being the current reportable version because of source correction, deletion, or recalculation.",
          "constraints": "Null means current; non-null rows are excluded from ordinary list reads unless includeSuperseded=true and authorized.",
          "relationship": "Preserves audit history without mutating source Events or Results.",
          "invalidWhen": "Used to hard-delete old rows or omitted on a correction that replaces a prior fact.",
          "example": "null",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-111-axis-privacy-retention",
              "title": "API Axis: Privacy And Retention",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-111-axis-privacy-retention"
            },
            {
              "id": "aitd-012-corrections-and-reversals",
              "title": "Corrections Are Signed Facts With Provenance",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-012-corrections-and-reversals"
            }
          ]
        },
        {
          "name": "source_deleted_at",
          "type": "TIMESTAMPTZ",
          "nullability": "nullable",
          "meaning": "When the source Event/Result became deleted or invalidated.",
          "constraints": "Null for live source rows; set from source tombstone/correction notifications.",
          "relationship": "Ordinary reads exclude tombstoned facts unless includeSuperseded=true and authorized.",
          "invalidWhen": "Used as a physical delete or ignored by raw-path report queries.",
          "example": "null",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-111-axis-privacy-retention",
              "title": "API Axis: Privacy And Retention",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-111-axis-privacy-retention"
            }
          ]
        }
      ],
      "plainLanguage": "The Learning Report time-commitment row: active minutes plus the materialized school-day denominator and report-ready minutes per enrolled school day."
    },
    {
      "name": "alpha.analytics_xp_rollup",
      "title": "XP Rollup",
      "kind": "Alpha extension rollup table",
      "grain": "student_id x subject_id nullable x window_kind x window_start x window_end x policy_ref.",
      "primaryKey": "id; unique current grain is (tenant_id, student_id, subject_id, window_kind, window_start, window_end, policy_ref, calculation_version).",
      "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.",
      "purpose": "Report-ready XP total plus goal progress fields. The goal fields use the same materialized school-day denominator as time commitment.",
      "metricChecks": [
        "XP"
      ],
      "architecture": [
        {
          "id": "aitd-007-xp-rollups",
          "title": "XP Totals, Goal, Remaining, And Completion Percent Are Ingested Report Facts",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-007-xp-rollups"
        },
        {
          "id": "aitd-001-report-source-ingestion",
          "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
        },
        {
          "id": "aitd-004-provenance-no-literals",
          "title": "Every Report Value Traces To An Ingested Source Row, Or Reads Null",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-004-provenance-no-literals"
        },
        {
          "id": "aitd-003-close-time-materialization",
          "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
        },
        {
          "id": "aitd-012-corrections-and-reversals",
          "title": "Corrections Are Signed Facts With Provenance",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-012-corrections-and-reversals"
        }
      ],
      "api": "GET /alpha/analytics/v1/xp-rollups",
      "apiReadRule": "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.",
      "rawRule": "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.",
      "example": {
        "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
      },
      "fields": [
        {
          "name": "id",
          "type": "UUID",
          "nullability": "required",
          "meaning": "Analytics-owned stable row id for this derived fact.",
          "constraints": "Generated by the platform; globally unique within alpha.analytics_* objects.",
          "relationship": "Primary key for list/detail endpoints.",
          "invalidWhen": "Provided by a public import client or reused across tenants.",
          "example": "8e9c0ef2-bc75-4f53-8124-df77df49f25f",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-000-extend-only-storage",
              "title": "Analytics Is New Extend-Only Alpha Storage",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-000-extend-only-storage"
            }
          ]
        },
        {
          "name": "tenant_id",
          "type": "UUID",
          "nullability": "required",
          "meaning": "Tenant boundary for the derived fact.",
          "constraints": "Set from the JWT tenant claim or internal materializer context; never accepted from request body/query.",
          "relationship": "All raw-path queries must filter by tenant_id before joining, sorting, paging, or counting.",
          "invalidWhen": "Missing, caller-supplied in body/query, or mismatched with the JWT tenant claim.",
          "example": "7b0bb5d8-9a38-4a62-9fdc-9f8d2dc1a111",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-109-axis-tenant-routing",
              "title": "API Axis: Tenant Routing",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-109-axis-tenant-routing"
            },
            {
              "id": "aitd-106-axis-auth-shape",
              "title": "API Axis: Auth Shape",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-106-axis-auth-shape"
            }
          ]
        },
        {
          "name": "student_id",
          "type": "TEXT",
          "nullability": "required",
          "meaning": "Canonical Alpha student id the source Event or Result resolved to at materialization time.",
          "constraints": "Must resolve through People and Orgs as a real student for the source timestamp/effective date.",
          "relationship": "References People and Orgs student identity; see https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/data_dictionary.",
          "invalidWhen": "Parsed from email/name/source payload instead of resolved by the Events/Results adapter.",
          "example": "student_01HT7G3YZV7QB5N4YKQ1K0Z9A9",
          "sourceClass": "Alpha extension reference",
          "itds": [
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            },
            {
              "id": "aitd-106-axis-auth-shape",
              "title": "API Axis: Auth Shape",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-106-axis-auth-shape"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "subject_id",
          "type": "TEXT",
          "nullability": "nullable where the row is all-subject or the source cannot validly resolve a subject",
          "meaning": "Canonical Alpha subject used for reporting and grouping.",
          "constraints": "Closed Alpha subject enum after write-time source-label normalization; unknown source subject becomes an adapter finding or null_reason, not a new string.",
          "relationship": "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.",
          "invalidWhen": "Copied from source strings such as FastMath, Vocabulary, Science-notqced, or ISEE variants without normalization.",
          "example": "math",
          "sourceClass": "Alpha extension reference",
          "itds": [
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "policy_ref",
          "type": "TEXT",
          "nullability": "required",
          "meaning": "Named policy/config version used to compute the measure or rollup.",
          "constraints": "Must point at alpha.policy.analytics.* or an inherited Curriculum/Results policy active for the source effective date.",
          "relationship": "Many Analytics facts can share one policy row; changing policy creates new calculation versions or corrections.",
          "invalidWhen": "A consumer hard-codes thresholds, school-day calendars, Growth X formulas, or completion denominators instead of using the policy ref.",
          "example": "alpha.policy.analytics.xp_goal_percent.v1",
          "sourceClass": "Alpha extension reference",
          "itds": [
            {
              "id": "aitd-007-xp-rollups",
              "title": "XP Totals, Goal, Remaining, And Completion Percent Are Ingested Report Facts",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-007-xp-rollups"
            },
            {
              "id": "aitd-006-school-day-minutes",
              "title": "Minutes Per Enrolled School Day Uses The Alpha School Calendar",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-006-school-day-minutes"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "window_kind",
          "type": "TEXT enum",
          "nullability": "required",
          "meaning": "Named window family for the XP rollup.",
          "constraints": "Allowed values: window_kind enum.",
          "relationship": "Part of XP rollup grain and list filters.",
          "invalidWhen": "Parsed from report title or term label.",
          "example": "term",
          "enum": "window_kind",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-007-xp-rollups",
              "title": "XP Totals, Goal, Remaining, And Completion Percent Are Ingested Report Facts",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-007-xp-rollups"
            },
            {
              "id": "aitd-103-axis-query-model",
              "title": "API Axis: Query Model",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-103-axis-query-model"
            }
          ]
        },
        {
          "name": "window_start",
          "type": "DATE",
          "nullability": "required",
          "meaning": "Inclusive start date for included XP ledger effective dates.",
          "constraints": "ISO date; half-open with window_end.",
          "relationship": "Defines XP reporting period.",
          "invalidWhen": "Uses computed_at instead of ledger effective date.",
          "example": "2026-01-01",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-007-xp-rollups",
              "title": "XP Totals, Goal, Remaining, And Completion Percent Are Ingested Report Facts",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-007-xp-rollups"
            }
          ]
        },
        {
          "name": "window_end",
          "type": "DATE",
          "nullability": "required",
          "meaning": "Exclusive end date for included XP ledger effective dates.",
          "constraints": "ISO date; must be after window_start.",
          "relationship": "Defines XP reporting period.",
          "invalidWhen": "Treated as inclusive in raw queries.",
          "example": "2026-06-01",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-007-xp-rollups",
              "title": "XP Totals, Goal, Remaining, And Completion Percent Are Ingested Report Facts",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-007-xp-rollups"
            }
          ]
        },
        {
          "name": "positive_xp",
          "type": "NUMERIC(14,3)",
          "nullability": "required",
          "meaning": "Positive XP contribution subtotal retained for audit/explanation.",
          "constraints": "Nonnegative; normalized by the adapter/materializer, with Results xp_ledger refs when available.",
          "relationship": "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.",
          "invalidWhen": "Computed by apps from accuracy, effort, expected_xp, or raw source rows.",
          "example": "11850.000",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-007-xp-rollups",
              "title": "XP Totals, Goal, Remaining, And Completion Percent Are Ingested Report Facts",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-007-xp-rollups"
            }
          ]
        },
        {
          "name": "negative_xp",
          "type": "NUMERIC(14,3)",
          "nullability": "required",
          "meaning": "Sum of negative XP penalties/reversals in this rollup.",
          "constraints": "Zero or negative; gaming/cheating signals and reversals stay signed.",
          "relationship": "Explains why net_xp may be lower than positive_xp.",
          "invalidWhen": "Dropped from reports or clamped to zero by consumers.",
          "example": "-50.000",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-007-xp-rollups",
              "title": "XP Totals, Goal, Remaining, And Completion Percent Are Ingested Report Facts",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-007-xp-rollups"
            },
            {
              "id": "aitd-012-corrections-and-reversals",
              "title": "Corrections Are Signed Facts With Provenance",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-012-corrections-and-reversals"
            }
          ]
        },
        {
          "name": "xp_total",
          "type": "NUMERIC(14,3)",
          "nullability": "required",
          "meaning": "Policy-defined report XP total after the report-source adapter applies subject normalization, exclusions, corrections, and signed contributions.",
          "constraints": "Non-null values require source_import_id provenance; should equal the report value for this student/subject/window.",
          "relationship": "The XP value dashboards render.",
          "invalidWhen": "Recomputed from processed_facts, xp_ledger, expected_xp, accuracy, or effort by a report.",
          "example": "11800.000",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-007-xp-rollups",
              "title": "XP Totals, Goal, Remaining, And Completion Percent Are Ingested Report Facts",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-007-xp-rollups"
            },
            {
              "id": "aitd-001-report-source-ingestion",
              "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
            },
            {
              "id": "aitd-004-provenance-no-literals",
              "title": "Every Report Value Traces To An Ingested Source Row, Or Reads Null",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-004-provenance-no-literals"
            }
          ]
        },
        {
          "name": "net_xp",
          "type": "NUMERIC(14,3)",
          "nullability": "required",
          "meaning": "Signed audit total after positive and negative XP contributions; equal to xp_total for ordinary report rows under the current policy.",
          "constraints": "positive_xp + negative_xp under policy_ref; retained for correction/reversal reconciliation.",
          "relationship": "Explains how signed contributions reconcile to xp_total.",
          "invalidWhen": "Used by a consumer instead of xp_total when the two diverge under a future policy.",
          "example": "11800.000",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-007-xp-rollups",
              "title": "XP Totals, Goal, Remaining, And Completion Percent Are Ingested Report Facts",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-007-xp-rollups"
            },
            {
              "id": "aitd-012-corrections-and-reversals",
              "title": "Corrections Are Signed Facts With Provenance",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-012-corrections-and-reversals"
            }
          ]
        },
        {
          "name": "xp_goal",
          "type": "NUMERIC(14,3)",
          "nullability": "required when null_reason=none; nullable only when enrolled_school_day_count or XP goal policy is missing",
          "meaning": "Window XP target for this student, subject, and window, used by the Learning Report XP Remaining and XP Goal Percent panels.",
          "constraints": "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.",
          "relationship": "Lets reports show XP remaining without reading Curriculum trees or goal policy directly.",
          "invalidWhen": "A report computes the goal from Content expected_xp, active dates, attendance days, raw calendar days, or hard-coded course sizes.",
          "example": "9000.000",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-007-xp-rollups",
              "title": "XP Totals, Goal, Remaining, And Completion Percent Are Ingested Report Facts",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-007-xp-rollups"
            },
            {
              "id": "aitd-006-school-day-minutes",
              "title": "Minutes Per Enrolled School Day Uses The Alpha School Calendar",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-006-school-day-minutes"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "daily_xp_goal",
          "type": "NUMERIC(14,3)",
          "nullability": "nullable when daily XP policy is missing",
          "meaning": "Daily XP target used in the auditor-pinned XP goal percent denominator.",
          "constraints": "Nonnegative; read from alpha.policy.analytics.xp_goal_percent.v1 / Curriculum Policy, never from a consumer constant.",
          "relationship": "Multiplied by enrolled_school_day_count to produce xp_goal.",
          "invalidWhen": "Hard-coded in a report, skill pack, or import caller.",
          "example": "100.000",
          "sourceClass": "Alpha extension policy reference value",
          "itds": [
            {
              "id": "aitd-007-xp-rollups",
              "title": "XP Totals, Goal, Remaining, And Completion Percent Are Ingested Report Facts",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-007-xp-rollups"
            },
            {
              "id": "aitd-006-school-day-minutes",
              "title": "Minutes Per Enrolled School Day Uses The Alpha School Calendar",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-006-school-day-minutes"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "enrolled_school_day_count",
          "type": "INTEGER",
          "nullability": "required when null_reason=none; nullable only when school-day denominator source is missing",
          "meaning": "Number of days in the XP percent denominator: days the student was enrolled and school was in session.",
          "constraints": "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.",
          "relationship": "Same ratified denominator policy as alpha.analytics_school_day_minutes, reused for xp_goal_percent.",
          "invalidWhen": "Computed from active dates, attendance rows, weekdays, or a current-only enrollment shortcut.",
          "example": "90",
          "sourceClass": "Alpha extension policy reference value",
          "itds": [
            {
              "id": "aitd-007-xp-rollups",
              "title": "XP Totals, Goal, Remaining, And Completion Percent Are Ingested Report Facts",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-007-xp-rollups"
            },
            {
              "id": "aitd-006-school-day-minutes",
              "title": "Minutes Per Enrolled School Day Uses The Alpha School Calendar",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-006-school-day-minutes"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "xp_remaining",
          "type": "NUMERIC(14,3)",
          "nullability": "required when null_reason=none; nullable when xp_goal is null/source_missing",
          "meaning": "Report-ready remaining XP under policy_ref.",
          "constraints": "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.",
          "relationship": "Displayed as XP Remaining in the Learning Report.",
          "invalidWhen": "Negative, or recomputed by a dashboard after reading net_xp.",
          "example": "0.000",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-007-xp-rollups",
              "title": "XP Totals, Goal, Remaining, And Completion Percent Are Ingested Report Facts",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-007-xp-rollups"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "xp_goal_percent",
          "type": "NUMERIC(9,3)",
          "nullability": "nullable when daily_xp_goal or enrolled_school_day_count is null or zero",
          "meaning": "Uncapped percent of the XP goal reached in this window when the school-day denominator is available.",
          "constraints": "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.",
          "relationship": "Canonical Learning Report XP percent; xp_completion_percent, if present, is only a deprecated compatibility alias with the same value.",
          "invalidWhen": "Capped at 100, named as a captured percent, recomputed by a report, or divided by a locally computed goal.",
          "example": "131.111",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-007-xp-rollups",
              "title": "XP Totals, Goal, Remaining, And Completion Percent Are Ingested Report Facts",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-007-xp-rollups"
            },
            {
              "id": "aitd-006-school-day-minutes",
              "title": "Minutes Per Enrolled School Day Uses The Alpha School Calendar",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-006-school-day-minutes"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "xp_completion_percent",
          "type": "NUMERIC(9,3)",
          "nullability": "deprecated compatibility alias; nullability matches xp_goal_percent",
          "meaning": "Deprecated compatibility alias for xp_goal_percent.",
          "constraints": "Must equal xp_goal_percent exactly and remains uncapped. It has no independent capped-completion meaning. Nullability matches xp_goal_percent.",
          "relationship": "Kept only so older deployed consumers can migrate; new reports use xp_goal_percent.",
          "invalidWhen": "Different from xp_goal_percent, capped at 100, or treated as course completion percent.",
          "example": "131.111",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-007-xp-rollups",
              "title": "XP Totals, Goal, Remaining, And Completion Percent Are Ingested Report Facts",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-007-xp-rollups"
            },
            {
              "id": "aitd-006-school-day-minutes",
              "title": "Minutes Per Enrolled School Day Uses The Alpha School Calendar",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-006-school-day-minutes"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "on_track",
          "type": "BOOLEAN",
          "nullability": "nullable when xp_goal_percent is null",
          "meaning": "Whether the student is on track against the XP goal policy for this window.",
          "constraints": "Computed under policy_ref; null means the goal policy or denominator is missing.",
          "relationship": "Report flag for XP-goal intervention workflows.",
          "invalidWhen": "Client compares XP to a local threshold.",
          "example": "true",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-007-xp-rollups",
              "title": "XP Totals, Goal, Remaining, And Completion Percent Are Ingested Report Facts",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-007-xp-rollups"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "award_count",
          "type": "INTEGER",
          "nullability": "required",
          "meaning": "Number of positive or neutral XP ledger rows contributing to this rollup.",
          "constraints": "Nonnegative; excludes superseded rows unless audit query requests them.",
          "relationship": "Provenance summary for Results xp_ledger source rows.",
          "invalidWhen": "Used as a count of attempts or Events.",
          "example": "24",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-007-xp-rollups",
              "title": "XP Totals, Goal, Remaining, And Completion Percent Are Ingested Report Facts",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-007-xp-rollups"
            },
            {
              "id": "aitd-102-axis-read-shape",
              "title": "API Axis: Read Shape",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-102-axis-read-shape"
            }
          ]
        },
        {
          "name": "reversal_count",
          "type": "INTEGER",
          "nullability": "required",
          "meaning": "Number of reversal/correction XP ledger rows included.",
          "constraints": "Nonnegative.",
          "relationship": "Audit signal for signed corrections.",
          "invalidWhen": "Ignored when reconciling old source totals to current reports.",
          "example": "1",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-007-xp-rollups",
              "title": "XP Totals, Goal, Remaining, And Completion Percent Are Ingested Report Facts",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-007-xp-rollups"
            },
            {
              "id": "aitd-012-corrections-and-reversals",
              "title": "Corrections Are Signed Facts With Provenance",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-012-corrections-and-reversals"
            }
          ]
        },
        {
          "name": "source_ledger_refs",
          "type": "JSONB",
          "nullability": "required",
          "meaning": "Compact ids/cursor for contributing Results xp_ledger rows.",
          "constraints": "Stores refs/hashes only; never copies scores, content expected_xp, or event payloads.",
          "relationship": "Supports /xp-rollups/{id}/source-refs for authorized audits.",
          "invalidWhen": "Stores raw Results columns that belong to Results.",
          "example": "[\"xp_award_01HT7K\"]",
          "sourceClass": "Alpha extension reference list",
          "itds": [
            {
              "id": "aitd-000-extend-only-storage",
              "title": "Analytics Is New Extend-Only Alpha Storage",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-000-extend-only-storage"
            },
            {
              "id": "aitd-007-xp-rollups",
              "title": "XP Totals, Goal, Remaining, And Completion Percent Are Ingested Report Facts",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-007-xp-rollups"
            },
            {
              "id": "aitd-102-axis-read-shape",
              "title": "API Axis: Read Shape",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-102-axis-read-shape"
            }
          ]
        },
        {
          "name": "source_import_id",
          "type": "TEXT",
          "nullability": "required for report-tile rows; nullable for purely derived event-axis rows",
          "meaning": "Analytics source-import receipt that proves which named report-source adapter produced this report-grade fact.",
          "constraints": "Must reference alpha.analytics_source_import for non-null Learning Report tile values; no literal or fixture value may be reportable without this provenance.",
          "relationship": "Many report-fact rows can reference one source import; detail/sourceRefs endpoints join here for adapter, source_table, and source_row_key_hashes.",
          "invalidWhen": "Missing on a non-null report-tile value, or replaced by copied raw reporting-DB columns.",
          "example": "imp_01HT8XPTIME_2026_SPRING",
          "sourceClass": "Alpha extension provenance reference",
          "itds": [
            {
              "id": "aitd-001-report-source-ingestion",
              "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
            },
            {
              "id": "aitd-004-provenance-no-literals",
              "title": "Every Report Value Traces To An Ingested Source Row, Or Reads Null",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-004-provenance-no-literals"
            },
            {
              "id": "aitd-007-xp-rollups",
              "title": "XP Totals, Goal, Remaining, And Completion Percent Are Ingested Report Facts",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-007-xp-rollups"
            }
          ]
        },
        {
          "name": "quality_status",
          "type": "TEXT enum",
          "nullability": "required",
          "meaning": "Current materialization quality state for this fact.",
          "constraints": "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.",
          "relationship": "Used by raw/API convergence filters and source-ref audit views.",
          "invalidWhen": "Free-text status or hidden failures represented as HTTP 200 success.",
          "example": "ok",
          "enum": "quality_status",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            },
            {
              "id": "aitd-108-axis-error-envelope",
              "title": "API Axis: Error Envelope",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-108-axis-error-envelope"
            },
            {
              "id": "aitd-111-axis-privacy-retention",
              "title": "API Axis: Privacy And Retention",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-111-axis-privacy-retention"
            }
          ]
        },
        {
          "name": "null_reason",
          "type": "TEXT enum",
          "nullability": "required",
          "meaning": "Why XP goal fields are null or unavailable while xp_total itself may still be reportable.",
          "constraints": "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.",
          "relationship": "Uses the same materialized school-day denominator as alpha.analytics_school_day_minutes.",
          "invalidWhen": "XP goal fields are null with no typed reason, or a consumer computes them anyway.",
          "example": "none",
          "enum": "null_reason",
          "sourceClass": "Alpha extension enum",
          "itds": [
            {
              "id": "aitd-007-xp-rollups",
              "title": "XP Totals, Goal, Remaining, And Completion Percent Are Ingested Report Facts",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-007-xp-rollups"
            },
            {
              "id": "aitd-006-school-day-minutes",
              "title": "Minutes Per Enrolled School Day Uses The Alpha School Calendar",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-006-school-day-minutes"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "calculation_version",
          "type": "INTEGER",
          "nullability": "required",
          "meaning": "Materializer calculation version for this fact shape.",
          "constraints": "Positive integer; starts at 1 and increments when policy/materializer logic intentionally changes.",
          "relationship": "Part of deterministic source_fact_key/idempotency for materializer writes.",
          "invalidWhen": "Omitted from replay keys or changed without a new policy/materializer decision.",
          "example": "1",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            },
            {
              "id": "aitd-105-axis-idempotency",
              "title": "API Axis: Idempotency Model",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-105-axis-idempotency"
            },
            {
              "id": "aitd-104-axis-concurrency",
              "title": "API Axis: Concurrency Model",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-104-axis-concurrency"
            }
          ]
        },
        {
          "name": "computed_at",
          "type": "TIMESTAMPTZ",
          "nullability": "required",
          "meaning": "When Analytics wrote this derived fact.",
          "constraints": "UTC timestamp with timezone; updated only by Analytics materializers.",
          "relationship": "Used for audit and source-ref subcollections, not for school-day grouping.",
          "invalidWhen": "Used as a substitute for the source event time, result effective time, or window boundaries.",
          "example": "2026-06-10T00:51:14Z",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            }
          ]
        },
        {
          "name": "modified_at",
          "type": "TIMESTAMPTZ",
          "nullability": "required",
          "meaning": "Last time the Analytics row changed for polling and modifiedSince queries.",
          "constraints": "UTC timestamp; list endpoints support modifiedSince against this field.",
          "relationship": "Supports poll plus modifiedSince eventing.",
          "invalidWhen": "Client-supplied or used as the business effective date.",
          "example": "2026-06-10T00:51:14Z",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-107-axis-eventing",
              "title": "API Axis: Eventing Model",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-107-axis-eventing"
            },
            {
              "id": "aitd-103-axis-query-model",
              "title": "API Axis: Query Model",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-103-axis-query-model"
            }
          ]
        },
        {
          "name": "superseded_at",
          "type": "TIMESTAMPTZ",
          "nullability": "nullable",
          "meaning": "When this row stopped being the current reportable version because of source correction, deletion, or recalculation.",
          "constraints": "Null means current; non-null rows are excluded from ordinary list reads unless includeSuperseded=true and authorized.",
          "relationship": "Preserves audit history without mutating source Events or Results.",
          "invalidWhen": "Used to hard-delete old rows or omitted on a correction that replaces a prior fact.",
          "example": "null",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-111-axis-privacy-retention",
              "title": "API Axis: Privacy And Retention",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-111-axis-privacy-retention"
            },
            {
              "id": "aitd-012-corrections-and-reversals",
              "title": "Corrections Are Signed Facts With Provenance",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-012-corrections-and-reversals"
            }
          ]
        },
        {
          "name": "source_deleted_at",
          "type": "TIMESTAMPTZ",
          "nullability": "nullable",
          "meaning": "When the source Event/Result became deleted or invalidated.",
          "constraints": "Null for live source rows; set from source tombstone/correction notifications.",
          "relationship": "Ordinary reads exclude tombstoned facts unless includeSuperseded=true and authorized.",
          "invalidWhen": "Used as a physical delete or ignored by raw-path report queries.",
          "example": "null",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-111-axis-privacy-retention",
              "title": "API Axis: Privacy And Retention",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-111-axis-privacy-retention"
            }
          ]
        }
      ],
      "plainLanguage": "The XP Goal tile row: report-source XP total plus daily goal, stored school-day denominator, remaining XP, and uncapped XP goal percent."
    },
    {
      "name": "alpha.analytics_accuracy",
      "title": "Accuracy Rollup",
      "kind": "Alpha extension rollup table",
      "grain": "student_id x subject_id nullable x window_kind x window_start x window_end x policy_ref.",
      "primaryKey": "id; unique current grain is (tenant_id, student_id, subject_id, window_kind, window_start, window_end, policy_ref, calculation_version).",
      "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.",
      "purpose": "Report-ready Accuracy panel facts: correct questions, total questions, incorrect questions, and percent correct without client-side processed_facts math.",
      "metricChecks": [
        "Learning Report accuracy"
      ],
      "architecture": [
        {
          "id": "aitd-001-report-source-ingestion",
          "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
        },
        {
          "id": "aitd-004-provenance-no-literals",
          "title": "Every Report Value Traces To An Ingested Source Row, Or Reads Null",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-004-provenance-no-literals"
        },
        {
          "id": "aitd-011-policy-and-enum-normalization",
          "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
        },
        {
          "id": "aitd-003-close-time-materialization",
          "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
        },
        {
          "id": "aitd-012-corrections-and-reversals",
          "title": "Corrections Are Signed Facts With Provenance",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-012-corrections-and-reversals"
        }
      ],
      "api": "GET /alpha/analytics/v1/accuracy-rollups",
      "rawRule": "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.",
      "example": {
        "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
      },
      "fields": [
        {
          "name": "id",
          "type": "UUID",
          "nullability": "required",
          "meaning": "Analytics-owned stable row id for this derived fact.",
          "constraints": "Generated by the platform; globally unique within alpha.analytics_* objects.",
          "relationship": "Primary key for list/detail endpoints.",
          "invalidWhen": "Provided by a public import client or reused across tenants.",
          "example": "8e9c0ef2-bc75-4f53-8124-df77df49f25f",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-000-extend-only-storage",
              "title": "Analytics Is New Extend-Only Alpha Storage",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-000-extend-only-storage"
            }
          ]
        },
        {
          "name": "tenant_id",
          "type": "UUID",
          "nullability": "required",
          "meaning": "Tenant boundary for the derived fact.",
          "constraints": "Set from the JWT tenant claim or internal materializer context; never accepted from request body/query.",
          "relationship": "All raw-path queries must filter by tenant_id before joining, sorting, paging, or counting.",
          "invalidWhen": "Missing, caller-supplied in body/query, or mismatched with the JWT tenant claim.",
          "example": "7b0bb5d8-9a38-4a62-9fdc-9f8d2dc1a111",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-109-axis-tenant-routing",
              "title": "API Axis: Tenant Routing",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-109-axis-tenant-routing"
            },
            {
              "id": "aitd-106-axis-auth-shape",
              "title": "API Axis: Auth Shape",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-106-axis-auth-shape"
            }
          ]
        },
        {
          "name": "student_id",
          "type": "TEXT",
          "nullability": "required",
          "meaning": "Canonical Alpha student id the source Event or Result resolved to at materialization time.",
          "constraints": "Must resolve through People and Orgs as a real student for the source timestamp/effective date.",
          "relationship": "References People and Orgs student identity; see https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/data_dictionary.",
          "invalidWhen": "Parsed from email/name/source payload instead of resolved by the Events/Results adapter.",
          "example": "student_01HT7G3YZV7QB5N4YKQ1K0Z9A9",
          "sourceClass": "Alpha extension reference",
          "itds": [
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            },
            {
              "id": "aitd-106-axis-auth-shape",
              "title": "API Axis: Auth Shape",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-106-axis-auth-shape"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "subject_id",
          "type": "TEXT",
          "nullability": "nullable where the row is all-subject or the source cannot validly resolve a subject",
          "meaning": "Canonical Alpha subject used for reporting and grouping.",
          "constraints": "Closed Alpha subject enum after write-time source-label normalization; unknown source subject becomes an adapter finding or null_reason, not a new string.",
          "relationship": "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.",
          "invalidWhen": "Copied from source strings such as FastMath, Vocabulary, Science-notqced, or ISEE variants without normalization.",
          "example": "math",
          "sourceClass": "Alpha extension reference",
          "itds": [
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "policy_ref",
          "type": "TEXT",
          "nullability": "required",
          "meaning": "Named policy/config version used to compute the measure or rollup.",
          "constraints": "Must point at alpha.policy.analytics.* or an inherited Curriculum/Results policy active for the source effective date.",
          "relationship": "Many Analytics facts can share one policy row; changing policy creates new calculation versions or corrections.",
          "invalidWhen": "A consumer hard-codes thresholds, school-day calendars, Growth X formulas, or completion denominators instead of using the policy ref.",
          "example": "alpha.policy.analytics.accuracy.v2026-06-12",
          "sourceClass": "Alpha extension reference",
          "itds": [
            {
              "id": "aitd-001-report-source-ingestion",
              "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "window_kind",
          "type": "TEXT enum",
          "nullability": "required",
          "meaning": "Named window family for the Accuracy rollup.",
          "constraints": "Allowed values: window_kind enum.",
          "relationship": "Part of Accuracy rollup grain and list filters.",
          "invalidWhen": "Parsed from report title or term label.",
          "example": "term",
          "enum": "window_kind",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-103-axis-query-model",
              "title": "API Axis: Query Model",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-103-axis-query-model"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "window_start",
          "type": "DATE",
          "nullability": "required",
          "meaning": "Inclusive start date for source question rows included in this rollup.",
          "constraints": "ISO date; half-open with window_end.",
          "relationship": "Defines the reporting period for the Accuracy panel.",
          "invalidWhen": "Uses computed_at instead of the source/report effective date.",
          "example": "2026-01-01",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-005-time-facts-and-windows",
              "title": "Active, Inactive, And Waste Seconds Are Typed Derived Time Facts",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-005-time-facts-and-windows"
            },
            {
              "id": "aitd-001-report-source-ingestion",
              "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
            }
          ]
        },
        {
          "name": "window_end",
          "type": "DATE",
          "nullability": "required",
          "meaning": "Exclusive end date for source question rows included in this rollup.",
          "constraints": "ISO date; must be after window_start.",
          "relationship": "Defines the reporting period for the Accuracy panel.",
          "invalidWhen": "Treated as inclusive in raw queries.",
          "example": "2026-06-01",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-005-time-facts-and-windows",
              "title": "Active, Inactive, And Waste Seconds Are Typed Derived Time Facts",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-005-time-facts-and-windows"
            },
            {
              "id": "aitd-001-report-source-ingestion",
              "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
            }
          ]
        },
        {
          "name": "correct_question_count",
          "type": "INTEGER",
          "nullability": "required",
          "meaning": "Reportable correct-question numerator after the adapter applies subject, app/source, score_type, correction, and real-student rules.",
          "constraints": "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.",
          "relationship": "Numerator for accuracy_percent.",
          "invalidWhen": "Summed by a consumer from reporting.processed_facts or copied as raw source rows without source_import_id provenance.",
          "example": "480",
          "sourceClass": "Alpha extension derived rollup value",
          "itds": [
            {
              "id": "aitd-001-report-source-ingestion",
              "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
            },
            {
              "id": "aitd-004-provenance-no-literals",
              "title": "Every Report Value Traces To An Ingested Source Row, Or Reads Null",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-004-provenance-no-literals"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "total_question_count",
          "type": "INTEGER",
          "nullability": "required",
          "meaning": "Reportable question-attempt denominator after the adapter applies the same policy filters as correct_question_count.",
          "constraints": "Nonnegative integer. Zero is allowed only with null_reason=no_questions and null accuracy_percent.",
          "relationship": "Denominator for accuracy_percent.",
          "invalidWhen": "Computed by counting Events, QTI attempts, or processed_facts rows in a report.",
          "example": "600",
          "sourceClass": "Alpha extension derived rollup value",
          "itds": [
            {
              "id": "aitd-001-report-source-ingestion",
              "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
            },
            {
              "id": "aitd-004-provenance-no-literals",
              "title": "Every Report Value Traces To An Ingested Source Row, Or Reads Null",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-004-provenance-no-literals"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "incorrect_question_count",
          "type": "INTEGER",
          "nullability": "required",
          "meaning": "Reportable incorrect-question count retained for explanations.",
          "constraints": "Nonnegative integer; equals total_question_count - correct_question_count under the policy version.",
          "relationship": "Audit/explanation value for parent-facing Accuracy cards.",
          "invalidWhen": "Calculated differently by the client or allowed to go negative.",
          "example": "120",
          "sourceClass": "Alpha extension derived rollup value",
          "itds": [
            {
              "id": "aitd-001-report-source-ingestion",
              "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "accuracy_percent",
          "type": "NUMERIC(9,3)",
          "nullability": "nullable when total_question_count is zero or source/policy is missing",
          "meaning": "Report-ready percent of reportable questions answered correctly.",
          "constraints": "0 through 100 when populated; null requires a typed null_reason. Formula and rounding are owned by Analytics under policy_ref.",
          "relationship": "The Learning Report Accuracy panel reads this value directly.",
          "invalidWhen": "A dashboard divides correct_question_count by total_question_count itself, rounds differently, or substitutes 0/100 when there are no questions.",
          "example": "80.000",
          "sourceClass": "Alpha extension derived measure",
          "itds": [
            {
              "id": "aitd-001-report-source-ingestion",
              "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "source_import_id",
          "type": "TEXT",
          "nullability": "required for report-tile rows; nullable for purely derived event-axis rows",
          "meaning": "Analytics source-import receipt that proves which named report-source adapter produced this report-grade fact.",
          "constraints": "Must reference alpha.analytics_source_import for non-null Learning Report tile values; no literal or fixture value may be reportable without this provenance.",
          "relationship": "Many report-fact rows can reference one source import; detail/sourceRefs endpoints join here for adapter, source_table, and source_row_key_hashes.",
          "invalidWhen": "Missing on a non-null report-tile value, or replaced by copied raw reporting-DB columns.",
          "example": "imp_01HT8XPTIME_2026_SPRING",
          "sourceClass": "Alpha extension provenance reference",
          "itds": [
            {
              "id": "aitd-001-report-source-ingestion",
              "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
            },
            {
              "id": "aitd-004-provenance-no-literals",
              "title": "Every Report Value Traces To An Ingested Source Row, Or Reads Null",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-004-provenance-no-literals"
            }
          ]
        },
        {
          "name": "source_fact_refs",
          "type": "JSONB",
          "nullability": "required",
          "meaning": "Compact ids/hashes/cursor for source-shaped processed_facts rows accepted by the adapter.",
          "constraints": "Stores refs/hashes only; never copies raw processed_facts rows or student identifiers.",
          "relationship": "Supports /accuracy-rollups/{id}/source-refs for authorized audits.",
          "invalidWhen": "Contains raw source table columns or enough payload to become a copied reporting table.",
          "example": "[\"processed_facts_hash_01HT7Q\"]",
          "sourceClass": "Alpha extension reference list",
          "itds": [
            {
              "id": "aitd-000-extend-only-storage",
              "title": "Analytics Is New Extend-Only Alpha Storage",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-000-extend-only-storage"
            },
            {
              "id": "aitd-001-report-source-ingestion",
              "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
            },
            {
              "id": "aitd-102-axis-read-shape",
              "title": "API Axis: Read Shape",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-102-axis-read-shape"
            }
          ]
        },
        {
          "name": "quality_status",
          "type": "TEXT enum",
          "nullability": "required",
          "meaning": "Current materialization quality state for this fact.",
          "constraints": "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.",
          "relationship": "Used by raw/API convergence filters and source-ref audit views.",
          "invalidWhen": "Free-text status or hidden failures represented as HTTP 200 success.",
          "example": "ok",
          "enum": "quality_status",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            },
            {
              "id": "aitd-108-axis-error-envelope",
              "title": "API Axis: Error Envelope",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-108-axis-error-envelope"
            },
            {
              "id": "aitd-111-axis-privacy-retention",
              "title": "API Axis: Privacy And Retention",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-111-axis-privacy-retention"
            }
          ]
        },
        {
          "name": "null_reason",
          "type": "TEXT enum",
          "nullability": "required",
          "meaning": "Why accuracy_percent is null or not reportable.",
          "constraints": "Allowed values: null_reason enum. no_questions means the source window had zero reportable question attempts; none means the metric is populated.",
          "relationship": "Prevents clients from turning no attempts into 0% or 100%.",
          "invalidWhen": "Null accuracy_percent with no typed reason, or a free-text explanation.",
          "example": "none",
          "enum": "null_reason",
          "sourceClass": "Alpha extension enum",
          "itds": [
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            },
            {
              "id": "aitd-108-axis-error-envelope",
              "title": "API Axis: Error Envelope",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-108-axis-error-envelope"
            }
          ]
        },
        {
          "name": "calculation_version",
          "type": "INTEGER",
          "nullability": "required",
          "meaning": "Materializer calculation version for this fact shape.",
          "constraints": "Positive integer; starts at 1 and increments when policy/materializer logic intentionally changes.",
          "relationship": "Part of deterministic source_fact_key/idempotency for materializer writes.",
          "invalidWhen": "Omitted from replay keys or changed without a new policy/materializer decision.",
          "example": "1",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            },
            {
              "id": "aitd-105-axis-idempotency",
              "title": "API Axis: Idempotency Model",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-105-axis-idempotency"
            },
            {
              "id": "aitd-104-axis-concurrency",
              "title": "API Axis: Concurrency Model",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-104-axis-concurrency"
            }
          ]
        },
        {
          "name": "computed_at",
          "type": "TIMESTAMPTZ",
          "nullability": "required",
          "meaning": "When Analytics wrote this derived fact.",
          "constraints": "UTC timestamp with timezone; updated only by Analytics materializers.",
          "relationship": "Used for audit and source-ref subcollections, not for school-day grouping.",
          "invalidWhen": "Used as a substitute for the source event time, result effective time, or window boundaries.",
          "example": "2026-06-10T00:51:14Z",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            }
          ]
        },
        {
          "name": "modified_at",
          "type": "TIMESTAMPTZ",
          "nullability": "required",
          "meaning": "Last time the Analytics row changed for polling and modifiedSince queries.",
          "constraints": "UTC timestamp; list endpoints support modifiedSince against this field.",
          "relationship": "Supports poll plus modifiedSince eventing.",
          "invalidWhen": "Client-supplied or used as the business effective date.",
          "example": "2026-06-10T00:51:14Z",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-107-axis-eventing",
              "title": "API Axis: Eventing Model",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-107-axis-eventing"
            },
            {
              "id": "aitd-103-axis-query-model",
              "title": "API Axis: Query Model",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-103-axis-query-model"
            }
          ]
        },
        {
          "name": "superseded_at",
          "type": "TIMESTAMPTZ",
          "nullability": "nullable",
          "meaning": "When this row stopped being the current reportable version because of source correction, deletion, or recalculation.",
          "constraints": "Null means current; non-null rows are excluded from ordinary list reads unless includeSuperseded=true and authorized.",
          "relationship": "Preserves audit history without mutating source Events or Results.",
          "invalidWhen": "Used to hard-delete old rows or omitted on a correction that replaces a prior fact.",
          "example": "null",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-111-axis-privacy-retention",
              "title": "API Axis: Privacy And Retention",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-111-axis-privacy-retention"
            },
            {
              "id": "aitd-012-corrections-and-reversals",
              "title": "Corrections Are Signed Facts With Provenance",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-012-corrections-and-reversals"
            }
          ]
        },
        {
          "name": "source_deleted_at",
          "type": "TIMESTAMPTZ",
          "nullability": "nullable",
          "meaning": "When the source Event/Result became deleted or invalidated.",
          "constraints": "Null for live source rows; set from source tombstone/correction notifications.",
          "relationship": "Ordinary reads exclude tombstoned facts unless includeSuperseded=true and authorized.",
          "invalidWhen": "Used as a physical delete or ignored by raw-path report queries.",
          "example": "null",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-111-axis-privacy-retention",
              "title": "API Axis: Privacy And Retention",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-111-axis-privacy-retention"
            }
          ]
        }
      ],
      "plainLanguage": "The Learning Report Accuracy tile row: correct questions, total questions, incorrect questions, and percent correct with source-import provenance."
    },
    {
      "name": "alpha.analytics_attempt_rollup",
      "title": "Attempt Count Rollup",
      "kind": "Alpha extension rollup table",
      "grain": "student_id x subject_id nullable x window_kind x window_start x window_end x policy_ref.",
      "primaryKey": "id; unique current grain is (tenant_id, student_id, subject_id, window_kind, window_start, window_end, policy_ref, calculation_version).",
      "lifecycle": "Rows are materialized when governed Events question_answered player extensions close or when source-shaped imports provide equivalent evidence. Reads serve stored rows and do not parse Events extensions at request time.",
      "purpose": "Report-ready attempt-count facts from governed player question_answered events and source-shaped imports.",
      "metricChecks": [
        "Learning Report attempt count",
        "AP scheduling attempt signal"
      ],
      "architecture": [
        {
          "id": "aitd-001-report-source-ingestion",
          "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
        },
        {
          "id": "aitd-003-close-time-materialization",
          "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
        },
        {
          "id": "aitd-011-policy-and-enum-normalization",
          "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
        }
      ],
      "api": "GET /alpha/analytics/v1/attempt-rollups",
      "rawRule": "Read alpha.analytics_attempt_rollup current ok/corrected rows for report answers. Do not parse player extensions or source payloads in an app.",
      "formula": "Events-backed attempt_count sums the maximum governed attempt_count per question interaction in the window, falling back to attempt_ordinal when attempt_count is absent; source-shaped imports may provide already-aggregated attempt_count rows. max_attempt_ordinal is the maximum governed attempt_ordinal in the window.",
      "example": {
        "attempt_count": 620,
        "max_attempt_ordinal": 3,
        "policy_ref": "alpha.policy.analytics.attempt_count.v2026-07-08"
      },
      "fields": [
        {
          "name": "id",
          "type": "TEXT",
          "nullability": "required",
          "meaning": "Analytics-owned stable row id for this derived rollup.",
          "constraints": "Set by Analytics materialization; not caller-supplied by public clients.",
          "relationship": "Part of the public Analytics rollup contract.",
          "invalidWhen": "Computed in app code or copied from an ungoverned source field.",
          "example": "attempt_rollup_event_4f8a9c4d2a1b0e9f8d7c6b5a",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-001-report-source-ingestion",
              "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
            },
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "tenant_id",
          "type": "TEXT",
          "nullability": "required",
          "meaning": "Tenant boundary for the derived rollup.",
          "constraints": "Set by Analytics materialization; not caller-supplied by public clients.",
          "relationship": "Part of the public Analytics rollup contract.",
          "invalidWhen": "Computed in app code or copied from an ungoverned source field.",
          "example": "demo",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-001-report-source-ingestion",
              "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
            },
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "student_id",
          "type": "TEXT",
          "nullability": "required",
          "meaning": "Canonical Alpha student id resolved at materialization time.",
          "constraints": "Set by Analytics materialization; not caller-supplied by public clients.",
          "relationship": "Part of the public Analytics rollup contract.",
          "invalidWhen": "Computed in app code or copied from an ungoverned source field.",
          "example": "student_01HT7G3YZV7QB5N4YKQ1K0Z9A9",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-001-report-source-ingestion",
              "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
            },
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "subject_id",
          "type": "TEXT",
          "nullability": "nullable",
          "meaning": "Canonical Alpha subject when the source can resolve one; null for all-subject event rollups.",
          "constraints": "Set by Analytics materialization; not caller-supplied by public clients.",
          "relationship": "Part of the public Analytics rollup contract.",
          "invalidWhen": "Computed in app code or copied from an ungoverned source field.",
          "example": "math",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-001-report-source-ingestion",
              "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
            },
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "policy_ref",
          "type": "TEXT",
          "nullability": "required",
          "meaning": "Named Analytics policy version used to compute the rollup.",
          "constraints": "Set by Analytics materialization; not caller-supplied by public clients.",
          "relationship": "Part of the public Analytics rollup contract.",
          "invalidWhen": "Computed in app code or copied from an ungoverned source field.",
          "example": "alpha.policy.analytics.attempt_count.v2026-07-08",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-001-report-source-ingestion",
              "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
            },
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "window_kind",
          "type": "TEXT enum",
          "nullability": "required",
          "meaning": "Named reporting window family.",
          "constraints": "Set by Analytics materialization; not caller-supplied by public clients.",
          "relationship": "Part of the public Analytics rollup contract.",
          "invalidWhen": "Computed in app code or copied from an ungoverned source field.",
          "example": "term",
          "sourceClass": "Alpha extension",
          "enum": "window_kind",
          "itds": [
            {
              "id": "aitd-001-report-source-ingestion",
              "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
            },
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "window_start",
          "type": "DATE",
          "nullability": "required",
          "meaning": "Inclusive start date for source question events or source rows included in this rollup.",
          "constraints": "Set by Analytics materialization; not caller-supplied by public clients.",
          "relationship": "Part of the public Analytics rollup contract.",
          "invalidWhen": "Computed in app code or copied from an ungoverned source field.",
          "example": "2026-01-01",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-001-report-source-ingestion",
              "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
            },
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "window_end",
          "type": "DATE",
          "nullability": "required",
          "meaning": "Exclusive end date for source question events or source rows included in this rollup.",
          "constraints": "Set by Analytics materialization; not caller-supplied by public clients.",
          "relationship": "Part of the public Analytics rollup contract.",
          "invalidWhen": "Computed in app code or copied from an ungoverned source field.",
          "example": "2026-06-01",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-001-report-source-ingestion",
              "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
            },
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "attempt_count",
          "type": "INTEGER",
          "nullability": "required",
          "meaning": "Total governed attempts in the window.",
          "constraints": "Set by Analytics materialization; not caller-supplied by public clients.",
          "relationship": "Part of the public Analytics rollup contract.",
          "invalidWhen": "Computed in app code or copied from an ungoverned source field.",
          "example": 620,
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-001-report-source-ingestion",
              "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
            },
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "max_attempt_ordinal",
          "type": "INTEGER",
          "nullability": "nullable",
          "meaning": "Largest attempt ordinal observed in the window.",
          "constraints": "Set by Analytics materialization; not caller-supplied by public clients.",
          "relationship": "Part of the public Analytics rollup contract.",
          "invalidWhen": "Computed in app code or copied from an ungoverned source field.",
          "example": 3,
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-001-report-source-ingestion",
              "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
            },
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "source_import_id",
          "type": "TEXT",
          "nullability": "nullable",
          "meaning": "Source import id when the rollup came from source-shaped report ingestion.",
          "constraints": "Set by Analytics materialization; not caller-supplied by public clients.",
          "relationship": "Part of the public Analytics rollup contract.",
          "invalidWhen": "Computed in app code or copied from an ungoverned source field.",
          "example": "import_123",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-001-report-source-ingestion",
              "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
            },
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "source_event_refs",
          "type": "JSONB array",
          "nullability": "required",
          "meaning": "Events/source row refs included in the rollup.",
          "constraints": "Set by Analytics materialization; not caller-supplied by public clients.",
          "relationship": "Part of the public Analytics rollup contract.",
          "invalidWhen": "Computed in app code or copied from an ungoverned source field.",
          "example": [
            "events:demo:event_row_123"
          ],
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-001-report-source-ingestion",
              "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
            },
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "quality_status",
          "type": "TEXT enum",
          "nullability": "required",
          "meaning": "Quality status for the current rollup row.",
          "constraints": "Set by Analytics materialization; not caller-supplied by public clients.",
          "relationship": "Part of the public Analytics rollup contract.",
          "invalidWhen": "Computed in app code or copied from an ungoverned source field.",
          "example": "ok",
          "sourceClass": "Alpha extension",
          "enum": "quality_status",
          "itds": [
            {
              "id": "aitd-001-report-source-ingestion",
              "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
            },
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "null_reason",
          "type": "TEXT enum",
          "nullability": "required",
          "meaning": "Typed reason when the rollup has no reportable value.",
          "constraints": "Set by Analytics materialization; not caller-supplied by public clients.",
          "relationship": "Part of the public Analytics rollup contract.",
          "invalidWhen": "Computed in app code or copied from an ungoverned source field.",
          "example": "none",
          "sourceClass": "Alpha extension",
          "enum": "null_reason",
          "itds": [
            {
              "id": "aitd-001-report-source-ingestion",
              "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
            },
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "calculation_version",
          "type": "INTEGER",
          "nullability": "required",
          "meaning": "Materializer version for reproducibility.",
          "constraints": "Set by Analytics materialization; not caller-supplied by public clients.",
          "relationship": "Part of the public Analytics rollup contract.",
          "invalidWhen": "Computed in app code or copied from an ungoverned source field.",
          "example": 1,
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-001-report-source-ingestion",
              "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
            },
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "computed_at",
          "type": "TIMESTAMPTZ",
          "nullability": "required",
          "meaning": "Timestamp when Analytics computed this row.",
          "constraints": "Set by Analytics materialization; not caller-supplied by public clients.",
          "relationship": "Part of the public Analytics rollup contract.",
          "invalidWhen": "Computed in app code or copied from an ungoverned source field.",
          "example": "2026-07-08T00:00:00.000Z",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-001-report-source-ingestion",
              "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
            },
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "modified_at",
          "type": "TIMESTAMPTZ",
          "nullability": "required",
          "meaning": "Timestamp when this row was last written.",
          "constraints": "Set by Analytics materialization; not caller-supplied by public clients.",
          "relationship": "Part of the public Analytics rollup contract.",
          "invalidWhen": "Computed in app code or copied from an ungoverned source field.",
          "example": "2026-07-08T00:00:00.000Z",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-001-report-source-ingestion",
              "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
            },
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "superseded_at",
          "type": "TIMESTAMPTZ",
          "nullability": "nullable",
          "meaning": "Timestamp when a later current row superseded this row.",
          "constraints": "Set by Analytics materialization; not caller-supplied by public clients.",
          "relationship": "Part of the public Analytics rollup contract.",
          "invalidWhen": "Computed in app code or copied from an ungoverned source field.",
          "example": null,
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-001-report-source-ingestion",
              "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
            },
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "source_deleted_at",
          "type": "TIMESTAMPTZ",
          "nullability": "nullable",
          "meaning": "Timestamp when source deletion tombstoned this row.",
          "constraints": "Set by Analytics materialization; not caller-supplied by public clients.",
          "relationship": "Part of the public Analytics rollup contract.",
          "invalidWhen": "Computed in app code or copied from an ungoverned source field.",
          "example": null,
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-001-report-source-ingestion",
              "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
            },
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        }
      ],
      "plainLanguage": "Report-ready attempt-count facts from governed player question_answered events and source-shaped imports."
    },
    {
      "name": "alpha.analytics_response_latency_rollup",
      "title": "Response Latency Rollup",
      "kind": "Alpha extension rollup table",
      "grain": "student_id x subject_id nullable x window_kind x window_start x window_end x policy_ref.",
      "primaryKey": "id; unique current grain is (tenant_id, student_id, subject_id, window_kind, window_start, window_end, policy_ref, calculation_version).",
      "lifecycle": "Rows are materialized when governed Events question_answered player extensions close or when source-shaped imports provide equivalent evidence. Reads serve stored rows and do not parse Events extensions at request time.",
      "purpose": "Report-ready response latency facts in milliseconds from governed player response_time_ms evidence.",
      "metricChecks": [
        "Learning Report response latency",
        "AP scheduling fast/slow response signal"
      ],
      "architecture": [
        {
          "id": "aitd-001-report-source-ingestion",
          "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
        },
        {
          "id": "aitd-003-close-time-materialization",
          "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
        },
        {
          "id": "aitd-011-policy-and-enum-normalization",
          "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
        }
      ],
      "api": "GET /alpha/analytics/v1/response-latency-rollups",
      "rawRule": "Read alpha.analytics_response_latency_rollup current ok/corrected rows for report answers. Do not parse player extensions or source payloads in an app.",
      "formula": "response_time_ms_total is the sum of governed response_time_ms values; response_time_ms_avg is total divided by response_count; min and max preserve the observed bounds.",
      "example": {
        "response_count": 620,
        "response_time_ms_total": 1550000,
        "response_time_ms_avg": 2500,
        "response_time_ms_min": 400,
        "response_time_ms_max": 18000,
        "policy_ref": "alpha.policy.analytics.response_latency.v2026-07-08"
      },
      "fields": [
        {
          "name": "id",
          "type": "TEXT",
          "nullability": "required",
          "meaning": "Analytics-owned stable row id for this derived rollup.",
          "constraints": "Set by Analytics materialization; not caller-supplied by public clients.",
          "relationship": "Part of the public Analytics rollup contract.",
          "invalidWhen": "Computed in app code or copied from an ungoverned source field.",
          "example": "attempt_rollup_event_4f8a9c4d2a1b0e9f8d7c6b5a",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-001-report-source-ingestion",
              "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
            },
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "tenant_id",
          "type": "TEXT",
          "nullability": "required",
          "meaning": "Tenant boundary for the derived rollup.",
          "constraints": "Set by Analytics materialization; not caller-supplied by public clients.",
          "relationship": "Part of the public Analytics rollup contract.",
          "invalidWhen": "Computed in app code or copied from an ungoverned source field.",
          "example": "demo",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-001-report-source-ingestion",
              "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
            },
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "student_id",
          "type": "TEXT",
          "nullability": "required",
          "meaning": "Canonical Alpha student id resolved at materialization time.",
          "constraints": "Set by Analytics materialization; not caller-supplied by public clients.",
          "relationship": "Part of the public Analytics rollup contract.",
          "invalidWhen": "Computed in app code or copied from an ungoverned source field.",
          "example": "student_01HT7G3YZV7QB5N4YKQ1K0Z9A9",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-001-report-source-ingestion",
              "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
            },
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "subject_id",
          "type": "TEXT",
          "nullability": "nullable",
          "meaning": "Canonical Alpha subject when the source can resolve one; null for all-subject event rollups.",
          "constraints": "Set by Analytics materialization; not caller-supplied by public clients.",
          "relationship": "Part of the public Analytics rollup contract.",
          "invalidWhen": "Computed in app code or copied from an ungoverned source field.",
          "example": "math",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-001-report-source-ingestion",
              "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
            },
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "policy_ref",
          "type": "TEXT",
          "nullability": "required",
          "meaning": "Named Analytics policy version used to compute the rollup.",
          "constraints": "Set by Analytics materialization; not caller-supplied by public clients.",
          "relationship": "Part of the public Analytics rollup contract.",
          "invalidWhen": "Computed in app code or copied from an ungoverned source field.",
          "example": "alpha.policy.analytics.response_latency.v2026-07-08",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-001-report-source-ingestion",
              "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
            },
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "window_kind",
          "type": "TEXT enum",
          "nullability": "required",
          "meaning": "Named reporting window family.",
          "constraints": "Set by Analytics materialization; not caller-supplied by public clients.",
          "relationship": "Part of the public Analytics rollup contract.",
          "invalidWhen": "Computed in app code or copied from an ungoverned source field.",
          "example": "term",
          "sourceClass": "Alpha extension",
          "enum": "window_kind",
          "itds": [
            {
              "id": "aitd-001-report-source-ingestion",
              "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
            },
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "window_start",
          "type": "DATE",
          "nullability": "required",
          "meaning": "Inclusive start date for source question events or source rows included in this rollup.",
          "constraints": "Set by Analytics materialization; not caller-supplied by public clients.",
          "relationship": "Part of the public Analytics rollup contract.",
          "invalidWhen": "Computed in app code or copied from an ungoverned source field.",
          "example": "2026-01-01",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-001-report-source-ingestion",
              "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
            },
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "window_end",
          "type": "DATE",
          "nullability": "required",
          "meaning": "Exclusive end date for source question events or source rows included in this rollup.",
          "constraints": "Set by Analytics materialization; not caller-supplied by public clients.",
          "relationship": "Part of the public Analytics rollup contract.",
          "invalidWhen": "Computed in app code or copied from an ungoverned source field.",
          "example": "2026-06-01",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-001-report-source-ingestion",
              "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
            },
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "response_count",
          "type": "INTEGER",
          "nullability": "required",
          "meaning": "Number of responses with governed latency evidence.",
          "constraints": "Set by Analytics materialization; not caller-supplied by public clients.",
          "relationship": "Part of the public Analytics rollup contract.",
          "invalidWhen": "Computed in app code or copied from an ungoverned source field.",
          "example": 620,
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-001-report-source-ingestion",
              "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
            },
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "response_time_ms_total",
          "type": "NUMERIC",
          "nullability": "required",
          "meaning": "Total response latency in milliseconds.",
          "constraints": "Set by Analytics materialization; not caller-supplied by public clients.",
          "relationship": "Part of the public Analytics rollup contract.",
          "invalidWhen": "Computed in app code or copied from an ungoverned source field.",
          "example": 1550000,
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-001-report-source-ingestion",
              "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
            },
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "response_time_ms_avg",
          "type": "NUMERIC",
          "nullability": "nullable",
          "meaning": "Average response latency in milliseconds.",
          "constraints": "Set by Analytics materialization; not caller-supplied by public clients.",
          "relationship": "Part of the public Analytics rollup contract.",
          "invalidWhen": "Computed in app code or copied from an ungoverned source field.",
          "example": 2500,
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-001-report-source-ingestion",
              "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
            },
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "response_time_ms_min",
          "type": "INTEGER",
          "nullability": "nullable",
          "meaning": "Minimum response latency in milliseconds.",
          "constraints": "Set by Analytics materialization; not caller-supplied by public clients.",
          "relationship": "Part of the public Analytics rollup contract.",
          "invalidWhen": "Computed in app code or copied from an ungoverned source field.",
          "example": 400,
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-001-report-source-ingestion",
              "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
            },
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "response_time_ms_max",
          "type": "INTEGER",
          "nullability": "nullable",
          "meaning": "Maximum response latency in milliseconds.",
          "constraints": "Set by Analytics materialization; not caller-supplied by public clients.",
          "relationship": "Part of the public Analytics rollup contract.",
          "invalidWhen": "Computed in app code or copied from an ungoverned source field.",
          "example": 18000,
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-001-report-source-ingestion",
              "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
            },
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "source_import_id",
          "type": "TEXT",
          "nullability": "nullable",
          "meaning": "Source import id when the rollup came from source-shaped report ingestion.",
          "constraints": "Set by Analytics materialization; not caller-supplied by public clients.",
          "relationship": "Part of the public Analytics rollup contract.",
          "invalidWhen": "Computed in app code or copied from an ungoverned source field.",
          "example": "import_123",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-001-report-source-ingestion",
              "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
            },
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "source_event_refs",
          "type": "JSONB array",
          "nullability": "required",
          "meaning": "Events/source row refs included in the rollup.",
          "constraints": "Set by Analytics materialization; not caller-supplied by public clients.",
          "relationship": "Part of the public Analytics rollup contract.",
          "invalidWhen": "Computed in app code or copied from an ungoverned source field.",
          "example": [
            "events:demo:event_row_123"
          ],
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-001-report-source-ingestion",
              "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
            },
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "quality_status",
          "type": "TEXT enum",
          "nullability": "required",
          "meaning": "Quality status for the current rollup row.",
          "constraints": "Set by Analytics materialization; not caller-supplied by public clients.",
          "relationship": "Part of the public Analytics rollup contract.",
          "invalidWhen": "Computed in app code or copied from an ungoverned source field.",
          "example": "ok",
          "sourceClass": "Alpha extension",
          "enum": "quality_status",
          "itds": [
            {
              "id": "aitd-001-report-source-ingestion",
              "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
            },
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "null_reason",
          "type": "TEXT enum",
          "nullability": "required",
          "meaning": "Typed reason when the rollup has no reportable value.",
          "constraints": "Set by Analytics materialization; not caller-supplied by public clients.",
          "relationship": "Part of the public Analytics rollup contract.",
          "invalidWhen": "Computed in app code or copied from an ungoverned source field.",
          "example": "none",
          "sourceClass": "Alpha extension",
          "enum": "null_reason",
          "itds": [
            {
              "id": "aitd-001-report-source-ingestion",
              "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
            },
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "calculation_version",
          "type": "INTEGER",
          "nullability": "required",
          "meaning": "Materializer version for reproducibility.",
          "constraints": "Set by Analytics materialization; not caller-supplied by public clients.",
          "relationship": "Part of the public Analytics rollup contract.",
          "invalidWhen": "Computed in app code or copied from an ungoverned source field.",
          "example": 1,
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-001-report-source-ingestion",
              "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
            },
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "computed_at",
          "type": "TIMESTAMPTZ",
          "nullability": "required",
          "meaning": "Timestamp when Analytics computed this row.",
          "constraints": "Set by Analytics materialization; not caller-supplied by public clients.",
          "relationship": "Part of the public Analytics rollup contract.",
          "invalidWhen": "Computed in app code or copied from an ungoverned source field.",
          "example": "2026-07-08T00:00:00.000Z",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-001-report-source-ingestion",
              "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
            },
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "modified_at",
          "type": "TIMESTAMPTZ",
          "nullability": "required",
          "meaning": "Timestamp when this row was last written.",
          "constraints": "Set by Analytics materialization; not caller-supplied by public clients.",
          "relationship": "Part of the public Analytics rollup contract.",
          "invalidWhen": "Computed in app code or copied from an ungoverned source field.",
          "example": "2026-07-08T00:00:00.000Z",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-001-report-source-ingestion",
              "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
            },
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "superseded_at",
          "type": "TIMESTAMPTZ",
          "nullability": "nullable",
          "meaning": "Timestamp when a later current row superseded this row.",
          "constraints": "Set by Analytics materialization; not caller-supplied by public clients.",
          "relationship": "Part of the public Analytics rollup contract.",
          "invalidWhen": "Computed in app code or copied from an ungoverned source field.",
          "example": null,
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-001-report-source-ingestion",
              "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
            },
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "source_deleted_at",
          "type": "TIMESTAMPTZ",
          "nullability": "nullable",
          "meaning": "Timestamp when source deletion tombstoned this row.",
          "constraints": "Set by Analytics materialization; not caller-supplied by public clients.",
          "relationship": "Part of the public Analytics rollup contract.",
          "invalidWhen": "Computed in app code or copied from an ungoverned source field.",
          "example": null,
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-001-report-source-ingestion",
              "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
            },
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        }
      ],
      "plainLanguage": "Report-ready response latency facts in milliseconds from governed player response_time_ms evidence."
    },
    {
      "name": "alpha.analytics_hint_usage_rollup",
      "title": "Hint Usage Rollup",
      "kind": "Alpha extension rollup table",
      "grain": "student_id x subject_id nullable x window_kind x window_start x window_end x policy_ref.",
      "primaryKey": "id; unique current grain is (tenant_id, student_id, subject_id, window_kind, window_start, window_end, policy_ref, calculation_version).",
      "lifecycle": "Rows are materialized when governed Events question_answered player extensions close or when source-shaped imports provide equivalent evidence. Reads serve stored rows and do not parse Events extensions at request time.",
      "purpose": "Report-ready hint usage facts from governed player hint_usage evidence.",
      "metricChecks": [
        "Learning Report hint usage",
        "AP scheduling help-seeking signal"
      ],
      "architecture": [
        {
          "id": "aitd-001-report-source-ingestion",
          "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
        },
        {
          "id": "aitd-003-close-time-materialization",
          "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
        },
        {
          "id": "aitd-011-policy-and-enum-normalization",
          "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
        }
      ],
      "api": "GET /alpha/analytics/v1/hint-usage-rollups",
      "rawRule": "Read alpha.analytics_hint_usage_rollup current ok/corrected rows for report answers. Do not parse player extensions or source payloads in an app.",
      "formula": "Counts sum governed hint_usage.requested_count, viewed_count, and used evidence across the window.",
      "example": {
        "hint_request_count": 42,
        "hint_view_count": 39,
        "hint_used_count": 38,
        "policy_ref": "alpha.policy.analytics.hint_usage.v2026-07-08"
      },
      "fields": [
        {
          "name": "id",
          "type": "TEXT",
          "nullability": "required",
          "meaning": "Analytics-owned stable row id for this derived rollup.",
          "constraints": "Set by Analytics materialization; not caller-supplied by public clients.",
          "relationship": "Part of the public Analytics rollup contract.",
          "invalidWhen": "Computed in app code or copied from an ungoverned source field.",
          "example": "attempt_rollup_event_4f8a9c4d2a1b0e9f8d7c6b5a",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-001-report-source-ingestion",
              "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
            },
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "tenant_id",
          "type": "TEXT",
          "nullability": "required",
          "meaning": "Tenant boundary for the derived rollup.",
          "constraints": "Set by Analytics materialization; not caller-supplied by public clients.",
          "relationship": "Part of the public Analytics rollup contract.",
          "invalidWhen": "Computed in app code or copied from an ungoverned source field.",
          "example": "demo",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-001-report-source-ingestion",
              "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
            },
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "student_id",
          "type": "TEXT",
          "nullability": "required",
          "meaning": "Canonical Alpha student id resolved at materialization time.",
          "constraints": "Set by Analytics materialization; not caller-supplied by public clients.",
          "relationship": "Part of the public Analytics rollup contract.",
          "invalidWhen": "Computed in app code or copied from an ungoverned source field.",
          "example": "student_01HT7G3YZV7QB5N4YKQ1K0Z9A9",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-001-report-source-ingestion",
              "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
            },
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "subject_id",
          "type": "TEXT",
          "nullability": "nullable",
          "meaning": "Canonical Alpha subject when the source can resolve one; null for all-subject event rollups.",
          "constraints": "Set by Analytics materialization; not caller-supplied by public clients.",
          "relationship": "Part of the public Analytics rollup contract.",
          "invalidWhen": "Computed in app code or copied from an ungoverned source field.",
          "example": "math",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-001-report-source-ingestion",
              "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
            },
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "policy_ref",
          "type": "TEXT",
          "nullability": "required",
          "meaning": "Named Analytics policy version used to compute the rollup.",
          "constraints": "Set by Analytics materialization; not caller-supplied by public clients.",
          "relationship": "Part of the public Analytics rollup contract.",
          "invalidWhen": "Computed in app code or copied from an ungoverned source field.",
          "example": "alpha.policy.analytics.hint_usage.v2026-07-08",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-001-report-source-ingestion",
              "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
            },
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "window_kind",
          "type": "TEXT enum",
          "nullability": "required",
          "meaning": "Named reporting window family.",
          "constraints": "Set by Analytics materialization; not caller-supplied by public clients.",
          "relationship": "Part of the public Analytics rollup contract.",
          "invalidWhen": "Computed in app code or copied from an ungoverned source field.",
          "example": "term",
          "sourceClass": "Alpha extension",
          "enum": "window_kind",
          "itds": [
            {
              "id": "aitd-001-report-source-ingestion",
              "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
            },
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "window_start",
          "type": "DATE",
          "nullability": "required",
          "meaning": "Inclusive start date for source question events or source rows included in this rollup.",
          "constraints": "Set by Analytics materialization; not caller-supplied by public clients.",
          "relationship": "Part of the public Analytics rollup contract.",
          "invalidWhen": "Computed in app code or copied from an ungoverned source field.",
          "example": "2026-01-01",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-001-report-source-ingestion",
              "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
            },
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "window_end",
          "type": "DATE",
          "nullability": "required",
          "meaning": "Exclusive end date for source question events or source rows included in this rollup.",
          "constraints": "Set by Analytics materialization; not caller-supplied by public clients.",
          "relationship": "Part of the public Analytics rollup contract.",
          "invalidWhen": "Computed in app code or copied from an ungoverned source field.",
          "example": "2026-06-01",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-001-report-source-ingestion",
              "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
            },
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "hint_request_count",
          "type": "INTEGER",
          "nullability": "required",
          "meaning": "Number of requested hints in the window.",
          "constraints": "Set by Analytics materialization; not caller-supplied by public clients.",
          "relationship": "Part of the public Analytics rollup contract.",
          "invalidWhen": "Computed in app code or copied from an ungoverned source field.",
          "example": 42,
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-001-report-source-ingestion",
              "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
            },
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "hint_view_count",
          "type": "INTEGER",
          "nullability": "required",
          "meaning": "Number of viewed hints in the window.",
          "constraints": "Set by Analytics materialization; not caller-supplied by public clients.",
          "relationship": "Part of the public Analytics rollup contract.",
          "invalidWhen": "Computed in app code or copied from an ungoverned source field.",
          "example": 39,
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-001-report-source-ingestion",
              "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
            },
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "hint_used_count",
          "type": "INTEGER",
          "nullability": "required",
          "meaning": "Number of used-hint observations in the window.",
          "constraints": "Set by Analytics materialization; not caller-supplied by public clients.",
          "relationship": "Part of the public Analytics rollup contract.",
          "invalidWhen": "Computed in app code or copied from an ungoverned source field.",
          "example": 38,
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-001-report-source-ingestion",
              "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
            },
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "source_import_id",
          "type": "TEXT",
          "nullability": "nullable",
          "meaning": "Source import id when the rollup came from source-shaped report ingestion.",
          "constraints": "Set by Analytics materialization; not caller-supplied by public clients.",
          "relationship": "Part of the public Analytics rollup contract.",
          "invalidWhen": "Computed in app code or copied from an ungoverned source field.",
          "example": "import_123",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-001-report-source-ingestion",
              "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
            },
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "source_event_refs",
          "type": "JSONB array",
          "nullability": "required",
          "meaning": "Events/source row refs included in the rollup.",
          "constraints": "Set by Analytics materialization; not caller-supplied by public clients.",
          "relationship": "Part of the public Analytics rollup contract.",
          "invalidWhen": "Computed in app code or copied from an ungoverned source field.",
          "example": [
            "events:demo:event_row_123"
          ],
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-001-report-source-ingestion",
              "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
            },
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "quality_status",
          "type": "TEXT enum",
          "nullability": "required",
          "meaning": "Quality status for the current rollup row.",
          "constraints": "Set by Analytics materialization; not caller-supplied by public clients.",
          "relationship": "Part of the public Analytics rollup contract.",
          "invalidWhen": "Computed in app code or copied from an ungoverned source field.",
          "example": "ok",
          "sourceClass": "Alpha extension",
          "enum": "quality_status",
          "itds": [
            {
              "id": "aitd-001-report-source-ingestion",
              "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
            },
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "null_reason",
          "type": "TEXT enum",
          "nullability": "required",
          "meaning": "Typed reason when the rollup has no reportable value.",
          "constraints": "Set by Analytics materialization; not caller-supplied by public clients.",
          "relationship": "Part of the public Analytics rollup contract.",
          "invalidWhen": "Computed in app code or copied from an ungoverned source field.",
          "example": "none",
          "sourceClass": "Alpha extension",
          "enum": "null_reason",
          "itds": [
            {
              "id": "aitd-001-report-source-ingestion",
              "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
            },
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "calculation_version",
          "type": "INTEGER",
          "nullability": "required",
          "meaning": "Materializer version for reproducibility.",
          "constraints": "Set by Analytics materialization; not caller-supplied by public clients.",
          "relationship": "Part of the public Analytics rollup contract.",
          "invalidWhen": "Computed in app code or copied from an ungoverned source field.",
          "example": 1,
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-001-report-source-ingestion",
              "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
            },
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "computed_at",
          "type": "TIMESTAMPTZ",
          "nullability": "required",
          "meaning": "Timestamp when Analytics computed this row.",
          "constraints": "Set by Analytics materialization; not caller-supplied by public clients.",
          "relationship": "Part of the public Analytics rollup contract.",
          "invalidWhen": "Computed in app code or copied from an ungoverned source field.",
          "example": "2026-07-08T00:00:00.000Z",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-001-report-source-ingestion",
              "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
            },
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "modified_at",
          "type": "TIMESTAMPTZ",
          "nullability": "required",
          "meaning": "Timestamp when this row was last written.",
          "constraints": "Set by Analytics materialization; not caller-supplied by public clients.",
          "relationship": "Part of the public Analytics rollup contract.",
          "invalidWhen": "Computed in app code or copied from an ungoverned source field.",
          "example": "2026-07-08T00:00:00.000Z",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-001-report-source-ingestion",
              "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
            },
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "superseded_at",
          "type": "TIMESTAMPTZ",
          "nullability": "nullable",
          "meaning": "Timestamp when a later current row superseded this row.",
          "constraints": "Set by Analytics materialization; not caller-supplied by public clients.",
          "relationship": "Part of the public Analytics rollup contract.",
          "invalidWhen": "Computed in app code or copied from an ungoverned source field.",
          "example": null,
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-001-report-source-ingestion",
              "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
            },
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "source_deleted_at",
          "type": "TIMESTAMPTZ",
          "nullability": "nullable",
          "meaning": "Timestamp when source deletion tombstoned this row.",
          "constraints": "Set by Analytics materialization; not caller-supplied by public clients.",
          "relationship": "Part of the public Analytics rollup contract.",
          "invalidWhen": "Computed in app code or copied from an ungoverned source field.",
          "example": null,
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-001-report-source-ingestion",
              "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
            },
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        }
      ],
      "plainLanguage": "Report-ready hint usage facts from governed player hint_usage evidence."
    },
    {
      "name": "alpha.analytics_mastery_delta",
      "title": "Mastery Delta",
      "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.",
      "primaryKey": "id; unique source transition key is (tenant_id, source_state_ref, state_dimension, effective_at, policy_ref, calculation_version).",
      "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.",
      "purpose": "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.",
      "metricChecks": [
        "mastery|student_kc_state"
      ],
      "architecture": [
        {
          "id": "aitd-008-mastery-and-grade-levels",
          "title": "Grade Levels Mastered Are Ingested; Mastery Deltas Read Results State",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-008-mastery-and-grade-levels"
        },
        {
          "id": "aitd-001-report-source-ingestion",
          "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
        },
        {
          "id": "aitd-004-provenance-no-literals",
          "title": "Every Report Value Traces To An Ingested Source Row, Or Reads Null",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-004-provenance-no-literals"
        },
        {
          "id": "aitd-003-close-time-materialization",
          "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
        },
        {
          "id": "aitd-011-policy-and-enum-normalization",
          "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
        }
      ],
      "api": "GET /alpha/analytics/v1/mastery-deltas",
      "rawRule": "Raw readers query mastery_delta by effective_at/state_dimension; they do not recompute mastery, decay, HMG, or due dates from attempts.",
      "example": {
        "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
      },
      "fields": [
        {
          "name": "id",
          "type": "UUID",
          "nullability": "required",
          "meaning": "Analytics-owned stable row id for this derived fact.",
          "constraints": "Generated by the platform; globally unique within alpha.analytics_* objects.",
          "relationship": "Primary key for list/detail endpoints.",
          "invalidWhen": "Provided by a public import client or reused across tenants.",
          "example": "8e9c0ef2-bc75-4f53-8124-df77df49f25f",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-000-extend-only-storage",
              "title": "Analytics Is New Extend-Only Alpha Storage",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-000-extend-only-storage"
            }
          ]
        },
        {
          "name": "tenant_id",
          "type": "UUID",
          "nullability": "required",
          "meaning": "Tenant boundary for the derived fact.",
          "constraints": "Set from the JWT tenant claim or internal materializer context; never accepted from request body/query.",
          "relationship": "All raw-path queries must filter by tenant_id before joining, sorting, paging, or counting.",
          "invalidWhen": "Missing, caller-supplied in body/query, or mismatched with the JWT tenant claim.",
          "example": "7b0bb5d8-9a38-4a62-9fdc-9f8d2dc1a111",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-109-axis-tenant-routing",
              "title": "API Axis: Tenant Routing",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-109-axis-tenant-routing"
            },
            {
              "id": "aitd-106-axis-auth-shape",
              "title": "API Axis: Auth Shape",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-106-axis-auth-shape"
            }
          ]
        },
        {
          "name": "student_id",
          "type": "TEXT",
          "nullability": "required",
          "meaning": "Canonical Alpha student id the source Event or Result resolved to at materialization time.",
          "constraints": "Must resolve through People and Orgs as a real student for the source timestamp/effective date.",
          "relationship": "References People and Orgs student identity; see https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/data_dictionary.",
          "invalidWhen": "Parsed from email/name/source payload instead of resolved by the Events/Results adapter.",
          "example": "student_01HT7G3YZV7QB5N4YKQ1K0Z9A9",
          "sourceClass": "Alpha extension reference",
          "itds": [
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            },
            {
              "id": "aitd-106-axis-auth-shape",
              "title": "API Axis: Auth Shape",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-106-axis-auth-shape"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "kc_id",
          "type": "TEXT",
          "nullability": "nullable when the row is a grade-level mastered fact without a single KC",
          "meaning": "Knowledge Component whose student state changed.",
          "constraints": "Must reference a Curriculum KC; never a standard or lesson id.",
          "relationship": "References Curriculum KC tree; see https://platform3-andymontgomery-9773s-projects.vercel.app/curriculum/alpha/data_dictionary.",
          "invalidWhen": "Points to a standard, lesson, content item, or parsed source course string.",
          "example": "kc_math_fraction_addition_unlike_denominators",
          "sourceClass": "Alpha extension reference",
          "itds": [
            {
              "id": "aitd-008-mastery-and-grade-levels",
              "title": "Grade Levels Mastered Are Ingested; Mastery Deltas Read Results State",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-008-mastery-and-grade-levels"
            }
          ]
        },
        {
          "name": "grade_subject",
          "type": "TEXT enum",
          "nullability": "nullable except grade-level mastered rows",
          "meaning": "Subject for a Grade Levels Mastered row shown in the Learning Report.",
          "constraints": "Closed Alpha subject enum after write-time normalization; required when grade_level/completed_on are populated.",
          "relationship": "Ingested from reporting.assessment_results through the timeback-grade-mastery adapter.",
          "invalidWhen": "Parsed by a report from assessment names or display text.",
          "example": "math",
          "enum": "subject_id",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-008-mastery-and-grade-levels",
              "title": "Grade Levels Mastered Are Ingested; Mastery Deltas Read Results State",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-008-mastery-and-grade-levels"
            },
            {
              "id": "aitd-001-report-source-ingestion",
              "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "grade_level",
          "type": "INTEGER",
          "nullability": "nullable except grade-level mastered rows",
          "meaning": "Grade level the student has mastered in the subject.",
          "constraints": "Positive integer; set by the grade-mastery adapter from passed gate/assessment evidence.",
          "relationship": "Learning Report Grade Levels Mastered tile reads this field with grade_subject and completed_on.",
          "invalidWhen": "Computed by a dashboard from current grade, MAP RIT, or a course name.",
          "example": "5",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-008-mastery-and-grade-levels",
              "title": "Grade Levels Mastered Are Ingested; Mastery Deltas Read Results State",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-008-mastery-and-grade-levels"
            },
            {
              "id": "aitd-001-report-source-ingestion",
              "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
            }
          ]
        },
        {
          "name": "completed_on",
          "type": "DATE",
          "nullability": "nullable except grade-level mastered rows",
          "meaning": "Date the grade-level mastery fact became effective for reporting.",
          "constraints": "ISO date derived from the source assessment/gate completion date.",
          "relationship": "Used to order Grade Levels Mastered entries in Learning Reports.",
          "invalidWhen": "Filled from Analytics computed_at or import time.",
          "example": "2026-05-14",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-008-mastery-and-grade-levels",
              "title": "Grade Levels Mastered Are Ingested; Mastery Deltas Read Results State",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-008-mastery-and-grade-levels"
            },
            {
              "id": "aitd-001-report-source-ingestion",
              "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
            }
          ]
        },
        {
          "name": "source_state_ref",
          "type": "TEXT",
          "nullability": "nullable for grade-level mastered rows; required for Results state-delta rows",
          "meaning": "Results student_kc_state row/version this delta derives from.",
          "constraints": "Must reference Results state or ledger evidence in same tenant.",
          "relationship": "References Results current state/history; see https://platform3-andymontgomery-9773s-projects.vercel.app/results/alpha/data_dictionary#table-alpha-student-kc-state.",
          "invalidWhen": "Analytics becomes the authoritative mastery state or stores state without source ref.",
          "example": "student_kc_state_01HT7K7S9Q",
          "sourceClass": "Alpha extension reference",
          "itds": [
            {
              "id": "aitd-000-extend-only-storage",
              "title": "Analytics Is New Extend-Only Alpha Storage",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-000-extend-only-storage"
            },
            {
              "id": "aitd-008-mastery-and-grade-levels",
              "title": "Grade Levels Mastered Are Ingested; Mastery Deltas Read Results State",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-008-mastery-and-grade-levels"
            }
          ]
        },
        {
          "name": "source_result_refs",
          "type": "JSONB",
          "nullability": "required",
          "meaning": "Result/evidence ids that caused or explain the state transition or grade-level mastery fact.",
          "constraints": "Stores ids/hashes only; no raw scored payload copies.",
          "relationship": "Links back to result_record/result_kc_evidence or imported assessment_results source refs for audit.",
          "invalidWhen": "Contains copied response bodies, raw attempts, or mastery math inputs for client recomputation.",
          "example": "[\"result_01HT7K8BR3\"]",
          "sourceClass": "Alpha extension reference list",
          "itds": [
            {
              "id": "aitd-000-extend-only-storage",
              "title": "Analytics Is New Extend-Only Alpha Storage",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-000-extend-only-storage"
            },
            {
              "id": "aitd-008-mastery-and-grade-levels",
              "title": "Grade Levels Mastered Are Ingested; Mastery Deltas Read Results State",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-008-mastery-and-grade-levels"
            },
            {
              "id": "aitd-102-axis-read-shape",
              "title": "API Axis: Read Shape",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-102-axis-read-shape"
            }
          ]
        },
        {
          "name": "state_dimension",
          "type": "TEXT enum",
          "nullability": "required",
          "meaning": "Which Results mastery-state dimension changed.",
          "constraints": "Allowed values: state_dimension enum.",
          "relationship": "Part of the delta grain and filter model.",
          "invalidWhen": "Free-text state labels or dashboard-specific columns.",
          "example": "durable_mastery",
          "enum": "state_dimension",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-008-mastery-and-grade-levels",
              "title": "Grade Levels Mastered Are Ingested; Mastery Deltas Read Results State",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-008-mastery-and-grade-levels"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "effective_at",
          "type": "TIMESTAMPTZ",
          "nullability": "required",
          "meaning": "When the state transition is effective for as-of reporting.",
          "constraints": "UTC timestamp; comes from Results state transition, not Analytics computed_at.",
          "relationship": "Raw/API answer to \"what changed between A and B\" filters this field.",
          "invalidWhen": "Substituted with computed_at or source import time.",
          "example": "2026-05-14T18:45:00Z",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-008-mastery-and-grade-levels",
              "title": "Grade Levels Mastered Are Ingested; Mastery Deltas Read Results State",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-008-mastery-and-grade-levels"
            }
          ]
        },
        {
          "name": "previous_value",
          "type": "JSONB",
          "nullability": "nullable",
          "meaning": "Typed previous value for the changed state dimension.",
          "constraints": "JSON shape must match state_dimension; null allowed for first known state.",
          "relationship": "Used for report explanations; not for recomputing Results state.",
          "invalidWhen": "Unstructured notes or mixed units without state_dimension shape.",
          "example": "{\"value\":0.82}",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-008-mastery-and-grade-levels",
              "title": "Grade Levels Mastered Are Ingested; Mastery Deltas Read Results State",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-008-mastery-and-grade-levels"
            }
          ]
        },
        {
          "name": "new_value",
          "type": "JSONB",
          "nullability": "required",
          "meaning": "Typed new value for the changed state dimension.",
          "constraints": "JSON shape must match state_dimension.",
          "relationship": "Report-ready delta endpoint output.",
          "invalidWhen": "Consumer has to fetch Results and calculate the value itself.",
          "example": "{\"value\":0.91}",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-008-mastery-and-grade-levels",
              "title": "Grade Levels Mastered Are Ingested; Mastery Deltas Read Results State",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-008-mastery-and-grade-levels"
            }
          ]
        },
        {
          "name": "delta_value",
          "type": "NUMERIC(12,6)",
          "nullability": "nullable",
          "meaning": "Numeric difference where the state dimension has a numeric value.",
          "constraints": "Null for non-numeric dimensions such as next_due_at or fluency_state.",
          "relationship": "Used for sorting and report summaries.",
          "invalidWhen": "Invented for categorical dimensions without policy meaning.",
          "example": "0.090000",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-008-mastery-and-grade-levels",
              "title": "Grade Levels Mastered Are Ingested; Mastery Deltas Read Results State",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-008-mastery-and-grade-levels"
            }
          ]
        },
        {
          "name": "transition_kind",
          "type": "TEXT enum",
          "nullability": "required",
          "meaning": "Human-readable category of the state transition.",
          "constraints": "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.",
          "relationship": "Lets reports group deltas without client-side classifiers.",
          "invalidWhen": "Classified by a dashboard from score percentages or attempt names.",
          "example": "acquired",
          "enum": "transition_kind",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-008-mastery-and-grade-levels",
              "title": "Grade Levels Mastered Are Ingested; Mastery Deltas Read Results State",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-008-mastery-and-grade-levels"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "source_import_id",
          "type": "TEXT",
          "nullability": "required for report-tile rows; nullable for purely derived event-axis rows",
          "meaning": "Analytics source-import receipt that proves which named report-source adapter produced this report-grade fact.",
          "constraints": "Must reference alpha.analytics_source_import for non-null Learning Report tile values; no literal or fixture value may be reportable without this provenance.",
          "relationship": "Many report-fact rows can reference one source import; detail/sourceRefs endpoints join here for adapter, source_table, and source_row_key_hashes.",
          "invalidWhen": "Missing on a non-null report-tile value, or replaced by copied raw reporting-DB columns.",
          "example": "imp_01HT8GRADE_2026_SPRING",
          "sourceClass": "Alpha extension provenance reference",
          "itds": [
            {
              "id": "aitd-001-report-source-ingestion",
              "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
            },
            {
              "id": "aitd-004-provenance-no-literals",
              "title": "Every Report Value Traces To An Ingested Source Row, Or Reads Null",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-004-provenance-no-literals"
            },
            {
              "id": "aitd-008-mastery-and-grade-levels",
              "title": "Grade Levels Mastered Are Ingested; Mastery Deltas Read Results State",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-008-mastery-and-grade-levels"
            }
          ]
        },
        {
          "name": "policy_ref",
          "type": "TEXT",
          "nullability": "required",
          "meaning": "Named policy/config version used to compute the measure or rollup.",
          "constraints": "Must point at alpha.policy.analytics.* or an inherited Curriculum/Results policy active for the source effective date.",
          "relationship": "Many Analytics facts can share one policy row; changing policy creates new calculation versions or corrections.",
          "invalidWhen": "A consumer hard-codes thresholds, school-day calendars, Growth X formulas, or completion denominators instead of using the policy ref.",
          "example": "alpha.policy.results.mastery_state.v2026-06-10",
          "sourceClass": "Alpha extension reference",
          "itds": [
            {
              "id": "aitd-008-mastery-and-grade-levels",
              "title": "Grade Levels Mastered Are Ingested; Mastery Deltas Read Results State",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-008-mastery-and-grade-levels"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "quality_status",
          "type": "TEXT enum",
          "nullability": "required",
          "meaning": "Current materialization quality state for this fact.",
          "constraints": "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.",
          "relationship": "Used by raw/API convergence filters and source-ref audit views.",
          "invalidWhen": "Free-text status or hidden failures represented as HTTP 200 success.",
          "example": "ok",
          "enum": "quality_status",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            },
            {
              "id": "aitd-108-axis-error-envelope",
              "title": "API Axis: Error Envelope",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-108-axis-error-envelope"
            },
            {
              "id": "aitd-111-axis-privacy-retention",
              "title": "API Axis: Privacy And Retention",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-111-axis-privacy-retention"
            }
          ]
        },
        {
          "name": "calculation_version",
          "type": "INTEGER",
          "nullability": "required",
          "meaning": "Materializer calculation version for this fact shape.",
          "constraints": "Positive integer; starts at 1 and increments when policy/materializer logic intentionally changes.",
          "relationship": "Part of deterministic source_fact_key/idempotency for materializer writes.",
          "invalidWhen": "Omitted from replay keys or changed without a new policy/materializer decision.",
          "example": "1",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            },
            {
              "id": "aitd-105-axis-idempotency",
              "title": "API Axis: Idempotency Model",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-105-axis-idempotency"
            },
            {
              "id": "aitd-104-axis-concurrency",
              "title": "API Axis: Concurrency Model",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-104-axis-concurrency"
            }
          ]
        },
        {
          "name": "computed_at",
          "type": "TIMESTAMPTZ",
          "nullability": "required",
          "meaning": "When Analytics wrote this derived fact.",
          "constraints": "UTC timestamp with timezone; updated only by Analytics materializers.",
          "relationship": "Used for audit and source-ref subcollections, not for school-day grouping.",
          "invalidWhen": "Used as a substitute for the source event time, result effective time, or window boundaries.",
          "example": "2026-06-10T00:51:14Z",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            }
          ]
        },
        {
          "name": "modified_at",
          "type": "TIMESTAMPTZ",
          "nullability": "required",
          "meaning": "Last time the Analytics row changed for polling and modifiedSince queries.",
          "constraints": "UTC timestamp; list endpoints support modifiedSince against this field.",
          "relationship": "Supports poll plus modifiedSince eventing.",
          "invalidWhen": "Client-supplied or used as the business effective date.",
          "example": "2026-06-10T00:51:14Z",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-107-axis-eventing",
              "title": "API Axis: Eventing Model",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-107-axis-eventing"
            },
            {
              "id": "aitd-103-axis-query-model",
              "title": "API Axis: Query Model",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-103-axis-query-model"
            }
          ]
        },
        {
          "name": "superseded_at",
          "type": "TIMESTAMPTZ",
          "nullability": "nullable",
          "meaning": "When this row stopped being the current reportable version because of source correction, deletion, or recalculation.",
          "constraints": "Null means current; non-null rows are excluded from ordinary list reads unless includeSuperseded=true and authorized.",
          "relationship": "Preserves audit history without mutating source Events or Results.",
          "invalidWhen": "Used to hard-delete old rows or omitted on a correction that replaces a prior fact.",
          "example": "null",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-111-axis-privacy-retention",
              "title": "API Axis: Privacy And Retention",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-111-axis-privacy-retention"
            },
            {
              "id": "aitd-012-corrections-and-reversals",
              "title": "Corrections Are Signed Facts With Provenance",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-012-corrections-and-reversals"
            }
          ]
        },
        {
          "name": "source_deleted_at",
          "type": "TIMESTAMPTZ",
          "nullability": "nullable",
          "meaning": "When the source Event/Result became deleted or invalidated.",
          "constraints": "Null for live source rows; set from source tombstone/correction notifications.",
          "relationship": "Ordinary reads exclude tombstoned facts unless includeSuperseded=true and authorized.",
          "invalidWhen": "Used as a physical delete or ignored by raw-path report queries.",
          "example": "null",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-111-axis-privacy-retention",
              "title": "API Axis: Privacy And Retention",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-111-axis-privacy-retention"
            }
          ]
        },
        {
          "name": "subject_id",
          "type": "TEXT",
          "physicalType": "TEXT",
          "nullability": "nullable",
          "meaning": "Canonical subject for the mastery transition or grade-level mastery fact.",
          "constraints": "When populated, one of the canonical Analytics subject ids; source labels are normalized before materialization.",
          "relationship": "References the Results/Curriculum subject vocabulary and supports subjectId filtering.",
          "provenance": "Analytics materializer output governed by loop/context/ap-one-platform-capabilities-decision.md.",
          "invalidWhen": "The value is caller-computed, cross-tenant, or detached from the governed source relationship.",
          "example": "science",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        }
      ],
      "plainLanguage": "Grade Levels Mastered plus KC mastery-state changes. It is not the current mastery state."
    },
    {
      "name": "alpha.analytics_map_growth_rollup",
      "title": "MAP Growth Rollup",
      "kind": "Alpha extension rollup table",
      "grain": "student_id x subject_id x canonical_term_id x growth_window x norms_set x policy_ref.",
      "primaryKey": "id; unique current grain is (tenant_id, student_id, subject_id, canonical_term_id, growth_window, norms_set, policy_ref, calculation_version).",
      "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.",
      "purpose": "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.",
      "metricChecks": [
        "RIT|GrowthX|MAP growth windows",
        "MAP sittings/scores"
      ],
      "architecture": [
        {
          "id": "aitd-009-map-growth-rollups",
          "title": "MAP RIT And Growth X Are Ingested From hp_map_results, Deduped, And Norms-Calculated",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-009-map-growth-rollups"
        },
        {
          "id": "aitd-001-report-source-ingestion",
          "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
        },
        {
          "id": "aitd-004-provenance-no-literals",
          "title": "Every Report Value Traces To An Ingested Source Row, Or Reads Null",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-004-provenance-no-literals"
        },
        {
          "id": "aitd-003-close-time-materialization",
          "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
        },
        {
          "id": "aitd-011-policy-and-enum-normalization",
          "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
        }
      ],
      "api": "GET /alpha/analytics/v1/map-growth-rollups",
      "rawRule": "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.",
      "example": {
        "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
      },
      "fields": [
        {
          "name": "id",
          "type": "UUID",
          "nullability": "required",
          "meaning": "Analytics-owned stable row id for this derived fact.",
          "constraints": "Generated by the platform; globally unique within alpha.analytics_* objects.",
          "relationship": "Primary key for list/detail endpoints.",
          "invalidWhen": "Provided by a public import client or reused across tenants.",
          "example": "8e9c0ef2-bc75-4f53-8124-df77df49f25f",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-000-extend-only-storage",
              "title": "Analytics Is New Extend-Only Alpha Storage",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-000-extend-only-storage"
            }
          ]
        },
        {
          "name": "tenant_id",
          "type": "UUID",
          "nullability": "required",
          "meaning": "Tenant boundary for the derived fact.",
          "constraints": "Set from the JWT tenant claim or internal materializer context; never accepted from request body/query.",
          "relationship": "All raw-path queries must filter by tenant_id before joining, sorting, paging, or counting.",
          "invalidWhen": "Missing, caller-supplied in body/query, or mismatched with the JWT tenant claim.",
          "example": "7b0bb5d8-9a38-4a62-9fdc-9f8d2dc1a111",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-109-axis-tenant-routing",
              "title": "API Axis: Tenant Routing",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-109-axis-tenant-routing"
            },
            {
              "id": "aitd-106-axis-auth-shape",
              "title": "API Axis: Auth Shape",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-106-axis-auth-shape"
            }
          ]
        },
        {
          "name": "student_id",
          "type": "TEXT",
          "nullability": "required",
          "meaning": "Canonical Alpha student id the source Event or Result resolved to at materialization time.",
          "constraints": "Must resolve through People and Orgs as a real student for the source timestamp/effective date.",
          "relationship": "References People and Orgs student identity; see https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/data_dictionary.",
          "invalidWhen": "Parsed from email/name/source payload instead of resolved by the Events/Results adapter.",
          "example": "student_01HT7G3YZV7QB5N4YKQ1K0Z9A9",
          "sourceClass": "Alpha extension reference",
          "itds": [
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            },
            {
              "id": "aitd-106-axis-auth-shape",
              "title": "API Axis: Auth Shape",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-106-axis-auth-shape"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "subject_id",
          "type": "TEXT",
          "nullability": "required for MAP rollups",
          "meaning": "Canonical Alpha subject used for reporting and grouping.",
          "constraints": "Closed Alpha subject enum after write-time source-label normalization; unknown source subject becomes an adapter finding or null_reason, not a new string.",
          "relationship": "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.",
          "invalidWhen": "Copied from source strings such as FastMath, Vocabulary, Science-notqced, or ISEE variants without normalization.",
          "example": "math",
          "sourceClass": "Alpha extension reference",
          "itds": [
            {
              "id": "aitd-009-map-growth-rollups",
              "title": "MAP RIT And Growth X Are Ingested From hp_map_results, Deduped, And Norms-Calculated",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-009-map-growth-rollups"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "canonical_term_id",
          "type": "TEXT",
          "nullability": "required",
          "meaning": "Alpha canonical term id for the MAP observation/window.",
          "constraints": "Set by Results/NWEAMap term normalization; not parsed by Analytics clients.",
          "relationship": "References People and Orgs academic-session term.",
          "invalidWhen": "A report parses source strings like Winter 2026 or growth-window columns.",
          "example": "term_2026_winter",
          "sourceClass": "Alpha extension reference",
          "itds": [
            {
              "id": "aitd-009-map-growth-rollups",
              "title": "MAP RIT And Growth X Are Ingested From hp_map_results, Deduped, And Norms-Calculated",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-009-map-growth-rollups"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "growth_window",
          "type": "TEXT enum",
          "nullability": "required",
          "meaning": "MAP growth interval represented by this row.",
          "constraints": "Allowed values: growth_window enum.",
          "relationship": "Part of the MAP rollup grain.",
          "invalidWhen": "A client switches over NWEA wide growth-window columns.",
          "example": "winter_to_winter",
          "enum": "growth_window",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-009-map-growth-rollups",
              "title": "MAP RIT And Growth X Are Ingested From hp_map_results, Deduped, And Norms-Calculated",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-009-map-growth-rollups"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "norms_set",
          "type": "TEXT enum",
          "nullability": "required",
          "meaning": "NWEA norms family used for projected growth and normed outputs.",
          "constraints": "Allowed values: norms_set enum; the same report can be regenerated by changing this filter.",
          "relationship": "Prevents mixed-norm calculations.",
          "invalidWhen": "A report ships its own norms table or combines 2020 and 2025 values.",
          "example": "2025",
          "enum": "norms_set",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-009-map-growth-rollups",
              "title": "MAP RIT And Growth X Are Ingested From hp_map_results, Deduped, And Norms-Calculated",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-009-map-growth-rollups"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "map_score_id",
          "type": "TEXT",
          "nullability": "required",
          "meaning": "Results MAP score/test-of-record row this report fact derives from.",
          "constraints": "Same tenant; Results owns test-of-record and raw sitting decisions.",
          "relationship": "References Results MAP score; see https://platform3-andymontgomery-9773s-projects.vercel.app/results/alpha/data_dictionary#table-alpha-map-score.",
          "invalidWhen": "Analytics selects the highest RIT itself or copies raw sitting fields.",
          "example": "map_score_01HT7N0T9Q",
          "sourceClass": "Alpha extension reference",
          "itds": [
            {
              "id": "aitd-000-extend-only-storage",
              "title": "Analytics Is New Extend-Only Alpha Storage",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-000-extend-only-storage"
            },
            {
              "id": "aitd-009-map-growth-rollups",
              "title": "MAP RIT And Growth X Are Ingested From hp_map_results, Deduped, And Norms-Calculated",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-009-map-growth-rollups"
            }
          ]
        },
        {
          "name": "map_growth_window_ref",
          "type": "TEXT",
          "nullability": "nullable for single-term observations",
          "meaning": "Results MAP growth-window row used for projected/observed growth.",
          "constraints": "Required when growth_window is not term.",
          "relationship": "References Results MAP growth window; see https://platform3-andymontgomery-9773s-projects.vercel.app/results/alpha/data_dictionary#table-alpha-map-growth-window.",
          "invalidWhen": "Client computes projected growth or window pairing.",
          "example": "map_growth_01HT7N5YDG",
          "sourceClass": "Alpha extension reference",
          "itds": [
            {
              "id": "aitd-000-extend-only-storage",
              "title": "Analytics Is New Extend-Only Alpha Storage",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-000-extend-only-storage"
            },
            {
              "id": "aitd-009-map-growth-rollups",
              "title": "MAP RIT And Growth X Are Ingested From hp_map_results, Deduped, And Norms-Calculated",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-009-map-growth-rollups"
            }
          ]
        },
        {
          "name": "rit_score",
          "type": "NUMERIC(6,2)",
          "nullability": "required",
          "meaning": "Report-ready RIT value from Results MAP test-of-record for this subject/term.",
          "constraints": "Positive numeric; no local test-of-record choice in Analytics clients.",
          "relationship": "Displayed in MAP reports and used with Growth X fields.",
          "invalidWhen": "Selected from raw sittings by the consumer.",
          "example": "239.00",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-009-map-growth-rollups",
              "title": "MAP RIT And Growth X Are Ingested From hp_map_results, Deduped, And Norms-Calculated",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-009-map-growth-rollups"
            }
          ]
        },
        {
          "name": "growth_percentile",
          "type": "NUMERIC(6,2)",
          "nullability": "nullable when the selected growth_window has no conditional growth percentile",
          "meaning": "Conditional growth percentile for the selected MAP window; the Learning Report \"vs 1yr ago\" panel reads this from the winter_to_winter row.",
          "constraints": "0 to 100 when present; null requires null_reason for report windows that should have growth.",
          "relationship": "For winter_to_winter, normalized from Results/NWEAMap wintertowinterconditionalgrowthpercentile source evidence.",
          "invalidWhen": "Filled from fall_to_winter for a one-year-growth report panel.",
          "example": "43.00",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-009-map-growth-rollups",
              "title": "MAP RIT And Growth X Are Ingested From hp_map_results, Deduped, And Norms-Calculated",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-009-map-growth-rollups"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "achievement_percentile",
          "type": "NUMERIC(6,2)",
          "nullability": "nullable when the MAP source row has no achievement percentile",
          "meaning": "Achievement percentile for the test-of-record sitting.",
          "constraints": "0 to 100 when present; for hp_map_results this is normalized from testpercentile.",
          "relationship": "Displayed beside RIT in MAP report panels.",
          "invalidWhen": "Filled from conditional growth percentile or mixed with growth_percentile.",
          "example": "91.00",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-009-map-growth-rollups",
              "title": "MAP RIT And Growth X Are Ingested From hp_map_results, Deduped, And Norms-Calculated",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-009-map-growth-rollups"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "observed_growth",
          "type": "NUMERIC(7,3)",
          "nullability": "nullable when no paired window exists",
          "meaning": "Actual RIT growth for the growth_window.",
          "constraints": "Null for term-only observations; otherwise computed by Results MAP views.",
          "relationship": "Numerator for Growth X.",
          "invalidWhen": "Computed by subtracting RIT values in a report.",
          "example": "6.000",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-009-map-growth-rollups",
              "title": "MAP RIT And Growth X Are Ingested From hp_map_results, Deduped, And Norms-Calculated",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-009-map-growth-rollups"
            }
          ]
        },
        {
          "name": "typical_growth",
          "type": "NUMERIC(7,3)",
          "nullability": "nullable when the selected growth_window has no typical-growth value",
          "meaning": "NWEA typical-growth context value for the selected growth window.",
          "constraints": "Comes from normalized Results/NWEAMap typical*growth columns; retained for audit and comparison.",
          "relationship": "For winter_to_winter, normalized from typicalwintertowintergrowth.",
          "invalidWhen": "Used as the Learning Report Growth X denominator; the approved architecture pins projected_growth for Growth X.",
          "example": "2.000",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-009-map-growth-rollups",
              "title": "MAP RIT And Growth X Are Ingested From hp_map_results, Deduped, And Norms-Calculated",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-009-map-growth-rollups"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "projected_growth",
          "type": "NUMERIC(7,3)",
          "nullability": "nullable when no projected growth exists",
          "meaning": "NWEA projected-growth value for the selected window.",
          "constraints": "Must be greater than 0 when growth_x is present; comes from Results/NWEAMap normalized projections and never from a client norms table.",
          "relationship": "The pinned Learning Report Growth X denominator under AITD-009.",
          "invalidWhen": "Copied from a skill pack or dashboard constants file.",
          "example": "7.000",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-009-map-growth-rollups",
              "title": "MAP RIT And Growth X Are Ingested From hp_map_results, Deduped, And Norms-Calculated",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-009-map-growth-rollups"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "growth_x",
          "type": "NUMERIC(8,4)",
          "nullability": "nullable when observed or projected growth is unavailable",
          "meaning": "Observed growth divided by projected_growth, using the named norms_set and growth_window.",
          "constraints": "Null requires null_reason; target comparisons use growth_x_target.",
          "relationship": "The report-ready Alpha growth measure.",
          "invalidWhen": "Computed by a consumer from exported RIT/projection fields, or computed with typical_growth as the denominator.",
          "example": "0.8571",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-009-map-growth-rollups",
              "title": "MAP RIT And Growth X Are Ingested From hp_map_results, Deduped, And Norms-Calculated",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-009-map-growth-rollups"
            }
          ]
        },
        {
          "name": "growth_x_target",
          "type": "NUMERIC(8,4)",
          "nullability": "required",
          "meaning": "Alpha target Growth X for intervention/on-track decisions.",
          "constraints": "Normally 2 under current Alpha policy, but read from policy_ref.",
          "relationship": "Feeds on_track flag and GOALS-style reports.",
          "invalidWhen": "Hard-coded in a report or skill pack.",
          "example": "2.0000",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-009-map-growth-rollups",
              "title": "MAP RIT And Growth X Are Ingested From hp_map_results, Deduped, And Norms-Calculated",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-009-map-growth-rollups"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "on_track",
          "type": "BOOLEAN",
          "nullability": "nullable when growth_x or target is null",
          "meaning": "Whether the student is meeting the Growth X target for this row.",
          "constraints": "Computed under policy_ref; null requires null_reason.",
          "relationship": "Report flag for intervention workflows.",
          "invalidWhen": "Client compares growth_x to a local threshold.",
          "example": "true",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-009-map-growth-rollups",
              "title": "MAP RIT And Growth X Are Ingested From hp_map_results, Deduped, And Norms-Calculated",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-009-map-growth-rollups"
            }
          ]
        },
        {
          "name": "sitting_count",
          "type": "INTEGER",
          "nullability": "required",
          "meaning": "Number of MAP sittings Results observed for this subject/term before test-of-record selection.",
          "constraints": "Nonnegative; includes source-visible sittings according to Results policy.",
          "relationship": "Retake/audit display; not a dedupe instruction for clients.",
          "invalidWhen": "Consumer counts raw NWEA rows itself.",
          "example": "2",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-009-map-growth-rollups",
              "title": "MAP RIT And Growth X Are Ingested From hp_map_results, Deduped, And Norms-Calculated",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-009-map-growth-rollups"
            }
          ]
        },
        {
          "name": "retake_count",
          "type": "INTEGER",
          "nullability": "required",
          "meaning": "Number of non-test-of-record sittings represented by the sitting_count.",
          "constraints": "Nonnegative; computed by Results/NWEAMap policy.",
          "relationship": "Retake audit metric.",
          "invalidWhen": "Client infers retakes from source term strings or GrowthMeasureYN flags.",
          "example": "1",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-009-map-growth-rollups",
              "title": "MAP RIT And Growth X Are Ingested From hp_map_results, Deduped, And Norms-Calculated",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-009-map-growth-rollups"
            }
          ]
        },
        {
          "name": "map_sitting_refs",
          "type": "JSONB",
          "nullability": "required",
          "meaning": "Compact ids/cursor for Results MAP sitting rows used in the rollup.",
          "constraints": "Refs/hashes only; no raw NWEA row copy.",
          "relationship": "Authorized audit sourceRefs subcollection.",
          "invalidWhen": "Stores raw CDF fields or lets consumers dedupe.",
          "example": "[\"map_sitting_01HT7N\", \"map_sitting_01HT7P\"]",
          "sourceClass": "Alpha extension reference list",
          "itds": [
            {
              "id": "aitd-000-extend-only-storage",
              "title": "Analytics Is New Extend-Only Alpha Storage",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-000-extend-only-storage"
            },
            {
              "id": "aitd-009-map-growth-rollups",
              "title": "MAP RIT And Growth X Are Ingested From hp_map_results, Deduped, And Norms-Calculated",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-009-map-growth-rollups"
            },
            {
              "id": "aitd-102-axis-read-shape",
              "title": "API Axis: Read Shape",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-102-axis-read-shape"
            }
          ]
        },
        {
          "name": "source_import_id",
          "type": "TEXT",
          "nullability": "required for report-tile rows; nullable for purely derived event-axis rows",
          "meaning": "Analytics source-import receipt that proves which named report-source adapter produced this report-grade fact.",
          "constraints": "Must reference alpha.analytics_source_import for non-null Learning Report tile values; no literal or fixture value may be reportable without this provenance.",
          "relationship": "Many report-fact rows can reference one source import; detail/sourceRefs endpoints join here for adapter, source_table, and source_row_key_hashes.",
          "invalidWhen": "Missing on a non-null report-tile value, or replaced by copied raw reporting-DB columns.",
          "example": "imp_01HT8MAP_2026_WINTER",
          "sourceClass": "Alpha extension provenance reference",
          "itds": [
            {
              "id": "aitd-001-report-source-ingestion",
              "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
            },
            {
              "id": "aitd-004-provenance-no-literals",
              "title": "Every Report Value Traces To An Ingested Source Row, Or Reads Null",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-004-provenance-no-literals"
            },
            {
              "id": "aitd-009-map-growth-rollups",
              "title": "MAP RIT And Growth X Are Ingested From hp_map_results, Deduped, And Norms-Calculated",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-009-map-growth-rollups"
            }
          ]
        },
        {
          "name": "policy_ref",
          "type": "TEXT",
          "nullability": "required",
          "meaning": "Named policy/config version used to compute the measure or rollup.",
          "constraints": "Must point at alpha.policy.analytics.* or an inherited Curriculum/Results policy active for the source effective date.",
          "relationship": "Many Analytics facts can share one policy row; changing policy creates new calculation versions or corrections.",
          "invalidWhen": "A consumer hard-codes thresholds, school-day calendars, Growth X formulas, or completion denominators instead of using the policy ref.",
          "example": "alpha.policy.analytics.map_growth.v2026-06-10",
          "sourceClass": "Alpha extension reference",
          "itds": [
            {
              "id": "aitd-009-map-growth-rollups",
              "title": "MAP RIT And Growth X Are Ingested From hp_map_results, Deduped, And Norms-Calculated",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-009-map-growth-rollups"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "null_reason",
          "type": "TEXT enum",
          "nullability": "required",
          "meaning": "Why a MAP rollup value is null or not applicable.",
          "constraints": "Allowed values: null_reason enum; none means core report fields are populated.",
          "relationship": "Prevents client fallback term/norm math.",
          "invalidWhen": "Null growth fields without a typed reason.",
          "example": "none",
          "enum": "null_reason",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-009-map-growth-rollups",
              "title": "MAP RIT And Growth X Are Ingested From hp_map_results, Deduped, And Norms-Calculated",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-009-map-growth-rollups"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "quality_status",
          "type": "TEXT enum",
          "nullability": "required",
          "meaning": "Current materialization quality state for this fact.",
          "constraints": "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.",
          "relationship": "Used by raw/API convergence filters and source-ref audit views.",
          "invalidWhen": "Free-text status or hidden failures represented as HTTP 200 success.",
          "example": "ok",
          "enum": "quality_status",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            },
            {
              "id": "aitd-108-axis-error-envelope",
              "title": "API Axis: Error Envelope",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-108-axis-error-envelope"
            },
            {
              "id": "aitd-111-axis-privacy-retention",
              "title": "API Axis: Privacy And Retention",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-111-axis-privacy-retention"
            }
          ]
        },
        {
          "name": "calculation_version",
          "type": "INTEGER",
          "nullability": "required",
          "meaning": "Materializer calculation version for this fact shape.",
          "constraints": "Positive integer; starts at 1 and increments when policy/materializer logic intentionally changes.",
          "relationship": "Part of deterministic source_fact_key/idempotency for materializer writes.",
          "invalidWhen": "Omitted from replay keys or changed without a new policy/materializer decision.",
          "example": "1",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            },
            {
              "id": "aitd-105-axis-idempotency",
              "title": "API Axis: Idempotency Model",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-105-axis-idempotency"
            },
            {
              "id": "aitd-104-axis-concurrency",
              "title": "API Axis: Concurrency Model",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-104-axis-concurrency"
            }
          ]
        },
        {
          "name": "computed_at",
          "type": "TIMESTAMPTZ",
          "nullability": "required",
          "meaning": "When Analytics wrote this derived fact.",
          "constraints": "UTC timestamp with timezone; updated only by Analytics materializers.",
          "relationship": "Used for audit and source-ref subcollections, not for school-day grouping.",
          "invalidWhen": "Used as a substitute for the source event time, result effective time, or window boundaries.",
          "example": "2026-06-10T00:51:14Z",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            }
          ]
        },
        {
          "name": "modified_at",
          "type": "TIMESTAMPTZ",
          "nullability": "required",
          "meaning": "Last time the Analytics row changed for polling and modifiedSince queries.",
          "constraints": "UTC timestamp; list endpoints support modifiedSince against this field.",
          "relationship": "Supports poll plus modifiedSince eventing.",
          "invalidWhen": "Client-supplied or used as the business effective date.",
          "example": "2026-06-10T00:51:14Z",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-107-axis-eventing",
              "title": "API Axis: Eventing Model",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-107-axis-eventing"
            },
            {
              "id": "aitd-103-axis-query-model",
              "title": "API Axis: Query Model",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-103-axis-query-model"
            }
          ]
        },
        {
          "name": "superseded_at",
          "type": "TIMESTAMPTZ",
          "nullability": "nullable",
          "meaning": "When this row stopped being the current reportable version because of source correction, deletion, or recalculation.",
          "constraints": "Null means current; non-null rows are excluded from ordinary list reads unless includeSuperseded=true and authorized.",
          "relationship": "Preserves audit history without mutating source Events or Results.",
          "invalidWhen": "Used to hard-delete old rows or omitted on a correction that replaces a prior fact.",
          "example": "null",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-111-axis-privacy-retention",
              "title": "API Axis: Privacy And Retention",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-111-axis-privacy-retention"
            },
            {
              "id": "aitd-012-corrections-and-reversals",
              "title": "Corrections Are Signed Facts With Provenance",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-012-corrections-and-reversals"
            }
          ]
        },
        {
          "name": "source_deleted_at",
          "type": "TIMESTAMPTZ",
          "nullability": "nullable",
          "meaning": "When the source Event/Result became deleted or invalidated.",
          "constraints": "Null for live source rows; set from source tombstone/correction notifications.",
          "relationship": "Ordinary reads exclude tombstoned facts unless includeSuperseded=true and authorized.",
          "invalidWhen": "Used as a physical delete or ignored by raw-path report queries.",
          "example": "null",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-111-axis-privacy-retention",
              "title": "API Axis: Privacy And Retention",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-111-axis-privacy-retention"
            }
          ]
        },
        {
          "name": "start_rit",
          "type": "NUMERIC(6,2)",
          "physicalType": "NUMERIC(6,2)",
          "nullability": "nullable when the window has no valid start sitting",
          "meaning": "RIT score at the start of the selected MAP growth window.",
          "constraints": "Comes from the selected NWEA window; never reverse-engineered from a grade label.",
          "relationship": "Pairs with rit_score and observed_growth for the named window.",
          "provenance": "Analytics materializer output governed by loop/context/ap-one-platform-capabilities-decision.md.",
          "invalidWhen": "The value is caller-computed, cross-tenant, or detached from the governed source relationship.",
          "example": 230,
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "r50_grade",
          "type": "NUMERIC(8,3)",
          "physicalType": "NUMERIC(8,3)",
          "nullability": "nullable",
          "meaning": "Median grade position for rit_score from the NWEAMAP-owned RIT-to-grade table.",
          "constraints": "Readable compatibility projection only; not actual course progress.",
          "relationship": "References alpha.analytics_r90_table / NWEAMAP PowerPath RIT-to-grade ownership.",
          "provenance": "Analytics materializer output governed by loop/context/ap-one-platform-capabilities-decision.md.",
          "invalidWhen": "The value is caller-computed, cross-tenant, or detached from the governed source relationship.",
          "example": 7.3,
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "r90_grade",
          "type": "NUMERIC(8,3)",
          "physicalType": "NUMERIC(8,3)",
          "nullability": "nullable",
          "meaning": "90th-percentile grade position for rit_score.",
          "constraints": "Readable compatibility projection only; not actual course progress.",
          "relationship": "References the NWEAMAP-owned RIT-to-grade table.",
          "provenance": "Analytics materializer output governed by loop/context/ap-one-platform-capabilities-decision.md.",
          "invalidWhen": "The value is caller-computed, cross-tenant, or detached from the governed source relationship.",
          "example": 4.8,
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "effective_grade",
          "type": "NUMERIC(8,3)",
          "physicalType": "NUMERIC(8,3)",
          "nullability": "nullable",
          "meaning": "MAP-inferred effective grade derived from the owned RIT-to-grade row.",
          "constraints": "A grade-position setup field, never course or grade-level completion.",
          "relationship": "Delegates to the NWEAMAP-owned PowerPath RIT-to-grade mapping.",
          "provenance": "Analytics materializer output governed by loop/context/ap-one-platform-capabilities-decision.md.",
          "invalidWhen": "The value is caller-computed, cross-tenant, or detached from the governed source relationship.",
          "example": 5,
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "r90_grade_level",
          "type": "INTEGER",
          "physicalType": "INTEGER",
          "nullability": "nullable",
          "meaning": "Integer grade band containing r90_grade.",
          "constraints": "Derived from the same owned RIT-to-grade row as r90_grade.",
          "relationship": "Compatibility projection for qualified MAP grade position.",
          "provenance": "Analytics materializer output governed by loop/context/ap-one-platform-capabilities-decision.md.",
          "invalidWhen": "The value is caller-computed, cross-tenant, or detached from the governed source relationship.",
          "example": 4,
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "r90_percent_complete",
          "type": "NUMERIC(8,3)",
          "physicalType": "NUMERIC(8,3)",
          "nullability": "nullable",
          "meaning": "Legacy compatibility percentage within the MAP-inferred RIT90 grade band.",
          "constraints": "Not actual course or grade-level progress; new consumers use the qualified rit90_grade_band_percent meaning.",
          "relationship": "Delegates to NWEAMAP RIT-to-grade evidence.",
          "provenance": "Analytics materializer output governed by loop/context/ap-one-platform-capabilities-decision.md.",
          "invalidWhen": "The value is caller-computed, cross-tenant, or detached from the governed source relationship.",
          "example": 80,
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "r90_table_version",
          "type": "TEXT",
          "physicalType": "TEXT",
          "nullability": "nullable",
          "meaning": "Version of the NWEAMAP-owned RIT-to-grade table used for the projection.",
          "constraints": "Must identify the exact owner table version.",
          "relationship": "Joins the row to its immutable RIT-to-grade reference data.",
          "provenance": "Analytics materializer output governed by loop/context/ap-one-platform-capabilities-decision.md.",
          "invalidWhen": "The value is caller-computed, cross-tenant, or detached from the governed source relationship.",
          "example": "analytics.rit_to_grade.powerpath.v2026-06-15",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "conditional_growth_percentile",
          "type": "NUMERIC(7,3)",
          "physicalType": "NUMERIC(7,3)",
          "nullability": "nullable",
          "meaning": "Canonical conditional growth percentile for the selected MAP window.",
          "constraints": "NWEA norm-edition-specific; growth_percentile is a compatibility alias.",
          "relationship": "References the same MAP window and norms set as observed_growth and projected_growth.",
          "provenance": "Analytics materializer output governed by loop/context/ap-one-platform-capabilities-decision.md.",
          "invalidWhen": "The value is caller-computed, cross-tenant, or detached from the governed source relationship.",
          "example": 43,
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        }
      ],
      "plainLanguage": "The MAP result row the Learning Report renders: RIT, achievement percentile, growth percentile, Growth X, norms set, growth window, retakes, and on-track flag."
    },
    {
      "name": "alpha.analytics_norms_achievement",
      "title": "NWEA Achievement Norms",
      "kind": "Alpha readable reference table",
      "grain": "norms_set x table_version x subject_id x role x grade_key x season.",
      "primaryKey": "resource_id; unique published grain is (norms_set, table_version, subject_id, role, grade_key, season).",
      "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.",
      "purpose": "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.",
      "metricChecks": [
        "RIT|GrowthX|MAP windows",
        "GOALS percentile-to-RIT"
      ],
      "architecture": [
        {
          "id": "aitd-015-norms-r90-readable-resources",
          "title": "NWEA Norms And NWEAMAP R90 Are Versioned, Readable Surface Reference Tables",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-015-norms-r90-readable-resources"
        },
        {
          "id": "aitd-016-scale-translation-apis",
          "title": "Percentile<->RIT And RIT->R90/Grade Are Server-Side Surface Translations",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-016-scale-translation-apis"
        },
        {
          "id": "aitd-009-map-growth-rollups",
          "title": "MAP RIT And Growth X Are Ingested From hp_map_results, Deduped, And Norms-Calculated",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-009-map-growth-rollups"
        },
        {
          "id": "aitd-011-policy-and-enum-normalization",
          "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
        },
        {
          "id": "aitd-112-axis-list-endpoints",
          "title": "API Axis: List Endpoints",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-112-axis-list-endpoints"
        }
      ],
      "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",
      "rawRule": "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.",
      "example": {
        "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"
      },
      "fields": [
        {
          "name": "resource_id",
          "type": "TEXT",
          "nullability": "required",
          "meaning": "Stable Analytics id for this norms reference row.",
          "constraints": "Generated by Analytics when the versioned table is published; unique across achievement norms rows.",
          "relationship": "Primary key for raw reads and /norms row paging.",
          "invalidWhen": "Caller-supplied, tenant-specific, or reused across table_version values.",
          "example": "norms_2025_math_g5_winter_student",
          "sourceClass": "Alpha readable reference id",
          "itds": [
            {
              "id": "aitd-015-norms-r90-readable-resources",
              "title": "NWEA Norms And NWEAMAP R90 Are Versioned, Readable Surface Reference Tables",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-015-norms-r90-readable-resources"
            }
          ]
        },
        {
          "name": "tenant_id",
          "type": "UUID",
          "nullability": "nullable; must be null for platform-global reference rows",
          "meaning": "Tenant scope marker. Achievement norms rows are platform-global reference data, so tenant_id is null by design.",
          "constraints": "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.",
          "relationship": "Separates global reference data from student-specific Analytics facts.",
          "invalidWhen": "A tenant-specific norms row exists or a raw query joins norms rows by student tenant to create a fork.",
          "example": "null",
          "sourceClass": "Alpha readable reference scope",
          "itds": [
            {
              "id": "aitd-015-norms-r90-readable-resources",
              "title": "NWEA Norms And NWEAMAP R90 Are Versioned, Readable Surface Reference Tables",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-015-norms-r90-readable-resources"
            },
            {
              "id": "aitd-109-axis-tenant-routing",
              "title": "API Axis: Tenant Routing",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-109-axis-tenant-routing"
            }
          ]
        },
        {
          "name": "norms_set",
          "type": "TEXT enum",
          "nullability": "required",
          "meaning": "NWEA norms family this achievement norms row belongs to.",
          "constraints": "Allowed values: norms_set enum. A table version belongs to exactly one norms_set.",
          "relationship": "Required input for /norms, /norms/rit, and /norms/percentile; prevents mixed-norm reports.",
          "invalidWhen": "A row omits norms_set, uses free-text labels, or mixes 2020 and 2025 values in one table_version.",
          "example": "2025",
          "enum": "norms_set",
          "sourceClass": "Alpha readable reference dimension",
          "itds": [
            {
              "id": "aitd-015-norms-r90-readable-resources",
              "title": "NWEA Norms And NWEAMAP R90 Are Versioned, Readable Surface Reference Tables",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-015-norms-r90-readable-resources"
            },
            {
              "id": "aitd-016-scale-translation-apis",
              "title": "Percentile<->RIT And RIT->R90/Grade Are Server-Side Surface Translations",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-016-scale-translation-apis"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "table_version",
          "type": "TEXT",
          "nullability": "required",
          "meaning": "Immutable version id of the published achievement norms table.",
          "constraints": "Stable, cacheable identifier; new source publication or correction creates a new version. Maximum 128 characters.",
          "relationship": "Part of every raw/API lookup. HTTP responses are cache-control: no-store; table_version is the reproducibility key.",
          "invalidWhen": "Rows are edited in place under the same version or a client caches without version.",
          "example": "analytics.norms.achievement.v2026-06-12",
          "sourceClass": "Alpha readable reference version",
          "itds": [
            {
              "id": "aitd-015-norms-r90-readable-resources",
              "title": "NWEA Norms And NWEAMAP R90 Are Versioned, Readable Surface Reference Tables",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-015-norms-r90-readable-resources"
            }
          ]
        },
        {
          "name": "subject_id",
          "type": "TEXT",
          "nullability": "required",
          "meaning": "Canonical Alpha subject for this achievement norms row.",
          "constraints": "Must be one of the MAP-supported Alpha subject values for the table version.",
          "relationship": "Part of percentile/RIT lookup grain.",
          "invalidWhen": "A source label such as Math K-12 or Language Usage is stored without write-time subject normalization.",
          "example": "math",
          "sourceClass": "Alpha extension reference",
          "itds": [
            {
              "id": "aitd-015-norms-r90-readable-resources",
              "title": "NWEA Norms And NWEAMAP R90 Are Versioned, Readable Surface Reference Tables",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-015-norms-r90-readable-resources"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "role",
          "type": "TEXT",
          "nullability": "required",
          "meaning": "NWEA role/population label for the norms row.",
          "constraints": "Governed by the published norms table. Current public student translations use role=student unless a future NWEA publication distinguishes another role.",
          "relationship": "Part of the achievement norms lookup grain.",
          "invalidWhen": "Dropped by a raw query, causing population-specific rows to be mixed if NWEA publishes them.",
          "example": "student",
          "sourceClass": "Alpha readable reference dimension",
          "itds": [
            {
              "id": "aitd-015-norms-r90-readable-resources",
              "title": "NWEA Norms And NWEAMAP R90 Are Versioned, Readable Surface Reference Tables",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-015-norms-r90-readable-resources"
            },
            {
              "id": "aitd-016-scale-translation-apis",
              "title": "Percentile<->RIT And RIT->R90/Grade Are Server-Side Surface Translations",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-016-scale-translation-apis"
            }
          ]
        },
        {
          "name": "grade_key",
          "type": "TEXT",
          "nullability": "required",
          "meaning": "NWEA grade key for this achievement norms row.",
          "constraints": "Governed grade label from the published norms table; examples include K and 1 through 12.",
          "relationship": "Used with subject_id and season for achievement-status lookup.",
          "invalidWhen": "Inferred from a student current grade or Alpha level tag instead of the published norms row.",
          "example": "5",
          "sourceClass": "Alpha readable reference dimension",
          "itds": [
            {
              "id": "aitd-015-norms-r90-readable-resources",
              "title": "NWEA Norms And NWEAMAP R90 Are Versioned, Readable Surface Reference Tables",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-015-norms-r90-readable-resources"
            },
            {
              "id": "aitd-016-scale-translation-apis",
              "title": "Percentile<->RIT And RIT->R90/Grade Are Server-Side Surface Translations",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-016-scale-translation-apis"
            }
          ]
        },
        {
          "name": "season",
          "type": "TEXT",
          "nullability": "required",
          "meaning": "MAP testing season for this achievement norms row.",
          "constraints": "Governed values for the table version: fall, winter, spring, or another NWEA-published season label.",
          "relationship": "Used by percentile-to-RIT and RIT-to-percentile translations.",
          "invalidWhen": "Parsed from report prose or mapped by a client-side term switch statement.",
          "example": "winter",
          "sourceClass": "Alpha readable reference dimension",
          "itds": [
            {
              "id": "aitd-015-norms-r90-readable-resources",
              "title": "NWEA Norms And NWEAMAP R90 Are Versioned, Readable Surface Reference Tables",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-015-norms-r90-readable-resources"
            },
            {
              "id": "aitd-016-scale-translation-apis",
              "title": "Percentile<->RIT And RIT->R90/Grade Are Server-Side Surface Translations",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-016-scale-translation-apis"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "mean_rit",
          "type": "NUMERIC(7,2)",
          "nullability": "required",
          "meaning": "Published mean RIT for this subject/role/grade/season row.",
          "constraints": "Positive numeric RIT value from the NWEA-published achievement-status norms; never estimated by a client.",
          "relationship": "Used by /norms/rit and /norms/percentile normal-model translations.",
          "invalidWhen": "Rounded differently per app or copied from an app-private norms table.",
          "example": "214.20",
          "sourceClass": "Alpha readable reference value",
          "itds": [
            {
              "id": "aitd-015-norms-r90-readable-resources",
              "title": "NWEA Norms And NWEAMAP R90 Are Versioned, Readable Surface Reference Tables",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-015-norms-r90-readable-resources"
            },
            {
              "id": "aitd-016-scale-translation-apis",
              "title": "Percentile<->RIT And RIT->R90/Grade Are Server-Side Surface Translations",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-016-scale-translation-apis"
            }
          ]
        },
        {
          "name": "sd_rit",
          "type": "NUMERIC(6,3)",
          "nullability": "required",
          "meaning": "Published standard deviation of RIT for this subject/role/grade/season row.",
          "constraints": "Must be positive. It is the denominator for RIT-to-percentile and multiplier for percentile-to-RIT.",
          "relationship": "Used by the normal-model translation APIs and raw-DB twin formula.",
          "invalidWhen": "Blank, zero, averaged from adjacent rows, or copied from a different norms_set.",
          "example": "14.100",
          "sourceClass": "Alpha readable reference value",
          "itds": [
            {
              "id": "aitd-015-norms-r90-readable-resources",
              "title": "NWEA Norms And NWEAMAP R90 Are Versioned, Readable Surface Reference Tables",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-015-norms-r90-readable-resources"
            },
            {
              "id": "aitd-016-scale-translation-apis",
              "title": "Percentile<->RIT And RIT->R90/Grade Are Server-Side Surface Translations",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-016-scale-translation-apis"
            }
          ]
        },
        {
          "name": "source_ref",
          "type": "TEXT",
          "nullability": "required",
          "meaning": "Opaque provenance pointer to the NWEA-published norms row in the NWEAMap 1EdTech raw mirror.",
          "constraints": "Must identify the source publication/row without copying a private app table.",
          "relationship": "References the NWEAMAP-owned PowerPath RIT-to-grade master; see https://platform3-andymontgomery-9773s-projects.vercel.app/nweamap/1edtech/data_dictionary.",
          "invalidWhen": "Points at a skill pack file, production app constant, or unversioned spreadsheet export.",
          "example": "nweamap:NormsReferenceData:2025:math:5:winter:student",
          "sourceClass": "Alpha readable reference provenance",
          "itds": [
            {
              "id": "aitd-015-norms-r90-readable-resources",
              "title": "NWEA Norms And NWEAMAP R90 Are Versioned, Readable Surface Reference Tables",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-015-norms-r90-readable-resources"
            }
          ]
        },
        {
          "name": "source_publication",
          "type": "TEXT",
          "nullability": "required",
          "meaning": "Human-readable source publication name for the norms table.",
          "constraints": "Names the NWEA publication behind source_ref; maximum 256 characters.",
          "relationship": "Lets parent/LLM readers understand where the table came from without source code.",
          "invalidWhen": "Blank, generic, or says Alpha extrapolation for an NWEA-published norms point.",
          "example": "NWEA MAP Growth achievement status norms, 2025",
          "sourceClass": "Alpha readable reference provenance",
          "itds": [
            {
              "id": "aitd-015-norms-r90-readable-resources",
              "title": "NWEA Norms And NWEAMAP R90 Are Versioned, Readable Surface Reference Tables",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-015-norms-r90-readable-resources"
            }
          ]
        },
        {
          "name": "is_current_version",
          "type": "BOOLEAN",
          "nullability": "required",
          "meaning": "Whether this table_version is the current default for its norms_set.",
          "constraints": "At most one current version per norms_set and table; historical versions remain readable.",
          "relationship": "Allows callers to request latest without losing reproducibility for pinned historical reports.",
          "invalidWhen": "Old versions are hidden/deleted or multiple versions are current for one norms_set.",
          "example": "true",
          "sourceClass": "Alpha readable reference version metadata",
          "itds": [
            {
              "id": "aitd-015-norms-r90-readable-resources",
              "title": "NWEA Norms And NWEAMAP R90 Are Versioned, Readable Surface Reference Tables",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-015-norms-r90-readable-resources"
            }
          ]
        },
        {
          "name": "published_at",
          "type": "TIMESTAMPTZ",
          "nullability": "required",
          "meaning": "When Analytics published this readable table version.",
          "constraints": "UTC timestamp; not a student test date.",
          "relationship": "Resource lifecycle/audit metadata.",
          "invalidWhen": "Used as a MAP term date or modified in place for corrections.",
          "example": "2026-06-12T00:00:00Z",
          "sourceClass": "Alpha readable reference lifecycle metadata",
          "itds": [
            {
              "id": "aitd-015-norms-r90-readable-resources",
              "title": "NWEA Norms And NWEAMAP R90 Are Versioned, Readable Surface Reference Tables",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-015-norms-r90-readable-resources"
            }
          ]
        },
        {
          "name": "quality_status",
          "type": "TEXT enum",
          "nullability": "required",
          "meaning": "Publication quality state for this reference row.",
          "constraints": "Current public rows use ok. Unpublished or failed rows are not returned by ordinary /norms reads.",
          "relationship": "Keeps reference publication failures visible to operators without fabricating translations.",
          "invalidWhen": "A row with policy_pending/source_missing is used in a translation response.",
          "example": "ok",
          "enum": "quality_status",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-015-norms-r90-readable-resources",
              "title": "NWEA Norms And NWEAMAP R90 Are Versioned, Readable Surface Reference Tables",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-015-norms-r90-readable-resources"
            },
            {
              "id": "aitd-108-axis-error-envelope",
              "title": "API Axis: Error Envelope",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-108-axis-error-envelope"
            }
          ]
        }
      ],
      "plainLanguage": "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."
    },
    {
      "name": "alpha.analytics_r90_table",
      "title": "R90 Table",
      "kind": "Alpha readable reference table",
      "grain": "table_version x table_subject_id x rit_score.",
      "primaryKey": "resource_id; unique published grain is (table_version, table_subject_id, rit_score).",
      "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.",
      "purpose": "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.",
      "metricChecks": [
        "RIT|GrowthX|MAP windows",
        "GOALS RIT-to-grade/R90"
      ],
      "architecture": [
        {
          "id": "aitd-015-norms-r90-readable-resources",
          "title": "NWEA Norms And NWEAMAP R90 Are Versioned, Readable Surface Reference Tables",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-015-norms-r90-readable-resources"
        },
        {
          "id": "aitd-016-scale-translation-apis",
          "title": "Percentile<->RIT And RIT->R90/Grade Are Server-Side Surface Translations",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-016-scale-translation-apis"
        },
        {
          "id": "aitd-017-r90-version-supersession",
          "title": "RIT-to-grade Table Versioning: PowerPath v2026-06-15 Is The Current Version, And One Named Config Picks It For Every Path",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-017-r90-version-supersession"
        },
        {
          "id": "aitd-009-map-growth-rollups",
          "title": "MAP RIT And Growth X Are Ingested From hp_map_results, Deduped, And Norms-Calculated",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-009-map-growth-rollups"
        },
        {
          "id": "aitd-011-policy-and-enum-normalization",
          "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
        },
        {
          "id": "aitd-112-axis-list-endpoints",
          "title": "API Axis: List Endpoints",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-112-axis-list-endpoints"
        }
      ],
      "api": "GET /alpha/analytics/v1/r90/table and GET /alpha/analytics/v1/r90",
      "rawRule": "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.",
      "example": {
        "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"
      },
      "fields": [
        {
          "name": "resource_id",
          "type": "TEXT",
          "nullability": "required",
          "meaning": "Stable Analytics id for this R90 reference row.",
          "constraints": "Generated by Analytics when the R90 table version is published; unique across R90 rows.",
          "relationship": "Primary key for raw reads and /r90 row paging.",
          "invalidWhen": "Caller-supplied or reused across table_version values.",
          "example": "r90_2025_math_239",
          "sourceClass": "Alpha readable reference id",
          "itds": [
            {
              "id": "aitd-015-norms-r90-readable-resources",
              "title": "NWEA Norms And NWEAMAP R90 Are Versioned, Readable Surface Reference Tables",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-015-norms-r90-readable-resources"
            }
          ]
        },
        {
          "name": "tenant_id",
          "type": "UUID",
          "nullability": "nullable; must be null for platform-global reference rows",
          "meaning": "Tenant scope marker. R90 rows are platform-global reference data, so tenant_id is null by design.",
          "constraints": "Apps authenticate with a tenant-scoped JWT, but the raw row itself is global. Tenant-specific R90 forks are forbidden.",
          "relationship": "Enforces the one-canonical-R90-copy decision.",
          "invalidWhen": "A tenant-local R90 table or row exists.",
          "example": "null",
          "sourceClass": "Alpha readable reference scope",
          "itds": [
            {
              "id": "aitd-015-norms-r90-readable-resources",
              "title": "NWEA Norms And NWEAMAP R90 Are Versioned, Readable Surface Reference Tables",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-015-norms-r90-readable-resources"
            },
            {
              "id": "aitd-109-axis-tenant-routing",
              "title": "API Axis: Tenant Routing",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-109-axis-tenant-routing"
            }
          ]
        },
        {
          "name": "norms_set",
          "type": "TEXT enum",
          "nullability": "required",
          "meaning": "NWEA norms family the R90 table version is tied to.",
          "constraints": "Allowed values: norms_set enum.",
          "relationship": "Required input for /r90/table and /r90.",
          "invalidWhen": "An R90 row is used without stating whether it belongs to the 2020 or 2025 norms.",
          "example": "2025",
          "enum": "norms_set",
          "sourceClass": "Alpha readable reference dimension",
          "itds": [
            {
              "id": "aitd-015-norms-r90-readable-resources",
              "title": "NWEA Norms And NWEAMAP R90 Are Versioned, Readable Surface Reference Tables",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-015-norms-r90-readable-resources"
            },
            {
              "id": "aitd-016-scale-translation-apis",
              "title": "Percentile<->RIT And RIT->R90/Grade Are Server-Side Surface Translations",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-016-scale-translation-apis"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "table_version",
          "type": "TEXT",
          "nullability": "required",
          "meaning": "Immutable version id of the published R90 table.",
          "constraints": "Stable, cacheable identifier; current reads use analytics.rit_to_grade.powerpath.v2026-06-15; a method or source change creates a new version.",
          "relationship": "Part of every raw/API lookup. HTTP responses are cache-control: no-store; table_version is the reproducibility key.",
          "invalidWhen": "Two different R90 methods share one version id, or a current raw read omits the current-version filter.",
          "example": "analytics.rit_to_grade.powerpath.v2026-06-15",
          "sourceClass": "Alpha readable reference version",
          "itds": [
            {
              "id": "aitd-015-norms-r90-readable-resources",
              "title": "NWEA Norms And NWEAMAP R90 Are Versioned, Readable Surface Reference Tables",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-015-norms-r90-readable-resources"
            },
            {
              "id": "aitd-017-r90-version-supersession",
              "title": "RIT-to-grade Table Versioning: PowerPath v2026-06-15 Is The Current Version, And One Named Config Picks It For Every Path",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-017-r90-version-supersession"
            }
          ]
        },
        {
          "name": "table_subject_id",
          "type": "TEXT",
          "nullability": "required",
          "meaning": "Canonical table subject for this R90 row.",
          "constraints": "Must be one of the supported MAP/GOALS subject values for the table version.",
          "relationship": "Part of RIT-to-grade/R90 lookup grain.",
          "invalidWhen": "A report maps subject labels locally before looking up R90.",
          "example": "math",
          "sourceClass": "Alpha readable reference dimension",
          "itds": [
            {
              "id": "aitd-015-norms-r90-readable-resources",
              "title": "NWEA Norms And NWEAMAP R90 Are Versioned, Readable Surface Reference Tables",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-015-norms-r90-readable-resources"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "rit_score",
          "type": "NUMERIC(7,2)",
          "nullability": "required",
          "meaning": "Observed RIT score from the PowerPath source row represented by this R90/grade row.",
          "constraints": "Unique within (table_version, table_subject_id); current raw/API lookups use this as the exact key.",
          "relationship": "Exact lookup key for /rit-to-grade and legacy /r90.",
          "invalidWhen": "Duplicated within a subject/version, or a report uses grade2rit.csv as an observed-RIT inverse.",
          "example": "239.00",
          "sourceClass": "Alpha readable reference dimension",
          "itds": [
            {
              "id": "aitd-015-norms-r90-readable-resources",
              "title": "NWEA Norms And NWEAMAP R90 Are Versioned, Readable Surface Reference Tables",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-015-norms-r90-readable-resources"
            },
            {
              "id": "aitd-016-scale-translation-apis",
              "title": "Percentile<->RIT And RIT->R90/Grade Are Server-Side Surface Translations",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-016-scale-translation-apis"
            },
            {
              "id": "aitd-017-r90-version-supersession",
              "title": "RIT-to-grade Table Versioning: PowerPath v2026-06-15 Is The Current Version, And One Named Config Picks It For Every Path",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-017-r90-version-supersession"
            }
          ]
        },
        {
          "name": "rit50_rit",
          "type": "NUMERIC(7,2)",
          "nullability": "required",
          "meaning": "Compatibility anchor for older RIT50/RIT90 reports; in the current PowerPath version this equals the observed RIT source row.",
          "constraints": "Current version uses the PowerPath RIT value. Apps must not use this field to reconstruct the current lookup method.",
          "relationship": "Retained so older report templates that require the headline RIT50/RIT90 fields still receive a surfaced value.",
          "invalidWhen": "Recomputed or rounded differently by an app.",
          "example": "239.00",
          "sourceClass": "Alpha readable reference compatibility value",
          "itds": [
            {
              "id": "aitd-015-norms-r90-readable-resources",
              "title": "NWEA Norms And NWEAMAP R90 Are Versioned, Readable Surface Reference Tables",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-015-norms-r90-readable-resources"
            },
            {
              "id": "aitd-016-scale-translation-apis",
              "title": "Percentile<->RIT And RIT->R90/Grade Are Server-Side Surface Translations",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-016-scale-translation-apis"
            },
            {
              "id": "aitd-017-r90-version-supersession",
              "title": "RIT-to-grade Table Versioning: PowerPath v2026-06-15 Is The Current Version, And One Named Config Picks It For Every Path",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-017-r90-version-supersession"
            }
          ]
        },
        {
          "name": "rit90_rit",
          "type": "NUMERIC(7,2)",
          "nullability": "required",
          "meaning": "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.",
          "constraints": "Must be produced by r90_method_ref; because NWEA does not publish R90 directly, rows carry extend_kind=alpha_extrapolation.",
          "relationship": "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.",
          "invalidWhen": "Copied from a private app table or undocumented production constant.",
          "example": "239.00",
          "sourceClass": "Alpha readable reference compatibility value",
          "itds": [
            {
              "id": "aitd-015-norms-r90-readable-resources",
              "title": "NWEA Norms And NWEAMAP R90 Are Versioned, Readable Surface Reference Tables",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-015-norms-r90-readable-resources"
            },
            {
              "id": "aitd-016-scale-translation-apis",
              "title": "Percentile<->RIT And RIT->R90/Grade Are Server-Side Surface Translations",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-016-scale-translation-apis"
            },
            {
              "id": "aitd-017-r90-version-supersession",
              "title": "RIT-to-grade Table Versioning: PowerPath v2026-06-15 Is The Current Version, And One Named Config Picks It For Every Path",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-017-r90-version-supersession"
            }
          ]
        },
        {
          "name": "r90_grade",
          "type": "NUMERIC(8,3)",
          "nullability": "required",
          "meaning": "Grade-position value from the selected PowerPath row.",
          "constraints": "Governed display/ordering value from the R90 table version; must be reproducible from the same row.",
          "relationship": "Returned by /r90 and read by GOALS when converting a RIT target to grade progress.",
          "invalidWhen": "Computed by a consumer from a private RIT-to-grade table.",
          "example": "4.800",
          "sourceClass": "Alpha readable reference value",
          "itds": [
            {
              "id": "aitd-015-norms-r90-readable-resources",
              "title": "NWEA Norms And NWEAMAP R90 Are Versioned, Readable Surface Reference Tables",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-015-norms-r90-readable-resources"
            },
            {
              "id": "aitd-016-scale-translation-apis",
              "title": "Percentile<->RIT And RIT->R90/Grade Are Server-Side Surface Translations",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-016-scale-translation-apis"
            },
            {
              "id": "aitd-017-r90-version-supersession",
              "title": "RIT-to-grade Table Versioning: PowerPath v2026-06-15 Is The Current Version, And One Named Config Picks It For Every Path",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-017-r90-version-supersession"
            }
          ]
        },
        {
          "name": "effective_grade",
          "type": "INTEGER",
          "nullability": "required",
          "meaning": "Plain report-ready grade/effective-grade label produced by the R90 method.",
          "constraints": "Governed display label; must be reproducible from the same row and method version.",
          "relationship": "Used by Learning Report placement/progress and GOALS.",
          "invalidWhen": "Derived client-side from a local RIT-to-grade table.",
          "example": "5",
          "sourceClass": "Alpha readable reference value",
          "itds": [
            {
              "id": "aitd-015-norms-r90-readable-resources",
              "title": "NWEA Norms And NWEAMAP R90 Are Versioned, Readable Surface Reference Tables",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-015-norms-r90-readable-resources"
            },
            {
              "id": "aitd-016-scale-translation-apis",
              "title": "Percentile<->RIT And RIT->R90/Grade Are Server-Side Surface Translations",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-016-scale-translation-apis"
            },
            {
              "id": "aitd-017-r90-version-supersession",
              "title": "RIT-to-grade Table Versioning: PowerPath v2026-06-15 Is The Current Version, And One Named Config Picks It For Every Path",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-017-r90-version-supersession"
            }
          ]
        },
        {
          "name": "r90_grade_level",
          "type": "INTEGER",
          "nullability": "required",
          "meaning": "Governed grade-level bucket for this R90 row.",
          "constraints": "Integer floor of r90_grade under the current PowerPath method.",
          "relationship": "Supports GOALS and Learning Report grouping without parsing effective_grade text.",
          "invalidWhen": "Derived by splitting display text client-side.",
          "example": "4",
          "sourceClass": "Alpha readable reference value",
          "itds": [
            {
              "id": "aitd-015-norms-r90-readable-resources",
              "title": "NWEA Norms And NWEAMAP R90 Are Versioned, Readable Surface Reference Tables",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-015-norms-r90-readable-resources"
            },
            {
              "id": "aitd-016-scale-translation-apis",
              "title": "Percentile<->RIT And RIT->R90/Grade Are Server-Side Surface Translations",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-016-scale-translation-apis"
            },
            {
              "id": "aitd-017-r90-version-supersession",
              "title": "RIT-to-grade Table Versioning: PowerPath v2026-06-15 Is The Current Version, And One Named Config Picks It For Every Path",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-017-r90-version-supersession"
            }
          ]
        },
        {
          "name": "r90_percent_complete",
          "type": "NUMERIC(7,3)",
          "nullability": "required",
          "meaning": "MAP-inferred percent through the R90 grade band represented by this RIT row.",
          "constraints": "Usually 0 through 100 inside a grade band; computed by the documented R90 method and immutable for the table_version.",
          "relationship": "Used by GOALS to describe grade-band position. It is not actual work progress and must not populate course or grade-level completion.",
          "invalidWhen": "Calculated in GOALS or Learning Report code from a private table, or treated as actual course/grade-level progress.",
          "example": "80.000",
          "sourceClass": "Alpha readable reference value",
          "itds": [
            {
              "id": "aitd-015-norms-r90-readable-resources",
              "title": "NWEA Norms And NWEAMAP R90 Are Versioned, Readable Surface Reference Tables",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-015-norms-r90-readable-resources"
            },
            {
              "id": "aitd-016-scale-translation-apis",
              "title": "Percentile<->RIT And RIT->R90/Grade Are Server-Side Surface Translations",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-016-scale-translation-apis"
            },
            {
              "id": "aitd-017-r90-version-supersession",
              "title": "RIT-to-grade Table Versioning: PowerPath v2026-06-15 Is The Current Version, And One Named Config Picks It For Every Path",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-017-r90-version-supersession"
            }
          ]
        },
        {
          "name": "alpha_min_rit",
          "type": "NUMERIC(7,2)",
          "nullability": "nullable when the Alpha minimum rule does not apply to the row",
          "meaning": "Alpha Minimum RIT associated with this R90/effective-grade band.",
          "constraints": "Nullable in the current PowerPath version; no app-side override.",
          "relationship": "Feeds GOALS and progress predictions.",
          "invalidWhen": "Hard-coded in GOALS or Learning Report code.",
          "example": "null",
          "sourceClass": "Alpha readable reference value",
          "itds": [
            {
              "id": "aitd-015-norms-r90-readable-resources",
              "title": "NWEA Norms And NWEAMAP R90 Are Versioned, Readable Surface Reference Tables",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-015-norms-r90-readable-resources"
            },
            {
              "id": "aitd-016-scale-translation-apis",
              "title": "Percentile<->RIT And RIT->R90/Grade Are Server-Side Surface Translations",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-016-scale-translation-apis"
            }
          ]
        },
        {
          "name": "alpha_predicted_rit",
          "type": "NUMERIC(7,2)",
          "nullability": "nullable when no Alpha predicted value is published for the row",
          "meaning": "Alpha predicted RIT associated with this band under the current R90 method.",
          "constraints": "Set by the documented Alpha method and table_version; current PowerPath version uses the selected observed RIT.",
          "relationship": "Used for GOALS/prediction workflows as a surface value.",
          "invalidWhen": "Computed by a consumer from private expected-growth assumptions.",
          "example": "239.00",
          "sourceClass": "Alpha readable reference value",
          "itds": [
            {
              "id": "aitd-015-norms-r90-readable-resources",
              "title": "NWEA Norms And NWEAMAP R90 Are Versioned, Readable Surface Reference Tables",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-015-norms-r90-readable-resources"
            },
            {
              "id": "aitd-016-scale-translation-apis",
              "title": "Percentile<->RIT And RIT->R90/Grade Are Server-Side Surface Translations",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-016-scale-translation-apis"
            },
            {
              "id": "aitd-017-r90-version-supersession",
              "title": "RIT-to-grade Table Versioning: PowerPath v2026-06-15 Is The Current Version, And One Named Config Picks It For Every Path",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-017-r90-version-supersession"
            }
          ]
        },
        {
          "name": "extend_kind",
          "type": "TEXT",
          "nullability": "required",
          "meaning": "Honest source classification for this row.",
          "constraints": "Allowed value for R90-derived rows: alpha_extrapolation. NWEA-published 50%-correct points may be represented through exact_nwea_point=true.",
          "relationship": "Makes the ALPHA-4 tension visible: R90 is not an NWEA-published field.",
          "invalidWhen": "R90 rows are presented as NWEA-published facts.",
          "example": "alpha_extrapolation",
          "sourceClass": "Alpha readable reference provenance",
          "itds": [
            {
              "id": "aitd-015-norms-r90-readable-resources",
              "title": "NWEA Norms And NWEAMAP R90 Are Versioned, Readable Surface Reference Tables",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-015-norms-r90-readable-resources"
            }
          ]
        },
        {
          "name": "r90_method_ref",
          "type": "TEXT",
          "nullability": "required",
          "meaning": "Named method/policy version that produced R90, effective_grade, alpha_min_rit, and alpha_predicted_rit.",
          "constraints": "Stable versioned R90 method policy reference, for example alpha.policy.analytics.r90_method.v2026-06-12; changing the method creates a new table_version.",
          "relationship": "Lets raw readers reproduce why a row is Alpha extrapolation rather than NWEA pass-through.",
          "invalidWhen": "Blank, unversioned, or stored only in app code.",
          "example": "alpha.policy.analytics.r90_method.v2026-06-12",
          "sourceClass": "Alpha readable reference method",
          "itds": [
            {
              "id": "aitd-015-norms-r90-readable-resources",
              "title": "NWEA Norms And NWEAMAP R90 Are Versioned, Readable Surface Reference Tables",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-015-norms-r90-readable-resources"
            },
            {
              "id": "aitd-016-scale-translation-apis",
              "title": "Percentile<->RIT And RIT->R90/Grade Are Server-Side Surface Translations",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-016-scale-translation-apis"
            },
            {
              "id": "aitd-017-r90-version-supersession",
              "title": "RIT-to-grade Table Versioning: PowerPath v2026-06-15 Is The Current Version, And One Named Config Picks It For Every Path",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-017-r90-version-supersession"
            }
          ]
        },
        {
          "name": "source_norms_refs",
          "type": "JSONB",
          "nullability": "required",
          "meaning": "Published/source refs that anchor this Alpha R90 extrapolation.",
          "constraints": "Array of opaque refs/hashes; no raw private app table data.",
          "relationship": "References the NWEAMap 1EdTech raw mirror; see https://platform3-andymontgomery-9773s-projects.vercel.app/nweamap/1edtech/data_dictionary.",
          "invalidWhen": "Points at an app-owned R90 file or has no provenance.",
          "example": "[\"powerpath:/powerpath/rit-to-grade\", \"powerpath:2026-06-15:Math:RIT:239\"]",
          "sourceClass": "Alpha readable reference provenance",
          "itds": [
            {
              "id": "aitd-015-norms-r90-readable-resources",
              "title": "NWEA Norms And NWEAMAP R90 Are Versioned, Readable Surface Reference Tables",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-015-norms-r90-readable-resources"
            },
            {
              "id": "aitd-017-r90-version-supersession",
              "title": "RIT-to-grade Table Versioning: PowerPath v2026-06-15 Is The Current Version, And One Named Config Picks It For Every Path",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-017-r90-version-supersession"
            }
          ]
        },
        {
          "name": "exact_nwea_point",
          "type": "BOOLEAN",
          "nullability": "required",
          "meaning": "Whether the row value being referenced is an exact NWEA-published point.",
          "constraints": "false for Alpha R90 extrapolations; true only for values reproduced directly from NWEA-published data.",
          "relationship": "Lets apps and parents distinguish NWEA pass-through from Alpha extrapolation.",
          "invalidWhen": "true on a rit90_rit value that NWEA did not publish.",
          "example": "false",
          "sourceClass": "Alpha readable reference provenance",
          "itds": [
            {
              "id": "aitd-015-norms-r90-readable-resources",
              "title": "NWEA Norms And NWEAMAP R90 Are Versioned, Readable Surface Reference Tables",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-015-norms-r90-readable-resources"
            }
          ]
        },
        {
          "name": "source_point_kind",
          "type": "TEXT enum",
          "nullability": "required",
          "meaning": "How the /r90 lookup should describe the source point for this row or translated response.",
          "constraints": "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.",
          "relationship": "Carries the step-floor behavior promised by AITD-016/AITD-017 instead of forcing apps to extrapolate.",
          "invalidWhen": "Missing on a translation response or replaced with a silent nearest-value lookup.",
          "example": "exact",
          "enum": "source_point_kind",
          "sourceClass": "Alpha readable reference lookup metadata",
          "itds": [
            {
              "id": "aitd-015-norms-r90-readable-resources",
              "title": "NWEA Norms And NWEAMAP R90 Are Versioned, Readable Surface Reference Tables",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-015-norms-r90-readable-resources"
            },
            {
              "id": "aitd-016-scale-translation-apis",
              "title": "Percentile<->RIT And RIT->R90/Grade Are Server-Side Surface Translations",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-016-scale-translation-apis"
            },
            {
              "id": "aitd-017-r90-version-supersession",
              "title": "RIT-to-grade Table Versioning: PowerPath v2026-06-15 Is The Current Version, And One Named Config Picks It For Every Path",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-017-r90-version-supersession"
            }
          ]
        },
        {
          "name": "is_current_version",
          "type": "BOOLEAN",
          "nullability": "required",
          "meaning": "Whether this table_version is the current default for its norms_set.",
          "constraints": "At most one current R90 version per norms_set; current is analytics.rit_to_grade.powerpath.v2026-06-15.",
          "relationship": "Supports latest reads while preserving historical reproducibility.",
          "invalidWhen": "Historical versions are deleted or multiple current versions exist.",
          "example": "true",
          "sourceClass": "Alpha readable reference version metadata",
          "itds": [
            {
              "id": "aitd-015-norms-r90-readable-resources",
              "title": "NWEA Norms And NWEAMAP R90 Are Versioned, Readable Surface Reference Tables",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-015-norms-r90-readable-resources"
            },
            {
              "id": "aitd-017-r90-version-supersession",
              "title": "RIT-to-grade Table Versioning: PowerPath v2026-06-15 Is The Current Version, And One Named Config Picks It For Every Path",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-017-r90-version-supersession"
            }
          ]
        },
        {
          "name": "published_at",
          "type": "TIMESTAMPTZ",
          "nullability": "required",
          "meaning": "When Analytics published this R90 table version.",
          "constraints": "UTC timestamp; not a student result date.",
          "relationship": "Resource lifecycle/audit metadata.",
          "invalidWhen": "Used as a MAP term date.",
          "example": "2026-06-14T00:00:00Z",
          "sourceClass": "Alpha readable reference lifecycle metadata",
          "itds": [
            {
              "id": "aitd-015-norms-r90-readable-resources",
              "title": "NWEA Norms And NWEAMAP R90 Are Versioned, Readable Surface Reference Tables",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-015-norms-r90-readable-resources"
            },
            {
              "id": "aitd-017-r90-version-supersession",
              "title": "RIT-to-grade Table Versioning: PowerPath v2026-06-15 Is The Current Version, And One Named Config Picks It For Every Path",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-017-r90-version-supersession"
            }
          ]
        },
        {
          "name": "quality_status",
          "type": "TEXT enum",
          "nullability": "required",
          "meaning": "Publication quality state for this R90 reference row.",
          "constraints": "Current public rows use ok. Failed or unpublished rows are not returned by ordinary /r90/table or /r90 reads.",
          "relationship": "Keeps reference publication failures visible to operators without fabricating translations.",
          "invalidWhen": "A non-ok row is used to answer a report or GOALS translation.",
          "example": "ok",
          "enum": "quality_status",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-015-norms-r90-readable-resources",
              "title": "NWEA Norms And NWEAMAP R90 Are Versioned, Readable Surface Reference Tables",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-015-norms-r90-readable-resources"
            },
            {
              "id": "aitd-108-axis-error-envelope",
              "title": "API Axis: Error Envelope",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-108-axis-error-envelope"
            }
          ]
        }
      ],
      "plainLanguage": "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."
    },
    {
      "name": "analytics.school_days_remaining",
      "title": "School Days Remaining Response",
      "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.",
      "primaryKey": "No stored primary key. The deterministic request grain is student_id, school_id, as_of, end_date, school_day_policy_ref, and effort inputs.",
      "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.",
      "purpose": "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.",
      "metricChecks": [
        "GOALS target date",
        "GOALS school-days-remaining"
      ],
      "architecture": [
        {
          "id": "aitd-018-goals-school-days-remaining",
          "title": "GOALS School-Days-Remaining Read And XP Expected-Minute Unit Live On Analytics",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-018-goals-school-days-remaining"
        },
        {
          "id": "aitd-006-school-day-minutes",
          "title": "Minutes Per Enrolled School Day Uses The Alpha School Calendar",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-006-school-day-minutes"
        },
        {
          "id": "aitd-007-xp-rollups",
          "title": "XP Totals, Goal, Remaining, And Completion Percent Are Ingested Report Facts",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-007-xp-rollups"
        },
        {
          "id": "aitd-016-scale-translation-apis",
          "title": "Percentile<->RIT And RIT->R90/Grade Are Server-Side Surface Translations",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-016-scale-translation-apis"
        },
        {
          "id": "aitd-011-policy-and-enum-normalization",
          "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
        }
      ],
      "api": "GET /alpha/analytics/v1/school-days-remaining",
      "rawRule": "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.",
      "example": {
        "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"
        }
      },
      "fields": [
        {
          "name": "object",
          "type": "TEXT",
          "nullability": "required",
          "meaning": "Response object discriminator for this endpoint.",
          "constraints": "Always analytics.school_days_remaining.",
          "relationship": "Lets docs, skill packs, and contract checks identify the response shape.",
          "invalidWhen": "Missing or replaced with a generic list object.",
          "example": "analytics.school_days_remaining",
          "sourceClass": "Analytics response metadata",
          "itds": [
            {
              "id": "aitd-018-goals-school-days-remaining",
              "title": "GOALS School-Days-Remaining Read And XP Expected-Minute Unit Live On Analytics",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-018-goals-school-days-remaining"
            }
          ]
        },
        {
          "name": "student_id",
          "type": "TEXT",
          "nullability": "required",
          "meaning": "Canonical Alpha student id whose enrolled school calendar is used for the forward count.",
          "constraints": "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.",
          "relationship": "References People and Orgs student identity; see https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/data_dictionary.",
          "invalidWhen": "GOALS supplies a name/email or a current-only student lookup.",
          "example": "student_01HT7G3YZV7QB5N4YKQ1K0Z9A9",
          "sourceClass": "Alpha extension reference",
          "itds": [
            {
              "id": "aitd-018-goals-school-days-remaining",
              "title": "GOALS School-Days-Remaining Read And XP Expected-Minute Unit Live On Analytics",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-018-goals-school-days-remaining"
            },
            {
              "id": "aitd-006-school-day-minutes",
              "title": "Minutes Per Enrolled School Day Uses The Alpha School Calendar",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-006-school-day-minutes"
            },
            {
              "id": "aitd-106-axis-auth-shape",
              "title": "API Axis: Auth Shape",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-106-axis-auth-shape"
            }
          ]
        },
        {
          "name": "school_id",
          "type": "TEXT",
          "nullability": "required",
          "meaning": "School whose alpha.school_calendar rows were read for the forward window.",
          "constraints": "Resolved from request schoolId or the student effective-dated enrollment. Must be one real People and Orgs school.",
          "relationship": "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).",
          "invalidWhen": "Inferred from a display campus string or current-only school assignment outside the requested date.",
          "example": "school_alpha_austin",
          "sourceClass": "Alpha reference",
          "itds": [
            {
              "id": "aitd-018-goals-school-days-remaining",
              "title": "GOALS School-Days-Remaining Read And XP Expected-Minute Unit Live On Analytics",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-018-goals-school-days-remaining"
            },
            {
              "id": "aitd-006-school-day-minutes",
              "title": "Minutes Per Enrolled School Day Uses The Alpha School Calendar",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-006-school-day-minutes"
            }
          ]
        },
        {
          "name": "as_of",
          "type": "DATE",
          "nullability": "required",
          "meaning": "Inclusive start date for the forward school-day count.",
          "constraints": "ISO date. The response uses the half-open window [as_of, end_date).",
          "relationship": "Alias of the asOf request parameter.",
          "invalidWhen": "Treated as exclusive or defaulted to server time without request provenance.",
          "example": "2026-06-14",
          "sourceClass": "Request-derived response field",
          "itds": [
            {
              "id": "aitd-018-goals-school-days-remaining",
              "title": "GOALS School-Days-Remaining Read And XP Expected-Minute Unit Live On Analytics",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-018-goals-school-days-remaining"
            }
          ]
        },
        {
          "name": "end_date",
          "type": "DATE",
          "nullability": "required",
          "meaning": "Exclusive end date for the forward school-day count.",
          "constraints": "ISO date; must be after as_of. If omitted by request, Analytics uses the policy-defined GOALS school-year end.",
          "relationship": "Alias of endDate/schoolYearEnd request parameter.",
          "invalidWhen": "Treated as inclusive, or guessed by a client from a local school-year calendar.",
          "example": "2026-07-24",
          "sourceClass": "Request/policy-derived response field",
          "itds": [
            {
              "id": "aitd-018-goals-school-days-remaining",
              "title": "GOALS School-Days-Remaining Read And XP Expected-Minute Unit Live On Analytics",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-018-goals-school-days-remaining"
            },
            {
              "id": "aitd-006-school-day-minutes",
              "title": "Minutes Per Enrolled School Day Uses The Alpha School Calendar",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-006-school-day-minutes"
            }
          ]
        },
        {
          "name": "school_day_policy_ref",
          "type": "TEXT",
          "nullability": "required",
          "meaning": "Policy ref used to decide which calendar rows count as instructional school days.",
          "constraints": "Current value: alpha.policy.school_day.v2026-06-10. The policy excludes MAP-testing days.",
          "relationship": "Same policy family as alpha.analytics_school_day_minutes.school_day_policy_ref.",
          "invalidWhen": "Blank, unversioned, or replaced by local weekday filtering.",
          "example": "alpha.policy.school_day.v2026-06-10",
          "sourceClass": "Policy reference",
          "itds": [
            {
              "id": "aitd-018-goals-school-days-remaining",
              "title": "GOALS School-Days-Remaining Read And XP Expected-Minute Unit Live On Analytics",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-018-goals-school-days-remaining"
            },
            {
              "id": "aitd-006-school-day-minutes",
              "title": "Minutes Per Enrolled School Day Uses The Alpha School Calendar",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-006-school-day-minutes"
            }
          ]
        },
        {
          "name": "instructional_days_remaining",
          "type": "INTEGER",
          "nullability": "required",
          "meaning": "Count of remaining instructional school days in [as_of, end_date) after calendar, enrollment, and MAP-day exclusion rules.",
          "constraints": "Nonnegative integer. Zero is valid and means no instructional days remain in the requested window.",
          "relationship": "GOALS target-date denominator.",
          "invalidWhen": "Computed from weekdays, attendance days, active dates, or private school-period bounds.",
          "example": "29",
          "sourceClass": "Derived response value",
          "itds": [
            {
              "id": "aitd-018-goals-school-days-remaining",
              "title": "GOALS School-Days-Remaining Read And XP Expected-Minute Unit Live On Analytics",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-018-goals-school-days-remaining"
            },
            {
              "id": "aitd-006-school-day-minutes",
              "title": "Minutes Per Enrolled School Day Uses The Alpha School Calendar",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-006-school-day-minutes"
            }
          ]
        },
        {
          "name": "calendar_ref_count",
          "type": "INTEGER",
          "nullability": "required",
          "meaning": "Count of alpha.school_calendar rows inspected for the requested window before instructional-day filtering.",
          "constraints": "Nonnegative; not the same as instructional_days_remaining.",
          "relationship": "Audit summary for calendar coverage.",
          "invalidWhen": "Rendered as school days remaining or computed from raw date span length.",
          "example": "40",
          "sourceClass": "Audit response value",
          "itds": [
            {
              "id": "aitd-018-goals-school-days-remaining",
              "title": "GOALS School-Days-Remaining Read And XP Expected-Minute Unit Live On Analytics",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-018-goals-school-days-remaining"
            },
            {
              "id": "aitd-006-school-day-minutes",
              "title": "Minutes Per Enrolled School Day Uses The Alpha School Calendar",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-006-school-day-minutes"
            },
            {
              "id": "aitd-102-axis-read-shape",
              "title": "API Axis: Read Shape",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-102-axis-read-shape"
            }
          ]
        },
        {
          "name": "first_instructional_date",
          "type": "DATE",
          "nullability": "nullable when instructional_days_remaining=0",
          "meaning": "First counted instructional date in the requested window.",
          "constraints": "Must be one of instructional_dates when present.",
          "relationship": "GOALS display and audit field.",
          "invalidWhen": "A non-null date appears while instructional_days_remaining=0.",
          "example": "2026-06-15",
          "sourceClass": "Derived response value",
          "itds": [
            {
              "id": "aitd-018-goals-school-days-remaining",
              "title": "GOALS School-Days-Remaining Read And XP Expected-Minute Unit Live On Analytics",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-018-goals-school-days-remaining"
            },
            {
              "id": "aitd-006-school-day-minutes",
              "title": "Minutes Per Enrolled School Day Uses The Alpha School Calendar",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-006-school-day-minutes"
            }
          ]
        },
        {
          "name": "last_instructional_date",
          "type": "DATE",
          "nullability": "nullable when instructional_days_remaining=0",
          "meaning": "Last counted instructional date in the requested window.",
          "constraints": "Must be one of instructional_dates when present and must be before end_date.",
          "relationship": "GOALS display and audit field.",
          "invalidWhen": "Equals end_date when end_date is exclusive, unless end_date itself is not counted and this is a prior date.",
          "example": "2026-07-23",
          "sourceClass": "Derived response value",
          "itds": [
            {
              "id": "aitd-018-goals-school-days-remaining",
              "title": "GOALS School-Days-Remaining Read And XP Expected-Minute Unit Live On Analytics",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-018-goals-school-days-remaining"
            },
            {
              "id": "aitd-006-school-day-minutes",
              "title": "Minutes Per Enrolled School Day Uses The Alpha School Calendar",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-006-school-day-minutes"
            }
          ]
        },
        {
          "name": "instructional_dates",
          "type": "DATE[]",
          "nullability": "required",
          "meaning": "The counted instructional dates returned by the surface for this request.",
          "constraints": "Array length must equal instructional_days_remaining. Values are ISO dates, sorted ascending, and all satisfy the school-day policy.",
          "relationship": "GOALS may render or cache the returned dates by request, but must not recreate them from a private calendar.",
          "invalidWhen": "Unsorted, includes MAP-testing/non-school dates, includes end_date, or differs in length from instructional_days_remaining.",
          "example": "[\"2026-06-15\",\"2026-06-16\",\"2026-06-17\"]",
          "sourceClass": "Derived response value",
          "itds": [
            {
              "id": "aitd-018-goals-school-days-remaining",
              "title": "GOALS School-Days-Remaining Read And XP Expected-Minute Unit Live On Analytics",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-018-goals-school-days-remaining"
            },
            {
              "id": "aitd-006-school-day-minutes",
              "title": "Minutes Per Enrolled School Day Uses The Alpha School Calendar",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-006-school-day-minutes"
            }
          ]
        },
        {
          "name": "xp_unit.policy_ref",
          "type": "TEXT",
          "nullability": "required",
          "meaning": "Versioned policy that defines XP-to-expected-minute conversion.",
          "constraints": "Current value: alpha.policy.analytics.xp_expected_minute.v2026-06-14.",
          "relationship": "Resolves to the XP Expected-Minute Unit policy on this page.",
          "invalidWhen": "Omitted while effort fields are returned, or replaced by a client constant.",
          "example": "alpha.policy.analytics.xp_expected_minute.v2026-06-14",
          "sourceClass": "Policy reference",
          "itds": [
            {
              "id": "aitd-018-goals-school-days-remaining",
              "title": "GOALS School-Days-Remaining Read And XP Expected-Minute Unit Live On Analytics",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-018-goals-school-days-remaining"
            },
            {
              "id": "aitd-007-xp-rollups",
              "title": "XP Totals, Goal, Remaining, And Completion Percent Are Ingested Report Facts",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-007-xp-rollups"
            }
          ]
        },
        {
          "name": "xp_unit.xp_per_expected_minute",
          "type": "NUMERIC(8,3)",
          "nullability": "required",
          "meaning": "How many XP equal one expected minute.",
          "constraints": "Current value is 1.000. It is policy, not a client constant.",
          "relationship": "Used to compute effort.expected_minutes_remaining.",
          "invalidWhen": "GOALS hard-codes a different value or infers it from observed student actuals.",
          "example": "1.000",
          "sourceClass": "Policy response value",
          "itds": [
            {
              "id": "aitd-018-goals-school-days-remaining",
              "title": "GOALS School-Days-Remaining Read And XP Expected-Minute Unit Live On Analytics",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-018-goals-school-days-remaining"
            },
            {
              "id": "aitd-007-xp-rollups",
              "title": "XP Totals, Goal, Remaining, And Completion Percent Are Ingested Report Facts",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-007-xp-rollups"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "xp_unit.xp_per_hour",
          "type": "NUMERIC(8,3)",
          "nullability": "required",
          "meaning": "How many XP equal one expected hour.",
          "constraints": "Current value is 60.000. Derived from 1 XP per expected minute and 60 minutes per hour.",
          "relationship": "Used to compute effort.hours_remaining.",
          "invalidWhen": "Hard-coded in a skill pack or GOALS client instead of read from the surface.",
          "example": "60.000",
          "sourceClass": "Policy response value",
          "itds": [
            {
              "id": "aitd-018-goals-school-days-remaining",
              "title": "GOALS School-Days-Remaining Read And XP Expected-Minute Unit Live On Analytics",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-018-goals-school-days-remaining"
            },
            {
              "id": "aitd-007-xp-rollups",
              "title": "XP Totals, Goal, Remaining, And Completion Percent Are Ingested Report Facts",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-007-xp-rollups"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "xp_unit.meaning",
          "type": "TEXT",
          "nullability": "required",
          "meaning": "Plain-language statement of the XP expected-minute convention.",
          "constraints": "Must state 1 XP = 1 expected minute and 60 XP = 1 expected hour.",
          "relationship": "Allows parent-readable docs and skill packs to explain the conversion without source code.",
          "invalidWhen": "Absent or inconsistent with xp_per_expected_minute/xp_per_hour.",
          "example": "1 XP = 1 expected minute; 60 XP = 1 expected hour.",
          "sourceClass": "Policy response text",
          "itds": [
            {
              "id": "aitd-018-goals-school-days-remaining",
              "title": "GOALS School-Days-Remaining Read And XP Expected-Minute Unit Live On Analytics",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-018-goals-school-days-remaining"
            },
            {
              "id": "aitd-007-xp-rollups",
              "title": "XP Totals, Goal, Remaining, And Completion Percent Are Ingested Report Facts",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-007-xp-rollups"
            }
          ]
        },
        {
          "name": "effort.xp_remaining",
          "type": "NUMERIC(14,3)",
          "nullability": "nullable unless request supplies xpRemaining",
          "meaning": "Remaining XP supplied by the caller or read from related XP rollup flow for effort projection.",
          "constraints": "Nonnegative when present. Mutually exclusive request inputs xpRemaining, minutesRemaining, and hoursRemaining collapse to expected_minutes_remaining.",
          "relationship": "Same XP unit convention as alpha.analytics_xp_rollup.xp_remaining.",
          "invalidWhen": "Negative, or derived by GOALS from a private XP goal formula.",
          "example": "600.000",
          "sourceClass": "Request-derived effort value",
          "itds": [
            {
              "id": "aitd-018-goals-school-days-remaining",
              "title": "GOALS School-Days-Remaining Read And XP Expected-Minute Unit Live On Analytics",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-018-goals-school-days-remaining"
            },
            {
              "id": "aitd-007-xp-rollups",
              "title": "XP Totals, Goal, Remaining, And Completion Percent Are Ingested Report Facts",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-007-xp-rollups"
            }
          ]
        },
        {
          "name": "effort.expected_minutes_remaining",
          "type": "NUMERIC(14,3)",
          "nullability": "nullable unless any effort input is supplied",
          "meaning": "Remaining effort normalized to expected minutes under the XP expected-minute policy.",
          "constraints": "Nonnegative when present.",
          "relationship": "Source for hours_remaining and pacing fields.",
          "invalidWhen": "Computed locally with a private XP_PER_HOUR constant.",
          "example": "600.000",
          "sourceClass": "Derived response value",
          "itds": [
            {
              "id": "aitd-018-goals-school-days-remaining",
              "title": "GOALS School-Days-Remaining Read And XP Expected-Minute Unit Live On Analytics",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-018-goals-school-days-remaining"
            },
            {
              "id": "aitd-007-xp-rollups",
              "title": "XP Totals, Goal, Remaining, And Completion Percent Are Ingested Report Facts",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-007-xp-rollups"
            }
          ]
        },
        {
          "name": "effort.hours_remaining",
          "type": "NUMERIC(14,3)",
          "nullability": "nullable unless any effort input is supplied",
          "meaning": "Remaining effort in expected hours.",
          "constraints": "expected_minutes_remaining / 60 under xp_unit.xp_per_hour.",
          "relationship": "GOALS hours-to-target-date display.",
          "invalidWhen": "Computed locally or rounded differently from the surface.",
          "example": "10.000",
          "sourceClass": "Derived response value",
          "itds": [
            {
              "id": "aitd-018-goals-school-days-remaining",
              "title": "GOALS School-Days-Remaining Read And XP Expected-Minute Unit Live On Analytics",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-018-goals-school-days-remaining"
            },
            {
              "id": "aitd-007-xp-rollups",
              "title": "XP Totals, Goal, Remaining, And Completion Percent Are Ingested Report Facts",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-007-xp-rollups"
            }
          ]
        },
        {
          "name": "effort.target_date",
          "type": "DATE",
          "nullability": "nullable unless targetDate is supplied",
          "meaning": "Requested target date for required-hours-per-school-day projection.",
          "constraints": "Must be after as_of and on or before end_date when supplied.",
          "relationship": "Alias of request targetDate.",
          "invalidWhen": "Before/as_of or after the requested end_date.",
          "example": "2026-07-24",
          "sourceClass": "Request-derived response field",
          "itds": [
            {
              "id": "aitd-018-goals-school-days-remaining",
              "title": "GOALS School-Days-Remaining Read And XP Expected-Minute Unit Live On Analytics",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-018-goals-school-days-remaining"
            }
          ]
        },
        {
          "name": "effort.school_days_until_target_date",
          "type": "INTEGER",
          "nullability": "nullable unless targetDate is supplied",
          "meaning": "Instructional days from as_of through the target-date window according to the same school-day policy.",
          "constraints": "Nonnegative; uses the same half-open counting convention against targetDate as the endpoint documents.",
          "relationship": "Denominator for required_hours_per_school_day_to_target_date.",
          "invalidWhen": "Counts calendar days, weekdays, or dates outside instructional_dates.",
          "example": "29",
          "sourceClass": "Derived response value",
          "itds": [
            {
              "id": "aitd-018-goals-school-days-remaining",
              "title": "GOALS School-Days-Remaining Read And XP Expected-Minute Unit Live On Analytics",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-018-goals-school-days-remaining"
            },
            {
              "id": "aitd-006-school-day-minutes",
              "title": "Minutes Per Enrolled School Day Uses The Alpha School Calendar",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-006-school-day-minutes"
            }
          ]
        },
        {
          "name": "effort.required_hours_per_school_day_to_target_date",
          "type": "NUMERIC(12,3)",
          "nullability": "nullable unless targetDate and effort are supplied and target window has school days",
          "meaning": "Expected hours per remaining instructional day needed to finish by targetDate.",
          "constraints": "hours_remaining / school_days_until_target_date; null when school_days_until_target_date=0.",
          "relationship": "GOALS target-date pacing value.",
          "invalidWhen": "Computed over calendar days or rounded in client code.",
          "example": "0.345",
          "sourceClass": "Derived response value",
          "itds": [
            {
              "id": "aitd-018-goals-school-days-remaining",
              "title": "GOALS School-Days-Remaining Read And XP Expected-Minute Unit Live On Analytics",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-018-goals-school-days-remaining"
            },
            {
              "id": "aitd-007-xp-rollups",
              "title": "XP Totals, Goal, Remaining, And Completion Percent Are Ingested Report Facts",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-007-xp-rollups"
            }
          ]
        },
        {
          "name": "effort.hours_per_school_day",
          "type": "NUMERIC(12,3)",
          "nullability": "nullable unless request supplies hoursPerSchoolDay",
          "meaning": "Caller-supplied planned expected hours per instructional day.",
          "constraints": "Must be positive when supplied.",
          "relationship": "Input for school_days_needed_at_hours_per_school_day.",
          "invalidWhen": "Zero, negative, or interpreted as clock-hours available on non-school days.",
          "example": "1.500",
          "sourceClass": "Request-derived effort value",
          "itds": [
            {
              "id": "aitd-018-goals-school-days-remaining",
              "title": "GOALS School-Days-Remaining Read And XP Expected-Minute Unit Live On Analytics",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-018-goals-school-days-remaining"
            }
          ]
        },
        {
          "name": "effort.school_days_needed_at_hours_per_school_day",
          "type": "INTEGER",
          "nullability": "nullable unless hoursPerSchoolDay and effort are supplied",
          "meaning": "Instructional-day count needed to finish at the supplied pace.",
          "constraints": "ceil(hours_remaining / hoursPerSchoolDay).",
          "relationship": "GOALS date-at-pace calculation.",
          "invalidWhen": "Counts weekdays or rounds down.",
          "example": "7",
          "sourceClass": "Derived response value",
          "itds": [
            {
              "id": "aitd-018-goals-school-days-remaining",
              "title": "GOALS School-Days-Remaining Read And XP Expected-Minute Unit Live On Analytics",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-018-goals-school-days-remaining"
            },
            {
              "id": "aitd-007-xp-rollups",
              "title": "XP Totals, Goal, Remaining, And Completion Percent Are Ingested Report Facts",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-007-xp-rollups"
            }
          ]
        },
        {
          "name": "effort.target_date_at_hours_per_school_day",
          "type": "DATE",
          "nullability": "nullable unless the supplied pace finishes inside the requested window",
          "meaning": "Instructional date reached at the supplied pace.",
          "constraints": "Must be one of instructional_dates when present; null when the window is too short.",
          "relationship": "GOALS predicted finish date at the supplied pace.",
          "invalidWhen": "Falls on a non-school/MAP day or after end_date without null/false finish status.",
          "example": "2026-06-23",
          "sourceClass": "Derived response value",
          "itds": [
            {
              "id": "aitd-018-goals-school-days-remaining",
              "title": "GOALS School-Days-Remaining Read And XP Expected-Minute Unit Live On Analytics",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-018-goals-school-days-remaining"
            },
            {
              "id": "aitd-006-school-day-minutes",
              "title": "Minutes Per Enrolled School Day Uses The Alpha School Calendar",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-006-school-day-minutes"
            },
            {
              "id": "aitd-007-xp-rollups",
              "title": "XP Totals, Goal, Remaining, And Completion Percent Are Ingested Report Facts",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-007-xp-rollups"
            }
          ]
        },
        {
          "name": "effort.can_finish_by_end_date_at_hours_per_school_day",
          "type": "BOOLEAN",
          "nullability": "nullable unless hoursPerSchoolDay and effort are supplied",
          "meaning": "Whether the supplied pace finishes within the requested forward window.",
          "constraints": "True only when school_days_needed_at_hours_per_school_day <= instructional_days_remaining.",
          "relationship": "GOALS finishability flag.",
          "invalidWhen": "True while target_date_at_hours_per_school_day is null.",
          "example": "true",
          "sourceClass": "Derived response value",
          "itds": [
            {
              "id": "aitd-018-goals-school-days-remaining",
              "title": "GOALS School-Days-Remaining Read And XP Expected-Minute Unit Live On Analytics",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-018-goals-school-days-remaining"
            },
            {
              "id": "aitd-007-xp-rollups",
              "title": "XP Totals, Goal, Remaining, And Completion Percent Are Ingested Report Facts",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-007-xp-rollups"
            }
          ]
        },
        {
          "name": "provenance.source",
          "type": "TEXT",
          "nullability": "required",
          "meaning": "Plain source statement for the calendar/enrollment rows behind the response.",
          "constraints": "Must name alpha.school_calendar over Ed-Fi CalendarDate and People and Orgs enrollment.",
          "relationship": "Points readers to the raw-DB path without exposing PII payloads.",
          "invalidWhen": "Claims weekday math or a private GOALS school-period table as the source.",
          "example": "alpha.school_calendar over ed_fi.CalendarDate plus People and Orgs enrollment",
          "sourceClass": "Provenance response field",
          "itds": [
            {
              "id": "aitd-018-goals-school-days-remaining",
              "title": "GOALS School-Days-Remaining Read And XP Expected-Minute Unit Live On Analytics",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-018-goals-school-days-remaining"
            },
            {
              "id": "aitd-006-school-day-minutes",
              "title": "Minutes Per Enrolled School Day Uses The Alpha School Calendar",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-006-school-day-minutes"
            }
          ]
        },
        {
          "name": "provenance.source_ref_sample",
          "type": "TEXT[]",
          "nullability": "nullable",
          "meaning": "Opaque sample refs for calendar rows used by the read.",
          "constraints": "May include refs/hashes only; no raw calendar payload or student PII.",
          "relationship": "Audit pointer for operators.",
          "invalidWhen": "Contains raw source rows or student names/emails.",
          "example": "[\"calendar_date:school_alpha_austin:2026-06-15\"]",
          "sourceClass": "Provenance response field",
          "itds": [
            {
              "id": "aitd-018-goals-school-days-remaining",
              "title": "GOALS School-Days-Remaining Read And XP Expected-Minute Unit Live On Analytics",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-018-goals-school-days-remaining"
            },
            {
              "id": "aitd-111-axis-privacy-retention",
              "title": "API Axis: Privacy And Retention",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-111-axis-privacy-retention"
            }
          ]
        },
        {
          "name": "provenance.policy_ref",
          "type": "TEXT",
          "nullability": "required",
          "meaning": "School-day policy ref used for the calendar count.",
          "constraints": "Must match school_day_policy_ref.",
          "relationship": "Audit-friendly duplicate for the provenance block.",
          "invalidWhen": "Differs from school_day_policy_ref.",
          "example": "alpha.policy.school_day.v2026-06-10",
          "sourceClass": "Policy provenance field",
          "itds": [
            {
              "id": "aitd-018-goals-school-days-remaining",
              "title": "GOALS School-Days-Remaining Read And XP Expected-Minute Unit Live On Analytics",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-018-goals-school-days-remaining"
            },
            {
              "id": "aitd-006-school-day-minutes",
              "title": "Minutes Per Enrolled School Day Uses The Alpha School Calendar",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-006-school-day-minutes"
            }
          ]
        },
        {
          "name": "provenance.xp_unit_policy_ref",
          "type": "TEXT",
          "nullability": "required",
          "meaning": "XP expected-minute policy ref used for effort projection.",
          "constraints": "Must match alpha.policy.analytics.xp_expected_minute.v2026-06-14.",
          "relationship": "Audit-friendly pointer to the XP unit policy.",
          "invalidWhen": "Missing while effort or xp_unit fields are returned.",
          "example": "alpha.policy.analytics.xp_expected_minute.v2026-06-14",
          "sourceClass": "Policy provenance field",
          "itds": [
            {
              "id": "aitd-018-goals-school-days-remaining",
              "title": "GOALS School-Days-Remaining Read And XP Expected-Minute Unit Live On Analytics",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-018-goals-school-days-remaining"
            },
            {
              "id": "aitd-007-xp-rollups",
              "title": "XP Totals, Goal, Remaining, And Completion Percent Are Ingested Report Facts",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-007-xp-rollups"
            }
          ]
        },
        {
          "name": "links.self",
          "type": "URL",
          "nullability": "required",
          "meaning": "The request URL for this read.",
          "constraints": "Must preserve the effective query parameters used to produce the answer.",
          "relationship": "Useful for skill-pack reproduction and support.",
          "invalidWhen": "Missing or points at a stale/non-equivalent query.",
          "example": "/alpha/analytics/v1/school-days-remaining?studentId=student_01HT7G3YZV7QB5N4YKQ1K0Z9A9&asOf=2026-06-14&endDate=2026-07-24",
          "sourceClass": "Response link",
          "itds": [
            {
              "id": "aitd-018-goals-school-days-remaining",
              "title": "GOALS School-Days-Remaining Read And XP Expected-Minute Unit Live On Analytics",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-018-goals-school-days-remaining"
            },
            {
              "id": "aitd-102-axis-read-shape",
              "title": "API Axis: Read Shape",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-102-axis-read-shape"
            }
          ]
        },
        {
          "name": "links.schoolDayMinutes",
          "type": "URL",
          "nullability": "required",
          "meaning": "Related consumed-day rollup endpoint for past Time Commitment rows.",
          "constraints": "This is a related link, not the source for future-day counts.",
          "relationship": "Points to alpha.analytics_school_day_minutes when a report also needs consumed days.",
          "invalidWhen": "Used to answer future school-days remaining when no consumed-day row exists.",
          "example": "/alpha/analytics/v1/school-day-minutes?studentId=student_01HT7G3YZV7QB5N4YKQ1K0Z9A9&windowKind=school_year",
          "sourceClass": "Response link",
          "itds": [
            {
              "id": "aitd-018-goals-school-days-remaining",
              "title": "GOALS School-Days-Remaining Read And XP Expected-Minute Unit Live On Analytics",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-018-goals-school-days-remaining"
            },
            {
              "id": "aitd-006-school-day-minutes",
              "title": "Minutes Per Enrolled School Day Uses The Alpha School Calendar",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-006-school-day-minutes"
            }
          ]
        },
        {
          "name": "links.xpRollups",
          "type": "URL",
          "nullability": "required",
          "meaning": "Related XP rollup endpoint for XP total/remaining/goal rows.",
          "constraints": "GOALS may use the rollup to obtain xp_remaining, then pass it into this endpoint for effort projection.",
          "relationship": "Points to alpha.analytics_xp_rollup.",
          "invalidWhen": "Used as permission to calculate XP goal fields locally.",
          "example": "/alpha/analytics/v1/xp-rollups?studentId=student_01HT7G3YZV7QB5N4YKQ1K0Z9A9&windowKind=school_year",
          "sourceClass": "Response link",
          "itds": [
            {
              "id": "aitd-018-goals-school-days-remaining",
              "title": "GOALS School-Days-Remaining Read And XP Expected-Minute Unit Live On Analytics",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-018-goals-school-days-remaining"
            },
            {
              "id": "aitd-007-xp-rollups",
              "title": "XP Totals, Goal, Remaining, And Completion Percent Are Ingested Report Facts",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-007-xp-rollups"
            }
          ]
        }
      ],
      "plainLanguage": "The GOALS endpoint response object: remaining instructional days and XP-to-time effort projections from the surface calendar and XP expected-minute policy."
    },
    {
      "name": "analytics.grade_level_status",
      "title": "Grade-Level Status Response",
      "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.",
      "primaryKey": "No stored primary key. The deterministic request grain is student_id, subject_id, and as_of_date.",
      "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.",
      "purpose": "GOALS age-grade status without local comparison logic: exactly two named comparisons, working vs age grade and mastered vs age grade.",
      "metricChecks": [
        "GOALS age-grade status",
        "GOALS ahead/at/behind"
      ],
      "architecture": [
        {
          "id": "aitd-102-axis-read-shape",
          "title": "API Axis: Read Shape",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-102-axis-read-shape"
        },
        {
          "id": "aitd-008-mastery-and-grade-levels",
          "title": "Grade Levels Mastered Are Ingested; Mastery Deltas Read Results State",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-008-mastery-and-grade-levels"
        },
        {
          "id": "aitd-011-policy-and-enum-normalization",
          "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
        },
        {
          "id": "aitd-112-axis-list-endpoints",
          "title": "API Axis: List Endpoints",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-112-axis-list-endpoints"
        }
      ],
      "api": "GET /alpha/analytics/v1/grade-level-status",
      "rawRule": "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.",
      "example": {
        "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"
        }
      },
      "fields": [
        {
          "name": "object",
          "type": "TEXT",
          "nullability": "required",
          "meaning": "Response object discriminator for this endpoint.",
          "constraints": "Always analytics.grade_level_status.",
          "relationship": "Lets docs, skill packs, and contract checks identify the response shape.",
          "invalidWhen": "Missing or replaced by a generic status object.",
          "example": "analytics.grade_level_status",
          "sourceClass": "Analytics response metadata",
          "itds": [
            {
              "id": "aitd-102-axis-read-shape",
              "title": "API Axis: Read Shape",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-102-axis-read-shape"
            }
          ]
        },
        {
          "name": "student_id",
          "type": "TEXT",
          "nullability": "required",
          "meaning": "Canonical Alpha student id used to read P&O age grade and Results grade positions.",
          "constraints": "Must resolve to the same student across People and Orgs and Results source tenants.",
          "relationship": "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).",
          "invalidWhen": "Name/email/local app id is used directly.",
          "example": "b6fa7128-f641-4efd-9075-375411fd6c39",
          "sourceClass": "Alpha extension reference",
          "itds": [
            {
              "id": "aitd-102-axis-read-shape",
              "title": "API Axis: Read Shape",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-102-axis-read-shape"
            },
            {
              "id": "aitd-109-axis-tenant-routing",
              "title": "API Axis: Tenant Routing",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-109-axis-tenant-routing"
            }
          ]
        },
        {
          "name": "subject_id",
          "type": "TEXT enum",
          "nullability": "required",
          "meaning": "Canonical subject for Results working grade and HMG lookup.",
          "constraints": "Use Analytics/Results governed subject ids; subject aliases normalize at the platform boundary.",
          "relationship": "Same governed subject id family as other Analytics report endpoints.",
          "invalidWhen": "Parsed from MAP test names or course titles by a client.",
          "example": "math",
          "enum": "subject_id",
          "sourceClass": "Request-derived response field",
          "itds": [
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "as_of_date",
          "type": "DATE",
          "nullability": "required",
          "meaning": "Date used for the point-in-time P&O age-grade row and Results state read.",
          "constraints": "ISO date. The response does not default age grade from a current-only scalar.",
          "relationship": "Drives the effective-dated age-grade and Results state reads.",
          "invalidWhen": "Ignored or replaced by server-now without provenance.",
          "example": "2026-05-20",
          "sourceClass": "Request-derived response field",
          "itds": [
            {
              "id": "aitd-102-axis-read-shape",
              "title": "API Axis: Read Shape",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-102-axis-read-shape"
            }
          ]
        },
        {
          "name": "age_grade",
          "type": "INTEGER",
          "nullability": "nullable when P&O has no active age-grade history row",
          "meaning": "Student's school-assigned cohort grade for school-year reporting as of as_of_date.",
          "constraints": "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.",
          "relationship": "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.",
          "invalidWhen": "Computed from achievement, parsed from labels, or copied into Results.",
          "example": "5",
          "sourceClass": "People and Orgs source fact",
          "itds": [
            {
              "id": "aitd-102-axis-read-shape",
              "title": "API Axis: Read Shape",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-102-axis-read-shape"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "working_grade",
          "type": "INTEGER",
          "nullability": "nullable when Results has no working-grade state",
          "meaning": "Results-owned working grade for the subject and as_of_date.",
          "constraints": "Read from Results; Analytics does not recompute the working-grade resolver.",
          "relationship": "Owned by Results student track state; see https://platform3-andymontgomery-9773s-projects.vercel.app/results/alpha/data_dictionary.",
          "invalidWhen": "Derived from MAP/RIT/R90 or duplicated into P&O.",
          "example": "6",
          "sourceClass": "Results source fact",
          "itds": [
            {
              "id": "aitd-008-mastery-and-grade-levels",
              "title": "Grade Levels Mastered Are Ingested; Mastery Deltas Read Results State",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-008-mastery-and-grade-levels"
            },
            {
              "id": "aitd-102-axis-read-shape",
              "title": "API Axis: Read Shape",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-102-axis-read-shape"
            }
          ]
        },
        {
          "name": "highest_mastered_grade",
          "type": "INTEGER",
          "nullability": "nullable when Results has no HMG state",
          "meaning": "Results-owned highest mastered grade for the subject and as_of_date.",
          "constraints": "Read from Results; strict mastery-vs-age status uses this field directly.",
          "relationship": "Owned by Results highest-mastered state; see https://platform3-andymontgomery-9773s-projects.vercel.app/results/alpha/data_dictionary.",
          "invalidWhen": "Inferred from working grade without Results provenance.",
          "example": "5",
          "sourceClass": "Results source fact",
          "itds": [
            {
              "id": "aitd-008-mastery-and-grade-levels",
              "title": "Grade Levels Mastered Are Ingested; Mastery Deltas Read Results State",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-008-mastery-and-grade-levels"
            },
            {
              "id": "aitd-102-axis-read-shape",
              "title": "API Axis: Read Shape",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-102-axis-read-shape"
            }
          ]
        },
        {
          "name": "working_age_grade_delta",
          "type": "INTEGER",
          "nullability": "nullable when age_grade or working_grade is missing",
          "meaning": "Signed difference between working_grade and age_grade.",
          "constraints": "Formula: working_grade - age_grade.",
          "relationship": "Drives working_age_grade_status.",
          "invalidWhen": "Computed against HMG or MAP-inferred grade position.",
          "example": "1",
          "sourceClass": "Derived response value",
          "itds": [
            {
              "id": "aitd-102-axis-read-shape",
              "title": "API Axis: Read Shape",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-102-axis-read-shape"
            }
          ]
        },
        {
          "name": "working_age_grade_status",
          "type": "TEXT enum",
          "nullability": "required",
          "meaning": "Named working-vs-age status.",
          "constraints": "Allowed values: working_behind_age_grade, working_at_age_grade, working_above_age_grade, unknown.",
          "relationship": "Preferred GOALS ahead/at/behind status field.",
          "invalidWhen": "Replaced by generic ahead/at/behind or instructional_level_status as preferred public contract.",
          "example": "working_above_age_grade",
          "sourceClass": "Derived response label",
          "itds": [
            {
              "id": "aitd-102-axis-read-shape",
              "title": "API Axis: Read Shape",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-102-axis-read-shape"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "mastered_age_grade_delta",
          "type": "INTEGER",
          "nullability": "nullable when age_grade or highest_mastered_grade is missing",
          "meaning": "Signed difference between highest_mastered_grade and age_grade.",
          "constraints": "Formula: highest_mastered_grade - age_grade.",
          "relationship": "Drives mastered_age_grade_status.",
          "invalidWhen": "Computed from working grade or MAP-inferred grade position.",
          "example": "0",
          "sourceClass": "Derived response value",
          "itds": [
            {
              "id": "aitd-102-axis-read-shape",
              "title": "API Axis: Read Shape",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-102-axis-read-shape"
            }
          ]
        },
        {
          "name": "mastered_age_grade_status",
          "type": "TEXT enum",
          "nullability": "required",
          "meaning": "Named strict mastery-vs-age status.",
          "constraints": "Allowed values: mastered_behind_age_grade, mastered_at_age_grade, mastered_above_age_grade, unknown.",
          "relationship": "Separate qualified read from working_age_grade_status.",
          "invalidWhen": "Used as the default GOALS working status or hidden under generic mastery_level_status.",
          "example": "mastered_at_age_grade",
          "sourceClass": "Derived response label",
          "itds": [
            {
              "id": "aitd-102-axis-read-shape",
              "title": "API Axis: Read Shape",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-102-axis-read-shape"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "source_refs",
          "type": "JSON object",
          "nullability": "required",
          "meaning": "Machine-readable owner pointers for the facts used by the response.",
          "constraints": "Must name P&O for age grade and Results for working/HMG.",
          "relationship": "Prevents clients and doers from moving ownership into Analytics.",
          "invalidWhen": "Missing, names Analytics as the owner of age_grade/HMG, or points at MAP/RIT.",
          "example": "{\"age_grade\":\"people_and_orgs.alpha.age_grade_history\",\"working_grade\":\"results.student_track_state.working_grade\",\"highest_mastered_grade\":\"results.highest_mastered_grade\"}",
          "sourceClass": "Provenance response field",
          "itds": [
            {
              "id": "aitd-004-provenance-no-literals",
              "title": "Every Report Value Traces To An Ingested Source Row, Or Reads Null",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-004-provenance-no-literals"
            },
            {
              "id": "aitd-102-axis-read-shape",
              "title": "API Axis: Read Shape",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-102-axis-read-shape"
            }
          ]
        },
        {
          "name": "deprecated_aliases",
          "type": "JSON object",
          "nullability": "nullable compatibility block",
          "meaning": "Compatibility mapping for old field names; not the preferred public contract.",
          "constraints": "If served, instructional_level_status delegates to working_age_grade_status and strict_mastery_status delegates to mastered_age_grade_status.",
          "relationship": "Allows old consumers to migrate without reintroducing generic status terminology.",
          "invalidWhen": "Documented as preferred or computed with different formulas.",
          "example": "{\"instructional_level_status\":\"working_age_grade_status\",\"strict_mastery_status\":\"mastered_age_grade_status\"}",
          "sourceClass": "Compatibility metadata",
          "itds": [
            {
              "id": "aitd-102-axis-read-shape",
              "title": "API Axis: Read Shape",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-102-axis-read-shape"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        }
      ],
      "plainLanguage": "The GOALS endpoint response object: P&O age grade plus Results working/HMG positions and the two named age-grade comparisons."
    },
    {
      "name": "alpha.analytics_completion_rollup",
      "title": "Completion Rollup",
      "kind": "Alpha extension rollup table",
      "grain": "student_id x completion_scope x scope_id x window_start x window_end x policy_ref.",
      "primaryKey": "id; unique current grain is (tenant_id, student_id, completion_scope, scope_id, window_start, window_end, policy_ref, calculation_version).",
      "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. Probe/eval tenants (reviewer-analytics, analytics-*debug*) are operational stores: retention keeps current rows and sweeps superseded rows under alpha.policy.analytics.completion_rollup_retention.v2026-07-03.",
      "purpose": "Progress evidence for Results and Analytics audits without MAP/RIT/R90 inference, client-side Curriculum tree walking, or Results-row counting.",
      "metricChecks": [
        "completion|curriculum refs"
      ],
      "architecture": [
        {
          "id": "aitd-010-completion-rollups",
          "title": "Completion Percent Is Ingested Earned XP Over A Curriculum Denominator, Never Invented",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-010-completion-rollups"
        },
        {
          "id": "aitd-001-report-source-ingestion",
          "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
        },
        {
          "id": "aitd-004-provenance-no-literals",
          "title": "Every Report Value Traces To An Ingested Source Row, Or Reads Null",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-004-provenance-no-literals"
        },
        {
          "id": "aitd-003-close-time-materialization",
          "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
        },
        {
          "id": "aitd-011-policy-and-enum-normalization",
          "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
        }
      ],
      "api": "GET /alpha/analytics/v1/completion-rollups",
      "rawRule": "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. Raw/API readers must filter to current rows before sorting or paging; reviewer/debug probe row count is bounded by current rollup-key cardinality, not by historical probe runs.",
      "example": {
        "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
      },
      "fields": [
        {
          "name": "id",
          "type": "UUID",
          "nullability": "required",
          "meaning": "Analytics-owned stable row id for this derived fact.",
          "constraints": "Generated by the platform; globally unique within alpha.analytics_* objects.",
          "relationship": "Primary key for list/detail endpoints.",
          "invalidWhen": "Provided by a public import client or reused across tenants.",
          "example": "8e9c0ef2-bc75-4f53-8124-df77df49f25f",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-000-extend-only-storage",
              "title": "Analytics Is New Extend-Only Alpha Storage",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-000-extend-only-storage"
            }
          ]
        },
        {
          "name": "tenant_id",
          "type": "UUID",
          "nullability": "required",
          "meaning": "Tenant boundary for the derived fact.",
          "constraints": "Set from the JWT tenant claim or internal materializer context; never accepted from request body/query.",
          "relationship": "All raw-path queries must filter by tenant_id before joining, sorting, paging, or counting.",
          "invalidWhen": "Missing, caller-supplied in body/query, or mismatched with the JWT tenant claim.",
          "example": "7b0bb5d8-9a38-4a62-9fdc-9f8d2dc1a111",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-109-axis-tenant-routing",
              "title": "API Axis: Tenant Routing",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-109-axis-tenant-routing"
            },
            {
              "id": "aitd-106-axis-auth-shape",
              "title": "API Axis: Auth Shape",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-106-axis-auth-shape"
            }
          ]
        },
        {
          "name": "student_id",
          "type": "TEXT",
          "nullability": "required",
          "meaning": "Canonical Alpha student id the source Event or Result resolved to at materialization time.",
          "constraints": "Must resolve through People and Orgs as a real student for the source timestamp/effective date.",
          "relationship": "References People and Orgs student identity; see https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/data_dictionary.",
          "invalidWhen": "Parsed from email/name/source payload instead of resolved by the Events/Results adapter.",
          "example": "student_01HT7G3YZV7QB5N4YKQ1K0Z9A9",
          "sourceClass": "Alpha extension reference",
          "itds": [
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            },
            {
              "id": "aitd-106-axis-auth-shape",
              "title": "API Axis: Auth Shape",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-106-axis-auth-shape"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "completion_scope",
          "type": "TEXT enum",
          "nullability": "required",
          "meaning": "Curriculum/reporting scope for this completion measure.",
          "constraints": "Allowed values: completion_scope enum.",
          "relationship": "Determines what scope_id points to.",
          "invalidWhen": "A consumer invents separate columns per course/track/segment instead of using the typed scope.",
          "example": "course",
          "enum": "completion_scope",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-010-completion-rollups",
              "title": "Completion Percent Is Ingested Earned XP Over A Curriculum Denominator, Never Invented",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-010-completion-rollups"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "scope_id",
          "type": "TEXT",
          "nullability": "required",
          "meaning": "Identifier of the Curriculum or subject scope being measured.",
          "constraints": "Must match completion_scope: course id for course, subject id for subject, track id for track, etc.",
          "relationship": "References Curriculum scope refs; see https://platform3-andymontgomery-9773s-projects.vercel.app/curriculum/alpha/data_dictionary.",
          "invalidWhen": "A report walks the course tree and generates its own scope id.",
          "example": "course_math_grade_4_powerpath",
          "sourceClass": "Alpha extension reference",
          "itds": [
            {
              "id": "aitd-000-extend-only-storage",
              "title": "Analytics Is New Extend-Only Alpha Storage",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-000-extend-only-storage"
            },
            {
              "id": "aitd-010-completion-rollups",
              "title": "Completion Percent Is Ingested Earned XP Over A Curriculum Denominator, Never Invented",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-010-completion-rollups"
            }
          ]
        },
        {
          "name": "subject_id",
          "type": "TEXT",
          "nullability": "nullable; required when completion_scope=subject or the scope resolves to one subject",
          "meaning": "Canonical Alpha subject used for reporting and grouping.",
          "constraints": "Closed Alpha subject enum after write-time source-label normalization; unknown source subject becomes an adapter finding or null_reason, not a new string.",
          "relationship": "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.",
          "invalidWhen": "Copied from source strings such as FastMath, Vocabulary, Science-notqced, or ISEE variants without normalization.",
          "example": "math",
          "sourceClass": "Alpha extension reference",
          "itds": [
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "grade_level",
          "type": "INTEGER",
          "nullability": "nullable for non-grade-level scopes without a course grade",
          "meaning": "Working grade level associated with the course progress row, or the grade represented by a grade_level aggregate.",
          "constraints": "Must come from the course/Caliper/Curriculum scope metadata, not from MAP/RIT/R90.",
          "relationship": "GOALS filters grade-level progress by this typed field.",
          "invalidWhen": "Derived from RIT, R90, effective_grade, or a private placement table.",
          "example": "4",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-010-completion-rollups",
              "title": "Completion Percent Is Ingested Earned XP Over A Curriculum Denominator, Never Invented",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-010-completion-rollups"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "is_main_course",
          "type": "BOOLEAN",
          "nullability": "nullable when not applicable; true for main course and grade_level aggregate rows",
          "meaning": "Whether the course row counts toward grade-level progress.",
          "constraints": "Main grade-level courses count; remediation, hole-filling, catalog, practice, and review courses do not.",
          "relationship": "Defines the denominator for completion_scope=grade_level rows.",
          "invalidWhen": "Unset on a course row that contributes to grade-level progress, or true for a hole-filling/remediation/catalog course.",
          "example": "true",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-010-completion-rollups",
              "title": "Completion Percent Is Ingested Earned XP Over A Curriculum Denominator, Never Invented",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-010-completion-rollups"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "progress_source_kind",
          "type": "TEXT enum",
          "nullability": "required for reportable progress rows",
          "meaning": "Which evidence source produced completion_percent.",
          "constraints": "Allowed values include app_reported_percent, xp_remaining, lesson_count, subject_aggregate, and main_course_aggregate.",
          "relationship": "Explains whether a row came directly from the app, an XP fallback, or an Analytics aggregate.",
          "invalidWhen": "Missing on a reportable completion row or used to hide MAP/RIT/R90-derived progress.",
          "example": "app_reported_percent",
          "sourceClass": "Alpha extension enum",
          "itds": [
            {
              "id": "aitd-010-completion-rollups",
              "title": "Completion Percent Is Ingested Earned XP Over A Curriculum Denominator, Never Invented",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-010-completion-rollups"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "window_start",
          "type": "DATE",
          "nullability": "required",
          "meaning": "Inclusive start date for Results evidence included in completion.",
          "constraints": "ISO date; half-open with window_end.",
          "relationship": "Defines the report interval.",
          "invalidWhen": "Uses source import time or current term label.",
          "example": "2026-01-01",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-010-completion-rollups",
              "title": "Completion Percent Is Ingested Earned XP Over A Curriculum Denominator, Never Invented",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-010-completion-rollups"
            }
          ]
        },
        {
          "name": "window_end",
          "type": "DATE",
          "nullability": "required",
          "meaning": "Exclusive end date for Results evidence included in completion.",
          "constraints": "ISO date; must be after window_start.",
          "relationship": "Defines the report interval.",
          "invalidWhen": "Treated as inclusive in raw queries.",
          "example": "2026-06-01",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-010-completion-rollups",
              "title": "Completion Percent Is Ingested Earned XP Over A Curriculum Denominator, Never Invented",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-010-completion-rollups"
            }
          ]
        },
        {
          "name": "xp_earned",
          "type": "NUMERIC(14,3)",
          "nullability": "nullable when progress_source_kind is app_reported_percent or an aggregate without XP evidence",
          "meaning": "Earned XP for this completion scope when the row uses the XP fallback.",
          "constraints": "Nonnegative when present; source corrections are reflected through quality_status/corrections before this value is reportable.",
          "relationship": "Fallback numerator for completion_percent; direct app percent rows may leave XP fields null.",
          "invalidWhen": "Computed by a consumer from active days, activity flags, passed result counts, or processed_facts rows.",
          "example": "null",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-010-completion-rollups",
              "title": "Completion Percent Is Ingested Earned XP Over A Curriculum Denominator, Never Invented",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-010-completion-rollups"
            },
            {
              "id": "aitd-001-report-source-ingestion",
              "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
            }
          ]
        },
        {
          "name": "xp_remaining",
          "type": "NUMERIC(14,3)",
          "nullability": "nullable when progress_source_kind is app_reported_percent or an aggregate without XP evidence",
          "meaning": "Remaining expected XP for this completion scope when the row uses the XP fallback.",
          "constraints": "Nonnegative when present; computed from Curriculum expected XP refs under denominator_policy_ref.",
          "relationship": "Fallback denominator complement for completion_percent. Direct app percent rows may leave XP fields null.",
          "invalidWhen": "A report walks Curriculum trees or hard-codes expected XP locally.",
          "example": "null",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-010-completion-rollups",
              "title": "Completion Percent Is Ingested Earned XP Over A Curriculum Denominator, Never Invented",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-010-completion-rollups"
            }
          ]
        },
        {
          "name": "completion_percent",
          "type": "NUMERIC(7,3)",
          "nullability": "nullable when no direct percent, XP denominator, lesson denominator, or source/policy is available",
          "meaning": "Report-ready completion measure for the scope.",
          "constraints": "Direct app percent wins. If absent, fallback formula is xp_earned / (xp_earned + xp_remaining) * 100. Normally 0 to 100; null requires null_reason.",
          "relationship": "The value dashboards and skill packs render.",
          "invalidWhen": "Consumer divides local counts, treats any activity as complete, returns 1-if-active, or derives progress from MAP/RIT/R90.",
          "example": "75.000",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-010-completion-rollups",
              "title": "Completion Percent Is Ingested Earned XP Over A Curriculum Denominator, Never Invented",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-010-completion-rollups"
            }
          ]
        },
        {
          "name": "denominator_policy_ref",
          "type": "TEXT",
          "nullability": "required",
          "meaning": "Policy that decides which Curriculum expected-XP refs belong in the remaining-XP denominator.",
          "constraints": "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.",
          "relationship": "Keeps Curriculum scope decisions on the surface.",
          "invalidWhen": "A report carries its own course tree filter or expected-XP lookup table.",
          "example": "alpha.policy.analytics.course_progress.v2026-06-15",
          "sourceClass": "Alpha extension reference",
          "itds": [
            {
              "id": "aitd-010-completion-rollups",
              "title": "Completion Percent Is Ingested Earned XP Over A Curriculum Denominator, Never Invented",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-010-completion-rollups"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "curriculum_scope_refs",
          "type": "JSONB",
          "nullability": "required",
          "meaning": "Compact ids/cursor for Curriculum refs used to form the denominator.",
          "constraints": "Refs/hashes only; never copies Curriculum trees or Content rows.",
          "relationship": "Authorized sourceRefs audit view.",
          "invalidWhen": "Duplicates course_component hierarchy in Analytics.",
          "example": "[\"course_component_01HT8ROOT\", \"kc_math_fraction_addition\"]",
          "sourceClass": "Alpha extension reference list",
          "itds": [
            {
              "id": "aitd-000-extend-only-storage",
              "title": "Analytics Is New Extend-Only Alpha Storage",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-000-extend-only-storage"
            },
            {
              "id": "aitd-010-completion-rollups",
              "title": "Completion Percent Is Ingested Earned XP Over A Curriculum Denominator, Never Invented",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-010-completion-rollups"
            },
            {
              "id": "aitd-102-axis-read-shape",
              "title": "API Axis: Read Shape",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-102-axis-read-shape"
            }
          ]
        },
        {
          "name": "source_import_id",
          "type": "TEXT",
          "nullability": "required for report-tile rows; nullable for purely derived event-axis rows",
          "meaning": "Analytics source-import receipt that proves which named report-source adapter produced this report-grade fact.",
          "constraints": "Must reference alpha.analytics_source_import for non-null Learning Report tile values; no literal or fixture value may be reportable without this provenance.",
          "relationship": "Many report-fact rows can reference one source import; detail/sourceRefs endpoints join here for adapter, source_table, and source_row_key_hashes.",
          "invalidWhen": "Missing on a non-null report-tile value, or replaced by copied raw reporting-DB columns.",
          "example": "imp_01HT8COMPLETION_2026_SPRING",
          "sourceClass": "Alpha extension provenance reference",
          "itds": [
            {
              "id": "aitd-001-report-source-ingestion",
              "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
            },
            {
              "id": "aitd-004-provenance-no-literals",
              "title": "Every Report Value Traces To An Ingested Source Row, Or Reads Null",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-004-provenance-no-literals"
            },
            {
              "id": "aitd-010-completion-rollups",
              "title": "Completion Percent Is Ingested Earned XP Over A Curriculum Denominator, Never Invented",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-010-completion-rollups"
            }
          ]
        },
        {
          "name": "null_reason",
          "type": "TEXT enum",
          "nullability": "required",
          "meaning": "Why completion_percent is null or not reportable.",
          "constraints": "Allowed values: null_reason enum; none means the metric is populated.",
          "relationship": "Prevents client fallback completion math.",
          "invalidWhen": "Null completion_percent with no typed explanation.",
          "example": "none",
          "enum": "null_reason",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-010-completion-rollups",
              "title": "Completion Percent Is Ingested Earned XP Over A Curriculum Denominator, Never Invented",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-010-completion-rollups"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "policy_ref",
          "type": "TEXT",
          "nullability": "required",
          "meaning": "Named policy/config version used to compute the measure or rollup.",
          "constraints": "Must point at alpha.policy.analytics.* or an inherited Curriculum/Results policy active for the source effective date.",
          "relationship": "Many Analytics facts can share one policy row; changing policy creates new calculation versions or corrections.",
          "invalidWhen": "A consumer hard-codes thresholds, school-day calendars, Growth X formulas, or completion denominators instead of using the policy ref.",
          "example": "alpha.policy.analytics.course_progress.v2026-06-15",
          "sourceClass": "Alpha extension reference",
          "itds": [
            {
              "id": "aitd-010-completion-rollups",
              "title": "Completion Percent Is Ingested Earned XP Over A Curriculum Denominator, Never Invented",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-010-completion-rollups"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "quality_status",
          "type": "TEXT enum",
          "nullability": "required",
          "meaning": "Current materialization quality state for this fact.",
          "constraints": "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.",
          "relationship": "Used by raw/API convergence filters and source-ref audit views.",
          "invalidWhen": "Free-text status or hidden failures represented as HTTP 200 success.",
          "example": "ok",
          "enum": "quality_status",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            },
            {
              "id": "aitd-108-axis-error-envelope",
              "title": "API Axis: Error Envelope",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-108-axis-error-envelope"
            },
            {
              "id": "aitd-111-axis-privacy-retention",
              "title": "API Axis: Privacy And Retention",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-111-axis-privacy-retention"
            }
          ]
        },
        {
          "name": "calculation_version",
          "type": "INTEGER",
          "nullability": "required",
          "meaning": "Materializer calculation version for this fact shape.",
          "constraints": "Positive integer; starts at 1 and increments when policy/materializer logic intentionally changes.",
          "relationship": "Part of deterministic source_fact_key/idempotency for materializer writes.",
          "invalidWhen": "Omitted from replay keys or changed without a new policy/materializer decision.",
          "example": "1",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            },
            {
              "id": "aitd-105-axis-idempotency",
              "title": "API Axis: Idempotency Model",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-105-axis-idempotency"
            },
            {
              "id": "aitd-104-axis-concurrency",
              "title": "API Axis: Concurrency Model",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-104-axis-concurrency"
            }
          ]
        },
        {
          "name": "computed_at",
          "type": "TIMESTAMPTZ",
          "nullability": "required",
          "meaning": "When Analytics wrote this derived fact.",
          "constraints": "UTC timestamp with timezone; updated only by Analytics materializers.",
          "relationship": "Used for audit and source-ref subcollections, not for school-day grouping.",
          "invalidWhen": "Used as a substitute for the source event time, result effective time, or window boundaries.",
          "example": "2026-06-10T00:51:14Z",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            }
          ]
        },
        {
          "name": "modified_at",
          "type": "TIMESTAMPTZ",
          "nullability": "required",
          "meaning": "Last time the Analytics row changed for polling and modifiedSince queries.",
          "constraints": "UTC timestamp; list endpoints support modifiedSince against this field.",
          "relationship": "Supports poll plus modifiedSince eventing.",
          "invalidWhen": "Client-supplied or used as the business effective date.",
          "example": "2026-06-10T00:51:14Z",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-107-axis-eventing",
              "title": "API Axis: Eventing Model",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-107-axis-eventing"
            },
            {
              "id": "aitd-103-axis-query-model",
              "title": "API Axis: Query Model",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-103-axis-query-model"
            }
          ]
        },
        {
          "name": "superseded_at",
          "type": "TIMESTAMPTZ",
          "nullability": "nullable",
          "meaning": "When this row stopped being the current reportable version because of source correction, deletion, or recalculation. For reviewer/debug probe tenants, non-null rows are retention backlog and are swept after replacement materialization.",
          "constraints": "Null means current; non-null rows are excluded from ordinary list reads unless includeSuperseded=true and authorized.",
          "relationship": "Preserves audit history without mutating source Events or Results.",
          "invalidWhen": "Used to hard-delete old rows or omitted on a correction that replaces a prior fact. Invalid when ordinary completion-rollups reads include this row, or when reviewer/debug probe tenants accumulate superseded rows after retention.",
          "example": "null",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-111-axis-privacy-retention",
              "title": "API Axis: Privacy And Retention",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-111-axis-privacy-retention"
            },
            {
              "id": "aitd-012-corrections-and-reversals",
              "title": "Corrections Are Signed Facts With Provenance",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-012-corrections-and-reversals"
            }
          ]
        },
        {
          "name": "source_deleted_at",
          "type": "TIMESTAMPTZ",
          "nullability": "nullable",
          "meaning": "When the source Event/Result became deleted or invalidated.",
          "constraints": "Null for live source rows; set from source tombstone/correction notifications.",
          "relationship": "Ordinary reads exclude tombstoned facts unless includeSuperseded=true and authorized.",
          "invalidWhen": "Used as a physical delete or ignored by raw-path report queries.",
          "example": "null",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-111-axis-privacy-retention",
              "title": "API Axis: Privacy And Retention",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-111-axis-privacy-retention"
            }
          ]
        },
        {
          "name": "completed_count",
          "type": "INTEGER",
          "physicalType": "INTEGER",
          "nullability": "required",
          "meaning": "Count of completed units represented by the stored completion evidence.",
          "constraints": "Nonnegative; interpreted only with expected_count and the named scope/policy.",
          "relationship": "Auditable numerator evidence for the completion row.",
          "provenance": "Analytics materializer output governed by loop/context/ap-one-platform-capabilities-decision.md.",
          "invalidWhen": "The value is caller-computed, cross-tenant, or detached from the governed source relationship.",
          "example": 70,
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "expected_count",
          "type": "INTEGER",
          "physicalType": "INTEGER",
          "nullability": "required",
          "meaning": "Count of expected units represented by the stored completion evidence.",
          "constraints": "Nonnegative and denominator-policy governed.",
          "relationship": "Auditable denominator evidence for the completion row.",
          "provenance": "Analytics materializer output governed by loop/context/ap-one-platform-capabilities-decision.md.",
          "invalidWhen": "The value is caller-computed, cross-tenant, or detached from the governed source relationship.",
          "example": 100,
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "numerator_policy_ref",
          "type": "TEXT",
          "physicalType": "TEXT",
          "nullability": "required",
          "meaning": "Policy version that selected or interpreted the completion numerator.",
          "constraints": "Must resolve to the dictionary-referenced course-progress policy.",
          "relationship": "Pairs with denominator_policy_ref so consumers do not recompute progress.",
          "provenance": "Analytics materializer output governed by loop/context/ap-one-platform-capabilities-decision.md.",
          "invalidWhen": "The value is caller-computed, cross-tenant, or detached from the governed source relationship.",
          "example": "alpha.policy.analytics.course_progress.v2026-06-15",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "source_result_refs",
          "type": "JSONB",
          "physicalType": "JSONB",
          "nullability": "required",
          "meaning": "Authorized Results evidence references contributing to the row.",
          "constraints": "Array of opaque ids/references; no copied Results payload or credentials.",
          "relationship": "Links Analytics completion evidence back to Results without duplicating the source store.",
          "provenance": "Analytics materializer output governed by loop/context/ap-one-platform-capabilities-decision.md.",
          "invalidWhen": "The value is caller-computed, cross-tenant, or detached from the governed source relationship.",
          "example": [
            "result:course-progress-001"
          ],
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        }
      ],
      "plainLanguage": "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.",
      "retention": {
        "id": "analytics.completion_rollup.probe_tenant_retention.v2026-07-03",
        "policyRef": "alpha.policy.analytics.completion_rollup_retention.v2026-07-03",
        "issue": "https://github.com/andymontgomery-byte/platform3/issues/286",
        "table": "alpha.analytics_completion_rollup",
        "endpoint": "GET /alpha/analytics/v1/completion-rollups",
        "appliesToTenants": [
          "reviewer-analytics",
          "analytics-*debug*"
        ],
        "currentReadRule": "Ordinary completion-rollups reads filter to superseded_at is null, source_deleted_at is null, and reportable quality_status values before sorting or paging.",
        "paginationRule": "completion-rollups reads are page-bounded. The endpoint accepts limit/cursor and the implementation fetches at most limit + 1 rows to determine hasMore; no unbounded total-count query is allowed.",
        "retentionRule": "Probe-generated reviewer/debug rows are operational evidence, not customer history. Repeated materializations retain the latest current row per rollup key; superseded probe rows are swept so latency does not depend on historical probe volume.",
        "rollupKey": [
          "tenant_id",
          "student_id",
          "subject_id",
          "completion_scope",
          "scope_id",
          "window_start",
          "window_end",
          "policy_ref",
          "calculation_version"
        ],
        "documentedBound": "For reviewer/debug tenants, total row count is bounded by current rollup-key cardinality plus any transient in-flight page; supersededRows must return to 0 after retention.",
        "readback": {
          "checkedAt": "2026-07-03T23:33:00Z",
          "source": "read-only production Supabase query against alpha.analytics_completion_rollup",
          "rows": [
            {
              "tenantId": "analytics-debug-debug-1781267631521",
              "totalRows": 45,
              "currentRows": 45,
              "supersededRows": 0
            },
            {
              "tenantId": "analytics-live-debug-1781267728987",
              "totalRows": 1250,
              "currentRows": 1250,
              "supersededRows": 0
            },
            {
              "tenantId": "reviewer-analytics",
              "totalRows": 1606,
              "currentRows": 1606,
              "supersededRows": 0
            }
          ]
        },
        "indexes": [
          "analytics_completion_rollup_current_page_idx",
          "analytics_completion_rollup_current_lookup_idx"
        ]
      }
    },
    {
      "name": "alpha.analytics_fluency_probe",
      "title": "Fluency Probe",
      "kind": "Alpha extension derived-fact table",
      "grain": "One accepted Events fluency_probe_completed fact per tenant_id and source_event_id.",
      "primaryKey": "(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": "Inherits Events authorization and retention; source deletion/tombstone and superseded rows remain auditable under AITD-111.",
      "currentRowSemantics": "Ordinary reads require superseded_at IS NULL and source_deleted_at IS NULL; modifiedSince polls modified_at.",
      "provenance": "Events owns the immutable source fact; Analytics owns DCPM, performance_band, policy_ref, and materialization timestamps.",
      "sourceRelationships": [
        "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"
      ],
      "purpose": "Publishes the dictionary-owned digits-correct-per-minute calculation and band without renderer or BFF recomputation.",
      "architecture": [
        {
          "id": "aitd-000-extend-only-storage",
          "title": "Analytics Is New Extend-Only Alpha Storage",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-000-extend-only-storage"
        },
        {
          "id": "aitd-003-close-time-materialization",
          "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
        },
        {
          "id": "aitd-011-policy-and-enum-normalization",
          "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
        },
        {
          "id": "aitd-110-axis-conformance-evidence",
          "title": "API Axis: Conformance Evidence",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-110-axis-conformance-evidence"
        },
        {
          "id": "aitd-111-axis-privacy-retention",
          "title": "API Axis: Privacy And Retention",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-111-axis-privacy-retention"
        }
      ],
      "api": "GET /alpha/analytics/v1/fluency-probes",
      "queryAxes": [
        "modifiedSince",
        "sort",
        "limit",
        "cursor",
        "studentId",
        "courseId",
        "kcId",
        "performanceBand",
        "startDate",
        "endDate"
      ],
      "rawRule": "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": [
        {
          "name": "id",
          "type": "TEXT",
          "physicalType": "TEXT",
          "nullability": "required",
          "meaning": "Analytics-owned stable fluency-probe row id.",
          "constraints": "Unique with tenant_id.",
          "relationship": "Primary key component for the public collection.",
          "provenance": "Analytics materializer output governed by loop/context/ap-one-platform-capabilities-decision.md.",
          "invalidWhen": "The value is caller-computed, cross-tenant, or detached from the governed source relationship.",
          "example": "fluency_probe_7f3a",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "tenant_id",
          "type": "TEXT",
          "physicalType": "TEXT",
          "nullability": "required",
          "meaning": "Tenant boundary taken from the authenticated materializer context.",
          "constraints": "Never accepted from public query or source extensions.",
          "relationship": "All reads filter tenant_id before other predicates.",
          "provenance": "Analytics materializer output governed by loop/context/ap-one-platform-capabilities-decision.md.",
          "invalidWhen": "The value is caller-computed, cross-tenant, or detached from the governed source relationship.",
          "example": "reviewer-analytics",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-000-extend-only-storage",
              "title": "Analytics Is New Extend-Only Alpha Storage",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-000-extend-only-storage"
            },
            {
              "id": "aitd-111-axis-privacy-retention",
              "title": "API Axis: Privacy And Retention",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-111-axis-privacy-retention"
            }
          ]
        },
        {
          "name": "student_id",
          "type": "TEXT",
          "physicalType": "TEXT",
          "nullability": "required",
          "meaning": "Canonical student whose accepted probe event was measured.",
          "constraints": "Resolved from the Events fact, not a display name or email.",
          "relationship": "References People and Orgs identity through the source Event.",
          "provenance": "Analytics materializer output governed by loop/context/ap-one-platform-capabilities-decision.md.",
          "invalidWhen": "The value is caller-computed, cross-tenant, or detached from the governed source relationship.",
          "example": "student-ada-001",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "course_id",
          "type": "TEXT",
          "physicalType": "TEXT",
          "nullability": "required",
          "meaning": "Governed Curriculum course id carried by the accepted Events extension.",
          "constraints": "Must be present on the fluency_probe_completed source event.",
          "relationship": "References the Curriculum course containing the KC.",
          "provenance": "Analytics materializer output governed by loop/context/ap-one-platform-capabilities-decision.md.",
          "invalidWhen": "The value is caller-computed, cross-tenant, or detached from the governed source relationship.",
          "example": "ap-chemistry",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "kc_id",
          "type": "TEXT",
          "physicalType": "TEXT",
          "nullability": "required",
          "meaning": "Curriculum Knowledge Component measured by the probe.",
          "constraints": "Must resolve at the source event grain.",
          "relationship": "References the smallest durable Curriculum mastery target.",
          "provenance": "Analytics materializer output governed by loop/context/ap-one-platform-capabilities-decision.md.",
          "invalidWhen": "The value is caller-computed, cross-tenant, or detached from the governed source relationship.",
          "example": "kc_chem_formula_fluency",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "source_event_id",
          "type": "TEXT",
          "physicalType": "TEXT",
          "nullability": "required",
          "meaning": "Immutable Events fluency_probe_completed fact id.",
          "constraints": "Unique with tenant_id for this table.",
          "relationship": "One Analytics fluency row derives from one accepted Events fact.",
          "provenance": "Analytics materializer output governed by loop/context/ap-one-platform-capabilities-decision.md.",
          "invalidWhen": "The value is caller-computed, cross-tenant, or detached from the governed source relationship.",
          "example": "events:fluency_probe_001",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "occurred_at",
          "type": "TIMESTAMPTZ",
          "physicalType": "TIMESTAMPTZ",
          "nullability": "required",
          "meaning": "UTC timestamp when the fluency probe occurred.",
          "constraints": "ISO 8601 timestamp with timezone; this is not a date-only field.",
          "relationship": "Copies the governed Events happened_at instant for temporal filtering.",
          "provenance": "Analytics materializer output governed by loop/context/ap-one-platform-capabilities-decision.md.",
          "invalidWhen": "The value is caller-computed, cross-tenant, or detached from the governed source relationship.",
          "example": "2026-07-18T14:30:00.000Z",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "probe_kind",
          "type": "TEXT enum",
          "physicalType": "TEXT",
          "nullability": "required",
          "meaning": "Typed measurement family for the probe.",
          "constraints": "Allowed values: probe_kind enum.",
          "relationship": "Selects the dictionary-owned formula and units.",
          "provenance": "Analytics materializer output governed by loop/context/ap-one-platform-capabilities-decision.md.",
          "invalidWhen": "The value is caller-computed, cross-tenant, or detached from the governed source relationship.",
          "example": "digits_correct_per_minute",
          "enum": "probe_kind",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "correct_units",
          "type": "INTEGER",
          "physicalType": "INTEGER",
          "nullability": "required",
          "meaning": "Number of correct units completed during the probe.",
          "constraints": "Nonnegative integer from the accepted Events extension.",
          "relationship": "Numerator of rate_per_minute.",
          "provenance": "Analytics materializer output governed by loop/context/ap-one-platform-capabilities-decision.md.",
          "invalidWhen": "The value is caller-computed, cross-tenant, or detached from the governed source relationship.",
          "example": 18,
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "elapsed_ms",
          "type": "INTEGER",
          "physicalType": "INTEGER",
          "nullability": "required",
          "meaning": "Positive elapsed milliseconds for the probe.",
          "constraints": "Positive integer from the accepted Events extension.",
          "relationship": "Denominator of rate_per_minute.",
          "provenance": "Analytics materializer output governed by loop/context/ap-one-platform-capabilities-decision.md.",
          "invalidWhen": "The value is caller-computed, cross-tenant, or detached from the governed source relationship.",
          "example": 60000,
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "rate_per_minute",
          "type": "NUMERIC(10,3)",
          "physicalType": "NUMERIC(10,3)",
          "nullability": "required",
          "meaning": "Analytics-owned correct units per minute.",
          "constraints": "rate_per_minute = correct_units * 60000 / elapsed_ms, rounded to 3 decimals.",
          "relationship": "Stored calculation used to assign performance_band.",
          "provenance": "Analytics materializer output governed by loop/context/ap-one-platform-capabilities-decision.md.",
          "invalidWhen": "The value is caller-computed, cross-tenant, or detached from the governed source relationship.",
          "example": 18,
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "performance_band",
          "type": "TEXT enum",
          "physicalType": "TEXT",
          "nullability": "required",
          "meaning": "Policy-owned fluency band for the calculated rate.",
          "constraints": "Allowed values: performance_band enum; acquisition <10, fluency_building >=10 and <20, mastery >=20.",
          "relationship": "Derived only by the named fluency policy.",
          "provenance": "Analytics materializer output governed by loop/context/ap-one-platform-capabilities-decision.md.",
          "invalidWhen": "The value is caller-computed, cross-tenant, or detached from the governed source relationship.",
          "example": "fluency_building",
          "enum": "performance_band",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "policy_ref",
          "type": "TEXT",
          "physicalType": "TEXT",
          "nullability": "required",
          "meaning": "Exact fluency calculation and band policy version.",
          "constraints": "Must equal the active dictionary-referenced policy for this row.",
          "relationship": "Resolves formula and thresholds without client recomputation.",
          "provenance": "Analytics materializer output governed by loop/context/ap-one-platform-capabilities-decision.md.",
          "invalidWhen": "The value is caller-computed, cross-tenant, or detached from the governed source relationship.",
          "example": "alpha.policy.analytics.fluency_probe.v2026-07-18.issue-1128",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "quality_status",
          "type": "TEXT enum",
          "physicalType": "TEXT",
          "nullability": "required",
          "meaning": "Current materialization quality state.",
          "constraints": "Allowed values: quality_status enum; this table writes ok, corrected, or source_missing as applicable.",
          "relationship": "Used with current-row timestamps for ordinary reads.",
          "provenance": "Analytics materializer output governed by loop/context/ap-one-platform-capabilities-decision.md.",
          "invalidWhen": "The value is caller-computed, cross-tenant, or detached from the governed source relationship.",
          "example": "ok",
          "enum": "quality_status",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            },
            {
              "id": "aitd-111-axis-privacy-retention",
              "title": "API Axis: Privacy And Retention",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-111-axis-privacy-retention"
            }
          ]
        },
        {
          "name": "calculation_version",
          "type": "INTEGER",
          "physicalType": "INTEGER",
          "nullability": "required",
          "meaning": "Materializer calculation version for this row shape.",
          "constraints": "Positive integer; corrections preserve traceable versions.",
          "relationship": "Supports deterministic replay and audit.",
          "provenance": "Analytics materializer output governed by loop/context/ap-one-platform-capabilities-decision.md.",
          "invalidWhen": "The value is caller-computed, cross-tenant, or detached from the governed source relationship.",
          "example": 1,
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "computed_at",
          "type": "TIMESTAMPTZ",
          "physicalType": "TIMESTAMPTZ",
          "nullability": "required",
          "meaning": "UTC timestamp when Analytics calculated the row.",
          "constraints": "ISO 8601 timestamp with timezone.",
          "relationship": "Materialization audit timestamp.",
          "provenance": "Analytics materializer output governed by loop/context/ap-one-platform-capabilities-decision.md.",
          "invalidWhen": "The value is caller-computed, cross-tenant, or detached from the governed source relationship.",
          "example": "2026-07-18T14:30:01.000Z",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "modified_at",
          "type": "TIMESTAMPTZ",
          "physicalType": "TIMESTAMPTZ",
          "nullability": "required",
          "meaning": "UTC timestamp of the last row change.",
          "constraints": "Supports modifiedSince polling.",
          "relationship": "Public eventing cursor timestamp.",
          "provenance": "Analytics materializer output governed by loop/context/ap-one-platform-capabilities-decision.md.",
          "invalidWhen": "The value is caller-computed, cross-tenant, or detached from the governed source relationship.",
          "example": "2026-07-18T14:30:01.000Z",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "superseded_at",
          "type": "TIMESTAMPTZ",
          "physicalType": "TIMESTAMPTZ",
          "nullability": "nullable",
          "meaning": "When a correction made this row non-current.",
          "constraints": "Null on current rows.",
          "relationship": "Ordinary reads require superseded_at is null.",
          "provenance": "Analytics materializer output governed by loop/context/ap-one-platform-capabilities-decision.md.",
          "invalidWhen": "The value is caller-computed, cross-tenant, or detached from the governed source relationship.",
          "example": null,
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-111-axis-privacy-retention",
              "title": "API Axis: Privacy And Retention",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-111-axis-privacy-retention"
            }
          ]
        },
        {
          "name": "source_deleted_at",
          "type": "TIMESTAMPTZ",
          "physicalType": "TIMESTAMPTZ",
          "nullability": "nullable",
          "meaning": "When the source Events fact was deleted or invalidated.",
          "constraints": "Null while the source is current.",
          "relationship": "Ordinary reads require source_deleted_at is null.",
          "provenance": "Analytics materializer output governed by loop/context/ap-one-platform-capabilities-decision.md.",
          "invalidWhen": "The value is caller-computed, cross-tenant, or detached from the governed source relationship.",
          "example": null,
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-111-axis-privacy-retention",
              "title": "API Axis: Privacy And Retention",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-111-axis-privacy-retention"
            }
          ]
        }
      ],
      "plainLanguage": "One governed fluency probe with its source event, stored DCPM rate, and policy-owned performance band."
    },
    {
      "name": "alpha.analytics_lab_progress",
      "title": "AP Lab Progress",
      "kind": "Alpha extension derived rollup table",
      "grain": "One current row per tenant_id, student_id, course_id, and resolved policy_profile over the stored activity window.",
      "primaryKey": "(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": "Inherits Events authorization and retention; source deletion/tombstone and superseded rows remain auditable under AITD-111.",
      "currentRowSemantics": "Ordinary reads require superseded_at IS NULL and source_deleted_at IS NULL; modifiedSince polls modified_at.",
      "provenance": "Events owns lab/activity facts, Curriculum owns policy_profile, and Analytics owns counts, percentages, thresholds, verdict, and null reason.",
      "sourceRelationships": [
        "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"
      ],
      "purpose": "Publishes AP Chemistry completed-lab and AP Environmental Science hands-on-time requirements without client-side event counting or threshold math.",
      "architecture": [
        {
          "id": "aitd-000-extend-only-storage",
          "title": "Analytics Is New Extend-Only Alpha Storage",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-000-extend-only-storage"
        },
        {
          "id": "aitd-003-close-time-materialization",
          "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
        },
        {
          "id": "aitd-011-policy-and-enum-normalization",
          "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
        },
        {
          "id": "aitd-110-axis-conformance-evidence",
          "title": "API Axis: Conformance Evidence",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-110-axis-conformance-evidence"
        },
        {
          "id": "aitd-111-axis-privacy-retention",
          "title": "API Axis: Privacy And Retention",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-111-axis-privacy-retention"
        }
      ],
      "api": "GET /alpha/analytics/v1/lab-progress",
      "queryAxes": [
        "modifiedSince",
        "sort",
        "limit",
        "cursor",
        "studentId",
        "courseId",
        "policyProfile",
        "startDate",
        "endDate"
      ],
      "rawRule": "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": [
        {
          "name": "id",
          "type": "TEXT",
          "physicalType": "TEXT",
          "nullability": "required",
          "meaning": "Analytics-owned stable lab-progress row id.",
          "constraints": "Unique with tenant_id.",
          "relationship": "Primary key component for the public collection.",
          "provenance": "Analytics materializer output governed by loop/context/ap-one-platform-capabilities-decision.md.",
          "invalidWhen": "The value is caller-computed, cross-tenant, or detached from the governed source relationship.",
          "example": "lab_progress_a8d1",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "tenant_id",
          "type": "TEXT",
          "physicalType": "TEXT",
          "nullability": "required",
          "meaning": "Tenant boundary taken from the authenticated materializer context.",
          "constraints": "Never accepted from query or Events extensions.",
          "relationship": "All reads filter tenant_id first.",
          "provenance": "Analytics materializer output governed by loop/context/ap-one-platform-capabilities-decision.md.",
          "invalidWhen": "The value is caller-computed, cross-tenant, or detached from the governed source relationship.",
          "example": "reviewer-analytics",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-000-extend-only-storage",
              "title": "Analytics Is New Extend-Only Alpha Storage",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-000-extend-only-storage"
            },
            {
              "id": "aitd-111-axis-privacy-retention",
              "title": "API Axis: Privacy And Retention",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-111-axis-privacy-retention"
            }
          ]
        },
        {
          "name": "student_id",
          "type": "TEXT",
          "physicalType": "TEXT",
          "nullability": "required",
          "meaning": "Canonical student whose course lab evidence is aggregated.",
          "constraints": "Resolved through accepted Events facts.",
          "relationship": "References People and Orgs identity through Events.",
          "provenance": "Analytics materializer output governed by loop/context/ap-one-platform-capabilities-decision.md.",
          "invalidWhen": "The value is caller-computed, cross-tenant, or detached from the governed source relationship.",
          "example": "student-ada-001",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "course_id",
          "type": "TEXT",
          "physicalType": "TEXT",
          "nullability": "required",
          "meaning": "Governed Curriculum course whose lab evidence is aggregated.",
          "constraints": "Required on contributing course-scoped Events facts.",
          "relationship": "References the Curriculum course and its policy profile.",
          "provenance": "Analytics materializer output governed by loop/context/ap-one-platform-capabilities-decision.md.",
          "invalidWhen": "The value is caller-computed, cross-tenant, or detached from the governed source relationship.",
          "example": "ap-chemistry",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "policy_profile",
          "type": "TEXT enum",
          "physicalType": "TEXT",
          "nullability": "nullable when Events do not resolve exactly one governed profile",
          "meaning": "Curriculum policy profile selecting the applicable AP requirement.",
          "constraints": "Allowed values: policy_profile enum.",
          "relationship": "AP Chemistry selects the 16-lab floor; AP Environmental Science selects the 25% hands-on floor.",
          "provenance": "Analytics materializer output governed by loop/context/ap-one-platform-capabilities-decision.md.",
          "invalidWhen": "The value is caller-computed, cross-tenant, or detached from the governed source relationship.",
          "example": "ap_chemistry",
          "enum": "policy_profile",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "window_start",
          "type": "DATE",
          "physicalType": "DATE",
          "nullability": "required",
          "meaning": "Inclusive first course-activity date represented by the rollup.",
          "constraints": "ISO YYYY-MM-DD date-only value; never a timestamp.",
          "relationship": "Lower bound for contributing governed Events facts.",
          "provenance": "Analytics materializer output governed by loop/context/ap-one-platform-capabilities-decision.md.",
          "invalidWhen": "The value is caller-computed, cross-tenant, or detached from the governed source relationship.",
          "example": "2026-01-01",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "window_end",
          "type": "DATE",
          "physicalType": "DATE",
          "nullability": "required",
          "meaning": "Exclusive date after the last course activity represented by the rollup.",
          "constraints": "ISO YYYY-MM-DD date-only value; never a timestamp.",
          "relationship": "Upper bound for contributing governed Events facts.",
          "provenance": "Analytics materializer output governed by loop/context/ap-one-platform-capabilities-decision.md.",
          "invalidWhen": "The value is caller-computed, cross-tenant, or detached from the governed source relationship.",
          "example": "2026-07-19",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "completed_hands_on_lab_count",
          "type": "INTEGER",
          "physicalType": "INTEGER",
          "nullability": "required",
          "meaning": "Distinct accepted hands-on lab sessions completed in the window.",
          "constraints": "Nonnegative; counts lab_completed with hands_on=true and a lab_session_id.",
          "relationship": "AP Chemistry requirement numerator.",
          "provenance": "Analytics materializer output governed by loop/context/ap-one-platform-capabilities-decision.md.",
          "invalidWhen": "The value is caller-computed, cross-tenant, or detached from the governed source relationship.",
          "example": 16,
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "hands_on_minutes",
          "type": "NUMERIC(12,3)",
          "physicalType": "NUMERIC(12,3)",
          "nullability": "required",
          "meaning": "Accepted active minutes attached to hands-on lab completion facts.",
          "constraints": "Nonnegative and no greater than total_course_active_minutes.",
          "relationship": "Numerator of hands_on_percent.",
          "provenance": "Analytics materializer output governed by loop/context/ap-one-platform-capabilities-decision.md.",
          "invalidWhen": "The value is caller-computed, cross-tenant, or detached from the governed source relationship.",
          "example": 720,
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "total_course_active_minutes",
          "type": "NUMERIC(12,3)",
          "physicalType": "NUMERIC(12,3)",
          "nullability": "required",
          "meaning": "Governed active minutes for the course in the same window.",
          "constraints": "Nonnegative course-scoped denominator.",
          "relationship": "Denominator of hands_on_percent.",
          "provenance": "Analytics materializer output governed by loop/context/ap-one-platform-capabilities-decision.md.",
          "invalidWhen": "The value is caller-computed, cross-tenant, or detached from the governed source relationship.",
          "example": 900,
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "hands_on_percent",
          "type": "NUMERIC(7,3)",
          "physicalType": "NUMERIC(7,3)",
          "nullability": "nullable when the denominator is unavailable or zero",
          "meaning": "Percent of course active minutes that were hands-on lab minutes.",
          "constraints": "0 through 100; hands_on_minutes / total_course_active_minutes * 100.",
          "relationship": "AP Environmental Science requirement numerator.",
          "provenance": "Analytics materializer output governed by loop/context/ap-one-platform-capabilities-decision.md.",
          "invalidWhen": "The value is caller-computed, cross-tenant, or detached from the governed source relationship.",
          "example": 80,
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "required_lab_count",
          "type": "INTEGER",
          "physicalType": "INTEGER",
          "nullability": "nullable when policy_profile is not ap_chemistry",
          "meaning": "Policy-required completed hands-on lab count.",
          "constraints": "16 for ap_chemistry; otherwise null.",
          "relationship": "Threshold used by meets_course_requirement.",
          "provenance": "Analytics materializer output governed by loop/context/ap-one-platform-capabilities-decision.md.",
          "invalidWhen": "The value is caller-computed, cross-tenant, or detached from the governed source relationship.",
          "example": 16,
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "required_hands_on_percent",
          "type": "NUMERIC(7,3)",
          "physicalType": "NUMERIC(7,3)",
          "nullability": "nullable when policy_profile is not ap_environmental_science",
          "meaning": "Policy-required hands-on share of active course time.",
          "constraints": "25 for ap_environmental_science; otherwise null.",
          "relationship": "Threshold used by meets_course_requirement.",
          "provenance": "Analytics materializer output governed by loop/context/ap-one-platform-capabilities-decision.md.",
          "invalidWhen": "The value is caller-computed, cross-tenant, or detached from the governed source relationship.",
          "example": null,
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "meets_course_requirement",
          "type": "BOOLEAN",
          "physicalType": "BOOLEAN",
          "nullability": "nullable when no supported policy profile or usable denominator applies",
          "meaning": "Stored verdict for the profile-specific AP lab requirement.",
          "constraints": "Chemistry compares completed labs to 16; Environmental Science compares hands_on_percent to 25.",
          "relationship": "Consumers render this value and do not recompute thresholds.",
          "provenance": "Analytics materializer output governed by loop/context/ap-one-platform-capabilities-decision.md.",
          "invalidWhen": "The value is caller-computed, cross-tenant, or detached from the governed source relationship.",
          "example": true,
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "source_event_refs",
          "type": "JSONB",
          "physicalType": "JSONB",
          "nullability": "required",
          "meaning": "Authorized contributing Events fact ids.",
          "constraints": "JSON array of opaque source ids; no copied event payloads.",
          "relationship": "Provenance link to lab_completed and course activity facts.",
          "provenance": "Analytics materializer output governed by loop/context/ap-one-platform-capabilities-decision.md.",
          "invalidWhen": "The value is caller-computed, cross-tenant, or detached from the governed source relationship.",
          "example": [
            "events:lab_completed_001",
            "events:lab_completed_016"
          ],
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "null_reason",
          "type": "TEXT enum",
          "physicalType": "TEXT",
          "nullability": "required",
          "meaning": "Typed explanation when the denominator or applicable profile is unavailable.",
          "constraints": "Allowed values: null_reason enum; this table uses none, source_missing, and not_applicable.",
          "relationship": "Explains nullable percentage, threshold, and verdict fields.",
          "provenance": "Analytics materializer output governed by loop/context/ap-one-platform-capabilities-decision.md.",
          "invalidWhen": "The value is caller-computed, cross-tenant, or detached from the governed source relationship.",
          "example": "none",
          "enum": "null_reason",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "policy_ref",
          "type": "TEXT",
          "physicalType": "TEXT",
          "nullability": "required",
          "meaning": "Exact AP lab-progress calculation policy version.",
          "constraints": "Must resolve to the dictionary-referenced policy.",
          "relationship": "Resolves formulas and thresholds without client recomputation.",
          "provenance": "Analytics materializer output governed by loop/context/ap-one-platform-capabilities-decision.md.",
          "invalidWhen": "The value is caller-computed, cross-tenant, or detached from the governed source relationship.",
          "example": "alpha.policy.analytics.ap_lab_progress.v2026-07-18.issue-1128",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "quality_status",
          "type": "TEXT enum",
          "physicalType": "TEXT",
          "nullability": "required",
          "meaning": "Current materialization quality state.",
          "constraints": "Allowed values: quality_status enum; source_missing marks unavailable required evidence.",
          "relationship": "Used with null_reason and current-row timestamps.",
          "provenance": "Analytics materializer output governed by loop/context/ap-one-platform-capabilities-decision.md.",
          "invalidWhen": "The value is caller-computed, cross-tenant, or detached from the governed source relationship.",
          "example": "ok",
          "enum": "quality_status",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            },
            {
              "id": "aitd-111-axis-privacy-retention",
              "title": "API Axis: Privacy And Retention",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-111-axis-privacy-retention"
            }
          ]
        },
        {
          "name": "calculation_version",
          "type": "INTEGER",
          "physicalType": "INTEGER",
          "nullability": "required",
          "meaning": "Materializer calculation version for this row shape.",
          "constraints": "Positive integer.",
          "relationship": "Supports deterministic replay and audit.",
          "provenance": "Analytics materializer output governed by loop/context/ap-one-platform-capabilities-decision.md.",
          "invalidWhen": "The value is caller-computed, cross-tenant, or detached from the governed source relationship.",
          "example": 1,
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "computed_at",
          "type": "TIMESTAMPTZ",
          "physicalType": "TIMESTAMPTZ",
          "nullability": "required",
          "meaning": "UTC timestamp when Analytics calculated the row.",
          "constraints": "ISO 8601 timestamp with timezone.",
          "relationship": "Materialization audit timestamp.",
          "provenance": "Analytics materializer output governed by loop/context/ap-one-platform-capabilities-decision.md.",
          "invalidWhen": "The value is caller-computed, cross-tenant, or detached from the governed source relationship.",
          "example": "2026-07-19T00:00:01.000Z",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "modified_at",
          "type": "TIMESTAMPTZ",
          "physicalType": "TIMESTAMPTZ",
          "nullability": "required",
          "meaning": "UTC timestamp of the last row change.",
          "constraints": "Supports modifiedSince polling.",
          "relationship": "Public eventing cursor timestamp.",
          "provenance": "Analytics materializer output governed by loop/context/ap-one-platform-capabilities-decision.md.",
          "invalidWhen": "The value is caller-computed, cross-tenant, or detached from the governed source relationship.",
          "example": "2026-07-19T00:00:01.000Z",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "superseded_at",
          "type": "TIMESTAMPTZ",
          "physicalType": "TIMESTAMPTZ",
          "nullability": "nullable",
          "meaning": "When a replacement made this row non-current.",
          "constraints": "Null on current rows.",
          "relationship": "Ordinary reads require superseded_at is null.",
          "provenance": "Analytics materializer output governed by loop/context/ap-one-platform-capabilities-decision.md.",
          "invalidWhen": "The value is caller-computed, cross-tenant, or detached from the governed source relationship.",
          "example": null,
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-111-axis-privacy-retention",
              "title": "API Axis: Privacy And Retention",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-111-axis-privacy-retention"
            }
          ]
        },
        {
          "name": "source_deleted_at",
          "type": "TIMESTAMPTZ",
          "physicalType": "TIMESTAMPTZ",
          "nullability": "nullable",
          "meaning": "When contributing source evidence was deleted or invalidated.",
          "constraints": "Null while source evidence remains current.",
          "relationship": "Ordinary reads require source_deleted_at is null.",
          "provenance": "Analytics materializer output governed by loop/context/ap-one-platform-capabilities-decision.md.",
          "invalidWhen": "The value is caller-computed, cross-tenant, or detached from the governed source relationship.",
          "example": null,
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-111-axis-privacy-retention",
              "title": "API Axis: Privacy And Retention",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-111-axis-privacy-retention"
            }
          ]
        }
      ],
      "plainLanguage": "One student's governed AP lab progress for one course and policy profile."
    },
    {
      "name": "alpha.analytics_source_import",
      "title": "Source Import",
      "kind": "Alpha extension provenance ledger",
      "grain": "One named-adapter ingestion run from one report-source producer.",
      "primaryKey": "import_id; idempotency key hash is unique per tenant for public imports.",
      "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.",
      "purpose": "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.",
      "metricChecks": [
        "all metric checks"
      ],
      "architecture": [
        {
          "id": "aitd-001-report-source-ingestion",
          "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
        },
        {
          "id": "aitd-004-provenance-no-literals",
          "title": "Every Report Value Traces To An Ingested Source Row, Or Reads Null",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-004-provenance-no-literals"
        },
        {
          "id": "aitd-101-axis-write-granularity",
          "title": "API Axis: Write Granularity",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-101-axis-write-granularity"
        },
        {
          "id": "aitd-105-axis-idempotency",
          "title": "API Axis: Idempotency Model",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-105-axis-idempotency"
        },
        {
          "id": "aitd-108-axis-error-envelope",
          "title": "API Axis: Error Envelope",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-108-axis-error-envelope"
        }
      ],
      "api": "POST /alpha/analytics/v1/source-imports/{adapter} and GET /alpha/analytics/v1/source-imports",
      "rawRule": "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.",
      "example": {
        "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"
      },
      "fields": [
        {
          "name": "import_id",
          "type": "TEXT",
          "nullability": "required",
          "meaning": "Stable id for this source import request.",
          "constraints": "Generated by platform; unique per tenant.",
          "relationship": "Primary key and detail endpoint id.",
          "invalidWhen": "Caller-supplied to overwrite a prior import.",
          "example": "imp_01HT8ANALYTICS",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-001-report-source-ingestion",
              "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
            }
          ]
        },
        {
          "name": "tenant_id",
          "type": "UUID",
          "nullability": "required",
          "meaning": "Tenant boundary for the derived fact.",
          "constraints": "Set from the JWT tenant claim or internal materializer context; never accepted from request body/query.",
          "relationship": "All raw-path queries must filter by tenant_id before joining, sorting, paging, or counting.",
          "invalidWhen": "Missing, caller-supplied in body/query, or mismatched with the JWT tenant claim.",
          "example": "7b0bb5d8-9a38-4a62-9fdc-9f8d2dc1a111",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-109-axis-tenant-routing",
              "title": "API Axis: Tenant Routing",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-109-axis-tenant-routing"
            },
            {
              "id": "aitd-106-axis-auth-shape",
              "title": "API Axis: Auth Shape",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-106-axis-auth-shape"
            }
          ]
        },
        {
          "name": "import_kind",
          "type": "TEXT enum",
          "nullability": "required",
          "meaning": "Which source/replay contract this batch follows.",
          "constraints": "Allowed values: import_kind enum.",
          "relationship": "Selects the server-side adapter/materializer.",
          "invalidWhen": "Generic upload with caller-provided normalized metric rows.",
          "example": "timeback-xp-time-accuracy",
          "enum": "import_kind",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-001-report-source-ingestion",
              "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
            },
            {
              "id": "aitd-101-axis-write-granularity",
              "title": "API Axis: Write Granularity",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-101-axis-write-granularity"
            }
          ]
        },
        {
          "name": "adapter_name",
          "type": "TEXT",
          "nullability": "required",
          "meaning": "Named server-side adapter that normalized this source batch.",
          "constraints": "Must match one approved adapter: timeback-xp-time-accuracy, timeback-map, timeback-grade-mastery, or timeback-completion, plus internal replay kinds where applicable.",
          "relationship": "Selects the source-table contract and normalization rules; no client-computed metric values are accepted.",
          "invalidWhen": "Generic import, free-text adapter names, or client-chosen formulas.",
          "example": "timeback-xp-time-accuracy",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-001-report-source-ingestion",
              "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
            },
            {
              "id": "aitd-101-axis-write-granularity",
              "title": "API Axis: Write Granularity",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-101-axis-write-granularity"
            }
          ]
        },
        {
          "name": "source_system",
          "type": "TEXT",
          "nullability": "required",
          "meaning": "Producer system the adapter read from.",
          "constraints": "Closed governed values for approved adapters: reporting, events, results, migration_reconcile.",
          "relationship": "Audits whether a fact came from report-source ingestion or internal derived replay.",
          "invalidWhen": "Raw database URL, credentials, or ungoverned free text.",
          "example": "reporting",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-001-report-source-ingestion",
              "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
            },
            {
              "id": "aitd-004-provenance-no-literals",
              "title": "Every Report Value Traces To An Ingested Source Row, Or Reads Null",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-004-provenance-no-literals"
            }
          ]
        },
        {
          "name": "source_table",
          "type": "TEXT",
          "nullability": "required for report-source adapters",
          "meaning": "Report-source table or producer collection read by the adapter.",
          "constraints": "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.",
          "relationship": "Explains which approved upstream source produced the report-grade fact without exposing raw rows.",
          "invalidWhen": "A source table is missing for a non-null report tile value.",
          "example": "processed_facts",
          "sourceClass": "Alpha extension provenance reference",
          "itds": [
            {
              "id": "aitd-001-report-source-ingestion",
              "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
            },
            {
              "id": "aitd-004-provenance-no-literals",
              "title": "Every Report Value Traces To An Ingested Source Row, Or Reads Null",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-004-provenance-no-literals"
            }
          ]
        },
        {
          "name": "status",
          "type": "TEXT enum",
          "nullability": "required",
          "meaning": "Processing state of the source import.",
          "constraints": "Allowed values: import_status enum.",
          "relationship": "A status of materialized or partially_rejected can be followed by reads of created Analytics facts.",
          "invalidWhen": "A validation or adapter rejection is represented as success without Problem details.",
          "example": "materialized",
          "enum": "import_status",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-001-report-source-ingestion",
              "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
            },
            {
              "id": "aitd-108-axis-error-envelope",
              "title": "API Axis: Error Envelope",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-108-axis-error-envelope"
            }
          ]
        },
        {
          "name": "idempotency_key_hash",
          "type": "TEXT",
          "nullability": "required for public POST imports",
          "meaning": "Hash of the Idempotency-Key header used for replay safety.",
          "constraints": "Stores a hash, never the raw key; replay with same hash and same body is a no-op, different body is analytics:idempotency_conflict.",
          "relationship": "Unique with tenant_id for source import writes.",
          "invalidWhen": "Missing on public writes or stored as plaintext secret material.",
          "example": "sha256:4b463adfe0...",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-105-axis-idempotency",
              "title": "API Axis: Idempotency Model",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-105-axis-idempotency"
            }
          ]
        },
        {
          "name": "source_batch_ref",
          "type": "TEXT",
          "nullability": "nullable",
          "meaning": "Operator/source identifier for the imported file, replay, or reconciliation run.",
          "constraints": "Opaque reference; no PII or raw row contents.",
          "relationship": "Audit linkage to migration/reconciliation artifacts.",
          "invalidWhen": "Contains raw source rows, emails, or credentials.",
          "example": "migration-2026-06-10-processed-facts-001",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-001-report-source-ingestion",
              "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
            },
            {
              "id": "aitd-111-axis-privacy-retention",
              "title": "API Axis: Privacy And Retention",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-111-axis-privacy-retention"
            }
          ]
        },
        {
          "name": "source_payload_hash",
          "type": "TEXT",
          "nullability": "required",
          "meaning": "Hash of the submitted source-shaped payload or replay source set.",
          "constraints": "SHA-256 or stronger; no raw payload copy in this table.",
          "relationship": "Supports idempotency and audit without storing PII rows.",
          "invalidWhen": "Raw processed_facts rows are stored here.",
          "example": "sha256:91f25d7371...",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-001-report-source-ingestion",
              "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
            },
            {
              "id": "aitd-111-axis-privacy-retention",
              "title": "API Axis: Privacy And Retention",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-111-axis-privacy-retention"
            }
          ]
        },
        {
          "name": "source_row_key_hashes",
          "type": "JSONB",
          "nullability": "required",
          "meaning": "Hashes of natural source-row keys included in the import.",
          "constraints": "Hashes/opaque keys only; no student names, emails, credentials, or raw source payloads.",
          "relationship": "Allows a non-null report value to prove it came from a resolvable source row while keeping public reads PII-safe.",
          "invalidWhen": "Missing on a report-source import that produced materialized rows, or stores raw source records.",
          "example": "[\"sha256:rowkey001...\", \"sha256:rowkey002...\"]",
          "sourceClass": "Alpha extension provenance reference",
          "itds": [
            {
              "id": "aitd-004-provenance-no-literals",
              "title": "Every Report Value Traces To An Ingested Source Row, Or Reads Null",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-004-provenance-no-literals"
            },
            {
              "id": "aitd-111-axis-privacy-retention",
              "title": "API Axis: Privacy And Retention",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-111-axis-privacy-retention"
            }
          ]
        },
        {
          "name": "submitted_row_count",
          "type": "INTEGER",
          "nullability": "required",
          "meaning": "Number of source-shaped rows submitted in the batch.",
          "constraints": "Nonnegative.",
          "relationship": "Top-level import audit, not a materialized-fact count.",
          "invalidWhen": "Used as proof that Analytics rows exist.",
          "example": "5000",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-001-report-source-ingestion",
              "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
            }
          ]
        },
        {
          "name": "accepted_row_count",
          "type": "INTEGER",
          "nullability": "required",
          "meaning": "Rows accepted by request validation and adapter mapping.",
          "constraints": "Nonnegative and not greater than submitted_row_count.",
          "relationship": "Accepted rows should materialize or have a documented source_missing or policy_pending state.",
          "invalidWhen": "Returned with HTTP 200 while validation actually failed.",
          "example": "4970",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-001-report-source-ingestion",
              "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
            },
            {
              "id": "aitd-108-axis-error-envelope",
              "title": "API Axis: Error Envelope",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-108-axis-error-envelope"
            }
          ]
        },
        {
          "name": "materialized_row_count",
          "type": "INTEGER",
          "nullability": "required",
          "meaning": "Rows that produced readable Analytics facts.",
          "constraints": "Nonnegative; successful nonempty imports must produce readable rows unless status explains otherwise.",
          "relationship": "Migration gate checks this count against the public Analytics reads.",
          "invalidWhen": "Zero after a claimed successful import of rows that should materialize.",
          "example": "4970",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-001-report-source-ingestion",
              "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
            },
            {
              "id": "aitd-110-axis-conformance-evidence",
              "title": "API Axis: Conformance Evidence",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-110-axis-conformance-evidence"
            }
          ]
        },
        {
          "name": "rejected_row_count",
          "type": "INTEGER",
          "nullability": "required",
          "meaning": "Rows rejected by validation or adapter mapping.",
          "constraints": "Nonnegative; submitted = accepted + rejected for completed imports.",
          "relationship": "Problem details summarize why rows could not materialize.",
          "invalidWhen": "Hidden in a success body without typed Problem codes.",
          "example": "30",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-001-report-source-ingestion",
              "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
            },
            {
              "id": "aitd-108-axis-error-envelope",
              "title": "API Axis: Error Envelope",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-108-axis-error-envelope"
            }
          ]
        },
        {
          "name": "problem_counts",
          "type": "JSONB",
          "nullability": "required",
          "meaning": "Counts of typed Problem codes produced by the import.",
          "constraints": "Keys must be stable analytics:* codes; values nonnegative integers.",
          "relationship": "Summarizes analytics:validation_failed, analytics:adapter_rejected, analytics:source_missing, analytics:policy_pending, and related errors.",
          "invalidWhen": "Free-text error blobs or HTTP 200 with embedded failure status.",
          "example": "{\"analytics:adapter_rejected\":30}",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-108-axis-error-envelope",
              "title": "API Axis: Error Envelope",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-108-axis-error-envelope"
            },
            {
              "id": "aitd-001-report-source-ingestion",
              "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
            }
          ]
        },
        {
          "name": "received_at",
          "type": "TIMESTAMPTZ",
          "nullability": "required",
          "meaning": "When the import request was received.",
          "constraints": "UTC timestamp.",
          "relationship": "Import audit timeline.",
          "invalidWhen": "Used as a business effective date for metrics.",
          "example": "2026-06-10T00:55:00Z",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-001-report-source-ingestion",
              "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
            }
          ]
        },
        {
          "name": "completed_at",
          "type": "TIMESTAMPTZ",
          "nullability": "nullable until processing completes",
          "meaning": "When import processing reached a terminal status.",
          "constraints": "UTC timestamp; null while status is received/running.",
          "relationship": "Import audit timeline.",
          "invalidWhen": "Set before materialization/rejection summary is final.",
          "example": "2026-06-10T00:56:12Z",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-001-report-source-ingestion",
              "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
            }
          ]
        },
        {
          "name": "modified_at",
          "type": "TIMESTAMPTZ",
          "nullability": "required",
          "meaning": "Last time the Analytics row changed for polling and modifiedSince queries.",
          "constraints": "UTC timestamp; list endpoints support modifiedSince against this field.",
          "relationship": "Supports poll plus modifiedSince eventing.",
          "invalidWhen": "Client-supplied or used as the business effective date.",
          "example": "2026-06-10T00:51:14Z",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-107-axis-eventing",
              "title": "API Axis: Eventing Model",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-107-axis-eventing"
            },
            {
              "id": "aitd-103-axis-query-model",
              "title": "API Axis: Query Model",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-103-axis-query-model"
            }
          ]
        }
      ],
      "plainLanguage": "The audit receipt for every named report-source adapter run and reconciliation replay."
    }
  ],
  "objects": [
    {
      "name": "alpha.analytics_event_time_fact",
      "title": "Event Time Fact",
      "kind": "Alpha extension table",
      "grain": "One source Event contribution per fact_kind, policy_ref, and calculation_version.",
      "primaryKey": "id; unique report grain is (tenant_id, source_event_id, fact_kind, policy_ref, calculation_version) for current rows.",
      "lifecycle": "Written when an Event closes or when an event-close replay runs. Corrections write signed replacement/reversal rows.",
      "purpose": "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.",
      "metricChecks": [
        "minutes|Caliper events"
      ],
      "architecture": [
        {
          "id": "aitd-000-extend-only-storage",
          "title": "Analytics Is New Extend-Only Alpha Storage",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-000-extend-only-storage"
        },
        {
          "id": "aitd-002-derived-events-complement",
          "title": "Derived-From-Events Facts Complement, Never Substitute For, Ingested Tiles",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-002-derived-events-complement"
        },
        {
          "id": "aitd-003-close-time-materialization",
          "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
        },
        {
          "id": "aitd-005-time-facts-and-windows",
          "title": "Active, Inactive, And Waste Seconds Are Typed Derived Time Facts",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-005-time-facts-and-windows"
        },
        {
          "id": "aitd-011-policy-and-enum-normalization",
          "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
        },
        {
          "id": "aitd-012-corrections-and-reversals",
          "title": "Corrections Are Signed Facts With Provenance",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-012-corrections-and-reversals"
        }
      ],
      "api": "GET /alpha/analytics/v1/event-time-facts",
      "rawRule": "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.",
      "example": {
        "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
      },
      "fields": [
        {
          "name": "id",
          "type": "UUID",
          "nullability": "required",
          "meaning": "Analytics-owned stable row id for this derived fact.",
          "constraints": "Generated by the platform; globally unique within alpha.analytics_* objects.",
          "relationship": "Primary key for list/detail endpoints.",
          "invalidWhen": "Provided by a public import client or reused across tenants.",
          "example": "8e9c0ef2-bc75-4f53-8124-df77df49f25f",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-000-extend-only-storage",
              "title": "Analytics Is New Extend-Only Alpha Storage",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-000-extend-only-storage"
            }
          ]
        },
        {
          "name": "tenant_id",
          "type": "UUID",
          "nullability": "required",
          "meaning": "Tenant boundary for the derived fact.",
          "constraints": "Set from the JWT tenant claim or internal materializer context; never accepted from request body/query.",
          "relationship": "All raw-path queries must filter by tenant_id before joining, sorting, paging, or counting.",
          "invalidWhen": "Missing, caller-supplied in body/query, or mismatched with the JWT tenant claim.",
          "example": "7b0bb5d8-9a38-4a62-9fdc-9f8d2dc1a111",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-109-axis-tenant-routing",
              "title": "API Axis: Tenant Routing",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-109-axis-tenant-routing"
            },
            {
              "id": "aitd-106-axis-auth-shape",
              "title": "API Axis: Auth Shape",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-106-axis-auth-shape"
            }
          ]
        },
        {
          "name": "student_id",
          "type": "TEXT",
          "nullability": "required",
          "meaning": "Canonical Alpha student id the source Event or Result resolved to at materialization time.",
          "constraints": "Must resolve through People and Orgs as a real student for the source timestamp/effective date.",
          "relationship": "References People and Orgs student identity; see https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/data_dictionary.",
          "invalidWhen": "Parsed from email/name/source payload instead of resolved by the Events/Results adapter.",
          "example": "student_01HT7G3YZV7QB5N4YKQ1K0Z9A9",
          "sourceClass": "Alpha extension reference",
          "itds": [
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            },
            {
              "id": "aitd-106-axis-auth-shape",
              "title": "API Axis: Auth Shape",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-106-axis-auth-shape"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "source_event_id",
          "type": "TEXT",
          "nullability": "required",
          "meaning": "Events Alpha event id this contribution derives from.",
          "constraints": "Must reference one closed Events row in the same tenant.",
          "relationship": "Many Analytics facts can reference one Events row; see https://platform3-andymontgomery-9773s-projects.vercel.app/events/alpha/data_dictionary#table-event.",
          "invalidWhen": "Null, cross-tenant, or replaced by a copied Caliper payload column.",
          "example": "evt_alpha_000891",
          "sourceClass": "Alpha extension reference",
          "itds": [
            {
              "id": "aitd-000-extend-only-storage",
              "title": "Analytics Is New Extend-Only Alpha Storage",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-000-extend-only-storage"
            },
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            },
            {
              "id": "aitd-005-time-facts-and-windows",
              "title": "Active, Inactive, And Waste Seconds Are Typed Derived Time Facts",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-005-time-facts-and-windows"
            }
          ]
        },
        {
          "name": "source_fact_key",
          "type": "TEXT",
          "nullability": "required",
          "meaning": "Deterministic idempotency key for the materialized source contribution or rollup.",
          "constraints": "Includes tenant, source ref, fact kind/scope, policy_ref, and calculation_version; max 512 bytes.",
          "relationship": "Unique per table where the row is a single materialized source contribution.",
          "invalidWhen": "Generated from non-deterministic timestamps or caller-provided display labels.",
          "example": "tenant:7b0b:event:evt_891:fact:active_seconds:policy:v2026-06-10:calc:1",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-105-axis-idempotency",
              "title": "API Axis: Idempotency Model",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-105-axis-idempotency"
            }
          ]
        },
        {
          "name": "source_closed_at",
          "type": "TIMESTAMPTZ",
          "nullability": "required",
          "meaning": "When the source Event or Result became closed enough for Analytics to materialize from it.",
          "constraints": "Set by Events/Results close/import notifications; UTC timestamp.",
          "relationship": "Prevents reports from reading provisional source rows as final derived facts.",
          "invalidWhen": "Null on a reportable row or copied from source payload without source close confirmation.",
          "example": "2026-05-14T18:32:20Z",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            }
          ]
        },
        {
          "name": "fact_kind",
          "type": "TEXT enum",
          "nullability": "required",
          "meaning": "Which time bucket this signed contribution belongs to.",
          "constraints": "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.",
          "relationship": "One source event can create up to one current row for each fact_kind under a policy.",
          "invalidWhen": "A caller supplies the bucket or a report parses app names/actions to infer it.",
          "example": "active_seconds",
          "enum": "fact_kind",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-005-time-facts-and-windows",
              "title": "Active, Inactive, And Waste Seconds Are Typed Derived Time Facts",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-005-time-facts-and-windows"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "seconds_delta",
          "type": "NUMERIC(14,3)",
          "nullability": "required",
          "meaning": "Signed seconds contributed by this source event to the fact_kind bucket.",
          "constraints": "May be negative for correction/reversal rows; ordinary display measures use rollup fields, not client-side clamping.",
          "relationship": "Feeds alpha.analytics_time_window totals.",
          "invalidWhen": "Assumed nonnegative for corrections or recomputed from source duration by a report.",
          "example": "420.000",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-005-time-facts-and-windows",
              "title": "Active, Inactive, And Waste Seconds Are Typed Derived Time Facts",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-005-time-facts-and-windows"
            },
            {
              "id": "aitd-012-corrections-and-reversals",
              "title": "Corrections Are Signed Facts With Provenance",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-012-corrections-and-reversals"
            }
          ]
        },
        {
          "name": "subject_id",
          "type": "TEXT",
          "nullability": "nullable where the row is all-subject or the source cannot validly resolve a subject",
          "meaning": "Canonical Alpha subject used for reporting and grouping.",
          "constraints": "Closed Alpha subject enum after write-time source-label normalization; unknown source subject becomes an adapter finding or null_reason, not a new string.",
          "relationship": "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.",
          "invalidWhen": "Copied from source strings such as FastMath, Vocabulary, Science-notqced, or ISEE variants without normalization.",
          "example": "math",
          "sourceClass": "Alpha extension reference",
          "itds": [
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "application_ref",
          "type": "TEXT",
          "nullability": "nullable",
          "meaning": "Application/activity-source reference resolved from the source event when available.",
          "constraints": "Reference only; application identity/lifecycle belongs to Applications.",
          "relationship": "Optional grouping key for app-level time evidence; not a user id.",
          "invalidWhen": "Used as a credential, treated as a student, or copied from app display text without registry resolution.",
          "example": "app_math_academy",
          "sourceClass": "Alpha extension reference",
          "itds": [
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "policy_ref",
          "type": "TEXT",
          "nullability": "required",
          "meaning": "Named policy/config version used to compute the measure or rollup.",
          "constraints": "Must point at alpha.policy.analytics.* or an inherited Curriculum/Results policy active for the source effective date.",
          "relationship": "Many Analytics facts can share one policy row; changing policy creates new calculation versions or corrections.",
          "invalidWhen": "A consumer hard-codes thresholds, school-day calendars, Growth X formulas, or completion denominators instead of using the policy ref.",
          "example": "alpha.policy.analytics.time_classification.v2026-06-10",
          "sourceClass": "Alpha extension reference",
          "itds": [
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            },
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            }
          ]
        },
        {
          "name": "quality_status",
          "type": "TEXT enum",
          "nullability": "required",
          "meaning": "Current materialization quality state for this fact.",
          "constraints": "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.",
          "relationship": "Used by raw/API convergence filters and source-ref audit views.",
          "invalidWhen": "Free-text status or hidden failures represented as HTTP 200 success.",
          "example": "ok",
          "enum": "quality_status",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            },
            {
              "id": "aitd-108-axis-error-envelope",
              "title": "API Axis: Error Envelope",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-108-axis-error-envelope"
            },
            {
              "id": "aitd-111-axis-privacy-retention",
              "title": "API Axis: Privacy And Retention",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-111-axis-privacy-retention"
            }
          ]
        },
        {
          "name": "calculation_version",
          "type": "INTEGER",
          "nullability": "required",
          "meaning": "Materializer calculation version for this fact shape.",
          "constraints": "Positive integer; starts at 1 and increments when policy/materializer logic intentionally changes.",
          "relationship": "Part of deterministic source_fact_key/idempotency for materializer writes.",
          "invalidWhen": "Omitted from replay keys or changed without a new policy/materializer decision.",
          "example": "1",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            },
            {
              "id": "aitd-105-axis-idempotency",
              "title": "API Axis: Idempotency Model",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-105-axis-idempotency"
            },
            {
              "id": "aitd-104-axis-concurrency",
              "title": "API Axis: Concurrency Model",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-104-axis-concurrency"
            }
          ]
        },
        {
          "name": "computed_at",
          "type": "TIMESTAMPTZ",
          "nullability": "required",
          "meaning": "When Analytics wrote this derived fact.",
          "constraints": "UTC timestamp with timezone; updated only by Analytics materializers.",
          "relationship": "Used for audit and source-ref subcollections, not for school-day grouping.",
          "invalidWhen": "Used as a substitute for the source event time, result effective time, or window boundaries.",
          "example": "2026-06-10T00:51:14Z",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            }
          ]
        },
        {
          "name": "modified_at",
          "type": "TIMESTAMPTZ",
          "nullability": "required",
          "meaning": "Last time the Analytics row changed for polling and modifiedSince queries.",
          "constraints": "UTC timestamp; list endpoints support modifiedSince against this field.",
          "relationship": "Supports poll plus modifiedSince eventing.",
          "invalidWhen": "Client-supplied or used as the business effective date.",
          "example": "2026-06-10T00:51:14Z",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-107-axis-eventing",
              "title": "API Axis: Eventing Model",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-107-axis-eventing"
            },
            {
              "id": "aitd-103-axis-query-model",
              "title": "API Axis: Query Model",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-103-axis-query-model"
            }
          ]
        },
        {
          "name": "superseded_at",
          "type": "TIMESTAMPTZ",
          "nullability": "nullable",
          "meaning": "When this row stopped being the current reportable version because of source correction, deletion, or recalculation.",
          "constraints": "Null means current; non-null rows are excluded from ordinary list reads unless includeSuperseded=true and authorized.",
          "relationship": "Preserves audit history without mutating source Events or Results.",
          "invalidWhen": "Used to hard-delete old rows or omitted on a correction that replaces a prior fact.",
          "example": "null",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-111-axis-privacy-retention",
              "title": "API Axis: Privacy And Retention",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-111-axis-privacy-retention"
            },
            {
              "id": "aitd-012-corrections-and-reversals",
              "title": "Corrections Are Signed Facts With Provenance",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-012-corrections-and-reversals"
            }
          ]
        },
        {
          "name": "source_deleted_at",
          "type": "TIMESTAMPTZ",
          "nullability": "nullable",
          "meaning": "When the source Event/Result became deleted or invalidated.",
          "constraints": "Null for live source rows; set from source tombstone/correction notifications.",
          "relationship": "Ordinary reads exclude tombstoned facts unless includeSuperseded=true and authorized.",
          "invalidWhen": "Used as a physical delete or ignored by raw-path report queries.",
          "example": "null",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-111-axis-privacy-retention",
              "title": "API Axis: Privacy And Retention",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-111-axis-privacy-retention"
            }
          ]
        }
      ],
      "plainLanguage": "One source event became one signed time contribution. Reports normally read the rollups, but this table explains why minutes changed."
    },
    {
      "name": "alpha.analytics_time_window",
      "title": "Time Window",
      "kind": "Alpha extension rollup table",
      "grain": "student_id x subject_id nullable x window_kind x window_start x window_end x policy_ref.",
      "primaryKey": "id; unique current grain is (tenant_id, student_id, subject_id, window_kind, window_start, window_end, policy_ref, calculation_version).",
      "lifecycle": "Refreshed idempotently after event-time facts close, replay, correct, or reverse.",
      "purpose": "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.",
      "metricChecks": [
        "minutes|Caliper events"
      ],
      "architecture": [
        {
          "id": "aitd-005-time-facts-and-windows",
          "title": "Active, Inactive, And Waste Seconds Are Typed Derived Time Facts",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-005-time-facts-and-windows"
        },
        {
          "id": "aitd-002-derived-events-complement",
          "title": "Derived-From-Events Facts Complement, Never Substitute For, Ingested Tiles",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-002-derived-events-complement"
        },
        {
          "id": "aitd-003-close-time-materialization",
          "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
        },
        {
          "id": "aitd-011-policy-and-enum-normalization",
          "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
        },
        {
          "id": "aitd-112-axis-list-endpoints",
          "title": "API Axis: List Endpoints",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-112-axis-list-endpoints"
        }
      ],
      "api": "GET /alpha/analytics/v1/time-windows",
      "rawRule": "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.",
      "example": {
        "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
      },
      "fields": [
        {
          "name": "id",
          "type": "UUID",
          "nullability": "required",
          "meaning": "Analytics-owned stable row id for this derived fact.",
          "constraints": "Generated by the platform; globally unique within alpha.analytics_* objects.",
          "relationship": "Primary key for list/detail endpoints.",
          "invalidWhen": "Provided by a public import client or reused across tenants.",
          "example": "8e9c0ef2-bc75-4f53-8124-df77df49f25f",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-000-extend-only-storage",
              "title": "Analytics Is New Extend-Only Alpha Storage",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-000-extend-only-storage"
            }
          ]
        },
        {
          "name": "tenant_id",
          "type": "UUID",
          "nullability": "required",
          "meaning": "Tenant boundary for the derived fact.",
          "constraints": "Set from the JWT tenant claim or internal materializer context; never accepted from request body/query.",
          "relationship": "All raw-path queries must filter by tenant_id before joining, sorting, paging, or counting.",
          "invalidWhen": "Missing, caller-supplied in body/query, or mismatched with the JWT tenant claim.",
          "example": "7b0bb5d8-9a38-4a62-9fdc-9f8d2dc1a111",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-109-axis-tenant-routing",
              "title": "API Axis: Tenant Routing",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-109-axis-tenant-routing"
            },
            {
              "id": "aitd-106-axis-auth-shape",
              "title": "API Axis: Auth Shape",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-106-axis-auth-shape"
            }
          ]
        },
        {
          "name": "student_id",
          "type": "TEXT",
          "nullability": "required",
          "meaning": "Canonical Alpha student id the source Event or Result resolved to at materialization time.",
          "constraints": "Must resolve through People and Orgs as a real student for the source timestamp/effective date.",
          "relationship": "References People and Orgs student identity; see https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/data_dictionary.",
          "invalidWhen": "Parsed from email/name/source payload instead of resolved by the Events/Results adapter.",
          "example": "student_01HT7G3YZV7QB5N4YKQ1K0Z9A9",
          "sourceClass": "Alpha extension reference",
          "itds": [
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            },
            {
              "id": "aitd-106-axis-auth-shape",
              "title": "API Axis: Auth Shape",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-106-axis-auth-shape"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "subject_id",
          "type": "TEXT",
          "nullability": "nullable where the row is all-subject or the source cannot validly resolve a subject",
          "meaning": "Canonical Alpha subject used for reporting and grouping.",
          "constraints": "Closed Alpha subject enum after write-time source-label normalization; unknown source subject becomes an adapter finding or null_reason, not a new string.",
          "relationship": "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.",
          "invalidWhen": "Copied from source strings such as FastMath, Vocabulary, Science-notqced, or ISEE variants without normalization.",
          "example": "math",
          "sourceClass": "Alpha extension reference",
          "itds": [
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "window_kind",
          "type": "TEXT enum",
          "nullability": "required",
          "meaning": "Named window family for this rollup.",
          "constraints": "Allowed values: window_kind enum; custom requires explicit policy/window metadata.",
          "relationship": "Part of the rollup grain and list filters.",
          "invalidWhen": "Inferred by parsing term labels or source date strings in a consumer.",
          "example": "day",
          "enum": "window_kind",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-005-time-facts-and-windows",
              "title": "Active, Inactive, And Waste Seconds Are Typed Derived Time Facts",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-005-time-facts-and-windows"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            },
            {
              "id": "aitd-103-axis-query-model",
              "title": "API Axis: Query Model",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-103-axis-query-model"
            }
          ]
        },
        {
          "name": "window_start",
          "type": "DATE",
          "nullability": "required",
          "meaning": "Inclusive start date of the reporting window in the school timezone.",
          "constraints": "Must be before window_end; ISO date.",
          "relationship": "Half-open range [window_start, window_end).",
          "invalidWhen": "Computed from modified_at or source_closed_at instead of the policy window.",
          "example": "2026-05-14",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-005-time-facts-and-windows",
              "title": "Active, Inactive, And Waste Seconds Are Typed Derived Time Facts",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-005-time-facts-and-windows"
            }
          ]
        },
        {
          "name": "window_end",
          "type": "DATE",
          "nullability": "required",
          "meaning": "Exclusive end date of the reporting window in the school timezone.",
          "constraints": "Must be after window_start; ISO date.",
          "relationship": "Half-open range [window_start, window_end).",
          "invalidWhen": "Treated as inclusive by raw-path queries.",
          "example": "2026-05-15",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-005-time-facts-and-windows",
              "title": "Active, Inactive, And Waste Seconds Are Typed Derived Time Facts",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-005-time-facts-and-windows"
            }
          ]
        },
        {
          "name": "active_seconds_total",
          "type": "NUMERIC(14,3)",
          "nullability": "required",
          "meaning": "Net active seconds from current event_time_fact rows in this window.",
          "constraints": "Can include signed corrections; display fields apply policy presentation.",
          "relationship": "Numerator source for school-day minutes.",
          "invalidWhen": "Recomputed by the app from source events.",
          "example": "3240.000",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-005-time-facts-and-windows",
              "title": "Active, Inactive, And Waste Seconds Are Typed Derived Time Facts",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-005-time-facts-and-windows"
            },
            {
              "id": "aitd-012-corrections-and-reversals",
              "title": "Corrections Are Signed Facts With Provenance",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-012-corrections-and-reversals"
            }
          ]
        },
        {
          "name": "inactive_seconds_total",
          "type": "NUMERIC(14,3)",
          "nullability": "required",
          "meaning": "Net inactive seconds from current event_time_fact rows in this window.",
          "constraints": "Can include signed corrections.",
          "relationship": "Report display/audit metric; not subtracted by consumers unless a named policy says so.",
          "invalidWhen": "Derived by client idle-threshold logic.",
          "example": "120.000",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-005-time-facts-and-windows",
              "title": "Active, Inactive, And Waste Seconds Are Typed Derived Time Facts",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-005-time-facts-and-windows"
            },
            {
              "id": "aitd-012-corrections-and-reversals",
              "title": "Corrections Are Signed Facts With Provenance",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-012-corrections-and-reversals"
            }
          ]
        },
        {
          "name": "waste_seconds_total",
          "type": "NUMERIC(14,3)",
          "nullability": "required",
          "meaning": "Net waste/gaming seconds from current event_time_fact rows in this window.",
          "constraints": "Can be positive or negative after corrections.",
          "relationship": "Feeds closed-loop dashboards and XP penalty audits.",
          "invalidWhen": "Modeled as an event category rather than an Analytics derived fact.",
          "example": "0.000",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-005-time-facts-and-windows",
              "title": "Active, Inactive, And Waste Seconds Are Typed Derived Time Facts",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-005-time-facts-and-windows"
            },
            {
              "id": "aitd-012-corrections-and-reversals",
              "title": "Corrections Are Signed Facts With Provenance",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-012-corrections-and-reversals"
            }
          ]
        },
        {
          "name": "display_active_minutes",
          "type": "NUMERIC(12,3)",
          "nullability": "required",
          "meaning": "Policy-defined active minutes shown in reports for this time window.",
          "constraints": "Computed by Analytics from active_seconds_total under policy_ref; consumers read it directly.",
          "relationship": "Used by app/report display when the question asks for active minutes, not raw seconds.",
          "invalidWhen": "Consumer divides seconds by 60 differently or clamps signed corrections locally.",
          "example": "54.000",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-005-time-facts-and-windows",
              "title": "Active, Inactive, And Waste Seconds Are Typed Derived Time Facts",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-005-time-facts-and-windows"
            },
            {
              "id": "aitd-012-corrections-and-reversals",
              "title": "Corrections Are Signed Facts With Provenance",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-012-corrections-and-reversals"
            }
          ]
        },
        {
          "name": "source_fact_count",
          "type": "INTEGER",
          "nullability": "required",
          "meaning": "Number of current event_time_fact rows contributing to this rollup.",
          "constraints": "Nonnegative integer.",
          "relationship": "Audit/provenance summary; detailed refs live in the authorized sourceRefs subcollection.",
          "invalidWhen": "Used as a proxy for number of Events without applying fact_kind and correction rules.",
          "example": "12",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-102-axis-read-shape",
              "title": "API Axis: Read Shape",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-102-axis-read-shape"
            }
          ]
        },
        {
          "name": "source_fact_refs",
          "type": "JSONB",
          "nullability": "required",
          "meaning": "Compact list or cursor descriptor for contributing analytics_event_time_fact ids.",
          "constraints": "Contains ids/hashes only, never raw Caliper payload or PII.",
          "relationship": "Supports /time-windows/{id}/source-refs for authorized audit users.",
          "invalidWhen": "Stores source payload copies or student display names.",
          "example": "[\"8e9c0ef2-bc75-4f53-8124-df77df49f25f\"]",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-000-extend-only-storage",
              "title": "Analytics Is New Extend-Only Alpha Storage",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-000-extend-only-storage"
            },
            {
              "id": "aitd-102-axis-read-shape",
              "title": "API Axis: Read Shape",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-102-axis-read-shape"
            },
            {
              "id": "aitd-111-axis-privacy-retention",
              "title": "API Axis: Privacy And Retention",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-111-axis-privacy-retention"
            }
          ]
        },
        {
          "name": "policy_ref",
          "type": "TEXT",
          "nullability": "required",
          "meaning": "Named policy/config version used to compute the measure or rollup.",
          "constraints": "Must point at alpha.policy.analytics.* or an inherited Curriculum/Results policy active for the source effective date.",
          "relationship": "Many Analytics facts can share one policy row; changing policy creates new calculation versions or corrections.",
          "invalidWhen": "A consumer hard-codes thresholds, school-day calendars, Growth X formulas, or completion denominators instead of using the policy ref.",
          "example": "alpha.policy.analytics.time_classification.v2026-06-10",
          "sourceClass": "Alpha extension reference",
          "itds": [
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            },
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            }
          ]
        },
        {
          "name": "quality_status",
          "type": "TEXT enum",
          "nullability": "required",
          "meaning": "Current materialization quality state for this fact.",
          "constraints": "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.",
          "relationship": "Used by raw/API convergence filters and source-ref audit views.",
          "invalidWhen": "Free-text status or hidden failures represented as HTTP 200 success.",
          "example": "ok",
          "enum": "quality_status",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            },
            {
              "id": "aitd-108-axis-error-envelope",
              "title": "API Axis: Error Envelope",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-108-axis-error-envelope"
            },
            {
              "id": "aitd-111-axis-privacy-retention",
              "title": "API Axis: Privacy And Retention",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-111-axis-privacy-retention"
            }
          ]
        },
        {
          "name": "calculation_version",
          "type": "INTEGER",
          "nullability": "required",
          "meaning": "Materializer calculation version for this fact shape.",
          "constraints": "Positive integer; starts at 1 and increments when policy/materializer logic intentionally changes.",
          "relationship": "Part of deterministic source_fact_key/idempotency for materializer writes.",
          "invalidWhen": "Omitted from replay keys or changed without a new policy/materializer decision.",
          "example": "1",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            },
            {
              "id": "aitd-105-axis-idempotency",
              "title": "API Axis: Idempotency Model",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-105-axis-idempotency"
            },
            {
              "id": "aitd-104-axis-concurrency",
              "title": "API Axis: Concurrency Model",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-104-axis-concurrency"
            }
          ]
        },
        {
          "name": "computed_at",
          "type": "TIMESTAMPTZ",
          "nullability": "required",
          "meaning": "When Analytics wrote this derived fact.",
          "constraints": "UTC timestamp with timezone; updated only by Analytics materializers.",
          "relationship": "Used for audit and source-ref subcollections, not for school-day grouping.",
          "invalidWhen": "Used as a substitute for the source event time, result effective time, or window boundaries.",
          "example": "2026-06-10T00:51:14Z",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            }
          ]
        },
        {
          "name": "modified_at",
          "type": "TIMESTAMPTZ",
          "nullability": "required",
          "meaning": "Last time the Analytics row changed for polling and modifiedSince queries.",
          "constraints": "UTC timestamp; list endpoints support modifiedSince against this field.",
          "relationship": "Supports poll plus modifiedSince eventing.",
          "invalidWhen": "Client-supplied or used as the business effective date.",
          "example": "2026-06-10T00:51:14Z",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-107-axis-eventing",
              "title": "API Axis: Eventing Model",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-107-axis-eventing"
            },
            {
              "id": "aitd-103-axis-query-model",
              "title": "API Axis: Query Model",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-103-axis-query-model"
            }
          ]
        },
        {
          "name": "superseded_at",
          "type": "TIMESTAMPTZ",
          "nullability": "nullable",
          "meaning": "When this row stopped being the current reportable version because of source correction, deletion, or recalculation.",
          "constraints": "Null means current; non-null rows are excluded from ordinary list reads unless includeSuperseded=true and authorized.",
          "relationship": "Preserves audit history without mutating source Events or Results.",
          "invalidWhen": "Used to hard-delete old rows or omitted on a correction that replaces a prior fact.",
          "example": "null",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-111-axis-privacy-retention",
              "title": "API Axis: Privacy And Retention",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-111-axis-privacy-retention"
            },
            {
              "id": "aitd-012-corrections-and-reversals",
              "title": "Corrections Are Signed Facts With Provenance",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-012-corrections-and-reversals"
            }
          ]
        },
        {
          "name": "source_deleted_at",
          "type": "TIMESTAMPTZ",
          "nullability": "nullable",
          "meaning": "When the source Event/Result became deleted or invalidated.",
          "constraints": "Null for live source rows; set from source tombstone/correction notifications.",
          "relationship": "Ordinary reads exclude tombstoned facts unless includeSuperseded=true and authorized.",
          "invalidWhen": "Used as a physical delete or ignored by raw-path report queries.",
          "example": "null",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-111-axis-privacy-retention",
              "title": "API Axis: Privacy And Retention",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-111-axis-privacy-retention"
            }
          ]
        }
      ],
      "plainLanguage": "How much active, inactive, and waste time a student had in a day, week, term, school year, or named custom range."
    },
    {
      "name": "alpha.analytics_school_day_minutes",
      "title": "School-Day Minutes",
      "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.",
      "primaryKey": "id; unique current grain is (tenant_id, student_id, school_id, subject_id, window_start, window_end, school_day_policy_ref, calculation_version).",
      "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.",
      "purpose": "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.",
      "metricChecks": [
        "minutes|Caliper events"
      ],
      "architecture": [
        {
          "id": "aitd-006-school-day-minutes",
          "title": "Minutes Per Enrolled School Day Uses The Alpha School Calendar",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-006-school-day-minutes"
        },
        {
          "id": "aitd-001-report-source-ingestion",
          "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
        },
        {
          "id": "aitd-004-provenance-no-literals",
          "title": "Every Report Value Traces To An Ingested Source Row, Or Reads Null",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-004-provenance-no-literals"
        },
        {
          "id": "aitd-005-time-facts-and-windows",
          "title": "Active, Inactive, And Waste Seconds Are Typed Derived Time Facts",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-005-time-facts-and-windows"
        },
        {
          "id": "aitd-011-policy-and-enum-normalization",
          "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
        }
      ],
      "api": "GET /alpha/analytics/v1/school-day-minutes",
      "rawRule": "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.",
      "example": {
        "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
      },
      "fields": [
        {
          "name": "id",
          "type": "UUID",
          "nullability": "required",
          "meaning": "Analytics-owned stable row id for this derived fact.",
          "constraints": "Generated by the platform; globally unique within alpha.analytics_* objects.",
          "relationship": "Primary key for list/detail endpoints.",
          "invalidWhen": "Provided by a public import client or reused across tenants.",
          "example": "8e9c0ef2-bc75-4f53-8124-df77df49f25f",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-000-extend-only-storage",
              "title": "Analytics Is New Extend-Only Alpha Storage",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-000-extend-only-storage"
            }
          ]
        },
        {
          "name": "tenant_id",
          "type": "UUID",
          "nullability": "required",
          "meaning": "Tenant boundary for the derived fact.",
          "constraints": "Set from the JWT tenant claim or internal materializer context; never accepted from request body/query.",
          "relationship": "All raw-path queries must filter by tenant_id before joining, sorting, paging, or counting.",
          "invalidWhen": "Missing, caller-supplied in body/query, or mismatched with the JWT tenant claim.",
          "example": "7b0bb5d8-9a38-4a62-9fdc-9f8d2dc1a111",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-109-axis-tenant-routing",
              "title": "API Axis: Tenant Routing",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-109-axis-tenant-routing"
            },
            {
              "id": "aitd-106-axis-auth-shape",
              "title": "API Axis: Auth Shape",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-106-axis-auth-shape"
            }
          ]
        },
        {
          "name": "student_id",
          "type": "TEXT",
          "nullability": "required",
          "meaning": "Canonical Alpha student id the source Event or Result resolved to at materialization time.",
          "constraints": "Must resolve through People and Orgs as a real student for the source timestamp/effective date.",
          "relationship": "References People and Orgs student identity; see https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/data_dictionary.",
          "invalidWhen": "Parsed from email/name/source payload instead of resolved by the Events/Results adapter.",
          "example": "student_01HT7G3YZV7QB5N4YKQ1K0Z9A9",
          "sourceClass": "Alpha extension reference",
          "itds": [
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            },
            {
              "id": "aitd-106-axis-auth-shape",
              "title": "API Axis: Auth Shape",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-106-axis-auth-shape"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "school_id",
          "type": "TEXT",
          "nullability": "required",
          "meaning": "People and Orgs school whose calendar/enrollment intersection defines the denominator.",
          "constraints": "Must resolve as the student school for the effective range; no current-only shortcut.",
          "relationship": "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).",
          "invalidWhen": "Copied from source campus_name or joined through current roster instead of effective-dated enrollment.",
          "example": "school_alpha_austin",
          "sourceClass": "Alpha extension reference",
          "itds": [
            {
              "id": "aitd-006-school-day-minutes",
              "title": "Minutes Per Enrolled School Day Uses The Alpha School Calendar",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-006-school-day-minutes"
            }
          ]
        },
        {
          "name": "subject_id",
          "type": "TEXT",
          "nullability": "nullable; null means all reportable subjects",
          "meaning": "Canonical Alpha subject used for reporting and grouping.",
          "constraints": "Closed Alpha subject enum after write-time source-label normalization; unknown source subject becomes an adapter finding or null_reason, not a new string.",
          "relationship": "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.",
          "invalidWhen": "Copied from source strings such as FastMath, Vocabulary, Science-notqced, or ISEE variants without normalization.",
          "example": "math",
          "sourceClass": "Alpha extension reference",
          "itds": [
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "school_day_policy_ref",
          "type": "TEXT",
          "nullability": "required",
          "meaning": "Named policy/config version used to compute the measure or rollup.",
          "constraints": "Must point at alpha.policy.analytics.* or an inherited Curriculum/Results policy active for the source effective date.",
          "relationship": "Many Analytics facts can share one policy row; changing policy creates new calculation versions or corrections.",
          "invalidWhen": "A consumer hard-codes thresholds, school-day calendars, Growth X formulas, or completion denominators instead of using the policy ref.",
          "example": "alpha.policy.school_day.v2026-06-10",
          "sourceClass": "Alpha extension reference",
          "itds": [
            {
              "id": "aitd-006-school-day-minutes",
              "title": "Minutes Per Enrolled School Day Uses The Alpha School Calendar",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-006-school-day-minutes"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "window_start",
          "type": "DATE",
          "nullability": "required",
          "meaning": "Inclusive start date for the denominator/numerator window.",
          "constraints": "ISO date; half-open range with window_end.",
          "relationship": "Used with school_id calendar and enrollment refs.",
          "invalidWhen": "Parsed from report labels or MAP term strings.",
          "example": "2026-05-01",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-006-school-day-minutes",
              "title": "Minutes Per Enrolled School Day Uses The Alpha School Calendar",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-006-school-day-minutes"
            }
          ]
        },
        {
          "name": "window_end",
          "type": "DATE",
          "nullability": "required",
          "meaning": "Exclusive end date for the denominator/numerator window.",
          "constraints": "ISO date; must be after window_start.",
          "relationship": "Used with school_id calendar and enrollment refs.",
          "invalidWhen": "Treated as inclusive by raw queries.",
          "example": "2026-06-01",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-006-school-day-minutes",
              "title": "Minutes Per Enrolled School Day Uses The Alpha School Calendar",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-006-school-day-minutes"
            }
          ]
        },
        {
          "name": "enrolled_school_day_count",
          "type": "INTEGER",
          "nullability": "required when null_reason=none; nullable only for source_missing repair rows",
          "meaning": "Denominator: school days intersecting the student effective-dated enrollment and subject assignment when subject_id is present.",
          "constraints": "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.",
          "relationship": "Comes from alpha.school_calendar and People and Orgs enrollment windows.",
          "invalidWhen": "Computed from processed_facts active dates, attendance days, raw calendar days, or current enrollment by a report.",
          "example": "90",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-006-school-day-minutes",
              "title": "Minutes Per Enrolled School Day Uses The Alpha School Calendar",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-006-school-day-minutes"
            }
          ]
        },
        {
          "name": "excluded_school_day_count",
          "type": "INTEGER",
          "nullability": "required when null_reason=none; nullable only for source_missing repair rows",
          "meaning": "Calendar dates inside the requested window that the school-day policy excluded from the denominator.",
          "constraints": "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.",
          "relationship": "Same alpha.school_calendar source and enrollment/subject intersection pass as enrolled_school_day_count.",
          "invalidWhen": "Guessed from weekends, hard-coded MAP dates, or attendance gaps without calendar rows.",
          "example": "61",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-006-school-day-minutes",
              "title": "Minutes Per Enrolled School Day Uses The Alpha School Calendar",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-006-school-day-minutes"
            }
          ]
        },
        {
          "name": "active_minutes",
          "type": "NUMERIC(12,3)",
          "nullability": "required",
          "meaning": "Policy-defined active minutes for the same window and subject grain.",
          "constraints": "Normalized by the timeback-xp-time-accuracy adapter from reporting.processed_facts.active_seconds, then stored as minutes under policy_ref.",
          "relationship": "Numerator for minutes_per_enrolled_school_day; analytics_time_window remains the derived Events audit complement.",
          "invalidWhen": "A consumer sums raw event durations, divides processed_facts seconds, or substitutes derived audit seconds for the report tile.",
          "example": "4860.000",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-006-school-day-minutes",
              "title": "Minutes Per Enrolled School Day Uses The Alpha School Calendar",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-006-school-day-minutes"
            },
            {
              "id": "aitd-001-report-source-ingestion",
              "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
            },
            {
              "id": "aitd-005-time-facts-and-windows",
              "title": "Active, Inactive, And Waste Seconds Are Typed Derived Time Facts",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-005-time-facts-and-windows"
            }
          ]
        },
        {
          "name": "minutes_per_enrolled_school_day",
          "type": "NUMERIC(12,3)",
          "nullability": "nullable when denominator is zero or policy/source is missing",
          "meaning": "Report-ready average active minutes per enrolled school day when the school-day denominator source is available.",
          "constraints": "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.",
          "relationship": "The value reports and skill packs read. A null/source_missing row is a repair state, not a normal rendered value.",
          "invalidWhen": "Computed by a dashboard from active_minutes and a client-side day count.",
          "example": "54.000",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-006-school-day-minutes",
              "title": "Minutes Per Enrolled School Day Uses The Alpha School Calendar",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-006-school-day-minutes"
            }
          ]
        },
        {
          "name": "calendar_ref_count",
          "type": "INTEGER",
          "nullability": "required when null_reason=none; nullable only for source_missing repair rows",
          "meaning": "Count of school calendar rows used in the denominator calculation.",
          "constraints": "Nonnegative when populated; detailed ids available only to authorized audit reads. Null only when calendar coverage itself is source_missing.",
          "relationship": "Audit summary for alpha.school_calendar source coverage.",
          "invalidWhen": "Treated as enrolled school day count without applying enrollment/subject filters.",
          "example": "151",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-006-school-day-minutes",
              "title": "Minutes Per Enrolled School Day Uses The Alpha School Calendar",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-006-school-day-minutes"
            },
            {
              "id": "aitd-102-axis-read-shape",
              "title": "API Axis: Read Shape",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-102-axis-read-shape"
            }
          ]
        },
        {
          "name": "enrollment_ref_count",
          "type": "INTEGER",
          "nullability": "required",
          "meaning": "Count of People and Orgs enrollment/membership rows used for the point-in-time denominator.",
          "constraints": "Nonnegative; null begin_date memberships are excluded from denominator claims.",
          "relationship": "Audit summary for point-in-time roster source coverage.",
          "invalidWhen": "Used to infer current school membership outside the requested date range.",
          "example": "1",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-006-school-day-minutes",
              "title": "Minutes Per Enrolled School Day Uses The Alpha School Calendar",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-006-school-day-minutes"
            }
          ]
        },
        {
          "name": "quality_status",
          "type": "TEXT enum",
          "nullability": "required",
          "meaning": "Current materialization quality state for this school-day denominator row.",
          "constraints": "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.",
          "relationship": "Used with null_reason so the API and raw path can expose repair states without letting reports guess.",
          "invalidWhen": "A source_missing row is treated as a reportable time-commitment value.",
          "example": "ok",
          "enum": "quality_status",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-006-school-day-minutes",
              "title": "Minutes Per Enrolled School Day Uses The Alpha School Calendar",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-006-school-day-minutes"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            },
            {
              "id": "aitd-108-axis-error-envelope",
              "title": "API Axis: Error Envelope",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-108-axis-error-envelope"
            }
          ]
        },
        {
          "name": "null_reason",
          "type": "TEXT enum",
          "nullability": "required",
          "meaning": "Why minutes_per_enrolled_school_day and denominator counts are null or not reportable.",
          "constraints": "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.",
          "relationship": "Prevents clients from guessing fallback denominator rules.",
          "invalidWhen": "Null denominator fields with no typed reason, or a free-text explanation.",
          "example": "none",
          "enum": "null_reason",
          "sourceClass": "Alpha extension enum",
          "itds": [
            {
              "id": "aitd-006-school-day-minutes",
              "title": "Minutes Per Enrolled School Day Uses The Alpha School Calendar",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-006-school-day-minutes"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "source_import_id",
          "type": "TEXT",
          "nullability": "required for report-tile rows; nullable for purely derived event-axis rows",
          "meaning": "Analytics source-import receipt that proves which named report-source adapter produced this report-grade fact.",
          "constraints": "Must reference alpha.analytics_source_import for non-null Learning Report tile values; no literal or fixture value may be reportable without this provenance.",
          "relationship": "Many report-fact rows can reference one source import; detail/sourceRefs endpoints join here for adapter, source_table, and source_row_key_hashes.",
          "invalidWhen": "Missing on a non-null report-tile value, or replaced by copied raw reporting-DB columns.",
          "example": "imp_01HT8XPTIME_2026_SPRING",
          "sourceClass": "Alpha extension provenance reference",
          "itds": [
            {
              "id": "aitd-001-report-source-ingestion",
              "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
            },
            {
              "id": "aitd-004-provenance-no-literals",
              "title": "Every Report Value Traces To An Ingested Source Row, Or Reads Null",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-004-provenance-no-literals"
            },
            {
              "id": "aitd-006-school-day-minutes",
              "title": "Minutes Per Enrolled School Day Uses The Alpha School Calendar",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-006-school-day-minutes"
            }
          ]
        },
        {
          "name": "calculation_version",
          "type": "INTEGER",
          "nullability": "required",
          "meaning": "Materializer calculation version for this fact shape.",
          "constraints": "Positive integer; starts at 1 and increments when policy/materializer logic intentionally changes.",
          "relationship": "Part of deterministic source_fact_key/idempotency for materializer writes.",
          "invalidWhen": "Omitted from replay keys or changed without a new policy/materializer decision.",
          "example": "1",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            },
            {
              "id": "aitd-105-axis-idempotency",
              "title": "API Axis: Idempotency Model",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-105-axis-idempotency"
            },
            {
              "id": "aitd-104-axis-concurrency",
              "title": "API Axis: Concurrency Model",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-104-axis-concurrency"
            }
          ]
        },
        {
          "name": "computed_at",
          "type": "TIMESTAMPTZ",
          "nullability": "required",
          "meaning": "When Analytics wrote this derived fact.",
          "constraints": "UTC timestamp with timezone; updated only by Analytics materializers.",
          "relationship": "Used for audit and source-ref subcollections, not for school-day grouping.",
          "invalidWhen": "Used as a substitute for the source event time, result effective time, or window boundaries.",
          "example": "2026-06-10T00:51:14Z",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            }
          ]
        },
        {
          "name": "modified_at",
          "type": "TIMESTAMPTZ",
          "nullability": "required",
          "meaning": "Last time the Analytics row changed for polling and modifiedSince queries.",
          "constraints": "UTC timestamp; list endpoints support modifiedSince against this field.",
          "relationship": "Supports poll plus modifiedSince eventing.",
          "invalidWhen": "Client-supplied or used as the business effective date.",
          "example": "2026-06-10T00:51:14Z",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-107-axis-eventing",
              "title": "API Axis: Eventing Model",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-107-axis-eventing"
            },
            {
              "id": "aitd-103-axis-query-model",
              "title": "API Axis: Query Model",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-103-axis-query-model"
            }
          ]
        },
        {
          "name": "superseded_at",
          "type": "TIMESTAMPTZ",
          "nullability": "nullable",
          "meaning": "When this row stopped being the current reportable version because of source correction, deletion, or recalculation.",
          "constraints": "Null means current; non-null rows are excluded from ordinary list reads unless includeSuperseded=true and authorized.",
          "relationship": "Preserves audit history without mutating source Events or Results.",
          "invalidWhen": "Used to hard-delete old rows or omitted on a correction that replaces a prior fact.",
          "example": "null",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-111-axis-privacy-retention",
              "title": "API Axis: Privacy And Retention",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-111-axis-privacy-retention"
            },
            {
              "id": "aitd-012-corrections-and-reversals",
              "title": "Corrections Are Signed Facts With Provenance",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-012-corrections-and-reversals"
            }
          ]
        },
        {
          "name": "source_deleted_at",
          "type": "TIMESTAMPTZ",
          "nullability": "nullable",
          "meaning": "When the source Event/Result became deleted or invalidated.",
          "constraints": "Null for live source rows; set from source tombstone/correction notifications.",
          "relationship": "Ordinary reads exclude tombstoned facts unless includeSuperseded=true and authorized.",
          "invalidWhen": "Used as a physical delete or ignored by raw-path report queries.",
          "example": "null",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-111-axis-privacy-retention",
              "title": "API Axis: Privacy And Retention",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-111-axis-privacy-retention"
            }
          ]
        }
      ],
      "plainLanguage": "The Learning Report time-commitment row: active minutes plus the materialized school-day denominator and report-ready minutes per enrolled school day."
    },
    {
      "name": "alpha.analytics_xp_rollup",
      "title": "XP Rollup",
      "kind": "Alpha extension rollup table",
      "grain": "student_id x subject_id nullable x window_kind x window_start x window_end x policy_ref.",
      "primaryKey": "id; unique current grain is (tenant_id, student_id, subject_id, window_kind, window_start, window_end, policy_ref, calculation_version).",
      "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.",
      "purpose": "Report-ready XP total plus goal progress fields. The goal fields use the same materialized school-day denominator as time commitment.",
      "metricChecks": [
        "XP"
      ],
      "architecture": [
        {
          "id": "aitd-007-xp-rollups",
          "title": "XP Totals, Goal, Remaining, And Completion Percent Are Ingested Report Facts",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-007-xp-rollups"
        },
        {
          "id": "aitd-001-report-source-ingestion",
          "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
        },
        {
          "id": "aitd-004-provenance-no-literals",
          "title": "Every Report Value Traces To An Ingested Source Row, Or Reads Null",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-004-provenance-no-literals"
        },
        {
          "id": "aitd-003-close-time-materialization",
          "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
        },
        {
          "id": "aitd-012-corrections-and-reversals",
          "title": "Corrections Are Signed Facts With Provenance",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-012-corrections-and-reversals"
        }
      ],
      "api": "GET /alpha/analytics/v1/xp-rollups",
      "apiReadRule": "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.",
      "rawRule": "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.",
      "example": {
        "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
      },
      "fields": [
        {
          "name": "id",
          "type": "UUID",
          "nullability": "required",
          "meaning": "Analytics-owned stable row id for this derived fact.",
          "constraints": "Generated by the platform; globally unique within alpha.analytics_* objects.",
          "relationship": "Primary key for list/detail endpoints.",
          "invalidWhen": "Provided by a public import client or reused across tenants.",
          "example": "8e9c0ef2-bc75-4f53-8124-df77df49f25f",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-000-extend-only-storage",
              "title": "Analytics Is New Extend-Only Alpha Storage",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-000-extend-only-storage"
            }
          ]
        },
        {
          "name": "tenant_id",
          "type": "UUID",
          "nullability": "required",
          "meaning": "Tenant boundary for the derived fact.",
          "constraints": "Set from the JWT tenant claim or internal materializer context; never accepted from request body/query.",
          "relationship": "All raw-path queries must filter by tenant_id before joining, sorting, paging, or counting.",
          "invalidWhen": "Missing, caller-supplied in body/query, or mismatched with the JWT tenant claim.",
          "example": "7b0bb5d8-9a38-4a62-9fdc-9f8d2dc1a111",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-109-axis-tenant-routing",
              "title": "API Axis: Tenant Routing",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-109-axis-tenant-routing"
            },
            {
              "id": "aitd-106-axis-auth-shape",
              "title": "API Axis: Auth Shape",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-106-axis-auth-shape"
            }
          ]
        },
        {
          "name": "student_id",
          "type": "TEXT",
          "nullability": "required",
          "meaning": "Canonical Alpha student id the source Event or Result resolved to at materialization time.",
          "constraints": "Must resolve through People and Orgs as a real student for the source timestamp/effective date.",
          "relationship": "References People and Orgs student identity; see https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/data_dictionary.",
          "invalidWhen": "Parsed from email/name/source payload instead of resolved by the Events/Results adapter.",
          "example": "student_01HT7G3YZV7QB5N4YKQ1K0Z9A9",
          "sourceClass": "Alpha extension reference",
          "itds": [
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            },
            {
              "id": "aitd-106-axis-auth-shape",
              "title": "API Axis: Auth Shape",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-106-axis-auth-shape"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "subject_id",
          "type": "TEXT",
          "nullability": "nullable where the row is all-subject or the source cannot validly resolve a subject",
          "meaning": "Canonical Alpha subject used for reporting and grouping.",
          "constraints": "Closed Alpha subject enum after write-time source-label normalization; unknown source subject becomes an adapter finding or null_reason, not a new string.",
          "relationship": "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.",
          "invalidWhen": "Copied from source strings such as FastMath, Vocabulary, Science-notqced, or ISEE variants without normalization.",
          "example": "math",
          "sourceClass": "Alpha extension reference",
          "itds": [
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "policy_ref",
          "type": "TEXT",
          "nullability": "required",
          "meaning": "Named policy/config version used to compute the measure or rollup.",
          "constraints": "Must point at alpha.policy.analytics.* or an inherited Curriculum/Results policy active for the source effective date.",
          "relationship": "Many Analytics facts can share one policy row; changing policy creates new calculation versions or corrections.",
          "invalidWhen": "A consumer hard-codes thresholds, school-day calendars, Growth X formulas, or completion denominators instead of using the policy ref.",
          "example": "alpha.policy.analytics.xp_goal_percent.v1",
          "sourceClass": "Alpha extension reference",
          "itds": [
            {
              "id": "aitd-007-xp-rollups",
              "title": "XP Totals, Goal, Remaining, And Completion Percent Are Ingested Report Facts",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-007-xp-rollups"
            },
            {
              "id": "aitd-006-school-day-minutes",
              "title": "Minutes Per Enrolled School Day Uses The Alpha School Calendar",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-006-school-day-minutes"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "window_kind",
          "type": "TEXT enum",
          "nullability": "required",
          "meaning": "Named window family for the XP rollup.",
          "constraints": "Allowed values: window_kind enum.",
          "relationship": "Part of XP rollup grain and list filters.",
          "invalidWhen": "Parsed from report title or term label.",
          "example": "term",
          "enum": "window_kind",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-007-xp-rollups",
              "title": "XP Totals, Goal, Remaining, And Completion Percent Are Ingested Report Facts",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-007-xp-rollups"
            },
            {
              "id": "aitd-103-axis-query-model",
              "title": "API Axis: Query Model",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-103-axis-query-model"
            }
          ]
        },
        {
          "name": "window_start",
          "type": "DATE",
          "nullability": "required",
          "meaning": "Inclusive start date for included XP ledger effective dates.",
          "constraints": "ISO date; half-open with window_end.",
          "relationship": "Defines XP reporting period.",
          "invalidWhen": "Uses computed_at instead of ledger effective date.",
          "example": "2026-01-01",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-007-xp-rollups",
              "title": "XP Totals, Goal, Remaining, And Completion Percent Are Ingested Report Facts",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-007-xp-rollups"
            }
          ]
        },
        {
          "name": "window_end",
          "type": "DATE",
          "nullability": "required",
          "meaning": "Exclusive end date for included XP ledger effective dates.",
          "constraints": "ISO date; must be after window_start.",
          "relationship": "Defines XP reporting period.",
          "invalidWhen": "Treated as inclusive in raw queries.",
          "example": "2026-06-01",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-007-xp-rollups",
              "title": "XP Totals, Goal, Remaining, And Completion Percent Are Ingested Report Facts",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-007-xp-rollups"
            }
          ]
        },
        {
          "name": "positive_xp",
          "type": "NUMERIC(14,3)",
          "nullability": "required",
          "meaning": "Positive XP contribution subtotal retained for audit/explanation.",
          "constraints": "Nonnegative; normalized by the adapter/materializer, with Results xp_ledger refs when available.",
          "relationship": "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.",
          "invalidWhen": "Computed by apps from accuracy, effort, expected_xp, or raw source rows.",
          "example": "11850.000",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-007-xp-rollups",
              "title": "XP Totals, Goal, Remaining, And Completion Percent Are Ingested Report Facts",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-007-xp-rollups"
            }
          ]
        },
        {
          "name": "negative_xp",
          "type": "NUMERIC(14,3)",
          "nullability": "required",
          "meaning": "Sum of negative XP penalties/reversals in this rollup.",
          "constraints": "Zero or negative; gaming/cheating signals and reversals stay signed.",
          "relationship": "Explains why net_xp may be lower than positive_xp.",
          "invalidWhen": "Dropped from reports or clamped to zero by consumers.",
          "example": "-50.000",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-007-xp-rollups",
              "title": "XP Totals, Goal, Remaining, And Completion Percent Are Ingested Report Facts",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-007-xp-rollups"
            },
            {
              "id": "aitd-012-corrections-and-reversals",
              "title": "Corrections Are Signed Facts With Provenance",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-012-corrections-and-reversals"
            }
          ]
        },
        {
          "name": "xp_total",
          "type": "NUMERIC(14,3)",
          "nullability": "required",
          "meaning": "Policy-defined report XP total after the report-source adapter applies subject normalization, exclusions, corrections, and signed contributions.",
          "constraints": "Non-null values require source_import_id provenance; should equal the report value for this student/subject/window.",
          "relationship": "The XP value dashboards render.",
          "invalidWhen": "Recomputed from processed_facts, xp_ledger, expected_xp, accuracy, or effort by a report.",
          "example": "11800.000",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-007-xp-rollups",
              "title": "XP Totals, Goal, Remaining, And Completion Percent Are Ingested Report Facts",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-007-xp-rollups"
            },
            {
              "id": "aitd-001-report-source-ingestion",
              "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
            },
            {
              "id": "aitd-004-provenance-no-literals",
              "title": "Every Report Value Traces To An Ingested Source Row, Or Reads Null",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-004-provenance-no-literals"
            }
          ]
        },
        {
          "name": "net_xp",
          "type": "NUMERIC(14,3)",
          "nullability": "required",
          "meaning": "Signed audit total after positive and negative XP contributions; equal to xp_total for ordinary report rows under the current policy.",
          "constraints": "positive_xp + negative_xp under policy_ref; retained for correction/reversal reconciliation.",
          "relationship": "Explains how signed contributions reconcile to xp_total.",
          "invalidWhen": "Used by a consumer instead of xp_total when the two diverge under a future policy.",
          "example": "11800.000",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-007-xp-rollups",
              "title": "XP Totals, Goal, Remaining, And Completion Percent Are Ingested Report Facts",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-007-xp-rollups"
            },
            {
              "id": "aitd-012-corrections-and-reversals",
              "title": "Corrections Are Signed Facts With Provenance",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-012-corrections-and-reversals"
            }
          ]
        },
        {
          "name": "xp_goal",
          "type": "NUMERIC(14,3)",
          "nullability": "required when null_reason=none; nullable only when enrolled_school_day_count or XP goal policy is missing",
          "meaning": "Window XP target for this student, subject, and window, used by the Learning Report XP Remaining and XP Goal Percent panels.",
          "constraints": "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.",
          "relationship": "Lets reports show XP remaining without reading Curriculum trees or goal policy directly.",
          "invalidWhen": "A report computes the goal from Content expected_xp, active dates, attendance days, raw calendar days, or hard-coded course sizes.",
          "example": "9000.000",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-007-xp-rollups",
              "title": "XP Totals, Goal, Remaining, And Completion Percent Are Ingested Report Facts",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-007-xp-rollups"
            },
            {
              "id": "aitd-006-school-day-minutes",
              "title": "Minutes Per Enrolled School Day Uses The Alpha School Calendar",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-006-school-day-minutes"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "daily_xp_goal",
          "type": "NUMERIC(14,3)",
          "nullability": "nullable when daily XP policy is missing",
          "meaning": "Daily XP target used in the auditor-pinned XP goal percent denominator.",
          "constraints": "Nonnegative; read from alpha.policy.analytics.xp_goal_percent.v1 / Curriculum Policy, never from a consumer constant.",
          "relationship": "Multiplied by enrolled_school_day_count to produce xp_goal.",
          "invalidWhen": "Hard-coded in a report, skill pack, or import caller.",
          "example": "100.000",
          "sourceClass": "Alpha extension policy reference value",
          "itds": [
            {
              "id": "aitd-007-xp-rollups",
              "title": "XP Totals, Goal, Remaining, And Completion Percent Are Ingested Report Facts",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-007-xp-rollups"
            },
            {
              "id": "aitd-006-school-day-minutes",
              "title": "Minutes Per Enrolled School Day Uses The Alpha School Calendar",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-006-school-day-minutes"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "enrolled_school_day_count",
          "type": "INTEGER",
          "nullability": "required when null_reason=none; nullable only when school-day denominator source is missing",
          "meaning": "Number of days in the XP percent denominator: days the student was enrolled and school was in session.",
          "constraints": "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.",
          "relationship": "Same ratified denominator policy as alpha.analytics_school_day_minutes, reused for xp_goal_percent.",
          "invalidWhen": "Computed from active dates, attendance rows, weekdays, or a current-only enrollment shortcut.",
          "example": "90",
          "sourceClass": "Alpha extension policy reference value",
          "itds": [
            {
              "id": "aitd-007-xp-rollups",
              "title": "XP Totals, Goal, Remaining, And Completion Percent Are Ingested Report Facts",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-007-xp-rollups"
            },
            {
              "id": "aitd-006-school-day-minutes",
              "title": "Minutes Per Enrolled School Day Uses The Alpha School Calendar",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-006-school-day-minutes"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "xp_remaining",
          "type": "NUMERIC(14,3)",
          "nullability": "required when null_reason=none; nullable when xp_goal is null/source_missing",
          "meaning": "Report-ready remaining XP under policy_ref.",
          "constraints": "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.",
          "relationship": "Displayed as XP Remaining in the Learning Report.",
          "invalidWhen": "Negative, or recomputed by a dashboard after reading net_xp.",
          "example": "0.000",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-007-xp-rollups",
              "title": "XP Totals, Goal, Remaining, And Completion Percent Are Ingested Report Facts",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-007-xp-rollups"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "xp_goal_percent",
          "type": "NUMERIC(9,3)",
          "nullability": "nullable when daily_xp_goal or enrolled_school_day_count is null or zero",
          "meaning": "Uncapped percent of the XP goal reached in this window when the school-day denominator is available.",
          "constraints": "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.",
          "relationship": "Canonical Learning Report XP percent; xp_completion_percent, if present, is only a deprecated compatibility alias with the same value.",
          "invalidWhen": "Capped at 100, named as a captured percent, recomputed by a report, or divided by a locally computed goal.",
          "example": "131.111",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-007-xp-rollups",
              "title": "XP Totals, Goal, Remaining, And Completion Percent Are Ingested Report Facts",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-007-xp-rollups"
            },
            {
              "id": "aitd-006-school-day-minutes",
              "title": "Minutes Per Enrolled School Day Uses The Alpha School Calendar",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-006-school-day-minutes"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "xp_completion_percent",
          "type": "NUMERIC(9,3)",
          "nullability": "deprecated compatibility alias; nullability matches xp_goal_percent",
          "meaning": "Deprecated compatibility alias for xp_goal_percent.",
          "constraints": "Must equal xp_goal_percent exactly and remains uncapped. It has no independent capped-completion meaning. Nullability matches xp_goal_percent.",
          "relationship": "Kept only so older deployed consumers can migrate; new reports use xp_goal_percent.",
          "invalidWhen": "Different from xp_goal_percent, capped at 100, or treated as course completion percent.",
          "example": "131.111",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-007-xp-rollups",
              "title": "XP Totals, Goal, Remaining, And Completion Percent Are Ingested Report Facts",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-007-xp-rollups"
            },
            {
              "id": "aitd-006-school-day-minutes",
              "title": "Minutes Per Enrolled School Day Uses The Alpha School Calendar",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-006-school-day-minutes"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "on_track",
          "type": "BOOLEAN",
          "nullability": "nullable when xp_goal_percent is null",
          "meaning": "Whether the student is on track against the XP goal policy for this window.",
          "constraints": "Computed under policy_ref; null means the goal policy or denominator is missing.",
          "relationship": "Report flag for XP-goal intervention workflows.",
          "invalidWhen": "Client compares XP to a local threshold.",
          "example": "true",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-007-xp-rollups",
              "title": "XP Totals, Goal, Remaining, And Completion Percent Are Ingested Report Facts",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-007-xp-rollups"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "award_count",
          "type": "INTEGER",
          "nullability": "required",
          "meaning": "Number of positive or neutral XP ledger rows contributing to this rollup.",
          "constraints": "Nonnegative; excludes superseded rows unless audit query requests them.",
          "relationship": "Provenance summary for Results xp_ledger source rows.",
          "invalidWhen": "Used as a count of attempts or Events.",
          "example": "24",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-007-xp-rollups",
              "title": "XP Totals, Goal, Remaining, And Completion Percent Are Ingested Report Facts",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-007-xp-rollups"
            },
            {
              "id": "aitd-102-axis-read-shape",
              "title": "API Axis: Read Shape",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-102-axis-read-shape"
            }
          ]
        },
        {
          "name": "reversal_count",
          "type": "INTEGER",
          "nullability": "required",
          "meaning": "Number of reversal/correction XP ledger rows included.",
          "constraints": "Nonnegative.",
          "relationship": "Audit signal for signed corrections.",
          "invalidWhen": "Ignored when reconciling old source totals to current reports.",
          "example": "1",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-007-xp-rollups",
              "title": "XP Totals, Goal, Remaining, And Completion Percent Are Ingested Report Facts",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-007-xp-rollups"
            },
            {
              "id": "aitd-012-corrections-and-reversals",
              "title": "Corrections Are Signed Facts With Provenance",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-012-corrections-and-reversals"
            }
          ]
        },
        {
          "name": "source_ledger_refs",
          "type": "JSONB",
          "nullability": "required",
          "meaning": "Compact ids/cursor for contributing Results xp_ledger rows.",
          "constraints": "Stores refs/hashes only; never copies scores, content expected_xp, or event payloads.",
          "relationship": "Supports /xp-rollups/{id}/source-refs for authorized audits.",
          "invalidWhen": "Stores raw Results columns that belong to Results.",
          "example": "[\"xp_award_01HT7K\"]",
          "sourceClass": "Alpha extension reference list",
          "itds": [
            {
              "id": "aitd-000-extend-only-storage",
              "title": "Analytics Is New Extend-Only Alpha Storage",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-000-extend-only-storage"
            },
            {
              "id": "aitd-007-xp-rollups",
              "title": "XP Totals, Goal, Remaining, And Completion Percent Are Ingested Report Facts",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-007-xp-rollups"
            },
            {
              "id": "aitd-102-axis-read-shape",
              "title": "API Axis: Read Shape",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-102-axis-read-shape"
            }
          ]
        },
        {
          "name": "source_import_id",
          "type": "TEXT",
          "nullability": "required for report-tile rows; nullable for purely derived event-axis rows",
          "meaning": "Analytics source-import receipt that proves which named report-source adapter produced this report-grade fact.",
          "constraints": "Must reference alpha.analytics_source_import for non-null Learning Report tile values; no literal or fixture value may be reportable without this provenance.",
          "relationship": "Many report-fact rows can reference one source import; detail/sourceRefs endpoints join here for adapter, source_table, and source_row_key_hashes.",
          "invalidWhen": "Missing on a non-null report-tile value, or replaced by copied raw reporting-DB columns.",
          "example": "imp_01HT8XPTIME_2026_SPRING",
          "sourceClass": "Alpha extension provenance reference",
          "itds": [
            {
              "id": "aitd-001-report-source-ingestion",
              "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
            },
            {
              "id": "aitd-004-provenance-no-literals",
              "title": "Every Report Value Traces To An Ingested Source Row, Or Reads Null",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-004-provenance-no-literals"
            },
            {
              "id": "aitd-007-xp-rollups",
              "title": "XP Totals, Goal, Remaining, And Completion Percent Are Ingested Report Facts",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-007-xp-rollups"
            }
          ]
        },
        {
          "name": "quality_status",
          "type": "TEXT enum",
          "nullability": "required",
          "meaning": "Current materialization quality state for this fact.",
          "constraints": "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.",
          "relationship": "Used by raw/API convergence filters and source-ref audit views.",
          "invalidWhen": "Free-text status or hidden failures represented as HTTP 200 success.",
          "example": "ok",
          "enum": "quality_status",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            },
            {
              "id": "aitd-108-axis-error-envelope",
              "title": "API Axis: Error Envelope",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-108-axis-error-envelope"
            },
            {
              "id": "aitd-111-axis-privacy-retention",
              "title": "API Axis: Privacy And Retention",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-111-axis-privacy-retention"
            }
          ]
        },
        {
          "name": "null_reason",
          "type": "TEXT enum",
          "nullability": "required",
          "meaning": "Why XP goal fields are null or unavailable while xp_total itself may still be reportable.",
          "constraints": "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.",
          "relationship": "Uses the same materialized school-day denominator as alpha.analytics_school_day_minutes.",
          "invalidWhen": "XP goal fields are null with no typed reason, or a consumer computes them anyway.",
          "example": "none",
          "enum": "null_reason",
          "sourceClass": "Alpha extension enum",
          "itds": [
            {
              "id": "aitd-007-xp-rollups",
              "title": "XP Totals, Goal, Remaining, And Completion Percent Are Ingested Report Facts",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-007-xp-rollups"
            },
            {
              "id": "aitd-006-school-day-minutes",
              "title": "Minutes Per Enrolled School Day Uses The Alpha School Calendar",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-006-school-day-minutes"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "calculation_version",
          "type": "INTEGER",
          "nullability": "required",
          "meaning": "Materializer calculation version for this fact shape.",
          "constraints": "Positive integer; starts at 1 and increments when policy/materializer logic intentionally changes.",
          "relationship": "Part of deterministic source_fact_key/idempotency for materializer writes.",
          "invalidWhen": "Omitted from replay keys or changed without a new policy/materializer decision.",
          "example": "1",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            },
            {
              "id": "aitd-105-axis-idempotency",
              "title": "API Axis: Idempotency Model",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-105-axis-idempotency"
            },
            {
              "id": "aitd-104-axis-concurrency",
              "title": "API Axis: Concurrency Model",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-104-axis-concurrency"
            }
          ]
        },
        {
          "name": "computed_at",
          "type": "TIMESTAMPTZ",
          "nullability": "required",
          "meaning": "When Analytics wrote this derived fact.",
          "constraints": "UTC timestamp with timezone; updated only by Analytics materializers.",
          "relationship": "Used for audit and source-ref subcollections, not for school-day grouping.",
          "invalidWhen": "Used as a substitute for the source event time, result effective time, or window boundaries.",
          "example": "2026-06-10T00:51:14Z",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            }
          ]
        },
        {
          "name": "modified_at",
          "type": "TIMESTAMPTZ",
          "nullability": "required",
          "meaning": "Last time the Analytics row changed for polling and modifiedSince queries.",
          "constraints": "UTC timestamp; list endpoints support modifiedSince against this field.",
          "relationship": "Supports poll plus modifiedSince eventing.",
          "invalidWhen": "Client-supplied or used as the business effective date.",
          "example": "2026-06-10T00:51:14Z",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-107-axis-eventing",
              "title": "API Axis: Eventing Model",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-107-axis-eventing"
            },
            {
              "id": "aitd-103-axis-query-model",
              "title": "API Axis: Query Model",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-103-axis-query-model"
            }
          ]
        },
        {
          "name": "superseded_at",
          "type": "TIMESTAMPTZ",
          "nullability": "nullable",
          "meaning": "When this row stopped being the current reportable version because of source correction, deletion, or recalculation.",
          "constraints": "Null means current; non-null rows are excluded from ordinary list reads unless includeSuperseded=true and authorized.",
          "relationship": "Preserves audit history without mutating source Events or Results.",
          "invalidWhen": "Used to hard-delete old rows or omitted on a correction that replaces a prior fact.",
          "example": "null",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-111-axis-privacy-retention",
              "title": "API Axis: Privacy And Retention",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-111-axis-privacy-retention"
            },
            {
              "id": "aitd-012-corrections-and-reversals",
              "title": "Corrections Are Signed Facts With Provenance",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-012-corrections-and-reversals"
            }
          ]
        },
        {
          "name": "source_deleted_at",
          "type": "TIMESTAMPTZ",
          "nullability": "nullable",
          "meaning": "When the source Event/Result became deleted or invalidated.",
          "constraints": "Null for live source rows; set from source tombstone/correction notifications.",
          "relationship": "Ordinary reads exclude tombstoned facts unless includeSuperseded=true and authorized.",
          "invalidWhen": "Used as a physical delete or ignored by raw-path report queries.",
          "example": "null",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-111-axis-privacy-retention",
              "title": "API Axis: Privacy And Retention",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-111-axis-privacy-retention"
            }
          ]
        }
      ],
      "plainLanguage": "The XP Goal tile row: report-source XP total plus daily goal, stored school-day denominator, remaining XP, and uncapped XP goal percent."
    },
    {
      "name": "alpha.analytics_accuracy",
      "title": "Accuracy Rollup",
      "kind": "Alpha extension rollup table",
      "grain": "student_id x subject_id nullable x window_kind x window_start x window_end x policy_ref.",
      "primaryKey": "id; unique current grain is (tenant_id, student_id, subject_id, window_kind, window_start, window_end, policy_ref, calculation_version).",
      "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.",
      "purpose": "Report-ready Accuracy panel facts: correct questions, total questions, incorrect questions, and percent correct without client-side processed_facts math.",
      "metricChecks": [
        "Learning Report accuracy"
      ],
      "architecture": [
        {
          "id": "aitd-001-report-source-ingestion",
          "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
        },
        {
          "id": "aitd-004-provenance-no-literals",
          "title": "Every Report Value Traces To An Ingested Source Row, Or Reads Null",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-004-provenance-no-literals"
        },
        {
          "id": "aitd-011-policy-and-enum-normalization",
          "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
        },
        {
          "id": "aitd-003-close-time-materialization",
          "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
        },
        {
          "id": "aitd-012-corrections-and-reversals",
          "title": "Corrections Are Signed Facts With Provenance",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-012-corrections-and-reversals"
        }
      ],
      "api": "GET /alpha/analytics/v1/accuracy-rollups",
      "rawRule": "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.",
      "example": {
        "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
      },
      "fields": [
        {
          "name": "id",
          "type": "UUID",
          "nullability": "required",
          "meaning": "Analytics-owned stable row id for this derived fact.",
          "constraints": "Generated by the platform; globally unique within alpha.analytics_* objects.",
          "relationship": "Primary key for list/detail endpoints.",
          "invalidWhen": "Provided by a public import client or reused across tenants.",
          "example": "8e9c0ef2-bc75-4f53-8124-df77df49f25f",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-000-extend-only-storage",
              "title": "Analytics Is New Extend-Only Alpha Storage",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-000-extend-only-storage"
            }
          ]
        },
        {
          "name": "tenant_id",
          "type": "UUID",
          "nullability": "required",
          "meaning": "Tenant boundary for the derived fact.",
          "constraints": "Set from the JWT tenant claim or internal materializer context; never accepted from request body/query.",
          "relationship": "All raw-path queries must filter by tenant_id before joining, sorting, paging, or counting.",
          "invalidWhen": "Missing, caller-supplied in body/query, or mismatched with the JWT tenant claim.",
          "example": "7b0bb5d8-9a38-4a62-9fdc-9f8d2dc1a111",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-109-axis-tenant-routing",
              "title": "API Axis: Tenant Routing",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-109-axis-tenant-routing"
            },
            {
              "id": "aitd-106-axis-auth-shape",
              "title": "API Axis: Auth Shape",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-106-axis-auth-shape"
            }
          ]
        },
        {
          "name": "student_id",
          "type": "TEXT",
          "nullability": "required",
          "meaning": "Canonical Alpha student id the source Event or Result resolved to at materialization time.",
          "constraints": "Must resolve through People and Orgs as a real student for the source timestamp/effective date.",
          "relationship": "References People and Orgs student identity; see https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/data_dictionary.",
          "invalidWhen": "Parsed from email/name/source payload instead of resolved by the Events/Results adapter.",
          "example": "student_01HT7G3YZV7QB5N4YKQ1K0Z9A9",
          "sourceClass": "Alpha extension reference",
          "itds": [
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            },
            {
              "id": "aitd-106-axis-auth-shape",
              "title": "API Axis: Auth Shape",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-106-axis-auth-shape"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "subject_id",
          "type": "TEXT",
          "nullability": "nullable where the row is all-subject or the source cannot validly resolve a subject",
          "meaning": "Canonical Alpha subject used for reporting and grouping.",
          "constraints": "Closed Alpha subject enum after write-time source-label normalization; unknown source subject becomes an adapter finding or null_reason, not a new string.",
          "relationship": "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.",
          "invalidWhen": "Copied from source strings such as FastMath, Vocabulary, Science-notqced, or ISEE variants without normalization.",
          "example": "math",
          "sourceClass": "Alpha extension reference",
          "itds": [
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "policy_ref",
          "type": "TEXT",
          "nullability": "required",
          "meaning": "Named policy/config version used to compute the measure or rollup.",
          "constraints": "Must point at alpha.policy.analytics.* or an inherited Curriculum/Results policy active for the source effective date.",
          "relationship": "Many Analytics facts can share one policy row; changing policy creates new calculation versions or corrections.",
          "invalidWhen": "A consumer hard-codes thresholds, school-day calendars, Growth X formulas, or completion denominators instead of using the policy ref.",
          "example": "alpha.policy.analytics.accuracy.v2026-06-12",
          "sourceClass": "Alpha extension reference",
          "itds": [
            {
              "id": "aitd-001-report-source-ingestion",
              "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "window_kind",
          "type": "TEXT enum",
          "nullability": "required",
          "meaning": "Named window family for the Accuracy rollup.",
          "constraints": "Allowed values: window_kind enum.",
          "relationship": "Part of Accuracy rollup grain and list filters.",
          "invalidWhen": "Parsed from report title or term label.",
          "example": "term",
          "enum": "window_kind",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-103-axis-query-model",
              "title": "API Axis: Query Model",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-103-axis-query-model"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "window_start",
          "type": "DATE",
          "nullability": "required",
          "meaning": "Inclusive start date for source question rows included in this rollup.",
          "constraints": "ISO date; half-open with window_end.",
          "relationship": "Defines the reporting period for the Accuracy panel.",
          "invalidWhen": "Uses computed_at instead of the source/report effective date.",
          "example": "2026-01-01",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-005-time-facts-and-windows",
              "title": "Active, Inactive, And Waste Seconds Are Typed Derived Time Facts",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-005-time-facts-and-windows"
            },
            {
              "id": "aitd-001-report-source-ingestion",
              "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
            }
          ]
        },
        {
          "name": "window_end",
          "type": "DATE",
          "nullability": "required",
          "meaning": "Exclusive end date for source question rows included in this rollup.",
          "constraints": "ISO date; must be after window_start.",
          "relationship": "Defines the reporting period for the Accuracy panel.",
          "invalidWhen": "Treated as inclusive in raw queries.",
          "example": "2026-06-01",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-005-time-facts-and-windows",
              "title": "Active, Inactive, And Waste Seconds Are Typed Derived Time Facts",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-005-time-facts-and-windows"
            },
            {
              "id": "aitd-001-report-source-ingestion",
              "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
            }
          ]
        },
        {
          "name": "correct_question_count",
          "type": "INTEGER",
          "nullability": "required",
          "meaning": "Reportable correct-question numerator after the adapter applies subject, app/source, score_type, correction, and real-student rules.",
          "constraints": "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.",
          "relationship": "Numerator for accuracy_percent.",
          "invalidWhen": "Summed by a consumer from reporting.processed_facts or copied as raw source rows without source_import_id provenance.",
          "example": "480",
          "sourceClass": "Alpha extension derived rollup value",
          "itds": [
            {
              "id": "aitd-001-report-source-ingestion",
              "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
            },
            {
              "id": "aitd-004-provenance-no-literals",
              "title": "Every Report Value Traces To An Ingested Source Row, Or Reads Null",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-004-provenance-no-literals"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "total_question_count",
          "type": "INTEGER",
          "nullability": "required",
          "meaning": "Reportable question-attempt denominator after the adapter applies the same policy filters as correct_question_count.",
          "constraints": "Nonnegative integer. Zero is allowed only with null_reason=no_questions and null accuracy_percent.",
          "relationship": "Denominator for accuracy_percent.",
          "invalidWhen": "Computed by counting Events, QTI attempts, or processed_facts rows in a report.",
          "example": "600",
          "sourceClass": "Alpha extension derived rollup value",
          "itds": [
            {
              "id": "aitd-001-report-source-ingestion",
              "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
            },
            {
              "id": "aitd-004-provenance-no-literals",
              "title": "Every Report Value Traces To An Ingested Source Row, Or Reads Null",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-004-provenance-no-literals"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "incorrect_question_count",
          "type": "INTEGER",
          "nullability": "required",
          "meaning": "Reportable incorrect-question count retained for explanations.",
          "constraints": "Nonnegative integer; equals total_question_count - correct_question_count under the policy version.",
          "relationship": "Audit/explanation value for parent-facing Accuracy cards.",
          "invalidWhen": "Calculated differently by the client or allowed to go negative.",
          "example": "120",
          "sourceClass": "Alpha extension derived rollup value",
          "itds": [
            {
              "id": "aitd-001-report-source-ingestion",
              "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "accuracy_percent",
          "type": "NUMERIC(9,3)",
          "nullability": "nullable when total_question_count is zero or source/policy is missing",
          "meaning": "Report-ready percent of reportable questions answered correctly.",
          "constraints": "0 through 100 when populated; null requires a typed null_reason. Formula and rounding are owned by Analytics under policy_ref.",
          "relationship": "The Learning Report Accuracy panel reads this value directly.",
          "invalidWhen": "A dashboard divides correct_question_count by total_question_count itself, rounds differently, or substitutes 0/100 when there are no questions.",
          "example": "80.000",
          "sourceClass": "Alpha extension derived measure",
          "itds": [
            {
              "id": "aitd-001-report-source-ingestion",
              "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "source_import_id",
          "type": "TEXT",
          "nullability": "required for report-tile rows; nullable for purely derived event-axis rows",
          "meaning": "Analytics source-import receipt that proves which named report-source adapter produced this report-grade fact.",
          "constraints": "Must reference alpha.analytics_source_import for non-null Learning Report tile values; no literal or fixture value may be reportable without this provenance.",
          "relationship": "Many report-fact rows can reference one source import; detail/sourceRefs endpoints join here for adapter, source_table, and source_row_key_hashes.",
          "invalidWhen": "Missing on a non-null report-tile value, or replaced by copied raw reporting-DB columns.",
          "example": "imp_01HT8XPTIME_2026_SPRING",
          "sourceClass": "Alpha extension provenance reference",
          "itds": [
            {
              "id": "aitd-001-report-source-ingestion",
              "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
            },
            {
              "id": "aitd-004-provenance-no-literals",
              "title": "Every Report Value Traces To An Ingested Source Row, Or Reads Null",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-004-provenance-no-literals"
            }
          ]
        },
        {
          "name": "source_fact_refs",
          "type": "JSONB",
          "nullability": "required",
          "meaning": "Compact ids/hashes/cursor for source-shaped processed_facts rows accepted by the adapter.",
          "constraints": "Stores refs/hashes only; never copies raw processed_facts rows or student identifiers.",
          "relationship": "Supports /accuracy-rollups/{id}/source-refs for authorized audits.",
          "invalidWhen": "Contains raw source table columns or enough payload to become a copied reporting table.",
          "example": "[\"processed_facts_hash_01HT7Q\"]",
          "sourceClass": "Alpha extension reference list",
          "itds": [
            {
              "id": "aitd-000-extend-only-storage",
              "title": "Analytics Is New Extend-Only Alpha Storage",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-000-extend-only-storage"
            },
            {
              "id": "aitd-001-report-source-ingestion",
              "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
            },
            {
              "id": "aitd-102-axis-read-shape",
              "title": "API Axis: Read Shape",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-102-axis-read-shape"
            }
          ]
        },
        {
          "name": "quality_status",
          "type": "TEXT enum",
          "nullability": "required",
          "meaning": "Current materialization quality state for this fact.",
          "constraints": "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.",
          "relationship": "Used by raw/API convergence filters and source-ref audit views.",
          "invalidWhen": "Free-text status or hidden failures represented as HTTP 200 success.",
          "example": "ok",
          "enum": "quality_status",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            },
            {
              "id": "aitd-108-axis-error-envelope",
              "title": "API Axis: Error Envelope",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-108-axis-error-envelope"
            },
            {
              "id": "aitd-111-axis-privacy-retention",
              "title": "API Axis: Privacy And Retention",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-111-axis-privacy-retention"
            }
          ]
        },
        {
          "name": "null_reason",
          "type": "TEXT enum",
          "nullability": "required",
          "meaning": "Why accuracy_percent is null or not reportable.",
          "constraints": "Allowed values: null_reason enum. no_questions means the source window had zero reportable question attempts; none means the metric is populated.",
          "relationship": "Prevents clients from turning no attempts into 0% or 100%.",
          "invalidWhen": "Null accuracy_percent with no typed reason, or a free-text explanation.",
          "example": "none",
          "enum": "null_reason",
          "sourceClass": "Alpha extension enum",
          "itds": [
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            },
            {
              "id": "aitd-108-axis-error-envelope",
              "title": "API Axis: Error Envelope",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-108-axis-error-envelope"
            }
          ]
        },
        {
          "name": "calculation_version",
          "type": "INTEGER",
          "nullability": "required",
          "meaning": "Materializer calculation version for this fact shape.",
          "constraints": "Positive integer; starts at 1 and increments when policy/materializer logic intentionally changes.",
          "relationship": "Part of deterministic source_fact_key/idempotency for materializer writes.",
          "invalidWhen": "Omitted from replay keys or changed without a new policy/materializer decision.",
          "example": "1",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            },
            {
              "id": "aitd-105-axis-idempotency",
              "title": "API Axis: Idempotency Model",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-105-axis-idempotency"
            },
            {
              "id": "aitd-104-axis-concurrency",
              "title": "API Axis: Concurrency Model",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-104-axis-concurrency"
            }
          ]
        },
        {
          "name": "computed_at",
          "type": "TIMESTAMPTZ",
          "nullability": "required",
          "meaning": "When Analytics wrote this derived fact.",
          "constraints": "UTC timestamp with timezone; updated only by Analytics materializers.",
          "relationship": "Used for audit and source-ref subcollections, not for school-day grouping.",
          "invalidWhen": "Used as a substitute for the source event time, result effective time, or window boundaries.",
          "example": "2026-06-10T00:51:14Z",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            }
          ]
        },
        {
          "name": "modified_at",
          "type": "TIMESTAMPTZ",
          "nullability": "required",
          "meaning": "Last time the Analytics row changed for polling and modifiedSince queries.",
          "constraints": "UTC timestamp; list endpoints support modifiedSince against this field.",
          "relationship": "Supports poll plus modifiedSince eventing.",
          "invalidWhen": "Client-supplied or used as the business effective date.",
          "example": "2026-06-10T00:51:14Z",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-107-axis-eventing",
              "title": "API Axis: Eventing Model",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-107-axis-eventing"
            },
            {
              "id": "aitd-103-axis-query-model",
              "title": "API Axis: Query Model",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-103-axis-query-model"
            }
          ]
        },
        {
          "name": "superseded_at",
          "type": "TIMESTAMPTZ",
          "nullability": "nullable",
          "meaning": "When this row stopped being the current reportable version because of source correction, deletion, or recalculation.",
          "constraints": "Null means current; non-null rows are excluded from ordinary list reads unless includeSuperseded=true and authorized.",
          "relationship": "Preserves audit history without mutating source Events or Results.",
          "invalidWhen": "Used to hard-delete old rows or omitted on a correction that replaces a prior fact.",
          "example": "null",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-111-axis-privacy-retention",
              "title": "API Axis: Privacy And Retention",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-111-axis-privacy-retention"
            },
            {
              "id": "aitd-012-corrections-and-reversals",
              "title": "Corrections Are Signed Facts With Provenance",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-012-corrections-and-reversals"
            }
          ]
        },
        {
          "name": "source_deleted_at",
          "type": "TIMESTAMPTZ",
          "nullability": "nullable",
          "meaning": "When the source Event/Result became deleted or invalidated.",
          "constraints": "Null for live source rows; set from source tombstone/correction notifications.",
          "relationship": "Ordinary reads exclude tombstoned facts unless includeSuperseded=true and authorized.",
          "invalidWhen": "Used as a physical delete or ignored by raw-path report queries.",
          "example": "null",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-111-axis-privacy-retention",
              "title": "API Axis: Privacy And Retention",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-111-axis-privacy-retention"
            }
          ]
        }
      ],
      "plainLanguage": "The Learning Report Accuracy tile row: correct questions, total questions, incorrect questions, and percent correct with source-import provenance."
    },
    {
      "name": "alpha.analytics_mastery_delta",
      "title": "Mastery Delta",
      "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.",
      "primaryKey": "id; unique source transition key is (tenant_id, source_state_ref, state_dimension, effective_at, policy_ref, calculation_version).",
      "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.",
      "purpose": "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.",
      "metricChecks": [
        "mastery|student_kc_state"
      ],
      "architecture": [
        {
          "id": "aitd-008-mastery-and-grade-levels",
          "title": "Grade Levels Mastered Are Ingested; Mastery Deltas Read Results State",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-008-mastery-and-grade-levels"
        },
        {
          "id": "aitd-001-report-source-ingestion",
          "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
        },
        {
          "id": "aitd-004-provenance-no-literals",
          "title": "Every Report Value Traces To An Ingested Source Row, Or Reads Null",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-004-provenance-no-literals"
        },
        {
          "id": "aitd-003-close-time-materialization",
          "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
        },
        {
          "id": "aitd-011-policy-and-enum-normalization",
          "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
        }
      ],
      "api": "GET /alpha/analytics/v1/mastery-deltas",
      "rawRule": "Raw readers query mastery_delta by effective_at/state_dimension; they do not recompute mastery, decay, HMG, or due dates from attempts.",
      "example": {
        "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
      },
      "fields": [
        {
          "name": "id",
          "type": "UUID",
          "nullability": "required",
          "meaning": "Analytics-owned stable row id for this derived fact.",
          "constraints": "Generated by the platform; globally unique within alpha.analytics_* objects.",
          "relationship": "Primary key for list/detail endpoints.",
          "invalidWhen": "Provided by a public import client or reused across tenants.",
          "example": "8e9c0ef2-bc75-4f53-8124-df77df49f25f",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-000-extend-only-storage",
              "title": "Analytics Is New Extend-Only Alpha Storage",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-000-extend-only-storage"
            }
          ]
        },
        {
          "name": "tenant_id",
          "type": "UUID",
          "nullability": "required",
          "meaning": "Tenant boundary for the derived fact.",
          "constraints": "Set from the JWT tenant claim or internal materializer context; never accepted from request body/query.",
          "relationship": "All raw-path queries must filter by tenant_id before joining, sorting, paging, or counting.",
          "invalidWhen": "Missing, caller-supplied in body/query, or mismatched with the JWT tenant claim.",
          "example": "7b0bb5d8-9a38-4a62-9fdc-9f8d2dc1a111",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-109-axis-tenant-routing",
              "title": "API Axis: Tenant Routing",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-109-axis-tenant-routing"
            },
            {
              "id": "aitd-106-axis-auth-shape",
              "title": "API Axis: Auth Shape",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-106-axis-auth-shape"
            }
          ]
        },
        {
          "name": "student_id",
          "type": "TEXT",
          "nullability": "required",
          "meaning": "Canonical Alpha student id the source Event or Result resolved to at materialization time.",
          "constraints": "Must resolve through People and Orgs as a real student for the source timestamp/effective date.",
          "relationship": "References People and Orgs student identity; see https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/data_dictionary.",
          "invalidWhen": "Parsed from email/name/source payload instead of resolved by the Events/Results adapter.",
          "example": "student_01HT7G3YZV7QB5N4YKQ1K0Z9A9",
          "sourceClass": "Alpha extension reference",
          "itds": [
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            },
            {
              "id": "aitd-106-axis-auth-shape",
              "title": "API Axis: Auth Shape",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-106-axis-auth-shape"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "kc_id",
          "type": "TEXT",
          "nullability": "nullable when the row is a grade-level mastered fact without a single KC",
          "meaning": "Knowledge Component whose student state changed.",
          "constraints": "Must reference a Curriculum KC; never a standard or lesson id.",
          "relationship": "References Curriculum KC tree; see https://platform3-andymontgomery-9773s-projects.vercel.app/curriculum/alpha/data_dictionary.",
          "invalidWhen": "Points to a standard, lesson, content item, or parsed source course string.",
          "example": "kc_math_fraction_addition_unlike_denominators",
          "sourceClass": "Alpha extension reference",
          "itds": [
            {
              "id": "aitd-008-mastery-and-grade-levels",
              "title": "Grade Levels Mastered Are Ingested; Mastery Deltas Read Results State",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-008-mastery-and-grade-levels"
            }
          ]
        },
        {
          "name": "grade_subject",
          "type": "TEXT enum",
          "nullability": "nullable except grade-level mastered rows",
          "meaning": "Subject for a Grade Levels Mastered row shown in the Learning Report.",
          "constraints": "Closed Alpha subject enum after write-time normalization; required when grade_level/completed_on are populated.",
          "relationship": "Ingested from reporting.assessment_results through the timeback-grade-mastery adapter.",
          "invalidWhen": "Parsed by a report from assessment names or display text.",
          "example": "math",
          "enum": "subject_id",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-008-mastery-and-grade-levels",
              "title": "Grade Levels Mastered Are Ingested; Mastery Deltas Read Results State",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-008-mastery-and-grade-levels"
            },
            {
              "id": "aitd-001-report-source-ingestion",
              "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "grade_level",
          "type": "INTEGER",
          "nullability": "nullable except grade-level mastered rows",
          "meaning": "Grade level the student has mastered in the subject.",
          "constraints": "Positive integer; set by the grade-mastery adapter from passed gate/assessment evidence.",
          "relationship": "Learning Report Grade Levels Mastered tile reads this field with grade_subject and completed_on.",
          "invalidWhen": "Computed by a dashboard from current grade, MAP RIT, or a course name.",
          "example": "5",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-008-mastery-and-grade-levels",
              "title": "Grade Levels Mastered Are Ingested; Mastery Deltas Read Results State",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-008-mastery-and-grade-levels"
            },
            {
              "id": "aitd-001-report-source-ingestion",
              "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
            }
          ]
        },
        {
          "name": "completed_on",
          "type": "DATE",
          "nullability": "nullable except grade-level mastered rows",
          "meaning": "Date the grade-level mastery fact became effective for reporting.",
          "constraints": "ISO date derived from the source assessment/gate completion date.",
          "relationship": "Used to order Grade Levels Mastered entries in Learning Reports.",
          "invalidWhen": "Filled from Analytics computed_at or import time.",
          "example": "2026-05-14",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-008-mastery-and-grade-levels",
              "title": "Grade Levels Mastered Are Ingested; Mastery Deltas Read Results State",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-008-mastery-and-grade-levels"
            },
            {
              "id": "aitd-001-report-source-ingestion",
              "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
            }
          ]
        },
        {
          "name": "source_state_ref",
          "type": "TEXT",
          "nullability": "nullable for grade-level mastered rows; required for Results state-delta rows",
          "meaning": "Results student_kc_state row/version this delta derives from.",
          "constraints": "Must reference Results state or ledger evidence in same tenant.",
          "relationship": "References Results current state/history; see https://platform3-andymontgomery-9773s-projects.vercel.app/results/alpha/data_dictionary#table-alpha-student-kc-state.",
          "invalidWhen": "Analytics becomes the authoritative mastery state or stores state without source ref.",
          "example": "student_kc_state_01HT7K7S9Q",
          "sourceClass": "Alpha extension reference",
          "itds": [
            {
              "id": "aitd-000-extend-only-storage",
              "title": "Analytics Is New Extend-Only Alpha Storage",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-000-extend-only-storage"
            },
            {
              "id": "aitd-008-mastery-and-grade-levels",
              "title": "Grade Levels Mastered Are Ingested; Mastery Deltas Read Results State",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-008-mastery-and-grade-levels"
            }
          ]
        },
        {
          "name": "source_result_refs",
          "type": "JSONB",
          "nullability": "required",
          "meaning": "Result/evidence ids that caused or explain the state transition or grade-level mastery fact.",
          "constraints": "Stores ids/hashes only; no raw scored payload copies.",
          "relationship": "Links back to result_record/result_kc_evidence or imported assessment_results source refs for audit.",
          "invalidWhen": "Contains copied response bodies, raw attempts, or mastery math inputs for client recomputation.",
          "example": "[\"result_01HT7K8BR3\"]",
          "sourceClass": "Alpha extension reference list",
          "itds": [
            {
              "id": "aitd-000-extend-only-storage",
              "title": "Analytics Is New Extend-Only Alpha Storage",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-000-extend-only-storage"
            },
            {
              "id": "aitd-008-mastery-and-grade-levels",
              "title": "Grade Levels Mastered Are Ingested; Mastery Deltas Read Results State",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-008-mastery-and-grade-levels"
            },
            {
              "id": "aitd-102-axis-read-shape",
              "title": "API Axis: Read Shape",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-102-axis-read-shape"
            }
          ]
        },
        {
          "name": "state_dimension",
          "type": "TEXT enum",
          "nullability": "required",
          "meaning": "Which Results mastery-state dimension changed.",
          "constraints": "Allowed values: state_dimension enum.",
          "relationship": "Part of the delta grain and filter model.",
          "invalidWhen": "Free-text state labels or dashboard-specific columns.",
          "example": "durable_mastery",
          "enum": "state_dimension",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-008-mastery-and-grade-levels",
              "title": "Grade Levels Mastered Are Ingested; Mastery Deltas Read Results State",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-008-mastery-and-grade-levels"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "effective_at",
          "type": "TIMESTAMPTZ",
          "nullability": "required",
          "meaning": "When the state transition is effective for as-of reporting.",
          "constraints": "UTC timestamp; comes from Results state transition, not Analytics computed_at.",
          "relationship": "Raw/API answer to \"what changed between A and B\" filters this field.",
          "invalidWhen": "Substituted with computed_at or source import time.",
          "example": "2026-05-14T18:45:00Z",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-008-mastery-and-grade-levels",
              "title": "Grade Levels Mastered Are Ingested; Mastery Deltas Read Results State",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-008-mastery-and-grade-levels"
            }
          ]
        },
        {
          "name": "previous_value",
          "type": "JSONB",
          "nullability": "nullable",
          "meaning": "Typed previous value for the changed state dimension.",
          "constraints": "JSON shape must match state_dimension; null allowed for first known state.",
          "relationship": "Used for report explanations; not for recomputing Results state.",
          "invalidWhen": "Unstructured notes or mixed units without state_dimension shape.",
          "example": "{\"value\":0.82}",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-008-mastery-and-grade-levels",
              "title": "Grade Levels Mastered Are Ingested; Mastery Deltas Read Results State",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-008-mastery-and-grade-levels"
            }
          ]
        },
        {
          "name": "new_value",
          "type": "JSONB",
          "nullability": "required",
          "meaning": "Typed new value for the changed state dimension.",
          "constraints": "JSON shape must match state_dimension.",
          "relationship": "Report-ready delta endpoint output.",
          "invalidWhen": "Consumer has to fetch Results and calculate the value itself.",
          "example": "{\"value\":0.91}",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-008-mastery-and-grade-levels",
              "title": "Grade Levels Mastered Are Ingested; Mastery Deltas Read Results State",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-008-mastery-and-grade-levels"
            }
          ]
        },
        {
          "name": "delta_value",
          "type": "NUMERIC(12,6)",
          "nullability": "nullable",
          "meaning": "Numeric difference where the state dimension has a numeric value.",
          "constraints": "Null for non-numeric dimensions such as next_due_at or fluency_state.",
          "relationship": "Used for sorting and report summaries.",
          "invalidWhen": "Invented for categorical dimensions without policy meaning.",
          "example": "0.090000",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-008-mastery-and-grade-levels",
              "title": "Grade Levels Mastered Are Ingested; Mastery Deltas Read Results State",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-008-mastery-and-grade-levels"
            }
          ]
        },
        {
          "name": "transition_kind",
          "type": "TEXT enum",
          "nullability": "required",
          "meaning": "Human-readable category of the state transition.",
          "constraints": "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.",
          "relationship": "Lets reports group deltas without client-side classifiers.",
          "invalidWhen": "Classified by a dashboard from score percentages or attempt names.",
          "example": "acquired",
          "enum": "transition_kind",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-008-mastery-and-grade-levels",
              "title": "Grade Levels Mastered Are Ingested; Mastery Deltas Read Results State",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-008-mastery-and-grade-levels"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "source_import_id",
          "type": "TEXT",
          "nullability": "required for report-tile rows; nullable for purely derived event-axis rows",
          "meaning": "Analytics source-import receipt that proves which named report-source adapter produced this report-grade fact.",
          "constraints": "Must reference alpha.analytics_source_import for non-null Learning Report tile values; no literal or fixture value may be reportable without this provenance.",
          "relationship": "Many report-fact rows can reference one source import; detail/sourceRefs endpoints join here for adapter, source_table, and source_row_key_hashes.",
          "invalidWhen": "Missing on a non-null report-tile value, or replaced by copied raw reporting-DB columns.",
          "example": "imp_01HT8GRADE_2026_SPRING",
          "sourceClass": "Alpha extension provenance reference",
          "itds": [
            {
              "id": "aitd-001-report-source-ingestion",
              "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
            },
            {
              "id": "aitd-004-provenance-no-literals",
              "title": "Every Report Value Traces To An Ingested Source Row, Or Reads Null",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-004-provenance-no-literals"
            },
            {
              "id": "aitd-008-mastery-and-grade-levels",
              "title": "Grade Levels Mastered Are Ingested; Mastery Deltas Read Results State",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-008-mastery-and-grade-levels"
            }
          ]
        },
        {
          "name": "policy_ref",
          "type": "TEXT",
          "nullability": "required",
          "meaning": "Named policy/config version used to compute the measure or rollup.",
          "constraints": "Must point at alpha.policy.analytics.* or an inherited Curriculum/Results policy active for the source effective date.",
          "relationship": "Many Analytics facts can share one policy row; changing policy creates new calculation versions or corrections.",
          "invalidWhen": "A consumer hard-codes thresholds, school-day calendars, Growth X formulas, or completion denominators instead of using the policy ref.",
          "example": "alpha.policy.results.mastery_state.v2026-06-10",
          "sourceClass": "Alpha extension reference",
          "itds": [
            {
              "id": "aitd-008-mastery-and-grade-levels",
              "title": "Grade Levels Mastered Are Ingested; Mastery Deltas Read Results State",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-008-mastery-and-grade-levels"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "quality_status",
          "type": "TEXT enum",
          "nullability": "required",
          "meaning": "Current materialization quality state for this fact.",
          "constraints": "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.",
          "relationship": "Used by raw/API convergence filters and source-ref audit views.",
          "invalidWhen": "Free-text status or hidden failures represented as HTTP 200 success.",
          "example": "ok",
          "enum": "quality_status",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            },
            {
              "id": "aitd-108-axis-error-envelope",
              "title": "API Axis: Error Envelope",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-108-axis-error-envelope"
            },
            {
              "id": "aitd-111-axis-privacy-retention",
              "title": "API Axis: Privacy And Retention",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-111-axis-privacy-retention"
            }
          ]
        },
        {
          "name": "calculation_version",
          "type": "INTEGER",
          "nullability": "required",
          "meaning": "Materializer calculation version for this fact shape.",
          "constraints": "Positive integer; starts at 1 and increments when policy/materializer logic intentionally changes.",
          "relationship": "Part of deterministic source_fact_key/idempotency for materializer writes.",
          "invalidWhen": "Omitted from replay keys or changed without a new policy/materializer decision.",
          "example": "1",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            },
            {
              "id": "aitd-105-axis-idempotency",
              "title": "API Axis: Idempotency Model",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-105-axis-idempotency"
            },
            {
              "id": "aitd-104-axis-concurrency",
              "title": "API Axis: Concurrency Model",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-104-axis-concurrency"
            }
          ]
        },
        {
          "name": "computed_at",
          "type": "TIMESTAMPTZ",
          "nullability": "required",
          "meaning": "When Analytics wrote this derived fact.",
          "constraints": "UTC timestamp with timezone; updated only by Analytics materializers.",
          "relationship": "Used for audit and source-ref subcollections, not for school-day grouping.",
          "invalidWhen": "Used as a substitute for the source event time, result effective time, or window boundaries.",
          "example": "2026-06-10T00:51:14Z",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            }
          ]
        },
        {
          "name": "modified_at",
          "type": "TIMESTAMPTZ",
          "nullability": "required",
          "meaning": "Last time the Analytics row changed for polling and modifiedSince queries.",
          "constraints": "UTC timestamp; list endpoints support modifiedSince against this field.",
          "relationship": "Supports poll plus modifiedSince eventing.",
          "invalidWhen": "Client-supplied or used as the business effective date.",
          "example": "2026-06-10T00:51:14Z",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-107-axis-eventing",
              "title": "API Axis: Eventing Model",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-107-axis-eventing"
            },
            {
              "id": "aitd-103-axis-query-model",
              "title": "API Axis: Query Model",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-103-axis-query-model"
            }
          ]
        },
        {
          "name": "superseded_at",
          "type": "TIMESTAMPTZ",
          "nullability": "nullable",
          "meaning": "When this row stopped being the current reportable version because of source correction, deletion, or recalculation.",
          "constraints": "Null means current; non-null rows are excluded from ordinary list reads unless includeSuperseded=true and authorized.",
          "relationship": "Preserves audit history without mutating source Events or Results.",
          "invalidWhen": "Used to hard-delete old rows or omitted on a correction that replaces a prior fact.",
          "example": "null",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-111-axis-privacy-retention",
              "title": "API Axis: Privacy And Retention",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-111-axis-privacy-retention"
            },
            {
              "id": "aitd-012-corrections-and-reversals",
              "title": "Corrections Are Signed Facts With Provenance",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-012-corrections-and-reversals"
            }
          ]
        },
        {
          "name": "source_deleted_at",
          "type": "TIMESTAMPTZ",
          "nullability": "nullable",
          "meaning": "When the source Event/Result became deleted or invalidated.",
          "constraints": "Null for live source rows; set from source tombstone/correction notifications.",
          "relationship": "Ordinary reads exclude tombstoned facts unless includeSuperseded=true and authorized.",
          "invalidWhen": "Used as a physical delete or ignored by raw-path report queries.",
          "example": "null",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-111-axis-privacy-retention",
              "title": "API Axis: Privacy And Retention",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-111-axis-privacy-retention"
            }
          ]
        }
      ],
      "plainLanguage": "Grade Levels Mastered plus KC mastery-state changes. It is not the current mastery state."
    },
    {
      "name": "alpha.analytics_map_growth_rollup",
      "title": "MAP Growth Rollup",
      "kind": "Alpha extension rollup table",
      "grain": "student_id x subject_id x canonical_term_id x growth_window x norms_set x policy_ref.",
      "primaryKey": "id; unique current grain is (tenant_id, student_id, subject_id, canonical_term_id, growth_window, norms_set, policy_ref, calculation_version).",
      "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.",
      "purpose": "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.",
      "metricChecks": [
        "RIT|GrowthX|MAP growth windows",
        "MAP sittings/scores"
      ],
      "architecture": [
        {
          "id": "aitd-009-map-growth-rollups",
          "title": "MAP RIT And Growth X Are Ingested From hp_map_results, Deduped, And Norms-Calculated",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-009-map-growth-rollups"
        },
        {
          "id": "aitd-001-report-source-ingestion",
          "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
        },
        {
          "id": "aitd-004-provenance-no-literals",
          "title": "Every Report Value Traces To An Ingested Source Row, Or Reads Null",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-004-provenance-no-literals"
        },
        {
          "id": "aitd-003-close-time-materialization",
          "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
        },
        {
          "id": "aitd-011-policy-and-enum-normalization",
          "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
        }
      ],
      "api": "GET /alpha/analytics/v1/map-growth-rollups",
      "rawRule": "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.",
      "example": {
        "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
      },
      "fields": [
        {
          "name": "id",
          "type": "UUID",
          "nullability": "required",
          "meaning": "Analytics-owned stable row id for this derived fact.",
          "constraints": "Generated by the platform; globally unique within alpha.analytics_* objects.",
          "relationship": "Primary key for list/detail endpoints.",
          "invalidWhen": "Provided by a public import client or reused across tenants.",
          "example": "8e9c0ef2-bc75-4f53-8124-df77df49f25f",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-000-extend-only-storage",
              "title": "Analytics Is New Extend-Only Alpha Storage",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-000-extend-only-storage"
            }
          ]
        },
        {
          "name": "tenant_id",
          "type": "UUID",
          "nullability": "required",
          "meaning": "Tenant boundary for the derived fact.",
          "constraints": "Set from the JWT tenant claim or internal materializer context; never accepted from request body/query.",
          "relationship": "All raw-path queries must filter by tenant_id before joining, sorting, paging, or counting.",
          "invalidWhen": "Missing, caller-supplied in body/query, or mismatched with the JWT tenant claim.",
          "example": "7b0bb5d8-9a38-4a62-9fdc-9f8d2dc1a111",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-109-axis-tenant-routing",
              "title": "API Axis: Tenant Routing",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-109-axis-tenant-routing"
            },
            {
              "id": "aitd-106-axis-auth-shape",
              "title": "API Axis: Auth Shape",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-106-axis-auth-shape"
            }
          ]
        },
        {
          "name": "student_id",
          "type": "TEXT",
          "nullability": "required",
          "meaning": "Canonical Alpha student id the source Event or Result resolved to at materialization time.",
          "constraints": "Must resolve through People and Orgs as a real student for the source timestamp/effective date.",
          "relationship": "References People and Orgs student identity; see https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/data_dictionary.",
          "invalidWhen": "Parsed from email/name/source payload instead of resolved by the Events/Results adapter.",
          "example": "student_01HT7G3YZV7QB5N4YKQ1K0Z9A9",
          "sourceClass": "Alpha extension reference",
          "itds": [
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            },
            {
              "id": "aitd-106-axis-auth-shape",
              "title": "API Axis: Auth Shape",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-106-axis-auth-shape"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "subject_id",
          "type": "TEXT",
          "nullability": "required for MAP rollups",
          "meaning": "Canonical Alpha subject used for reporting and grouping.",
          "constraints": "Closed Alpha subject enum after write-time source-label normalization; unknown source subject becomes an adapter finding or null_reason, not a new string.",
          "relationship": "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.",
          "invalidWhen": "Copied from source strings such as FastMath, Vocabulary, Science-notqced, or ISEE variants without normalization.",
          "example": "math",
          "sourceClass": "Alpha extension reference",
          "itds": [
            {
              "id": "aitd-009-map-growth-rollups",
              "title": "MAP RIT And Growth X Are Ingested From hp_map_results, Deduped, And Norms-Calculated",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-009-map-growth-rollups"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "canonical_term_id",
          "type": "TEXT",
          "nullability": "required",
          "meaning": "Alpha canonical term id for the MAP observation/window.",
          "constraints": "Set by Results/NWEAMap term normalization; not parsed by Analytics clients.",
          "relationship": "References People and Orgs academic-session term.",
          "invalidWhen": "A report parses source strings like Winter 2026 or growth-window columns.",
          "example": "term_2026_winter",
          "sourceClass": "Alpha extension reference",
          "itds": [
            {
              "id": "aitd-009-map-growth-rollups",
              "title": "MAP RIT And Growth X Are Ingested From hp_map_results, Deduped, And Norms-Calculated",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-009-map-growth-rollups"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "growth_window",
          "type": "TEXT enum",
          "nullability": "required",
          "meaning": "MAP growth interval represented by this row.",
          "constraints": "Allowed values: growth_window enum.",
          "relationship": "Part of the MAP rollup grain.",
          "invalidWhen": "A client switches over NWEA wide growth-window columns.",
          "example": "winter_to_winter",
          "enum": "growth_window",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-009-map-growth-rollups",
              "title": "MAP RIT And Growth X Are Ingested From hp_map_results, Deduped, And Norms-Calculated",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-009-map-growth-rollups"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "norms_set",
          "type": "TEXT enum",
          "nullability": "required",
          "meaning": "NWEA norms family used for projected growth and normed outputs.",
          "constraints": "Allowed values: norms_set enum; the same report can be regenerated by changing this filter.",
          "relationship": "Prevents mixed-norm calculations.",
          "invalidWhen": "A report ships its own norms table or combines 2020 and 2025 values.",
          "example": "2025",
          "enum": "norms_set",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-009-map-growth-rollups",
              "title": "MAP RIT And Growth X Are Ingested From hp_map_results, Deduped, And Norms-Calculated",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-009-map-growth-rollups"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "map_score_id",
          "type": "TEXT",
          "nullability": "required",
          "meaning": "Results MAP score/test-of-record row this report fact derives from.",
          "constraints": "Same tenant; Results owns test-of-record and raw sitting decisions.",
          "relationship": "References Results MAP score; see https://platform3-andymontgomery-9773s-projects.vercel.app/results/alpha/data_dictionary#table-alpha-map-score.",
          "invalidWhen": "Analytics selects the highest RIT itself or copies raw sitting fields.",
          "example": "map_score_01HT7N0T9Q",
          "sourceClass": "Alpha extension reference",
          "itds": [
            {
              "id": "aitd-000-extend-only-storage",
              "title": "Analytics Is New Extend-Only Alpha Storage",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-000-extend-only-storage"
            },
            {
              "id": "aitd-009-map-growth-rollups",
              "title": "MAP RIT And Growth X Are Ingested From hp_map_results, Deduped, And Norms-Calculated",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-009-map-growth-rollups"
            }
          ]
        },
        {
          "name": "map_growth_window_ref",
          "type": "TEXT",
          "nullability": "nullable for single-term observations",
          "meaning": "Results MAP growth-window row used for projected/observed growth.",
          "constraints": "Required when growth_window is not term.",
          "relationship": "References Results MAP growth window; see https://platform3-andymontgomery-9773s-projects.vercel.app/results/alpha/data_dictionary#table-alpha-map-growth-window.",
          "invalidWhen": "Client computes projected growth or window pairing.",
          "example": "map_growth_01HT7N5YDG",
          "sourceClass": "Alpha extension reference",
          "itds": [
            {
              "id": "aitd-000-extend-only-storage",
              "title": "Analytics Is New Extend-Only Alpha Storage",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-000-extend-only-storage"
            },
            {
              "id": "aitd-009-map-growth-rollups",
              "title": "MAP RIT And Growth X Are Ingested From hp_map_results, Deduped, And Norms-Calculated",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-009-map-growth-rollups"
            }
          ]
        },
        {
          "name": "rit_score",
          "type": "NUMERIC(6,2)",
          "nullability": "required",
          "meaning": "Report-ready RIT value from Results MAP test-of-record for this subject/term.",
          "constraints": "Positive numeric; no local test-of-record choice in Analytics clients.",
          "relationship": "Displayed in MAP reports and used with Growth X fields.",
          "invalidWhen": "Selected from raw sittings by the consumer.",
          "example": "239.00",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-009-map-growth-rollups",
              "title": "MAP RIT And Growth X Are Ingested From hp_map_results, Deduped, And Norms-Calculated",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-009-map-growth-rollups"
            }
          ]
        },
        {
          "name": "growth_percentile",
          "type": "NUMERIC(6,2)",
          "nullability": "nullable when the selected growth_window has no conditional growth percentile",
          "meaning": "Conditional growth percentile for the selected MAP window; the Learning Report \"vs 1yr ago\" panel reads this from the winter_to_winter row.",
          "constraints": "0 to 100 when present; null requires null_reason for report windows that should have growth.",
          "relationship": "For winter_to_winter, normalized from Results/NWEAMap wintertowinterconditionalgrowthpercentile source evidence.",
          "invalidWhen": "Filled from fall_to_winter for a one-year-growth report panel.",
          "example": "43.00",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-009-map-growth-rollups",
              "title": "MAP RIT And Growth X Are Ingested From hp_map_results, Deduped, And Norms-Calculated",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-009-map-growth-rollups"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "achievement_percentile",
          "type": "NUMERIC(6,2)",
          "nullability": "nullable when the MAP source row has no achievement percentile",
          "meaning": "Achievement percentile for the test-of-record sitting.",
          "constraints": "0 to 100 when present; for hp_map_results this is normalized from testpercentile.",
          "relationship": "Displayed beside RIT in MAP report panels.",
          "invalidWhen": "Filled from conditional growth percentile or mixed with growth_percentile.",
          "example": "91.00",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-009-map-growth-rollups",
              "title": "MAP RIT And Growth X Are Ingested From hp_map_results, Deduped, And Norms-Calculated",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-009-map-growth-rollups"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "observed_growth",
          "type": "NUMERIC(7,3)",
          "nullability": "nullable when no paired window exists",
          "meaning": "Actual RIT growth for the growth_window.",
          "constraints": "Null for term-only observations; otherwise computed by Results MAP views.",
          "relationship": "Numerator for Growth X.",
          "invalidWhen": "Computed by subtracting RIT values in a report.",
          "example": "6.000",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-009-map-growth-rollups",
              "title": "MAP RIT And Growth X Are Ingested From hp_map_results, Deduped, And Norms-Calculated",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-009-map-growth-rollups"
            }
          ]
        },
        {
          "name": "typical_growth",
          "type": "NUMERIC(7,3)",
          "nullability": "nullable when the selected growth_window has no typical-growth value",
          "meaning": "NWEA typical-growth context value for the selected growth window.",
          "constraints": "Comes from normalized Results/NWEAMap typical*growth columns; retained for audit and comparison.",
          "relationship": "For winter_to_winter, normalized from typicalwintertowintergrowth.",
          "invalidWhen": "Used as the Learning Report Growth X denominator; the approved architecture pins projected_growth for Growth X.",
          "example": "2.000",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-009-map-growth-rollups",
              "title": "MAP RIT And Growth X Are Ingested From hp_map_results, Deduped, And Norms-Calculated",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-009-map-growth-rollups"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "projected_growth",
          "type": "NUMERIC(7,3)",
          "nullability": "nullable when no projected growth exists",
          "meaning": "NWEA projected-growth value for the selected window.",
          "constraints": "Must be greater than 0 when growth_x is present; comes from Results/NWEAMap normalized projections and never from a client norms table.",
          "relationship": "The pinned Learning Report Growth X denominator under AITD-009.",
          "invalidWhen": "Copied from a skill pack or dashboard constants file.",
          "example": "7.000",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-009-map-growth-rollups",
              "title": "MAP RIT And Growth X Are Ingested From hp_map_results, Deduped, And Norms-Calculated",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-009-map-growth-rollups"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "growth_x",
          "type": "NUMERIC(8,4)",
          "nullability": "nullable when observed or projected growth is unavailable",
          "meaning": "Observed growth divided by projected_growth, using the named norms_set and growth_window.",
          "constraints": "Null requires null_reason; target comparisons use growth_x_target.",
          "relationship": "The report-ready Alpha growth measure.",
          "invalidWhen": "Computed by a consumer from exported RIT/projection fields, or computed with typical_growth as the denominator.",
          "example": "0.8571",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-009-map-growth-rollups",
              "title": "MAP RIT And Growth X Are Ingested From hp_map_results, Deduped, And Norms-Calculated",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-009-map-growth-rollups"
            }
          ]
        },
        {
          "name": "growth_x_target",
          "type": "NUMERIC(8,4)",
          "nullability": "required",
          "meaning": "Alpha target Growth X for intervention/on-track decisions.",
          "constraints": "Normally 2 under current Alpha policy, but read from policy_ref.",
          "relationship": "Feeds on_track flag and GOALS-style reports.",
          "invalidWhen": "Hard-coded in a report or skill pack.",
          "example": "2.0000",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-009-map-growth-rollups",
              "title": "MAP RIT And Growth X Are Ingested From hp_map_results, Deduped, And Norms-Calculated",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-009-map-growth-rollups"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "on_track",
          "type": "BOOLEAN",
          "nullability": "nullable when growth_x or target is null",
          "meaning": "Whether the student is meeting the Growth X target for this row.",
          "constraints": "Computed under policy_ref; null requires null_reason.",
          "relationship": "Report flag for intervention workflows.",
          "invalidWhen": "Client compares growth_x to a local threshold.",
          "example": "true",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-009-map-growth-rollups",
              "title": "MAP RIT And Growth X Are Ingested From hp_map_results, Deduped, And Norms-Calculated",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-009-map-growth-rollups"
            }
          ]
        },
        {
          "name": "sitting_count",
          "type": "INTEGER",
          "nullability": "required",
          "meaning": "Number of MAP sittings Results observed for this subject/term before test-of-record selection.",
          "constraints": "Nonnegative; includes source-visible sittings according to Results policy.",
          "relationship": "Retake/audit display; not a dedupe instruction for clients.",
          "invalidWhen": "Consumer counts raw NWEA rows itself.",
          "example": "2",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-009-map-growth-rollups",
              "title": "MAP RIT And Growth X Are Ingested From hp_map_results, Deduped, And Norms-Calculated",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-009-map-growth-rollups"
            }
          ]
        },
        {
          "name": "retake_count",
          "type": "INTEGER",
          "nullability": "required",
          "meaning": "Number of non-test-of-record sittings represented by the sitting_count.",
          "constraints": "Nonnegative; computed by Results/NWEAMap policy.",
          "relationship": "Retake audit metric.",
          "invalidWhen": "Client infers retakes from source term strings or GrowthMeasureYN flags.",
          "example": "1",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-009-map-growth-rollups",
              "title": "MAP RIT And Growth X Are Ingested From hp_map_results, Deduped, And Norms-Calculated",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-009-map-growth-rollups"
            }
          ]
        },
        {
          "name": "map_sitting_refs",
          "type": "JSONB",
          "nullability": "required",
          "meaning": "Compact ids/cursor for Results MAP sitting rows used in the rollup.",
          "constraints": "Refs/hashes only; no raw NWEA row copy.",
          "relationship": "Authorized audit sourceRefs subcollection.",
          "invalidWhen": "Stores raw CDF fields or lets consumers dedupe.",
          "example": "[\"map_sitting_01HT7N\", \"map_sitting_01HT7P\"]",
          "sourceClass": "Alpha extension reference list",
          "itds": [
            {
              "id": "aitd-000-extend-only-storage",
              "title": "Analytics Is New Extend-Only Alpha Storage",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-000-extend-only-storage"
            },
            {
              "id": "aitd-009-map-growth-rollups",
              "title": "MAP RIT And Growth X Are Ingested From hp_map_results, Deduped, And Norms-Calculated",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-009-map-growth-rollups"
            },
            {
              "id": "aitd-102-axis-read-shape",
              "title": "API Axis: Read Shape",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-102-axis-read-shape"
            }
          ]
        },
        {
          "name": "source_import_id",
          "type": "TEXT",
          "nullability": "required for report-tile rows; nullable for purely derived event-axis rows",
          "meaning": "Analytics source-import receipt that proves which named report-source adapter produced this report-grade fact.",
          "constraints": "Must reference alpha.analytics_source_import for non-null Learning Report tile values; no literal or fixture value may be reportable without this provenance.",
          "relationship": "Many report-fact rows can reference one source import; detail/sourceRefs endpoints join here for adapter, source_table, and source_row_key_hashes.",
          "invalidWhen": "Missing on a non-null report-tile value, or replaced by copied raw reporting-DB columns.",
          "example": "imp_01HT8MAP_2026_WINTER",
          "sourceClass": "Alpha extension provenance reference",
          "itds": [
            {
              "id": "aitd-001-report-source-ingestion",
              "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
            },
            {
              "id": "aitd-004-provenance-no-literals",
              "title": "Every Report Value Traces To An Ingested Source Row, Or Reads Null",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-004-provenance-no-literals"
            },
            {
              "id": "aitd-009-map-growth-rollups",
              "title": "MAP RIT And Growth X Are Ingested From hp_map_results, Deduped, And Norms-Calculated",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-009-map-growth-rollups"
            }
          ]
        },
        {
          "name": "policy_ref",
          "type": "TEXT",
          "nullability": "required",
          "meaning": "Named policy/config version used to compute the measure or rollup.",
          "constraints": "Must point at alpha.policy.analytics.* or an inherited Curriculum/Results policy active for the source effective date.",
          "relationship": "Many Analytics facts can share one policy row; changing policy creates new calculation versions or corrections.",
          "invalidWhen": "A consumer hard-codes thresholds, school-day calendars, Growth X formulas, or completion denominators instead of using the policy ref.",
          "example": "alpha.policy.analytics.map_growth.v2026-06-10",
          "sourceClass": "Alpha extension reference",
          "itds": [
            {
              "id": "aitd-009-map-growth-rollups",
              "title": "MAP RIT And Growth X Are Ingested From hp_map_results, Deduped, And Norms-Calculated",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-009-map-growth-rollups"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "null_reason",
          "type": "TEXT enum",
          "nullability": "required",
          "meaning": "Why a MAP rollup value is null or not applicable.",
          "constraints": "Allowed values: null_reason enum; none means core report fields are populated.",
          "relationship": "Prevents client fallback term/norm math.",
          "invalidWhen": "Null growth fields without a typed reason.",
          "example": "none",
          "enum": "null_reason",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-009-map-growth-rollups",
              "title": "MAP RIT And Growth X Are Ingested From hp_map_results, Deduped, And Norms-Calculated",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-009-map-growth-rollups"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "quality_status",
          "type": "TEXT enum",
          "nullability": "required",
          "meaning": "Current materialization quality state for this fact.",
          "constraints": "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.",
          "relationship": "Used by raw/API convergence filters and source-ref audit views.",
          "invalidWhen": "Free-text status or hidden failures represented as HTTP 200 success.",
          "example": "ok",
          "enum": "quality_status",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            },
            {
              "id": "aitd-108-axis-error-envelope",
              "title": "API Axis: Error Envelope",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-108-axis-error-envelope"
            },
            {
              "id": "aitd-111-axis-privacy-retention",
              "title": "API Axis: Privacy And Retention",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-111-axis-privacy-retention"
            }
          ]
        },
        {
          "name": "calculation_version",
          "type": "INTEGER",
          "nullability": "required",
          "meaning": "Materializer calculation version for this fact shape.",
          "constraints": "Positive integer; starts at 1 and increments when policy/materializer logic intentionally changes.",
          "relationship": "Part of deterministic source_fact_key/idempotency for materializer writes.",
          "invalidWhen": "Omitted from replay keys or changed without a new policy/materializer decision.",
          "example": "1",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            },
            {
              "id": "aitd-105-axis-idempotency",
              "title": "API Axis: Idempotency Model",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-105-axis-idempotency"
            },
            {
              "id": "aitd-104-axis-concurrency",
              "title": "API Axis: Concurrency Model",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-104-axis-concurrency"
            }
          ]
        },
        {
          "name": "computed_at",
          "type": "TIMESTAMPTZ",
          "nullability": "required",
          "meaning": "When Analytics wrote this derived fact.",
          "constraints": "UTC timestamp with timezone; updated only by Analytics materializers.",
          "relationship": "Used for audit and source-ref subcollections, not for school-day grouping.",
          "invalidWhen": "Used as a substitute for the source event time, result effective time, or window boundaries.",
          "example": "2026-06-10T00:51:14Z",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            }
          ]
        },
        {
          "name": "modified_at",
          "type": "TIMESTAMPTZ",
          "nullability": "required",
          "meaning": "Last time the Analytics row changed for polling and modifiedSince queries.",
          "constraints": "UTC timestamp; list endpoints support modifiedSince against this field.",
          "relationship": "Supports poll plus modifiedSince eventing.",
          "invalidWhen": "Client-supplied or used as the business effective date.",
          "example": "2026-06-10T00:51:14Z",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-107-axis-eventing",
              "title": "API Axis: Eventing Model",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-107-axis-eventing"
            },
            {
              "id": "aitd-103-axis-query-model",
              "title": "API Axis: Query Model",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-103-axis-query-model"
            }
          ]
        },
        {
          "name": "superseded_at",
          "type": "TIMESTAMPTZ",
          "nullability": "nullable",
          "meaning": "When this row stopped being the current reportable version because of source correction, deletion, or recalculation.",
          "constraints": "Null means current; non-null rows are excluded from ordinary list reads unless includeSuperseded=true and authorized.",
          "relationship": "Preserves audit history without mutating source Events or Results.",
          "invalidWhen": "Used to hard-delete old rows or omitted on a correction that replaces a prior fact.",
          "example": "null",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-111-axis-privacy-retention",
              "title": "API Axis: Privacy And Retention",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-111-axis-privacy-retention"
            },
            {
              "id": "aitd-012-corrections-and-reversals",
              "title": "Corrections Are Signed Facts With Provenance",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-012-corrections-and-reversals"
            }
          ]
        },
        {
          "name": "source_deleted_at",
          "type": "TIMESTAMPTZ",
          "nullability": "nullable",
          "meaning": "When the source Event/Result became deleted or invalidated.",
          "constraints": "Null for live source rows; set from source tombstone/correction notifications.",
          "relationship": "Ordinary reads exclude tombstoned facts unless includeSuperseded=true and authorized.",
          "invalidWhen": "Used as a physical delete or ignored by raw-path report queries.",
          "example": "null",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-111-axis-privacy-retention",
              "title": "API Axis: Privacy And Retention",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-111-axis-privacy-retention"
            }
          ]
        }
      ],
      "plainLanguage": "The MAP result row the Learning Report renders: RIT, achievement percentile, growth percentile, Growth X, norms set, growth window, retakes, and on-track flag."
    },
    {
      "name": "alpha.analytics_norms_achievement",
      "title": "NWEA Achievement Norms",
      "kind": "Alpha readable reference table",
      "grain": "norms_set x table_version x subject_id x role x grade_key x season.",
      "primaryKey": "resource_id; unique published grain is (norms_set, table_version, subject_id, role, grade_key, season).",
      "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.",
      "purpose": "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.",
      "metricChecks": [
        "RIT|GrowthX|MAP windows",
        "GOALS percentile-to-RIT"
      ],
      "architecture": [
        {
          "id": "aitd-015-norms-r90-readable-resources",
          "title": "NWEA Norms And NWEAMAP R90 Are Versioned, Readable Surface Reference Tables",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-015-norms-r90-readable-resources"
        },
        {
          "id": "aitd-016-scale-translation-apis",
          "title": "Percentile<->RIT And RIT->R90/Grade Are Server-Side Surface Translations",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-016-scale-translation-apis"
        },
        {
          "id": "aitd-009-map-growth-rollups",
          "title": "MAP RIT And Growth X Are Ingested From hp_map_results, Deduped, And Norms-Calculated",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-009-map-growth-rollups"
        },
        {
          "id": "aitd-011-policy-and-enum-normalization",
          "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
        },
        {
          "id": "aitd-112-axis-list-endpoints",
          "title": "API Axis: List Endpoints",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-112-axis-list-endpoints"
        }
      ],
      "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",
      "rawRule": "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.",
      "example": {
        "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"
      },
      "fields": [
        {
          "name": "resource_id",
          "type": "TEXT",
          "nullability": "required",
          "meaning": "Stable Analytics id for this norms reference row.",
          "constraints": "Generated by Analytics when the versioned table is published; unique across achievement norms rows.",
          "relationship": "Primary key for raw reads and /norms row paging.",
          "invalidWhen": "Caller-supplied, tenant-specific, or reused across table_version values.",
          "example": "norms_2025_math_g5_winter_student",
          "sourceClass": "Alpha readable reference id",
          "itds": [
            {
              "id": "aitd-015-norms-r90-readable-resources",
              "title": "NWEA Norms And NWEAMAP R90 Are Versioned, Readable Surface Reference Tables",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-015-norms-r90-readable-resources"
            }
          ]
        },
        {
          "name": "tenant_id",
          "type": "UUID",
          "nullability": "nullable; must be null for platform-global reference rows",
          "meaning": "Tenant scope marker. Achievement norms rows are platform-global reference data, so tenant_id is null by design.",
          "constraints": "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.",
          "relationship": "Separates global reference data from student-specific Analytics facts.",
          "invalidWhen": "A tenant-specific norms row exists or a raw query joins norms rows by student tenant to create a fork.",
          "example": "null",
          "sourceClass": "Alpha readable reference scope",
          "itds": [
            {
              "id": "aitd-015-norms-r90-readable-resources",
              "title": "NWEA Norms And NWEAMAP R90 Are Versioned, Readable Surface Reference Tables",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-015-norms-r90-readable-resources"
            },
            {
              "id": "aitd-109-axis-tenant-routing",
              "title": "API Axis: Tenant Routing",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-109-axis-tenant-routing"
            }
          ]
        },
        {
          "name": "norms_set",
          "type": "TEXT enum",
          "nullability": "required",
          "meaning": "NWEA norms family this achievement norms row belongs to.",
          "constraints": "Allowed values: norms_set enum. A table version belongs to exactly one norms_set.",
          "relationship": "Required input for /norms, /norms/rit, and /norms/percentile; prevents mixed-norm reports.",
          "invalidWhen": "A row omits norms_set, uses free-text labels, or mixes 2020 and 2025 values in one table_version.",
          "example": "2025",
          "enum": "norms_set",
          "sourceClass": "Alpha readable reference dimension",
          "itds": [
            {
              "id": "aitd-015-norms-r90-readable-resources",
              "title": "NWEA Norms And NWEAMAP R90 Are Versioned, Readable Surface Reference Tables",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-015-norms-r90-readable-resources"
            },
            {
              "id": "aitd-016-scale-translation-apis",
              "title": "Percentile<->RIT And RIT->R90/Grade Are Server-Side Surface Translations",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-016-scale-translation-apis"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "table_version",
          "type": "TEXT",
          "nullability": "required",
          "meaning": "Immutable version id of the published achievement norms table.",
          "constraints": "Stable, cacheable identifier; new source publication or correction creates a new version. Maximum 128 characters.",
          "relationship": "Part of every raw/API lookup. HTTP responses are cache-control: no-store; table_version is the reproducibility key.",
          "invalidWhen": "Rows are edited in place under the same version or a client caches without version.",
          "example": "analytics.norms.achievement.v2026-06-12",
          "sourceClass": "Alpha readable reference version",
          "itds": [
            {
              "id": "aitd-015-norms-r90-readable-resources",
              "title": "NWEA Norms And NWEAMAP R90 Are Versioned, Readable Surface Reference Tables",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-015-norms-r90-readable-resources"
            }
          ]
        },
        {
          "name": "subject_id",
          "type": "TEXT",
          "nullability": "required",
          "meaning": "Canonical Alpha subject for this achievement norms row.",
          "constraints": "Must be one of the MAP-supported Alpha subject values for the table version.",
          "relationship": "Part of percentile/RIT lookup grain.",
          "invalidWhen": "A source label such as Math K-12 or Language Usage is stored without write-time subject normalization.",
          "example": "math",
          "sourceClass": "Alpha extension reference",
          "itds": [
            {
              "id": "aitd-015-norms-r90-readable-resources",
              "title": "NWEA Norms And NWEAMAP R90 Are Versioned, Readable Surface Reference Tables",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-015-norms-r90-readable-resources"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "role",
          "type": "TEXT",
          "nullability": "required",
          "meaning": "NWEA role/population label for the norms row.",
          "constraints": "Governed by the published norms table. Current public student translations use role=student unless a future NWEA publication distinguishes another role.",
          "relationship": "Part of the achievement norms lookup grain.",
          "invalidWhen": "Dropped by a raw query, causing population-specific rows to be mixed if NWEA publishes them.",
          "example": "student",
          "sourceClass": "Alpha readable reference dimension",
          "itds": [
            {
              "id": "aitd-015-norms-r90-readable-resources",
              "title": "NWEA Norms And NWEAMAP R90 Are Versioned, Readable Surface Reference Tables",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-015-norms-r90-readable-resources"
            },
            {
              "id": "aitd-016-scale-translation-apis",
              "title": "Percentile<->RIT And RIT->R90/Grade Are Server-Side Surface Translations",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-016-scale-translation-apis"
            }
          ]
        },
        {
          "name": "grade_key",
          "type": "TEXT",
          "nullability": "required",
          "meaning": "NWEA grade key for this achievement norms row.",
          "constraints": "Governed grade label from the published norms table; examples include K and 1 through 12.",
          "relationship": "Used with subject_id and season for achievement-status lookup.",
          "invalidWhen": "Inferred from a student current grade or Alpha level tag instead of the published norms row.",
          "example": "5",
          "sourceClass": "Alpha readable reference dimension",
          "itds": [
            {
              "id": "aitd-015-norms-r90-readable-resources",
              "title": "NWEA Norms And NWEAMAP R90 Are Versioned, Readable Surface Reference Tables",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-015-norms-r90-readable-resources"
            },
            {
              "id": "aitd-016-scale-translation-apis",
              "title": "Percentile<->RIT And RIT->R90/Grade Are Server-Side Surface Translations",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-016-scale-translation-apis"
            }
          ]
        },
        {
          "name": "season",
          "type": "TEXT",
          "nullability": "required",
          "meaning": "MAP testing season for this achievement norms row.",
          "constraints": "Governed values for the table version: fall, winter, spring, or another NWEA-published season label.",
          "relationship": "Used by percentile-to-RIT and RIT-to-percentile translations.",
          "invalidWhen": "Parsed from report prose or mapped by a client-side term switch statement.",
          "example": "winter",
          "sourceClass": "Alpha readable reference dimension",
          "itds": [
            {
              "id": "aitd-015-norms-r90-readable-resources",
              "title": "NWEA Norms And NWEAMAP R90 Are Versioned, Readable Surface Reference Tables",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-015-norms-r90-readable-resources"
            },
            {
              "id": "aitd-016-scale-translation-apis",
              "title": "Percentile<->RIT And RIT->R90/Grade Are Server-Side Surface Translations",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-016-scale-translation-apis"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "mean_rit",
          "type": "NUMERIC(7,2)",
          "nullability": "required",
          "meaning": "Published mean RIT for this subject/role/grade/season row.",
          "constraints": "Positive numeric RIT value from the NWEA-published achievement-status norms; never estimated by a client.",
          "relationship": "Used by /norms/rit and /norms/percentile normal-model translations.",
          "invalidWhen": "Rounded differently per app or copied from an app-private norms table.",
          "example": "214.20",
          "sourceClass": "Alpha readable reference value",
          "itds": [
            {
              "id": "aitd-015-norms-r90-readable-resources",
              "title": "NWEA Norms And NWEAMAP R90 Are Versioned, Readable Surface Reference Tables",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-015-norms-r90-readable-resources"
            },
            {
              "id": "aitd-016-scale-translation-apis",
              "title": "Percentile<->RIT And RIT->R90/Grade Are Server-Side Surface Translations",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-016-scale-translation-apis"
            }
          ]
        },
        {
          "name": "sd_rit",
          "type": "NUMERIC(6,3)",
          "nullability": "required",
          "meaning": "Published standard deviation of RIT for this subject/role/grade/season row.",
          "constraints": "Must be positive. It is the denominator for RIT-to-percentile and multiplier for percentile-to-RIT.",
          "relationship": "Used by the normal-model translation APIs and raw-DB twin formula.",
          "invalidWhen": "Blank, zero, averaged from adjacent rows, or copied from a different norms_set.",
          "example": "14.100",
          "sourceClass": "Alpha readable reference value",
          "itds": [
            {
              "id": "aitd-015-norms-r90-readable-resources",
              "title": "NWEA Norms And NWEAMAP R90 Are Versioned, Readable Surface Reference Tables",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-015-norms-r90-readable-resources"
            },
            {
              "id": "aitd-016-scale-translation-apis",
              "title": "Percentile<->RIT And RIT->R90/Grade Are Server-Side Surface Translations",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-016-scale-translation-apis"
            }
          ]
        },
        {
          "name": "source_ref",
          "type": "TEXT",
          "nullability": "required",
          "meaning": "Opaque provenance pointer to the NWEA-published norms row in the NWEAMap 1EdTech raw mirror.",
          "constraints": "Must identify the source publication/row without copying a private app table.",
          "relationship": "References the NWEAMAP-owned PowerPath RIT-to-grade master; see https://platform3-andymontgomery-9773s-projects.vercel.app/nweamap/1edtech/data_dictionary.",
          "invalidWhen": "Points at a skill pack file, production app constant, or unversioned spreadsheet export.",
          "example": "nweamap:NormsReferenceData:2025:math:5:winter:student",
          "sourceClass": "Alpha readable reference provenance",
          "itds": [
            {
              "id": "aitd-015-norms-r90-readable-resources",
              "title": "NWEA Norms And NWEAMAP R90 Are Versioned, Readable Surface Reference Tables",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-015-norms-r90-readable-resources"
            }
          ]
        },
        {
          "name": "source_publication",
          "type": "TEXT",
          "nullability": "required",
          "meaning": "Human-readable source publication name for the norms table.",
          "constraints": "Names the NWEA publication behind source_ref; maximum 256 characters.",
          "relationship": "Lets parent/LLM readers understand where the table came from without source code.",
          "invalidWhen": "Blank, generic, or says Alpha extrapolation for an NWEA-published norms point.",
          "example": "NWEA MAP Growth achievement status norms, 2025",
          "sourceClass": "Alpha readable reference provenance",
          "itds": [
            {
              "id": "aitd-015-norms-r90-readable-resources",
              "title": "NWEA Norms And NWEAMAP R90 Are Versioned, Readable Surface Reference Tables",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-015-norms-r90-readable-resources"
            }
          ]
        },
        {
          "name": "is_current_version",
          "type": "BOOLEAN",
          "nullability": "required",
          "meaning": "Whether this table_version is the current default for its norms_set.",
          "constraints": "At most one current version per norms_set and table; historical versions remain readable.",
          "relationship": "Allows callers to request latest without losing reproducibility for pinned historical reports.",
          "invalidWhen": "Old versions are hidden/deleted or multiple versions are current for one norms_set.",
          "example": "true",
          "sourceClass": "Alpha readable reference version metadata",
          "itds": [
            {
              "id": "aitd-015-norms-r90-readable-resources",
              "title": "NWEA Norms And NWEAMAP R90 Are Versioned, Readable Surface Reference Tables",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-015-norms-r90-readable-resources"
            }
          ]
        },
        {
          "name": "published_at",
          "type": "TIMESTAMPTZ",
          "nullability": "required",
          "meaning": "When Analytics published this readable table version.",
          "constraints": "UTC timestamp; not a student test date.",
          "relationship": "Resource lifecycle/audit metadata.",
          "invalidWhen": "Used as a MAP term date or modified in place for corrections.",
          "example": "2026-06-12T00:00:00Z",
          "sourceClass": "Alpha readable reference lifecycle metadata",
          "itds": [
            {
              "id": "aitd-015-norms-r90-readable-resources",
              "title": "NWEA Norms And NWEAMAP R90 Are Versioned, Readable Surface Reference Tables",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-015-norms-r90-readable-resources"
            }
          ]
        },
        {
          "name": "quality_status",
          "type": "TEXT enum",
          "nullability": "required",
          "meaning": "Publication quality state for this reference row.",
          "constraints": "Current public rows use ok. Unpublished or failed rows are not returned by ordinary /norms reads.",
          "relationship": "Keeps reference publication failures visible to operators without fabricating translations.",
          "invalidWhen": "A row with policy_pending/source_missing is used in a translation response.",
          "example": "ok",
          "enum": "quality_status",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-015-norms-r90-readable-resources",
              "title": "NWEA Norms And NWEAMAP R90 Are Versioned, Readable Surface Reference Tables",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-015-norms-r90-readable-resources"
            },
            {
              "id": "aitd-108-axis-error-envelope",
              "title": "API Axis: Error Envelope",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-108-axis-error-envelope"
            }
          ]
        }
      ],
      "plainLanguage": "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."
    },
    {
      "name": "alpha.analytics_r90_table",
      "title": "R90 Table",
      "kind": "Alpha readable reference table",
      "grain": "table_version x table_subject_id x rit_score.",
      "primaryKey": "resource_id; unique published grain is (table_version, table_subject_id, rit_score).",
      "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.",
      "purpose": "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.",
      "metricChecks": [
        "RIT|GrowthX|MAP windows",
        "GOALS RIT-to-grade/R90"
      ],
      "architecture": [
        {
          "id": "aitd-015-norms-r90-readable-resources",
          "title": "NWEA Norms And NWEAMAP R90 Are Versioned, Readable Surface Reference Tables",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-015-norms-r90-readable-resources"
        },
        {
          "id": "aitd-016-scale-translation-apis",
          "title": "Percentile<->RIT And RIT->R90/Grade Are Server-Side Surface Translations",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-016-scale-translation-apis"
        },
        {
          "id": "aitd-017-r90-version-supersession",
          "title": "RIT-to-grade Table Versioning: PowerPath v2026-06-15 Is The Current Version, And One Named Config Picks It For Every Path",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-017-r90-version-supersession"
        },
        {
          "id": "aitd-009-map-growth-rollups",
          "title": "MAP RIT And Growth X Are Ingested From hp_map_results, Deduped, And Norms-Calculated",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-009-map-growth-rollups"
        },
        {
          "id": "aitd-011-policy-and-enum-normalization",
          "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
        },
        {
          "id": "aitd-112-axis-list-endpoints",
          "title": "API Axis: List Endpoints",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-112-axis-list-endpoints"
        }
      ],
      "api": "GET /alpha/analytics/v1/r90/table and GET /alpha/analytics/v1/r90",
      "rawRule": "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.",
      "example": {
        "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"
      },
      "fields": [
        {
          "name": "resource_id",
          "type": "TEXT",
          "nullability": "required",
          "meaning": "Stable Analytics id for this R90 reference row.",
          "constraints": "Generated by Analytics when the R90 table version is published; unique across R90 rows.",
          "relationship": "Primary key for raw reads and /r90 row paging.",
          "invalidWhen": "Caller-supplied or reused across table_version values.",
          "example": "r90_2025_math_239",
          "sourceClass": "Alpha readable reference id",
          "itds": [
            {
              "id": "aitd-015-norms-r90-readable-resources",
              "title": "NWEA Norms And NWEAMAP R90 Are Versioned, Readable Surface Reference Tables",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-015-norms-r90-readable-resources"
            }
          ]
        },
        {
          "name": "tenant_id",
          "type": "UUID",
          "nullability": "nullable; must be null for platform-global reference rows",
          "meaning": "Tenant scope marker. R90 rows are platform-global reference data, so tenant_id is null by design.",
          "constraints": "Apps authenticate with a tenant-scoped JWT, but the raw row itself is global. Tenant-specific R90 forks are forbidden.",
          "relationship": "Enforces the one-canonical-R90-copy decision.",
          "invalidWhen": "A tenant-local R90 table or row exists.",
          "example": "null",
          "sourceClass": "Alpha readable reference scope",
          "itds": [
            {
              "id": "aitd-015-norms-r90-readable-resources",
              "title": "NWEA Norms And NWEAMAP R90 Are Versioned, Readable Surface Reference Tables",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-015-norms-r90-readable-resources"
            },
            {
              "id": "aitd-109-axis-tenant-routing",
              "title": "API Axis: Tenant Routing",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-109-axis-tenant-routing"
            }
          ]
        },
        {
          "name": "norms_set",
          "type": "TEXT enum",
          "nullability": "required",
          "meaning": "NWEA norms family the R90 table version is tied to.",
          "constraints": "Allowed values: norms_set enum.",
          "relationship": "Required input for /r90/table and /r90.",
          "invalidWhen": "An R90 row is used without stating whether it belongs to the 2020 or 2025 norms.",
          "example": "2025",
          "enum": "norms_set",
          "sourceClass": "Alpha readable reference dimension",
          "itds": [
            {
              "id": "aitd-015-norms-r90-readable-resources",
              "title": "NWEA Norms And NWEAMAP R90 Are Versioned, Readable Surface Reference Tables",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-015-norms-r90-readable-resources"
            },
            {
              "id": "aitd-016-scale-translation-apis",
              "title": "Percentile<->RIT And RIT->R90/Grade Are Server-Side Surface Translations",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-016-scale-translation-apis"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "table_version",
          "type": "TEXT",
          "nullability": "required",
          "meaning": "Immutable version id of the published R90 table.",
          "constraints": "Stable, cacheable identifier; current reads use analytics.rit_to_grade.powerpath.v2026-06-15; a method or source change creates a new version.",
          "relationship": "Part of every raw/API lookup. HTTP responses are cache-control: no-store; table_version is the reproducibility key.",
          "invalidWhen": "Two different R90 methods share one version id, or a current raw read omits the current-version filter.",
          "example": "analytics.rit_to_grade.powerpath.v2026-06-15",
          "sourceClass": "Alpha readable reference version",
          "itds": [
            {
              "id": "aitd-015-norms-r90-readable-resources",
              "title": "NWEA Norms And NWEAMAP R90 Are Versioned, Readable Surface Reference Tables",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-015-norms-r90-readable-resources"
            },
            {
              "id": "aitd-017-r90-version-supersession",
              "title": "RIT-to-grade Table Versioning: PowerPath v2026-06-15 Is The Current Version, And One Named Config Picks It For Every Path",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-017-r90-version-supersession"
            }
          ]
        },
        {
          "name": "table_subject_id",
          "type": "TEXT",
          "nullability": "required",
          "meaning": "Canonical table subject for this R90 row.",
          "constraints": "Must be one of the supported MAP/GOALS subject values for the table version.",
          "relationship": "Part of RIT-to-grade/R90 lookup grain.",
          "invalidWhen": "A report maps subject labels locally before looking up R90.",
          "example": "math",
          "sourceClass": "Alpha readable reference dimension",
          "itds": [
            {
              "id": "aitd-015-norms-r90-readable-resources",
              "title": "NWEA Norms And NWEAMAP R90 Are Versioned, Readable Surface Reference Tables",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-015-norms-r90-readable-resources"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "rit_score",
          "type": "NUMERIC(7,2)",
          "nullability": "required",
          "meaning": "Observed RIT score from the PowerPath source row represented by this R90/grade row.",
          "constraints": "Unique within (table_version, table_subject_id); current raw/API lookups use this as the exact key.",
          "relationship": "Exact lookup key for /rit-to-grade and legacy /r90.",
          "invalidWhen": "Duplicated within a subject/version, or a report uses grade2rit.csv as an observed-RIT inverse.",
          "example": "239.00",
          "sourceClass": "Alpha readable reference dimension",
          "itds": [
            {
              "id": "aitd-015-norms-r90-readable-resources",
              "title": "NWEA Norms And NWEAMAP R90 Are Versioned, Readable Surface Reference Tables",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-015-norms-r90-readable-resources"
            },
            {
              "id": "aitd-016-scale-translation-apis",
              "title": "Percentile<->RIT And RIT->R90/Grade Are Server-Side Surface Translations",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-016-scale-translation-apis"
            },
            {
              "id": "aitd-017-r90-version-supersession",
              "title": "RIT-to-grade Table Versioning: PowerPath v2026-06-15 Is The Current Version, And One Named Config Picks It For Every Path",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-017-r90-version-supersession"
            }
          ]
        },
        {
          "name": "rit50_rit",
          "type": "NUMERIC(7,2)",
          "nullability": "required",
          "meaning": "Compatibility anchor for older RIT50/RIT90 reports; in the current PowerPath version this equals the observed RIT source row.",
          "constraints": "Current version uses the PowerPath RIT value. Apps must not use this field to reconstruct the current lookup method.",
          "relationship": "Retained so older report templates that require the headline RIT50/RIT90 fields still receive a surfaced value.",
          "invalidWhen": "Recomputed or rounded differently by an app.",
          "example": "239.00",
          "sourceClass": "Alpha readable reference compatibility value",
          "itds": [
            {
              "id": "aitd-015-norms-r90-readable-resources",
              "title": "NWEA Norms And NWEAMAP R90 Are Versioned, Readable Surface Reference Tables",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-015-norms-r90-readable-resources"
            },
            {
              "id": "aitd-016-scale-translation-apis",
              "title": "Percentile<->RIT And RIT->R90/Grade Are Server-Side Surface Translations",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-016-scale-translation-apis"
            },
            {
              "id": "aitd-017-r90-version-supersession",
              "title": "RIT-to-grade Table Versioning: PowerPath v2026-06-15 Is The Current Version, And One Named Config Picks It For Every Path",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-017-r90-version-supersession"
            }
          ]
        },
        {
          "name": "rit90_rit",
          "type": "NUMERIC(7,2)",
          "nullability": "required",
          "meaning": "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.",
          "constraints": "Must be produced by r90_method_ref; because NWEA does not publish R90 directly, rows carry extend_kind=alpha_extrapolation.",
          "relationship": "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.",
          "invalidWhen": "Copied from a private app table or undocumented production constant.",
          "example": "239.00",
          "sourceClass": "Alpha readable reference compatibility value",
          "itds": [
            {
              "id": "aitd-015-norms-r90-readable-resources",
              "title": "NWEA Norms And NWEAMAP R90 Are Versioned, Readable Surface Reference Tables",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-015-norms-r90-readable-resources"
            },
            {
              "id": "aitd-016-scale-translation-apis",
              "title": "Percentile<->RIT And RIT->R90/Grade Are Server-Side Surface Translations",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-016-scale-translation-apis"
            },
            {
              "id": "aitd-017-r90-version-supersession",
              "title": "RIT-to-grade Table Versioning: PowerPath v2026-06-15 Is The Current Version, And One Named Config Picks It For Every Path",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-017-r90-version-supersession"
            }
          ]
        },
        {
          "name": "r90_grade",
          "type": "NUMERIC(8,3)",
          "nullability": "required",
          "meaning": "Grade-position value from the selected PowerPath row.",
          "constraints": "Governed display/ordering value from the R90 table version; must be reproducible from the same row.",
          "relationship": "Returned by /r90 and read by GOALS when converting a RIT target to grade progress.",
          "invalidWhen": "Computed by a consumer from a private RIT-to-grade table.",
          "example": "4.800",
          "sourceClass": "Alpha readable reference value",
          "itds": [
            {
              "id": "aitd-015-norms-r90-readable-resources",
              "title": "NWEA Norms And NWEAMAP R90 Are Versioned, Readable Surface Reference Tables",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-015-norms-r90-readable-resources"
            },
            {
              "id": "aitd-016-scale-translation-apis",
              "title": "Percentile<->RIT And RIT->R90/Grade Are Server-Side Surface Translations",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-016-scale-translation-apis"
            },
            {
              "id": "aitd-017-r90-version-supersession",
              "title": "RIT-to-grade Table Versioning: PowerPath v2026-06-15 Is The Current Version, And One Named Config Picks It For Every Path",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-017-r90-version-supersession"
            }
          ]
        },
        {
          "name": "effective_grade",
          "type": "INTEGER",
          "nullability": "required",
          "meaning": "Plain report-ready grade/effective-grade label produced by the R90 method.",
          "constraints": "Governed display label; must be reproducible from the same row and method version.",
          "relationship": "Used by Learning Report placement/progress and GOALS.",
          "invalidWhen": "Derived client-side from a local RIT-to-grade table.",
          "example": "5",
          "sourceClass": "Alpha readable reference value",
          "itds": [
            {
              "id": "aitd-015-norms-r90-readable-resources",
              "title": "NWEA Norms And NWEAMAP R90 Are Versioned, Readable Surface Reference Tables",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-015-norms-r90-readable-resources"
            },
            {
              "id": "aitd-016-scale-translation-apis",
              "title": "Percentile<->RIT And RIT->R90/Grade Are Server-Side Surface Translations",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-016-scale-translation-apis"
            },
            {
              "id": "aitd-017-r90-version-supersession",
              "title": "RIT-to-grade Table Versioning: PowerPath v2026-06-15 Is The Current Version, And One Named Config Picks It For Every Path",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-017-r90-version-supersession"
            }
          ]
        },
        {
          "name": "r90_grade_level",
          "type": "INTEGER",
          "nullability": "required",
          "meaning": "Governed grade-level bucket for this R90 row.",
          "constraints": "Integer floor of r90_grade under the current PowerPath method.",
          "relationship": "Supports GOALS and Learning Report grouping without parsing effective_grade text.",
          "invalidWhen": "Derived by splitting display text client-side.",
          "example": "4",
          "sourceClass": "Alpha readable reference value",
          "itds": [
            {
              "id": "aitd-015-norms-r90-readable-resources",
              "title": "NWEA Norms And NWEAMAP R90 Are Versioned, Readable Surface Reference Tables",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-015-norms-r90-readable-resources"
            },
            {
              "id": "aitd-016-scale-translation-apis",
              "title": "Percentile<->RIT And RIT->R90/Grade Are Server-Side Surface Translations",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-016-scale-translation-apis"
            },
            {
              "id": "aitd-017-r90-version-supersession",
              "title": "RIT-to-grade Table Versioning: PowerPath v2026-06-15 Is The Current Version, And One Named Config Picks It For Every Path",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-017-r90-version-supersession"
            }
          ]
        },
        {
          "name": "r90_percent_complete",
          "type": "NUMERIC(7,3)",
          "nullability": "required",
          "meaning": "MAP-inferred percent through the R90 grade band represented by this RIT row.",
          "constraints": "Usually 0 through 100 inside a grade band; computed by the documented R90 method and immutable for the table_version.",
          "relationship": "Used by GOALS to describe grade-band position. It is not actual work progress and must not populate course or grade-level completion.",
          "invalidWhen": "Calculated in GOALS or Learning Report code from a private table, or treated as actual course/grade-level progress.",
          "example": "80.000",
          "sourceClass": "Alpha readable reference value",
          "itds": [
            {
              "id": "aitd-015-norms-r90-readable-resources",
              "title": "NWEA Norms And NWEAMAP R90 Are Versioned, Readable Surface Reference Tables",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-015-norms-r90-readable-resources"
            },
            {
              "id": "aitd-016-scale-translation-apis",
              "title": "Percentile<->RIT And RIT->R90/Grade Are Server-Side Surface Translations",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-016-scale-translation-apis"
            },
            {
              "id": "aitd-017-r90-version-supersession",
              "title": "RIT-to-grade Table Versioning: PowerPath v2026-06-15 Is The Current Version, And One Named Config Picks It For Every Path",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-017-r90-version-supersession"
            }
          ]
        },
        {
          "name": "alpha_min_rit",
          "type": "NUMERIC(7,2)",
          "nullability": "nullable when the Alpha minimum rule does not apply to the row",
          "meaning": "Alpha Minimum RIT associated with this R90/effective-grade band.",
          "constraints": "Nullable in the current PowerPath version; no app-side override.",
          "relationship": "Feeds GOALS and progress predictions.",
          "invalidWhen": "Hard-coded in GOALS or Learning Report code.",
          "example": "null",
          "sourceClass": "Alpha readable reference value",
          "itds": [
            {
              "id": "aitd-015-norms-r90-readable-resources",
              "title": "NWEA Norms And NWEAMAP R90 Are Versioned, Readable Surface Reference Tables",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-015-norms-r90-readable-resources"
            },
            {
              "id": "aitd-016-scale-translation-apis",
              "title": "Percentile<->RIT And RIT->R90/Grade Are Server-Side Surface Translations",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-016-scale-translation-apis"
            }
          ]
        },
        {
          "name": "alpha_predicted_rit",
          "type": "NUMERIC(7,2)",
          "nullability": "nullable when no Alpha predicted value is published for the row",
          "meaning": "Alpha predicted RIT associated with this band under the current R90 method.",
          "constraints": "Set by the documented Alpha method and table_version; current PowerPath version uses the selected observed RIT.",
          "relationship": "Used for GOALS/prediction workflows as a surface value.",
          "invalidWhen": "Computed by a consumer from private expected-growth assumptions.",
          "example": "239.00",
          "sourceClass": "Alpha readable reference value",
          "itds": [
            {
              "id": "aitd-015-norms-r90-readable-resources",
              "title": "NWEA Norms And NWEAMAP R90 Are Versioned, Readable Surface Reference Tables",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-015-norms-r90-readable-resources"
            },
            {
              "id": "aitd-016-scale-translation-apis",
              "title": "Percentile<->RIT And RIT->R90/Grade Are Server-Side Surface Translations",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-016-scale-translation-apis"
            },
            {
              "id": "aitd-017-r90-version-supersession",
              "title": "RIT-to-grade Table Versioning: PowerPath v2026-06-15 Is The Current Version, And One Named Config Picks It For Every Path",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-017-r90-version-supersession"
            }
          ]
        },
        {
          "name": "extend_kind",
          "type": "TEXT",
          "nullability": "required",
          "meaning": "Honest source classification for this row.",
          "constraints": "Allowed value for R90-derived rows: alpha_extrapolation. NWEA-published 50%-correct points may be represented through exact_nwea_point=true.",
          "relationship": "Makes the ALPHA-4 tension visible: R90 is not an NWEA-published field.",
          "invalidWhen": "R90 rows are presented as NWEA-published facts.",
          "example": "alpha_extrapolation",
          "sourceClass": "Alpha readable reference provenance",
          "itds": [
            {
              "id": "aitd-015-norms-r90-readable-resources",
              "title": "NWEA Norms And NWEAMAP R90 Are Versioned, Readable Surface Reference Tables",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-015-norms-r90-readable-resources"
            }
          ]
        },
        {
          "name": "r90_method_ref",
          "type": "TEXT",
          "nullability": "required",
          "meaning": "Named method/policy version that produced R90, effective_grade, alpha_min_rit, and alpha_predicted_rit.",
          "constraints": "Stable versioned R90 method policy reference, for example alpha.policy.analytics.r90_method.v2026-06-12; changing the method creates a new table_version.",
          "relationship": "Lets raw readers reproduce why a row is Alpha extrapolation rather than NWEA pass-through.",
          "invalidWhen": "Blank, unversioned, or stored only in app code.",
          "example": "alpha.policy.analytics.r90_method.v2026-06-12",
          "sourceClass": "Alpha readable reference method",
          "itds": [
            {
              "id": "aitd-015-norms-r90-readable-resources",
              "title": "NWEA Norms And NWEAMAP R90 Are Versioned, Readable Surface Reference Tables",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-015-norms-r90-readable-resources"
            },
            {
              "id": "aitd-016-scale-translation-apis",
              "title": "Percentile<->RIT And RIT->R90/Grade Are Server-Side Surface Translations",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-016-scale-translation-apis"
            },
            {
              "id": "aitd-017-r90-version-supersession",
              "title": "RIT-to-grade Table Versioning: PowerPath v2026-06-15 Is The Current Version, And One Named Config Picks It For Every Path",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-017-r90-version-supersession"
            }
          ]
        },
        {
          "name": "source_norms_refs",
          "type": "JSONB",
          "nullability": "required",
          "meaning": "Published/source refs that anchor this Alpha R90 extrapolation.",
          "constraints": "Array of opaque refs/hashes; no raw private app table data.",
          "relationship": "References the NWEAMap 1EdTech raw mirror; see https://platform3-andymontgomery-9773s-projects.vercel.app/nweamap/1edtech/data_dictionary.",
          "invalidWhen": "Points at an app-owned R90 file or has no provenance.",
          "example": "[\"powerpath:/powerpath/rit-to-grade\", \"powerpath:2026-06-15:Math:RIT:239\"]",
          "sourceClass": "Alpha readable reference provenance",
          "itds": [
            {
              "id": "aitd-015-norms-r90-readable-resources",
              "title": "NWEA Norms And NWEAMAP R90 Are Versioned, Readable Surface Reference Tables",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-015-norms-r90-readable-resources"
            },
            {
              "id": "aitd-017-r90-version-supersession",
              "title": "RIT-to-grade Table Versioning: PowerPath v2026-06-15 Is The Current Version, And One Named Config Picks It For Every Path",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-017-r90-version-supersession"
            }
          ]
        },
        {
          "name": "exact_nwea_point",
          "type": "BOOLEAN",
          "nullability": "required",
          "meaning": "Whether the row value being referenced is an exact NWEA-published point.",
          "constraints": "false for Alpha R90 extrapolations; true only for values reproduced directly from NWEA-published data.",
          "relationship": "Lets apps and parents distinguish NWEA pass-through from Alpha extrapolation.",
          "invalidWhen": "true on a rit90_rit value that NWEA did not publish.",
          "example": "false",
          "sourceClass": "Alpha readable reference provenance",
          "itds": [
            {
              "id": "aitd-015-norms-r90-readable-resources",
              "title": "NWEA Norms And NWEAMAP R90 Are Versioned, Readable Surface Reference Tables",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-015-norms-r90-readable-resources"
            }
          ]
        },
        {
          "name": "source_point_kind",
          "type": "TEXT enum",
          "nullability": "required",
          "meaning": "How the /r90 lookup should describe the source point for this row or translated response.",
          "constraints": "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.",
          "relationship": "Carries the step-floor behavior promised by AITD-016/AITD-017 instead of forcing apps to extrapolate.",
          "invalidWhen": "Missing on a translation response or replaced with a silent nearest-value lookup.",
          "example": "exact",
          "enum": "source_point_kind",
          "sourceClass": "Alpha readable reference lookup metadata",
          "itds": [
            {
              "id": "aitd-015-norms-r90-readable-resources",
              "title": "NWEA Norms And NWEAMAP R90 Are Versioned, Readable Surface Reference Tables",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-015-norms-r90-readable-resources"
            },
            {
              "id": "aitd-016-scale-translation-apis",
              "title": "Percentile<->RIT And RIT->R90/Grade Are Server-Side Surface Translations",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-016-scale-translation-apis"
            },
            {
              "id": "aitd-017-r90-version-supersession",
              "title": "RIT-to-grade Table Versioning: PowerPath v2026-06-15 Is The Current Version, And One Named Config Picks It For Every Path",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-017-r90-version-supersession"
            }
          ]
        },
        {
          "name": "is_current_version",
          "type": "BOOLEAN",
          "nullability": "required",
          "meaning": "Whether this table_version is the current default for its norms_set.",
          "constraints": "At most one current R90 version per norms_set; current is analytics.rit_to_grade.powerpath.v2026-06-15.",
          "relationship": "Supports latest reads while preserving historical reproducibility.",
          "invalidWhen": "Historical versions are deleted or multiple current versions exist.",
          "example": "true",
          "sourceClass": "Alpha readable reference version metadata",
          "itds": [
            {
              "id": "aitd-015-norms-r90-readable-resources",
              "title": "NWEA Norms And NWEAMAP R90 Are Versioned, Readable Surface Reference Tables",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-015-norms-r90-readable-resources"
            },
            {
              "id": "aitd-017-r90-version-supersession",
              "title": "RIT-to-grade Table Versioning: PowerPath v2026-06-15 Is The Current Version, And One Named Config Picks It For Every Path",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-017-r90-version-supersession"
            }
          ]
        },
        {
          "name": "published_at",
          "type": "TIMESTAMPTZ",
          "nullability": "required",
          "meaning": "When Analytics published this R90 table version.",
          "constraints": "UTC timestamp; not a student result date.",
          "relationship": "Resource lifecycle/audit metadata.",
          "invalidWhen": "Used as a MAP term date.",
          "example": "2026-06-14T00:00:00Z",
          "sourceClass": "Alpha readable reference lifecycle metadata",
          "itds": [
            {
              "id": "aitd-015-norms-r90-readable-resources",
              "title": "NWEA Norms And NWEAMAP R90 Are Versioned, Readable Surface Reference Tables",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-015-norms-r90-readable-resources"
            },
            {
              "id": "aitd-017-r90-version-supersession",
              "title": "RIT-to-grade Table Versioning: PowerPath v2026-06-15 Is The Current Version, And One Named Config Picks It For Every Path",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-017-r90-version-supersession"
            }
          ]
        },
        {
          "name": "quality_status",
          "type": "TEXT enum",
          "nullability": "required",
          "meaning": "Publication quality state for this R90 reference row.",
          "constraints": "Current public rows use ok. Failed or unpublished rows are not returned by ordinary /r90/table or /r90 reads.",
          "relationship": "Keeps reference publication failures visible to operators without fabricating translations.",
          "invalidWhen": "A non-ok row is used to answer a report or GOALS translation.",
          "example": "ok",
          "enum": "quality_status",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-015-norms-r90-readable-resources",
              "title": "NWEA Norms And NWEAMAP R90 Are Versioned, Readable Surface Reference Tables",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-015-norms-r90-readable-resources"
            },
            {
              "id": "aitd-108-axis-error-envelope",
              "title": "API Axis: Error Envelope",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-108-axis-error-envelope"
            }
          ]
        }
      ],
      "plainLanguage": "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."
    },
    {
      "name": "analytics.school_days_remaining",
      "title": "School Days Remaining Response",
      "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.",
      "primaryKey": "No stored primary key. The deterministic request grain is student_id, school_id, as_of, end_date, school_day_policy_ref, and effort inputs.",
      "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.",
      "purpose": "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.",
      "metricChecks": [
        "GOALS target date",
        "GOALS school-days-remaining"
      ],
      "architecture": [
        {
          "id": "aitd-018-goals-school-days-remaining",
          "title": "GOALS School-Days-Remaining Read And XP Expected-Minute Unit Live On Analytics",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-018-goals-school-days-remaining"
        },
        {
          "id": "aitd-006-school-day-minutes",
          "title": "Minutes Per Enrolled School Day Uses The Alpha School Calendar",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-006-school-day-minutes"
        },
        {
          "id": "aitd-007-xp-rollups",
          "title": "XP Totals, Goal, Remaining, And Completion Percent Are Ingested Report Facts",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-007-xp-rollups"
        },
        {
          "id": "aitd-016-scale-translation-apis",
          "title": "Percentile<->RIT And RIT->R90/Grade Are Server-Side Surface Translations",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-016-scale-translation-apis"
        },
        {
          "id": "aitd-011-policy-and-enum-normalization",
          "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
        }
      ],
      "api": "GET /alpha/analytics/v1/school-days-remaining",
      "rawRule": "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.",
      "example": {
        "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"
        }
      },
      "fields": [
        {
          "name": "object",
          "type": "TEXT",
          "nullability": "required",
          "meaning": "Response object discriminator for this endpoint.",
          "constraints": "Always analytics.school_days_remaining.",
          "relationship": "Lets docs, skill packs, and contract checks identify the response shape.",
          "invalidWhen": "Missing or replaced with a generic list object.",
          "example": "analytics.school_days_remaining",
          "sourceClass": "Analytics response metadata",
          "itds": [
            {
              "id": "aitd-018-goals-school-days-remaining",
              "title": "GOALS School-Days-Remaining Read And XP Expected-Minute Unit Live On Analytics",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-018-goals-school-days-remaining"
            }
          ]
        },
        {
          "name": "student_id",
          "type": "TEXT",
          "nullability": "required",
          "meaning": "Canonical Alpha student id whose enrolled school calendar is used for the forward count.",
          "constraints": "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.",
          "relationship": "References People and Orgs student identity; see https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/data_dictionary.",
          "invalidWhen": "GOALS supplies a name/email or a current-only student lookup.",
          "example": "student_01HT7G3YZV7QB5N4YKQ1K0Z9A9",
          "sourceClass": "Alpha extension reference",
          "itds": [
            {
              "id": "aitd-018-goals-school-days-remaining",
              "title": "GOALS School-Days-Remaining Read And XP Expected-Minute Unit Live On Analytics",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-018-goals-school-days-remaining"
            },
            {
              "id": "aitd-006-school-day-minutes",
              "title": "Minutes Per Enrolled School Day Uses The Alpha School Calendar",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-006-school-day-minutes"
            },
            {
              "id": "aitd-106-axis-auth-shape",
              "title": "API Axis: Auth Shape",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-106-axis-auth-shape"
            }
          ]
        },
        {
          "name": "school_id",
          "type": "TEXT",
          "nullability": "required",
          "meaning": "School whose alpha.school_calendar rows were read for the forward window.",
          "constraints": "Resolved from request schoolId or the student effective-dated enrollment. Must be one real People and Orgs school.",
          "relationship": "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).",
          "invalidWhen": "Inferred from a display campus string or current-only school assignment outside the requested date.",
          "example": "school_alpha_austin",
          "sourceClass": "Alpha reference",
          "itds": [
            {
              "id": "aitd-018-goals-school-days-remaining",
              "title": "GOALS School-Days-Remaining Read And XP Expected-Minute Unit Live On Analytics",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-018-goals-school-days-remaining"
            },
            {
              "id": "aitd-006-school-day-minutes",
              "title": "Minutes Per Enrolled School Day Uses The Alpha School Calendar",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-006-school-day-minutes"
            }
          ]
        },
        {
          "name": "as_of",
          "type": "DATE",
          "nullability": "required",
          "meaning": "Inclusive start date for the forward school-day count.",
          "constraints": "ISO date. The response uses the half-open window [as_of, end_date).",
          "relationship": "Alias of the asOf request parameter.",
          "invalidWhen": "Treated as exclusive or defaulted to server time without request provenance.",
          "example": "2026-06-14",
          "sourceClass": "Request-derived response field",
          "itds": [
            {
              "id": "aitd-018-goals-school-days-remaining",
              "title": "GOALS School-Days-Remaining Read And XP Expected-Minute Unit Live On Analytics",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-018-goals-school-days-remaining"
            }
          ]
        },
        {
          "name": "end_date",
          "type": "DATE",
          "nullability": "required",
          "meaning": "Exclusive end date for the forward school-day count.",
          "constraints": "ISO date; must be after as_of. If omitted by request, Analytics uses the policy-defined GOALS school-year end.",
          "relationship": "Alias of endDate/schoolYearEnd request parameter.",
          "invalidWhen": "Treated as inclusive, or guessed by a client from a local school-year calendar.",
          "example": "2026-07-24",
          "sourceClass": "Request/policy-derived response field",
          "itds": [
            {
              "id": "aitd-018-goals-school-days-remaining",
              "title": "GOALS School-Days-Remaining Read And XP Expected-Minute Unit Live On Analytics",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-018-goals-school-days-remaining"
            },
            {
              "id": "aitd-006-school-day-minutes",
              "title": "Minutes Per Enrolled School Day Uses The Alpha School Calendar",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-006-school-day-minutes"
            }
          ]
        },
        {
          "name": "school_day_policy_ref",
          "type": "TEXT",
          "nullability": "required",
          "meaning": "Policy ref used to decide which calendar rows count as instructional school days.",
          "constraints": "Current value: alpha.policy.school_day.v2026-06-10. The policy excludes MAP-testing days.",
          "relationship": "Same policy family as alpha.analytics_school_day_minutes.school_day_policy_ref.",
          "invalidWhen": "Blank, unversioned, or replaced by local weekday filtering.",
          "example": "alpha.policy.school_day.v2026-06-10",
          "sourceClass": "Policy reference",
          "itds": [
            {
              "id": "aitd-018-goals-school-days-remaining",
              "title": "GOALS School-Days-Remaining Read And XP Expected-Minute Unit Live On Analytics",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-018-goals-school-days-remaining"
            },
            {
              "id": "aitd-006-school-day-minutes",
              "title": "Minutes Per Enrolled School Day Uses The Alpha School Calendar",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-006-school-day-minutes"
            }
          ]
        },
        {
          "name": "instructional_days_remaining",
          "type": "INTEGER",
          "nullability": "required",
          "meaning": "Count of remaining instructional school days in [as_of, end_date) after calendar, enrollment, and MAP-day exclusion rules.",
          "constraints": "Nonnegative integer. Zero is valid and means no instructional days remain in the requested window.",
          "relationship": "GOALS target-date denominator.",
          "invalidWhen": "Computed from weekdays, attendance days, active dates, or private school-period bounds.",
          "example": "29",
          "sourceClass": "Derived response value",
          "itds": [
            {
              "id": "aitd-018-goals-school-days-remaining",
              "title": "GOALS School-Days-Remaining Read And XP Expected-Minute Unit Live On Analytics",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-018-goals-school-days-remaining"
            },
            {
              "id": "aitd-006-school-day-minutes",
              "title": "Minutes Per Enrolled School Day Uses The Alpha School Calendar",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-006-school-day-minutes"
            }
          ]
        },
        {
          "name": "calendar_ref_count",
          "type": "INTEGER",
          "nullability": "required",
          "meaning": "Count of alpha.school_calendar rows inspected for the requested window before instructional-day filtering.",
          "constraints": "Nonnegative; not the same as instructional_days_remaining.",
          "relationship": "Audit summary for calendar coverage.",
          "invalidWhen": "Rendered as school days remaining or computed from raw date span length.",
          "example": "40",
          "sourceClass": "Audit response value",
          "itds": [
            {
              "id": "aitd-018-goals-school-days-remaining",
              "title": "GOALS School-Days-Remaining Read And XP Expected-Minute Unit Live On Analytics",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-018-goals-school-days-remaining"
            },
            {
              "id": "aitd-006-school-day-minutes",
              "title": "Minutes Per Enrolled School Day Uses The Alpha School Calendar",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-006-school-day-minutes"
            },
            {
              "id": "aitd-102-axis-read-shape",
              "title": "API Axis: Read Shape",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-102-axis-read-shape"
            }
          ]
        },
        {
          "name": "first_instructional_date",
          "type": "DATE",
          "nullability": "nullable when instructional_days_remaining=0",
          "meaning": "First counted instructional date in the requested window.",
          "constraints": "Must be one of instructional_dates when present.",
          "relationship": "GOALS display and audit field.",
          "invalidWhen": "A non-null date appears while instructional_days_remaining=0.",
          "example": "2026-06-15",
          "sourceClass": "Derived response value",
          "itds": [
            {
              "id": "aitd-018-goals-school-days-remaining",
              "title": "GOALS School-Days-Remaining Read And XP Expected-Minute Unit Live On Analytics",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-018-goals-school-days-remaining"
            },
            {
              "id": "aitd-006-school-day-minutes",
              "title": "Minutes Per Enrolled School Day Uses The Alpha School Calendar",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-006-school-day-minutes"
            }
          ]
        },
        {
          "name": "last_instructional_date",
          "type": "DATE",
          "nullability": "nullable when instructional_days_remaining=0",
          "meaning": "Last counted instructional date in the requested window.",
          "constraints": "Must be one of instructional_dates when present and must be before end_date.",
          "relationship": "GOALS display and audit field.",
          "invalidWhen": "Equals end_date when end_date is exclusive, unless end_date itself is not counted and this is a prior date.",
          "example": "2026-07-23",
          "sourceClass": "Derived response value",
          "itds": [
            {
              "id": "aitd-018-goals-school-days-remaining",
              "title": "GOALS School-Days-Remaining Read And XP Expected-Minute Unit Live On Analytics",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-018-goals-school-days-remaining"
            },
            {
              "id": "aitd-006-school-day-minutes",
              "title": "Minutes Per Enrolled School Day Uses The Alpha School Calendar",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-006-school-day-minutes"
            }
          ]
        },
        {
          "name": "instructional_dates",
          "type": "DATE[]",
          "nullability": "required",
          "meaning": "The counted instructional dates returned by the surface for this request.",
          "constraints": "Array length must equal instructional_days_remaining. Values are ISO dates, sorted ascending, and all satisfy the school-day policy.",
          "relationship": "GOALS may render or cache the returned dates by request, but must not recreate them from a private calendar.",
          "invalidWhen": "Unsorted, includes MAP-testing/non-school dates, includes end_date, or differs in length from instructional_days_remaining.",
          "example": "[\"2026-06-15\",\"2026-06-16\",\"2026-06-17\"]",
          "sourceClass": "Derived response value",
          "itds": [
            {
              "id": "aitd-018-goals-school-days-remaining",
              "title": "GOALS School-Days-Remaining Read And XP Expected-Minute Unit Live On Analytics",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-018-goals-school-days-remaining"
            },
            {
              "id": "aitd-006-school-day-minutes",
              "title": "Minutes Per Enrolled School Day Uses The Alpha School Calendar",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-006-school-day-minutes"
            }
          ]
        },
        {
          "name": "xp_unit.policy_ref",
          "type": "TEXT",
          "nullability": "required",
          "meaning": "Versioned policy that defines XP-to-expected-minute conversion.",
          "constraints": "Current value: alpha.policy.analytics.xp_expected_minute.v2026-06-14.",
          "relationship": "Resolves to the XP Expected-Minute Unit policy on this page.",
          "invalidWhen": "Omitted while effort fields are returned, or replaced by a client constant.",
          "example": "alpha.policy.analytics.xp_expected_minute.v2026-06-14",
          "sourceClass": "Policy reference",
          "itds": [
            {
              "id": "aitd-018-goals-school-days-remaining",
              "title": "GOALS School-Days-Remaining Read And XP Expected-Minute Unit Live On Analytics",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-018-goals-school-days-remaining"
            },
            {
              "id": "aitd-007-xp-rollups",
              "title": "XP Totals, Goal, Remaining, And Completion Percent Are Ingested Report Facts",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-007-xp-rollups"
            }
          ]
        },
        {
          "name": "xp_unit.xp_per_expected_minute",
          "type": "NUMERIC(8,3)",
          "nullability": "required",
          "meaning": "How many XP equal one expected minute.",
          "constraints": "Current value is 1.000. It is policy, not a client constant.",
          "relationship": "Used to compute effort.expected_minutes_remaining.",
          "invalidWhen": "GOALS hard-codes a different value or infers it from observed student actuals.",
          "example": "1.000",
          "sourceClass": "Policy response value",
          "itds": [
            {
              "id": "aitd-018-goals-school-days-remaining",
              "title": "GOALS School-Days-Remaining Read And XP Expected-Minute Unit Live On Analytics",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-018-goals-school-days-remaining"
            },
            {
              "id": "aitd-007-xp-rollups",
              "title": "XP Totals, Goal, Remaining, And Completion Percent Are Ingested Report Facts",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-007-xp-rollups"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "xp_unit.xp_per_hour",
          "type": "NUMERIC(8,3)",
          "nullability": "required",
          "meaning": "How many XP equal one expected hour.",
          "constraints": "Current value is 60.000. Derived from 1 XP per expected minute and 60 minutes per hour.",
          "relationship": "Used to compute effort.hours_remaining.",
          "invalidWhen": "Hard-coded in a skill pack or GOALS client instead of read from the surface.",
          "example": "60.000",
          "sourceClass": "Policy response value",
          "itds": [
            {
              "id": "aitd-018-goals-school-days-remaining",
              "title": "GOALS School-Days-Remaining Read And XP Expected-Minute Unit Live On Analytics",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-018-goals-school-days-remaining"
            },
            {
              "id": "aitd-007-xp-rollups",
              "title": "XP Totals, Goal, Remaining, And Completion Percent Are Ingested Report Facts",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-007-xp-rollups"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "xp_unit.meaning",
          "type": "TEXT",
          "nullability": "required",
          "meaning": "Plain-language statement of the XP expected-minute convention.",
          "constraints": "Must state 1 XP = 1 expected minute and 60 XP = 1 expected hour.",
          "relationship": "Allows parent-readable docs and skill packs to explain the conversion without source code.",
          "invalidWhen": "Absent or inconsistent with xp_per_expected_minute/xp_per_hour.",
          "example": "1 XP = 1 expected minute; 60 XP = 1 expected hour.",
          "sourceClass": "Policy response text",
          "itds": [
            {
              "id": "aitd-018-goals-school-days-remaining",
              "title": "GOALS School-Days-Remaining Read And XP Expected-Minute Unit Live On Analytics",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-018-goals-school-days-remaining"
            },
            {
              "id": "aitd-007-xp-rollups",
              "title": "XP Totals, Goal, Remaining, And Completion Percent Are Ingested Report Facts",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-007-xp-rollups"
            }
          ]
        },
        {
          "name": "effort.xp_remaining",
          "type": "NUMERIC(14,3)",
          "nullability": "nullable unless request supplies xpRemaining",
          "meaning": "Remaining XP supplied by the caller or read from related XP rollup flow for effort projection.",
          "constraints": "Nonnegative when present. Mutually exclusive request inputs xpRemaining, minutesRemaining, and hoursRemaining collapse to expected_minutes_remaining.",
          "relationship": "Same XP unit convention as alpha.analytics_xp_rollup.xp_remaining.",
          "invalidWhen": "Negative, or derived by GOALS from a private XP goal formula.",
          "example": "600.000",
          "sourceClass": "Request-derived effort value",
          "itds": [
            {
              "id": "aitd-018-goals-school-days-remaining",
              "title": "GOALS School-Days-Remaining Read And XP Expected-Minute Unit Live On Analytics",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-018-goals-school-days-remaining"
            },
            {
              "id": "aitd-007-xp-rollups",
              "title": "XP Totals, Goal, Remaining, And Completion Percent Are Ingested Report Facts",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-007-xp-rollups"
            }
          ]
        },
        {
          "name": "effort.expected_minutes_remaining",
          "type": "NUMERIC(14,3)",
          "nullability": "nullable unless any effort input is supplied",
          "meaning": "Remaining effort normalized to expected minutes under the XP expected-minute policy.",
          "constraints": "Nonnegative when present.",
          "relationship": "Source for hours_remaining and pacing fields.",
          "invalidWhen": "Computed locally with a private XP_PER_HOUR constant.",
          "example": "600.000",
          "sourceClass": "Derived response value",
          "itds": [
            {
              "id": "aitd-018-goals-school-days-remaining",
              "title": "GOALS School-Days-Remaining Read And XP Expected-Minute Unit Live On Analytics",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-018-goals-school-days-remaining"
            },
            {
              "id": "aitd-007-xp-rollups",
              "title": "XP Totals, Goal, Remaining, And Completion Percent Are Ingested Report Facts",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-007-xp-rollups"
            }
          ]
        },
        {
          "name": "effort.hours_remaining",
          "type": "NUMERIC(14,3)",
          "nullability": "nullable unless any effort input is supplied",
          "meaning": "Remaining effort in expected hours.",
          "constraints": "expected_minutes_remaining / 60 under xp_unit.xp_per_hour.",
          "relationship": "GOALS hours-to-target-date display.",
          "invalidWhen": "Computed locally or rounded differently from the surface.",
          "example": "10.000",
          "sourceClass": "Derived response value",
          "itds": [
            {
              "id": "aitd-018-goals-school-days-remaining",
              "title": "GOALS School-Days-Remaining Read And XP Expected-Minute Unit Live On Analytics",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-018-goals-school-days-remaining"
            },
            {
              "id": "aitd-007-xp-rollups",
              "title": "XP Totals, Goal, Remaining, And Completion Percent Are Ingested Report Facts",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-007-xp-rollups"
            }
          ]
        },
        {
          "name": "effort.target_date",
          "type": "DATE",
          "nullability": "nullable unless targetDate is supplied",
          "meaning": "Requested target date for required-hours-per-school-day projection.",
          "constraints": "Must be after as_of and on or before end_date when supplied.",
          "relationship": "Alias of request targetDate.",
          "invalidWhen": "Before/as_of or after the requested end_date.",
          "example": "2026-07-24",
          "sourceClass": "Request-derived response field",
          "itds": [
            {
              "id": "aitd-018-goals-school-days-remaining",
              "title": "GOALS School-Days-Remaining Read And XP Expected-Minute Unit Live On Analytics",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-018-goals-school-days-remaining"
            }
          ]
        },
        {
          "name": "effort.school_days_until_target_date",
          "type": "INTEGER",
          "nullability": "nullable unless targetDate is supplied",
          "meaning": "Instructional days from as_of through the target-date window according to the same school-day policy.",
          "constraints": "Nonnegative; uses the same half-open counting convention against targetDate as the endpoint documents.",
          "relationship": "Denominator for required_hours_per_school_day_to_target_date.",
          "invalidWhen": "Counts calendar days, weekdays, or dates outside instructional_dates.",
          "example": "29",
          "sourceClass": "Derived response value",
          "itds": [
            {
              "id": "aitd-018-goals-school-days-remaining",
              "title": "GOALS School-Days-Remaining Read And XP Expected-Minute Unit Live On Analytics",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-018-goals-school-days-remaining"
            },
            {
              "id": "aitd-006-school-day-minutes",
              "title": "Minutes Per Enrolled School Day Uses The Alpha School Calendar",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-006-school-day-minutes"
            }
          ]
        },
        {
          "name": "effort.required_hours_per_school_day_to_target_date",
          "type": "NUMERIC(12,3)",
          "nullability": "nullable unless targetDate and effort are supplied and target window has school days",
          "meaning": "Expected hours per remaining instructional day needed to finish by targetDate.",
          "constraints": "hours_remaining / school_days_until_target_date; null when school_days_until_target_date=0.",
          "relationship": "GOALS target-date pacing value.",
          "invalidWhen": "Computed over calendar days or rounded in client code.",
          "example": "0.345",
          "sourceClass": "Derived response value",
          "itds": [
            {
              "id": "aitd-018-goals-school-days-remaining",
              "title": "GOALS School-Days-Remaining Read And XP Expected-Minute Unit Live On Analytics",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-018-goals-school-days-remaining"
            },
            {
              "id": "aitd-007-xp-rollups",
              "title": "XP Totals, Goal, Remaining, And Completion Percent Are Ingested Report Facts",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-007-xp-rollups"
            }
          ]
        },
        {
          "name": "effort.hours_per_school_day",
          "type": "NUMERIC(12,3)",
          "nullability": "nullable unless request supplies hoursPerSchoolDay",
          "meaning": "Caller-supplied planned expected hours per instructional day.",
          "constraints": "Must be positive when supplied.",
          "relationship": "Input for school_days_needed_at_hours_per_school_day.",
          "invalidWhen": "Zero, negative, or interpreted as clock-hours available on non-school days.",
          "example": "1.500",
          "sourceClass": "Request-derived effort value",
          "itds": [
            {
              "id": "aitd-018-goals-school-days-remaining",
              "title": "GOALS School-Days-Remaining Read And XP Expected-Minute Unit Live On Analytics",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-018-goals-school-days-remaining"
            }
          ]
        },
        {
          "name": "effort.school_days_needed_at_hours_per_school_day",
          "type": "INTEGER",
          "nullability": "nullable unless hoursPerSchoolDay and effort are supplied",
          "meaning": "Instructional-day count needed to finish at the supplied pace.",
          "constraints": "ceil(hours_remaining / hoursPerSchoolDay).",
          "relationship": "GOALS date-at-pace calculation.",
          "invalidWhen": "Counts weekdays or rounds down.",
          "example": "7",
          "sourceClass": "Derived response value",
          "itds": [
            {
              "id": "aitd-018-goals-school-days-remaining",
              "title": "GOALS School-Days-Remaining Read And XP Expected-Minute Unit Live On Analytics",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-018-goals-school-days-remaining"
            },
            {
              "id": "aitd-007-xp-rollups",
              "title": "XP Totals, Goal, Remaining, And Completion Percent Are Ingested Report Facts",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-007-xp-rollups"
            }
          ]
        },
        {
          "name": "effort.target_date_at_hours_per_school_day",
          "type": "DATE",
          "nullability": "nullable unless the supplied pace finishes inside the requested window",
          "meaning": "Instructional date reached at the supplied pace.",
          "constraints": "Must be one of instructional_dates when present; null when the window is too short.",
          "relationship": "GOALS predicted finish date at the supplied pace.",
          "invalidWhen": "Falls on a non-school/MAP day or after end_date without null/false finish status.",
          "example": "2026-06-23",
          "sourceClass": "Derived response value",
          "itds": [
            {
              "id": "aitd-018-goals-school-days-remaining",
              "title": "GOALS School-Days-Remaining Read And XP Expected-Minute Unit Live On Analytics",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-018-goals-school-days-remaining"
            },
            {
              "id": "aitd-006-school-day-minutes",
              "title": "Minutes Per Enrolled School Day Uses The Alpha School Calendar",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-006-school-day-minutes"
            },
            {
              "id": "aitd-007-xp-rollups",
              "title": "XP Totals, Goal, Remaining, And Completion Percent Are Ingested Report Facts",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-007-xp-rollups"
            }
          ]
        },
        {
          "name": "effort.can_finish_by_end_date_at_hours_per_school_day",
          "type": "BOOLEAN",
          "nullability": "nullable unless hoursPerSchoolDay and effort are supplied",
          "meaning": "Whether the supplied pace finishes within the requested forward window.",
          "constraints": "True only when school_days_needed_at_hours_per_school_day <= instructional_days_remaining.",
          "relationship": "GOALS finishability flag.",
          "invalidWhen": "True while target_date_at_hours_per_school_day is null.",
          "example": "true",
          "sourceClass": "Derived response value",
          "itds": [
            {
              "id": "aitd-018-goals-school-days-remaining",
              "title": "GOALS School-Days-Remaining Read And XP Expected-Minute Unit Live On Analytics",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-018-goals-school-days-remaining"
            },
            {
              "id": "aitd-007-xp-rollups",
              "title": "XP Totals, Goal, Remaining, And Completion Percent Are Ingested Report Facts",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-007-xp-rollups"
            }
          ]
        },
        {
          "name": "provenance.source",
          "type": "TEXT",
          "nullability": "required",
          "meaning": "Plain source statement for the calendar/enrollment rows behind the response.",
          "constraints": "Must name alpha.school_calendar over Ed-Fi CalendarDate and People and Orgs enrollment.",
          "relationship": "Points readers to the raw-DB path without exposing PII payloads.",
          "invalidWhen": "Claims weekday math or a private GOALS school-period table as the source.",
          "example": "alpha.school_calendar over ed_fi.CalendarDate plus People and Orgs enrollment",
          "sourceClass": "Provenance response field",
          "itds": [
            {
              "id": "aitd-018-goals-school-days-remaining",
              "title": "GOALS School-Days-Remaining Read And XP Expected-Minute Unit Live On Analytics",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-018-goals-school-days-remaining"
            },
            {
              "id": "aitd-006-school-day-minutes",
              "title": "Minutes Per Enrolled School Day Uses The Alpha School Calendar",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-006-school-day-minutes"
            }
          ]
        },
        {
          "name": "provenance.source_ref_sample",
          "type": "TEXT[]",
          "nullability": "nullable",
          "meaning": "Opaque sample refs for calendar rows used by the read.",
          "constraints": "May include refs/hashes only; no raw calendar payload or student PII.",
          "relationship": "Audit pointer for operators.",
          "invalidWhen": "Contains raw source rows or student names/emails.",
          "example": "[\"calendar_date:school_alpha_austin:2026-06-15\"]",
          "sourceClass": "Provenance response field",
          "itds": [
            {
              "id": "aitd-018-goals-school-days-remaining",
              "title": "GOALS School-Days-Remaining Read And XP Expected-Minute Unit Live On Analytics",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-018-goals-school-days-remaining"
            },
            {
              "id": "aitd-111-axis-privacy-retention",
              "title": "API Axis: Privacy And Retention",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-111-axis-privacy-retention"
            }
          ]
        },
        {
          "name": "provenance.policy_ref",
          "type": "TEXT",
          "nullability": "required",
          "meaning": "School-day policy ref used for the calendar count.",
          "constraints": "Must match school_day_policy_ref.",
          "relationship": "Audit-friendly duplicate for the provenance block.",
          "invalidWhen": "Differs from school_day_policy_ref.",
          "example": "alpha.policy.school_day.v2026-06-10",
          "sourceClass": "Policy provenance field",
          "itds": [
            {
              "id": "aitd-018-goals-school-days-remaining",
              "title": "GOALS School-Days-Remaining Read And XP Expected-Minute Unit Live On Analytics",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-018-goals-school-days-remaining"
            },
            {
              "id": "aitd-006-school-day-minutes",
              "title": "Minutes Per Enrolled School Day Uses The Alpha School Calendar",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-006-school-day-minutes"
            }
          ]
        },
        {
          "name": "provenance.xp_unit_policy_ref",
          "type": "TEXT",
          "nullability": "required",
          "meaning": "XP expected-minute policy ref used for effort projection.",
          "constraints": "Must match alpha.policy.analytics.xp_expected_minute.v2026-06-14.",
          "relationship": "Audit-friendly pointer to the XP unit policy.",
          "invalidWhen": "Missing while effort or xp_unit fields are returned.",
          "example": "alpha.policy.analytics.xp_expected_minute.v2026-06-14",
          "sourceClass": "Policy provenance field",
          "itds": [
            {
              "id": "aitd-018-goals-school-days-remaining",
              "title": "GOALS School-Days-Remaining Read And XP Expected-Minute Unit Live On Analytics",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-018-goals-school-days-remaining"
            },
            {
              "id": "aitd-007-xp-rollups",
              "title": "XP Totals, Goal, Remaining, And Completion Percent Are Ingested Report Facts",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-007-xp-rollups"
            }
          ]
        },
        {
          "name": "links.self",
          "type": "URL",
          "nullability": "required",
          "meaning": "The request URL for this read.",
          "constraints": "Must preserve the effective query parameters used to produce the answer.",
          "relationship": "Useful for skill-pack reproduction and support.",
          "invalidWhen": "Missing or points at a stale/non-equivalent query.",
          "example": "/alpha/analytics/v1/school-days-remaining?studentId=student_01HT7G3YZV7QB5N4YKQ1K0Z9A9&asOf=2026-06-14&endDate=2026-07-24",
          "sourceClass": "Response link",
          "itds": [
            {
              "id": "aitd-018-goals-school-days-remaining",
              "title": "GOALS School-Days-Remaining Read And XP Expected-Minute Unit Live On Analytics",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-018-goals-school-days-remaining"
            },
            {
              "id": "aitd-102-axis-read-shape",
              "title": "API Axis: Read Shape",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-102-axis-read-shape"
            }
          ]
        },
        {
          "name": "links.schoolDayMinutes",
          "type": "URL",
          "nullability": "required",
          "meaning": "Related consumed-day rollup endpoint for past Time Commitment rows.",
          "constraints": "This is a related link, not the source for future-day counts.",
          "relationship": "Points to alpha.analytics_school_day_minutes when a report also needs consumed days.",
          "invalidWhen": "Used to answer future school-days remaining when no consumed-day row exists.",
          "example": "/alpha/analytics/v1/school-day-minutes?studentId=student_01HT7G3YZV7QB5N4YKQ1K0Z9A9&windowKind=school_year",
          "sourceClass": "Response link",
          "itds": [
            {
              "id": "aitd-018-goals-school-days-remaining",
              "title": "GOALS School-Days-Remaining Read And XP Expected-Minute Unit Live On Analytics",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-018-goals-school-days-remaining"
            },
            {
              "id": "aitd-006-school-day-minutes",
              "title": "Minutes Per Enrolled School Day Uses The Alpha School Calendar",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-006-school-day-minutes"
            }
          ]
        },
        {
          "name": "links.xpRollups",
          "type": "URL",
          "nullability": "required",
          "meaning": "Related XP rollup endpoint for XP total/remaining/goal rows.",
          "constraints": "GOALS may use the rollup to obtain xp_remaining, then pass it into this endpoint for effort projection.",
          "relationship": "Points to alpha.analytics_xp_rollup.",
          "invalidWhen": "Used as permission to calculate XP goal fields locally.",
          "example": "/alpha/analytics/v1/xp-rollups?studentId=student_01HT7G3YZV7QB5N4YKQ1K0Z9A9&windowKind=school_year",
          "sourceClass": "Response link",
          "itds": [
            {
              "id": "aitd-018-goals-school-days-remaining",
              "title": "GOALS School-Days-Remaining Read And XP Expected-Minute Unit Live On Analytics",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-018-goals-school-days-remaining"
            },
            {
              "id": "aitd-007-xp-rollups",
              "title": "XP Totals, Goal, Remaining, And Completion Percent Are Ingested Report Facts",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-007-xp-rollups"
            }
          ]
        }
      ],
      "plainLanguage": "The GOALS endpoint response object: remaining instructional days and XP-to-time effort projections from the surface calendar and XP expected-minute policy."
    },
    {
      "name": "analytics.grade_level_status",
      "title": "Grade-Level Status Response",
      "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.",
      "primaryKey": "No stored primary key. The deterministic request grain is student_id, subject_id, and as_of_date.",
      "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.",
      "purpose": "GOALS age-grade status without local comparison logic: exactly two named comparisons, working vs age grade and mastered vs age grade.",
      "metricChecks": [
        "GOALS age-grade status",
        "GOALS ahead/at/behind"
      ],
      "architecture": [
        {
          "id": "aitd-102-axis-read-shape",
          "title": "API Axis: Read Shape",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-102-axis-read-shape"
        },
        {
          "id": "aitd-008-mastery-and-grade-levels",
          "title": "Grade Levels Mastered Are Ingested; Mastery Deltas Read Results State",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-008-mastery-and-grade-levels"
        },
        {
          "id": "aitd-011-policy-and-enum-normalization",
          "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
        },
        {
          "id": "aitd-112-axis-list-endpoints",
          "title": "API Axis: List Endpoints",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-112-axis-list-endpoints"
        }
      ],
      "api": "GET /alpha/analytics/v1/grade-level-status",
      "rawRule": "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.",
      "example": {
        "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"
        }
      },
      "fields": [
        {
          "name": "object",
          "type": "TEXT",
          "nullability": "required",
          "meaning": "Response object discriminator for this endpoint.",
          "constraints": "Always analytics.grade_level_status.",
          "relationship": "Lets docs, skill packs, and contract checks identify the response shape.",
          "invalidWhen": "Missing or replaced by a generic status object.",
          "example": "analytics.grade_level_status",
          "sourceClass": "Analytics response metadata",
          "itds": [
            {
              "id": "aitd-102-axis-read-shape",
              "title": "API Axis: Read Shape",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-102-axis-read-shape"
            }
          ]
        },
        {
          "name": "student_id",
          "type": "TEXT",
          "nullability": "required",
          "meaning": "Canonical Alpha student id used to read P&O age grade and Results grade positions.",
          "constraints": "Must resolve to the same student across People and Orgs and Results source tenants.",
          "relationship": "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).",
          "invalidWhen": "Name/email/local app id is used directly.",
          "example": "b6fa7128-f641-4efd-9075-375411fd6c39",
          "sourceClass": "Alpha extension reference",
          "itds": [
            {
              "id": "aitd-102-axis-read-shape",
              "title": "API Axis: Read Shape",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-102-axis-read-shape"
            },
            {
              "id": "aitd-109-axis-tenant-routing",
              "title": "API Axis: Tenant Routing",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-109-axis-tenant-routing"
            }
          ]
        },
        {
          "name": "subject_id",
          "type": "TEXT enum",
          "nullability": "required",
          "meaning": "Canonical subject for Results working grade and HMG lookup.",
          "constraints": "Use Analytics/Results governed subject ids; subject aliases normalize at the platform boundary.",
          "relationship": "Same governed subject id family as other Analytics report endpoints.",
          "invalidWhen": "Parsed from MAP test names or course titles by a client.",
          "example": "math",
          "enum": "subject_id",
          "sourceClass": "Request-derived response field",
          "itds": [
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "as_of_date",
          "type": "DATE",
          "nullability": "required",
          "meaning": "Date used for the point-in-time P&O age-grade row and Results state read.",
          "constraints": "ISO date. The response does not default age grade from a current-only scalar.",
          "relationship": "Drives the effective-dated age-grade and Results state reads.",
          "invalidWhen": "Ignored or replaced by server-now without provenance.",
          "example": "2026-05-20",
          "sourceClass": "Request-derived response field",
          "itds": [
            {
              "id": "aitd-102-axis-read-shape",
              "title": "API Axis: Read Shape",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-102-axis-read-shape"
            }
          ]
        },
        {
          "name": "age_grade",
          "type": "INTEGER",
          "nullability": "nullable when P&O has no active age-grade history row",
          "meaning": "Student's school-assigned cohort grade for school-year reporting as of as_of_date.",
          "constraints": "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.",
          "relationship": "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.",
          "invalidWhen": "Computed from achievement, parsed from labels, or copied into Results.",
          "example": "5",
          "sourceClass": "People and Orgs source fact",
          "itds": [
            {
              "id": "aitd-102-axis-read-shape",
              "title": "API Axis: Read Shape",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-102-axis-read-shape"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "working_grade",
          "type": "INTEGER",
          "nullability": "nullable when Results has no working-grade state",
          "meaning": "Results-owned working grade for the subject and as_of_date.",
          "constraints": "Read from Results; Analytics does not recompute the working-grade resolver.",
          "relationship": "Owned by Results student track state; see https://platform3-andymontgomery-9773s-projects.vercel.app/results/alpha/data_dictionary.",
          "invalidWhen": "Derived from MAP/RIT/R90 or duplicated into P&O.",
          "example": "6",
          "sourceClass": "Results source fact",
          "itds": [
            {
              "id": "aitd-008-mastery-and-grade-levels",
              "title": "Grade Levels Mastered Are Ingested; Mastery Deltas Read Results State",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-008-mastery-and-grade-levels"
            },
            {
              "id": "aitd-102-axis-read-shape",
              "title": "API Axis: Read Shape",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-102-axis-read-shape"
            }
          ]
        },
        {
          "name": "highest_mastered_grade",
          "type": "INTEGER",
          "nullability": "nullable when Results has no HMG state",
          "meaning": "Results-owned highest mastered grade for the subject and as_of_date.",
          "constraints": "Read from Results; strict mastery-vs-age status uses this field directly.",
          "relationship": "Owned by Results highest-mastered state; see https://platform3-andymontgomery-9773s-projects.vercel.app/results/alpha/data_dictionary.",
          "invalidWhen": "Inferred from working grade without Results provenance.",
          "example": "5",
          "sourceClass": "Results source fact",
          "itds": [
            {
              "id": "aitd-008-mastery-and-grade-levels",
              "title": "Grade Levels Mastered Are Ingested; Mastery Deltas Read Results State",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-008-mastery-and-grade-levels"
            },
            {
              "id": "aitd-102-axis-read-shape",
              "title": "API Axis: Read Shape",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-102-axis-read-shape"
            }
          ]
        },
        {
          "name": "working_age_grade_delta",
          "type": "INTEGER",
          "nullability": "nullable when age_grade or working_grade is missing",
          "meaning": "Signed difference between working_grade and age_grade.",
          "constraints": "Formula: working_grade - age_grade.",
          "relationship": "Drives working_age_grade_status.",
          "invalidWhen": "Computed against HMG or MAP-inferred grade position.",
          "example": "1",
          "sourceClass": "Derived response value",
          "itds": [
            {
              "id": "aitd-102-axis-read-shape",
              "title": "API Axis: Read Shape",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-102-axis-read-shape"
            }
          ]
        },
        {
          "name": "working_age_grade_status",
          "type": "TEXT enum",
          "nullability": "required",
          "meaning": "Named working-vs-age status.",
          "constraints": "Allowed values: working_behind_age_grade, working_at_age_grade, working_above_age_grade, unknown.",
          "relationship": "Preferred GOALS ahead/at/behind status field.",
          "invalidWhen": "Replaced by generic ahead/at/behind or instructional_level_status as preferred public contract.",
          "example": "working_above_age_grade",
          "sourceClass": "Derived response label",
          "itds": [
            {
              "id": "aitd-102-axis-read-shape",
              "title": "API Axis: Read Shape",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-102-axis-read-shape"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "mastered_age_grade_delta",
          "type": "INTEGER",
          "nullability": "nullable when age_grade or highest_mastered_grade is missing",
          "meaning": "Signed difference between highest_mastered_grade and age_grade.",
          "constraints": "Formula: highest_mastered_grade - age_grade.",
          "relationship": "Drives mastered_age_grade_status.",
          "invalidWhen": "Computed from working grade or MAP-inferred grade position.",
          "example": "0",
          "sourceClass": "Derived response value",
          "itds": [
            {
              "id": "aitd-102-axis-read-shape",
              "title": "API Axis: Read Shape",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-102-axis-read-shape"
            }
          ]
        },
        {
          "name": "mastered_age_grade_status",
          "type": "TEXT enum",
          "nullability": "required",
          "meaning": "Named strict mastery-vs-age status.",
          "constraints": "Allowed values: mastered_behind_age_grade, mastered_at_age_grade, mastered_above_age_grade, unknown.",
          "relationship": "Separate qualified read from working_age_grade_status.",
          "invalidWhen": "Used as the default GOALS working status or hidden under generic mastery_level_status.",
          "example": "mastered_at_age_grade",
          "sourceClass": "Derived response label",
          "itds": [
            {
              "id": "aitd-102-axis-read-shape",
              "title": "API Axis: Read Shape",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-102-axis-read-shape"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "source_refs",
          "type": "JSON object",
          "nullability": "required",
          "meaning": "Machine-readable owner pointers for the facts used by the response.",
          "constraints": "Must name P&O for age grade and Results for working/HMG.",
          "relationship": "Prevents clients and doers from moving ownership into Analytics.",
          "invalidWhen": "Missing, names Analytics as the owner of age_grade/HMG, or points at MAP/RIT.",
          "example": "{\"age_grade\":\"people_and_orgs.alpha.age_grade_history\",\"working_grade\":\"results.student_track_state.working_grade\",\"highest_mastered_grade\":\"results.highest_mastered_grade\"}",
          "sourceClass": "Provenance response field",
          "itds": [
            {
              "id": "aitd-004-provenance-no-literals",
              "title": "Every Report Value Traces To An Ingested Source Row, Or Reads Null",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-004-provenance-no-literals"
            },
            {
              "id": "aitd-102-axis-read-shape",
              "title": "API Axis: Read Shape",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-102-axis-read-shape"
            }
          ]
        },
        {
          "name": "deprecated_aliases",
          "type": "JSON object",
          "nullability": "nullable compatibility block",
          "meaning": "Compatibility mapping for old field names; not the preferred public contract.",
          "constraints": "If served, instructional_level_status delegates to working_age_grade_status and strict_mastery_status delegates to mastered_age_grade_status.",
          "relationship": "Allows old consumers to migrate without reintroducing generic status terminology.",
          "invalidWhen": "Documented as preferred or computed with different formulas.",
          "example": "{\"instructional_level_status\":\"working_age_grade_status\",\"strict_mastery_status\":\"mastered_age_grade_status\"}",
          "sourceClass": "Compatibility metadata",
          "itds": [
            {
              "id": "aitd-102-axis-read-shape",
              "title": "API Axis: Read Shape",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-102-axis-read-shape"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        }
      ],
      "plainLanguage": "The GOALS endpoint response object: P&O age grade plus Results working/HMG positions and the two named age-grade comparisons."
    },
    {
      "name": "alpha.analytics_completion_rollup",
      "title": "Completion Rollup",
      "kind": "Alpha extension rollup table",
      "grain": "student_id x completion_scope x scope_id x window_start x window_end x policy_ref.",
      "primaryKey": "id; unique current grain is (tenant_id, student_id, completion_scope, scope_id, window_start, window_end, policy_ref, calculation_version).",
      "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.",
      "purpose": "Progress evidence for Results and Analytics audits without MAP/RIT/R90 inference, client-side Curriculum tree walking, or Results-row counting.",
      "metricChecks": [
        "completion|curriculum refs"
      ],
      "architecture": [
        {
          "id": "aitd-010-completion-rollups",
          "title": "Completion Percent Is Ingested Earned XP Over A Curriculum Denominator, Never Invented",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-010-completion-rollups"
        },
        {
          "id": "aitd-001-report-source-ingestion",
          "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
        },
        {
          "id": "aitd-004-provenance-no-literals",
          "title": "Every Report Value Traces To An Ingested Source Row, Or Reads Null",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-004-provenance-no-literals"
        },
        {
          "id": "aitd-003-close-time-materialization",
          "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
        },
        {
          "id": "aitd-011-policy-and-enum-normalization",
          "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
        }
      ],
      "api": "GET /alpha/analytics/v1/completion-rollups",
      "rawRule": "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.",
      "example": {
        "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
      },
      "fields": [
        {
          "name": "id",
          "type": "UUID",
          "nullability": "required",
          "meaning": "Analytics-owned stable row id for this derived fact.",
          "constraints": "Generated by the platform; globally unique within alpha.analytics_* objects.",
          "relationship": "Primary key for list/detail endpoints.",
          "invalidWhen": "Provided by a public import client or reused across tenants.",
          "example": "8e9c0ef2-bc75-4f53-8124-df77df49f25f",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-000-extend-only-storage",
              "title": "Analytics Is New Extend-Only Alpha Storage",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-000-extend-only-storage"
            }
          ]
        },
        {
          "name": "tenant_id",
          "type": "UUID",
          "nullability": "required",
          "meaning": "Tenant boundary for the derived fact.",
          "constraints": "Set from the JWT tenant claim or internal materializer context; never accepted from request body/query.",
          "relationship": "All raw-path queries must filter by tenant_id before joining, sorting, paging, or counting.",
          "invalidWhen": "Missing, caller-supplied in body/query, or mismatched with the JWT tenant claim.",
          "example": "7b0bb5d8-9a38-4a62-9fdc-9f8d2dc1a111",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-109-axis-tenant-routing",
              "title": "API Axis: Tenant Routing",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-109-axis-tenant-routing"
            },
            {
              "id": "aitd-106-axis-auth-shape",
              "title": "API Axis: Auth Shape",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-106-axis-auth-shape"
            }
          ]
        },
        {
          "name": "student_id",
          "type": "TEXT",
          "nullability": "required",
          "meaning": "Canonical Alpha student id the source Event or Result resolved to at materialization time.",
          "constraints": "Must resolve through People and Orgs as a real student for the source timestamp/effective date.",
          "relationship": "References People and Orgs student identity; see https://platform3-andymontgomery-9773s-projects.vercel.app/people_and_orgs/alpha/data_dictionary.",
          "invalidWhen": "Parsed from email/name/source payload instead of resolved by the Events/Results adapter.",
          "example": "student_01HT7G3YZV7QB5N4YKQ1K0Z9A9",
          "sourceClass": "Alpha extension reference",
          "itds": [
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            },
            {
              "id": "aitd-106-axis-auth-shape",
              "title": "API Axis: Auth Shape",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-106-axis-auth-shape"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "completion_scope",
          "type": "TEXT enum",
          "nullability": "required",
          "meaning": "Curriculum/reporting scope for this completion measure.",
          "constraints": "Allowed values: completion_scope enum.",
          "relationship": "Determines what scope_id points to.",
          "invalidWhen": "A consumer invents separate columns per course/track/segment instead of using the typed scope.",
          "example": "course",
          "enum": "completion_scope",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-010-completion-rollups",
              "title": "Completion Percent Is Ingested Earned XP Over A Curriculum Denominator, Never Invented",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-010-completion-rollups"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "scope_id",
          "type": "TEXT",
          "nullability": "required",
          "meaning": "Identifier of the Curriculum or subject scope being measured.",
          "constraints": "Must match completion_scope: course id for course, subject id for subject, track id for track, etc.",
          "relationship": "References Curriculum scope refs; see https://platform3-andymontgomery-9773s-projects.vercel.app/curriculum/alpha/data_dictionary.",
          "invalidWhen": "A report walks the course tree and generates its own scope id.",
          "example": "course_math_grade_4_powerpath",
          "sourceClass": "Alpha extension reference",
          "itds": [
            {
              "id": "aitd-000-extend-only-storage",
              "title": "Analytics Is New Extend-Only Alpha Storage",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-000-extend-only-storage"
            },
            {
              "id": "aitd-010-completion-rollups",
              "title": "Completion Percent Is Ingested Earned XP Over A Curriculum Denominator, Never Invented",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-010-completion-rollups"
            }
          ]
        },
        {
          "name": "subject_id",
          "type": "TEXT",
          "nullability": "nullable; required when completion_scope=subject or the scope resolves to one subject",
          "meaning": "Canonical Alpha subject used for reporting and grouping.",
          "constraints": "Closed Alpha subject enum after write-time source-label normalization; unknown source subject becomes an adapter finding or null_reason, not a new string.",
          "relationship": "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.",
          "invalidWhen": "Copied from source strings such as FastMath, Vocabulary, Science-notqced, or ISEE variants without normalization.",
          "example": "math",
          "sourceClass": "Alpha extension reference",
          "itds": [
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "grade_level",
          "type": "INTEGER",
          "nullability": "nullable for non-grade-level scopes without a course grade",
          "meaning": "Working grade level associated with the course progress row, or the grade represented by a grade_level aggregate.",
          "constraints": "Must come from the course/Caliper/Curriculum scope metadata, not from MAP/RIT/R90.",
          "relationship": "GOALS filters grade-level progress by this typed field.",
          "invalidWhen": "Derived from RIT, R90, effective_grade, or a private placement table.",
          "example": "4",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-010-completion-rollups",
              "title": "Completion Percent Is Ingested Earned XP Over A Curriculum Denominator, Never Invented",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-010-completion-rollups"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "is_main_course",
          "type": "BOOLEAN",
          "nullability": "nullable when not applicable; true for main course and grade_level aggregate rows",
          "meaning": "Whether the course row counts toward grade-level progress.",
          "constraints": "Main grade-level courses count; remediation, hole-filling, catalog, practice, and review courses do not.",
          "relationship": "Defines the denominator for completion_scope=grade_level rows.",
          "invalidWhen": "Unset on a course row that contributes to grade-level progress, or true for a hole-filling/remediation/catalog course.",
          "example": "true",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-010-completion-rollups",
              "title": "Completion Percent Is Ingested Earned XP Over A Curriculum Denominator, Never Invented",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-010-completion-rollups"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "progress_source_kind",
          "type": "TEXT enum",
          "nullability": "required for reportable progress rows",
          "meaning": "Which evidence source produced completion_percent.",
          "constraints": "Allowed values include app_reported_percent, xp_remaining, lesson_count, subject_aggregate, and main_course_aggregate.",
          "relationship": "Explains whether a row came directly from the app, an XP fallback, or an Analytics aggregate.",
          "invalidWhen": "Missing on a reportable completion row or used to hide MAP/RIT/R90-derived progress.",
          "example": "app_reported_percent",
          "sourceClass": "Alpha extension enum",
          "itds": [
            {
              "id": "aitd-010-completion-rollups",
              "title": "Completion Percent Is Ingested Earned XP Over A Curriculum Denominator, Never Invented",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-010-completion-rollups"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "window_start",
          "type": "DATE",
          "nullability": "required",
          "meaning": "Inclusive start date for Results evidence included in completion.",
          "constraints": "ISO date; half-open with window_end.",
          "relationship": "Defines the report interval.",
          "invalidWhen": "Uses source import time or current term label.",
          "example": "2026-01-01",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-010-completion-rollups",
              "title": "Completion Percent Is Ingested Earned XP Over A Curriculum Denominator, Never Invented",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-010-completion-rollups"
            }
          ]
        },
        {
          "name": "window_end",
          "type": "DATE",
          "nullability": "required",
          "meaning": "Exclusive end date for Results evidence included in completion.",
          "constraints": "ISO date; must be after window_start.",
          "relationship": "Defines the report interval.",
          "invalidWhen": "Treated as inclusive in raw queries.",
          "example": "2026-06-01",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-010-completion-rollups",
              "title": "Completion Percent Is Ingested Earned XP Over A Curriculum Denominator, Never Invented",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-010-completion-rollups"
            }
          ]
        },
        {
          "name": "xp_earned",
          "type": "NUMERIC(14,3)",
          "nullability": "nullable when progress_source_kind is app_reported_percent or an aggregate without XP evidence",
          "meaning": "Earned XP for this completion scope when the row uses the XP fallback.",
          "constraints": "Nonnegative when present; source corrections are reflected through quality_status/corrections before this value is reportable.",
          "relationship": "Fallback numerator for completion_percent; direct app percent rows may leave XP fields null.",
          "invalidWhen": "Computed by a consumer from active days, activity flags, passed result counts, or processed_facts rows.",
          "example": "null",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-010-completion-rollups",
              "title": "Completion Percent Is Ingested Earned XP Over A Curriculum Denominator, Never Invented",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-010-completion-rollups"
            },
            {
              "id": "aitd-001-report-source-ingestion",
              "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
            }
          ]
        },
        {
          "name": "xp_remaining",
          "type": "NUMERIC(14,3)",
          "nullability": "nullable when progress_source_kind is app_reported_percent or an aggregate without XP evidence",
          "meaning": "Remaining expected XP for this completion scope when the row uses the XP fallback.",
          "constraints": "Nonnegative when present; computed from Curriculum expected XP refs under denominator_policy_ref.",
          "relationship": "Fallback denominator complement for completion_percent. Direct app percent rows may leave XP fields null.",
          "invalidWhen": "A report walks Curriculum trees or hard-codes expected XP locally.",
          "example": "null",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-010-completion-rollups",
              "title": "Completion Percent Is Ingested Earned XP Over A Curriculum Denominator, Never Invented",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-010-completion-rollups"
            }
          ]
        },
        {
          "name": "completion_percent",
          "type": "NUMERIC(7,3)",
          "nullability": "nullable when no direct percent, XP denominator, lesson denominator, or source/policy is available",
          "meaning": "Report-ready completion measure for the scope.",
          "constraints": "Direct app percent wins. If absent, fallback formula is xp_earned / (xp_earned + xp_remaining) * 100. Normally 0 to 100; null requires null_reason.",
          "relationship": "The value dashboards and skill packs render.",
          "invalidWhen": "Consumer divides local counts, treats any activity as complete, returns 1-if-active, or derives progress from MAP/RIT/R90.",
          "example": "75.000",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-010-completion-rollups",
              "title": "Completion Percent Is Ingested Earned XP Over A Curriculum Denominator, Never Invented",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-010-completion-rollups"
            }
          ]
        },
        {
          "name": "denominator_policy_ref",
          "type": "TEXT",
          "nullability": "required",
          "meaning": "Policy that decides which Curriculum expected-XP refs belong in the remaining-XP denominator.",
          "constraints": "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.",
          "relationship": "Keeps Curriculum scope decisions on the surface.",
          "invalidWhen": "A report carries its own course tree filter or expected-XP lookup table.",
          "example": "alpha.policy.analytics.course_progress.v2026-06-15",
          "sourceClass": "Alpha extension reference",
          "itds": [
            {
              "id": "aitd-010-completion-rollups",
              "title": "Completion Percent Is Ingested Earned XP Over A Curriculum Denominator, Never Invented",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-010-completion-rollups"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "curriculum_scope_refs",
          "type": "JSONB",
          "nullability": "required",
          "meaning": "Compact ids/cursor for Curriculum refs used to form the denominator.",
          "constraints": "Refs/hashes only; never copies Curriculum trees or Content rows.",
          "relationship": "Authorized sourceRefs audit view.",
          "invalidWhen": "Duplicates course_component hierarchy in Analytics.",
          "example": "[\"course_component_01HT8ROOT\", \"kc_math_fraction_addition\"]",
          "sourceClass": "Alpha extension reference list",
          "itds": [
            {
              "id": "aitd-000-extend-only-storage",
              "title": "Analytics Is New Extend-Only Alpha Storage",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-000-extend-only-storage"
            },
            {
              "id": "aitd-010-completion-rollups",
              "title": "Completion Percent Is Ingested Earned XP Over A Curriculum Denominator, Never Invented",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-010-completion-rollups"
            },
            {
              "id": "aitd-102-axis-read-shape",
              "title": "API Axis: Read Shape",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-102-axis-read-shape"
            }
          ]
        },
        {
          "name": "source_import_id",
          "type": "TEXT",
          "nullability": "required for report-tile rows; nullable for purely derived event-axis rows",
          "meaning": "Analytics source-import receipt that proves which named report-source adapter produced this report-grade fact.",
          "constraints": "Must reference alpha.analytics_source_import for non-null Learning Report tile values; no literal or fixture value may be reportable without this provenance.",
          "relationship": "Many report-fact rows can reference one source import; detail/sourceRefs endpoints join here for adapter, source_table, and source_row_key_hashes.",
          "invalidWhen": "Missing on a non-null report-tile value, or replaced by copied raw reporting-DB columns.",
          "example": "imp_01HT8COMPLETION_2026_SPRING",
          "sourceClass": "Alpha extension provenance reference",
          "itds": [
            {
              "id": "aitd-001-report-source-ingestion",
              "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
            },
            {
              "id": "aitd-004-provenance-no-literals",
              "title": "Every Report Value Traces To An Ingested Source Row, Or Reads Null",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-004-provenance-no-literals"
            },
            {
              "id": "aitd-010-completion-rollups",
              "title": "Completion Percent Is Ingested Earned XP Over A Curriculum Denominator, Never Invented",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-010-completion-rollups"
            }
          ]
        },
        {
          "name": "null_reason",
          "type": "TEXT enum",
          "nullability": "required",
          "meaning": "Why completion_percent is null or not reportable.",
          "constraints": "Allowed values: null_reason enum; none means the metric is populated.",
          "relationship": "Prevents client fallback completion math.",
          "invalidWhen": "Null completion_percent with no typed explanation.",
          "example": "none",
          "enum": "null_reason",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-010-completion-rollups",
              "title": "Completion Percent Is Ingested Earned XP Over A Curriculum Denominator, Never Invented",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-010-completion-rollups"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "policy_ref",
          "type": "TEXT",
          "nullability": "required",
          "meaning": "Named policy/config version used to compute the measure or rollup.",
          "constraints": "Must point at alpha.policy.analytics.* or an inherited Curriculum/Results policy active for the source effective date.",
          "relationship": "Many Analytics facts can share one policy row; changing policy creates new calculation versions or corrections.",
          "invalidWhen": "A consumer hard-codes thresholds, school-day calendars, Growth X formulas, or completion denominators instead of using the policy ref.",
          "example": "alpha.policy.analytics.course_progress.v2026-06-15",
          "sourceClass": "Alpha extension reference",
          "itds": [
            {
              "id": "aitd-010-completion-rollups",
              "title": "Completion Percent Is Ingested Earned XP Over A Curriculum Denominator, Never Invented",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-010-completion-rollups"
            },
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            }
          ]
        },
        {
          "name": "quality_status",
          "type": "TEXT enum",
          "nullability": "required",
          "meaning": "Current materialization quality state for this fact.",
          "constraints": "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.",
          "relationship": "Used by raw/API convergence filters and source-ref audit views.",
          "invalidWhen": "Free-text status or hidden failures represented as HTTP 200 success.",
          "example": "ok",
          "enum": "quality_status",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-011-policy-and-enum-normalization",
              "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
            },
            {
              "id": "aitd-108-axis-error-envelope",
              "title": "API Axis: Error Envelope",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-108-axis-error-envelope"
            },
            {
              "id": "aitd-111-axis-privacy-retention",
              "title": "API Axis: Privacy And Retention",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-111-axis-privacy-retention"
            }
          ]
        },
        {
          "name": "calculation_version",
          "type": "INTEGER",
          "nullability": "required",
          "meaning": "Materializer calculation version for this fact shape.",
          "constraints": "Positive integer; starts at 1 and increments when policy/materializer logic intentionally changes.",
          "relationship": "Part of deterministic source_fact_key/idempotency for materializer writes.",
          "invalidWhen": "Omitted from replay keys or changed without a new policy/materializer decision.",
          "example": "1",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            },
            {
              "id": "aitd-105-axis-idempotency",
              "title": "API Axis: Idempotency Model",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-105-axis-idempotency"
            },
            {
              "id": "aitd-104-axis-concurrency",
              "title": "API Axis: Concurrency Model",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-104-axis-concurrency"
            }
          ]
        },
        {
          "name": "computed_at",
          "type": "TIMESTAMPTZ",
          "nullability": "required",
          "meaning": "When Analytics wrote this derived fact.",
          "constraints": "UTC timestamp with timezone; updated only by Analytics materializers.",
          "relationship": "Used for audit and source-ref subcollections, not for school-day grouping.",
          "invalidWhen": "Used as a substitute for the source event time, result effective time, or window boundaries.",
          "example": "2026-06-10T00:51:14Z",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-003-close-time-materialization",
              "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
            }
          ]
        },
        {
          "name": "modified_at",
          "type": "TIMESTAMPTZ",
          "nullability": "required",
          "meaning": "Last time the Analytics row changed for polling and modifiedSince queries.",
          "constraints": "UTC timestamp; list endpoints support modifiedSince against this field.",
          "relationship": "Supports poll plus modifiedSince eventing.",
          "invalidWhen": "Client-supplied or used as the business effective date.",
          "example": "2026-06-10T00:51:14Z",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-107-axis-eventing",
              "title": "API Axis: Eventing Model",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-107-axis-eventing"
            },
            {
              "id": "aitd-103-axis-query-model",
              "title": "API Axis: Query Model",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-103-axis-query-model"
            }
          ]
        },
        {
          "name": "superseded_at",
          "type": "TIMESTAMPTZ",
          "nullability": "nullable",
          "meaning": "When this row stopped being the current reportable version because of source correction, deletion, or recalculation.",
          "constraints": "Null means current; non-null rows are excluded from ordinary list reads unless includeSuperseded=true and authorized.",
          "relationship": "Preserves audit history without mutating source Events or Results.",
          "invalidWhen": "Used to hard-delete old rows or omitted on a correction that replaces a prior fact.",
          "example": "null",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-111-axis-privacy-retention",
              "title": "API Axis: Privacy And Retention",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-111-axis-privacy-retention"
            },
            {
              "id": "aitd-012-corrections-and-reversals",
              "title": "Corrections Are Signed Facts With Provenance",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-012-corrections-and-reversals"
            }
          ]
        },
        {
          "name": "source_deleted_at",
          "type": "TIMESTAMPTZ",
          "nullability": "nullable",
          "meaning": "When the source Event/Result became deleted or invalidated.",
          "constraints": "Null for live source rows; set from source tombstone/correction notifications.",
          "relationship": "Ordinary reads exclude tombstoned facts unless includeSuperseded=true and authorized.",
          "invalidWhen": "Used as a physical delete or ignored by raw-path report queries.",
          "example": "null",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-111-axis-privacy-retention",
              "title": "API Axis: Privacy And Retention",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-111-axis-privacy-retention"
            }
          ]
        }
      ],
      "plainLanguage": "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."
    },
    {
      "name": "alpha.analytics_source_import",
      "title": "Source Import",
      "kind": "Alpha extension provenance ledger",
      "grain": "One named-adapter ingestion run from one report-source producer.",
      "primaryKey": "import_id; idempotency key hash is unique per tenant for public imports.",
      "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.",
      "purpose": "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.",
      "metricChecks": [
        "all metric checks"
      ],
      "architecture": [
        {
          "id": "aitd-001-report-source-ingestion",
          "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
        },
        {
          "id": "aitd-004-provenance-no-literals",
          "title": "Every Report Value Traces To An Ingested Source Row, Or Reads Null",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-004-provenance-no-literals"
        },
        {
          "id": "aitd-101-axis-write-granularity",
          "title": "API Axis: Write Granularity",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-101-axis-write-granularity"
        },
        {
          "id": "aitd-105-axis-idempotency",
          "title": "API Axis: Idempotency Model",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-105-axis-idempotency"
        },
        {
          "id": "aitd-108-axis-error-envelope",
          "title": "API Axis: Error Envelope",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-108-axis-error-envelope"
        }
      ],
      "api": "POST /alpha/analytics/v1/source-imports/{adapter} and GET /alpha/analytics/v1/source-imports",
      "rawRule": "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.",
      "example": {
        "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"
      },
      "fields": [
        {
          "name": "import_id",
          "type": "TEXT",
          "nullability": "required",
          "meaning": "Stable id for this source import request.",
          "constraints": "Generated by platform; unique per tenant.",
          "relationship": "Primary key and detail endpoint id.",
          "invalidWhen": "Caller-supplied to overwrite a prior import.",
          "example": "imp_01HT8ANALYTICS",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-001-report-source-ingestion",
              "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
            }
          ]
        },
        {
          "name": "tenant_id",
          "type": "UUID",
          "nullability": "required",
          "meaning": "Tenant boundary for the derived fact.",
          "constraints": "Set from the JWT tenant claim or internal materializer context; never accepted from request body/query.",
          "relationship": "All raw-path queries must filter by tenant_id before joining, sorting, paging, or counting.",
          "invalidWhen": "Missing, caller-supplied in body/query, or mismatched with the JWT tenant claim.",
          "example": "7b0bb5d8-9a38-4a62-9fdc-9f8d2dc1a111",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-109-axis-tenant-routing",
              "title": "API Axis: Tenant Routing",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-109-axis-tenant-routing"
            },
            {
              "id": "aitd-106-axis-auth-shape",
              "title": "API Axis: Auth Shape",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-106-axis-auth-shape"
            }
          ]
        },
        {
          "name": "import_kind",
          "type": "TEXT enum",
          "nullability": "required",
          "meaning": "Which source/replay contract this batch follows.",
          "constraints": "Allowed values: import_kind enum.",
          "relationship": "Selects the server-side adapter/materializer.",
          "invalidWhen": "Generic upload with caller-provided normalized metric rows.",
          "example": "timeback-xp-time-accuracy",
          "enum": "import_kind",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-001-report-source-ingestion",
              "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
            },
            {
              "id": "aitd-101-axis-write-granularity",
              "title": "API Axis: Write Granularity",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-101-axis-write-granularity"
            }
          ]
        },
        {
          "name": "adapter_name",
          "type": "TEXT",
          "nullability": "required",
          "meaning": "Named server-side adapter that normalized this source batch.",
          "constraints": "Must match one approved adapter: timeback-xp-time-accuracy, timeback-map, timeback-grade-mastery, or timeback-completion, plus internal replay kinds where applicable.",
          "relationship": "Selects the source-table contract and normalization rules; no client-computed metric values are accepted.",
          "invalidWhen": "Generic import, free-text adapter names, or client-chosen formulas.",
          "example": "timeback-xp-time-accuracy",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-001-report-source-ingestion",
              "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
            },
            {
              "id": "aitd-101-axis-write-granularity",
              "title": "API Axis: Write Granularity",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-101-axis-write-granularity"
            }
          ]
        },
        {
          "name": "source_system",
          "type": "TEXT",
          "nullability": "required",
          "meaning": "Producer system the adapter read from.",
          "constraints": "Closed governed values for approved adapters: reporting, events, results, migration_reconcile.",
          "relationship": "Audits whether a fact came from report-source ingestion or internal derived replay.",
          "invalidWhen": "Raw database URL, credentials, or ungoverned free text.",
          "example": "reporting",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-001-report-source-ingestion",
              "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
            },
            {
              "id": "aitd-004-provenance-no-literals",
              "title": "Every Report Value Traces To An Ingested Source Row, Or Reads Null",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-004-provenance-no-literals"
            }
          ]
        },
        {
          "name": "source_table",
          "type": "TEXT",
          "nullability": "required for report-source adapters",
          "meaning": "Report-source table or producer collection read by the adapter.",
          "constraints": "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.",
          "relationship": "Explains which approved upstream source produced the report-grade fact without exposing raw rows.",
          "invalidWhen": "A source table is missing for a non-null report tile value.",
          "example": "processed_facts",
          "sourceClass": "Alpha extension provenance reference",
          "itds": [
            {
              "id": "aitd-001-report-source-ingestion",
              "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
            },
            {
              "id": "aitd-004-provenance-no-literals",
              "title": "Every Report Value Traces To An Ingested Source Row, Or Reads Null",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-004-provenance-no-literals"
            }
          ]
        },
        {
          "name": "status",
          "type": "TEXT enum",
          "nullability": "required",
          "meaning": "Processing state of the source import.",
          "constraints": "Allowed values: import_status enum.",
          "relationship": "A status of materialized or partially_rejected can be followed by reads of created Analytics facts.",
          "invalidWhen": "A validation or adapter rejection is represented as success without Problem details.",
          "example": "materialized",
          "enum": "import_status",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-001-report-source-ingestion",
              "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
            },
            {
              "id": "aitd-108-axis-error-envelope",
              "title": "API Axis: Error Envelope",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-108-axis-error-envelope"
            }
          ]
        },
        {
          "name": "idempotency_key_hash",
          "type": "TEXT",
          "nullability": "required for public POST imports",
          "meaning": "Hash of the Idempotency-Key header used for replay safety.",
          "constraints": "Stores a hash, never the raw key; replay with same hash and same body is a no-op, different body is analytics:idempotency_conflict.",
          "relationship": "Unique with tenant_id for source import writes.",
          "invalidWhen": "Missing on public writes or stored as plaintext secret material.",
          "example": "sha256:4b463adfe0...",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-105-axis-idempotency",
              "title": "API Axis: Idempotency Model",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-105-axis-idempotency"
            }
          ]
        },
        {
          "name": "source_batch_ref",
          "type": "TEXT",
          "nullability": "nullable",
          "meaning": "Operator/source identifier for the imported file, replay, or reconciliation run.",
          "constraints": "Opaque reference; no PII or raw row contents.",
          "relationship": "Audit linkage to migration/reconciliation artifacts.",
          "invalidWhen": "Contains raw source rows, emails, or credentials.",
          "example": "migration-2026-06-10-processed-facts-001",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-001-report-source-ingestion",
              "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
            },
            {
              "id": "aitd-111-axis-privacy-retention",
              "title": "API Axis: Privacy And Retention",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-111-axis-privacy-retention"
            }
          ]
        },
        {
          "name": "source_payload_hash",
          "type": "TEXT",
          "nullability": "required",
          "meaning": "Hash of the submitted source-shaped payload or replay source set.",
          "constraints": "SHA-256 or stronger; no raw payload copy in this table.",
          "relationship": "Supports idempotency and audit without storing PII rows.",
          "invalidWhen": "Raw processed_facts rows are stored here.",
          "example": "sha256:91f25d7371...",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-001-report-source-ingestion",
              "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
            },
            {
              "id": "aitd-111-axis-privacy-retention",
              "title": "API Axis: Privacy And Retention",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-111-axis-privacy-retention"
            }
          ]
        },
        {
          "name": "source_row_key_hashes",
          "type": "JSONB",
          "nullability": "required",
          "meaning": "Hashes of natural source-row keys included in the import.",
          "constraints": "Hashes/opaque keys only; no student names, emails, credentials, or raw source payloads.",
          "relationship": "Allows a non-null report value to prove it came from a resolvable source row while keeping public reads PII-safe.",
          "invalidWhen": "Missing on a report-source import that produced materialized rows, or stores raw source records.",
          "example": "[\"sha256:rowkey001...\", \"sha256:rowkey002...\"]",
          "sourceClass": "Alpha extension provenance reference",
          "itds": [
            {
              "id": "aitd-004-provenance-no-literals",
              "title": "Every Report Value Traces To An Ingested Source Row, Or Reads Null",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-004-provenance-no-literals"
            },
            {
              "id": "aitd-111-axis-privacy-retention",
              "title": "API Axis: Privacy And Retention",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-111-axis-privacy-retention"
            }
          ]
        },
        {
          "name": "submitted_row_count",
          "type": "INTEGER",
          "nullability": "required",
          "meaning": "Number of source-shaped rows submitted in the batch.",
          "constraints": "Nonnegative.",
          "relationship": "Top-level import audit, not a materialized-fact count.",
          "invalidWhen": "Used as proof that Analytics rows exist.",
          "example": "5000",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-001-report-source-ingestion",
              "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
            }
          ]
        },
        {
          "name": "accepted_row_count",
          "type": "INTEGER",
          "nullability": "required",
          "meaning": "Rows accepted by request validation and adapter mapping.",
          "constraints": "Nonnegative and not greater than submitted_row_count.",
          "relationship": "Accepted rows should materialize or have a documented source_missing or policy_pending state.",
          "invalidWhen": "Returned with HTTP 200 while validation actually failed.",
          "example": "4970",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-001-report-source-ingestion",
              "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
            },
            {
              "id": "aitd-108-axis-error-envelope",
              "title": "API Axis: Error Envelope",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-108-axis-error-envelope"
            }
          ]
        },
        {
          "name": "materialized_row_count",
          "type": "INTEGER",
          "nullability": "required",
          "meaning": "Rows that produced readable Analytics facts.",
          "constraints": "Nonnegative; successful nonempty imports must produce readable rows unless status explains otherwise.",
          "relationship": "Migration gate checks this count against the public Analytics reads.",
          "invalidWhen": "Zero after a claimed successful import of rows that should materialize.",
          "example": "4970",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-001-report-source-ingestion",
              "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
            },
            {
              "id": "aitd-110-axis-conformance-evidence",
              "title": "API Axis: Conformance Evidence",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-110-axis-conformance-evidence"
            }
          ]
        },
        {
          "name": "rejected_row_count",
          "type": "INTEGER",
          "nullability": "required",
          "meaning": "Rows rejected by validation or adapter mapping.",
          "constraints": "Nonnegative; submitted = accepted + rejected for completed imports.",
          "relationship": "Problem details summarize why rows could not materialize.",
          "invalidWhen": "Hidden in a success body without typed Problem codes.",
          "example": "30",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-001-report-source-ingestion",
              "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
            },
            {
              "id": "aitd-108-axis-error-envelope",
              "title": "API Axis: Error Envelope",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-108-axis-error-envelope"
            }
          ]
        },
        {
          "name": "problem_counts",
          "type": "JSONB",
          "nullability": "required",
          "meaning": "Counts of typed Problem codes produced by the import.",
          "constraints": "Keys must be stable analytics:* codes; values nonnegative integers.",
          "relationship": "Summarizes analytics:validation_failed, analytics:adapter_rejected, analytics:source_missing, analytics:policy_pending, and related errors.",
          "invalidWhen": "Free-text error blobs or HTTP 200 with embedded failure status.",
          "example": "{\"analytics:adapter_rejected\":30}",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-108-axis-error-envelope",
              "title": "API Axis: Error Envelope",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-108-axis-error-envelope"
            },
            {
              "id": "aitd-001-report-source-ingestion",
              "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
            }
          ]
        },
        {
          "name": "received_at",
          "type": "TIMESTAMPTZ",
          "nullability": "required",
          "meaning": "When the import request was received.",
          "constraints": "UTC timestamp.",
          "relationship": "Import audit timeline.",
          "invalidWhen": "Used as a business effective date for metrics.",
          "example": "2026-06-10T00:55:00Z",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-001-report-source-ingestion",
              "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
            }
          ]
        },
        {
          "name": "completed_at",
          "type": "TIMESTAMPTZ",
          "nullability": "nullable until processing completes",
          "meaning": "When import processing reached a terminal status.",
          "constraints": "UTC timestamp; null while status is received/running.",
          "relationship": "Import audit timeline.",
          "invalidWhen": "Set before materialization/rejection summary is final.",
          "example": "2026-06-10T00:56:12Z",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-001-report-source-ingestion",
              "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
            }
          ]
        },
        {
          "name": "modified_at",
          "type": "TIMESTAMPTZ",
          "nullability": "required",
          "meaning": "Last time the Analytics row changed for polling and modifiedSince queries.",
          "constraints": "UTC timestamp; list endpoints support modifiedSince against this field.",
          "relationship": "Supports poll plus modifiedSince eventing.",
          "invalidWhen": "Client-supplied or used as the business effective date.",
          "example": "2026-06-10T00:51:14Z",
          "sourceClass": "Alpha extension",
          "itds": [
            {
              "id": "aitd-107-axis-eventing",
              "title": "API Axis: Eventing Model",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-107-axis-eventing"
            },
            {
              "id": "aitd-103-axis-query-model",
              "title": "API Axis: Query Model",
              "status": "Accepted",
              "owner": "TimeBack Platform Architecture",
              "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-103-axis-query-model"
            }
          ]
        }
      ],
      "plainLanguage": "The audit receipt for every named report-source adapter run and reconciliation replay."
    }
  ],
  "policyDefinitions": [
    {
      "id": "time-classification",
      "policyRef": "alpha.policy.analytics.time_classification.v2026-06-10",
      "title": "Time Classification",
      "answers": "What makes a second active, inactive, or waste?",
      "controls": "Classifies closed Events time into fact_kind rows before any report reads it.",
      "plainLanguage": "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.",
      "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."
        ]
      ],
      "configFields": [
        [
          "eligible_event_types",
          "Caliper/TimebackProfile event types allowed to contribute seconds.",
          "[\"TimeSpentEvent\", \"ActivityEvent\", \"TimebackProfile.AntiPatternEvent\"]"
        ],
        [
          "active_source_rules",
          "Registry refs for apps/actions/content refs that qualify as active learning work.",
          "[\"caliper:TimeSpentEvent/SpentTime\", \"caliper:ActivityEvent/Completed\"] with real-student, subject/content/course ref, and foreground checks"
        ],
        [
          "inactive_rules",
          "Policy-owned idle, paused, missing-engagement, and background rules. Values live in alpha.policy, not in reports.",
          "{\"idle_after_seconds\":60, \"paused_actions\":[\"Paused\"], \"background_visibility\":[\"hidden\",\"background\"]}"
        ],
        [
          "waste_rules",
          "Policy-owned anti-pattern/gaming rules that create waste_seconds or negative XP evidence.",
          "{\"event_profile\":\"TimebackProfile\", \"anti_pattern_types\":[\"gaming\", \"cheating\", \"distraction\", \"counterproductive_work\"]}"
        ],
        [
          "subject_alias_policy_ref",
          "The subject normalization policy used before a fact is written.",
          "alpha.policy.analytics.subject_normalization.v2026-06-10"
        ]
      ],
      "currentValues": [
        [
          "eligible_event_tuples",
          "TimeSpentEvent/SpentTime; ActivityEvent/Completed; TimebackProfile.AntiPatternEvent/*.",
          "Other Caliper tuples can still exist in Events, but they contribute zero Analytics seconds unless this policy adds them. Fresh evidence also shows Event/Created, ToolUseEvent/Used, AnnotationEvent/Tagged, AssessmentItemEvent/*, SessionEvent/*, AssessmentEvent/*, FeedbackEvent/*, and GradeEvent/* as observed non-time sources."
        ],
        [
          "active_seconds rule",
          "Closed source event + resolved real student + reportable subject/content/course ref + foreground learning activity + no idle/waste override.",
          "A source tuple alone is not enough; the row must also resolve to the school-language refs Analytics reports on."
        ],
        [
          "foreground classifier",
          "Foreground means the source was the active learning app or activity at the event timestamp, not hidden/background/paused, and the event links to a content_id, course_id, kc_id, or subject_id accepted by policy.",
          "A foreground TimeSpentEvent/SpentTime contributes its reported duration up to the idle threshold; an ActivityEvent/Completed contributes active seconds only through its linked time source, not by inventing duration from a point event."
        ],
        [
          "zero-contribution observed tuples",
          "Event/Created; ToolUseEvent/Used; AnnotationEvent/Tagged; AssessmentItemEvent/Completed or Skipped; SessionEvent/LoggedIn or LoggedOut; AssessmentEvent/Started, Paused, or Submitted; FeedbackEvent/*; GradeEvent/Graded.",
          "These tuples can be source evidence, result evidence, or audit context, but they do not add active/inactive/waste seconds unless a future accepted policy version explicitly makes them duration-bearing."
        ],
        [
          "idle_after_seconds",
          "60",
          "After 60 consecutive seconds with no foreground learning activity inside an open time source, additional seconds are inactive_seconds until activity resumes or the source closes."
        ],
        [
          "paused/background rule",
          "Paused actions and browser/app visibility values hidden/background become inactive_seconds.",
          "Inactive time is reportable as present-but-not-working; it is not active work and it is not gaming by default."
        ],
        [
          "waste_seconds rule",
          "TimebackProfile anti-pattern kinds gaming, cheating, distraction, counterproductive_work.",
          "Waste seconds stay separate from inactive seconds and can also feed negative XP evidence through Results."
        ],
        [
          "subject fallback ladder",
          "1 source subject_id if canonical; 2 linked Content/Curriculum subject from content_id/course_id/kc_id; 3 app/source source-label normalization; 4 MAP/report source-label normalization when the report asks for MAP proxy subject; 5 source_unlinked or adapter_rejected.",
          "Reports never parse source app or subject strings; the materialized row either has a canonical subject_id or a typed rejection/null_reason."
        ],
        [
          "display rounding",
          "Store seconds as NUMERIC(14,3); display minutes as seconds / 60 rounded to 3 decimal places.",
          "Reports read display_active_minutes or active_minutes; they do not divide and round locally."
        ]
      ],
      "rawDbRule": "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.",
      "itds": [
        {
          "id": "aitd-005-time-facts-and-windows",
          "title": "Active, Inactive, And Waste Seconds Are Typed Derived Time Facts",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-005-time-facts-and-windows"
        },
        {
          "id": "aitd-011-policy-and-enum-normalization",
          "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
        },
        {
          "id": "aitd-012-corrections-and-reversals",
          "title": "Corrections Are Signed Facts With Provenance",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-012-corrections-and-reversals"
        }
      ]
    },
    {
      "id": "window",
      "policyRef": "alpha.policy.analytics.window.v2026-06-10",
      "title": "Window Boundaries",
      "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.",
      "plainLanguage": "Reports ask for named windows. Analytics has already chosen the start and end dates, so a dashboard does not parse labels like Winter 2026.",
      "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."
        ]
      ],
      "configFields": [
        [
          "school_timezone_source",
          "Where the school timezone comes from.",
          "People and Orgs school/org config"
        ],
        [
          "week_start_day",
          "First day of the platform week.",
          "Monday"
        ],
        [
          "academic_session_source",
          "Source of terms and school years.",
          "People and Orgs academicSession rows"
        ]
      ],
      "currentValues": [
        [
          "range convention",
          "[window_start, window_end)",
          "window_start is included; window_end is excluded for every day/week/term/school-year/custom rollup."
        ],
        [
          "week_start_day",
          "Monday",
          "Weekly rollups start Monday in the school timezone."
        ],
        [
          "timezone",
          "People and Orgs school/org timezone; tenant default only if the school timezone is policy_pending.",
          "A missing timezone does not authorize client-side timezone guessing."
        ],
        [
          "term/school_year source",
          "People and Orgs academic-session rows.",
          "Reports filter by canonical_term_id or stored window dates; they do not parse labels like Winter 2026."
        ]
      ],
      "rawDbRule": "Filter by window_kind, window_start, and window_end. Do not derive windows from modified_at, source_closed_at, or source term strings.",
      "itds": [
        {
          "id": "aitd-005-time-facts-and-windows",
          "title": "Active, Inactive, And Waste Seconds Are Typed Derived Time Facts",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-005-time-facts-and-windows"
        },
        {
          "id": "aitd-103-axis-query-model",
          "title": "API Axis: Query Model",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-103-axis-query-model"
        },
        {
          "id": "aitd-011-policy-and-enum-normalization",
          "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
        }
      ]
    },
    {
      "id": "subject-normalization",
      "policyRef": "alpha.policy.analytics.subject_normalization.v2026-06-10",
      "title": "Subject Normalization",
      "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.",
      "plainLanguage": "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.",
      "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."
        ]
      ],
      "configFields": [
        [
          "canonical_values",
          "Allowed subject_id values.",
          "math, reading, language, science, vocabulary, writing"
        ],
        [
          "source_label_normalization",
          "Source labels mapped at write time.",
          "FastMath->math when accepted by the adapter; Vocab/Vocabulary->vocabulary; Writing->writing; ELA/Language Arts->language"
        ],
        [
          "rejected_values",
          "Out-of-scope or test values that must not become new subjects.",
          "dev/screener junk, unknown source strings"
        ]
      ],
      "currentValues": [
        [
          "canonical subject_id values",
          "math, reading, language, science, vocabulary, writing",
          "Analytics rows use these values only."
        ],
        [
          "learning source-label normalization",
          "FastMath->math; ELA/Language Arts->language; Vocab/Vocabulary->vocabulary; Science->science.",
          "These normalization happens before a derived fact is written."
        ],
        [
          "MAP/report source-label normalization",
          "FastMath->math when accepted by the adapter; Vocab/Vocabulary->vocabulary; Writing->writing; ELA/Language Arts->language.",
          "Used when a MAP/goal/report question needs the Brainlift proxy subject rules rather than the activity subject itself."
        ],
        [
          "unknown source value",
          "analytics:adapter_rejected or quality_status=source_unlinked.",
          "A consumer never creates a new subject string to make a report work."
        ]
      ],
      "rawDbRule": "Use subject_id on alpha.analytics_* rows. Do not group by source subject/app strings or create local alias tables.",
      "itds": [
        {
          "id": "aitd-011-policy-and-enum-normalization",
          "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
        }
      ]
    },
    {
      "id": "school-day",
      "policyRef": "alpha.policy.school_day.v2026-06-10",
      "title": "School-Day Denominator",
      "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.",
      "plainLanguage": "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.",
      "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."
        ]
      ],
      "configFields": [
        [
          "calendar_source",
          "Calendar rows behind alpha.school_calendar.",
          "Ed-Fi CalendarDate.CalendarEvents, surfaced as the Alpha school calendar source for denominator materialization"
        ],
        [
          "reason_map",
          "Mapping from Ed-Fi CalendarEventDescriptor values to Alpha reasons.",
          "See the Calendar Code Map below."
        ],
        [
          "enrollment_source",
          "Effective-dated People and Orgs membership/enrollment rows.",
          "begin_date/end_date point-in-time rule"
        ],
        [
          "subject_assignment_source",
          "Course/test assignment evidence used for subject-specific denominators.",
          "Curriculum/Results refs"
        ]
      ],
      "currentValues": [
        [
          "launch/reportability requirement",
          "alpha.school_calendar coverage must exist before Learning Report time-commitment rows are complete.",
          "A source_missing row is a blocking repair signal. It is not a permanent answer and does not authorize client-side denominator math."
        ],
        [
          "ratified denominator",
          "days the student was ENROLLED and school was IN SESSION.",
          "Enrollment begin/end bound the denominator; the student's school calendar is authoritative; MAP testing days are excluded; per-subject rows count a day only if the student had a subject assignment that day."
        ],
        [
          "is_school_day",
          "reason=instructional only.",
          "Every other Alpha reason is excluded unless a future accepted policy version explicitly maps a governed value to instructional."
        ],
        [
          "excluded reasons",
          "weekend, teacher_workshop, holiday_break, nwea_map_testing, other.",
          "NWEA MAP testing days are not school days for this time-commitment denominator."
        ],
        [
          "MAP testing exclusion",
          "3 terms x 4 days = 12 excluded MAP days per school year when calendar coverage exists.",
          "The actual dates come from alpha.school_calendar, not a hard-coded date list."
        ],
        [
          "enrollment intersection",
          "begin_date NULL is excluded; end_date NULL remains active for dates on/after begin_date.",
          "Same point-in-time rule as People and Orgs."
        ],
        [
          "subject denominator",
          "A date counts for a subject only when the student has a subject course, test, or assignment on that date.",
          "All-subject rows use subject_id null and do not require subject assignment."
        ],
        [
          "legacy panel divergence",
          "Documented divergence, not the platform target.",
          "Legacy values are not reproducible from source because the old panel applied an undocumented filter. Analytics exposes one source-backed denominator under alpha.policy.school_day.v2026-06-10."
        ],
        [
          "forbidden fallback",
          "processed_facts active dates, attendance dates, and raw calendar-day counts are not school-day denominators.",
          "If calendar coverage is missing, emit null/source_missing for repair/audit; do not fabricate enrolled_school_day_count or excluded_school_day_count."
        ]
      ],
      "rawDbRule": "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.",
      "itds": [
        {
          "id": "aitd-006-school-day-minutes",
          "title": "Minutes Per Enrolled School Day Uses The Alpha School Calendar",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-006-school-day-minutes"
        },
        {
          "id": "aitd-011-policy-and-enum-normalization",
          "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
        }
      ]
    },
    {
      "id": "xp-rollup",
      "policyRef": "alpha.policy.analytics.xp_rollup.v2026-06-10",
      "title": "XP Rollup",
      "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.",
      "plainLanguage": "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.",
      "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."
        ]
      ],
      "configFields": [
        [
          "report_source_adapter",
          "Named source adapter for report XP values.",
          "timeback-xp-time-accuracy over reporting.processed_facts"
        ],
        [
          "ledger_source",
          "Canonical source for awarded XP audit refs when present.",
          "Results alpha.xp_ledger"
        ],
        [
          "window_policy_ref",
          "Window policy used for grouping.",
          "alpha.policy.analytics.window.v2026-06-10"
        ],
        [
          "goal_policy_ref",
          "Policy/Curriculum source for daily XP goals and school-day denominator.",
          "alpha.policy.analytics.xp_goal_percent.v1 plus Curriculum expected_xp refs"
        ],
        [
          "include_reversals",
          "Whether signed reversal rows are included in ordinary net totals.",
          "true under current Analytics policy"
        ]
      ],
      "currentValues": [
        [
          "report source",
          "timeback-xp-time-accuracy adapter over reporting.processed_facts.",
          "Naive SUM(processed_facts.xp_earned) reproduced only 1 of 6 report subjects in architecture grounding, so the adapter is the source of the report-grade value."
        ],
        [
          "ledger_source",
          "Results alpha.xp_ledger for audit refs where a platform ledger row exists.",
          "The Learning Report tile reads xp_total from Analytics, not a consumer ledger sum."
        ],
        [
          "included quality statuses",
          "ok, corrected, reversed when signed into the net total.",
          "source_missing, source_unlinked, policy_pending, and adapter_rejected are audit/findings, not ordinary display totals."
        ],
        [
          "quality_status=ok",
          "Include in positive_xp or negative_xp according to the signed XP value.",
          "Ordinary report rows include ok."
        ],
        [
          "quality_status=corrected",
          "Include the current corrected signed value; exclude the superseded row by superseded_at/source_deleted_at current-row filters.",
          "Corrections are reportable only through the current Analytics row."
        ],
        [
          "quality_status=reversed",
          "Include only as a signed reversal contribution when the row carries reversal_count or a negative signed XP delta.",
          "A reversal reduces net_xp; it does not erase the audit trail."
        ],
        [
          "quality_status source_missing/source_unlinked/policy_pending/adapter_rejected",
          "Exclude from display totals; expose through import/problem/audit reads.",
          "These statuses explain why no reportable XP total could be materialized."
        ],
        [
          "positive_xp",
          "Positive contribution audit subtotal from the adapter/ledger refs.",
          "Nonnegative by definition; supports explanations but is not a client formula source."
        ],
        [
          "negative_xp",
          "Penalty/reversal audit subtotal from the adapter/ledger refs.",
          "Kept zero-or-negative; never clamped away by a report."
        ],
        [
          "xp_total",
          "The report-ready XP total the Learning Report renders.",
          "Non-null values require source_import_id provenance under aitd-004."
        ],
        [
          "denominator source",
          "alpha.analytics_school_day_minutes / alpha.school_calendar school-day denominator.",
          "XP goal fields use the same materialized enrolled_school_day_count as time commitment; a source_missing denominator is a repair state, not an app-side fallback."
        ],
        [
          "canonical XP percent policy",
          "alpha.policy.analytics.xp_goal_percent.v1.",
          "There is one rule only: xp_goal_percent = total_xp_earned / (daily_xp_goal x enrolled_school_days) * 100. The result is uncapped when the denominator is present."
        ],
        [
          "XP denominator",
          "daily_xp_goal x enrolled_school_day_count.",
          "enrolled_school_day_count uses the ratified school-day rule: enrolled and school-in-session days, MAP days excluded, per-subject days only with a subject assignment. If that count is null/source_missing, xp_goal_percent is also null/source_missing."
        ],
        [
          "xp_goal and remaining",
          "xp_goal = daily_xp_goal x enrolled_school_day_count; xp_remaining = max(xp_goal - xp_total, 0) only when xp_goal is present; xp_goal_percent is NOT capped by xp_remaining.",
          "Over-goal rows are valid when the shared school-day denominator is present. The worked example is intentionally above 100% so readers do not cap the policy."
        ],
        [
          "deprecated alias",
          "xp_completion_percent, when present for compatibility, equals xp_goal_percent exactly and is also uncapped.",
          "It must never mean capped completion, captured percent, or ordinary 0-to-100 course completion."
        ],
        [
          "worked over-goal XP example status",
          "reportable Analytics rows may exceed 100%.",
          "The example row shows xp_goal_percent above 100 because the policy is uncapped. This is the canonical report path once the school-day denominator is materialized."
        ]
      ],
      "rawDbRule": "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.",
      "itds": [
        {
          "id": "aitd-007-xp-rollups",
          "title": "XP Totals, Goal, Remaining, And Completion Percent Are Ingested Report Facts",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-007-xp-rollups"
        },
        {
          "id": "aitd-001-report-source-ingestion",
          "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
        },
        {
          "id": "aitd-004-provenance-no-literals",
          "title": "Every Report Value Traces To An Ingested Source Row, Or Reads Null",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-004-provenance-no-literals"
        },
        {
          "id": "aitd-012-corrections-and-reversals",
          "title": "Corrections Are Signed Facts With Provenance",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-012-corrections-and-reversals"
        }
      ]
    },
    {
      "id": "xp-goal-percent",
      "policyRef": "alpha.policy.analytics.xp_goal_percent.v1",
      "title": "XP Goal Percent",
      "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.",
      "plainLanguage": "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.",
      "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."
        ]
      ],
      "configFields": [
        [
          "daily_xp_goal_source",
          "Source of the daily XP target.",
          "alpha.policy.analytics.xp_goal_percent.v1 / Curriculum Policy"
        ],
        [
          "school_day_source",
          "Source of enrolled_school_days.",
          "alpha.policy.school_day.v2026-06-10"
        ],
        [
          "cap_behavior",
          "Whether the percent is capped.",
          "uncapped"
        ]
      ],
      "currentValues": [
        [
          "denominator source",
          "enrolled_school_day_count stored by Analytics under alpha.policy.school_day.",
          "The same school-calendar denominator is used for time commitment and XP goal percent. Reports read it; they do not count active days, weekdays, or attendance rows."
        ],
        [
          "formula",
          "xp_goal_percent = total_xp_earned / (daily_xp_goal x enrolled_school_days) x 100.",
          "total_xp_earned is xp_total; the denominator is daily_xp_goal multiplied by enrolled_school_day_count. Apply only when enrolled_school_day_count is present."
        ],
        [
          "cap behavior",
          "uncapped when populated.",
          "Calendar-backed Analytics rows may legitimately remain above 100 instead of being capped. source_missing is only a repair state for uncovered school/window coverage, not the ordinary XP-goal report path."
        ],
        [
          "invalid capped variant",
          "rejected.",
          "No field, website, implementation, report, or skill pack may define a captured/capped 0-to-100 XP percent variant for this tile."
        ],
        [
          "null behavior",
          "null_reason=policy_pending, source_missing, or no_school_days.",
          "If daily_xp_goal or enrolled_school_day_count is missing, do not substitute active days or return 100%; treat the row as not reportable until repaired."
        ]
      ],
      "rawDbRule": "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.",
      "itds": [
        {
          "id": "aitd-007-xp-rollups",
          "title": "XP Totals, Goal, Remaining, And Completion Percent Are Ingested Report Facts",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-007-xp-rollups"
        },
        {
          "id": "aitd-006-school-day-minutes",
          "title": "Minutes Per Enrolled School Day Uses The Alpha School Calendar",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-006-school-day-minutes"
        },
        {
          "id": "aitd-011-policy-and-enum-normalization",
          "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
        }
      ]
    },
    {
      "id": "xp-expected-minute",
      "policyRef": "alpha.policy.analytics.xp_expected_minute.v2026-06-14",
      "title": "XP Expected-Minute Unit",
      "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.",
      "plainLanguage": "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.",
      "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."
        ]
      ],
      "configFields": [
        [
          "xp_per_expected_minute",
          "How many XP equal one expected minute.",
          "1"
        ],
        [
          "xp_per_hour",
          "How many XP equal one expected hour.",
          "60"
        ],
        [
          "unit_owner",
          "Where the convention lives.",
          "alpha.policy.analytics.xp_expected_minute.v2026-06-14"
        ],
        [
          "applies_to",
          "Fields that use this unit for GOALS effort projection.",
          "expected_xp, daily_xp_goal, xp_remaining, xp_unit.*, effort.*"
        ]
      ],
      "currentValues": [
        [
          "xp_per_expected_minute",
          "1",
          "1 XP equals 1 expected minute for GOALS and target-date effort reads."
        ],
        [
          "xp_per_hour",
          "60",
          "60 XP equals one expected hour."
        ],
        [
          "hours formula",
          "hours_remaining = expected_minutes_remaining / 60.",
          "Analytics returns the value; GOALS does not keep a private XP_PER_HOUR constant."
        ],
        [
          "school-day pacing formula",
          "required_hours_per_school_day_to_target_date = hours_remaining / school_days_until_target_date.",
          "Null when targetDate is absent or the target window has zero instructional days."
        ],
        [
          "finish-date formula",
          "school_days_needed_at_hours_per_school_day = ceil(hours_remaining / hoursPerSchoolDay).",
          "target_date_at_hours_per_school_day is the returned instructional date at that ordinal, or null when the requested endDate window is too short."
        ]
      ],
      "rawDbRule": "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.",
      "itds": [
        {
          "id": "aitd-018-goals-school-days-remaining",
          "title": "GOALS School-Days-Remaining Read And XP Expected-Minute Unit Live On Analytics",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-018-goals-school-days-remaining"
        },
        {
          "id": "aitd-007-xp-rollups",
          "title": "XP Totals, Goal, Remaining, And Completion Percent Are Ingested Report Facts",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-007-xp-rollups"
        },
        {
          "id": "aitd-011-policy-and-enum-normalization",
          "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
        }
      ]
    },
    {
      "id": "accuracy",
      "policyRef": "alpha.policy.analytics.accuracy.v2026-06-12",
      "title": "Accuracy (P7)",
      "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.",
      "plainLanguage": "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.",
      "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."
        ]
      ],
      "configFields": [
        [
          "report_source_adapter",
          "Named source adapter for report Accuracy values.",
          "timeback-xp-time-accuracy over reporting.processed_facts"
        ],
        [
          "question_columns",
          "Source-shaped columns the adapter accepts.",
          "total_questions, correct_questions, subject, date, app, source, score_type"
        ],
        [
          "include_source_rules",
          "Policy-owned app/source/score_type rules for whether a processed_facts row contributes to Accuracy.",
          "reportable learning work; test/dev/internal rows excluded by policy"
        ],
        [
          "rounding",
          "Display precision for the stored percent.",
          "3 decimal places"
        ]
      ],
      "currentValues": [
        [
          "report source",
          "timeback-xp-time-accuracy adapter over reporting.processed_facts.",
          "The same adapter that owns XP and Time Commitment also owns Accuracy because the live report source carries total_questions and correct_questions."
        ],
        [
          "formula",
          "accuracy_percent = correct_question_count / total_question_count x 100.",
          "Analytics stores the percent. Consumers read it and never recompute from processed_facts."
        ],
        [
          "denominator zero",
          "accuracy_percent=null and null_reason=no_questions.",
          "A report shows unavailable/no attempts instead of pretending the student had 0% or 100% accuracy."
        ],
        [
          "question filters",
          "Only rows accepted by the adapter under policy_ref count.",
          "Apps do not keep local app/source/score_type allowlists."
        ],
        [
          "source provenance",
          "Non-null values require source_import_id.",
          "The report can audit which source-shaped import produced the Accuracy row."
        ]
      ],
      "rawDbRule": "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.",
      "itds": [
        {
          "id": "aitd-001-report-source-ingestion",
          "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
        },
        {
          "id": "aitd-004-provenance-no-literals",
          "title": "Every Report Value Traces To An Ingested Source Row, Or Reads Null",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-004-provenance-no-literals"
        },
        {
          "id": "aitd-011-policy-and-enum-normalization",
          "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
        }
      ]
    },
    {
      "id": "attempt-count",
      "policyRef": "alpha.policy.analytics.attempt_count.v2026-07-08",
      "title": "Attempt Count Rollup",
      "answers": "How many governed player attempts occurred in a reporting window?",
      "controls": "For Events question_answered extensions, sums the maximum governed attempt_count per question interaction, falling back to attempt_ordinal when needed. Source-shaped imports may provide already-aggregated attempt_count rows.",
      "plainLanguage": "Analytics owns the attempt-count report fact. Apps do not count local button presses or infer attempts from answer history.",
      "definitions": [
        [
          "attempt_count",
          "Total governed attempts in the window."
        ],
        [
          "max_attempt_ordinal",
          "Largest governed attempt ordinal in the window."
        ]
      ],
      "currentValues": [
        [
          "source namespace",
          "https://platform3.timeback.com/player/attempt_count and /attempt_ordinal.",
          "Events validates these keys before Analytics rolls them up."
        ]
      ],
      "rawDbRule": "Read alpha.analytics_attempt_rollup current rows; do not parse Events extensions at report read time.",
      "itds": [
        {
          "id": "aitd-001-report-source-ingestion",
          "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
        },
        {
          "id": "aitd-003-close-time-materialization",
          "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
        },
        {
          "id": "aitd-011-policy-and-enum-normalization",
          "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
        }
      ]
    },
    {
      "id": "response-latency",
      "policyRef": "alpha.policy.analytics.response_latency.v2026-07-08",
      "title": "Response Latency Rollup",
      "answers": "How fast or slow were governed player responses?",
      "controls": "Aggregates governed player response_time_ms in milliseconds from Events question_answered extensions or source-shaped imports.",
      "plainLanguage": "Analytics owns the latency report fact so AP scheduling and reports share one millisecond definition.",
      "definitions": [
        [
          "response_time_ms",
          "Milliseconds from question render to response submit."
        ],
        [
          "response_time_ms_avg",
          "Average milliseconds across responses in the window."
        ]
      ],
      "currentValues": [
        [
          "source namespace",
          "https://platform3.timeback.com/player/response_time_ms.",
          "Events validates this key before Analytics rolls it up."
        ]
      ],
      "rawDbRule": "Read alpha.analytics_response_latency_rollup current rows; do not compute response latency in an app.",
      "itds": [
        {
          "id": "aitd-001-report-source-ingestion",
          "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
        },
        {
          "id": "aitd-003-close-time-materialization",
          "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
        },
        {
          "id": "aitd-011-policy-and-enum-normalization",
          "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
        }
      ]
    },
    {
      "id": "hint-usage",
      "policyRef": "alpha.policy.analytics.hint_usage.v2026-07-08",
      "title": "Hint Usage Rollup",
      "answers": "How often did governed player hints get requested, viewed, or used?",
      "controls": "Aggregates governed player hint_usage requested_count, viewed_count, and used evidence from Events question_answered extensions or source-shaped imports.",
      "plainLanguage": "Analytics owns hint usage so producers do not fragment requested/viewed/used counts.",
      "definitions": [
        [
          "hint_request_count",
          "Requested hint count."
        ],
        [
          "hint_view_count",
          "Viewed hint count."
        ],
        [
          "hint_used_count",
          "Used-hint observation count."
        ]
      ],
      "currentValues": [
        [
          "source namespace",
          "https://platform3.timeback.com/player/hint_usage.",
          "Events validates this key before Analytics rolls it up."
        ]
      ],
      "rawDbRule": "Read alpha.analytics_hint_usage_rollup current rows; do not count hint UI state locally.",
      "itds": [
        {
          "id": "aitd-001-report-source-ingestion",
          "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
        },
        {
          "id": "aitd-003-close-time-materialization",
          "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
        },
        {
          "id": "aitd-011-policy-and-enum-normalization",
          "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
        }
      ]
    },
    {
      "id": "mastery-delta",
      "policyRef": "alpha.policy.results.mastery_state.v2026-06-10",
      "title": "Mastery Delta",
      "answers": "Which mastery state changes are reportable?",
      "controls": "Defines which Results state dimensions create Analytics delta rows and how null/blocked transitions are represented.",
      "plainLanguage": "Analytics shows what changed. Results still owns the current mastery state.",
      "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."
        ]
      ],
      "configFields": [
        [
          "state_source",
          "Current/state history source.",
          "Results alpha.student_kc_state"
        ],
        [
          "evidence_source",
          "Results/KC evidence refs explaining the transition.",
          "alpha.result_kc_evidence"
        ],
        [
          "blocked_transition_handling",
          "How missing source/policy evidence is surfaced.",
          "transition_kind=blocked plus quality_status/null_reason"
        ]
      ],
      "currentValues": [
        [
          "state dimensions",
          "initial_mastery, current_retention, durable_mastery, fluency_state, next_due_at.",
          "Closed list for this policy version; there is no \"other per policy\" dimension on Analytics rows."
        ],
        [
          "mastery_cutoff_ref",
          "alpha.policy.mastery_cutoff:2026-06-03 = 89.5%, displayed as >=90%.",
          "Owned by Results/Policy; Analytics records the delta created by that settled Results state."
        ],
        [
          "retention_model_ref",
          "alpha.policy.retention_model:2026-06-03 = FIRe-style, exposed output next_due_at.",
          "Results owns retention/decay math. Analytics shows previous_value, new_value, delta_value, transition_kind, and effective_at."
        ],
        [
          "initial_mastery rule",
          "A Results state transition crossing the 89.5% acquisition cutoff writes state_dimension=initial_mastery and transition_kind=acquired.",
          "Analytics records the transition; Results remains the source of truth for the state."
        ],
        [
          "durable_mastery rule",
          "A durable Results mastery state change writes state_dimension=durable_mastery with previous_value, new_value, and delta_value.",
          "Reports read the delta row instead of recomputing mastery from attempts."
        ],
        [
          "current_retention rule",
          "A Results FIRe retention output change writes state_dimension=current_retention; decreases use transition_kind=decayed and increases use improved or corrected as appropriate.",
          "The curve coefficients stay in Results/Policy; Analytics stores the observable change."
        ],
        [
          "next_due_at rule",
          "A Results retention schedule change writes state_dimension=next_due_at with transition_kind=review_due when the due date becomes actionable.",
          "A Learning Report can show what became due without running a retention scheduler."
        ],
        [
          "fluency_state rule",
          "A Results fluency/automaticity state change writes state_dimension=fluency_state and transition_kind=fluency_changed.",
          "Fluency remains a state output, not a client-side speed calculation."
        ],
        [
          "FIRe summary",
          "Results policy emits current_retention and next_due_at from the FIRe-style retention model; Analytics materializes only the before/after values and transition kind.",
          "The data dictionary intentionally does not publish curve coefficients as report logic."
        ],
        [
          "decay visibility",
          "current_retention changes are materialized as state_dimension=current_retention; due-date changes as state_dimension=next_due_at.",
          "A parent can see that retention decayed or a review became due without a skill pack running the decay curve."
        ],
        [
          "blocked transition",
          "transition_kind=blocked and quality_status/source null_reason explain missing evidence.",
          "No guessed mastery delta is written."
        ]
      ],
      "rawDbRule": "Read alpha.analytics_mastery_delta for changes between dates. Do not recompute mastery, decay, HMG, or review due dates from attempts.",
      "itds": [
        {
          "id": "aitd-008-mastery-and-grade-levels",
          "title": "Grade Levels Mastered Are Ingested; Mastery Deltas Read Results State",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-008-mastery-and-grade-levels"
        },
        {
          "id": "aitd-011-policy-and-enum-normalization",
          "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
        }
      ]
    },
    {
      "id": "map-growth",
      "policyRef": "alpha.policy.analytics.map_growth.v2026-06-10",
      "title": "MAP Growth",
      "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.",
      "plainLanguage": "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.",
      "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."
        ]
      ],
      "configFields": [
        [
          "test_of_record_source",
          "Results row that already applied the MAP test-of-record rule.",
          "alpha.map_score"
        ],
        [
          "report_source_adapter",
          "Named source adapter for MAP report values.",
          "timeback-map over reporting.hp_map_results"
        ],
        [
          "learning_report_growth_window",
          "Window used by the parent Learning Report \"Growth Percentile (vs 1yr ago)\" panel.",
          "winter_to_winter"
        ],
        [
          "growth_x_target",
          "Target multiplier used by on_track.",
          "2.0000 under current Alpha commitment, read from policy"
        ],
        [
          "norms_sets",
          "Allowed NWEA norms families.",
          "2020, 2025"
        ]
      ],
      "currentValues": [
        [
          "allowed norms_set",
          "2020, 2025.",
          "Every MAP row carries the selected norms family; reports regenerate under a different norms set by changing this filter."
        ],
        [
          "growth_window values",
          "fall_to_fall, fall_to_winter, winter_to_spring, fall_to_spring, winter_to_winter, spring_to_spring, baseline_to_current, term, custom.",
          "Analytics stores the typed window; clients do not switch over NWEA wide columns."
        ],
        [
          "Learning Report MAP window",
          "Use growth_window=winter_to_winter for \"Growth Percentile (vs 1yr ago)\".",
          "The old fall_to_winter window is a within-year window and does not reproduce the report panel."
        ],
        [
          "Learning Report source mapping",
          "RIT = testritscore; achievement_percentile = testpercentile; growth_percentile = wintertowinterconditionalgrowthpercentile; observed_growth = wintertowinterobservedgrowth; projected_growth = wintertowinterprojectedgrowth; typical_growth = typicalwintertowintergrowth; growth_x = observed_growth / projected_growth.",
          "These source columns are normalized by the timeback-map adapter and materialized by Analytics; reports never read hp_map_results directly."
        ],
        [
          "timeback-map source-shaped import",
          "Accept the FULL reporting.hp_map_results source row.",
          "The adapter accepts all hp_map_results columns, including wintertowinter*, fall/winter/spring growth-window blocks and goal1..goal8 blocks. Unknown extra columns are ignored, not rejected; only missing required columns or unresolved identities produce typed Problems."
        ],
        [
          "Real report-source grounding",
          "Architecture evidence found naive observed/typical reproduced only 2 of 4 subjects; observed/projected is the pinned Growth X rule.",
          "Captured in source/evidence/report-source-grounding.json and enforced by AITD-009."
        ],
        [
          "Growth X formula",
          "growth_x = observed_growth / projected_growth.",
          "The surface stores the result. Consumers read growth_x; they do not ship the formula as report logic."
        ],
        [
          "growth_x_target",
          "2.0000.",
          "Current Alpha commitment: twice typical growth."
        ],
        [
          "on_track rule",
          "on_track = growth_x >= growth_x_target when both values are present.",
          "Null growth_x or target yields on_track=null with null_reason."
        ],
        [
          "norms source",
          "Analytics readable reference tables alpha.analytics_norms_achievement and alpha.analytics_r90_table, with provenance to NWEAMap NormsReferenceData.",
          "No private norms/R90 table belongs in the skill pack or report. Apps call the surface or read the surface versioned resources."
        ]
      ],
      "rawDbRule": "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.",
      "itds": [
        {
          "id": "aitd-009-map-growth-rollups",
          "title": "MAP RIT And Growth X Are Ingested From hp_map_results, Deduped, And Norms-Calculated",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-009-map-growth-rollups"
        },
        {
          "id": "aitd-011-policy-and-enum-normalization",
          "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
        }
      ]
    },
    {
      "id": "scale-translation",
      "policyRef": "alpha.policy.analytics.scale_translation.v2026-06-12",
      "title": "MAP Scale Translation",
      "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.",
      "plainLanguage": "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.",
      "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."
        ]
      ],
      "configFields": [
        [
          "norms_resource",
          "Readable NWEA achievement-status norms table.",
          "alpha.analytics_norms_achievement"
        ],
        [
          "r90_resource",
          "Readable RIT50/RIT90/effective-grade table.",
          "alpha.analytics_r90_table"
        ],
        [
          "version_key",
          "Cache/reproducibility key.",
          "norms_set + table_version"
        ],
        [
          "percentile_rit_rule",
          "How percentile<->RIT is answered.",
          "Use the published mean_rit and sd_rit row for (norms_set, subject, grade, season, role) and the documented normal-model translation."
        ],
        [
          "rit_to_grade_lookup_rule",
          "How RIT-to-grade requests are answered.",
          "Filter to the current R90 table version, then use the PowerPath RIT-to-grade row for the requested RIT. If no such row exists, return source_missing; never use grade2rit.csv, interpolate, clamp upward, or extrapolate."
        ]
      ],
      "currentValues": [
        [
          "serving home",
          "analytics/alpha.",
          "Per ruling R1, Analytics serves Alpha-side norms/R90 resources; NWEAMap 1EdTech remains the raw mirror and provenance source."
        ],
        [
          "allowed norms_set",
          "2020, 2025.",
          "The same GOALS or Learning Report query can be rerun under either norms family by flipping norms_set."
        ],
        [
          "current norms table_version",
          "analytics.norms.achievement.v2026-06-12",
          "The NWEA achievement norms table version used by current percentile<->RIT reads."
        ],
        [
          "current R90 table_version",
          "analytics.rit_to_grade.powerpath.v2026-06-15",
          "The PowerPath RIT-to-grade table version required for current raw/API convergence; raw readers do not infer current by sorting names."
        ],
        [
          "R90 one-version rule",
          "alpha.analytics_r90_table currently holds exactly one live observed RIT-to-grade table_version.",
          "The only live observed-RIT version is analytics.rit_to_grade.powerpath.v2026-06-15; grade2rit.csv is forecast-only and is not a historical observed-RIT target."
        ],
        [
          "percentile_to_rit rule",
          "Read mean_rit and sd_rit from alpha.analytics_norms_achievement, then convert percentile to a z-score and RIT under the surface calculator.",
          "No app ships a norms table or private calculator."
        ],
        [
          "rit_to_percentile rule",
          "Use the same alpha.analytics_norms_achievement row and normal model in reverse.",
          "The response carries mean_rit, sd_rit, calculator_version, and norms_set so the answer is inspectable."
        ],
        [
          "rit_to_r90 rule",
          "Read alpha.analytics_r90_table where table_version='analytics.rit_to_grade.powerpath.v2026-06-15' and table_subject_id matches the subject and rit_score equals the requested RIT.",
          "This is the PowerPath observed RIT-to-grade lookup. Missing rows return source_missing instead of a fabricated grade."
        ],
        [
          "R90 honesty rule",
          "R90 rows use extend_kind=alpha_extrapolation and r90_method_ref.",
          "The row exposes that R90/effective-grade is an Alpha/PowerPath mapping, not an NWEA-published value."
        ],
        [
          "cache behavior",
          "Responses include table_version; translation responses include calculator_version; HTTP cache-control is no-store.",
          "Clients may cache by table_version as the cache key, but must not maintain or edit a private copy."
        ],
        [
          "missing table behavior",
          "Invalid subjects/table parameters return analytics:validation_failed field codes; R90 requests with no PowerPath source row return source_missing.",
          "A missing norms_set/table_version never falls back to a nearby version."
        ]
      ],
      "rawDbRule": "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.",
      "itds": [
        {
          "id": "aitd-015-norms-r90-readable-resources",
          "title": "NWEA Norms And NWEAMAP R90 Are Versioned, Readable Surface Reference Tables",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-015-norms-r90-readable-resources"
        },
        {
          "id": "aitd-016-scale-translation-apis",
          "title": "Percentile<->RIT And RIT->R90/Grade Are Server-Side Surface Translations",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-016-scale-translation-apis"
        },
        {
          "id": "aitd-017-r90-version-supersession",
          "title": "RIT-to-grade Table Versioning: PowerPath v2026-06-15 Is The Current Version, And One Named Config Picks It For Every Path",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-017-r90-version-supersession"
        },
        {
          "id": "aitd-011-policy-and-enum-normalization",
          "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
        }
      ]
    },
    {
      "id": "r90-method",
      "policyRef": "alpha.policy.analytics.r90_method.v2026-06-12",
      "title": "R90 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.",
      "plainLanguage": "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.",
      "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."
        ]
      ],
      "configFields": [
        [
          "source_resource",
          "Readable surface resource using this method.",
          "alpha.analytics_r90_table"
        ],
        [
          "published_anchor_source",
          "Source of the current R90 grade-position rows.",
          "powerpath:/powerpath/rit-to-grade"
        ],
        [
          "owner_module",
          "Platform module that owns the PowerPath RIT-to-grade master.",
          "nweamap"
        ],
        [
          "extend_kind",
          "Honesty marker on R90 rows.",
          "alpha_extrapolation"
        ],
        [
          "version_boundary",
          "When this policy changes.",
          "Any R90 calculation-method, anchor-source, step-floor, missing-row, or effective-grade rule change"
        ]
      ],
      "currentValues": [
        [
          "serving home",
          "analytics/alpha mirror; nweamap owner.",
          "The Alpha-readable R90 table and API live on Analytics, but the PowerPath RIT-to-grade master source lives in NWEAMAP."
        ],
        [
          "current R90 table_version",
          "analytics.rit_to_grade.powerpath.v2026-06-15",
          "Pinned by AITD-017 and echoed by /r90 plus /r90/table."
        ],
        [
          "RIT50 handling",
          "The current R50/R90 serving follows the PowerPath RIT-to-grade table.",
          "The dictionary current path follows the served PowerPath mirror."
        ],
        [
          "RIT90 handling",
          "Rows carry extend_kind=alpha_extrapolation and r90_method_ref=alpha.policy.analytics.r90_method.v2026-06-12.",
          "The field makes the Alpha-added method visible in raw DB reads and API responses."
        ],
        [
          "lookup behavior",
          "Filter table_version='analytics.rit_to_grade.powerpath.v2026-06-15', then use the PowerPath row whose rit_score equals the requested RIT.",
          "Exact matches return source_point_kind=exact; missing rows return source_missing."
        ],
        [
          "versioning behavior",
          "Any legitimate future method change publishes a new table_version and r90_method_ref.",
          "The prior production derivation is not a valid historical target; current reads use analytics.rit_to_grade.powerpath.v2026-06-15."
        ],
        [
          "cache behavior",
          "Responses include table_version and calculator_version and use no-store for mutable HTTP caching.",
          "Clients may cache by immutable table_version, but do not maintain a separate R90 table."
        ]
      ],
      "rawDbRule": "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.",
      "itds": [
        {
          "id": "aitd-015-norms-r90-readable-resources",
          "title": "NWEA Norms And NWEAMAP R90 Are Versioned, Readable Surface Reference Tables",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-015-norms-r90-readable-resources"
        },
        {
          "id": "aitd-016-scale-translation-apis",
          "title": "Percentile<->RIT And RIT->R90/Grade Are Server-Side Surface Translations",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-016-scale-translation-apis"
        },
        {
          "id": "aitd-017-r90-version-supersession",
          "title": "RIT-to-grade Table Versioning: PowerPath v2026-06-15 Is The Current Version, And One Named Config Picks It For Every Path",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-017-r90-version-supersession"
        },
        {
          "id": "aitd-011-policy-and-enum-normalization",
          "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
        }
      ]
    },
    {
      "id": "completion",
      "policyRef": "alpha.policy.analytics.course_progress.v2026-06-15",
      "title": "Course Progress Evidence",
      "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.",
      "plainLanguage": "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.",
      "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."
        ]
      ],
      "configFields": [
        [
          "event_source",
          "Named Events extension source for direct course progress.",
          "TimebackProfile courseProgressPercent / percentComplete"
        ],
        [
          "report_source_adapter",
          "Named source adapter for XP-remaining fallback.",
          "timeback-completion over reporting.processed_facts"
        ],
        [
          "denominator_policy_ref",
          "Which denominator policy was used for the scope.",
          "alpha.policy.analytics.course_progress.v2026-06-15"
        ],
        [
          "zero_denominator_behavior",
          "How empty scopes appear.",
          "completion_percent=null and null_reason=no_subject_assignment/no_enrollment/source_missing as applicable"
        ]
      ],
      "currentValues": [
        [
          "precedence",
          "app-reported percent_complete; then 1 - (xp_remaining / total_xp); then lesson count only as last adapter fallback.",
          "Analytics stores the computed percent and progress_source_kind; consumers read it."
        ],
        [
          "zero denominator",
          "completion_percent=null with null_reason no_subject_assignment, no_enrollment, source_missing, source_unlinked, or not_applicable.",
          "No report may divide by zero, return 1-if-active, or invent 0%."
        ],
        [
          "ordinary quality statuses",
          "ok, corrected.",
          "Other quality statuses are audit/findings until repaired."
        ],
        [
          "scope grain",
          "course, subject, track, track_level, grade_level, segment.",
          "The scope controls what scope_id points to and what policy selected as expected work."
        ],
        [
          "worked direct example",
          "A course progress event with percent_complete=75 writes completion_percent=75.000 and progress_source_kind=app_reported_percent.",
          "Direct app evidence wins over any fallback count or XP row."
        ],
        [
          "worked XP fallback example",
          "A course scope with xp_earned=900 and xp_remaining=300 writes completion_percent=75.000 when no direct percent exists.",
          "The remaining-XP denominator comes from Curriculum expected XP; the report does not walk the tree."
        ]
      ],
      "rawDbRule": "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.",
      "itds": [
        {
          "id": "aitd-010-completion-rollups",
          "title": "Completion Percent Is Ingested Earned XP Over A Curriculum Denominator, Never Invented",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-010-completion-rollups"
        },
        {
          "id": "aitd-001-report-source-ingestion",
          "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
        },
        {
          "id": "aitd-004-provenance-no-literals",
          "title": "Every Report Value Traces To An Ingested Source Row, Or Reads Null",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-004-provenance-no-literals"
        },
        {
          "id": "aitd-011-policy-and-enum-normalization",
          "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
        }
      ]
    },
    {
      "id": "completion-numerator",
      "policyRef": "alpha.policy.analytics.course_progress.v2026-06-15",
      "title": "Completion XP Fallback",
      "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.",
      "plainLanguage": "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.",
      "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."
        ]
      ],
      "configFields": [
        [
          "accepted_report_source_shapes",
          "Report-source shapes allowed to count.",
          "reporting.processed_facts rows linked to scope and accepted by adapter policy"
        ],
        [
          "required_quality_status",
          "Quality statuses allowed in ordinary completion reports.",
          "ok, corrected; exclude source_missing/source_unlinked/policy_pending/adapter_rejected"
        ],
        [
          "source_ref_match",
          "How source evidence must link to Curriculum expected refs.",
          "source course/activity/KC refs must resolve to denominator scope"
        ]
      ],
      "currentValues": [
        [
          "accepted_report_source_shapes",
          "reporting.processed_facts rows linked to the requested completion scope.",
          "Each accepted row must resolve to a Curriculum denominator scope."
        ],
        [
          "ordinary report statuses",
          "ok, corrected.",
          "reversed/source_missing/source_unlinked/policy_pending/adapter_rejected do not increase xp_earned."
        ],
        [
          "completion evidence rule",
          "Earned XP is accumulated once per accepted source key under adapter policy.",
          "Retries and corrections are already handled by source refs and quality_status."
        ]
      ],
      "rawDbRule": "Read xp_earned from alpha.analytics_completion_rollup. Use source_import_id/sourceRefs only for authorized audits.",
      "itds": [
        {
          "id": "aitd-010-completion-rollups",
          "title": "Completion Percent Is Ingested Earned XP Over A Curriculum Denominator, Never Invented",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-010-completion-rollups"
        },
        {
          "id": "aitd-011-policy-and-enum-normalization",
          "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
        }
      ]
    },
    {
      "id": "completion-denominator",
      "policyRef": "alpha.policy.curriculum.main_course_grade_level.v2026-06-15",
      "title": "Completion Denominator",
      "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.",
      "plainLanguage": "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.",
      "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."
        ]
      ],
      "configFields": [
        [
          "scope_ref_source",
          "Curriculum refs used for denominator membership.",
          "course_component, course_component_member, KC refs"
        ],
        [
          "included_course_role",
          "Course role that contributes to grade-level progress.",
          "main"
        ],
        [
          "excluded_course_roles",
          "Course roles excluded from grade-level progress.",
          "hole_filling, remediation, remedial, catalog, practice, review"
        ],
        [
          "zero_denominator_reason",
          "The null_reason to emit for empty/unlinked scopes.",
          "no_subject_assignment, source_missing, source_unlinked, not_applicable"
        ]
      ],
      "currentValues": [
        [
          "included_course_role",
          "main.",
          "Only main courses count toward grade-level progress. Hole-filling and remediation do not."
        ],
        [
          "denominator worked shape",
          "Two main courses at 25% and 75% write grade_level completion_percent=50.000.",
          "A 100% hole-filling course does not change that grade-level percent."
        ],
        [
          "scope traversal",
          "Server-side Curriculum reference expansion under denominator_policy_ref.",
          "Reports do not recursively query course_component or course_component_member."
        ],
        [
          "student-specific filtering",
          "Expected refs must apply to the student, subject, track/level, enrollment window, and personalized course when present.",
          "A shared course and a personalized course can have different xp_remaining values."
        ],
        [
          "zero denominator",
          "xp_earned + xp_remaining = 0 and completion_percent=null with typed null_reason.",
          "No client fallback to 0%, 100%, or hidden row."
        ]
      ],
      "rawDbRule": "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.",
      "itds": [
        {
          "id": "aitd-010-completion-rollups",
          "title": "Completion Percent Is Ingested Earned XP Over A Curriculum Denominator, Never Invented",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-010-completion-rollups"
        },
        {
          "id": "aitd-011-policy-and-enum-normalization",
          "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
        }
      ]
    },
    {
      "id": "fluency-probe",
      "policyRef": "alpha.policy.analytics.fluency_probe.v2026-07-18.issue-1128",
      "title": "Fluency Probe DCPM And Bands",
      "answers": "What rate and performance band did this governed fluency probe produce?",
      "controls": "Calculates rate_per_minute and assigns acquisition, fluency_building, or mastery.",
      "plainLanguage": "Analytics divides correct units by elapsed minutes and stores the result and band; apps only display it.",
      "definitions": [
        [
          "rate_per_minute",
          "correct_units * 60000 / elapsed_ms"
        ],
        [
          "bands",
          "acquisition <10; fluency_building >=10 and <20; mastery >=20"
        ]
      ],
      "configFields": [
        [
          "probe_kind",
          "Initial governed probe family.",
          "digits_correct_per_minute"
        ]
      ],
      "currentValues": [
        [
          "formula",
          "correct_units * 60000 / elapsed_ms",
          "Rounded to three decimals."
        ],
        [
          "band thresholds",
          "10 and 20",
          "Lower bounds are inclusive for fluency_building and mastery."
        ]
      ],
      "rawDbRule": "Read rate_per_minute and performance_band from alpha.analytics_fluency_probe; do not recalculate from Events.",
      "itds": [
        {
          "id": "aitd-003-close-time-materialization",
          "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
        },
        {
          "id": "aitd-011-policy-and-enum-normalization",
          "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
        },
        {
          "id": "aitd-110-axis-conformance-evidence",
          "title": "API Axis: Conformance Evidence",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-110-axis-conformance-evidence"
        }
      ]
    },
    {
      "id": "ap-lab-progress",
      "policyRef": "alpha.policy.analytics.ap_lab_progress.v2026-07-18.issue-1128",
      "title": "AP Lab Progress",
      "answers": "Does the student meet the course's governed AP lab requirement?",
      "controls": "Counts completed hands-on labs, calculates hands-on share, and applies the profile-specific threshold.",
      "plainLanguage": "AP Chemistry requires 16 hands-on labs; AP Environmental Science requires 25% of active course time to be hands-on.",
      "definitions": [
        [
          "ap_chemistry",
          "completed_hands_on_lab_count >= 16"
        ],
        [
          "ap_environmental_science",
          "hands_on_percent >= 25"
        ]
      ],
      "configFields": [
        [
          "policy_profile",
          "Curriculum profile selecting the threshold.",
          "ap_chemistry or ap_environmental_science"
        ]
      ],
      "currentValues": [
        [
          "Chemistry floor",
          "16 completed hands-on labs",
          "Only when policy_profile=ap_chemistry."
        ],
        [
          "Environmental Science floor",
          "25 percent hands-on active time",
          "Only when policy_profile=ap_environmental_science."
        ]
      ],
      "rawDbRule": "Read stored thresholds and meets_course_requirement from alpha.analytics_lab_progress; do not count Events or apply thresholds in a report.",
      "itds": [
        {
          "id": "aitd-003-close-time-materialization",
          "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
        },
        {
          "id": "aitd-011-policy-and-enum-normalization",
          "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
        },
        {
          "id": "aitd-110-axis-conformance-evidence",
          "title": "API Axis: Conformance Evidence",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-110-axis-conformance-evidence"
        }
      ]
    }
  ],
  "calendarReasonMappings": [
    {
      "alphaReason": "instructional",
      "edFiCalendarEventCodes": [
        "Instructional day",
        "Make-up day",
        "Student late arrival/early dismissal"
      ],
      "countsAsSchoolDay": "yes",
      "meaning": "Counts in the denominator when it also intersects the student enrollment and, for subject rows, subject assignment."
    },
    {
      "alphaReason": "teacher_workshop",
      "edFiCalendarEventCodes": [
        "Teacher only day"
      ],
      "countsAsSchoolDay": "no",
      "meaning": "Teachers are working but students are not expected to produce learning minutes."
    },
    {
      "alphaReason": "holiday_break",
      "edFiCalendarEventCodes": [
        "Holiday"
      ],
      "countsAsSchoolDay": "no",
      "meaning": "Instruction is cancelled for holiday or break; minutes are not divided by this date."
    },
    {
      "alphaReason": "nwea_map_testing",
      "edFiCalendarEventCodes": [
        "Tenant-governed NWEA/MAP testing CalendarEventDescriptor values"
      ],
      "countsAsSchoolDay": "no",
      "meaning": "MAP testing days are excluded from the time-commitment denominator by alpha.policy.school_day."
    },
    {
      "alphaReason": "other",
      "edFiCalendarEventCodes": [
        "Emergency day",
        "Non-instructional day",
        "Other",
        "Strike",
        "Weather day",
        "tenant-governed uncovered values"
      ],
      "countsAsSchoolDay": "no unless policy explicitly maps the governed value to instructional",
      "meaning": "A catch-all for non-instructional or locally-governed calendar codes; uncovered tenant values produce policy_pending/source_unlinked findings before they affect reports."
    }
  ],
  "calendarSourceStatus": {
    "status": "verified_available",
    "checkedBy": "data dictionary attempt 1 using current read-only Node/Postgres persistence evidence plus operator reporting-probe settlement",
    "rowCount": 9238,
    "schoolDayRows": 5674,
    "schoolCount": 14,
    "dateRange": "2025-08-13 to 2027-06-06",
    "reasons": "holiday_break, instructional, nwea_map_testing, other, weekend",
    "contract": "A reportable Learning Report row carries a real enrolled_school_day_count from alpha.school_calendar over Ed-Fi CalendarDate intersected with enrollment and subject assignment. If a particular school/window lacks coverage, Analytics emits source_missing for repair/audit; consumers still never fabricate a denominator."
  },
  "reportSources": [
    {
      "adapter": "timeback-xp-time-accuracy",
      "panel": "XP Goal (P5), Time Commitment (P6), Accuracy (P7)",
      "sourceTable": "reporting.processed_facts",
      "reportColumns": "xp_earned, active_seconds, total_questions, correct_questions, subject, date, app, source, score_type",
      "analyticsObject": "alpha.analytics_xp_rollup, alpha.analytics_school_day_minutes, alpha.analytics_accuracy",
      "itd": "aitd-007-xp-rollups",
      "adapterContract": "Accept the source-shaped producer row for this adapter; normalize server-side and reject only missing required fields or unlinked governed refs."
    },
    {
      "adapter": "timeback-map",
      "panel": "MAP Results (P3)",
      "sourceTable": "reporting.hp_map_results",
      "reportColumns": "testritscore, testpercentile, wintertowinterobservedgrowth, wintertowinterprojectedgrowth, typicalwintertowintergrowth, wintertowinterconditionalgrowthpercentile, termname, growthmeasureyn",
      "analyticsObject": "alpha.analytics_map_growth_rollup",
      "itd": "aitd-009-map-growth-rollups",
      "adapterContract": "Accept the full source-shaped reporting.hp_map_results row, including wintertowinter*, fall/winter/spring window blocks, goal1..goal8 blocks, and any unknown extra columns. Unknown extra columns are ignored; missing required columns or unlinked identities produce typed Problems."
    },
    {
      "adapter": "timeback-grade-mastery",
      "panel": "Grade Levels Mastered (P4)",
      "sourceTable": "reporting.assessment_results",
      "reportColumns": "student_sourced_id, score, score_status, score_date, learning_objective_set, assessment_line_item_sourced_id",
      "analyticsObject": "alpha.analytics_mastery_delta",
      "itd": "aitd-008-mastery-and-grade-levels",
      "adapterContract": "Accept the source-shaped producer row for this adapter; normalize server-side and reject only missing required fields or unlinked governed refs."
    },
    {
      "adapter": "timeback-completion",
      "panel": "Course Completion (P2)",
      "sourceTable": "reporting.processed_facts + reporting.courses + reporting.course_components",
      "reportColumns": "xp_earned (earned) + course expected XP (remaining denominator)",
      "analyticsObject": "alpha.analytics_completion_rollup",
      "itd": "aitd-010-completion-rollups",
      "adapterContract": "Accept the source-shaped producer row for this adapter; normalize server-side and reject only missing required fields or unlinked governed refs."
    }
  ],
  "learningReportRecipes": [
    {
      "id": "minutes-per-school-day",
      "panel": "timeCommitment",
      "title": "Time Commitment: Minutes Per Enrolled School Day",
      "question": "Is the school-day denominator available, and if so how many active minutes per enrolled school day did this student average?",
      "api": "GET /alpha/analytics/v1/school-day-minutes?studentId=student_01HT7G3YZV7QB5N4YKQ1K0Z9A9&subjectId=math&startDate=2026-01-01&endDate=2026-06-01",
      "rawSql": "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;",
      "resultFields": [
        "active_minutes",
        "enrolled_school_day_count",
        "excluded_school_day_count",
        "minutes_per_enrolled_school_day",
        "school_day_policy_ref",
        "quality_status",
        "null_reason"
      ],
      "table": "alpha.analytics_school_day_minutes",
      "reads": [
        "alpha.analytics_school_day_minutes"
      ]
    },
    {
      "id": "xp-total",
      "panel": "xpGoals",
      "title": "XP: Earned, Goal Availability, And Uncapped Percent",
      "question": "How much XP was earned, and are the goal, remaining, and uncapped percent fields available under the shared school-day denominator?",
      "api": "GET /alpha/analytics/v1/xp-rollups?studentId=student_01HT7G3YZV7QB5N4YKQ1K0Z9A9&subjectId=math&windowKind=term&startDate=2026-01-01&endDate=2026-06-01",
      "rawSql": "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;",
      "resultFields": [
        "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"
      ],
      "table": "alpha.analytics_xp_rollup",
      "reads": [
        "alpha.analytics_xp_rollup"
      ]
    },
    {
      "id": "accuracy",
      "panel": "accuracy",
      "title": "Accuracy (P7): Correct Questions Over Total Questions",
      "question": "What accuracy percent should the Learning Report show for this student and subject?",
      "api": "GET /alpha/analytics/v1/accuracy-rollups?studentId=student_01HT7G3YZV7QB5N4YKQ1K0Z9A9&subjectId=math&windowKind=term&startDate=2026-01-01&endDate=2026-06-01",
      "rawSql": "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;",
      "resultFields": [
        "correct_question_count",
        "total_question_count",
        "incorrect_question_count",
        "accuracy_percent",
        "source_import_id",
        "policy_ref",
        "quality_status",
        "null_reason"
      ],
      "table": "alpha.analytics_accuracy",
      "exampleResponse": {
        "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"
      },
      "reads": [
        "alpha.analytics_accuracy"
      ]
    },
    {
      "id": "attempt-count",
      "panel": "attemptCount",
      "title": "Attempts: Count And Max Ordinal",
      "question": "How many attempts did this student need in the reporting window?",
      "api": "GET /alpha/analytics/v1/attempt-rollups?studentId=student_01HT7G3YZV7QB5N4YKQ1K0Z9A9&subjectId=math&windowKind=term&startDate=2026-01-01&endDate=2026-06-01",
      "rawSql": "select attempt_count, max_attempt_ordinal, source_event_refs, source_import_id, policy_ref from alpha.analytics_attempt_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;",
      "resultFields": [
        "attempt_count",
        "max_attempt_ordinal",
        "source_event_refs",
        "source_import_id",
        "policy_ref"
      ],
      "table": "alpha.analytics_attempt_rollup",
      "reads": [
        "alpha.analytics_attempt_rollup"
      ]
    },
    {
      "id": "response-latency",
      "panel": "responseLatency",
      "title": "Response Latency: Milliseconds",
      "question": "How long did responses take in the reporting window?",
      "api": "GET /alpha/analytics/v1/response-latency-rollups?studentId=student_01HT7G3YZV7QB5N4YKQ1K0Z9A9&subjectId=math&windowKind=term&startDate=2026-01-01&endDate=2026-06-01",
      "rawSql": "select response_count, response_time_ms_total, response_time_ms_avg, response_time_ms_min, response_time_ms_max, source_event_refs, source_import_id, policy_ref from alpha.analytics_response_latency_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;",
      "resultFields": [
        "response_count",
        "response_time_ms_total",
        "response_time_ms_avg",
        "response_time_ms_min",
        "response_time_ms_max",
        "source_event_refs",
        "source_import_id",
        "policy_ref"
      ],
      "table": "alpha.analytics_response_latency_rollup",
      "reads": [
        "alpha.analytics_response_latency_rollup"
      ]
    },
    {
      "id": "hint-usage",
      "panel": "hintUsage",
      "title": "Hint Usage: Requests, Views, Used",
      "question": "How often were hints requested, viewed, or used in the reporting window?",
      "api": "GET /alpha/analytics/v1/hint-usage-rollups?studentId=student_01HT7G3YZV7QB5N4YKQ1K0Z9A9&subjectId=math&windowKind=term&startDate=2026-01-01&endDate=2026-06-01",
      "rawSql": "select hint_request_count, hint_view_count, hint_used_count, source_event_refs, source_import_id, policy_ref from alpha.analytics_hint_usage_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;",
      "resultFields": [
        "hint_request_count",
        "hint_view_count",
        "hint_used_count",
        "source_event_refs",
        "source_import_id",
        "policy_ref"
      ],
      "table": "alpha.analytics_hint_usage_rollup",
      "reads": [
        "alpha.analytics_hint_usage_rollup"
      ]
    },
    {
      "id": "mastery-deltas",
      "panel": "masteryTransitions",
      "title": "Mastery: KC Changes During A Date Range",
      "question": "Which Knowledge Components changed mastery state for this student?",
      "api": "GET /alpha/analytics/v1/mastery-deltas?studentId=student_01HT7G3YZV7QB5N4YKQ1K0Z9A9&startDate=2026-05-01&endDate=2026-06-01&stateDimension=durable_mastery",
      "rawSql": "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;",
      "resultFields": [
        "kc_id",
        "state_dimension",
        "effective_at",
        "previous_value",
        "new_value",
        "delta_value",
        "transition_kind"
      ],
      "table": "alpha.analytics_mastery_delta",
      "reads": [
        "alpha.analytics_mastery_delta"
      ]
    },
    {
      "id": "map-growth",
      "panel": "mapResults",
      "title": "MAP Results: RIT And Growth X",
      "question": "What RIT and Growth X should the Learning Report show for this term?",
      "api": "GET /alpha/analytics/v1/map-growth-rollups?studentId=student_01HT7G3YZV7QB5N4YKQ1K0Z9A9&subjectId=math&termId=term_2026_winter&growthWindow=winter_to_winter&normsSet=2025",
      "rawSql": "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;",
      "resultFields": [
        "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"
      ],
      "table": "alpha.analytics_map_growth_rollup",
      "reads": [
        "alpha.analytics_map_growth_rollup"
      ]
    },
    {
      "id": "scale-translation",
      "panel": "goalsScaleTranslation",
      "title": "GOALS: Percentile To RIT And RIT To R90",
      "question": "What RIT is a target percentile, and what grade/R90 does a RIT map to?",
      "api": "GET /alpha/analytics/v1/norms/rit?subjectId=math&gradeLevel=5&termName=winter&percentile=90&normsSet=2025\nGET /alpha/analytics/v1/r90?subjectId=math&rit=239&normsSet=2025",
      "rawSql": "with\nnorms_row as (\n  select mean_rit, sd_rit, table_version\n  from alpha.analytics_norms_achievement\n  where tenant_id is null\n    and norms_set = :norms_set\n    and table_version = :norms_table_version\n    and subject_id = :subject_id\n    and role = :role\n    and grade_key = :grade_key\n    and season = :season\n    and quality_status = 'ok'\n  limit 1\n),\npercentile_to_rit as (\n  select\n    mean_rit + (sd_rit * :z_score_for_requested_percentile) as rit_score,\n    mean_rit,\n    sd_rit,\n    table_version\n  from norms_row\n),\nr90 as (\n  select\n    r90_grade,\n    effective_grade,\n    r90_grade_level,\n    r90_percent_complete,\n    'exact' as source_point_kind,\n    table_version,\n    rit_score as table_rit_score\n  from alpha.analytics_r90_table\n  where tenant_id is null\n    and norms_set = :norms_set\n    and table_version = 'analytics.rit_to_grade.powerpath.v2026-06-15'\n    and table_subject_id = :subject_id\n    and rit_score = :input_rit\n    and quality_status = 'ok'\n  limit 1\n)\nselect jsonb_build_object(\n  'percentileToRit', (select to_jsonb(percentile_to_rit) from percentile_to_rit),\n  'ritToR90', (select to_jsonb(r90) from r90)\n) as scale_translation;",
      "resultFields": [
        "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"
      ],
      "tables": [
        "alpha.analytics_norms_achievement",
        "alpha.analytics_r90_table"
      ],
      "steps": [
        "Use the norms table_version pinned in the report and the current R90 table_version analytics.rit_to_grade.powerpath.v2026-06-15 unless the report explicitly asks to reproduce a historical R90 answer. HTTP responses are no-store; the version string is the cache key.",
        "For percentile-to-RIT, read mean_rit and sd_rit from the achievement norms row and apply the documented normal-model translation, or call /norms/rit.",
        "For RIT-to-R90, filter the current R90 table version and choose the PowerPath row whose rit_score equals the requested score. Exact matches return exact; missing rows return source_missing."
      ],
      "exampleResponse": {
        "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"
        }
      },
      "reads": [
        "alpha.analytics_norms_achievement",
        "alpha.analytics_r90_table"
      ]
    },
    {
      "id": "school-days-remaining",
      "panel": "goalsTargetDate",
      "title": "GOALS: School Days Remaining And Target-Date Effort",
      "question": "How many instructional days remain, and what daily effort is needed to finish by a target date?",
      "api": "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",
      "rawSql": "with\nstudent_school as (\n  select :school_id as school_id\n  -- If schoolId is omitted, resolve this from People and Orgs effective-dated enrollment\n  -- where begin_date is not null and :as_of falls inside [begin_date, end_date].\n),\ninstructional_dates as (\n  select calendar_date\n  from alpha.school_calendar\n  where school_id = (select school_id from student_school)\n    and calendar_date >= :as_of::date\n    and calendar_date < :end_date::date\n    and is_school_day = true\n    and reason = 'instructional'\n    and policy_ref = 'alpha.policy.school_day.v2026-06-10'\n  order by calendar_date\n),\neffort as (\n  select\n    :xp_remaining::numeric as xp_remaining,\n    (:xp_remaining::numeric / 1.0) as expected_minutes_remaining,\n    (:xp_remaining::numeric / 60.0) as hours_remaining,\n    :hours_per_school_day::numeric as hours_per_school_day\n),\ntarget_window as (\n  select count(*)::integer as school_days_until_target_date\n  from instructional_dates\n  where calendar_date < :target_date::date\n)\nselect jsonb_build_object(\n  'object', 'analytics.school_days_remaining',\n  'student_id', :student_id,\n  'school_id', (select school_id from student_school),\n  'as_of', :as_of,\n  'end_date', :end_date,\n  'school_day_policy_ref', 'alpha.policy.school_day.v2026-06-10',\n  'instructional_days_remaining', (select count(*) from instructional_dates),\n  'calendar_ref_count', (\n    select count(*) from alpha.school_calendar\n    where school_id = (select school_id from student_school)\n      and calendar_date >= :as_of::date\n      and calendar_date < :end_date::date\n  ),\n  'first_instructional_date', (select min(calendar_date) from instructional_dates),\n  'last_instructional_date', (select max(calendar_date) from instructional_dates),\n  'instructional_dates', (select jsonb_agg(calendar_date order by calendar_date) from instructional_dates),\n  'xp_unit', jsonb_build_object(\n    'policy_ref', 'alpha.policy.analytics.xp_expected_minute.v2026-06-14',\n    'xp_per_expected_minute', 1,\n    'xp_per_hour', 60,\n    'meaning', '1 XP = 1 expected minute; 60 XP = 1 expected hour.'\n  ),\n  'effort', jsonb_build_object(\n    'xp_remaining', (select xp_remaining from effort),\n    'expected_minutes_remaining', (select expected_minutes_remaining from effort),\n    'hours_remaining', (select hours_remaining from effort),\n    'target_date', :target_date,\n    'school_days_until_target_date', (select school_days_until_target_date from target_window),\n    'required_hours_per_school_day_to_target_date',\n      case when (select school_days_until_target_date from target_window) > 0\n        then (select hours_remaining from effort) / (select school_days_until_target_date from target_window)\n        else null end,\n    'hours_per_school_day', (select hours_per_school_day from effort),\n    'school_days_needed_at_hours_per_school_day',\n      case when (select hours_per_school_day from effort) > 0\n        then ceil((select hours_remaining from effort) / (select hours_per_school_day from effort))\n        else null end\n  )\n) as school_days_remaining;",
      "resultFields": [
        "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"
      ],
      "tables": [
        "analytics.school_days_remaining",
        "alpha.school_calendar",
        "alpha.analytics_xp_rollup"
      ],
      "steps": [
        "Resolve the student school by effective-dated People and Orgs enrollment, or pass a schoolId when the caller already has the governed school id.",
        "Count only alpha.school_calendar rows that are instructional under alpha.policy.school_day inside the half-open [asOf, endDate) window; asOf is included and endDate is excluded.",
        "Use alpha.policy.analytics.xp_expected_minute.v2026-06-14: 1 XP = 1 expected minute, 60 XP = 1 expected hour. Do not keep XP_PER_HOUR or weekday math in GOALS.",
        "Render the returned fields. If the window has no instructional days, instructional_days_remaining is 0 and target-date effort fields that divide by days are null instead of guessed."
      ],
      "exampleResponse": {
        "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
        }
      },
      "reads": [
        "analytics.school_days_remaining",
        "alpha.school_calendar",
        "alpha.analytics_xp_rollup"
      ]
    },
    {
      "id": "grade-level-status",
      "panel": "goalsAgeGradeStatus",
      "title": "GOALS: Working And Mastered Age-Grade Status",
      "question": "Is the student working above, at, or behind their school-assigned age grade, and is strict mastery above, at, or behind age grade?",
      "api": "GET /alpha/analytics/v1/grade-level-status?studentId=b6fa7128-f641-4efd-9075-375411fd6c39&subject=math&asOfDate=2026-05-20",
      "rawSql": "with\nage_grade as (\n  select age_grade, begin_date, end_date\n  from alpha.age_grade_history\n  where tenant_id = :people_and_orgs_tenant_id\n    and person_id = :student_id\n    and is_time_locatable is true\n    and begin_date <= :as_of_date::date\n    and (end_date is null or :as_of_date::date < end_date)\n    and deleted_at is null\n  order by begin_date desc\n  limit 1\n),\nresults_grade as (\n  select working_grade, highest_mastered_grade\n  from results.student_track_state\n  where tenant_id = :results_tenant_id\n    and student_id = :student_id\n    and subject_id = :subject_id\n    and as_of_date <= :as_of_date::date\n  order by as_of_date desc\n  limit 1\n)\nselect jsonb_build_object(\n  'object', 'analytics.grade_level_status',\n  'student_id', :student_id,\n  'subject_id', :subject_id,\n  'as_of_date', :as_of_date,\n  'age_grade', (select age_grade from age_grade),\n  'working_grade', (select working_grade from results_grade),\n  'highest_mastered_grade', (select highest_mastered_grade from results_grade),\n  'working_age_grade_delta', (select working_grade from results_grade) - (select age_grade from age_grade),\n  'mastered_age_grade_delta', (select highest_mastered_grade from results_grade) - (select age_grade from age_grade)\n) as grade_level_status;",
      "resultFields": [
        "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"
      ],
      "tables": [
        "analytics.grade_level_status"
      ],
      "steps": [
        "Read age_grade from People and Orgs alpha.age_grade_history for the requested asOfDate. Do not infer it from birthdays, prior-year close, MAP/RIT, working grade, HMG, or course placement.",
        "Read working_grade and highest_mastered_grade from Results. Results owns the working-grade resolver; Analytics only compares returned grade positions.",
        "Return exactly two named comparisons: working_age_grade_status = working_grade - age_grade and mastered_age_grade_status = highest_mastered_grade - age_grade. Old generic status names, if present, are compatibility aliases only."
      ],
      "exampleResponse": {
        "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"
        }
      },
      "reads": [
        "analytics.grade_level_status"
      ]
    },
    {
      "id": "completion",
      "panel": "courseCompletion",
      "title": "Course Progress Evidence: Completion Percent",
      "question": "What completion evidence did Analytics materialize for this course?",
      "api": "GET /alpha/analytics/v1/completion-rollups?studentId=student_01HT7G3YZV7QB5N4YKQ1K0Z9A9&completionScope=course&scopeId=course_math_grade_4_powerpath",
      "rawSql": "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;",
      "resultFields": [
        "xp_earned",
        "xp_remaining",
        "completion_percent",
        "denominator_policy_ref",
        "source_import_id",
        "null_reason"
      ],
      "table": "alpha.analytics_completion_rollup",
      "reads": [
        "alpha.analytics_completion_rollup"
      ]
    },
    {
      "id": "learning-report-assembly",
      "panel": "fullLearningReport",
      "title": "End-To-End Learning Report Assembly",
      "question": "How does one studentId + term become the Learning Report panels, including Accuracy?",
      "api": "GET /alpha/analytics/v1/school-day-minutes?studentId=student_01HT7G3YZV7QB5N4YKQ1K0Z9A9&subjectId=math&startDate=2026-01-01&endDate=2026-06-01\nGET /alpha/analytics/v1/xp-rollups?studentId=student_01HT7G3YZV7QB5N4YKQ1K0Z9A9&subjectId=math&windowKind=term&startDate=2026-01-01&endDate=2026-06-01\nGET /alpha/analytics/v1/accuracy-rollups?studentId=student_01HT7G3YZV7QB5N4YKQ1K0Z9A9&subjectId=math&windowKind=term&startDate=2026-01-01&endDate=2026-06-01\nGET /alpha/analytics/v1/mastery-deltas?studentId=student_01HT7G3YZV7QB5N4YKQ1K0Z9A9&startDate=2026-01-01&endDate=2026-06-01\nGET /alpha/analytics/v1/map-growth-rollups?studentId=student_01HT7G3YZV7QB5N4YKQ1K0Z9A9&subjectId=math&termId=term_2026_winter&growthWindow=winter_to_winter&normsSet=2025\nGET /alpha/analytics/v1/completion-rollups?studentId=student_01HT7G3YZV7QB5N4YKQ1K0Z9A9&completionScope=course&scopeId=course_math_grade_4_powerpath",
      "rawSql": "with\ntime_commitment as (\n  select active_minutes, enrolled_school_day_count, excluded_school_day_count, minutes_per_enrolled_school_day, quality_status, null_reason\n  from alpha.analytics_school_day_minutes\n  where tenant_id = :tenant_id and student_id = :student_id and subject_id = :subject_id\n    and window_start = :term_start and window_end = :term_end\n    and quality_status in ('ok','corrected') and null_reason = 'none' and superseded_at is null and source_deleted_at is null\n),\nxp as (\n  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\n  from alpha.analytics_xp_rollup\n  where tenant_id = :tenant_id and student_id = :student_id and subject_id = :subject_id\n    and window_kind = 'term' and window_start = :term_start and window_end = :term_end\n    and quality_status in ('ok','corrected') and superseded_at is null and source_deleted_at is null\n),\naccuracy as (\n  select correct_question_count, total_question_count, incorrect_question_count, accuracy_percent, source_import_id, null_reason\n  from alpha.analytics_accuracy\n  where tenant_id = :tenant_id and student_id = :student_id and subject_id = :subject_id\n    and window_kind = 'term' and window_start = :term_start and window_end = :term_end\n    and quality_status in ('ok','corrected') and superseded_at is null and source_deleted_at is null\n),\nmastery as (\n  select jsonb_agg(jsonb_build_object(\n    'kcId', kc_id,\n    'stateDimension', state_dimension,\n    'transition', transition_kind,\n    'previousValue', previous_value,\n    'newValue', new_value,\n    'effectiveAt', effective_at\n  ) order by effective_at desc) as deltas\n  from alpha.analytics_mastery_delta\n  where tenant_id = :tenant_id and student_id = :student_id\n    and effective_at >= :term_start::timestamptz and effective_at < :term_end::timestamptz\n    and quality_status in ('ok','corrected') and superseded_at is null and source_deleted_at is null\n),\nmap as (\n  select rit_score, achievement_percentile, growth_percentile, observed_growth, projected_growth, typical_growth, growth_x, growth_x_target, on_track,\n         sitting_count, retake_count, norms_set, growth_window, source_import_id\n  from alpha.analytics_map_growth_rollup\n  where tenant_id = :tenant_id and student_id = :student_id and subject_id = :subject_id\n    and canonical_term_id = :canonical_term_id and growth_window = :growth_window and norms_set = :norms_set\n    and quality_status in ('ok','corrected') and superseded_at is null and source_deleted_at is null\n),\ncompletion as (\n  select completion_scope, scope_id, xp_earned, xp_remaining, completion_percent, null_reason, source_import_id\n  from alpha.analytics_completion_rollup\n  where tenant_id = :tenant_id and student_id = :student_id\n    and completion_scope = :completion_scope and scope_id = :scope_id\n    and quality_status in ('ok','corrected') and superseded_at is null and source_deleted_at is null\n)\nselect jsonb_build_object(\n  'studentId', :student_id,\n  'termId', :canonical_term_id,\n  'panels', jsonb_build_object(\n    'timeCommitment', (select to_jsonb(time_commitment) from time_commitment),\n    'xpGoals', (select to_jsonb(xp) from xp),\n    'accuracy', (select to_jsonb(accuracy) from accuracy),\n    'masteryTransitions', coalesce((select deltas from mastery), '[]'::jsonb),\n    'mapResults', (select to_jsonb(map) from map),\n    'courseCompletion', (select to_jsonb(completion) from completion)\n  )\n) as learning_report_json;",
      "resultFields": [
        "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"
      ],
      "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"
      ],
      "steps": [
        "Resolve studentId, subjectId, canonicalTermId, term_start, term_end, normsSet, growthWindow=winter_to_winter for the \"vs 1yr ago\" MAP panel, completionScope, and scopeId from the report route or upstream Alpha surfaces.",
        "Read the six Analytics tables/endpoints at their documented grains with the ordinary current-row filters.",
        "Place returned fields into report panels. If a time-commitment row or XP goal row has null_reason=source_missing, it is a repair state and the report is incomplete until the source is fixed/replayed; do not substitute active dates, attendance days, or calendar-day counts. The only client work is shaping JSON for display; no minutes, XP, accuracy, mastery, MAP, or completion math runs in the report."
      ],
      "exampleResponse": {
        "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"
          }
        }
      },
      "reads": [
        "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"
      ]
    }
  ],
  "learningReportPanelCoverage": [
    {
      "panel": "timeCommitment",
      "label": "Time Commitment",
      "recipeId": "minutes-per-school-day",
      "analyticsObject": "alpha.analytics_school_day_minutes",
      "requiredFields": "active_minutes, enrolled_school_day_count, excluded_school_day_count, minutes_per_enrolled_school_day, null_reason",
      "api": "GET /alpha/analytics/v1/school-day-minutes",
      "rawDbRule": "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."
    },
    {
      "panel": "xpGoals",
      "label": "XP Goals",
      "recipeId": "xp-total",
      "analyticsObject": "alpha.analytics_xp_rollup",
      "requiredFields": "xp_total, daily_xp_goal, enrolled_school_day_count, xp_goal, xp_remaining, xp_goal_percent, on_track, null_reason",
      "api": "GET /alpha/analytics/v1/xp-rollups",
      "rawDbRule": "Read alpha.analytics_xp_rollup; never sum Results XP ledger or processed_facts in the report."
    },
    {
      "panel": "accuracy",
      "label": "Accuracy (P7)",
      "recipeId": "accuracy",
      "analyticsObject": "alpha.analytics_accuracy",
      "requiredFields": "correct_question_count, total_question_count, incorrect_question_count, accuracy_percent, source_import_id, null_reason",
      "api": "GET /alpha/analytics/v1/accuracy-rollups",
      "rawDbRule": "Read alpha.analytics_accuracy; never sum reporting.processed_facts.total_questions/correct_questions, keep app allowlists, or divide and round locally."
    },
    {
      "panel": "attemptCount",
      "label": "Attempt Count",
      "recipeId": "attempt-count",
      "analyticsObject": "alpha.analytics_attempt_rollup",
      "requiredFields": "attempt_count, max_attempt_ordinal, source_event_refs, source_import_id, policy_ref",
      "api": "GET /alpha/analytics/v1/attempt-rollups",
      "rawDbRule": "Read alpha.analytics_attempt_rollup; never infer attempts from UI state or parse Events extensions in the report."
    },
    {
      "panel": "responseLatency",
      "label": "Response Latency",
      "recipeId": "response-latency",
      "analyticsObject": "alpha.analytics_response_latency_rollup",
      "requiredFields": "response_count, response_time_ms_total, response_time_ms_avg, response_time_ms_min, response_time_ms_max, source_event_refs, source_import_id, policy_ref",
      "api": "GET /alpha/analytics/v1/response-latency-rollups",
      "rawDbRule": "Read alpha.analytics_response_latency_rollup; latency unit is milliseconds; never invent response_latency aliases."
    },
    {
      "panel": "hintUsage",
      "label": "Hint Usage",
      "recipeId": "hint-usage",
      "analyticsObject": "alpha.analytics_hint_usage_rollup",
      "requiredFields": "hint_request_count, hint_view_count, hint_used_count, source_event_refs, source_import_id, policy_ref",
      "api": "GET /alpha/analytics/v1/hint-usage-rollups",
      "rawDbRule": "Read alpha.analytics_hint_usage_rollup; never count hint UI state locally."
    },
    {
      "panel": "masteryTransitions",
      "label": "Mastery / Grade Levels",
      "recipeId": "mastery-deltas",
      "analyticsObject": "alpha.analytics_mastery_delta",
      "requiredFields": "kc_id, state_dimension, transition_kind, previous_value, new_value, effective_at, source_import_id/source_state_ref",
      "api": "GET /alpha/analytics/v1/mastery-deltas",
      "rawDbRule": "Read alpha.analytics_mastery_delta; never recompute mastery, HMG, or decay from attempts in the report."
    },
    {
      "panel": "mapResults",
      "label": "MAP Results",
      "recipeId": "map-growth",
      "analyticsObject": "alpha.analytics_map_growth_rollup",
      "requiredFields": "rit_score, achievement_percentile, growth_percentile, observed_growth, projected_growth, growth_x, norms_set, growth_window",
      "api": "GET /alpha/analytics/v1/map-growth-rollups",
      "rawDbRule": "Read alpha.analytics_map_growth_rollup; never dedupe MAP sittings, parse term strings, or maintain norms locally."
    },
    {
      "panel": "courseCompletion",
      "label": "Course Completion",
      "recipeId": "completion",
      "analyticsObject": "alpha.analytics_completion_rollup",
      "requiredFields": "completion_scope, scope_id, xp_earned, xp_remaining, completion_percent, denominator_policy_ref, null_reason",
      "api": "GET /alpha/analytics/v1/completion-rollups",
      "rawDbRule": "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."
    },
    {
      "panel": "goalsTargetDate",
      "label": "GOALS Target Date",
      "recipeId": "school-days-remaining",
      "analyticsObject": "analytics.school_days_remaining",
      "requiredFields": "instructional_days_remaining, instructional_dates, xp_unit.xp_per_expected_minute, xp_unit.xp_per_hour, effort.*",
      "api": "GET /alpha/analytics/v1/school-days-remaining",
      "rawDbRule": "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."
    },
    {
      "panel": "goalsAgeGradeStatus",
      "label": "GOALS Age-Grade Status",
      "recipeId": "grade-level-status",
      "analyticsObject": "analytics.grade_level_status",
      "requiredFields": "age_grade, working_grade, highest_mastered_grade, working_age_grade_status, mastered_age_grade_status, working_age_grade_delta, mastered_age_grade_delta",
      "api": "GET /alpha/analytics/v1/grade-level-status",
      "rawDbRule": "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."
    },
    {
      "panel": "fullLearningReport",
      "label": "End-To-End Assembly",
      "recipeId": "learning-report-assembly",
      "analyticsObject": "six alpha.analytics_* report tables",
      "requiredFields": "All panel fields above, including panels.accuracy.*",
      "api": "six GET calls listed in the assembly recipe",
      "rawDbRule": "Assemble already-computed Analytics rows into JSON only; no minutes, XP, accuracy, mastery, MAP, or completion math runs in the report."
    }
  ],
  "learningReportPanels": [
    {
      "panel": "timeCommitment",
      "label": "Time Commitment",
      "recipeId": "minutes-per-school-day",
      "analyticsObject": "alpha.analytics_school_day_minutes",
      "requiredFields": "active_minutes, enrolled_school_day_count, excluded_school_day_count, minutes_per_enrolled_school_day, null_reason",
      "api": "GET /alpha/analytics/v1/school-day-minutes",
      "rawDbRule": "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."
    },
    {
      "panel": "xpGoals",
      "label": "XP Goals",
      "recipeId": "xp-total",
      "analyticsObject": "alpha.analytics_xp_rollup",
      "requiredFields": "xp_total, daily_xp_goal, enrolled_school_day_count, xp_goal, xp_remaining, xp_goal_percent, on_track, null_reason",
      "api": "GET /alpha/analytics/v1/xp-rollups",
      "rawDbRule": "Read alpha.analytics_xp_rollup; never sum Results XP ledger or processed_facts in the report."
    },
    {
      "panel": "accuracy",
      "label": "Accuracy (P7)",
      "recipeId": "accuracy",
      "analyticsObject": "alpha.analytics_accuracy",
      "requiredFields": "correct_question_count, total_question_count, incorrect_question_count, accuracy_percent, source_import_id, null_reason",
      "api": "GET /alpha/analytics/v1/accuracy-rollups",
      "rawDbRule": "Read alpha.analytics_accuracy; never sum reporting.processed_facts.total_questions/correct_questions, keep app allowlists, or divide and round locally."
    },
    {
      "panel": "attemptCount",
      "label": "Attempt Count",
      "recipeId": "attempt-count",
      "analyticsObject": "alpha.analytics_attempt_rollup",
      "requiredFields": "attempt_count, max_attempt_ordinal, source_event_refs, source_import_id, policy_ref",
      "api": "GET /alpha/analytics/v1/attempt-rollups",
      "rawDbRule": "Read alpha.analytics_attempt_rollup; never infer attempts from UI state or parse Events extensions in the report."
    },
    {
      "panel": "responseLatency",
      "label": "Response Latency",
      "recipeId": "response-latency",
      "analyticsObject": "alpha.analytics_response_latency_rollup",
      "requiredFields": "response_count, response_time_ms_total, response_time_ms_avg, response_time_ms_min, response_time_ms_max, source_event_refs, source_import_id, policy_ref",
      "api": "GET /alpha/analytics/v1/response-latency-rollups",
      "rawDbRule": "Read alpha.analytics_response_latency_rollup; latency unit is milliseconds; never invent response_latency aliases."
    },
    {
      "panel": "hintUsage",
      "label": "Hint Usage",
      "recipeId": "hint-usage",
      "analyticsObject": "alpha.analytics_hint_usage_rollup",
      "requiredFields": "hint_request_count, hint_view_count, hint_used_count, source_event_refs, source_import_id, policy_ref",
      "api": "GET /alpha/analytics/v1/hint-usage-rollups",
      "rawDbRule": "Read alpha.analytics_hint_usage_rollup; never count hint UI state locally."
    },
    {
      "panel": "masteryTransitions",
      "label": "Mastery / Grade Levels",
      "recipeId": "mastery-deltas",
      "analyticsObject": "alpha.analytics_mastery_delta",
      "requiredFields": "kc_id, state_dimension, transition_kind, previous_value, new_value, effective_at, source_import_id/source_state_ref",
      "api": "GET /alpha/analytics/v1/mastery-deltas",
      "rawDbRule": "Read alpha.analytics_mastery_delta; never recompute mastery, HMG, or decay from attempts in the report."
    },
    {
      "panel": "mapResults",
      "label": "MAP Results",
      "recipeId": "map-growth",
      "analyticsObject": "alpha.analytics_map_growth_rollup",
      "requiredFields": "rit_score, achievement_percentile, growth_percentile, observed_growth, projected_growth, growth_x, norms_set, growth_window",
      "api": "GET /alpha/analytics/v1/map-growth-rollups",
      "rawDbRule": "Read alpha.analytics_map_growth_rollup; never dedupe MAP sittings, parse term strings, or maintain norms locally."
    },
    {
      "panel": "courseCompletion",
      "label": "Course Completion",
      "recipeId": "completion",
      "analyticsObject": "alpha.analytics_completion_rollup",
      "requiredFields": "completion_scope, scope_id, xp_earned, xp_remaining, completion_percent, denominator_policy_ref, null_reason",
      "api": "GET /alpha/analytics/v1/completion-rollups",
      "rawDbRule": "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."
    },
    {
      "panel": "goalsTargetDate",
      "label": "GOALS Target Date",
      "recipeId": "school-days-remaining",
      "analyticsObject": "analytics.school_days_remaining",
      "requiredFields": "instructional_days_remaining, instructional_dates, xp_unit.xp_per_expected_minute, xp_unit.xp_per_hour, effort.*",
      "api": "GET /alpha/analytics/v1/school-days-remaining",
      "rawDbRule": "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."
    },
    {
      "panel": "goalsAgeGradeStatus",
      "label": "GOALS Age-Grade Status",
      "recipeId": "grade-level-status",
      "analyticsObject": "analytics.grade_level_status",
      "requiredFields": "age_grade, working_grade, highest_mastered_grade, working_age_grade_status, mastered_age_grade_status, working_age_grade_delta, mastered_age_grade_delta",
      "api": "GET /alpha/analytics/v1/grade-level-status",
      "rawDbRule": "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."
    },
    {
      "panel": "fullLearningReport",
      "label": "End-To-End Assembly",
      "recipeId": "learning-report-assembly",
      "analyticsObject": "six alpha.analytics_* report tables",
      "requiredFields": "All panel fields above, including panels.accuracy.*",
      "api": "six GET calls listed in the assembly recipe",
      "rawDbRule": "Assemble already-computed Analytics rows into JSON only; no minutes, XP, accuracy, mastery, MAP, or completion math runs in the report."
    }
  ],
  "apiEndpoints": [
    {
      "method": "GET",
      "path": "/alpha/analytics/v1/school-day-minutes",
      "id": "get-alpha-analytics-v1-school-day-minutes",
      "panel": "timeCommitment",
      "recipeId": "minutes-per-school-day",
      "tables": [
        "alpha.analytics_school_day_minutes"
      ],
      "purpose": "Is the school-day denominator available, and if so how many active minutes per enrolled school day did this student average?",
      "contractStatus": "documented Analytics read contract"
    },
    {
      "method": "GET",
      "path": "/alpha/analytics/v1/xp-rollups",
      "id": "get-alpha-analytics-v1-xp-rollups",
      "panel": "xpGoals",
      "recipeId": "xp-total",
      "tables": [
        "alpha.analytics_xp_rollup"
      ],
      "purpose": "How much XP was earned, and are the goal, remaining, and uncapped percent fields available under the shared school-day denominator?",
      "contractStatus": "documented Analytics read contract"
    },
    {
      "method": "GET",
      "path": "/alpha/analytics/v1/accuracy-rollups",
      "id": "get-alpha-analytics-v1-accuracy-rollups",
      "panel": "accuracy",
      "recipeId": "accuracy",
      "tables": [
        "alpha.analytics_accuracy"
      ],
      "purpose": "What accuracy percent should the Learning Report show for this student and subject?",
      "contractStatus": "served at this wave's implementation cell; docs-first contract with live materializer evidence in implementation/integration"
    },
    {
      "method": "GET",
      "path": "/alpha/analytics/v1/attempt-rollups",
      "id": "get-alpha-analytics-v1-attempt-rollups",
      "panel": "attemptCount",
      "recipeId": "attempt-count",
      "tables": [
        "alpha.analytics_attempt_rollup"
      ],
      "purpose": "How many attempts did the student need in the window?",
      "contractStatus": "documented Analytics read contract"
    },
    {
      "method": "GET",
      "path": "/alpha/analytics/v1/response-latency-rollups",
      "id": "get-alpha-analytics-v1-response-latency-rollups",
      "panel": "responseLatency",
      "recipeId": "response-latency",
      "tables": [
        "alpha.analytics_response_latency_rollup"
      ],
      "purpose": "How long did responses take in the window?",
      "contractStatus": "documented Analytics read contract"
    },
    {
      "method": "GET",
      "path": "/alpha/analytics/v1/hint-usage-rollups",
      "id": "get-alpha-analytics-v1-hint-usage-rollups",
      "panel": "hintUsage",
      "recipeId": "hint-usage",
      "tables": [
        "alpha.analytics_hint_usage_rollup"
      ],
      "purpose": "How often were hints requested, viewed, or used in the window?",
      "contractStatus": "documented Analytics read contract"
    },
    {
      "method": "GET",
      "path": "/alpha/analytics/v1/mastery-deltas",
      "id": "get-alpha-analytics-v1-mastery-deltas",
      "panel": "masteryTransitions",
      "recipeId": "mastery-deltas",
      "tables": [
        "alpha.analytics_mastery_delta"
      ],
      "purpose": "Which Knowledge Components changed mastery state for this student?",
      "contractStatus": "documented Analytics read contract"
    },
    {
      "method": "GET",
      "path": "/alpha/analytics/v1/map-growth-rollups",
      "id": "get-alpha-analytics-v1-map-growth-rollups",
      "panel": "mapResults",
      "recipeId": "map-growth",
      "tables": [
        "alpha.analytics_map_growth_rollup"
      ],
      "purpose": "What RIT and Growth X should the Learning Report show for this term?",
      "contractStatus": "documented Analytics read contract"
    },
    {
      "method": "GET",
      "path": "/alpha/analytics/v1/norms/rit",
      "id": "get-alpha-analytics-v1-norms-rit",
      "panel": "goalsScaleTranslation",
      "recipeId": "scale-translation",
      "tables": [
        "alpha.analytics_norms_achievement",
        "alpha.analytics_r90_table"
      ],
      "purpose": "What RIT is a target percentile, and what grade/R90 does a RIT map to?",
      "contractStatus": "documented Analytics read contract"
    },
    {
      "method": "GET",
      "path": "/alpha/analytics/v1/r90",
      "id": "get-alpha-analytics-v1-r90",
      "panel": "goalsScaleTranslation",
      "recipeId": "scale-translation",
      "tables": [
        "alpha.analytics_norms_achievement",
        "alpha.analytics_r90_table"
      ],
      "purpose": "What RIT is a target percentile, and what grade/R90 does a RIT map to?",
      "contractStatus": "documented Analytics read contract"
    },
    {
      "method": "GET",
      "path": "/alpha/analytics/v1/school-days-remaining",
      "id": "get-alpha-analytics-v1-school-days-remaining",
      "panel": "goalsTargetDate",
      "recipeId": "school-days-remaining",
      "tables": [
        "analytics.school_days_remaining",
        "alpha.school_calendar",
        "alpha.analytics_xp_rollup"
      ],
      "purpose": "How many instructional days remain, and what daily effort is needed to finish by a target date?",
      "contractStatus": "documented Analytics read contract"
    },
    {
      "method": "GET",
      "path": "/alpha/analytics/v1/grade-level-status",
      "id": "get-alpha-analytics-v1-grade-level-status",
      "panel": "goalsAgeGradeStatus",
      "recipeId": "grade-level-status",
      "tables": [
        "analytics.grade_level_status"
      ],
      "purpose": "Is the student working above, at, or behind their school-assigned age grade, and is strict mastery above, at, or behind age grade?",
      "contractStatus": "documented Analytics read contract"
    },
    {
      "method": "GET",
      "path": "/alpha/analytics/v1/completion-rollups",
      "id": "get-alpha-analytics-v1-completion-rollups",
      "panel": "courseCompletion",
      "recipeId": "completion",
      "tables": [
        "alpha.analytics_completion_rollup"
      ],
      "purpose": "What completion evidence did Analytics materialize for this course?",
      "contractStatus": "documented Analytics read contract; page-bounded and current-row scoped under completion-rollup retention",
      "retentionPolicyRef": "alpha.policy.analytics.completion_rollup_retention.v2026-07-03"
    },
    {
      "method": "GET",
      "path": "/alpha/analytics/v1/event-time-facts",
      "id": "get-alpha-analytics-v1-event-time-facts",
      "tables": [
        "alpha.analytics_event_time_fact"
      ],
      "purpose": "Read signed Event-derived time contributions.",
      "queryAxes": [
        "modifiedSince",
        "sort",
        "limit",
        "cursor",
        "studentId",
        "subjectId",
        "startDate",
        "endDate",
        "factKind",
        "sourceEventId"
      ],
      "contractStatus": "documented Analytics read contract; inventory-checked against the runtime route map"
    },
    {
      "method": "GET",
      "path": "/alpha/analytics/v1/time-windows",
      "id": "get-alpha-analytics-v1-time-windows",
      "tables": [
        "alpha.analytics_time_window"
      ],
      "purpose": "Read stored active, inactive, and waste time windows.",
      "queryAxes": [
        "modifiedSince",
        "sort",
        "limit",
        "cursor",
        "studentId",
        "subjectId",
        "startDate",
        "endDate",
        "windowKind"
      ],
      "contractStatus": "documented Analytics read contract; inventory-checked against the runtime route map"
    },
    {
      "method": "GET",
      "path": "/alpha/analytics/v1/fluency-probes",
      "id": "get-alpha-analytics-v1-fluency-probes",
      "tables": [
        "alpha.analytics_fluency_probe"
      ],
      "purpose": "Read governed fluency-probe rates and performance bands.",
      "queryAxes": [
        "modifiedSince",
        "sort",
        "limit",
        "cursor",
        "studentId",
        "courseId",
        "kcId",
        "performanceBand",
        "startDate",
        "endDate"
      ],
      "contractStatus": "documented Analytics read contract; inventory-checked against the runtime route map"
    },
    {
      "method": "GET",
      "path": "/alpha/analytics/v1/lab-progress",
      "id": "get-alpha-analytics-v1-lab-progress",
      "tables": [
        "alpha.analytics_lab_progress"
      ],
      "purpose": "Read governed AP lab counts, hands-on share, thresholds, and verdicts.",
      "queryAxes": [
        "modifiedSince",
        "sort",
        "limit",
        "cursor",
        "studentId",
        "courseId",
        "policyProfile",
        "startDate",
        "endDate"
      ],
      "contractStatus": "documented Analytics read contract; inventory-checked against the runtime route map"
    },
    {
      "method": "GET",
      "path": "/alpha/analytics/v1/source-imports",
      "id": "get-alpha-analytics-v1-source-imports",
      "tables": [
        "alpha.analytics_source_import"
      ],
      "purpose": "Read source-import audit receipts.",
      "queryAxes": [
        "modifiedSince",
        "sort",
        "limit",
        "cursor",
        "importKind",
        "status"
      ],
      "contractStatus": "documented Analytics read contract; inventory-checked against the runtime route map"
    }
  ],
  "endpoints": [
    {
      "method": "GET",
      "path": "/alpha/analytics/v1/school-day-minutes",
      "id": "get-alpha-analytics-v1-school-day-minutes",
      "panel": "timeCommitment",
      "recipeId": "minutes-per-school-day",
      "tables": [
        "alpha.analytics_school_day_minutes"
      ],
      "purpose": "Is the school-day denominator available, and if so how many active minutes per enrolled school day did this student average?",
      "contractStatus": "documented Analytics read contract"
    },
    {
      "method": "GET",
      "path": "/alpha/analytics/v1/xp-rollups",
      "id": "get-alpha-analytics-v1-xp-rollups",
      "panel": "xpGoals",
      "recipeId": "xp-total",
      "tables": [
        "alpha.analytics_xp_rollup"
      ],
      "purpose": "How much XP was earned, and are the goal, remaining, and uncapped percent fields available under the shared school-day denominator?",
      "contractStatus": "documented Analytics read contract"
    },
    {
      "method": "GET",
      "path": "/alpha/analytics/v1/accuracy-rollups",
      "id": "get-alpha-analytics-v1-accuracy-rollups",
      "panel": "accuracy",
      "recipeId": "accuracy",
      "tables": [
        "alpha.analytics_accuracy"
      ],
      "purpose": "What accuracy percent should the Learning Report show for this student and subject?",
      "contractStatus": "served at this wave's implementation cell; docs-first contract with live materializer evidence in implementation/integration"
    },
    {
      "method": "GET",
      "path": "/alpha/analytics/v1/attempt-rollups",
      "id": "get-alpha-analytics-v1-attempt-rollups",
      "panel": "attemptCount",
      "recipeId": "attempt-count",
      "tables": [
        "alpha.analytics_attempt_rollup"
      ],
      "purpose": "How many attempts did the student need in the window?",
      "contractStatus": "documented Analytics read contract"
    },
    {
      "method": "GET",
      "path": "/alpha/analytics/v1/response-latency-rollups",
      "id": "get-alpha-analytics-v1-response-latency-rollups",
      "panel": "responseLatency",
      "recipeId": "response-latency",
      "tables": [
        "alpha.analytics_response_latency_rollup"
      ],
      "purpose": "How long did responses take in the window?",
      "contractStatus": "documented Analytics read contract"
    },
    {
      "method": "GET",
      "path": "/alpha/analytics/v1/hint-usage-rollups",
      "id": "get-alpha-analytics-v1-hint-usage-rollups",
      "panel": "hintUsage",
      "recipeId": "hint-usage",
      "tables": [
        "alpha.analytics_hint_usage_rollup"
      ],
      "purpose": "How often were hints requested, viewed, or used in the window?",
      "contractStatus": "documented Analytics read contract"
    },
    {
      "method": "GET",
      "path": "/alpha/analytics/v1/mastery-deltas",
      "id": "get-alpha-analytics-v1-mastery-deltas",
      "panel": "masteryTransitions",
      "recipeId": "mastery-deltas",
      "tables": [
        "alpha.analytics_mastery_delta"
      ],
      "purpose": "Which Knowledge Components changed mastery state for this student?",
      "contractStatus": "documented Analytics read contract"
    },
    {
      "method": "GET",
      "path": "/alpha/analytics/v1/map-growth-rollups",
      "id": "get-alpha-analytics-v1-map-growth-rollups",
      "panel": "mapResults",
      "recipeId": "map-growth",
      "tables": [
        "alpha.analytics_map_growth_rollup"
      ],
      "purpose": "What RIT and Growth X should the Learning Report show for this term?",
      "contractStatus": "documented Analytics read contract"
    },
    {
      "method": "GET",
      "path": "/alpha/analytics/v1/norms/rit",
      "id": "get-alpha-analytics-v1-norms-rit",
      "panel": "goalsScaleTranslation",
      "recipeId": "scale-translation",
      "tables": [
        "alpha.analytics_norms_achievement",
        "alpha.analytics_r90_table"
      ],
      "purpose": "What RIT is a target percentile, and what grade/R90 does a RIT map to?",
      "contractStatus": "documented Analytics read contract"
    },
    {
      "method": "GET",
      "path": "/alpha/analytics/v1/r90",
      "id": "get-alpha-analytics-v1-r90",
      "panel": "goalsScaleTranslation",
      "recipeId": "scale-translation",
      "tables": [
        "alpha.analytics_norms_achievement",
        "alpha.analytics_r90_table"
      ],
      "purpose": "What RIT is a target percentile, and what grade/R90 does a RIT map to?",
      "contractStatus": "documented Analytics read contract"
    },
    {
      "method": "GET",
      "path": "/alpha/analytics/v1/school-days-remaining",
      "id": "get-alpha-analytics-v1-school-days-remaining",
      "panel": "goalsTargetDate",
      "recipeId": "school-days-remaining",
      "tables": [
        "analytics.school_days_remaining",
        "alpha.school_calendar",
        "alpha.analytics_xp_rollup"
      ],
      "purpose": "How many instructional days remain, and what daily effort is needed to finish by a target date?",
      "contractStatus": "documented Analytics read contract"
    },
    {
      "method": "GET",
      "path": "/alpha/analytics/v1/grade-level-status",
      "id": "get-alpha-analytics-v1-grade-level-status",
      "panel": "goalsAgeGradeStatus",
      "recipeId": "grade-level-status",
      "tables": [
        "analytics.grade_level_status"
      ],
      "purpose": "Is the student working above, at, or behind their school-assigned age grade, and is strict mastery above, at, or behind age grade?",
      "contractStatus": "documented Analytics read contract"
    },
    {
      "method": "GET",
      "path": "/alpha/analytics/v1/completion-rollups",
      "id": "get-alpha-analytics-v1-completion-rollups",
      "panel": "courseCompletion",
      "recipeId": "completion",
      "tables": [
        "alpha.analytics_completion_rollup"
      ],
      "purpose": "What completion evidence did Analytics materialize for this course?",
      "contractStatus": "documented Analytics read contract; page-bounded and current-row scoped under completion-rollup retention",
      "retentionPolicyRef": "alpha.policy.analytics.completion_rollup_retention.v2026-07-03"
    },
    {
      "method": "GET",
      "path": "/alpha/analytics/v1/event-time-facts",
      "id": "get-alpha-analytics-v1-event-time-facts",
      "tables": [
        "alpha.analytics_event_time_fact"
      ],
      "purpose": "Read signed Event-derived time contributions.",
      "queryAxes": [
        "modifiedSince",
        "sort",
        "limit",
        "cursor",
        "studentId",
        "subjectId",
        "startDate",
        "endDate",
        "factKind",
        "sourceEventId"
      ],
      "contractStatus": "documented Analytics read contract; inventory-checked against the runtime route map"
    },
    {
      "method": "GET",
      "path": "/alpha/analytics/v1/time-windows",
      "id": "get-alpha-analytics-v1-time-windows",
      "tables": [
        "alpha.analytics_time_window"
      ],
      "purpose": "Read stored active, inactive, and waste time windows.",
      "queryAxes": [
        "modifiedSince",
        "sort",
        "limit",
        "cursor",
        "studentId",
        "subjectId",
        "startDate",
        "endDate",
        "windowKind"
      ],
      "contractStatus": "documented Analytics read contract; inventory-checked against the runtime route map"
    },
    {
      "method": "GET",
      "path": "/alpha/analytics/v1/fluency-probes",
      "id": "get-alpha-analytics-v1-fluency-probes",
      "tables": [
        "alpha.analytics_fluency_probe"
      ],
      "purpose": "Read governed fluency-probe rates and performance bands.",
      "queryAxes": [
        "modifiedSince",
        "sort",
        "limit",
        "cursor",
        "studentId",
        "courseId",
        "kcId",
        "performanceBand",
        "startDate",
        "endDate"
      ],
      "contractStatus": "documented Analytics read contract; inventory-checked against the runtime route map"
    },
    {
      "method": "GET",
      "path": "/alpha/analytics/v1/lab-progress",
      "id": "get-alpha-analytics-v1-lab-progress",
      "tables": [
        "alpha.analytics_lab_progress"
      ],
      "purpose": "Read governed AP lab counts, hands-on share, thresholds, and verdicts.",
      "queryAxes": [
        "modifiedSince",
        "sort",
        "limit",
        "cursor",
        "studentId",
        "courseId",
        "policyProfile",
        "startDate",
        "endDate"
      ],
      "contractStatus": "documented Analytics read contract; inventory-checked against the runtime route map"
    },
    {
      "method": "GET",
      "path": "/alpha/analytics/v1/source-imports",
      "id": "get-alpha-analytics-v1-source-imports",
      "tables": [
        "alpha.analytics_source_import"
      ],
      "purpose": "Read source-import audit receipts.",
      "queryAxes": [
        "modifiedSince",
        "sort",
        "limit",
        "cursor",
        "importKind",
        "status"
      ],
      "contractStatus": "documented Analytics read contract; inventory-checked against the runtime route map"
    }
  ],
  "enumSets": {
    "subject_id": [
      [
        "math",
        "Math subject rollups and MAP/math source-label normalization."
      ],
      [
        "reading",
        "Reading subject rollups."
      ],
      [
        "language",
        "Language / ELA subject rollups. Public reads keep vocabulary and writing as distinct canonical subjects."
      ],
      [
        "science",
        "Science subject rollups."
      ],
      [
        "vocabulary",
        "Vocabulary activity rollups as the canonical vocabulary subject."
      ],
      [
        "writing",
        "Writing activity rollups as the canonical writing subject."
      ]
    ],
    "fact_kind": [
      [
        "active_seconds",
        "Seconds the policy classifies as productive engaged work for a closed source event."
      ],
      [
        "inactive_seconds",
        "Seconds the policy classifies as idle or not meaningfully engaged."
      ],
      [
        "waste_seconds",
        "Seconds the policy classifies as gaming, distraction, or otherwise counterproductive work."
      ]
    ],
    "window_kind": [
      [
        "day",
        "A calendar day in the school timezone, represented as a half-open date range."
      ],
      [
        "week",
        "A platform week under alpha.policy.analytics.window."
      ],
      [
        "term",
        "An academic term from the People and Orgs academic-session calendar."
      ],
      [
        "school_year",
        "A school-year window from the org academic-session calendar."
      ],
      [
        "custom",
        "A caller-requested or migration reconciliation range with explicit start and end dates."
      ],
      [
        "range",
        "An explicit caller-supplied startDate/endDate window that must match a stored producer window where the endpoint requires exact-window reads."
      ]
    ],
    "quality_status": [
      [
        "ok",
        "The row is the current reportable fact for its key and policy."
      ],
      [
        "corrected",
        "The row includes a correction contribution but remains reportable."
      ],
      [
        "reversed",
        "The row reverses a prior contribution and should be read as signed history."
      ],
      [
        "source_missing",
        "A required source row was removed or unavailable before the fact could be finalized."
      ],
      [
        "source_unlinked",
        "The source row exists but could not link to a required Event, Result, student, subject, KC, course, or policy ref."
      ],
      [
        "policy_pending",
        "A required policy configuration was missing or not yet active at materialization time."
      ],
      [
        "adapter_rejected",
        "The source-shaped row was valid input but the server-side adapter rejected it with a typed Problem."
      ]
    ],
    "null_reason": [
      [
        "none",
        "No null-producing condition applies."
      ],
      [
        "no_school_days",
        "The denominator window has zero enrolled school days after calendar and enrollment intersection."
      ],
      [
        "no_questions",
        "The window has zero reportable question attempts, so accuracy_percent is null rather than guessed as 0 or 100."
      ],
      [
        "no_enrollment",
        "The student has no time-locatable enrollment for the requested range."
      ],
      [
        "no_subject_assignment",
        "The student had no subject assignment/course/test membership for the subject denominator."
      ],
      [
        "source_missing",
        "Required Event, Result, calendar, enrollment, or curriculum source evidence is missing."
      ],
      [
        "source_unlinked",
        "Source evidence exists but cannot be linked to platform ids under the current policy."
      ],
      [
        "policy_pending",
        "The named policy needed to compute the measure is missing or not active."
      ],
      [
        "not_applicable",
        "The metric does not apply at this grain, such as MAP growth for a non-MAP subject."
      ]
    ],
    "state_dimension": [
      [
        "initial_mastery",
        "The acquisition/mastery signal changed for the KC."
      ],
      [
        "current_retention",
        "The retained mastery value changed under the Results retention policy."
      ],
      [
        "durable_mastery",
        "The durable mastery state changed."
      ],
      [
        "fluency_state",
        "The fluency/automaticity state changed."
      ],
      [
        "next_due_at",
        "The next review or practice due date changed."
      ]
    ],
    "transition_kind": [
      [
        "acquired",
        "The student crossed into mastery/acquisition for the KC."
      ],
      [
        "improved",
        "The state value increased but did not represent first acquisition."
      ],
      [
        "decayed",
        "The value decreased under Results retention state."
      ],
      [
        "review_due",
        "The due-date dimension moved into a new due state."
      ],
      [
        "fluency_changed",
        "The fluency dimension changed."
      ],
      [
        "corrected",
        "The transition reflects a source correction or migration repair."
      ],
      [
        "blocked",
        "A required source or policy row was missing, so the state change is blocked."
      ]
    ],
    "norms_set": [
      [
        "2020",
        "NWEA 2020 norms, kept distinct for historical report reproduction."
      ],
      [
        "2025",
        "NWEA 2025 norms, the current norms family when requested by policy or caller."
      ]
    ],
    "source_point_kind": [
      [
        "exact",
        "The requested RIT exactly matched a PowerPath RIT-to-grade row in the current R90 table version."
      ],
      [
        "source_missing",
        "No PowerPath RIT-to-grade source row exists for the requested RIT and subject, so the surface returns a typed missing answer instead of extrapolating."
      ]
    ],
    "growth_window": [
      [
        "fall_to_fall",
        "Year-over-year growth from fall of the prior school year to fall of the selected school year."
      ],
      [
        "fall_to_winter",
        "Observed and projected growth from fall to winter."
      ],
      [
        "winter_to_spring",
        "Observed and projected growth from winter to spring."
      ],
      [
        "fall_to_spring",
        "Observed and projected growth from fall to spring."
      ],
      [
        "winter_to_winter",
        "Year-over-year growth from winter of the prior school year to winter of the selected school year. This is the Learning Report \"vs 1yr ago\" MAP window."
      ],
      [
        "spring_to_spring",
        "Year-over-year growth from spring of the prior school year to spring of the selected school year."
      ],
      [
        "baseline_to_current",
        "Growth from the student baseline term to the current term."
      ],
      [
        "term",
        "A single-term MAP observation with no paired growth delta."
      ],
      [
        "custom",
        "A named migration or report window whose dates are stored in policy/config."
      ]
    ],
    "completion_scope": [
      [
        "course",
        "Completion for one course."
      ],
      [
        "subject",
        "Completion for all expected work in one subject."
      ],
      [
        "track",
        "Completion for a full track."
      ],
      [
        "track_level",
        "Completion for one level inside a track."
      ],
      [
        "grade_level",
        "Progress evidence across the main courses that make up one grade level; the student-facing answer is served by Results."
      ],
      [
        "segment",
        "Completion for one curriculum segment."
      ]
    ],
    "import_kind": [
      [
        "timeback-xp-time-accuracy",
        "Named report-source adapter for the Learning Report XP Goal, Time Commitment, and Accuracy panels from reporting.processed_facts."
      ],
      [
        "timeback-map",
        "Named report-source adapter for the MAP Results panel from reporting.hp_map_results. It accepts the full source-shaped hp_map_results row, including every wintertowinter* and goal* column; unknown extra columns are ignored, never rejected."
      ],
      [
        "timeback-grade-mastery",
        "Named report-source adapter for the Grade Levels Mastered panel from reporting.assessment_results."
      ],
      [
        "timeback-completion",
        "Named report-source adapter for XP-remaining fallback course progress from reporting.processed_facts plus Curriculum expected-XP refs."
      ],
      [
        "event_close_replay",
        "A replay of Events close notifications into Analytics materializers."
      ],
      [
        "result_close_replay",
        "A replay of Results close/change notifications into Analytics materializers."
      ],
      [
        "migration_reconcile",
        "A migration gate rerun that imports source-shaped rows and checks metric reconciliation."
      ]
    ],
    "import_status": [
      [
        "received",
        "The batch envelope is recorded but not yet processed."
      ],
      [
        "running",
        "The adapter/materializer is processing the batch."
      ],
      [
        "materialized",
        "Accepted rows produced readable Analytics rows."
      ],
      [
        "partially_rejected",
        "Some rows materialized and some rows produced typed Problems."
      ],
      [
        "rejected",
        "No rows materialized because the batch failed validation or adapter mapping."
      ],
      [
        "failed",
        "A platform failure interrupted processing after the batch was accepted."
      ]
    ],
    "probe_kind": [
      [
        "digits_correct_per_minute",
        "Correct units completed per elapsed minute; the initial governed fluency probe family."
      ]
    ],
    "performance_band": [
      [
        "acquisition",
        "rate_per_minute below 10."
      ],
      [
        "fluency_building",
        "rate_per_minute at least 10 and below 20."
      ],
      [
        "mastery",
        "rate_per_minute at least 20."
      ]
    ],
    "policy_profile": [
      [
        "ap_chemistry",
        "Applies the 16 completed hands-on lab requirement."
      ],
      [
        "ap_environmental_science",
        "Applies the 25 percent hands-on active-time requirement."
      ]
    ]
  },
  "enumMeta": {
    "subject_id": {
      "sourceClass": "Alpha/Curriculum governed enum",
      "itds": [
        {
          "id": "aitd-011-policy-and-enum-normalization",
          "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
        }
      ]
    },
    "fact_kind": {
      "sourceClass": "Alpha extension enum",
      "itds": [
        {
          "id": "aitd-005-time-facts-and-windows",
          "title": "Active, Inactive, And Waste Seconds Are Typed Derived Time Facts",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-005-time-facts-and-windows"
        },
        {
          "id": "aitd-011-policy-and-enum-normalization",
          "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
        }
      ]
    },
    "window_kind": {
      "sourceClass": "Alpha extension enum",
      "itds": [
        {
          "id": "aitd-005-time-facts-and-windows",
          "title": "Active, Inactive, And Waste Seconds Are Typed Derived Time Facts",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-005-time-facts-and-windows"
        },
        {
          "id": "aitd-103-axis-query-model",
          "title": "API Axis: Query Model",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-103-axis-query-model"
        },
        {
          "id": "aitd-011-policy-and-enum-normalization",
          "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
        }
      ]
    },
    "quality_status": {
      "sourceClass": "Alpha extension enum",
      "itds": [
        {
          "id": "aitd-011-policy-and-enum-normalization",
          "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
        },
        {
          "id": "aitd-108-axis-error-envelope",
          "title": "API Axis: Error Envelope",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-108-axis-error-envelope"
        },
        {
          "id": "aitd-111-axis-privacy-retention",
          "title": "API Axis: Privacy And Retention",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-111-axis-privacy-retention"
        }
      ]
    },
    "null_reason": {
      "sourceClass": "Alpha extension enum",
      "itds": [
        {
          "id": "aitd-011-policy-and-enum-normalization",
          "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
        }
      ]
    },
    "state_dimension": {
      "sourceClass": "Alpha extension enum",
      "itds": [
        {
          "id": "aitd-008-mastery-and-grade-levels",
          "title": "Grade Levels Mastered Are Ingested; Mastery Deltas Read Results State",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-008-mastery-and-grade-levels"
        },
        {
          "id": "aitd-011-policy-and-enum-normalization",
          "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
        }
      ]
    },
    "transition_kind": {
      "sourceClass": "Alpha extension enum",
      "itds": [
        {
          "id": "aitd-008-mastery-and-grade-levels",
          "title": "Grade Levels Mastered Are Ingested; Mastery Deltas Read Results State",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-008-mastery-and-grade-levels"
        },
        {
          "id": "aitd-011-policy-and-enum-normalization",
          "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
        }
      ]
    },
    "norms_set": {
      "sourceClass": "Alpha extension enum",
      "itds": [
        {
          "id": "aitd-009-map-growth-rollups",
          "title": "MAP RIT And Growth X Are Ingested From hp_map_results, Deduped, And Norms-Calculated",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-009-map-growth-rollups"
        },
        {
          "id": "aitd-015-norms-r90-readable-resources",
          "title": "NWEA Norms And NWEAMAP R90 Are Versioned, Readable Surface Reference Tables",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-015-norms-r90-readable-resources"
        },
        {
          "id": "aitd-016-scale-translation-apis",
          "title": "Percentile<->RIT And RIT->R90/Grade Are Server-Side Surface Translations",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-016-scale-translation-apis"
        },
        {
          "id": "aitd-011-policy-and-enum-normalization",
          "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
        }
      ]
    },
    "source_point_kind": {
      "sourceClass": "Alpha reference lookup enum",
      "itds": [
        {
          "id": "aitd-015-norms-r90-readable-resources",
          "title": "NWEA Norms And NWEAMAP R90 Are Versioned, Readable Surface Reference Tables",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-015-norms-r90-readable-resources"
        },
        {
          "id": "aitd-016-scale-translation-apis",
          "title": "Percentile<->RIT And RIT->R90/Grade Are Server-Side Surface Translations",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-016-scale-translation-apis"
        },
        {
          "id": "aitd-017-r90-version-supersession",
          "title": "RIT-to-grade Table Versioning: PowerPath v2026-06-15 Is The Current Version, And One Named Config Picks It For Every Path",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-017-r90-version-supersession"
        }
      ]
    },
    "growth_window": {
      "sourceClass": "Alpha extension enum",
      "itds": [
        {
          "id": "aitd-009-map-growth-rollups",
          "title": "MAP RIT And Growth X Are Ingested From hp_map_results, Deduped, And Norms-Calculated",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-009-map-growth-rollups"
        },
        {
          "id": "aitd-011-policy-and-enum-normalization",
          "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
        }
      ]
    },
    "completion_scope": {
      "sourceClass": "Alpha extension enum",
      "itds": [
        {
          "id": "aitd-010-completion-rollups",
          "title": "Completion Percent Is Ingested Earned XP Over A Curriculum Denominator, Never Invented",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-010-completion-rollups"
        },
        {
          "id": "aitd-011-policy-and-enum-normalization",
          "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
        }
      ]
    },
    "import_kind": {
      "sourceClass": "Alpha extension enum",
      "itds": [
        {
          "id": "aitd-001-report-source-ingestion",
          "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
        },
        {
          "id": "aitd-101-axis-write-granularity",
          "title": "API Axis: Write Granularity",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-101-axis-write-granularity"
        }
      ]
    },
    "import_status": {
      "sourceClass": "Alpha extension enum",
      "itds": [
        {
          "id": "aitd-001-report-source-ingestion",
          "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
        },
        {
          "id": "aitd-108-axis-error-envelope",
          "title": "API Axis: Error Envelope",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-108-axis-error-envelope"
        }
      ]
    },
    "probe_kind": {
      "sourceClass": "Analytics/Curriculum governed enum",
      "itds": [
        {
          "id": "aitd-011-policy-and-enum-normalization",
          "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
        },
        {
          "id": "aitd-110-axis-conformance-evidence",
          "title": "API Axis: Conformance Evidence",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-110-axis-conformance-evidence"
        }
      ]
    },
    "performance_band": {
      "sourceClass": "Analytics/Curriculum governed enum",
      "itds": [
        {
          "id": "aitd-011-policy-and-enum-normalization",
          "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
        },
        {
          "id": "aitd-110-axis-conformance-evidence",
          "title": "API Axis: Conformance Evidence",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-110-axis-conformance-evidence"
        }
      ]
    },
    "policy_profile": {
      "sourceClass": "Analytics/Curriculum governed enum",
      "itds": [
        {
          "id": "aitd-011-policy-and-enum-normalization",
          "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
        },
        {
          "id": "aitd-110-axis-conformance-evidence",
          "title": "API Axis: Conformance Evidence",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-110-axis-conformance-evidence"
        }
      ]
    }
  },
  "problemEnvelope": {
    "format": "Typed RFC 7807 Problem JSON",
    "contentType": "application/problem+json",
    "typeUriPrefix": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/data_dictionary#problem-",
    "fields": [
      [
        "type",
        "URI",
        "required",
        "Stable deep link for this Analytics Problem code."
      ],
      [
        "title",
        "TEXT",
        "required",
        "Short human-readable summary."
      ],
      [
        "status",
        "INTEGER",
        "required",
        "HTTP status code; validation=400, adapter/policy normalization=422, conflict/not-ready=409, platform failure=500."
      ],
      [
        "code",
        "TEXT",
        "required",
        "Stable analytics:* code. Consumers switch on this, not title/detail text."
      ],
      [
        "detail",
        "TEXT",
        "required",
        "Specific explanation safe to show to the caller."
      ],
      [
        "requestId",
        "TEXT",
        "required",
        "Per-request id for support and audit correlation."
      ],
      [
        "traceId",
        "TEXT",
        "required",
        "Cross-service trace id for operator investigation."
      ],
      [
        "fieldErrors",
        "JSONB array",
        "optional",
        "Per-field validation failures for analytics:validation_failed."
      ],
      [
        "sourceRef",
        "TEXT",
        "optional",
        "Opaque source row/ref when a source-shaped row or close notification failed."
      ],
      [
        "resolution",
        "TEXT",
        "required",
        "Next safe action: correct request, repair source mapping, seed policy, replay, or wait for source close."
      ],
      [
        "links.dataDictionary",
        "URI",
        "required",
        "Deep link to the table, field, or Problem-code section that explains the rule."
      ]
    ],
    "example": {
      "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"
      }
    }
  },
  "problemCodes": [
    {
      "code": "analytics:validation_failed",
      "httpStatus": 400,
      "meaning": "The request envelope, query string, dates, enum values, or required fields are invalid before an adapter/materializer can run. Carries field-level codes, including the norms/R90 reference codes norms_subject_not_found, r90_subject_not_found, norms_point_not_found, r90_point_not_found (aitd-015/016). Also the status carrier for 401/403/404/405/415 envelope errors.",
      "whenRaised": "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.",
      "clientFix": "Correct the request shape or query parameter. Do not retry the same body under a new idempotency key.",
      "rawDbEffect": "No new alpha.analytics_* row is written. analytics_source_import, when present, records status=rejected and materialized_row_count=0.",
      "example": "normsSet=2026, completionScope=course_component, window_end before window_start, or tenantId supplied in the query string.",
      "trace": [
        {
          "id": "aitd-103-axis-query-model",
          "title": "API Axis: Query Model",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-103-axis-query-model"
        },
        {
          "id": "aitd-108-axis-error-envelope",
          "title": "API Axis: Error Envelope",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-108-axis-error-envelope"
        }
      ]
    },
    {
      "code": "analytics:unsupported_parameter",
      "httpStatus": 400,
      "meaning": "A query parameter is not part of the typed query model (Vercel routing params such as path are stripped before validation).",
      "whenRaised": "A request includes a filter or sort parameter outside the typed query model.",
      "clientFix": "Use only documented filters from the table grain and endpoint contract; strip routing params before validation.",
      "rawDbEffect": "No raw-path equivalent exists for the unsupported filter; adding ad hoc WHERE clauses breaks convergence.",
      "example": "Filtering completion-rollups by raw course_component_kind instead of completion_scope/scope_id.",
      "trace": [
        {
          "id": "aitd-103-axis-query-model",
          "title": "API Axis: Query Model",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-103-axis-query-model"
        },
        {
          "id": "aitd-108-axis-error-envelope",
          "title": "API Axis: Error Envelope",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-108-axis-error-envelope"
        }
      ]
    },
    {
      "code": "analytics:adapter_rejected",
      "httpStatus": 422,
      "meaning": "A valid source-shaped row cannot be normalized, OR an expected report-source row is missing — a reconciliation error, never a silent default.",
      "whenRaised": "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.",
      "clientFix": "Repair the source mapping or upstream row, then replay the same source-shaped row idempotently.",
      "rawDbEffect": "Rejected rows appear only as typed import findings; reportable tables do not get fake partial facts.",
      "example": "A processed_facts row names an unknown subject, or a completion row points at a course the Curriculum surface cannot resolve.",
      "trace": [
        {
          "id": "aitd-001-report-source-ingestion",
          "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
        },
        {
          "id": "aitd-011-policy-and-enum-normalization",
          "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
        },
        {
          "id": "aitd-108-axis-error-envelope",
          "title": "API Axis: Error Envelope",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-108-axis-error-envelope"
        }
      ]
    },
    {
      "code": "analytics:idempotency_conflict",
      "httpStatus": 409,
      "meaning": "The same Idempotency-Key or source_fact_key was replayed with different content.",
      "whenRaised": "The same Idempotency-Key or deterministic source_fact_key is replayed with different content.",
      "clientFix": "Use the original body for replay, or submit a correction through the correction/reversal pathway.",
      "rawDbEffect": "Existing materialized rows remain unchanged; no duplicate or replacement row is written.",
      "example": "A migration replay keeps the same source_fact_key but changes active_seconds from 300 to 360.",
      "trace": [
        {
          "id": "aitd-105-axis-idempotency",
          "title": "API Axis: Idempotency Model",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-105-axis-idempotency"
        },
        {
          "id": "aitd-012-corrections-and-reversals",
          "title": "Corrections Are Signed Facts With Provenance",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-012-corrections-and-reversals"
        }
      ]
    },
    {
      "code": "analytics:schema_migration_failed",
      "httpStatus": 500,
      "meaning": "The Postgres schema-readiness path could not complete the version-gated migration or schema sentinel check.",
      "whenRaised": "Raised only by Analytics schema initialization/readiness before a route can safely use the Postgres repository.",
      "clientFix": "Retry after the platform operator resolves the schema/readiness incident; do not treat it as an adapter or import-row failure.",
      "rawDbEffect": "No report should treat this Problem as a materialized Analytics fact.",
      "example": "A cold-start schema sentinel check or idempotent migration fails before the import handler starts writing source rows.",
      "trace": [
        {
          "id": "aitd-108-axis-error-envelope",
          "title": "API Axis: Error Envelope",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-108-axis-error-envelope"
        }
      ]
    },
    {
      "code": "analytics:server_error",
      "httpStatus": 500,
      "meaning": "An unexpected runtime failure outside the typed validation, adapter, policy, source, idempotency, and schema-readiness paths.",
      "whenRaised": "Raised by the generic Analytics error envelope for uncaught runtime errors such as import-write statement timeouts.",
      "clientFix": "Capture requestId and traceId for operator support; retry only after checking idempotency and whether the platform incident has cleared.",
      "rawDbEffect": "The request failed before Analytics could guarantee the intended write/read result. Idempotent replays must use the same body and key.",
      "example": "A source-import write is canceled by Postgres statement_timeout after the schema was already ready.",
      "trace": [
        {
          "id": "aitd-108-axis-error-envelope",
          "title": "API Axis: Error Envelope",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-108-axis-error-envelope"
        }
      ]
    },
    {
      "code": "analytics:source_missing",
      "httpStatus": 409,
      "meaning": "Analytics expected an Event, Result, calendar, enrollment, or Curriculum source row, but it was not available or not closed.",
      "whenRaised": "A materializer or read-side source-ref audit cannot finish because a required upstream row is absent, tombstoned before materialization, or still open.",
      "clientFix": "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.",
      "rawDbEffect": "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.",
      "example": "A TimeSpentEvent close notification references an event id that Events has already tombstoned.",
      "trace": [
        {
          "id": "aitd-003-close-time-materialization",
          "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
        },
        {
          "id": "aitd-111-axis-privacy-retention",
          "title": "API Axis: Privacy And Retention",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-111-axis-privacy-retention"
        },
        {
          "id": "aitd-108-axis-error-envelope",
          "title": "API Axis: Error Envelope",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-108-axis-error-envelope"
        }
      ]
    },
    {
      "code": "analytics:source_unlinked",
      "httpStatus": 422,
      "meaning": "The source row exists, but Analytics cannot link it to the required Alpha student, subject, KC, course, school calendar, or policy ref.",
      "whenRaised": "Server-side normalization sees a source-shaped row whose identity or relationship keys do not resolve under the current tenant and policy value-space.",
      "clientFix": "Fix the upstream id mapping or governed alias/policy row. Do not supply a caller-normalized replacement id just for this import.",
      "rawDbEffect": "The finding is visible through import/problem counts or quality_status=source_unlinked; report queries exclude it.",
      "example": "A processed_facts row has subject=Science-notqced and no accepted subject normalization.",
      "trace": [
        {
          "id": "aitd-011-policy-and-enum-normalization",
          "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
        },
        {
          "id": "aitd-001-report-source-ingestion",
          "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
        },
        {
          "id": "aitd-108-axis-error-envelope",
          "title": "API Axis: Error Envelope",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-108-axis-error-envelope"
        }
      ]
    },
    {
      "code": "analytics:policy_pending",
      "httpStatus": 422,
      "meaning": "A required alpha.policy.* row is missing, inactive for the effective date, or lacks a governed value needed to compute the fact.",
      "whenRaised": "Analytics cannot classify time, count school days, roll up XP, interpret MAP norms, or count completion because the named policy/config value is unavailable.",
      "clientFix": "Seed or activate the policy row and replay. Reports and skill packs must not hard-code the missing value.",
      "rawDbEffect": "Rows may carry quality_status=policy_pending or null_reason=policy_pending for audit, but ordinary report queries exclude them.",
      "example": "alpha.policy.school_day has no reason mapping for a real Ed-Fi CalendarEventDescriptor.",
      "trace": [
        {
          "id": "aitd-011-policy-and-enum-normalization",
          "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
        },
        {
          "id": "aitd-108-axis-error-envelope",
          "title": "API Axis: Error Envelope",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-108-axis-error-envelope"
        }
      ]
    }
  ],
  "convergenceRules": [
    {
      "id": "tenant_scope",
      "domain": "tenant_scope",
      "question": "Which rows belong to this tenant?",
      "apiRule": "The API takes tenant_id only from the JWT claim; tenantId in URL/query/body is rejected or ignored according to the endpoint contract.",
      "rawRule": "Every raw query must filter alpha.analytics_* by tenant_id before joins, windows, counts, sorting, or paging.",
      "failureMode": "A raw report mixes demo/reviewer/production tenants and returns plausible but wrong totals.",
      "itds": [
        {
          "id": "aitd-109-axis-tenant-routing",
          "title": "API Axis: Tenant Routing",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-109-axis-tenant-routing"
        },
        {
          "id": "aitd-106-axis-auth-shape",
          "title": "API Axis: Auth Shape",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-106-axis-auth-shape"
        }
      ]
    },
    {
      "id": "read_analytics_not_sources",
      "domain": "all_learning_report_metrics",
      "question": "How should a report answer a metric question?",
      "apiRule": "Reports call the named Analytics endpoint for the metric.",
      "rawRule": "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.",
      "failureMode": "Client-side math leaks platform-owned logic into skill packs and fails three-way convergence.",
      "itds": [
        {
          "id": "aitd-003-close-time-materialization",
          "title": "Facts Are Written When Sources Close Or Import, Read Never Recomputed",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-003-close-time-materialization"
        },
        {
          "id": "aitd-110-axis-conformance-evidence",
          "title": "API Axis: Conformance Evidence",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-110-axis-conformance-evidence"
        }
      ]
    },
    {
      "id": "source_ref_not_source_copy",
      "domain": "storage_model",
      "question": "How do I audit a derived fact?",
      "apiRule": "Detail/sourceRefs subcollections expose authorized source ids and provenance summaries.",
      "rawRule": "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.",
      "failureMode": "A raw query looks for Caliper payload, NWEA raw fields, Results scores, or Curriculum trees duplicated in Analytics.",
      "itds": [
        {
          "id": "aitd-000-extend-only-storage",
          "title": "Analytics Is New Extend-Only Alpha Storage",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-000-extend-only-storage"
        },
        {
          "id": "aitd-102-axis-read-shape",
          "title": "API Axis: Read Shape",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-102-axis-read-shape"
        }
      ]
    },
    {
      "id": "current_rows_only",
      "domain": "corrections_and_tombstones",
      "question": "Which derived rows are reportable by default?",
      "apiRule": "Ordinary list/detail endpoints exclude superseded/tombstoned rows unless includeSuperseded=true and the caller is authorized.",
      "rawRule": "Filter superseded_at IS NULL AND source_deleted_at IS NULL for ordinary reports, then apply table-specific quality_status rules.",
      "failureMode": "A raw report double-counts corrections or invalidated source rows.",
      "itds": [
        {
          "id": "aitd-111-axis-privacy-retention",
          "title": "API Axis: Privacy And Retention",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-111-axis-privacy-retention"
        },
        {
          "id": "aitd-012-corrections-and-reversals",
          "title": "Corrections Are Signed Facts With Provenance",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-012-corrections-and-reversals"
        }
      ]
    },
    {
      "id": "signed_corrections",
      "domain": "signed_corrections",
      "question": "How do corrections affect totals?",
      "apiRule": "Analytics exposes signed source contributions and report-ready net/display totals.",
      "rawRule": "Use signed seconds_delta/negative_xp/net fields exactly as documented; do not clamp, drop, or recompute corrections locally.",
      "failureMode": "A report silently removes negative gaming XP or reversal seconds and stops reconciling.",
      "itds": [
        {
          "id": "aitd-012-corrections-and-reversals",
          "title": "Corrections Are Signed Facts With Provenance",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-012-corrections-and-reversals"
        }
      ]
    },
    {
      "id": "typed_subjects",
      "domain": "subject_normalization",
      "question": "How are source subjects handled?",
      "apiRule": "Materializers write canonical subject_id or typed null_reason/adapter Problem at write time.",
      "rawRule": "Filter/group by subject_id, not source strings such as FastMath, Vocabulary, Science-notqced, ELA, or ISEE variants.",
      "failureMode": "A raw report creates extra subjects or mixes MAP proxy subjects after policy changes.",
      "itds": [
        {
          "id": "aitd-011-policy-and-enum-normalization",
          "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
        }
      ]
    },
    {
      "id": "minutes_school_day",
      "domain": "minutes_per_enrolled_school_day",
      "question": "Is the school-day denominator available, and if so how many active minutes per enrolled school day did this student have?",
      "apiRule": "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.",
      "rawRule": "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.",
      "failureMode": "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.",
      "itds": [
        {
          "id": "aitd-006-school-day-minutes",
          "title": "Minutes Per Enrolled School Day Uses The Alpha School Calendar",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-006-school-day-minutes"
        }
      ]
    },
    {
      "id": "xp_totals",
      "domain": "xp_totals",
      "question": "How much XP did a student earn, how much remains, and what percent of the XP goal is complete?",
      "apiRule": "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.",
      "rawRule": "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.",
      "failureMode": "A client sums TimeBack processed_facts.xp_earned or xp_ledger, then computes goals, remaining XP, or a capped percent locally.",
      "itds": [
        {
          "id": "aitd-007-xp-rollups",
          "title": "XP Totals, Goal, Remaining, And Completion Percent Are Ingested Report Facts",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-007-xp-rollups"
        },
        {
          "id": "aitd-001-report-source-ingestion",
          "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
        },
        {
          "id": "aitd-004-provenance-no-literals",
          "title": "Every Report Value Traces To An Ingested Source Row, Or Reads Null",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-004-provenance-no-literals"
        }
      ]
    },
    {
      "id": "accuracy_rollup",
      "domain": "accuracy_percent",
      "question": "What percent of reportable questions did the student answer correctly?",
      "apiRule": "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.",
      "rawRule": "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%.",
      "failureMode": "A report computes accuracy by summing raw processed_facts, counting QTI/Events attempts, keeping a private app/source allowlist, or dividing and rounding locally.",
      "itds": [
        {
          "id": "aitd-001-report-source-ingestion",
          "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
        },
        {
          "id": "aitd-004-provenance-no-literals",
          "title": "Every Report Value Traces To An Ingested Source Row, Or Reads Null",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-004-provenance-no-literals"
        },
        {
          "id": "aitd-011-policy-and-enum-normalization",
          "title": "Policy, Subject, Window, And Quality Values Are Typed Server-Side At Write Time",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-011-policy-and-enum-normalization"
        }
      ]
    },
    {
      "id": "mastery_delta_not_state",
      "domain": "mastery_delta",
      "question": "Which KCs changed between dates?",
      "apiRule": "GET /mastery-deltas filters by effective_at and state_dimension.",
      "rawRule": "Query alpha.analytics_mastery_delta; current state remains Results student_kc_state and mastery math remains Results/Policy.",
      "failureMode": "A report rebuilds mastery/decay/HMG from attempts or treats Analytics as current state of record.",
      "itds": [
        {
          "id": "aitd-008-mastery-and-grade-levels",
          "title": "Grade Levels Mastered Are Ingested; Mastery Deltas Read Results State",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-008-mastery-and-grade-levels"
        }
      ]
    },
    {
      "id": "map_norms_windows",
      "domain": "rit_growthx_map_windows",
      "question": "What RIT and Growth X did the student have under a norms set?",
      "apiRule": "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.",
      "rawRule": "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.",
      "failureMode": "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.",
      "itds": [
        {
          "id": "aitd-009-map-growth-rollups",
          "title": "MAP RIT And Growth X Are Ingested From hp_map_results, Deduped, And Norms-Calculated",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-009-map-growth-rollups"
        },
        {
          "id": "aitd-001-report-source-ingestion",
          "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
        }
      ]
    },
    {
      "id": "scale_reference_resources",
      "domain": "percentile_rit_r90_translation",
      "question": "What RIT maps to a percentile, and what R90/effective grade maps to a RIT?",
      "apiRule": "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.",
      "rawRule": "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.",
      "failureMode": "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.",
      "itds": [
        {
          "id": "aitd-015-norms-r90-readable-resources",
          "title": "NWEA Norms And NWEAMAP R90 Are Versioned, Readable Surface Reference Tables",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-015-norms-r90-readable-resources"
        },
        {
          "id": "aitd-016-scale-translation-apis",
          "title": "Percentile<->RIT And RIT->R90/Grade Are Server-Side Surface Translations",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-016-scale-translation-apis"
        },
        {
          "id": "aitd-017-r90-version-supersession",
          "title": "RIT-to-grade Table Versioning: PowerPath v2026-06-15 Is The Current Version, And One Named Config Picks It For Every Path",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-017-r90-version-supersession"
        }
      ]
    },
    {
      "id": "goals_school_days_remaining",
      "domain": "goals_target_date_school_days",
      "question": "How many instructional days remain, and what daily effort is needed to finish by the target date?",
      "apiRule": "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.",
      "rawRule": "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.",
      "failureMode": "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.",
      "itds": [
        {
          "id": "aitd-018-goals-school-days-remaining",
          "title": "GOALS School-Days-Remaining Read And XP Expected-Minute Unit Live On Analytics",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-018-goals-school-days-remaining"
        },
        {
          "id": "aitd-006-school-day-minutes",
          "title": "Minutes Per Enrolled School Day Uses The Alpha School Calendar",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-006-school-day-minutes"
        },
        {
          "id": "aitd-007-xp-rollups",
          "title": "XP Totals, Goal, Remaining, And Completion Percent Are Ingested Report Facts",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-007-xp-rollups"
        }
      ]
    },
    {
      "id": "completion_scope",
      "domain": "completion_percent",
      "question": "What progress evidence exists for a course/subject/track?",
      "apiRule": "GET /completion-rollups returns xp_earned, xp_remaining, completion_percent, source_import_id, and null_reason as Analytics evidence. Reads are page-bounded and ordinary responses include only current rows.",
      "rawRule": "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. For reviewer/debug probe tenants, do not request or process superseded history; retention keeps latest current rows and sweeps superseded rows under alpha.policy.analytics.completion_rollup_retention.v2026-07-03.",
      "failureMode": "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.",
      "itds": [
        {
          "id": "aitd-010-completion-rollups",
          "title": "Completion Percent Is Ingested Earned XP Over A Curriculum Denominator, Never Invented",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-010-completion-rollups"
        },
        {
          "id": "aitd-001-report-source-ingestion",
          "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
        },
        {
          "id": "aitd-004-provenance-no-literals",
          "title": "Every Report Value Traces To An Ingested Source Row, Or Reads Null",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-004-provenance-no-literals"
        }
      ]
    },
    {
      "id": "source_import_status",
      "domain": "source_shaped_imports",
      "question": "Did source-shaped import materialize rows?",
      "apiRule": "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.",
      "rawRule": "Migration checks count readable alpha.analytics_* rows plus analytics_source_import.materialized_row_count, not submitted source rows or Problem bodies.",
      "failureMode": "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.",
      "itds": [
        {
          "id": "aitd-001-report-source-ingestion",
          "title": "Report-Grade Facts Are Ingested From The Report Source, Never Re-Derived",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-001-report-source-ingestion"
        },
        {
          "id": "aitd-108-axis-error-envelope",
          "title": "API Axis: Error Envelope",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-108-axis-error-envelope"
        },
        {
          "id": "aitd-110-axis-conformance-evidence",
          "title": "API Axis: Conformance Evidence",
          "status": "Accepted",
          "owner": "TimeBack Platform Architecture",
          "href": "https://platform3-andymontgomery-9773s-projects.vercel.app/analytics/alpha/architecture#aitd-110-axis-conformance-evidence"
        }
      ]
    }
  ],
  "sourceEvidence": {
    "freshQueriedWith": "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.",
    "freshTokenQueryAttempt": {
      "attempted_at": "2026-06-10T23:45:00Z",
      "query_tool": "node loop/nweamap/vendor/skill-pack-baseline/nwea-map-analysis/scripts/timeback-query.mjs --token-file ~/Documents/timeback-danny-mcp-creds --database reporting",
      "queries_attempted": [
        "select table_name, column_name, data_type from information_schema.columns where table_schema = 'public' and table_name in ('processed_facts','hp_map_results','assessment_results','courses','course_components') order by table_name, ordinal_position",
        "select 1 as ok"
      ],
      "result": "Both read-only probes hung with no stdout for more than 60 seconds; the stuck node processes were terminated so the loop would not leave background work running.",
      "fallback_used": "Approved Analytics architecture evidence at loop/analytics/artifacts/alpha/architecture/source/evidence/report-source-grounding.json, produced from the same reporting DB value-space, plus existing PII-safe evidence files in this data_dictionary source/evidence directory.",
      "data_safety": "No PII or raw report rows were emitted by the hung probes."
    },
    "attempt4ReportingVisibilityCheck": [
      {
        "checked_at": "2026-06-12T19:50:19-04:00",
        "purpose": "Attempt 4 recheck that the token-file path was exercised before rebuilding the data dictionary.",
        "queries": [
          {
            "helper": "/Users/andymontgomery/.codex/skills/timeback/scripts/timeback-query.mjs",
            "database": "timeback",
            "shape": "PII-safe reporting.processed_facts aggregate over total_questions and correct_questions",
            "result": "empty_result_set"
          },
          {
            "helper": "/Users/andymontgomery/.codex/skills/timeback/scripts/timeback-query.mjs",
            "database": "timeback",
            "shape": "information_schema visibility check for schema='reporting'",
            "result": "empty_result_set"
          },
          {
            "helper": "loop/nweamap/vendor/skill-pack-baseline/nwea-map-analysis/scripts/timeback-query.mjs",
            "database": "timeback",
            "shape": "PII-safe reporting.processed_facts aggregate over total_questions and correct_questions",
            "result": "empty_result_set"
          }
        ],
        "interpretation": "The current token-file helper path did not expose the separate reporting schema during attempt 4. The data dictionary therefore continues to rely on the approved Analytics architecture grounding and the existing 2026-06-12 PII-safe aggregate evidence for reporting.processed_facts accuracy columns; it does not invent replacement values."
      }
    ],
    "freshHpMapResultsFullRowProbe": [],
    "freshHpMapResultsColumnProbe": [],
    "freshReportingColumns20260612": [
      {
        "table_name": "assessment_results",
        "column_name": "sourced_id",
        "data_type": "text"
      },
      {
        "table_name": "assessment_results",
        "column_name": "status",
        "data_type": "USER-DEFINED"
      },
      {
        "table_name": "assessment_results",
        "column_name": "date_last_modified",
        "data_type": "timestamp without time zone"
      },
      {
        "table_name": "assessment_results",
        "column_name": "metadata",
        "data_type": "jsonb"
      },
      {
        "table_name": "assessment_results",
        "column_name": "assessment_line_item_sourced_id",
        "data_type": "text"
      },
      {
        "table_name": "assessment_results",
        "column_name": "student_sourced_id",
        "data_type": "text"
      },
      {
        "table_name": "assessment_results",
        "column_name": "score",
        "data_type": "real"
      },
      {
        "table_name": "assessment_results",
        "column_name": "text_score",
        "data_type": "text"
      },
      {
        "table_name": "assessment_results",
        "column_name": "score_date",
        "data_type": "timestamp without time zone"
      },
      {
        "table_name": "assessment_results",
        "column_name": "score_scale_sourced_id",
        "data_type": "text"
      },
      {
        "table_name": "assessment_results",
        "column_name": "score_percentile",
        "data_type": "real"
      },
      {
        "table_name": "assessment_results",
        "column_name": "score_status",
        "data_type": "USER-DEFINED"
      },
      {
        "table_name": "assessment_results",
        "column_name": "comment",
        "data_type": "text"
      },
      {
        "table_name": "assessment_results",
        "column_name": "learning_objective_set",
        "data_type": "jsonb"
      },
      {
        "table_name": "assessment_results",
        "column_name": "in_progress",
        "data_type": "boolean"
      },
      {
        "table_name": "assessment_results",
        "column_name": "incomplete",
        "data_type": "boolean"
      },
      {
        "table_name": "assessment_results",
        "column_name": "late",
        "data_type": "boolean"
      },
      {
        "table_name": "assessment_results",
        "column_name": "missing",
        "data_type": "boolean"
      },
      {
        "table_name": "assessment_results",
        "column_name": "tenant_id",
        "data_type": "uuid"
      },
      {
        "table_name": "assessment_results",
        "column_name": "client_app_id",
        "data_type": "uuid"
      },
      {
        "table_name": "course_components",
        "column_name": "sourced_id",
        "data_type": "text"
      },
      {
        "table_name": "course_components",
        "column_name": "status",
        "data_type": "USER-DEFINED"
      },
      {
        "table_name": "course_components",
        "column_name": "date_last_modified",
        "data_type": "timestamp without time zone"
      },
      {
        "table_name": "course_components",
        "column_name": "metadata",
        "data_type": "jsonb"
      },
      {
        "table_name": "course_components",
        "column_name": "course_sourced_id",
        "data_type": "text"
      },
      {
        "table_name": "course_components",
        "column_name": "parent_sourced_id",
        "data_type": "text"
      },
      {
        "table_name": "course_components",
        "column_name": "title",
        "data_type": "text"
      },
      {
        "table_name": "course_components",
        "column_name": "sort_order",
        "data_type": "integer"
      },
      {
        "table_name": "course_components",
        "column_name": "prerequisites",
        "data_type": "ARRAY"
      },
      {
        "table_name": "course_components",
        "column_name": "prerequisite_criteria",
        "data_type": "text"
      },
      {
        "table_name": "course_components",
        "column_name": "unlock_date",
        "data_type": "timestamp without time zone"
      },
      {
        "table_name": "course_components",
        "column_name": "tenant_id",
        "data_type": "uuid"
      },
      {
        "table_name": "course_components",
        "column_name": "client_app_id",
        "data_type": "uuid"
      },
      {
        "table_name": "courses",
        "column_name": "sourced_id",
        "data_type": "text"
      },
      {
        "table_name": "courses",
        "column_name": "status",
        "data_type": "USER-DEFINED"
      },
      {
        "table_name": "courses",
        "column_name": "date_last_modified",
        "data_type": "timestamp without time zone"
      },
      {
        "table_name": "courses",
        "column_name": "metadata",
        "data_type": "jsonb"
      },
      {
        "table_name": "courses",
        "column_name": "title",
        "data_type": "text"
      },
      {
        "table_name": "courses",
        "column_name": "school_year_sourced_id",
        "data_type": "text"
      },
      {
        "table_name": "courses",
        "column_name": "course_code",
        "data_type": "text"
      },
      {
        "table_name": "courses",
        "column_name": "org_sourced_id",
        "data_type": "text"
      },
      {
        "table_name": "courses",
        "column_name": "level",
        "data_type": "text"
      },
      {
        "table_name": "courses",
        "column_name": "grading_scheme",
        "data_type": "text"
      },
      {
        "table_name": "courses",
        "column_name": "grades",
        "data_type": "ARRAY"
      },
      {
        "table_name": "courses",
        "column_name": "subjects",
        "data_type": "ARRAY"
      },
      {
        "table_name": "courses",
        "column_name": "subject_codes",
        "data_type": "ARRAY"
      },
      {
        "table_name": "courses",
        "column_name": "tenant_id",
        "data_type": "uuid"
      },
      {
        "table_name": "courses",
        "column_name": "client_app_id",
        "data_type": "uuid"
      },
      {
        "table_name": "courses",
        "column_name": "primary_app_sourced_id",
        "data_type": "text"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "id",
        "data_type": "integer"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "termname",
        "data_type": "text"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "districtname",
        "data_type": "text"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "district_stateid",
        "data_type": "text"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "schoolname",
        "data_type": "text"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "school_stateid",
        "data_type": "text"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "studentid",
        "data_type": "text"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "student_stateid",
        "data_type": "text"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "subject",
        "data_type": "text"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "course",
        "data_type": "text"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "growthmeasureyn",
        "data_type": "text"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "normsreferencedata",
        "data_type": "integer"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "wiselectedayfall",
        "data_type": "integer"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "wiselectedaywinter",
        "data_type": "integer"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "wiselectedayspring",
        "data_type": "integer"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "wipreviousayfall",
        "data_type": "integer"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "wipreviousaywinter",
        "data_type": "integer"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "wipreviousayspring",
        "data_type": "integer"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "testtype",
        "data_type": "text"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "testname",
        "data_type": "text"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "testid",
        "data_type": "text"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "teststartdate",
        "data_type": "date"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "teststarttime",
        "data_type": "time without time zone"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "testdurationminutes",
        "data_type": "integer"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "testritscore",
        "data_type": "integer"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "teststandarderror",
        "data_type": "numeric"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "testpercentile",
        "data_type": "integer"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "achievementquintile",
        "data_type": "text"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "percentcorrect",
        "data_type": "integer"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "rapidguessingpercentage",
        "data_type": "numeric"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "falltofallprojectedgrowth",
        "data_type": "numeric"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "falltofallobservedgrowth",
        "data_type": "numeric"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "falltofallobservedgrowthse",
        "data_type": "numeric"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "falltofallmetprojectedgrowth",
        "data_type": "text"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "falltofallconditionalgrowthindex",
        "data_type": "numeric"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "falltofallconditionalgrowthpercentile",
        "data_type": "numeric"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "falltofallgrowthquintile",
        "data_type": "text"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "falltowinterprojectedgrowth",
        "data_type": "numeric"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "falltowinterobservedgrowth",
        "data_type": "numeric"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "falltowinterobservedgrowthse",
        "data_type": "numeric"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "falltowintermetprojectedgrowth",
        "data_type": "text"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "falltowinterconditionalgrowthindex",
        "data_type": "numeric"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "falltowinterconditionalgrowthpercentile",
        "data_type": "numeric"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "falltowintergrowthquintile",
        "data_type": "text"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "falltospringprojectedgrowth",
        "data_type": "numeric"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "falltospringobservedgrowth",
        "data_type": "numeric"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "falltospringobservedgrowthse",
        "data_type": "numeric"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "falltospringmetprojectedgrowth",
        "data_type": "text"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "falltospringconditionalgrowthindex",
        "data_type": "numeric"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "falltospringconditionalgrowthpercentile",
        "data_type": "numeric"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "falltospringgrowthquintile",
        "data_type": "text"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "wintertowinterprojectedgrowth",
        "data_type": "numeric"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "wintertowinterobservedgrowth",
        "data_type": "numeric"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "wintertowinterobservedgrowthse",
        "data_type": "numeric"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "wintertowintermetprojectedgrowth",
        "data_type": "text"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "wintertowinterconditionalgrowthindex",
        "data_type": "numeric"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "wintertowinterconditionalgrowthpercentile",
        "data_type": "numeric"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "wintertowintergrowthquintile",
        "data_type": "text"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "wintertospringprojectedgrowth",
        "data_type": "numeric"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "wintertospringobservedgrowth",
        "data_type": "numeric"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "wintertospringobservedgrowthse",
        "data_type": "numeric"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "wintertospringmetprojectedgrowth",
        "data_type": "text"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "wintertospringconditionalgrowthindex",
        "data_type": "numeric"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "wintertospringconditionalgrowthpercentile",
        "data_type": "numeric"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "wintertospringgrowthquintile",
        "data_type": "text"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "springtospringprojectedgrowth",
        "data_type": "numeric"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "springtospringobservedgrowth",
        "data_type": "numeric"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "springtospringobservedgrowthse",
        "data_type": "numeric"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "springtospringmetprojectedgrowth",
        "data_type": "text"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "springtospringconditionalgrowthindex",
        "data_type": "numeric"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "springtospringconditionalgrowthpercentile",
        "data_type": "numeric"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "springtospringgrowthquintile",
        "data_type": "text"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "lexilescore",
        "data_type": "text"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "lexilemin",
        "data_type": "text"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "lexilemax",
        "data_type": "text"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "quantilescore",
        "data_type": "text"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "quantilemin",
        "data_type": "text"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "quantilemax",
        "data_type": "text"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "goal1name",
        "data_type": "text"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "goal1ritscore",
        "data_type": "numeric"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "goal1stderr",
        "data_type": "numeric"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "goal1range",
        "data_type": "text"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "goal1adjective",
        "data_type": "text"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "goal2name",
        "data_type": "text"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "goal2ritscore",
        "data_type": "numeric"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "goal2stderr",
        "data_type": "numeric"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "goal2range",
        "data_type": "text"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "goal2adjective",
        "data_type": "text"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "goal3name",
        "data_type": "text"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "goal3ritscore",
        "data_type": "numeric"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "goal3stderr",
        "data_type": "numeric"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "goal3range",
        "data_type": "text"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "goal3adjective",
        "data_type": "text"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "goal4name",
        "data_type": "text"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "goal4ritscore",
        "data_type": "numeric"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "goal4stderr",
        "data_type": "numeric"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "goal4range",
        "data_type": "text"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "goal4adjective",
        "data_type": "text"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "goal5name",
        "data_type": "text"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "goal5ritscore",
        "data_type": "numeric"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "goal5stderr",
        "data_type": "numeric"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "goal5range",
        "data_type": "text"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "goal5adjective",
        "data_type": "text"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "goal6name",
        "data_type": "text"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "goal6ritscore",
        "data_type": "numeric"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "goal6stderr",
        "data_type": "numeric"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "goal6range",
        "data_type": "text"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "goal6adjective",
        "data_type": "text"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "goal7name",
        "data_type": "text"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "goal7ritscore",
        "data_type": "numeric"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "goal7stderr",
        "data_type": "numeric"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "goal7range",
        "data_type": "text"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "goal7adjective",
        "data_type": "text"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "goal8name",
        "data_type": "text"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "goal8ritscore",
        "data_type": "numeric"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "goal8stderr",
        "data_type": "numeric"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "goal8range",
        "data_type": "text"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "goal8adjective",
        "data_type": "text"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "typicalfalltofallgrowth",
        "data_type": "numeric"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "typicalfalltowintergrowth",
        "data_type": "numeric"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "typicalfalltospringgrowth",
        "data_type": "numeric"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "typicalwintertowintergrowth",
        "data_type": "numeric"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "typicalwintertospringgrowth",
        "data_type": "numeric"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "typicalspringtospringgrowth",
        "data_type": "numeric"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "projectedproficiencystudy1",
        "data_type": "text"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "projectedproficiencylevel1",
        "data_type": "text"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "projectedproficiencystudy2",
        "data_type": "text"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "projectedproficiencylevel2",
        "data_type": "text"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "projectedproficiencystudy3",
        "data_type": "text"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "projectedproficiencylevel3",
        "data_type": "text"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "projectedproficiencystudy4",
        "data_type": "text"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "projectedproficiencylevel4",
        "data_type": "text"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "projectedproficiencystudy5",
        "data_type": "text"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "projectedproficiencylevel5",
        "data_type": "text"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "projectedproficiencystudy6",
        "data_type": "text"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "projectedproficiencylevel6",
        "data_type": "text"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "projectedproficiencystudy7",
        "data_type": "text"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "projectedproficiencylevel7",
        "data_type": "text"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "projectedproficiencystudy8",
        "data_type": "text"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "projectedproficiencylevel8",
        "data_type": "text"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "projectedproficiencystudy9",
        "data_type": "text"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "projectedproficiencylevel9",
        "data_type": "text"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "projectedproficiencystudy10",
        "data_type": "text"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "projectedproficiencylevel10",
        "data_type": "text"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "classname",
        "data_type": "text"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "teachername",
        "data_type": "text"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "teacherid",
        "data_type": "text"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "teacher_stateid",
        "data_type": "text"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "studentlastname",
        "data_type": "text"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "studentfirstname",
        "data_type": "text"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "studentmi",
        "data_type": "text"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "studentdateofbirth",
        "data_type": "date"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "studentethnicgroup",
        "data_type": "text"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "nweastandard_ethnicgroup",
        "data_type": "text"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "studentgender",
        "data_type": "text"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "grade",
        "data_type": "text"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "nweastandard_grade",
        "data_type": "text"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "learningrate",
        "data_type": "numeric"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "termprojectedgrowth",
        "data_type": "numeric"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "termobservedgrowth",
        "data_type": "numeric"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "teststartdatelatestinterm",
        "data_type": "date"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "minstandarderror",
        "data_type": "numeric"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "springtospringprojectedgrowth_forward",
        "data_type": "numeric"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "falltospringprojectedgrowth_forward",
        "data_type": "numeric"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "wintertospringprojectedgrowth_forward",
        "data_type": "numeric"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "falltofallprojectedgrowth_forward",
        "data_type": "numeric"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "falltowinterprojectedgrowth_forward",
        "data_type": "numeric"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "wintertowinterprojectedgrowth_forward",
        "data_type": "numeric"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "email",
        "data_type": "text"
      },
      {
        "table_name": "hp_map_results",
        "column_name": "sourced_id",
        "data_type": "text"
      },
      {
        "table_name": "processed_facts",
        "column_name": "id",
        "data_type": "integer"
      },
      {
        "table_name": "processed_facts",
        "column_name": "email",
        "data_type": "character varying"
      },
      {
        "table_name": "processed_facts",
        "column_name": "date",
        "data_type": "date"
      },
      {
        "table_name": "processed_facts",
        "column_name": "datetime",
        "data_type": "timestamp without time zone"
      },
      {
        "table_name": "processed_facts",
        "column_name": "username",
        "data_type": "character varying"
      },
      {
        "table_name": "processed_facts",
        "column_name": "user_grade",
        "data_type": "character varying"
      },
      {
        "table_name": "processed_facts",
        "column_name": "user_family_name",
        "data_type": "character varying"
      },
      {
        "table_name": "processed_facts",
        "column_name": "user_given_name",
        "data_type": "character varying"
      },
      {
        "table_name": "processed_facts",
        "column_name": "user_id",
        "data_type": "character varying"
      },
      {
        "table_name": "processed_facts",
        "column_name": "subject",
        "data_type": "character varying"
      },
      {
        "table_name": "processed_facts",
        "column_name": "app",
        "data_type": "character varying"
      },
      {
        "table_name": "processed_facts",
        "column_name": "course_id",
        "data_type": "character varying"
      },
      {
        "table_name": "processed_facts",
        "column_name": "course_name",
        "data_type": "character varying"
      },
      {
        "table_name": "processed_facts",
        "column_name": "campus_id",
        "data_type": "character varying"
      },
      {
        "table_name": "processed_facts",
        "column_name": "campus_name",
        "data_type": "character varying"
      },
      {
        "table_name": "processed_facts",
        "column_name": "enrollment_id",
        "data_type": "character varying"
      },
      {
        "table_name": "processed_facts",
        "column_name": "activity_id",
        "data_type": "character varying"
      },
      {
        "table_name": "processed_facts",
        "column_name": "activity_name",
        "data_type": "character varying"
      },
      {
        "table_name": "processed_facts",
        "column_name": "total_questions",
        "data_type": "integer"
      },
      {
        "table_name": "processed_facts",
        "column_name": "correct_questions",
        "data_type": "integer"
      },
      {
        "table_name": "processed_facts",
        "column_name": "xp_earned",
        "data_type": "numeric"
      },
      {
        "table_name": "processed_facts",
        "column_name": "mastered_units",
        "data_type": "integer"
      },
      {
        "table_name": "processed_facts",
        "column_name": "active_seconds",
        "data_type": "numeric"
      },
      {
        "table_name": "processed_facts",
        "column_name": "inactive_seconds",
        "data_type": "numeric"
      },
      {
        "table_name": "processed_facts",
        "column_name": "waste_seconds",
        "data_type": "numeric"
      },
      {
        "table_name": "processed_facts",
        "column_name": "source",
        "data_type": "character varying"
      },
      {
        "table_name": "processed_facts",
        "column_name": "alpha_level",
        "data_type": "character varying"
      },
      {
        "table_name": "processed_facts",
        "column_name": "generated_at",
        "data_type": "timestamp without time zone"
      },
      {
        "table_name": "processed_facts",
        "column_name": "send_time",
        "data_type": "timestamp without time zone"
      },
      {
        "table_name": "processed_facts",
        "column_name": "sensor",
        "data_type": "character varying"
      },
      {
        "table_name": "processed_facts",
        "column_name": "event_type",
        "data_type": "character varying"
      },
      {
        "table_name": "processed_facts",
        "column_name": "year",
        "data_type": "integer"
      },
      {
        "table_name": "processed_facts",
        "column_name": "month",
        "data_type": "integer"
      },
      {
        "table_name": "processed_facts",
        "column_name": "day",
        "data_type": "integer"
      },
      {
        "table_name": "processed_facts",
        "column_name": "day_of_week",
        "data_type": "integer"
      },
      {
        "table_name": "processed_facts",
        "column_name": "session_id",
        "data_type": "character varying"
      },
      {
        "table_name": "processed_facts",
        "column_name": "source_system",
        "data_type": "character varying"
      },
      {
        "table_name": "processed_facts",
        "column_name": "score_type",
        "data_type": "character varying"
      },
      {
        "table_name": "processed_facts",
        "column_name": "max_score",
        "data_type": "numeric"
      },
      {
        "table_name": "processed_facts",
        "column_name": "original_event_type",
        "data_type": "character varying"
      },
      {
        "table_name": "processed_facts",
        "column_name": "original_event_id",
        "data_type": "character varying"
      },
      {
        "table_name": "processed_facts",
        "column_name": "action",
        "data_type": "character varying"
      },
      {
        "table_name": "processed_facts",
        "column_name": "score_given",
        "data_type": "numeric"
      },
      {
        "table_name": "processed_facts",
        "column_name": "object_type",
        "data_type": "character varying"
      },
      {
        "table_name": "processed_facts",
        "column_name": "parent_object_id",
        "data_type": "character varying"
      }
    ],
    "freshReportingProcessedFactsSubjectSummary20260612": [
      {
        "subject": "Writing",
        "n": 4974715,
        "active_seconds": 79160252.57,
        "inactive_seconds": 7.08,
        "waste_seconds": 0,
        "xp_earned": 1226124.18
      },
      {
        "subject": "Math",
        "n": 4039603,
        "active_seconds": 364972640.26,
        "inactive_seconds": 3822941.95,
        "waste_seconds": 452971.58,
        "xp_earned": 4434337.04
      },
      {
        "subject": "Language",
        "n": 2219490,
        "active_seconds": 158829436.14,
        "inactive_seconds": 618341.92,
        "waste_seconds": 311330.7,
        "xp_earned": 4924056.48
      },
      {
        "subject": "FastMath",
        "n": 2022748,
        "active_seconds": 70873766.86,
        "inactive_seconds": 480024.9,
        "waste_seconds": 38471840.1,
        "xp_earned": 1072054.64
      },
      {
        "subject": "Reading",
        "n": 1805944,
        "active_seconds": 180023835.5,
        "inactive_seconds": 559883.94,
        "waste_seconds": 124753.45,
        "xp_earned": 2979423.42
      },
      {
        "subject": "Social Studies",
        "n": 699552,
        "active_seconds": 11529499.33,
        "inactive_seconds": 3501554.5,
        "waste_seconds": 162669.99,
        "xp_earned": 358718.83
      },
      {
        "subject": "Science",
        "n": 546393,
        "active_seconds": 80107538.43,
        "inactive_seconds": 837338.19,
        "waste_seconds": 611348.02,
        "xp_earned": 1571641.41
      },
      {
        "subject": "Vocabulary",
        "n": 269936,
        "active_seconds": 8276420.16,
        "inactive_seconds": 198372.5,
        "waste_seconds": 0,
        "xp_earned": 1081696.58
      },
      {
        "subject": "None",
        "n": 38717,
        "active_seconds": 718490.02,
        "inactive_seconds": 8109.91,
        "waste_seconds": 12310.9,
        "xp_earned": 0
      },
      {
        "subject": "(blank)",
        "n": 13505,
        "active_seconds": 0,
        "inactive_seconds": 0,
        "waste_seconds": 0,
        "xp_earned": -24549
      },
      {
        "subject": "Other",
        "n": 3613,
        "active_seconds": 65648.85,
        "inactive_seconds": 1237.93,
        "waste_seconds": 0,
        "xp_earned": 32202
      },
      {
        "subject": "Biology",
        "n": 85,
        "active_seconds": 0,
        "inactive_seconds": 0,
        "waste_seconds": 0,
        "xp_earned": 0
      },
      {
        "subject": "Mathematics",
        "n": 30,
        "active_seconds": 0,
        "inactive_seconds": 0,
        "waste_seconds": 0,
        "xp_earned": 165
      },
      {
        "subject": "ELA",
        "n": 3,
        "active_seconds": 0,
        "inactive_seconds": 0,
        "waste_seconds": 0,
        "xp_earned": 35
      }
    ],
    "freshReportingHpMapWindowSummary20260612": [
      {
        "subject": "Reading",
        "termname": "Winter 2025-2026",
        "n": 5449,
        "rit_rows": 5449,
        "wtw_observed_rows": 329,
        "wtw_projected_rows": 313,
        "wtw_cgp_rows": 313,
        "min_rit": 136,
        "max_rit": 267
      },
      {
        "subject": "Math",
        "termname": "Fall 2025-2026",
        "n": 5272,
        "rit_rows": 5272,
        "wtw_observed_rows": 0,
        "wtw_projected_rows": 0,
        "wtw_cgp_rows": 0,
        "min_rit": 104,
        "max_rit": 307
      },
      {
        "subject": "Reading",
        "termname": "Fall 2025-2026",
        "n": 4740,
        "rit_rows": 4740,
        "wtw_observed_rows": 0,
        "wtw_projected_rows": 0,
        "wtw_cgp_rows": 0,
        "min_rit": 123,
        "max_rit": 267
      },
      {
        "subject": "Language",
        "termname": "Fall 2025-2026",
        "n": 4648,
        "rit_rows": 4648,
        "wtw_observed_rows": 0,
        "wtw_projected_rows": 0,
        "wtw_cgp_rows": 0,
        "min_rit": 136,
        "max_rit": 272
      },
      {
        "subject": "Language",
        "termname": "Winter 2025-2026",
        "n": 4392,
        "rit_rows": 4392,
        "wtw_observed_rows": 227,
        "wtw_projected_rows": 221,
        "wtw_cgp_rows": 221,
        "min_rit": 137,
        "max_rit": 267
      },
      {
        "subject": "Math",
        "termname": "Winter 2025-2026",
        "n": 3940,
        "rit_rows": 3940,
        "wtw_observed_rows": 328,
        "wtw_projected_rows": 312,
        "wtw_cgp_rows": 312,
        "min_rit": 123,
        "max_rit": 314
      },
      {
        "subject": "Reading",
        "termname": "Spring 2025-2026",
        "n": 3552,
        "rit_rows": 3552,
        "wtw_observed_rows": 0,
        "wtw_projected_rows": 0,
        "wtw_cgp_rows": 0,
        "min_rit": 143,
        "max_rit": 278
      },
      {
        "subject": "Language",
        "termname": "Spring 2025-2026",
        "n": 3075,
        "rit_rows": 3075,
        "wtw_observed_rows": 0,
        "wtw_projected_rows": 0,
        "wtw_cgp_rows": 0,
        "min_rit": 140,
        "max_rit": 289
      },
      {
        "subject": "Math",
        "termname": "Spring 2025-2026",
        "n": 2499,
        "rit_rows": 2499,
        "wtw_observed_rows": 0,
        "wtw_projected_rows": 0,
        "wtw_cgp_rows": 0,
        "min_rit": 144,
        "max_rit": 323
      },
      {
        "subject": "Science",
        "termname": "Winter 2025-2026",
        "n": 2155,
        "rit_rows": 2155,
        "wtw_observed_rows": 196,
        "wtw_projected_rows": 196,
        "wtw_cgp_rows": 196,
        "min_rit": 159,
        "max_rit": 276
      },
      {
        "subject": "Science",
        "termname": "Spring 2025-2026",
        "n": 1610,
        "rit_rows": 1610,
        "wtw_observed_rows": 0,
        "wtw_projected_rows": 0,
        "wtw_cgp_rows": 0,
        "min_rit": 158,
        "max_rit": 282
      },
      {
        "subject": "Science",
        "termname": "Fall 2025-2026",
        "n": 861,
        "rit_rows": 861,
        "wtw_observed_rows": 0,
        "wtw_projected_rows": 0,
        "wtw_cgp_rows": 0,
        "min_rit": 160,
        "max_rit": 271
      },
      {
        "subject": "Math",
        "termname": "Spring 2024-2025",
        "n": 642,
        "rit_rows": 642,
        "wtw_observed_rows": 0,
        "wtw_projected_rows": 0,
        "wtw_cgp_rows": 0,
        "min_rit": 127,
        "max_rit": 289
      },
      {
        "subject": "Reading",
        "termname": "Spring 2024-2025",
        "n": 580,
        "rit_rows": 580,
        "wtw_observed_rows": 0,
        "wtw_projected_rows": 0,
        "wtw_cgp_rows": 0,
        "min_rit": 116,
        "max_rit": 260
      },
      {
        "subject": "Language",
        "termname": "Spring 2024-2025",
        "n": 424,
        "rit_rows": 424,
        "wtw_observed_rows": 0,
        "wtw_projected_rows": 0,
        "wtw_cgp_rows": 0,
        "min_rit": 154,
        "max_rit": 268
      },
      {
        "subject": "Science",
        "termname": "Spring 2024-2025",
        "n": 369,
        "rit_rows": 369,
        "wtw_observed_rows": 0,
        "wtw_projected_rows": 0,
        "wtw_cgp_rows": 0,
        "min_rit": 167,
        "max_rit": 254
      }
    ],
    "freshCaliperTypeActionSummary20260612": [
      {
        "type": "TimeSpentEvent",
        "action": "SpentTime",
        "n": 13159747
      },
      {
        "type": "ActivityEvent",
        "action": "Completed",
        "n": 4194050
      },
      {
        "type": "Event",
        "action": "Created",
        "n": 34481
      },
      {
        "type": "ToolUseEvent",
        "action": "Used",
        "n": 3672
      },
      {
        "type": "AnnotationEvent",
        "action": "Tagged",
        "n": 1586
      },
      {
        "type": "AssessmentItemEvent",
        "action": "Completed",
        "n": 738
      },
      {
        "type": "SessionEvent",
        "action": "LoggedIn",
        "n": 270
      },
      {
        "type": "SessionEvent",
        "action": "LoggedOut",
        "n": 193
      },
      {
        "type": "Event",
        "action": "Achieved",
        "n": 132
      },
      {
        "type": "AssessmentItemEvent",
        "action": "Skipped",
        "n": 119
      },
      {
        "type": "AssessmentEvent",
        "action": "Submitted",
        "n": 18
      },
      {
        "type": "Event",
        "action": "Used",
        "n": 8
      },
      {
        "type": "Event",
        "action": "Completed",
        "n": 6
      },
      {
        "type": "Event",
        "action": "Viewed",
        "n": 4
      },
      {
        "type": "FeedbackEvent",
        "action": "Ranked",
        "n": 2
      },
      {
        "type": "FeedbackEvent",
        "action": "Commented",
        "n": 2
      },
      {
        "type": "GradeEvent",
        "action": "Graded",
        "n": 1
      },
      {
        "type": "AssessmentEvent",
        "action": "Started",
        "n": 1
      },
      {
        "type": "AssessmentEvent",
        "action": "Paused",
        "n": 1
      }
    ],
    "freshAccuracySourceColumns20260612": [
      {
        "column_name": "active_seconds",
        "data_type": "numeric"
      },
      {
        "column_name": "correct_questions",
        "data_type": "integer"
      },
      {
        "column_name": "total_questions",
        "data_type": "integer"
      },
      {
        "column_name": "xp_earned",
        "data_type": "numeric"
      }
    ],
    "freshAccuracySourceAggregate20260612": [
      {
        "row_count": 16636042,
        "rows_with_total_questions": 2975894,
        "rows_with_correct_questions": 2889369,
        "total_questions_sum": 59047653,
        "correct_questions_sum": 51288586
      }
    ],
    "freshAccuracySourceEvidence20260612": [],
    "freshAccuracySourceAggregate20260613": [
      {
        "row_count": 16662329,
        "rows_with_total_questions": 2980443,
        "rows_with_correct_questions": 2893838,
        "total_questions_sum": 59167608,
        "correct_questions_sum": 51390936,
        "accuracy_percent": 86.857
      }
    ],
    "currentAccuracySourceAggregate20260613": [
      {
        "row_count": 16662329,
        "rows_with_total_questions": 2980443,
        "rows_with_correct_questions": 2893838,
        "total_questions_sum": 59167608,
        "correct_questions_sum": 51390936,
        "accuracy_percent": 86.857
      }
    ],
    "currentAttemptAccuracySourceAggregate20260613": [
      {
        "row_count": 16662329,
        "rows_with_total_questions": 2980443,
        "rows_with_correct_questions": 2893838,
        "total_questions_sum": 59167608,
        "correct_questions_sum": 51390936,
        "accuracy_percent": 86.857
      }
    ],
    "currentAttemptAccuracyAuditRows": [
      {
        "attempt": 1,
        "status": "completed",
        "evidence_path": "source/evidence/attempt1-accuracy-source-aggregate-2026-06-13.json",
        "row_count": 16662329,
        "total_questions_sum": 59167608,
        "correct_questions_sum": 51390936,
        "interpretation": "Attempt 1 uses completed PII-safe aggregate evidence from the required token-file helper path; no raw source rows or student identifiers are published."
      }
    ],
    "currentAttemptAccuracyEvidencePath": "source/evidence/attempt1-accuracy-source-aggregate-2026-06-13.json",
    "currentAttemptSourceRefreshAttempt": {
      "attempt": 1,
      "checked_at": "2026-06-14T22:18:37Z",
      "status": "completed",
      "queried_with": "node loop/nweamap/vendor/skill-pack-baseline/nwea-map-analysis/scripts/timeback-query.mjs --token-file <redacted>",
      "purpose": "Current attempt read-only source refresh for alpha.analytics_accuracy question numerator/denominator value-space.",
      "pii_policy": "Aggregate-only query; no raw student rows, names, emails, or identifiers requested.",
      "queries_attempted": [
        {
          "name": "processed_facts_accuracy_aggregate",
          "purpose": "Refresh the PII-safe production value-space evidence for alpha.analytics_accuracy source numerator and denominator columns.",
          "sql_shape": "select count(*), count(total_questions), count(correct_questions), sum(total_questions), sum(correct_questions), aggregate accuracy from public.processed_facts",
          "status": "completed",
          "result": "completed",
          "elapsed_seconds": 5.17,
          "elapsed_seconds_before_cancel": 5.17,
          "out_path": "source/evidence/attempt1-accuracy-source-aggregate-2026-06-13.json",
          "out_path_requested": "source/evidence/attempt1-accuracy-source-aggregate-2026-06-13.json",
          "row_count": 16662329,
          "total_questions_sum": 59167608,
          "correct_questions_sum": 51390936
        }
      ]
    },
    "attempt1SourceRefreshAttempt20260613": {
      "attempt": 1,
      "checked_at": "2026-06-14T22:18:37Z",
      "status": "completed",
      "queried_with": "node loop/nweamap/vendor/skill-pack-baseline/nwea-map-analysis/scripts/timeback-query.mjs --token-file <redacted>",
      "purpose": "Current attempt read-only source refresh for alpha.analytics_accuracy question numerator/denominator value-space.",
      "pii_policy": "Aggregate-only query; no raw student rows, names, emails, or identifiers requested.",
      "queries_attempted": [
        {
          "name": "processed_facts_accuracy_aggregate",
          "purpose": "Refresh the PII-safe production value-space evidence for alpha.analytics_accuracy source numerator and denominator columns.",
          "sql_shape": "select count(*), count(total_questions), count(correct_questions), sum(total_questions), sum(correct_questions), aggregate accuracy from public.processed_facts",
          "status": "completed",
          "result": "completed",
          "elapsed_seconds": 5.17,
          "elapsed_seconds_before_cancel": 5.17,
          "out_path": "source/evidence/attempt1-accuracy-source-aggregate-2026-06-13.json",
          "out_path_requested": "source/evidence/attempt1-accuracy-source-aggregate-2026-06-13.json",
          "row_count": 16662329,
          "total_questions_sum": 59167608,
          "correct_questions_sum": 51390936
        }
      ]
    },
    "attempt2SourceRefreshAttempt20260613": {
      "purpose": "Attempt 2 bounded read-only token-file source refresh for the alpha.analytics_accuracy contract.",
      "queried_at": "2026-06-13T06:31:49Z",
      "query_method": "node loop/nweamap/vendor/skill-pack-baseline/nwea-map-analysis/scripts/timeback-query.mjs --token-file ~/Documents/timeback-danny-mcp-creds; credentials were not printed",
      "queries_attempted": [
        {
          "name": "processed_facts_accuracy_aggregate",
          "purpose": "Confirm current production source-shaped total_questions and correct_questions availability for alpha.analytics_accuracy without publishing student identifiers or raw source rows.",
          "result": "cancelled_after_helper_latency",
          "elapsed_seconds_before_cancel": 193,
          "out_path_requested": "source/evidence/attempt2-accuracy-source-aggregate-2026-06-13.json"
        }
      ],
      "fallback_evidence": "source/evidence/fresh-accuracy-source-aggregate-2026-06-13.json",
      "interpretation": "Attempt 2 started the required read-only token-file grounding probe, stopped it after helper latency exceeded the useful wait, and carries forward the latest completed PII-safe aggregate evidence instead of inventing replacement values."
    },
    "attempt8SourceRefreshAttempt20260613": {
      "attempt": 8,
      "checked_at": "2026-06-13T04:14:00-04:00",
      "tool": "node /Users/andymontgomery/.codex/skills/timeback/scripts/timeback-query.mjs",
      "token_file": "~/Documents/timeback-danny-mcp-creds",
      "database": "timeback",
      "queries_attempted": [
        {
          "name": "bounded_processed_facts_accuracy_aggregate",
          "purpose": "Refresh PII-safe current-attempt evidence that the source-shaped processed_facts table carries total_questions and correct_questions for alpha.analytics_accuracy.",
          "sql_shape": "select aggregate question numerator/denominator fields from a 10000-row bounded processed_facts sample where total_questions or correct_questions is present",
          "result": "cancelled_after_helper_latency",
          "elapsed_seconds_before_cancel": 65,
          "interpretation": "The read-only helper did not return within the doer window. The deliverable keeps the current stored PII-safe aggregate evidence and records this latency-limited refresh attempt rather than inventing replacement values."
        }
      ]
    },
    "attempt9SourceRefreshAttempt20260613": {
      "attempt": 9,
      "checked_at": "2026-06-13T07:55:00Z",
      "queried_with": "node loop/nweamap/vendor/skill-pack-baseline/nwea-map-analysis/scripts/timeback-query.mjs --token-file ~/Documents/timeback-danny-mcp-creds",
      "pii_policy": "Aggregate-only query; no raw student rows, names, emails, or identifiers requested.",
      "queries_attempted": [
        {
          "name": "processed_facts_accuracy_aggregate",
          "purpose": "Refresh the PII-safe production value-space evidence for alpha.analytics_accuracy source numerator and denominator columns.",
          "sql_shape": "select count(*), count(total_questions), count(correct_questions), sum(total_questions), sum(correct_questions) from public.processed_facts",
          "result": "cancelled_after_helper_latency",
          "elapsed_seconds_before_cancel": 60,
          "out_path_requested": null,
          "fallback_used": "source/evidence/attempt9-accuracy-source-aggregate-2026-06-13.json",
          "interpretation": "The required helper path was attempted for this rebuild but did not return in the bounded wait. The dictionary uses the already-completed attempt-9 PII-safe aggregate evidence rather than inventing replacement values."
        }
      ]
    },
    "attempt10SourceRefreshAttempt20260613": {
      "attempt": 10,
      "checked_at": "2026-06-13T04:40:38Z",
      "purpose": "Current attempt read-only source refresh for the Accuracy rollup value-space through the required TimeBack token-file helper.",
      "command": "node loop/nweamap/vendor/skill-pack-baseline/nwea-map-analysis/scripts/timeback-query.mjs --token-file ~/Documents/timeback-danny-mcp-creds --sql <bounded processed_facts accuracy aggregate>",
      "status": "cancelled_after_helper_latency",
      "elapsed_seconds_before_cancel": 90,
      "interpretation": "The helper did not return in the current attempt window. The data dictionary retains source/evidence/attempt10-accuracy-source-aggregate-2026-06-13.json and source/evidence/fresh-accuracy-source-aggregate-2026-06-13.json as the current PII-safe aggregate evidence instead of inventing replacement values.",
      "rechecked_at": "2026-06-13T08:02:02Z",
      "recheck_elapsed_seconds_before_cancel": 45,
      "queries_attempted": [
        {
          "name": "processed_facts_accuracy_aggregate",
          "purpose": "Bounded read-only source refresh for alpha.analytics_accuracy question numerator/denominator value-space.",
          "result": "cancelled_after_helper_latency",
          "elapsed_seconds_before_cancel": 45,
          "out_path_requested": "stdout only; no replacement evidence file written because the helper returned no rows before timeout"
        }
      ]
    },
    "attempt11SourceRefreshAttempt20260613": {
      "attempt": 11,
      "checked_at": "2026-06-13T04:50:51Z",
      "purpose": "Current attempt read-only source refresh for the Accuracy rollup value-space through the required TimeBack token-file helper.",
      "command": "timeout 35 node loop/nweamap/vendor/skill-pack-baseline/nwea-map-analysis/scripts/timeback-query.mjs --token-file ~/Documents/timeback-danny-mcp-creds --sql <processed_facts accuracy aggregate>",
      "status": "cancelled_after_helper_latency",
      "elapsed_seconds_before_cancel": 35,
      "queries_attempted": [
        {
          "name": "processed_facts_accuracy_aggregate",
          "purpose": "Refresh PII-safe current-attempt evidence that the source-shaped processed_facts table carries total_questions and correct_questions for alpha.analytics_accuracy.",
          "result": "cancelled_after_helper_latency",
          "elapsed_seconds_before_cancel": 35,
          "interpretation": "The helper did not return within the bounded doer window. The data dictionary keeps source/evidence/attempt11-accuracy-source-aggregate-2026-06-13.json and source/evidence/fresh-accuracy-source-aggregate-2026-06-13.json as current PII-safe aggregate evidence instead of inventing replacement values."
        }
      ],
      "interpretation": "The helper did not return within the bounded doer window. This attempt records the refresh attempt and keeps the existing attempt-11 PII-safe aggregate evidence rather than fabricating a new value."
    },
    "attempt12SourceRefreshAttempt20260613": {
      "attempt": 12,
      "checked_at": "2026-06-13T08:23:06Z",
      "purpose": "Current attempt read-only source refresh for the Accuracy rollup value-space through the required TimeBack token-file helper.",
      "command": "timeout 35 node loop/nweamap/vendor/skill-pack-baseline/nwea-map-analysis/scripts/timeback-query.mjs --token-file ~/Documents/timeback-danny-mcp-creds --sql <processed_facts accuracy aggregate>",
      "status": "cancelled_after_helper_latency",
      "elapsed_seconds_before_cancel": 35,
      "queries_attempted": [
        {
          "name": "processed_facts_accuracy_aggregate",
          "purpose": "Refresh PII-safe current-attempt evidence that the source-shaped processed_facts table carries total_questions and correct_questions for alpha.analytics_accuracy.",
          "result": "cancelled_after_helper_latency",
          "elapsed_seconds_before_cancel": 35,
          "interpretation": "The helper did not return within the bounded doer window. The data dictionary keeps source/evidence/attempt12-accuracy-source-aggregate-2026-06-13.json and source/evidence/fresh-accuracy-source-aggregate-2026-06-13.json as current PII-safe aggregate evidence instead of inventing replacement values."
        }
      ],
      "interpretation": "The helper did not return within the bounded doer window. This attempt records the refresh attempt and uses the completed attempt-12 PII-safe aggregate evidence rather than fabricating a replacement value."
    },
    "attempt13SourceRefreshAttempt20260613": {
      "purpose": "Attempt 13 bounded read-only refresh of processed_facts accuracy aggregate through the required TimeBack token-file helper.",
      "queried_at": "2026-06-13T05:13:31Z",
      "query_method": "node loop/nweamap/vendor/skill-pack-baseline/nwea-map-analysis/scripts/timeback-query.mjs --token-file ~/Documents/timeback-danny-mcp-creds --database timeback; credentials were not printed",
      "queries_attempted": [
        {
          "name": "bounded_processed_facts_accuracy_aggregate",
          "purpose": "Refresh PII-safe current-attempt evidence that the source-shaped public.processed_facts table carries total_questions and correct_questions for alpha.analytics_accuracy.",
          "result": "cancelled_after_helper_latency",
          "elapsed_seconds_before_cancel": 220,
          "out_path_requested": "source/evidence/attempt13-accuracy-source-aggregate-2026-06-13.json"
        }
      ],
      "fallback_used": "source/evidence/fresh-accuracy-source-aggregate-2026-06-13.json",
      "interpretation": "The helper did not return inside the bounded window, so attempt 13 carries forward the latest completed PII-safe aggregate evidence instead of inventing replacement values or relabeling a cancelled probe as completed."
    },
    "attempt16SourceRefreshAttempt20260613": {
      "attempt": 16,
      "checked_at": "2026-06-13T09:09:06Z",
      "purpose": "Current attempt read-only source refresh for the Accuracy rollup value-space through the required TimeBack token-file helper.",
      "query_method": "node loop/nweamap/vendor/skill-pack-baseline/nwea-map-analysis/scripts/timeback-query.mjs --token-file ~/Documents/timeback-danny-mcp-creds; credentials were not printed",
      "status": "cancelled_after_helper_latency",
      "queries_attempted": [
        {
          "name": "processed_facts_accuracy_full_aggregate",
          "purpose": "Refresh a PII-safe aggregate proving the source-shaped processed_facts table carries total_questions and correct_questions for alpha.analytics_accuracy.",
          "sql_shape": "select count, count(total_questions), count(correct_questions), sum(total_questions), sum(correct_questions), accuracy_percent from processed_facts",
          "result": "cancelled_after_helper_latency",
          "elapsed_seconds_before_cancel": 45,
          "out_path_requested": "source/evidence/attempt16-accuracy-source-aggregate-2026-06-13.json"
        },
        {
          "name": "processed_facts_accuracy_bounded_sample",
          "purpose": "Refresh a bounded PII-safe sample over rows where total_questions or correct_questions is present.",
          "sql_shape": "select aggregate question numerator/denominator fields from a 100000-row bounded processed_facts sample where total_questions or correct_questions is present",
          "result": "cancelled_after_helper_latency",
          "elapsed_seconds_before_cancel": 45,
          "out_path_requested": "source/evidence/attempt16-accuracy-source-sample-2026-06-13.json"
        },
        {
          "name": "timeback_token_file_smoke",
          "purpose": "Confirm the required token-file helper path is reachable without publishing credentials before carrying forward the latest completed PII-safe aggregate.",
          "sql_shape": "select 1 as ok",
          "result": "cancelled_after_helper_latency",
          "elapsed_seconds_before_cancel": 60,
          "out_path_requested": null
        }
      ],
      "fallback_used": "source/evidence/fresh-accuracy-source-aggregate-2026-06-13.json",
      "interpretation": "The helper did not return within the bounded doer window, so attempt 16 carries forward the latest completed PII-safe aggregate evidence instead of inventing replacement values or relabeling a cancelled probe as completed."
    },
    "attempt24SourceRefreshAttempt20260613": {
      "attempt": 24,
      "purpose": "Current attempt read-only source refresh for the Accuracy rollup value-space through the required TimeBack token-file helper.",
      "command": "timeout 45 node loop/nweamap/vendor/skill-pack-baseline/nwea-map-analysis/scripts/timeback-query.mjs --token-file ~/Documents/timeback-danny-mcp-creds --sql <processed_facts accuracy aggregate>",
      "queries_attempted": [
        {
          "name": "processed_facts_accuracy_aggregate",
          "purpose": "Refresh PII-safe current-attempt evidence that the source-shaped public.processed_facts table carries total_questions and correct_questions for alpha.analytics_accuracy.",
          "result": "completed",
          "elapsed_seconds_before_cancel": "not_cancelled",
          "out_path_requested": "source/evidence/attempt24-accuracy-source-aggregate-2026-06-13.json",
          "interpretation": "The helper returned an aggregate-only result with no raw source rows or student identifiers; the dictionary uses the completed attempt-24 evidence rather than carrying forward an older aggregate."
        }
      ]
    },
    "attempt25SourceRefreshAttempt20260613": {
      "attempt": 25,
      "purpose": "Current attempt read-only source refresh for the Accuracy rollup value-space through the required TimeBack token-file helper.",
      "command": "timeout 45 node loop/nweamap/vendor/skill-pack-baseline/nwea-map-analysis/scripts/timeback-query.mjs --token-file ~/Documents/timeback-danny-mcp-creds --sql <processed_facts accuracy aggregate>",
      "queries_attempted": [
        {
          "name": "processed_facts_accuracy_aggregate",
          "purpose": "Refresh PII-safe current-attempt evidence that the source-shaped public.processed_facts table carries total_questions and correct_questions for alpha.analytics_accuracy.",
          "result": "completed",
          "elapsed_seconds_before_cancel": "not_cancelled",
          "out_path_requested": "source/evidence/attempt25-accuracy-source-aggregate-2026-06-13.json",
          "interpretation": "The helper returned an aggregate-only result with no raw source rows or student identifiers; the dictionary uses the completed attempt-25 evidence rather than carrying forward an older aggregate."
        }
      ]
    },
    "attempt7SourceRefreshAttempt20260613": {
      "purpose": "Current attempt read-only source refresh for the Accuracy rollup value-space through the required TimeBack token-file helper.",
      "queried_at": "2026-06-13T07:23:15Z",
      "query_method": "node loop/nweamap/vendor/skill-pack-baseline/nwea-map-analysis/scripts/timeback-query.mjs --token-file ~/Documents/timeback-danny-mcp-creds --database reporting; credentials were not printed",
      "root_helper_status": "scripts/timeback-query.mjs was not present in this checkout, so the existing vendored TimeBack helper used by the artifact trail was used.",
      "queries_attempted": [
        {
          "name": "processed_facts_accuracy_aggregate",
          "purpose": "Refresh a PII-safe aggregate for total_questions and correct_questions over reporting.processed_facts.",
          "sql_shape": "select count, count(total_questions), count(correct_questions), sum(total_questions), sum(correct_questions) from processed_facts where total_questions is not null or correct_questions is not null",
          "result": "cancelled_after_timeout",
          "elapsed_seconds_before_cancel": 172
        },
        {
          "name": "processed_facts_accuracy_sample_aggregate",
          "purpose": "Bounded PII-safe sample aggregate for total_questions and correct_questions over reporting.processed_facts, attempted before the attempt-7 rebuild.",
          "sql_shape": "select count, count(total_questions), count(correct_questions), sum(total_questions), sum(correct_questions) from (select total_questions, correct_questions from processed_facts where total_questions is not null or correct_questions is not null limit 1000) s",
          "result": "cancelled_after_short_window",
          "elapsed_seconds_before_cancel": 41
        }
      ],
      "interpretation": "The helper did not return within the current attempt timeout windows. The data dictionary retains source/evidence/fresh-accuracy-source-aggregate-2026-06-13.json as the current stored aggregate and records these refresh attempts instead of inventing replacement values."
    },
    "attempt3SourceRefreshAttempt20260613": {
      "checked_at": "2026-06-13T03:21:15Z",
      "tool": "loop/nweamap/vendor/skill-pack-baseline/nwea-map-analysis/scripts/timeback-query.mjs",
      "token_file": "~/Documents/timeback-danny-mcp-creds",
      "database": "reporting",
      "queries_attempted": [
        {
          "name": "processed_facts_full_accuracy_aggregate",
          "purpose": "Refresh a full PII-safe aggregate for total_questions and correct_questions.",
          "result": "cancelled_after_timeout",
          "elapsed_seconds_before_cancel": 120
        },
        {
          "name": "processed_facts_bounded_accuracy_shape_probe",
          "purpose": "Refresh a bounded PII-safe source-shape and range probe for total_questions and correct_questions.",
          "result": "cancelled_after_timeout",
          "elapsed_seconds_before_cancel": 75
        }
      ],
      "interpretation": "The live helper path was available enough to start both read-only queries but did not return within the doer turn. This attempt keeps the existing 2026-06-13 PII-safe aggregate and calendar persistence evidence in force and does not invent replacement values."
    },
    "attempt6AccuracySourceAggregate20260612": [],
    "attempt1AccuracySourceAggregate20260613": [
      {
        "row_count": 16662329,
        "rows_with_total_questions": 2980443,
        "rows_with_correct_questions": 2893838,
        "total_questions_sum": 59167608,
        "correct_questions_sum": 51390936,
        "accuracy_percent": 86.857
      }
    ],
    "attempt8AccuracySourceAggregate20260613": [
      {
        "row_count": 16636688,
        "rows_with_total_questions": 2976029,
        "rows_with_correct_questions": 2889504,
        "total_questions_sum": 59051593,
        "correct_questions_sum": 51292145,
        "accuracy_percent": 86.86
      }
    ],
    "attempt9AccuracySourceAggregate20260613": [
      {
        "rows_with_questions": 2976040,
        "total_questions_sum": 59051833,
        "correct_questions_sum": 51198540,
        "accuracy_percent": 86.701
      }
    ],
    "attempt10AccuracySourceAggregate20260613": [
      {
        "row_count": 16636865,
        "rows_with_total_questions": 2976046,
        "rows_with_correct_questions": 2889521,
        "total_questions_sum": 59052007,
        "correct_questions_sum": 51292532,
        "accuracy_percent": 86.86
      }
    ],
    "attempt11AccuracySourceAggregate20260613": [
      {
        "row_count": 16636945,
        "rows_with_total_questions": 2976051,
        "rows_with_correct_questions": 2889526,
        "total_questions_sum": 59052087,
        "correct_questions_sum": 51292581,
        "accuracy_percent": 86.86
      }
    ],
    "attempt12AccuracySourceAggregate20260613": [
      {
        "row_count": 16637016,
        "rows_with_total_questions": 2976064,
        "rows_with_correct_questions": 2889539,
        "total_questions_sum": 59052844,
        "correct_questions_sum": 51293251,
        "accuracy_percent": 86.86
      }
    ],
    "attempt13SchoolCalendarPersistence": {
      "purpose": "Read-only persistence check for the operator settlement that alpha.school_calendar exists and can support reportable Time Commitment rows.",
      "queried_at": "2026-06-13T00:00:00-04:00",
      "query_method": "python3 + psycopg2 against SUPABASE_DB_URL from .env.local; credentials were not printed",
      "table": "alpha.school_calendar",
      "row_count": 9226,
      "school_day_rows": 5852,
      "school_count": 14,
      "min_calendar_date": "2025-08-17",
      "max_calendar_date": "2027-06-06",
      "columns": [
        [
          "school_id",
          "text"
        ],
        [
          "calendar_date",
          "date"
        ],
        [
          "is_school_day",
          "boolean"
        ],
        [
          "reason",
          "text"
        ],
        [
          "source_calendar_ref",
          "text"
        ],
        [
          "policy_ref",
          "text"
        ],
        [
          "modified_at",
          "timestamp with time zone"
        ]
      ],
      "reasons": [
        "holiday_break",
        "instructional",
        "nwea_map_testing",
        "weekend"
      ],
      "interpretation": "The prior customer-verdict premise that Time Commitment should render null is stale because alpha.school_calendar is present. The dictionary should treat source_missing as an edge-case repair state, not as the ordinary report path."
    },
    "attempt14AccuracySourceAggregate20260613": [
      {
        "row_count": 16637103,
        "rows_with_total_questions": 2976111,
        "rows_with_correct_questions": 2889586,
        "total_questions_sum": 59055414,
        "correct_questions_sum": 51295659,
        "accuracy_percent": 86.86
      }
    ],
    "attempt14SchoolCalendarPersistence": {
      "purpose": "Read-only persistence check for attempt 14 that alpha.school_calendar exists and supports reportable Time Commitment rows",
      "queried_at": "2026-06-13T01:46:44.954341Z",
      "query_method": "python3 + psycopg2 against SUPABASE_DB_URL from .env.local; credentials were not printed",
      "table": "alpha.school_calendar",
      "row_count": 9226,
      "school_day_rows": 5852,
      "school_count": 14,
      "min_calendar_date": "2025-08-17",
      "max_calendar_date": "2027-06-06",
      "columns": [
        [
          "school_id",
          "text"
        ],
        [
          "calendar_date",
          "date"
        ],
        [
          "is_school_day",
          "boolean"
        ],
        [
          "reason",
          "text"
        ],
        [
          "source_calendar_ref",
          "text"
        ],
        [
          "policy_ref",
          "text"
        ],
        [
          "modified_at",
          "timestamp with time zone"
        ]
      ],
      "reasons": [
        "holiday_break",
        "instructional",
        "nwea_map_testing",
        "weekend"
      ],
      "interpretation": "alpha.school_calendar remains present in the shared DB; Time Commitment examples should use reportable rows and keep source_missing as repair behavior only."
    },
    "attempt15AccuracySourceAggregate20260613": [
      {
        "row_count": 16637199,
        "rows_with_total_questions": 2976128,
        "rows_with_correct_questions": 2889603,
        "total_questions_sum": 59056634,
        "correct_questions_sum": 51296686,
        "accuracy_percent": 86.86
      }
    ],
    "attempt15SchoolCalendarPersistence": {
      "purpose": "Read-only persistence check for attempt 15 that alpha.school_calendar exists and supports reportable Time Commitment rows",
      "queried_at": "2026-06-13T01:58:13.635093Z",
      "query_method": "python3 + psycopg2 against SUPABASE_DB_URL from .env.local; credentials were not printed",
      "table": "alpha.school_calendar",
      "row_count": 9226,
      "school_day_rows": 5852,
      "school_count": 14,
      "min_calendar_date": "2025-08-17",
      "max_calendar_date": "2027-06-06",
      "columns": [
        [
          "school_id",
          "text"
        ],
        [
          "calendar_date",
          "date"
        ],
        [
          "is_school_day",
          "boolean"
        ],
        [
          "reason",
          "text"
        ],
        [
          "source_calendar_ref",
          "text"
        ],
        [
          "policy_ref",
          "text"
        ],
        [
          "modified_at",
          "timestamp with time zone"
        ]
      ],
      "reasons": [
        "holiday_break",
        "instructional",
        "nwea_map_testing",
        "weekend"
      ],
      "interpretation": "alpha.school_calendar remains present in the shared DB; Time Commitment examples should use reportable rows and keep source_missing as repair behavior only."
    },
    "attempt18AccuracySourceAggregate20260613": [
      {
        "row_count": 2981190,
        "rows_with_total_questions": 2976278,
        "rows_with_correct_questions": 2889752,
        "total_questions_sum": 59060632,
        "correct_questions_sum": 51300130,
        "accuracy_percent": 86.86
      }
    ],
    "attempt19AccuracySourceAggregate20260613": [
      {
        "row_count": 16638687,
        "rows_with_total_questions": 2976282,
        "rows_with_correct_questions": 2889755,
        "total_questions_sum": 59060657,
        "correct_questions_sum": 51300142,
        "accuracy_percent": 86.86
      }
    ],
    "attempt20AccuracySourceAggregate20260613": [
      {
        "row_count": 16638743,
        "rows_with_total_questions": 2976284,
        "rows_with_correct_questions": 2889756,
        "total_questions_sum": 59060700,
        "correct_questions_sum": 51300173,
        "accuracy_percent": 86.86
      }
    ],
    "attempt21AccuracySourceAggregate20260613": [
      {
        "row_count": 16638754,
        "rows_with_total_questions": 2976285,
        "rows_with_correct_questions": 2889757,
        "total_questions_sum": 59060705,
        "correct_questions_sum": 51300175,
        "accuracy_percent": 86.86
      }
    ],
    "attempt22AccuracySourceAggregate20260613": [
      {
        "row_count": 16638754,
        "rows_with_total_questions": 2976285,
        "rows_with_correct_questions": 2889757,
        "total_questions_sum": 59060705,
        "correct_questions_sum": 51300175,
        "accuracy_percent": 86.86
      }
    ],
    "attempt23AccuracySourceAggregate20260613": [
      {
        "row_count": 16638757,
        "rows_with_total_questions": 2976286,
        "rows_with_correct_questions": 2889758,
        "total_questions_sum": 59060750,
        "correct_questions_sum": 51300212,
        "accuracy_percent": 86.86
      }
    ],
    "attempt24AccuracySourceAggregate20260613": [
      {
        "row_count": 16638797,
        "rows_with_total_questions": 2976287,
        "rows_with_correct_questions": 2889759,
        "total_questions_sum": 59060754,
        "correct_questions_sum": 51300215,
        "accuracy_percent": 86.86
      }
    ],
    "attempt25AccuracySourceAggregate20260613": [
      {
        "row_count": 16638899,
        "rows_with_total_questions": 2976291,
        "rows_with_correct_questions": 2889762,
        "total_questions_sum": 59060785,
        "correct_questions_sum": 51300234,
        "accuracy_percent": 86.86
      }
    ],
    "attempt16SchoolCalendarPersistence": {
      "purpose": "Read-only persistence check for attempt 16 that alpha.school_calendar exists and supports reportable Time Commitment rows",
      "queried_at": "2026-06-13T09:09:47Z",
      "query_method": "node + pg from loop/analytics/artifacts/alpha/integration/site/node_modules against SUPABASE_DB_URL from .env.local; credentials were not printed",
      "table": "alpha.school_calendar",
      "row_count": 9226,
      "school_day_rows": 5852,
      "school_count": 14,
      "min_calendar_date": "2025-08-17",
      "max_calendar_date": "2027-06-06",
      "columns": [
        [
          "school_id",
          "text"
        ],
        [
          "calendar_date",
          "date"
        ],
        [
          "is_school_day",
          "boolean"
        ],
        [
          "reason",
          "text"
        ],
        [
          "source_calendar_ref",
          "text"
        ],
        [
          "policy_ref",
          "text"
        ],
        [
          "modified_at",
          "timestamp with time zone"
        ]
      ],
      "reasons": [
        "holiday_break",
        "instructional",
        "nwea_map_testing",
        "weekend"
      ],
      "interpretation": "alpha.school_calendar remains present in the shared DB; Time Commitment examples should use reportable rows and keep source_missing as repair behavior only."
    },
    "currentAttemptSchoolCalendarEvidencePath": "source/evidence/current-school-calendar-persistence-2026-06-13.json",
    "currentAttemptSchoolCalendarPersistence": {
      "purpose": "Current read-only persistence check for the operator settlement that alpha.school_calendar exists and supports reportable Time Commitment rows.",
      "queried_at": "2026-06-14T22:18:37Z",
      "query_method": "node + pg from loop/analytics/artifacts/alpha/implementation/impl/node_modules against SUPABASE_DB_URL from .env.local; credentials were not printed",
      "table": "alpha.school_calendar",
      "row_count": 9238,
      "school_day_rows": 5674,
      "school_count": 14,
      "min_calendar_date": "2025-08-13",
      "max_calendar_date": "2027-06-06",
      "columns": [
        [
          "school_id",
          "text"
        ],
        [
          "calendar_date",
          "date"
        ],
        [
          "is_school_day",
          "boolean"
        ],
        [
          "reason",
          "text"
        ],
        [
          "source_calendar_ref",
          "text"
        ],
        [
          "policy_ref",
          "text"
        ],
        [
          "modified_at",
          "timestamp with time zone"
        ]
      ],
      "reasons": [
        "holiday_break",
        "instructional",
        "nwea_map_testing",
        "other",
        "weekend"
      ],
      "interpretation": "alpha.school_calendar remains present in the shared DB; Time Commitment examples should use reportable rows and keep source_missing as repair behavior only."
    },
    "currentSchoolCalendarPersistence": {
      "purpose": "Current read-only persistence check for the operator settlement that alpha.school_calendar exists and supports reportable Time Commitment rows.",
      "queried_at": "2026-06-14T22:18:37Z",
      "query_method": "node + pg from loop/analytics/artifacts/alpha/implementation/impl/node_modules against SUPABASE_DB_URL from .env.local; credentials were not printed",
      "table": "alpha.school_calendar",
      "row_count": 9238,
      "school_day_rows": 5674,
      "school_count": 14,
      "min_calendar_date": "2025-08-13",
      "max_calendar_date": "2027-06-06",
      "columns": [
        [
          "school_id",
          "text"
        ],
        [
          "calendar_date",
          "date"
        ],
        [
          "is_school_day",
          "boolean"
        ],
        [
          "reason",
          "text"
        ],
        [
          "source_calendar_ref",
          "text"
        ],
        [
          "policy_ref",
          "text"
        ],
        [
          "modified_at",
          "timestamp with time zone"
        ]
      ],
      "reasons": [
        "holiday_break",
        "instructional",
        "nwea_map_testing",
        "other",
        "weekend"
      ],
      "interpretation": "alpha.school_calendar remains present in the shared DB; Time Commitment examples should use reportable rows and keep source_missing as repair behavior only."
    },
    "approvedArchitectureGrounding": {
      "queriedWith": "mcp danny-timeback query(database='reporting'); same value-space as scripts/timeback-query.mjs --token-file ~/Documents/timeback-danny-mcp-creds",
      "queriedAt": "2026-06-10",
      "reportingDbReachable": true,
      "reconciliationHeadline": "Naive re-derivation from raw source rows produces wrong-but-plausible values for MOST report tiles. The report applies per-subject normalization (source-label normalization, test-app exclusion, daily caps, norms-referenced growth) that only the report pipeline knows. Therefore report-grade facts must be INGESTED from the report source, never re-derived.",
      "xpNaiveMatches": "1/6 subjects",
      "mapNaiveMatches": "2/4 subjects for observed/typical",
      "consequence": "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."
    },
    "freshProcessedFactsColumns": [
      "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"
    ],
    "freshCaliperTypeAction": [
      {
        "type": "TimeSpentEvent",
        "action": "SpentTime",
        "n": 13045113,
        "deleted_n": 0
      },
      {
        "type": "ActivityEvent",
        "action": "Completed",
        "n": 4137166,
        "deleted_n": 0
      },
      {
        "type": "Event",
        "action": "Created",
        "n": 34481,
        "deleted_n": 0
      },
      {
        "type": "ToolUseEvent",
        "action": "Used",
        "n": 3672,
        "deleted_n": 0
      },
      {
        "type": "AnnotationEvent",
        "action": "Tagged",
        "n": 1568,
        "deleted_n": 0
      },
      {
        "type": "AssessmentItemEvent",
        "action": "Completed",
        "n": 738,
        "deleted_n": 0
      },
      {
        "type": "SessionEvent",
        "action": "LoggedIn",
        "n": 270,
        "deleted_n": 0
      },
      {
        "type": "SessionEvent",
        "action": "LoggedOut",
        "n": 193,
        "deleted_n": 0
      },
      {
        "type": "Event",
        "action": "Achieved",
        "n": 132,
        "deleted_n": 0
      },
      {
        "type": "AssessmentItemEvent",
        "action": "Skipped",
        "n": 119,
        "deleted_n": 0
      },
      {
        "type": "AssessmentEvent",
        "action": "Submitted",
        "n": 18,
        "deleted_n": 0
      },
      {
        "type": "Event",
        "action": "Used",
        "n": 8,
        "deleted_n": 0
      },
      {
        "type": "Event",
        "action": "Completed",
        "n": 6,
        "deleted_n": 0
      },
      {
        "type": "Event",
        "action": "Viewed",
        "n": 4,
        "deleted_n": 0
      },
      {
        "type": "FeedbackEvent",
        "action": "Commented",
        "n": 2,
        "deleted_n": 0
      },
      {
        "type": "FeedbackEvent",
        "action": "Ranked",
        "n": 2,
        "deleted_n": 0
      },
      {
        "type": "AssessmentEvent",
        "action": "Paused",
        "n": 1,
        "deleted_n": 0
      },
      {
        "type": "AssessmentEvent",
        "action": "Started",
        "n": 1,
        "deleted_n": 0
      },
      {
        "type": "GradeEvent",
        "action": "Graded",
        "n": 1,
        "deleted_n": 0
      }
    ],
    "reportGroundingQueriedWith": "mcp danny-timeback query(database='reporting'); same value-space as scripts/timeback-query.mjs --token-file ~/Documents/timeback-danny-mcp-creds",
    "reportGroundingTarget": "single required target student; identity omitted from public evidence",
    "reportGrounding": [
      {
        "reportPanel": "Panel 3 MAP: Growth Percentile (vs 1yr ago), Growth X, RIT",
        "reportingSource": "timeback-map over full source-shaped reporting.hp_map_results Winter 2025-2026 rows; RIT = testritscore; achievement percentile = testpercentile; growth percentile = wintertowinterconditionalgrowthpercentile; observed = wintertowinterobservedgrowth; Growth X denominator = wintertowinterprojectedgrowth",
        "analyticsObject": "alpha.analytics_map_growth_rollup",
        "requiredFields": "source_import_id, growth_window=winter_to_winter, rit_score, achievement_percentile, growth_percentile, observed_growth, projected_growth, typical_growth, growth_x",
        "probeValue": "Math source evidence: rit_score=239, growth_percentile=43, observed_growth=6, projected_growth=7, typical_growth=2; pinned Growth X is 0.8571 from observed/projected, while the old observed/typical probe was only diagnostic evidence. Full-row import contract: accept all hp_map_results columns, including wintertowinter* and unknown extras; ignore extras rather than rejecting."
      },
      {
        "reportPanel": "Time Commitment / minutes per enrolled school day",
        "reportingSource": "timeback-xp-time-accuracy over reporting.processed_facts active_seconds, inactive_seconds, waste_seconds by student/date/subject for the numerator; the denominator is alpha.school_calendar over Ed-Fi CalendarDate intersected with enrollment and subject assignment.",
        "analyticsObject": "alpha.analytics_event_time_fact + alpha.analytics_school_day_minutes",
        "requiredFields": "source_import_id, active_seconds/active_minutes, enrolled_school_day_count, excluded_school_day_count, minutes_per_enrolled_school_day, null_reason",
        "probeValue": "Report-period processed_facts evidence: 20,390 rows, 193 active dates, active_seconds=1,434,663.17, active_minutes=23,911.053. Those active dates are explicitly not the school-day denominator; the reportable denominator must be the materialized Analytics calendar/enrollment intersection."
      },
      {
        "reportPanel": "XP Earned / XP Remaining / XP Goal Percent",
        "reportingSource": "timeback-xp-time-accuracy over reporting.processed_facts plus XP-goal policy and Curriculum expected-XP refs; Results xp_ledger remains the audit source where platform ledger rows exist",
        "analyticsObject": "alpha.analytics_xp_rollup",
        "requiredFields": "source_import_id, xp_total, daily_xp_goal, enrolled_school_day_count, xp_goal, xp_remaining, xp_goal_percent, on_track, positive_xp, negative_xp, award_count, reversal_count, null_reason",
        "probeValue": "Approved architecture evidence found naive SUM(processed_facts.xp_earned) reproduced only 1/6 report subjects, so xp_total is an ingested report-ready value with provenance, not a raw SQL sum. XP percent follows alpha.policy.analytics.xp_goal_percent.v1, uses the stored enrolled_school_day_count, and remains uncapped when populated."
      },
      {
        "reportPanel": "Accuracy",
        "reportingSource": "timeback-xp-time-accuracy over reporting.processed_facts total_questions and correct_questions by student/date/subject, after the adapter applies reportable app/source/score_type filters.",
        "analyticsObject": "alpha.analytics_accuracy",
        "requiredFields": "source_import_id, correct_question_count, total_question_count, incorrect_question_count, accuracy_percent, null_reason",
        "probeValue": "Current token-file evidence confirms the source-shaped processed_facts table carries integer total_questions and correct_questions. The aggregate probe found 2,980,443 rows with total_questions, 59,167,608 total questions, and 51,390,936 correct questions. Attempt 1 documents the Analytics contract for the in-wave implementation family; reports will read alpha.analytics_accuracy and never divide raw source rows or keep private app allowlists."
      },
      {
        "reportPanel": "Knowledge Grade / Grade Levels Mastered",
        "reportingSource": "timeback-grade-mastery over reporting.assessment_results passed gates; Results student_kc_state remains the canonical mastery state for KC deltas",
        "analyticsObject": "alpha.analytics_mastery_delta",
        "requiredFields": "source_import_id, grade_subject, grade_level, completed_on, state_dimension, transition_kind, source_result_refs",
        "probeValue": "Approved architecture evidence pins assessment_results as the report source for Grade Levels Mastered; old visibility aggregates remain diagnostic only."
      },
      {
        "reportPanel": "Course / subject completion %",
        "reportingSource": "Events app-reported course percent first; timeback-completion XP remaining fallback second; Curriculum main-course refs define grade-level denominator",
        "analyticsObject": "alpha.analytics_completion_rollup",
        "requiredFields": "source_import_id, completion_scope, scope_id, grade_level, is_main_course, progress_source_kind, xp_earned, xp_remaining, completion_percent, denominator_policy_ref",
        "probeValue": "Direct app-reported percent_complete wins as evidence; if absent, use XP remaining fallback evidence. Results owns grade-level progress and applies main-course active-path semantics. total_questions/correct_questions evidence belongs to Accuracy, not Course Completion."
      }
    ],
    "reportMapWinter2026": [
      {
        "subject": "Language",
        "termname": "Winter 2025-2026",
        "teststartdate": "2026-01-29",
        "testritscore": 232,
        "testpercentile": 96,
        "wintertowinterconditionalgrowthpercentile": 56,
        "wintertowinterobservedgrowth": 3,
        "typicalwintertowintergrowth": 2,
        "falltowinterconditionalgrowthpercentile": 67,
        "falltowinterobservedgrowth": 3,
        "typicalfalltowintergrowth": null,
        "normsreferencedata": 2025,
        "old_observed_over_typical_probe": 1.5
      },
      {
        "subject": "Language",
        "termname": "Winter 2025-2026",
        "teststartdate": "2026-01-29",
        "testritscore": 232,
        "testpercentile": 96,
        "wintertowinterconditionalgrowthpercentile": 56,
        "wintertowinterobservedgrowth": 3,
        "typicalwintertowintergrowth": 2,
        "falltowinterconditionalgrowthpercentile": 67,
        "falltowinterobservedgrowth": 3,
        "typicalfalltowintergrowth": null,
        "normsreferencedata": 2025,
        "old_observed_over_typical_probe": 1.5
      },
      {
        "subject": "Math",
        "termname": "Winter 2025-2026",
        "teststartdate": "2026-01-28",
        "testritscore": 239,
        "testpercentile": 94,
        "wintertowinterconditionalgrowthpercentile": 43,
        "wintertowinterobservedgrowth": 6,
        "typicalwintertowintergrowth": 2,
        "falltowinterconditionalgrowthpercentile": 64,
        "falltowinterobservedgrowth": 9,
        "typicalfalltowintergrowth": null,
        "normsreferencedata": 2025,
        "old_observed_over_typical_probe": 3
      },
      {
        "subject": "Math",
        "termname": "Winter 2025-2026",
        "teststartdate": "2026-01-28",
        "testritscore": 239,
        "testpercentile": 94,
        "wintertowinterconditionalgrowthpercentile": 43,
        "wintertowinterobservedgrowth": 6,
        "typicalwintertowintergrowth": 2,
        "falltowinterconditionalgrowthpercentile": 64,
        "falltowinterobservedgrowth": 9,
        "typicalfalltowintergrowth": null,
        "normsreferencedata": 2025,
        "old_observed_over_typical_probe": 3
      },
      {
        "subject": "Reading",
        "termname": "Winter 2025-2026",
        "teststartdate": "2026-02-02",
        "testritscore": 239,
        "testpercentile": 97,
        "wintertowinterconditionalgrowthpercentile": 58,
        "wintertowinterobservedgrowth": 3,
        "typicalwintertowintergrowth": 2,
        "falltowinterconditionalgrowthpercentile": 61,
        "falltowinterobservedgrowth": 1,
        "typicalfalltowintergrowth": null,
        "normsreferencedata": 2025,
        "old_observed_over_typical_probe": 1.5
      },
      {
        "subject": "Reading",
        "termname": "Winter 2025-2026",
        "teststartdate": "2026-02-02",
        "testritscore": 239,
        "testpercentile": 97,
        "wintertowinterconditionalgrowthpercentile": 58,
        "wintertowinterobservedgrowth": 3,
        "typicalwintertowintergrowth": 2,
        "falltowinterconditionalgrowthpercentile": 61,
        "falltowinterobservedgrowth": 1,
        "typicalfalltowintergrowth": null,
        "normsreferencedata": 2025,
        "old_observed_over_typical_probe": 1.5
      },
      {
        "subject": "Science",
        "termname": "Winter 2025-2026",
        "teststartdate": "2026-02-09",
        "testritscore": 229,
        "testpercentile": 97,
        "wintertowinterconditionalgrowthpercentile": 44,
        "wintertowinterobservedgrowth": 2,
        "typicalwintertowintergrowth": 2,
        "falltowinterconditionalgrowthpercentile": 48,
        "falltowinterobservedgrowth": 0,
        "typicalfalltowintergrowth": null,
        "normsreferencedata": 2025,
        "old_observed_over_typical_probe": 1
      },
      {
        "subject": "Science",
        "termname": "Winter 2025-2026",
        "teststartdate": "2026-02-09",
        "testritscore": 229,
        "testpercentile": 97,
        "wintertowinterconditionalgrowthpercentile": 44,
        "wintertowinterobservedgrowth": 2,
        "typicalwintertowintergrowth": 2,
        "falltowinterconditionalgrowthpercentile": 48,
        "falltowinterobservedgrowth": 0,
        "typicalfalltowintergrowth": null,
        "normsreferencedata": 2025,
        "old_observed_over_typical_probe": 1
      }
    ],
    "reportMapProjectionColumns": [
      {
        "subject": "Language",
        "termname": "Winter 2025-2026",
        "testritscore": 232,
        "wintertowinterprojectedgrowth": 2,
        "wintertowinterobservedgrowth": 3,
        "typicalwintertowintergrowth": 2,
        "wintertowinterconditionalgrowthpercentile": 56,
        "old_observed_over_typical_probe": 1.5,
        "growth_x_vs_projected": 1.5
      },
      {
        "subject": "Language",
        "termname": "Winter 2025-2026",
        "testritscore": 232,
        "wintertowinterprojectedgrowth": 2,
        "wintertowinterobservedgrowth": 3,
        "typicalwintertowintergrowth": 2,
        "wintertowinterconditionalgrowthpercentile": 56,
        "old_observed_over_typical_probe": 1.5,
        "growth_x_vs_projected": 1.5
      },
      {
        "subject": "Math",
        "termname": "Winter 2025-2026",
        "testritscore": 239,
        "wintertowinterprojectedgrowth": 7,
        "wintertowinterobservedgrowth": 6,
        "typicalwintertowintergrowth": 2,
        "wintertowinterconditionalgrowthpercentile": 43,
        "old_observed_over_typical_probe": 3,
        "growth_x_vs_projected": 0.8571
      },
      {
        "subject": "Math",
        "termname": "Winter 2025-2026",
        "testritscore": 239,
        "wintertowinterprojectedgrowth": 7,
        "wintertowinterobservedgrowth": 6,
        "typicalwintertowintergrowth": 2,
        "wintertowinterconditionalgrowthpercentile": 43,
        "old_observed_over_typical_probe": 3,
        "growth_x_vs_projected": 0.8571
      },
      {
        "subject": "Reading",
        "termname": "Winter 2025-2026",
        "testritscore": 239,
        "wintertowinterprojectedgrowth": 2,
        "wintertowinterobservedgrowth": 3,
        "typicalwintertowintergrowth": 2,
        "wintertowinterconditionalgrowthpercentile": 58,
        "old_observed_over_typical_probe": 1.5,
        "growth_x_vs_projected": 1.5
      },
      {
        "subject": "Reading",
        "termname": "Winter 2025-2026",
        "testritscore": 239,
        "wintertowinterprojectedgrowth": 2,
        "wintertowinterobservedgrowth": 3,
        "typicalwintertowintergrowth": 2,
        "wintertowinterconditionalgrowthpercentile": 58,
        "old_observed_over_typical_probe": 1.5,
        "growth_x_vs_projected": 1.5
      },
      {
        "subject": "Science",
        "termname": "Winter 2025-2026",
        "testritscore": 229,
        "wintertowinterprojectedgrowth": 3,
        "wintertowinterobservedgrowth": 2,
        "typicalwintertowintergrowth": 2,
        "wintertowinterconditionalgrowthpercentile": 44,
        "old_observed_over_typical_probe": 1,
        "growth_x_vs_projected": 0.6667
      },
      {
        "subject": "Science",
        "termname": "Winter 2025-2026",
        "testritscore": 229,
        "wintertowinterprojectedgrowth": 3,
        "wintertowinterobservedgrowth": 2,
        "typicalwintertowintergrowth": 2,
        "wintertowinterconditionalgrowthpercentile": 44,
        "old_observed_over_typical_probe": 1,
        "growth_x_vs_projected": 0.6667
      }
    ],
    "reportProcessedFactsSummary": [
      {
        "rows": 20390,
        "active_dates": 193,
        "active_seconds": 1434663.17,
        "active_minutes": 23911.053,
        "waste_seconds": 37241.85,
        "xp_earned": 21371.73,
        "mastered_units": 3053,
        "total_questions": 109643,
        "correct_questions": 92808
      }
    ],
    "reportProcessedFactsBySubject": [
      {
        "subject": "FastMath",
        "rows": 1058,
        "active_dates": 47,
        "active_seconds": 41821,
        "active_minutes": 697.017,
        "waste_seconds": 37155,
        "xp_earned": 563.75,
        "mastered_units": 790,
        "total_questions": 15660,
        "correct_questions": 13409
      },
      {
        "subject": "Language",
        "rows": 2313,
        "active_dates": 155,
        "active_seconds": 271145,
        "active_minutes": 4519.083,
        "waste_seconds": 0,
        "xp_earned": 4795.86,
        "mastered_units": 627,
        "total_questions": 18168,
        "correct_questions": 16997
      },
      {
        "subject": "Math",
        "rows": 1748,
        "active_dates": 144,
        "active_seconds": 374568.6,
        "active_minutes": 6242.81,
        "waste_seconds": 86.85,
        "xp_earned": 4060,
        "mastered_units": 649,
        "total_questions": 5451,
        "correct_questions": 3995
      },
      {
        "subject": "Other",
        "rows": 1,
        "active_dates": 1,
        "active_seconds": 0,
        "active_minutes": 0,
        "waste_seconds": 0,
        "xp_earned": 25,
        "mastered_units": 0,
        "total_questions": 0,
        "correct_questions": 0
      },
      {
        "subject": "Reading",
        "rows": 1406,
        "active_dates": 145,
        "active_seconds": 334431,
        "active_minutes": 5573.85,
        "waste_seconds": 0,
        "xp_earned": 5116,
        "mastered_units": 213,
        "total_questions": 5158,
        "correct_questions": 3363
      },
      {
        "subject": "Science",
        "rows": 1174,
        "active_dates": 52,
        "active_seconds": 190416,
        "active_minutes": 3173.6,
        "waste_seconds": 0,
        "xp_earned": 1163,
        "mastered_units": 141,
        "total_questions": 2374,
        "correct_questions": 1583
      },
      {
        "subject": "Vocabulary",
        "rows": 1033,
        "active_dates": 133,
        "active_seconds": 27644,
        "active_minutes": 460.733,
        "waste_seconds": 0,
        "xp_earned": 3195.62,
        "mastered_units": 467,
        "total_questions": 61053,
        "correct_questions": 51938
      },
      {
        "subject": "Writing",
        "rows": 11657,
        "active_dates": 112,
        "active_seconds": 194637.57,
        "active_minutes": 3243.96,
        "waste_seconds": 0,
        "xp_earned": 2452.5,
        "mastered_units": 166,
        "total_questions": 1779,
        "correct_questions": 1523
      }
    ],
    "reportMasteryVisibility": [
      {
        "course_subject": "FastMath",
        "rows": 1,
        "min_course_grade": 5,
        "max_course_grade": 5,
        "latest_completion_date": "2025-11-03T15:21:29.287"
      },
      {
        "course_subject": "Language",
        "rows": 1,
        "min_course_grade": 6,
        "max_course_grade": 6,
        "latest_completion_date": "2025-12-10T16:54:14.73"
      },
      {
        "course_subject": "Math",
        "rows": 1,
        "min_course_grade": 5,
        "max_course_grade": 5,
        "latest_completion_date": "2025-12-16T17:45:35.393"
      },
      {
        "course_subject": "Reading",
        "rows": 1,
        "min_course_grade": 8,
        "max_course_grade": 8,
        "latest_completion_date": "2026-03-24T14:59:36.049"
      },
      {
        "course_subject": "Science",
        "rows": 1,
        "min_course_grade": 5,
        "max_course_grade": 5,
        "latest_completion_date": "2025-08-27T16:11:38.767"
      },
      {
        "course_subject": "Social Studies",
        "rows": 1,
        "min_course_grade": 3,
        "max_course_grade": 3,
        "latest_completion_date": "2025-03-07T03:00:00"
      },
      {
        "course_subject": "Vocabulary",
        "rows": 1,
        "min_course_grade": 10,
        "max_course_grade": 10,
        "latest_completion_date": "2026-05-01T15:40:27.617"
      },
      {
        "course_subject": "Writing",
        "rows": 1,
        "min_course_grade": 5,
        "max_course_grade": 5,
        "latest_completion_date": "2026-04-10T18:29:51.149"
      }
    ],
    "processedFactsSubjectSummary": [
      {
        "subject": "Writing",
        "n": 4944526,
        "active_seconds": 78685082.01,
        "inactive_seconds": 7.08,
        "waste_seconds": 0,
        "xp_earned": 1215406.9
      },
      {
        "subject": "Math",
        "n": 3984163,
        "active_seconds": 361781553.96,
        "inactive_seconds": 3722875.12,
        "waste_seconds": 452971.58,
        "xp_earned": 4351580.04
      },
      {
        "subject": "Language",
        "n": 2199666,
        "active_seconds": 157274095.14,
        "inactive_seconds": 618341.92,
        "waste_seconds": 311330.7,
        "xp_earned": 4886201.78
      },
      {
        "subject": "FastMath",
        "n": 1993006,
        "active_seconds": 69638890.86,
        "inactive_seconds": 480024.9,
        "waste_seconds": 38169566.1,
        "xp_earned": 1054788.82
      },
      {
        "subject": "Reading",
        "n": 1776985,
        "active_seconds": 178347417.5,
        "inactive_seconds": 559883.94,
        "waste_seconds": 124753.45,
        "xp_earned": 2929304.42
      },
      {
        "subject": "Social Studies",
        "n": 693587,
        "active_seconds": 11492725.78,
        "inactive_seconds": 3240114.11,
        "waste_seconds": 162669.99,
        "xp_earned": 358558.43
      },
      {
        "subject": "Science",
        "n": 545023,
        "active_seconds": 79827954.43,
        "inactive_seconds": 837338.19,
        "waste_seconds": 611348.02,
        "xp_earned": 1563132.41
      },
      {
        "subject": "Vocabulary",
        "n": 268392,
        "active_seconds": 8209617.16,
        "inactive_seconds": 198372.5,
        "waste_seconds": 0,
        "xp_earned": 1073697.11
      },
      {
        "subject": "None",
        "n": 38702,
        "active_seconds": 718394.02,
        "inactive_seconds": 8109.91,
        "waste_seconds": 12310.9,
        "xp_earned": 0
      },
      {
        "subject": "(blank)",
        "n": 13444,
        "active_seconds": 0,
        "inactive_seconds": 0,
        "waste_seconds": 0,
        "xp_earned": -25179
      },
      {
        "subject": "Other",
        "n": 3610,
        "active_seconds": 65648.85,
        "inactive_seconds": 1237.93,
        "waste_seconds": 0,
        "xp_earned": 32157
      },
      {
        "subject": "Biology",
        "n": 85,
        "active_seconds": 0,
        "inactive_seconds": 0,
        "waste_seconds": 0,
        "xp_earned": 0
      },
      {
        "subject": "Mathematics",
        "n": 30,
        "active_seconds": 0,
        "inactive_seconds": 0,
        "waste_seconds": 0,
        "xp_earned": 165
      },
      {
        "subject": "ELA",
        "n": 3,
        "active_seconds": 0,
        "inactive_seconds": 0,
        "waste_seconds": 0,
        "xp_earned": 35
      }
    ],
    "processedFactsAppSummary": [
      {
        "app": "Alphawrite",
        "n": 4909058,
        "active_seconds": 69303957.47,
        "inactive_seconds": 0,
        "waste_seconds": 0,
        "xp_earned": 948123.15
      },
      {
        "app": "TimeBack Dash",
        "n": 2328169,
        "active_seconds": 25052400,
        "inactive_seconds": 0,
        "waste_seconds": 0,
        "xp_earned": 1834
      },
      {
        "app": "AlphaMath Fluency",
        "n": 1453120,
        "active_seconds": 55177283.51,
        "inactive_seconds": 0,
        "waste_seconds": 38169566.1,
        "xp_earned": 827989.41
      },
      {
        "app": "MobyMax",
        "n": 1194033,
        "active_seconds": 90547053,
        "inactive_seconds": 0,
        "waste_seconds": 0,
        "xp_earned": 1977383
      },
      {
        "app": "Zearn",
        "n": 1033749,
        "active_seconds": 118232419,
        "inactive_seconds": 0,
        "waste_seconds": 0,
        "xp_earned": 1264126
      },
      {
        "app": "Lalilo",
        "n": 712161,
        "active_seconds": 52269000,
        "inactive_seconds": 0,
        "waste_seconds": 0,
        "xp_earned": 1393125
      },
      {
        "app": "TeachTales",
        "n": 671367,
        "active_seconds": 7863110,
        "inactive_seconds": 0,
        "waste_seconds": 0,
        "xp_earned": 122692
      },
      {
        "app": "AlphaLearn",
        "n": 563247,
        "active_seconds": 29538987.05,
        "inactive_seconds": 2125652.69,
        "waste_seconds": 235176.8,
        "xp_earned": 116256.75
      },
      {
        "app": "Math Academy",
        "n": 460530,
        "active_seconds": 105892772,
        "inactive_seconds": 0,
        "waste_seconds": 0,
        "xp_earned": 1230324
      },
      {
        "app": "VocabLoco",
        "n": 274129,
        "active_seconds": 10271440,
        "inactive_seconds": 0,
        "waste_seconds": 0,
        "xp_earned": 731223
      },
      {
        "app": "DreamUp",
        "n": 272295,
        "active_seconds": 2410132,
        "inactive_seconds": 480006,
        "waste_seconds": 0,
        "xp_earned": 43618.11
      },
      {
        "app": "Math Raiders",
        "n": 261884,
        "active_seconds": 11864614,
        "inactive_seconds": 0,
        "waste_seconds": 0,
        "xp_earned": 174559.75
      },
      {
        "app": "Alpha Read",
        "n": 185041,
        "active_seconds": 68829064,
        "inactive_seconds": 0,
        "waste_seconds": 0,
        "xp_earned": 668135.5
      },
      {
        "app": "Incept",
        "n": 179902,
        "active_seconds": 2801244.29,
        "inactive_seconds": 0,
        "waste_seconds": 0,
        "xp_earned": 31809
      },
      {
        "app": "AlphaLiteracy",
        "n": 178808,
        "active_seconds": 8503037,
        "inactive_seconds": 0,
        "waste_seconds": 0,
        "xp_earned": 136622
      },
      {
        "app": "Synthesis Tutor",
        "n": 172351,
        "active_seconds": 17931580,
        "inactive_seconds": 0,
        "waste_seconds": 0,
        "xp_earned": 282250
      },
      {
        "app": "ClearFluency",
        "n": 160290,
        "active_seconds": 37175616.93,
        "inactive_seconds": 0,
        "waste_seconds": 0,
        "xp_earned": 320391
      },
      {
        "app": "Membean",
        "n": 150327,
        "active_seconds": 19707336,
        "inactive_seconds": 0,
        "waste_seconds": 0,
        "xp_earned": 321866.04
      },
      {
        "app": "Nice Academy",
        "n": 126634,
        "active_seconds": 22053832,
        "inactive_seconds": 0,
        "waste_seconds": 0,
        "xp_earned": 138805
      },
      {
        "app": "Mentava",
        "n": 118108,
        "active_seconds": 3798919,
        "inactive_seconds": 0,
        "waste_seconds": 0,
        "xp_earned": 144869
      }
    ],
    "resultSubjects": [
      {
        "subject": "(null)",
        "n": 1871757
      },
      {
        "subject": "Language",
        "n": 1417902
      },
      {
        "subject": "Math",
        "n": 1043040
      },
      {
        "subject": "FastMath",
        "n": 1030579
      },
      {
        "subject": "Reading",
        "n": 783905
      },
      {
        "subject": "Science-notqced",
        "n": 627047
      },
      {
        "subject": "Vocabulary",
        "n": 228333
      },
      {
        "subject": "Science",
        "n": 197166
      },
      {
        "subject": "Writing",
        "n": 61963
      },
      {
        "subject": "Social Studies",
        "n": 54811
      },
      {
        "subject": "Math-notqced",
        "n": 28140
      },
      {
        "subject": "None",
        "n": 21671
      },
      {
        "subject": "Math-ISEE",
        "n": 17642
      },
      {
        "subject": "Language-notqced",
        "n": 11907
      },
      {
        "subject": "ELA",
        "n": 8663
      },
      {
        "subject": "Reading-ISEE",
        "n": 8194
      },
      {
        "subject": "Language-ISEE",
        "n": 8074
      },
      {
        "subject": "Reading-notqced",
        "n": 7813
      },
      {
        "subject": "Math-unit",
        "n": 6297
      },
      {
        "subject": "Math-Athena",
        "n": 5970
      },
      {
        "subject": "Math-notQCed",
        "n": 5480
      },
      {
        "subject": "Math-athena",
        "n": 5471
      },
      {
        "subject": "Social Studies-notqced",
        "n": 4376
      },
      {
        "subject": "science",
        "n": 4250
      },
      {
        "subject": "Math-Athena-notqced",
        "n": 2186
      }
    ],
    "notes": [
      "Approved architecture report-source grounding confirms each Learning Report tile has a named adapter and provenance row; this dictionary inherits that source contract and does not re-derive the report values.",
      "Existing processed_facts schema evidence confirms source-shaped rows carry active_seconds, inactive_seconds, waste_seconds, xp_earned, total_questions, correct_questions, subject, app, score_type, original_event_type, original_event_id, action, and object_type.",
      "Current token-file accuracy evidence confirms processed_facts carries integer correct_questions and total_questions at production scale; attempt 1 turns that into the documented alpha.analytics_accuracy contract for this wave instead of making reports query or divide the source table.",
      "Historical attempt 4 re-ran the token-file helper path against reporting.processed_facts and information_schema; that schema-visibility helper call returned empty result sets, so the dictionary kept the approved architecture evidence and existing aggregate files rather than fabricating a source value.",
      "The timeback-map adapter contract accepts full source-shaped hp_map_results rows, including wintertowinter* and other growth-window/goal columns; unknown extra columns are ignored per source-shaped ingestion.",
      "Existing Caliper aggregate evidence confirms high-volume TimeSpentEvent/SpentTime and ActivityEvent/Completed remain the Events source shape Analytics materializes from for derived complements.",
      "Approved reporting DB target-student probes confirm the Learning Report MAP panel uses winter_to_winter, not fall_to_winter, and that report-period time/XP/mastery/completion facts come from named report-source adapters rather than client-side sums or literals.",
      "Production subject/app evidence is aggregate-only and PII-safe; it drives write-time normalization requirements, not client logic."
    ]
  },
  "metricChecks": [
    {
      "key": "minutes|Caliper events",
      "sourceOldCount": 21192,
      "sourceNewCount": 20693,
      "analyticsObject": "alpha.analytics_time_window (derived) + alpha.analytics_school_day_minutes (report tile)",
      "derivedFacts": "active_seconds, inactive_seconds, waste_seconds (derived from Events); minutes_per_enrolled_school_day (report tile, ingested numerator / calendar denominator)",
      "sourceRefs": "DERIVED: alpha.event/event_link (Caliper). INGESTED: reporting.processed_facts.active_seconds via timeback-xp-time-accuracy; denominator alpha.school_calendar ∩ enrollment window.",
      "itd": "aitd-006-school-day-minutes"
    },
    {
      "key": "XP",
      "sourceOldCount": 9478,
      "sourceNewCount": 13771,
      "analyticsObject": "alpha.analytics_xp_rollup",
      "derivedFacts": "xp_total, daily_xp_goal, enrolled_school_day_count, xp_goal (policy denominator), xp_remaining, xp_goal_percent (uncapped when populated), on_track, positive_xp, negative_xp, null_reason; source_missing is a repair state, not an app-side fallback",
      "sourceRefs": "INGESTED from reporting.processed_facts via timeback-xp-time-accuracy (report normalization, not naive SUM); daily-goal denominator from alpha.policy; xp_remaining from Curriculum expected XP.",
      "itd": "aitd-007-xp-rollups"
    },
    {
      "key": "mastery|student_kc_state",
      "sourceOldCount": 9178,
      "sourceNewCount": 9176,
      "analyticsObject": "alpha.analytics_mastery_delta",
      "derivedFacts": "grade_levels_mastered (subject, grade, completed_on); per-state previous_value, new_value, delta_value, transition_kind",
      "sourceRefs": "INGESTED grade-levels-mastered from reporting.assessment_results via timeback-grade-mastery; mastery deltas reference alpha.student_kc_state (Results) by FK, read as-of, never recomputed.",
      "itd": "aitd-008-mastery-and-grade-levels"
    },
    {
      "key": "RIT|GrowthX|MAP growth windows",
      "sourceOldCount": 12,
      "sourceNewCount": 12,
      "analyticsObject": "alpha.analytics_map_growth_rollup",
      "derivedFacts": "rit, achievement_percentile, growth_percentile, growth_x (= observed / projected, ALPHA-2), growth_x_target, on_track",
      "sourceRefs": "INGESTED from reporting.hp_map_results via timeback-map after test-of-record dedup (GAP-3 highest RIT); Growth X read from the NWEAMap norms-tagged calculator, never re-derived as observed/typical.",
      "itd": "aitd-009-map-growth-rollups"
    },
    {
      "key": "MAP sittings/scores",
      "sourceOldCount": 12,
      "sourceNewCount": 58,
      "analyticsObject": "alpha.analytics_map_growth_rollup",
      "derivedFacts": "test_of_record summary plus sitting_count and retake_count for audit/report cells",
      "sourceRefs": "INGESTED from reporting.hp_map_results (all sittings) via timeback-map; NWEAMap/Results own raw sittings, norms, and the calculators.",
      "itd": "aitd-009-map-growth-rollups"
    },
    {
      "key": "completion|curriculum refs",
      "sourceOldCount": 83,
      "sourceNewCount": 78,
      "analyticsObject": "alpha.analytics_completion_rollup",
      "derivedFacts": "xp_earned, xp_remaining, completion_percent, null_reason (NEVER a 1-if-active fallback)",
      "sourceRefs": "INGESTED earned XP from reporting.processed_facts; XP-remaining denominator from Curriculum course/course_component expected XP via timeback-completion. Missing denominator → null_reason=source_missing.",
      "itd": "aitd-010-completion-rollups"
    },
    {
      "key": "Learning Report accuracy",
      "analyticsObject": "alpha.analytics_accuracy",
      "derivedFacts": "correct_question_count, total_question_count, incorrect_question_count, accuracy_percent, null_reason",
      "itd": "aitd-001-report-source-ingestion"
    },
    {
      "key": "GOALS target date",
      "analyticsObject": "analytics.school_days_remaining",
      "derivedFacts": "instructional_days_remaining, instructional_dates, xp_unit.*, effort.*",
      "itd": "aitd-018-goals-school-days-remaining"
    }
  ],
  "stats": {
    "tableCount": 18,
    "fieldCount": 405,
    "enumSetCount": 16,
    "policyCount": 20,
    "learningReportRecipeCount": 10,
    "learningReportPanelCount": 9,
    "apiEndpointCount": 18,
    "convergenceRuleCount": 15,
    "problemCodeCount": 8,
    "accuracyPanelTable": "alpha.analytics_accuracy",
    "accuracyPanelRecipe": "accuracy",
    "endpointCount": 18
  },
  "apiAxes": [
    {
      "id": "aitd-101-axis-write-granularity",
      "title": "API Axis: Write Granularity",
      "status": "Accepted",
      "decision": "SHIP: public writes are bulk-only source imports (one endpoint per named adapter); live derived writes are internal close hooks from Events and Results; no public per-metric writes ship.",
      "trace": [
        "POST /alpha/analytics/v1/source-imports/timeback-xp-time-accuracy",
        "POST /alpha/analytics/v1/source-imports/timeback-map",
        "event/result close materializers"
      ]
    },
    {
      "id": "aitd-102-axis-read-shape",
      "title": "API Axis: Read Shape",
      "status": "Accepted",
      "decision": "SHIP: list plus detail for each rollup collection, with source-ref subcollections for audit/provenance users.",
      "trace": [
        "GET /xp-rollups",
        "GET /xp-rollups/{id}/source-refs",
        "GET /map-growth-rollups/{id}/source-refs"
      ]
    },
    {
      "id": "aitd-103-axis-query-model",
      "title": "API Axis: Query Model",
      "status": "Accepted",
      "decision": "SHIP: filter + sort + limit + cursor + modifiedSince for all list endpoints, with typed filters only.",
      "trace": [
        "all GET list endpoints"
      ]
    },
    {
      "id": "aitd-104-axis-concurrency",
      "title": "API Axis: Concurrency Model",
      "status": "Accepted",
      "decision": "SHIP: no public If-Match concurrency for derived facts; recompute uses materializer-owned calculation_version and supersedes/correction rows.",
      "trace": [
        "all alpha.analytics_* rows"
      ]
    },
    {
      "id": "aitd-105-axis-idempotency",
      "title": "API Axis: Idempotency Model",
      "status": "Accepted",
      "decision": "SHIP: Idempotency-Key required on source imports; deterministic source_fact_key required for materializer writes.",
      "trace": [
        "alpha.analytics_source_import",
        "all materializer writes"
      ]
    },
    {
      "id": "aitd-106-axis-auth-shape",
      "title": "API Axis: Auth Shape",
      "status": "Accepted",
      "decision": "SHIP: role plus scopes plus scoped claims such as studentIds, schoolSourcedIds, and agentOf.",
      "trace": [
        "all endpoints",
        "JWT claims"
      ]
    },
    {
      "id": "aitd-107-axis-eventing",
      "title": "API Axis: Eventing Model",
      "status": "Accepted",
      "decision": "SHIP: poll plus modifiedSince; DEFER webhooks until an integration demonstrates a persona-blocking need for push.",
      "trace": [
        "all GET list endpoints"
      ]
    },
    {
      "id": "aitd-108-axis-error-envelope",
      "title": "API Axis: Error Envelope",
      "status": "Accepted",
      "decision": "SHIP: typed RFC 7807 Problem responses with stable analytics:* codes and stable type URIs.",
      "trace": [
        "all endpoints",
        "source import adapters"
      ]
    },
    {
      "id": "aitd-109-axis-tenant-routing",
      "title": "API Axis: Tenant Routing",
      "status": "Accepted",
      "decision": "SHIP: tenant_id comes from the JWT claim only, not URL path or request body.",
      "trace": [
        "all endpoints",
        "all tables"
      ]
    },
    {
      "id": "aitd-110-axis-conformance-evidence",
      "title": "API Axis: Conformance Evidence",
      "status": "Accepted",
      "decision": "SHIP: Analytics conformance is the migration metric_check runner plus the reporting probe plus three-way convergence, not a 1EdTech spec runner.",
      "trace": [
        "loop/migration/artifacts/alpha/reconcile",
        "loop/scripts/reporting-probe.mjs",
        "surface_qc",
        "skill_pack"
      ]
    },
    {
      "id": "aitd-111-axis-privacy-retention",
      "title": "API Axis: Privacy And Retention",
      "status": "Accepted",
      "decision": "SHIP: derived/ingested facts inherit source retention and authorization, with tombstone/correction rows when a source is deleted or superseded.",
      "trace": [
        "all alpha.analytics_* tables",
        "alpha.analytics_source_import"
      ]
    },
    {
      "id": "aitd-112-axis-list-endpoints",
      "title": "API Axis: List Endpoints",
      "status": "Accepted",
      "decision": "SHIP: one named list endpoint per Analytics collection, plus the readable MAP reference tables (/norms, /norms/table, /r90/table), the norms/R90 translations (/norms/rit, /norms/percentile, /r90), and the GOALS forward calendar read (/school-days-remaining); DEFER a generic metric endpoint until at least two external consumers need dynamic metric discovery.",
      "trace": [
        "API catalog",
        "aitd-015-norms-r90-readable-resources",
        "aitd-016-scale-translation-apis",
        "aitd-018-goals-school-days-remaining"
      ]
    }
  ],
  "completionRollupRetention": {
    "id": "analytics.completion_rollup.probe_tenant_retention.v2026-07-03",
    "policyRef": "alpha.policy.analytics.completion_rollup_retention.v2026-07-03",
    "issue": "https://github.com/andymontgomery-byte/platform3/issues/286",
    "table": "alpha.analytics_completion_rollup",
    "endpoint": "GET /alpha/analytics/v1/completion-rollups",
    "appliesToTenants": [
      "reviewer-analytics",
      "analytics-*debug*"
    ],
    "currentReadRule": "Ordinary completion-rollups reads filter to superseded_at is null, source_deleted_at is null, and reportable quality_status values before sorting or paging.",
    "paginationRule": "completion-rollups reads are page-bounded. The endpoint accepts limit/cursor and the implementation fetches at most limit + 1 rows to determine hasMore; no unbounded total-count query is allowed.",
    "retentionRule": "Probe-generated reviewer/debug rows are operational evidence, not customer history. Repeated materializations retain the latest current row per rollup key; superseded probe rows are swept so latency does not depend on historical probe volume.",
    "rollupKey": [
      "tenant_id",
      "student_id",
      "subject_id",
      "completion_scope",
      "scope_id",
      "window_start",
      "window_end",
      "policy_ref",
      "calculation_version"
    ],
    "documentedBound": "For reviewer/debug tenants, total row count is bounded by current rollup-key cardinality plus any transient in-flight page; supersededRows must return to 0 after retention.",
    "readback": {
      "checkedAt": "2026-07-03T23:33:00Z",
      "source": "read-only production Supabase query against alpha.analytics_completion_rollup",
      "rows": [
        {
          "tenantId": "analytics-debug-debug-1781267631521",
          "totalRows": 45,
          "currentRows": 45,
          "supersededRows": 0
        },
        {
          "tenantId": "analytics-live-debug-1781267728987",
          "totalRows": 1250,
          "currentRows": 1250,
          "supersededRows": 0
        },
        {
          "tenantId": "reviewer-analytics",
          "totalRows": 1606,
          "currentRows": 1606,
          "supersededRows": 0
        }
      ]
    },
    "indexes": [
      "analytics_completion_rollup_current_page_idx",
      "analytics_completion_rollup_current_lookup_idx"
    ]
  }
}
