This repository has been archived on 2026-09-12. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
praxis/.ciagent/PROJECT.md
T
Praxis CI 1b3617da3b docs(P02): review + audit — APPROVE_WITH_NOTES, HEALTHY, 2 P0 fixed
REVIEW.md: 2 P0 fixed (stale test defaults, sandbox isolation),
  8 P1+ flagged for post-hoc review. Verdict: APPROVE_WITH_NOTES.
AUDIT.md: 0 critical, 5 warnings. Reconstruction PASS, file
  discipline PASS, branch hygiene PASS, commit discipline PASS.
  Verdict: HEALTHY. Doc-drift fixed (REQ statuses → complete).

P0 fixes in working tree:
  1. lxc-config.bats: aligned stale defaults with production code
  2. lxc-deploy.bats: fixed sandbox isolation (HOME redirect)

---ci---
project: praxis
phase: 2
milestone: v0.2
status: review
---/ci---
2026-08-03 18:54:38 +00:00

16 KiB
Raw Blame History

Praxis — Voice-first AI Apprenticeship Platform

Milestone: v0.2 (Proxmox LXC deployment) Status: phase 1 complete — P2 review/ship in-progress Autonomy: full

Vision

Praxis is a voice-first, AI-tutored skill platform for learners in resource-constrained environments. Instead of courses, videos, and quizzes, learners practice real job scenarios through real-time spoken conversation with AI tutors. The platform treats every learner as an apprentice to a master craftsperson — open the app, talk, do the job, get better at it.

One-line pitch: Praxis turns every smartphone into a master craftsperson that talks to you, challenges you, and helps you get good at your job.

Objective

Build a voice-first AI apprenticeship platform where learners engage in spoken role-play scenarios with AI tutors, receive coaching debriefs, and progress via mastery gates — working on low-cost phones over constrained bandwidth.

v0.2 Scope (Proxmox LXC Deployment)

v0.2 deploys praxis into a Proxmox LXC container, reusing and adapting the battle-tested deployment toolkit from ~/coreci/scripts/proxmox/. The v0.1 voice loop becomes deployable infrastructure — a Docker image runs the Python/Pipecat server (serving the React client as static files) inside an LXC container on the operator's Proxmox cluster.

v0.2 in scope:

  • Docker image (multi-stage: Node builds client/dist, Python runs server + serves dist via FastAPI StaticFiles)
  • scripts/proxmox/ adapted from coreci (api.sh, lxc-deploy, lxc-clone, lxc-config, lxc-start, health-check, rollback, stage-snippet, firstboot-hook, timing)
  • scripts/install-service.sh (systemd unit for docker compose up)
  • Secret wiring: PROXMOX_* sourced from coreci's .env.secrets; GITEA_TOKEN + DEEPGRAM_API_KEY from praxis's secrets
  • Health-check adapted for /health :8789 (praxis's endpoint, not coreci's /healthz :18080)
  • E2E deploy verification against the live Proxmox cluster

v0.2 out of scope (deferred):

  • Mastery scoring, competency rubrics (deferred to v0.3)
  • CARTESIA_API_KEY / OLLAMA_API_KEY provisioning (infrastructure-only; server degrades gracefully per v0.1 design)
  • Traefik proxy / public TLS (pilot = direct bridge IP access)
  • Multi-environment (dev/staging/prod) — single pilot CT
  • vmbr1 private network (pilot uses vmbr0 DHCP)

Product Principles (non-negotiable)

  1. Voice is the primary interface. Text is fallback, not default.
  2. Doing > Knowing. Every session produces observable action, not passive consumption.
  3. One skill, one outcome. Each path is a job someone can get.
  4. Works on a cheap phone, on 2G. Engineering constraints are product features.
  5. The AI is a master, not a chatbot. Personality, standards, opinions.
  6. Mastery gates progression. Move on when you can do the thing.
  7. Failure is the curriculum. AI provokes mistakes, then coaches recovery.

Requirements (summary — see REQUIREMENTS.md for formal REQ-IDs)

  • Voice conversation engine: real-time ASR + streaming TTS, <600ms round-trip, interruptible, persona switching
  • Scenario engine: branching role-plays with failure-injection and dynamic difficulty (v0.1: one scenario)
  • Learner state: progress, session history, mastery accumulation (v0.1: single-learner state, no mastery scoring yet)
  • LLM foundation: Ollama-hosted open-weights models gemma4:cloud and deepseek-v4-flash:cloud
  • Low-bandwidth surfaces (later milestones)
  • Employer dashboard (later milestones)

Constraints

  • C-1 Voice is primary interface; text is fallback only
  • C-2 Must work on $100 Android phone over 2G/3G
  • C-3 Cost ≤ $3/active learner/month (target markets; v0.1 is Canada launch — relaxed for pilot)
  • C-4 Audio-only in v1 (no large video assets)
  • C-5 Open-weights LLM via Ollama catalog — gemma4:cloud + deepseek-v4-flash:cloud
  • C-6 Domain safety guardrails + human-in-the-loop + 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)

Key Decisions

ID Decision Rationale Confidence Alternatives
D-001 Launch market = Canada (path: Customer Service) User-directed; Canada as initial market for v0.1 pilot. PRD named Kenya — overridden. 0.70 Kenya + Customer Service (PRD default)
D-002 Milestone = v0.1 foundation (v1.0 reserved for working/tested product) User-directed; v0.1 is the foundation slice (Phase 0 + Phase 1 minimal voice loop). v1.0 is a future milestone. 0.90 v1.0 = Phase 0 + Phase 1 (too ambitious for first milestone)
D-003 LLM foundation = Ollama cataloggemma4:cloud + deepseek-v4-flash:cloud User-directed; open-weights via Ollama, two base models for edge/cloud split. Research phase to verify exact catalog IDs. 0.75 Llama-family, Mistral-family, Qwen-family
D-004 Defer monetization model decision to Phase 1 PRD §11.5 explicitly lists this as a Phase 1 decision (B2C paid, B2B per-seat, donor-funded, government). 0.85 Decide now (insufficient data)
D-005 Single-project mode Fresh repo with one project; no multi-project need. 1.00 Multi-project mode
D-006 "One persona" = one voice persona; scenario role-play uses the same TTS voice as mentor (no distinct character voice in v0.1) Minimizes v0.1 surface area; PRD's full persona-switching (REQ-VOICE-06) is deferred. Same voice avoids a second TTS configuration to validate. 0.70 Two voices (mentor + character) — adds TTS config risk
D-007 "Single learner state" = local single hardcoded profile, no auth, no multi-tenant; persisted via SQLite on-device (or local file fallback) v0.1 is a pilot harness, not a production multi-user system. Auth/multi-tenant is a later-milestone concern. SQLite chosen as the default local store; research phase may refine. 0.80 In-memory only (no persistence), server-side Postgres (premature)
D-008 Interruptibility = abort-and-yield (learner speech cuts AI TTS immediately, AI yields the floor, no pause/resume state machine in v0.1) Matches real-conversation semantics per PRD §6.1; pause/resume adds state-machine complexity inappropriate for v0.1. 0.75 Pause/resume state machine
D-009 Failure-injection hook = architecturally present (scenario declares a failure_mode field) but NOT actively provoked in v0.1 sessions v0.1 validates the data model and one scenario's success criteria; provoking failures is a coaching-debrief feature tied to mastery (deferred). Hook present so Phase 2+ can activate it without schema change. 0.70 Active failure injection in v0.1 (couples to deferred mastery engine)
D-010 v0.1 Canada Customer Service scenario = "Angry customer requesting refund on a damaged product" (retail context, single branch point) Concrete, universally recognizable, low safety-risk (non-medical/non-electrical). One branch point (customer escalates vs accepts resolution) keeps scenario runtime minimal while exercising branching. 0.65 "Customer with wrong booking" (hospitality — less universal for Canada pilot)
D-011 Coaching debrief = included in v0.1 as a single end-of-session text+voice summary (not the full PRD §5.1 multi-moment replay) The debrief is part of the core daily loop and cheap to include at a basic level. Full replay/multi-moment coaching is tied to mastery (deferred). 0.70 Exclude debrief entirely (loses core loop identity), full replay (over-scoped)
D-012 v0.1 cost ceiling = no enforced ceiling (pilot); architecture must not bake in assumptions that would prevent meeting ≤$3/learner/month post-pilot C-3 is a target-market constraint. Canada pilot is a foundation/tech-validation milestone, not a unit-economics milestone. Logging actual cost per session is a v0.1 NFR to inform later milestones. 0.85 Enforce $3 ceiling in v0.1 (premature optimization, wrong market)
D-013 ASR = Deepgram Nova-3 streaming (cloud, WebSocket) Research-verified: streaming-native, ~200-300ms first partial, accent-robust for Canadian English, first-class Pipecat integration, Canada data-residency available. Fallback: Groq-hosted Whisper. 0.85 whisper.cpp (breaks <600ms budget), OpenAI Whisper API (batch)
D-014 TTS = Cartesia Sonic (cloud, ~120ms first audio) primary; Piper (self-hosted, ~80ms) fallback behind interface Research-verified: Cartesia #1 on Speech Arena; Piper is open-weights post-pilot ≤$3/learner path. R4 risk: all-cloud path ~670ms — Piper local may be required for production v0.1 latency. 0.80 ElevenLabs (quality but higher latency/cost), Amazon Polly
D-015 Client = React + WebRTC via Pipecat client SDK Research-verified: Pipecat ships React/RN/Swift/Kotlin SDKs; web client = fastest v0.1 iteration, no app-store distribution, upgrades to React Native for Android later. 0.85 Python CLI harness (dev-integration only), native Android Kotlin (premature)
D-016 Transport = WebRTC (UDP, sub-50ms audio); WebSocket dev fallback Research-verified: WebRTC is Pipecat's production transport; adaptive bitrate, UDP. SSE/HTTP rejected (unidirectional/high overhead). 0.85 WebSocket-only (higher audio latency), custom raw HTTP/2
D-017 Orchestration = Pipecat (not custom, not Vocode) Research-verified: 13.8k★, active, integrates Deepgram+Cartesia+Piper+Ollama natively, has VAD/interrupt/Flows for branching. Vocode stale since Nov 2024. Custom orchestration rebuilds solved problems. 0.85 Vocode (stale), custom from scratch
D-018 Scenario format = YAML DSL → Pydantic → Pipecat Flows Research-verified: YAML is human-authorable + diffable + supports comments (critical for learning-designer rationale per C-7); Pydantic gives typed runtime; Pipecat Flows consumes the schema for branching. JSON is wire format only. 0.85 JSON DSL (no comments), code-authored (couples authoring to engineering)
D-019 v0.1 guardrail layer = pluggable interface with Customer Service ruleset implementation Research: v0.1 is low-risk (Customer Service) but architecture must support pluggable guardrails for later high-risk domains (health/electrical). Ruleset: no legal/financial/medical advice, no real-company employee impersonation, stay-in-role, session-start disclaimer audio, no PII beyond hardcoded profile. 0.80 No guardrails (violates C-6), hardcoded non-pluggable rules (blocks future domains)
D-020 LLM access = Ollama Cloud direct API (https://ollama.com/api/chat + OLLAMA_API_KEY) — no local daemon Research-verified: :cloud tags are real Ollama hosted-inference on NVIDIA cloud partners. Direct API eliminates local-daemon deployment dependency. gemma4:cloud (256K ctx) → role-play fast path; deepseek-v4-flash:cloud (1M ctx, no-think mode) → debrief. Self-host gemma4:e4b is the post-pilot cost-reduction path. 0.85 Local Ollama daemon proxy mode (adds deployment dependency)
D-021 v0.2 scope = Proxmox LXC deployment (replaces roadmap's mastery-scoring v0.2) User-directed: deploy praxis into an LXC container hosted on Proxmox, reusing ~/coreci/scripts/proxmox/ methods. Mastery scoring deferred to v0.3. 0.95 v0.2 = mastery scoring (original roadmap), v0.2 = LXC deploy + mastery (too large)
D-022 Artifact = Docker image in LXC (nesting=1) User-directed. Isolates Python/Pipecat deps; coreci's clone script already sets features=nesting=1. Avoids venv/pip first-boot fragility (Pipecat has many native deps). Multi-stage build: Node stage produces client/dist, Python stage runs the server. 0.85 Clone repo + venv + pip (fragile first-boot), sdist tarball (needs build/release step)
D-023 Client serving = FastAPI serves client/dist as StaticFiles User-directed. Single port (8789), simplest pilot — no nginx/caddy. The Docker image bundles the pre-built dist. 0.90 Separate static server (nginx/caddy — more moving parts), client out of scope
D-024 Voice-service keys = infrastructure-only for v0.2 User-directed. Server starts and /health passes even without CARTESIA/OLLAMA keys (v0.1 graceful degradation). Keys provisioned in a later milestone. Only GITEA_TOKEN + DEEPGRAM_API_KEY are in .env.secrets. 0.90 Provision all keys in v0.2 (premature — deploy infra first)
D-025 Image distribution = host-build → pct push tarball (research decision, see RESEARCH.md) The LXC CT may not route to the internet (coreci pattern: host-fetch → pct push). Build the Docker image on the PVE host (Docker available on Proxmox host) and `docker save pct exec -- docker load, or pct push` a tarball. Avoids needing a container registry. 0.75
D-026 Proxmox secrets sourced from ~/coreci/.ciagent/.env.secrets Same Proxmox cluster, same operator. PROXMOX_API_URL/TOKEN/NODE/STORAGE/TEMPLATE_VOLID already provisioned there. Praxis's .env.secrets adds GITEA_TOKEN + DEEPGRAM_API_KEY. The deploy script sources both. 0.90 Duplicate proxmox secrets in praxis (drift risk)
D-027 VMID = auto (fresh allocation via pve_nextid) CLARIFY auto-decide (full autonomy). Don't reuse coreci's fixed PROXMOX_LXC_VMID — praxis gets its own CT on the same cluster. 0.95 Reuse coreci's VMID (collision), hardcode a new fixed VMID (manual allocation)
D-028 Docker installed inside the CT via apt (CT has network via vmbr0 DHCP) CLARIFY auto-decide. Avoids needing Docker on the PVE host. The debian-12 template + nesting=1 supports Docker-in-LXC. firstboot hook runs pct exec to install docker.io + docker-compose-v2. 0.90 Docker on PVE host (extra host dependency), pre-baked template (custom template maintenance)
D-029 Image built inside the CT (clone repo from Gitea, docker build, docker compose up) CLARIFY auto-decide. Self-contained — CT fetches its own source + builds. No image transfer needed. Slower first-boot (~3-5 min for build) but simpler and reproducible. 0.80 Build on PVE host + pct push tarball (host Docker dependency), pre-built image from registry (external dependency)
D-030 CT network = vmbr0 DHCP only (pilot, no vmbr1, no Traefik proxy) CLARIFY auto-decide. v0.2 is infrastructure-only pilot. Direct bridge IP access for health-check. Proxy/TLS deferred to a later milestone. 0.90 vmbr1 + Traefik proxy (over-scoped for pilot)

Confidence updates from research

ID Before After Reason
D-003 0.75 0.95 Both Ollama model IDs verified in catalog as real, current, cloud-hosted tags
D-007 0.80 0.90 SQLite confirmed appropriate for v0.1 single-learner scale; no evidence favors alternatives

Target Users (v0.1 pilot: Canada)

Persona Description Pain
Aspiring Adebayo → "Aspiring Alex" 1928, Canada. Recent secondary school grad. Smartphone, limited data. Wants a service job. Can't afford vocational school. Needs to actually do the job.
Upskilling Ursula → "Upskilling Uma" 2540, Canada. Retail, hospitality, healthcare. Wants promotion/new role. No time for courses. Learns on the job.
Frontline Felix Customer service / sales / field tech agent, hired recently. Manager has no time to coach. Wants quick on-shift practice.

Success Metrics (Year-1 targets, post-v0.1)

Metric Target Why
Active weekly learners 100k Engagement, not downloads
Sessions per learner / week ≥5 Habit formation
Mastery rate per path ≥40% completion Real learning
Median session length 610 min On-the-go use
Cost / active learner / month ≤$3 Sustainable
Reported job/promotion outcome ≥25% North star
NPS (learner) ≥50 Word-of-mouth growth

Open Questions (for research/clarify phases)

  1. Will learners talk to their phone in public? (earbuds + "no one will know" framing)
  2. How to certify mastery credibly? (employer/agency recognition)
  3. Domain safety minimum HITL for health/electrical scenarios
  4. Voice cloning / impersonation disclosure
  5. Monetization model (deferred to Phase 1)
  6. Skills that should remain out of scope

References

  • PRD v0.1 (this document's source)
  • ARCHITECTURE.md — system architecture
  • ROADMAP.md — phase breakdown
  • REQUIREMENTS.md — formal requirements with REQ-IDs