stacktrace-cli 0.8.0__tar.gz → 0.9.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (475) hide show
  1. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/CLAUDE.md +10 -0
  2. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/PKG-INFO +2 -2
  3. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/README.md +1 -1
  4. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/docs/adrs/0006-trust-boundary-and-detection-upload.md +1 -1
  5. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/docs/adrs/0026-the-console-becomes-a-product-surface.md +1 -1
  6. stacktrace_cli-0.9.0/docs/adrs/0092-cost-is-its-own-rule-family.md +49 -0
  7. stacktrace_cli-0.9.0/docs/adrs/0093-environment-cost-baselines-count-tokens-keyed-by-model.md +78 -0
  8. stacktrace_cli-0.9.0/docs/adrs/0094-estimate-cost-from-tokens-the-agent-figure-is-a-cross-check.md +63 -0
  9. stacktrace_cli-0.9.0/docs/adrs/0095-cost-findings-reach-fleet-each-rule-can-be-muted.md +53 -0
  10. stacktrace_cli-0.9.0/docs/adrs/0096-cost-usage-may-leave-as-token-totals-and-work-identifiers.md +86 -0
  11. stacktrace_cli-0.9.0/docs/adrs/0097-the-daemon-makes-cost-findings-and-the-monitor-reads-them.md +69 -0
  12. stacktrace_cli-0.9.0/docs/adrs/0098-a-run-is-its-main-session.md +53 -0
  13. stacktrace_cli-0.9.0/docs/adrs/0099-cost-is-measured-in-tokens-and-relative-increases.md +85 -0
  14. stacktrace_cli-0.9.0/docs/adrs/0100-the-monitor-runs-offline-for-the-website.md +70 -0
  15. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/docs/adrs/INDEX.md +10 -1
  16. stacktrace_cli-0.9.0/docs/plans/016-cost-phase-1.md +832 -0
  17. stacktrace_cli-0.9.0/docs/plans/017-cost-phase-2.md +89 -0
  18. stacktrace_cli-0.9.0/docs/releases/v0.9.0.md +116 -0
  19. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/docs/specs/aidr.md +19 -11
  20. stacktrace_cli-0.9.0/docs/specs/cost-phase-1.md +477 -0
  21. stacktrace_cli-0.9.0/docs/specs/cost-phase-2.md +159 -0
  22. stacktrace_cli-0.9.0/docs/specs/cost.md +248 -0
  23. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/docs/specs/detection-policies.md +73 -3
  24. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/docs/specs/detector.md +13 -1
  25. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/docs/specs/monitor.md +83 -4
  26. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/docs/specs/session-input.md +11 -9
  27. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/pyproject.toml +1 -1
  28. stacktrace_cli-0.9.0/scripts/cost_latency.py +85 -0
  29. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/src/stacktrace_cli/__init__.py +1 -1
  30. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/src/stacktrace_cli/analysis.py +13 -1
  31. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/src/stacktrace_cli/cli.py +3 -1
  32. stacktrace_cli-0.9.0/src/stacktrace_cli/cost/__init__.py +6 -0
  33. stacktrace_cli-0.9.0/src/stacktrace_cli/cost/baseline.py +493 -0
  34. stacktrace_cli-0.9.0/src/stacktrace_cli/cost/clock.py +40 -0
  35. stacktrace_cli-0.9.0/src/stacktrace_cli/cost/components.py +143 -0
  36. stacktrace_cli-0.9.0/src/stacktrace_cli/cost/evidence.py +69 -0
  37. stacktrace_cli-0.9.0/src/stacktrace_cli/cost/ledger.py +58 -0
  38. stacktrace_cli-0.9.0/src/stacktrace_cli/cost/measures.py +351 -0
  39. stacktrace_cli-0.9.0/src/stacktrace_cli/cost/models.py +38 -0
  40. stacktrace_cli-0.9.0/src/stacktrace_cli/cost/rules.py +1138 -0
  41. stacktrace_cli-0.9.0/src/stacktrace_cli/cost/runs.py +126 -0
  42. stacktrace_cli-0.9.0/src/stacktrace_cli/cost/tokens.py +69 -0
  43. stacktrace_cli-0.9.0/src/stacktrace_cli/cost/totals.py +62 -0
  44. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/src/stacktrace_cli/daemon/cli.py +46 -0
  45. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/src/stacktrace_cli/daemon/config.py +42 -0
  46. stacktrace_cli-0.9.0/src/stacktrace_cli/daemon/costs.py +882 -0
  47. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/src/stacktrace_cli/daemon/db.py +65 -0
  48. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/src/stacktrace_cli/daemon/fleet.py +3 -1
  49. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/src/stacktrace_cli/daemon/jobs.py +90 -0
  50. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/src/stacktrace_cli/daemon/observer.py +17 -2
  51. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/src/stacktrace_cli/daemon/presentation.py +33 -0
  52. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/src/stacktrace_cli/daemon/runtime.py +107 -8
  53. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/src/stacktrace_cli/daemon/scan.py +31 -0
  54. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/src/stacktrace_cli/daemon/store.py +243 -2
  55. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/src/stacktrace_cli/detector/finding.py +1 -1
  56. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/src/stacktrace_cli/detector/render.py +14 -12
  57. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/src/stacktrace_cli/detector/rules.py +58 -4
  58. stacktrace_cli-0.9.0/src/stacktrace_cli/monitor/costs.py +375 -0
  59. stacktrace_cli-0.9.0/src/stacktrace_cli/monitor/offline.py +266 -0
  60. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/src/stacktrace_cli/monitor/render.py +79 -21
  61. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/src/stacktrace_cli/monitor/server.py +5 -0
  62. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/src/stacktrace_cli/monitor/site/app.js +64 -1
  63. stacktrace_cli-0.9.0/src/stacktrace_cli/monitor/site/cost.js +436 -0
  64. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/src/stacktrace_cli/monitor/site/index.html +8 -0
  65. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/src/stacktrace_cli/monitor/site/inventory.js +1 -1
  66. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/src/stacktrace_cli/monitor/site/styles.css +23 -0
  67. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/src/stacktrace_cli/monitor/state.py +5 -0
  68. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/src/stacktrace_cli/monitor/watch.py +16 -0
  69. stacktrace_cli-0.9.0/src/stacktrace_cli/sessions/lineage.py +24 -0
  70. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/src/stacktrace_cli/sessions/protocols.py +81 -8
  71. stacktrace_cli-0.9.0/tests/cost/fakes.py +57 -0
  72. stacktrace_cli-0.9.0/tests/cost/scenarios.py +169 -0
  73. stacktrace_cli-0.9.0/tests/cost/test_baseline.py +223 -0
  74. stacktrace_cli-0.9.0/tests/cost/test_clock.py +61 -0
  75. stacktrace_cli-0.9.0/tests/cost/test_components.py +129 -0
  76. stacktrace_cli-0.9.0/tests/cost/test_cost_evidence_travels.py +135 -0
  77. stacktrace_cli-0.9.0/tests/cost/test_cost_findings_are_dated_by_their_citations.py +557 -0
  78. stacktrace_cli-0.9.0/tests/cost/test_cost_findings_carry_no_session_text.py +120 -0
  79. stacktrace_cli-0.9.0/tests/cost/test_cost_is_tokens.py +72 -0
  80. stacktrace_cli-0.9.0/tests/cost/test_cost_latency.py +82 -0
  81. stacktrace_cli-0.9.0/tests/cost/test_evidence.py +40 -0
  82. stacktrace_cli-0.9.0/tests/cost/test_ledger.py +44 -0
  83. stacktrace_cli-0.9.0/tests/cost/test_measures.py +251 -0
  84. stacktrace_cli-0.9.0/tests/cost/test_models.py +15 -0
  85. stacktrace_cli-0.9.0/tests/cost/test_rules_baseline.py +535 -0
  86. stacktrace_cli-0.9.0/tests/cost/test_rules_budget.py +189 -0
  87. stacktrace_cli-0.9.0/tests/cost/test_runs.py +43 -0
  88. stacktrace_cli-0.9.0/tests/cost/test_totals.py +55 -0
  89. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/tests/daemon/test_activity_log.py +23 -0
  90. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/tests/daemon/test_cli.py +96 -0
  91. stacktrace_cli-0.9.0/tests/daemon/test_cost_guidance.py +23 -0
  92. stacktrace_cli-0.9.0/tests/daemon/test_costs.py +1510 -0
  93. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/tests/daemon/test_db.py +2 -0
  94. stacktrace_cli-0.9.0/tests/daemon/test_job_thread.py +63 -0
  95. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/tests/daemon/test_runtime.py +64 -2
  96. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/tests/daemon/test_scan.py +105 -0
  97. stacktrace_cli-0.9.0/tests/daemon/test_stage_times.py +80 -0
  98. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/tests/detector_session_fixture.py +6 -0
  99. stacktrace_cli-0.9.0/tests/monitor/cost_harness.mjs +133 -0
  100. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/tests/monitor/feed_harness.mjs +71 -0
  101. stacktrace_cli-0.9.0/tests/monitor/test_cost_page.py +232 -0
  102. stacktrace_cli-0.9.0/tests/monitor/test_cost_range_switch.py +133 -0
  103. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/tests/monitor/test_feed_model.py +23 -0
  104. stacktrace_cli-0.9.0/tests/monitor/test_offline.py +242 -0
  105. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/tests/monitor/test_render.py +34 -3
  106. stacktrace_cli-0.9.0/tests/monitor/test_render_cost.py +641 -0
  107. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/tests/monitor/test_site_assets.py +1 -1
  108. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/tests/remote/test_facade_contract.py +19 -0
  109. stacktrace_cli-0.9.0/tests/telemetry/__init__.py +0 -0
  110. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/tests/test_call_status_conventions.py +158 -2
  111. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/tests/test_detector_end_to_end.py +2 -0
  112. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/tests/test_fingerprint_covers_what_the_analyzer_reads.py +9 -0
  113. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/tests/test_openaidr_contract.py +67 -0
  114. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/tests/test_seam_boundary.py +3 -0
  115. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/tests/test_session_identity_is_the_pair.py +13 -0
  116. stacktrace_cli-0.9.0/tests/test_sessions_protocol_typing.py +44 -0
  117. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/tests/test_sessions_protocols.py +35 -2
  118. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/tests/test_the_detector_spec_lists_the_shipped_catalogue.py +12 -2
  119. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/tests/test_title_disclosure_invariant.py +11 -4
  120. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/uv.lock +2 -2
  121. stacktrace_cli-0.8.0/tests/test_sessions_protocol_typing.py +0 -18
  122. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/.agents/skills/release-stacktrace/SKILL.md +0 -0
  123. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/.claude/settings.json +0 -0
  124. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/.claude/skills/pr-review-loop/SKILL.md +0 -0
  125. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/.claude/skills/release-stacktrace/SKILL.md +0 -0
  126. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/.codex/hooks.json +0 -0
  127. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/.github/managed-autofix.md +0 -0
  128. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/.github/pull_request_template.md +0 -0
  129. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/.github/workflows/ci.yml +0 -0
  130. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/.github/workflows/publish-pypi.yml +0 -0
  131. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/.gitignore +0 -0
  132. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/AGENTS.md +0 -0
  133. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/docs/adrs/0001-session-telemetry-as-input.md +0 -0
  134. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/docs/adrs/0002-session-collection-in-openaidr.md +0 -0
  135. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/docs/adrs/0003-runtime-edges.md +0 -0
  136. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/docs/adrs/0004-three-stage-detector.md +0 -0
  137. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/docs/adrs/0005-detection-family-and-report-assembly.md +0 -0
  138. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/docs/adrs/0007-proprietary-package-on-open-dependencies.md +0 -0
  139. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/docs/adrs/0008-console-in-separate-demo-package.md +0 -0
  140. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/docs/adrs/0010-detection-severity-and-confidence-ladders.md +0 -0
  141. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/docs/adrs/0011-verdict-cache.md +0 -0
  142. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/docs/adrs/0012-observation-evidence-kinds-and-transport.md +0 -0
  143. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/docs/adrs/0013-rule-catalogue-triage-and-per-rule-context.md +0 -0
  144. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/docs/adrs/0014-declared-project-mapping.md +0 -0
  145. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/docs/adrs/0015-narrow-the-security-catalogue.md +0 -0
  146. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/docs/adrs/0016-stall-grouping-is-session-wide.md +0 -0
  147. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/docs/adrs/0017-a-declined-repeat-is-a-stall.md +0 -0
  148. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/docs/adrs/0018-remote-sync-config-and-facade-consumption.md +0 -0
  149. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/docs/adrs/0019-delegated-commands-are-openaca-objects.md +0 -0
  150. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/docs/adrs/0020-openaca-consumption-boundary.md +0 -0
  151. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/docs/adrs/0021-two-command-kinds.md +0 -0
  152. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/docs/adrs/0022-detection-scope-is-a-catalogue-column.md +0 -0
  153. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/docs/adrs/0023-sync-detect-collects-and-does-not-escalate.md +0 -0
  154. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/docs/adrs/0024-the-upload-carries-observations.md +0 -0
  155. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/docs/adrs/0025-a-denied-call-is-activity-never-an-invocation.md +0 -0
  156. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/docs/adrs/0027-a-finding-may-name-what-it-could-not-place.md +0 -0
  157. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/docs/adrs/0028-the-console-shows-what-it-placed.md +0 -0
  158. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/docs/adrs/0029-stage-three-returns-to-opt-in.md +0 -0
  159. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/docs/adrs/0030-a-detection-is-dated-by-the-turns-it-cites.md +0 -0
  160. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/docs/adrs/0031-one-host-daemon-observes-native-session-logs.md +0 -0
  161. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/docs/adrs/0032-refresh-daemon-compositions-outside-detection.md +0 -0
  162. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/docs/adrs/0033-a-third-party-analyzer-only-by-a-flag-that-names-it.md +0 -0
  163. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/docs/adrs/0034-the-drift-grade-is-read-off-a-run-not-a-call.md +0 -0
  164. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/docs/adrs/0035-naming-an-analyzer-selects-stored-answers.md +0 -0
  165. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/docs/adrs/0036-deliver-eligible-findings-to-slack-from-the-daemon.md +0 -0
  166. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/docs/adrs/0037-reuse-openaidr-append-cursors-in-the-daemon.md +0 -0
  167. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/docs/adrs/0038-poll-normalized-sessions-for-supplemental-changes.md +0 -0
  168. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/docs/adrs/0039-send-usage-telemetry-by-default-with-an-opt-out.md +0 -0
  169. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/docs/adrs/0041-defer-native-windows-support.md +0 -0
  170. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/docs/adrs/0042-read-the-build-commit-from-the-install-record.md +0 -0
  171. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/docs/adrs/0043-name-the-session-agent-and-host-and-count-errors-by-class.md +0 -0
  172. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/docs/adrs/0044-send-the-build-as-version-prints-it.md +0 -0
  173. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/docs/adrs/0045-scan-every-session-and-outlive-them.md +0 -0
  174. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/docs/adrs/0046-the-finding-store-is-an-append-only-queue.md +0 -0
  175. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/docs/adrs/0047-capture-activity-during-correlation-or-lose-it.md +0 -0
  176. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/docs/adrs/0048-the-daemon-keeps-a-leveled-content-free-activity-log.md +0 -0
  177. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/docs/adrs/0056-stop-a-resident-daemon-by-record-and-signal.md +0 -0
  178. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/docs/adrs/0057-grow-the-queue-schema-additively-and-share-only-the-document.md +0 -0
  179. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/docs/adrs/0058-one-word-for-a-finding-columns-for-a-counter-and-a-push-that-does-not-wait.md +0 -0
  180. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/docs/adrs/0059-the-daemon-does-not-decide-whether-it-should-be-running.md +0 -0
  181. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/docs/adrs/0060-two-upload-postures-not-one-command-with-two-sources.md +0 -0
  182. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/docs/adrs/0061-the-drain-sends-findings-only.md +0 -0
  183. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/docs/adrs/0062-hold-the-transition-lock-across-remote-side-effects.md +0 -0
  184. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/docs/adrs/0063-underbuilt-debt-does-not-hold-the-scan-watermark.md +0 -0
  185. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/docs/adrs/0064-a-redacted-value-has-one-path-span.md +0 -0
  186. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/docs/adrs/0065-asset-external-id-resolves-by-a-ladder.md +0 -0
  187. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/docs/adrs/0066-host-owned-daemon-supervision.md +0 -0
  188. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/docs/adrs/0067-a-webhook-is-an-independent-queue-subscriber.md +0 -0
  189. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/docs/adrs/0068-webhooks-retry-the-retained-backlog.md +0 -0
  190. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/docs/adrs/0069-webhooks-deliver-what-retention-holds.md +0 -0
  191. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/docs/adrs/0070-package-the-cloud-agent-environment-bootstrap.md +0 -0
  192. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/docs/adrs/0071-render-the-allowlisted-payload-per-destination.md +0 -0
  193. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/docs/adrs/0072-host-supervisors-own-daemon-restarts.md +0 -0
  194. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/docs/adrs/0073-name-what-fired-and-which-component.md +0 -0
  195. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/docs/adrs/0074-a-window-selects-findings-by-when-they-happened.md +0 -0
  196. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/docs/adrs/0076-two-phase-detection-pipeline.md +0 -0
  197. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/docs/adrs/0077-the-bom-job-wakes-once-at-startup-staggered.md +0 -0
  198. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/docs/adrs/0078-a-seeded-display-prefix-replaces-the-hostname-label.md +0 -0
  199. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/docs/adrs/0079-the-monitor-page-renders-findings-not-pipeline-health.md +0 -0
  200. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/docs/adrs/0080-enabling-reasoning-does-not-requeue-the-past.md +0 -0
  201. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/docs/adrs/0081-reasoning-activation-returns-to-explicit-opt-in.md +0 -0
  202. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/docs/adrs/0082-monitor-checks-every-installed-component-by-default.md +0 -0
  203. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/docs/adrs/0083-each-block-reason-is-its-own-rule.md +0 -0
  204. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/docs/adrs/0084-a-recursive-deletes-evidence-is-the-rm-that-ran.md +0 -0
  205. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/docs/adrs/0085-show-when-and-which-finding-slack-delivered.md +0 -0
  206. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/docs/adrs/0086-a-refusal-names-who-answered-the-call.md +0 -0
  207. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/docs/adrs/0087-deploy-compiled-policy-with-a-privileged-scheduled-job.md +0 -0
  208. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/docs/adrs/0088-slack-alerts-leave-out-confidence.md +0 -0
  209. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/docs/adrs/0089-infra-gate-reads-commands-not-shell-semantics.md +0 -0
  210. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/docs/adrs/0090-count-completed-commands-locate-by-ip-send-through-the-managed-proxy.md +0 -0
  211. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/docs/adrs/0091-mark-our-own-machines-and-name-what-failed.md +0 -0
  212. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/docs/adrs/HOOK-PROMPT.md +0 -0
  213. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/docs/adrs/TEMPLATE.md +0 -0
  214. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/docs/cutover-openaca-remote.md +0 -0
  215. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/docs/plans/002-session-input.md +0 -0
  216. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/docs/plans/003-correlation.md +0 -0
  217. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/docs/plans/004-detector.md +0 -0
  218. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/docs/plans/005-remote-sync.md +0 -0
  219. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/docs/plans/006-cli-composition.md +0 -0
  220. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/docs/plans/007-detection-upload.md +0 -0
  221. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/docs/plans/008-monitor.md +0 -0
  222. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/docs/plans/009-reasoning-jev.md +0 -0
  223. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/docs/plans/010-session-daemon.md +0 -0
  224. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/docs/plans/011-daemon-store.md +0 -0
  225. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/docs/plans/012-daemon-scanning.md +0 -0
  226. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/docs/plans/013-daemon-uploads.md +0 -0
  227. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/docs/plans/014-asset-identity.md +0 -0
  228. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/docs/plans/015-managed-policy-deployment.md +0 -0
  229. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/docs/releases/v0.0.1.md +0 -0
  230. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/docs/releases/v0.1.0.md +0 -0
  231. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/docs/releases/v0.2.0.md +0 -0
  232. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/docs/releases/v0.2.1.md +0 -0
  233. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/docs/releases/v0.2.2.md +0 -0
  234. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/docs/releases/v0.2.3.md +0 -0
  235. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/docs/releases/v0.3.0.md +0 -0
  236. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/docs/releases/v0.3.1.md +0 -0
  237. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/docs/releases/v0.4.0.md +0 -0
  238. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/docs/releases/v0.4.1.md +0 -0
  239. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/docs/releases/v0.5.0.md +0 -0
  240. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/docs/releases/v0.5.1.md +0 -0
  241. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/docs/releases/v0.5.2.md +0 -0
  242. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/docs/releases/v0.5.3.md +0 -0
  243. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/docs/releases/v0.6.0.md +0 -0
  244. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/docs/releases/v0.6.1.md +0 -0
  245. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/docs/releases/v0.7.0.md +0 -0
  246. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/docs/releases/v0.7.1.md +0 -0
  247. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/docs/releases/v0.8.0.md +0 -0
  248. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/docs/research/001-intent-drift-metric.md +0 -0
  249. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/docs/specs/cli-composition.md +0 -0
  250. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/docs/specs/correlation.md +0 -0
  251. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/docs/specs/daemon-scanning.md +0 -0
  252. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/docs/specs/daemon-store.md +0 -0
  253. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/docs/specs/daemon-uploads.md +0 -0
  254. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/docs/specs/detection-upload.md +0 -0
  255. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/docs/specs/event-time.md +0 -0
  256. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/docs/specs/managed-policy-deployment.md +0 -0
  257. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/docs/specs/monitor-inventory.md +0 -0
  258. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/docs/specs/notification-delivery.md +0 -0
  259. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/docs/specs/reasoning-jev.md +0 -0
  260. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/docs/specs/remote-sync.md +0 -0
  261. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/scripts/git-hooks/pre-push +0 -0
  262. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/scripts/install-hooks.sh +0 -0
  263. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/src/stacktrace_cli/__main__.py +0 -0
  264. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/src/stacktrace_cli/build.py +0 -0
  265. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/src/stacktrace_cli/cloud/__init__.py +0 -0
  266. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/src/stacktrace_cli/cloud/setup.sh +0 -0
  267. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/src/stacktrace_cli/correlate/__init__.py +0 -0
  268. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/src/stacktrace_cli/correlate/acquire.py +0 -0
  269. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/src/stacktrace_cli/correlate/composition.py +0 -0
  270. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/src/stacktrace_cli/correlate/join.py +0 -0
  271. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/src/stacktrace_cli/correlate/observed.py +0 -0
  272. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/src/stacktrace_cli/correlate/orchestrate.py +0 -0
  273. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/src/stacktrace_cli/correlate/project_map.py +0 -0
  274. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/src/stacktrace_cli/correlate/record.py +0 -0
  275. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/src/stacktrace_cli/correlate/render.py +0 -0
  276. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/src/stacktrace_cli/daemon/__init__.py +0 -0
  277. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/src/stacktrace_cli/daemon/activity_log.py +0 -0
  278. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/src/stacktrace_cli/daemon/bom.py +0 -0
  279. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/src/stacktrace_cli/daemon/client.py +0 -0
  280. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/src/stacktrace_cli/daemon/composition.py +0 -0
  281. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/src/stacktrace_cli/daemon/identity.py +0 -0
  282. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/src/stacktrace_cli/daemon/lifecycle.py +0 -0
  283. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/src/stacktrace_cli/daemon/paths.py +0 -0
  284. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/src/stacktrace_cli/daemon/protocol.py +0 -0
  285. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/src/stacktrace_cli/daemon/server.py +0 -0
  286. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/src/stacktrace_cli/daemon/service.py +0 -0
  287. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/src/stacktrace_cli/daemon/webhook.py +0 -0
  288. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/src/stacktrace_cli/detector/__init__.py +0 -0
  289. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/src/stacktrace_cli/detector/analyzer.py +0 -0
  290. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/src/stacktrace_cli/detector/blocked.py +0 -0
  291. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/src/stacktrace_cli/detector/cache.py +0 -0
  292. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/src/stacktrace_cli/detector/deterministic.py +0 -0
  293. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/src/stacktrace_cli/detector/history.py +0 -0
  294. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/src/stacktrace_cli/detector/jev.py +0 -0
  295. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/src/stacktrace_cli/detector/priors.py +0 -0
  296. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/src/stacktrace_cli/detector/prompts/__init__.py +0 -0
  297. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/src/stacktrace_cli/detector/prompts/jev-v1/stacktrace-deceptive-completion.json +0 -0
  298. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/src/stacktrace_cli/detector/prompts/jev-v2/stacktrace-deceptive-completion.json +0 -0
  299. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/src/stacktrace_cli/detector/prompts/jev-v2/stacktrace-infra-unsafe-action.json +0 -0
  300. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/src/stacktrace_cli/detector/prompts/v1/exclusions.md +0 -0
  301. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/src/stacktrace_cli/detector/prompts/v1/framing.md +0 -0
  302. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/src/stacktrace_cli/detector/prompts/v1/stacktrace-deceptive-completion.md +0 -0
  303. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/src/stacktrace_cli/detector/reasoning.py +0 -0
  304. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/src/stacktrace_cli/detector/run.py +0 -0
  305. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/src/stacktrace_cli/detector/secrets.py +0 -0
  306. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/src/stacktrace_cli/detector/verdict.py +0 -0
  307. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/src/stacktrace_cli/detector/windows.py +0 -0
  308. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/src/stacktrace_cli/monitor/__init__.py +0 -0
  309. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/src/stacktrace_cli/monitor/inventory.py +0 -0
  310. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/src/stacktrace_cli/monitor/reasoning.py +0 -0
  311. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/src/stacktrace_cli/monitor/site/apple-icon.png +0 -0
  312. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/src/stacktrace_cli/monitor/site/favicon.ico +0 -0
  313. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/src/stacktrace_cli/monitor/site/fonts/OFL.txt +0 -0
  314. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/src/stacktrace_cli/monitor/site/fonts/dm-mono-400-latin.woff2 +0 -0
  315. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/src/stacktrace_cli/monitor/site/fonts/dm-mono-500-latin.woff2 +0 -0
  316. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/src/stacktrace_cli/monitor/site/fonts/dm-sans-latin.woff2 +0 -0
  317. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/src/stacktrace_cli/monitor/site/icon.svg +0 -0
  318. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/src/stacktrace_cli/monitor/verdicts.py +0 -0
  319. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/src/stacktrace_cli/options.py +0 -0
  320. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/src/stacktrace_cli/private_state.py +0 -0
  321. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/src/stacktrace_cli/remote/__init__.py +0 -0
  322. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/src/stacktrace_cli/remote/cli.py +0 -0
  323. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/src/stacktrace_cli/remote/client.py +0 -0
  324. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/src/stacktrace_cli/remote/config.py +0 -0
  325. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/src/stacktrace_cli/remote/detect_payload.py +0 -0
  326. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/src/stacktrace_cli/remote/identity.py +0 -0
  327. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/src/stacktrace_cli/remote/payload.py +0 -0
  328. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/src/stacktrace_cli/remote/policy.py +0 -0
  329. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/src/stacktrace_cli/remote/policy_service.py +0 -0
  330. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/src/stacktrace_cli/remote/policy_worker.py +0 -0
  331. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/src/stacktrace_cli/remote/redact.py +0 -0
  332. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/src/stacktrace_cli/remote/spool.py +0 -0
  333. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/src/stacktrace_cli/remote/sync.py +0 -0
  334. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/src/stacktrace_cli/remote/sync_detect.py +0 -0
  335. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/src/stacktrace_cli/remote/upload_contract.py +0 -0
  336. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/src/stacktrace_cli/sessions/__init__.py +0 -0
  337. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/src/stacktrace_cli/sessions/access.py +0 -0
  338. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/src/stacktrace_cli/sessions/index.py +0 -0
  339. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/src/stacktrace_cli/sessions/outcome.py +0 -0
  340. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/src/stacktrace_cli/sessions/render.py +0 -0
  341. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/src/stacktrace_cli/telemetry/__init__.py +0 -0
  342. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/src/stacktrace_cli/telemetry/cli.py +0 -0
  343. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/src/stacktrace_cli/telemetry/events.py +0 -0
  344. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/src/stacktrace_cli/telemetry/posthog.py +0 -0
  345. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/src/stacktrace_cli/telemetry/state.py +0 -0
  346. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/src/stacktrace_cli/webhook/__init__.py +0 -0
  347. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/src/stacktrace_cli/webhook/cli.py +0 -0
  348. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/src/stacktrace_cli/webhook/config.py +0 -0
  349. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/tests/__init__.py +0 -0
  350. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/tests/agent_bom_fixture.py +0 -0
  351. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/tests/conftest.py +0 -0
  352. {stacktrace_cli-0.8.0/tests/monitor → stacktrace_cli-0.9.0/tests/cost}/__init__.py +0 -0
  353. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/tests/daemon/__init__.py +0 -0
  354. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/tests/daemon/test_client.py +0 -0
  355. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/tests/daemon/test_composition.py +0 -0
  356. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/tests/daemon/test_config.py +0 -0
  357. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/tests/daemon/test_detection_needs_no_subscriber.py +0 -0
  358. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/tests/daemon/test_fleet.py +0 -0
  359. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/tests/daemon/test_identity.py +0 -0
  360. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/tests/daemon/test_jobs.py +0 -0
  361. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/tests/daemon/test_lifecycle.py +0 -0
  362. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/tests/daemon/test_observer.py +0 -0
  363. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/tests/daemon/test_queue_reader.py +0 -0
  364. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/tests/daemon/test_service.py +0 -0
  365. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/tests/daemon/test_socket.py +0 -0
  366. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/tests/daemon/test_store.py +0 -0
  367. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/tests/daemon/test_the_drained_payload_is_the_cold_one.py +0 -0
  368. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/tests/daemon/test_the_stored_row_is_sufficient.py +0 -0
  369. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/tests/daemon/test_webhook.py +0 -0
  370. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/tests/daemon/test_wire_frames_are_bounded.py +0 -0
  371. {stacktrace_cli-0.8.0/tests/remote → stacktrace_cli-0.9.0/tests/monitor}/__init__.py +0 -0
  372. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/tests/monitor/inventory_harness.mjs +0 -0
  373. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/tests/monitor/test_inventory.py +0 -0
  374. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/tests/monitor/test_inventory_page.py +0 -0
  375. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/tests/monitor/test_reasoning_gates.py +0 -0
  376. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/tests/monitor/test_server.py +0 -0
  377. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/tests/monitor/test_state.py +0 -0
  378. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/tests/monitor/test_verdicts.py +0 -0
  379. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/tests/monitor/test_watch.py +0 -0
  380. {stacktrace_cli-0.8.0/tests/telemetry → stacktrace_cli-0.9.0/tests/remote}/__init__.py +0 -0
  381. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/tests/remote/helpers.py +0 -0
  382. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/tests/remote/test_cli.py +0 -0
  383. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/tests/remote/test_client.py +0 -0
  384. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/tests/remote/test_config.py +0 -0
  385. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/tests/remote/test_detect_activity.py +0 -0
  386. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/tests/remote/test_detect_cli.py +0 -0
  387. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/tests/remote/test_detect_client.py +0 -0
  388. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/tests/remote/test_detect_contract_is_exhaustive.py +0 -0
  389. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/tests/remote/test_detect_gate_matches_the_cloud.py +0 -0
  390. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/tests/remote/test_detect_layers_compose.py +0 -0
  391. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/tests/remote/test_detect_payload_reaches_the_cloud_model.py +0 -0
  392. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/tests/remote/test_detect_redaction.py +0 -0
  393. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/tests/remote/test_detect_spool.py +0 -0
  394. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/tests/remote/test_detect_upload_contract.py +0 -0
  395. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/tests/remote/test_detect_wire_payload.py +0 -0
  396. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/tests/remote/test_identity.py +0 -0
  397. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/tests/remote/test_no_local_path_survives_redaction.py +0 -0
  398. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/tests/remote/test_payload.py +0 -0
  399. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/tests/remote/test_policy.py +0 -0
  400. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/tests/remote/test_policy_service.py +0 -0
  401. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/tests/remote/test_policy_service_cli.py +0 -0
  402. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/tests/remote/test_redact_payload.py +0 -0
  403. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/tests/remote/test_seam.py +0 -0
  404. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/tests/remote/test_spool.py +0 -0
  405. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/tests/remote/test_sync.py +0 -0
  406. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/tests/remote/test_sync_detect.py +0 -0
  407. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/tests/remote/test_upload_contract.py +0 -0
  408. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/tests/telemetry/test_activity_log.py +0 -0
  409. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/tests/telemetry/test_cli.py +0 -0
  410. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/tests/telemetry/test_events.py +0 -0
  411. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/tests/telemetry/test_every_derived_site.py +0 -0
  412. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/tests/telemetry/test_every_internal_save_is_reported.py +0 -0
  413. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/tests/telemetry/test_hooks.py +0 -0
  414. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/tests/telemetry/test_release_gate.py +0 -0
  415. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/tests/telemetry/test_state.py +0 -0
  416. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/tests/telemetry/test_uploader.py +0 -0
  417. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/tests/test_acquire.py +0 -0
  418. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/tests/test_adr_cross_references_are_reciprocal.py +0 -0
  419. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/tests/test_agent_instance_id.py +0 -0
  420. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/tests/test_analysis.py +0 -0
  421. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/tests/test_bom_shape.py +0 -0
  422. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/tests/test_build_commit.py +0 -0
  423. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/tests/test_cli.py +0 -0
  424. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/tests/test_composition.py +0 -0
  425. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/tests/test_correlate_orchestrate.py +0 -0
  426. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/tests/test_correlate_render.py +0 -0
  427. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/tests/test_correlated_session.py +0 -0
  428. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/tests/test_detection_components.py +0 -0
  429. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/tests/test_detection_event_time.py +0 -0
  430. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/tests/test_detection_subject.py +0 -0
  431. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/tests/test_detector_analyzer_contract.py +0 -0
  432. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/tests/test_detector_analyzer_live.py +0 -0
  433. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/tests/test_detector_blocked.py +0 -0
  434. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/tests/test_detector_cache.py +0 -0
  435. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/tests/test_detector_deterministic.py +0 -0
  436. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/tests/test_detector_finding.py +0 -0
  437. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/tests/test_detector_history.py +0 -0
  438. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/tests/test_detector_infra_reasoning.py +0 -0
  439. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/tests/test_detector_jev.py +0 -0
  440. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/tests/test_detector_names_the_service.py +0 -0
  441. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/tests/test_detector_new_deterministic.py +0 -0
  442. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/tests/test_detector_priors.py +0 -0
  443. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/tests/test_detector_prompts.py +0 -0
  444. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/tests/test_detector_reasoning.py +0 -0
  445. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/tests/test_detector_render.py +0 -0
  446. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/tests/test_detector_run.py +0 -0
  447. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/tests/test_detector_secrets.py +0 -0
  448. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/tests/test_detector_verdict.py +0 -0
  449. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/tests/test_detector_vulnerable_dep_invoked.py +0 -0
  450. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/tests/test_detector_why_it_stopped.py +0 -0
  451. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/tests/test_detector_windows.py +0 -0
  452. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/tests/test_evidence_is_dated_not_numbered.py +0 -0
  453. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/tests/test_help_sections.py +0 -0
  454. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/tests/test_join.py +0 -0
  455. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/tests/test_monitor_cli.py +0 -0
  456. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/tests/test_no_live_document_states_the_old_stage_three_default.py +0 -0
  457. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/tests/test_no_test_undoes_every_patch_at_once.py +0 -0
  458. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/tests/test_observed.py +0 -0
  459. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/tests/test_openaca_contract.py +0 -0
  460. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/tests/test_option_arity_matches_the_binary.py +0 -0
  461. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/tests/test_project_map.py +0 -0
  462. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/tests/test_readme_examples_are_real_output.py +0 -0
  463. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/tests/test_release_gate_coverage.py +0 -0
  464. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/tests/test_release_readiness.py +0 -0
  465. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/tests/test_sessions_access.py +0 -0
  466. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/tests/test_sessions_end_to_end.py +0 -0
  467. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/tests/test_sessions_render.py +0 -0
  468. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/tests/test_shell_separators_match_the_shell.py +0 -0
  469. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/tests/test_stored_verdicts_are_never_gated_on_reasoning.py +0 -0
  470. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/tests/test_the_jev_spec_states_the_shipped_thresholds.py +0 -0
  471. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/tests/test_the_locality_claim_is_qualified_everywhere.py +0 -0
  472. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/tests/test_untrusted_content_never_travels.py +0 -0
  473. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/tests/test_verification_subcommands_match_the_binary.py +0 -0
  474. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/tests/test_what_jev_is_told_is_what_was_disclosed.py +0 -0
  475. {stacktrace_cli-0.8.0 → stacktrace_cli-0.9.0}/tests/webhook/test_cli.py +0 -0
@@ -108,6 +108,10 @@ nothing about detection.
108
108
  - **OpenACA carries nothing AIDR** (ADR-0006). No finding family, no output row
109
109
  type, no scan flag, no rule namespace upstream. Detection rule identifiers are
110
110
  `stacktrace-*`, never `openaca-*`, and the combined report is assembled here.
111
+ - **Cost is tokens, never dollars** (ADR-0099). Every cost figure, threshold,
112
+ severity, budget, label and doc line is in tokens or a ratio to the usual
113
+ ("3× the usual", "40M tokens more"). No price table, no dollar amount, no
114
+ currency, here or in Fleet. The family is still called `cost`.
111
115
  - **Session collection is not ours** (ADR-0002). It lives in `openaidr`, open
112
116
  source. Its types stop at our adapter; parsing an agent format here would
113
117
  duplicate the thing the split exists to prevent.
@@ -122,6 +126,12 @@ nothing about detection.
122
126
  `test_bom_shape.py`, `test_fingerprint_covers_what_the_analyzer_reads.py`. When
123
127
  a review names a site, fix the invariant and extend the exhaustive test — a
124
128
  second finding of the same class means the first fix was at the wrong level.
129
+ Cost has its own: `tests/cost/test_cost_findings_carry_no_session_text.py`,
130
+ `tests/cost/test_cost_is_tokens.py`, `test_cost_findings_are_dated_by_their_citations.py`,
131
+ and the range and usual checks in
132
+ `tests/monitor/test_render_cost.py`. When reviews keep re-arguing scope (a
133
+ time boundary, which sessions a rule reads), write the answer into the spec,
134
+ as `docs/specs/cost-phase-1.md` §1 "What a rule reads, and when" does.
125
135
 
126
136
  ## Adding a command
127
137
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: stacktrace-cli
3
- Version: 0.8.0
3
+ Version: 0.9.0
4
4
  Summary: CLI for Stacktrace — Detection and Response platform for AI Agents.
5
5
  Project-URL: Homepage, https://stacktrace.ai
6
6
  Author-email: "Stacktrace AI, Inc" <founders@stacktrace.ai>
@@ -51,7 +51,7 @@ Requires Python 3.11 or newer.
51
51
 
52
52
  ```console
53
53
  $ stacktrace --version
54
- stacktrace 0.8.0 (openaca 0.8.0)
54
+ stacktrace 0.9.0 (openaca 0.8.0)
55
55
  ```
56
56
 
57
57
  ## Quick start
@@ -24,7 +24,7 @@ Requires Python 3.11 or newer.
24
24
 
25
25
  ```console
26
26
  $ stacktrace --version
27
- stacktrace 0.8.0 (openaca 0.8.0)
27
+ stacktrace 0.9.0 (openaca 0.8.0)
28
28
  ```
29
29
 
30
30
  ## Quick start
@@ -5,7 +5,7 @@ status: accepted
5
5
  date: 2026-08-28
6
6
  supersedes: null
7
7
  superseded-by: null
8
- amended-by: 0011, 0027, 0031, 0039, 0064, 0084, 0086
8
+ amended-by: 0011, 0027, 0031, 0039, 0064, 0084, 0086, 0096
9
9
  ---
10
10
 
11
11
  ## Context
@@ -6,7 +6,7 @@ date: 2026-09-06
6
6
  supersedes: 0008
7
7
  superseded-by: null
8
8
  amends: null
9
- amended-by: null
9
+ amended-by: 0097
10
10
  ---
11
11
 
12
12
  ## Context
@@ -0,0 +1,49 @@
1
+ ---
2
+ id: 0092
3
+ title: Cost is its own rule family
4
+ status: proposed
5
+ date: 2026-10-05
6
+ supersedes: null
7
+ superseded-by: null
8
+ amends: null
9
+ amended-by: null
10
+ ---
11
+
12
+ ## Context
13
+
14
+ Cost Phase 1 adds cost rules (`docs/specs/cost-phase-1.md`). The catalogue has
15
+ two families, security and reliability, and Fleet's `detection_rules` check
16
+ constraint allows only those two (migration 0016). ADR-0013 created reliability
17
+ because stuck sessions needed their own heading and handling. Cost now needs the
18
+ same, as one of the product's main use cases.
19
+
20
+ ## Decision
21
+
22
+ Cost rules form a third family, **`cost`**, named `stacktrace-cost-*`, with a
23
+ `COST_RULES` set in the catalogue. `rules.family_of` derives it, never stored on
24
+ a finding (ADR-0013). `stacktrace-blocked-quota` stays reliability, because the
25
+ agent got stuck, and cost findings may cite it as evidence.
26
+
27
+ ## Alternatives considered
28
+
29
+ - **Reliability, separated by name prefix.** This was the first proposal. It is
30
+ rejected for three reasons:
31
+ - Fleet users count, filter and route by family, and a prefix is invisible to
32
+ them.
33
+ - Cost goes to the people who own the budget, not to whoever runs the agent.
34
+ - Reliability asks whether the session worked; a runaway can work perfectly
35
+ and still use far more tokens than it needs.
36
+ - **Security.** Rejected: costly behaviour is not an attack.
37
+
38
+ ## Consequences
39
+
40
+ - One Fleet migration adds `cost` to the family check constraint, done in Phase
41
+ 1 before any cost finding exists, so no stored data moves.
42
+ - The CLI catalogue, the monitor's `by_family` summary, the Fleet console and
43
+ Slack each gain a third family.
44
+ - Phase 2 can route notifications per family.
45
+
46
+ ## When to revisit
47
+
48
+ If a cost rule turns out to be mainly about a session failing rather than
49
+ using too many tokens, move that rule to reliability.
@@ -0,0 +1,78 @@
1
+ ---
2
+ id: 0093
3
+ title: Environment cost baselines count tokens and are keyed by model
4
+ status: proposed
5
+ date: 2026-10-05
6
+ supersedes: null
7
+ superseded-by: null
8
+ amends: null
9
+ amended-by: 0099
10
+ ---
11
+
12
+ ## Context
13
+
14
+ `stacktrace-cost-runaway-session` must catch a session running away, while it
15
+ runs, against this developer's normal. Three things move "normal" without
16
+ anything going wrong: a price change, a new default model, and idle time.
17
+
18
+ ## Decision
19
+
20
+ - The daemon keeps p50, p95 and p99 of **cumulative tokens by active minute**,
21
+ and of 5-minute burn, from this environment's finished sessions over 30 days.
22
+ - It also keeps a **day curve**: cumulative tokens by local time of day per
23
+ working day, per model. That curve gives the personal-anomaly rule "your usual
24
+ by now", and needs 10 working days of history.
25
+ The rule's score is log(today ÷ usual) divided by the spread: 1.48 × the
26
+ median absolute deviation of that log, at least 0.25. The spec's "beyond the
27
+ normal range" is a score of 3 or more; "far beyond" is 6 or more.
28
+ - It also keeps **behaviour curves** per run: sub-agents started in 10 minutes,
29
+ repeats with an unchanged result, input per response, cache reads and cache
30
+ writes, as p5 and p99, and fresh input at p95. A waste rule fires only when
31
+ the behaviour and the cost are both unusual for this developer, so no waste
32
+ rule rests on a fixed limit alone.
33
+ - The summaries are keyed by cohort, `(repo, entrypoint, model)`, falling back
34
+ to `(entrypoint, model)`, then `(model)`. Each level needs at least 20
35
+ sessions; with none, the rule is silent.
36
+ - **Tokens, not dollars**, throughout: floors and severity too (ADR-0099).
37
+ - **Recorded tokens on both sides.** Baselines and rules count only what the
38
+ transcripts record.
39
+ - The client's own totals are not read at all (ADR-0099): they arrive after
40
+ the work, with no time of their own, and add about half a percent.
41
+ - A comparison then undercounts alike on both sides.
42
+ - On a run with many sub-agents, whose output is often a lower bound, a rule
43
+ fires later, never falsely sooner.
44
+ - The baseline is backfilled from transcripts at start, excludes sessions with
45
+ an open cost finding, and is written only by the daemon (ADR-0046).
46
+ - Rules get a frozen snapshot as an input.
47
+ - **The table holds one numeric summary per finished session**, not the
48
+ percentiles: the summary's curves and behaviour measures, its cohort, run,
49
+ day and login type. The snapshot computes the percentiles from these rows,
50
+ which is what lets it drop a flagged run or a row older than 30 days.
51
+ - Numbers only, never content, so it is an exception to ADR-0006 constraint 1
52
+ on the same terms as the verdict cache (ADR-0011). It is not the sessions
53
+ table ADR-0046 rejected, which would have held session models.
54
+ - It is additive, so `SCHEMA_VERSION` does not move (ADR-0057).
55
+ - The monitor reads the same snapshot, read-only, for "your usual" (ADR-0097).
56
+
57
+ ## Alternatives considered
58
+
59
+ - **Dollar baselines.** Rejected: a price change would fire everywhere.
60
+ - **One baseline across models.** Rejected: a model launch would fire everywhere.
61
+ - **Thresholds on finished-session totals.** Rejected: they fire after the
62
+ tokens are used.
63
+ - **Recompute from transcripts every scan.** Rejected: it repeats the cold pass
64
+ ADR-0011 and ADR-0037 avoid.
65
+ - **Rules querying the store directly.** Rejected: it breaks the single writer,
66
+ and output would depend on when it was read.
67
+
68
+ ## Consequences
69
+
70
+ - Price changes and model launches can't trigger the rule on their own.
71
+ - It costs a new store table and a backfill.
72
+ - A developer with too few sessions gets no runaway findings until Phase 2
73
+ sends peer numbers.
74
+
75
+ ## When to revisit
76
+
77
+ If the cohorts prove too thin in measurement, or Phase 2's fleet-wide numbers
78
+ make the narrow levels unnecessary.
@@ -0,0 +1,63 @@
1
+ ---
2
+ id: 0094
3
+ title: Cost is tokens × price at the time of use; the agent's own figure is a cross-check
4
+ status: superseded
5
+ date: 2026-10-05
6
+ supersedes: null
7
+ superseded-by: 0099
8
+ amends: null
9
+ amended-by: null
10
+ ---
11
+
12
+ ## Context
13
+
14
+ Phase 1 shows dollars and uses them as floors. Claude Code already
15
+ writes a running `totalCostUSD` in `cost-state` records, in 109 of 181 measured
16
+ sessions. Using it is the obvious shortcut.
17
+
18
+ ## Decision
19
+
20
+ - The CLI prices each response's token buckets from a **versioned,
21
+ effective-dated price table**, at the price **in effect when the response
22
+ happened**.
23
+ - A model with no price is **unpriced**: shown in tokens, never priced at zero.
24
+ - Every dollar says which rate produced it: at list price, or at the org's own
25
+ rates once entered (Phase 2). The arithmetic is exact for what it prices —
26
+ tokens by model, type and date — but that excludes two billing dimensions
27
+ the agent's own figure does include: the 10% multiplier Anthropic applies to
28
+ a response on US data residency, and per-request fees such as web search,
29
+ which aren't token charges at all ([cost.md §4.3](../specs/cost.md#43-what-cost-is)).
30
+ - Claude Code's own figure is compared per session as a **cross-check only**.
31
+ - Tokens the transcripts miss, such as some sub-agent work, are taken from
32
+ Claude Code's per-model token totals and priced the same way, as one
33
+ "unrecorded" line — reconciled once per **run**, against the run's own
34
+ latest cumulative figure, never once per session: a resumed session's figure
35
+ already includes its earlier spend, and a parent's already includes its
36
+ sub-agents', so summing each session's own remainder would double-count
37
+ both. Its dollars are never used.
38
+
39
+ ## Alternatives considered
40
+
41
+ - **Use Claude Code's `cost-state` as the cost.** Rejected, for four reasons:
42
+ - it is a per-session running total, so it can't price a window, a run or a
43
+ response;
44
+ - it is missing in 72 of 181 sessions;
45
+ - it is Claude Code's alone, and Codex records none;
46
+ - it can't take org rates or be re-priced.
47
+ - **Price in OpenAIDR.** Rejected by OpenAIDR ADR-0015: a price is
48
+ interpretation.
49
+ - **The provider's usage API.** Not available in the environment: it needs an
50
+ admin key, lags, and has no per-session detail. It is Phase 2's reconciliation
51
+ source.
52
+
53
+ ## Consequences
54
+
55
+ - One method prices every agent, window and run.
56
+ - The price table must be maintained, and every price change noted in a release.
57
+ - A persistent gap against the cross-check, beyond the data-residency and
58
+ per-request gaps above, points to a missing price or a counting error.
59
+
60
+ ## When to revisit
61
+
62
+ If a provider records per-response cost in the transcript: carry it as recorded,
63
+ and make the estimate the cross-check.
@@ -0,0 +1,53 @@
1
+ ---
2
+ id: 0095
3
+ title: Every cost finding shows in Fleet; each cost rule's Slack notifications can be switched off
4
+ status: proposed
5
+ date: 2026-10-05
6
+ supersedes: null
7
+ superseded-by: null
8
+ amends: null
9
+ amended-by: null
10
+ ---
11
+
12
+ ## Context
13
+
14
+ Fleet posts every newly stored finding to Slack (`detections.py`, first
15
+ insert), with no filter by rule or severity. Phase 1 accepts that: its few
16
+ environment rules are checked on recorded sessions before they ship. Phase 2
17
+ adds Fleet's own rules, which compare people with the org and cannot be fully
18
+ tested before real org data exists. A rule that turns out noisy would keep
19
+ paging Fleet users until the next release.
20
+
21
+ ## Decision
22
+
23
+ - Cost findings drain to Fleet over the existing upload, with **no wire change**,
24
+ and show in its console per environment and run from day one.
25
+ - In Phase 1, Fleet posts every cost finding to Slack, like any other finding.
26
+ - From Phase 2, Fleet's catalogue gives each cost rule a **`notify` switch**,
27
+ on by default, and the Slack outbox skips rules with it off.
28
+ - The Stacktrace team turns a rule's `notify` off when it proves noisy, and back
29
+ on once it is fixed. Its findings still show in Fleet.
30
+ - Reviewing findings as right or wrong is available to the team but optional,
31
+ and never a gate before a rule notifies.
32
+ - Developers get every cost finding locally either way.
33
+
34
+ ## Alternatives considered
35
+
36
+ - **Keep findings local until Phase 2.** Rejected: Phase 1 would not be end to
37
+ end, and Fleet would have no evidence to evaluate.
38
+ - **Hold every new rule off until its findings are reviewed.** Rejected: manual
39
+ review does not scale, and every new rule would wait on reviewers.
40
+ - **No switch.** Rejected: a noisy rule would page until a release removed it,
41
+ and teach Fleet users to skip cost alerts.
42
+ - **Send them as low severity.** Rejected: severity says how bad a finding is,
43
+ not whether a rule is trustworthy, and Slack V1 has no severity filter.
44
+
45
+ ## Consequences
46
+
47
+ - A small Fleet change: a per-rule setting and one outbox condition.
48
+ - Other rules keep today's behaviour, with `notify` on.
49
+
50
+ ## When to revisit
51
+
52
+ When Fleet's Slack delivery gains severity or routing filters, which would make
53
+ this flag redundant.
@@ -0,0 +1,86 @@
1
+ ---
2
+ id: 0096
3
+ title: Cost usage may leave as token totals and work identifiers
4
+ status: accepted
5
+ date: 2026-10-06
6
+ supersedes: null
7
+ superseded-by: null
8
+ amends: 0006
9
+ amended-by: null
10
+ ---
11
+
12
+ ## Context
13
+
14
+ Cost Phase 2 (`docs/specs/cost-phase-2.md`) needs Fleet to judge an environment
15
+ owner's spend against their own past and against the org. Phase 1 already sends
16
+ findings and nothing else (ADR-0061, ADR-0095), and Fleet still has no usage.
17
+ The phase 2 upload, a new endpoint beside `detect-runs`, would send token totals
18
+ per run, session, model and minute, and per run the repo, branch, title and the
19
+ Anthropic account the agent is signed into.
20
+
21
+ That document is not a finding. [ADR-0006](0006-trust-boundary-and-detection-upload.md)
22
+ constraint 1 says detection findings are the one thing that may travel — amended
23
+ only by ADR-0039, for a different channel — and constraint 2 says the uploaded
24
+ document carries no user. The account is sent because, on a shared dev box or CI
25
+ runner, it names the person and the Fleet enrollment key does not. None of
26
+ ADR-0092 through ADR-0095 amends constraint 1 or 2, so an implementer who followed
27
+ the spec alone would cross the boundary those constraints still state.
28
+
29
+ ## Decision
30
+
31
+ This amends ADR-0006 constraints 1 and 2 for one document: the cost usage upload,
32
+ and the cost findings Fleet draws from it. The rest of ADR-0006 stays in force,
33
+ including for every other finding family and for ADR-0039's telemetry.
34
+
35
+ 1. **Token totals may travel. The session may not.** Counts per run, session,
36
+ model, minute and token type (input, output, cache read, cache write — the
37
+ rates differ by type), plus a local reduction of the last 30 days to those
38
+ same counts. The session id is the key already allowed on a finding's session
39
+ reference, not the session. Transcripts, correlation records and session
40
+ models stay on the machine. There is still no upload path for them.
41
+ 2. **A closed set of work identifiers, and the provider account.** Per run: repo
42
+ name, branch name, title, and the Anthropic account the agent is signed into.
43
+ Per component: the tokens its definitions add to every call, whether it was
44
+ used, and how many calls carried it per model. Repo, branch and title are
45
+ names of the work, not a path, a working directory or a machine name. The
46
+ account may appear on a cost finding because that finding is about who spent;
47
+ it is how a shared environment names the person. No other finding family
48
+ gains a user.
49
+ 3. **Nothing else.** Prompts, tool arguments, tool results and paths do not
50
+ travel. A title that reproduces the prompt is a prompt and does not travel.
51
+ Absolute paths and secret-shaped strings are still refused (ADR-0006
52
+ constraint 4). ADR-0039 is unchanged: its events still exclude repository
53
+ names.
54
+
55
+ The findings drain stays findings-only (ADR-0061). This is a separate endpoint.
56
+
57
+ ## Alternatives considered
58
+
59
+ - **Cut the upload back to what ADR-0006 already allows.** Rejected. Findings
60
+ carry no usage, so Fleet cannot price an owner's past, separate a shared rise
61
+ from one person's, or say which work cost the money. That is the gap Phase 2
62
+ exists to close; Phase 1 already sends findings alone.
63
+ - **Upload the transcripts and price them in Fleet.** Rejected. ADR-0006 already
64
+ rejected central analysis of session content. The 30-day backfill is computed
65
+ locally and only the aggregates leave.
66
+ - **Put the rows on the findings drain.** Rejected. ADR-0061 keeps that drain
67
+ findings-only so the detection document does not grow a second shape.
68
+ - **Drop repo, branch, title and the account, and send token totals under the
69
+ Fleet key alone.** Rejected. A shared box enrolls as one Fleet member, so the
70
+ key is not the person who signed the agent in, and a finding that cannot name
71
+ the work cannot be acted on.
72
+
73
+ ## Consequences
74
+
75
+ - The cost spec may name these fields because this decision does. A field that
76
+ is not in the list above is still a breach.
77
+ - Cost findings and their Slack text may repeat the account, the repo, the
78
+ branch and the title. Other families may not.
79
+ - A title is the easiest way for conversation to leak through a field this
80
+ decision allows. Watch for one that is the prompt.
81
+
82
+ ## When to revisit
83
+
84
+ If Phase 2 ships without this upload, supersede this amendment. If the account
85
+ or the title is found to carry a credential or conversation in practice, narrow
86
+ clause 2 rather than widening what else may travel.
@@ -0,0 +1,69 @@
1
+ ---
2
+ id: 0097
3
+ title: The daemon makes cost findings once, and the monitor reads them from the store
4
+ status: proposed
5
+ date: 2026-10-06
6
+ supersedes: null
7
+ superseded-by: null
8
+ amends: 0026
9
+ amended-by: null
10
+ ---
11
+
12
+ ## Context
13
+
14
+ ADR-0026 clause 2 says the console does no analysis of its own: it calls
15
+ `collect_sessions`, `acquire_correlated_view` and `run_detector`, and "a
16
+ finding on the page is a finding `detect` would print".
17
+
18
+ Cost findings don't fit that shape.
19
+
20
+ - `budget-breach` and `personal-anomaly` judge today's usage across the
21
+ whole environment, whatever range the page shows.
22
+ - Every rule but budget breach judges against the 30-day baseline the daemon
23
+ keeps (ADR-0093).
24
+ - The waste rules judge a run, whose sub-agents the daemon collects.
25
+
26
+ The monitor sees only the sessions in its range. `detect` sees only its
27
+ window.
28
+
29
+ ## Decision
30
+
31
+ - **The daemon is the only host that turns cost rules into findings.** It
32
+ stores them like any other finding, and they reach the session, the webhook
33
+ and Fleet from there.
34
+ - **The monitor reads cost findings from the store, read-only,** and shows
35
+ them in `alerts` in `detection_json`'s shape. The baseline snapshot behind
36
+ "your usual" is read the same way.
37
+ - **`detect` runs no cost rules in Phase 1.** `stacktrace findings` prints the
38
+ stored ones.
39
+ - The cost numbers themselves (tokens and runs) are pure functions of the
40
+ sessions, and every surface computes them the same way.
41
+ - This amends ADR-0026 clause 2 for the cost family only: **a cost finding on
42
+ the page is one the daemon stored.** For security and reliability the
43
+ clause stands.
44
+
45
+ ## Alternatives considered
46
+
47
+ - **Every surface runs the cost rules.** Rejected:
48
+ - A page showing five minutes would judge "today" from five minutes of
49
+ sessions.
50
+ - Three hosts would give three answers, and the one Slack received is the
51
+ daemon's.
52
+ - **The monitor computes its own baseline.** Rejected: it repeats a 30-day
53
+ cold pass per monitor start (ADR-0011, ADR-0037), and still differs from
54
+ what Fleet was sent.
55
+
56
+ ## Consequences
57
+
58
+ - Without a running daemon, the Cost tab shows numbers but no cost findings,
59
+ and says why.
60
+ - The monitor gains a second input, the store, opened read-only (ADR-0046).
61
+ The store's newest `seq` joins the watcher's fingerprint, so a new finding
62
+ shows without waiting for a transcript to change.
63
+ - `detect` users in CI see cost numbers nowhere until a later phase decides
64
+ otherwise.
65
+
66
+ ## When to revisit
67
+
68
+ If `detect` gains a reason to report cost findings, such as CI budget checks,
69
+ or the monitor gains a cheaper way to hold a baseline of its own.
@@ -0,0 +1,53 @@
1
+ ---
2
+ id: 0098
3
+ title: A run is its main session, and a finding about a run is filed under it
4
+ status: proposed
5
+ date: 2026-10-06
6
+ supersedes: null
7
+ superseded-by: null
8
+ amends: null
9
+ amended-by: null
10
+ ---
11
+
12
+ ## Context
13
+
14
+ Cost judges a piece of work: a main session together with its sub-agents and
15
+ workflow agents (cost-phase-1, "Measure"). Fleet must show cost findings "per
16
+ environment and run" with no wire change (ADR-0095). But neither side's
17
+ detection document has a run field, and Fleet reads a span's session from the
18
+ span itself, so a finding can cite only its own session's spans.
19
+
20
+ ## Decision
21
+
22
+ - **A run's id is its main session's id.** The parent of a sub-agent is read
23
+ from OpenAIDR's identity, `<kind>:<parent>:<file stem>` (OpenAIDR ADR-0001),
24
+ in one place: `sessions/lineage.py`.
25
+ - **A run is keyed by the pair `(agent_kind, run id)`**, like every session.
26
+ - **A finding about a run is filed under its main session.** Fleet then shows
27
+ it under that session, which is the run, with no new field.
28
+ - The run's other sessions are counted in an evidence line, not listed.
29
+ - A sub-agent's own spans are never cited, because Fleet would refuse them.
30
+ Evidence cites the main session's turns.
31
+
32
+ ## Alternatives considered
33
+
34
+ - **A `run_id` field on the detection wire.** Rejected for Phase 1 by ADR-0095.
35
+ Phase 2's usage upload is where run identity, and the list of a run's
36
+ sessions, reach Fleet.
37
+ - **File each finding under the sub-agent where the waste happened.** Rejected:
38
+ a fan-out of small sub-agents is the waste, and each looks normal alone.
39
+ - **Group resumes into a run by transcript file.** Not needed: no transcript
40
+ on the measuring machine held more than one session id. A resume that keeps
41
+ its id is already inside its session.
42
+
43
+ ## Consequences
44
+
45
+ - Fleet shows a run as its main session, plus a count of its sessions and
46
+ sub-agents.
47
+ - A sub-agent never gets a cost finding of its own.
48
+ - If a client writes a resume as a new session, it is a run of its own.
49
+
50
+ ## When to revisit
51
+
52
+ When Phase 2's usage upload carries run identity, or a client is found writing
53
+ resumes as new sessions.
@@ -0,0 +1,85 @@
1
+ ---
2
+ id: 0099
3
+ title: Cost is measured in tokens and relative increases, never in dollars
4
+ status: proposed
5
+ date: 2026-10-06
6
+ supersedes: 0094
7
+ superseded-by: null
8
+ amends: 0093
9
+ amended-by: null
10
+ ---
11
+
12
+ ## Context
13
+
14
+ ADR-0094 priced every response at list price and stated cost, floors, budgets
15
+ and severity in dollars. That needs a price table kept current for every model,
16
+ and a dollar figure invites a comparison with an invoice it never matches:
17
+ subscriptions, discounts and committed spend all differ from list price. On a
18
+ subscription, a "spend" figure is not money anyone pays.
19
+
20
+ Tokens are what the agent actually uses, and what cost follows. Measured on one
21
+ environment's 30 days (193 sessions, 3.1B tokens), 98.1% of all tokens were
22
+ cache reads, and what a token cost varied 3.6-fold from hour to hour (p10 to
23
+ p90) as the mix of token kinds moved. A raw count across people or models
24
+ tracks cost loosely. A count relative to the same developer's similar runs
25
+ (ADR-0093's cohorts) tracks it closely, because the mix of token kinds is
26
+ similar.
27
+
28
+ ## Decision
29
+
30
+ **Every cost figure is tokens, or a relative increase.** That covers evidence,
31
+ thresholds, severity, budgets, the monitor, notifications, Fleet, specs and
32
+ release notes. Nothing carries a price, a dollar amount or a currency, and
33
+ there is no price table.
34
+
35
+ - **Relative to the usual.** A finding says how far above this developer's
36
+ usual it is ("3× the usual"), and how many tokens that is ("40M more").
37
+ - **The tokens a rule is about.** A rule counts the kind of token its
38
+ behaviour wastes. `cache-collapse` counts uncached input, fresh input and
39
+ cache writes, for both its triggers: a cache that stops being reused re-sends
40
+ the same tokens uncached, and one re-written again and again writes them
41
+ afresh, while the total barely moves. The other rules count all recorded
42
+ tokens.
43
+ - **Thresholds are token amounts or ratios.** Materiality floors and budget
44
+ limits are token amounts; severity is how many times the usual a finding is
45
+ (low under 3×, medium from 3×, high from 10×). The defaults are starting
46
+ points in tokens, to be tuned against recorded sessions. No exchange rate between
47
+ tokens and money is recorded or used anywhere.
48
+ - **The family is still `cost`.** Cost is what the rules protect; tokens are
49
+ how it is measured. Rule ids stay `stacktrace-cost-*`.
50
+ - **Claude Code's own running totals** (`cost-state`) are not read at all,
51
+ neither their dollars nor their tokens. Measured on 111 sessions, their
52
+ tokens add 0.54% to what the transcripts record, and they carry no time and
53
+ arrive only after the work. Every figure comes from the transcripts' own
54
+ per-response counts.
55
+
56
+ ## Alternatives considered
57
+
58
+ - **Tokens × list price (ADR-0094).** Rejected: a table to maintain, a figure
59
+ that differs from every invoice, and a "spend" that subscription users never
60
+ pay.
61
+ - **Dollars at the org's own rates (Phase 2).** Rejected for the same reasons,
62
+ and because no org has entered rates.
63
+ - **Total tokens for every rule.** Rejected: cache reads dominate, so a cache
64
+ that stops being reused is invisible in the total.
65
+ - **Tokens weighted by kind**, such as a cache read counting a tenth. Rejected:
66
+ that is a price table by another name.
67
+
68
+ ## Consequences
69
+
70
+ - A new model works on day one: there is nothing to price and no "unpriced"
71
+ response.
72
+ - Token counts are large and less intuitive than dollars, so every figure is
73
+ paired with a ratio to the usual.
74
+ - A budget limit is a guard against runaway volume, not a spend cap: the same
75
+ token limit is different money on different models and plans.
76
+ - There is no check against the client's own figures, in dollars or tokens.
77
+ The transcripts miss about half a percent of tokens, mostly side calls on a
78
+ small model and unfinished sub-agent output; rules and baselines count the
79
+ same recorded tokens on both sides, so a comparison stays fair.
80
+
81
+ ## When to revisit
82
+
83
+ If customers ask for spend in their own currency, at their own rates, and
84
+ supply those rates, a Phase 2 view could price tokens for display only. Rules,
85
+ thresholds and evidence would stay in tokens.