tenuo-claude-code 0.2.1__tar.gz → 0.2.2__tar.gz

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 (54) hide show
  1. {tenuo_claude_code-0.2.1 → tenuo_claude_code-0.2.2}/.gitignore +1 -1
  2. {tenuo_claude_code-0.2.1 → tenuo_claude_code-0.2.2}/PKG-INFO +114 -61
  3. {tenuo_claude_code-0.2.1 → tenuo_claude_code-0.2.2}/README.md +113 -60
  4. {tenuo_claude_code-0.2.1 → tenuo_claude_code-0.2.2}/demo/README.md +42 -14
  5. tenuo_claude_code-0.2.2/demo/docs/README.md +21 -0
  6. {tenuo_claude_code-0.2.1 → tenuo_claude_code-0.2.2}/docs/DETAILS.md +44 -17
  7. tenuo_claude_code-0.2.2/docs/TROUBLESHOOTING.md +221 -0
  8. {tenuo_claude_code-0.2.1 → tenuo_claude_code-0.2.2}/docs/images/README.md +1 -1
  9. {tenuo_claude_code-0.2.1 → tenuo_claude_code-0.2.2}/pyproject.toml +1 -1
  10. {tenuo_claude_code-0.2.1 → tenuo_claude_code-0.2.2}/src/tenuo_claude_code/admin.py +29 -0
  11. {tenuo_claude_code-0.2.1 → tenuo_claude_code-0.2.2}/src/tenuo_claude_code/authorizer_runtime.py +13 -1
  12. {tenuo_claude_code-0.2.1 → tenuo_claude_code-0.2.2}/src/tenuo_claude_code/cli.py +205 -23
  13. {tenuo_claude_code-0.2.1 → tenuo_claude_code-0.2.2}/templates/README.md +2 -0
  14. {tenuo_claude_code-0.2.1 → tenuo_claude_code-0.2.2}/templates/tenuo.yaml.advanced.example +2 -2
  15. {tenuo_claude_code-0.2.1 → tenuo_claude_code-0.2.2}/tests/test_admin.py +87 -0
  16. tenuo_claude_code-0.2.2/tests/test_cloud_bindings.py +331 -0
  17. tenuo_claude_code-0.2.2/tests/test_scaffold.py +244 -0
  18. tenuo_claude_code-0.2.1/tests/test_scaffold.py +0 -133
  19. {tenuo_claude_code-0.2.1 → tenuo_claude_code-0.2.2}/CONTRIBUTING.md +0 -0
  20. {tenuo_claude_code-0.2.1 → tenuo_claude_code-0.2.2}/LICENSE +0 -0
  21. {tenuo_claude_code-0.2.1 → tenuo_claude_code-0.2.2}/demo/.claude/agents/researcher.md +0 -0
  22. {tenuo_claude_code-0.2.1 → tenuo_claude_code-0.2.2}/demo/.mcp.json +0 -0
  23. {tenuo_claude_code-0.2.1 → tenuo_claude_code-0.2.2}/demo/fake-secrets.env +0 -0
  24. {tenuo_claude_code-0.2.1 → tenuo_claude_code-0.2.2}/demo/ops_server.py +0 -0
  25. {tenuo_claude_code-0.2.1 → tenuo_claude_code-0.2.2}/demo/sandbox/incident-report.md +0 -0
  26. {tenuo_claude_code-0.2.1 → tenuo_claude_code-0.2.2}/demo/sandbox/notes.txt +0 -0
  27. {tenuo_claude_code-0.2.1 → tenuo_claude_code-0.2.2}/demo/tenuo.yaml +0 -0
  28. {tenuo_claude_code-0.2.1 → tenuo_claude_code-0.2.2}/demo/tenuo_demo.py +0 -0
  29. {tenuo_claude_code-0.2.1 → tenuo_claude_code-0.2.2}/docs/images/cloud-audit-stream.png +0 -0
  30. {tenuo_claude_code-0.2.1 → tenuo_claude_code-0.2.2}/docs/images/cloud-receipt-approval-detail.png +0 -0
  31. {tenuo_claude_code-0.2.1 → tenuo_claude_code-0.2.2}/docs/images/tenuo_claude_code_architecture.png +0 -0
  32. {tenuo_claude_code-0.2.1 → tenuo_claude_code-0.2.2}/docs/images/tenuo_claude_code_architecture.svg +0 -0
  33. {tenuo_claude_code-0.2.1 → tenuo_claude_code-0.2.2}/examples/policies/README.md +0 -0
  34. {tenuo_claude_code-0.2.1 → tenuo_claude_code-0.2.2}/examples/policies/audit-rollout.yaml +0 -0
  35. {tenuo_claude_code-0.2.1 → tenuo_claude_code-0.2.2}/examples/policies/enforce-with-mcp.yaml +0 -0
  36. {tenuo_claude_code-0.2.1 → tenuo_claude_code-0.2.2}/examples/policies/read-only-research.yaml +0 -0
  37. {tenuo_claude_code-0.2.1 → tenuo_claude_code-0.2.2}/src/tenuo_claude_code/__init__.py +0 -0
  38. {tenuo_claude_code-0.2.1 → tenuo_claude_code-0.2.2}/src/tenuo_claude_code/data/harness_tools.yaml +0 -0
  39. {tenuo_claude_code-0.2.1 → tenuo_claude_code-0.2.2}/src/tenuo_claude_code/paths.py +0 -0
  40. {tenuo_claude_code-0.2.1 → tenuo_claude_code-0.2.2}/src/tenuo_claude_code/templates/tenuo.yaml.example +0 -0
  41. {tenuo_claude_code-0.2.1 → tenuo_claude_code-0.2.2}/src/tenuo_claude_code/verify.py +0 -0
  42. {tenuo_claude_code-0.2.1 → tenuo_claude_code-0.2.2}/templates/admin.env.example +0 -0
  43. {tenuo_claude_code-0.2.1 → tenuo_claude_code-0.2.2}/templates/cloud.env.example +0 -0
  44. {tenuo_claude_code-0.2.1 → tenuo_claude_code-0.2.2}/templates/tenuo.yaml.cloud.example +0 -0
  45. {tenuo_claude_code-0.2.1 → tenuo_claude_code-0.2.2}/templates/tenuo.yaml.example +0 -0
  46. {tenuo_claude_code-0.2.1 → tenuo_claude_code-0.2.2}/tests/conftest.py +0 -0
  47. {tenuo_claude_code-0.2.1 → tenuo_claude_code-0.2.2}/tests/test_approvals.py +0 -0
  48. {tenuo_claude_code-0.2.1 → tenuo_claude_code-0.2.2}/tests/test_authorize_call.py +0 -0
  49. {tenuo_claude_code-0.2.1 → tenuo_claude_code-0.2.2}/tests/test_authorizer_runtime.py +0 -0
  50. {tenuo_claude_code-0.2.1 → tenuo_claude_code-0.2.2}/tests/test_check.py +0 -0
  51. {tenuo_claude_code-0.2.1 → tenuo_claude_code-0.2.2}/tests/test_constraints.py +0 -0
  52. {tenuo_claude_code-0.2.1 → tenuo_claude_code-0.2.2}/tests/test_permissions.py +0 -0
  53. {tenuo_claude_code-0.2.1 → tenuo_claude_code-0.2.2}/tests/test_routing.py +0 -0
  54. {tenuo_claude_code-0.2.1 → tenuo_claude_code-0.2.2}/tests/test_subagents.py +0 -0
@@ -24,7 +24,7 @@ tenuo.advanced.yaml
24
24
  demo/sandbox/out.txt
25
25
  demo/sandbox/_probe.txt
26
26
 
27
- # Local-only presentation notes (optional; not part of the public repo)
27
+ # Local-only presentation notes (gitignored — keep your own copy; see demo/docs/README.md)
28
28
  demo/docs/PRESENTATION.md
29
29
 
30
30
  # OS / editor
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: tenuo-claude-code
3
- Version: 0.2.1
3
+ Version: 0.2.2
4
4
  Summary: Tenuo governance for Claude Code — warrants, hooks, MCP proxy, and Cloud lifecycle
5
5
  Project-URL: Homepage, https://tenuo.ai
6
6
  Project-URL: Repository, https://github.com/tenuo-ai/claude-governance
@@ -51,9 +51,21 @@ mkdir my-project && cd my-project
51
51
  tenuo-claude bootstrap
52
52
  ```
53
53
 
54
- Open Claude Code here when `verify` passes. No Claude? `bootstrap` + `verify` is enough to prove enforcement.
54
+ When `verify` passes, open Claude Code in this directory.
55
55
 
56
- No Docker, or prefer native? Run `tenuo-claude install-authorizer` once, then `bootstrap`. Without Docker, the CLI uses native automatically. To force native while Docker is running, set `TENUO_AUTHORIZER_BACKEND=native` before `bootstrap`.
56
+ **Native authorizer (no Docker):**
57
+
58
+ ```bash
59
+ tenuo-claude install-authorizer
60
+ tenuo-claude bootstrap
61
+ ```
62
+
63
+ If Docker is not installed, `bootstrap` uses the native authorizer automatically. If Docker is installed and you want native anyway:
64
+
65
+ ```bash
66
+ export TENUO_AUTHORIZER_BACKEND=native
67
+ tenuo-claude bootstrap
68
+ ```
57
69
 
58
70
  ### Where to go next
59
71
 
@@ -61,10 +73,11 @@ No Docker, or prefer native? Run `tenuo-claude install-authorizer` once, then `b
61
73
  |-----------------|------------|
62
74
  | Day-to-day commands, ports, CLI reference | [Use the tool](#use-the-tool-pypi) |
63
75
  | Edit or replace the example policy | [Policy](#policy-tenuoyaml) |
64
- | Clone, hack, or run the sample project | [Build from source](#build-from-source) |
76
+ | Clone the repo or run the sample project | [Build from source](#build-from-source) |
65
77
  | Connect to Tenuo Cloud | [Cloud mode](#cloud-mode) |
66
78
  | Review security posture | [Security](#security) |
67
79
  | Plan org-wide rollout | [Talk to us](https://tenuo.ai/early-access.html) |
80
+ | Something failed during setup | [Troubleshooting (Q&A)](docs/TROUBLESHOOTING.md) |
68
81
  | Implementation depth | [docs/DETAILS.md](docs/DETAILS.md) |
69
82
 
70
83
  ## How it works
@@ -85,41 +98,42 @@ tenuo.yaml → init/up → warrant + authorizer + hooks + MCP proxy
85
98
 
86
99
  **Native tools** (Read, Bash, WebFetch, and the rest) go through a PreToolUse hook. **MCP tools** go through a proxy in place of the downstream server. At `init`, Tenuo mints a **session warrant**; each call must prove it holds that warrant before the authorizer allows the action.
87
100
 
88
- Both paths use the same warrant and authorizer.
89
-
90
101
  More: [docs/DETAILS.md](docs/DETAILS.md)
91
102
 
92
103
  ## Prerequisites
93
104
 
94
105
  - Python ≥ 3.10
95
- - **Authorizer runtime** (pick one):
96
- - **Docker:** [Docker Desktop](https://www.docker.com/products/docker-desktop/) or your engine, then `tenuo-claude up`. Pulls the pinned `tenuo/authorizer` image. Default when Docker is running.
97
- - **Native (no Docker):** `tenuo-claude install-authorizer`, then `tenuo-claude up --native`. First run: add `--install`. Override the binary with `TENUO_AUTHORIZER_BIN`. Set `TENUO_AUTHORIZER_SKIP_VERSION=1` only for local dev builds.
106
+ - **Authorizer runtime** (use one):
107
+ - **Docker** (default when the daemon is running): [Docker Desktop](https://www.docker.com/products/docker-desktop/) or your engine, then `tenuo-claude up`. Uses the pinned `tenuo/authorizer` image.
108
+ - **Native** (no Docker): run `tenuo-claude install-authorizer`, then `tenuo-claude up --native`. On first run, add `--install`. Override the binary with `TENUO_AUTHORIZER_BIN`. Set `TENUO_AUTHORIZER_SKIP_VERSION=1` only for local dev builds.
109
+ - To force native while Docker is installed, set `TENUO_AUTHORIZER_BACKEND=native` before `bootstrap` or `up`.
110
+ - [Claude Code](https://code.claude.com/docs) — Tenuo wires PreToolUse hooks and MCP proxy at `init`.
98
111
 
99
- Without Docker, `bootstrap` uses native. Run `install-authorizer` first. To force native while Docker is running, set `TENUO_AUTHORIZER_BACKEND=native`.
100
- - [Claude Code](https://code.claude.com/docs) for live agent use. Optional: `verify` works without it.
112
+ **Local mode:** no Tenuo Cloud account. Suitable for single-project evaluation.
101
113
 
102
- **Local mode:** no Tenuo Cloud account. Good for one project or evaluation.
103
-
104
- **Cloud mode:** [cloud.tenuo.ai](https://cloud.tenuo.ai) tenant for tenant-root warrants, central audit, fleet revocation, and org-wide rollout ([Cloud mode](#cloud-mode)).
114
+ **Cloud mode:** requires a [cloud.tenuo.ai](https://cloud.tenuo.ai) tenant for tenant-root warrants, central audit, fleet revocation, and org-wide rollout ([Cloud mode](#cloud-mode)).
105
115
 
106
116
  ---
107
117
 
108
118
  ## Use the tool (PyPI)
109
119
 
110
- After [Try it](#try-it), you have an example `tenuo.yaml`, a running authorizer, and passing `verify`. Stay in that project directory for every command below.
120
+ After [Try it](#try-it), you have an example `tenuo.yaml`, a running authorizer, and passing `verify`.
111
121
 
112
122
  ### Day to day
113
123
 
114
124
  | When | Command |
115
125
  |------|---------|
116
- | Start work | `tenuo-claude up` or `tenuo-claude up --native` |
117
- | You edited `tenuo.yaml` | `tenuo-claude refresh` |
118
- | Something broken | `tenuo-claude check` |
126
+ | Start work (Cloud) | `tenuo-claude check && tenuo-claude up` |
127
+ | Start work (local only) | `tenuo-claude up` or `tenuo-claude up --native` |
128
+ | `check` reports cloud bindings failure | `tenuo-admin setup`, then `check && up` again |
129
+ | You edited `tenuo.yaml` | `tenuo-claude refresh` (local); Cloud capability changes also need `tenuo-admin setup` |
130
+ | Diagnose setup | `tenuo-claude check` |
119
131
  | See decisions | `tenuo-claude audit` |
120
132
  | Stop authorizer | `tenuo-claude down` |
121
133
 
122
- If you always use native without Docker, set `TENUO_AUTHORIZER_BACKEND=native` in your shell so plain `up` picks the host binary.
134
+ See [Troubleshooting (Q&A)](docs/TROUBLESHOOTING.md) for common errors.
135
+
136
+ If you always use the native authorizer without Docker, set `TENUO_AUTHORIZER_BACKEND=native` in your shell so plain `up` selects the host binary.
123
137
 
124
138
  ### Port conflicts
125
139
 
@@ -146,13 +160,15 @@ tenuo-claude up
146
160
  tenuo-claude verify
147
161
  ```
148
162
 
149
- Use `--native` when not running Docker. First native run: add `--install`. Or run `tenuo-claude onboard --local`.
163
+ Use `--native` when Docker is not available. On the first native run, add `--install`. Alternatively, run `tenuo-claude onboard --local` for an interactive setup.
150
164
 
151
165
  ### Reference demo
152
166
 
153
167
  Sample policy, MCP stub, and scripted tour in [demo/](demo/). The shipped `demo/tenuo.yaml` is richer than the bootstrap example; Cloud and approval overlays may already be present.
154
168
 
155
- **First time, local only** (no `.state/cloud.env` yet):
169
+ From repo root: `uv venv && uv sync && source .venv/bin/activate`, then:
170
+
171
+ **First time, local only** (no `.state/cloud.env`):
156
172
 
157
173
  ```bash
158
174
  cd demo
@@ -160,18 +176,37 @@ tenuo-claude bootstrap
160
176
  tenuo-claude demo
161
177
  ```
162
178
 
163
- **Already Cloud-configured** (`.state/cloud.env` or `tenuo.cloud.yaml` present): do not run plain `bootstrap`. It switches to local mode and moves Cloud files aside. Use:
179
+ **First time, Cloud** (recommended for the reference demo with receipts):
164
180
 
165
181
  ```bash
166
182
  cd demo
167
- tenuo-claude up
183
+ tenuo-claude bootstrap --cloud
184
+ # or: tenuo-claude onboard --cloud
185
+ tenuo-claude demo
186
+ ```
187
+
188
+ Paste Quick Connect (**Authorizer Only**) into `.state/cloud.env` and tenant-admin
189
+ key into `~/.tenuo/admin.env` when prompted. See [Cloud mode](#cloud-mode).
190
+
191
+ **Already Cloud-configured** (`.state/cloud.env` or `tenuo.cloud.yaml` present):
192
+
193
+ Do **not** run plain `bootstrap` — it switches to local mode and moves Cloud files
194
+ aside. Use:
195
+
196
+ ```bash
197
+ cd demo
198
+ tenuo-claude check && tenuo-claude up
168
199
  tenuo-claude verify
169
200
  tenuo-claude demo
170
201
  ```
171
202
 
203
+ If `check` fails on **cloud bindings** → `tenuo-admin setup`, then retry.
204
+
172
205
  For human approval: [Cloud mode § Human approval](#human-approval-cloud), then `tenuo-claude demo --advanced --live-approval`.
173
206
 
174
- If you ran local `bootstrap` on a Cloud setup by mistake, restore `.state/cloud.env` and overlays from backup, then run `tenuo-admin setup` to re-claim the holder key.
207
+ If plain `bootstrap` was run on a Cloud-configured project, restore `.state/cloud.env`
208
+ and policy overlays from backup, then `tenuo-admin setup`. See
209
+ [Troubleshooting](docs/TROUBLESHOOTING.md).
175
210
 
176
211
  From a git checkout, see [Build from source](#build-from-source).
177
212
 
@@ -184,21 +219,21 @@ From a git checkout, see [Build from source](#build-from-source).
184
219
  | `up` / `down` | Start / stop authorizer. `up` flags: `--native`, `--docker`, `--install` (native, first run) |
185
220
  | `install-authorizer` | Install `tenuo-authorizer` to `~/.tenuo/bin` (no manual `cargo`) |
186
221
  | `refresh` | Re-apply `tenuo.yaml` (restarts authorizer if up) |
187
- | `check` | Preflight: deps, credentials, wiring drift |
188
- | `verify [--deep]` | Policy self-test against the authorizer |
222
+ | `check` | Preflight: deps, credentials, wiring drift, Cloud binding probe |
223
+ | `verify [--deep]` | Policy self-test against the authorizer (no agent session required) |
189
224
  | `status` | Warrant, posture, Cloud summary |
190
225
  | `onboard` | Interactive local or Cloud setup wizard |
191
226
  | `bench [--json]` | Per-tool-call overhead |
192
227
  | `audit [--tail N]` | Receipt trail |
193
228
  | `revoke` | Revoke session warrant |
194
229
 
195
- See also: [Policy](#policy-tenuoyaml) · [Cloud mode](#cloud-mode) · [docs/DETAILS.md](docs/DETAILS.md)
230
+ See also: [Policy](#policy-tenuoyaml) · [Cloud mode](#cloud-mode) · [Troubleshooting](docs/TROUBLESHOOTING.md) · [docs/DETAILS.md](docs/DETAILS.md)
196
231
 
197
232
  ---
198
233
 
199
234
  ## Build from source
200
235
 
201
- For hacking on the CLI, running the reference demo from git, or using `./bin/tenuo-claude` instead of a PyPI install.
236
+ For local development, the reference demo from git, or `./bin/tenuo-claude` instead of a PyPI install.
202
237
 
203
238
  ```bash
204
239
  git clone https://github.com/tenuo-ai/claude-governance.git
@@ -222,13 +257,14 @@ Run commands via the repo launcher or editable install:
222
257
 
223
258
  ```bash
224
259
  cd demo
225
- tenuo-claude up # if Cloud is already wired; see Reference demo above
260
+ tenuo-claude check && tenuo-claude up # Cloud; see Reference demo if check fails
226
261
  tenuo-claude demo
227
262
  ```
228
263
 
229
- First local-only run: `tenuo-claude bootstrap` instead of `up`, only when `.state/cloud.env` is absent.
264
+ First local-only run (no `.state/cloud.env`): use `tenuo-claude bootstrap` instead.
265
+ First Cloud run: `tenuo-claude bootstrap --cloud` or `onboard --cloud`.
230
266
 
231
- Use `tenuo-claude up --native` instead of plain `up` if you are not running Docker.
267
+ Use `tenuo-claude up --native` when Docker is not available.
232
268
 
233
269
  Open Claude Code in `demo/`. See [demo/README.md](demo/README.md) and [Reference demo](#reference-demo) above.
234
270
 
@@ -292,8 +328,6 @@ Use Cloud when you need organization-scale governance, not just a single laptop:
292
328
  every tool call at the hook and MCP proxy. Engineers cannot disable it with local
293
329
  Claude permission edits or `--dangerously-skip-permissions`
294
330
 
295
- Local mode (no Cloud account) remains fully supported for evaluation and single-project use.
296
-
297
331
  ### Cloud quickstart
298
332
 
299
333
  Two keys, two files. Runtime never sees the admin key:
@@ -305,9 +339,7 @@ Two keys, two files. Runtime never sees the admin key:
305
339
 
306
340
  **Do not** put the tenant-admin key in `.state/cloud.env` or your shell when running `tenuo-claude up`. Runtime refuses to start if an admin key is reachable.
307
341
 
308
- **Fresh project**
309
-
310
- Creates an example `tenuo.yaml` if none exists.
342
+ **Fresh project** (creates `tenuo.yaml` if none exists):
311
343
 
312
344
  ```bash
313
345
  pip install tenuo-claude-code
@@ -315,9 +347,7 @@ mkdir my-project && cd my-project
315
347
  tenuo-claude bootstrap --cloud
316
348
  ```
317
349
 
318
- Requires a Quick Connect token (`tenuo_ct_…`). The wizard prompts for it. Using explicit Cloud URL + API key instead? Use the manual setup block below; `bootstrap --cloud` expects Quick Connect.
319
-
320
- Prompts for credentials, then runs `init`, `tenuo-admin setup`, `up`, and `verify`. Pass a tenant-admin key to run setup in the same step.
350
+ The wizard prompts for a Quick Connect token (`tenuo_ct_…`), then runs `init`, `tenuo-admin setup`, `up`, and `verify`. For an explicit Cloud URL and API key without Quick Connect, use the manual setup block below.
321
351
 
322
352
  Non-interactive:
323
353
 
@@ -327,7 +357,7 @@ tenuo-claude bootstrap --cloud --yes \
327
357
  --admin-key "tc_…"
328
358
  ```
329
359
 
330
- Omit `--admin-key` if `tenuo-admin setup` already ran. Prefer flags over `export TENUO_ADMIN_KEY`. A lingering admin key in the shell makes later `tenuo-claude up` fail.
360
+ Omit `--admin-key` if `tenuo-admin setup` already ran. Pass credentials with flags rather than `export TENUO_ADMIN_KEY`. Unset the admin key before `tenuo-claude up`; an admin key in the runtime environment causes startup to fail.
331
361
 
332
362
  One-shot env vars for CI:
333
363
 
@@ -345,9 +375,9 @@ cd my-project
345
375
  tenuo-claude onboard --cloud
346
376
  ```
347
377
 
348
- Without providing an admin key to the wizard, have an admin run `tenuo-admin setup` before `up`, or place the admin key in `~/.tenuo/admin.env` and run it yourself.
378
+ If you do not pass an admin key to the wizard, run `tenuo-admin setup` before `up`, or place the admin key in `~/.tenuo/admin.env` and run setup yourself.
349
379
 
350
- Manual equivalent. Credential templates in [templates/](templates/):
380
+ **Manual setup** (equivalent to the wizard). Credential templates are in [templates/](templates/):
351
381
 
352
382
  ```bash
353
383
  cd my-project
@@ -357,13 +387,21 @@ mkdir -p .state ~/.tenuo
357
387
 
358
388
  tenuo-claude init --cloud
359
389
  tenuo-admin setup
360
- tenuo-claude up
390
+ tenuo-claude check && tenuo-claude up
361
391
  tenuo-claude verify
362
392
  ```
363
393
 
364
- ### Success looks like
394
+ **Every session** (after onboarding):
365
395
 
366
- After onboarding:
396
+ ```bash
397
+ tenuo-claude check && tenuo-claude up
398
+ ```
399
+
400
+ If `check` reports **cloud bindings** failure, run `tenuo-admin setup` and retry.
401
+
402
+ ### Verify onboarding
403
+
404
+ After onboarding, run:
367
405
 
368
406
  ```bash
369
407
  tenuo-claude status
@@ -371,11 +409,14 @@ tenuo-claude check
371
409
  tenuo-admin show
372
410
  ```
373
411
 
374
- You should see: authorizer up, cloud profile merged, a trigger id in `tenuo-admin show`, and CHECK OK with no admin key in runtime env.
412
+ You should see: authorizer up, cloud profile merged, a trigger id in `tenuo-admin show`, **cloud bindings — trigger fire dry-run OK**, and CHECK OK with no admin key in runtime env.
375
413
 
376
414
  Re-run `tenuo-admin setup` when Cloud capabilities change — setup syncs the local
377
- gateway and reloads the authorizer when it is already running. Re-run
378
- `tenuo-claude refresh` for local-only policy edits (no Cloud trigger change).
415
+ gateway, reconciles agent/trigger/holder bindings, and reloads the authorizer when
416
+ it is already running. Re-run `tenuo-claude refresh` for local-only policy edits (no
417
+ Cloud trigger change).
418
+
419
+ Stuck? [Troubleshooting (Q&A)](docs/TROUBLESHOOTING.md).
379
420
 
380
421
  ### Human approval (Cloud)
381
422
 
@@ -392,8 +433,8 @@ Both use the same session approval policy and the same hook/proxy approval workf
392
433
 
393
434
  1. Configure a notification channel and identity binding in Cloud ([channels](https://docs.tenuo.ai/guides/adding-channels),
394
435
  [identity bindings](https://docs.tenuo.ai/integrations/identity-bindings)).
395
- 2. Add approval gates in policy. Prefer `cloud.approver_identity_id` for team/shared
396
- configs; `cloud.approver_identity` (display name) is fine for demos and quickstarts.
436
+ 2. Add approval gates in policy. Use `cloud.approver_identity_id` for team and
437
+ shared configs. Use `cloud.approver_identity` (display name) for demos only.
397
438
  See [templates/tenuo.yaml.advanced.example](templates/tenuo.yaml.advanced.example).
398
439
  3. Wire Cloud and re-run setup:
399
440
 
@@ -404,14 +445,14 @@ tenuo-claude up # if authorizer was down
404
445
  tenuo-claude verify
405
446
  ```
406
447
 
407
- For a quick demo, display-name lookup is still supported:
448
+ For demos, display-name lookup is supported:
408
449
 
409
450
  ```bash
410
451
  tenuo-claude onboard --cloud --advanced --approver "Alice Example"
411
452
  ```
412
453
 
413
- If multiple Cloud identities share a display name, setup will ask you to use
414
- `--approver-id` / `cloud.approver_identity_id`.
454
+ If multiple Cloud identities share a display name, use `--approver-id` or
455
+ `cloud.approver_identity_id` in policy.
415
456
 
416
457
  Reference demo:
417
458
 
@@ -430,9 +471,7 @@ Details: [docs/DETAILS.md § Human approval](docs/DETAILS.md#human-approval-clou
430
471
 
431
472
  ## Security
432
473
 
433
- Tenuo works **alongside** Claude Code permissions. It does not replace managed settings.
434
-
435
- You still deploy hooks. Tenuo adds a signed session warrant, a local authorizer on every tool call, and a decision log per call. Policy is one file (`tenuo.yaml`).
474
+ Tenuo works **alongside** Claude Code permissions — it does not replace managed settings. `tenuo-claude init` wires a PreToolUse hook and MCP proxy; the authorizer enforces the session warrant on every tool call and logs a receipt. Policy is one file (`tenuo.yaml`).
436
475
 
437
476
  ### vs. Claude Code permissions
438
477
 
@@ -446,7 +485,7 @@ You still deploy hooks. Tenuo adds a signed session warrant, a local authorizer
446
485
  | Org-wide deployment | Per-user settings; users can edit local hooks | Managed settings + shared policy; hook/proxy enforcement is not user-editable |
447
486
  | `--dangerously-skip-permissions` | Bypasses Claude permission prompts | Hook and MCP proxy still enforce the warrant |
448
487
 
449
- That flag skips Claude's permission UI, not the warrant.
488
+ `--dangerously-skip-permissions` skips Claude's permission UI, not the warrant.
450
489
 
451
490
  Org admins can block it in managed settings (`disableBypassPermissionsMode`).
452
491
 
@@ -463,7 +502,7 @@ For teams that need a **global configuration engineers cannot bypass**:
463
502
 
464
503
  ### Receipts
465
504
 
466
- Every governed tool call must prove possession of the session key (proof-of-possession) when asking the authorizer for allow/deny.
505
+ Every governed tool call carries a proof-of-possession signature; the authorizer verifies it before returning allow/deny.
467
506
 
468
507
  What you can **read back** depends on mode:
469
508
 
@@ -504,11 +543,25 @@ Runtime refuses to start if an admin key is in the environment.
504
543
  in version control, and the [Cloud capabilities above](#cloud-mode). See
505
544
  [Tenuo Cloud docs](https://docs.tenuo.ai).
506
545
 
507
- ### Scope and fail-closed
546
+ ### Scope and boundaries
547
+
548
+ Tenuo governs **model-invoked tool calls**: Read, Bash, WebFetch, MCP tools,
549
+ subagent spawns, and the rest of the PreToolUse hook path. Each call is checked
550
+ against the signed session warrant before it runs.
551
+
552
+ **Agent Bash is in scope.** When the model uses the Bash tool, PreToolUse fires and
553
+ the authorizer applies your policy.
554
+
555
+ **TUI `!` shell is outside this scope.** In Claude Code, typing `!` in the input
556
+ box runs a command the **operator** typed. The model cannot invoke that path.
557
+ Prompt injection and tool overreach stay on the governed PreToolUse path; they do
558
+ not reach `!`.
559
+
560
+ Details: [docs/DETAILS.md § Agent tools vs operator shell](docs/DETAILS.md#agent-tools-vs-operator-shell).
508
561
 
509
- Governance covers agent tool calls (Read, Bash, MCP, subagent spawns), not interactive `!` shell in the Claude TUI ([Map vs Territory](https://niyikiza.com/posts/map-territory/)).
562
+ ### Fail-closed
510
563
 
511
- Missing or broken `tenuo.yaml` denies every call until restored.
564
+ Missing or broken `tenuo.yaml` denies every governed tool call until restored.
512
565
 
513
566
  Keys and credentials in `.state/` must be owner-only (`0600` in a `0700` directory).
514
567