DNPI 3.0 · Visual Implementation Plan

One profile-backed verification story
Built in three milestones, nine epics

DNPI 3.0 transforms Dynamic NPI from a “find every gap” project into profile-backed verification. Each provider’s credentials are unified under a shared profile, enabling every check to consistently map a client’s roster to official sources. This approach ensures the same plain-English statuses appear in both the web app (PTApp) and in API feeds. Name variants are only promoted when they’re supported by matching NPI, license, and board data. Onboarding (pre-go-live file passes) is kept distinct from ongoing (post-go-live) monitoring. And, before a broader launch, ProviderTrust staff will have an internal “what changed?” audit view—secured behind RBAC and feature flags—for early pilots.

Last updated: 2026-05-08 Status: Parent program ERD & 9 epic summaries drafted Phase 0: 6 of 8 blocking decisions still open Pilot: Small client set before full release

TL;DR — what we are building, in plain English

The four promises below are the heart of the program. The rest of this plan exists to make these promises hold up reliably when many clients and many credentials use the system every day.

Promise 1 One vocabulary across two surfaces

The web app (PTApp) and the computer-to-computer feed (the API) use the same plain-English status for the same real-world situation. A check that is simply old is labeled “Stale,” not “Failed.” A check that ran and found nothing is labeled “Not found,” which does not mean “we never looked.”

Promise 2 Aliases earn their place

Name variants that a client or CAQH supplied stay internal hints until the National Provider Identifier (NPI), license, and board records support the same story. Then the variant can move to confirmed and help the next lookup for any client who touches that profile.

Promise 3 Onboarding and monitoring are different journeys

The pre-go-live file pass is not the same product path as live monitoring after go-live. The file pass returns a result for every row, never drops a row quietly, and allows reruns. When something conflicts after go-live, the experience compares what the client submitted to what the primary source shows. It does not ask the client to “fix ProviderTrust’s profile” as the default story.

Promise 4 The audit trail is for PT staff, not customers

ProviderTrust employees who need to investigate get a “what changed?” timeline behind role-based access control (RBAC). A full customer-facing audit log for every field change is deliberately out of scope for version 3.0.

What we are deliberately not building in 3.0. Shipping Dynamic NPI 3.0 does not require finishing Monitor API 2.0 first—that larger rebuild stays off the critical path for this release. We are not shipping a client-facing “remove this provider from monitoring” API or screen. We are not shipping a full client-facing change history. Clients will not get free-form “pick any field” controls that break our named packages and contracts. We are also leaving out the user experience for demographic mismatches that come only from PTNetwork-style sources (for example NPPES / HCIDEA), as agreed in the requirements doc—client- and CAQH-originated signals stay in scope where the product spec says so.

The story (one page)

Dynamic NPI 3.0 is not one epic—it is a coordinated program. The sequencing matters: first put the foundation in place (shared statuses, clear origin labels, role-based access control (RBAC), feature flags) so teams do not build on shifting ground. Then ship what clients actually see and feel (the pre-go-live file pass, alias matching, conflict handling, honest monitoring alerts). Finally, nail down how named lifecycle packages show up in the public API after Product answers how a caller should ask for initial credentialing versus ongoing monitoring versus re-credentialing.

Now — roughly zero to four weeks

Phase 0 — Decisions

Finish the open calls on minimum viable product (MVP) scope, how lifecycle requests should look on the wire, alias reuse and cross-client policy, what happens when file uploads change shape, how “origin” shifts when a credential moves from client-supplied to DNPI-led, how today’s internal statuses map to the new vocabulary, cutover strategy, and the internal role model. Each topic has one directly responsible individual (DRI) who drives the answer.

Once those calls are closed (or explicitly deferred with risk written down), engineering can treat the design as stable enough to build on—instead of freezing scope every time a definition moves.

Milestone 1 — Foundation

Trustworthy internals

One canonical status list, clear attribution for where each fact came from, a small bridge of about five fields from the verification application (VAP) into Monitor so production paths stay coherent, pilot feature flags, an early ProviderTrust-admin audit experience, the RBAC design intent, and a mapping table from legacy internal states to the new client-facing words.

With the foundation in place, the team can ship what clients actually touch without constantly revisiting invisible state definitions.

Milestone 2 — Core minimum viable product

Client-visible value

The end-to-end onboarding file pass; alias triangulation; conflict screens and workflows; monitoring alerts that treat seriousness seriously and never time out real human work; honest handling of deactivated credentials, manual steps, and paid-board fees; and verification that runs on production data—staging-only checks cannot be the only place problems surface.

In parallel from Milestone 1 through Milestone 2 Cross-cutting

RBAC, flags, and audit

We set RBAC direction in Milestone 1 and carry enforcement through Epics 1–9. Pilot and cohort feature flags limit how many clients see a change at once. The audit experience is thin in Milestone 1 and stronger in Milestone 2.

When Decision 2 (lifecycle request shape) is firm, Milestone 3 can move from draft to predictable API contracts—until then, packaging language stays a program risk, not a delivery commitment.

Milestone 3 — Conditional

Lifecycle packaging

Named packages for initial, ongoing, and re-credentialing moments, each with predictable fields in the response only after Decision 2 (lifecycle request shape) closes. If that decision slips, Milestone 3 stays a draft and Epic 6 on lifecycle may need its own engineering requirements document (ERD).

Cutover is how the story lands in production: one pilot at a time, measured, and reversible—rather than assuming a single flip for the whole company.

Pilot first

Cutover

Move one pilot client at a time with a written runbook, before-and-after counts of subjects and alerts, and a clear rollback switch. Retiring the legacy experience for the whole company in a single “big bang” is a long-term hope, not a commitment in the 3.0 plan.

Phase 0 — open decisions blocking design

Engineering needs each of these answers to be closed—or explicitly deferred with the risk written down—before the team can treat the design as stable. At program kickoff, assign one directly responsible individual (DRI) per row to drive the decision and the follow-up documentation.

#DecisionWhy it mattersStatusDownstream impact if deferred
1Minimum viable product (MVP) boundary It keeps a Monitor rewrite, lifecycle packaging, audit depth, and migration from collapsing into a single impossible release. Partially closed Schedules and scope keep fighting each other; releases grow too large; estimates for Epics 5, 6, and 9 stay unreliable.
2Lifecycle request shape Without it, engineers cannot design the public API surface or support any firm commercial wording on initial versus ongoing versus re-credentialing packages. Open Epic 6 cannot be sold or estimated safely, and Milestone 3 stays on paper only.
3Alias promotion and cross-client reuse It fixes the data model and the policy question of whether a confirmed alias learned from one client may help another tenant. Partially closed Epic 3 deduplication rules wobble, and legal or compliance review may block general availability (GA).
4File ingest persistence and deletion semantics When a client sends a smaller or narrower file after a larger one, the system must define what still counts as “on the roster” and what counts as gone. Open Operators point monitoring at the wrong subjects, and clients see false “credential dropped” noise.
5Provenance shift behavior When a credential’s origin changes—for example from client-supplied to DNPI-discovered—with similar compliance exposure, alerting and repeatability rules must stay clear. Open Teams get floods of duplicate alerts, unclear remediation steps, and harder compliance interpretation.
6Status mapping from current systems We need a published map from today’s Monitor and VAP internal states to the new Dynamic NPI client vocabulary. Open Epic 1 cannot finish, and “one vocabulary” between the web app and the API remains a theory on a slide.
7Cutover strategy This chooses whether we lean sandbox-first or net-new tenants first, per-client versus broader switches, and how long two experiences may run side by side. Open Epic 9 tools and Client Success load stay guesswork, and rollout risk goes up.
8Internal role model Final names and permission intent for client admin, read-only users, implementation and customer success, monitoring operations, ProviderTrust administrator, and API service accounts need alignment. Open We either expose internal-only tools to the wrong audience or block pilot users who should have access.
Prototypes are allowed on written assumptions. Engineering may build throwaway code against temporary assumptions while a row stays open, but Product must sign those assumptions in writing. Without that handshake, the design rests on guesswork and will not survive the first real client.

Data flow — built vs net-new

Read the diagram from top to bottom. The top band is what the client touches: application programming interface (API) endpoints and the new user interface (Theme B and E in the requirements). The bottom band is automated ingest from EGEN-style jobs. The middle band is profile enrichment and the “V app” path that monitors and verifies credentials. Nodes styled in dark blue in the diagram represent components that are already built or largely in place; nodes styled in light red represent net-new engineering for Dynamic NPI 3.0.

%%{init: {"theme":"neutral","themeVariables":{"fontSize":"13px"}}}%% flowchart BT subgraph delivery [APIs and UI] newUI["New UI
same labels as API
(Theme B, E)"] apiInitial["Initial cred API
(Theme E)"] apiOngoing["Ongoing API
(Theme E)"] apiRecurrent["Re-cred API
(Theme E)"] auditWork["PT-admin audit UI/API
RBAC-gated (Theme H)"] end subgraph profileLane [Profile] aliasWork["Alias work
temp → confirmed → known
(Theme D)"] augmentedRecord["Augmented
provider record"] caqhFeed["CAQH augmentation
(EGEN)"] nscEdu["NSC education and certification
(EGEN)"] end subgraph vapp [V app — monitor and verify] monitorVerify["Monitor and verify
(Theme C)"] originWork["Origin work
reduce admin tasks
(Theme G)"] end autoIngest["Automated data ingest
(EGEN)"] autoIngest --> monitorVerify originWork --> monitorVerify monitorVerify --> augmentedRecord caqhFeed --> augmentedRecord caqhFeed --> nscEdu nscEdu --> augmentedRecord aliasWork --> augmentedRecord augmentedRecord --> apiInitial augmentedRecord --> apiOngoing augmentedRecord --> apiRecurrent apiInitial --> newUI apiOngoing --> newUI apiRecurrent --> newUI auditWork --> newUI classDef workTodo fill:#fde6e3,stroke:#c0322b,color:#5b1410,stroke-width:2px; classDef built fill:#222b46,stroke:#0e1430,color:#ffffff,stroke-width:2px; class originWork,aliasWork,auditWork,apiInitial,apiOngoing,apiRecurrent,newUI workTodo; class autoIngest,monitorVerify,augmentedRecord,caqhFeed,nscEdu built;

What stays in place, what we add

Already built or stays: automated data ingest (labeled EGEN in the diagram), the verification application’s monitor-and-verify path, the augmented provider record, and feeds from CAQH and NSC that enrich the profile.

New for 3.0: clearer origin attribution, alias resolution before data leaves the profile, lifecycle-aware APIs for initial credentialing, ongoing monitoring, and re-credentialing, the redesigned client experience, and the internal audit experience for ProviderTrust administrators.

Interim bridge: a handful of VAP fields into Monitor

Until a deeper Monitor API redesign lands, we plan to forward about five carefully chosen fields from the verification application (VAP) into Monitor so that what a person sees in the product matches what automated checks record.

Engineering leadership has questioned a “shoehorn only” long-term path; treat “about five fields” as planning shorthand until the responsible engineering manager publishes a revised estimate and scope.

Milestones & sequencing

We split the program into three milestones so the minimum viable product (MVP) stays honest—lifecycle packaging cannot quietly swallow every other epic without Product’s explicit decision on request shape (Decision 2). Each milestone is a delivery beat in a single story: epics listed below are the cast; monospace edge tags mirror arrows in the nine-epic graph (not a second source of truth).

Milestone 1
Foundation & internal validation
Milestone 2
Core verification minimum viable product
(client-visible value)
Milestone 3
Lifecycle packaging
(waits on Decision 2)
Milestone 1

Trustworthy internals

1 Status & origin 8 RBAC & flags 7 Internal audit (first slice)
Spine unlocks · outgoing from 1 & 8
1→31→41→5 8→28→78→9

Epics 1 and 8 are the spine: vocabulary and gates have to be real before client-heavy epics lean on them. Epic 7 starts thin so ProviderTrust admins see a real timeline behind RBAC while you add depth in Milestone 2.

Exit criteria

  • At least twenty golden test fixtures show the web app (PTApp) and the computer-to-computer feed (the API) returning the same status for the same situation.
  • The Dynamic NPI pilot feature flag applies to at least one tenant while every other tenant behaves exactly as before.
  • A ProviderTrust administrator can open a “what changed?” timeline for the events we instrument in this milestone.

Then open client-visible work: file pass, aliases, conflicts, monitoring, and pilot cutover—still respecting the arrows above (for example 3 before 4).

Milestone 2

Client-visible value (+ pilot rollout)

2 Onboarding file pass 3 Aliases 4 Conflict UX 5 Monitoring & alerts 7 Audit (deeper) 9 Migration & cutover — pilot
Chains chiefly closed in this beat
3→4 2→9

Epic 6 stays out of this milestone—it waits on Decision 2. Epic 9 is the rollout track: it ramps with pilots as 2 and 8 stabilize (see 2→9), not a fourth bar on the timeline.

Exit criteria

  • Pilot clients receive deterministic, row-level results from the pre-go-live onboarding file pass.
  • False “not found” outcomes drop measurably when the license and board already agree on the identity, because alias triangulation works.
  • No client-facing copy tells the customer their job is to “fix ProviderTrust’s aggregate profile” by default.
  • Temporary alias hints remain internal and never appear as if the client typed them.

When Decision 2 closes and conflict/monitoring stories are mature, lifecycle packages can ship as a coherent API surface.

Milestone 3 · conditional

Lifecycle packaging

6 Lifecycle packages
Into Epic 6 · plus product gate
4→6 5→6 Decision 2

Epic 6 is gated on Decision 2 (lifecycle request shape) and logically follows 4 and 5 in the graph. If Decision 2 slips, this milestone stays a draft and Epic 6 may need its own engineering requirements document (ERD).

Exit criteria

  • Product management, engineering, commercial, and Client Success share the same story for how to buy, implement, and consume named lifecycle packages.
  • New customers can land on standard packages without a one-off engineering project for each deal.
  • Existing customers have a written playbook for converting from their current setup.
How to read this. The horizontal bars are release beats. Each block below is the same beat with who (epic chips), which arrows you are satisfying (monospace tags), and what “done” means (exit criteria). Parallel work is fine where the graph allows—e.g. much of 1 with early 8—but do not treat 4 as finished before 3 catches up. Full topology: nine-epic dependency graph.

Nine epics & their dependency graph

%%{init: {"theme":"neutral","themeVariables":{"fontSize":"13px"}}}%% flowchart LR e1["Epic 1
Status & origin"] --> e3["Epic 3
Aliases"] e1 --> e4["Epic 4
Conflict UX"] e1 --> e5["Epic 5
Monitoring & alerts"] e8["Epic 8
RBAC & flags"] --> e2["Epic 2
Onboarding file pass"] e8 --> e7["Epic 7
Internal audit"] e8 --> e9["Epic 9
Migration & cutover"] e3 --> e4 e2 --> e9 e4 --> e6["Epic 6
Lifecycle packages
(gated)"] e5 --> e6 classDef gate fill:#fff3df,stroke:#b8730d,color:#5b3b06; class e6 gate
1

One clear status story in the app and the API Must-have for launch

The web app (PTApp) and the computer-to-computer feed (the API) use the same plain-English words for the same situation, and each fact shows where it came from. “Stale” is not the same as “failed,” and “not found” is not the same as “we never checked.”

3

Names that almost match still connect to the right person Must-have for launch

When the National Provider Identifier (NPI), license number, and board record line up, a name variant can move from temporary to confirmed to known. Hints stay inside ProviderTrust until they earn that promotion.

4

When two sources disagree, the client sees both sides Must-have for launch

Show what the client submitted next to what the primary source reports. Offer accept or reject flows where the requirements call for them, and raise alerts when policy says so. Use different guidance when the roster has zero credentials versus when only an incomplete federal taxonomy (for example NPPES-only) is available.

5

After go-live: monitoring that tells the truth Serious case for launch; extra noise control can follow

High-severity items such as federal-style hits surface with appropriate urgency. Alerts that need a human do not disappear because a timer expired. Deactivated National Provider Identifiers, termed subjects, delisted licenses, and brand-new identifiers in mid-cycle all get honest labels.

6

Named packages for initial, ongoing, and re-check moments Waits on Decision 2

Sold packages return predictable shapes for initial credentialing, ongoing monitoring, and re-credentialing. ProviderTrust configures what comes back; the client does not get a “pick your own fields” filter that breaks packaging rules. When we add fields to an object, those additions apply to every buyer mapped to that object footprint.

2

Before go-live: a full-file check that keeps every row Must-have for launch

Every uploaded row receives an explicit outcome. When automation cannot finish, the run still returns the client’s original fields and flags the row for review. Teams can rerun corrected files without duplicating operational work.

7

ProviderTrust staff can see what changed on a profile Must-have for launch (internal only)

Behind role-based access control (RBAC), internal users see a timeline of alias moves, license checks and removals, primary-source mismatches, demographic updates, lifecycle transitions, and manual overrides. This is not a substitute for a full customer audit log in 3.0.

8

Right people, right screens; safe pilots Must-have for launch

Read-only roles cannot upload files or accept conflicts, and they see the same error wording in the app and on the API. Permission tags marked for ProviderTrust-only use must deny access for global client roles even when a screen exists. Per-tenant and cohort feature flags keep rollout risk contained.

9

Pilot move from traditional monitoring to Dynamic NPI Pilot first

Convert one client at a time with before-and-after subject counts, alert-volume monitoring, documented rollback, and runbooks for deactivated identifiers, fee-based boards, and entity-type mismatches.

Sources: DNPI 3.0 Epics Index (Confluence).

Status model — one vocabulary, two surfaces

The hardest product promise in 3.0 is simple to say: for the same real-world condition, the web app (PTApp) and the computer-to-computer feed (the API) must expose the same canonical status—the same meaning, not just a similar label—plus consistent client-facing detail where it matters (short reasons, conflict actions, fee context, and so on). The table below lists those statuses. The card beside it explains how engineering maps today’s internal codes without rewriting every database column overnight.

StatusMeaningSurfaces
VerifiedApproved check completed and passedPTApp + API
Not verifiedNo approved check, or check failedPTApp + API + short reason
In progress / PendingCheck in flight inside the agreed service-level agreement (SLA)PTApp + API
ConflictSources disagree; client must resolvePTApp + API + accept/reject
Manual / Fee requiredPaid or manual jurisdiction stepPTApp + API + fee context if applicable
Not foundLooked; nothing matched — not "did not look"PTApp + API
On file (unverified)Data present without approved pathPTApp + API; never implies verified
StaleOld timestamp, no hard failurePTApp + API; neutral cue
DeactivatedNPI deactivated federallyPTApp + API; monitoring stops

Engineering note: a translator, not a rewrite

We do not need to repaint every legacy database value in one release. Instead, stand up a status mapping layer—a translator—at the boundary where data becomes a client response. That layer turns internal Monitor and VAP states into the canonical vocabulary in the table. Keep the legacy codes in storage; only the wire format that PTApp and public integrators see changes.

The sample code below shows how such a translator behaves; the exact switch values will mirror Decision 6 once the mapping artifact lands.

// Pseudocode — status translator at the API/UI boundary
enum DnpiStatus {
  VERIFIED, NOT_VERIFIED, IN_PROGRESS,
  CONFLICT, MANUAL_FEE_REQUIRED,
  NOT_FOUND, ON_FILE_UNVERIFIED, STALE, DEACTIVATED
}

function toDnpi(internal): DnpiStatus {
  switch (internal.legacyState) {
    case 'AUTO_VERIFIED':        return VERIFIED;
    case 'STALE_NO_FAILURE':      return STALE;
    case 'NPPES_DEACTIVATED':     return DEACTIVATED;
    case 'NO_MATCH_AFTER_LOOKUP': return NOT_FOUND;
    case 'CHECK_NEVER_RAN':
      // CRITICAL: never collapse this into NOT_FOUND
      return IN_PROGRESS;
    case 'SOURCES_DIVERGE':       return CONFLICT;
    case 'FEE_REQUIRED':          return MANUAL_FEE_REQUIRED;
    default:
      // fail-loud: surface a structured warning to ops
      ops.warn('unmapped_legacy_state', internal);
      return ON_FILE_UNVERIFIED;
  }
}
Decision 6 is still open. The spreadsheet or document that maps current internal states to the canonical Dynamic NPI vocabulary is a deliverable engineering owes Product before Milestone 1 closes. Until that file exists, the default branch in the sample above must raise a visible warning for our operations teams whenever an unknown legacy code appears, instead of quietly folding it into a harmless-looking label.

Alias state machine (Epic 3)

When a client or CAQH sends a name that does not exactly match federal records, we still treat that variant carefully. It does not show up in the “what you typed” column as a confirmed fact until a primary source backs the story. The diagram below is the lifecycle contract: internal hold, promotion with proof, or rejection when the official record disagrees.

%%{init: {"theme":"neutral","themeVariables":{"fontSize":"16px","fontFamily":"'Inter','Segoe UI',sans-serif","primaryColor":"#f8fafc","primaryBorderColor":"#416fbe","primaryTextColor":"#0b2544","noteBorderRadius":"8px","noteBkgColor":"#e9f2fc","noteTextColor":"#205080"}}}%% stateDiagram-v2 direction LR [*] --> TemporaryHeld: client/CAQH\nvariant captured TemporaryHeld --> Confirmed: NPI + license + board\ncoherence proven TemporaryHeld --> RejectedInternal: contradicted by\nprimary source Confirmed --> Known: persisted on\nprofile (cross-lookup) Known --> [*] RejectedInternal --> [*] note right of TemporaryHeld Internal-only.\nNEVER visible to clients. end note note right of Confirmed Persistent.\nMay appear under PT profile/center\n(NOT in "client data" column). end note

Promotion rule (read this carefully)

Hearing “the client says it is the same person” is not sufficient by itself. Promotion to a shared, long-lived alias requires the National Provider Identifier (NPI), name signals, and credential details to line up with what a board or similar primary source publishes.

// Promotion guard for Temporary → Confirmed
function canPromote(alias, evidence) {
  return evidence.npi.matches(alias.npi)
      && evidence.licenseNumber.matchesBoard(alias.licenseNumber)
      && evidence.licenseType.matchesBoardTaxonomy(alias.licenseType)
      && nameSignal.coherent(alias.name, evidence.boardName, {
           middle: 'rules',            // per dnpi_credentials.md
           lastSubstring: true,        // at-add only
         })
      && !clientAttestationOnly(evidence);  // hard NO
}
Moving an alias into ProviderTrust’s shared Proprietary Profile Store (PPS) intelligence—and deciding when that intelligence may reuse across clients—is Decision 3, and it remains open. Until Product and Compliance close it, treat every promoted alias as owned by the client that supplied the evidence, and run compliance review before any cross-tenant reuse.

Mockups — the three primary use cases

These screens are conceptual, not final visual design. They show the information architecture the services must support: what the client submitted, what lives on the ProviderTrust profile, and what the official primary source says—with clear origin labels and the same status vocabulary as the computer-to-computer feed (the API).

Use Case 1 — Implementation user runs the pre-go-live file pass

ptapp.providertrust.com / implementation / onboarding-runs / run_8b1f3

Onboarding run · run_8b1f3

Acme Health Pre-Go-Live · roster_2026_05_08.csv · 4 rows

2 verified 1 needs review 1 partial failure
RowSubmitted nameSubmitted NPIResult vs profileResult vs primaryStatusAction
1 Jane A. Doe 1234567890 match verified Verified
2 Janie Doe 1234567890 alias candidate (internal) board confirms Verified auto-promote alias to confirmed
3 John Q Smith 9988776655 profile says different last name conflict Conflict queue for review · client retains submitted fields
4 5555555555 primary-source fetch timed out unable to verify Manual / Fee required row preserved · flagged for re-run · not dropped
What “done” looks like for the file pass. If automation cannot finish a row, the response still includes the client’s original fields, marks the row for follow-up, and never drops it from the run. When the client uploads a corrected file, reruns de-duplicate work using a stable key such as (client_id, population_id, file_hash) so completed rows are not paid for twice.

Use Case 2 — Client views a live monitoring conflict

ptapp.providertrust.com / providers / 1234567890 / credentials / lic-tn-12345

Jane A. Doe — TN RN License #RN-12345

NPI 1234567890 · checked 2026-05-07 14:21 UTC
What you submitted (client)
Jane Doe — RN-12345
Submitted 2026-04-12
ProviderTrust profile aliases: 2 confirmed
Jane A. Doe (primary)
Aliases known: Janie Doe, J. A. Doe
Primary source (TN board)
Jane Anne Doe — RN-12345
Board status: SUSPENDED · effective 2026-05-01
Status
Conflict License board reports SUSPENDED while submitted record showed ACTIVE
Reason
Primary source disagrees with submitted state — compliance-urgent
Action
An email alert was sent to the compliance contact.
How the conflict screen should read. Nothing on this page tells the user their first job is to “fix ProviderTrust’s profile.” The left column keeps what the client submitted. The center shows what ProviderTrust already knows, including confirmed aliases. The right column shows what the licensing board published. That three-way layout keeps compliance conversations honest.

Use Case 3 — PT internal investigator answers "what changed?"

internal.providertrust.com / dnpi / profiles / prof_27aa / audit

Profile prof_27aa · Jane A. Doe · NPI 1234567890

Internal-only timeline · RBAC: PT_ADMIN DATA_SERVICES

2026-05-07 14:21 UTC · monitor.scheduler
License conflict surfaced — TN RN-12345 board status SUSPENDED, prior verified ACTIVE
→ Alert: client_email + ptapp_inapp · Severity: urgent
2026-04-30 09:02 UTC · alias.engine
Alias promoted — "Janie Doe" : Temporary → Confirmed
Triangulation: NPI=1234567890, license RN-12345, board name "Jane Anne Doe" (substring last-name match)
2026-04-29 16:44 UTC · vap.bridge
Origin attribution updated — primary source label switched from PROFILE to BOARD
Reason: live re-verify cycle picked up board update
2026-04-12 11:00 UTC · onboarding.run_8b1f3
Credential added on file — TN RN-12345 (client-supplied)
Initial origin: CLIENT_SUPPLIED · awaiting first verify
Internal operators only. This investigator view sits behind role-based access control (RBAC). It helps ProviderTrust staff answer “what changed?” without replacing a full customer audit product. A client-facing stream of every change is intentionally out of scope for version 3.0.

API contracts — draft sketches for engineering managers to refine

The six rows below are draft endpoint sketches. HTTP verbs and paths stay illustrative until engineering leadership aligns naming, versioning, and security boundaries. Nothing here is a committed JSON schema or contract; it is a shared vocabulary for workshops.

VerbSketch pathPurposeOwning epic
POST/dnpi/onboarding-runsStart an onboarding run keyed to client/population/contextEpic 2
GET/dnpi/onboarding-runs/{run_id}/resultsAggregated + row-level outcomesEpic 2
GET/dnpi/providers/{npi}/verification-statusConsolidated status for surfaced credentialsEpic 1, 4
POST/dnpi/providers/{npi}/conflict-resolutionsRecord explicit client remediationEpic 4
GET/internal/dnpi/profiles/{profile_id}/audit-eventsAdmin-only timelineEpic 7
POST/internal/dnpi/profiles/{profile_id}/aliases/{alias_id}/promoteAdmin-only guarded promotionEpic 3, 7

Sample — verification status response

// GET /dnpi/providers/1234567890/verification-status
{
  "npi": "1234567890",
  "profile_id": "prof_27aa",
  "as_of": "2026-05-07T14:21:00Z",
  "status": "CONFLICT",
  "reason_code": "BOARD_SUSPENDED_VS_SUBMITTED_ACTIVE",
  "required_action": "client_acknowledge",
  "credentials": [
    {
      "id": "lic-tn-12345",
      "type": "RN",
      "jurisdiction": "TN",
      "status": "CONFLICT",
      "submitted": { "name": "Jane Doe",
                      "license_number": "RN-12345",
                      "origin": "CLIENT_SUPPLIED" },
      "profile": { "name": "Jane A. Doe",
                    "aliases_known": ["Janie Doe","J. A. Doe"],
                    "origin": "PT_PROFILE" },
      "primary_source": { "name": "Jane Anne Doe",
                           "board_status": "SUSPENDED",
                           "effective": "2026-05-01",
                           "origin": "PRIMARY_SOURCE_BOARD" },
      "reason_code": "BOARD_SUSPENDED_VS_SUBMITTED_ACTIVE"
    }
  ],
  "explainability": {
    "freshness_seconds": 14400,
    "matched_via": ["NPI","LICENSE_NUMBER","BOARD_NAME"]
  }
}

Sample — onboarding row outcome

// GET /dnpi/onboarding-runs/run_8b1f3/results (one row)
{
  "row_index": 4,
  "submitted": { "name": null,
                  "npi": "5555555555" },
  "outcome": "UNABLE_TO_VERIFY_AUTOMATICALLY",
  "status": "MANUAL_FEE_REQUIRED",
  "reason_code": "PRIMARY_SOURCE_TIMEOUT",
  "review_queue": "impl_review",
  "client_fields_preserved": true,
  "silent_drop": false,    // invariant for Epic 2
  "can_rerun": true
}
Non-negotiable for Epic 2. The silent_drop flag must remain false for every row that appeared in an uploaded file. Automated tests for the onboarding file pass should assert that invariant on every fixture so a silent omission can never slip through.

Role-based access control (RBAC) matrix — Epic 8 (read before building UI)

Decision 8 on the internal role model is still open. The matrix below is the working assumption pulled from the requirements documents; build toward it, but expect Product and Operations to rename or tune roles before launch. When in doubt, default to the least privilege that still lets pilots succeed.

Capability Client Admin Client Read-only Implementation / CS Monitoring Ops / Data Services PT_ADMIN API service account
Upload onboarding file allow deny — clear msg allow (on-behalf) deny allow allow (scoped)
Accept / reject conflict allow deny — clear msg allow (on-behalf) deny allow (audited) allow (scoped)
View internal audit timeline deny deny limited (own client) allow allow deny
Promote alias (Temporary → Confirmed) deny deny deny propose only allow (audited) deny
Toggle DNPI feature flag for tenant deny deny request deny allow deny

Permission tag pattern

Each capability maps to a permission tag, and tags attach to access roles. When a tag is marked for ProviderTrust-only internal work, global client roles must receive a hard denial—even if a screen URL leaks.

// Permission tags map to AccessRoles. PT-Only must DENY for Global-Client roles.
permissions:
  - id: "dnpi.onboarding.upload"
    pt_only: false
    default_for: ["CLIENT_ADMIN", "IMPLEMENTATION"]
  - id: "dnpi.audit.read"
    pt_only: true     // MUST deny for Global-Client AccessRoles
    default_for: ["PT_ADMIN", "DATA_SERVICES"]
  - id: "dnpi.alias.promote"
    pt_only: true
    default_for: ["PT_ADMIN"]
    requires_audit_event: true

Read-only failure mode

A read-only user who tries to upload a roster or resolve a conflict should see the same plain-English explanation in the web app (PTApp) and in the error payload from the computer-to-computer feed (the API)—the same “one vocabulary” discipline as Epic 1, applied to permission errors.

// 403 response shape (PTApp surfaces the same wording)
{
  "error": "FORBIDDEN_ROLE",
  "message": "Your role can view but not modify this. Ask your admin for access.",
  "required_permission": "dnpi.onboarding.upload",
  "current_role": "CLIENT_READ_ONLY"
}

Migration & cutover (Epic 9) — pilot first

Moving from traditional monitoring to Dynamic NPI is most often a per-client switch rather than flipping every tenant in the company on the same day. The flow diagram below is the playbook we expect operations and engineering to follow together.

%%{init: {"theme":"neutral","themeVariables":{"fontSize":"13px"}}}%% flowchart LR s1["1. Baseline counts
subjects, alerts, statuses"] --> s2["2. Enable DNPI flag
for pilot tenant only"] s2 --> s3["3. Run shadow window
compare alerts vs baseline"] s3 --> s4{"Drift in tolerance?"} s4 -- yes --> s5["4. Switch primary
per-client cutover"] s4 -- no --> s6["Investigate · fix · loop"] s5 --> s7["5. Watch alert volume
+ resolution rates"] s7 --> s8{"Sev-1 risk?"} s8 -- no --> s9["6. Stand down war room
graduate pilot"] s8 -- yes --> s10["Roll back via flag
(documented rollback)"]

Before you cut a pilot over

  • Capture baseline counts of monitored subjects and open alerts.
  • Review the status-mapping table against this tenant’s live data quirks.
  • Spot-check a handful of alias confirmations for obvious mistakes.
  • Confirm role-based access control matches the real user list for that client.
  • Have the engineering manager and Client Success sign the rollback runbook.

During the cutover window

  • Keep the change in alert volume within the agreed band versus baseline (exact percentage is tuned per pilot).
  • Do not introduce new client copy that implies the customer must “fix ProviderTrust’s aggregate profile.”
  • When credential origin shifts, avoid duplicate alerts for the same underlying issue.
  • Exclude termed or deactivated subjects from automated re-check loops.

If you need to roll back

  • Turn off the Dynamic NPI pilot flag for that tenant so legacy behavior returns immediately.
  • Write a short postmortem that includes before/after tables and the alert diff.
  • Feed lessons learned back into Decision 7 (cutover strategy) so the next pilot benefits.

Glossary & pointers back to source

Use this table as a reading list: each row highlights where to go deeper if you own one slice of the program.

Term / areaWhat it means hereSource
Documentation indexConfluence entry point that links DNPI 3.0 wiki pages and how they fit together.DNPI 3.0 Summary of Documents
Parent ERDThe 3.0 program-level engineering requirements (milestones, use cases, pillars, API placeholders, non-scope).DNPI 3.0 Engineering Requirements Document (Parent Program)
Decision logPhase 0 governance — eight blocking decisions, status, downstream impact.Claude project (decision log)
Epics indexPlain-English summary of the nine epics with the dependency graph.DNPI 3.0 Epics Index
Per-epic detailOne file per epic — what you get, what's not in, where it comes from.Claude project (per-epic detail)
Theme → epic mapHow Themes A–H land in epics with acceptance signals.Claude project (theme → epic map)
Lifecycle placementWhen Epic 6 stays in-program vs splits into its own ERD.DNPI 3.0 Summary of Documents (wiki index)
Claire's PM breakdownThe blunt program memo this plan is built from.DNPI 3.0 Summary of Documents (wiki index)
Plain-English requirementsThemes A–H, decisions made, open questions, statuses table, journey + platform diagrams.DNPI 3.0 Requirements
Data quality SLAsVerification path-by-path SLAs (V-app, NPPES, HCIdea, dataQ, DEA, ABMS, client-supplied).DNPI_3_0_SLA_Upgrade_Matrix

This page is intentionally self-contained. It will go stale the moment any of the source files do — treat it as a snapshot of the visual story, not as the canonical spec. The canonical product source remains the Confluence DNPI 3.0 Requirements page in the PRODUCT space.