# Shakti Domain — Technical Specifications

> **Shakti** — Physical Discipline and Movement Intelligence Platform

This document specifies what is **implemented** in `libs/shakti/*`. Shakti is a
pure library domain: 28 Nx library projects, no `apps/shakti` and no
`services/shakti`. Every library is a self-contained TypeScript package with an
empty `dependencies` map — there are **no runtime npm dependencies and no
cross-domain imports** anywhere in `libs/shakti/`. `@shakti/core` is the only
library other Shakti libraries would build on; in the current source even that
coupling is not yet wired (libraries re-declare their own local types).

The dominant implementation pattern is a **knowledge-base / configuration
registry**: each source module declares typed, domain-specific records (e.g.
heart-rate zones, periodization presets, asana taxonomy, API endpoint
configurations), registers them into module-level `Map` stores, and exposes
`getAll*()`, `get*ById()`, `search*()`, `count*()`, and `reset*Store()`
accessors plus pure calculation helpers. This specification documents the parts
of that surface that are stable and load-bearing.

---

## 1. Core Foundation (`@shakti/core`)

`@shakti/core` is the foundation library. Its barrel (`src/index.ts`) re-exports
five modules: `types.ts`, `schemas.ts`, `db-schema.ts`, `events.ts`, `auth.ts`.
Each section below documents one of these modules in detail.

### 1.1 `Result<T, E>` (`types.ts`)

Shakti uses a discriminated-union outcome type for domain operations instead of
throwing exceptions. This allows callers to handle domain errors without
try/catch, and keeps the error handling surface explicit and type-safe.

| Member                 | Shape                     | Meaning |
| ---------------------- | ------------------------- | ------- |
| `Ok<T>`                | `{ ok: true; value: T }`  | Success |
| `Err<E>`               | `{ ok: false; error: E }` | Failure |
| `Result<T, E = Error>` | `Ok<T> \| Err<E>`         | Union   |

Constructors and combinators: `ok`, `err`, `isOk`, `isErr`, `unwrap`,
`unwrapOr`, `mapResult`, `mapError`, `flatMap`, `tryCatch`, `tryCatchAsync`.

Domain error type `ShaktiError` carries `{ code, message, details? }`. The
`SHAKTI_ERROR_CODES` constant enumerates twelve codes: `INVALID_INPUT`,
`NOT_FOUND`, `UNAUTHORIZED`, `FORBIDDEN`, `CONFLICT`, `EXERCISE_UNSAFE`,
`INJURY_RESTRICTION`, `PROGRAM_INVALID`, `SESSION_EXPIRED`, `EQUIPMENT_MISSING`,
`PREREQUISITE_UNMET`, `OVERTRAINING_RISK`. `ShaktiResult<T>` aliases
`Result<T, ShaktiError>`.

### 1.2 Movement and anatomy taxonomy (`types.ts`)

The movement and anatomy taxonomy is the shared vocabulary used throughout the
domain. Every exercise, technique, and form-analysis result references these
types — they are the conceptual atoms of the Shakti type system.

| Type                 | Values                                                                                                                                                                                     |
| -------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `MovementPattern`    | `push`, `pull`, `hinge`, `squat`, `lunge`, `rotate`, `gait`, `carry`, `brace`, `anti_rotation`, `crawl`, `climb`, `throw`, `strike` (14)                                                   |
| `BodyRegion`         | `upper_body`, `lower_body`, `core`, `full_body`                                                                                                                                            |
| `UpperBodySubRegion` | `chest`, `upper_back`, `lower_back`, `shoulders`, `biceps`, `triceps`, `forearms`, `neck`, `traps`                                                                                         |
| `LowerBodySubRegion` | `quadriceps`, `hamstrings`, `glutes`, `calves`, `hip_flexors`, `adductors`, `abductors`, `tibialis`                                                                                        |
| `CoreSubRegion`      | `rectus_abdominis`, `obliques`, `transverse_abdominis`, `erector_spinae`, `pelvic_floor`, `diaphragm`                                                                                      |
| `MuscleGroup`        | 76 individually-named muscles (chest, shoulders, back, arms, forearms, core, glutes, quads, hamstrings, adductors, calves, neck), exported as `ALL_MUSCLE_GROUPS`                          |
| `JointType`          | `shoulder`, `elbow`, `wrist`, `hip`, `knee`, `ankle`, `spine_cervical`, `spine_thoracic`, `spine_lumbar`, `sacroiliac`, `metacarpophalangeal`, `interphalangeal`, `temporomandibular` (13) |

`BODY_REGION_MAP` maps each region to its sub-regions;
`getBodyRegionForSubRegion` resolves the reverse. `JOINT_ROM_NORMS` holds
normative range-of-motion data (flexion / extension and optional abduction,
adduction, rotation, lateral flexion, internal/external rotation) per joint;
`getJointROM(joint)` looks one up.

### 1.3 Training value objects (`types.ts`)

Training value objects model the building blocks of how exercise is prescribed.
Rather than embedding raw numbers in workout records, these types carry semantic
meaning — a `Tempo` is not just four integers but a named set of eccentric,
pause, concentric, and pause phases with helpers to format and compute total
time. This prevents ambiguity when workouts are serialized, shared, or analysed.

- **`DifficultyScale`** — `beginner`, `intermediate`, `advanced`, `elite`,
  `master`. Ordered via `DIFFICULTY_ORDER`; compared with `compareDifficulty`
  and `isDifficultyAtLeast`.
- **`IntensityLevel`** — `low`, `moderate`, `high`, `very_high`, `maximal`.
  `getIntensityHRPercent(level)` returns a heart-rate `%` band.
- **`Duration`** — `{ seconds }` value object with
  `durationFromSeconds/Minutes/Hours`, `durationToMinutes/Hours`,
  `formatDuration`, `addDurations`.
- **`Tempo`** — `{ eccentric, pauseBottom, concentric, pauseTop }`. Helpers:
  `createTempo`, `tempoTotalSeconds`, `formatTempo`. Seven `TEMPO_PRESETS`
  (`controlled`, `explosive`, `time_under_tension`, `isometric`, `normal`,
  `eccentric_focus`, `speed`).
- **`RepRange`** — `{ min, max, target }` with `createRepRange` and five
  `REP_RANGE_PRESETS` (`strength`, `power`, `hypertrophy`, `muscular_endurance`,
  `endurance`).
- **`SetType`** — `straight`, `drop`, `super`, `giant`, `cluster`, `rest_pause`,
  `myo_rep`, `pyramid`, `reverse_pyramid`, `amrap`, `emom`, `tabata` (12).
  `SetConfiguration` bundles `{ type, sets, repRange, restBetweenSets }`.
- **`RestPeriod`** — `{ duration, mode, activity? }` with `RestMode` of `active`
  / `passive`; five `REST_PRESETS`.
- **`EquipmentCategory`** — 14 categories (`barbell`, `dumbbell`, `kettlebell`,
  `machine`, `cable`, `band`, `bodyweight`, `cardio`, `yoga`, `martial_arts`,
  `recovery`, `specialty`, `outdoor`, `home`). `EQUIPMENT_CATALOG` holds 75
  `EquipmentItem` records (`id`, `name`, `category`, `portability`,
  `spaceRequired`); `getEquipmentByCategory` and `getPortableEquipment` filter
  it.
- **`PhysicalAttributes`** — height, weight, optional wingspan, body-fat,
  resting/max HR, VO2max, measurement system. Helpers: `estimateMaxHR(age)`
  (`220 − age`), `calculateBMI`, `getBMICategory`.
- **`FitnessAssessment`** — eight scored qualities (cardiovascular, strength,
  flexibility, balance, power, endurance, agility, coordination).
  `computeOverallFitness` averages them; `getFitnessLevel(score)` maps a 0–100
  score to a `DifficultyScale`.
- **`InjuryStatus`** —
  `{ id, bodyPart, severity, phase, description, dateReported, restrictions }`.
  `InjurySeverity` ∈ {`minor`, `moderate`, `severe`, `critical`}; `InjuryPhase`
  ∈ {`acute`, `subacute`, `chronic`, `rehabilitation`, `return_to_sport`}.
- **`MovementRestriction`** — `RestrictionType` ∈ {`avoid`, `reduce_load`,
  `reduce_rom`, `modify_tempo`, `use_alternative`}, with affected patterns /
  joints and optional load/ROM caps.
  `isExerciseSafe(patterns, joints, restrictions)` returns whether an exercise
  clears the `avoid` restrictions.
- **`EnergySystem`** — `phosphagen`, `glycolytic`, `oxidative`. `ENERGY_SYSTEMS`
  documents duration and intensity ranges;
  `dominantEnergySystem(durationSeconds)` selects one.
- **`TrainingGoal`** — 20 goal values, exported as `ALL_TRAINING_GOALS`.
- **`Laterality`** — `unilateral`, `bilateral`, `alternating`, `ipsilateral`,
  `contralateral`. `PlaneOfMotion` — `sagittal`, `frontal`, `transverse`,
  `multiplanar` (with `PLANE_DESCRIPTIONS`). `ForceVector` — six values with
  `FORCE_VECTOR_EXAMPLES`.
- **`LoadType`** — `absolute`, `relative`, `bodyweight_percentage`, `rpe`,
  `rir`, `percentage_1rm`. `LoadPrescription` builders: `createAbsoluteLoad`,
  `createRelativeLoad`, `createRPELoad` (validates 1–10), `createRIRLoad`.
  `rpeToRIR` / `rirToRPE` convert between RPE and reps-in-reserve.
- **`ProgressionModelType`** — `linear`, `undulating`, `block`, `conjugate`,
  `step_loading`, `autoregulated`. `PROGRESSION_PRESETS` provides a
  `ProgressionModel` per type with weekly increment, deload frequency, and
  deload percentage.

### 1.4 Validation schemas (`schemas.ts`)

`schemas.ts` defines TypeScript interfaces plus hand-written `validate*`
functions that return `readonly string[]` of error messages (empty = valid).
**Validation is plain TypeScript — there is no Zod, Yup, or Joi in this
domain.**

The foundational enums define the platform's disciplinary vocabulary. These
values appear throughout the rest of the codebase — in technique records,
session logs, program schemas, and the database schema — so knowing them is
essential context:

| Type                | Values (count)                                                                                                                                                                                                                                                                                                             |
| ------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `Discipline`        | `yoga`, `martial_arts`, `strength_training`, `combat_sports`, `calisthenics`, `cardio`, `mobility`, `dance`, `pilates`, `crossfit`, `functional_training`, `olympic_weightlifting`, `powerlifting`, `strongman`, `gymnastics`, `swimming`, `running`, `cycling`, `rowing`, `climbing` (20) — exported as `ALL_DISCIPLINES` |
| `YogaStyle`         | `hatha`, `vinyasa`, `ashtanga`, `iyengar`, `bikram`, `yin`, `restorative`, `kundalini`, `power`, `jivamukti`, `anusara`, `sivananda`, `forrest`, `rocket`, `aerial` (15)                                                                                                                                                   |
| `MartialArtStyle`   | 28 styles (BJJ, judo, three karate variants, two taekwondo variants, Muay Thai, boxing, kickboxing, wing chun, aikido, krav maga, hapkido, capoeira, sambo, three wrestling variants, two kung fu variants, tai chi, MMA, kendo, fencing, savate, lethwei, sanda, pencak silat)                                            |
| `DifficultyLevel`   | `beginner`, `intermediate`, `advanced`, `elite`, `master`                                                                                                                                                                                                                                                                  |
| `MeasurementSystem` | `metric`, `imperial`                                                                                                                                                                                                                                                                                                       |
| `Gender`            | `male`, `female`, `non_binary`, `prefer_not_to_say`                                                                                                                                                                                                                                                                        |

The schema interfaces and their validation functions cover the complete data
surface of the platform. Each interface has a paired `validate*` function that
returns an array of error strings — an empty array means the record is valid:

- **`TechniqueSchema`** / `validateTechnique` — id, name, discipline, optional
  style, difficulty, description, instruction steps, common mistakes, target +
  synergy muscles, optional breathing pattern, contraindications, prerequisites,
  media URLs.
- **`ExerciseSchema`** / `validateExercise` — `ExerciseCategory` ∈ {`compound`,
  `isolation`, `plyometric`, `isometric`, `ballistic`, `flexibility`, `balance`,
  `cardio`, `core`, `corrective`}; movement patterns, planes,
  primary/secondary/stabilizer muscles, joints, required/optional equipment,
  laterality, force vector, instructions, cues, common mistakes, regressions,
  progressions, alternatives, contraindications, media.
- **`WorkoutSchema`** + `WorkoutBlockSchema` + `WorkoutExerciseSchema` /
  `validateWorkout` — `WorkoutType` has 16 values (`strength`, `hypertrophy`,
  `endurance`, `hiit`, `circuit`, `yoga_flow`, `martial_arts_drill`, `sparring`,
  `technique`, `mobility`, `recovery`, `sport_specific`, `competition`,
  `assessment`, `warmup`, `cooldown`). A workout has an optional warmup block,
  one-or-more main blocks, and an optional cooldown block.
- **`ProgramSchema`** + `ProgramPhaseSchema` / `validateProgram` — `ProgramGoal`
  (10 values), `PeriodizationType` ∈ {`linear`, `undulating`, `block`,
  `conjugate`, `concurrent`, `reverse_linear`}; duration weeks, days per week
  (1–7), and one-or-more phases each with a week range, focus, intensity range,
  volume multiplier, deload flag, and workout IDs.
- **`SessionSchema`** + `SessionExerciseData` + `SessionSetData` /
  `validateSession` — `SessionStatus` ∈ {`planned`, `in_progress`, `completed`,
  `paused`, `skipped`, `cancelled`}. A session records practitioner, optional
  workout/program, discipline, type, start/end times, planned/actual duration,
  per-exercise set data, totals (volume, sets, reps), optional calories, heart
  rates, perceived exertion (1–10), mood (1–10), and energy level.
- **`PractitionerSchema`** / `validatePractitioner` — user id, display name,
  optional demographics, measurement system, disciplines, goals, fitness level,
  experience years, available equipment, available days/week, session duration
  preference, injuries, restrictions, timezone, timestamps.
- **`BeltRankSchema`** / `validateBeltRank` — `BeltColor` ∈ {`white`, `yellow`,
  `orange`, `green`, `blue`, `purple`, `brown`, `red`, `black`, `coral`,
  `red_white`}; style, optional degree, order, minimum time in months,
  requirements.
- **`AchievementSchema`** + `AchievementCondition` / `validateAchievement` —
  `AchievementCategory` (10 values), `AchievementRarity` ∈ {`common`,
  `uncommon`, `rare`, `epic`, `legendary`}; xp reward, one-or-more conditions
  (metric / operator / value), secret flag.
- **`ChallengeSchema`** / `validateChallenge` — `ChallengeType` ∈ {`streak`,
  `volume`, `consistency`, `skill`, `competition`, `team`, `seasonal`};
  duration, date window, target value/metric, optional participant cap, rewards,
  rules.
- **`InstructorSchema`** + `CertificationSchema` / `validateInstructor` — bio,
  disciplines, styles, certifications, years of experience, specializations,
  rating (0–5), student/class counts, verification flag, languages.
- **`ClassSchema`** / `validateClass` — `ClassFormat` ∈ {`in_person`, `virtual`,
  `hybrid`, `on_demand`}; instructor, discipline, difficulty, duration,
  capacity, enrollment, scheduled time, optional recurrence, location, virtual
  meeting URL, equipment, price/currency.
- **`GoalSchema`** + `GoalMilestoneSchema` / `validateGoal` — title, target /
  current value, unit, optional deadline, milestones, completion flag.

`schemas.ts` also provides standalone calculation helpers that derive numeric
results from schema data: `checkEquipmentAvailability`, `calculateVolume`,
`calculateOneRepMax` (Brzycki formula `w · 36/(37−reps)`),
`calculateWeightForReps`, `calculateTotalSessionVolume`,
`calculateSessionDensity`, `calculateFormScore`, `calculateTrainingAge`.

### 1.5 Authorization (`auth.ts`)

Role-based access control is implemented as static permission tables evaluated
at call time. There is no middleware framework or runtime token-signing — this
module is pure logic that any application layer can call to enforce access
rules.

- **`ShaktiRole`** — `practitioner`, `instructor`, `studio_owner`, `admin`,
  `moderator`, `content_creator`, `guest`. `ROLE_HIERARCHY` assigns numeric
  ranks (guest 0 → admin 100); `isRoleAtLeast` / `compareRoles` order them.
- **`ResourceType`** — 16 resources (`exercise`, `technique`, `workout`,
  `program`, `session`, `practitioner_profile`, `class`, `achievement`,
  `challenge`, `instructor_profile`, `studio`, `certification`, `belt_rank`,
  `comment`, `media`, `analytics`).
- **`Action`** — `create`, `read`, `update`, `delete`, `publish`, `enroll`,
  `manage`.
- **`Permission`** — `{ resource, action, scope }` with `scope` ∈ {`own`,
  `assigned`, `all`}. `PermissionKey` is the templated string
  `` `${resource}:${action}:${scope}` ``.
- Per-role permission arrays are defined for all seven roles;
  `getPermissionsForRole(role)` returns them.
- **`checkPermission(ctx, resource, action, resourceOwnerId?)`** evaluates an
  `AuthContext` against the permission set, checking `all` then `own` then
  `assigned` scope, and returns an `AuthorizationResult`
  (`{ allowed, reason?, matchedPermission? }`).
- Token helpers: `TokenClaims`, `isTokenExpired`, `getTokenRemainingSeconds`,
  `tokenClaimsToAuthContext`. API-key helpers: `ApiKeyConfig`,
  `validateApiKeyAccess` (checks expiry, allowed resources, then permission).

This is a pure authorization-logic library; it performs no token signing,
network calls, or session storage.

---

## 2. Discipline Domain Objects

Each discipline library is a knowledge base of typed records. The common pattern
across all five disciplines is: typed record interfaces declared locally,
records registered into module-level `Map` stores at module initialization, and
`getAll*` / `get*ById` / `search*` accessors exported for querying. Field and
enum definitions are local to each module — they share no cross-library imports.

### 2.1 `@shakti/yoga`

Six modules (`asanas`, `pranayama`, `sequences`, `styles`, `meditation`,
`ayurveda`). Asana taxonomy includes `AsanaCategory` (11 values: standing,
seated, prone, supine, inversion, balance, twist, backbend, forward fold, arm
balance, hip opener), and yoga-specific concepts modelled as types:

- `Chakra` — 7 energy centres
- `Dosha` — `vata` / `pitta` / `kapha` (Ayurvedic constitutions)
- `Drishti` — 8 traditional gaze points used during asana practice
- `Bandha` — `mula`, `uddiyana`, `jalandhara`, `maha` (energy locks)
- `PropType` — 9 supported yoga props (blocks, straps, bolsters, etc.)
- `EngagementLevel` — `primary`, `secondary`, `stabilizer`, `stretched`

`pranayama` covers breathwork techniques; `sequences` covers sequence
construction; `ayurveda` covers dosha-based personalization.

### 2.2 `@shakti/strength`

Eight modules: `exercises`, `compounds`, `olympic`, `calisthenics`, `programs`,
`powerlifting`, `hypertrophy`, `programs`. `programs.ts` ships 15 complete
program templates plus 5 deload protocols spanning linear progression,
undulating, block, and conjugate periodization. These are fully specified
multi-week templates — not just parameter ranges, but complete program
structures with phases, loading schemes, and deload triggers.

### 2.3 `@shakti/martial-arts`

Eight modules: `techniques`, `striking`, `grappling`, `mma`, `traditional`,
`weapons`, `ranks`, `sparring`.

- `weapons.ts` covers bo staff, nunchaku, sword, kendo, kali, and HEMA
  (Historical European Martial Arts)
- `ranks.ts` covers belt/rank progression across multiple martial art styles
- `sparring.ts` covers sparring and competition formats with scoring and
  matchmaking

### 2.4 `@shakti/combat-sports`

Five modules: `boxing`, `kickboxing`, `muay-thai`, `wrestling`, `mma-training`.
Boxing alone covers stances, footwork, shadowboxing, bag and pad work,
conditioning, rulesets, training camps, and weight-cutting protocols — showing
the depth of coverage: each module models the full sport preparation lifecycle,
not just a technique list.

### 2.5 `@shakti/mobility`

Six modules: `stretching`, `joint-mobility`, `smr` (self-myofascial release),
`recovery`, `injury-prevention`, `rehabilitation`. The rehabilitation module
includes graduated return-to-training protocols with clearance checkpoints,
making the library useful for practitioners coming back from injury as well as
healthy practitioners maintaining movement quality.

---

## 3. Intelligence Libraries

The intelligence libraries work across all disciplines. They consume the shared
anatomy taxonomy and exercise vocabulary from `@shakti/core` (and from their own
local type re-declarations) to provide analysis, adaptation, and advanced
feature modules that are not tied to any single discipline.

### 3.1 `@shakti/biometrics`

Five modules: `heart-rate`, `hrv` (within `heart-rate`), `body-composition`,
`performance-metrics`, `recovery-metrics`, `device-integrations`.

`heart-rate.ts` exposes the following types and calculators:

- **Types**: `HRZoneNumber` (1–5), `MaxHRMethod`, `HRVMetric` (`rmssd`, `sdnn`,
  `pnn50`, `lf_hf_ratio`, `ln_rmssd`, `hrv_score`), `ThresholdType`,
  `CardiacDriftCategory`, `RecoverySpeed`.
- **Record types**: `HeartRateZone`, `MaxHRFormula`, `HRVAnalysisConfig`,
  `RestingHRBenchmark`, `CardiacDriftConfig`, `HRRecoveryBenchmark`,
  `ThresholdEstimation`, `HRTrackingConfig`.
- **Calculations**: `calculateMaxHR`, `calculateHRR`, `calculateTargetHR`.
- **Registry accessors**: `getAll*`, `get*`, `searchHeartRate`,
  `getHeartRateCount`, `resetHeartRateStore`.

`device-integrations.ts` provides a catalog of named wearable and sensor
integrations as descriptive configuration records — not live SDK clients. Each
record documents how to connect and what data the platform provides, so
application code can use the catalog to guide integration implementation:

- **Types**: `PlatformType`, `ConnectionType` (`bluetooth_le`, `ant_plus`,
  `wifi`, `usb`, `api_rest`, `api_oauth2`, `nfc`), `DeviceCategory` (10),
  `DataType` (15), `SyncFrequency`.
- **Documented platforms**: Apple HealthKit, Google Health Connect, Samsung
  Health SDK, Garmin Connect, Whoop 4.0, Oura Ring Gen3, Fitbit, Polar Vantage
  V3, COROS PACE 3, Wahoo TICKR, Stages power meters, the Bluetooth GATT
  services (Heart Rate, Cycling Power, Cycling/Running Speed and Cadence), ANT+
  profiles, Tonal, and PUSH Band 2.0. Each record carries prose-level setup and
  rate-limit metadata.

### 3.2 `@shakti/form-analysis`

Five modules: `motion-capture`, `form-scoring`, `technique-analysis`,
`real-time-feedback`, `video-analysis`.

`form-scoring.ts` is the domain's fault taxonomy and scoring knowledge base. It
defines:

- `FormCategory` — 10 exercise categories, each with different evaluation
  criteria
- `DeviationType` — 14 fault patterns: `knee_valgus`, `butt_wink`,
  `forward_lean`, `bar_drift`, `lockout_incomplete`, `elbow_flare`, and 8 others
- `SeverityLevel` — fault severity on a graded scale
- `ScoreGrade` — letter grades `A` through `F` rolled up from severity scores

`motion-capture.ts` documents pose-estimation approaches (MediaPipe /
TensorFlow.js are referenced as descriptive options). All pose math is
self-contained — there is no `@aja` dependency in this library.

### 3.3 `@shakti/personalization`

Five modules: `practitioner-profiling`, `adaptive-programming`,
`ai-workout-generation`, `recommendation-engine`, `goal-management`. Together
these modules model the full lifecycle of a personalized training relationship —
from initial profiling through adaptive adjustments to goal tracking.

### 3.4 `@shakti/gamification`

Six modules: `achievement-system`, `streak-system`, `xp-leveling`, `challenges`,
`leaderboards`, `rewards-virtual-items`. The gamification library is designed to
listen to domain events rather than be called directly from session-logging code
— this keeps the two concerns decoupled and ensures gamification enrichment adds
no latency to the core training flow.

### 3.5 `@shakti/sota-critical`

`@shakti/sota-critical` contains 16 modules. These modules represent
production-near capabilities that need special hardware or research-grade data
sources, and so are kept separate from the main platform to allow independent
deployment and validation:

- `mental-health-mood`, `readiness-scheduling`, `velocity-based-training`
- `dynamic-sequence-generation`, `virtual-world-gamification`,
  `longevity-healthspan`
- `genetic-biomarker`, `vr-fitness`, `smart-gym-intelligence`, `health-ai-coach`
- `advanced-social-live`, `edge-ai-offline`, `voice-first-handsfree`
- `data-privacy-control`, `enterprise-b2b`, `v2-combat-style-classifier`

`voice-first-handsfree.ts` is the canonical home of the `Hey Shakti` wake-word
phrase definition. The V2 combat-style classifier module is described in detail
in §5.4.

### 3.6 `@shakti/sota-advanced`

`@shakti/sota-advanced` contains 10 modules for differentiating next-generation
capabilities that sit further along the research-to-production spectrum than
`sota-critical`:

- `accessibility-inclusion`, `advanced-equipment-integration`
- `advanced-motion-analysis`, `ai-coach-personal-trainer`
- `global-cultural-features`, `nutrition-holistic-health`
- `predictive-analytics`, `research-science-integration`
- `social-competitive-features`, `wearable-deep-integration`

### 3.7 Operations, delivery, and platform libraries

The remaining libraries handle the operational and delivery surfaces of the
platform. Each follows the same knowledge-base pattern: typed records, `Map`
stores, and `getAll*` accessors. Module counts are listed for orientation:

- `@shakti/community` — 5 modules: social profiles/feed, training groups,
  accountability partners, messaging
- `@shakti/audio` — 3 modules: audio content, music integration, voice commands
- `@shakti/video` — 4 modules: content management, follow-along workouts, live
  streaming, instructional library
- `@shakti/visualization` — 5 modules: movement/anatomy visualization, AR, VR,
  avatar
- `@shakti/studio` — 5 modules: class/equipment/facility/membership/staff
  management
- `@shakti/events` — 5 modules: calendar, class scheduling, competitions, live
  class delivery, workshops
- `@shakti/certifications` — 4 modules: credential management, continuing
  education, licensing/insurance, the Shakti certification program
- `@shakti/instructor-sdk` — 5 modules: assessment tools, business analytics,
  client management, content creation, program builder
- `@shakti/sdk` — 3 modules: SDK core, resources, utilities
- `@shakti/web` — 6 portal page-spec modules
- `@shakti/mobile` — 7 mobile feature-spec modules
- `@shakti/testing` — 5 modules: unit, integration, e2e, performance, security
  testing utilities
- `@shakti/documentation` — 3 documentation-spec modules
- `@shakti/deployment` — 5 modules: CI/CD, containerization, GPU/ML
  infrastructure, infrastructure setup, monitoring/observability

---

## 4. API Configuration Layer (`@shakti/api`)

`@shakti/api` is **not a running HTTP server and not a per-resource REST
contract.** It is a configuration-and-metadata registry: each module declares
typed configuration records describing API building blocks and registers them
into `Map` stores. It exposes `getAll*()` accessors over those records. There
are no `/api/v1/users`, `/api/v1/workouts/{id}`-style per-resource routes in the
source.

The purpose of this library is to give applications and integrators a
machine-readable description of the API surface they will build — endpoint
behaviours, auth strategies, rate-limit tiers, error-handling patterns — without
coupling to any specific HTTP framework.

Six modules (re-exported from `src/index.ts`):

- **`core-api.ts`** — declares ten record categories: 7 generic `RestEndpoint`
  configs, 7 `GraphQLSchema` configs, 7 `AuthMiddleware` configs, 7 `RateLimit`
  tier configs, 7 `ApiVersion` configs, 7 `ValidationSchema` configs, 7
  `ErrorHandler` configs, 7 `ApiDoc` configs, 7 `CorsConfig` configs, 6
  `ApiMonitor` configs. The seven `RestEndpoint` records use generic paths
  (`/api/v1/resources`, `/api/v1/resources/:id`, `/api/v1/search`,
  `/api/v1/batch`) and carry `httpMethod`, `authRequired`, `rateLimitPerMinute`,
  `responseFormat`, `cacheDuration`, and `endpointType` ∈ {`resource-listing`,
  `resource-detail`, `resource-create`, `resource-update`, `resource-delete`,
  `search`, `batch-operation`}.
- **`exercise-workout-endpoints.ts`** — endpoint _configuration_ records for
  exercise listing/detail/search, workout listing/creation/update, AI workout
  generation, and program listing/enrollment. Records carry behavioural fields
  (e.g. `WorkoutCreation` has `creationMethod`, `maxExercises`, `templateBased`,
  `validationStrict`, `draftSupport`, `collaborativeEditing`) — not literal URL
  paths.
- **`session-tracking-endpoints.ts`** — configs for session start/update,
  exercise logging, session completion, history, and progress summaries.
- **`social-community-endpoints.ts`** — configs for activity feeds, posts,
  likes, comments, user profiles, follow systems.
- **`instructor-business-endpoints.ts`** — configs for client lists, program
  assignment, class schedules/creation, business analytics, content uploads.
- **`form-analysis-endpoints.ts`** — configs for video upload, analysis
  status/results, real-time analysis, WebSocket feedback, analysis history.

Consumers query this registry to understand intended API shape; an actual HTTP
server would be built in a separate application.

---

## 5. Fighting-Ruleset Bridge

`@shakti/fighting-ruleset-bridge` is a fully-implemented, deterministic
transform library. It takes real combat-sport biomechanics measurements and
converts them into fighting-game frame data appropriate for a specific ruleset.
The bridge's barrel re-exports `fighting-ruleset-bridge.ts` and
`profiles/launch-profiles.ts`.

### 5.1 Constants and identifiers

Three constants anchor the bridge's identity and versioning:

- `SHAKTI_FIGHTING_RULESET_BRIDGE_PACKAGE_NAME = '@shakti/fighting-ruleset-bridge'`
- `SHAKTI_FIGHTING_RULESET_BRIDGE_SCHEMA_VERSION = 1`
- `SHAKTI_RULESET_IDS = ['mk', 'sf', 'tekken', 'wwe', 'ufc', 'sc', 'dj']` →
  `ShaktiRulesetId`

### 5.2 `ShaktiRulesetProfile`

A ruleset profile is the key configuration object: it maps real-sport reference
numerics onto the game-feel constants that a specific fighting game demands.
Each of the seven launch profiles holds a distinct set of scaling factors and
rule flags corresponding to that game's design language.

| Field                    | Type                         | Meaning                                                                     |
| ------------------------ | ---------------------------- | --------------------------------------------------------------------------- |
| `rulesetId`              | `ShaktiRulesetId`            | Which ruleset                                                               |
| `displayName`            | `string`                     | Human-readable name                                                         |
| `tickRate`               | `number`                     | Game tick (60 in all launch profiles)                                       |
| `startupScale`           | `number`                     | Multiplier on real-sport startup frames                                     |
| `recoveryScale`          | `number`                     | Multiplier on real-sport recovery frames                                    |
| `activeFrames`           | `ShaktiActiveFrameModel`     | `real`, `extended`, or `compressed`                                         |
| `reachScale`             | `number`                     | Multiplier on real-sport reach                                              |
| `meterModel`             | `ShaktiMeterModel`           | `super-bar`, `drive`, `heat`, `rage`, `soul-charge`, `fatal-blow`, `blazin` |
| `staminaModel`           | `ShaktiStaminaModel`         | `none`, `ufc-cardiac`, `wwe-exhaustion`, `dj-rush`                          |
| `damageScaling`          | `ShaktiRulesetDamageScaling` | `{ juggle, combo, counterHit }` multipliers                                 |
| `ringOut`                | `boolean`                    | Ring-out enabled                                                            |
| `weightDetection`        | `boolean`                    | Weight-class detection enabled                                              |
| `pinSubmissionMiniGame`  | `boolean`                    | Pin/submission mini-game enabled                                            |
| `environmentalFinishers` | `boolean`                    | Environmental finishers enabled                                             |
| `guardImpact`            | `ShaktiGuardImpactModel`     | `parry`, `guard-impact`, `drive-impact`, `none`                             |

`profiles/launch-profiles.ts` exports the seven launch profiles
(`SHAKTI_MK_RULESET_PROFILE`, `SHAKTI_SF_RULESET_PROFILE`, …) and the
`SHAKTI_LAUNCH_RULESET_PROFILES` array. `getAllShaktiRulesetProfiles()` returns
them; `getShaktiRulesetProfile(id)` looks one up (throwing
`ShaktiRulesetBridgeError` for an unknown id).

### 5.3 Move biomechanics → frame data

The bridge's core operation is a three-step pipeline:

1. **Describe the real-sport antecedent.** A `ShaktiMoveBiomechanicsInput`
   record captures everything known about a move's real-world origin: `moveId`,
   `fighterId`, `rulesetId`, optional `gameOnly` flag, `sourceSport`
   (`ShaktiCombatSport`: `boxing`, `kickboxing`, `muay-thai`, `wrestling`,
   `mma`, `bjj`, `karate`, `taekwondo`, `weapon-forms`, `game-only`),
   `shaktiTechnique`, `energyClass` (`light`/`medium`/`heavy`/`super`),
   `rangeClass` (`point-blank`/`close`/`mid`/`far`/`weapon`), the three real
   durations (`realStartupMs`, `realActiveMs`, `realRecoveryMs`),
   `forceNewtons`, `reachMeters`, and optional `rotationDegrees`, `balanceCost`,
   `staminaCost`, `cancelComplexity`, `notes`, `tags`.

2. **Validate and stamp a reference card.**
   `buildShaktiMoveReferenceCard(input)` returns a `ShaktiMoveReferenceCard`
   after enforcing the authoring rule via `validateBiomechanicsInput`:
   non-game-only moves **must** supply a real `sourceSport` and
   `shaktiTechnique`; the five numeric duration/force/reach fields must be
   positive and finite. The reference-card id is the caller's id or a stable
   SHA-256 hash of fighter/move/ruleset/sport/technique.

3. **Transform to frame data.** `transformBiomechanicsToFrameData(input)`
   returns a `ShaktiRulesetFrameDataRow` by deterministically converting real
   durations to frames (`tickRate`-scaled), applying the ruleset profile's
   startup/recovery scales and active-frame model, computing hitstop, reach in
   Unreal units, damage, and on-hit / on-block advantage from force, energy
   class, range class, and the profile's damage-scaling and guard-impact
   settings. `transformBiomechanicsCatalogToFrameData(inputs)` maps over a
   catalog.

### 5.4 V2 combat-style classifier (`@shakti/sota-critical`)

`v2-combat-style-classifier.ts` implements per-player style classification, used
by the V2 AI director to matchup players with appropriate opponents.

- **Constants**:
  `V2_STYLE_CLASSIFICATION_EVENT_TOPIC = 'shakti.player.style.updated'`,
  `V2_STYLE_CLASSIFICATION_SCHEMA_VERSION = 1`.
- **`V2CombatStyle`** — the five classifiable play styles: `boxer`, `kickboxer`,
  `striker`, `grappler`, `submission-specialist`.
- **`V2CombatStyleTelemetryEvent`** — observed combat actions with range, strike
  kind, grappling kind, success, normalized damage, frame data, cancel usage,
  and pressure state.
- **`classifyV2CombatStyle`** consumes a `V2CombatStyleClassifierInput` (player,
  match, ruleset, telemetry events) and returns a `V2CombatStyleClassification`
  carrying `primaryStyle`, `secondaryStyle`, `confidence`, `rangePreference`
  (`point-blank`/`close`/`mid`/`far`), `pressureTolerance`, `cancelConfidence`,
  a per-style `scoreVector`, a per-ruleset `styleAffinityVector`, scoring
  `evidence`, and `offRollback: true`.

### 5.5 Sister-monorepo consumption (planned, external)

The integration boundary between Shakti and the V2 fighting-game project is a
**documented contract only** — no Shakti source file imports any `@v2` package.
The V2 project documents how it consumes these libraries in
`V2/docs/integration/shakti-ruleset-bridge.md` and
`V2/docs/integration/shakti-style-classification.md`:

- V2 wraps the bridge in `@v2/shakti-ruleset-bridge`, which serializes
  deterministic CSV rows for `V2BalanceImporter`. The wrapper preserves the
  ruleset-specific table differences across the **MK / SF / Tekken / SC / DJ**
  launch profiles — Tekken's extended actives, Street Fighter's drive-impact
  guard model, Soul Calibur's weapon reach and ring-out, and Def Jam's `dj-rush`
  stamina each survive the transform intact instead of being averaged into one
  generic table. The bridge RPC is `off-rollback` and is rejected inside
  rollback frames; `game-only` reference cards are allowed (they need no
  real-sport antecedent).
- V2 wraps the classifier in `@v2/shakti-style-classification`, which turns the
  `@shakti/sota-critical` style buckets (`boxer`, `kickboxer`, `striker`,
  `grappler`, `submission-specialist`) into **AI Director** matchup hints via
  `buildV2ShaktiAIDirectorMatchupPlan`. Each hint carries
  `preferredOpponentStyles` and the `pairwiseMatchups` table the AI Director
  uses to pick opponents. Because the underlying classification is
  `offRollback: true`, the wrapper downgrades any rollback-enabled session to a
  `next-match-only` snapshot so style data never influences a live deterministic
  frame.

Those `@v2/*` adapters live in the V2 monorepo, not in `libs/shakti/`. The
per-move reference-card corpus authoring for the full V2 launch roster is
planned work tracked outside this domain.

### 5.6 Frame-data output format

The bridge's final output is a CSV row ready for downstream import. Each
`ShaktiRulesetFrameDataRow` carries all the information needed to drive a
fighting game's balance system:

- Startup / active / recovery frames
- On-hit and on-block advantage values
- Gap-to-followup, damage, hitstop
- Reach in Unreal units
- Juggle / combo / counter-hit scaling
- The profile's meter and stamina model references
- Special-rule flags
- The real-sport reference numerics the row was derived from

`serializeShaktiFrameDataCsv(rows)` serializes a batch of rows to a 26-column
CSV using the `SHAKTI_FRAME_DATA_CSV_COLUMNS` header.

---

## 6. Persistence Model

Shakti defines its database schema as data rather than using a mainstream ORM.
This fits the library-domain model: there is no running service to apply
migrations, so the schema definition serves as a source of truth that can emit
DDL when a deployment pipeline needs it.

`@shakti/core/db-schema.ts` uses a custom declarative `TableDef` model — **not
Drizzle ORM, not Prisma.** A hand-written SQL generator turns those definitions
into DDL.

- `SHAKTI_SCHEMA = 'shakti'` — the target PostgreSQL schema name.
- **Type model**: `ColumnType` (14 values: `uuid`, `text`, `varchar`, `integer`,
  `bigint`, `decimal`, `float`, `boolean`, `timestamp`, `date`, `json`, `jsonb`,
  `enum`, `array`), `ColumnDef`, `ForeignKeyRef`, `IndexDef`, `TableDef`.

The 11 tables exported as `ALL_SHAKTI_TABLES` cover the data that must survive
across requests. In-memory knowledge-base content (asana taxonomies, exercise
libraries, API configuration records) does not need table rows — it lives in the
module-level `Map` stores:

| Table               | Purpose                              |
| ------------------- | ------------------------------------ |
| `practitioners`     | Core practitioner profiles           |
| `disciplines`       | Physical disciplines                 |
| `discipline_styles` | Styles within a discipline           |
| `techniques`        | Techniques within a discipline/style |
| `exercises`         | Exercise library                     |
| `programs`          | Multi-week training programs         |
| `sessions`          | Logged training sessions             |
| `personal_records`  | Per-exercise PRs                     |
| `achievements`      | Achievement definitions              |
| `belt_ranks`        | Martial-arts belt/rank systems       |
| `streaks`           | Consistency / training streaks       |

Each `TableDef` carries columns (with nullability, defaults, foreign keys, enum
value lists, check constraints) and indexes (including `gin` trigram / JSONB
indexes). Utilities: `getTableByName`, `getTableColumns`, `getRequiredColumns`,
`getForeignKeys`, `getTableIndexes`, `generateCreateTableSQL`,
`generateAllTablesSQL`, `countTotalColumns`, `countTotalIndexes`.

There is no migration runner, ORM, or live database client in this domain — the
schema module produces DDL strings only.

---

## 7. Event System

`@shakti/core/events.ts` implements an **in-process, synchronous** event bus. It
is not Redis-backed and not a network broker. Its purpose is cross-module
decoupling within a single process — specifically, letting
`@shakti/gamification` react to training events without the session-logging code
knowing gamification exists.

### 7.1 Event envelope

Every event in the system carries a standard metadata header for traceability.
Applications can correlate events back to their originating request using
`correlationId`, and understand causal chains using `causationId`:

- **`ShaktiEventMetadata`** — `eventId`, `correlationId`, optional
  `causationId`, `timestamp`, `version`, `source`, optional `userId` /
  `practitionerId`.
- **`ShaktiEvent<T>`** — `{ type, metadata, payload }`.
- `generateEventId()` produces monotonically-suffixed `evt_<ts>_<n>` ids;
  `createEventMetadata(...)` builds metadata.

### 7.2 Event types

`ShaktiEventMap` keys the 20 supported event types (also exported as
`ALL_EVENT_TYPES`). Each event type has a strongly-typed payload interface,
preventing consumers from having to cast or check payload shape at runtime:

| Event type                 | Payload interface            |
| -------------------------- | ---------------------------- |
| `session.started`          | `SessionStartedPayload`      |
| `session.completed`        | `SessionCompletedPayload`    |
| `session.paused`           | `SessionPausedPayload`       |
| `session.resumed`          | `SessionResumedPayload`      |
| `exercise.performed`       | `ExercisePerformedPayload`   |
| `technique.attempted`      | `TechniqueAttemptedPayload`  |
| `personal_record.achieved` | `PersonalRecordPayload`      |
| `program.enrolled`         | `ProgramEnrolledPayload`     |
| `program.completed`        | `ProgramCompletedPayload`    |
| `workout.generated`        | `WorkoutGeneratedPayload`    |
| `form_analysis.completed`  | `FormAnalysisPayload`        |
| `achievement.unlocked`     | `AchievementUnlockedPayload` |
| `streak.milestone`         | `StreakMilestonePayload`     |
| `challenge.joined`         | `ChallengeJoinedPayload`     |
| `challenge.completed`      | `ChallengeCompletedPayload`  |
| `certification.earned`     | `CertificationEarnedPayload` |
| `belt.promotion`           | `BeltPromotionPayload`       |
| `injury.reported`          | `InjuryReportedPayload`      |
| `recovery.updated`         | `RecoveryStatusPayload`      |
| `biometric.synced`         | `BiometricSyncedPayload`     |

`FormAnalysisPayload` carries a `corrections` array of `FormCorrection`
(`{ cue, severity, description }`, severity ∈ `info`/`warning`/`critical`).

The separate `@shakti/sota-critical` V2 classifier publishes off-rollback under
the topic string `shakti.player.style.updated` (defined as its own constant,
independent of `ShaktiEventMap`).

### 7.3 Bus operations

The bus API covers the full lifecycle of event-driven communication, including
batching for performance, dead-letter handling for fault tolerance, and replay
for debugging and testing:

- `subscribe(type, handler)` → returns an unsubscribe function.
- `publish(type, payload, meta?)` → builds an event, appends it to the in-memory
  `eventLog`, dispatches synchronously to all handlers, and routes handler
  exceptions to a dead-letter queue.
- `publishBatched(...)` / `flushBatch()` — batches events, flushing on a 100 ms
  timer or at 50 events (`BATCH_INTERVAL_MS = 100`, `MAX_BATCH_SIZE = 50`).
- Dead-letter handling: `getDeadLetterQueue()`, `retryDeadLetterEvents()`
  (`MAX_RETRY = 3`).
- Replay / inspection: `replayEvents(from, to?)`, `getEventLog()`.
- Serialization / versioning: `serializeEvent`, `deserializeEvent`,
  `migrateEventVersion`.
- Monitoring: `getEventMetrics()` → `EventMetrics` (`published`, `handled`,
  `failed`, `batched`, `deadLetterSize`, `logSize`, `subscriberCount`).
- `resetEventSystem()` clears all bus state for test isolation.

---

## 8. Technology Stack and Build

The following table summarizes the technology decisions for the Shakti domain.
The most notable choices are the deliberate absence of runtime dependencies
(every library ships with an empty `dependencies` map) and the custom validation
and persistence layers that avoid third-party frameworks.

| Layer                | Technology                                                                                         |
| -------------------- | -------------------------------------------------------------------------------------------------- |
| Language             | TypeScript, ESM (`"type": "module"`)                                                               |
| Runtime dependencies | None — every `libs/shakti/*` `package.json` has an empty `dependencies` map                        |
| Validation           | Hand-written `validate*` functions returning `string[]` (no Zod/Yup/Joi)                           |
| Persistence model    | Custom declarative `TableDef` + SQL string generator targeting PostgreSQL schema `shakti` (no ORM) |
| Events               | In-process synchronous bus in `@shakti/core`                                                       |
| Hashing              | Node `node:crypto` (`createHash`) — used by the fighting-ruleset bridge and V2 classifier          |
| Build executor       | `@nx/js:tsc` (most libraries); `nx:run-commands` for `@shakti/fighting-ruleset-bridge`             |
| Test executor        | `@nx/vite:test` / Vitest; `nx:run-commands` running Vitest for `fighting-ruleset-bridge`           |
| Nx tags              | `scope:shakti`, `layer:domain`, `type:lib` (the bridge adds `domain:combat`)                       |

Each library co-locates `*.spec.ts` Vitest suites next to its source. Direct
invocation when Nx is unavailable:
`cd libs/shakti/<library> && npx tsc --noEmit` and `npx vitest run`.

> Note: the `libs/shakti/README.md` quick-start examples (e.g.
> `createShaktiClient`, `shakti.workouts.generate`) describe an aspirational
> client surface and an API port. They are illustrative; the implemented `sdk`
> and `api` libraries are configuration/utility modules, and no Shakti library
> binds an HTTP port.

---

## 9. Acceptance Criteria

A change to the Shakti domain is acceptable when all of the following conditions
hold. These criteria exist to prevent the domain from drifting toward stubs —
each criterion is designed to be independently verifiable.

1. **No fabricated surface.** Every type, enum value, function, table, and event
   documented or added is present in `libs/shakti/*` source.
2. **Knowledge-base coherence.** New registry records are typed against the
   module's declared interfaces and reachable through that module's `getAll*` /
   `get*` / `search*` / `count*` accessors.
3. **Domain correctness.** Calculation helpers compute real domain formulas
   (e.g. Brzycki 1RM, heart-rate reserve, frame conversion) and tests assert
   specific computed values, not just shape or truthiness.
4. **Validation parity.** Each schema interface that needs validation has a
   matching `validate*` function returning a `string[]` of messages.
5. **Bridge determinism.** `transformBiomechanicsToFrameData` produces identical
   output for identical input; non-game-only moves are rejected without a real
   `sourceSport` and `shaktiTechnique`.
6. **Self-containment.** Libraries add no runtime npm dependencies and no
   cross-domain imports; the standalone-library model is preserved.
7. **Build and lint.** `npx tsc --noEmit` and the library's Vitest suite pass.
