flameox 0.2.2__tar.gz → 0.2.4__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 (186) hide show
  1. {flameox-0.2.2 → flameox-0.2.4}/.github/workflows/release.yml +27 -1
  2. {flameox-0.2.2 → flameox-0.2.4}/CHANGELOG.md +50 -0
  3. {flameox-0.2.2 → flameox-0.2.4}/CONTRIBUTING.md +6 -6
  4. {flameox-0.2.2 → flameox-0.2.4}/PKG-INFO +68 -31
  5. flameox-0.2.4/README.md +158 -0
  6. {flameox-0.2.2 → flameox-0.2.4}/README.zh-CN.md +13 -12
  7. {flameox-0.2.2 → flameox-0.2.4}/docs/adapters.md +30 -12
  8. flameox-0.2.4/docs/architecture.md +73 -0
  9. flameox-0.2.4/docs/interfaces.md +179 -0
  10. {flameox-0.2.2 → flameox-0.2.4}/docs/investigations.md +18 -5
  11. {flameox-0.2.2 → flameox-0.2.4}/docs/runtime-safety.md +22 -14
  12. {flameox-0.2.2 → flameox-0.2.4}/docs/storage-and-evidence.md +11 -8
  13. {flameox-0.2.2 → flameox-0.2.4}/docs/testing.md +3 -3
  14. {flameox-0.2.2 → flameox-0.2.4}/examples/semantic-matrix/README.md +2 -2
  15. flameox-0.2.4/npm/README.md +19 -0
  16. {flameox-0.2.2 → flameox-0.2.4}/npm/package-lock.json +2 -2
  17. {flameox-0.2.2 → flameox-0.2.4}/npm/package.json +1 -1
  18. {flameox-0.2.2 → flameox-0.2.4}/npm/test/bootstrap.test.cjs +12 -0
  19. {flameox-0.2.2 → flameox-0.2.4}/pyproject.toml +3 -2
  20. {flameox-0.2.2 → flameox-0.2.4}/server.json +2 -10
  21. flameox-0.2.4/src/flameox/cli.py +420 -0
  22. flameox-0.2.4/src/flameox/mcp/capability_tools.py +79 -0
  23. flameox-0.2.4/src/flameox/mcp/server.py +455 -0
  24. flameox-0.2.4/src/flameox/paths.py +20 -0
  25. flameox-0.2.4/src/flameox/providers/availability.py +28 -0
  26. flameox-0.2.4/src/flameox/providers/capture.py +449 -0
  27. {flameox-0.2.2 → flameox-0.2.4}/src/flameox/providers/memray.py +1 -5
  28. {flameox-0.2.2 → flameox-0.2.4}/src/flameox/providers/nsight_compute.py +5 -3
  29. {flameox-0.2.2 → flameox-0.2.4}/src/flameox/providers/nvbench.py +1 -1
  30. {flameox-0.2.2 → flameox-0.2.4}/src/flameox/providers/reliability.py +86 -11
  31. {flameox-0.2.2 → flameox-0.2.4}/src/flameox/providers/source_evidence.py +2 -4
  32. {flameox-0.2.2 → flameox-0.2.4}/src/flameox/providers/structured_workers.py +43 -5
  33. {flameox-0.2.2 → flameox-0.2.4}/src/flameox/pytest_capture.py +14 -3
  34. {flameox-0.2.2 → flameox-0.2.4}/src/flameox/repository.py +4 -52
  35. {flameox-0.2.2 → flameox-0.2.4}/src/flameox/runtime_contracts.py +194 -163
  36. flameox-0.2.4/src/flameox/setup.py +442 -0
  37. {flameox-0.2.2 → flameox-0.2.4}/src/flameox/stateless.py +619 -1146
  38. {flameox-0.2.2 → flameox-0.2.4}/src/flameox/workers/compute_sanitizer.py +5 -12
  39. {flameox-0.2.2 → flameox-0.2.4}/src/flameox/workers/compute_sanitizer_contract.py +0 -1
  40. {flameox-0.2.2 → flameox-0.2.4}/src/flameox/workers/coverage.py +3 -14
  41. {flameox-0.2.2 → flameox-0.2.4}/src/flameox/workers/coverage_contract.py +0 -1
  42. {flameox-0.2.2 → flameox-0.2.4}/src/flameox/workers/harness.py +4 -4
  43. {flameox-0.2.2 → flameox-0.2.4}/src/flameox/workers/memray.py +3 -38
  44. {flameox-0.2.2 → flameox-0.2.4}/src/flameox/workers/memray_contract.py +0 -6
  45. {flameox-0.2.2 → flameox-0.2.4}/src/flameox/workers/protocol.py +1 -0
  46. flameox-0.2.4/src/flameox/workers/pstats.py +58 -0
  47. flameox-0.2.4/src/flameox/workers/pstats_contract.py +40 -0
  48. flameox-0.2.4/src/flameox/workers/pyperf_target.py +25 -0
  49. {flameox-0.2.2 → flameox-0.2.4}/src/flameox/workers/v8_profiles.py +1 -17
  50. {flameox-0.2.2 → flameox-0.2.4}/src/flameox/workers/v8_profiles_contract.py +0 -1
  51. {flameox-0.2.2 → flameox-0.2.4}/tests/adapters/test_memray_aggregation.py +8 -57
  52. {flameox-0.2.2 → flameox-0.2.4}/tests/performance/test_stateless_scale.py +1 -1
  53. {flameox-0.2.2 → flameox-0.2.4}/tests/providers/test_compute_sanitizer.py +2 -1
  54. {flameox-0.2.2 → flameox-0.2.4}/tests/providers/test_cpu.py +42 -7
  55. {flameox-0.2.2 → flameox-0.2.4}/tests/providers/test_inference_exports.py +4 -4
  56. {flameox-0.2.2 → flameox-0.2.4}/tests/providers/test_kernel_evidence.py +3 -3
  57. {flameox-0.2.2 → flameox-0.2.4}/tests/providers/test_nsight_compute.py +51 -4
  58. {flameox-0.2.2 → flameox-0.2.4}/tests/providers/test_nsight_systems.py +5 -3
  59. {flameox-0.2.2 → flameox-0.2.4}/tests/providers/test_nvbench.py +4 -4
  60. {flameox-0.2.2 → flameox-0.2.4}/tests/providers/test_rocprof.py +4 -2
  61. {flameox-0.2.2 → flameox-0.2.4}/tests/providers/test_xctrace.py +2 -1
  62. flameox-0.2.4/tests/test_cli_stateless.py +398 -0
  63. {flameox-0.2.2 → flameox-0.2.4}/tests/test_release_metadata.py +0 -2
  64. flameox-0.2.4/tests/test_runtime_contracts.py +25 -0
  65. flameox-0.2.4/tests/test_setup_stateless.py +437 -0
  66. {flameox-0.2.2 → flameox-0.2.4}/tests/test_stateless.py +577 -404
  67. {flameox-0.2.2 → flameox-0.2.4}/uv.lock +46 -14
  68. flameox-0.2.2/README.md +0 -122
  69. flameox-0.2.2/docs/architecture.md +0 -64
  70. flameox-0.2.2/docs/interfaces.md +0 -108
  71. flameox-0.2.2/npm/README.md +0 -14
  72. flameox-0.2.2/src/flameox/cli.py +0 -297
  73. flameox-0.2.2/src/flameox/mcp/server.py +0 -271
  74. flameox-0.2.2/src/flameox/setup.py +0 -141
  75. flameox-0.2.2/tests/fixtures/compute_sanitizer/kernel_probe.cu +0 -26
  76. flameox-0.2.2/tests/fixtures/coverage/README.md +0 -34
  77. flameox-0.2.2/tests/fixtures/coverage/coverage-7.13.sqlite +0 -0
  78. flameox-0.2.2/tests/fixtures/coverage/coverage-7.14.sqlite +0 -0
  79. flameox-0.2.2/tests/fixtures/coverage/coverage-7.15.sqlite +0 -0
  80. flameox-0.2.2/tests/fixtures/coverage/workload.py +0 -12
  81. flameox-0.2.2/tests/fixtures/kernel_validation/pass.json +0 -57
  82. flameox-0.2.2/tests/fixtures/nsight_compute/basic.py.txt +0 -154
  83. flameox-0.2.2/tests/fixtures/nsight_compute/corrupt.py.txt +0 -2
  84. flameox-0.2.2/tests/fixtures/nsight_compute/invalid_uint64.py.txt +0 -49
  85. flameox-0.2.2/tests/fixtures/nsight_compute/multi_range.py.txt +0 -47
  86. flameox-0.2.2/tests/fixtures/nsight_compute/source_files.py.txt +0 -46
  87. flameox-0.2.2/tests/fixtures/nsight_compute/source_markers.py.txt +0 -53
  88. flameox-0.2.2/tests/fixtures/nsight_compute/uint_boundaries.py.txt +0 -68
  89. flameox-0.2.2/tests/fixtures/pyspy/chrometrace-0.4.2.json +0 -1
  90. flameox-0.2.2/tests/fixtures/rocprofv3/project-owned-rocm-shaped-perfetto.json +0 -47
  91. flameox-0.2.2/tests/fixtures/triton/vector_add.py.txt +0 -20
  92. flameox-0.2.2/tests/support/execution.py +0 -36
  93. flameox-0.2.2/tests/test_cli_stateless.py +0 -216
  94. flameox-0.2.2/tests/test_runtime_contracts.py +0 -12
  95. flameox-0.2.2/tests/test_setup_stateless.py +0 -81
  96. {flameox-0.2.2 → flameox-0.2.4}/.devcontainer/devcontainer.json +0 -0
  97. {flameox-0.2.2 → flameox-0.2.4}/.env.example +0 -0
  98. {flameox-0.2.2 → flameox-0.2.4}/.github/CODEOWNERS +0 -0
  99. {flameox-0.2.2 → flameox-0.2.4}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
  100. {flameox-0.2.2 → flameox-0.2.4}/.github/ISSUE_TEMPLATE/config.yml +0 -0
  101. {flameox-0.2.2 → flameox-0.2.4}/.github/ISSUE_TEMPLATE/design_discussion.yml +0 -0
  102. {flameox-0.2.2 → flameox-0.2.4}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
  103. {flameox-0.2.2 → flameox-0.2.4}/.github/labels.yml +0 -0
  104. {flameox-0.2.2 → flameox-0.2.4}/.github/pull_request_template.md +0 -0
  105. {flameox-0.2.2 → flameox-0.2.4}/.github/renovate.json +0 -0
  106. {flameox-0.2.2 → flameox-0.2.4}/.github/workflows/ci.yml +0 -0
  107. {flameox-0.2.2 → flameox-0.2.4}/.github/workflows/labels.yml +0 -0
  108. {flameox-0.2.2 → flameox-0.2.4}/.github/workflows/release-please.yml +0 -0
  109. {flameox-0.2.2 → flameox-0.2.4}/.gitignore +0 -0
  110. {flameox-0.2.2 → flameox-0.2.4}/.jscpd.json +0 -0
  111. {flameox-0.2.2 → flameox-0.2.4}/.pre-commit-config.yaml +0 -0
  112. {flameox-0.2.2 → flameox-0.2.4}/.python-version +0 -0
  113. {flameox-0.2.2 → flameox-0.2.4}/AGENTS.md +0 -0
  114. {flameox-0.2.2 → flameox-0.2.4}/LICENSE +0 -0
  115. {flameox-0.2.2 → flameox-0.2.4}/SECURITY.md +0 -0
  116. {flameox-0.2.2 → flameox-0.2.4}/cliff.toml +0 -0
  117. {flameox-0.2.2 → flameox-0.2.4}/docs/assets/flameox-mascot-flamegraph.png +0 -0
  118. {flameox-0.2.2 → flameox-0.2.4}/examples/semantic-matrix/semantic_workload.py +0 -0
  119. {flameox-0.2.2 → flameox-0.2.4}/mcp-publisher +0 -0
  120. {flameox-0.2.2 → flameox-0.2.4}/mcp-publisher.tar.gz +0 -0
  121. {flameox-0.2.2 → flameox-0.2.4}/npm/.oxlintrc.json +0 -0
  122. {flameox-0.2.2 → flameox-0.2.4}/npm/bin/flameox.cjs +0 -0
  123. {flameox-0.2.2 → flameox-0.2.4}/src/flameox/__init__.py +0 -0
  124. {flameox-0.2.2 → flameox-0.2.4}/src/flameox/__main__.py +0 -0
  125. {flameox-0.2.2 → flameox-0.2.4}/src/flameox/adapters/__init__.py +0 -0
  126. {flameox-0.2.2 → flameox-0.2.4}/src/flameox/adapters/sarif.py +0 -0
  127. {flameox-0.2.2 → flameox-0.2.4}/src/flameox/adapters/torch_benchmark.py +0 -0
  128. {flameox-0.2.2 → flameox-0.2.4}/src/flameox/atomic.py +0 -0
  129. {flameox-0.2.2 → flameox-0.2.4}/src/flameox/benchmark_samples.py +0 -0
  130. {flameox-0.2.2 → flameox-0.2.4}/src/flameox/canonical.py +0 -0
  131. {flameox-0.2.2 → flameox-0.2.4}/src/flameox/command_binding.py +0 -0
  132. {flameox-0.2.2 → flameox-0.2.4}/src/flameox/environment_policy.py +0 -0
  133. {flameox-0.2.2 → flameox-0.2.4}/src/flameox/executable_models.py +0 -0
  134. {flameox-0.2.2 → flameox-0.2.4}/src/flameox/execution.py +0 -0
  135. {flameox-0.2.2 → flameox-0.2.4}/src/flameox/filesystem.py +0 -0
  136. {flameox-0.2.2 → flameox-0.2.4}/src/flameox/mcp/__init__.py +0 -0
  137. {flameox-0.2.2 → flameox-0.2.4}/src/flameox/models.py +0 -0
  138. {flameox-0.2.2 → flameox-0.2.4}/src/flameox/nsight_compute.py +0 -0
  139. {flameox-0.2.2 → flameox-0.2.4}/src/flameox/process_models.py +0 -0
  140. {flameox-0.2.2 → flameox-0.2.4}/src/flameox/providers/__init__.py +0 -0
  141. {flameox-0.2.2 → flameox-0.2.4}/src/flameox/providers/aiperf.py +0 -0
  142. {flameox-0.2.2 → flameox-0.2.4}/src/flameox/providers/benchmarks.py +0 -0
  143. {flameox-0.2.2 → flameox-0.2.4}/src/flameox/providers/contracts.py +0 -0
  144. {flameox-0.2.2 → flameox-0.2.4}/src/flameox/providers/cpu.py +0 -0
  145. {flameox-0.2.2 → flameox-0.2.4}/src/flameox/providers/inference_exports.py +0 -0
  146. {flameox-0.2.2 → flameox-0.2.4}/src/flameox/providers/kernel_evidence.py +0 -0
  147. {flameox-0.2.2 → flameox-0.2.4}/src/flameox/providers/nsight_systems.py +0 -0
  148. {flameox-0.2.2 → flameox-0.2.4}/src/flameox/providers/otlp.py +0 -0
  149. {flameox-0.2.2 → flameox-0.2.4}/src/flameox/providers/perfetto.py +0 -0
  150. {flameox-0.2.2 → flameox-0.2.4}/src/flameox/providers/xctrace.py +0 -0
  151. {flameox-0.2.2 → flameox-0.2.4}/src/flameox/py.typed +0 -0
  152. {flameox-0.2.2 → flameox-0.2.4}/src/flameox/pytest_runner.py +0 -0
  153. {flameox-0.2.2 → flameox-0.2.4}/src/flameox/runtime_errors.py +0 -0
  154. {flameox-0.2.2 → flameox-0.2.4}/src/flameox/sdk.py +0 -0
  155. {flameox-0.2.2 → flameox-0.2.4}/src/flameox/workers/__init__.py +0 -0
  156. {flameox-0.2.2 → flameox-0.2.4}/src/flameox/workers/aiperf.py +0 -0
  157. {flameox-0.2.2 → flameox-0.2.4}/src/flameox/workers/aiperf_contract.py +0 -0
  158. {flameox-0.2.2 → flameox-0.2.4}/src/flameox/workers/benchmark_samples.py +0 -0
  159. {flameox-0.2.2 → flameox-0.2.4}/src/flameox/workers/benchmark_samples_contract.py +0 -0
  160. {flameox-0.2.2 → flameox-0.2.4}/src/flameox/workers/nsight_compute.py +0 -0
  161. {flameox-0.2.2 → flameox-0.2.4}/src/flameox/workers/nsight_compute_contract.py +0 -0
  162. {flameox-0.2.2 → flameox-0.2.4}/src/flameox/workers/nsight_systems.py +0 -0
  163. {flameox-0.2.2 → flameox-0.2.4}/src/flameox/workers/nsight_systems_contract.py +0 -0
  164. {flameox-0.2.2 → flameox-0.2.4}/src/flameox/workers/otlp.py +0 -0
  165. {flameox-0.2.2 → flameox-0.2.4}/src/flameox/workers/otlp_contract.py +0 -0
  166. {flameox-0.2.2 → flameox-0.2.4}/src/flameox/workers/otlp_parser.py +0 -0
  167. {flameox-0.2.2 → flameox-0.2.4}/src/flameox/workers/parquet_schemas.py +0 -0
  168. {flameox-0.2.2 → flameox-0.2.4}/src/flameox/workers/perfetto.py +0 -0
  169. {flameox-0.2.2 → flameox-0.2.4}/src/flameox/workers/perfetto_contract.py +0 -0
  170. {flameox-0.2.2 → flameox-0.2.4}/src/flameox/workers/pyperf.py +0 -0
  171. {flameox-0.2.2 → flameox-0.2.4}/src/flameox/workers/pyperf_contract.py +0 -0
  172. {flameox-0.2.2 → flameox-0.2.4}/tests/__init__.py +0 -0
  173. {flameox-0.2.2 → flameox-0.2.4}/tests/adapters/test_torch_benchmark.py +0 -0
  174. {flameox-0.2.2 → flameox-0.2.4}/tests/adapters/test_torch_benchmark_live.py +0 -0
  175. {flameox-0.2.2 → flameox-0.2.4}/tests/conftest.py +0 -0
  176. {flameox-0.2.2 → flameox-0.2.4}/tests/execution/test_bound_execution.py +0 -0
  177. {flameox-0.2.2 → flameox-0.2.4}/tests/execution/test_broker.py +0 -0
  178. {flameox-0.2.2 → flameox-0.2.4}/tests/execution/test_command_binding.py +0 -0
  179. {flameox-0.2.2 → flameox-0.2.4}/tests/providers/test_aiperf.py +0 -0
  180. {flameox-0.2.2 → flameox-0.2.4}/tests/providers/test_contracts.py +0 -0
  181. {flameox-0.2.2 → flameox-0.2.4}/tests/storage/test_bounded_filesystem.py +0 -0
  182. {flameox-0.2.2 → flameox-0.2.4}/tests/support/__init__.py +0 -0
  183. {flameox-0.2.2 → flameox-0.2.4}/tests/support/providers.py +0 -0
  184. {flameox-0.2.2 → flameox-0.2.4}/tests/test_canonical.py +0 -0
  185. {flameox-0.2.2 → flameox-0.2.4}/tests/test_sdk.py +0 -0
  186. {flameox-0.2.2 → flameox-0.2.4}/tools/__init__.py +0 -0
@@ -300,9 +300,35 @@ jobs:
300
300
  tar -xzf "$archive" mcp-publisher
301
301
 
302
302
  - name: Publish MCP server metadata
303
+ env:
304
+ RELEASE_VERSION: ${{ needs.build.outputs.version }}
303
305
  run: |
306
+ set -euo pipefail
304
307
  ./mcp-publisher login github-oidc
305
- ./mcp-publisher publish server.json
308
+ for attempt in {1..12}; do
309
+ set +e
310
+ output=$(./mcp-publisher publish server.json 2>&1)
311
+ status=$?
312
+ set -e
313
+ printf '%s\n' "$output"
314
+
315
+ if [[ "$status" -eq 0 ]]; then
316
+ exit 0
317
+ fi
318
+
319
+ missing_version="version '${RELEASE_VERSION}' was not found (status: 404)"
320
+ if ! grep --fixed-strings --quiet "$missing_version" <<< "$output"; then
321
+ exit "$status"
322
+ fi
323
+
324
+ if [[ "$attempt" -lt 12 ]]; then
325
+ echo "MCP Registry has not observed PyPI $RELEASE_VERSION; retrying in 10 seconds"
326
+ sleep 10
327
+ fi
328
+ done
329
+
330
+ echo "MCP Registry did not observe PyPI $RELEASE_VERSION within 120 seconds" >&2
331
+ exit 1
306
332
 
307
333
  verify-npm-latest:
308
334
  name: Verify npm latest bootstrap
@@ -2,6 +2,56 @@
2
2
 
3
3
  All notable changes to flameox are documented in this file.
4
4
 
5
+ ## [0.2.4] - 2026-09-02
6
+
7
+ ### Bug Fixes
8
+
9
+ - **mcp:** Include cwd in capture examples
10
+ - **release:** Retry MCP registry propagation
11
+
12
+ ### Documentation
13
+
14
+ - Explain workspace-free evidence runtime
15
+
16
+ ### Features
17
+
18
+ - **setup:** Configure global MCP clients
19
+
20
+ ### Refactoring
21
+
22
+ - **runtime:** Simplify bounded capture lifecycle
23
+ - **runtime:** Remove workspace binding
24
+
25
+ ### Styling
26
+
27
+ - Format capture provider module
28
+
29
+ ### Testing
30
+
31
+ - Remove stale redesign assertions
32
+ - Remove unused execution helper
33
+ ## [0.2.3] - 2026-09-02
34
+
35
+ ### Bug Fixes
36
+
37
+ - **setup:** Pin generated MCP launchers
38
+
39
+ ### Documentation
40
+
41
+ - **mcp:** Clarify provider and comparison workflows
42
+ - **setup:** Clarify uvx preparation lifecycle (#421) ([#421](https://github.com/morluto/flameox/pull/421))
43
+
44
+ ### Features
45
+
46
+ - **mcp:** Return provider reconnection action
47
+ - **mcp:** Expose typed capability tools (#422) ([#422](https://github.com/morluto/flameox/pull/422))
48
+ - **mcp:** Restore explicit provider preparation (#419) ([#419](https://github.com/morluto/flameox/pull/419))
49
+ - **runtime:** Unify bounded capture contracts (#417) ([#417](https://github.com/morluto/flameox/pull/417))
50
+
51
+ ### Refactoring
52
+
53
+ - **setup:** Prepare the returned uvx environment (#420) ([#420](https://github.com/morluto/flameox/pull/420))
54
+ - **runtime:** Validate captures atomically (#418) ([#418](https://github.com/morluto/flameox/pull/418))
5
55
  ## [0.2.2] - 2026-09-01
6
56
 
7
57
  ### Bug Fixes
@@ -45,11 +45,11 @@ uv sync --extra dev --extra memory --extra trace --extra cpu --extra torch
45
45
 
46
46
  ## Understand the contract you are changing
47
47
 
48
- Production code uses a `src/` layout. Domain types and errors belong in
49
- `src/flameox/domain/`, transport-independent orchestration in
50
- `src/flameox/application/`, persistence in `src/flameox/storage/`, external tool
51
- integration in `src/flameox/adapters/`, and transport code in `src/flameox/cli.py`
52
- and `src/flameox/mcp/`. Tests mirror these boundaries under `tests/`.
48
+ Production code uses a `src/` layout. `runtime_contracts.py` owns public contracts and registries,
49
+ `stateless.py` owns request-local orchestration, `repository.py` owns optional immutable
50
+ preservation, and `execution.py` owns bounded subprocess work. Provider integrations live in
51
+ `providers/`, reusable native-format parsing in `adapters/`, isolated protocols in `workers/`, and
52
+ transport code in `cli.py` and `mcp/`. Tests mirror these semantic owners under `tests/`.
53
53
 
54
54
  Read the contract that owns the behavior before editing it:
55
55
 
@@ -58,7 +58,7 @@ Read the contract that owns the behavior before editing it:
58
58
  | Process model, dependencies, and package boundaries | [Architecture](docs/architecture.md) |
59
59
  | Storage, provenance, publication, and schemas | [Storage and evidence](docs/storage-and-evidence.md) |
60
60
  | Experiments, comparisons, statistics, and evidence quality | [Investigations](docs/investigations.md) |
61
- | Profiler integrations, compatibility, and capability probing | [Adapters](docs/adapters.md) |
61
+ | Profiler integrations, compatibility, and adapter policy | [Adapters](docs/adapters.md) |
62
62
  | Concurrency, recovery, integrity, security, and privacy | [Runtime safety](docs/runtime-safety.md) |
63
63
  | CLI and MCP behavior and trust boundaries | [Interfaces](docs/interfaces.md) |
64
64
  | Test markers, provider requirements, and CI | [Testing](docs/testing.md) |
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: flameox
3
- Version: 0.2.2
3
+ Version: 0.2.4
4
4
  Summary: Runtime evidence that helps agents trace, profile, and burn down hotspots in application and native code, GPU kernels, and inference stacks.
5
5
  Project-URL: Homepage, https://github.com/morluto/flameox
6
6
  Project-URL: Repository, https://github.com/morluto/flameox
@@ -16,13 +16,14 @@ Requires-Dist: ijson<4,>=3.4
16
16
  Requires-Dist: mcp-types==2.0.0
17
17
  Requires-Dist: mcp==2.0.0
18
18
  Requires-Dist: packaging<27,>=24
19
- Requires-Dist: portalocker<4,>=3.2
20
19
  Requires-Dist: psutil<8,>=7.0
21
20
  Requires-Dist: pyarrow<26,>=20
22
21
  Requires-Dist: pydantic<2.14,>=2.13.4
23
22
  Requires-Dist: pyperf<2.11,>=2.10
24
23
  Requires-Dist: pytz>=2024.2
24
+ Requires-Dist: questionary<3,>=2.1
25
25
  Requires-Dist: rfc8785==0.1.4
26
+ Requires-Dist: tomlkit<1,>=0.13
26
27
  Requires-Dist: typer<1,>=0.16
27
28
  Provides-Extra: all
28
29
  Requires-Dist: aiperf<0.13,>=0.12; extra == 'all'
@@ -77,23 +78,36 @@ paths and formats to `analyze`; old `.diagnostics` state is not migrated.
77
78
 
78
79
  ```console
79
80
  uv sync --extra dev --extra memory --extra trace --extra cpu
80
- uv run flameox capabilities discover --intent "CPU hotspots"
81
+ uv run flameox mcp inspect
81
82
  uv run flameox analyze artifact.preview /absolute/path/to/artifact.json
82
- uv run flameox capture --provider direct -- python benchmark.py
83
+ uv run flameox capture --provider direct --cwd "$PWD" -- python benchmark.py
83
84
  ```
84
85
 
85
- The MCP server fixes its project root at startup. Manual launches default to
86
- the startup working directory:
86
+ The MCP server has no workspace or project binding:
87
87
 
88
88
  ```console
89
- uv run flameox mcp serve --project-root "$PWD"
89
+ uv run flameox mcp serve
90
90
  ```
91
91
 
92
- `flameox setup` prints the equivalent stdio client configuration. Explicit
93
- `--provider` selections add the matching Python extras to a persistent uv tool
94
- environment without removing its existing provider extras. System and vendor
95
- tools are diagnosed with external install guidance. Setup never initializes the
96
- project or creates `.flameox`.
92
+ Run the short global setup wizard through npm:
93
+
94
+ ```console
95
+ npx flameox@latest setup
96
+ ```
97
+
98
+ Setup detects Claude Code, Cursor, OpenCode, Codex, Gemini CLI, and Google Antigravity, then asks
99
+ which clients should use Flameox. It preserves unrelated client configuration and writes a
100
+ Python 3.12 `uvx` launcher pinned to the exact Flameox release that ran setup. Restart or reconnect
101
+ changed clients afterward. For automation, pass `--client codex --yes`, repeat `--client`, or use
102
+ `--all --yes`; `--dry-run` reports the same global paths without writing them. Detection is never
103
+ automation consent.
104
+
105
+ Explicit `--provider` selections prepare the exact version-pinned `uvx` environment in the saved
106
+ launcher by resolving it once into uvx's cache; they do not create a persistent global `uv tool`
107
+ installation. Each invocation declares the complete managed provider set for that launcher rather
108
+ than adding to remembered state. Use `--timeout-seconds` for a slow cold resolution. System and
109
+ vendor tools are diagnosed with external install guidance. Setup never initializes or mutates a
110
+ project.
97
111
 
98
112
  ## Authority model
99
113
 
@@ -109,14 +123,16 @@ explicit artifact paths / typed direct target
109
123
  explicit preservation
110
124
  │
111
125
  ▼
112
- <project>/.flameox
126
+ user Flameox data directory
113
127
  ```
114
128
 
115
129
  Analysis and unpreserved capture make no durable Flameox writes. Capture
116
- artifacts stay in bounded session scratch until preservation or server
117
- shutdown. The first `preserve_evidence` call creates `.flameox`, stores native
118
- bytes and a canonical evidence bundle by SHA-256, and adds `.flameox/` to the
119
- repository-local `.git/info/exclude` when applicable.
130
+ artifacts stay in bounded session scratch until preservation, least-recently-used eviction, or
131
+ server shutdown. An evicted `analysis_id` returns `EXPIRED_SESSION_ANALYSIS`; preserve conclusions
132
+ before relying on them. The first `preserve_evidence` call creates the user-level Flameox data
133
+ directory and stores native bytes and a canonical evidence bundle by SHA-256. `FLAMEOX_DATA_DIR`
134
+ overrides the platform default for isolation or another storage location. Flameox never edits
135
+ project Git files.
120
136
 
121
137
  The agent owns hypotheses and narrative findings in its own notes. Flameox owns
122
138
  only observed inputs, effective requests, execution provenance, typed evidence,
@@ -124,14 +140,23 @@ coverage, truncation, limitations, and optional immutable preservation.
124
140
 
125
141
  ## MCP interface
126
142
 
127
- The server exposes exactly six tools:
143
+ The server exposes actual evidence operations for client-side tool search instead of hiding its
144
+ capabilities behind `discover`, `inspect`, or generic `analyze(capability_id, arguments)` calls.
145
+ There are 24 read-only analysis tools, 17 executing capture tools, and three lifecycle tools. For
146
+ example:
147
+
148
+ ```text
149
+ analyze_cpu_hotspots capture_cpu_hotspots
150
+ analyze_gpu_launches capture_gpu_launches
151
+ analyze_benchmark_compare capture_benchmark_summary
152
+ analyze_kernel_validation capture_sanitizer_failures
153
+ prepare_providers preserve_evidence query_evidence
154
+ ```
128
155
 
129
- - `discover_capabilities`
130
- - `inspect_capabilities`
131
- - `analyze`
132
- - `capture_and_analyze`
133
- - `preserve_evidence`
134
- - `query_evidence`
156
+ Each tool advertises its capability-specific options and compatible providers in its input schema.
157
+ Analysis and capture have separate names and annotations because reading an artifact and executing a
158
+ target are materially different effects. Tool search happens in the MCP client; Flameox does not
159
+ require an additional catalog-search call.
135
160
 
136
161
  It exposes one resource template, `flameox://evidence/{evidence_id}`, for the
137
162
  digest-bound, redacted projection of the canonical immutable manifest. Full
@@ -139,16 +164,28 @@ argv, environment values, working directories, and host paths remain available
139
164
  only through explicit local manifest inspection. Native artifact bytes are
140
165
  deliberately not available as MCP resources.
141
166
 
142
- Direct capture accepts an argv array, a project-contained cwd, bounded
143
- environment overrides, provider and analysis arguments, and limits. Shell
144
- strings are never accepted. Work remains owned by the live MCP request, so SDK
145
- progress and cancellation apply directly; there are no detached or
146
- restart-surviving tasks.
167
+ Direct capture accepts an argv array, an explicit absolute cwd, bounded environment overrides, a
168
+ typed compatible-provider variant, capability-specific options, an explicit single/experiment
169
+ choice, and limits as top-level tool arguments. There is no generic request or arguments envelope.
170
+ Shell strings are never accepted. Work remains owned by the live MCP request, so SDK progress and
171
+ cancellation apply directly; there are no detached or restart-surviving tasks.
147
172
 
148
- Managed external collectors such as py-spy execute from Flameox's uv tool
173
+ Managed external collectors such as py-spy execute from Flameox's uvx
149
174
  environment. In-process collectors such as coverage.py and Memray are verified
150
175
  in, and run with, the workload's declared Python interpreter. Flameox does not
151
- substitute one Python runtime for the other.
176
+ substitute one Python runtime for the other. When a capture reports a missing managed provider,
177
+ `prepare_providers` prepares its version-pinned uvx environment and returns that same launcher for
178
+ reconnection. The agent supplies the complete provider list it wants in that launcher; Flameox does
179
+ not merge it with prior calls. Preparation does not modify the running MCP process. When the client
180
+ must reconnect, the result returns a typed `next_action` with `kind: "reconnect_mcp"`, an agent-facing
181
+ message, and the launcher to use. The managed provider IDs are `aiperf`, `memray`, `otlp`, `perfetto`,
182
+ `py-spy`, and `torch`. Host tools, drivers, and permissions are never installed or changed; the same
183
+ result reports their setup guidance.
184
+
185
+ Comparison is intentionally a two-stage workflow. Flameox captures representative baseline and
186
+ candidate summaries separately, optionally preserves them, and then passes both artifacts to an
187
+ `analyze_*_compare` tool. There are no `capture_*_compare` tools: experiment capture measures cases
188
+ and reports an effect, but it is not a substitute for comparing explicit native artifacts.
152
189
 
153
190
  ## Evidence quality
154
191
 
@@ -0,0 +1,158 @@
1
+ <h1 align="center">flameox</h1>
2
+
3
+ <p align="center"><strong>Bounded local runtime evidence for coding agents.</strong></p>
4
+
5
+ <!-- mcp-name: io.github.morluto/flameox -->
6
+
7
+ Flameox coordinates profilers, benchmark tools, trace processors, and direct
8
+ local targets. It gives an agent a short path from an explicit native artifact
9
+ or live command to bounded evidence, while keeping preservation optional.
10
+
11
+ Version 0.2 is a clean break. There is no workspace to initialize, no
12
+ `flameox.toml`, no SQLite control plane, no durable job to poll, and no parent
13
+ directory discovery. Existing artifacts remain usable by passing their exact
14
+ paths and formats to `analyze`; old `.diagnostics` state is not migrated.
15
+
16
+ ## Quick start
17
+
18
+ ```console
19
+ uv sync --extra dev --extra memory --extra trace --extra cpu
20
+ uv run flameox mcp inspect
21
+ uv run flameox analyze artifact.preview /absolute/path/to/artifact.json
22
+ uv run flameox capture --provider direct --cwd "$PWD" -- python benchmark.py
23
+ ```
24
+
25
+ The MCP server has no workspace or project binding:
26
+
27
+ ```console
28
+ uv run flameox mcp serve
29
+ ```
30
+
31
+ Run the short global setup wizard through npm:
32
+
33
+ ```console
34
+ npx flameox@latest setup
35
+ ```
36
+
37
+ Setup detects Claude Code, Cursor, OpenCode, Codex, Gemini CLI, and Google Antigravity, then asks
38
+ which clients should use Flameox. It preserves unrelated client configuration and writes a
39
+ Python 3.12 `uvx` launcher pinned to the exact Flameox release that ran setup. Restart or reconnect
40
+ changed clients afterward. For automation, pass `--client codex --yes`, repeat `--client`, or use
41
+ `--all --yes`; `--dry-run` reports the same global paths without writing them. Detection is never
42
+ automation consent.
43
+
44
+ Explicit `--provider` selections prepare the exact version-pinned `uvx` environment in the saved
45
+ launcher by resolving it once into uvx's cache; they do not create a persistent global `uv tool`
46
+ installation. Each invocation declares the complete managed provider set for that launcher rather
47
+ than adding to remembered state. Use `--timeout-seconds` for a slow cold resolution. System and
48
+ vendor tools are diagnosed with external install guidance. Setup never initializes or mutates a
49
+ project.
50
+
51
+ ## Authority model
52
+
53
+ ```text
54
+ explicit artifact paths / typed direct target
55
+ │
56
+ ▼
57
+ bounded process-lifespan runtime
58
+ │ │
59
+ ▼ ▼
60
+ inline evidence session scratch/cache
61
+ │
62
+ explicit preservation
63
+ │
64
+ ▼
65
+ user Flameox data directory
66
+ ```
67
+
68
+ Analysis and unpreserved capture make no durable Flameox writes. Capture
69
+ artifacts stay in bounded session scratch until preservation, least-recently-used eviction, or
70
+ server shutdown. An evicted `analysis_id` returns `EXPIRED_SESSION_ANALYSIS`; preserve conclusions
71
+ before relying on them. The first `preserve_evidence` call creates the user-level Flameox data
72
+ directory and stores native bytes and a canonical evidence bundle by SHA-256. `FLAMEOX_DATA_DIR`
73
+ overrides the platform default for isolation or another storage location. Flameox never edits
74
+ project Git files.
75
+
76
+ The agent owns hypotheses and narrative findings in its own notes. Flameox owns
77
+ only observed inputs, effective requests, execution provenance, typed evidence,
78
+ coverage, truncation, limitations, and optional immutable preservation.
79
+
80
+ ## MCP interface
81
+
82
+ The server exposes actual evidence operations for client-side tool search instead of hiding its
83
+ capabilities behind `discover`, `inspect`, or generic `analyze(capability_id, arguments)` calls.
84
+ There are 24 read-only analysis tools, 17 executing capture tools, and three lifecycle tools. For
85
+ example:
86
+
87
+ ```text
88
+ analyze_cpu_hotspots capture_cpu_hotspots
89
+ analyze_gpu_launches capture_gpu_launches
90
+ analyze_benchmark_compare capture_benchmark_summary
91
+ analyze_kernel_validation capture_sanitizer_failures
92
+ prepare_providers preserve_evidence query_evidence
93
+ ```
94
+
95
+ Each tool advertises its capability-specific options and compatible providers in its input schema.
96
+ Analysis and capture have separate names and annotations because reading an artifact and executing a
97
+ target are materially different effects. Tool search happens in the MCP client; Flameox does not
98
+ require an additional catalog-search call.
99
+
100
+ It exposes one resource template, `flameox://evidence/{evidence_id}`, for the
101
+ digest-bound, redacted projection of the canonical immutable manifest. Full
102
+ argv, environment values, working directories, and host paths remain available
103
+ only through explicit local manifest inspection. Native artifact bytes are
104
+ deliberately not available as MCP resources.
105
+
106
+ Direct capture accepts an argv array, an explicit absolute cwd, bounded environment overrides, a
107
+ typed compatible-provider variant, capability-specific options, an explicit single/experiment
108
+ choice, and limits as top-level tool arguments. There is no generic request or arguments envelope.
109
+ Shell strings are never accepted. Work remains owned by the live MCP request, so SDK progress and
110
+ cancellation apply directly; there are no detached or restart-surviving tasks.
111
+
112
+ Managed external collectors such as py-spy execute from Flameox's uvx
113
+ environment. In-process collectors such as coverage.py and Memray are verified
114
+ in, and run with, the workload's declared Python interpreter. Flameox does not
115
+ substitute one Python runtime for the other. When a capture reports a missing managed provider,
116
+ `prepare_providers` prepares its version-pinned uvx environment and returns that same launcher for
117
+ reconnection. The agent supplies the complete provider list it wants in that launcher; Flameox does
118
+ not merge it with prior calls. Preparation does not modify the running MCP process. When the client
119
+ must reconnect, the result returns a typed `next_action` with `kind: "reconnect_mcp"`, an agent-facing
120
+ message, and the launcher to use. The managed provider IDs are `aiperf`, `memray`, `otlp`, `perfetto`,
121
+ `py-spy`, and `torch`. Host tools, drivers, and permissions are never installed or changed; the same
122
+ result reports their setup guidance.
123
+
124
+ Comparison is intentionally a two-stage workflow. Flameox captures representative baseline and
125
+ candidate summaries separately, optionally preserves them, and then passes both artifacts to an
126
+ `analyze_*_compare` tool. There are no `capture_*_compare` tools: experiment capture measures cases
127
+ and reports an effect, but it is not a substitute for comparing explicit native artifacts.
128
+
129
+ ## Evidence quality
130
+
131
+ An investigation still follows:
132
+
133
+ ```text
134
+ symptom → capture or explicit artifact → bounded evidence → hypothesis
135
+ → discriminating experiment → supported, refuted, or inconclusive finding
136
+ ```
137
+
138
+ A profile supports exploration, not causality. Confirmatory claims require a
139
+ representative target, declared metric and estimand, compatible identities,
140
+ preserved samples, a practical threshold, and an appropriate semantic oracle.
141
+
142
+ See [architecture](docs/architecture.md), [storage and evidence](docs/storage-and-evidence.md),
143
+ [interfaces](docs/interfaces.md), [runtime safety](docs/runtime-safety.md), and
144
+ [investigations](docs/investigations.md) for the contracts.
145
+
146
+ ## Development
147
+
148
+ Flameox requires Python 3.12 or newer and uses the committed `uv.lock`.
149
+
150
+ ```console
151
+ uv run ruff check src tests tools
152
+ uv run ruff format --check src tests tools
153
+ uv run mypy src tests tools
154
+ uv run lint-imports
155
+ uv run pytest -q
156
+ ```
157
+
158
+ The project is licensed under the MIT License.
@@ -5,27 +5,28 @@ Flameox 是面向编码代理的本地、有界运行时证据层。它协调分
5
5
 
6
6
  0.2 是一次不兼容重构:无需初始化工作区,没有命名工作负载、SQLite 控制面、
7
7
  持久 DuckDB 目录或可轮询的后台任务。调用方直接传入原生证据的绝对路径,或
8
- 包含 argv、项目内 cwd、环境覆盖、提供方参数和限制的类型化目标。
8
+ 包含 argv、绝对 cwd、环境覆盖、提供方参数和限制的类型化目标。服务本身不绑定项目或工作区。
9
9
 
10
10
  ```console
11
- uv run flameox capabilities discover --intent "CPU 热点"
11
+ uv run flameox mcp inspect
12
12
  uv run flameox analyze artifact.preview /absolute/path/to/artifact.json
13
- uv run flameox capture --provider direct -- python benchmark.py
14
- uv run flameox mcp serve --project-root "$PWD"
13
+ uv run flameox capture --provider direct --cwd "$PWD" -- python benchmark.py
14
+ uv run flameox mcp serve
15
15
  ```
16
16
 
17
17
  `flameox setup` 会输出 MCP 客户端配置。显式传入 `--provider` 时,它可将对应的
18
18
  Python 扩展安装到持久的 uv 工具环境;NVIDIA 等系统或厂商工具则提供外部安装
19
- 指引。setup 不会初始化项目,也不会创建 `.flameox`。
19
+ 指引。setup 不会初始化或修改项目。
20
20
 
21
- 分析和未保存的采集不会在项目中写入 Flameox 状态。只有显式调用
22
- `preserve_evidence` 或 CLI 的 `--preserve` 后,才会延迟创建
23
- `<project>/.flameox`。原生字节和证据清单按 SHA-256 寻址,并通过同一文件系统
24
- 上的暂存、校验、fsync 和原子重命名发布。
21
+ 分析和未保存的采集不会写入持久状态。只有显式调用 `preserve_evidence` 或 CLI 的
22
+ `--preserve` 后,才会延迟创建用户级 Flameox 数据目录;`FLAMEOX_DATA_DIR` 可覆盖
23
+ 平台默认位置。原生字节和证据清单按 SHA-256 寻址,并通过同一文件系统上的暂存、
24
+ 校验、fsync 和原子重命名发布。Flameox 不修改项目的 Git 配置。
25
25
 
26
- MCP 只公开六个工具:`discover_capabilities`、`inspect_capabilities`、
27
- `analyze`、`capture_and_analyze`、`preserve_evidence` 和
28
- `query_evidence`。唯一资源模板是
26
+ MCP 公开面向任务的类型化分析和采集工具,例如 `analyze_cpu_hotspots`、
27
+ `capture_gpu_launches` 和 `analyze_benchmark_compare`,以及
28
+ `prepare_providers`、`preserve_evidence` 和 `query_evidence`。工具搜索由 MCP
29
+ 客户端负责。唯一资源模板是
29
30
  `flameox://evidence/{evidence_id}`,只返回不可变规范清单,不公开原生载荷。
30
31
 
31
32
  `analysis_id` 仅在当前服务进程内有效;重启后过期。`evidence_id` 是持久的内容
@@ -11,14 +11,19 @@ Each capability registry entry owns:
11
11
  - the capability descriptor and stable ID;
12
12
  - accepted source modes and formats;
13
13
  - a strict validation-equivalent argument model;
14
- - provider probes and compatibility rules;
14
+ - compatibility rules derived from declared artifact formats;
15
15
  - capture and analysis handlers;
16
- - bounded examples, limits, overhead, and limitations.
16
+ - model-visible selection guidance, bounded examples, limits, overhead, and limitations.
17
17
 
18
- Discovery probes packages, executables, platform, supported version, permission,
19
- and required external resources without mutating the host. Missing dependencies
20
- are successful availability results with remediation outside Flameox. Invoking
21
- an unavailable provider is a typed tool error.
18
+ One immutable capture-provider contract owns each provider's argument model, declared artifact
19
+ roles and formats, and selection description. Generated MCP schemas, pre-execution compatibility
20
+ checks, and capture argument validation consume that same contract so their format claims cannot
21
+ drift.
22
+
23
+ Capability tools remain discoverable when a provider is absent. Capture validates the selected
24
+ provider's package, executable, platform, version, permission, and required external resources as
25
+ part of the attempted operation, before workload execution. An unavailable provider returns a typed
26
+ error with either an exact `prepare_providers` retry action or external host guidance.
22
27
 
23
28
  ## Evidence and capture support
24
29
 
@@ -29,7 +34,7 @@ Artifact analysis and typed capture are separate contracts:
29
34
 
30
35
  | Evidence family | Explicit artifact analysis | Typed capture provider |
31
36
  | --- | --- | --- |
32
- | CPU profiles | Node/V8, py-spy Speedscope, perf collapsed stacks, perf data | `node-cpu-profile`, `py-spy`, `perf` |
37
+ | CPU profiles | Node/V8, cProfile pstats, py-spy Speedscope, perf collapsed stacks, perf data | `node-cpu-profile`, `py-spy`, `perf` |
33
38
  | Memory profiles | Memray | `memray` |
34
39
  | Benchmarks | pyperf, benchmark samples, PyTorch samples, NVBench | `pyperf`, `benchmark-samples`, `nvbench` |
35
40
  | Execution traces | Perfetto/Chrome, PyTorch, OTLP, ROCprof PFTrace, xctrace, Nsight Systems | `torch-profiler`, `rocprofv3`, `xctrace`, `nsight-systems` |
@@ -37,7 +42,7 @@ Artifact analysis and typed capture are separate contracts:
37
42
  | Reliability | pytest events, observations, coverage.py | `pytest`, `observations`, `coverage` |
38
43
  | Static candidates | SARIF | — |
39
44
  | Inference exports | AIPerf, vLLM, SGLang, Mooncake | — |
40
- | Generic previews | JSON, JSONL, CSV, text, Parquet | — |
45
+ | Generic previews | JSON, JSONL, CSV, text, Parquet | `direct` process output |
41
46
 
42
47
  An em dash means callers provide an explicit artifact path; it does not mean
43
48
  the format is unsupported. The offline inference readers omit prompts,
@@ -45,6 +50,11 @@ generations, error text, endpoints, tools, payloads, and prefix-hash values.
45
50
  Pytest capture runs an explicit `python -m pytest` target with a request-bound,
46
51
  bounded event plugin.
47
52
 
53
+ `failures.summary` scans the complete bounded pytest event artifact for aggregate outcomes, but its
54
+ table projects only failed, errored, interrupted, and unexecuted identities. Failed collection
55
+ reports retain their collector identity; successful collection events, passing tests, and skipped
56
+ tests cannot consume the diagnostic row budget.
57
+
48
58
  Support is honest rather than substitutive. A missing Trace Processor does not
49
59
  turn a Perfetto request into a JSON preview; a missing `ncu` does not become an
50
60
  empty kernel report.
@@ -82,14 +92,22 @@ session-local in-memory DuckDB; it does not create a temporary SQLite database.
82
92
 
83
93
  ## Provider setup boundary
84
94
 
85
- An explicit `flameox setup --provider ...` invocation adds the selected Python
86
- extras to the persistent uv tool environment while retaining extras from its
87
- existing uv receipt. The result reports the complete managed provider set.
95
+ An explicit `flameox setup --provider ...` invocation prepares the exact
96
+ version-pinned uvx environment returned in its launcher. The invocation's
97
+ provider list is complete; Flameox retains no provider inventory or setup receipt.
88
98
  System and vendor packages remain externally installed. Setup creates no
89
99
  project state and is not a prerequisite for explicit-path analysis.
100
+ Nsight Compute capture requires both the `ncu` executable and NVIDIA's vendor-shipped
101
+ `extras/python/ncu_report.py` reader. Flameox resolves both before workload execution and returns
102
+ external setup guidance if the installation is incomplete.
90
103
 
91
104
  Provider ownership is explicit during capture. External collectors installed
92
- with Flameox, such as py-spy, execute from the managed tool environment rather
105
+ with Flameox, such as py-spy, execute from the launched uvx environment rather
93
106
  than ambient request `PATH`. In-process collectors, including coverage.py and
94
107
  Memray, must be installed in the declared workload interpreter; capture probes
95
108
  that interpreter before execution and never substitutes Flameox's interpreter.
109
+
110
+ Pyperf command capture preserves multiline typed argv through a metadata-safe launcher because
111
+ pyperf rejects newline characters in its display metadata. The launcher executes the original argv
112
+ without shell parsing, but its startup is included in each command measurement; exact Flameox
113
+ capture provenance remains authoritative for the requested argv.
@@ -0,0 +1,73 @@
1
+ # Architecture
2
+
3
+ Flameox 0.2 is a process-lifespan capability runtime with an optional immutable
4
+ evidence repository. It is not a workspace application and has no mutable
5
+ control plane.
6
+
7
+ ## Authority map
8
+
9
+ | Concern | Authority |
10
+ | --- | --- |
11
+ | Artifact location | Exact paths supplied by each analysis request |
12
+ | Target location | Exact absolute `cwd` supplied by each capture request |
13
+ | Available operations | Process-lifespan capability registry |
14
+ | In-progress work | Current MCP request and cancellation scope |
15
+ | Unpreserved output | Bounded session scratch |
16
+ | Completed preserved evidence | Immutable manifest in the user Flameox data directory |
17
+ | Native bytes | Content-addressed artifact bundle |
18
+ | Query view | Sorted manifest inventory pinned for one query |
19
+ | Limits | Startup defaults, lowerable per request |
20
+ | Hypotheses and narrative | Agent-owned notes outside Flameox |
21
+
22
+ The runtime has no workspace identity and never searches parent directories. Analysis consumes
23
+ explicit absolute paths. Capture consumes a typed argv and explicit absolute working directory.
24
+ Neither is interpreted relative to server startup.
25
+
26
+ ## Process model
27
+
28
+ `AnalysisRuntime` owns the capability registry, subprocess broker, bounded scratch,
29
+ conversion cache, and least-recently-used session analysis cache. The MCP lifespan creates one
30
+ runtime, exposes it through the SDK request context, and destroys its scratch on shutdown. Evicting
31
+ a capture analysis removes its native session artifacts; a later preservation attempt reports that
32
+ the session handle expired. Long work stays inside the request that started it. Progress is reported
33
+ through the SDK context and cancellation unwinds the broker, including descendant cleanup.
34
+
35
+ `analysis_id` is a session handle. It is intentionally meaningless after
36
+ restart and can only be passed to `preserve_evidence`. `evidence_id` is a
37
+ durable SHA-256 identity derived from the canonical manifest body.
38
+
39
+ ## Package boundaries
40
+
41
+ - `runtime_contracts.py` owns public models and the capability/capture-provider registries.
42
+ - `stateless.py` owns bounded analysis, capture orchestration, scratch, and the session cache.
43
+ - `providers/capture.py` owns provider-specific command construction and expected native outputs;
44
+ `providers/availability.py` owns installation and workload requirements.
45
+ - `repository.py` owns lazy repository creation, validation, publication,
46
+ inventory queries, and immutable resource reads.
47
+ - `execution.py` and `command_binding.py` own executable binding, subprocess
48
+ limits, cancellation, output bounds, and descendant cleanup.
49
+ - `mcp/server.py` and `cli.py` are thin projections over the same runtime.
50
+ - Provider adapters accept resolved explicit inputs and return typed evidence;
51
+ they do not discover source trees or publish evidence.
52
+
53
+ DuckDB may be used in memory for bounded aggregation. It is never a durable
54
+ catalog. Flameox production code must not create or depend on SQLite state.
55
+
56
+ ## Capability boundary
57
+
58
+ One registry entry owns a capability descriptor, strict argument model, accepted formats,
59
+ capture/analysis semantics, and model-visible selection guidance. MCP projects each entry
60
+ into a read-only analysis tool and, when a compatible capture provider exists, a separate executing
61
+ capture tool. The generated callable closes over the stable capability ID; agents never pass a
62
+ capability selector or a free-form analysis argument object.
63
+
64
+ Capture-provider contracts supply the discriminated provider variants for each compatible capture
65
+ tool. Missing packages, executables, permissions, versions, or platforms do not change the catalog;
66
+ the attempted tool returns typed remediation. The separately invoked CLI setup command or MCP
67
+ `prepare_providers` tool may prepare the exact version-pinned uvx environment named by an explicit
68
+ Python provider set; neither creates project state nor owns a durable operation or provider
69
+ inventory. Host profilers, drivers, and permissions remain external and receive guidance only.
70
+
71
+ Direct capture is trusted local execution, not containment. Typed argv prevents
72
+ shell interpretation, while the broker provides process-group cleanup, bounded
73
+ output, timeouts, resource observation, and exact executable identity.