v0.5 (Live Assist — on-the-job voice companion) milestone complete. 4 phases: P0 (pre-execution, v0.1.10) → P1 (assist core + guardrail, v0.1.11) → P2 (integration + tech-debt + NFR, v0.1.12) → P3 (final review + ship, v0.1.13 = milestone release). 16/16 REQs covered (3 ASSIST + 4 NFR + 9 IDEATE). 4 v0.6 backlog. 469 tests passed, 0 failed. 1 P0 fixed (guardrail processor safety). 8 P1+ flagged for v0.6. 8 v0.4 P1+ tech-debt addressed. G-049 + G-067 grill MUSTs resolved. ESCALATION-01 (PIPEDA) OPEN for human legal review before assist surface go-live. ---ci--- project: praxis phase: 3 milestone: v0.5 status: complete requirements: covered: [REQ-ASSIST-01, REQ-ASSIST-02, REQ-ASSIST-03, REQ-NFR-ASSIST-01, REQ-NFR-ASSIST-02, REQ-NFR-ASSIST-03, REQ-NFR-ASSIST-04, REQ-IDEATE-01, REQ-IDEATE-02, REQ-IDEATE-03, REQ-IDEATE-04, REQ-IDEATE-05, REQ-IDEATE-06, REQ-IDEATE-07, REQ-IDEATE-08, REQ-IDEATE-09] partial: [] ---/ci---
32 KiB
Praxis — Requirements
Milestone: v0.5 (Live Assist — on-the-job voice companion) — complete Status: milestone released as v0.1.13 (merged to main) — 16/16 v0.5 REQ covered; v0.4 complete (released as v0.1.9, 8/8 REQ covered); v0.3 complete (released as v0.1.5, 13/13 REQ covered)
Formal requirements with REQ-IDs. Scoped to the active milestone unless noted. v0.1/v0.2/v0.3/v0.4/v0.5 requirements (complete) are retained for reference with their final status. Later-milestone requirements are marked deferred.
v0.5 Active Requirements (complete — released as v0.1.13, retained for reference)
Live Assist (v0.5 core)
| REQ-ID | Requirement | Priority | Phase | Status |
|---|---|---|---|---|
| REQ-ASSIST-01 | Hands-free voice companion invocable while working — distinct from the practice voice loop (v0.1). Always-listening or wake-word/hotkey-activated, short coaching turns interleaved with real work. Reuses the v0.1 voice pipeline (Pipecat + Deepgram + Cartesia + Ollama Cloud) in a new "assist" mode. | must | P1 | complete |
| REQ-ASSIST-02 | Context-aware — knows the learner's current scenario/skill path. Binds to the learner's active path week (D-037) + scenario context so coaching is relevant to the job they're doing. Carries forward learner state from SQLite (D-007 preserved). | must | P1 | complete |
| REQ-ASSIST-03 | Guardrails: coaches, does not do the job; never lies to real customers. Safety-critical: the AI is in the learner's ear during real customer interactions. Extends D-019 guardrail layer with Live-Assist-specific ruleset. Never impersonates, never gives parrot-able answers, never claims false authority. | must | P1 | complete |
v0.5 Non-Functional Requirements (complete)
| REQ-ID | Requirement | Target | Phase | Status |
|---|---|---|---|---|
| REQ-NFR-ASSIST-01 | Live Assist voice round-trip latency | < 600ms target (C-8); estimated ~655ms (Piper + lean prompt — D-065, D-066). AT RISK — accept ~650ms for pilot if trending down; <600ms hardening in v0.6. Wake-word → first-audio is a separate ~850-1150ms budget (warm WebRTC — D-067). Must not degrade the practice pipeline (assist is a separate mode, not concurrent — D-061). | P1 | complete (p95 measurement in P2) |
| REQ-NFR-ASSIST-02 | Hands-free invocation on $100 Android | Picovoice Porcupine on-device (offline, ~1MB RAM, <4% core — verified). Battery ~4-9% per 8h shift (estimated, needs Phase-1 measurement — R-ASSIST-14). Foreground service of type microphone (Android 14+). Built-in wake word for v0.5 pilot (D-064 — MAU pricing has no recurring free tier, R-ASSIST-01); custom "Hey Praxis" post-pilot; Vosk fallback. Tap-to-talk fallback for battery-saving / wake-word failure / noisy environments. |
P1 | complete (tap-to-talk only per D-071; wake-word deferred to v0.6) |
| REQ-NFR-ASSIST-03 | Live Assist guardrail enforcement | 3-layer guardrail (D-060, D-068): (1) coaching-mode system prompt (ask guiding questions, never give the answer, never claim false authority, never impersonate); (2) regex output filter (DIRECT_SCRIPT_RE + IMPERATIVE_RE + FALSE_AUTHORITY_RE + IMPERSONATION_RE; COACHING_QUESTION_RE allowed) with one retry on block + canned coaching fallback; (3) audit log (turns table guardrail_verdict JSON + cohort guardrail_block_rate safety signal for operators). Consent disclosure: foreground-service notification + learner-facing "Assist is on — those around you may be recorded" at shift start (D-070). Output filter false-negative residual risk mitigated by defense-in-depth + post-v0.5 LLM-as-judge. | P1 | complete (FN 13.3% ≤ 20% pilot threshold per G-067) |
| REQ-NFR-ASSIST-04 | Live Assist session model | Shift-bounded (learner starts/ends a shift; assist turns within — D-062). Auto-end after 8h via PRAXIS_ASSIST_MAX_SHIFT_HOURS=8 (D-069). Aggregates as session_type=assist in v0.4 cohort pipeline (no schema change — new metric strings: assist_shifts_count, assist_turns_count, assist_avg_turns_per_shift, assist_active_learners_count, assist_guardrail_block_rate). Does NOT update mastery (D-063 — schedule_mastery=False for assist shifts). k-anonymity ≥ 10 applies to assist metrics (D-034 carry-forward). |
P1 | complete |
NFRs refined from pending-research to research-grounded after the v0.5 RESEARCH stage (see RESEARCH-v0.5-live-assist.md). Targets are research-derived; Phase-1 measurement may further refine R-ASSIST-02 (latency) and R-ASSIST-14 (battery).
v0.5 Ideation-Derived Requirements (IDEATE-01..09, accepted)
Generated by the IDEATE stage (3-tier analysis: mechanical git-mining + backend-enriched + chaos engineering). 9 of 13 ideas accepted into v0.5; 4 deferred to v0.6 (see v0.6 Backlog below).
Guardrail Quality & Safety (IDEATE-01, 02, 09)
| REQ-ID | Requirement | Priority | Phase | Status |
|---|---|---|---|---|
| REQ-IDEATE-01 | Guardrail output-filter tuning corpus + adversarial bypass test (pre-ship). Build a synthetic corpus (LLM-generate coaching vs direct-answer responses, label, tune the regex patterns DIRECT_SCRIPT_RE/IMPERATIVE_RE/FALSE_AUTHORITY_RE/IMPERSONATION_RE). Add an adversarial-bypass test with paraphrased direct answers designed to slip past the regex. Proactively mitigates R-ASSIST-06/07 (false-positive + false-negative risks) before the guardrail ships blind on its two most safety-critical metrics. Relates to the v0.1 latent safety-trap lesson (misspelled _DEBRIFF_LEGAL_REDIRECT — the rewrite/fallback path was never exercised by tests). |
must | P1 | complete |
| REQ-IDEATE-02 | In-loop guardrail processor pipeline test + GuardrailContext.role 'assist' extension. (1) Add a pipeline-integration test that inserts the LiveAssistGuardrail as a post-LLM Pipecat frame processor between llm and tts (the existing test_guardrail.py only tests check() standalone). (2) Extend the GuardrailContext.role Literal to include 'assist' (currently `system |
user | assistant | debrief` — the LiveAssistGuardrail hits an interface gap). Both are structural coverage holes Phase 1 will hit immediately. |
| REQ-IDEATE-09 | Audit-log completeness on abrupt shift end. Log the assist turn incrementally — persist the ASR transcript + LLM response + guardrail verdict before/at TTS start, not after playback completes — so abrupt termination (battery death R-ASSIST-14, power loss mid-turn) still leaves an audit trail. For a safety-critical surface (REQ-ASSIST-03), an incomplete audit log undermines the guardrail_block_rate safety signal and the operator's ability to investigate incidents. | must | P1 | complete |
Chaos & Resilience (IDEATE-03, 08)
| REQ-ID | Requirement | Priority | Phase | Status |
|---|---|---|---|---|
| REQ-IDEATE-03 | Mode-conflict enforcement: assist vs practice mutual exclusivity. Add a server-side guard (reject shift-start if a practice session is active, or vice versa) + a chaos test invoking assist during an active practice session. D-061 states assist is a separate mode (not concurrent), but nothing currently enforces mutual exclusivity — the server-side assist API and the practice /pipecat/webrtc endpoint are independent with no shared state guarding against a second connection. | must | P1 | complete |
| REQ-IDEATE-08 | WebRTC mid-shift drop + reconnect logic. Specify the reconnect state machine (does the foreground service auto-reconnect? what does the learner experience during the gap? does the in-flight assist turn retry or fail?) + add a chaos test (kill the WebRTC connection mid-shift, verify reconnect + turn recovery). R-ASSIST-09 names the risk; D-067 mandates warm WebRTC with 30s heartbeat but the reconnect logic is unspecified. | must | P1 | complete |
Security & Privacy (IDEATE-05)
| REQ-ID | Requirement | Priority | Phase | Status |
|---|---|---|---|---|
| REQ-IDEATE-05 | Customer-speech PII handling in the assist turns audit log (STRIDE information-disclosure). The ambient mic (R-ASSIST-08) captures BOTH the learner and the real customer; ASR transcribes both; the turns table stores transcribed text. The customer is a third party — their transcribed speech is third-party PII in SQLite. v0.5 needs an explicit policy: (a) strip customer turns from the audit log, (b) store only the learner's utterances, or (c) document that the audit log contains customer speech + apply consent-disclosure (D-070) + retention limits. Intersects with the R-ASSIST-08 legal review (D-073). | must | P1 | complete |
Spec Refinement (IDEATE-04)
| REQ-ID | Requirement | Priority | Phase | Status |
|---|---|---|---|---|
| REQ-IDEATE-04 | Measurable NFR targets for REQ-NFR-ASSIST-01 and REQ-NFR-ASSIST-03. (1) Latency: specify 'p95 assist-turn latency ≤ 650ms in Phase-1 measurement (pilot tolerance per D-072); <600ms hardening deferred to v0.6' — resolves the ambiguity in REQ-NFR-ASSIST-01's current text. (2) Guardrail: specify 'false-positive rate < 5% on the tuning corpus (REQ-IDEATE-01); false-negative rate measured + trended nightly' — makes REQ-NFR-ASSIST-03 verifiable. | must | P1 | complete |
Process / Tech Debt (IDEATE-06)
| REQ-ID | Requirement | Priority | Phase | Status |
|---|---|---|---|---|
| REQ-IDEATE-06 | Carry-forward the 8 v0.4 P1+ findings into the v0.5 backlog as a 'tech-debt wave'. Especially: (1) aggregation in-memory cache lost on restart (REVIEW.md P1+ #7 — directly corrupts v0.5 assist_active_learners_count after a server restart); (2) cookie-secret length validation (P1+ #3); (3) set_credential_status enum/f-string SQL (P1+ #4/#8). High-value, low-effort — folding into the v0.5 PLAN as a dedicated wave. | should | P1 | complete |
Cost (IDEATE-07)
| REQ-ID | Requirement | Priority | Phase | Status |
|---|---|---|---|---|
| REQ-IDEATE-07 | Assist per-turn cost tracking + C-3 budget impact verification. Extend server/cost.py to log per-assist-turn cost (each assist turn is a separate gemma4:cloud invocation). Add a Phase-1 budget check: estimate monthly assist cost per learner (e.g., 20 turns/shift × 20 shifts/month = 400 extra LLM calls) and flag if it pushes the total over the C-3 ≤ $3/active learner/month target. Extends REQ-NFR-COST-01 (v0.1 cost logging) to the new assist surface. | should | P1 | complete |
v0.6 Backlog (IDEATE-10..13, accepted for v0.6)
4 ideas accepted for the v0.6 milestone (low-bandwidth surfaces). Recorded here for the v0.6 run; not active in v0.5.
| REQ-ID | Requirement | Priority | Phase | Status |
|---|---|---|---|---|
| REQ-IDEATE-10 | LLM-as-judge guardrail evaluation (nightly, off-voice-path) — measure the true false-negative rate the regex filter cannot. A nightly deepseek-v4-flash:cloud job sampling assist turns, classifying 'coached' vs 'did the job', feeding a 'guardrail adherence score' to the cohort dashboard. Natural v0.6 follow-on to v0.5's regex layer (D-068). | later | v0.6 P1 | deferred |
| REQ-IDEATE-11 | Assist-weaning metric — track reducing assist reliance over shifts as a mastery signal. A 'turns-per-shift trend per learner' metric (k-anonymized) giving operators a leading indicator of skill transfer from practice to the real job. Bridges v0.5 assist + v0.3 mastery without violating D-063 (descriptive metric, not a gate input). | later | v0.6 P1 | deferred |
| REQ-IDEATE-12 | Offline assist degraded mode — what happens when the backend is unreachable mid-shift? A canned local coaching redirect played from the client ('I can't reach the coaching server — take a moment and think about what the customer needs most right now') preserves the product's trust contract. Relevant to the v0.6 low-bandwidth/offline milestone (REQ-LOWBW-03). | later | v0.6 P1 | deferred |
| REQ-IDEATE-13 | Voice-only context declaration (hands-free context binding, no tap). A voice-only path ('Hey Praxis, starting my shift, week 3, damaged-product refund') parsed by ASR into the context fields. Faithful to product principle #1 (voice-first); depends on an ASR-parsing spike. | later | v0.6 P1 | deferred |
v0.5 Out of Scope (still deferred)
- REQ-PATH-01 (full multi-path launch) — still Customer Service path only; Live Assist binds to that path
- REQ-LOWBW-01..03 (WhatsApp/USSD/offline) — v0.5 is voice; low-bandwidth surfaces later
- REQ-VOICE-05/06 (multi-language, persona switching) — Canadian English only in v0.5
- REQ-DASH-02 (full operator-suite dashboard) — v0.4's foundational cohort view is sufficient
- Learner auth / multi-learner-per-device — still single-learner-per-device (D-007)
- Live Assist session recording/replay — v0.5 is live coaching, not recording
- Proactive intervention (AI speaks unprompted) — v0.5 is learner-invoked
- Multi-modal (camera/screen context) — audio-only (C-4)
v0.4 Active Requirements (complete — released as v0.1.9, retained for reference)
Operator-Tier Postgres (v0.4 foundation)
| REQ-ID | Requirement | Priority | Phase | Status |
|---|---|---|---|---|
| REQ-MT-01 | Operator-tier Postgres store — cohort aggregations, operator accounts, issued credentials, mastery-gate audit log. Separate from learner-local SQLite (D-007 preserved for learner surface). Migration path: SQLite stays for learner; Postgres added for operator. Postgres 16, persistent volume, internal Docker network only (D-040). | must | P1 | complete |
| REQ-MT-02 | Cohort aggregation pipeline — on-session-end hook + nightly reconciliation job writes k-anonymized aggregates to Postgres from learner sessions (D-045). No raw learner PII in Postgres. | must | P1 | complete |
Operator Auth (v0.4)
| REQ-ID | Requirement | Priority | Phase | Status |
|---|---|---|---|---|
| REQ-AUTH-01 | Operator-tier auth — session-based, single operator role in v0.4. Operator accounts in Postgres. Login endpoint + session cookie. Protects cohort dashboard + credential issuance. argon2id passwords, httpOnly+secure cookie, SameSite=Strict, 8h expiry, login rate-limited 5/min (D-041). |
must | P1 | complete |
Cohort Dashboard (v0.4)
| REQ-ID | Requirement | Priority | Phase | Status |
|---|---|---|---|---|
| REQ-DASH-01 | Anonymized cohort view (practice, mastery progression, failure patterns) for training operators — k-anonymity ≥ 10, 7-day aggregation window (D-034). Operator UI (React) under /operator/*, served by same FastAPI server (/api/operator/* prefix), reuses v0.2 StaticFiles (D-044). No separate SPA build — same client/dist. |
must | P2 | complete |
v0.4 Non-Functional Requirements
| REQ-ID | Requirement | Target | Phase | Status |
|---|---|---|---|---|
| REQ-NFR-AUTH-01 | Operator auth — passwords hashed (argon2id), session cookie httpOnly + secure + SameSite=Strict, login rate-limited (5/min), 8h expiry | must | P1 | complete |
| REQ-NFR-MT-01 | Postgres-in-LXC — operator Postgres runs as a second Docker service in the existing LXC CT (D-040) without destabilizing the learner-facing praxis service. Internal Docker network only (not exposed to bridge). | must | P1 | complete |
| REQ-NFR-DASH-01 | Cohort dashboard k-anonymity ≥ 10 — any cohort view cell with < 10 learners is suppressed | must | P2 | complete |
| REQ-NFR-DASH-02 | Cohort dashboard freshness — aggregates ≤ 24h stale (nightly reconciliation + on-session-end hook per D-045) | must | P2 | complete |
v0.4 Out of Scope (still deferred)
- REQ-PATH-01 (full multi-path launch) — v0.3 ships Customer Service path only, multi-path later
- REQ-DASH-02 (full operator-suite dashboard) — later milestone (v0.4 ships the foundational cohort view only)
- REQ-ASSIST-01..03 (Live Assist) — later milestone
- REQ-LOWBW-01..03 (WhatsApp/USSD/offline) — later milestone
- REQ-VOICE-05/06 (multi-language, persona switching) — later milestone
- Learner auth / multi-learner-per-device — operator auth is v0.4; learner auth later
- RBAC (multiple operator roles) — single
operatorrole in v0.4; RBAC deferred - Third-party credential issuers (university/agency) — v0.9 credentialing milestone
- Differential privacy — k-anonymity ≥ 10 is sufficient for v0.4 scale (D-034)
Constraints (binding — carry forward from v0.1/v0.2/v0.3)
- C-1 Voice is primary interface; text is fallback only
- C-2 Must work on $100 Android phone over 2G/3G (relaxed for v0.1 Canada pilot)
- C-3 Cost ≤ $3/active learner/month (relaxed for v0.1 pilot)
- C-4 Audio-only in v1
- C-5 Open-weights LLM via Ollama catalog —
gemma4:cloud+deepseek-v4-flash:cloud - C-6 Domain safety guardrails + HITL + disclaimers for safety-sensitive domains
- C-7 Scenarios authored by domain experts + learning designers; AI generates variations only
- C-8 Latency budget < 600ms end-to-end (ASR → LLM → TTS) — mastery scoring + cohort aggregation must not be on the voice path
v0.3 Requirements (complete — released as v0.1.5, retained for reference)
Mastery & Assessment (v0.3 core)
| REQ-ID | Requirement | Priority | Phase | Status |
|---|---|---|---|---|
| REQ-MAST-01 | Competency rubric per skill — a typed rubric model (criteria, 5-level scale, per-skill weights) authored as YAML, mapped to scenarios (D-036). At least one rubric for the Customer Service path in v0.3. | must | P1 | complete |
| REQ-MAST-02 | Mastery Score updated after each session — computed from rubric scores + varied-scenario-success gate (D-032: N=3 distinct scenarios, rubric mean ≥ 3.5/5.0). Score persisted per learner per path. Mastery gate opens when condition met. | must | P1 | complete |
| REQ-MAST-03 | Portable verifiable credentials on mastery — W3C VC Data Model 2.0, platform-issued Ed25519 signatures, status-list revocation (D-033). Issued when a mastery gate opens. Verifiable by third parties via a public verification endpoint. | must | P1 | complete |
| REQ-MAST-04 | No quizzes — assessment built into scenarios | principle | — | accepted |
Scenario Engine (v0.3 extensions)
| REQ-ID | Requirement | Priority | Phase | Status |
|---|---|---|---|---|
| REQ-SCEN-02 | Dynamic difficulty adjustment based on learner performance — IRT 1PL/Rasch, Bayesian θ update per session (D-035). Difficulty selection picks next scenario targeting ~50% expected success for current θ. | must | P1 | complete |
| REQ-SCEN-03 | Scenario library tagged by skill, difficulty, failure mode, rubric criteria — YAML directory + scenarios/index.yaml manifest (D-036). v0.3 ships ≥6 scenarios for the Customer Service path (one per week minimum). |
must | P1 | complete |
| REQ-SCEN-04 | Expert-authored scenario format with AI-generated variations — extends D-018 YAML DSL with rubric mapping + generated_from backref for AI variations. Expert-authored = canonical; AI variations = same schema, flagged, reviewable. |
must | P1 | complete |
Skill Paths (v0.3)
| REQ-ID | Requirement | Priority | Phase | Status |
|---|---|---|---|---|
| REQ-PATH-02 | Path structured as a job — 6-week structure per PRD §6.4, mastery-paced (D-037). Path = paths/<slug>.yaml defining weeks, each week = scenarios + a mastery gate. v0.3 ships the Customer Service path fully (6 weeks, ≥1 scenario/week). |
must | P1 | complete |
v0.3 Non-Functional Requirements (complete)
| REQ-ID | Requirement | Target | Phase | Status |
|---|---|---|---|---|
| REQ-NFR-MAST-01 | Rubric scoring determinism — same session + rubric → same score (no LLM non-determinism in the scoring path; LLM may assist rubric criterion extraction but final score is rule-based) | must | P1 | complete |
| REQ-NFR-MAST-02 | Mastery gate auditability — every gate-open event recorded with evidence (which 3 scenarios, rubric scores, timestamp) | must | P1 | complete |
| REQ-NFR-VC-01 | Verifiable credential tamper-evidence — Ed25519 signature, issuer key in operator-tier secrets (not committed), verification endpoint validates signature + status + interop test against external W3C verifier (grill Axis 3) | must | P1 | complete |
| REQ-NFR-VC-02 | Credential revocation latency — revoked credential must fail verification within 1 sync of the status list (next verify call — no cache) | must | P1 | complete |
| REQ-NFR-IRT-01 | IRT θ update latency — < 100ms (in-process, no LLM call) | must | P1 | complete |
v0.3 Out of Scope (now activated in v0.4)
REQ-DASH-01 (cohort dashboard) — deferred to v0.4→ activated in v0.4REQ-AUTH-01, REQ-MT-01, REQ-MT-02 (operator auth + Postgres) — deferred to v0.4→ activated in v0.4REQ-NFR-DASH-01, REQ-NFR-DASH-02, REQ-NFR-AUTH-01, REQ-NFR-MT-01 — deferred to v0.4→ activated in v0.4
v0.3 Out of Scope (still deferred)
- REQ-PATH-01 (full multi-path launch) — v0.3 ships Customer Service path only
- REQ-DASH-02 (full operator-suite dashboard) — later milestone
- REQ-ASSIST-01..03 (Live Assist) — later milestone
- REQ-LOWBW-01..03 (WhatsApp/USSD/offline) — later milestone
- REQ-VOICE-05/06 (multi-language, persona switching) — later milestone
- Third-party credential issuers (university/agency) — v0.9 credentialing milestone
- Learner auth / multi-learner-per-device — operator auth is v0.4; learner auth later
- Active failure injection (D-009) — evaluated in v0.3 RESEARCH (D-049), stays off
- Dynamic rubric weight re-weighting on branch outcome — static weights in v0.3, dynamic is a future feature (grill Axis 9)
v0.2 Requirements (complete — retained for reference)
Functional Requirements
Voice Conversation Engine
| REQ-ID | Requirement | Priority | Phase | Status |
|---|---|---|---|---|
| REQ-VOICE-01 | Real-time streaming ASR accepting accented, noisy speech (Canadian English pilot) | must | P1 | complete |
| REQ-VOICE-02 | Streaming TTS with natural prosody, one voice persona (single voice for both mentor and role-play character per D-006) | must | P1 | complete |
| REQ-VOICE-03 | End-to-end voice round-trip < 600ms (ASR → LLM → TTS first audio) | must | P1 | complete |
| REQ-VOICE-04 | Interruptibility — learner can cut the AI off mid-sentence (abort-and-yield semantics per D-008) | must | P1 | complete |
| REQ-VOICE-05 | Multi-language support (10+ launch languages) | later | deferred | deferred |
| REQ-VOICE-06 | Persona switching — same AI becomes customer/colleague/patient/mentor | later | deferred | deferred |
Scenario Engine
| REQ-ID | Requirement | Priority | Phase | Status |
|---|---|---|---|---|
| REQ-SCEN-01 | One branching Customer Service role-play scenario (Canada context): "Angry customer requesting refund on damaged product" with one branch point (escalate vs accept), defined success criteria, common mistakes, and a failure_mode field present but not actively provoked in v0.1 (per D-009, D-010) |
must | P1 | complete |
| REQ-SCEN-02 | Dynamic difficulty adjustment based on learner performance | later | deferred | deferred |
| REQ-SCEN-03 | Scenario library tagged by skill, difficulty, failure mode | later | deferred | deferred |
| REQ-SCEN-04 | Expert-authored scenario format with AI-generated variations | later | deferred | deferred |
Mastery & Assessment
| REQ-ID | Requirement | Priority | Phase | Status |
|---|---|---|---|---|
| REQ-MAST-01 | Competency rubric per skill | later | deferred | deferred |
| REQ-MAST-02 | Mastery Score updated after each session, requiring varied-scenario success | later | deferred | deferred |
| REQ-MAST-03 | Portable verifiable credentials on mastery | later | deferred | deferred |
| REQ-MAST-04 | No quizzes — assessment built into scenarios | principle | — | accepted |
Skill Paths
| REQ-ID | Requirement | Priority | Phase | Status |
|---|---|---|---|---|
| REQ-PATH-01 | Launch paths: Customer Service, Retail Sales, Hospitality Front Desk, Home Health Aide, Basic English for Work, Auto-Rickshaw/Taxi | later | deferred | deferred |
| REQ-PATH-02 | Path structured as a job (6-week example structure per PRD §6.4) | later | deferred | deferred |
Live Assist (active in v0.5 — see v0.5 Active Requirements above)
REQ-ASSIST-01/02/03 activated in v0.5. See "v0.5 Active Requirements" section at the top of this file.
Low-Bandwidth Surfaces
| REQ-ID | Requirement | Priority | Phase | Status |
|---|---|---|---|---|
| REQ-LOWBW-01 | WhatsApp/SMS bot thin entry point (2-min voice-note scenarios) | later | deferred | deferred |
| REQ-LOWBW-02 | USSD fallback for feature phones | later | deferred | deferred |
| REQ-LOWBW-03 | Offline cache for pre-downloaded scenarios and voices | later | deferred | deferred |
Employer / Program Dashboard
| REQ-ID | Requirement | Priority | Phase | Status |
|---|---|---|---|---|
| REQ-DASH-01 | Anonymized cohort view (practice, mastery progression, failure patterns) | later | deferred | deferred |
| REQ-DASH-02 | For training operators and SME HR, not individual learners | later | deferred | deferred |
Learner State
| REQ-ID | Requirement | Priority | Phase | Status |
|---|---|---|---|---|
| REQ-STATE-01 | Single-learner session log with progress and session history (v0.1: local SQLite persistence, no auth, no multi-tenant per D-007) | must | P1 | complete |
Coaching Debrief
| REQ-ID | Requirement | Priority | Phase | Status |
|---|---|---|---|---|
| REQ-DEBRIEF-01 | End-of-session single text+voice summary (not full multi-moment replay) per D-011 | must | P1 | complete |
LLM Foundation
| REQ-ID | Requirement | Priority | Phase | Status |
|---|---|---|---|---|
| REQ-LLM-01 | Ollama-hosted gemma4:cloud model callable for edge/fast-path persona responses (via Ollama Cloud direct API per D-020) |
must | P1 | complete |
| REQ-LLM-02 | Ollama-hosted deepseek-v4-flash:cloud model callable for complex coaching/debrief (no-think mode for latency per D-020) |
must | P1 | complete |
| REQ-LLM-03 | Open-weights foundation enabling on-prem option for partners (model-call layer swappable per D-020) | principle | — | accepted |
Orchestration & Pipeline (research-derived D-017)
| REQ-ID | Requirement | Priority | Phase | Status |
|---|---|---|---|---|
| REQ-ORCH-01 | Pipecat server orchestrates ASR→LLM→TTS pipeline with Silero VAD + interruptibility (D-017) | must | P1 | complete |
| REQ-ORCH-02 | Pluggable guardrail layer with Customer Service ruleset (D-019): no legal/financial/medical advice, no real-company impersonation, stay-in-role, session-start disclaimer | must | P1 | complete |
Scenario Format (research-derived D-018)
| REQ-ID | Requirement | Priority | Phase | Status |
|---|---|---|---|---|
| REQ-SCEN-FMT-01 | YAML DSL scenario definition → Pydantic model → Pipecat Flows consumption (D-018); supports failure_mode field (D-009) |
must | P1 | complete |
Non-Functional Requirements
| REQ-ID | Requirement | Target | Phase | Status |
|---|---|---|---|---|
| REQ-NFR-LAT-01 | End-to-end voice round-trip latency | < 600ms | P1 | complete |
| REQ-NFR-COST-01 | Cost per active learner per month | ≤ $3 (target markets; no enforced ceiling in v0.1 Canada pilot per D-012, but architecture must not preclude it). Log actual per-session cost in v0.1. | P1 (logging only) | complete |
| REQ-NFR-SAFE-01 | Domain safety guardrails + disclaimers for safety-sensitive scenarios | baseline for v0.1 (Customer Service lower risk) | P1 | complete |
| REQ-NFR-BW-01 | Usable on 2G/3G bandwidth | target | later | deferred |
| REQ-NFR-DEVICE-01 | Usable on $100 Android phone | target | later | deferred |
| REQ-NFR-AUDIO-01 | Audio-only in v1 (no large video assets) | principle | — | accepted |
Constraints (binding)
- C-1 Voice is primary interface; text is fallback only
- C-2 Must work on $100 Android phone over 2G/3G (relaxed for v0.1 Canada pilot)
- C-3 Cost ≤ $3/active learner/month (relaxed for v0.1 pilot)
- C-4 Audio-only in v1
- C-5 Open-weights LLM via Ollama catalog —
gemma4:cloud+deepseek-v4-flash:cloud - C-6 Domain safety guardrails + HITL + disclaimers for safety-sensitive domains
- C-7 Scenarios authored by domain experts + learning designers; AI generates variations only
- C-8 Latency budget < 600ms end-to-end
Deployment (v0.2 — Proxmox LXC)
| REQ-ID | Requirement | Priority | Phase | Status |
|---|---|---|---|---|
| REQ-DEPLOY-01 | Multi-stage Dockerfile: Node stage builds client/dist via npm run build, Python stage runs the Pipecat server and serves client/dist via FastAPI StaticFiles (D-022, D-023) |
must | P1 | complete |
| REQ-DEPLOY-02 | docker-compose.yml defining the praxis service with volume for SQLite DB (praxis.db), env injection, port mapping (8789), restart policy |
must | P1 | complete |
| REQ-DEPLOY-03 | Port scripts/proxmox/api.sh from coreci verbatim (PVE REST helpers: pve_curl, pve_poll, pve_nextid, pve_get, pve_env, pve_lxc_env_args) |
must | P1 | complete |
| REQ-DEPLOY-04 | Port scripts/proxmox/lxc-clone.sh adapted for praxis (hostname=praxis, port 8789, features=nesting=1 for Docker-in-LXC) |
must | P1 | complete |
| REQ-DEPLOY-05 | Port scripts/proxmox/lxc-config.sh adapted: hookscript snippet, lxc.environment injects GITEA_TOKEN + DEEPGRAM_API_KEY + voice-service env vars (empty if unprovisioned), PRAXIS_PORT=8789 |
must | P1 | complete |
| REQ-DEPLOY-06 | Port scripts/proxmox/firstboot-hook.sh adapted: host-builds Docker image (or loads pre-built), pct exec runs docker compose up -d inside the CT, health-checks /health :8789 |
must | P1 | complete |
| REQ-DEPLOY-07 | Port scripts/proxmox/health-check.sh adapted for praxis: polls http://<bridge-ip>:8789/health (not coreci's /healthz :18080) |
must | P1 | complete |
| REQ-DEPLOY-08 | Port scripts/proxmox/{lxc-start,rollback,stage-snippet,timing}.sh from coreci (adapted for praxis snippet name) |
must | P1 | complete |
| REQ-DEPLOY-09 | Port scripts/proxmox/lxc-deploy.sh orchestrator: clone → config → start → health-check → rollback-on-failure, with idempotency (--recreate/--reconfigure) |
must | P1 | complete |
| REQ-DEPLOY-10 | scripts/install-service.sh adapted: creates praxis user, data/log dirs, env file, systemd unit (praxis.service) that runs docker compose up -d, health-checks /health :8789 |
must | P1 | complete |
| REQ-DEPLOY-11 | scripts/proxmox/praxis.service systemd unit running docker compose up -d with Restart=on-failure |
must | P1 | complete |
| REQ-DEPLOY-12 | Secret wiring: extend config.json secrets.scopes with proxmox + voice scopes; source PROXMOX_* from ~/coreci/.ciagent/.env.secrets |
must | P1 | complete |
| REQ-DEPLOY-13 | FastAPI server/__main__.py mounts client/dist as StaticFiles at / (serving the React client from the same port as the API) |
must | P1 | complete |
| REQ-DEPLOY-14 | .env.example updated with PROXMOX_* + deployment env vars (documented, not secret) |
must | P1 | complete |
| REQ-DEPLOY-15 | E2E deploy verification: scripts/proxmox/test/ bats tests (mirroring coreci's test structure) + health-check + smoke against live CT |
must | P1 | complete |
| REQ-DEPLOY-16 | .dockerignore excluding node_modules, .git, __pycache__, .pytest_cache, client/dist (rebuilt in image), .ciagent/.env* (secrets) |
must | P1 | complete |
Non-Functional Requirements (v0.2)
| REQ-ID | Requirement | Target | Phase | Status |
|---|---|---|---|---|
| REQ-NFR-DEPLOY-01 | Deploy idempotency — re-running lxc-deploy.sh against a healthy CT is a no-op; unhealthy CT requires explicit --recreate/--reconfigure |
must | P1 | complete |
| REQ-NFR-DEPLOY-02 | Deploy rollback — any stage failure (clone/config/start/health) triggers rollback.sh (stop + destroy the partial CT) |
must | P1 | complete |
| REQ-NFR-DEPLOY-03 | First-boot install time | < 5 min (Docker image load + compose up + health) | P1 | deferred (live cluster required) |
| REQ-NFR-DEPLOY-04 | Secrets never committed to git (.ciagent/.env* in .gitignore, secrets injected via lxc.environment at runtime) |
must | P1 | complete |
Out of Scope (v0.1)
- Mastery scoring, competency rubrics, verifiable credentials
- Multi-language (launch: Canadian English only)
- Employer dashboard
- Live Assist mode
- WhatsApp/SMS/USSD surfaces
- Drill Mode, Review Mode
- Scenario authoring marketplace
- B2B SaaS
- Voice cloning of real individuals
- Early childhood education, medical procedures (permanent per PRD §11.6)