@datarails-ai/dr-cli 0.0.1-locked → 1.6.71

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.
Files changed (58) hide show
  1. package/README.md +608 -0
  2. package/dist/chunk-DWMCBGQH.js +242 -0
  3. package/dist/cli.js +64468 -0
  4. package/dist/kb-6UWI7Q32.js +21 -0
  5. package/dist/scopes-map.json +4412 -0
  6. package/dist/skills/connector-sandbox/SKILL.md +95 -0
  7. package/dist/skills/datarails-connect-workato/SKILL.md +140 -0
  8. package/dist/skills/datarails-connectors-onboard-connector/SKILL.md +813 -0
  9. package/dist/skills/dr-cli/SKILL.md +659 -0
  10. package/dist/skills/dr-cli/reference/admin.md +796 -0
  11. package/dist/skills/dr-cli/reference/budget-builder.md +151 -0
  12. package/dist/skills/dr-cli/reference/calc-vals.md +73 -0
  13. package/dist/skills/dr-cli/reference/calcmodels.md +76 -0
  14. package/dist/skills/dr-cli/reference/cash.md +61 -0
  15. package/dist/skills/dr-cli/reference/dashboards-widgets.md +85 -0
  16. package/dist/skills/dr-cli/reference/datamappers.md +150 -0
  17. package/dist/skills/dr-cli/reference/desk.md +472 -0
  18. package/dist/skills/dr-cli/reference/filebox-documents.md +373 -0
  19. package/dist/skills/dr-cli/reference/forecast.md +51 -0
  20. package/dist/skills/dr-cli/reference/integrations.md +57 -0
  21. package/dist/skills/dr-cli/reference/lookups.md +168 -0
  22. package/dist/skills/dr-cli/reference/metrics.md +512 -0
  23. package/dist/skills/dr-cli/reference/multi-product.md +180 -0
  24. package/dist/skills/dr-cli/reference/reconciliation-mec.md +76 -0
  25. package/dist/skills/dr-cli/reference/rh-config.md +84 -0
  26. package/dist/skills/dr-cli/reference/safety.md +143 -0
  27. package/dist/skills/dr-cli/reference/spend-control.md +206 -0
  28. package/dist/skills/dr-cli/reference/templates.md +163 -0
  29. package/dist/skills/dr-cli/reference/workflows.md +137 -0
  30. package/dist/skills/dr-error-enrichment/SKILL.md +80 -0
  31. package/dist/skills/dr-error-enrichment/reference/core.md +257 -0
  32. package/dist/skills/dr-error-enrichment/reference/groundcover.md +84 -0
  33. package/dist/skills/dr-error-enrichment/reference/jira-bugs.md +219 -0
  34. package/dist/skills/dr-error-enrichment/reference/safety-backup.md +122 -0
  35. package/dist/skills/dr-error-enrichment-author/SKILL.md +219 -0
  36. package/dist/skills/dr-error-enrichment-improve/SKILL.md +218 -0
  37. package/dist/skills/dr-error-enrichment-maintain/SKILL.md +237 -0
  38. package/dist/skills/dr-error-enrichment-reconcile/SKILL.md +167 -0
  39. package/dist/skills/dr-filebox-api-setup/SKILL.md +170 -0
  40. package/dist/skills/dr-switch-user/SKILL.md +395 -0
  41. package/dist/skills/dr-validate/SKILL.md +392 -0
  42. package/dist/skills/dr-validate/report-template.html +950 -0
  43. package/dist/skills/fx-conversion-matrix/SKILL.md +763 -0
  44. package/dist/skills/fx-conversion-matrix/scripts/_args.mjs +52 -0
  45. package/dist/skills/fx-conversion-matrix/scripts/_xlsx.mjs +241 -0
  46. package/dist/skills/fx-conversion-matrix/scripts/build-matrix.mjs +366 -0
  47. package/dist/skills/fx-conversion-matrix/scripts/gen-mappers.mjs +171 -0
  48. package/dist/skills/fx-conversion-matrix/scripts/rates-to-xlsx.mjs +172 -0
  49. package/dist/skills/fx-onboard/SKILL.md +325 -0
  50. package/dist/skills/mec-table-validation/SKILL.md +383 -0
  51. package/dist/skills/plugins.json +24 -0
  52. package/dist/skills/validate-workato-migration/SKILL.md +167 -0
  53. package/dist/skills/validate-workato-migration/reference/gotchas.md +16 -0
  54. package/dist/skills/validate-workato-migration/reference/staging-orgs.md +26 -0
  55. package/dist/skills/validate-workato-migration/scripts/compare_files.py +255 -0
  56. package/dist/zendeskKb-JPSHVOPH.js +243 -0
  57. package/package.json +56 -9
  58. package/scripts/postinstall.mjs +91 -0
@@ -0,0 +1,392 @@
1
+ ---
2
+ name: dr-validate
3
+ description: Validate a Datarails-generated financial report against a customer's own P&L or Balance Sheet mid-onboarding. Drives the `dr validate onboarding` command group (part of the dr-cli binary) to create a session, upload the source files, run reconcile + investigation on the per-env onboarding-validation service, and return a CSM-actionable report of resolved and unresolved discrepancies. The customer's own report is the only file the operator supplies; the Datarails report, Chart of Accounts, GL/transactions, and (for a Balance Sheet) the trial balance are pulled from the client's Datarails environment via dr-cli. Triggers - "validate the mapping for client X", "reconcile the customer's P&L against our Datarails export", "check the discrepancies between the client's numbers and ours", "why don't the customer's numbers match ours", "audit the onboarding mapping before we hand it back", "/dr-validate".
4
+ ---
5
+
6
+ # dr-validate — Datarails onboarding reconciliation harness
7
+
8
+ ## When Claude should invoke this skill
9
+
10
+ Use any time a CSM (or engineer) needs to validate a client's Datarails
11
+ mapping mid-onboarding — i.e. to explain why the customer's own numbers
12
+ don't match the Datarails-generated report. Concrete triggers:
13
+
14
+ - "validate the mapping for client X"
15
+ - "reconcile the customer's P&L against our Datarails export"
16
+ - "the customer's numbers don't match ours — why?"
17
+ - "audit this onboarding before we hand it back"
18
+ - "/dr-validate" or any direct invocation
19
+
20
+ ## Not the same as `dr reconciliation`
21
+
22
+ This skill is **onboarding-mapping validation** via `dr validate
23
+ onboarding …`. It is a different service and a different lifecycle from
24
+ the MEC month-end-close group `dr reconciliation` (alias `dr recon`):
25
+
26
+ - **`dr validate onboarding`** (this skill) — validates a client's own
27
+ report against the Datarails export *before* hand-off, against the
28
+ per-env onboarding-validation service.
29
+ - **`dr reconciliation`** — inspects/operates a live financial-close
30
+ (MEC) tenant. Unrelated. Don't reach for it here, and don't route
31
+ onboarding validation through it.
32
+
33
+ ## How the files work (read this first)
34
+
35
+ Two things about this service drive everything below:
36
+
37
+ 1. **You hand off files; the service classifies them.** There is no
38
+ per-file "role" flag. Upload every relevant workbook with a repeated
39
+ `--file`, and the service auto-detects each one's role (client
40
+ report, Datarails report, Chart of Accounts, GL/transactions, trial
41
+ balance, ...). Don't try to label files — just get the right ones in.
42
+
43
+ 2. **Only the customer's own report comes from the operator.** During
44
+ onboarding, the client's data already lives in their Datarails
45
+ environment, so the **Datarails report, Chart of Accounts,
46
+ GL/transactions, and trial balance are fetched via dr-cli** (fileboxes
47
+ / file download — see the dr-cli skill for the exact commands) and
48
+ then uploaded. The one artifact Datarails does *not* have is the
49
+ **customer's own P&L/Balance Sheet export** — the "truth" they
50
+ produced outside Datarails. That is the only file you ask the operator
51
+ for. If it isn't already in the conversation, ask for it as a local
52
+ path (or an attachment you can save locally). Don't ask the operator
53
+ for the locations of the Datarails-side files.
54
+
55
+ 3. **Validate on the client's own env — one login.** The
56
+ onboarding-validation service is deployed per-env, and the CLI derives
57
+ each env's host from the server registry. **You do not need to know
58
+ which envs are supported** — pass the client's env as the single
59
+ `--server` for *everything* and the CLI targets the right host: one
60
+ `dr login` for that env, then the same `--server <ENV>` on every
61
+ command. Keeping the client's data on the client's own env is the right
62
+ default for real financials (data residency).
63
+
64
+ **Fallback — an env with no onboarding instance.** Not every registry
65
+ env has one deployed (mostly internal test envs); where it isn't, the
66
+ command simply fails to reach the host. The service never
67
+ queries the client tenant — it sees only the files you hand it — so you
68
+ *can* validate by pointing the validate commands at a working instance
69
+ while fetching the files from the client env.
70
+
71
+ It is **not** stateless, though: it creates a server-side session and
72
+ stores your uploaded files against it, so this path physically copies
73
+ the client's financials onto the validation env. They persist there
74
+ until the session goes away — sessions TTL after ~24h and a server
75
+ restart can drop them, but don't rely on either as cleanup: run
76
+ `dr validate onboarding session delete <id>` when you are done. Use
77
+ this path only for testing or non-sensitive data unless that env's
78
+ isolation and retention have been verified.
79
+
80
+ It also needs a second `dr login`, and **that login is the point** —
81
+ pass the *validation* env as `--server`, not the client's. The JWT
82
+ follows `--server`, so validating on one env while still passing the
83
+ client's key would hand that client's live production token to the
84
+ other env's pod.
85
+
86
+ ## Required inputs (gather before running)
87
+
88
+ Which files you want depends on the report type. Core files materially
89
+ determine the result; the recommended ones aren't hard-required but
90
+ substantially improve the investigation.
91
+
92
+ | Report type | Core files | Strongly recommended |
93
+ |---|---|---|
94
+ | **P&L** | Customer's own P&L · Datarails P&L · Chart of Accounts | GL / transactions |
95
+ | **Balance Sheet** | Customer's own Balance Sheet · Datarails Balance Sheet · Chart of Accounts | Trial Balance (drives opening-balance checks) · GL / transactions |
96
+
97
+ - **Customer's own report** → from the operator (the only operator-supplied file).
98
+ - **Everything else** → fetch from the client's Datarails environment via dr-cli.
99
+ - **Accepted formats:** `.xlsx`, `.xlsm`, `.xls`, `.xlsb`, `.csv`.
100
+
101
+ Two more parameters, both of which Claude should resolve on its own —
102
+ don't interrogate the operator:
103
+
104
+ - **Report type** (`P&L` or `BS`): infer it from the request. "Reconcile
105
+ the P&L" → `P&L`; "check the balance sheet" → `BS`. Only ask if the
106
+ request is genuinely ambiguous.
107
+ - **Period**: optional — do **not** ask for it. The reconciliation agent
108
+ infers the period from the files. Pass `--period` only if the operator
109
+ already stated one.
110
+
111
+ ## Prerequisites
112
+
113
+ - `dr` (the Datarails CLI) installed. This skill ships inside dr-cli and
114
+ is auto-installed with it — no separate install step.
115
+ - `dr login` run once for the env you'll use — the CLI reads the JWT from
116
+ the OS keychain. Normally that's **one** login: the client's own env
117
+ both fetches the Datarails files and validates.
118
+ Only the fallback — for an env with no onboarding instance — needs a
119
+ second login (the validation env). If a server isn't logged in, the
120
+ command errors and suggests `dr login --server <S>`.
121
+ - **`--server` selects both the onboarding host and the identity.** On the
122
+ `dr validate onboarding` commands, `--server <ENV>` targets that env's
123
+ onboarding host using that env's JWT. The host is derived from the
124
+ server registry, so **every registry env is supported and there is no
125
+ list to check** — just pass the env you want. Never hand-build the host
126
+ yourself; the subdomain is not always the lowercased key, and the CLI
127
+ already knows the difference. Only a custom `--server` URL can't be
128
+ derived — use the override below for those.
129
+ - **`DR_VALIDATE_ONBOARDING_HOST` overrides the host only** — you still
130
+ pass a real, logged-in `--server`, which keeps supplying the identity.
131
+ It takes a **literal, absolute URL including the scheme** — e.g.
132
+ `DR_VALIDATE_ONBOARDING_HOST=http://localhost:8000` for a local
133
+ instance. A bare hostname builds an invalid request URL. Point it at a
134
+ local/CI instance, a custom `--server` URL's pod, or an instance that
135
+ isn't in the registry yet.
136
+
137
+ You rarely need this for a normal env — derivation already handles those.
138
+ Don't hand-build a URL by substituting a key into a template: the
139
+ subdomain isn't always the key, and an env with no instance has nothing
140
+ to point at either way. Confirm a candidate first:
141
+ `curl -sf "$DR_VALIDATE_ONBOARDING_HOST/openapi.json" | head -c 80`.
142
+
143
+ **Match `--server` to the host you override to.** The override moves the
144
+ data URL only; the JWT still comes from `--server`. Pointing the override
145
+ at another env's pod while leaving `--server` on the client's env
146
+ forwards that client's token there — a production key with the override
147
+ aimed at a non-production pod hands that pod a live production JWT. Log
148
+ in to the env that owns the override host and pass *that* key.
149
+
150
+ **Only ever point this at a host you trust.** The CLI attaches your live
151
+ Bearer JWT to whatever absolute URL it is given, and does not validate
152
+ the override beyond trimming trailing slashes — so a typo'd or
153
+ attacker-supplied value sends a working token to that host. Reachability
154
+ is not trust: `/openapi.json` answering proves the pod is up, not that it
155
+ is ours.
156
+
157
+ ## Standard command sequence
158
+
159
+ Run the steps in order. Capture the session id from step 1 and reuse it.
160
+ `--server` must name the env whose onboarding instance you are actually
161
+ hitting — normally the **client's own env** (add `--account <email>` if the
162
+ operator has multiple identities stored).
163
+
164
+ **If you are on the fallback path** — validating somewhere other than the
165
+ client's env, whether by choice or via `DR_VALIDATE_ONBOARDING_HOST` — set
166
+ `SERVER` to that *validation* env instead. The JWT follows `--server`, so
167
+ leaving it on the client's env sends the client's live token to the host you
168
+ redirected to.
169
+
170
+ ```bash
171
+ # The env whose onboarding instance you're hitting. Normally the client's
172
+ # own env (one login). On the fallback path, set this to the VALIDATION
173
+ # env instead — the JWT follows it. Substitute your env.
174
+ SERVER=US
175
+
176
+ # 1. Create a session — prints just the session_id on stdout.
177
+ SID=$(dr validate onboarding session create --server "$SERVER")
178
+
179
+ # 2. Gather the files, then upload them all in one call (repeat --file).
180
+ # - the customer's own report (operator-supplied)
181
+ # - the Datarails report, CoA, GL/transactions, and (for BS) the
182
+ # trial balance, fetched from the client's env via dr-cli
183
+ # The service classifies each file's role automatically.
184
+ dr validate onboarding files upload "$SID" --server "$SERVER" \
185
+ --file "/path/to/customer_report.xlsx" \
186
+ --file "/path/to/datarails_report.xlsx" \
187
+ --file "/path/to/coa.xlsx" \
188
+ --file "/path/to/gl.xlsx"
189
+
190
+ # 3. Kick off reconcile + investigation. Returns in <1s with
191
+ # status="started"; the work continues server-side. Infer
192
+ # --report-type from the request; omit --period (the agent infers it).
193
+ # Note: --report-type "P&L" must be quoted — unquoted `&` would
194
+ # background the command in bash. "BS" is safe either way.
195
+ dr validate onboarding reconcile "$SID" --server "$SERVER" --report-type "P&L"
196
+
197
+ # 4. Poll every ~30 seconds. Investigation can take up to ~20 minutes.
198
+ dr validate onboarding status "$SID" --server "$SERVER"
199
+
200
+ # 5. Once status shows "investigation: complete", fetch the final report.
201
+ dr validate onboarding result "$SID" --server "$SERVER"
202
+ ```
203
+
204
+ ## Polling loop pattern
205
+
206
+ Keep polling until the synthesized top-level `status` reaches a
207
+ terminal state. The `--json` output exposes a `status` field that
208
+ collapses both pipeline stages into one of `pending` / `running` /
209
+ `complete` / `failed` — match against that, not against
210
+ `investigation_status` alone, or the loop hangs forever on failure.
211
+
212
+ ```bash
213
+ until dr validate onboarding status "$SID" --server "$SERVER" --json \
214
+ | grep -qE '"status": "(complete|failed)"'; do
215
+ sleep 30
216
+ done
217
+ ```
218
+
219
+ After the loop exits, inspect the terminal state before fetching the
220
+ result. If `status` is `failed`, surface the failure explicitly — do
221
+ **not** blindly run `result` and pretend the investigation succeeded.
222
+ Use `result "$SID" --reconcile` to fall back to the raw reconcile-only
223
+ report, or read the error string out of `status "$SID" --json` and
224
+ report it to the operator.
225
+
226
+ ```bash
227
+ TERMINAL=$(dr validate onboarding status "$SID" --server "$SERVER" --json \
228
+ | grep -oE '"status": "[^"]+"' | cut -d'"' -f4)
229
+ if [ "$TERMINAL" = "complete" ]; then
230
+ dr validate onboarding result "$SID" --server "$SERVER"
231
+ else
232
+ # investigation failed — surface the error and offer the reconcile fallback
233
+ dr validate onboarding status "$SID" --server "$SERVER" --json
234
+ dr validate onboarding result "$SID" --server "$SERVER" --reconcile
235
+ fi
236
+ ```
237
+
238
+ Acceptable terminal states are `complete` and `failed`. Anything else
239
+ (`pending` / `running`) means keep polling.
240
+
241
+ ## Output interpretation
242
+
243
+ Default `result` output is a concise markdown report with two sections:
244
+
245
+ 1. **Resolved discrepancies** — annotated reconcile lines with the
246
+ investigator's verdict (root cause) and the recommended CSM action.
247
+ 2. **Unresolved discrepancies** — lines the investigator couldn't
248
+ confidently explain. The CSM owns the next step on these.
249
+
250
+ Representative root-cause categories you'll see (not exhaustive):
251
+
252
+ | Category | Meaning |
253
+ |---|---|
254
+ | aggregation / mapping error | DR rolls accounts up differently than the customer (e.g. a sub-account included on one side). Fix the mapping. |
255
+ | sign convention | Customer uses negative expenses, DR uses positive (or vice versa). Flip the sign rule. |
256
+ | missing ERP data / partial integration | A GL account exists on one side and not the other. Likely an integration gap. |
257
+ | rounding | Sub-cent or sub-dollar diff. Usually safe to ignore. |
258
+ | manual adjustment / formula override | The customer file has a hardcoded value or formula override the GL doesn't reflect. Surface to the customer. |
259
+ | currency conversion | FX applied differently between the two sides. |
260
+
261
+ Flags to know:
262
+
263
+ - `--json` — emits the full structured payload (use for programmatic
264
+ inspection, downstream filtering, or when you want every per-line
265
+ flag the report writer captured).
266
+ - `--reconcile` — falls back to the raw reconcile-only output. Use this
267
+ only when investigation failed (`investigation: failed` from status);
268
+ otherwise prefer the default (investigation has strictly more info).
269
+
270
+ ## Generate the HTML report (final step)
271
+
272
+ Once `status` is `complete` and you've fetched `result`, render the branded HTML
273
+ report and show it to the operator. The CLI owns every number and all structure;
274
+ you (the agent) may enrich ONLY prose.
275
+
276
+ 1. Emit the faithful data block (numbers / structure / per-line detail):
277
+
278
+ ```bash
279
+ dr validate onboarding report "$SID" --server "$SERVER" \
280
+ --org "<client name>" \
281
+ [--client-report-name "…" --client-report-ref "Filebox <id> · v<n>"] \
282
+ [--dr-report-name "…" --dr-report-ref "Filebox <id> · v<n>"] \
283
+ --emit-data --out data.json
284
+ ```
285
+
286
+ 2. **(Optional)** Read `data.json` and write a prose overlay `prose.json` to
287
+ sharpen the wording:
288
+
289
+ ```json
290
+ { "rowProse": { "row-12": { "what": "One plain sentence about this gap." } },
291
+ "banner": "One-line tie-out narrative." }
292
+ ```
293
+
294
+ **Hard rule:** the overlay may contain ONLY `rowProse.<id>.what` and `banner`
295
+ — never a number and never any other field. Numbers are re-derived by the CLI
296
+ and cannot be changed from this file. Keep prose short; only `<strong>`,
297
+ `<em>`, and `<code>` tags survive sanitization.
298
+
299
+ 3. Render the HTML (pass `--prose` only if you wrote an overlay):
300
+
301
+ ```bash
302
+ dr validate onboarding report "$SID" --server "$SERVER" --org "<client name>" \
303
+ [--prose prose.json] --out report.html
304
+ ```
305
+
306
+ 4. Open `report.html` in the browser for the operator and print the path plus a
307
+ two-line summary (verdict + top action).
308
+
309
+ Skipping step 2 is fine — step 3 without `--prose` still produces a correct
310
+ report with templated prose. Notes: the tie-out card + headline verdict are
311
+ derived for **both** P&L (does Net Income tie) and Balance Sheet (assets = L+E);
312
+ grouped rows show member line names + the aggregate (the service does not expose
313
+ per-line amounts for a grouped match, and there are no section dividers);
314
+ `--from-json <result.json>` renders offline from a saved `result --json` payload.
315
+
316
+ ## Common pitfalls + recovery
317
+
318
+ | Symptom | Fix |
319
+ |---|---|
320
+ | `error: not logged in: <SERVER>:<email> …` / an HTTP 401 | Operator's keychain JWT expired or missing. Run `dr login --server <S>`, then retry. |
321
+ | `error: no known onboarding host for server "<X>"` | `<X>` is a custom `--server` URL, which has no registry subdomain to derive a host from. Set `DR_VALIDATE_ONBOARDING_HOST` to that instance's absolute URL and retry (still pass a real, logged-in `--server`). Registry env keys never hit this. |
322
+ | `error: could not reach ...` / a DNS failure | Either a network/DNS/VPN problem, or that env genuinely has no onboarding instance deployed (mostly internal test envs). A name that doesn't resolve fails *before* any request is made, so no token was transmitted. Validate on an env that does have one, noting that this uploads the files to that env (see the fallback caveat above). |
323
+ | a 404 on **every** call (not just after creating a session) | The host resolved and answered — so the request, and the Bearer JWT on it, did reach whatever is at that address. Usually `DR_VALIDATE_ONBOARDING_HOST` pointing at something that isn't an onboarding instance. Fix the target; and if it wasn't a host you trust, treat that token as exposed and re-login to rotate it. |
324
+ | `error: HTTP 404` after creating a session | Session ids TTL after 24h, and a server restart can drop them. Create a new session and re-upload the files. |
325
+ | `error: HTTP 404` from `result` (not `status`) | The investigation hasn't started yet. Poll `status` until it reports complete, then fetch `result` — don't call `result` before reconcile + investigation finish. |
326
+ | `error: … 400 … no files uploaded for this session` | The session has no files — usually `reconcile` ran before `files upload`, but a dropped session or an all-rejected upload triggers it too. Upload the files (at minimum the customer's own report) first. |
327
+ | `investigation: failed` in status | The investigation agent hit an unrecoverable error. Use `result "$SID" --reconcile` for the raw reconcile-only report, or inspect the error via `status "$SID" --json`. |
328
+ | `reconcile: failed` in status | The reconcile pipeline itself blew up — usually a malformed input file or a server-side bug. Surface the error from `status --json` to engineering. |
329
+ | Result blames a "missing" file that you didn't upload | Expected — some files are recommended, not required (e.g. GL, trial balance). If the finding needs one, fetch it via dr-cli and re-upload before re-running. |
330
+ | Multiple dr-cli identities in the keychain | Add `--account user@datarails.com` (alongside `--server`) on each command to pin which identity to use. |
331
+
332
+ ## What NOT to do
333
+
334
+ - **Don't tag files by role.** There is no `--pnl`/`--coa`/`--gl` flag —
335
+ upload with `--file` and let the service classify. Trying to force
336
+ roles is both impossible and unnecessary.
337
+ - **Don't ask the operator for the Datarails-side files.** Only the
338
+ customer's own report is operator-supplied; fetch the rest via dr-cli.
339
+ - **Don't ask for the period.** It's inferred. Only pass `--period` if
340
+ the operator volunteered one.
341
+ - **Don't re-run `reconcile` on a completed session.** Check status
342
+ first. Re-running on a `complete` session does nothing useful; on a
343
+ `running` session it short-circuits with `already_running`.
344
+ - **Don't delete a session before fetching the result.** `session
345
+ delete` is destructive — the investigation report is gone with it.
346
+ - **Don't pass file paths the CLI can't read.** Uploaded paths must
347
+ resolve on the operator's local machine.
348
+ - **Don't expect reconcile to be synchronous.** It returns in <1s with
349
+ `status="started"`. The actual work runs in the background and is
350
+ observed only via `status` / `result`.
351
+ - **Don't paste JWTs or `Authorization` headers into chat.** The CLI
352
+ pulls the token from the OS keychain by design; the operator never
353
+ needs to see it and neither does Claude.
354
+
355
+ ## Quick reference — all 8 commands
356
+
357
+ | Command | What it does |
358
+ |---|---|
359
+ | `dr validate onboarding session create` | Create a session; prints the new id on stdout. |
360
+ | `dr validate onboarding session get SID [--json]` | Fetch one session's full state. |
361
+ | `dr validate onboarding session delete SID` | Destroy a session (and its in-server state). Two-step: first run prints a `--confirm-token`; re-run with it to actually delete. |
362
+ | `dr validate onboarding files upload SID --file P [--file P ...]` | Upload one or more files in a single multipart call. The service classifies each file's role automatically. |
363
+ | `dr validate onboarding reconcile SID --report-type <"P&L"\|"BS"> [--period STR] [--csm-notes STR]` | Fast-return kickoff; reconcile + investigation run in background. Quote `"P&L"` in shells (bash treats `&` as backgrounding). `--period` is optional. |
364
+ | `dr validate onboarding status SID [--json]` | Poll reconcile + investigation status; one line by default. `--json` adds the synthesized top-level `status`. |
365
+ | `dr validate onboarding result SID [--json] [--reconcile]` | Fetch the final investigation report (or raw reconcile with `--reconcile`). |
366
+ | `dr validate onboarding report SID [--emit-data] [--prose P] [--out P] [--org NAME] [--from-json P]` | Render the investigation result as a self-contained HTML report (or `--emit-data` for the raw data block the agent enriches). |
367
+
368
+ Per-command flags (dr-cli convention): `--server <KEY>` selects the
369
+ identity **and** the env's onboarding host; `--account <email>` pins the
370
+ email when several identities are stored. `DR_VALIDATE_ONBOARDING_HOST`
371
+ overrides the host (only) when you need it.
372
+
373
+ ## Guard rails
374
+
375
+ - **Read-and-write.** `session create / delete` and `files upload` are
376
+ writes; treat them with the same care as any `dr` write command.
377
+ - **Never read or surface tokens.** The JWT lives in the OS keychain;
378
+ Claude should never paste it back.
379
+ - **Always use `--json` when parsing.** Default output is human-friendly
380
+ but not parser-friendly; pass `--json` and read structured fields
381
+ instead of regex-ing the table.
382
+ - **One session per validation.** Don't reuse a session id across
383
+ unrelated client validations — create a fresh session each time.
384
+
385
+ ## Related skills
386
+
387
+ - `~/.claude/skills/dr-cli/SKILL.md` — the broader dr-cli surface. Use it
388
+ to **fetch the Datarails-side files** (Datarails report, CoA,
389
+ GL/transactions, trial balance) from the client's fileboxes before
390
+ uploading, and for the shared keychain auth this skill piggybacks on.
391
+ - `~/.claude/skills/dr-switch-user/SKILL.md` — switch the active
392
+ dr-cli identity if the operator has multiple emails saved.