@nexalink/carecompass-sdk 0.2.0-beta.12 → 0.2.0-beta.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,142 +1,128 @@
1
- # CareCompass Healthcare Embed SDK
1
+ # CareCompass Healthcare SDK
2
2
 
3
- `@nexalink/carecompass-sdk` helps healthcare organizations embed a branded CareCompass chat experience in their own websites and applications. It includes a React component, a vanilla JavaScript mount helper, shared configuration validation, and a CLI for setup, validation, snippet generation, and local diagnostics.
3
+ CareCompass is a healthcare navigation AI for healthcare apps and portals. The SDK gives payers, providers, employers, and healthcare technology teams a branded member-facing chat experience backed by Nexalink-hosted AI infrastructure.
4
4
 
5
- CareCompass lets healthcare teams offer member-facing navigation support while keeping LLM inference behind Nexalink-hosted APIs. The integrating organization controls the placement, branding, theme, labels, support links, allowed origins, and approved prompt configuration. Nexalink controls account validation, API-key enforcement, embed-key authorization, usage tracking, and the hosted model path.
5
+ CareCompass is not a general-purpose LLM SDK, medical diagnosis tool, replacement for clinical decision making, or system for autonomous treatment recommendations.
6
6
 
7
- This package is publicly installable for developer convenience, but live regulated use requires Nexalink onboarding, BAA coverage where PHI may be involved, and Nexalink-issued API credentials.
7
+ ## What You Can Build
8
8
 
9
- ## Who This Is For
9
+ - Member navigation assistants
10
+ - Benefits guidance tools
11
+ - Provider discovery experiences
12
+ - Healthcare support chat interfaces
13
+ - Employer healthcare navigation portals
14
+ - Payer member engagement tools
10
15
 
11
- This SDK is for enterprise healthcare teams that want to add CareCompass to their own frontend without building a model gateway, prompt validation layer, key-management flow, or token-metering pipeline.
16
+ ## Why CareCompass
12
17
 
13
- Typical users include:
18
+ - **Healthcare-focused experience**: prompts, labels, guardrails, and defaults are oriented around healthcare navigation.
19
+ - **Hosted AI infrastructure**: chat requests go through Nexalink-hosted APIs and the Nexalink-managed AI runtime.
20
+ - **Branding and customization**: configure display name, logo, support links, theme, labels, placement, and approved prompt context.
21
+ - **Usage tracking**: Nexalink tracks usage under issued keys for deployment monitoring and future metered billing.
22
+ - **Enterprise deployment support**: use separate staging/production keys, origin allowlists, validation, BAA-gated onboarding where PHI may be involved, and security controls.
14
23
 
15
- - payer, provider, employer-benefits, care-navigation, and digital-health teams embedding CareCompass in a member or patient site
16
- - implementation engineers configuring staging and production deployments
17
- - technical operators validating origins, branding, and prompt policy
18
- - non-technical customer admins issuing SDK keys from the Nexalink portal
24
+ ## Quick Start
19
25
 
20
- ## Account Required
26
+ The package is publicly installable for developer convenience. Live regulated use requires Nexalink onboarding, BAA coverage where PHI may be involved, and Nexalink-issued credentials.
21
27
 
22
- You need a Nexalink account with SDK access before using the SDK beyond package installation. For deployments that may involve PHI, a signed BAA and approved credentials are required before live use.
28
+ ```bash
29
+ npx @nexalink/carecompass-sdk init --account-type developer --api-key <nexalink-api-key> --payer-id acme-health --origin https://members.acme-health.com
30
+ npx @nexalink/carecompass-sdk validate --config carecompass/carecompass.config.json
31
+ npx @nexalink/carecompass-sdk doctor --config carecompass/carecompass.config.json
32
+ ```
23
33
 
24
- The account is required because Nexalink validates:
34
+ `init` validates your Nexalink API key, stores it locally, and generates:
25
35
 
26
- - the customer or payer ID
27
- - the secret SDK API key
28
- - the public browser embed key
29
- - the deployment environment
30
- - the allowed website origins
31
- - the approved prompt configuration
32
- - API usage and token counts for future metered billing
36
+ - `carecompass/carecompass.config.json`
37
+ - `carecompass/system-prompt.md`
38
+ - `carecompass/carecompass-embed.html`
39
+ - `carecompass/carecompass-iframe.html`
40
+ - `carecompass/README.md`
33
41
 
34
- API keys are issued in the Nexalink portal under the CareCompass SDK section.
35
- For first-time onboarding, a tenant owner or admin executes the canonical BAA
36
- from the portal BAA page before generating the first key. The secret API key is
37
- shown once and should be stored locally by the developer. It should never be
38
- committed to source control or placed in browser code.
42
+ `npx` does not install a permanent `carecompass` command. Keep using `npx @nexalink/carecompass-sdk <command>` or install the package. The CLI requires Node.js 18 or newer.
39
43
 
40
- ### API Key Vs Embed Key
44
+ ## How It Works
41
45
 
42
- CareCompass uses two different keys with different security expectations:
46
+ ```text
47
+ Your Application
48
+ ↓
49
+ CareCompass SDK
50
+ ↓
51
+ Nexalink Hosted APIs
52
+ ↓
53
+ CareCompass AI Runtime
54
+ ```
43
55
 
44
- - **API key**: a secret credential for trusted setup and server-side/CLI
45
- workflows. Use it to authenticate actions such as signing in during `init` and
46
- creating or managing SDK access. Never include it in browser code, generated
47
- embed HTML, frontend config, or source control.
48
- - **Embed key**: a public browser-facing identifier for the CareCompass embed.
49
- It is safe to include in `carecompass.config.json` and generated snippets. It
50
- identifies the payer, environment, and embed client for runtime requests, but
51
- it is not a secret and should not be treated as proof of identity on its own.
56
+ Your application renders the React component, JavaScript mount helper, generated embed page, or iframe. The browser receives only public embed configuration: payer ID, environment, public embed key, branding, labels, theme, support links, approved prompt settings, and telemetry defaults. Chat goes to Nexalink-hosted CareCompass API routes.
52
57
 
53
- Start onboarding with:
58
+ ## Account Requirements
54
59
 
55
- ```bash
56
- npx @nexalink/carecompass-sdk init
57
- ```
60
+ A Nexalink account with SDK access is required beyond package installation so Nexalink can validate payer identity, environment, secret API key, public embed key, allowed origins, approved prompt configuration, and API usage. API keys are issued in the Nexalink portal. When PHI may be involved, a tenant owner or admin executes the canonical BAA before generating the first key. The secret API key is shown once, stored locally, and must never be committed or placed in browser code.
58
61
 
59
- The CLI routes developers without accounts to the configured signup path,
60
- validates the API key with Nexalink, stores it locally only after successful
61
- sign-in, and generates the SDK config. BAA execution happens in the Nexalink web
62
- app before API key creation.
62
+ ## Common Use Cases
63
63
 
64
- ## Install And Run
64
+ - Payers: branded member assistants for benefits, coverage navigation, support resources, and next steps.
65
+ - Employers: healthcare navigation portals that route employees to plan resources and approved support channels.
66
+ - Providers and digital health companies: support chat with model access, validation, and usage tracking behind Nexalink-hosted APIs.
65
67
 
66
- Use any common JavaScript package manager. For first-time testing, the simplest
67
- path is to run each command with `npx`.
68
+ ## React Example
68
69
 
69
- ```bash
70
- npx @nexalink/carecompass-sdk init --account-type developer --api-key <nexalink-api-key> --payer-id acme-health --origin https://members.acme-health.com
71
- npx @nexalink/carecompass-sdk validate --config carecompass/carecompass.config.json
72
- npx @nexalink/carecompass-sdk doctor --config carecompass/carecompass.config.json
70
+ ```tsx
71
+ import { CareCompassEmbed } from "@nexalink/carecompass-sdk";
72
+ import config from "./carecompass/carecompass.config.json";
73
+
74
+ export function MemberSupport() {
75
+ return <CareCompassEmbed config={config} />;
76
+ }
73
77
  ```
74
78
 
75
- `npx` does not permanently install a `carecompass` shell command. Keep using
76
- `npx @nexalink/carecompass-sdk <command>` for init, validate, snippet, and
77
- doctor.
79
+ ## JavaScript Example
78
80
 
79
- Package-manager equivalents:
81
+ ```ts
82
+ import { mountCareCompass } from "@nexalink/carecompass-sdk";
83
+ import config from "./carecompass/carecompass.config.json";
80
84
 
81
- ```bash
82
- npm exec --package @nexalink/carecompass-sdk -- carecompass init
83
- pnpm dlx @nexalink/carecompass-sdk init
84
- yarn dlx @nexalink/carecompass-sdk init
85
- bunx @nexalink/carecompass-sdk init
85
+ mountCareCompass(document.getElementById("carecompass-root"), config);
86
86
  ```
87
87
 
88
- You can also install it in a project and run the binary through your package
89
- manager:
88
+ ## Enterprise Features
90
89
 
91
- ```bash
92
- npm install @nexalink/carecompass-sdk
93
- npm exec carecompass -- init --payer-id acme-health --origin https://members.acme-health.com
94
- ```
90
+ CareCompass uses separate credentials for trusted setup and browser runtime:
91
+
92
+ - **API key**: a secret credential for trusted setup and server-side/CLI workflows, including `init` sign-in and validation. Never include it in browser code, generated embed HTML, frontend config, or source control.
93
+ - **Embed key**: a public browser-facing identifier for the CareCompass embed. It is safe to include in `carecompass.config.json` and generated snippets. It identifies the payer, environment, and embed client for runtime requests, but it is not a secret or proof of identity on its own.
94
+
95
+ Enterprise concepts include API keys, embed keys, origin allowlists, BAA requirements where PHI may be involved, usage tracking, future Stripe metered billing support, hosted validation, prompt guardrails, rate limiting, request attribution, tenant isolation, and staging/production separation. Enterprise signup and BAA execution happen in the Nexalink web app before API key creation.
95
96
 
96
- Or install it globally if your organization permits global npm tools:
97
+ Use separate keys and config files for staging and production:
97
98
 
98
99
  ```bash
99
- npm install -g @nexalink/carecompass-sdk
100
- carecompass init --payer-id acme-health --origin https://members.acme-health.com
100
+ npx @nexalink/carecompass-sdk validate --config carecompass.staging.json
101
+ npx @nexalink/carecompass-sdk snippet --config carecompass.staging.json --output carecompass/staging-embed.html
102
+ npx @nexalink/carecompass-sdk doctor --config carecompass.staging.json
101
103
  ```
102
104
 
103
- ## CLI Commands
105
+ Before production, confirm the exact origin allowlist, a production-specific `embedKey`, approved Nexalink-hosted `apiBaseUrl`, support links, prompt instructions, and no secret API key in generated source code.
104
106
 
105
- ### `init`
107
+ ## Security & Compliance
106
108
 
107
- Runs the complete first-time onboarding flow:
109
+ CareCompass keeps secret SDK API keys out of the browser. The browser uses public `embedKey`, payer ID, environment, and allowed origin metadata to call Nexalink-hosted embed API routes. Staging and production `apiBaseUrl` values must be Nexalink-hosted HTTPS URLs; `localhost` is accepted only for `development`.
108
110
 
109
- - routes users without accounts to the configured signup path
110
- - validates the API key with Nexalink before continuing
111
- - stores the secret Nexalink API key locally
112
- - generates the SDK config, prompt starter, embed page, iframe, and setup guide
113
- with only public embed configuration
111
+ The browser does not receive SageMaker credentials, AppSync signing roles, private model endpoint details, Nexalink server-side allowlists, or the secret SDK API key. Generated snippets escape serialized config, and React renders chat messages and labels as text.
114
112
 
115
- Creates a `carecompass` folder with all generated SDK files in one place:
113
+ Telemetry is enabled automatically with Nexalink-managed defaults. The SDK sends only allowlisted anonymous deployment-health events to PostHog's public ingestion API. It does not bundle `posthog-js`, enable session replay or autocapture, identify users, set cookies, or persist analytics state. Prompts, responses, chat history, user context, PHI/PII, credentials, raw errors, stack traces, CLI arguments, terminal input, and file paths are excluded.
116
114
 
117
- - `carecompass/carecompass.config.json`
118
- - `carecompass/system-prompt.md`
119
- - `carecompass/carecompass-embed.html`
120
- - `carecompass/carecompass-iframe.html`
121
- - `carecompass/README.md`
115
+ Some MVP and development model endpoints may use scale-to-zero capacity; first request after an idle period can take several minutes while the endpoint warms through Nexalink-hosted APIs.
122
116
 
123
- Credentials are stored at `~/.nexalink/carecompass/credentials.json` by
124
- default. You can also set `CARECOMPASS_API_KEY` in your shell or CI environment.
125
- The generated config contains payer-facing configuration only. It does not
126
- contain the secret API key. The embed HTML and iframe are generated
127
- automatically during `init`; you do not need to run a separate snippet command
128
- for the first setup.
117
+ ## CLI Reference
129
118
 
130
- For scripted setup, pass `--account-type developer`. The developer signup route
131
- can be configured with `--developer-signup-url` or
132
- `CARECOMPASS_DEVELOPER_SIGNUP_URL`. By default, that route is
133
- `https://www.nexalink.care/developer/signup`.
119
+ ### `init`
120
+
121
+ Runs first-time setup: routes users to signup, validates the API key, stores it locally, and generates the config, prompt starter, embed page, iframe, and setup guide with only public embed configuration.
134
122
 
135
- By default, generated HTML is bundler-friendly and imports the package as
136
- `@nexalink/carecompass-sdk`, which works with Parcel, Vite, Next.js, and similar
137
- tooling when the package is installed as a dependency. For a raw browser HTML
138
- demo that is not processed by Parcel or another bundler, add
139
- `--snippet-mode cdn`.
123
+ Credentials are stored at `~/.nexalink/carecompass/credentials.json` by default. You can also set `CARECOMPASS_API_KEY`. For scripted setup, pass `--account-type developer`. Configure signup with `--developer-signup-url` or `CARECOMPASS_DEVELOPER_SIGNUP_URL`; default: `https://www.nexalink.care/developer/signup`.
124
+
125
+ Generated HTML defaults to bundler-friendly imports from `@nexalink/carecompass-sdk`. For a raw browser HTML demo that is not processed by a bundler, add `--snippet-mode cdn`.
140
126
 
141
127
  ```bash
142
128
  npx @nexalink/carecompass-sdk init --account-type developer --api-key <nexalink-api-key> --payer-id acme-health --origin https://members.acme-health.com
@@ -145,12 +131,7 @@ npx @nexalink/carecompass-sdk init --account-type developer --snippet-mode cdn -
145
131
 
146
132
  ### `validate`
147
133
 
148
- Checks that the config shape is valid and that credentials are available.
149
- By default this also calls the hosted Nexalink config-validation endpoint, which
150
- confirms the API base URL, public embed key, payer ID, environment, and allowed
151
- origins are accepted by the server. The browser-side validation request uses
152
- public embed headers; it does not send the secret API key. Use `--local-only`
153
- for schema-only checks.
134
+ Checks local config shape and credentials, then hosted validation for `apiBaseUrl`, `embedKey`, `payerId`, `environment`, and `allowedOrigins` unless `--local-only` is passed. Browser-side validation uses public embed headers and does not send the secret API key.
154
135
 
155
136
  ```bash
156
137
  npx @nexalink/carecompass-sdk validate --config carecompass/carecompass.config.json
@@ -174,14 +155,9 @@ Prints a deployment readiness summary for the selected config.
174
155
  npx @nexalink/carecompass-sdk doctor --config carecompass/carecompass.config.json
175
156
  ```
176
157
 
177
- ## Configuration
178
-
179
- `carecompass/carecompass.config.json` is safe to commit when it only contains public embed configuration. Do not add the secret API key to this file.
158
+ ## Configuration Reference
180
159
 
181
- The config is client-facing by design. It should contain the public `embedKey`,
182
- the payer ID, environment, allowed origins, branding, labels, theme, and prompt
183
- settings. Store the secret API key only in the local CLI credentials file or an
184
- approved server-side secret store.
160
+ `carecompass/carecompass.config.json` is safe to commit when it contains only public embed configuration. Store the secret API key only in local CLI credentials or an approved server-side secret store.
185
161
 
186
162
  ```json
187
163
  {
@@ -221,33 +197,9 @@ approved server-side secret store.
221
197
  }
222
198
  ```
223
199
 
224
- ## Privacy-Safe Telemetry
225
-
226
- Telemetry is enabled automatically with Nexalink-managed defaults. Integrators
227
- do not need to run an additional CLI command, add a runtime config block, or
228
- manage a PostHog token. The CLI also sends anonymous onboarding funnel events
229
- using an ephemeral per-process session ID that is never persisted.
230
-
231
- The SDK sends only allowlisted anonymous deployment-health events directly to
232
- PostHog's public ingestion API. It does not bundle `posthog-js`, enable session
233
- replay or autocapture, identify users, set cookies, or persist analytics state.
234
- Prompts, model responses, chat history, user context, PHI/PII, credentials, raw
235
- errors, and stack traces are never included. CLI arguments, terminal input, and
236
- file paths are also excluded.
237
-
238
- The SDK uses a Nexalink-owned public PostHog ingestion token. See
239
- [`TELEMETRY.md`](./TELEMETRY.md) for the shared web, React Native, and Flutter
240
- event contract.
241
-
242
- ## System Prompt File
200
+ `carecompass/system-prompt.md` defines approved context before a member message reaches the AI runtime: plan terminology, support boundaries, escalation rules, and navigation context. The CLI resolves the prompt file into `carecompass/carecompass-embed.html`; the browser receives prompt text, not a local file path. Nexalink guardrails still validate prompt content.
243
201
 
244
- `carecompass/system-prompt.md` lets the payer define approved context before a member message reaches the LLM. Use it to steer CareCompass toward plan-specific terminology, support boundaries, escalation rules, and benefit-navigation context.
245
-
246
- The prompt file is resolved by the CLI when it generates `carecompass/carecompass-embed.html`. The browser receives the resolved prompt text, not a local file path. Prompt content is still validated against Nexalink guardrails.
247
-
248
- ## Iframe Placement
249
-
250
- `carecompass/carecompass-iframe.html` contains the iframe to place on the integrating page where the CareCompass LLM should appear.
202
+ `carecompass/carecompass-iframe.html` contains the iframe to place on the integrating page:
251
203
 
252
204
  ```html
253
205
  <iframe
@@ -258,212 +210,18 @@ The prompt file is resolved by the CLI when it generates `carecompass/carecompas
258
210
  ></iframe>
259
211
  ```
260
212
 
261
- Serve `carecompass/carecompass-embed.html` from the integrating site at the iframe `src`. For many apps, that means copying the generated `carecompass` folder into the app's public/static assets folder before deployment.
262
-
263
- ## React Usage
264
-
265
- ```tsx
266
- import { CareCompassEmbed } from "@nexalink/carecompass-sdk";
267
- import config from "./carecompass/carecompass.config.json";
268
-
269
- export function MemberSupport() {
270
- return <CareCompassEmbed config={config} />;
271
- }
272
- ```
273
-
274
- ## Vanilla JavaScript Usage
275
-
276
- ```ts
277
- import { mountCareCompass } from "@nexalink/carecompass-sdk";
278
- import config from "./carecompass/carecompass.config.json";
279
-
280
- mountCareCompass(document.getElementById("carecompass-root"), config);
281
- ```
282
-
283
- ## Package Exports
284
-
285
- ```ts
286
- import {
287
- CareCompassEmbed,
288
- mountCareCompass,
289
- validateCareCompassConfig,
290
- createCareCompassClient,
291
- } from "@nexalink/carecompass-sdk";
292
-
293
- import type {
294
- CareCompassConfig,
295
- CareCompassTheme,
296
- CareCompassLabels,
297
- CareCompassPromptConfig,
298
- } from "@nexalink/carecompass-sdk";
299
- ```
300
-
301
- ## Runtime Dependencies
302
-
303
- The package has a small runtime surface:
304
-
305
- - `zod` for shared config validation
306
- - `react` as a peer dependency for the embed component
307
- - `react-dom` as a peer dependency for mounting
308
-
309
- Peer dependency range:
310
-
311
- ```json
312
- {
313
- "react": "^18.3.0 || ^19.0.0",
314
- "react-dom": "^18.3.0 || ^19.0.0"
315
- }
316
- ```
317
-
318
- The CLI requires Node.js 18 or newer.
319
-
320
- ## Development
321
-
322
- This repository uses Bun for local development.
323
-
324
- ```bash
325
- bun install
326
- bun run build
327
- bun run test
328
- bun run pack:dry-run
329
- ```
330
-
331
- Do not publish a new package version unless the SDK version is intentionally
332
- changed and release approval is complete.
333
-
334
- ## What Runs In The Browser
335
-
336
- The browser receives only public embed configuration:
337
-
338
- - customer or payer ID
339
- - environment
340
- - public `embedKey`
341
- - branding and theme values
342
- - labels and support links
343
- - approved prompt settings
344
- - Nexalink-managed telemetry defaults compiled into the SDK
345
-
346
- The browser does not receive:
347
-
348
- - the secret SDK API key
349
- - SageMaker credentials
350
- - the AppSync signing role
351
- - private model endpoint details
352
- - Nexalink server-side allowlists
353
-
354
- Chat requests are sent to Nexalink-hosted CareCompass API routes. The component does not call the model endpoint directly.
355
-
356
- ## Hosted LLM Warm-Up
357
-
358
- Nexalink hosts the proprietary CareCompass LLM runtime behind Nexalink-managed
359
- API routes. To control infrastructure costs for early deployments, Nexalink may
360
- run some hosted model endpoints with scale-to-zero capacity. When an endpoint
361
- has scaled to zero, the first chat request after an idle period can take several
362
- minutes while cloud GPU capacity is allocated and the model endpoint warms up.
363
-
364
- This warm-up delay is expected for some MVP and development environments. It
365
- does not mean the browser embed needs a secret API key, and it does not mean the
366
- SDK is calling SageMaker directly. The request is queued through Nexalink-hosted
367
- APIs while the model endpoint starts. Nexalink is actively working on
368
- improvements to reduce or avoid first-request warm-up delays.
369
-
370
- ## Runtime Security Model
371
-
372
- The SDK component uses the public browser `embedKey`, payer ID, environment, and
373
- allowed origin metadata to call Nexalink-hosted embed API routes. The secret SDK
374
- API key is used only by trusted setup and server-side/CLI workflows and must
375
- never be placed in browser config or generated snippets.
376
-
377
- For staging and production, `apiBaseUrl` must be a Nexalink-hosted HTTPS URL.
378
- `localhost` API and origin values are accepted only for `development`
379
- configurations. Hosted validation still remains authoritative: Nexalink API
380
- routes must enforce payer ID, embed key, environment, allowed origin, prompt
381
- guardrails, rate limiting, request attribution, and tenant isolation for config,
382
- analytics, logs, prompts, and model requests.
383
-
384
- Generated snippets escape serialized config before embedding it in a module
385
- script. React renders chat messages and labels as text rather than raw HTML.
386
- Do not add `dangerouslySetInnerHTML`, raw HTML snippets, unreviewed third-party
387
- scripts, or payer-provided secret values to an embed page.
388
-
389
- ## API Keys And Usage Tracking
390
-
391
- SDK API keys are issued in the Nexalink portal and stored server-side as hashes.
392
- Each secret API key is associated with a customer or payer ID, environment,
393
- public embed key, and allowed origins. The API key authenticates trusted setup
394
- and management flows; the public embed key is what the browser uses for
395
- client-facing runtime requests.
396
-
397
- CareCompass usage under a key is tracked so Nexalink can support future Stripe metered billing. The backend records prompt tokens, completion tokens, total tokens, and last-used timestamps per payer/API key. Hosted routes use MedGemma token counts when they are available and fall back to estimates only when needed.
398
-
399
- ## Staging And Production
400
-
401
- Use separate keys and config files for staging and production.
402
-
403
- ```bash
404
- npx @nexalink/carecompass-sdk validate --config carecompass.staging.json
405
- npx @nexalink/carecompass-sdk snippet --config carecompass.staging.json --output carecompass/staging-embed.html
406
- npx @nexalink/carecompass-sdk doctor --config carecompass.staging.json
407
- ```
408
-
409
- Before production, confirm:
410
-
411
- - production origin is allowlisted exactly
412
- - production `embedKey` is separate from staging
413
- - production `apiBaseUrl` points at the approved Nexalink-hosted environment
414
- - support links route to the payer's approved support surface
415
- - prompt instructions are approved by Nexalink and the payer
416
- - no secret API key appears in generated source code
417
- - diagnostics, logs, and analytics are configured to avoid raw PHI/PII, raw
418
- prompts, raw model responses, credentials, or privileged backend tokens unless
419
- Nexalink has approved a secure diagnostic path
213
+ Serve `carecompass/carecompass-embed.html` at the iframe `src`, often by copying the generated `carecompass` folder into public/static assets.
420
214
 
421
215
  ## Troubleshooting
422
216
 
423
- `Missing Nexalink API key`
424
-
425
- Run `npx @nexalink/carecompass-sdk init`, choose Developer, and sign in with an
426
- API key. For non-interactive setup, pass `--account-type developer` with
427
- `--api-key <key>`, or set `CARECOMPASS_API_KEY` with
428
- `CARECOMPASS_ACCOUNT_TYPE=developer`.
429
-
430
- `zsh: command not found: carecompass`
431
-
432
- You ran the SDK with `npx`, which does not install a permanent global command.
433
- Run the next command with `npx @nexalink/carecompass-sdk <command>`, install the
434
- package in your project, or install it globally.
435
-
436
- `@parcel/core: Failed to resolve 'https://esm.sh/...'`
437
-
438
- Regenerate the snippet with the default bundler mode instead of CDN mode:
439
- `npx @nexalink/carecompass-sdk snippet --config carecompass/carecompass.config.json`.
440
- Parcel does not allow `https:` imports in HTML. CDN mode is only for raw browser
441
- HTML that is not bundled.
442
-
443
- `CareCompass could not reach http://localhost:3000`
444
-
445
- The browser cannot reach the configured API base URL. If the embed is running in
446
- a hosted sandbox, `localhost` points at the sandbox/browser environment, not the
447
- Nexalink server on your machine. Run the Nexalink web app locally and test from
448
- a local page, or point `apiBaseUrl` at a deployed Nexalink environment that has
449
- the CareCompass embed API routes deployed. Run `validate` to check this before
450
- typing into the embed.
451
-
452
- `Origin is not authorized`
453
-
454
- Add the exact website origin to the Nexalink portal SDK configuration.
455
-
456
- `Prompt configuration violates CareCompass guardrails`
457
-
458
- Remove unsafe or unsupported instructions and re-run validation.
459
-
460
- `CareCompass embed client is not authorized`
461
-
462
- Confirm `payerId`, `embedKey`, `environment`, and allowed origins match the key issued in the Nexalink portal.
463
-
464
- `CareCompass AppSync inference service is not configured`
465
-
466
- Nexalink server operators should confirm the hosted web environment has `NEXT_PUBLIC_API_URL` or `CARECOMPASS_APPSYNC_URL` configured. The SDK browser embed does not require a payer-provided LLM URL.
217
+ - `Missing Nexalink API key`: run `init`, choose Developer, and sign in. For scripts, pass `--account-type developer` with `--api-key <key>`, or set `CARECOMPASS_API_KEY` with `CARECOMPASS_ACCOUNT_TYPE=developer`.
218
+ - `zsh: command not found: carecompass`: `npx` does not install a permanent command. Run `npx @nexalink/carecompass-sdk <command>` or install the package.
219
+ - `@parcel/core: Failed to resolve 'https://esm.sh/...'`: regenerate with bundler mode: `npx @nexalink/carecompass-sdk snippet --config carecompass/carecompass.config.json`. CDN mode is for raw browser HTML.
220
+ - `CareCompass could not reach http://localhost:3000`: hosted sandboxes cannot reach your machine's `localhost`. Test locally or use a deployed Nexalink `apiBaseUrl`. Run `validate` before typing into the embed.
221
+ - `Origin is not authorized`: add the exact website origin to the Nexalink portal SDK configuration.
222
+ - `Prompt configuration violates CareCompass guardrails`: remove unsafe or unsupported instructions and re-run validation.
223
+ - `CareCompass embed client is not authorized`: confirm `payerId`, `embedKey`, `environment`, and allowed origins match the key issued in the Nexalink portal.
224
+ - `CareCompass AppSync inference service is not configured`: Nexalink server operators should confirm `NEXT_PUBLIC_API_URL` or `CARECOMPASS_APPSYNC_URL`. The embed does not require a payer-provided LLM URL.
467
225
 
468
226
  ## License
469
227
 
package/dist/version.js CHANGED
@@ -1,3 +1,3 @@
1
- export const CARECOMPASS_SDK_VERSION = "0.2.0-beta.12"; // x-release-please-version
1
+ export const CARECOMPASS_SDK_VERSION = "0.2.0-beta.13"; // x-release-please-version
2
2
  export const CARECOMPASS_COMPONENT_VERSION = "1.0.0";
3
3
  export const CARECOMPASS_TELEMETRY_CONTRACT_VERSION = "1.0.0";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nexalink/carecompass-sdk",
3
- "version": "0.2.0-beta.12",
3
+ "version": "0.2.0-beta.14",
4
4
  "description": "Embeddable CareCompass SDK and CLI for healthcare ecosystem integrations with Nexalink onboarding, BAA coverage, and API keys.",
5
5
  "type": "module",
6
6
  "packageManager": "bun@1.3.9",
@@ -40,10 +40,7 @@
40
40
  "dist/**/*.js",
41
41
  "dist/**/*.d.ts",
42
42
  "README.md",
43
- "TELEMETRY.md",
44
- "LICENSE",
45
- "SECURITY_AUDIT.md",
46
- "RUNTIME_SECURITY_AUDIT.md"
43
+ "LICENSE"
47
44
  ],
48
45
  "engines": {
49
46
  "node": ">=18"
@@ -1,180 +0,0 @@
1
- # CARE-153 Runtime, API, And Tenant-Isolation Audit
2
-
3
- Audit date: 2026-05-30
4
-
5
- Scope: SDK-side runtime, embed, CLI validation, generated snippets, browser configuration, prompt configuration, sensitive-data handling, and documentation for payer deployments. Hosted Nexalink API route implementations, backend rate limiting, backend CORS enforcement, backend logs, analytics stores, and SageMaker/AppSync infrastructure are outside this repository and must be validated in the hosted API codebase.
6
-
7
- ## Summary
8
-
9
- The SDK does not ship private SageMaker credentials, AppSync signing roles, privileged backend tokens, or secret Nexalink SDK API keys to the browser. Browser requests use public payer configuration and public embed headers; backend hosted routes remain the authoritative enforcement point for payer identity, embed-key authorization, allowed origins, rate limits, prompt guardrails, logs, analytics, and tenant isolation.
10
-
11
- This audit found and remediated two SDK-side runtime issues:
12
-
13
- - Staging and production configs could previously point `apiBaseUrl` at any HTTPS origin. The schema now requires a Nexalink-hosted HTTPS API URL for staging and production, with localhost allowed only for development.
14
- - Generated embed snippets previously serialized config with plain `JSON.stringify` inside a module script. Config values containing `</script>` could break the script context when served as raw HTML. Snippet generation now escapes script-sensitive JSON characters and iframe attributes.
15
-
16
- ## Auth And API Access Model
17
-
18
- - CLI commands use the secret Nexalink SDK API key from `--api-key`, `CARECOMPASS_API_KEY`, or the local credentials file.
19
- - `init` uses that API key to check BAA status and submit execution metadata to Nexalink-hosted routes. The CLI never receives AWS credentials.
20
- - Browser/runtime code never receives the secret SDK API key.
21
- - Browser requests include:
22
- - `x-carecompass-payer-id`
23
- - `x-carecompass-embed-key`
24
- - `x-carecompass-environment`
25
- - Browser requests target only these SDK paths under the configured Nexalink-hosted API base URL:
26
- - `POST /api/carecompass/embed/config/validate`
27
- - `POST /api/carecompass/embed/ask`
28
- - `GET /api/carecompass/embed/status/:jobId`
29
-
30
- Backend requirements that must remain enforced outside this SDK:
31
-
32
- - payer ID and embed key binding
33
- - environment binding
34
- - exact allowed-origin checks
35
- - tenant isolation for configuration, prompts, requests, responses, logs, analytics, and usage records
36
- - rate limiting and request attribution by payer/deployment
37
-
38
- ## Tenant Isolation Review
39
-
40
- SDK-side controls:
41
-
42
- - The config schema validates payer ID format, embed key format, deployment environment, allowed origins, API base URL, prompt structure, theme values, and public branding fields.
43
- - Staging and production cannot use localhost API base URLs or localhost allowed origins.
44
- - The client sends payer ID, embed key, and environment on every config-validation and inference request.
45
- - The SDK does not expose APIs for reading another payer's configuration, analytics, logs, prompt history, or user data.
46
-
47
- Backend-owned validation:
48
-
49
- - The SDK cannot prove cross-payer isolation by itself because tenant state lives in hosted Nexalink services.
50
- - Hosted routes must reject mismatched payer ID, embed key, environment, and origin tuples.
51
- - Hosted routes must scope job status lookups by payer/deployment, not only by `jobId`.
52
-
53
- ## Allowed Origin And API Base URL Controls
54
-
55
- Resolved in this branch:
56
-
57
- - `apiBaseUrl` must be a Nexalink-hosted HTTPS URL, except localhost for development.
58
- - Staging and production configs reject localhost `apiBaseUrl`.
59
- - Staging and production configs reject localhost allowed origins.
60
- - Browser-hosted pages still fail fast if a non-local page tries to call a localhost API base URL.
61
-
62
- Follow-up for hosted API:
63
-
64
- - Test unauthorized origins against deployed staging and production routes.
65
- - Confirm CORS and origin checks happen server-side and are not based only on SDK validation.
66
-
67
- ## Client-Side Token And Secret Handling
68
-
69
- No client-side secret exposure was found.
70
-
71
- - Secret SDK API keys are read by the CLI only.
72
- - The browser receives public `embedKey`, payer ID, environment, branding, labels, allowed origins, and prompt configuration.
73
- - Credential storage writes local keys with file mode `0600`.
74
- - CLI output prints the credentials path and source, not the API key value.
75
- - Executed BAA copies contain agreement metadata and terms, not the SDK API key
76
- or private cloud credentials. The CLI writes local executed copies with
77
- owner-only (`0600`) permissions.
78
-
79
- ## Prompt Controls And Sensitive Data Handling
80
-
81
- SDK-side controls:
82
-
83
- - Prompt instructions are length-limited and checked for explicit guardrail-bypass patterns.
84
- - Generated setup guidance warns against secrets, raw PHI, diagnosis instructions, treatment instructions, and guardrail bypass attempts in prompt files.
85
- - `allowUserContext` defaults to `false`.
86
-
87
- Backend-owned validation:
88
-
89
- - Hosted routes must re-validate prompt configuration against Nexalink policy because browser config is attacker-controlled.
90
- - Hosted routes must treat user messages, prompt content, model responses, and optional user context as sensitive data.
91
-
92
- ## Embed, XSS, And CSP Review
93
-
94
- Resolved in this branch:
95
-
96
- - Generated config JSON is escaped before insertion into `<script type="module">`.
97
- - Generated iframe `title` and `src` attributes are HTML-attribute escaped.
98
-
99
- Existing controls:
100
-
101
- - React renders labels and messages as text, not raw HTML.
102
- - The component does not use `dangerouslySetInnerHTML`, `innerHTML`, `eval`, or `new Function`.
103
-
104
- Integration guidance:
105
-
106
- - Prefer bundler mode over CDN mode for production.
107
- - If CDN mode is used for a raw browser demo, the integrating page should set CSP `script-src` for the approved CDN and Nexalink assets only.
108
- - Do not place unreviewed payer-provided HTML or third-party scripts in generated embed pages.
109
-
110
- ## Logging, Diagnostics, Telemetry, And Errors
111
-
112
- CARE-158 adds an always-on privacy-safe telemetry transport documented in
113
- `TELEMETRY.md`. The SDK sends only allowlisted anonymous lifecycle metadata to
114
- PostHog's public ingestion API using a Nexalink-owned public ingestion token.
115
- Integrators do not configure telemetry or receive a disable switch. The SDK
116
- does not bundle `posthog-js`, enable session replay or autocapture, identify
117
- users, set cookies, or persist analytics state.
118
-
119
- The CLI sends fixed onboarding funnel events through the same transport. Each
120
- CLI process uses an ephemeral random session ID that is not persisted. CLI
121
- payloads exclude arguments, terminal input, file paths, API keys, and BAA signer
122
- details.
123
-
124
- Telemetry payloads exclude prompts, model responses, chat history, optional
125
- user context, PHI/PII, credentials, raw errors, stack traces, request payloads,
126
- and response bodies. Error telemetry uses fixed codes and categories. Telemetry
127
- delivery failures are swallowed so analytics cannot interrupt SDK workflows.
128
- Runtime errors shown in the component remain derived from local network
129
- failures or backend error responses.
130
-
131
- Backend-owned controls:
132
-
133
- - Hosted routes must avoid logging raw PHI/PII, credentials, raw prompts, raw model responses, or privileged backend tokens unless an explicitly approved secure diagnostic path exists.
134
- - Backend error responses should be sanitized because the component may display the error message.
135
-
136
- ## Rate Limiting And Abuse Prevention
137
-
138
- The SDK can attribute requests by payer ID, embed key, and environment headers, but cannot enforce real rate limits or abuse controls because browser clients are untrusted.
139
-
140
- Hosted routes must enforce:
141
-
142
- - per-payer and per-origin rate limits
143
- - per-embed-key request attribution
144
- - abuse detection for prompt flooding and job-status polling
145
- - safe status lookup scoping by payer/deployment
146
-
147
- ## Verification
148
-
149
- Commands run:
150
-
151
- | Command | Result |
152
- | ----------------------- | ------------------------------------------------------------------------------------------- |
153
- | `bun run test` | Validates schema hardening, snippet escaping, CLI behavior, and component runtime requests. |
154
- | `bun run lint` | Ensures code quality after remediation. |
155
- | `bun run build` | Regenerates distributable JavaScript and declarations. |
156
- | `bun run release:check` | Runs frozen install, lint, tests, build, audit, and package dry run. |
157
-
158
- New regression coverage:
159
-
160
- - Reject non-Nexalink `apiBaseUrl` values.
161
- - Allow localhost API/origin/support URLs only for development.
162
- - Reject unsafe branding URL schemes.
163
- - Escape `</script>`-style values in generated embed config JSON.
164
- - Escape iframe attributes.
165
-
166
- ## Findings And Follow-Up
167
-
168
- Resolved:
169
-
170
- - Medium: staging/production `apiBaseUrl` allowed arbitrary HTTPS endpoints. Owner: SDK. Remediation: require Nexalink-hosted HTTPS API URLs outside development.
171
- - Medium: generated script snippets did not escape script-sensitive JSON characters. Owner: SDK. Remediation: escape `<`, `>`, `&`, U+2028, and U+2029 in serialized config JSON.
172
-
173
- No high or critical SDK-side runtime findings remain in this repository.
174
-
175
- Follow-up required outside this SDK repository:
176
-
177
- - Validate deployed hosted API CORS/origin enforcement with unauthorized origins.
178
- - Validate cross-payer tenant isolation for config, prompt, analytics, logs, job status, and model request data in the hosted API codebase.
179
- - Validate backend log/telemetry redaction for raw prompts, model responses, credentials, PHI/PII, and privileged tokens.
180
- - Validate backend rate limiting and request attribution by payer, environment, origin, and embed key.
package/SECURITY_AUDIT.md DELETED
@@ -1,78 +0,0 @@
1
- # CARE-152 Dependency And Supply-Chain Audit
2
-
3
- Audit date: 2026-05-30
4
-
5
- Scope: `@nexalink/carecompass-sdk` source, package metadata, Bun lockfile, generated `dist` artifacts, README guidance, local package assembly, and release-process documentation.
6
-
7
- ## Summary
8
-
9
- No high or critical dependency vulnerabilities were found by the available package-manager audit. No hardcoded Nexalink API key, payer credential, SageMaker credential, AppSync signing role, private model endpoint, AWS access key, or private endpoint URL was found in the package source or generated distributable files.
10
-
11
- The audit found supply-chain process gaps rather than an active secret exposure: release provenance and SBOM expectations were not previously documented, the package manager was not pinned in `package.json`, and the package dry-run script delegated to `bunx --bun npm pack`. These have been remediated in this branch with pinned package-manager metadata, a safer dry-run pack script, explicit release documentation, and exclusion of source maps from the published package surface.
12
-
13
- ## Commands Run
14
-
15
- | Command | Result |
16
- | ---------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- |
17
- | `bun audit` | Passed. No vulnerabilities found. |
18
- | `npm audit --audit-level=high` | Not applicable because this repository uses `bun.lock` and has no `package-lock.json`. |
19
- | `bun outdated` | Runtime dependency `zod` current. Dev-tooling major updates available for `@eslint/js`, `eslint`, `@types/node`, `globals`, and `typescript`. |
20
- | `bun run build` | Passed after refreshing local Bun install links. |
21
- | `bun run lint` | Passed. |
22
- | `bun run test` | Passed: 3 suites, 17 tests. |
23
- | `bun pm pack --dry-run --ignore-scripts` | Passed and confirmed the intended package contents. |
24
-
25
- ## Dependency Review
26
-
27
- Runtime dependency:
28
-
29
- - `zod` `^4.4.3`
30
-
31
- Peer dependencies:
32
-
33
- - `react` `^18.3.0 || ^19.0.0`
34
- - `react-dom` `^18.3.0 || ^19.0.0`
35
-
36
- Development dependencies are limited to the React, Jest, ESLint, Prettier, TypeScript, and type-definition toolchain. The dependencies are mainstream packages, and the runtime package surface is small.
37
-
38
- `bun.lock` pins concrete transitive versions and integrity hashes for Bun installs. Non-Bun package managers are supported for consumers, but repository development and release validation are intentionally pinned to Bun with `bun install --frozen-lockfile`.
39
-
40
- ## Package Script Review
41
-
42
- No `preinstall`, `install`, `postinstall`, `prepare`, `prepublish`, `publish`, or `postpublish` lifecycle scripts are declared by the root package.
43
-
44
- Package assembly now uses:
45
-
46
- ```bash
47
- bun pm pack --dry-run --ignore-scripts
48
- ```
49
-
50
- This avoids fetching or executing an external pack command through `bunx` and prevents lifecycle scripts during the dry run.
51
-
52
- ## Generated Artifact Review
53
-
54
- The package publishes only `dist/**/*.js`, `dist/**/*.d.ts`, `README.md`, `LICENSE`, `RELEASE.md`, `SECURITY_AUDIT.md`, `RUNTIME_SECURITY_AUDIT.md`, and `package.json`.
55
-
56
- Source maps were removed from the published package surface. They did not contain embedded `sourcesContent`, but excluding them reduces accidental source-path and metadata disclosure in the public npm package.
57
-
58
- Searches for secret-like terms found only documented placeholders, public configuration examples, local credential handling code, and expected hosted API URLs. Credential writes use file mode `0600`, and CLI output does not print the secret API key.
59
-
60
- ## Release-Process Risks And Remediation
61
-
62
- Resolved in this branch:
63
-
64
- - Added `packageManager` to pin Bun for development and release validation.
65
- - Added repository and issue metadata to `package.json`.
66
- - Added npm registry to `publishConfig`.
67
- - Added `audit` and `release:check` scripts.
68
- - Replaced `pack:dry-run` with a Bun-native dry run that ignores scripts.
69
- - Added `RELEASE.md` with versioning, validation, provenance, SBOM, and secret-handling expectations.
70
- - Excluded source maps from the package surface.
71
-
72
- Follow-up recommendations:
73
-
74
- - Add CI that runs `bun install --frozen-lockfile`, `bun run release:check`, and stores audit and package dry-run output as artifacts.
75
- - Publish through npm trusted publishing or `npm publish --provenance --access public`.
76
- - Generate and retain an SBOM for each production release.
77
- - Review major dev-tooling updates reported by `bun outdated` on a maintenance cadence.
78
- - Keep runtime dependency additions rare and require security review for any package with install lifecycle scripts or native binary behavior.
package/TELEMETRY.md DELETED
@@ -1,129 +0,0 @@
1
- # CareCompass SDK Telemetry Contract
2
-
3
- Contract version: `1.0.0`
4
-
5
- CareCompass SDK telemetry measures deployment health without collecting PHI,
6
- PII, chat content, or credentials. The web SDK sends allowlisted anonymous
7
- events directly to PostHog's public ingestion API. The CLI uses the same narrow
8
- transport for onboarding funnel events. React Native and Flutter SDKs should
9
- adopt the same event names and property contract.
10
-
11
- ## Configuration
12
-
13
- Telemetry is enabled automatically for every web SDK deployment. Integrators do
14
- not need to run an additional CLI command, add a runtime config block, or manage
15
- a PostHog token.
16
-
17
- The web SDK sends events to Nexalink's PostHog project through the public US
18
- ingestion endpoint. It uses a Nexalink-owned public PostHog project token
19
- compiled into the SDK. The token permits event ingestion only; it is never a
20
- PostHog personal or admin API key.
21
-
22
- The anonymous deployment ID is derived from the public payer ID, environment,
23
- and web platform. For example, payer `acme-health` in staging is reported as
24
- `acme-health-staging-web`.
25
-
26
- CLI invocations use an ephemeral random `cli_session_id` as their anonymous
27
- PostHog `distinct_id`. It is created in memory for one process invocation and is
28
- not persisted. Before the CLI has public payer context, events use
29
- `anonymous-unknown-cli`; later events use the public payer ID and environment.
30
-
31
- ## Event Taxonomy
32
-
33
- Initialization and configuration:
34
-
35
- - `carecompass_sdk_initialized`
36
- - `carecompass_sdk_initialization_failed`
37
- - `carecompass_sdk_configuration_validated`
38
- - `carecompass_sdk_configuration_failed`
39
-
40
- Component lifecycle:
41
-
42
- - `carecompass_component_rendered`
43
- - `carecompass_component_opened`
44
- - `carecompass_component_closed`
45
- - `carecompass_component_error`
46
-
47
- Inference lifecycle:
48
-
49
- - `carecompass_prompt_submitted`
50
- - `carecompass_inference_succeeded`
51
- - `carecompass_inference_failed`
52
- - `carecompass_inference_rate_limited`
53
-
54
- Customization and deployment health:
55
-
56
- - `carecompass_theme_loaded`
57
- - `carecompass_prompt_configuration_loaded`
58
- - `carecompass_prompt_configuration_failed`
59
-
60
- CLI onboarding:
61
-
62
- - `carecompass_cli_started`
63
- - `carecompass_cli_login_started`
64
- - `carecompass_cli_login_succeeded`
65
- - `carecompass_cli_login_failed`
66
- - `carecompass_cli_init_started`
67
- - `carecompass_cli_init_failed`
68
- - `carecompass_cli_setup_kit_generated`
69
- - `carecompass_cli_validation_succeeded`
70
- - `carecompass_cli_validation_failed`
71
- - `carecompass_cli_snippet_generated`
72
- - `carecompass_cli_doctor_completed`
73
- - `carecompass_cli_command_failed`
74
-
75
- For the always-visible web embed, opened and closed map to mount and unmount.
76
- Future mobile components should map these events to their equivalent visible
77
- screen lifecycle.
78
-
79
- ## Allowed Properties
80
-
81
- Events contain only:
82
-
83
- - `contract_version`
84
- - `sdk_version`
85
- - `component_version`
86
- - `platform`
87
- - `environment`
88
- - `payer_id`
89
- - `deployment_id`
90
- - `event_timestamp`
91
- - `duration_bucket`, when applicable
92
- - `failure_category`, when applicable
93
- - `error_code`, when applicable
94
- - `cli_session_id`, for CLI events only
95
- - `$process_person_profile: false`
96
-
97
- The transport also sends the public PostHog project token, event name, anonymous
98
- `distinct_id`, and timestamp required by the PostHog ingestion API. Web events
99
- use the deployment ID as `distinct_id`; CLI events use the ephemeral
100
- `cli_session_id`. It does not identify individual users or create person
101
- profiles.
102
-
103
- ## Prohibited Data
104
-
105
- Never send:
106
-
107
- - raw user prompts, model responses, chat history, or optional user context
108
- - PHI, PII, member IDs, policy IDs, names, emails, or phone numbers
109
- - API keys, access tokens, cookies, credentials, or session secrets
110
- - CLI arguments, terminal input, or file paths
111
- - SageMaker credentials, internal infrastructure details, or privileged tokens
112
- - raw error objects, stack traces, request payloads, or response bodies
113
- - payer prompt text; use an approved non-sensitive configuration ID in a future
114
- contract version if needed
115
-
116
- The web SDK intentionally does not bundle `posthog-js`. It does not enable
117
- session replay, autocapture, DOM capture, form capture, cookies, persistence,
118
- surveys, feature flags, or user identification.
119
-
120
- Package download counts remain registry-owned metrics. CLI telemetry begins when
121
- the user invokes the installed package.
122
-
123
- ## Verification
124
-
125
- 1. Mount a development component, submit a non-PHI prompt, and complete an
126
- inference.
127
- 2. Confirm the expected lifecycle events arrive in Nexalink's PostHog project.
128
- 3. Inspect event payloads and verify they contain only the allowlisted
129
- properties above.