subactor-shell 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 (61) hide show
  1. subactor_shell-0.2.2/LICENSE +13 -0
  2. subactor_shell-0.2.2/PKG-INFO +449 -0
  3. subactor_shell-0.2.2/README.md +427 -0
  4. subactor_shell-0.2.2/pyproject.toml +65 -0
  5. subactor_shell-0.2.2/setup.cfg +4 -0
  6. subactor_shell-0.2.2/src/subactor_shell/__init__.py +3 -0
  7. subactor_shell-0.2.2/src/subactor_shell/__main__.py +4 -0
  8. subactor_shell-0.2.2/src/subactor_shell/acp_agent.py +363 -0
  9. subactor_shell-0.2.2/src/subactor_shell/app.py +482 -0
  10. subactor_shell-0.2.2/src/subactor_shell/artifacts.py +198 -0
  11. subactor_shell-0.2.2/src/subactor_shell/catalog.py +416 -0
  12. subactor_shell-0.2.2/src/subactor_shell/chat.py +517 -0
  13. subactor_shell-0.2.2/src/subactor_shell/compiler.py +191 -0
  14. subactor_shell-0.2.2/src/subactor_shell/config.py +374 -0
  15. subactor_shell-0.2.2/src/subactor_shell/connectors.py +503 -0
  16. subactor_shell-0.2.2/src/subactor_shell/context_builder.py +153 -0
  17. subactor_shell-0.2.2/src/subactor_shell/control.py +141 -0
  18. subactor_shell-0.2.2/src/subactor_shell/control_env.py +93 -0
  19. subactor_shell-0.2.2/src/subactor_shell/intent_ir.py +187 -0
  20. subactor_shell-0.2.2/src/subactor_shell/models.py +78 -0
  21. subactor_shell-0.2.2/src/subactor_shell/operations.py +287 -0
  22. subactor_shell-0.2.2/src/subactor_shell/orchestration.py +324 -0
  23. subactor_shell-0.2.2/src/subactor_shell/policy.py +38 -0
  24. subactor_shell-0.2.2/src/subactor_shell/providers/__init__.py +63 -0
  25. subactor_shell-0.2.2/src/subactor_shell/providers/anthropic.py +101 -0
  26. subactor_shell-0.2.2/src/subactor_shell/providers/base.py +81 -0
  27. subactor_shell-0.2.2/src/subactor_shell/providers/mock.py +32 -0
  28. subactor_shell-0.2.2/src/subactor_shell/providers/openai_compat.py +303 -0
  29. subactor_shell-0.2.2/src/subactor_shell/providers/subactor_control.py +191 -0
  30. subactor_shell-0.2.2/src/subactor_shell/redaction.py +62 -0
  31. subactor_shell-0.2.2/src/subactor_shell/repl.py +480 -0
  32. subactor_shell-0.2.2/src/subactor_shell/routing.py +334 -0
  33. subactor_shell-0.2.2/src/subactor_shell/secret_refs.py +82 -0
  34. subactor_shell-0.2.2/src/subactor_shell/store.py +857 -0
  35. subactor_shell-0.2.2/src/subactor_shell/terminal.py +79 -0
  36. subactor_shell-0.2.2/src/subactor_shell/token_budget.py +46 -0
  37. subactor_shell-0.2.2/src/subactor_shell/vault.py +170 -0
  38. subactor_shell-0.2.2/src/subactor_shell.egg-info/PKG-INFO +449 -0
  39. subactor_shell-0.2.2/src/subactor_shell.egg-info/SOURCES.txt +59 -0
  40. subactor_shell-0.2.2/src/subactor_shell.egg-info/dependency_links.txt +1 -0
  41. subactor_shell-0.2.2/src/subactor_shell.egg-info/entry_points.txt +2 -0
  42. subactor_shell-0.2.2/src/subactor_shell.egg-info/requires.txt +16 -0
  43. subactor_shell-0.2.2/src/subactor_shell.egg-info/top_level.txt +1 -0
  44. subactor_shell-0.2.2/tests/test_acp_agent.py +87 -0
  45. subactor_shell-0.2.2/tests/test_acp_extensions.py +86 -0
  46. subactor_shell-0.2.2/tests/test_app_errors.py +27 -0
  47. subactor_shell-0.2.2/tests/test_artifact_selection.py +19 -0
  48. subactor_shell-0.2.2/tests/test_canonical_cli.py +47 -0
  49. subactor_shell-0.2.2/tests/test_chat.py +105 -0
  50. subactor_shell-0.2.2/tests/test_context_budget.py +65 -0
  51. subactor_shell-0.2.2/tests/test_control.py +114 -0
  52. subactor_shell-0.2.2/tests/test_control_env.py +51 -0
  53. subactor_shell-0.2.2/tests/test_operations.py +117 -0
  54. subactor_shell-0.2.2/tests/test_orchestration.py +129 -0
  55. subactor_shell-0.2.2/tests/test_providers.py +163 -0
  56. subactor_shell-0.2.2/tests/test_redaction.py +26 -0
  57. subactor_shell-0.2.2/tests/test_router_local_parser.py +128 -0
  58. subactor_shell-0.2.2/tests/test_shell_integration.py +52 -0
  59. subactor_shell-0.2.2/tests/test_store.py +118 -0
  60. subactor_shell-0.2.2/tests/test_structured_output.py +65 -0
  61. subactor_shell-0.2.2/tests/test_vault.py +82 -0
@@ -0,0 +1,13 @@
1
+ Copyright 2026 Subactor shell bridge contributors
2
+
3
+ Licensed under the Apache License, Version 2.0 (the "License");
4
+ you may not use this file except in compliance with the License.
5
+ You may obtain a copy of the License at
6
+
7
+ http://www.apache.org/licenses/LICENSE-2.0
8
+
9
+ Unless required by applicable law or agreed to in writing, software
10
+ distributed under the License is distributed on an "AS IS" BASIS,
11
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ See the License for the specific language governing permissions and
13
+ limitations under the License.
@@ -0,0 +1,449 @@
1
+ Metadata-Version: 2.4
2
+ Name: subactor-shell
3
+ Version: 0.2.2
4
+ Summary: Subactor terminal shell with IntentIR orchestration, governed Control integration, persistent sessions and ACP stdio.
5
+ Author: Subactor community
6
+ Author-email: Tom Sapletta <tom@sapletta.com>
7
+ License-Expression: Apache-2.0
8
+ Project-URL: Repository, https://github.com/subactor/shell
9
+ Requires-Python: >=3.11
10
+ Description-Content-Type: text/markdown
11
+ License-File: LICENSE
12
+ Requires-Dist: httpx<1,>=0.27
13
+ Requires-Dist: prompt-toolkit<4,>=3.0
14
+ Requires-Dist: rich<15,>=13
15
+ Provides-Extra: dev
16
+ Requires-Dist: pytest<10,>=8; extra == "dev"
17
+ Requires-Dist: pytest-asyncio<1,>=0.23; extra == "dev"
18
+ Requires-Dist: goal>=2.1.0; python_version >= "3.12" and extra == "dev"
19
+ Requires-Dist: costs>=0.1.53; python_version >= "3.9" and extra == "dev"
20
+ Requires-Dist: pfix>=0.1.60; python_version >= "3.10" and extra == "dev"
21
+ Dynamic: license-file
22
+
23
+ # Subactor Shell 0.2.2
24
+
25
+
26
+ ## AI Cost Tracking
27
+
28
+ ![PyPI](https://img.shields.io/badge/pypi-costs-blue) ![Version](https://img.shields.io/badge/version-0.2.2-blue) ![Python](https://img.shields.io/badge/python-3.9+-blue) ![License](https://img.shields.io/badge/license-Apache--2.0-green)
29
+ ![AI Cost](https://img.shields.io/badge/AI%20Cost-$0.06-orange) ![Human Time](https://img.shields.io/badge/Human%20Time-9.5h-blue) ![Model](https://img.shields.io/badge/Model-openrouter%2Fqwen%2Fqwen3--coder--next-lightgrey)
30
+
31
+ - 🤖 **LLM usage:** $0.0595 (3 commits)
32
+ - 👤 **Human dev:** ~$953 (9.5h @ $100/h, 30min dedup)
33
+
34
+ Generated on 2026-08-29 using [openrouter/qwen/qwen3-coder-next](https://openrouter.ai/qwen/qwen3-coder-next)
35
+
36
+ ---
37
+
38
+
39
+
40
+ Subactor Shell jest trwałą warstwą rozmowy i orkiestracji dla terminala oraz klientów ACP. Wersja 0.2.2 integruje pytania operacyjne z zarządzanym CLI Subactora, poprawia obsługę kończenia sesji i nie przejmuje nazwy Founder Chat.
41
+
42
+ ```text
43
+ polecenie użytkownika
44
+ → exact/template/phrase match (0 tokenów)
45
+ → lokalny lub tani parser NL → IntentIR v1
46
+ → lokalna walidacja JSON Schema
47
+ → deterministyczny ExecutionPlan
48
+ → policy + capability/connector preflight
49
+ → nazwany connector
50
+ → krótki ExecutionReceipt
51
+ → duży LLM tylko przy niepewności lub zadaniu konwersacyjnym
52
+ ```
53
+
54
+ Pełny transcript nadal jest zapisywany w SQLite, ale provider rozmowy dostaje tylko ograniczony `WorkingState`, kilka ostatnich wiadomości, krótką informację o trasie oraz lokalnie wybrane fragmenty danych i artefaktów.
55
+
56
+ ## Najważniejsze właściwości
57
+
58
+ - lokalny fast path bez LLM dla znanych poleceń;
59
+ - typowany i walidowany `IntentIR v1` zamiast swobodnego planowania w prozie;
60
+ - routing: deterministic/cache → local 4B → cheap remote → large/chat provider;
61
+ - `ExecutionPlan` tworzony wyłącznie przez lokalny kompilator;
62
+ - nazwane connectory `builtin`, Subactor Control, process oraz HTTP;
63
+ - brak `shell=True` i brak możliwości wskazania przez model dowolnej komendy;
64
+ - plan hash, fingerprint stanu i jawne `EXECUTE` dla operacji zmieniających stan;
65
+ - `ExecutionReceipt` zamiast przekazywania pełnych logów między modelami;
66
+ - telemetria tokenów, cached input, szacowanego kosztu i udziału tras bez LLM;
67
+ - trwałe sesje, jawne dane, artefakty oraz referencje Vault;
68
+ - ACP v1 po `stdin/stdout`, wraz z rozszerzeniami katalogu, planów, receiptów i metryk;
69
+ - migracja istniejącej bazy 0.1 bez usuwania sesji ani wiadomości.
70
+
71
+ ## Instalacja
72
+
73
+ Pakiet instaluje wyłącznie polecenie `subactor-shell`. Nazwa `subactor` jest
74
+ zarezerwowana dla Founder Chat dostarczanego przez Platformę, dzięki czemu
75
+ `subactor chat` zachowuje swój interfejs, pełną diagnostykę i kontrakt sesji.
76
+ Powłokę z trwałym stanem, Vault, lokalnym routingiem i ACP uruchamia się
77
+ jawnie przez `subactor-shell chat`.
78
+
79
+ Z wheel:
80
+
81
+ ```bash
82
+ python -m venv .venv
83
+ . .venv/bin/activate
84
+ pip install ./subactor_shell_bridge-0.2.0-py3-none-any.whl
85
+ subactor-shell init
86
+ ```
87
+
88
+ Ze źródeł:
89
+
90
+ ```bash
91
+ python -m venv .venv
92
+ . .venv/bin/activate
93
+ pip install -e .
94
+ subactor-shell init
95
+ ```
96
+
97
+ Domyślne lokalizacje:
98
+
99
+ ```text
100
+ ~/.config/subactor-shell/config.toml
101
+ ~/.local/share/subactor-shell/subactor-shell.sqlite3
102
+ ~/.local/share/subactor-shell/artifacts/
103
+ ```
104
+
105
+ Katalog danych otrzymuje tryb `0700`, a config, SQLite i artefakty `0600`, o ile system plików wspiera te tryby.
106
+
107
+ ## Szybki start
108
+
109
+ ```bash
110
+ subactor-shell chat
111
+ ```
112
+
113
+ Przykładowe polecenia w REPL:
114
+
115
+ ```text
116
+ pokaż sesje
117
+ pokaż zużycie tokenów
118
+ /status
119
+ /plans
120
+ /receipts
121
+ /catalog
122
+ /connectors
123
+ /route
124
+ ```
125
+
126
+ Jedna wiadomość bez REPL:
127
+
128
+ ```bash
129
+ subactor-shell one 'pokaż sesje'
130
+ ```
131
+
132
+ Przy znanym intencie read-only wynik może zostać wykonany lokalnie bez wywołania providera rozmowy.
133
+
134
+ ## Routing modeli
135
+
136
+ Minimalna konfiguracja lokalnego parsera OpenAI-compatible:
137
+
138
+ ```toml
139
+ [orchestration]
140
+ enabled = true
141
+ mode = "active"
142
+ local_parser_provider = "local_4b"
143
+ local_parser_model = "local-4b-instruct"
144
+ cheap_parser_provider = ""
145
+ large_provider = ""
146
+ top_k = 5
147
+ max_parser_output_tokens = 192
148
+
149
+ [providers.local_4b]
150
+ kind = "openai_compat"
151
+ base_url = "http://127.0.0.1:8000/v1"
152
+ endpoint = "/chat/completions"
153
+ auth_required = false
154
+ api_key_ref = ""
155
+ model = "local-4b-instruct"
156
+ max_output_tokens = 192
157
+ structured_mode = "json_schema"
158
+ ```
159
+
160
+ Tani i duży fallback można dodać jako kolejne profile:
161
+
162
+ ```toml
163
+ [orchestration]
164
+ local_parser_provider = "local_4b"
165
+ cheap_parser_provider = "budget_remote"
166
+ large_provider = "planner_remote"
167
+
168
+ [providers.budget_remote]
169
+ kind = "openai_compat"
170
+ base_url = "https://provider.example/v1"
171
+ endpoint = "/chat/completions"
172
+ api_key_ref = "env://BUDGET_LLM_API_KEY"
173
+ auth_required = true
174
+ model = "budget-model"
175
+ max_output_tokens = 192
176
+ structured_mode = "json_schema"
177
+ input_cost_per_million = 0.0
178
+ cached_input_cost_per_million = 0.0
179
+ output_cost_per_million = 0.0
180
+
181
+ [providers.planner_remote]
182
+ kind = "openai_compat"
183
+ base_url = "https://provider.example/v1"
184
+ endpoint = "/chat/completions"
185
+ api_key_ref = "env://PLANNER_LLM_API_KEY"
186
+ auth_required = true
187
+ model = "large-planner"
188
+ max_output_tokens = 800
189
+ structured_mode = "json_schema"
190
+ ```
191
+
192
+ Stawki w configu są wyłącznie danymi użytkownika do lokalnego szacowania kosztu. Projekt nie pobiera automatycznie cenników.
193
+
194
+ Tryby orkiestracji:
195
+
196
+ - `active` — wykonuje poprawne lokalne plany;
197
+ - `shadow` — zapisuje routing i IntentIR, ale odpowiedź nadal prowadzi provider rozmowy;
198
+ - `off` — zachowanie konwersacyjne bez DSL.
199
+
200
+ ## IntentIR v1
201
+
202
+ Model parsera może zwrócić tylko obiekt zgodny z `schemas/intent-ir.v1.schema.json`, na przykład:
203
+
204
+ ```json
205
+ {
206
+ "v": 1,
207
+ "intent_id": "project.deploy",
208
+ "mode": "plan",
209
+ "args": {
210
+ "project_ref": "project://docs",
211
+ "environment": "prod"
212
+ },
213
+ "requirements": ["verify_tls"],
214
+ "constraints": ["no_secret_export"],
215
+ "unresolved": []
216
+ }
217
+ ```
218
+
219
+ Model nie wybiera komendy, ścieżki wykonywalnej, URL, connectora ani secret ref. Te elementy pochodzą z lokalnego katalogu intentów i konfiguracji connectorów.
220
+
221
+ ## Katalog intentów
222
+
223
+ Wbudowane intenty obejmują pomoc, sesje, dane, bindingi sekretów, metryki oraz `cli.status`/`cli.plan` istniejącego Subactor Control.
224
+
225
+ Dodatkowe katalogi wskazuje się w configu:
226
+
227
+ ```toml
228
+ [orchestration]
229
+ intent_catalog_paths = ["./intent-catalog.v1.json"]
230
+ ```
231
+
232
+ Przykład znajduje się w `examples/intent-catalog.v1.json`. Loader akceptuje własny format `{"intents": [...]}` oraz kilka typowych nazw pól spotykanych w intent packach, ale dokładna integracja z repozytorium nadrzędnym wymaga rzeczywistych plików JSON, nie samej mapy symboli.
233
+
234
+ ## Named connectors
235
+
236
+ ### Process connector
237
+
238
+ ```toml
239
+ [connectors.project_ops]
240
+ kind = "process"
241
+ command = ["/opt/subactor/bin/project-connector", "--json-stdin"]
242
+ allowed_operations = ["project.inspect", "project.apply"]
243
+ effect = "external_write"
244
+ inherit_env = false
245
+ pass_env = ["PATH", "LANG", "LC_ALL", "TZ"]
246
+ timeout_seconds = 30.0
247
+ output_limit_bytes = 65536
248
+
249
+ [connectors.project_ops.env_refs]
250
+ PROJECT_API_TOKEN = "vault://secret/subactor/project#token"
251
+ ```
252
+
253
+ Pierwszy element `command` musi być ścieżką absolutną. Runtime uruchamia stałe argv przez `create_subprocess_exec`, bez powłoki. Domyślnie nie dziedziczy całego środowiska procesu; przepuszcza tylko nazwy z `pass_env` oraz jawne `env_refs`. Connector dostaje JSON przez `stdin`:
254
+
255
+ ```json
256
+ {
257
+ "plan_id": "plan_...",
258
+ "plan_hash": "...",
259
+ "session_id": "...",
260
+ "intent_id": "project.apply",
261
+ "operation": "project.apply",
262
+ "args": {}
263
+ }
264
+ ```
265
+
266
+ Minimalny przykład implementacji: `examples/process-connector.py`.
267
+
268
+ ### HTTP connector
269
+
270
+ ```toml
271
+ [connectors.project_http]
272
+ kind = "http"
273
+ base_url = "https://connector.internal"
274
+ path = "/v1/execute"
275
+ method = "POST"
276
+ bearer_ref = "file://~/.config/subactor-shell/project-http.token"
277
+ allowed_operations = ["project.inspect", "project.apply"]
278
+ effect = "external_write"
279
+ ```
280
+
281
+ ### Subactor Control
282
+
283
+ `subactor_control` pozostaje specjalnym connectorom z dokładną allowlistą:
284
+
285
+ ```toml
286
+ [control]
287
+ allowed_tools = ["cli.status", "cli.plan", "cli.execute"]
288
+ ```
289
+
290
+ Bridge wykonuje `tools/list` przed wywołaniem i odrzuca endpoint, który reklamuje inny zestaw narzędzi. `cli.execute` wymaga zaakceptowanego planu.
291
+
292
+ ## Plan i apply
293
+
294
+ Operacja read-only może wykonać się automatycznie. Operacja zmieniająca stan zapisuje plan:
295
+
296
+ ```bash
297
+ subactor-shell plans list
298
+ subactor-shell plans show PLAN_ID
299
+ subactor-shell plans apply PLAN_ID --confirm EXECUTE
300
+ subactor-shell receipts list
301
+ subactor-shell receipts show RECEIPT_ID
302
+ ```
303
+
304
+ Przed apply sprawdzane są:
305
+
306
+ 1. status planu;
307
+ 2. `plan_hash`;
308
+ 3. dokładne `EXECUTE` dla zmian stanu;
309
+ 4. aktualny fingerprint SQLite, katalogu intentów i registry connectorów;
310
+ 5. allowlista connectora i operation;
311
+ 6. lokalna policy.
312
+
313
+ ## Ograniczanie kontekstu
314
+
315
+ Pełna historia jest przechowywana, lecz nie jest ponownie wysyłana przy każdej turze. Limity ustawia sekcja:
316
+
317
+ ```toml
318
+ [context]
319
+ recent_messages = 6
320
+ max_history_chars = 12000
321
+ max_message_chars = 4000
322
+ max_data_chars = 6000
323
+ max_attachment_prompt_chars = 8000
324
+ artifact_chunk_chars = 1800
325
+ max_artifact_chunks = 4
326
+ max_embedded_context_chars = 8000
327
+ max_route_context_chars = 4000
328
+ ```
329
+
330
+ `{{data:NAME}}` i załączniki są dzielone lokalnie na fragmenty i wybierane leksykalnie względem bieżącego polecenia. Model otrzymuje tylko wynik mieszczący się w budżecie. To nie jest pełny silnik semantyczny; dla rozbudowanego repozytorium należy podłączyć istniejące DOQL/DQL lub własny retriever jako nazwany connector.
331
+
332
+ ## Dane i artefakty
333
+
334
+ ```bash
335
+ subactor-shell data set ENVIRONMENT staging
336
+ subactor-shell data put SPEC ./specification.md
337
+ subactor-shell data list
338
+ ```
339
+
340
+ W rozmowie:
341
+
342
+ ```text
343
+ Przeanalizuj ustawienia {{data:ENVIRONMENT}} oraz sekcję deployment w {{data:SPEC}}.
344
+ ```
345
+
346
+ Jawne dane mogą zostać wysłane do providera po lokalnym wyborze fragmentów. Nie należy zapisywać w tej warstwie sekretów.
347
+
348
+ ## Vault i jednorazowe granty
349
+
350
+ Binding zapisuje wyłącznie referencję:
351
+
352
+ ```bash
353
+ subactor-shell vault bind DB_PASSWORD 'vault://secret/subactor/prod/database#password'
354
+ ```
355
+
356
+ Zapis wartości do Vault KV v2 pobiera ją bez echa:
357
+
358
+ ```bash
359
+ subactor-shell vault put DB_PASSWORD 'vault://secret/subactor/prod/database#password'
360
+ ```
361
+
362
+ W REPL:
363
+
364
+ ```text
365
+ /vault grant DB_PASSWORD
366
+ Sprawdź format {{secret:DB_PASSWORD}}, ale jej nie powtarzaj.
367
+ ```
368
+
369
+ Grant jest jednorazowy i przechowywany wyłącznie w pamięci procesu. Placeholder w zapisanych danych, pliku lub embedded resource ACP nie może sam zużyć grantu. Lokalne fast path nie odczytuje sekretu i nie konsumuje grantu.
370
+
371
+ ## Metryki
372
+
373
+ ```bash
374
+ subactor-shell metrics --json
375
+ subactor-shell metrics --session SESSION_ID --json
376
+ ```
377
+
378
+ Wynik obejmuje:
379
+
380
+ - liczbę wywołań providerów;
381
+ - input, cached input i output tokens;
382
+ - wywołania z usage oszacowanym lokalnie;
383
+ - koszt według stawek wpisanych w configu;
384
+ - rozkład tras;
385
+ - udział tras `deterministic` i `cache` bez LLM.
386
+
387
+ ## ACP
388
+
389
+ ```bash
390
+ subactor-shell acp-agent
391
+ ```
392
+
393
+ Oprócz ACP v1 (`initialize`, `session/new`, `session/load`, `session/prompt`, `session/cancel`) agent obsługuje rozszerzenia:
394
+
395
+ ```text
396
+ subactor/data/set
397
+ subactor/data/list
398
+ subactor/secret/bind
399
+ subactor/secret/grant
400
+ subactor/secret/list
401
+ subactor/catalog/list
402
+ subactor/connectors/list
403
+ subactor/route/get
404
+ subactor/metrics/get
405
+ subactor/plan/list
406
+ subactor/plan/get
407
+ subactor/plan/apply
408
+ subactor/receipt/list
409
+ subactor/receipt/get
410
+ ```
411
+
412
+ `subactor/plan/apply` używa tej samej walidacji i wymaga pola `confirmation: "EXECUTE"` dla zmian stanu. `stdout` procesu ACP jest zarezerwowany dla jednoliniowych komunikatów JSON-RPC.
413
+
414
+ ## Migracja z 0.1
415
+
416
+ Po wskazaniu istniejącego `--data-dir` Store automatycznie dodaje tabele:
417
+
418
+ ```text
419
+ session_state
420
+ routing_decisions
421
+ provider_usage
422
+ execution_plans
423
+ execution_receipts
424
+ router_feedback
425
+ context_cache
426
+ ```
427
+
428
+ Istniejące `sessions`, `messages`, `artifacts`, jawne dane i bindingi sekretów pozostają zachowane. Przed migracją produkcyjną zalecana jest kopia pliku SQLite.
429
+
430
+ ## Testy
431
+
432
+ ```bash
433
+ python -m pip install -e '.[dev]'
434
+ pytest -q
435
+ ```
436
+
437
+ Pakiet wydaniowy 0.2.0 został sprawdzony testami jednostkowymi i integracyjnymi oraz instalacją wheel do izolowanego katalogu pakietów, uruchomioną poza drzewem źródeł. Integracje z prawdziwymi kontami Vault/LLM/Subactor należy dodatkowo sprawdzić w docelowym środowisku.
438
+
439
+ Więcej szczegółów:
440
+
441
+ - `docs/TOKEN_ROUTING.md` — routing, WorkingState i budżety;
442
+ - `docs/INTEGRATION.md` — dopasowanie do aktualnej mapy repozytorium Subactor;
443
+ - `SECURITY.md` — granice zaufania i model zagrożeń;
444
+ - `CHANGELOG.md` — zakres wersji 0.2.0.
445
+
446
+
447
+ ## License
448
+
449
+ Licensed under Apache-2.0.