P PraxisNotes
06 · Architecture · built on proven code

Built on a platform, not a greenfield.

The new PraxisNotes is a vertical on Monsoft's Loquent codebase — one Rust codebase that compiles to web, iOS, and Android. The platform already runs agents, escalations, drafts, layered rules, an org file system, streaming multilingual voice, and push in production. The new work is exactly the ABA domain — and nothing else.

PraxisNotes — the ABA vertical Built new
Session domain Note lifecycle Review pipeline Payer rule packs Office Puzzle bridge
assembled on
Loquent platform In production
Agent runtime Escalations Drafts & learning Layered rules File system Voice / STT Push Mobile shell Roles & permissions AI metering

This page is the blueprint: what we reuse untouched, what we extend, and what we honestly build from scratch — plus the data model, the voice pipeline, how one codebase ships two products, and the migration for today's users.

The platform underneath

Eleven capabilities the new PraxisNotes leans on directly. Every one is shipped, running, and metered today — the green chip is not a promise, it's the current state of the codebase.

Production
Agent runtime

Per-member agent clones from a centrally-edited template, a typed tool registry, per-agent budgets, and full turn logging. Every RBT gets their own note-writer; the template stays one edit.

Production
Escalations

Agent asks a question → push to the phone → one-tap answer card → the paused work resumes. The writer's "which prompt level did Maria need?" ask, verbatim.

Production
Draft & review

Propose → human edits → approve, and every edit is captured as a learning signal. The shape of note review — a draft to approve, never a blank box — already built.

Production
Layered rules

Platform → org → agent precedence, rendered into every prompt. A rule edit takes effect on the next turn — no deploy. The substrate the payer rule packs sit on.

Production
Learning

Corrections and lessons roll up into versioned learnings with approve / rollback — validated by shadow replay against historical turns before anything ships to a live agent.

Production
Org & roles

Role rows plus granular permissions — RBT, BCBA, and QA are configuration, not schema changes. Caseload scoping means an RBT sees only their assigned clients.

Production
File system

An org-scoped folder tree over cloud object storage, with an agent write harness that creates Clients/{client}/Sessions/{date}/ paths idempotently.

Production
Voice / STT

Streaming dictation over a server relay — provider keys never touch the browser. Two providers, 90+ languages with auto-detect, proven in the iOS shell. Plus batch diarized transcription.

Production
Mobile shell

Capacitor iOS/Android loading the deployed app. A server deploy updates every phone instantly — no app-store release for a UI change.

Production
Push & notifications

APNs + FCM, per-user preferences, deep links straight to the right card, and OS badge counts kept in sync across the fleet.

Production
AI metering

Every AI call — text, transcription, voice — logged with per-model cost pricing. Clinic-level spend visibility from the first note, not bolted on later.

Same brain, one modality more: voice and typed input call the same tool catalog the text agent uses — a new input, never a parallel capability surface. Meet the agents →

Reuse, extend, build new

The honest ledger. Most of the pipeline is proven code we reuse as-is; a middle tier gets parameterized for ABA; and a focused set is genuinely new. The build cost lives almost entirely in the coral rows.

Reuse runs today, untouched · Extend exists, parameterized for ABA · Build new the new engineering
Capability Tier What powers it
Capture & voice
Streaming STT relay + batch transcription Reuse Deepgram Flux + ElevenLabs Scribe over the WS relay; diarized transcribe_audio for recordings
Session-length ceilings + per-route language Extend Raise the composer-shaped 60s/120s relay caps; surface the language hint the adapters already accept
Offline-first mobile capture Build new Record locally, queue the upload, resume on network change — the single biggest genuinely-new mobile build
Agents & review
Escalation loop — ask → push → one-tap → resume Reuse The missing-session-data ask maps 1:1 onto the shipped escalation card
Draft → edit → approve, with edit-capture learning Reuse Suggest-mode drafts + correction capture feed the same learning pipeline
Autonomy dial — Suggest by default, destructive re-confirm Reuse QA starts in Suggest; earns Autonomous on clean-pass notes as trust accrues
Agent learning + shadow replay on historical turns Reuse Regression fixtures let the clinic test a guideline change against past sessions first
Role-targeted escalation routing (any QA reviewer) Extend Today it reaches the owning user; reviews need role/queue targeting — mirror the permission-based notify resolver
Session domain — start/stop, place of service, participants, EVV-ready Build new No visit/appointment entity exists; server-authoritative timing, event log modeled on the call-event pattern
session_note — versions + status machine + e-signatures Build new The core object: draft → signed → reviewed → billing-ready, with a credentialed signature and audit trail
Review pipeline — stages, verdicts, returns Build new Durable artifact-workflow state; the Atrium proposal pattern is the closest template to copy
Rules & catalogs
Layered rules rendered into every prompt Reuse Platform → org → agent precedence + a rule audit trail; edits apply on the next turn
Payer rule-pack module — versioned, clinic-editable Build new A new domain shape composed on the rule + template/revision machinery — never hardcoded logic
Clients & access
Roles & granular permissions (RBT/BCBA/QA = config) Reuse Role rows + the resource permission system; invite 100+ RBTs with the role pre-attached
Caseload assignment + scoping Reuse Member↔client assignment + *Assigned permissions inject the caseload filter end-to-end
Typed staffing — RBT vs supervising BCBA, effective dates Extend Add an assignment role + date window to the assignment table; the scope service extends naturally
Per-role file access scoping Extend Files are org-wide today; add assigned-client / subtree scoping on the existing file ABAC
insurance_authorization + versioned treatment_plan Build new Payer, auth #, CPT, a units ledger, a date window; a goals/targets tree the note agent cites — custom fields can't do this
Files, mobile & platform
File system + object storage + agent write harness Reuse Idempotent ensure_path materializes the per-session folder with zero schema change
Push / deep links / badges Reuse APNs/FCM dispatch, dead-token cleanup, and the deep-link resolver from tap → route
New notification categories Extend NoteReadyForReview, QaReturned, SignatureRequired — an enum + deep-link target each
Realtime sync Reuse Org-scoped WS + generic entity-change envelope keeps the QA board live by default
AI usage metering + pricing Reuse Every STT/generate call site logs usage; the providers in play are already priced and unit-tested
PDF generation + export packet Build new No PDF producer exists in the codebase; the compliant note PDF and signed export are net-new
Office Puzzle bridge Build new No public API on their side — a browser extension fills Office Puzzle's forms from the verified packet; a human confirms

Read down the coral: a session domain, the note lifecycle, the review pipeline, authorizations and plans, the rule packs, offline capture, PDF export, and the Office Puzzle bridge. That is the whole new build — everything else is assembly.

The data model

The spine from client to clean claim. Each entity carries a tier chip — most of the client and file layer is reused; the clinical and workflow entities are where the new schema lives.

Data first — the note is a rendering
Typed rows, never blobs

Session data lives as structured entities — ABC entries, replacement-program entries with prompt levels and progress, per-behavior measurements (count, duration, percentage), reinforcers — each row stamped with its source: tap, voice with timestamp, escalation answer, or manual edit. The narrative is generated from these rows and cites them; numbers never originate in prose.

Validated against the plan

Behaviors must map to targets in the client's assessment and versioned treatment plan; programs must be plan programs — the golden thread payers audit for. Off-plan data doesn't fail silently: it flags the BCBA that the plan may need a revision. Reauthorization tables and per-behavior graphs assemble from these rows automatically.

Per-code capture schemas

What a session must capture is itself data, not code: a versioned capture schema per CPT code (97153 = ABC + programs; 97155 = protocol modifications; 97156 = caregiver training; 97151 = assessment). New codes are new schemas — the exact governance pattern the rule packs use, and the two reference each other: a rule pack's required elements point at capture-schema fields.

Client Reuse

A contact with a clinical profile — demographics, preferred language, and the Office Puzzle client id on external_id.

TreatmentPlan New

Versioned goals & targets. A note references the plan version in force at session time.

InsuranceAuthorization New

Payer, auth #, CPT, a units ledger and a date window — queryable, so a session can be checked against remaining units.

Session New

Start/end times, place of service, participants, and the staff who ran it — EVV-ready, validated against the caseload and the auth window.

VoiceNote + transcript Reuse

Audio + transcripts land as files in the session folder via the agent write harness. Nothing new here but the glue.

SessionNote New

Versions (v1→vN), a credentialed e-signature, and a status machine — replacing today's single overwritten text column.

Review New

BCBA and QA stages, each with a verdict and findings; a return routes the note back to the RBT's writer thread.

BillingPacket New

Gates that every prerequisite is met, then hands the verified packet to the browser extension, which fills Office Puzzle's forms for a human to confirm.

One session · on disk
Clients/
  Maria-G/
    Sessions/
      2026-07-14/
        voice-note-1.m4a  ·transitory
        transcript.txt
        note-v1.json
        note-v2.json
        note-v3.json
        note-signed.pdf   ·final

Created idempotently by the agent write harness — the same folder tree the clinic can browse in the Files view. The raw audio is transitory; the signed PDF is the record of truth.

The voice pipeline

Two proven paths and one honest new build. The good-connectivity fast path is streaming; a batch path recovers uploaded recordings; and offline capture — the hardest piece — is the one we build from scratch.

Push-to-talk
RBT speaks, any language
Server relay
keys never in the browser
STT provider
Scribe v2 / Flux · auto language
Live transcript
partials · attached to session
Batch fallback
Reuse

A recorded clip uploads and runs through diarized transcription + speaker identification — the exact pipeline that already transcribes call recordings today. Handles a long memo, or a clip the live path missed.

Offline path
Build new

In-home sessions hit dead zones. The design: record to local files, hold an upload queue, and resume on network change — then the batch path takes over. The app has no offline layer today, so this is genuinely new work.

Where the real risk sits

Streaming capture in the mobile WebView stops when the screen locks or the app backgrounds, and there's no buffering when signal drops. That's why offline capture likely needs a native recorder — the one part of the voice story we treat as a build, not a reuse. Everything upstream of it is proven code. Every AI call along the path is metered from day one.

One codebase, two products

The new PraxisNotes is its own product — its own brand, its own deployment, its own mobile app — that shares the platform code with Loquent. It is not "an org inside Loquent." It's a standalone product built by extending the same foundation.

Its own everything at the edges

A PraxisNotes brand, a separate deployment, and a distinct mobile shell appId with its own App Store and Play listings. Re-skinning the Capacitor shell — new icons, new server URL — is a config-and-assets change, not new engineering.

Shared platform, flowing both ways

The agent runtime, escalations, drafts, voice, push, files, and metering are shared platform code. Improve the escalation loop or the STT relay once and both products get it — the leverage that makes this not a two-year build.

The ABA vertical stays PraxisNotes-only

Sessions, the note lifecycle, the review pipeline, the payer rule packs, and the Office Puzzle bridge live in PraxisNotes-only modules. Loquent never carries ABA logic; PraxisNotes never carries Loquent's CRM surface.

How the code stacks
L
Loquent
CRM vertical
P
PraxisNotes
ABA vertical
mods/feature slices · shared + per-product
bases/runtime, storage, auth, db
shared/cross-target types & hooks
ui/Aurora primitives

Shared foundation below; the ABA vertical is a set of PraxisNotes-only modules on top.

Bringing today's users over

The new PraxisNotes also upgrades today's solo-RBT users — so the migration is a first-class part of the build, not an afterthought. The old app stays read-only during cutover; nothing is lost.

Accounts & orgs

Users and clients move into real multi-user orgs with roles and caseloads — resurrecting the staff↔client links the old app defined but never used.

Clinical catalogs

The full domain spine ports as-is — 627 antecedents, 546 reinforcers, 273 replacement programs, 181 behaviors, 133 interventions, plus prompt, prompting, and teaching procedures.

Historical notes

Past notes import as read-only signed records — preserved and viewable, never re-opened for editing, so the audit history is intact.

Stripe subscriptions

Existing subscriptions carry over — no billing interruption for current PraxisNotes customers on the switch.

Read-only cutover

The old app is frozen read-only while data moves, so there's a single source of truth at every moment of the switch.

Dry run first

The whole import runs against a copy of production data before the real cutover — fidelity is verified, not assumed.

Honest engineering risks

The four places this build is genuinely hard. We'd rather name them now than discover them in the pilot. Each is open one click — read them before you decide.

Offline capture is the hardest item New native work · highest uncertainty

The app is a remote-loaded WebView with no offline data layer, and streaming mic capture suspends when the screen locks or the app backgrounds. In-home sessions in dead zones need a record-locally-first design: a native recorder writing to device storage, an upload queue, and network-change resume.

We de-risk it by shipping the streaming fast path first and treating offline as its own phase, with the batch pipeline as the recovery path underneath.

Office Puzzle has no public API A browser extension closes the loop · human confirms every submission

There is no public integration surface to submit into directly. So the bridge is a browser extension: the biller (or RBT) opens Office Puzzle, selects the client, and the extension fills the session, note, and billing fields from the verified packet — as the logged-in user, no API required. A side panel shows the packet; insert runs field by field or all at once; a human confirms every submission.

The engineering risk is DOM brittleness — Office Puzzle can change its screens. We contain it with a versioned field map (selectors shipped as data, updated without redeploying the platform) and never auto-fill EVV-verification fields, which must come from the EVV flow itself. Fallback ladder if the extension is ever blocked: guided copy flow → file-level import if OP supports one → the clearinghouse route (837P). Nothing is blocked on a partner we don't control.

PDF & e-signature rendering are new No PDF producer exists in the codebase today

The platform previews and serves PDFs but never generates them, and there is no signature-capture precedent. Producing the compliant note PDF and capturing a credentialed RBT/BCBA signature is net-new — well-understood engineering, but not a reuse.

It's contained: the note data and signature are already first-class in the model; rendering is the last mile.

Migration fidelity needs a dry run Verified against a copy of production data

Today's notes are flat text with no versioning or audit trail, and the old schema is a home-grown dual-dialect setup. Mapping that cleanly into the new versioned, signed model has edge cases we won't fully know until we run it.

The mitigation is simple and non-negotiable: a full dry run on a copy of production data, with the old app read-only, before any real cutover.

A focused new build, on a proven foundation.

The platform is shipped. The ABA vertical is the work. The risks are named. Next: how it rolls out — phases, the pilot, and pricing for a 100-RBT clinic.

See the rollout