The Standard no-login CMS path needs an ORIGINAL ink signature on paper
(CMS-10114: 'Stamped, faxed or copied signatures will not be accepted'). This
adds a pipeline to redraw the provider's own captured strokes in real ink with a
pen on a CR-10 V2 (or any Marlin/GRBL machine) — original, in ink, never copied.
- migration 090: esign_records.signature_vector (JSONB stroke paths, 0..1).
- signing page now captures normalized stroke paths alongside the PNG; API
stores a size-bounded vector for drawn signatures.
- ink_signature_plotter.py (hardware-independent): fit strokes to the signature
anchor box, PDF-pt -> bed-mm via jig offset, emit Marlin/GRBL G-code (Z pen or
M280 servo/BLTouch), SVG toolpath preview, and render_signature_on_pdf (a
digital twin that proves the toolpath lands on the cert line). Gated serial
sender (dry_run default).
- ink_signature_cli.py: end-to-end load-record -> gcode+preview, --test-box jig
calibration, --plot to stream over USB.
- Corrected CMS-10114 signature anchor to sit inside the Section 4A signing cell
(above the bottom rule, below the label).
- docs/ink-signature-plotter.md documents the CR-10 retrofit + interpretive risk.
Tests: test_ink_signature.py 30/30, test_cms10114.py 27/27, test_paper_batch.py
15/15, API tsc clean, Astro build 58 pages.
Verified firsthand against the live CMS-10114 (Rev. 02/25, OMB 0938-0931):
- Section 1A confirms paper is valid for Change of Information (#2) AND
Reactivation (#4), not just initial enumeration. Resolves the UNCERTAIN flag.
- Current mailing address is CMS NPI Enumerator Services, Mail Stop DO-01-51,
7500 Security Blvd, Baltimore MD 21244. The old Fargo PO Box 6059 is retired;
corrected in mac_routing.NPI_ENUMERATOR + all docs.
- No electronic no-login equivalent exists for CMS (NPI Registry API is
read-only; PECOS/NPPES-IA require login), unlike FMCSA's ask.fmcsa ticket form.
So tiers stay: Standard=paper CMS-10114 (no login), Expedited=NPPES surrogate.
New: cms10114_pdf_filler.py fills the flat official form via text overlay
(reason checkbox + NPI + Section 2A identity + Section 4A cert name + signature
anchor); wired into npi_provider._generate_10114_for_signing for nppes-update.
Signed forms route to the NPI Enumerator via the existing daily batch.
Tests: test_cms10114.py 27/27, test_paper_batch.py 15/15, Astro build 58 pages.
- NpiIntakeStep: add positively-framed 'can you grant electronic I&A Surrogate
access?' question for all filing slugs (reval/reactivation/nppes-update/
enrollment/bundle). Optional, never required, never mentions paper; captured
as intake_data.surrogate_access (yes/no/blank). Astro build green (58 pages).
- npi_provider.py: surface the surrogate answer in the admin todo so fulfillment
knows EXPEDITED (online via surrogate) vs STANDARD (e-sign + daily mail batch).
Standard (no-login) CMS filings are mailed in one Priority Mail envelope per
destination agency, batched each postal working-day morning to save postage.
- migration 089: paper_filing_batches table + esign_records.paper_batch_id /
filing_destination_key (idempotent: a filing is batched at most once).
- batch_cover_sheet.py: per-agency cover sheet (sender/dest/date/manifest) +
merged print-job PDF (cover + all enclosed signed filings).
- daily_paper_batch.py worker: gather signed+unbatched cms855/cms10114 filings,
group by destination (MAC by state via mac_routing; Fargo for CMS-10114),
build cover+merged PDF per agency, persist batch, mark filings batched.
Self-gates on postal working days (skips weekends + federal/USPS holidays).
Phase 1 = human prints+mails; phase 2 = wire print-mail API.
- worker-crons: pw-paper-batch systemd timer (Mon-Fri 13:30 UTC, self-gated).
- test_paper_batch.py: 15/15 pass (working-day gating, routing, cover+merge).
- Verified Standard(no-login)/Expedited(surrogate) matrix from official CMS-855
PDFs (docs/healthcare-filing-tiers-verified.md): reactivation+revalidation are
855I paper-to-MAC reasons, original-signature, routed by state; sig may not be
delegated; 855B needs PECOS app fee.
- Add scripts/workers/mac_routing.py: state->MAC routing (all 56 jurisdictions,
12 destinations) for envelope addressing + daily batch grouping. Addresses
marked VERIFY before live mail.
- npi_provider.py: fix access strings to two-tier framing; NPPES update/reactivation
no longer 'online-only'; note 855B fee.
- checkout.ts + service pages: strip client-facing mechanics & the paper-vs-tier
choice; surrogate is the only optional, positively-framed ask (faster, never
required, never share password).
- deploy.sh/deploy-dev.sh: bring up listmonk-hc (upstream image, excluded from
build); document the one-time listmonk_hc DB create + --install.
- docker-compose.dev.override.yml: dev-only override (committed) that drops the
prod host-port bindings and pins dev's own postgres volume (dev-pgdata) via
compose !override tags. deploy-dev ships it as docker-compose.override.yml so
syncing the canonical compose to the shared host no longer breaks dev's
api-postgres (port :5432 clash + volume switch). Discovered + fixed while
validating listmonk-hc on dev.
- pw-hc-rampcap.sh: healthcare analogue of pw-listmonk-rampcap, ramps the
listmonk_hc cap 100->1000/h off /etc/postfix/hc-warmup-start, fully
independent of the trucking ramp/cap.
Add scripts/healthcare_email_streams.py as the single source of truth for
classifying NPPES-endpoint emails into institutional (HOT stream) / consumer
(trucking-discipline stream) / direct (DirectTrust, parked), plus an exclude set
for non-prospect giants (va.gov, *.mil, cvshealth, walgreens, walmart).
Rework build_npi_outreach_lists.py to emit one CSV per stream
(npi_healthcare_institutional/consumer + npi_direct_secure), overdue-first
sorted, with companion files (revalidation/leie/optout) now optional.
Verified on May 2026 NPPES endpoint_pfile: 89,557 institutional / 19,366 consumer
/ 242,441 direct rows.
deploy.sh: include proxy-relay in the default service set; it's an upstream
image (ginuerzh/gost) with no build context, so exclude it from 'compose build'
while keeping it in 'compose up'.
deploy-dev.sh: rsync docker-compose.yml to the dev server (it was never synced,
so new services like proxy-relay never reached dev) and add proxy-relay to the
'compose up --build' set.
The residential proxy password contains a '#', which urlparse() misreads as a
URL fragment and corrupts the port (ValueError: Port could not be cast...).
Parse scheme://creds@host:port manually and percent-decode user/pass so both
raw ('#') and encoded ('%23') passwords work. Verified against the live
credential.
CMS healthcare portals (NPPES, PECOS, I&A) block datacenter IPs, so the
healthcare browser automation needs to egress via the residential proxy on
hg409y7ez04.sn.mynetname.net (username 'performancewest').
- undetected_browser: use_proxy now accepts an env-var name, so callers can
select a domain-specific proxy. _proxy_config(proxy_env) reads it and falls
back to UNDETECTED_PROXY_URL. Healthcare uses 'HEALTHCARE_PROXY_URL'.
- probe_npi_undetected: launches with use_proxy='HEALTHCARE_PROXY_URL' when set.
- npi_provider: documents that the (future) automated NPPES/PECOS flows must
use the healthcare proxy.
- Plumb HEALTHCARE_PROXY_URL (+ UNDETECTED_PROXY_URL fallback) through the
ansible env template and docker-compose workers env.
The credential itself is NOT in the repo. Set the full URL in the ansible
vault as vault_healthcare_proxy_url:
socks5://performancewest:<password>@hg409y7ez04.sn.mynetname.net:<port>
Verified parsing + Playwright proxy-dict wiring with a unit test.
The site header / Services mega-dropdown was duplicated across two render
systems (Astro pages via Base.astro->nav.html, and ~80 pre-rendered static
public/**/index.html pages each embedding their own copy). They had drifted
into 5 different variants (missing 'New Carrier Setup', misplaced Healthcare
column, NEW vs FREE badges, em-dash encoding differences), so
dev.performancewest.net, the order pages, and the rest of the site disagreed.
- Make site/src/partials/nav.html the single source of truth (adopts the most
complete variant).
- Add scripts/sync_nav.py to rewrite every static page's <nav> block from
nav.html (idempotent; --check guards against drift in CI/deploy).
- Run the sync automatically in deploy.sh and scripts/deploy-dev.sh.
- Deprecate scripts/inject_healthcare_nav.py (now delegates to sync_nav.py).
- Neutralize the broken no-op SiteNav.astro component.
All 80 headers + the Astro-built order pages now render the identical dropdown.
Copy: drop paper/electronic/fax framing across the revalidation + enrollment
marketing pages and the order-confirmation email; present two service tiers:
- Standard filing (no CMS account; we prepare CMS-855, you sign, we submit to MAC)
- Expedited filing (CMS I&A surrogate access; same-day PECOS filing + tracking)
Internal worker todos + the _STANDARD_FILING_SLUGS identifier updated to match.
New scripts/test_healthcare_e2e.py validates the whole order line (slug
consistency x6 places, price agreement, intake field collection+enforcement,
worker dispatch, handler execution producing CMS-855 PDF+anchor, free-tool
action_urls). 45 checks.
Bugs found + fixed by the test:
- medicare-enrollment requires practice_state server-side but the wizard never
enforced it -> orders could be paid then stall. Wizard now requires it.
- determine_form_type defaulted org NPIs to the individual 855I because
enumeration_type is never collected -> wrong form, CMS rejection. Now does a
live NPPES lookup (safe 855I fallback).
The site's pre-rendered public/**/index.html pages each embed their own copy
of the Services mega-dropdown and do not read src/partials/nav.html, so the
earlier nav.html-only edit never appeared. inject_healthcare_nav.py adds the
canonical Healthcare block (Medicare Revalidation, Medicare Enrollment, NPI/
NPPES Services, free NPI Compliance Check) to the desktop Column 3 + mobile
menu of all 80 static pages. Idempotent.
- cms855_pdf_filler.py: fills official CMS-855I/B/O/A AcroForms from intake
(name, NPI, DOB, cert-page printed name) and records the signature anchor at
the form's official /Sig box so the e-sign stamper lands on the cert line.
- npi_provider handlers (revalidation/reactivation/enrollment) now generate the
paper CMS-855, upload it to MinIO, request_esign with anchors, and email the
signing link. Human completes/verifies + USPS Priority Mails to the MAC.
- scripts/Dockerfile: copy the official CMS-855I/B/O/A forms into the image.
- order-confirmation email presents both filing methods: paper CMS-855 (no
account needed, client e-signs one page, we print+mail to their MAC) and
I&A surrogacy (faster, needs CMS account). NPPES-only services note that
surrogacy is required (web-only).
- npi_provider handlers record the access model per service in admin todos.
- marketing copy leads with the lowest-friction paper option.
Adds a systemd-timed worker that nudges customers who paid but never completed
their intake form (which stalls fulfillment).
- migration 087: intake_reminder_count + intake_reminder_last_at on
compliance_orders (makes the daily run idempotent and bounded), plus a
partial index for the paid-order eligibility scan.
- scripts/workers/intake_reminder.py: each run emails any paid order with
intake_data_validated != TRUE, capped at 10 reminders/order, at most one
consolidated email per customer per day (groups a customer's incomplete
services into one email). Reuses the post-payment intake URL format
(/order/{slug}?order={n}) and the API's email validation, skipping
placeholder/invalid addresses (synthetic@, pipeline.com, etc.). Sends via
smtplib with SMTP_PASS (verified working in the worker container).
- worker-crons: pw-intake-reminder timer, daily ~noon ET (16:00 UTC).
Root cause of customers being unable to log in: ERPNext (portal.performancewest.net)
is the intended single portal and already surfaces compliance/trucking orders
(performancewest_erpnext/www/orders.py reads compliance_orders by email). But
only the Stripe checkout path provisioned the ERPNext Website User up-front
(findOrCreateCustomer). PayPal / crypto / remediation-pipeline orders go straight
to handlePaymentComplete, which created NO portal user and never set
portal_user_created -> no login + no set-password invite (exactly what happened
to the Paul Wilson / Compound Technologies PayPal order).
- handlePaymentComplete: add ensureCompliancePortalUser() in the shared
post-payment path so EVERY paid compliance order (any payment method) gets an
ERPNext portal account + the set-password invite. Idempotent.
- Guard against placeholder emails (synthetic@/pipeline.com etc): skip portal
provisioning and the set-password invite for non-deliverable addresses.
- compliance-orders API: validate email format AND reject placeholder addresses
at order creation (was: presence-only, so synthetic@pipeline.com passed).
- delivery_worker: never email a set-password invite to a placeholder address.
Note: the legacy PG-customers login (api/routes/portal-auth.ts, /account/*) is
CRTC/formation-era and only backfills canada_crtc_orders/orders, never
compliance_orders. ERPNext is now the consistent portal for compliance.
Drop the two self-listings (Performance West C-TPA and supervisor training) and
the National Drug Screening / NDS entries from the Suggested Vendors panels.
The non-endorsement disclaimer (which still names Performance West) is unchanged.
- Add a one-page 'DER Quick-Start Checklist' tear-off as the first content page
(set-up-once / every-hire / ongoing checkboxes, each pointing to the relevant
section or form).
- Add a two-column 'Suggested Vendors & Resources' directory page: C-TPA/
consortium, collection sites & labs, MRO, SAP, supervisor training, and (mode-
aware) FMCSA Clearinghouse or DOT resources, plus employee help lines. Marked
as examples not endorsements; mode-aware.
- Remove forced page breaks between consecutive content sections (now a light
section rule) so they flow continuously; page breaks kept only for the cover,
quick-start, TOC, each form, the vendor page, regulations, and the addendum.
- New builder helpers: section_rule(), checkbox(), two_col_panels().
Adds the real-world know-how a first-time DER needs beyond the bare regs:
- Owner-operators / one-driver companies (must use a consortium; cannot self-test
or self-select) — the most misunderstood case.
- Audits & penalties: what the new-entrant safety audit asks for and the
consequences of no program (civil penalties, failed audit, out-of-service).
- Problem test results: dilute, shy bladder, cancelled test, split-specimen.
- Prescriptions / marijuana / CBD (marijuana prohibited regardless of state law;
CBD trap; route medical questions to the MRO).
- What counts as a refusal (treated as a positive).
- Costs & timeline expectations.
- DER do's and don'ts (act same-day, keep records separate/confidential, never
tip off a random selection, don't interpret results yourself).
Customers (the DER) had no concrete how-to for onboarding/enrolling drivers or
what information to collect. Add:
- Section 1 'Enrolling a driver (new-hire onboarding)' subsection: exact info to
collect, the onboarding sequence (collect info, sign Forms A/B, Clearinghouse
query, prior-employer inquiry, add to C-TPA pool, pre-employment test, wait for
MRO negative), and a driver-removal note.
- Form G — Driver Enrollment & Covered-Employee Roster: per-driver enrollment
block (name, DOB, SSN last4, CDL #/state, contact, hire date, test result,
Clearinghouse/prior-employer status) plus a roster table for the covered pool.
- TOC, email, and handler text updated A-F -> A-G.
The instant-delivery email told customers to 'just reply to this email' with no
way to view/manage their order. Add a portal line in the body and change the CTA
to 'View in Portal' pointing at PORTAL_URL (portal.performancewest.net), matching
delivery_worker/renewal_worker conventions. Add _site_url()/_portal_url() helpers.
- Rewrite dot_da_binder_generator.py to emit an editable .docx (was reportlab PDF)
so carriers/counsel can review and adapt the program. ~4000 words, 10 sections.
- Render all six required forms (A-F); previously only A, D, E existed. Each form
starts on its own page (page break) and fills a page.
- Mode-aware policy text for FMCSA/FRA/PHMSA/FTA/FAA/USCG with correct CFR parts
and random-testing rates; optional single-state Drug-Free Workplace addendum
(federal DOT program is nationwide; only the optional DFWP addendum is state-keyed).
- Handler now outputs .docx instead of .pdf.
- job_server instant-delivery: attach DOCX (correct MIME) as well as PDF, and use
DOT-specific email copy + CTA instead of the FCC/telecom boilerplate.