tenuo-claude-code 0.2.0__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 (56) hide show
  1. {tenuo_claude_code-0.2.0 → tenuo_claude_code-0.2.2}/.gitignore +1 -1
  2. {tenuo_claude_code-0.2.0 → tenuo_claude_code-0.2.2}/PKG-INFO +116 -65
  3. {tenuo_claude_code-0.2.0 → tenuo_claude_code-0.2.2}/README.md +115 -64
  4. {tenuo_claude_code-0.2.0 → 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.0 → 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.2/docs/images/README.md +22 -0
  9. tenuo_claude_code-0.2.2/docs/images/tenuo_claude_code_architecture.png +0 -0
  10. {tenuo_claude_code-0.2.0 → tenuo_claude_code-0.2.2}/pyproject.toml +1 -1
  11. {tenuo_claude_code-0.2.0 → tenuo_claude_code-0.2.2}/src/tenuo_claude_code/__init__.py +1 -1
  12. {tenuo_claude_code-0.2.0 → tenuo_claude_code-0.2.2}/src/tenuo_claude_code/admin.py +29 -0
  13. {tenuo_claude_code-0.2.0 → tenuo_claude_code-0.2.2}/src/tenuo_claude_code/authorizer_runtime.py +13 -1
  14. {tenuo_claude_code-0.2.0 → tenuo_claude_code-0.2.2}/src/tenuo_claude_code/cli.py +239 -56
  15. {tenuo_claude_code-0.2.0 → tenuo_claude_code-0.2.2}/templates/README.md +2 -0
  16. {tenuo_claude_code-0.2.0 → tenuo_claude_code-0.2.2}/templates/tenuo.yaml.advanced.example +2 -2
  17. {tenuo_claude_code-0.2.0 → tenuo_claude_code-0.2.2}/tests/test_admin.py +87 -0
  18. tenuo_claude_code-0.2.2/tests/test_check.py +74 -0
  19. tenuo_claude_code-0.2.2/tests/test_cloud_bindings.py +331 -0
  20. tenuo_claude_code-0.2.2/tests/test_scaffold.py +244 -0
  21. tenuo_claude_code-0.2.0/docs/images/README.md +0 -9
  22. tenuo_claude_code-0.2.0/tests/test_check.py +0 -31
  23. tenuo_claude_code-0.2.0/tests/test_scaffold.py +0 -133
  24. {tenuo_claude_code-0.2.0 → tenuo_claude_code-0.2.2}/CONTRIBUTING.md +0 -0
  25. {tenuo_claude_code-0.2.0 → tenuo_claude_code-0.2.2}/LICENSE +0 -0
  26. {tenuo_claude_code-0.2.0 → tenuo_claude_code-0.2.2}/demo/.claude/agents/researcher.md +0 -0
  27. {tenuo_claude_code-0.2.0 → tenuo_claude_code-0.2.2}/demo/.mcp.json +0 -0
  28. {tenuo_claude_code-0.2.0 → tenuo_claude_code-0.2.2}/demo/fake-secrets.env +0 -0
  29. {tenuo_claude_code-0.2.0 → tenuo_claude_code-0.2.2}/demo/ops_server.py +0 -0
  30. {tenuo_claude_code-0.2.0 → tenuo_claude_code-0.2.2}/demo/sandbox/incident-report.md +0 -0
  31. {tenuo_claude_code-0.2.0 → tenuo_claude_code-0.2.2}/demo/sandbox/notes.txt +0 -0
  32. {tenuo_claude_code-0.2.0 → tenuo_claude_code-0.2.2}/demo/tenuo.yaml +0 -0
  33. {tenuo_claude_code-0.2.0 → tenuo_claude_code-0.2.2}/demo/tenuo_demo.py +0 -0
  34. {tenuo_claude_code-0.2.0 → tenuo_claude_code-0.2.2}/docs/images/cloud-audit-stream.png +0 -0
  35. {tenuo_claude_code-0.2.0 → tenuo_claude_code-0.2.2}/docs/images/cloud-receipt-approval-detail.png +0 -0
  36. {tenuo_claude_code-0.2.0 → tenuo_claude_code-0.2.2}/docs/images/tenuo_claude_code_architecture.svg +0 -0
  37. {tenuo_claude_code-0.2.0 → tenuo_claude_code-0.2.2}/examples/policies/README.md +0 -0
  38. {tenuo_claude_code-0.2.0 → tenuo_claude_code-0.2.2}/examples/policies/audit-rollout.yaml +0 -0
  39. {tenuo_claude_code-0.2.0 → tenuo_claude_code-0.2.2}/examples/policies/enforce-with-mcp.yaml +0 -0
  40. {tenuo_claude_code-0.2.0 → tenuo_claude_code-0.2.2}/examples/policies/read-only-research.yaml +0 -0
  41. {tenuo_claude_code-0.2.0 → tenuo_claude_code-0.2.2}/src/tenuo_claude_code/data/harness_tools.yaml +0 -0
  42. {tenuo_claude_code-0.2.0 → tenuo_claude_code-0.2.2}/src/tenuo_claude_code/paths.py +0 -0
  43. {tenuo_claude_code-0.2.0 → tenuo_claude_code-0.2.2}/src/tenuo_claude_code/templates/tenuo.yaml.example +0 -0
  44. {tenuo_claude_code-0.2.0 → tenuo_claude_code-0.2.2}/src/tenuo_claude_code/verify.py +0 -0
  45. {tenuo_claude_code-0.2.0 → tenuo_claude_code-0.2.2}/templates/admin.env.example +0 -0
  46. {tenuo_claude_code-0.2.0 → tenuo_claude_code-0.2.2}/templates/cloud.env.example +0 -0
  47. {tenuo_claude_code-0.2.0 → tenuo_claude_code-0.2.2}/templates/tenuo.yaml.cloud.example +0 -0
  48. {tenuo_claude_code-0.2.0 → tenuo_claude_code-0.2.2}/templates/tenuo.yaml.example +0 -0
  49. {tenuo_claude_code-0.2.0 → tenuo_claude_code-0.2.2}/tests/conftest.py +0 -0
  50. {tenuo_claude_code-0.2.0 → tenuo_claude_code-0.2.2}/tests/test_approvals.py +0 -0
  51. {tenuo_claude_code-0.2.0 → tenuo_claude_code-0.2.2}/tests/test_authorize_call.py +0 -0
  52. {tenuo_claude_code-0.2.0 → tenuo_claude_code-0.2.2}/tests/test_authorizer_runtime.py +0 -0
  53. {tenuo_claude_code-0.2.0 → tenuo_claude_code-0.2.2}/tests/test_constraints.py +0 -0
  54. {tenuo_claude_code-0.2.0 → tenuo_claude_code-0.2.2}/tests/test_permissions.py +0 -0
  55. {tenuo_claude_code-0.2.0 → tenuo_claude_code-0.2.2}/tests/test_routing.py +0 -0
  56. {tenuo_claude_code-0.2.0 → 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.0
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
@@ -30,8 +30,6 @@ Description-Content-Type: text/markdown
30
30
 
31
31
  # Tenuo for Claude Code
32
32
 
33
- PyPI package: [`tenuo-claude-code`](https://pypi.org/project/tenuo-claude-code/) · CLI: `tenuo-claude`, `tenuo-admin`
34
-
35
33
  [![PyPI](https://img.shields.io/pypi/v/tenuo-claude-code)](https://pypi.org/project/tenuo-claude-code/)
36
34
  [![Python](https://img.shields.io/pypi/pyversions/tenuo-claude-code)](https://pypi.org/project/tenuo-claude-code/)
37
35
  [![CI](https://github.com/tenuo-ai/claude-governance/actions/workflows/ci.yml/badge.svg)](https://github.com/tenuo-ai/claude-governance/actions/workflows/ci.yml)
@@ -53,9 +51,21 @@ mkdir my-project && cd my-project
53
51
  tenuo-claude bootstrap
54
52
  ```
55
53
 
56
- 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
+
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:
57
64
 
58
- 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`.
65
+ ```bash
66
+ export TENUO_AUTHORIZER_BACKEND=native
67
+ tenuo-claude bootstrap
68
+ ```
59
69
 
60
70
  ### Where to go next
61
71
 
@@ -63,15 +73,16 @@ No Docker, or prefer native? Run `tenuo-claude install-authorizer` once, then `b
63
73
  |-----------------|------------|
64
74
  | Day-to-day commands, ports, CLI reference | [Use the tool](#use-the-tool-pypi) |
65
75
  | Edit or replace the example policy | [Policy](#policy-tenuoyaml) |
66
- | 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) |
67
77
  | Connect to Tenuo Cloud | [Cloud mode](#cloud-mode) |
68
78
  | Review security posture | [Security](#security) |
69
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) |
70
81
  | Implementation depth | [docs/DETAILS.md](docs/DETAILS.md) |
71
82
 
72
83
  ## How it works
73
84
 
74
- ![Architecture](docs/images/tenuo_claude_code_architecture.svg)
85
+ ![Architecture](https://raw.githubusercontent.com/tenuo-ai/claude-governance/main/docs/images/tenuo_claude_code_architecture.png)
75
86
 
76
87
  ```
77
88
  tenuo.yaml → init/up → warrant + authorizer + hooks + MCP proxy
@@ -87,41 +98,42 @@ tenuo.yaml → init/up → warrant + authorizer + hooks + MCP proxy
87
98
 
88
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.
89
100
 
90
- Both paths use the same warrant and authorizer.
91
-
92
101
  More: [docs/DETAILS.md](docs/DETAILS.md)
93
102
 
94
103
  ## Prerequisites
95
104
 
96
105
  - Python ≥ 3.10
97
- - **Authorizer runtime** (pick one):
98
- - **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.
99
- - **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.
100
-
101
- Without Docker, `bootstrap` uses native. Run `install-authorizer` first. To force native while Docker is running, set `TENUO_AUTHORIZER_BACKEND=native`.
102
- - [Claude Code](https://code.claude.com/docs) for live agent use. Optional: `verify` works without it.
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`.
103
111
 
104
- **Local mode:** no Tenuo Cloud account. Good for one project or evaluation.
112
+ **Local mode:** no Tenuo Cloud account. Suitable for single-project evaluation.
105
113
 
106
- **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)).
107
115
 
108
116
  ---
109
117
 
110
118
  ## Use the tool (PyPI)
111
119
 
112
- 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`.
113
121
 
114
122
  ### Day to day
115
123
 
116
124
  | When | Command |
117
125
  |------|---------|
118
- | Start work | `tenuo-claude up` or `tenuo-claude up --native` |
119
- | You edited `tenuo.yaml` | `tenuo-claude refresh` |
120
- | 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` |
121
131
  | See decisions | `tenuo-claude audit` |
122
132
  | Stop authorizer | `tenuo-claude down` |
123
133
 
124
- 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.
125
137
 
126
138
  ### Port conflicts
127
139
 
@@ -148,13 +160,15 @@ tenuo-claude up
148
160
  tenuo-claude verify
149
161
  ```
150
162
 
151
- 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.
152
164
 
153
165
  ### Reference demo
154
166
 
155
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.
156
168
 
157
- **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`):
158
172
 
159
173
  ```bash
160
174
  cd demo
@@ -162,18 +176,37 @@ tenuo-claude bootstrap
162
176
  tenuo-claude demo
163
177
  ```
164
178
 
165
- **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):
166
180
 
167
181
  ```bash
168
182
  cd demo
169
- 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
170
199
  tenuo-claude verify
171
200
  tenuo-claude demo
172
201
  ```
173
202
 
203
+ If `check` fails on **cloud bindings** → `tenuo-admin setup`, then retry.
204
+
174
205
  For human approval: [Cloud mode § Human approval](#human-approval-cloud), then `tenuo-claude demo --advanced --live-approval`.
175
206
 
176
- 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).
177
210
 
178
211
  From a git checkout, see [Build from source](#build-from-source).
179
212
 
@@ -186,21 +219,21 @@ From a git checkout, see [Build from source](#build-from-source).
186
219
  | `up` / `down` | Start / stop authorizer. `up` flags: `--native`, `--docker`, `--install` (native, first run) |
187
220
  | `install-authorizer` | Install `tenuo-authorizer` to `~/.tenuo/bin` (no manual `cargo`) |
188
221
  | `refresh` | Re-apply `tenuo.yaml` (restarts authorizer if up) |
189
- | `check` | Preflight: deps, credentials, wiring drift |
190
- | `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) |
191
224
  | `status` | Warrant, posture, Cloud summary |
192
225
  | `onboard` | Interactive local or Cloud setup wizard |
193
226
  | `bench [--json]` | Per-tool-call overhead |
194
227
  | `audit [--tail N]` | Receipt trail |
195
228
  | `revoke` | Revoke session warrant |
196
229
 
197
- 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)
198
231
 
199
232
  ---
200
233
 
201
234
  ## Build from source
202
235
 
203
- 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.
204
237
 
205
238
  ```bash
206
239
  git clone https://github.com/tenuo-ai/claude-governance.git
@@ -224,13 +257,14 @@ Run commands via the repo launcher or editable install:
224
257
 
225
258
  ```bash
226
259
  cd demo
227
- 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
228
261
  tenuo-claude demo
229
262
  ```
230
263
 
231
- 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`.
232
266
 
233
- 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.
234
268
 
235
269
  Open Claude Code in `demo/`. See [demo/README.md](demo/README.md) and [Reference demo](#reference-demo) above.
236
270
 
@@ -294,8 +328,6 @@ Use Cloud when you need organization-scale governance, not just a single laptop:
294
328
  every tool call at the hook and MCP proxy. Engineers cannot disable it with local
295
329
  Claude permission edits or `--dangerously-skip-permissions`
296
330
 
297
- Local mode (no Cloud account) remains fully supported for evaluation and single-project use.
298
-
299
331
  ### Cloud quickstart
300
332
 
301
333
  Two keys, two files. Runtime never sees the admin key:
@@ -307,9 +339,7 @@ Two keys, two files. Runtime never sees the admin key:
307
339
 
308
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.
309
341
 
310
- **Fresh project**
311
-
312
- Creates an example `tenuo.yaml` if none exists.
342
+ **Fresh project** (creates `tenuo.yaml` if none exists):
313
343
 
314
344
  ```bash
315
345
  pip install tenuo-claude-code
@@ -317,9 +347,7 @@ mkdir my-project && cd my-project
317
347
  tenuo-claude bootstrap --cloud
318
348
  ```
319
349
 
320
- 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.
321
-
322
- 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.
323
351
 
324
352
  Non-interactive:
325
353
 
@@ -329,7 +357,7 @@ tenuo-claude bootstrap --cloud --yes \
329
357
  --admin-key "tc_…"
330
358
  ```
331
359
 
332
- 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.
333
361
 
334
362
  One-shot env vars for CI:
335
363
 
@@ -347,9 +375,9 @@ cd my-project
347
375
  tenuo-claude onboard --cloud
348
376
  ```
349
377
 
350
- 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.
351
379
 
352
- Manual equivalent. Credential templates in [templates/](templates/):
380
+ **Manual setup** (equivalent to the wizard). Credential templates are in [templates/](templates/):
353
381
 
354
382
  ```bash
355
383
  cd my-project
@@ -359,13 +387,21 @@ mkdir -p .state ~/.tenuo
359
387
 
360
388
  tenuo-claude init --cloud
361
389
  tenuo-admin setup
362
- tenuo-claude up
390
+ tenuo-claude check && tenuo-claude up
363
391
  tenuo-claude verify
364
392
  ```
365
393
 
366
- ### Success looks like
394
+ **Every session** (after onboarding):
395
+
396
+ ```bash
397
+ tenuo-claude check && tenuo-claude up
398
+ ```
399
+
400
+ If `check` reports **cloud bindings** failure, run `tenuo-admin setup` and retry.
367
401
 
368
- After onboarding:
402
+ ### Verify onboarding
403
+
404
+ After onboarding, run:
369
405
 
370
406
  ```bash
371
407
  tenuo-claude status
@@ -373,11 +409,14 @@ tenuo-claude check
373
409
  tenuo-admin show
374
410
  ```
375
411
 
376
- 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.
377
413
 
378
414
  Re-run `tenuo-admin setup` when Cloud capabilities change — setup syncs the local
379
- gateway and reloads the authorizer when it is already running. Re-run
380
- `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).
381
420
 
382
421
  ### Human approval (Cloud)
383
422
 
@@ -394,8 +433,8 @@ Both use the same session approval policy and the same hook/proxy approval workf
394
433
 
395
434
  1. Configure a notification channel and identity binding in Cloud ([channels](https://docs.tenuo.ai/guides/adding-channels),
396
435
  [identity bindings](https://docs.tenuo.ai/integrations/identity-bindings)).
397
- 2. Add approval gates in policy. Prefer `cloud.approver_identity_id` for team/shared
398
- 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.
399
438
  See [templates/tenuo.yaml.advanced.example](templates/tenuo.yaml.advanced.example).
400
439
  3. Wire Cloud and re-run setup:
401
440
 
@@ -406,14 +445,14 @@ tenuo-claude up # if authorizer was down
406
445
  tenuo-claude verify
407
446
  ```
408
447
 
409
- For a quick demo, display-name lookup is still supported:
448
+ For demos, display-name lookup is supported:
410
449
 
411
450
  ```bash
412
451
  tenuo-claude onboard --cloud --advanced --approver "Alice Example"
413
452
  ```
414
453
 
415
- If multiple Cloud identities share a display name, setup will ask you to use
416
- `--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.
417
456
 
418
457
  Reference demo:
419
458
 
@@ -432,9 +471,7 @@ Details: [docs/DETAILS.md § Human approval](docs/DETAILS.md#human-approval-clou
432
471
 
433
472
  ## Security
434
473
 
435
- Tenuo works **alongside** Claude Code permissions. It does not replace managed settings.
436
-
437
- 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`).
438
475
 
439
476
  ### vs. Claude Code permissions
440
477
 
@@ -448,7 +485,7 @@ You still deploy hooks. Tenuo adds a signed session warrant, a local authorizer
448
485
  | Org-wide deployment | Per-user settings; users can edit local hooks | Managed settings + shared policy; hook/proxy enforcement is not user-editable |
449
486
  | `--dangerously-skip-permissions` | Bypasses Claude permission prompts | Hook and MCP proxy still enforce the warrant |
450
487
 
451
- That flag skips Claude's permission UI, not the warrant.
488
+ `--dangerously-skip-permissions` skips Claude's permission UI, not the warrant.
452
489
 
453
490
  Org admins can block it in managed settings (`disableBypassPermissionsMode`).
454
491
 
@@ -465,7 +502,7 @@ For teams that need a **global configuration engineers cannot bypass**:
465
502
 
466
503
  ### Receipts
467
504
 
468
- 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.
469
506
 
470
507
  What you can **read back** depends on mode:
471
508
 
@@ -483,7 +520,7 @@ In `mode: audit`, denials show as `WOULD-DENY` in `audit` output (`shadow: true`
483
520
 
484
521
  These are the non-repudiable receipts for compliance and fleet audit, not the local JSONL file.
485
522
 
486
- ![Authorization receipts in Tenuo Cloud](docs/images/cloud-audit-stream.png)
523
+ ![Authorization receipts in Tenuo Cloud](https://raw.githubusercontent.com/tenuo-ai/claude-governance/main/docs/images/cloud-audit-stream.png)
487
524
 
488
525
  More: [docs/DETAILS.md § Receipts](docs/DETAILS.md#receipts).
489
526
 
@@ -506,11 +543,25 @@ Runtime refuses to start if an admin key is in the environment.
506
543
  in version control, and the [Cloud capabilities above](#cloud-mode). See
507
544
  [Tenuo Cloud docs](https://docs.tenuo.ai).
508
545
 
509
- ### 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).
510
561
 
511
- 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
512
563
 
513
- Missing or broken `tenuo.yaml` denies every call until restored.
564
+ Missing or broken `tenuo.yaml` denies every governed tool call until restored.
514
565
 
515
566
  Keys and credentials in `.state/` must be owner-only (`0600` in a `0700` directory).
516
567