stacktrace-cli 0.6.0__tar.gz → 0.6.1__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 (391) hide show
  1. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/PKG-INFO +2 -2
  2. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/README.md +1 -1
  3. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/docs/adrs/0006-trust-boundary-and-detection-upload.md +1 -1
  4. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/docs/adrs/0039-send-usage-telemetry-by-default-with-an-opt-out.md +1 -1
  5. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/docs/adrs/0067-a-webhook-is-an-independent-queue-subscriber.md +1 -1
  6. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/docs/adrs/0068-webhooks-retry-the-retained-backlog.md +1 -1
  7. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/docs/adrs/0073-name-what-fired-and-which-component.md +1 -1
  8. stacktrace_cli-0.6.1/docs/adrs/0082-monitor-checks-every-installed-component-by-default.md +72 -0
  9. stacktrace_cli-0.6.1/docs/adrs/0083-each-block-reason-is-its-own-rule.md +127 -0
  10. stacktrace_cli-0.6.1/docs/adrs/0084-a-recursive-deletes-evidence-is-the-rm-that-ran.md +85 -0
  11. stacktrace_cli-0.6.1/docs/adrs/0085-show-when-and-which-finding-slack-delivered.md +88 -0
  12. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/docs/adrs/INDEX.md +4 -0
  13. stacktrace_cli-0.6.1/docs/releases/v0.6.1.md +108 -0
  14. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/docs/specs/detection-policies.md +44 -22
  15. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/docs/specs/detection-upload.md +11 -7
  16. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/docs/specs/detector.md +35 -6
  17. stacktrace_cli-0.6.1/docs/specs/monitor-inventory.md +203 -0
  18. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/docs/specs/monitor.md +103 -5
  19. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/docs/specs/notification-delivery.md +21 -18
  20. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/pyproject.toml +1 -1
  21. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/src/stacktrace_cli/__init__.py +1 -1
  22. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/src/stacktrace_cli/cli.py +5 -0
  23. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/src/stacktrace_cli/correlate/acquire.py +60 -67
  24. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/src/stacktrace_cli/correlate/composition.py +4 -4
  25. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/src/stacktrace_cli/correlate/orchestrate.py +30 -38
  26. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/src/stacktrace_cli/daemon/identity.py +17 -1
  27. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/src/stacktrace_cli/daemon/presentation.py +6 -1
  28. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/src/stacktrace_cli/daemon/store.py +60 -15
  29. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/src/stacktrace_cli/daemon/webhook.py +34 -4
  30. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/src/stacktrace_cli/detector/blocked.py +12 -0
  31. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/src/stacktrace_cli/detector/deterministic.py +241 -172
  32. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/src/stacktrace_cli/detector/render.py +5 -5
  33. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/src/stacktrace_cli/detector/rules.py +47 -8
  34. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/src/stacktrace_cli/detector/run.py +2 -2
  35. stacktrace_cli-0.6.1/src/stacktrace_cli/monitor/inventory.py +495 -0
  36. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/src/stacktrace_cli/monitor/render.py +49 -1
  37. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/src/stacktrace_cli/monitor/server.py +40 -4
  38. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/src/stacktrace_cli/monitor/site/app.js +368 -78
  39. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/src/stacktrace_cli/monitor/site/index.html +27 -3
  40. stacktrace_cli-0.6.1/src/stacktrace_cli/monitor/site/inventory.js +554 -0
  41. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/src/stacktrace_cli/monitor/site/styles.css +139 -16
  42. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/src/stacktrace_cli/monitor/state.py +45 -2
  43. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/src/stacktrace_cli/monitor/watch.py +156 -65
  44. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/src/stacktrace_cli/remote/payload.py +10 -5
  45. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/src/stacktrace_cli/remote/redact.py +100 -2
  46. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/src/stacktrace_cli/remote/sync.py +11 -0
  47. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/src/stacktrace_cli/telemetry/events.py +12 -30
  48. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/src/stacktrace_cli/webhook/cli.py +35 -4
  49. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/tests/conftest.py +19 -0
  50. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/tests/daemon/test_cli.py +52 -13
  51. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/tests/daemon/test_runtime.py +12 -0
  52. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/tests/daemon/test_store.py +117 -7
  53. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/tests/daemon/test_the_drained_payload_is_the_cold_one.py +103 -0
  54. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/tests/daemon/test_webhook.py +99 -8
  55. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/tests/monitor/feed_harness.mjs +1048 -40
  56. stacktrace_cli-0.6.1/tests/monitor/inventory_harness.mjs +429 -0
  57. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/tests/monitor/test_feed_model.py +440 -13
  58. stacktrace_cli-0.6.1/tests/monitor/test_inventory.py +866 -0
  59. stacktrace_cli-0.6.1/tests/monitor/test_inventory_page.py +241 -0
  60. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/tests/monitor/test_render.py +49 -0
  61. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/tests/monitor/test_server.py +11 -2
  62. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/tests/monitor/test_site_assets.py +53 -23
  63. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/tests/monitor/test_state.py +37 -0
  64. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/tests/monitor/test_watch.py +441 -39
  65. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/tests/remote/test_detect_redaction.py +131 -0
  66. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/tests/remote/test_facade_contract.py +172 -1
  67. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/tests/telemetry/test_events.py +24 -34
  68. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/tests/telemetry/test_hooks.py +21 -10
  69. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/tests/test_acquire.py +94 -41
  70. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/tests/test_analysis.py +4 -4
  71. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/tests/test_correlate_orchestrate.py +49 -3
  72. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/tests/test_detection_components.py +4 -4
  73. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/tests/test_detection_event_time.py +2 -2
  74. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/tests/test_detection_subject.py +1 -1
  75. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/tests/test_detector_blocked.py +27 -0
  76. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/tests/test_detector_cache.py +6 -6
  77. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/tests/test_detector_end_to_end.py +1 -1
  78. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/tests/test_detector_finding.py +33 -7
  79. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/tests/test_detector_new_deterministic.py +359 -47
  80. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/tests/test_detector_priors.py +2 -2
  81. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/tests/test_detector_render.py +4 -4
  82. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/tests/test_detector_verdict.py +2 -2
  83. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/tests/test_detector_vulnerable_dep_invoked.py +1 -1
  84. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/tests/test_detector_why_it_stopped.py +46 -14
  85. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/tests/test_evidence_is_dated_not_numbered.py +6 -1
  86. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/tests/test_fingerprint_covers_what_the_analyzer_reads.py +1 -1
  87. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/tests/test_monitor_cli.py +1 -1
  88. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/tests/test_seam_boundary.py +3 -0
  89. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/tests/test_shell_separators_match_the_shell.py +29 -5
  90. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/tests/test_the_detector_spec_lists_the_shipped_catalogue.py +6 -1
  91. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/tests/test_title_disclosure_invariant.py +4 -4
  92. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/tests/test_untrusted_content_never_travels.py +59 -4
  93. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/tests/webhook/test_cli.py +82 -0
  94. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/uv.lock +1 -1
  95. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/.agents/skills/release-stacktrace/SKILL.md +0 -0
  96. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/.claude/settings.json +0 -0
  97. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/.claude/skills/pr-review-loop/SKILL.md +0 -0
  98. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/.claude/skills/release-stacktrace/SKILL.md +0 -0
  99. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/.codex/hooks.json +0 -0
  100. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/.github/managed-autofix.md +0 -0
  101. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/.github/workflows/autofix.yml +0 -0
  102. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/.github/workflows/ci.yml +0 -0
  103. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/.github/workflows/claude.yml +0 -0
  104. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/.github/workflows/publish-pypi.yml +0 -0
  105. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/.gitignore +0 -0
  106. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/AGENTS.md +0 -0
  107. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/CLAUDE.md +0 -0
  108. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/docs/adrs/0001-session-telemetry-as-input.md +0 -0
  109. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/docs/adrs/0002-session-collection-in-openaidr.md +0 -0
  110. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/docs/adrs/0003-runtime-edges.md +0 -0
  111. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/docs/adrs/0004-three-stage-detector.md +0 -0
  112. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/docs/adrs/0005-detection-family-and-report-assembly.md +0 -0
  113. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/docs/adrs/0007-proprietary-package-on-open-dependencies.md +0 -0
  114. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/docs/adrs/0008-console-in-separate-demo-package.md +0 -0
  115. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/docs/adrs/0010-detection-severity-and-confidence-ladders.md +0 -0
  116. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/docs/adrs/0011-verdict-cache.md +0 -0
  117. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/docs/adrs/0012-observation-evidence-kinds-and-transport.md +0 -0
  118. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/docs/adrs/0013-rule-catalogue-triage-and-per-rule-context.md +0 -0
  119. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/docs/adrs/0014-declared-project-mapping.md +0 -0
  120. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/docs/adrs/0015-narrow-the-security-catalogue.md +0 -0
  121. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/docs/adrs/0016-stall-grouping-is-session-wide.md +0 -0
  122. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/docs/adrs/0017-a-declined-repeat-is-a-stall.md +0 -0
  123. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/docs/adrs/0018-remote-sync-config-and-facade-consumption.md +0 -0
  124. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/docs/adrs/0019-delegated-commands-are-openaca-objects.md +0 -0
  125. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/docs/adrs/0020-openaca-consumption-boundary.md +0 -0
  126. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/docs/adrs/0021-two-command-kinds.md +0 -0
  127. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/docs/adrs/0022-detection-scope-is-a-catalogue-column.md +0 -0
  128. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/docs/adrs/0023-sync-detect-collects-and-does-not-escalate.md +0 -0
  129. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/docs/adrs/0024-the-upload-carries-observations.md +0 -0
  130. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/docs/adrs/0025-a-denied-call-is-activity-never-an-invocation.md +0 -0
  131. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/docs/adrs/0026-the-console-becomes-a-product-surface.md +0 -0
  132. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/docs/adrs/0027-a-finding-may-name-what-it-could-not-place.md +0 -0
  133. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/docs/adrs/0028-the-console-shows-what-it-placed.md +0 -0
  134. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/docs/adrs/0029-stage-three-returns-to-opt-in.md +0 -0
  135. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/docs/adrs/0030-a-detection-is-dated-by-the-turns-it-cites.md +0 -0
  136. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/docs/adrs/0031-one-host-daemon-observes-native-session-logs.md +0 -0
  137. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/docs/adrs/0032-refresh-daemon-compositions-outside-detection.md +0 -0
  138. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/docs/adrs/0033-a-third-party-analyzer-only-by-a-flag-that-names-it.md +0 -0
  139. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/docs/adrs/0034-the-drift-grade-is-read-off-a-run-not-a-call.md +0 -0
  140. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/docs/adrs/0035-naming-an-analyzer-selects-stored-answers.md +0 -0
  141. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/docs/adrs/0036-deliver-eligible-findings-to-slack-from-the-daemon.md +0 -0
  142. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/docs/adrs/0037-reuse-openaidr-append-cursors-in-the-daemon.md +0 -0
  143. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/docs/adrs/0038-poll-normalized-sessions-for-supplemental-changes.md +0 -0
  144. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/docs/adrs/0041-defer-native-windows-support.md +0 -0
  145. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/docs/adrs/0042-read-the-build-commit-from-the-install-record.md +0 -0
  146. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/docs/adrs/0043-name-the-session-agent-and-host-and-count-errors-by-class.md +0 -0
  147. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/docs/adrs/0044-send-the-build-as-version-prints-it.md +0 -0
  148. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/docs/adrs/0045-scan-every-session-and-outlive-them.md +0 -0
  149. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/docs/adrs/0046-the-finding-store-is-an-append-only-queue.md +0 -0
  150. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/docs/adrs/0047-capture-activity-during-correlation-or-lose-it.md +0 -0
  151. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/docs/adrs/0048-the-daemon-keeps-a-leveled-content-free-activity-log.md +0 -0
  152. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/docs/adrs/0056-stop-a-resident-daemon-by-record-and-signal.md +0 -0
  153. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/docs/adrs/0057-grow-the-queue-schema-additively-and-share-only-the-document.md +0 -0
  154. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/docs/adrs/0058-one-word-for-a-finding-columns-for-a-counter-and-a-push-that-does-not-wait.md +0 -0
  155. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/docs/adrs/0059-the-daemon-does-not-decide-whether-it-should-be-running.md +0 -0
  156. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/docs/adrs/0060-two-upload-postures-not-one-command-with-two-sources.md +0 -0
  157. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/docs/adrs/0061-the-drain-sends-findings-only.md +0 -0
  158. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/docs/adrs/0062-hold-the-transition-lock-across-remote-side-effects.md +0 -0
  159. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/docs/adrs/0063-underbuilt-debt-does-not-hold-the-scan-watermark.md +0 -0
  160. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/docs/adrs/0064-a-redacted-value-has-one-path-span.md +0 -0
  161. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/docs/adrs/0065-asset-external-id-resolves-by-a-ladder.md +0 -0
  162. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/docs/adrs/0066-host-owned-daemon-supervision.md +0 -0
  163. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/docs/adrs/0069-webhooks-deliver-what-retention-holds.md +0 -0
  164. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/docs/adrs/0070-package-the-cloud-agent-environment-bootstrap.md +0 -0
  165. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/docs/adrs/0071-render-the-allowlisted-payload-per-destination.md +0 -0
  166. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/docs/adrs/0072-host-supervisors-own-daemon-restarts.md +0 -0
  167. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/docs/adrs/0074-a-window-selects-findings-by-when-they-happened.md +0 -0
  168. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/docs/adrs/0076-two-phase-detection-pipeline.md +0 -0
  169. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/docs/adrs/0077-the-bom-job-wakes-once-at-startup-staggered.md +0 -0
  170. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/docs/adrs/0078-a-seeded-display-prefix-replaces-the-hostname-label.md +0 -0
  171. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/docs/adrs/0079-the-monitor-page-renders-findings-not-pipeline-health.md +0 -0
  172. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/docs/adrs/0080-enabling-reasoning-does-not-requeue-the-past.md +0 -0
  173. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/docs/adrs/0081-reasoning-activation-returns-to-explicit-opt-in.md +0 -0
  174. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/docs/adrs/HOOK-PROMPT.md +0 -0
  175. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/docs/adrs/TEMPLATE.md +0 -0
  176. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/docs/cutover-openaca-remote.md +0 -0
  177. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/docs/plans/002-session-input.md +0 -0
  178. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/docs/plans/003-correlation.md +0 -0
  179. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/docs/plans/004-detector.md +0 -0
  180. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/docs/plans/005-remote-sync.md +0 -0
  181. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/docs/plans/006-cli-composition.md +0 -0
  182. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/docs/plans/007-detection-upload.md +0 -0
  183. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/docs/plans/008-monitor.md +0 -0
  184. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/docs/plans/009-reasoning-jev.md +0 -0
  185. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/docs/plans/010-session-daemon.md +0 -0
  186. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/docs/plans/011-daemon-store.md +0 -0
  187. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/docs/plans/012-daemon-scanning.md +0 -0
  188. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/docs/plans/013-daemon-uploads.md +0 -0
  189. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/docs/plans/014-asset-identity.md +0 -0
  190. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/docs/releases/v0.0.1.md +0 -0
  191. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/docs/releases/v0.1.0.md +0 -0
  192. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/docs/releases/v0.2.0.md +0 -0
  193. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/docs/releases/v0.2.1.md +0 -0
  194. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/docs/releases/v0.2.2.md +0 -0
  195. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/docs/releases/v0.2.3.md +0 -0
  196. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/docs/releases/v0.3.0.md +0 -0
  197. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/docs/releases/v0.3.1.md +0 -0
  198. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/docs/releases/v0.4.0.md +0 -0
  199. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/docs/releases/v0.4.1.md +0 -0
  200. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/docs/releases/v0.5.0.md +0 -0
  201. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/docs/releases/v0.5.1.md +0 -0
  202. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/docs/releases/v0.5.2.md +0 -0
  203. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/docs/releases/v0.5.3.md +0 -0
  204. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/docs/releases/v0.6.0.md +0 -0
  205. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/docs/research/001-intent-drift-metric.md +0 -0
  206. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/docs/specs/aidr.md +0 -0
  207. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/docs/specs/cli-composition.md +0 -0
  208. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/docs/specs/correlation.md +0 -0
  209. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/docs/specs/daemon-scanning.md +0 -0
  210. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/docs/specs/daemon-store.md +0 -0
  211. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/docs/specs/daemon-uploads.md +0 -0
  212. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/docs/specs/event-time.md +0 -0
  213. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/docs/specs/reasoning-jev.md +0 -0
  214. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/docs/specs/remote-sync.md +0 -0
  215. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/docs/specs/session-input.md +0 -0
  216. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/scripts/git-hooks/pre-push +0 -0
  217. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/scripts/install-hooks.sh +0 -0
  218. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/src/stacktrace_cli/__main__.py +0 -0
  219. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/src/stacktrace_cli/analysis.py +0 -0
  220. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/src/stacktrace_cli/build.py +0 -0
  221. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/src/stacktrace_cli/cloud/__init__.py +0 -0
  222. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/src/stacktrace_cli/cloud/setup.sh +0 -0
  223. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/src/stacktrace_cli/correlate/__init__.py +0 -0
  224. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/src/stacktrace_cli/correlate/join.py +0 -0
  225. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/src/stacktrace_cli/correlate/observed.py +0 -0
  226. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/src/stacktrace_cli/correlate/project_map.py +0 -0
  227. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/src/stacktrace_cli/correlate/record.py +0 -0
  228. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/src/stacktrace_cli/correlate/render.py +0 -0
  229. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/src/stacktrace_cli/daemon/__init__.py +0 -0
  230. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/src/stacktrace_cli/daemon/activity_log.py +0 -0
  231. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/src/stacktrace_cli/daemon/bom.py +0 -0
  232. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/src/stacktrace_cli/daemon/cli.py +0 -0
  233. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/src/stacktrace_cli/daemon/client.py +0 -0
  234. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/src/stacktrace_cli/daemon/composition.py +0 -0
  235. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/src/stacktrace_cli/daemon/config.py +0 -0
  236. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/src/stacktrace_cli/daemon/db.py +0 -0
  237. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/src/stacktrace_cli/daemon/fleet.py +0 -0
  238. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/src/stacktrace_cli/daemon/jobs.py +0 -0
  239. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/src/stacktrace_cli/daemon/lifecycle.py +0 -0
  240. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/src/stacktrace_cli/daemon/observer.py +0 -0
  241. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/src/stacktrace_cli/daemon/paths.py +0 -0
  242. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/src/stacktrace_cli/daemon/protocol.py +0 -0
  243. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/src/stacktrace_cli/daemon/runtime.py +0 -0
  244. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/src/stacktrace_cli/daemon/scan.py +0 -0
  245. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/src/stacktrace_cli/daemon/server.py +0 -0
  246. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/src/stacktrace_cli/daemon/service.py +0 -0
  247. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/src/stacktrace_cli/detector/__init__.py +0 -0
  248. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/src/stacktrace_cli/detector/analyzer.py +0 -0
  249. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/src/stacktrace_cli/detector/cache.py +0 -0
  250. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/src/stacktrace_cli/detector/finding.py +0 -0
  251. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/src/stacktrace_cli/detector/history.py +0 -0
  252. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/src/stacktrace_cli/detector/jev.py +0 -0
  253. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/src/stacktrace_cli/detector/priors.py +0 -0
  254. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/src/stacktrace_cli/detector/prompts/__init__.py +0 -0
  255. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/src/stacktrace_cli/detector/prompts/jev-v1/stacktrace-deceptive-completion.json +0 -0
  256. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/src/stacktrace_cli/detector/prompts/jev-v2/stacktrace-deceptive-completion.json +0 -0
  257. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/src/stacktrace_cli/detector/prompts/v1/exclusions.md +0 -0
  258. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/src/stacktrace_cli/detector/prompts/v1/framing.md +0 -0
  259. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/src/stacktrace_cli/detector/prompts/v1/stacktrace-deceptive-completion.md +0 -0
  260. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/src/stacktrace_cli/detector/reasoning.py +0 -0
  261. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/src/stacktrace_cli/detector/secrets.py +0 -0
  262. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/src/stacktrace_cli/detector/verdict.py +0 -0
  263. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/src/stacktrace_cli/detector/windows.py +0 -0
  264. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/src/stacktrace_cli/monitor/__init__.py +0 -0
  265. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/src/stacktrace_cli/monitor/reasoning.py +0 -0
  266. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/src/stacktrace_cli/monitor/site/fonts/OFL.txt +0 -0
  267. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/src/stacktrace_cli/monitor/site/fonts/dm-mono-400-latin.woff2 +0 -0
  268. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/src/stacktrace_cli/monitor/site/fonts/dm-mono-500-latin.woff2 +0 -0
  269. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/src/stacktrace_cli/monitor/site/fonts/dm-sans-latin.woff2 +0 -0
  270. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/src/stacktrace_cli/monitor/verdicts.py +0 -0
  271. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/src/stacktrace_cli/options.py +0 -0
  272. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/src/stacktrace_cli/private_state.py +0 -0
  273. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/src/stacktrace_cli/remote/__init__.py +0 -0
  274. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/src/stacktrace_cli/remote/cli.py +0 -0
  275. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/src/stacktrace_cli/remote/client.py +0 -0
  276. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/src/stacktrace_cli/remote/config.py +0 -0
  277. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/src/stacktrace_cli/remote/detect_payload.py +0 -0
  278. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/src/stacktrace_cli/remote/identity.py +0 -0
  279. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/src/stacktrace_cli/remote/policy.py +0 -0
  280. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/src/stacktrace_cli/remote/spool.py +0 -0
  281. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/src/stacktrace_cli/remote/sync_detect.py +0 -0
  282. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/src/stacktrace_cli/remote/upload_contract.py +0 -0
  283. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/src/stacktrace_cli/sessions/__init__.py +0 -0
  284. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/src/stacktrace_cli/sessions/access.py +0 -0
  285. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/src/stacktrace_cli/sessions/index.py +0 -0
  286. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/src/stacktrace_cli/sessions/outcome.py +0 -0
  287. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/src/stacktrace_cli/sessions/protocols.py +0 -0
  288. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/src/stacktrace_cli/sessions/render.py +0 -0
  289. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/src/stacktrace_cli/telemetry/__init__.py +0 -0
  290. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/src/stacktrace_cli/telemetry/cli.py +0 -0
  291. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/src/stacktrace_cli/telemetry/posthog.py +0 -0
  292. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/src/stacktrace_cli/telemetry/state.py +0 -0
  293. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/src/stacktrace_cli/webhook/__init__.py +0 -0
  294. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/src/stacktrace_cli/webhook/config.py +0 -0
  295. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/tests/__init__.py +0 -0
  296. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/tests/agent_bom_fixture.py +0 -0
  297. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/tests/daemon/__init__.py +0 -0
  298. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/tests/daemon/test_activity_log.py +0 -0
  299. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/tests/daemon/test_client.py +0 -0
  300. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/tests/daemon/test_composition.py +0 -0
  301. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/tests/daemon/test_config.py +0 -0
  302. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/tests/daemon/test_db.py +0 -0
  303. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/tests/daemon/test_detection_needs_no_subscriber.py +0 -0
  304. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/tests/daemon/test_fleet.py +0 -0
  305. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/tests/daemon/test_identity.py +0 -0
  306. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/tests/daemon/test_jobs.py +0 -0
  307. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/tests/daemon/test_lifecycle.py +0 -0
  308. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/tests/daemon/test_observer.py +0 -0
  309. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/tests/daemon/test_queue_reader.py +0 -0
  310. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/tests/daemon/test_scan.py +0 -0
  311. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/tests/daemon/test_service.py +0 -0
  312. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/tests/daemon/test_socket.py +0 -0
  313. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/tests/daemon/test_the_stored_row_is_sufficient.py +0 -0
  314. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/tests/daemon/test_wire_frames_are_bounded.py +0 -0
  315. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/tests/detector_session_fixture.py +0 -0
  316. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/tests/monitor/__init__.py +0 -0
  317. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/tests/monitor/test_reasoning_gates.py +0 -0
  318. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/tests/monitor/test_verdicts.py +0 -0
  319. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/tests/remote/__init__.py +0 -0
  320. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/tests/remote/helpers.py +0 -0
  321. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/tests/remote/test_cli.py +0 -0
  322. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/tests/remote/test_client.py +0 -0
  323. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/tests/remote/test_config.py +0 -0
  324. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/tests/remote/test_detect_activity.py +0 -0
  325. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/tests/remote/test_detect_cli.py +0 -0
  326. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/tests/remote/test_detect_client.py +0 -0
  327. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/tests/remote/test_detect_contract_is_exhaustive.py +0 -0
  328. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/tests/remote/test_detect_gate_matches_the_cloud.py +0 -0
  329. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/tests/remote/test_detect_layers_compose.py +0 -0
  330. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/tests/remote/test_detect_payload_reaches_the_cloud_model.py +0 -0
  331. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/tests/remote/test_detect_spool.py +0 -0
  332. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/tests/remote/test_detect_upload_contract.py +0 -0
  333. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/tests/remote/test_detect_wire_payload.py +0 -0
  334. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/tests/remote/test_identity.py +0 -0
  335. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/tests/remote/test_no_local_path_survives_redaction.py +0 -0
  336. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/tests/remote/test_payload.py +0 -0
  337. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/tests/remote/test_policy.py +0 -0
  338. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/tests/remote/test_redact_payload.py +0 -0
  339. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/tests/remote/test_seam.py +0 -0
  340. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/tests/remote/test_spool.py +0 -0
  341. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/tests/remote/test_sync.py +0 -0
  342. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/tests/remote/test_sync_detect.py +0 -0
  343. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/tests/remote/test_upload_contract.py +0 -0
  344. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/tests/telemetry/__init__.py +0 -0
  345. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/tests/telemetry/test_activity_log.py +0 -0
  346. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/tests/telemetry/test_cli.py +0 -0
  347. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/tests/telemetry/test_release_gate.py +0 -0
  348. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/tests/telemetry/test_state.py +0 -0
  349. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/tests/telemetry/test_uploader.py +0 -0
  350. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/tests/test_adr_cross_references_are_reciprocal.py +0 -0
  351. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/tests/test_agent_instance_id.py +0 -0
  352. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/tests/test_bom_shape.py +0 -0
  353. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/tests/test_build_commit.py +0 -0
  354. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/tests/test_call_status_conventions.py +0 -0
  355. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/tests/test_cli.py +0 -0
  356. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/tests/test_composition.py +0 -0
  357. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/tests/test_correlate_render.py +0 -0
  358. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/tests/test_correlated_session.py +0 -0
  359. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/tests/test_detector_analyzer_contract.py +0 -0
  360. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/tests/test_detector_analyzer_live.py +0 -0
  361. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/tests/test_detector_deterministic.py +0 -0
  362. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/tests/test_detector_history.py +0 -0
  363. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/tests/test_detector_jev.py +0 -0
  364. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/tests/test_detector_prompts.py +0 -0
  365. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/tests/test_detector_reasoning.py +0 -0
  366. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/tests/test_detector_run.py +0 -0
  367. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/tests/test_detector_secrets.py +0 -0
  368. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/tests/test_detector_windows.py +0 -0
  369. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/tests/test_help_sections.py +0 -0
  370. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/tests/test_join.py +0 -0
  371. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/tests/test_no_live_document_states_the_old_stage_three_default.py +0 -0
  372. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/tests/test_no_test_undoes_every_patch_at_once.py +0 -0
  373. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/tests/test_observed.py +0 -0
  374. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/tests/test_openaca_contract.py +0 -0
  375. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/tests/test_openaidr_contract.py +0 -0
  376. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/tests/test_option_arity_matches_the_binary.py +0 -0
  377. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/tests/test_project_map.py +0 -0
  378. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/tests/test_readme_examples_are_real_output.py +0 -0
  379. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/tests/test_release_gate_coverage.py +0 -0
  380. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/tests/test_release_readiness.py +0 -0
  381. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/tests/test_session_identity_is_the_pair.py +0 -0
  382. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/tests/test_sessions_access.py +0 -0
  383. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/tests/test_sessions_end_to_end.py +0 -0
  384. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/tests/test_sessions_protocol_typing.py +0 -0
  385. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/tests/test_sessions_protocols.py +0 -0
  386. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/tests/test_sessions_render.py +0 -0
  387. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/tests/test_stored_verdicts_are_never_gated_on_reasoning.py +0 -0
  388. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/tests/test_the_jev_spec_states_the_shipped_thresholds.py +0 -0
  389. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/tests/test_the_locality_claim_is_qualified_everywhere.py +0 -0
  390. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/tests/test_verification_subcommands_match_the_binary.py +0 -0
  391. {stacktrace_cli-0.6.0 → stacktrace_cli-0.6.1}/tests/test_what_jev_is_told_is_what_was_disclosed.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: stacktrace-cli
3
- Version: 0.6.0
3
+ Version: 0.6.1
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.6.0 (openaca 0.7.0)
54
+ stacktrace 0.6.1 (openaca 0.7.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.6.0 (openaca 0.7.0)
27
+ stacktrace 0.6.1 (openaca 0.7.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
8
+ amended-by: 0011, 0027, 0031, 0039, 0064, 0084
9
9
  ---
10
10
 
11
11
  ## Context
@@ -6,7 +6,7 @@ date: 2026-09-21
6
6
  supersedes: null
7
7
  superseded-by: null
8
8
  amends: 0006, 0031
9
- amended-by: 0043, 0044
9
+ amended-by: 0043, 0044, 0083
10
10
  ---
11
11
 
12
12
  ## Context
@@ -6,7 +6,7 @@ date: 2026-09-24
6
6
  supersedes: null
7
7
  superseded-by: null
8
8
  amends: 0036, 0046
9
- amended-by: 0068, 0071, 0073
9
+ amended-by: 0068, 0071, 0073, 0085
10
10
  ---
11
11
 
12
12
  ## Context
@@ -6,7 +6,7 @@ date: 2026-09-25
6
6
  supersedes: null
7
7
  superseded-by: null
8
8
  amends: 0067
9
- amended-by: 0069
9
+ amended-by: 0069, 0085
10
10
  ---
11
11
 
12
12
  ## Context
@@ -6,7 +6,7 @@ date: 2026-09-26
6
6
  supersedes: null
7
7
  superseded-by: null
8
8
  amends: 0067, 0071
9
- amended-by: null
9
+ amended-by: 0084, 0085
10
10
  ---
11
11
 
12
12
  ## Context
@@ -0,0 +1,72 @@
1
+ ---
2
+ id: 0082
3
+ title: Monitor's static tabs check every installed component by default
4
+ status: accepted
5
+ date: 2026-09-30
6
+ supersedes: null
7
+ superseded-by: null
8
+ amends: null
9
+ amended-by: null
10
+ ---
11
+
12
+ ## Context
13
+
14
+ `correlate/orchestrate.py`'s `advisories_for` deliberately narrows advisory
15
+ lookups to the union of what a session actually invoked. Its own docstring
16
+ names this as a decision, not an accident of the optimization it also
17
+ describes: asking during acquisition would send every component on the
18
+ machine to osv.dev once per composition built, so it is asked after
19
+ correlation instead — "osv.dev learns only about components this machine
20
+ actually used."
21
+
22
+ `docs/specs/monitor-inventory.md` adds two tabs, Inventory and Vulnerabilities,
23
+ whose whole purpose is the opposite question: not what the agents did, but
24
+ what they *can* load and what is known to be wrong with it. Answering that
25
+ means checking every installed component, invoked or not, which reverses the
26
+ invoked-only default for this one surface. A future reader who finds
27
+ `advisories_for`'s comment and then finds `monitor` disclosing the full
28
+ install list would reasonably read that as a regression rather than a second,
29
+ deliberately different, disclosure boundary — the two call sites don't share
30
+ a docstring, and the reason the newer one is broader isn't visible from
31
+ either alone.
32
+
33
+ ## Decision
34
+
35
+ `stacktrace monitor`'s Inventory and Vulnerabilities tabs send the package names
36
+ of every *installed* component to osv.dev by default, independent of the
37
+ invoked-only lookup that Live and `detect` keep using. This is not a new
38
+ disclosure boundary: it is the same set `stacktrace scan endpoint` and Fleet's
39
+ composition upload already send, so the static tabs are catching up to a
40
+ boundary this package has already crossed elsewhere, not opening a new one.
41
+ `monitor --help` and its startup line say so, because widening what leaves
42
+ the machine is not something to do quietly. `detect` and the Live tab are
43
+ unchanged and continue to ask only about what a session invoked.
44
+
45
+ ## Alternatives considered
46
+
47
+ - **Invoked-only, matching Live** — rejected: it would leave every component
48
+ a session never happened to call unchecked, which defeats the tabs' stated
49
+ purpose (what the agent *can* load) in favor of what Live already shows
50
+ (what it did load).
51
+ - **Gate the wider scan behind a flag** — rejected: the tabs are
52
+ materially incomplete without it, so the flag would be mandatory in
53
+ practice for anyone actually using the feature — a step with no real
54
+ choice behind it.
55
+
56
+ ## Consequences
57
+
58
+ Every installed component that has a package name (an npm or PyPI MCP server,
59
+ a package) is named to osv.dev once per `monitor` run, not only the ones a
60
+ session reached. Skills and plugins with no package are never sent. This is a
61
+ strictly larger disclosure than Live's, in the same process. The cost is
62
+ proportional to install count rather than invocation count; this is accepted
63
+ because `scan endpoint` already pays it per sync. `detect`'s narrower,
64
+ invoked-only default is untouched and remains the answer for anyone who wants
65
+ the tighter boundary.
66
+
67
+ ## When to revisit
68
+
69
+ If install-count growth measurably slows the tabs' first paint (the spec's
70
+ "summarise before listing" goal assumes the summary doesn't lag), or if
71
+ someone asks for the invoked-only boundary on these tabs too — add a flag
72
+ rather than reverting the default silently.
@@ -0,0 +1,127 @@
1
+ ---
2
+ id: 0083
3
+ title: Each block reason is its own rule
4
+ status: accepted
5
+ date: 2026-09-30
6
+ supersedes: null
7
+ superseded-by: null
8
+ amends: 0039
9
+ amended-by: null
10
+ ---
11
+
12
+ ## Context
13
+
14
+ `stacktrace-agent-blocked` emitted one finding per block reason in
15
+ `detector/blocked.py` — `quota_exhausted`, `policy_blocked`,
16
+ `provider_throttled`, `upstream_refused` — and carried the reason only as the
17
+ anchor evidence's `kind`. Title, label, severity and remedy were all chosen per
18
+ reason, so the finding a reader got locally was specific.
19
+
20
+ Everything that keys on the rule id alone was not:
21
+
22
+ - **Fleet.** Its catalogue is seeded per rule id and never uploaded (Cloud
23
+ ADR-0027, ADR-0029), so every block in the console read "The agent was
24
+ blocked while working" with one remediation. Findings roll up by rule, so a
25
+ spend limit, a safety block, a throttle and a service refusal were one row.
26
+ Slack takes its title from the same catalogue.
27
+ - **Local notifications.** Prose is selected by rule id only (ADR-0031), so
28
+ every block notified as "The agent encountered a block while working".
29
+ - **Special cases.** `daemon/presentation.py` and the daemon's delivery
30
+ properties each read `evidence[0].kind` for this one rule, and telemetry grew
31
+ a `reason` property scoped to it (ADR-0039) with its own pairing table.
32
+
33
+ The four are not one finding with four wordings. Each has a different person
34
+ who acts and a different action: the account owner raises a limit or waits; the
35
+ person running the session starts a fresh one or leaves auto mode; nobody, at
36
+ first, for a throttle that clears by itself; whoever owns the service's
37
+ credentials grants a permission. They were already graded differently. ADR-0017
38
+ declined a second rule id for a declined stall because "the question a reader
39
+ asks is identical in both cases". Here it is not.
40
+
41
+ ## Decision
42
+
43
+ **Each block reason is its own rule.** `stacktrace-blocked-quota`,
44
+ `stacktrace-blocked-policy`, `stacktrace-blocked-throttled` and
45
+ `stacktrace-blocked-upstream` are reliability rules, and each `Reason` names
46
+ its `rule_id`. Detection is unchanged: one pass reads the session, groups by
47
+ reason, and files each group under that reason's rule. The reason code stays
48
+ the evidence `kind`.
49
+
50
+ **Each is `session`-scoped.** It fires at most once per session, which is the
51
+ cardinality ADR-0022 gives `session`. `agent-blocked` was `call` only because
52
+ it fired once per reason; the new ids have no stored identity to keep stable.
53
+
54
+ **`stacktrace-agent-blocked` is retired, not erased.** It leaves `RULE_IDS`, so
55
+ nothing can emit it, and stays in `rules.RETIRED_SCOPES` with its `call` scope,
56
+ because a finding the daemon stored before an upgrade still names it and the
57
+ Fleet drain asks for its scope on every row it sends. Raising there would fail
58
+ the drain on every tick for as long as the row was queued. The local findings
59
+ view reads such a row by its retained reason code, and telemetry still admits
60
+ the id.
61
+
62
+ **A block already notified does not ring again under its new rule.** The
63
+ daemon's transcript fingerprints live in memory, so the restart an upgrade
64
+ brings re-reads every live session, and each block it rang as `agent-blocked`
65
+ comes back with a new event id. `rules.SUCCEEDS` names the rule each new one
66
+ took over from, and the store rebuilds the old id from the same anchor:
67
+ `agent-blocked` was call-scoped on the first blocked call, which its successor
68
+ still cites first. The new finding is still stored and uploaded.
69
+
70
+ **Telemetry drops `reason`.** This amends ADR-0039's `finding_delivered` row,
71
+ "optional reason code": the rule now says which reason it was, and a second
72
+ property saying it again could only ever disagree.
73
+
74
+ **Fleet learns the reasons by seeding four catalogue rows**, and keeps the
75
+ `agent-blocked` row for findings already ingested and CLIs not yet upgraded.
76
+
77
+ ## Alternatives considered
78
+
79
+ - **Teach Fleet the reason code instead.** A reason column on detections,
80
+ grouping and filtering by `(rule_id, reason)`, a per-reason title table.
81
+ Rejected: it adds a second key to ingest, schema, roll-up, filters, counts,
82
+ the console and Slack, and every consumer written later has to learn the same
83
+ special case. Splitting the id makes the reason a fact every rule-keyed
84
+ consumer already reads.
85
+ - **Upload the per-reason title and remediation on the finding.** Rejected by
86
+ `docs/specs/detection-upload.md`: catalogue text is Cloud-derived so that two
87
+ copies cannot drift (ADR-0024).
88
+ - **Keep `call` scope.** Rejected: it contradicts ADR-0022's cardinality rule,
89
+ and since the ids are new there is no identity in Fleet or the daemon ledger
90
+ to preserve.
91
+ - **Keep `reason` in telemetry on the new rules.** Would keep a
92
+ group-by-reason insight working across versions. Rejected: it duplicates
93
+ `rule`, and keeping it honest needs a per-rule value check — the "a reason on
94
+ the wrong rule is a lie" argument ADR-0039's pairing table already made.
95
+ - **Rewrite stored `agent-blocked` rows to the new ids at upload.** Rejected: it
96
+ changes what was recorded, puts evidence parsing on the upload path, and Fleet
97
+ already holds rows under the old id that it would not match.
98
+ - **Name the rules after the codes** (`stacktrace-quota-exhausted`, …).
99
+ Rejected: a shared `blocked-` prefix keeps them together in sorted lists and
100
+ lets a prefix filter recover "every block" without a family column.
101
+
102
+ ## Consequences
103
+
104
+ The catalogue grows from 10 rules to 13 (8 security, 5 reliability). This is
105
+ not new coverage — the same pass finds the same blocks — so ADR-0015's case
106
+ for a narrow catalogue is not reopened.
107
+
108
+ Adding a block reason now means adding a rule: a `rules.py` entry with scope
109
+ and stage, a `Reason.rule_id`, and a Fleet seed migration. That is the cost, and
110
+ it is also the point: Fleet has to learn a new reason either way, and this
111
+ makes forgetting visible as a bare rule id in the console (ADR-0029).
112
+
113
+ During the transition, Fleet can hold both an `agent-blocked` row and a
114
+ `blocked-*` row for the same block: the restarted daemon re-reads recent
115
+ sessions and uploads each block again under its new rule, and an old and a new
116
+ CLI can both analyse one session. The two rows do not merge. Laptops on older versions keep sending `agent-blocked`, with `reason`
117
+ on `finding_delivered`, until they upgrade. A PostHog breakdown by `reason`
118
+ covers only those versions; newer ones answer by `rule`.
119
+
120
+ Notifications now name the reason, with the title `blocked.py` writes for it.
121
+
122
+ ## When to revisit
123
+
124
+ If block reasons grow past a handful and the per-rule catalogue churn becomes
125
+ the larger cost, or if a consumer needs "every block" as a unit a prefix cannot
126
+ give — a family below `reliability`, say — then a catalogue column for it is
127
+ the next step, not a return to one rule.
@@ -0,0 +1,85 @@
1
+ ---
2
+ id: 0084
3
+ title: A recursive delete's evidence names what it deleted
4
+ status: accepted
5
+ date: 2026-09-30
6
+ supersedes: null
7
+ superseded-by: null
8
+ amends: 0006, 0073
9
+ amended-by: null
10
+ ---
11
+
12
+ ## Context
13
+
14
+ `stacktrace-destructive-action` reached Fleet's Slack as *Subject: Bash (tool)
15
+ (built-in) · Evidence: recursive_delete*. On the machine this was written
16
+ against it fired four times in sixteen minutes, and every one was an agent
17
+ deleting its own test output in a sibling project after a `cd` out of the
18
+ session's starting directory. None of the four could be dismissed from the
19
+ alert, because nothing in it said what was deleted.
20
+
21
+ That is the condition ADR-0006 wrote for its own revision: a detection type
22
+ genuinely unactionable without an evidence excerpt. ADR-0027 met it once, for
23
+ one field.
24
+
25
+ ## Decision
26
+
27
+ **A `stacktrace-destructive-action` citation's `kind` is `rm -rf` and the
28
+ paths it deleted outside the workspace.**
29
+ This narrows ADR-0006 constraint 3 for that one field on that one rule, and
30
+ for that rule replaces ADR-0073's premise that a kind is a classifier: the
31
+ daemon webhook, which maps `evidence_kinds`, carries the command too.
32
+
33
+ 1. **No new field.** Fleet already stores `kind` and shows it as the alert's
34
+ *Evidence*, so the device and Fleet keep one schema.
35
+ 2. **`rm -rf` and the escaped paths, and nothing else.** Each path as it
36
+ resolved, listed once and whole. A path that does not fit under 500
37
+ characters is counted (`… and 3 more`), never cut. Wrappers, flags,
38
+ operands that stayed inside the workspace and the rest of the tool call are
39
+ left out.
40
+ 3. **The existing redactor applies, word by word.** `kind` is cleaned one shell
41
+ word at a time, so each path is redacted on its own: relative to `$HOME` or
42
+ a working directory where it sits under one, its last component otherwise.
43
+ Credential tokens are dropped. An absolute path still never leaves.
44
+ 4. **The display is best-effort, and this is its whole scope.** When the rule
45
+ fires is the resolver's existing behaviour. Its one change here carries
46
+ `sudo -R`'s root into a nested shell and prefixes it onto an absolute
47
+ operand, so the scratch exemption cannot hide `/tmp/x` under a chroot. A
48
+ relative operand under `sudo -R` resolves as on the host: a known gap, kept
49
+ because translating `cd` and `-D` through a chroot took four review rounds
50
+ and each fix found a narrower case. The evidence
51
+ reproduces no shell syntax, so a case it shows imperfectly is a cosmetic
52
+ gap, not a parser to extend. The upload contract still checks the redacted
53
+ `kind` for rooted paths and credentials, so a display flaw is refused at
54
+ the send, never leaked.
55
+
56
+ ## Alternatives considered
57
+
58
+ - **New evidence fields** (`deleted_paths`, `delete_commands`). Built and
59
+ dropped. They changed the schema between the device and Fleet, needed a
60
+ Fleet migration, and Fleet refuses keys it does not declare, so a CLI that
61
+ shipped first would have lost every run holding one.
62
+ - **The command as the subject.** Rejected. Fleet groups findings by subject,
63
+ so every distinct command would become its own row instead of one *Bash*.
64
+ - **`detail`.** Rejected. Fleet's Slack alert does not show it.
65
+ - **The command as typed, operands resolved in place.** Built first, then
66
+ dropped. Reproducing wrappers, flags, `env -S`, quoting and several `rm`s in
67
+ one call was a shell parser of its own: every review finding on it after
68
+ the first was about that reproduction, and none about what was deleted.
69
+
70
+ ## Consequences
71
+
72
+ Folder names, relative to the home directory, reach Fleet and every Slack
73
+ workspace it posts to. That exposure is accepted for this rule because a delete
74
+ cannot be triaged without it. A path outside `$HOME` and the working
75
+ directories shows only its last component (ADR-0064), so `rm -rf /etc/important`
76
+ reads `rm -rf important`; its `high` severity is what says it was a system
77
+ delete. Fleet's alert cuts a kind at 200 characters and strips `*` and `~`.
78
+ `tests/test_untrusted_content_never_travels.py` states the exemption beside the
79
+ invariant it narrows.
80
+
81
+ ## When to revisit
82
+
83
+ If a second rule asks to carry an excerpt, it needs its own ADR. If a customer
84
+ objects to folder names in Fleet, the answer is an org-level switch, not a
85
+ wider redactor.
@@ -0,0 +1,88 @@
1
+ ---
2
+ id: 0085
3
+ title: Show when and which finding Slack delivered
4
+ status: proposed
5
+ date: 2026-09-26
6
+ supersedes: null
7
+ superseded-by: null
8
+ amends: 0067, 0068, 0073
9
+ amended-by: null
10
+ ---
11
+
12
+ ## Context
13
+
14
+ The first Slack webhook configured on a host delivers every eligible finding
15
+ still inside local retention (ADR-0068). A host with a retained backlog can
16
+ therefore receive many messages at once. The Slack rendering did not show the
17
+ finding's stable event ID or when Stacktrace recorded its notifiable revision,
18
+ so a reader could not distinguish old backlog from new findings or name the
19
+ exact finding when investigating it.
20
+
21
+ The timestamp Slack adds to a posted message is delivery time. It cannot answer
22
+ that question: a retained finding posted today looks new even when Stacktrace
23
+ recorded it days earlier. ADR-0030's occurrence range answers a different
24
+ question -- when the cited session turns occurred -- and may span multiple
25
+ turns.
26
+
27
+ Configuration also stated only that retained history would be sent. It gave no
28
+ size before the write authorized delivery and woke the daemon.
29
+
30
+ ## Decision
31
+
32
+ `detected_at` joins the webhook's allowlisted projection for every format. It is
33
+ the queue row's `created_at`: the instant Stacktrace recorded the first revision
34
+ that crossed the notification gate. It is neither the cited-turn occurrence
35
+ range nor the later webhook delivery time. The payload remains version 1 because
36
+ the field is additive.
37
+
38
+ The Slack rendering shows `detected_at` with Slack's native date syntax, so each
39
+ viewer sees it in their own locale and timezone, and includes the stable event
40
+ ID under the label `finding ID`. The same event ID remains in
41
+ `X-Stacktrace-Event-ID` for receiver idempotency. A timestamp that cannot be
42
+ parsed as an offset-aware ISO 8601 value is omitted from the Slack presentation
43
+ rather than holding the delivery cursor forever; the finding ID still renders.
44
+
45
+ Before writing configuration, `stacktrace webhook configure` reads the webhook
46
+ subscriber's durable high-water mark and reports the exact number of retained,
47
+ notifiable revisions currently above it. It does not count unknowns, ineligible
48
+ findings, later revisions of an already-notified finding, or rows the subscriber
49
+ already passed. A missing database reports zero. An unreadable database reports
50
+ that the preview is unavailable but does not prevent configuration.
51
+
52
+ The count is an informational snapshot. It is not a confirmation prompt, a
53
+ configuration-time cutoff or a new acknowledgement: concurrent recording and
54
+ delivery may change the backlog immediately afterward, and ADR-0068's retained
55
+ history semantics remain in force.
56
+
57
+ ## Alternatives considered
58
+
59
+ - **Rely on Slack's message timestamp**: rejected because it is the delivery
60
+ time and makes an old retained finding look newly generated.
61
+ - **Render `occurred_start` or `occurred_end`**: rejected because those date the
62
+ cited session evidence, not the finding's creation, and a finding can cite a
63
+ range rather than one instant.
64
+ - **Keep the event ID only in the HTTP header**: rejected because headers help
65
+ automated receivers deduplicate but are invisible to the person investigating
66
+ a Slack alert.
67
+ - **Ask for confirmation or default to new findings only when backlog exists**:
68
+ rejected because that silently changes ADR-0068's reliable retained-history
69
+ contract. The count supplies informed context without creating a second
70
+ delivery policy.
71
+
72
+ ## Consequences
73
+
74
+ Backlog deliveries identify themselves as older findings, and operators can
75
+ copy one stable ID into a discussion or lookup. Generic webhook consumers gain
76
+ one additive field. Slack receives one more timestamp and the already-disclosed
77
+ event ID in its message body.
78
+
79
+ The configure count can be stale as soon as it is printed, and an unreadable
80
+ database cannot provide it. Both conditions are stated rather than disguised as
81
+ an exact authorization boundary.
82
+
83
+ ## When to revisit
84
+
85
+ Revisit the label if the product introduces a separately persisted finding
86
+ generation instant distinct from queue insertion. Revisit the preview if
87
+ configuration gains an explicit backlog policy; until then it must remain a
88
+ snapshot of the one retained-history policy, not a policy of its own.
@@ -110,3 +110,7 @@ supersedes anything yet.
110
110
  - [0079](0079-the-monitor-page-renders-findings-not-pipeline-health.md) — **The monitor page renders findings, not pipeline health.** `app.js` stops drawing `banners` (collection failures, unplaceable sessions, suppressed-reasoning counts) — an operator reading the page wants to know what their agent did wrong, not why a transcript reader choked on a broken symlink, and unlike a finding there was nothing on the page to act on from one. The backend is unchanged: `render.py`'s `_banners()` still computes them and `/api/state`'s JSON still carries them, so a script, `curl`, or support still sees exactly what they saw before; `stacktrace sessions` still prints the full local detail. `#banners` (the DOM element) stays — `showConnectionLost` still uses it for a different claim, that the page itself cannot currently say anything. Read before reintroducing a page-rendered pipeline-health banner, or before assuming the page and the JSON show the same things.
111
111
  - [0080](0080-enabling-reasoning-does-not-requeue-the-past.md) — **Enabling reasoning does not retroactively requeue sessions skipped while it was off.** ADR-0081 made reasoning off the daemon's default, so `reasoning_not_requested` (previously rare) is now the routine outcome for a gate-tripping session scanned while the switch is off — and unlike `budget_exhausted`, it carries no `_underbuilt` retry marker, so the watermark advances and that session is done for good unless its transcript changes again. Deliberately not fixed by mirroring `budget_exhausted`: with reasoning off by default, that would retry every such session on every tick forever. Turning reasoning on starts coverage from that point forward; catching up on the past is left to an explicit `detect --reasoning`/`sync detect` re-run. Read before adding retry logic for a skipped-reasoning session, or before assuming enabling reasoning is retroactive.
112
112
  - [0081](0081-reasoning-activation-returns-to-explicit-opt-in.md) — **Reasoning activation returns to explicit opt-in.** Amends ADR-0076's "conditional reasoning activation" clause only — the phase collapse, rule placement and async executor it introduced are unchanged. `TYPESAFE_API_KEY` presence stopped being sufficient consent on its own: it was already insufficient on `detect`, `monitor` and `sync detect` (ADR-0033), and only the daemon had drifted to key-alone activation, reopening the exact divergence ADR-0029 fixed once. The daemon gains `--reasoning/--no-reasoning` on both `run` and `start`, and `STACKTRACE_REASONING` in `DaemonConfig`, defaulting to off through the same flag-beats-environment-beats-default ladder every other daemon setting uses. `daemon start`'s key prompt now runs only behind an explicit `--reasoning`, and `cloud/setup.sh` passes `--no-reasoning` to `daemon run` explicitly rather than trusting an inherited default. Read before assuming a key alone turns reasoning on anywhere, or before adding a reasoning-activation path that bypasses `DaemonConfig`.
113
+ - [0082](0082-monitor-checks-every-installed-component-by-default.md) — **Monitor's static tabs check every installed component by default.** `correlate/orchestrate.py`'s `advisories_for` deliberately narrows osv.dev lookups to what a session actually invoked; `monitor`'s new Inventory and Vulnerabilities tabs (`docs/specs/monitor-inventory.md`) ask a different question — what the agent *can* load — so they send every installed component's package name by default, independent of that invoked-only lookup. Not a new disclosure boundary: the same set `scan endpoint` and Fleet's composition upload already send. `detect` and Live are unchanged. Read before touching `advisories_for`'s scope, before assuming monitor and detect share one disclosure boundary, or before widening what osv.dev sees from a third call site.
114
+ - [0083](0083-each-block-reason-is-its-own-rule.md) — **Each block reason is its own rule.** `stacktrace-agent-blocked` filed four reasons under one id, so everything keyed on the rule id alone — Fleet's seeded catalogue and roll-up, Slack, local notifications — read a spend limit, a safety block, a throttle and a service refusal as one finding. Now `stacktrace-blocked-quota`, `-policy`, `-throttled` and `-upstream`, each named by its `Reason`, each `session`-scoped by ADR-0022 cardinality. `agent-blocked` is retired to `rules.RETIRED_SCOPES` so stored rows still upload. Amends ADR-0039: `finding_delivered` no longer carries `reason`. Read before adding a block reason, before teaching Fleet a sub-rule key, or before putting a second property beside `rule` on a telemetry event.
115
+ - [0084](0084-a-recursive-deletes-evidence-is-the-rm-that-ran.md) — **A recursive delete's evidence names what it deleted.** Amends ADR-0006 constraint 3 and ADR-0073's kind-is-a-classifier rule, for `stacktrace-destructive-action` only. Its evidence `kind` is `rm -rf` and the paths that escaped the workspace, whole, listed once, counted past 500 characters; never wrappers, flags or the rest of the call, because an alert saying only `recursive_delete` cannot be triaged and a reproduced command is a parser of its own. No new field: Fleet already stores and shows `kind`, so device and Fleet keep one schema. The redactor cleans `kind` word by word and drops credentials; the upload contract still checks it, so a display flaw is refused, never leaked. Read before putting session text in any other field or rule, or before making the display reproduce more of the command.
116
+ - [0085](0085-show-when-and-which-finding-slack-delivered.md) — **Show when and which finding Slack delivered.** Amends ADR-0067, ADR-0068 and ADR-0073: `detected_at` is the first notifiable revision's queue creation time, Slack renders it in the viewer's locale beside the visible stable finding ID, and `webhook configure` previews the exact currently pending eligible count before enabling. The count is a snapshot, not a cutoff or confirmation policy; retained-history and at-least-once delivery semantics do not change. Read before redefining `detected_at`, hiding the ID again, or turning the preview into a second backlog policy.
@@ -0,0 +1,108 @@
1
+ # 0.6.1 — Inventory, and why an agent stopped
2
+
3
+ 0.6.0 told you what the agents on this machine did. This release adds what
4
+ they can load, and says why an agent stopped instead of only that it did.
5
+
6
+ The monitor gains Inventory and Vulnerabilities tabs. A blocked agent is now
7
+ one of four findings — a spend limit, a safety check, a rate limit, or a
8
+ service refusing it — each with its own title, fix and Fleet row. A
9
+ destructive-action finding names the `rm` that ran.
10
+
11
+ ## The monitor shows what your agents can load
12
+
13
+ Two new tabs, **Inventory** and **Vulnerabilities**, list every component the
14
+ agents on this machine can load: MCP servers, plugins, skills, hooks, commands,
15
+ subagents and packages. The list comes from the same collection the BOM upload uses, so
16
+ the monitor and Fleet agree on what is installed. Each component reads one of
17
+ four answers about known vulnerabilities: found, none found, not checked, or no
18
+ package to check.
19
+
20
+ To check them, the monitor sends the package names of installed components to
21
+ osv.dev. That is the set `stacktrace scan endpoint` and the Fleet upload already
22
+ send; the startup line and `monitor --help` say so (ADR-0082). `detect` and the
23
+ Live tab still ask only about what a session invoked.
24
+
25
+ ## Four rules for why an agent stopped
26
+
27
+ `stacktrace-agent-blocked` filed every block under one rule and kept the reason
28
+ inside its evidence, so anything that reads only the rule id — Fleet's titles
29
+ and grouping, Slack, notifications — saw a spend limit and a service refusal as
30
+ the same finding. Each reason is now its own rule (ADR-0083):
31
+
32
+ | Rule | Severity | Fires when |
33
+ | --- | --- | --- |
34
+ | `stacktrace-blocked-quota` | High | The account's spend limit stopped model calls |
35
+ | `stacktrace-blocked-policy` | High | A safety check refused the action for the rest of the session |
36
+ | `stacktrace-blocked-throttled` | Medium | Requests were rate-limited |
37
+ | `stacktrace-blocked-upstream` | Medium | A service refused the request |
38
+
39
+ Detection is unchanged; each block is filed under its reason's rule, once per
40
+ session. Notifications now say which reason it was. A block already notified
41
+ under the old rule before you upgrade does not notify again.
42
+
43
+ ## A destructive-action finding names the rm
44
+
45
+ A `stacktrace-destructive-action` alert read "Evidence: recursive_delete",
46
+ which said nothing about what was deleted. Its evidence is now `rm -rf` and the
47
+ paths it deleted outside the workspace. Paths under your home folder travel
48
+ home-relative, credentials are dropped, and an absolute path still never leaves
49
+ the machine (ADR-0084).
50
+
51
+ Severity now follows where the delete landed: high for system folders, a home
52
+ folder, or a folder that contains the workspace; medium within two levels of
53
+ the workspace; low deeper than that. Deletes under the temp directories are no
54
+ longer findings. `sudo -R`'s root is now followed into a nested shell, and
55
+ `env -S`'s split string is expanded before the target is read.
56
+
57
+ ## The monitor says what it is checking
58
+
59
+ - **The Findings column opens with the checks a pass runs.** A line reads
60
+ "Checking 106 sessions for security and reliability issues…" with a progress
61
+ bar, and each check shows "2 found" the moment it finds something. A clean
62
+ window reads "All clear" with every check ticked. A window with findings folds
63
+ the list so the findings lead, and **What we check** opens it again.
64
+ - **A range switch answers the click.** It used to change nothing on screen
65
+ until the new window had been read, 4 to 10 seconds on a real machine. A
66
+ retry click on a failed range now reaches the server, and a monitor restart
67
+ no longer confuses the page about which answer is its own.
68
+ - **Bug fixes.** The page keeps its token when the logo link drops it, a
69
+ completed window with no sessions no longer reads "All clear", and findings
70
+ cards drop the stage tag.
71
+
72
+ ## Daemon and Slack
73
+
74
+ - **Slack shows when a finding was detected, and its finding ID.** The webhook
75
+ payload gains `detected_at`, the moment Stacktrace first recorded the finding
76
+ (ADR-0085).
77
+ - **`webhook configure`'s backlog preview counts only what will be delivered.**
78
+ It promised findings that the next start was about to prune.
79
+
80
+ ## Install
81
+
82
+ `uv tool install stacktrace-cli==0.6.1` or `pip install stacktrace-cli==0.6.1`.
83
+ Python 3.11 or newer; macOS and Linux.
84
+
85
+ ## Compatibility
86
+
87
+ Beta — no back-compat hedging.
88
+
89
+ - **`stacktrace-agent-blocked` is no longer emitted.** Anything filtering on it
90
+ — saved Fleet filters, webhook receivers — needs the four
91
+ `stacktrace-blocked-*` ids. The new rules are session-scoped; the old one was
92
+ call-scoped. Findings stored before the upgrade still upload under the old id,
93
+ and Fleet keeps showing rows it already ingested.
94
+ - **Fleet titles for the new rules come from Fleet's own catalogue.** Until
95
+ that is deployed, they show as bare ids such as "Blocked quota".
96
+ - **Fleet can show a block twice, once.** After the upgrade the daemon re-reads
97
+ recent sessions and uploads each block under its new rule beside the old
98
+ `agent-blocked` row. The two do not merge.
99
+ - **Usage telemetry's `finding_delivered` no longer carries `reason`.** The
100
+ rule says which reason it was; a breakdown by `reason` covers older versions
101
+ only.
102
+ - **Destructive-action findings change.** Their severity can now be high or
103
+ low as well as medium, temp-directory deletes no longer fire, and the
104
+ evidence shows the command.
105
+ - **The monitor sends installed package names to osv.dev** for the Inventory
106
+ and Vulnerabilities tabs.
107
+ - **A monitor and a CLI of the same version are still required.**
108
+ - **Dependencies**: `openaca==0.7.0` and `openaidr==0.3.2`, both unchanged.