@ciphrix/cli 0.2.0 → 0.3.0

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
@@ -60,8 +60,9 @@ ciphrix test run result "MFA enforced" \
60
60
  --note "Rolled out organisation-wide"
61
61
  ```
62
62
 
63
- Add `--json` to any command for stable machine-readable output. Commands that perform consequential
64
- changes show the proposed action and ask for confirmation; automation can opt in with `--yes`.
63
+ Add `--json` for machine-readable output. Confirmed changes show a proposal and ask for consent;
64
+ automation must explicitly opt in with `--yes`. New immediate decision/send commands apply directly
65
+ and reject `--yes`; check command help rather than adding the flag to every write.
65
66
 
66
67
  ## One interface for compliance work
67
68
 
@@ -75,6 +76,31 @@ changes show the proposed action and ask for confirmation; automation can opt in
75
76
  Established record commands accept names and stable Ciphrix codes where advertised. Access inventory,
76
77
  review tasks and proposals require the exact IDs returned by their read commands; never guess identifiers.
77
78
 
79
+ ### Document review and approval
80
+
81
+ Configure Simple or Advanced workflows, assign active users, and explicitly send, recall or decide
82
+ review/approval requests. Admins and InfoSec leads operate these commands; employees can receive
83
+ assignments and complete decisions in the app.
84
+
85
+ ```bash
86
+ # Read state before configuring an existing draft
87
+ ciphrix document get "Access Control Policy" --json
88
+ ciphrix document workflow set "Access Control Policy" --type advanced
89
+ ciphrix user list --search "reviewer@example.com" --json
90
+ ciphrix document reviewer set "Access Control Policy" --user "reviewer@example.com"
91
+ ciphrix document approver set "Access Control Policy" --user "approver@example.com"
92
+
93
+ # Send only when authorized; review completion is a separate human decision
94
+ ciphrix document submit "Access Control Policy"
95
+ ```
96
+
97
+ After the reviewer completes review in the app (or an authorized caller explicitly records that
98
+ decision), request approval separately with `document approval send`. Ordinary approval remains
99
+ `document approve`; self-approval is a distinct explicit decision, not a review bypass.
100
+
101
+ See the [document workflow guide](skills/ciphrix/references/document-workflows.md) for recovery,
102
+ confirmation/retry boundaries and result interpretation. Use installed `--help` for exact options.
103
+
78
104
  ## Built for agent workspaces
79
105
 
80
106
  Ciphrix ships an agent skill as well as a CLI. The CLI provides the tools; the skill teaches an agent the
@@ -103,6 +129,12 @@ Run `npx skills update` to update installed skills when a newer version is avail
103
129
  aligned with your installed CLI version; its generated command reference and local help describe the
104
130
  available grammar. Server capability discovery remains authoritative for which operations you can use.
105
131
 
132
+ For document workflows, assignment and request sending are separate from formal review and approval
133
+ decisions. An agent may coordinate an authorized recall/configure/resend request, but must ask before
134
+ making a formal decision. A sent request must be recalled before changing its recipient, even when
135
+ selecting the same person. Recall clears that assignment. Active employees may be assigned and finish
136
+ their decisions in the app; tool access remains restricted to admins and InfoSec leads.
137
+
106
138
  ### Ask in natural language, operate through the CLI
107
139
 
108
140
  An agent can translate a request into a Ciphrix command, inspect the structured result, and present the
@@ -146,6 +178,7 @@ one command. Installed help is authoritative. The complete generated reference i
146
178
  | `ciphrix login` · `logout` | Authorize this device or revoke its session. |
147
179
  | `ciphrix context get` · `status` · `set` · `reset` | Read and maintain Business and Operating Context. |
148
180
  | `ciphrix document …` | Browse, read, create, edit, version, submit, approve, and delete documents. |
181
+ | `ciphrix user list` | Discover active users by name/email or paginated listing for assignment. |
149
182
  | `ciphrix test …` | Inspect tests, links, runs and evidence; attach items and record results. |
150
183
  | `ciphrix framework …` | Browse applied frameworks and work with clauses and mappings. |
151
184
  | `ciphrix control …` | Inspect controls, ownership, applicability, design requirements, and mappings. |
@@ -53,6 +53,23 @@ const inputFor = async (spec, args, options) => {
53
53
  }
54
54
  if (spec.path === 'access entry bulk-update')
55
55
  input.operation = 'update';
56
+ if (spec.inputAdapter === 'documentWorkflow') {
57
+ const uuid = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
58
+ const document = typeof input.document === 'string' ? input.document : '';
59
+ if (!document.trim())
60
+ throw new InputError('Provide a document name, code or ID.');
61
+ delete input.document;
62
+ input[uuid.test(document) ? 'policyId' : 'name'] = document;
63
+ if (input.user !== undefined) {
64
+ const user = typeof input.user === 'string' ? input.user : '';
65
+ if (uuid.test(user))
66
+ input.user = { id: user };
67
+ else if (/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(user))
68
+ input.user = { email: user };
69
+ else
70
+ throw new InputError('--user requires an exact email or User ID.');
71
+ }
72
+ }
56
73
  return input;
57
74
  };
58
75
  const partialFailure = (value, depth = 0) => {
@@ -154,6 +171,12 @@ const run = async (io, options, next, action) => {
154
171
  throw new RenderedCommandError();
155
172
  };
156
173
  const groupDescriptions = {
174
+ user: 'Active tenant-user discovery; no account administration',
175
+ 'document workflow': 'Configure workflow or explicitly return to draft',
176
+ 'document reviewer': 'Configure the review recipient; recall sent requests first',
177
+ 'document approver': 'Configure the approval recipient; recall sent requests first',
178
+ 'document review': 'Explicit review decisions and request recall; send with document submit',
179
+ 'document approval': 'Approval requests, explicit decisions and recall; ordinary decision with document approve',
157
180
  access: 'Access inventory, reviewed imports and assigned reviewer workflows',
158
181
  'access resource': 'Resources, owners and asset relationships',
159
182
  'access entry': 'Revisioned access inventory; inventory edits are not review decisions',
@@ -10,6 +10,7 @@ export interface Capability {
10
10
  path: string;
11
11
  description: string;
12
12
  argument?: string;
13
+ inputAdapter?: 'documentWorkflow';
13
14
  fields: Field[];
14
15
  next: string;
15
16
  }
@@ -63,6 +63,59 @@ const filters = () => [
63
63
  field('limit', 'limit', 'integer'),
64
64
  ];
65
65
  export const capabilities = [
66
+ ...[
67
+ ['document workflow set', 'Set workflow type in draft.', 'workflowType'],
68
+ ['document reviewer set', 'Set reviewer; sent requests must be recalled first.', 'user'],
69
+ ['document reviewer remove', 'Remove the reviewer from a draft.'],
70
+ ['document approver set', 'Set approver; sent requests must be recalled first.', 'user'],
71
+ ['document approver remove', 'Remove approver; sent requests must be recalled first.'],
72
+ [
73
+ 'document review complete',
74
+ 'Record an explicitly authorized review decision; does not send approval.',
75
+ ],
76
+ ['document review send-back', 'Record an explicit negative review decision; clears reviewer.'],
77
+ [
78
+ 'document review cancel',
79
+ 'Recall review request; clears reviewer. Configure and resend separately.',
80
+ ],
81
+ [
82
+ 'document approval send',
83
+ 'Send for approval after review; never completes review implicitly.',
84
+ ],
85
+ [
86
+ 'document approval send-back',
87
+ 'Record an explicit negative approval decision; clears approver.',
88
+ ],
89
+ [
90
+ 'document approval cancel',
91
+ 'Recall approval request; clears approver. Configure and resend separately.',
92
+ ],
93
+ [
94
+ 'document approval self-approve',
95
+ 'Explicit self-approval, separate from ordinary approve; no review bypass.',
96
+ ],
97
+ [
98
+ 'document workflow return-to-draft',
99
+ 'Return eligible advanced approval-stage document to draft; clears assignments.',
100
+ ],
101
+ ].map(([path, description, input]) => ({
102
+ path: path,
103
+ description: description,
104
+ argument: 'document',
105
+ inputAdapter: 'documentWorkflow',
106
+ fields: input === 'workflowType'
107
+ ? [field('type', 'workflowType', 'text', true, 'workflow type: simple or advanced')]
108
+ : input === 'user'
109
+ ? [
110
+ field('user', 'user', 'text', true, 'exact active user email or User ID; employees may be assigned'),
111
+ ]
112
+ : [],
113
+ next: 'document get',
114
+ })),
115
+ spec('user list', 'List active tenant users, including employees; discovery does not change accounts.', undefined, [
116
+ field('search', 'search', 'text', false, 'optional name/email search, at least three characters'),
117
+ ...page(),
118
+ ], 'document reviewer set'),
66
119
  spec('access resource list', 'List review inventory resources and owners.', undefined, [
67
120
  ...page(),
68
121
  field('search'),
@@ -1,10 +1,20 @@
1
1
  import { readFile } from 'node:fs/promises';
2
2
  import { applyTool } from '../actions.js';
3
+ import { getManifest, resolveBinding } from '../manifest.js';
3
4
  import { writeLine, writeTable } from '../io.js';
4
5
  import { asRecord, asText, callTool, errorMessage, resolveToolContext } from '../toolSurface.js';
5
6
  const UUID = /^[0-9a-f]{8}-[0-9a-f-]{27}$/i;
6
7
  const num = (value, fallback) => typeof value === 'number' ? String(value) : asText(value, fallback);
7
8
  const target = (policy) => UUID.test(policy) ? { policyId: policy } : { name: policy };
9
+ // Retain the original named calls only for older manifests without these bindings.
10
+ const documentWriteName = async (ctx, operation) => {
11
+ const manifest = await getManifest(ctx);
12
+ if (manifest.some((tool) => tool.cli?.operation === operation &&
13
+ JSON.stringify(tool.cli.group) === JSON.stringify(['document']))) {
14
+ return (await resolveBinding(ctx, ['document'], operation)).name;
15
+ }
16
+ return operation === 'submit' ? 'submit_document' : 'approve_document';
17
+ };
8
18
  const renderResult = (io, json, result) => {
9
19
  if (json) {
10
20
  writeLine(io.stdout, JSON.stringify(result, null, 2));
@@ -77,7 +87,7 @@ export const policySubmitCommand = async (options) => {
77
87
  const result = await applyTool({
78
88
  ctx,
79
89
  io,
80
- toolName: 'submit_document',
90
+ toolName: await documentWriteName(ctx, 'submit'),
81
91
  input: target(policy),
82
92
  fallback: 'Could not submit the document for review.',
83
93
  yes,
@@ -92,7 +102,7 @@ export const policyApproveCommand = async (options) => {
92
102
  const result = await applyTool({
93
103
  ctx,
94
104
  io,
95
- toolName: 'approve_document',
105
+ toolName: await documentWriteName(ctx, 'approve'),
96
106
  input: target(policy),
97
107
  fallback: 'Could not approve the document.',
98
108
  yes,
@@ -4,4 +4,4 @@
4
4
  */
5
5
  export declare const CLI_NAME = "ciphrix";
6
6
  export declare const CLI_TAGLINE = "Ciphrix compliance platform CLI";
7
- export declare const CLI_VERSION = "0.2.0";
7
+ export declare const CLI_VERSION = "0.3.0";
package/dist/constants.js CHANGED
@@ -4,4 +4,4 @@
4
4
  */
5
5
  export const CLI_NAME = 'ciphrix';
6
6
  export const CLI_TAGLINE = 'Ciphrix compliance platform CLI';
7
- export const CLI_VERSION = '0.2.0';
7
+ export const CLI_VERSION = '0.3.0';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ciphrix/cli",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
4
4
  "description": "Official command-line interface for the Ciphrix compliance platform.",
5
5
  "type": "module",
6
6
  "license": "Apache-2.0",
@@ -83,8 +83,9 @@ Two consequences worth internalising:
83
83
  addressed by their human name **or** their stable code (for example `ACME-DOC-A1B2`, `TSQ-001`,
84
84
  `ACME-RSK-CQJ4`, `ACME-AST-M5SD`). Ids work but are never required, and you never invent one. Prefer the
85
85
  code when a name is ambiguous.
86
- - **Intents, not steps.** Ask for the outcome; don't orchestrate the underlying calls. One user-facing
87
- request may be several platform operations — that composition is the CLI's job, not the user's.
86
+ - **Intents, not hidden decisions.** An agent may coordinate explicitly authorized platform operations
87
+ for one user request. Each operation remains separate: stop on errors or uncertain outcomes and never
88
+ infer a formal decision merely because it would let the next step proceed.
88
89
  - **Ask only for decisions.** Only actions that change something a person should review stop for
89
90
  confirmation — deleting, editing content, linking, or changing a control, clause, test or asset. A
90
91
  formal decision is its own verb (`approve`, `submit`, `test run result`) and applies directly. Everything
@@ -140,6 +141,19 @@ are what a check raised. `check disable` silences a check for the tenant — rec
140
141
 
141
142
  ## Guardrails
142
143
 
144
+ **Document workflow.** Configuration, request sending, review completion, ordinary approval and
145
+ self-approval are separate intents. Sending for approval never authorizes completing review first.
146
+ When a recipient setter reports an already-sent request, explain the current stage and offer recall,
147
+ configure and resend, even if the requested recipient is unchanged. Proceed only with authorization;
148
+ recall clears the recipient, so set them again before resending rather than removing an already-cleared
149
+ assignment. Unsent same-recipient selection reports already set. Read again between recovery steps and
150
+ use a separate write key per operation. Employees may be assigned and complete decisions in the app;
151
+ user discovery does not grant tool access. Use exact active User IDs/emails, not People IDs or fuzzy
152
+ name matches. Workflow readiness is business guidance, not permission or proof of notification delivery.
153
+ Before coordinating a document request or recovery, read
154
+ [the workflow guide](references/document-workflows.md) for stage-specific sequencing and result handling;
155
+ use installed help or [the generated reference](references/commands.md) for exact syntax.
156
+
143
157
  **Context and onboarding.** Read the server status and question schema, then save only facts agreed
144
158
  with the user. Business and Operating Context are separate. Let the server decide readiness; initial
145
159
  setup is optional and journey completion is explicit. A context save never authorizes starting agents,
@@ -34,6 +34,7 @@ Commands:
34
34
  risk Manage risks
35
35
  check Monitoring checks
36
36
  job Check background jobs started by other commands
37
+ user Active tenant-user discovery; no account administration
37
38
  access Access inventory, reviewed imports and assigned
38
39
  reviewer workflows
39
40
  agent Agent activity, complete proposals and explicit human
@@ -1143,6 +1144,16 @@ Commands:
1143
1144
  submit [options] <document> Submit a draft document for review
1144
1145
  approve [options] <document> Approve a document awaiting approval
1145
1146
  delete [options] <document> Delete a document
1147
+ workflow Configure workflow or explicitly return to
1148
+ draft
1149
+ reviewer Configure the review recipient; recall sent
1150
+ requests first
1151
+ approver Configure the approval recipient; recall sent
1152
+ requests first
1153
+ review Explicit review decisions and request recall;
1154
+ send with document submit
1155
+ approval Approval requests, explicit decisions and
1156
+ recall; ordinary decision with document approve
1146
1157
  help [command] display help for command
1147
1158
  ```
1148
1159
 
@@ -1312,6 +1323,379 @@ Options:
1312
1323
 
1313
1324
  **Effect:** Deletes a document; the CLI asks for confirmation when required.
1314
1325
 
1326
+ ## `ciphrix document workflow`
1327
+
1328
+ ```text
1329
+ Usage: ciphrix document workflow [options] [command]
1330
+
1331
+ Configure workflow or explicitly return to draft
1332
+
1333
+ Options:
1334
+ -h, --help display help for command
1335
+
1336
+ Commands:
1337
+ set [options] <document> Set workflow type in draft.
1338
+ return-to-draft [options] <document> Return eligible advanced approval-stage
1339
+ document to draft; clears assignments.
1340
+ help [command] display help for command
1341
+ ```
1342
+
1343
+ ## `ciphrix document workflow set`
1344
+
1345
+ ```text
1346
+ Usage: ciphrix document workflow set [options] <document>
1347
+
1348
+ Set workflow type in draft.
1349
+
1350
+ Options:
1351
+ --type <value> workflow type: simple or advanced
1352
+ --api-url <url> override the API base URL
1353
+ --json emit one complete result/error envelope
1354
+ --yes confirmed writes only: explicitly authorize without
1355
+ prompting; rejected on reads/immediate writes
1356
+ --idempotency-key <key> writes only: key for one logical operation; reuse
1357
+ identical input, at most 256 characters
1358
+ -h, --help display help for command
1359
+
1360
+ Writes use one idempotency key per operation. Reuse that key/input for retries; never bypass an unknown outcome with a new key. Confirmed calls also require valid confirmation: a fresh invocation re-preflights and may be blocked by changed state or expiry. Inspect current state/jobs when uncertain. Replayed status packs and signed URLs are snapshots, not refreshed reads.
1361
+ ```
1362
+
1363
+ **Effect:** Write controls apply only when advertised by the server: reads reject them, immediate writes do not accept --yes, and confirmed writes require valid explicit consent. Inspect uncertain outcomes rather than bypassing them with a new key.
1364
+
1365
+ ## `ciphrix document workflow return-to-draft`
1366
+
1367
+ ```text
1368
+ Usage: ciphrix document workflow return-to-draft [options] <document>
1369
+
1370
+ Return eligible advanced approval-stage document to draft; clears assignments.
1371
+
1372
+ Options:
1373
+ --api-url <url> override the API base URL
1374
+ --json emit one complete result/error envelope
1375
+ --yes confirmed writes only: explicitly authorize without
1376
+ prompting; rejected on reads/immediate writes
1377
+ --idempotency-key <key> writes only: key for one logical operation; reuse
1378
+ identical input, at most 256 characters
1379
+ -h, --help display help for command
1380
+
1381
+ Writes use one idempotency key per operation. Reuse that key/input for retries; never bypass an unknown outcome with a new key. Confirmed calls also require valid confirmation: a fresh invocation re-preflights and may be blocked by changed state or expiry. Inspect current state/jobs when uncertain. Replayed status packs and signed URLs are snapshots, not refreshed reads.
1382
+ ```
1383
+
1384
+ **Effect:** Write controls apply only when advertised by the server: reads reject them, immediate writes do not accept --yes, and confirmed writes require valid explicit consent. Inspect uncertain outcomes rather than bypassing them with a new key.
1385
+
1386
+ ## `ciphrix document reviewer`
1387
+
1388
+ ```text
1389
+ Usage: ciphrix document reviewer [options] [command]
1390
+
1391
+ Configure the review recipient; recall sent requests first
1392
+
1393
+ Options:
1394
+ -h, --help display help for command
1395
+
1396
+ Commands:
1397
+ set [options] <document> Set reviewer; sent requests must be recalled
1398
+ first.
1399
+ remove [options] <document> Remove the reviewer from a draft.
1400
+ help [command] display help for command
1401
+ ```
1402
+
1403
+ ## `ciphrix document reviewer set`
1404
+
1405
+ ```text
1406
+ Usage: ciphrix document reviewer set [options] <document>
1407
+
1408
+ Set reviewer; sent requests must be recalled first.
1409
+
1410
+ Options:
1411
+ --user <value> exact active user email or User ID; employees may be
1412
+ assigned
1413
+ --api-url <url> override the API base URL
1414
+ --json emit one complete result/error envelope
1415
+ --yes confirmed writes only: explicitly authorize without
1416
+ prompting; rejected on reads/immediate writes
1417
+ --idempotency-key <key> writes only: key for one logical operation; reuse
1418
+ identical input, at most 256 characters
1419
+ -h, --help display help for command
1420
+
1421
+ Writes use one idempotency key per operation. Reuse that key/input for retries; never bypass an unknown outcome with a new key. Confirmed calls also require valid confirmation: a fresh invocation re-preflights and may be blocked by changed state or expiry. Inspect current state/jobs when uncertain. Replayed status packs and signed URLs are snapshots, not refreshed reads.
1422
+ ```
1423
+
1424
+ **Effect:** Write controls apply only when advertised by the server: reads reject them, immediate writes do not accept --yes, and confirmed writes require valid explicit consent. Inspect uncertain outcomes rather than bypassing them with a new key.
1425
+
1426
+ ## `ciphrix document reviewer remove`
1427
+
1428
+ ```text
1429
+ Usage: ciphrix document reviewer remove [options] <document>
1430
+
1431
+ Remove the reviewer from a draft.
1432
+
1433
+ Options:
1434
+ --api-url <url> override the API base URL
1435
+ --json emit one complete result/error envelope
1436
+ --yes confirmed writes only: explicitly authorize without
1437
+ prompting; rejected on reads/immediate writes
1438
+ --idempotency-key <key> writes only: key for one logical operation; reuse
1439
+ identical input, at most 256 characters
1440
+ -h, --help display help for command
1441
+
1442
+ Writes use one idempotency key per operation. Reuse that key/input for retries; never bypass an unknown outcome with a new key. Confirmed calls also require valid confirmation: a fresh invocation re-preflights and may be blocked by changed state or expiry. Inspect current state/jobs when uncertain. Replayed status packs and signed URLs are snapshots, not refreshed reads.
1443
+ ```
1444
+
1445
+ **Effect:** Write controls apply only when advertised by the server: reads reject them, immediate writes do not accept --yes, and confirmed writes require valid explicit consent. Inspect uncertain outcomes rather than bypassing them with a new key.
1446
+
1447
+ ## `ciphrix document approver`
1448
+
1449
+ ```text
1450
+ Usage: ciphrix document approver [options] [command]
1451
+
1452
+ Configure the approval recipient; recall sent requests first
1453
+
1454
+ Options:
1455
+ -h, --help display help for command
1456
+
1457
+ Commands:
1458
+ set [options] <document> Set approver; sent requests must be recalled
1459
+ first.
1460
+ remove [options] <document> Remove approver; sent requests must be recalled
1461
+ first.
1462
+ help [command] display help for command
1463
+ ```
1464
+
1465
+ ## `ciphrix document approver set`
1466
+
1467
+ ```text
1468
+ Usage: ciphrix document approver set [options] <document>
1469
+
1470
+ Set approver; sent requests must be recalled first.
1471
+
1472
+ Options:
1473
+ --user <value> exact active user email or User ID; employees may be
1474
+ assigned
1475
+ --api-url <url> override the API base URL
1476
+ --json emit one complete result/error envelope
1477
+ --yes confirmed writes only: explicitly authorize without
1478
+ prompting; rejected on reads/immediate writes
1479
+ --idempotency-key <key> writes only: key for one logical operation; reuse
1480
+ identical input, at most 256 characters
1481
+ -h, --help display help for command
1482
+
1483
+ Writes use one idempotency key per operation. Reuse that key/input for retries; never bypass an unknown outcome with a new key. Confirmed calls also require valid confirmation: a fresh invocation re-preflights and may be blocked by changed state or expiry. Inspect current state/jobs when uncertain. Replayed status packs and signed URLs are snapshots, not refreshed reads.
1484
+ ```
1485
+
1486
+ **Effect:** Write controls apply only when advertised by the server: reads reject them, immediate writes do not accept --yes, and confirmed writes require valid explicit consent. Inspect uncertain outcomes rather than bypassing them with a new key.
1487
+
1488
+ ## `ciphrix document approver remove`
1489
+
1490
+ ```text
1491
+ Usage: ciphrix document approver remove [options] <document>
1492
+
1493
+ Remove approver; sent requests must be recalled first.
1494
+
1495
+ Options:
1496
+ --api-url <url> override the API base URL
1497
+ --json emit one complete result/error envelope
1498
+ --yes confirmed writes only: explicitly authorize without
1499
+ prompting; rejected on reads/immediate writes
1500
+ --idempotency-key <key> writes only: key for one logical operation; reuse
1501
+ identical input, at most 256 characters
1502
+ -h, --help display help for command
1503
+
1504
+ Writes use one idempotency key per operation. Reuse that key/input for retries; never bypass an unknown outcome with a new key. Confirmed calls also require valid confirmation: a fresh invocation re-preflights and may be blocked by changed state or expiry. Inspect current state/jobs when uncertain. Replayed status packs and signed URLs are snapshots, not refreshed reads.
1505
+ ```
1506
+
1507
+ **Effect:** Write controls apply only when advertised by the server: reads reject them, immediate writes do not accept --yes, and confirmed writes require valid explicit consent. Inspect uncertain outcomes rather than bypassing them with a new key.
1508
+
1509
+ ## `ciphrix document review`
1510
+
1511
+ ```text
1512
+ Usage: ciphrix document review [options] [command]
1513
+
1514
+ Explicit review decisions and request recall; send with document submit
1515
+
1516
+ Options:
1517
+ -h, --help display help for command
1518
+
1519
+ Commands:
1520
+ complete [options] <document> Record an explicitly authorized review
1521
+ decision; does not send approval.
1522
+ send-back [options] <document> Record an explicit negative review decision;
1523
+ clears reviewer.
1524
+ cancel [options] <document> Recall review request; clears reviewer.
1525
+ Configure and resend separately.
1526
+ help [command] display help for command
1527
+ ```
1528
+
1529
+ ## `ciphrix document review complete`
1530
+
1531
+ ```text
1532
+ Usage: ciphrix document review complete [options] <document>
1533
+
1534
+ Record an explicitly authorized review decision; does not send approval.
1535
+
1536
+ Options:
1537
+ --api-url <url> override the API base URL
1538
+ --json emit one complete result/error envelope
1539
+ --yes confirmed writes only: explicitly authorize without
1540
+ prompting; rejected on reads/immediate writes
1541
+ --idempotency-key <key> writes only: key for one logical operation; reuse
1542
+ identical input, at most 256 characters
1543
+ -h, --help display help for command
1544
+
1545
+ Writes use one idempotency key per operation. Reuse that key/input for retries; never bypass an unknown outcome with a new key. Confirmed calls also require valid confirmation: a fresh invocation re-preflights and may be blocked by changed state or expiry. Inspect current state/jobs when uncertain. Replayed status packs and signed URLs are snapshots, not refreshed reads.
1546
+ ```
1547
+
1548
+ **Effect:** Write controls apply only when advertised by the server: reads reject them, immediate writes do not accept --yes, and confirmed writes require valid explicit consent. Inspect uncertain outcomes rather than bypassing them with a new key.
1549
+
1550
+ ## `ciphrix document review send-back`
1551
+
1552
+ ```text
1553
+ Usage: ciphrix document review send-back [options] <document>
1554
+
1555
+ Record an explicit negative review decision; clears reviewer.
1556
+
1557
+ Options:
1558
+ --api-url <url> override the API base URL
1559
+ --json emit one complete result/error envelope
1560
+ --yes confirmed writes only: explicitly authorize without
1561
+ prompting; rejected on reads/immediate writes
1562
+ --idempotency-key <key> writes only: key for one logical operation; reuse
1563
+ identical input, at most 256 characters
1564
+ -h, --help display help for command
1565
+
1566
+ Writes use one idempotency key per operation. Reuse that key/input for retries; never bypass an unknown outcome with a new key. Confirmed calls also require valid confirmation: a fresh invocation re-preflights and may be blocked by changed state or expiry. Inspect current state/jobs when uncertain. Replayed status packs and signed URLs are snapshots, not refreshed reads.
1567
+ ```
1568
+
1569
+ **Effect:** Write controls apply only when advertised by the server: reads reject them, immediate writes do not accept --yes, and confirmed writes require valid explicit consent. Inspect uncertain outcomes rather than bypassing them with a new key.
1570
+
1571
+ ## `ciphrix document review cancel`
1572
+
1573
+ ```text
1574
+ Usage: ciphrix document review cancel [options] <document>
1575
+
1576
+ Recall review request; clears reviewer. Configure and resend separately.
1577
+
1578
+ Options:
1579
+ --api-url <url> override the API base URL
1580
+ --json emit one complete result/error envelope
1581
+ --yes confirmed writes only: explicitly authorize without
1582
+ prompting; rejected on reads/immediate writes
1583
+ --idempotency-key <key> writes only: key for one logical operation; reuse
1584
+ identical input, at most 256 characters
1585
+ -h, --help display help for command
1586
+
1587
+ Writes use one idempotency key per operation. Reuse that key/input for retries; never bypass an unknown outcome with a new key. Confirmed calls also require valid confirmation: a fresh invocation re-preflights and may be blocked by changed state or expiry. Inspect current state/jobs when uncertain. Replayed status packs and signed URLs are snapshots, not refreshed reads.
1588
+ ```
1589
+
1590
+ **Effect:** Write controls apply only when advertised by the server: reads reject them, immediate writes do not accept --yes, and confirmed writes require valid explicit consent. Inspect uncertain outcomes rather than bypassing them with a new key.
1591
+
1592
+ ## `ciphrix document approval`
1593
+
1594
+ ```text
1595
+ Usage: ciphrix document approval [options] [command]
1596
+
1597
+ Approval requests, explicit decisions and recall; ordinary decision with
1598
+ document approve
1599
+
1600
+ Options:
1601
+ -h, --help display help for command
1602
+
1603
+ Commands:
1604
+ send [options] <document> Send for approval after review; never
1605
+ completes review implicitly.
1606
+ send-back [options] <document> Record an explicit negative approval
1607
+ decision; clears approver.
1608
+ cancel [options] <document> Recall approval request; clears approver.
1609
+ Configure and resend separately.
1610
+ self-approve [options] <document> Explicit self-approval, separate from
1611
+ ordinary approve; no review bypass.
1612
+ help [command] display help for command
1613
+ ```
1614
+
1615
+ ## `ciphrix document approval send`
1616
+
1617
+ ```text
1618
+ Usage: ciphrix document approval send [options] <document>
1619
+
1620
+ Send for approval after review; never completes review implicitly.
1621
+
1622
+ Options:
1623
+ --api-url <url> override the API base URL
1624
+ --json emit one complete result/error envelope
1625
+ --yes confirmed writes only: explicitly authorize without
1626
+ prompting; rejected on reads/immediate writes
1627
+ --idempotency-key <key> writes only: key for one logical operation; reuse
1628
+ identical input, at most 256 characters
1629
+ -h, --help display help for command
1630
+
1631
+ Writes use one idempotency key per operation. Reuse that key/input for retries; never bypass an unknown outcome with a new key. Confirmed calls also require valid confirmation: a fresh invocation re-preflights and may be blocked by changed state or expiry. Inspect current state/jobs when uncertain. Replayed status packs and signed URLs are snapshots, not refreshed reads.
1632
+ ```
1633
+
1634
+ **Effect:** Write controls apply only when advertised by the server: reads reject them, immediate writes do not accept --yes, and confirmed writes require valid explicit consent. Inspect uncertain outcomes rather than bypassing them with a new key.
1635
+
1636
+ ## `ciphrix document approval send-back`
1637
+
1638
+ ```text
1639
+ Usage: ciphrix document approval send-back [options] <document>
1640
+
1641
+ Record an explicit negative approval decision; clears approver.
1642
+
1643
+ Options:
1644
+ --api-url <url> override the API base URL
1645
+ --json emit one complete result/error envelope
1646
+ --yes confirmed writes only: explicitly authorize without
1647
+ prompting; rejected on reads/immediate writes
1648
+ --idempotency-key <key> writes only: key for one logical operation; reuse
1649
+ identical input, at most 256 characters
1650
+ -h, --help display help for command
1651
+
1652
+ Writes use one idempotency key per operation. Reuse that key/input for retries; never bypass an unknown outcome with a new key. Confirmed calls also require valid confirmation: a fresh invocation re-preflights and may be blocked by changed state or expiry. Inspect current state/jobs when uncertain. Replayed status packs and signed URLs are snapshots, not refreshed reads.
1653
+ ```
1654
+
1655
+ **Effect:** Write controls apply only when advertised by the server: reads reject them, immediate writes do not accept --yes, and confirmed writes require valid explicit consent. Inspect uncertain outcomes rather than bypassing them with a new key.
1656
+
1657
+ ## `ciphrix document approval cancel`
1658
+
1659
+ ```text
1660
+ Usage: ciphrix document approval cancel [options] <document>
1661
+
1662
+ Recall approval request; clears approver. Configure and resend separately.
1663
+
1664
+ Options:
1665
+ --api-url <url> override the API base URL
1666
+ --json emit one complete result/error envelope
1667
+ --yes confirmed writes only: explicitly authorize without
1668
+ prompting; rejected on reads/immediate writes
1669
+ --idempotency-key <key> writes only: key for one logical operation; reuse
1670
+ identical input, at most 256 characters
1671
+ -h, --help display help for command
1672
+
1673
+ Writes use one idempotency key per operation. Reuse that key/input for retries; never bypass an unknown outcome with a new key. Confirmed calls also require valid confirmation: a fresh invocation re-preflights and may be blocked by changed state or expiry. Inspect current state/jobs when uncertain. Replayed status packs and signed URLs are snapshots, not refreshed reads.
1674
+ ```
1675
+
1676
+ **Effect:** Write controls apply only when advertised by the server: reads reject them, immediate writes do not accept --yes, and confirmed writes require valid explicit consent. Inspect uncertain outcomes rather than bypassing them with a new key.
1677
+
1678
+ ## `ciphrix document approval self-approve`
1679
+
1680
+ ```text
1681
+ Usage: ciphrix document approval self-approve [options] <document>
1682
+
1683
+ Explicit self-approval, separate from ordinary approve; no review bypass.
1684
+
1685
+ Options:
1686
+ --api-url <url> override the API base URL
1687
+ --json emit one complete result/error envelope
1688
+ --yes confirmed writes only: explicitly authorize without
1689
+ prompting; rejected on reads/immediate writes
1690
+ --idempotency-key <key> writes only: key for one logical operation; reuse
1691
+ identical input, at most 256 characters
1692
+ -h, --help display help for command
1693
+
1694
+ Writes use one idempotency key per operation. Reuse that key/input for retries; never bypass an unknown outcome with a new key. Confirmed calls also require valid confirmation: a fresh invocation re-preflights and may be blocked by changed state or expiry. Inspect current state/jobs when uncertain. Replayed status packs and signed URLs are snapshots, not refreshed reads.
1695
+ ```
1696
+
1697
+ **Effect:** Write controls apply only when advertised by the server: reads reject them, immediate writes do not accept --yes, and confirmed writes require valid explicit consent. Inspect uncertain outcomes rather than bypassing them with a new key.
1698
+
1315
1699
  ## `ciphrix risk`
1316
1700
 
1317
1701
  ```text
@@ -1701,6 +2085,47 @@ Options:
1701
2085
  -h, --help display help for command
1702
2086
  ```
1703
2087
 
2088
+ ## `ciphrix user`
2089
+
2090
+ ```text
2091
+ Usage: ciphrix user [options] [command]
2092
+
2093
+ Active tenant-user discovery; no account administration
2094
+
2095
+ Options:
2096
+ -h, --help display help for command
2097
+
2098
+ Commands:
2099
+ list [options] List active tenant users, including employees; discovery does
2100
+ not change accounts.
2101
+ help [command] display help for command
2102
+ ```
2103
+
2104
+ ## `ciphrix user list`
2105
+
2106
+ ```text
2107
+ Usage: ciphrix user list [options]
2108
+
2109
+ List active tenant users, including employees; discovery does not change
2110
+ accounts.
2111
+
2112
+ Options:
2113
+ --search <value> optional name/email search, at least three characters
2114
+ --page <value> page number starting at 1
2115
+ --limit <value> page size; server limits apply
2116
+ --api-url <url> override the API base URL
2117
+ --json emit one complete result/error envelope
2118
+ --yes confirmed writes only: explicitly authorize without
2119
+ prompting; rejected on reads/immediate writes
2120
+ --idempotency-key <key> writes only: key for one logical operation; reuse
2121
+ identical input, at most 256 characters
2122
+ -h, --help display help for command
2123
+
2124
+ Writes use one idempotency key per operation. Reuse that key/input for retries; never bypass an unknown outcome with a new key. Confirmed calls also require valid confirmation: a fresh invocation re-preflights and may be blocked by changed state or expiry. Inspect current state/jobs when uncertain. Replayed status packs and signed URLs are snapshots, not refreshed reads.
2125
+ ```
2126
+
2127
+ **Effect:** Write controls apply only when advertised by the server: reads reject them, immediate writes do not accept --yes, and confirmed writes require valid explicit consent. Inspect uncertain outcomes rather than bypassing them with a new key.
2128
+
1704
2129
  ## `ciphrix access`
1705
2130
 
1706
2131
  ```text
@@ -0,0 +1,62 @@
1
+ # Document workflows
2
+
3
+ Use this guide when configuring document review/approval, selecting recipients, recovering a sent
4
+ request or interpreting a workflow result. Installed command help is authoritative for exact options;
5
+ the [generated command reference](commands.md) covers the complete command tree.
6
+
7
+ ## Read, configure, send, decide
8
+
9
+ 1. Read the document with `document get --json`. Resolve the intended name, code or ID before writing.
10
+ Workflow readiness describes business state; the server still decides permissions and validates
11
+ prerequisites at execution time.
12
+ 2. Configure the workflow in draft. Simple supports explicit self-approval; Advanced requires review
13
+ before approval. An approved document needs a new version before editing.
14
+ 3. Assign recipients using exact active User email or User ID. `user list` supports name/email search
15
+ and pagination; search needs at least three characters. Resolve ambiguous matches with the user.
16
+ People IDs, fuzzy names and invitation requests are not recipient selectors.
17
+ 4. Send review with `document submit`. Completing review is a separate formal human decision; it
18
+ advances to approval-not-sent without sending approval. A request to send approval does not authorize
19
+ completing review on the user's behalf.
20
+ 5. Explicitly request approval with `document approval send`. Ordinary approval uses `document approve`;
21
+ `document approval self-approve` is a distinct human decision and never bypasses Advanced review.
22
+
23
+ Admins and InfoSec leads have tool access. Active employees may receive assignments and complete
24
+ review/approval in the app; listing or assigning a user does not grant them tool access. Decisions
25
+ record the authenticated caller, not an impersonated assignee.
26
+
27
+ ## Recover a sent request
28
+
29
+ A sent-recipient setter refuses both a different person and the same person. Explain the current
30
+ stage and ask whether the user wants an explicit recall → configure → resend sequence:
31
+
32
+ | Current request | Recall | Configure after recall | Resend |
33
+ | --------------- | -------------------------- | ----------------------- | ------------------------ |
34
+ | Review sent | `document review cancel` | `document reviewer set` | `document submit` |
35
+ | Approval sent | `document approval cancel` | `document approver set` | `document approval send` |
36
+
37
+ Recall clears the affected recipient; configure that person again even if unchanged. Removing an
38
+ already-cleared assignment is not a recovery step. In supported unsent states, setting the same
39
+ recipient succeeds without a change.
40
+
41
+ Read current state between steps. Each step has independent authorization, confirmation where required
42
+ and its own write key. Stop on an error or uncertain result; the sequence is not atomic. Send-back is
43
+ a negative human decision, not a synonym for recall. Return-to-draft is available only in the supported
44
+ Advanced approval-not-sent/rejected stages and clears assignments and decision attribution.
45
+
46
+ ## Confirmation, retries and results
47
+
48
+ - Configuration, recipient removal, recall and return-to-draft use confirmed writes. New commands in
49
+ JSON/noninteractive mode require `--yes`; supply it only for an already authorized change.
50
+ - New send/decision commands apply immediately, still require human authorization, and reject `--yes`.
51
+ Existing `document submit` and `document approve` retain their advertised options and successful JSON;
52
+ there are no alternate submit/approve spellings. Check each command's help.
53
+ - New write commands accept `--idempotency-key` for one logical operation. Reuse the same key and input
54
+ for retries. Confirmed replay also requires valid confirmation: a fresh CLI invocation preflights
55
+ again and can be refused after state changes or expiry. Never use a new key to bypass uncertainty.
56
+ - New commands return full envelopes with `--json`, preserving structured errors, warnings and
57
+ pagination. Existing submit success reports `data.status: submitted`, not a current raw workflow
58
+ state. A fresh document read gives current state; a replay returns the original result snapshot.
59
+ - Success records the committed/queued outcome. It is not evidence that an email arrived, a recipient
60
+ acted, or the document was published. Report these outcomes separately.
61
+
62
+ For general operating principles, return to [the Ciphrix skill](../SKILL.md).