vb-os 0.1.0__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 (145) hide show
  1. vb_os-0.1.0/.github/workflows/publish.yml +42 -0
  2. vb_os-0.1.0/.gitignore +12 -0
  3. vb_os-0.1.0/LICENSE +6 -0
  4. vb_os-0.1.0/MANIFEST.md +279 -0
  5. vb_os-0.1.0/PKG-INFO +500 -0
  6. vb_os-0.1.0/README.md +463 -0
  7. vb_os-0.1.0/SETUP.md +503 -0
  8. vb_os-0.1.0/docs/cli-developer-manual.md +455 -0
  9. vb_os-0.1.0/docs/cli-operator-manual.md +371 -0
  10. vb_os-0.1.0/postman/vb-os-python-sdk.postman_collection.json +522 -0
  11. vb_os-0.1.0/pyproject.toml +80 -0
  12. vb_os-0.1.0/scripts/install.sh +238 -0
  13. vb_os-0.1.0/tests/__init__.py +0 -0
  14. vb_os-0.1.0/tests/cli/__init__.py +1 -0
  15. vb_os-0.1.0/tests/cli/conftest.py +72 -0
  16. vb_os-0.1.0/tests/cli/test_account.py +119 -0
  17. vb_os-0.1.0/tests/cli/test_alert_rules.py +343 -0
  18. vb_os-0.1.0/tests/cli/test_analytics.py +79 -0
  19. vb_os-0.1.0/tests/cli/test_audit_log.py +110 -0
  20. vb_os-0.1.0/tests/cli/test_auth.py +638 -0
  21. vb_os-0.1.0/tests/cli/test_boundaries.py +810 -0
  22. vb_os-0.1.0/tests/cli/test_certify.py +307 -0
  23. vb_os-0.1.0/tests/cli/test_cli.py +123 -0
  24. vb_os-0.1.0/tests/cli/test_client.py +256 -0
  25. vb_os-0.1.0/tests/cli/test_command_registration.py +68 -0
  26. vb_os-0.1.0/tests/cli/test_completions.py +22 -0
  27. vb_os-0.1.0/tests/cli/test_config.py +74 -0
  28. vb_os-0.1.0/tests/cli/test_config_fallback.py +58 -0
  29. vb_os-0.1.0/tests/cli/test_connectors.py +393 -0
  30. vb_os-0.1.0/tests/cli/test_connectors_oauth.py +607 -0
  31. vb_os-0.1.0/tests/cli/test_credentials.py +391 -0
  32. vb_os-0.1.0/tests/cli/test_deployments.py +299 -0
  33. vb_os-0.1.0/tests/cli/test_environments.py +273 -0
  34. vb_os-0.1.0/tests/cli/test_error_handling.py +121 -0
  35. vb_os-0.1.0/tests/cli/test_evaluations.py +435 -0
  36. vb_os-0.1.0/tests/cli/test_flows.py +709 -0
  37. vb_os-0.1.0/tests/cli/test_formatters.py +138 -0
  38. vb_os-0.1.0/tests/cli/test_governed_workspaces.py +180 -0
  39. vb_os-0.1.0/tests/cli/test_integration.py +386 -0
  40. vb_os-0.1.0/tests/cli/test_integration_s0032.py +405 -0
  41. vb_os-0.1.0/tests/cli/test_keys.py +336 -0
  42. vb_os-0.1.0/tests/cli/test_local_bridge.py +132 -0
  43. vb_os-0.1.0/tests/cli/test_members.py +122 -0
  44. vb_os-0.1.0/tests/cli/test_named_sets.py +146 -0
  45. vb_os-0.1.0/tests/cli/test_notifications.py +106 -0
  46. vb_os-0.1.0/tests/cli/test_org_mgmt.py +104 -0
  47. vb_os-0.1.0/tests/cli/test_output.py +93 -0
  48. vb_os-0.1.0/tests/cli/test_profiles.py +26 -0
  49. vb_os-0.1.0/tests/cli/test_projects.py +311 -0
  50. vb_os-0.1.0/tests/cli/test_replay.py +165 -0
  51. vb_os-0.1.0/tests/cli/test_templates.py +114 -0
  52. vb_os-0.1.0/tests/cli/test_verify.py +357 -0
  53. vb_os-0.1.0/tests/cli/test_webhooks.py +427 -0
  54. vb_os-0.1.0/tests/cli/test_workspaces.py +121 -0
  55. vb_os-0.1.0/tests/conftest.py +71 -0
  56. vb_os-0.1.0/tests/contract/__init__.py +0 -0
  57. vb_os-0.1.0/tests/contract/test_sdk_contracts.py +2308 -0
  58. vb_os-0.1.0/tests/contract/test_verify_contract.py +172 -0
  59. vb_os-0.1.0/tests/test_async_client.py +188 -0
  60. vb_os-0.1.0/tests/test_async_evaluations.py +154 -0
  61. vb_os-0.1.0/tests/test_client.py +178 -0
  62. vb_os-0.1.0/tests/test_connectors_oauth.py +347 -0
  63. vb_os-0.1.0/tests/test_cross_cutting.py +350 -0
  64. vb_os-0.1.0/tests/test_endpoint_manifest.py +440 -0
  65. vb_os-0.1.0/tests/test_evaluations.py +198 -0
  66. vb_os-0.1.0/tests/test_exceptions.py +152 -0
  67. vb_os-0.1.0/tests/test_models.py +79 -0
  68. vb_os-0.1.0/tests/test_retry.py +143 -0
  69. vb_os-0.1.0/vbos/__init__.py +229 -0
  70. vb_os-0.1.0/vbos/_transport.py +40 -0
  71. vb_os-0.1.0/vbos/client.py +505 -0
  72. vb_os-0.1.0/vbos/exceptions.py +136 -0
  73. vb_os-0.1.0/vbos/models.py +920 -0
  74. vb_os-0.1.0/vbos/py.typed +0 -0
  75. vb_os-0.1.0/vbos/resources/__init__.py +0 -0
  76. vb_os-0.1.0/vbos/resources/account.py +96 -0
  77. vb_os-0.1.0/vbos/resources/alert_rules.py +125 -0
  78. vb_os-0.1.0/vbos/resources/analytics.py +144 -0
  79. vb_os-0.1.0/vbos/resources/audit_log.py +80 -0
  80. vb_os-0.1.0/vbos/resources/billing.py +64 -0
  81. vb_os-0.1.0/vbos/resources/boundaries.py +278 -0
  82. vb_os-0.1.0/vbos/resources/certification_models.py +107 -0
  83. vb_os-0.1.0/vbos/resources/certifications.py +147 -0
  84. vb_os-0.1.0/vbos/resources/connector_providers.py +67 -0
  85. vb_os-0.1.0/vbos/resources/connectors.py +541 -0
  86. vb_os-0.1.0/vbos/resources/deployments.py +261 -0
  87. vb_os-0.1.0/vbos/resources/environments.py +171 -0
  88. vb_os-0.1.0/vbos/resources/flow_templates.py +67 -0
  89. vb_os-0.1.0/vbos/resources/flows.py +458 -0
  90. vb_os-0.1.0/vbos/resources/governed_workspaces.py +349 -0
  91. vb_os-0.1.0/vbos/resources/keys.py +251 -0
  92. vb_os-0.1.0/vbos/resources/members.py +135 -0
  93. vb_os-0.1.0/vbos/resources/named_sets.py +146 -0
  94. vb_os-0.1.0/vbos/resources/notifications.py +83 -0
  95. vb_os-0.1.0/vbos/resources/org.py +135 -0
  96. vb_os-0.1.0/vbos/resources/projects.py +210 -0
  97. vb_os-0.1.0/vbos/resources/service_accounts.py +111 -0
  98. vb_os-0.1.0/vbos/resources/templates.py +80 -0
  99. vb_os-0.1.0/vbos/resources/users.py +53 -0
  100. vb_os-0.1.0/vbos/resources/webhooks.py +194 -0
  101. vb_os-0.1.0/vbos/resources/workspaces.py +170 -0
  102. vb_os-0.1.0/vbos/retry.py +72 -0
  103. vb_os-0.1.0/vbos_cli/__init__.py +3 -0
  104. vb_os-0.1.0/vbos_cli/__main__.py +5 -0
  105. vb_os-0.1.0/vbos_cli/cli.py +218 -0
  106. vb_os-0.1.0/vbos_cli/client.py +215 -0
  107. vb_os-0.1.0/vbos_cli/commands/__init__.py +1 -0
  108. vb_os-0.1.0/vbos_cli/commands/account.py +155 -0
  109. vb_os-0.1.0/vbos_cli/commands/alert_rules.py +205 -0
  110. vb_os-0.1.0/vbos_cli/commands/analytics.py +53 -0
  111. vb_os-0.1.0/vbos_cli/commands/audit_log.py +109 -0
  112. vb_os-0.1.0/vbos_cli/commands/auth.py +397 -0
  113. vb_os-0.1.0/vbos_cli/commands/boundaries.py +504 -0
  114. vb_os-0.1.0/vbos_cli/commands/certify.py +316 -0
  115. vb_os-0.1.0/vbos_cli/commands/completions.py +36 -0
  116. vb_os-0.1.0/vbos_cli/commands/config_cmd.py +101 -0
  117. vb_os-0.1.0/vbos_cli/commands/connectors.py +596 -0
  118. vb_os-0.1.0/vbos_cli/commands/deployments.py +248 -0
  119. vb_os-0.1.0/vbos_cli/commands/environments.py +213 -0
  120. vb_os-0.1.0/vbos_cli/commands/evaluations.py +236 -0
  121. vb_os-0.1.0/vbos_cli/commands/flows.py +812 -0
  122. vb_os-0.1.0/vbos_cli/commands/governed_workspaces.py +239 -0
  123. vb_os-0.1.0/vbos_cli/commands/keys.py +221 -0
  124. vb_os-0.1.0/vbos_cli/commands/members.py +187 -0
  125. vb_os-0.1.0/vbos_cli/commands/named_sets.py +190 -0
  126. vb_os-0.1.0/vbos_cli/commands/notifications.py +135 -0
  127. vb_os-0.1.0/vbos_cli/commands/org.py +83 -0
  128. vb_os-0.1.0/vbos_cli/commands/org_mgmt.py +121 -0
  129. vb_os-0.1.0/vbos_cli/commands/projects.py +330 -0
  130. vb_os-0.1.0/vbos_cli/commands/replay.py +44 -0
  131. vb_os-0.1.0/vbos_cli/commands/templates.py +128 -0
  132. vb_os-0.1.0/vbos_cli/commands/verify.py +150 -0
  133. vb_os-0.1.0/vbos_cli/commands/webhooks.py +353 -0
  134. vb_os-0.1.0/vbos_cli/commands/workspaces.py +163 -0
  135. vb_os-0.1.0/vbos_cli/config.py +99 -0
  136. vb_os-0.1.0/vbos_cli/credentials/__init__.py +1 -0
  137. vb_os-0.1.0/vbos_cli/credentials/file.py +141 -0
  138. vb_os-0.1.0/vbos_cli/credentials/keychain.py +54 -0
  139. vb_os-0.1.0/vbos_cli/credentials/migration.py +39 -0
  140. vb_os-0.1.0/vbos_cli/credentials/store.py +124 -0
  141. vb_os-0.1.0/vbos_cli/errors.py +40 -0
  142. vb_os-0.1.0/vbos_cli/formatters.py +288 -0
  143. vb_os-0.1.0/vbos_cli/local_bridge.py +233 -0
  144. vb_os-0.1.0/vbos_cli/output.py +67 -0
  145. vb_os-0.1.0/vbos_cli/profiles.py +15 -0
@@ -0,0 +1,42 @@
1
+ name: Publish to PyPI
2
+
3
+ on:
4
+ release:
5
+ types: [published]
6
+
7
+ permissions:
8
+ contents: read
9
+
10
+ jobs:
11
+ test:
12
+ runs-on: ubuntu-latest
13
+ strategy:
14
+ matrix:
15
+ python-version: ["3.11", "3.12", "3.13"]
16
+ steps:
17
+ - uses: actions/checkout@v4
18
+ - uses: actions/setup-python@v5
19
+ with:
20
+ python-version: ${{ matrix.python-version }}
21
+ - run: pip install -e ".[cli,dev]"
22
+ - run: ruff check vbos/ vbos_cli/
23
+ - run: pytest tests/ -v --tb=short
24
+
25
+ publish:
26
+ needs: test
27
+ runs-on: ubuntu-latest
28
+ environment: pypi
29
+ steps:
30
+ - uses: actions/checkout@v4
31
+ - uses: actions/setup-python@v5
32
+ with:
33
+ python-version: "3.12"
34
+ - run: pip install build
35
+ - run: python -m build
36
+ - name: Verify no binary artifacts in sdist
37
+ run: |
38
+ tar tzf dist/*.tar.gz | grep -E '\.(so|dylib|dll|exe)$' && exit 1 || true
39
+ - name: Publish to PyPI
40
+ uses: pypa/gh-action-pypi-publish@release/v1
41
+ with:
42
+ password: ${{ secrets.PYPI_API_TOKEN }}
vb_os-0.1.0/.gitignore ADDED
@@ -0,0 +1,12 @@
1
+ __pycache__/
2
+ *.pyc
3
+ *.pyo
4
+ *.egg-info/
5
+ dist/
6
+ build/
7
+ .venv/
8
+ .pytest_cache/
9
+ .coverage
10
+ *.egg
11
+ .mypy_cache/
12
+ .ruff_cache/
vb_os-0.1.0/LICENSE ADDED
@@ -0,0 +1,6 @@
1
+ Copyright (c) 2024-2026 MNC Labs, Inc. All rights reserved.
2
+
3
+ This software is proprietary and confidential. Unauthorized copying, modification,
4
+ distribution, or use of this software, via any medium, is strictly prohibited.
5
+
6
+ For licensing inquiries, contact: legal@vb-os.org
@@ -0,0 +1,279 @@
1
+ # VB-OS Python SDK — Manifest
2
+
3
+ ## Ticket
4
+
5
+ CP1-S0049 — Python SDK Core Architecture (issue #1)
6
+
7
+ ## Package
8
+
9
+ - **PyPI name:** `vb-os`
10
+ - **Import name:** `vbos`
11
+ - **Version:** 0.1.0
12
+ - **Python:** >=3.10
13
+ - **Dependencies:** httpx >=0.27.0,<1.0.0, pydantic >=2.0.0,<3.0.0
14
+
15
+ ## Files
16
+
17
+ ### Source (`vbos/`)
18
+
19
+ | File | Purpose |
20
+ |------|---------|
21
+ | `__init__.py` | Package init — exports all public classes + ~80 models, `__version__` |
22
+ | `_transport.py` | Shared HTTP helpers: `handle_json_response`, `parse_error_body`, `extract_request_id`, `extract_retry_after` |
23
+ | `exceptions.py` | Exception hierarchy: VBOSError base, 6 typed subclasses, `raise_for_status()` |
24
+ | `models.py` | Typed Pydantic response models matching API schema (~80 models, all `extra="ignore"`) |
25
+ | `retry.py` | Full jitter exponential backoff — `compute_delay()`, `sync_retry()`, `async_retry()` |
26
+ | `client.py` | VBOSClient (sync) + AsyncVBOSClient (async) with 27 resource namespaces + top-level `verify()`, `verify_batch()`, `validate()`, `certify()`, `replay()` |
27
+
28
+ ### Resource Modules (`vbos/resources/`)
29
+
30
+ | File | Sync/Async Classes | Methods |
31
+ |------|--------------------|---------|
32
+ | `__init__.py` | Package init | — |
33
+ | `account.py` | SyncAccount / AsyncAccount | delete, cancel_delete, deletion_status, export, export_latest, export_status, export_download |
34
+ | `alert_rules.py` | SyncAlertRules / AsyncAlertRules | create, list, get, update (PUT), delete |
35
+ | `analytics.py` | SyncAnalytics / AsyncAnalytics | assertion_rate, deferral_rate, evaluations, failure_reasons, latency |
36
+ | `audit_log.py` | SyncAuditLog / AsyncAuditLog | list, export, export_status |
37
+ | `billing.py` | SyncBilling / AsyncBilling | usage, subscription, invoices |
38
+ | `boundaries.py` | SyncBoundaries / AsyncBoundaries | list, create, get, update_draft, submit, versions, get_version, approve, reject, diff |
39
+ | `certification_models.py` | SyncCertificationModels / AsyncCertificationModels | list, create, create_version |
40
+ | `certifications.py` | SyncCertifications / AsyncCertifications | list, get, get_report, wait (polling helper) |
41
+ | `connector_providers.py` | SyncConnectorProviders / AsyncConnectorProviders | list, schema |
42
+ | `connectors.py` | SyncConnectors / AsyncConnectors | create, list, get, update, delete, test, gather, analytics, resources, schema, get_schedule, set_schedule, list_gathers, authorize, disconnect, reconnect, oauth_status, wait_for_authorization |
43
+ | `deployments.py` | SyncDeployments / AsyncDeployments | list, create, active, approve, reject, promote, rollback |
44
+ | `environments.py` | SyncEnvironments / AsyncEnvironments | list, create, get, update, deactivate, reactivate |
45
+ | `flow_templates.py` | SyncFlowTemplates / AsyncFlowTemplates | list, get |
46
+ | `flows.py` | SyncFlows / AsyncFlows | create, list, get, update, delete, export, import_flow, from_template, create_version, list_versions, get_version, update_version, delete_version, approve_version, deploy, suspend, dry_run, list_executions, reconstruct_execution |
47
+ | `governed_workspaces.py` | SyncGovernedWorkspaces / AsyncGovernedWorkspaces | create, list, get, create_version, get_version, submit, approve, deploy, archive, create_instance, submit_instance, get_instance |
48
+ | `keys.py` | SyncKeys / AsyncKeys | list, create, get, rotate, revoke, disable, enable |
49
+ | `members.py` | SyncMembers / AsyncMembers | list, invite, set_role, remove, suspend, reactivate, revoke_invitation |
50
+ | `named_sets.py` | SyncNamedSets / AsyncNamedSets | create, list, get, update, delete, usage |
51
+ | `notifications.py` | SyncNotifications / AsyncNotifications | list, read, unread |
52
+ | `org.py` | SyncOrg / AsyncOrg | get, update, get_settings, update_settings, get_ai_policy, update_ai_policy, transfer_ownership, accept_transfer, cancel_transfer, get_transfer |
53
+ | `projects.py` | SyncProjects / AsyncProjects | list, create, get, update, archive, delete, list_members, add_member, remove_member, update_member |
54
+ | `service_accounts.py` | SyncServiceAccounts / AsyncServiceAccounts | list, create, update, disable, enable |
55
+ | `templates.py` | SyncTemplates / AsyncTemplates | list, get, fork |
56
+ | `users.py` | SyncUsers / AsyncUsers | me, organizations |
57
+ | `webhooks.py` | SyncWebhooks / AsyncWebhooks | list, create, update, delete, rotate_secret, deliveries, list_org, create_org |
58
+ | `workspaces.py` | SyncWorkspaces / AsyncWorkspaces | list, create, get, update, archive, delete, list_members, add_member, remove_member |
59
+
60
+ **Total:** 27 resource modules, 180 endpoint-backed methods + 1 polling helper (`certifications.wait`)
61
+
62
+ ### Tests (`tests/`)
63
+
64
+ | File | Purpose | Count |
65
+ |------|---------|-------|
66
+ | `conftest.py` | Shared mock response fixtures (ASSERT, DEFER, error) | — |
67
+ | `test_exceptions.py` | Exception hierarchy + `raise_for_status()` | 18 |
68
+ | `test_models.py` | Pydantic model parsing (ASSERT, DEFER, sub-models) | 9 |
69
+ | `test_retry.py` | Retry logic (is_retryable, compute_delay, sync/async retry) | 18 |
70
+ | `test_client.py` | VBOSClient init + verify() happy/error paths | 15 |
71
+ | `test_async_client.py` | AsyncVBOSClient init + verify() happy/error paths | 13 |
72
+ | `test_async_evaluations.py` | AsyncVBOSClient evaluations replay, list, get | 6 |
73
+ | `tests/contract/test_verify_contract.py` | SDK ↔ API contract validation (sync + async) | 10 |
74
+ | `tests/contract/test_sdk_contracts.py` | Per-resource HTTP method/path contracts (CC-01 through CC-23) | ~73 |
75
+ | `test_endpoint_manifest.py` | 180-row ledger: sync+async method existence, parity, signature parity | 364 |
76
+ | `test_cross_cutting.py` | Forward compat (XC-02/03), secret leakage (XC-04), query params (XC-06), immutability (XC-07), error parity (XC-08/13), certifications.wait (XC-09/10/11), pagination cursors (XC-14) | 93 |
77
+ | **Total** | | **~1100** |
78
+
79
+ ### Configuration
80
+
81
+ | File | Purpose |
82
+ |------|---------|
83
+ | `pyproject.toml` | Package config, build, dev deps, tool configs (pytest, ruff, mypy) |
84
+ | `README.md` | Package README with quick start |
85
+
86
+ ### Postman
87
+
88
+ | File | Purpose |
89
+ |------|---------|
90
+ | `postman/vb-os-python-sdk.postman_collection.json` | Standalone SDK contract validation (runs against api.vb-os.org) |
91
+ | `vb-os-cloud-api/postman/...` → "SDK Contract Validation (S0049)" | Cloud API Postman collection folder — self-bootstrapping auth + 6 contract tests validating SDK response schema expectations (PR #101) |
92
+
93
+ ## REQ Coverage
94
+
95
+ | REQ | Description | Status |
96
+ |-----|-------------|--------|
97
+ | REQ-A1-144 | `pip install vb-os` | Complete |
98
+ | REQ-A1-145 | SDK wraps POST /v1/verify — `verify()` method only (remaining methods deferred to CP1-E14) | Partial |
99
+ | REQ-A1-146 | EvaluationResult fields: decision, replay_id, evaluation_id, admissibility, prohibitions, predicate_results, failure_reasons, latency_ms | Complete |
100
+ | REQ-A1-154 | Thin transport wrapper — no business logic in SDK | Complete |
101
+ | REQ-A1-155 | Typed Pydantic models (not raw dicts) for all API responses | Complete |
102
+ | REQ-A1-156 | AsyncVBOSClient.verify() for async usage (async counterpart) | Complete |
103
+ | REQ-A1-157 | Retry with backoff on 5xx/timeout, never on 4xx. Full jitter: `delay = random.uniform(0, base_delay * 2^attempt)` capped at max_delay | Complete |
104
+ | REQ-A1-158 | Structured exceptions carry error_code, message, details, request_id — not just status codes | Complete |
105
+ | REQ-A1-290 | Python SDK ships CP-1 | Complete |
106
+
107
+ ## CLI (`vbos_cli/`) — CP2-S0031
108
+
109
+ | File | Purpose |
110
+ |------|---------|
111
+ | `vbos_cli/__init__.py` | CLI package init — `__version__ = "0.1.0"` |
112
+ | `vbos_cli/__main__.py` | `python -m vbos_cli` support |
113
+ | `vbos_cli/errors.py` | Error hierarchy: CLIError(exit_code), AuthenticationError, CredentialStoreError, UnsupportedInLocalModeError, SessionExpiredError, APIKeyInvalidError |
114
+ | `vbos_cli/output.py` | print_json, print_table, print_result, print_error, stderr, print_banner (VB-OS logo on login) |
115
+ | `vbos_cli/profiles.py` | resolve_profile (flag > VBOS_PROFILE env > "default") |
116
+ | `vbos_cli/config.py` | TOML config at ~/.vbos/config — profile sections, atomic writes, get/set/list |
117
+ | `vbos_cli/credentials/__init__.py` | Credential store package |
118
+ | `vbos_cli/credentials/store.py` | CredentialStore abstraction, SessionCredential/APIKeyCredential dataclasses, resolve_credential |
119
+ | `vbos_cli/credentials/keychain.py` | KeychainStore — OS keychain via `keyring`, validates macOS/Windows/Linux backends |
120
+ | `vbos_cli/credentials/file.py` | FileStore — PBKDF2-HMAC-SHA256 (600k iterations) + Fernet encryption, atomic writes, 0600 permissions |
121
+ | `vbos_cli/credentials/migration.py` | Credential store migration (read→write→verify→delete) |
122
+ | `vbos_cli/client.py` | AuthenticatedClient — auth injection, pre-request JWT exp check, method-aware retry, token refresh |
123
+ | `vbos_cli/cli.py` | Click group with --version, --profile, --format, --cloud/--local, CLIGroup (catches CLIError), CloudOnlyCommand |
124
+ | `vbos_cli/commands/__init__.py` | Commands package |
125
+ | `vbos_cli/commands/auth.py` | login (interactive + --token + --org, MFA, multi-org, TOS), logout, resend_verification |
126
+ | `vbos_cli/commands/org.py` | switch_org command |
127
+ | `vbos_cli/commands/config_cmd.py` | config set/get/list with credential-store migration |
128
+ | `vbos_cli/commands/completions.py` | bash/zsh/fish completion script output |
129
+
130
+ ### CLI Tests (`tests/cli/`)
131
+
132
+ | File | Purpose | Count |
133
+ |------|---------|-------|
134
+ | `test_cli.py` | Version, help, execution modes (mutual exclusion, local rejection), output format, network error handling (ConnectError, TimeoutException) | 14 |
135
+ | `test_config.py` | Config set/get/list, profile isolation, credential absence | 7 |
136
+ | `test_credentials.py` | Serialization, keychain validation, file encryption, atomic writes, corrupted file, migration (success/verify-fail/delete-fail/empty), resolve | 25 |
137
+ | `test_client.py` | JWT exp extraction, expiry detection, API key bypass, session refresh, 401 handling, retry | 18 |
138
+ | `test_profiles.py` | Profile resolution precedence | 4 |
139
+ | `test_output.py` | JSON/table/error/stderr/banner output | 9 |
140
+ | `test_auth.py` | Login/logout, MFA recovery, MFA max attempts, --org bypass, switch-org (direct + interactive), TOS, lockout, PENDING_DELETION, resend-verification, credential leakage, password non-echo, session→API-key replacement, enrollment vs runtime auth | 22 |
141
+ | `test_completions.py` | Bash/zsh/fish completion output | 3 |
142
+ | `test_integration.py` | IT-S0031-01 through IT-S0031-08 end-to-end flows | 9 |
143
+ | **Total** | | **111** |
144
+
145
+ ### CLI Dependencies (pyproject.toml `[project.optional-dependencies] cli`)
146
+
147
+ | Package | Purpose |
148
+ |---------|---------|
149
+ | click >=8.1,<9.0 | CLI framework |
150
+ | keyring >=25.0,<26.0 | OS credential store |
151
+ | cryptography >=44.0,<45.0 | Fernet encryption for file store |
152
+ | tomli_w >=1.0,<2.0 | TOML writing |
153
+
154
+ ## CLI Full Command Surface (`vbos_cli/commands/`) — CP2-S0032
155
+
156
+ ### Shared Infrastructure
157
+
158
+ | File | Purpose |
159
+ |------|---------|
160
+ | `vbos_cli/formatters.py` | Shared output formatting: `format_output` (JSON/table/quiet), `format_secret`, `format_artifact_download`, `_atomic_write` (0600 perms), `handle_api_error`, `paginate_all` (cursor loop detection), `make_client`, `resolve_project`/`resolve_environment` (config fallback), `add_output_options`/`add_pagination_options`/`add_confirm_option` decorators, `confirm_destructive` |
161
+ | `vbos_cli/local_bridge.py` | Local binary bridge: `_find_binary` (PATH + /opt/vbos/bin fallback), `_verify_install` (A-REL-002 manifest), `_build_a_input_001` (bundle format), `_to_binary_dsl` (DSL conversion), `_parse_audit_parity`, `invoke_local` (full orchestration) |
162
+
163
+ ### Command Modules (23 groups, ~180+ commands)
164
+
165
+ | File | Group | Commands |
166
+ |------|-------|----------|
167
+ | `commands/verify.py` | `verify` | Submit workload (--cloud/--local/--batch), exit 0=ASSERT/1=DEFER/2=error |
168
+ | `commands/replay.py` | `replay` | Replay prior evaluation |
169
+ | `commands/evaluations.py` | `evaluations` | list, get, search, export, share, replay-analysis |
170
+ | `commands/boundaries.py` | `boundaries` | create, list, get, update, archive, compile, validate, diff, promote + `versions` subgroup (create, list, get, update, submit, approve, reject) |
171
+ | `commands/projects.py` | `projects` | create, list, get, update, archive, delete + `members` subgroup (list, add, remove) |
172
+ | `commands/environments.py` | `environments` | create, list, get, update, archive, unarchive |
173
+ | `commands/keys.py` | `keys` | create (format_secret), list, get, rotate (format_secret), revoke |
174
+ | `commands/connectors.py` | `connectors` | create, list, get, update, delete, test, gather, authorize, disconnect, reconnect, status + `providers` subgroup (list, get) |
175
+ | `commands/webhooks.py` | `webhooks` | create, list, get, update, delete, test, rotate-secret, deliveries, retry (project/org scope via --org) |
176
+ | `commands/flows.py` | `flows` | create, list, get, update, delete, export, import, from-template, deploy, suspend, resume, dry-run + `versions` (create, list, get, update, delete, approve) + `executions` (list, reconstruct) + `templates` (list, get) |
177
+ | `commands/alert_rules.py` | `alert-rules` | create, list, get, update (PUT), delete |
178
+ | `commands/deployments.py` | `deployments` | list, get, active, rollback, approve, reject |
179
+ | `commands/templates.py` | `templates` | list, get, fork |
180
+ | `commands/named_sets.py` | `named-sets` | list, get, create, update, delete |
181
+ | `commands/org_mgmt.py` | `org` | get, update + `settings` subgroup (get, update) |
182
+ | `commands/members.py` | `members` | list, invite, role, remove, suspend, reactivate |
183
+ | `commands/workspaces.py` | `workspaces` | list, get, create, update, archive |
184
+ | `commands/audit_log.py` | `audit-log` | list, export, export-status |
185
+ | `commands/certify.py` | `certify` (standalone command) + `certifications` group (list, get, report, revoke) + `certification-models` group (create, list, get, update, delete) |
186
+ | `commands/analytics.py` | `analytics` | assertion-rate |
187
+ | `commands/governed_workspaces.py` | `governed-workspaces` | provision, list, get, deploy, evaluate, seal, teardown |
188
+ | `commands/notifications.py` | `notifications` | list, read, unread |
189
+ | `commands/account.py` | `account` | delete, delete-status, delete-cancel, export, export-status |
190
+
191
+ ### S0032 Tests (`tests/cli/`)
192
+
193
+ | File | Purpose | Count |
194
+ |------|---------|-------|
195
+ | `test_command_registration.py` | All 25 S0032 + 6 S0031 commands registered, help works | 57 |
196
+ | `test_formatters.py` | Atomic write (0600), format_output, format_secret, quiet extractors, pagination | 14 |
197
+ | `test_local_bridge.py` | Binary discovery, verify-install, bundle build, DSL conversion, audit parity, decision map | 12 |
198
+ | `test_error_handling.py` | API error exit codes (401/403/404/500), client close lifecycle | 6 |
199
+ | `test_config_fallback.py` | Project/environment resolution from flag vs config | 3 |
200
+ | `test_verify.py` | Verify command: ASSERT/DEFER exit codes, batch, local exclusion, idempotency | 12 |
201
+ | `test_evaluations.py` | Evaluations group: list/get/search/export/share/replay-analysis | 21 |
202
+ | `test_replay.py` | Replay command: basic, API error, client lifecycle | 6 |
203
+ | `test_projects.py` | Projects group: CRUD, members, destructive confirm | 23 |
204
+ | `test_environments.py` | Environments group: CRUD, archive/unarchive | 14 |
205
+ | `test_keys.py` | Keys group: create/rotate (format_secret), revoke | 15 |
206
+ | `test_boundaries.py` | Boundaries group: CRUD, compile, validate, diff, promote, versions | 34 |
207
+ | `test_connectors.py` | Connectors group: CRUD, test, gather, providers | 20 |
208
+ | `test_connectors_oauth.py` | Connector OAuth: sync/async authorize, disconnect, reconnect, oauth_status, wait_for_authorization, terminal states, 404, timeout, security | 18 |
209
+ | `cli/test_connectors_oauth.py` | CLI OAuth commands: authorize (all terminal states, 503 retry, no-browser, quiet, API error), disconnect, reconnect, status, token leakage | 17 |
210
+ | `test_webhooks.py` | Webhooks group: CRUD, rotate-secret, deliveries, retry, org scope | 22 |
211
+ | `test_flows.py` | Flows group: CRUD, export/import, deploy, versions, executions | 33 |
212
+ | `test_alert_rules.py` | Alert rules group: CRUD, PUT update | 17 |
213
+ | `test_deployments.py` | Deployments group: list, get, active, rollback, approve, reject | 10 |
214
+ | `test_templates.py` | Templates group: list, get, fork | 8 |
215
+ | `test_named_sets.py` | Named sets group: CRUD | 7 |
216
+ | `test_org_mgmt.py` | Org group: get, update, settings get/update | 6 |
217
+ | `test_members.py` | Members group: list, invite, role, remove, suspend, reactivate | 10 |
218
+ | `test_workspaces.py` | Workspaces group: CRUD, archive | 7 |
219
+ | `test_audit_log.py` | Audit log group: list, export, export-status | 7 |
220
+ | `test_certify.py` | Certify + certifications + certification-models | 17 |
221
+ | `test_analytics.py` | Analytics group: assertion-rate | 4 |
222
+ | `test_governed_workspaces.py` | Governed workspaces: provision, list, get, deploy, evaluate, seal, teardown | 9 |
223
+ | `test_notifications.py` | Notifications group: list, read, unread | 7 |
224
+ | `test_account.py` | Account: delete, delete-status, delete-cancel, export, export-status | 11 |
225
+ | `test_integration_s0032.py` | IT-01 through IT-06: verify lifecycle, boundary lifecycle, project setup, file perms, exit codes, destructive confirm | 15 |
226
+ | **Total S0032 tests** | | **432** |
227
+
228
+ ## Distribution — CP2-S0050
229
+
230
+ ### Distribution Files
231
+
232
+ | File | Purpose |
233
+ |------|---------|
234
+ | `scripts/install.sh` | Shell installer — isolated vbos installation via pipx or dedicated venv |
235
+
236
+ ### Distribution Channels
237
+
238
+ | Channel | Command | Dependencies |
239
+ |---------|---------|-------------|
240
+ | pip | `pip install "vb-os[cli]"` | PyPI publication |
241
+ | Homebrew | `brew install VB-OS/tap/vbos` | PyPI + homebrew-tap formula generation |
242
+ | Shell installer | `curl -fsSL https://get.vb-os.org/cli \| sh` | PyPI + get.vb-os.org hosting |
243
+
244
+ ### Installer Behavior
245
+
246
+ - Detects OS (macOS, Linux), rejects unsupported
247
+ - Requires Python >= 3.10
248
+ - Fresh install: pipx if available, otherwise dedicated venv at `~/.vbos/venv`
249
+ - Upgrade: detects existing mechanism (pipx or venv), upgrades in-place
250
+ - Never silently migrates between installation mechanisms
251
+ - Detects pre-existing unrelated `vbos` on PATH, warns and aborts
252
+ - `VBOS_INSTALL_SOURCE` env var overrides package source for local testing
253
+ - shellcheck clean
254
+
255
+ ### Documentation
256
+
257
+ | File | Purpose |
258
+ |------|---------|
259
+ | `docs/cli-developer-manual.md` | Architecture, distribution, release procedures, rollback |
260
+ | `docs/cli-operator-manual.md` | Installation methods, authentication, upgrade, troubleshooting |
261
+
262
+ ## Architecture
263
+
264
+ - **Two-client pattern:** VBOSClient (httpx.Client) and AsyncVBOSClient (httpx.AsyncClient)
265
+ - **27 resource namespaces:** Each resource group is a SyncX/AsyncX sub-client taking `(client, max_retries)`, using `_request` helper → `build_request → sync_retry/async_retry → handle_json_response`
266
+ - **Transport extraction:** `_transport.py` holds shared HTTP helpers to avoid circular imports between `client.py` and `resources/*.py`
267
+ - **1:1 endpoint mapping:** Every SDK method maps to exactly one Cloud API endpoint — no business logic
268
+ - **Forward compatibility:** All Pydantic models use `extra="ignore"` to handle unknown fields
269
+ - **Context manager support:** Both clients support `with` / `async with`
270
+ - **CLI entry point:** `vbos` binary via `[project.scripts]`, Click group with 31 commands (6 S0031 + 25 S0032)
271
+ - **Default base URL:** `https://api.vb-os.org`
272
+ - **Default timeout:** 30.0s
273
+ - **Default max retries:** 3
274
+ - **User-Agent:** `vb-os-python-sdk/0.1.0` (SDK), `vbos-cli/0.1.0` (CLI)
275
+
276
+ ## Test Results
277
+
278
+ - **1100 total tests passed** (0 failures) — 111 S0031 CLI + 432 S0032 CLI + 17 S0032 integration + ~540 SDK core (83 original + 364 manifest + 93 cross-cutting + ~73 contract) = ~1100
279
+ - **Lint clean** (ruff — 0 errors)