Skills Taxonomy
The skills taxonomy is the canonical reference table that every other subsystem in Amal anchors on.
It is a read-only catalogue of 80 sub-skills organised into 9 domains, with gateway classification,
dependency mapping, and weight-type derivation. The taxonomy does not change at runtime; it is
seeded from the partner workbook (Arabic_Reading_Skills_Assessment_Mapping_v3_3.xlsx,
Skills_Master_Table sheet, 80 rows — MORPH-C01 Singular–Plural Recognition was added per the
partner Q9 memo 2026-06-21 (R12)) and is the same for every organisation.
What it contains
80 sub-skills
Each sub-skill row carries:
| Field | Purpose |
|---|---|
skillId | Kebab-string identifier (e.g. PA-01, VOCAB-C06) |
skillNameAr | Arabic display name |
domainId | Domain membership (see below) |
isGateway | Whether weakness in this skill blocks downstream learning |
startsFromGrade | First grade (1-4) at which this skill is assessed; nullable |
skillWeightType | Derived at request time from isGateway + domain membership |
skillWeightType is not stored; it is computed deterministically from the taxonomy row on every
read. The five values are Gateway, High, Core, Supporting, and Low. Derivation rule:
isGateway=Yes yields Gateway; isGateway=Partial with base_weight >= 2 yields High;
isGateway=Partial with base_weight = 1.5 yields Core; base_weight = 1.0 yields
Supporting. Arabic-accuracy indicator skills always yield Supporting regardless of gateway flag.
9 domains
| Domain ID | Description |
|---|---|
PA | الوعي الصوتي (Phonological Awareness) |
DWR | فك الرموز (Decoding) |
SENT_SYN | معنى الجملة (Sentence Syntax and Meaning) |
MORPH | الوعي الصرفي (Morphological Awareness) |
VOCAB | المفردات (Vocabulary) |
LISTEN | فهم المسموع (Listening Comprehension — wave1_active = false) |
COMP | فهم المقروء (Reading Comprehension) |
WR_SP | الكتابة (Writing and Spelling) |
FL_ACC | دقة وطلاقة (Fluency and Accuracy) |
These are the actual DomainIdEnum values used as database keys and API filter values. They are
distinct from the 6 macro-domain tiles (READ_FOUND, ACC_FLU, READ_COMP, LISTEN_COMP,
LANG_COMP, WR_SP) that appear on the dashboard. The mapping between domain IDs and macro tiles
is computed by the macro-domain rollup layer and is not a stored field on any skill row.
Wave 1 active skills
Wave 1 measures reading, comprehension, morphology, and vocabulary sub-skills (Grades 1-4). Writing
and Spelling (WR_SP domain) items will enter the bank in Wave 2. The API still returns all 80
rows; consumers filter by startsFromGrade and domain to determine applicability.
Gateway classification
A gateway skill is one whose weakness cascades. If a student is weak in a gateway skill, the Skill-Status Engine may escalate the domain status for connected downstream domains; a gateway weakness is not just about the skill itself, it shapes the intervention recommendation.
Arabic-accuracy indicator skills: the carve-out
A subset of skills are classified as Arabic-accuracy indicators: these cover features such as
shadda, tanween, madd, and short-vowel marking. These skills are never treated as standalone
gateway escalations. A weakness in an Arabic-accuracy indicator routes to the
ARABIC_ACCURACY_ONLY_MONITOR modifier profile rather than triggering a gateway domain escalation.
This carve-out is enforced in the Skill-Status Engine (FR-SSE-10) and cannot be overridden at the API level. It exists because these features are orthographic and pronunciation markers: their measurement requires written or visual items specifically, and they should not be interpreted as evidence of a broader reading difficulty in isolation.
An additional constraint: no Arabic-accuracy sub-flag may be derived from ORF or CBM data. Flags
such as AR_MADD_FLAG and AR_SHORT_VOWEL_FLAG fire only from written/visual item responses.
Hamza is out of scope entirely in Wave 1.
Skill dependencies
GET /api/skill-dependencies returns the thin skill dependency graph. In Wave 1 this still returns
an empty array (Q-SST-4); the skill_dependency_map table is structurally present but its 3-value
graph is not populated pending partner input. The endpoint shape is stable so consumers can build
against it now.
Skill relationship map (R12 Tier E — advisory only)
Separately from the empty dependency table above, R12 Tier E seeded a partner-authored skill
relationship map (PRD 12-skill-relationship-map.md, commit 312d71c0). This is a closed,
cross-country, scientifically-reviewed graph of how Arabic reading/language skills relate. It lives
in 11 GLOBAL config tables (skill_rel_type, skill_rel_subtype, skill_rel_runtime_use,
skill_rel_trigger, skill_rel_type_runtime_map, skill_rel_applicability, skill_rel_group,
skill_relationship, skill_rel_runtime_link, skill_rel_skill_coverage, skill_rel_qa_rule),
versioned by map_version (publish-then-freeze), with skill references as soft value-FKs to
skills_master_table.skillId.
The seed carries 195 relationships (176 ACTIVE + 19 FUTURE_INACTIVE) and 413 runtime
links across all dictionaries.
The relationship map is advisory-only and is deliberately NOT wired into bundle / cluster /
profile selection in Tier E. Every relationship row carries blockingEffect=NO_BLOCK and
measurementEffect=NONE — the map never changes a profile, score, RTI tier, domain status, or
measurement scope. It can only help select support / bridge / scaffold / related content after
the engine has already picked the bundle/anchor and computed every status. The boundary is enforced
by lint:skill-rel-not-wired, which fails CI if any decision/selection-engine module reads a
skillRel* accessor. There is no public endpoint for the map in Wave 1; it is seed data behind the
governance gate.
The 4 taxonomy endpoints
| Method | Path | Auth |
|---|---|---|
GET | /api/sub-skills | VIEW_OWN_PROFILE |
GET | /api/sub-skills/{id} | VIEW_OWN_PROFILE |
GET | /api/domains | VIEW_OWN_PROFILE |
GET | /api/skill-dependencies | VIEW_OWN_PROFILE |
VIEW_OWN_PROFILE is held by all 6 personas (effectively authenticated-only), but the permission
gate is explicit. The taxonomy is global reference data: requireTenantContext runs in the
middleware chain for uniformity, but responses are never filtered by organizationId.
Filtering and embedding
GET /api/sub-skills is keyset-paginated and accepts the following query parameters:
domainId, isGateway, skillRole, skillWeightType, cbmEligible, isActive,
startsFromGrade, limit (page size), and cursor (keyset cursor for pagination).
There is no macroKey filter; filter by domainId instead.
GET /api/sub-skills/{id} supports ?include=taxonomy,dependencies to embed the full taxonomy
row and any dependency edges.
# List all gateway skills in the Reading Comprehension domain
curl "https://localhost:3000/api/sub-skills?domainId=COMP&isGateway=true" \
-H "Authorization: Bearer <accessToken>"How the taxonomy connects to other subsystems
The taxonomy is the static foundation every dynamic subsystem reads from:
- Diagnostic sessions: each item in the item bank carries a
subSkillIdFK into this table. The engine scores one sub-skill at a time. - Skill-Status Engine: applies the gateway flag and Arabic-accuracy carve-out rules (ADR,
SSR, DDR layers) using
isGatewayand skill membership to decide escalation paths. - Intervention Bundles:
primaryAnchorSkillGroupin each bundle maps to a domain or skill group drawn from this taxonomy. - Progress Monitoring: per-bundle monitoring rules (PMR-001..PMR-012) reference specific skill groups from the taxonomy.
- Standards & Benchmarks: benchmark profiles are keyed by
skillIdfrom this table.
Related subsystems
- Skill-Status Engine: reads and applies the taxonomy rules
- Intervention Bundles: maps taxonomy skill groups to bundles
- Diagnostic & Practice: items are tagged by sub-skill
- Glossary: definitions for gateway skill, sub-skill, macro domain, and related terms