PharmLink
PharmLink business suite
Updated 2026-09-12 · merge claude-agent · SMTP off

CRM dashboard is a work queue. Inventory: docs/architecture/2026-09-12-crm-features-functions.md. Refine on suite-dev.pharmlink.ai.

Now 3 Start next 0 Waiting 0 Blocked 3 Shipped 44

Now

In flight. Do not start a second agent on the same files.

HOST-SYNCkernel · critical path

Deploy M5 code to Mini suite-dev

Implement

Deps met: HOST-DEV

Touch: scripts/suite_dev_sync.sh

docs/architecture/2026-09-12-suite-host-and-license-lock.md

rsync code+export; Mini JSONL books stay. Watchdog restarts origin.

AR-SANDBOX-ORIGINALar · critical path

Sandbox original from filed contract (no PHI RDS)

Implement

Deps met: PR-8, HOST-DEV

Touch: pharmlink_suite/pharmlink_suite/ar_api.py · apps/suite/pages/ar/

docs/architecture/2026-09-11-pharmlink-ar-design.md

POST /api/ar/orgs/{id}/sandbox-original. Fixture volume. Not catch-up CLI. Catch-up CLI still owns PowerGrid/RDS volume. No SMTP.

CRM-WALKcrm

After AP, start discussion is the next queue item

Implement

Deps met: CRM-DASH

Touch: saudi_jv_ledger/saudi_jv_ledger/crm_projections.py

docs/architecture/2026-09-12-crm-features-functions.md

start_thread next-step. Promote/handoff Primary runs when unique.

Start next (parallel OK if Touch: paths differ)

No ready items. Unblock a dependency first.

None

Waiting on a dependency

Do not start these yet. The missing dep is on the card.

None

Blocked

Must not start. IRL V or a hard gate.

IRL-Vkernel · critical path

Matthew click-through on :8480

Blocked

Deps met: PR-8

docs/architecture/2026-09-11-business-suite-design-0.md

Operator paused further IRL-V clicks 2026-09-12. Suite keeps building. SMTP stays off.

CRM-DROPcrm

Drop email/vCard to draft CRM person

Blocked

Deps met: CRM-DASH

Touch: saudi_jv_ledger/saudi_jv_ledger/crm_email_draft.py · apps/suite/components/ContactDrop.tsx

docs/architecture/2026-09-12-crm-features-functions.md

Parked 2026-09-12. Mail.app drag/paste did not meet IRL. Kernel parser kept. People add is manual. No SMTP.

HOST-PRODkernel

Promote code to suite.pharmlink.ai (empty books)

Blocked

Waiting on AR-SANDBOX-ORIGINAL

docs/architecture/2026-09-12-suite-host-and-license-lock.md

Same image, empty US books. Not until the walk is production-ready.

Shipped

Spec approved, loopback live, or operator V for that slice.

D0kernel · critical path

Design 0 architecture

Done

Touch: docs/architecture/2026-09-11-business-suite-design-0.md

docs/architecture/2026-09-11-business-suite-design-0.md

Parent lock. Rev 5. Nested orgs and commercial people via D11.

D1crm · critical path

Design 1 PharmLinkCRM

Done

Deps met: D0

Touch: docs/architecture/2026-09-11-pharmlink-crm-design.md

docs/architecture/2026-09-11-pharmlink-crm-design.md

Rev 5. Dashboard vs Entity, people, comms, same-origin :8480.

D11crm · critical path

Nested orgs, commercial people, action scope

Loopback

Deps met: D1

Touch: docs/architecture/2026-09-11-suite-org-scope-program-board.md

docs/architecture/2026-09-11-suite-org-scope-program-board.md

Design plus nested UI. Dashboard lists roots + descendant count. Entity add-child. Handoff asks one/subset/descendants. Open in Contract after handoff. Desk flow strip CRM→Contract→AR→Finance→AP.

D-CTRcontract · critical path

PharmLinkContract module design

Done

Deps met: D11

Touch: docs/architecture/2026-09-11-pharmlink-contract-design.md

docs/architecture/2026-09-11-pharmlink-contract-design.md

Design 2 rev 2 landed in parallel with PR-1 and PR-3. Q1–Q6 locked. Next on this track is PR-5a (stop finish_contract invoicing).

D-ARar

PharmLinkAR module design

Done

Deps met: D11, D-CTR

Touch: docs/architecture/2026-09-11-pharmlink-ar-design.md

docs/architecture/2026-09-11-pharmlink-ar-design.md

Design 3 rev 2. Q1–Q3 locked (users-file hospital_ids; many invoices one email; CLI catch-up only).

D-FINfinance

PharmLinkFinance Audit design

Done

Deps met: D-AR

Touch: docs/architecture/2026-09-11-pharmlink-finance-design.md

docs/architecture/2026-09-11-pharmlink-finance-design.md

Design 4 rev 2. controller1 attests; auditor1 flags. Fail-closed attest. Accounting stays on /ar. Product code waits IRL V.

D-APap

PharmLinkAP design

Done

Deps met: D-FIN

Touch: docs/architecture/2026-09-11-pharmlink-ap-design.md

docs/architecture/2026-09-11-pharmlink-ap-design.md

Design 5 rev 2. Pay any employee. JV payee directory. ap_clerk1 / TestPass2025. Product code waits IRL V.

P-P0board

Program board live page

Loopback

Deps met: D11

Touch: docs/suite-program/board.yaml · scripts/program_board_build.py · apps/program-board/

docs/architecture/2026-09-11-suite-org-scope-program-board.md

https://dev.pharmlink.ai. YAML is SoR. GitHub Action deploys on push.

PR-1kernel · critical path

Twin US log, compilers, JV guards

Done

Deps met: D0

Touch: saudi_jv_ledger/ · Dockerfile.backend · scripts/jv_ledger_ar_run.py

docs/architecture/2026-09-11-business-suite-design-0.md

Landed. Twin JSONL path, contracts_for_hospital, JV-only CR, SAR compilers, AWS refuse. PR-1b is next on this track.

PR-1bkernel

Purpose-scoped query + query_audit JSONL

Done

Deps met: PR-1

Touch: saudi_jv_ledger/saudi_jv_ledger/query.py · saudi_jv_ledger/saudi_jv_ledger/query_audit.py

docs/architecture/2026-09-11-business-suite-design-0.md

Landed. Purpose-scoped helpers; audit JSONL; fail closed. PR-9/PR-10 depend on this.

PR-3crm · critical path

Suite Next export + Workbench

Loopback

Deps met: D0

Touch: apps/suite/ · pharmlink_suite/ · scripts/pharmlink_suite_serve.py

docs/architecture/2026-09-11-pharmlink-crm-design.md

Landed. python3 scripts/pharmlink_suite_serve.py → http://127.0.0.1:8480/login (suite1 / ops1). Empty CRM tiles. Cookie never Domain=.pharmlink.ai.

PR-4acrm · critical path

CRM org/person/move kernel

Done

Deps met: PR-1, D11

Touch: saudi_jv_ledger/saudi_jv_ledger/crm.py · saudi_jv_ledger/saudi_jv_ledger/crm_contacts_map.py

docs/architecture/2026-09-11-pharmlink-crm-design.md

Landed. Nested orgs, first_name/phone on people, operator-only move, undelete same person_id. Next is PR-4b/4c.

PR-4bcrm

Opportunity + scoped handoff

Done

Deps met: PR-4a

Touch: saudi_jv_ledger/saudi_jv_ledger/crm.py · pharmlink_crm_sandbox/

docs/architecture/2026-09-11-pharmlink-crm-design.md

Landed. Org-only handoff with covers_org_ids + scope_mode. Parent omit scope refuses. Tour adapter maps hospital_id → org_id.

PR-4ccrm

Comms drafts + four auto-schedules

Done

Deps met: PR-4a

Touch: saudi_jv_ledger/saudi_jv_ledger/crm_comms.py · saudi_jv_ledger/saudi_jv_ledger/ar_packets.py

docs/architecture/2026-09-11-pharmlink-crm-design.md

Landed. Four auto-schedules on current_customer. NullSendPort only. Zero-attempt does not advance.

PR-4dcrm · critical path

CRM HTTP + pages + NullAssist

Loopback

Deps met: PR-3, PR-4a, PR-4b, PR-4c

Touch: apps/suite/ · pharmlink_suite/

docs/architecture/2026-09-11-pharmlink-crm-design.md

Landed. http://127.0.0.1:8480/crm after npm run build. ops1 can move; suite1 cannot. NullAssistPort Entity-only.

PR-5acontract · critical path

Stop finish_contract invoicing

Done

Deps met: D-CTR

Touch: saudi_jv_ledger/saudi_jv_ledger/contracting.py

docs/architecture/2026-09-11-pharmlink-contract-design.md

Landed. finish_contract files hospital_contract only. Catch-up owns originals. Tour/walk scripts may still need a follow-up.

PR-5bcontract · critical path

MSA/BAA/SOW instruments + accept handoff

Done

Deps met: PR-5a, PR-4b, D-CTR

Touch: saudi_jv_ledger/saudi_jv_ledger/contract_instruments.py

docs/architecture/2026-09-11-pharmlink-contract-design.md

Landed. MSA always before SOW. USA BAA gate. SOW emit hospital_contract per hospital_id. MSA/BAA do not open AR.

PR-5ccontract

Contract redlines + template review

Done

Deps met: PR-5b

Touch: saudi_jv_ledger/saudi_jv_ledger/contract_redlines.py

docs/architecture/2026-09-11-pharmlink-contract-design.md

Landed. Section-anchored comments. Velocity is a reader. No email.

PR-5dcontract

NullSignPort envelope hooks

Done

Deps met: PR-5b

Touch: saudi_jv_ledger/saudi_jv_ledger/sign_port.py

docs/architecture/2026-09-11-pharmlink-contract-design.md

Landed. NullSignPort only. suite1 send + suite1 countersign is SignSegregationError. No sign_envelope_sent.

PR-5econtract

provision_plan event + CRM append_person

Done

Deps met: PR-5b, PR-4a

Touch: saudi_jv_ledger/saudi_jv_ledger/contracting.py

docs/architecture/2026-09-11-pharmlink-contract-design.md

Landed. append_provision_plan applied=false. People via CRM append_person. No RDS.

PR-5fcontract · critical path

Contract suite Dashboard + Entity

Loopback

Deps met: PR-3, PR-5c, PR-5d, PR-5e, PR-4d

Touch: apps/suite/pages/contract/ · pharmlink_suite/

docs/architecture/2026-09-11-pharmlink-contract-design.md

Landed. http://127.0.0.1:8480/contract. ops1 countersigns; suite1 cannot. NullSignPort sandbox.

PR-6clinical

Provision job dry-run

Done

Deps met: PR-5e

Touch: src/services/hospitals/provision_from_plan.py

docs/architecture/2026-09-11-business-suite-design-0.md

Landed. Default LIVE_PROVISION_RDS=false. Missing hospital skips. No Hospital INSERT. No applied=true.

PR-7aar · critical path

Persist ar_preview_issued; catch-up stays preview-only

Done

Deps met: PR-1, PR-5a, D-AR

Touch: saudi_jv_ledger/saudi_jv_ledger/ar_preview.py · scripts/jv_ledger_ar_run.py

docs/architecture/2026-09-11-pharmlink-ar-design.md

Landed. Catch-up writes hospital_invoice + ar_preview_issued. Zero RECORD. Zero send.

PR-7bar · critical path

RECORD writer

Done

Deps met: PR-7a

Touch: saudi_jv_ledger/saudi_jv_ledger/ar_record.py

docs/architecture/2026-09-11-pharmlink-ar-design.md

Landed. Requires preview. At-most-one. Credit notes do not reset. Catch-up still cannot RECORD.

PR-7car · critical path

Send package + standing AP + scope

Done

Deps met: PR-7b, PR-4a

Touch: saudi_jv_ledger/saudi_jv_ledger/ar_packets.py

docs/architecture/2026-09-11-pharmlink-ar-design.md

Landed. Official send needs RECORD + standing AP + scope. Preview package does not RECORD. NullSendPort only.

PR-8ar · critical path

AR suite UI

Loopback

Deps met: PR-3, PR-4d, PR-7c

Touch: apps/suite/pages/ar/ · pharmlink_suite/

docs/architecture/2026-09-11-pharmlink-ar-design.md

Landed on loopback. python3 scripts/pharmlink_suite_serve.py → http://127.0.0.1:8480/login then /ar. ar1 / TestPass2025 preview → RECORD → NullSendPort (smtp=false, do_not_send=true). ops1 can issue preview, not RECORD/send. suite1 403. Distinct from /admin/ar-work-queue. SMTP off. Next: IRL-V Matthew click-through on :8480.

PR-2kernel

Extract pharmlink_ledger

Done

Deps met: PR-1

Touch: pharmlink_ledger/ · saudi_jv_ledger/

docs/architecture/2026-09-11-business-suite-design-0.md

Landed as a re-export. saudi_jv_ledger stays the implementation. pharmlink_ledger is the license-out name. No SMTP. No live adapters.

PR-9afinance

Finance kernel projections + SoD + flags + attest

Done

Deps met: PR-1b, D-FIN

Touch: saudi_jv_ledger/saudi_jv_ledger/finance_audit.py

docs/architecture/2026-09-11-pharmlink-finance-design.md

Landed. Completeness, aging, mix-up, flags, fail-closed attest, SoD. No HTTP.

PR-9cfinance

Finance need-to-know query_audit reader

Done

Deps met: PR-1b, D-FIN

Touch: saudi_jv_ledger/saudi_jv_ledger/finance_need_to_know.py

docs/architecture/2026-09-11-pharmlink-finance-design.md

Landed. Side JSONL. Accounting cannot read the query log. Not hashed into Event.event_hash.

PR-9bfinance

Finance live-gate register + geo honesty

Done

Deps met: PR-9c

Touch: saudi_jv_ledger/saudi_jv_ledger/finance_gates.py

docs/architecture/2026-09-11-pharmlink-finance-design.md

Landed. SMTP/e-sign/provision sandbox. Books/bank not_connected. AP pay NOT BUILT. No QBO Connected.

PR-9dfinance

Finance suite Dashboard + Entity

Loopback

Deps met: PR-9a, PR-9b, PR-9c, PR-3

Touch: apps/suite/pages/finance/ · pharmlink_suite/

docs/architecture/2026-09-11-pharmlink-finance-design.md

Landed. http://127.0.0.1:8480/finance. controller1 attests; auditor1 flags. ar1 403.

PR-9finance

Finance Audit (umbrella)

Loopback

Deps met: PR-9d

Touch: apps/suite/ · saudi_jv_ledger/

docs/architecture/2026-09-11-pharmlink-finance-design.md

Kernel + /finance loopback. No QBO. No invoice writes. AP aging is PR-11.

PR-10aap

AP kernel vendors + NullPayPort

Done

Deps met: PR-9d, D-AP

Touch: saudi_jv_ledger/saudi_jv_ledger/ap.py · saudi_jv_ledger/saudi_jv_ledger/pay_port.py

docs/architecture/2026-09-11-pharmlink-ap-design.md

Landed. US vendor_bill. JV other_fees. NullPayPort. Refuse JV vendor_bill.

PR-10cap

Employee payables

Done

Deps met: PR-4a, D-AP

Touch: saudi_jv_ledger/saudi_jv_ledger/employee_payable.py

docs/architecture/2026-09-11-pharmlink-ap-design.md

Landed. US only. tax_form on the payable. No SSN. No Payroll app.

PR-10bap

AP vendor contacts via CRM

Done

Deps met: PR-10a, PR-4a

Touch: saudi_jv_ledger/saudi_jv_ledger/ap_projections.py

docs/architecture/2026-09-11-pharmlink-ap-design.md

Landed. vendor_contact + vendor_id. Dashboard is tiles not a dump. ap.pay clerk-only.

PR-10dap

AP suite Dashboard + Entity

Loopback

Deps met: PR-10a, PR-10c, PR-3

Touch: apps/suite/pages/ap/ · pharmlink_suite/

docs/architecture/2026-09-11-pharmlink-ap-design.md

Landed. http://127.0.0.1:8480/ap. ap_clerk1. Expandable Vendors. NullPayPort.

PR-10ap

PharmLinkAP US (umbrella)

Loopback

Deps met: PR-10d

Touch: saudi_jv_ledger/ · apps/suite/

docs/architecture/2026-09-11-pharmlink-ap-design.md

Kernel + /ap loopback. live=false. No bank. No QBO. Finance AP aging is PR-11.

PR-11finance

Finance reads AP open bills (aging + duplicates)

Loopback

Deps met: PR-9d, PR-10

Touch: saudi_jv_ledger/saudi_jv_ledger/finance_audit.py · apps/suite/pages/finance/

docs/architecture/2026-09-11-pharmlink-finance-design.md

Landed. controller1/auditor1 see AP aging on /finance. No pay. ap_clerk 403 Finance.

PR-12kernel

US tax-review stub + UAE NullGeoCompiler

Done

Deps met: PR-1

Touch: saudi_jv_ledger/saudi_jv_ledger/geo_compiler.py · docs/specs/2026-09-12-us-tax-review-checklist.md

docs/architecture/2026-09-11-business-suite-design-0.md

US checklist stub (not tax advice, not e-file). UAE NullGeoCompiler raises NOT BUILT on live. No ZATCA duplicate. No SMTP.

PR-13kernel

Customer email live-gate plumbing

Done

Deps met: PR-4c

Touch: saudi_jv_ledger/saudi_jv_ledger/live_gate.py · charter.yaml

docs/architecture/2026-09-11-business-suite-design-0.md

Layer B customer_outbound_email. Dual gate LIVE_CUSTOMER_SMTP=false and missing var/live_gates/customer_smtp.json. No SmtpSendPort. No smtplib. Does not send.

FLOWcrm

Cross-desk CRM→Contract→AR→Finance→AP strip

Loopback

Deps met: PR-4d, PR-8, PR-9d, PR-10d

Touch: apps/suite/components/DeskFlow.tsx · apps/suite/pages/

docs/architecture/2026-09-11-suite-org-scope-program-board.md

DeskFlow on every dashboard and entity. Catch-up CLI still writes AR originals. Scope picker on parent handoff. No live SMTP.

HOST-DEVkernel · critical path

suite-dev.pharmlink.ai on Mini

Loopback

Deps met: PR-3

Touch: deploy/suite-dev/ · scripts/pharmlink_suite_serve.py

docs/architecture/2026-09-12-suite-host-and-license-lock.md

Named host + Access OTP + dedicated tunnel to Mini loopback :8480. Not clinical RDS. Not M5. Not EHR grand-central tunnel.

SIGN-UNIFYcontract

Execute instrument via NullSignPort only

Loopback

Deps met: PR-5d, PR-5f

Touch: saudi_jv_ledger/saudi_jv_ledger/contract_instruments.py · pharmlink_suite/pharmlink_suite/contract_api.py

docs/architecture/2026-09-11-pharmlink-contract-design.md

File uses NullSignPort restored terms. hospital_sign is not called from execute_instrument. No vendor SDK. No SMTP.

CRM-DASHcrm · critical path

CRM dashboard work queue + features inventory

Loopback

Deps met: PR-4d, FLOW

Touch: docs/architecture/2026-09-12-crm-features-functions.md · apps/suite/pages/crm/index.tsx

docs/architecture/2026-09-12-crm-features-functions.md

Pending actions are the work queue. Tiles expand. add_hospital_ap only for current_customer. Hash scroll on Entity.