stacktrace-cli 0.2.0__tar.gz → 0.2.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (218) hide show
  1. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/CLAUDE.md +27 -6
  2. stacktrace_cli-0.2.2/PKG-INFO +154 -0
  3. stacktrace_cli-0.2.2/README.md +129 -0
  4. stacktrace_cli-0.2.2/docs/adrs/0028-the-console-shows-what-it-placed.md +108 -0
  5. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/docs/adrs/INDEX.md +1 -0
  6. stacktrace_cli-0.2.2/docs/cutover-openaca-remote.md +87 -0
  7. stacktrace_cli-0.2.2/docs/releases/v0.2.1.md +49 -0
  8. stacktrace_cli-0.2.2/docs/releases/v0.2.2.md +76 -0
  9. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/docs/specs/monitor.md +25 -9
  10. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/pyproject.toml +8 -4
  11. stacktrace_cli-0.2.2/src/stacktrace_cli/__init__.py +3 -0
  12. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/src/stacktrace_cli/monitor/render.py +6 -2
  13. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/src/stacktrace_cli/monitor/site/app.js +48 -46
  14. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/src/stacktrace_cli/monitor/site/index.html +0 -2
  15. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/tests/monitor/feed_harness.mjs +62 -12
  16. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/tests/monitor/test_feed_model.py +55 -31
  17. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/tests/monitor/test_render.py +19 -0
  18. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/tests/monitor/test_site_assets.py +8 -4
  19. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/uv.lock +1 -1
  20. stacktrace_cli-0.2.0/PKG-INFO +0 -228
  21. stacktrace_cli-0.2.0/README.md +0 -207
  22. stacktrace_cli-0.2.0/src/stacktrace_cli/__init__.py +0 -3
  23. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/.agents/skills/release-stacktrace/SKILL.md +0 -0
  24. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/.claude/settings.json +0 -0
  25. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/.claude/skills/release-stacktrace/SKILL.md +0 -0
  26. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/.codex/hooks.json +0 -0
  27. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/.github/workflows/autofix.yml +0 -0
  28. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/.github/workflows/ci.yml +0 -0
  29. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/.github/workflows/claude.yml +0 -0
  30. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/.github/workflows/publish-pypi.yml +0 -0
  31. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/.gitignore +0 -0
  32. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/AGENTS.md +0 -0
  33. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/docs/adrs/0001-session-telemetry-as-input.md +0 -0
  34. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/docs/adrs/0002-session-collection-in-openaidr.md +0 -0
  35. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/docs/adrs/0003-runtime-edges.md +0 -0
  36. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/docs/adrs/0004-three-stage-detector.md +0 -0
  37. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/docs/adrs/0005-detection-family-and-report-assembly.md +0 -0
  38. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/docs/adrs/0006-trust-boundary-and-detection-upload.md +0 -0
  39. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/docs/adrs/0007-proprietary-package-on-open-dependencies.md +0 -0
  40. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/docs/adrs/0008-console-in-separate-demo-package.md +0 -0
  41. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/docs/adrs/0010-detection-severity-and-confidence-ladders.md +0 -0
  42. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/docs/adrs/0011-verdict-cache.md +0 -0
  43. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/docs/adrs/0012-observation-evidence-kinds-and-transport.md +0 -0
  44. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/docs/adrs/0013-rule-catalogue-triage-and-per-rule-context.md +0 -0
  45. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/docs/adrs/0014-declared-project-mapping.md +0 -0
  46. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/docs/adrs/0015-narrow-the-security-catalogue.md +0 -0
  47. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/docs/adrs/0016-stall-grouping-is-session-wide.md +0 -0
  48. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/docs/adrs/0017-a-declined-repeat-is-a-stall.md +0 -0
  49. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/docs/adrs/0018-remote-sync-config-and-facade-consumption.md +0 -0
  50. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/docs/adrs/0019-delegated-commands-are-openaca-objects.md +0 -0
  51. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/docs/adrs/0020-openaca-consumption-boundary.md +0 -0
  52. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/docs/adrs/0021-two-command-kinds.md +0 -0
  53. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/docs/adrs/0022-detection-scope-is-a-catalogue-column.md +0 -0
  54. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/docs/adrs/0023-sync-detect-collects-and-does-not-escalate.md +0 -0
  55. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/docs/adrs/0024-the-upload-carries-observations.md +0 -0
  56. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/docs/adrs/0025-a-denied-call-is-activity-never-an-invocation.md +0 -0
  57. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/docs/adrs/0026-the-console-becomes-a-product-surface.md +0 -0
  58. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/docs/adrs/0027-a-finding-may-name-what-it-could-not-place.md +0 -0
  59. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/docs/adrs/HOOK-PROMPT.md +0 -0
  60. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/docs/adrs/TEMPLATE.md +0 -0
  61. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/docs/plans/002-session-input.md +0 -0
  62. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/docs/plans/003-correlation.md +0 -0
  63. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/docs/plans/004-detector.md +0 -0
  64. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/docs/plans/005-remote-sync.md +0 -0
  65. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/docs/plans/006-cli-composition.md +0 -0
  66. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/docs/plans/007-detection-upload.md +0 -0
  67. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/docs/plans/008-monitor.md +0 -0
  68. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/docs/releases/v0.0.1.md +0 -0
  69. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/docs/releases/v0.1.0.md +0 -0
  70. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/docs/releases/v0.2.0.md +0 -0
  71. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/docs/specs/aidr.md +0 -0
  72. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/docs/specs/cli-composition.md +0 -0
  73. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/docs/specs/correlation.md +0 -0
  74. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/docs/specs/detection-upload.md +0 -0
  75. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/docs/specs/detector.md +0 -0
  76. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/docs/specs/remote-sync.md +0 -0
  77. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/docs/specs/session-input.md +0 -0
  78. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/scripts/git-hooks/pre-push +0 -0
  79. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/scripts/install-hooks.sh +0 -0
  80. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/src/stacktrace_cli/__main__.py +0 -0
  81. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/src/stacktrace_cli/analysis.py +0 -0
  82. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/src/stacktrace_cli/cli.py +0 -0
  83. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/src/stacktrace_cli/correlate/__init__.py +0 -0
  84. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/src/stacktrace_cli/correlate/acquire.py +0 -0
  85. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/src/stacktrace_cli/correlate/composition.py +0 -0
  86. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/src/stacktrace_cli/correlate/join.py +0 -0
  87. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/src/stacktrace_cli/correlate/observed.py +0 -0
  88. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/src/stacktrace_cli/correlate/orchestrate.py +0 -0
  89. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/src/stacktrace_cli/correlate/project_map.py +0 -0
  90. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/src/stacktrace_cli/correlate/record.py +0 -0
  91. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/src/stacktrace_cli/correlate/render.py +0 -0
  92. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/src/stacktrace_cli/detector/__init__.py +0 -0
  93. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/src/stacktrace_cli/detector/analyzer.py +0 -0
  94. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/src/stacktrace_cli/detector/cache.py +0 -0
  95. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/src/stacktrace_cli/detector/deterministic.py +0 -0
  96. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/src/stacktrace_cli/detector/finding.py +0 -0
  97. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/src/stacktrace_cli/detector/markers.py +0 -0
  98. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/src/stacktrace_cli/detector/priors.py +0 -0
  99. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/src/stacktrace_cli/detector/prompts/__init__.py +0 -0
  100. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/src/stacktrace_cli/detector/prompts/v1/exclusions.md +0 -0
  101. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/src/stacktrace_cli/detector/prompts/v1/framing.md +0 -0
  102. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/src/stacktrace_cli/detector/prompts/v1/stacktrace-deceptive-completion.md +0 -0
  103. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/src/stacktrace_cli/detector/prompts/v1/stacktrace-injected-instruction-followed.md +0 -0
  104. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/src/stacktrace_cli/detector/prompts/v1/stacktrace-intent-drift.md +0 -0
  105. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/src/stacktrace_cli/detector/reasoning.py +0 -0
  106. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/src/stacktrace_cli/detector/render.py +0 -0
  107. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/src/stacktrace_cli/detector/rules.py +0 -0
  108. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/src/stacktrace_cli/detector/run.py +0 -0
  109. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/src/stacktrace_cli/detector/secrets.py +0 -0
  110. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/src/stacktrace_cli/detector/verdict.py +0 -0
  111. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/src/stacktrace_cli/monitor/__init__.py +0 -0
  112. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/src/stacktrace_cli/monitor/escalate.py +0 -0
  113. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/src/stacktrace_cli/monitor/server.py +0 -0
  114. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/src/stacktrace_cli/monitor/site/fonts/OFL.txt +0 -0
  115. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/src/stacktrace_cli/monitor/site/fonts/dm-mono-400-latin.woff2 +0 -0
  116. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/src/stacktrace_cli/monitor/site/fonts/dm-mono-500-latin.woff2 +0 -0
  117. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/src/stacktrace_cli/monitor/site/fonts/dm-sans-latin.woff2 +0 -0
  118. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/src/stacktrace_cli/monitor/site/styles.css +0 -0
  119. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/src/stacktrace_cli/monitor/state.py +0 -0
  120. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/src/stacktrace_cli/monitor/verdicts.py +0 -0
  121. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/src/stacktrace_cli/monitor/watch.py +0 -0
  122. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/src/stacktrace_cli/remote/__init__.py +0 -0
  123. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/src/stacktrace_cli/remote/cli.py +0 -0
  124. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/src/stacktrace_cli/remote/client.py +0 -0
  125. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/src/stacktrace_cli/remote/config.py +0 -0
  126. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/src/stacktrace_cli/remote/detect_payload.py +0 -0
  127. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/src/stacktrace_cli/remote/payload.py +0 -0
  128. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/src/stacktrace_cli/remote/policy.py +0 -0
  129. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/src/stacktrace_cli/remote/redact.py +0 -0
  130. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/src/stacktrace_cli/remote/spool.py +0 -0
  131. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/src/stacktrace_cli/remote/sync.py +0 -0
  132. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/src/stacktrace_cli/remote/sync_detect.py +0 -0
  133. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/src/stacktrace_cli/remote/upload_contract.py +0 -0
  134. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/src/stacktrace_cli/sessions/__init__.py +0 -0
  135. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/src/stacktrace_cli/sessions/access.py +0 -0
  136. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/src/stacktrace_cli/sessions/outcome.py +0 -0
  137. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/src/stacktrace_cli/sessions/protocols.py +0 -0
  138. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/src/stacktrace_cli/sessions/render.py +0 -0
  139. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/tests/__init__.py +0 -0
  140. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/tests/agent_bom_fixture.py +0 -0
  141. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/tests/detector_session_fixture.py +0 -0
  142. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/tests/monitor/__init__.py +0 -0
  143. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/tests/monitor/test_escalation_gates.py +0 -0
  144. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/tests/monitor/test_server.py +0 -0
  145. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/tests/monitor/test_state.py +0 -0
  146. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/tests/monitor/test_verdicts.py +0 -0
  147. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/tests/monitor/test_watch.py +0 -0
  148. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/tests/remote/__init__.py +0 -0
  149. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/tests/remote/helpers.py +0 -0
  150. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/tests/remote/test_cli.py +0 -0
  151. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/tests/remote/test_client.py +0 -0
  152. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/tests/remote/test_config.py +0 -0
  153. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/tests/remote/test_detect_activity.py +0 -0
  154. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/tests/remote/test_detect_cli.py +0 -0
  155. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/tests/remote/test_detect_client.py +0 -0
  156. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/tests/remote/test_detect_contract_is_exhaustive.py +0 -0
  157. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/tests/remote/test_detect_gate_matches_the_cloud.py +0 -0
  158. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/tests/remote/test_detect_layers_compose.py +0 -0
  159. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/tests/remote/test_detect_payload_reaches_the_cloud_model.py +0 -0
  160. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/tests/remote/test_detect_redaction.py +0 -0
  161. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/tests/remote/test_detect_spool.py +0 -0
  162. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/tests/remote/test_detect_upload_contract.py +0 -0
  163. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/tests/remote/test_detect_wire_payload.py +0 -0
  164. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/tests/remote/test_facade_contract.py +0 -0
  165. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/tests/remote/test_payload.py +0 -0
  166. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/tests/remote/test_policy.py +0 -0
  167. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/tests/remote/test_redact_payload.py +0 -0
  168. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/tests/remote/test_seam.py +0 -0
  169. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/tests/remote/test_spool.py +0 -0
  170. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/tests/remote/test_sync.py +0 -0
  171. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/tests/remote/test_sync_detect.py +0 -0
  172. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/tests/remote/test_upload_contract.py +0 -0
  173. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/tests/test_acquire.py +0 -0
  174. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/tests/test_agent_instance_id.py +0 -0
  175. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/tests/test_analysis.py +0 -0
  176. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/tests/test_bom_shape.py +0 -0
  177. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/tests/test_call_status_conventions.py +0 -0
  178. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/tests/test_cli.py +0 -0
  179. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/tests/test_composition.py +0 -0
  180. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/tests/test_correlate_orchestrate.py +0 -0
  181. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/tests/test_correlate_render.py +0 -0
  182. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/tests/test_correlated_session.py +0 -0
  183. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/tests/test_detection_components.py +0 -0
  184. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/tests/test_detection_subject.py +0 -0
  185. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/tests/test_detector_analyzer_contract.py +0 -0
  186. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/tests/test_detector_analyzer_live.py +0 -0
  187. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/tests/test_detector_cache.py +0 -0
  188. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/tests/test_detector_deterministic.py +0 -0
  189. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/tests/test_detector_end_to_end.py +0 -0
  190. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/tests/test_detector_finding.py +0 -0
  191. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/tests/test_detector_liveness.py +0 -0
  192. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/tests/test_detector_markers.py +0 -0
  193. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/tests/test_detector_priors.py +0 -0
  194. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/tests/test_detector_reasoning.py +0 -0
  195. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/tests/test_detector_render.py +0 -0
  196. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/tests/test_detector_run.py +0 -0
  197. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/tests/test_detector_secrets.py +0 -0
  198. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/tests/test_detector_verdict.py +0 -0
  199. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/tests/test_fingerprint_covers_what_the_analyzer_reads.py +0 -0
  200. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/tests/test_help_sections.py +0 -0
  201. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/tests/test_join.py +0 -0
  202. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/tests/test_monitor_cli.py +0 -0
  203. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/tests/test_observed.py +0 -0
  204. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/tests/test_openaca_contract.py +0 -0
  205. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/tests/test_openaidr_contract.py +0 -0
  206. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/tests/test_option_arity_matches_the_binary.py +0 -0
  207. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/tests/test_project_map.py +0 -0
  208. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/tests/test_readme_examples_are_real_output.py +0 -0
  209. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/tests/test_release_readiness.py +0 -0
  210. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/tests/test_seam_boundary.py +0 -0
  211. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/tests/test_sessions_access.py +0 -0
  212. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/tests/test_sessions_end_to_end.py +0 -0
  213. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/tests/test_sessions_protocol_typing.py +0 -0
  214. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/tests/test_sessions_protocols.py +0 -0
  215. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/tests/test_sessions_render.py +0 -0
  216. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/tests/test_shell_separators_match_the_shell.py +0 -0
  217. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/tests/test_untrusted_content_never_travels.py +0 -0
  218. {stacktrace_cli-0.2.0 → stacktrace_cli-0.2.2}/tests/test_verification_subcommands_match_the_binary.py +0 -0
@@ -11,8 +11,8 @@ and by CI pipelines that invoke `stacktrace`, and it builds on the open-source
11
11
  It is also the **design home for Stacktrace Detect** — the AIDR product this CLI
12
12
  grows into. The specs in `docs/specs/` and the decisions in `docs/adrs/` describe
13
13
  the whole system: session input, correlation against the composition graph, the
14
- three-stage detector, and the combined report. The code here is the placeholder that
15
- precedes them.
14
+ three-stage detector, and the combined report. The code here implements them
15
+ incrementally.
16
16
 
17
17
  ## Common commands
18
18
 
@@ -52,11 +52,13 @@ the single source of truth for the version string reported by `--version`.
52
52
 
53
53
  Build backend is hatchling with a src layout; the wheel's contents are declared
54
54
  explicitly by `[tool.hatch.build.targets.wheel] packages = ["src/stacktrace_cli"]`.
55
- The only runtime dependency is `openaca>=0.4.0`, which supplies the Agent
56
- Composition Analysis primitives this CLI is intended to drive.
55
+ Runtime dependencies are `openaca` for the Agent Composition Analysis
56
+ primitives this CLI drives, `openaidr` for session collection, and `httpx` for
57
+ the remote channel. Each is pinned exactly before a release; see
58
+ `docs/cutover-openaca-remote.md`.
57
59
 
58
- The package is currently pre-alpha: `main()` reports its version and points at
59
- the docs. Real functionality lands in later releases.
60
+ `sessions`, `detect`, `monitor` and `remote` are native; `bom`, `policy` and
61
+ `scan` are OpenACA's own command objects.
60
62
 
61
63
  **The design that functionality implements is in this repo.** Read
62
64
  `docs/specs/aidr.md` first — it is the umbrella: components, contracts, the two
@@ -121,6 +123,25 @@ nothing about detection.
121
123
  a review names a site, fix the invariant and extend the exhaustive test — a
122
124
  second finding of the same class means the first fix was at the wrong level.
123
125
 
126
+ ## Adding a command
127
+
128
+ A command is a **pass-through** or it is **native**, never both — and a
129
+ pass-through never gains a flag of its own. See
130
+ [ADR-0021](docs/adrs/0021-two-command-kinds.md) for why.
131
+
132
+ - **Pass-through** — add one string to `PASSTHROUGH` in
133
+ `src/stacktrace_cli/cli.py`, having decided it belongs. The loop registers
134
+ OpenACA's own command object under that name; there is nothing else to
135
+ write and nothing to keep in step with OpenACA.
136
+ - **Native** — write a Click command or group and `add_command` it, the way
137
+ `remote` is. If it needs OpenACA it calls `openaca.core`
138
+ ([ADR-0020](docs/adrs/0020-openaca-consumption-boundary.md)), and whatever
139
+ it names there is added to the contract test in `tests/remote/`, because it
140
+ now holds duplicated knowledge of an interface.
141
+
142
+ The section a command lands under in `--help` follows from which kind it is;
143
+ there is no second list to update.
144
+
124
145
  ---
125
146
 
126
147
  ## Behavioral guidelines
@@ -0,0 +1,154 @@
1
+ Metadata-Version: 2.5
2
+ Name: stacktrace-cli
3
+ Version: 0.2.2
4
+ Summary: CLI for Stacktrace — Detection and Response platform for AI Agents.
5
+ Project-URL: Homepage, https://stacktrace.ai
6
+ Author-email: "Stacktrace AI, Inc" <founders@stacktrace.ai>
7
+ License-Expression: LicenseRef-Proprietary
8
+ Keywords: agent-security,ai-security,openaca,stacktrace
9
+ Classifier: Development Status :: 4 - Beta
10
+ Classifier: Environment :: Console
11
+ Classifier: Intended Audience :: Developers
12
+ Classifier: License :: Other/Proprietary License
13
+ Classifier: Operating System :: OS Independent
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3.11
16
+ Classifier: Programming Language :: Python :: 3.12
17
+ Classifier: Programming Language :: Python :: 3.13
18
+ Classifier: Topic :: Security
19
+ Requires-Python: >=3.11
20
+ Requires-Dist: click>=8.1
21
+ Requires-Dist: httpx<1.0.dev0,>=0.28.1
22
+ Requires-Dist: openaca==0.6.0
23
+ Requires-Dist: openaidr==0.1.0
24
+ Description-Content-Type: text/markdown
25
+
26
+ # stacktrace-cli
27
+
28
+ Detection and response for AI coding agents, from the command line.
29
+
30
+ Coding agents read files, run shell commands and call MCP servers on their own
31
+ initiative, and they write a transcript of every bit of it to disk.
32
+ `stacktrace` reads those transcripts, correlates what ran against the
33
+ components the agent is built from, and reports the security and reliability
34
+ findings in it — locally, on the machine the agent worked on.
35
+
36
+ The PyPI distribution is `stacktrace-cli`; the command it installs is
37
+ `stacktrace`. The two names differ because the bare `stacktrace` name on PyPI
38
+ belongs to an unrelated project.
39
+
40
+ ## Installation
41
+
42
+ ```bash
43
+ uv tool install stacktrace-cli # isolated; recommended
44
+ # or
45
+ pip install stacktrace-cli
46
+ ```
47
+
48
+ Requires Python 3.11 or newer.
49
+
50
+ ```console
51
+ $ stacktrace --version
52
+ stacktrace 0.2.1 (openaca 0.6.0)
53
+ ```
54
+
55
+ ## Quick start
56
+
57
+ ```bash
58
+ stacktrace sessions # what the agents on this machine did
59
+ stacktrace detect # what is wrong with it
60
+ stacktrace monitor # the same, live in a browser
61
+ ```
62
+
63
+ ## Commands
64
+
65
+ | Command | |
66
+ |---|---|
67
+ | `sessions` | Print what the agents on this machine actually did. |
68
+ | `detect` | Find security and reliability findings in what agents did. |
69
+ | `monitor` | Watch this machine's agents in a browser, live. |
70
+ | `remote` | Configure remote endpoint services and upload to Stacktrace Cloud. |
71
+ | `scan` | Scan a repository or endpoint for agent-composition findings. |
72
+ | `bom` | Generate an Agent BOM for a repository or endpoint. |
73
+ | `policy` | Validate and compile restrictive endpoint policies. |
74
+
75
+ The last three are composition analysis, supplied by
76
+ [`openaca`](https://pypi.org/project/openaca/) and available under either
77
+ name.
78
+
79
+ ## What it looks like
80
+
81
+ ```console
82
+ $ stacktrace sessions --since 2d --include-content
83
+ claude-code:s1 [claude-code] 2026-08-27T09:00:00+00:00 2 turns 2 calls
84
+ assistant: Reading the changelog before drafting the release notes.
85
+ ok 28c Read
86
+ result: ## 0.4.0 - correlate, detect
87
+ assistant: Filing the release-notes follow-up.
88
+ - github/create_issue
89
+
90
+ Summary — 1 sessions, 2 turns, 2 tool calls
91
+
92
+ agent kinds
93
+ 1 claude-code
94
+
95
+ tools called (2 distinct)
96
+ 1 Read
97
+ 1 github/create_issue
98
+
99
+ MCP servers reached (1 distinct)
100
+ 1 github
101
+
102
+ 0 subagent turns · 0 results abridged upstream · 1 ok
103
+
104
+ 1 of 2 calls returned with no outcome the collector could establish; the agent's parser supplies no success signal.
105
+ ```
106
+
107
+ A blank status column is the collector's `unknown`, not a pending call: the
108
+ client recorded no outcome that could be established, and the closing line
109
+ counts those rather than filling one in.
110
+
111
+ ## What `detect` finds
112
+
113
+ Four kinds of finding, under two families that carry separate severity
114
+ ladders — a stalled loop and a leaked credential do not belong on one scale.
115
+
116
+ **Security** — a credential reaching an outbound call; an injected instruction
117
+ the agent then followed; a vulnerable component actually reached, with the
118
+ vulnerability behind it.
119
+
120
+ **Reliability** — a loop that stalled; a call that hung.
121
+
122
+ Findings are correlated against an Agent BOM before they are judged, so a
123
+ vulnerable component is reported when something actually used it rather than
124
+ because it is installed.
125
+
126
+ ## What leaves your machine
127
+
128
+ Two of `detect`'s three stages run entirely locally and need no model or
129
+ credential. The third sends flagged sessions to the agent's *own* CLI — the
130
+ provider that produced the transcript, never a different one — capped by
131
+ `--budget`; `--no-escalate` turns it off and leaves the two local stages.
132
+
133
+ `sessions` omits prompts, tool arguments and results unless you pass
134
+ `--include-content`. `monitor` binds to loopback only, refuses a non-loopback
135
+ address rather than warning about it, and escalates nothing unless `--escalate`
136
+ is given.
137
+
138
+ ## Status
139
+
140
+ Beta, and under active development.
141
+
142
+ `sessions`, `detect` and `monitor` work end to end today. Session collection
143
+ currently reads Claude Code transcripts; further agent kinds are in progress
144
+ upstream in [OpenAIDR](https://github.com/open-agent-security/openaidr).
145
+
146
+ ## Built on
147
+
148
+ Two Apache-2.0 packages, neither of which depends on this one:
149
+ [`openaca`](https://pypi.org/project/openaca/) for agent composition analysis,
150
+ and [`openaidr`](https://pypi.org/project/openaidr/) for session collection.
151
+
152
+ ## Licence
153
+
154
+ Proprietary. © Stacktrace AI, Inc. — [stacktrace.ai](https://stacktrace.ai)
@@ -0,0 +1,129 @@
1
+ # stacktrace-cli
2
+
3
+ Detection and response for AI coding agents, from the command line.
4
+
5
+ Coding agents read files, run shell commands and call MCP servers on their own
6
+ initiative, and they write a transcript of every bit of it to disk.
7
+ `stacktrace` reads those transcripts, correlates what ran against the
8
+ components the agent is built from, and reports the security and reliability
9
+ findings in it — locally, on the machine the agent worked on.
10
+
11
+ The PyPI distribution is `stacktrace-cli`; the command it installs is
12
+ `stacktrace`. The two names differ because the bare `stacktrace` name on PyPI
13
+ belongs to an unrelated project.
14
+
15
+ ## Installation
16
+
17
+ ```bash
18
+ uv tool install stacktrace-cli # isolated; recommended
19
+ # or
20
+ pip install stacktrace-cli
21
+ ```
22
+
23
+ Requires Python 3.11 or newer.
24
+
25
+ ```console
26
+ $ stacktrace --version
27
+ stacktrace 0.2.1 (openaca 0.6.0)
28
+ ```
29
+
30
+ ## Quick start
31
+
32
+ ```bash
33
+ stacktrace sessions # what the agents on this machine did
34
+ stacktrace detect # what is wrong with it
35
+ stacktrace monitor # the same, live in a browser
36
+ ```
37
+
38
+ ## Commands
39
+
40
+ | Command | |
41
+ |---|---|
42
+ | `sessions` | Print what the agents on this machine actually did. |
43
+ | `detect` | Find security and reliability findings in what agents did. |
44
+ | `monitor` | Watch this machine's agents in a browser, live. |
45
+ | `remote` | Configure remote endpoint services and upload to Stacktrace Cloud. |
46
+ | `scan` | Scan a repository or endpoint for agent-composition findings. |
47
+ | `bom` | Generate an Agent BOM for a repository or endpoint. |
48
+ | `policy` | Validate and compile restrictive endpoint policies. |
49
+
50
+ The last three are composition analysis, supplied by
51
+ [`openaca`](https://pypi.org/project/openaca/) and available under either
52
+ name.
53
+
54
+ ## What it looks like
55
+
56
+ ```console
57
+ $ stacktrace sessions --since 2d --include-content
58
+ claude-code:s1 [claude-code] 2026-08-27T09:00:00+00:00 2 turns 2 calls
59
+ assistant: Reading the changelog before drafting the release notes.
60
+ ok 28c Read
61
+ result: ## 0.4.0 - correlate, detect
62
+ assistant: Filing the release-notes follow-up.
63
+ - github/create_issue
64
+
65
+ Summary — 1 sessions, 2 turns, 2 tool calls
66
+
67
+ agent kinds
68
+ 1 claude-code
69
+
70
+ tools called (2 distinct)
71
+ 1 Read
72
+ 1 github/create_issue
73
+
74
+ MCP servers reached (1 distinct)
75
+ 1 github
76
+
77
+ 0 subagent turns · 0 results abridged upstream · 1 ok
78
+
79
+ 1 of 2 calls returned with no outcome the collector could establish; the agent's parser supplies no success signal.
80
+ ```
81
+
82
+ A blank status column is the collector's `unknown`, not a pending call: the
83
+ client recorded no outcome that could be established, and the closing line
84
+ counts those rather than filling one in.
85
+
86
+ ## What `detect` finds
87
+
88
+ Four kinds of finding, under two families that carry separate severity
89
+ ladders — a stalled loop and a leaked credential do not belong on one scale.
90
+
91
+ **Security** — a credential reaching an outbound call; an injected instruction
92
+ the agent then followed; a vulnerable component actually reached, with the
93
+ vulnerability behind it.
94
+
95
+ **Reliability** — a loop that stalled; a call that hung.
96
+
97
+ Findings are correlated against an Agent BOM before they are judged, so a
98
+ vulnerable component is reported when something actually used it rather than
99
+ because it is installed.
100
+
101
+ ## What leaves your machine
102
+
103
+ Two of `detect`'s three stages run entirely locally and need no model or
104
+ credential. The third sends flagged sessions to the agent's *own* CLI — the
105
+ provider that produced the transcript, never a different one — capped by
106
+ `--budget`; `--no-escalate` turns it off and leaves the two local stages.
107
+
108
+ `sessions` omits prompts, tool arguments and results unless you pass
109
+ `--include-content`. `monitor` binds to loopback only, refuses a non-loopback
110
+ address rather than warning about it, and escalates nothing unless `--escalate`
111
+ is given.
112
+
113
+ ## Status
114
+
115
+ Beta, and under active development.
116
+
117
+ `sessions`, `detect` and `monitor` work end to end today. Session collection
118
+ currently reads Claude Code transcripts; further agent kinds are in progress
119
+ upstream in [OpenAIDR](https://github.com/open-agent-security/openaidr).
120
+
121
+ ## Built on
122
+
123
+ Two Apache-2.0 packages, neither of which depends on this one:
124
+ [`openaca`](https://pypi.org/project/openaca/) for agent composition analysis,
125
+ and [`openaidr`](https://pypi.org/project/openaidr/) for session collection.
126
+
127
+ ## Licence
128
+
129
+ Proprietary. © Stacktrace AI, Inc. — [stacktrace.ai](https://stacktrace.ai)
@@ -0,0 +1,108 @@
1
+ ---
2
+ id: 0028
3
+ title: The console shows what it placed, and states no coverage
4
+ status: accepted
5
+ date: 2026-09-08
6
+ supersedes: null
7
+ superseded-by: null
8
+ amends: null
9
+ amended-by: null
10
+ ---
11
+
12
+ ## Context
13
+
14
+ A reader opened `stacktrace monitor` on their own machine and asked why the
15
+ busiest row on the page was red. The row was the grouped built-in row for one
16
+ project — 4,467 calls over five days — and it carried `⚠ 16 refusals`. All 16
17
+ were `user-rejected` in the transcript, and their recorded reasons were the
18
+ Bash gate rather than a person: 29 `contains multiple operations`, 28 `requires
19
+ approval`, 6 `changes directory before running git`, 3 `brace with quote
20
+ character (expansion obfuscation)`, 2 `parser aborted`, 1 `contains
21
+ for_statement` across the project's 70 denials. Nothing reached a tool.
22
+
23
+ `sessions/outcome.py` already states the rule: *a denied call reached nothing,
24
+ so it is evidence of nothing* — written after six sites had each grown their own
25
+ `status == "rejected"` test. The page took that rule for its counters and then
26
+ painted the row red anyway, which reports the permission prompt as the
27
+ incident. ADR-0025 left this open deliberately: its Consequences name "a second
28
+ counter every activity read surface must decide whether to show".
29
+
30
+ The same page led with `⚠ unresolved` rows, an `Unresolved` row in the overview
31
+ table, a legend line, and a `6,867/7,055 placed` header fraction. `unresolved`
32
+ is a fact about the *record*, with four causes the reader cannot distinguish and
33
+ none of which they can act on: absent from the composition, no composition for
34
+ that agent kind, an ambiguous match, or a matched component whose type the
35
+ category map does not know. The row names no component — `classify_call`
36
+ returns no name for it by design (ADR-0027 admits a name at one position, and an
37
+ activity row is not one) — so what reached the reader was "something happened
38
+ and nothing here claims it", set in the page's warning colour.
39
+
40
+ The rule that would have made such a call actionable, `unsanctioned-mcp-tool-use`,
41
+ was withdrawn by ADR-0015. So no live rule is about an unplaceable call, and the
42
+ page was warning about something it could not then explain.
43
+
44
+ ## Decision
45
+
46
+ The console renders only activity it could place, and states no coverage
47
+ figure. Rows whose category is `unresolved` are dropped at the page boundary;
48
+ the `N/M placed` fraction and its `placing…` placeholder are gone from the
49
+ header, which now counts sessions and the actions it actually shows; a refusal
50
+ is counted in a row's `×N` and carries no badge and no colour; the
51
+ no-composition banner is gone, leaving the two banners that report a *reader*
52
+ which came back with nothing.
53
+
54
+ The snapshot contract does not change. `_activity` still emits unresolved rows,
55
+ `summary.coverage` and each session's `coverage` are still computed and still
56
+ sent, `activity_for_upload` and the `denied` counter are untouched, and every
57
+ detector rule reads what it always read. `stacktrace correlate` remains the
58
+ surface where coverage and unplaceability are the subject; ADR-0026's clause
59
+ holds, because a page that shows less has still invented nothing.
60
+
61
+ ## Alternatives considered
62
+
63
+ - **Filter in `_activity`, server-side** — rejected. The snapshot is also the
64
+ `/api/state` contract and the thing `tests/monitor/test_render.py` holds; a
65
+ page decision that narrows the record makes the two disagree, and the next
66
+ surface built on the snapshot would inherit a filter it never asked for.
67
+ - **Keep the rows, drop only the warning framing** — rejected by the person the
68
+ page is for. Neutral wording does not give the row a subject: with no
69
+ component name there is nothing for a reader to look up, so a quiet row is
70
+ the same non-answer in a calmer colour.
71
+ - **Keep the coverage fraction** — rejected. The gap between numerator and
72
+ denominator *is* the count of rows the page no longer shows, so the header
73
+ restated by arithmetic exactly what the feed had stopped saying.
74
+ - **Keep the red on refusals alone** — rejected. It is the page asserting the
75
+ opposite of `outcome.py`'s rule about the same call, and the measured reasons
76
+ above are a guardrail working, not an endpoint under attack.
77
+ - **Reword the no-composition banner rather than remove it** — rejected after
78
+ trying it. "No Agent BOM found, so its components are not identified" is the
79
+ same claim one step back, and it sends a reader looking for rows that are no
80
+ longer there.
81
+
82
+ ## Consequences
83
+
84
+ The page stops answering one question it used to answer badly: how much of the
85
+ window it could not attribute. A reader who wants that runs `stacktrace
86
+ correlate`, where the figure is the subject and the four causes are named
87
+ separately; the fleet still receives it, because the upload path is untouched.
88
+
89
+ The costs are real and worth naming. An agent kind with no Agent BOM now shows
90
+ fewer categories in the overview table and says nothing about why — the built-in
91
+ preview rows still appear, so the page does not go blank, but the absence is
92
+ silent. A responder cannot see from the console that an MCP call went to a
93
+ server no scan can find. And a denied-heavy endpoint — ADR-0025's own example of
94
+ a fact visible on no surface — is still visible on none.
95
+
96
+ **Watch for:** a second page-side filter added the same way, without an ADR,
97
+ because this one made it look routine; and the header regaining any derived
98
+ ratio, which is the shape this decision removed.
99
+
100
+ ## When to revisit
101
+
102
+ If ADR-0015's `unsanctioned-mcp-tool-use` returns, revisit immediately: its
103
+ evidence is exactly the rows this decision hides, and a finding whose subject
104
+ cannot be seen on the page it is reported on is worse than either state alone.
105
+ Also if the console gains an affordance for *why something is missing* — a
106
+ per-kind detail view, say — which is where the coverage figure and the four
107
+ causes belong, or if a remote surface starts reading the local snapshot and
108
+ assuming the page's filtering rather than the record's contents.
@@ -60,3 +60,4 @@ supersedes anything yet.
60
60
  - [0026](0026-the-console-becomes-a-product-surface.md) — **The console becomes a product surface, served by the engine.** Supersedes ADR-0008 on its own stated condition: the engine came first, 0.1.0 shipped, and the data is only useful if a person can follow it. `stacktrace monitor` serves a loopback page from in-process calls, so the wheel now carries a `site/` asset — the cost 0008 refused, accepted here explicitly. What survives from 0008 is the clause that matters: the console renders and never computes, so a finding on the page is one `detect` would print. Read before adding anything to the console that the detector does not produce.
61
61
  - [0025](0025-a-denied-call-is-activity-never-an-invocation.md) — **A denied call is activity, and never an invocation.** ADR-0017 makes a declined repeat a stall while `outcome.py` keeps a denied call out of every count, so a denied-only session produced a finding with no activity and the Cloud rejected the whole run; a separate `denied` counter resolves it without either rule bending, and coverage keeps summing `invocations` alone. Read before changing what `activity[]` counts, or before folding `denied` into a coverage-like ratio.
62
62
  - [0027](0027-a-finding-may-name-what-it-could-not-place.md) — **A finding may name the component it could not place.** Narrows ADR-0006 constraint 3 for one field: an unplaced subject carries the name the session addressed it by, never as an identity. Read before removing a name from a finding on trust-boundary grounds, or before widening this to a second field.
63
+ - [0028](0028-the-console-shows-what-it-placed.md) — **The console shows what it placed, and states no coverage.** Unplaceable rows, the `N/M placed` header fraction and the red on refusals are gone from `stacktrace monitor`: an unplaced row names no component, and `outcome.py`'s rule about a denied call makes reddening one the page contradicting its own counters. The snapshot contract, the upload and every rule are unchanged. Read before adding a page-side filter, before restoring a coverage ratio to the console, or if `unsanctioned-mcp-tool-use` returns.
@@ -0,0 +1,87 @@
1
+ # The openaca 0.6.0 cutover
2
+
3
+ Moved out of `README.md`, which is the PyPI long description and therefore a
4
+ public page: this is operator and maintainer detail for a private repository.
5
+
6
+ ## Dependency resolution
7
+
8
+ Both `openaca` and `openaidr` resolve from PyPI now, like any other
9
+ dependency — no sibling checkout, no `[tool.uv.sources]` override. What still
10
+ gates a release is narrower: both float on `>=` during normal development but
11
+ must be pinned exactly (`==`) before a version is published, so a built wheel
12
+ names precisely what it was tested against.
13
+ `uv run pytest tests/test_release_readiness.py -m release_gate` checks that —
14
+ the `release-stacktrace` skill runs it as part of cutting a release.
15
+
16
+
17
+ ## Cutover from `openaca remote`
18
+
19
+ `stacktrace remote` is the hosted-service client OpenACA is removing. The
20
+ behaviour, the payload and the Cloud endpoints are unchanged; only the code
21
+ that produces them moved. Machines already running `openaca remote sync
22
+ endpoint` need four steps each.
23
+
24
+ 1. **Have the collector token to hand, or mint a new one.** A collector token
25
+ cannot be recovered from the Cloud — it is returned once at issuance and
26
+ only a hash and its last four characters are kept — so it has to come from
27
+ wherever it was stored (an MDM secret store, a password manager). If it was
28
+ not stored, mint a new one and deploy that; nothing goes down while you do,
29
+ because the existing token keeps working until it is revoked.
30
+ 2. **Configure this machine.** `stacktrace remote configure --token …`, or set
31
+ `STACKTRACE_REMOTE_TOKEN` and `STACKTRACE_REMOTE_API_URL` for a scripted
32
+ deployment.
33
+ 3. **Repoint whatever schedules the sync** at `stacktrace remote sync
34
+ endpoint`.
35
+ 4. **Delete `~/.config/openaca/remote.toml`.** Once OpenACA has no `remote`
36
+ command, that file is an unused plaintext credential sitting on disk.
37
+ Nothing breaks if it stays, which is exactly why it will be forgotten.
38
+
39
+ ### What takes care of itself
40
+
41
+ - **The asset converges.** Registration is idempotent on `(org, asset_type,
42
+ external_id)` with the host name as `external_id`, so registering from here
43
+ resolves to the same asset OpenACA registered — one extra round trip on the
44
+ first run, no duplicate machine in the console.
45
+ - **Both commands may coexist during the overlap**, producing two BOM rows per
46
+ sync. That is noise rather than corruption.
47
+
48
+ > These two statements, and the unrecoverability of a collector token in step
49
+ > 1, describe what the deployed Cloud does. They have **not** been confirmed
50
+ > against the running service for this release — they are read from the
51
+ > hosted side's design, which records what some revision implements rather
52
+ > than what production does today. Confirm them before an operator acts on
53
+ > step 1 in particular: discarding the only copy of a token on the strength of
54
+ > an unverified sentence leaves no recovery.
55
+
56
+ ### What does not
57
+
58
+ - **A pending OpenACA spool is orphaned.** Its files are in
59
+ `~/.local/state/openaca`, and this channel never reads them. Drain it by
60
+ running the old command once before cutting over, or accept losing what it
61
+ holds. Do not assume that is one sync's worth: the spool keeps one file per
62
+ failed agent and accumulates across offline runs, so count the files first.
63
+ - **The MDM deploy scripts and the scheduled agent** do not exist here yet.
64
+
65
+ ## Release obligations
66
+
67
+ Finishing the remote-sync work was **not** the same as being releasable, and
68
+ the gap was structural rather than a matter of polish: while `pyproject.toml`
69
+ carried a path source to a sibling checkout, `pip install stacktrace-cli` from
70
+ PyPI would have resolved an `openaca` without the consumption facade, and every
71
+ `remote` command would have failed at import.
72
+
73
+ All three are discharged, at `openaca` 0.6.0 — the first release carrying the
74
+ facade:
75
+
76
+ 1. `[tool.uv.sources]` is gone; `uv.lock` resolves `openaca` from PyPI.
77
+ 2. `.github/workflows/ci.yml` checks out this repository alone. The sibling
78
+ checkout and its pinned-revision assertion went with the path source.
79
+ 3. The floor is `openaca>=0.6.0`, which is where plan 005 Task 1's
80
+ required-import probe first reports no missing name. Re-run that probe
81
+ against any candidate release before moving the floor again; it passes only
82
+ when it reports nothing missing.
83
+
84
+ One proof retired with them. The payload-equivalence test imported openaca's
85
+ `tools.remote` — the module 0.6.0 removed — so it cannot run against any
86
+ release that carries the facade. What it established is a fact about the
87
+ migration, not a property that a later release could re-check.
@@ -0,0 +1,49 @@
1
+ # 0.2.1 — the page in front of the CLI
2
+
3
+ For a distribution, the PyPI listing is the product surface a reader meets
4
+ first. This release treats it as one. Nothing about what `stacktrace` does
5
+ changes here — no command, flag, rule or output shape moves — and the whole
6
+ delta is what the page in front of it claims.
7
+
8
+ ## Highlights
9
+
10
+ - **The package metadata describes the product rather than a placeholder.**
11
+ The summary line said "Placeholder CLI for Stacktrace.ai — installs the
12
+ `stacktrace` command", written when that was true and left standing after
13
+ 0.1.0 and 0.2.0 made it false. It now says what the CLI is for. Authorship
14
+ moves from an individual to Stacktrace AI, Inc., and
15
+ `Development Status :: 2 - Pre-Alpha` becomes `4 - Beta`, matching the
16
+ README's own Status section rather than contradicting it two clicks away.
17
+ `Operating System :: OS Independent` and per-minor Python classifiers for
18
+ 3.11, 3.12 and 3.13 are added, so PyPI's own filters can find the package
19
+ under the versions `requires-python` already accepted.
20
+
21
+ - **The README is written for someone deciding whether to install.** It was a
22
+ contributor's design document — Design, Adding a command, Development,
23
+ Release obligations — that happened to be the `readme` field, so the long
24
+ description on PyPI opened by explaining the repository to people who
25
+ already had it checked out. It now opens with what the tool does in three
26
+ sentences and continues into install, a three-command quick start, the
27
+ command table, real sample output, what `detect` finds, and what leaves your
28
+ machine. That last section is the one a security reader arrives looking for
29
+ and previously had to infer.
30
+
31
+ - **The contributor material moved rather than being deleted.** The design and
32
+ workflow content is in `CLAUDE.md`, and the openaca 0.6.0 cutover notes and
33
+ release obligations are in `docs/cutover-openaca-remote.md`. Both stay in the
34
+ repository and neither is in the wheel.
35
+
36
+ ## Install
37
+
38
+ `uv tool install stacktrace-cli==0.2.1` or `pip install stacktrace-cli==0.2.1`.
39
+
40
+ ## Compatibility
41
+
42
+ Nothing to do. This release changes no behaviour: the CLI's commands, flags,
43
+ output and upload payloads are identical to 0.2.0, and an existing install has
44
+ no reason to upgrade beyond the version string.
45
+
46
+ One note on the `Development Status :: 4 - Beta` classifier. It is a claim
47
+ about the project's stage, not a back-compat promise — the terms 0.2.0 shipped
48
+ under still hold, and interfaces can still change between releases without a
49
+ deprecation window.
@@ -0,0 +1,76 @@
1
+ # 0.2.2 — what the console shows
2
+
3
+ `stacktrace monitor` shipped in 0.2.0 with two kinds of warning on it, and this
4
+ release removes both. Neither pointed at something a reader could act on: one
5
+ marked a call the correlator could not attribute, which names no component by
6
+ design, and the other marked a call a permission prompt had already blocked.
7
+ The engine is untouched — no rule, payload field, command or output shape
8
+ moves — and the whole delta is what one page renders.
9
+
10
+ ## Highlights
11
+
12
+ - **A blocked call is no longer an alarm.** A refusal is counted in its row's
13
+ `×N` and says nothing more: no `⚠ N refusals` badge, no red row. On the
14
+ machine that prompted this, 16 declined `Bash` calls out of 4,467 turned the
15
+ busiest row on the page red — and all 16 were the Bash gate refusing a
16
+ compound command, a `cd` before `git`, or an obfuscated brace. Nothing
17
+ reached a tool. `sessions/outcome.py` has held since 0.1.0 that a denied call
18
+ reached nothing, so it is evidence of nothing; the page took that rule for
19
+ its counters and then reddened the row anyway, which reports the permission
20
+ prompt as the incident. ADR-0025 left this to each surface deliberately, and
21
+ the console now answers it.
22
+
23
+ - **The console shows only activity it could place.** The `⚠ unresolved` rows,
24
+ the `Unresolved` row in the overview table and the legend line describing
25
+ them are gone. An unplaced row carries no component name — that is a design
26
+ constraint, not an omission (ADR-0027 admits a name at one position, and an
27
+ activity row is not one) — so what reached the reader was "something happened
28
+ and nothing here claims it", with four causes behind it they could not
29
+ distinguish and none they could act on. The rule that would have made such a
30
+ call actionable was withdrawn by ADR-0015, so nothing on the page could
31
+ explain the warning it was showing.
32
+
33
+ - **The header states no coverage figure.** `6,867/7,055 placed` and the
34
+ `placing…` placeholder it used while correlation ran are both gone: the gap
35
+ between those two numbers *is* the count of rows the page withholds, so the
36
+ header restated by arithmetic exactly what the rows had stopped saying. It
37
+ now reports sessions and the actions it actually shows — previously it read
38
+ `summary.actions`, the total over every call in the window, and so claimed
39
+ more actions than the feed below it could account for.
40
+
41
+ - **A legend line that described nothing.** `✓ resolved to something you
42
+ installed` is removed. The page has never drawn that checkmark: the glyph
43
+ appeared in the legend and in no row, summary or card.
44
+
45
+ - **The decision is recorded rather than implied.** ADR-0028 states it, lists
46
+ the five alternatives and is explicit about the costs — an agent kind with no
47
+ Agent BOM is now silent on the page, and ADR-0025's denied-heavy endpoint is
48
+ still visible on no surface. `docs/specs/monitor.md` said the opposite in four
49
+ places and now describes what ships.
50
+
51
+ ## Install
52
+
53
+ `uv tool install stacktrace-cli==0.2.2` or `pip install stacktrace-cli==0.2.2`.
54
+
55
+ ## Compatibility
56
+
57
+ Nothing to do, and nothing outside the console changes. `stacktrace detect`,
58
+ `stacktrace correlate` and `stacktrace sync detect` produce byte-identical
59
+ output to 0.2.1, the upload payload is unchanged, and every detector rule reads
60
+ what it always read. No finding is suppressed — ADR-0026's clause that the
61
+ console renders and never judges still holds, and a page that shows fewer
62
+ activity rows invents nothing.
63
+
64
+ The `/api/state` document is also unchanged: it still carries the unplaced
65
+ activity rows and both coverage figures. The filter is applied in the page, so
66
+ anything reading that endpoint sees the same record 0.2.1 served.
67
+
68
+ Two things you will notice if you relied on them. Coverage is no longer on the
69
+ console — run `stacktrace correlate`, where it is the subject and the four
70
+ causes of an unplaced call are named separately. And an agent kind with no
71
+ Agent BOM no longer raises a banner: its built-in rows still appear, so the
72
+ page does not go blank, but the absence is reported by `correlate` rather than
73
+ on screen.
74
+
75
+ Still pre-alpha, with no back-compat hedging: interfaces can change between
76
+ releases without a deprecation window.