Skip to content
decosa

Notes from your jottings, checked against each client's payer before billing; audits answered from the notes on file. A workflow over two tools: Write a note from my jottings and Answer a payer audit.

Who it is for

The owner of a solo or small therapy practice (LCSW, LPC, LMFT, psychologist) who is also the clinician and often the biller.

Notes pile up ("20 to 30 notes behind"), nobody checks them against what each insurer asks for, and when an audit letter comes ("140 charts", "ten calendar days") the practice copies charts by hand or pays someone to.

One container for the practice and three steps that feed each other: a note from your jottings, checked while it is fresh against your client's payer's own documentation list; a check of every note before it is billed, while anything missing can still be completed in your normal workflow; and, when an audit letter arrives, the answer built from the notes already on file, with the deadline, a date-of-service lock, a per-claim table, a checked cover letter and a packet. One signed log records every step.

The steps, and where a person decides

  1. Write the note (Write a note from my jottings)

    Your typed jottings become a DAP, SOAP or BIRP draft where every sentence cites the jotting it came from; the draft is then checked against your client's payer's own requirements (one claim through the payer-audit engine).

    Person: You edit the draft, paste it into your EHR and sign it there. Nothing here signs.

  2. Mark it signed

    You paste the EHR's signed copy (or say you signed the draft as it was). It becomes the copy on file, checked again against the payer's list.

    Person: You, after signing in your EHR.

  3. Check before billing (Answer a payer audit (self-audit mode))

    Every note not billed yet, each against its client's payer, plus overlapping sessions by you on the same day. What is missing is listed with the payer's own words and one instruction: complete these in your normal workflow before the date of service is billed. A random sample of billed notes can be self-audited too.

    Person: You decide what to do; a billed note is never "fixed": discuss it with your supervisor or counsel.

  4. An audit letter came

    The deadline is worked out in code from the letter's own words; each claim is matched to the note on file by member ID and date; every listed date of service is locked so nothing drafts or redrafts a note for it.

    Person: You confirm the claim table.

  5. Answer it from the notes on file (Answer a payer audit)

    No re-upload: a per-claim table with each requirement found (with its line) or missing, weak claims first, a cover letter whose sentences were each checked, a packet, and the values for the auditor's upload form.

    Person: A named person decides each weak claim (include as is, or discuss with counsel first), signs the letter and sends the packet by the auditor's own channel.

It never: records a session; writes a diagnosis, a risk level or a recommendation; suggests adding to, changing or back-dating a signed or billed note; signs, sends or submits anything, or logs in to a payer or auditor portal; keeps anything on the hosted service: the browser keeps the practice.

What we measured

On a made-up practice (12 clients, three payers, 70 sessions over 8 weeks, 73 planted documentation gaps, then a 20-claim records request), run end to end on our hosted route, against the same drafts used through the two tools separately. All synthetic, written blind; a simulated clinician completes only what she knows.

  • Planted gaps shown before billingThe two tools used separately showed 23 / 73 (the note tool's own list).63 / 73
  • Notes never signed, caught before billingSeparately: 0 / 4.4 / 4
  • Letter claims matched to the note on file, no upload20 / 20
  • Claims weak at the audit (by the key)12 / 20 with the tools separately: the forgotten signatures were caught and what could be completed before billing was.8 / 20
  • Weak claims the audit response flags7 of 8 counting one marked check (an overlapping session). 1 of 12 clean claims flagged weak (a 'per the treatment plan' line not read as a plan reference; fixed after: 7 of 8 and 0 of 12 on the same charts). Before the 29 Sep fix: 4 of 8, mostly SUDS ratings read as an objective tool.6 of 8
  • Same result as the audit tool on its own, same charts20 / 20 claims
  • Draft sentences not supported by the jottings (blind review)29 / 1,283 before the 29 Sep fixes; 12 of 70 notes. Zero was not met: read each draft before you sign it.13 / 1,292
  • Risk and safety statements carried in the drafts (blind check)Every risk statement is quoted word for word, a sentence that changes one is removed, and a draft that would lose one is blocked. Before: one sentence dropped a written 'no SI'.68 / 68
  • Cover-letter sentences not supported (blind review)Both name the index attachment the packet builds, which the reviewer's sources did not include; the letter code is unchanged (0 / 7 on 28 Sep).2 / 7
  • Cost of the whole chain (70 notes, 8 weekly checks, the audit answer)List price. A note with its payer check: $0.0096, 21 s median (71 s p95 on the busy shared service); every kept sentence now also gets a meaning check. The 20-claim answer: 37 s, $0.034.$0.87

Synthetic practice, one writer agent, one audit letter. The Optum and Evernorth packs are drafts a person has not reviewed.

No timed human baseline: time savings on this page are a tester's estimates, marked as such.

Measured again on 29 Sep after the accuracy fixes (one run, our hosted route); the blind reviews ran on that run.

Checked end to end, hosted (2026-09-29): Production (decosa.ai, our hosted route): in a private browser at 1280 and 390 px, the demo practice opened; a note from a made-up session drafted and checked against the payer in 27 s; signed with the demo EHR copy; billed; a self-audit of 20 billed notes; the made-up letter filed (20 of 20 claims matched, respond-by date, dates locked); the response built from the notes on file in 87 s with its cover letter and PDF packet; a weak claim decided; the lock refused a listed date; the log verified in the browser; no page errors, no sideways scroll, no psychotherapy code shown (32 of 32 checks). The smoke check (a note, a letter, the lock, the log) passed 3 of 3 times in 39-42 s at $0.004-0.005 each.

Self-hosted (2026-09-28): Fresh clone, the api container from its Dockerfile with the practice store on, our running Qwen3.8-27B: a four-note practice through notes, signed copies, the check before billing, billing, a records request (the lock refused a redraft), the response and its PDF packet; the log verified on the box and offline; the mock-data rehearsal 12/12; the /practice/app page at 1280 and 390 px. Torn down after.

Where it runs

  • Here (demo): Made-up practices only, kept in your browser. The server keeps nothing between steps.
  • Your own box: The whole workflow, for real clients: the practice lives in SQLite on your box, opened with its case key.
  • Confidential access: On request. A BAA is not in place yet, so real client data goes to your own box until it is.

The same decosa-api container every self-hosted Decosa tool uses, with the practice store switched on. It needs a GPU box that runs Qwen3.8-27B (or the model server you already run for Decosa); typed jottings need nothing else.

  • DECOSA_CASE_STORE: 1 (keep practices in SQLite under the data volume)
  • DECOSA_PRACTICE_SYNTHETIC_ONLY: 0 (accept real notes on your own box)
  • DECOSA_JOTTINGS_SYNTHETIC_ONLY: 0

Then open /practice/app on your box: create the practice (keep the case key), write notes, check before billing, file a letter, build the response, verify the log.

Setting up the box is the same as for the two tools: Write a note from my jottings and Answer a payer audit each have a "Run it yourself" tab with the containers and a copy-paste prompt for a coding agent.

The copy-paste prompt for a coding agent on your box
# Assemble "Keep your practice audit-ready" on this machine

You are setting up a documentation and audit workflow for a small therapy practice, on the practice's own machine. It
drafts progress notes from the therapist's own jottings (no session recording, ever), checks each note against the
client's insurer's own published documentation requirements, checks every note before it is billed, and answers an
insurer's records audit from the notes on file. It keeps the practice (clients by made-up labels, notes, checks, letters
and one signed log) in SQLite on this machine. Work step by step, show me each command before you run anything with
`sudo`, and stop to ask if a check fails.

## 0. Ground rules and licences
- Models: Qwen3.8-27B (Apache-2.0) drafts, checks each sentence against the jottings, reads each requirement in a note and
  drafts the audit cover letter. The workflow, the checks and the signed log are decosa-api (AGPL-3.0-or-later).
- Notes and letters are PHI. They stay on this machine. Bind every port to 127.0.0.1. Logs carry step names, counts and
  times only. Do not add request logging.
- Nothing here signs, sends or submits anything, or suggests changing or back-dating a signed or billed note. Do not add
  features that do.

## 1. The machine
Same as for the two tools this workflow uses: one GPU with at least 32 GB for Qwen3.8-27B NVFP4 (we measured on an RTX
PRO 6000 96 GB), Docker with the NVIDIA container toolkit, about 40 GB of disk. See "Run it yourself" on
decosa.ai/apps/jottings-note for the checks and the model image and revision.

## 2. docker-compose.yml (in `~/decosa/practice/`)

```yaml
services:
  llm:
    image: vllm/vllm-openai:v0.29.0
    command: ["--model", "nvidia/Qwen3.8-27B-NVFP4", "--served-model-name", "qwen3.8-27b", "--max-model-len", "32768",
              "--enable-prefix-caching"]
    ports: ["127.0.0.1:8114:8000"]
    volumes: ["~/.cache/huggingface:/root/.cache/huggingface"]
    deploy: { resources: { reservations: { devices: [{ driver: nvidia, count: 1, capabilities: [gpu] }] } } }
    healthcheck: { test: ["CMD", "curl", "-fs", "http://localhost:8000/v1/models"], interval: 30s, retries: 20 }
  api:
    image: ${DECOSA_REGISTRY}/decosa-api:<tag>   # or build docker/api/Dockerfile from a clone of decosa-api
    ports: ["127.0.0.1:8445:8445"]
    environment:
      DECOSA_HOST: 0.0.0.0
      DECOSA_PORT: "8445"
      DECOSA_DATA_DIR: /data
      DECOSA_LLM_ROUTE: direct
      DECOSA_LLM_URL: http://llm:8000/v1
      DECOSA_LLM_MODEL: qwen3.8-27b
      DECOSA_CASE_STORE: "1"
      DECOSA_PRACTICE_SYNTHETIC_ONLY: "0"
      DECOSA_JOTTINGS_SYNTHETIC_ONLY: "0"
      DECOSA_JOTTINGS_SECOND_READER: "0"
      DECOSA_BUDGET_LLM_TOKENS: "400000"
    volumes: ["decosa-data:/data"]
    depends_on: { llm: { condition: service_healthy } }
    healthcheck: { test: ["CMD", "python", "-c", "import urllib.request; urllib.request.urlopen('http://localhost:8445/practice/info', timeout=4)"], interval: 30s, retries: 10 }
volumes:
  decosa-data:
```

The practice store lives in the named volume (`/data/cases/cases.sqlite`, mode 0600). Back up the volume like any other
clinical record store. Then `docker compose up -d`.

## 3. Check it
1. `curl -s 127.0.0.1:8445/practice/info` shows `"stored": true` and `"synthetic_only": false`.
2. Open `http://127.0.0.1:8445/practice/app` in a browser on this machine. Create the practice: note format, your name
   and credential, the payers you bill (BCBS Michigan is built in; the Optum and Evernorth packs are drafts that a person
   has not reviewed yet), and clients by a made-up label with the member ID letters use. Keep the case key it shows once:
   it is the only way to open the practice.
3. Write one note from made-up jottings, paste a made-up signed copy, run "Check everything not billed yet", then verify
   the log ("Verify the log"). Download the log and check it offline with
   `python3 scripts/verify_case_ledger.py practice-log.json --records practice-log.json --pubkey <key from /attest/signing-key>`.
4. Only then use it with real notes.

Models, data and the rules

  • Qwen3.8-27B (Apache-2.0): drafts the note, judges each sentence against the jottings, reads each requirement in the note, drafts the cover letter
  • Payer packs (each payer's published requirement lines, quoted with the source; BCBSM built in, Optum and Evernorth drafts not yet reviewed by a person): what each payer checks
  • Jottings, notes, copies and letters go to the Decosa API for the length of one step, then back to your browser. Kept: nothing on the server (hosted); your box (self-host).
  • Model calls go to Qwen3.8-27B through the Decosa gateway (hosted) or your own model server (self-host). Kept: a receipt per call: hashes, token counts, no text.
  • The practice log go to your browser, or your box. Kept: labels, dates, hashes and counts; never note text.

Checked 28 Sep 2026. Not legal advice. Therapy notes are protected health information; a cloud service that holds encrypted PHI is still a business associate under HIPAA, so real notes run on your own box until Decosa has BAAs, and the hosted demo takes made-up practices only. Illinois HB 1806 (225 ILCS 155) allows AI for administrative and supplementary support, including preparing therapy notes, and requires written consent when a session is recorded or transcribed; nothing here records a session. The workflow never suggests adding to or back-dating documentation (False Claims Act exposure); a self-audit that finds unsupported billed claims can raise overpayment duties, so discuss those with counsel. 42 CFR Part 2 (substance-use records) is not assessed here.