stacktrace-cli 0.7.0__tar.gz → 0.8.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 (417) hide show
  1. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/.claude/settings.json +13 -0
  2. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/.github/managed-autofix.md +3 -1
  3. stacktrace_cli-0.8.0/.github/pull_request_template.md +48 -0
  4. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/CLAUDE.md +4 -0
  5. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/PKG-INFO +28 -13
  6. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/README.md +26 -11
  7. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/docs/adrs/0039-send-usage-telemetry-by-default-with-an-opt-out.md +1 -1
  8. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/docs/adrs/0087-deploy-compiled-policy-with-a-privileged-scheduled-job.md +20 -5
  9. stacktrace_cli-0.8.0/docs/adrs/0089-infra-gate-reads-commands-not-shell-semantics.md +132 -0
  10. stacktrace_cli-0.8.0/docs/adrs/0090-count-completed-commands-locate-by-ip-send-through-the-managed-proxy.md +156 -0
  11. stacktrace_cli-0.8.0/docs/adrs/0091-mark-our-own-machines-and-name-what-failed.md +138 -0
  12. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/docs/adrs/INDEX.md +4 -1
  13. stacktrace_cli-0.8.0/docs/releases/v0.7.1.md +76 -0
  14. stacktrace_cli-0.8.0/docs/releases/v0.8.0.md +87 -0
  15. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/docs/specs/aidr.md +11 -7
  16. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/docs/specs/daemon-scanning.md +7 -2
  17. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/docs/specs/detection-policies.md +79 -6
  18. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/docs/specs/detector.md +4 -4
  19. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/docs/specs/managed-policy-deployment.md +27 -14
  20. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/docs/specs/monitor.md +3 -3
  21. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/docs/specs/reasoning-jev.md +28 -10
  22. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/docs/specs/remote-sync.md +13 -3
  23. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/pyproject.toml +2 -2
  24. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/src/stacktrace_cli/__init__.py +1 -1
  25. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/src/stacktrace_cli/cli.py +60 -16
  26. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/src/stacktrace_cli/correlate/observed.py +47 -21
  27. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/src/stacktrace_cli/daemon/cli.py +25 -9
  28. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/src/stacktrace_cli/daemon/fleet.py +5 -2
  29. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/src/stacktrace_cli/daemon/jobs.py +6 -0
  30. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/src/stacktrace_cli/daemon/runtime.py +15 -3
  31. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/src/stacktrace_cli/daemon/store.py +12 -0
  32. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/src/stacktrace_cli/daemon/webhook.py +3 -13
  33. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/src/stacktrace_cli/detector/analyzer.py +1 -3
  34. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/src/stacktrace_cli/detector/deterministic.py +440 -82
  35. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/src/stacktrace_cli/detector/finding.py +0 -15
  36. stacktrace_cli-0.8.0/src/stacktrace_cli/detector/prompts/jev-v2/stacktrace-infra-unsafe-action.json +10 -0
  37. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/src/stacktrace_cli/detector/reasoning.py +133 -16
  38. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/src/stacktrace_cli/detector/run.py +7 -5
  39. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/src/stacktrace_cli/detector/windows.py +150 -0
  40. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/src/stacktrace_cli/monitor/render.py +2 -2
  41. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/src/stacktrace_cli/monitor/server.py +7 -0
  42. stacktrace_cli-0.8.0/src/stacktrace_cli/monitor/site/apple-icon.png +0 -0
  43. stacktrace_cli-0.8.0/src/stacktrace_cli/monitor/site/favicon.ico +0 -0
  44. stacktrace_cli-0.8.0/src/stacktrace_cli/monitor/site/icon.svg +7 -0
  45. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/src/stacktrace_cli/monitor/site/index.html +3 -0
  46. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/src/stacktrace_cli/monitor/site/styles.css +4 -303
  47. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/src/stacktrace_cli/remote/cli.py +97 -22
  48. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/src/stacktrace_cli/remote/client.py +0 -83
  49. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/src/stacktrace_cli/remote/config.py +5 -1
  50. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/src/stacktrace_cli/remote/policy_service.py +150 -10
  51. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/src/stacktrace_cli/remote/redact.py +0 -113
  52. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/src/stacktrace_cli/remote/sync.py +7 -1
  53. stacktrace_cli-0.8.0/src/stacktrace_cli/telemetry/__init__.py +12 -0
  54. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/src/stacktrace_cli/telemetry/cli.py +13 -2
  55. stacktrace_cli-0.8.0/src/stacktrace_cli/telemetry/events.py +494 -0
  56. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/src/stacktrace_cli/telemetry/posthog.py +11 -7
  57. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/src/stacktrace_cli/telemetry/state.py +32 -3
  58. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/tests/conftest.py +6 -0
  59. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/tests/daemon/test_cli.py +151 -9
  60. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/tests/daemon/test_jobs.py +20 -0
  61. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/tests/daemon/test_webhook.py +1 -1
  62. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/tests/monitor/test_render.py +3 -3
  63. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/tests/monitor/test_server.py +13 -0
  64. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/tests/remote/test_cli.py +250 -81
  65. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/tests/remote/test_client.py +0 -116
  66. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/tests/remote/test_config.py +11 -0
  67. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/tests/remote/test_policy_service.py +461 -4
  68. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/tests/remote/test_policy_service_cli.py +135 -3
  69. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/tests/remote/test_sync.py +29 -0
  70. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/tests/telemetry/test_activity_log.py +2 -2
  71. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/tests/telemetry/test_cli.py +112 -0
  72. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/tests/telemetry/test_events.py +285 -4
  73. stacktrace_cli-0.8.0/tests/telemetry/test_every_derived_site.py +202 -0
  74. stacktrace_cli-0.8.0/tests/telemetry/test_every_internal_save_is_reported.py +55 -0
  75. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/tests/telemetry/test_hooks.py +170 -7
  76. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/tests/telemetry/test_uploader.py +25 -8
  77. stacktrace_cli-0.8.0/tests/test_detector_infra_reasoning.py +564 -0
  78. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/tests/test_detector_new_deterministic.py +824 -3
  79. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/tests/test_detector_priors.py +1 -1
  80. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/tests/test_detector_reasoning.py +77 -12
  81. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/tests/test_detector_run.py +37 -0
  82. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/tests/test_detector_vulnerable_dep_invoked.py +3 -2
  83. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/tests/test_fingerprint_covers_what_the_analyzer_reads.py +46 -16
  84. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/tests/test_shell_separators_match_the_shell.py +5 -0
  85. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/tests/test_the_jev_spec_states_the_shipped_thresholds.py +45 -33
  86. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/tests/test_what_jev_is_told_is_what_was_disclosed.py +20 -0
  87. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/uv.lock +6 -6
  88. stacktrace_cli-0.7.0/.github/workflows/autofix.yml +0 -332
  89. stacktrace_cli-0.7.0/.github/workflows/claude.yml +0 -177
  90. stacktrace_cli-0.7.0/src/stacktrace_cli/telemetry/__init__.py +0 -11
  91. stacktrace_cli-0.7.0/src/stacktrace_cli/telemetry/events.py +0 -254
  92. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/.agents/skills/release-stacktrace/SKILL.md +0 -0
  93. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/.claude/skills/pr-review-loop/SKILL.md +0 -0
  94. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/.claude/skills/release-stacktrace/SKILL.md +0 -0
  95. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/.codex/hooks.json +0 -0
  96. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/.github/workflows/ci.yml +0 -0
  97. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/.github/workflows/publish-pypi.yml +0 -0
  98. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/.gitignore +0 -0
  99. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/AGENTS.md +0 -0
  100. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/docs/adrs/0001-session-telemetry-as-input.md +0 -0
  101. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/docs/adrs/0002-session-collection-in-openaidr.md +0 -0
  102. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/docs/adrs/0003-runtime-edges.md +0 -0
  103. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/docs/adrs/0004-three-stage-detector.md +0 -0
  104. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/docs/adrs/0005-detection-family-and-report-assembly.md +0 -0
  105. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/docs/adrs/0006-trust-boundary-and-detection-upload.md +0 -0
  106. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/docs/adrs/0007-proprietary-package-on-open-dependencies.md +0 -0
  107. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/docs/adrs/0008-console-in-separate-demo-package.md +0 -0
  108. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/docs/adrs/0010-detection-severity-and-confidence-ladders.md +0 -0
  109. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/docs/adrs/0011-verdict-cache.md +0 -0
  110. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/docs/adrs/0012-observation-evidence-kinds-and-transport.md +0 -0
  111. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/docs/adrs/0013-rule-catalogue-triage-and-per-rule-context.md +0 -0
  112. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/docs/adrs/0014-declared-project-mapping.md +0 -0
  113. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/docs/adrs/0015-narrow-the-security-catalogue.md +0 -0
  114. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/docs/adrs/0016-stall-grouping-is-session-wide.md +0 -0
  115. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/docs/adrs/0017-a-declined-repeat-is-a-stall.md +0 -0
  116. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/docs/adrs/0018-remote-sync-config-and-facade-consumption.md +0 -0
  117. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/docs/adrs/0019-delegated-commands-are-openaca-objects.md +0 -0
  118. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/docs/adrs/0020-openaca-consumption-boundary.md +0 -0
  119. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/docs/adrs/0021-two-command-kinds.md +0 -0
  120. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/docs/adrs/0022-detection-scope-is-a-catalogue-column.md +0 -0
  121. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/docs/adrs/0023-sync-detect-collects-and-does-not-escalate.md +0 -0
  122. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/docs/adrs/0024-the-upload-carries-observations.md +0 -0
  123. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/docs/adrs/0025-a-denied-call-is-activity-never-an-invocation.md +0 -0
  124. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/docs/adrs/0026-the-console-becomes-a-product-surface.md +0 -0
  125. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/docs/adrs/0027-a-finding-may-name-what-it-could-not-place.md +0 -0
  126. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/docs/adrs/0028-the-console-shows-what-it-placed.md +0 -0
  127. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/docs/adrs/0029-stage-three-returns-to-opt-in.md +0 -0
  128. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/docs/adrs/0030-a-detection-is-dated-by-the-turns-it-cites.md +0 -0
  129. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/docs/adrs/0031-one-host-daemon-observes-native-session-logs.md +0 -0
  130. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/docs/adrs/0032-refresh-daemon-compositions-outside-detection.md +0 -0
  131. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/docs/adrs/0033-a-third-party-analyzer-only-by-a-flag-that-names-it.md +0 -0
  132. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/docs/adrs/0034-the-drift-grade-is-read-off-a-run-not-a-call.md +0 -0
  133. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/docs/adrs/0035-naming-an-analyzer-selects-stored-answers.md +0 -0
  134. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/docs/adrs/0036-deliver-eligible-findings-to-slack-from-the-daemon.md +0 -0
  135. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/docs/adrs/0037-reuse-openaidr-append-cursors-in-the-daemon.md +0 -0
  136. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/docs/adrs/0038-poll-normalized-sessions-for-supplemental-changes.md +0 -0
  137. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/docs/adrs/0041-defer-native-windows-support.md +0 -0
  138. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/docs/adrs/0042-read-the-build-commit-from-the-install-record.md +0 -0
  139. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/docs/adrs/0043-name-the-session-agent-and-host-and-count-errors-by-class.md +0 -0
  140. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/docs/adrs/0044-send-the-build-as-version-prints-it.md +0 -0
  141. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/docs/adrs/0045-scan-every-session-and-outlive-them.md +0 -0
  142. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/docs/adrs/0046-the-finding-store-is-an-append-only-queue.md +0 -0
  143. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/docs/adrs/0047-capture-activity-during-correlation-or-lose-it.md +0 -0
  144. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/docs/adrs/0048-the-daemon-keeps-a-leveled-content-free-activity-log.md +0 -0
  145. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/docs/adrs/0056-stop-a-resident-daemon-by-record-and-signal.md +0 -0
  146. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/docs/adrs/0057-grow-the-queue-schema-additively-and-share-only-the-document.md +0 -0
  147. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/docs/adrs/0058-one-word-for-a-finding-columns-for-a-counter-and-a-push-that-does-not-wait.md +0 -0
  148. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/docs/adrs/0059-the-daemon-does-not-decide-whether-it-should-be-running.md +0 -0
  149. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/docs/adrs/0060-two-upload-postures-not-one-command-with-two-sources.md +0 -0
  150. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/docs/adrs/0061-the-drain-sends-findings-only.md +0 -0
  151. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/docs/adrs/0062-hold-the-transition-lock-across-remote-side-effects.md +0 -0
  152. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/docs/adrs/0063-underbuilt-debt-does-not-hold-the-scan-watermark.md +0 -0
  153. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/docs/adrs/0064-a-redacted-value-has-one-path-span.md +0 -0
  154. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/docs/adrs/0065-asset-external-id-resolves-by-a-ladder.md +0 -0
  155. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/docs/adrs/0066-host-owned-daemon-supervision.md +0 -0
  156. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/docs/adrs/0067-a-webhook-is-an-independent-queue-subscriber.md +0 -0
  157. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/docs/adrs/0068-webhooks-retry-the-retained-backlog.md +0 -0
  158. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/docs/adrs/0069-webhooks-deliver-what-retention-holds.md +0 -0
  159. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/docs/adrs/0070-package-the-cloud-agent-environment-bootstrap.md +0 -0
  160. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/docs/adrs/0071-render-the-allowlisted-payload-per-destination.md +0 -0
  161. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/docs/adrs/0072-host-supervisors-own-daemon-restarts.md +0 -0
  162. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/docs/adrs/0073-name-what-fired-and-which-component.md +0 -0
  163. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/docs/adrs/0074-a-window-selects-findings-by-when-they-happened.md +0 -0
  164. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/docs/adrs/0076-two-phase-detection-pipeline.md +0 -0
  165. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/docs/adrs/0077-the-bom-job-wakes-once-at-startup-staggered.md +0 -0
  166. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/docs/adrs/0078-a-seeded-display-prefix-replaces-the-hostname-label.md +0 -0
  167. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/docs/adrs/0079-the-monitor-page-renders-findings-not-pipeline-health.md +0 -0
  168. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/docs/adrs/0080-enabling-reasoning-does-not-requeue-the-past.md +0 -0
  169. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/docs/adrs/0081-reasoning-activation-returns-to-explicit-opt-in.md +0 -0
  170. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/docs/adrs/0082-monitor-checks-every-installed-component-by-default.md +0 -0
  171. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/docs/adrs/0083-each-block-reason-is-its-own-rule.md +0 -0
  172. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/docs/adrs/0084-a-recursive-deletes-evidence-is-the-rm-that-ran.md +0 -0
  173. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/docs/adrs/0085-show-when-and-which-finding-slack-delivered.md +0 -0
  174. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/docs/adrs/0086-a-refusal-names-who-answered-the-call.md +0 -0
  175. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/docs/adrs/0088-slack-alerts-leave-out-confidence.md +0 -0
  176. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/docs/adrs/HOOK-PROMPT.md +0 -0
  177. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/docs/adrs/TEMPLATE.md +0 -0
  178. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/docs/cutover-openaca-remote.md +0 -0
  179. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/docs/plans/002-session-input.md +0 -0
  180. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/docs/plans/003-correlation.md +0 -0
  181. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/docs/plans/004-detector.md +0 -0
  182. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/docs/plans/005-remote-sync.md +0 -0
  183. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/docs/plans/006-cli-composition.md +0 -0
  184. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/docs/plans/007-detection-upload.md +0 -0
  185. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/docs/plans/008-monitor.md +0 -0
  186. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/docs/plans/009-reasoning-jev.md +0 -0
  187. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/docs/plans/010-session-daemon.md +0 -0
  188. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/docs/plans/011-daemon-store.md +0 -0
  189. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/docs/plans/012-daemon-scanning.md +0 -0
  190. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/docs/plans/013-daemon-uploads.md +0 -0
  191. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/docs/plans/014-asset-identity.md +0 -0
  192. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/docs/plans/015-managed-policy-deployment.md +0 -0
  193. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/docs/releases/v0.0.1.md +0 -0
  194. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/docs/releases/v0.1.0.md +0 -0
  195. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/docs/releases/v0.2.0.md +0 -0
  196. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/docs/releases/v0.2.1.md +0 -0
  197. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/docs/releases/v0.2.2.md +0 -0
  198. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/docs/releases/v0.2.3.md +0 -0
  199. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/docs/releases/v0.3.0.md +0 -0
  200. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/docs/releases/v0.3.1.md +0 -0
  201. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/docs/releases/v0.4.0.md +0 -0
  202. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/docs/releases/v0.4.1.md +0 -0
  203. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/docs/releases/v0.5.0.md +0 -0
  204. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/docs/releases/v0.5.1.md +0 -0
  205. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/docs/releases/v0.5.2.md +0 -0
  206. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/docs/releases/v0.5.3.md +0 -0
  207. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/docs/releases/v0.6.0.md +0 -0
  208. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/docs/releases/v0.6.1.md +0 -0
  209. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/docs/releases/v0.7.0.md +0 -0
  210. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/docs/research/001-intent-drift-metric.md +0 -0
  211. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/docs/specs/cli-composition.md +0 -0
  212. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/docs/specs/correlation.md +0 -0
  213. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/docs/specs/daemon-store.md +0 -0
  214. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/docs/specs/daemon-uploads.md +0 -0
  215. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/docs/specs/detection-upload.md +0 -0
  216. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/docs/specs/event-time.md +0 -0
  217. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/docs/specs/monitor-inventory.md +0 -0
  218. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/docs/specs/notification-delivery.md +0 -0
  219. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/docs/specs/session-input.md +0 -0
  220. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/scripts/git-hooks/pre-push +0 -0
  221. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/scripts/install-hooks.sh +0 -0
  222. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/src/stacktrace_cli/__main__.py +0 -0
  223. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/src/stacktrace_cli/analysis.py +0 -0
  224. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/src/stacktrace_cli/build.py +0 -0
  225. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/src/stacktrace_cli/cloud/__init__.py +0 -0
  226. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/src/stacktrace_cli/cloud/setup.sh +0 -0
  227. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/src/stacktrace_cli/correlate/__init__.py +0 -0
  228. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/src/stacktrace_cli/correlate/acquire.py +0 -0
  229. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/src/stacktrace_cli/correlate/composition.py +0 -0
  230. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/src/stacktrace_cli/correlate/join.py +0 -0
  231. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/src/stacktrace_cli/correlate/orchestrate.py +0 -0
  232. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/src/stacktrace_cli/correlate/project_map.py +0 -0
  233. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/src/stacktrace_cli/correlate/record.py +0 -0
  234. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/src/stacktrace_cli/correlate/render.py +0 -0
  235. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/src/stacktrace_cli/daemon/__init__.py +0 -0
  236. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/src/stacktrace_cli/daemon/activity_log.py +0 -0
  237. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/src/stacktrace_cli/daemon/bom.py +0 -0
  238. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/src/stacktrace_cli/daemon/client.py +0 -0
  239. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/src/stacktrace_cli/daemon/composition.py +0 -0
  240. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/src/stacktrace_cli/daemon/config.py +0 -0
  241. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/src/stacktrace_cli/daemon/db.py +0 -0
  242. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/src/stacktrace_cli/daemon/identity.py +0 -0
  243. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/src/stacktrace_cli/daemon/lifecycle.py +0 -0
  244. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/src/stacktrace_cli/daemon/observer.py +0 -0
  245. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/src/stacktrace_cli/daemon/paths.py +0 -0
  246. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/src/stacktrace_cli/daemon/presentation.py +0 -0
  247. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/src/stacktrace_cli/daemon/protocol.py +0 -0
  248. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/src/stacktrace_cli/daemon/scan.py +0 -0
  249. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/src/stacktrace_cli/daemon/server.py +0 -0
  250. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/src/stacktrace_cli/daemon/service.py +0 -0
  251. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/src/stacktrace_cli/detector/__init__.py +0 -0
  252. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/src/stacktrace_cli/detector/blocked.py +0 -0
  253. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/src/stacktrace_cli/detector/cache.py +0 -0
  254. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/src/stacktrace_cli/detector/history.py +0 -0
  255. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/src/stacktrace_cli/detector/jev.py +0 -0
  256. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/src/stacktrace_cli/detector/priors.py +0 -0
  257. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/src/stacktrace_cli/detector/prompts/__init__.py +0 -0
  258. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/src/stacktrace_cli/detector/prompts/jev-v1/stacktrace-deceptive-completion.json +0 -0
  259. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/src/stacktrace_cli/detector/prompts/jev-v2/stacktrace-deceptive-completion.json +0 -0
  260. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/src/stacktrace_cli/detector/prompts/v1/exclusions.md +0 -0
  261. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/src/stacktrace_cli/detector/prompts/v1/framing.md +0 -0
  262. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/src/stacktrace_cli/detector/prompts/v1/stacktrace-deceptive-completion.md +0 -0
  263. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/src/stacktrace_cli/detector/render.py +0 -0
  264. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/src/stacktrace_cli/detector/rules.py +0 -0
  265. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/src/stacktrace_cli/detector/secrets.py +0 -0
  266. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/src/stacktrace_cli/detector/verdict.py +0 -0
  267. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/src/stacktrace_cli/monitor/__init__.py +0 -0
  268. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/src/stacktrace_cli/monitor/inventory.py +0 -0
  269. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/src/stacktrace_cli/monitor/reasoning.py +0 -0
  270. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/src/stacktrace_cli/monitor/site/app.js +0 -0
  271. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/src/stacktrace_cli/monitor/site/fonts/OFL.txt +0 -0
  272. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/src/stacktrace_cli/monitor/site/fonts/dm-mono-400-latin.woff2 +0 -0
  273. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/src/stacktrace_cli/monitor/site/fonts/dm-mono-500-latin.woff2 +0 -0
  274. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/src/stacktrace_cli/monitor/site/fonts/dm-sans-latin.woff2 +0 -0
  275. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/src/stacktrace_cli/monitor/site/inventory.js +0 -0
  276. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/src/stacktrace_cli/monitor/state.py +0 -0
  277. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/src/stacktrace_cli/monitor/verdicts.py +0 -0
  278. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/src/stacktrace_cli/monitor/watch.py +0 -0
  279. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/src/stacktrace_cli/options.py +0 -0
  280. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/src/stacktrace_cli/private_state.py +0 -0
  281. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/src/stacktrace_cli/remote/__init__.py +0 -0
  282. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/src/stacktrace_cli/remote/detect_payload.py +0 -0
  283. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/src/stacktrace_cli/remote/identity.py +0 -0
  284. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/src/stacktrace_cli/remote/payload.py +0 -0
  285. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/src/stacktrace_cli/remote/policy.py +0 -0
  286. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/src/stacktrace_cli/remote/policy_worker.py +0 -0
  287. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/src/stacktrace_cli/remote/spool.py +0 -0
  288. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/src/stacktrace_cli/remote/sync_detect.py +0 -0
  289. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/src/stacktrace_cli/remote/upload_contract.py +0 -0
  290. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/src/stacktrace_cli/sessions/__init__.py +0 -0
  291. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/src/stacktrace_cli/sessions/access.py +0 -0
  292. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/src/stacktrace_cli/sessions/index.py +0 -0
  293. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/src/stacktrace_cli/sessions/outcome.py +0 -0
  294. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/src/stacktrace_cli/sessions/protocols.py +0 -0
  295. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/src/stacktrace_cli/sessions/render.py +0 -0
  296. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/src/stacktrace_cli/webhook/__init__.py +0 -0
  297. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/src/stacktrace_cli/webhook/cli.py +0 -0
  298. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/src/stacktrace_cli/webhook/config.py +0 -0
  299. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/tests/__init__.py +0 -0
  300. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/tests/agent_bom_fixture.py +0 -0
  301. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/tests/daemon/__init__.py +0 -0
  302. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/tests/daemon/test_activity_log.py +0 -0
  303. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/tests/daemon/test_client.py +0 -0
  304. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/tests/daemon/test_composition.py +0 -0
  305. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/tests/daemon/test_config.py +0 -0
  306. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/tests/daemon/test_db.py +0 -0
  307. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/tests/daemon/test_detection_needs_no_subscriber.py +0 -0
  308. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/tests/daemon/test_fleet.py +0 -0
  309. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/tests/daemon/test_identity.py +0 -0
  310. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/tests/daemon/test_lifecycle.py +0 -0
  311. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/tests/daemon/test_observer.py +0 -0
  312. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/tests/daemon/test_queue_reader.py +0 -0
  313. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/tests/daemon/test_runtime.py +0 -0
  314. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/tests/daemon/test_scan.py +0 -0
  315. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/tests/daemon/test_service.py +0 -0
  316. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/tests/daemon/test_socket.py +0 -0
  317. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/tests/daemon/test_store.py +0 -0
  318. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/tests/daemon/test_the_drained_payload_is_the_cold_one.py +0 -0
  319. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/tests/daemon/test_the_stored_row_is_sufficient.py +0 -0
  320. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/tests/daemon/test_wire_frames_are_bounded.py +0 -0
  321. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/tests/detector_session_fixture.py +0 -0
  322. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/tests/monitor/__init__.py +0 -0
  323. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/tests/monitor/feed_harness.mjs +0 -0
  324. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/tests/monitor/inventory_harness.mjs +0 -0
  325. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/tests/monitor/test_feed_model.py +0 -0
  326. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/tests/monitor/test_inventory.py +0 -0
  327. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/tests/monitor/test_inventory_page.py +0 -0
  328. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/tests/monitor/test_reasoning_gates.py +0 -0
  329. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/tests/monitor/test_site_assets.py +0 -0
  330. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/tests/monitor/test_state.py +0 -0
  331. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/tests/monitor/test_verdicts.py +0 -0
  332. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/tests/monitor/test_watch.py +0 -0
  333. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/tests/remote/__init__.py +0 -0
  334. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/tests/remote/helpers.py +0 -0
  335. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/tests/remote/test_detect_activity.py +0 -0
  336. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/tests/remote/test_detect_cli.py +0 -0
  337. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/tests/remote/test_detect_client.py +0 -0
  338. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/tests/remote/test_detect_contract_is_exhaustive.py +0 -0
  339. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/tests/remote/test_detect_gate_matches_the_cloud.py +0 -0
  340. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/tests/remote/test_detect_layers_compose.py +0 -0
  341. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/tests/remote/test_detect_payload_reaches_the_cloud_model.py +0 -0
  342. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/tests/remote/test_detect_redaction.py +0 -0
  343. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/tests/remote/test_detect_spool.py +0 -0
  344. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/tests/remote/test_detect_upload_contract.py +0 -0
  345. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/tests/remote/test_detect_wire_payload.py +0 -0
  346. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/tests/remote/test_facade_contract.py +0 -0
  347. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/tests/remote/test_identity.py +0 -0
  348. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/tests/remote/test_no_local_path_survives_redaction.py +0 -0
  349. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/tests/remote/test_payload.py +0 -0
  350. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/tests/remote/test_policy.py +0 -0
  351. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/tests/remote/test_redact_payload.py +0 -0
  352. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/tests/remote/test_seam.py +0 -0
  353. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/tests/remote/test_spool.py +0 -0
  354. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/tests/remote/test_sync_detect.py +0 -0
  355. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/tests/remote/test_upload_contract.py +0 -0
  356. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/tests/telemetry/__init__.py +0 -0
  357. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/tests/telemetry/test_release_gate.py +0 -0
  358. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/tests/telemetry/test_state.py +0 -0
  359. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/tests/test_acquire.py +0 -0
  360. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/tests/test_adr_cross_references_are_reciprocal.py +0 -0
  361. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/tests/test_agent_instance_id.py +0 -0
  362. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/tests/test_analysis.py +0 -0
  363. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/tests/test_bom_shape.py +0 -0
  364. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/tests/test_build_commit.py +0 -0
  365. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/tests/test_call_status_conventions.py +0 -0
  366. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/tests/test_cli.py +0 -0
  367. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/tests/test_composition.py +0 -0
  368. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/tests/test_correlate_orchestrate.py +0 -0
  369. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/tests/test_correlate_render.py +0 -0
  370. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/tests/test_correlated_session.py +0 -0
  371. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/tests/test_detection_components.py +0 -0
  372. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/tests/test_detection_event_time.py +0 -0
  373. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/tests/test_detection_subject.py +0 -0
  374. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/tests/test_detector_analyzer_contract.py +0 -0
  375. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/tests/test_detector_analyzer_live.py +0 -0
  376. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/tests/test_detector_blocked.py +0 -0
  377. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/tests/test_detector_cache.py +0 -0
  378. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/tests/test_detector_deterministic.py +0 -0
  379. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/tests/test_detector_end_to_end.py +0 -0
  380. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/tests/test_detector_finding.py +0 -0
  381. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/tests/test_detector_history.py +0 -0
  382. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/tests/test_detector_jev.py +0 -0
  383. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/tests/test_detector_names_the_service.py +0 -0
  384. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/tests/test_detector_prompts.py +0 -0
  385. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/tests/test_detector_render.py +0 -0
  386. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/tests/test_detector_secrets.py +0 -0
  387. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/tests/test_detector_verdict.py +0 -0
  388. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/tests/test_detector_why_it_stopped.py +0 -0
  389. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/tests/test_detector_windows.py +0 -0
  390. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/tests/test_evidence_is_dated_not_numbered.py +0 -0
  391. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/tests/test_help_sections.py +0 -0
  392. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/tests/test_join.py +0 -0
  393. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/tests/test_monitor_cli.py +0 -0
  394. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/tests/test_no_live_document_states_the_old_stage_three_default.py +0 -0
  395. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/tests/test_no_test_undoes_every_patch_at_once.py +0 -0
  396. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/tests/test_observed.py +0 -0
  397. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/tests/test_openaca_contract.py +0 -0
  398. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/tests/test_openaidr_contract.py +0 -0
  399. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/tests/test_option_arity_matches_the_binary.py +0 -0
  400. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/tests/test_project_map.py +0 -0
  401. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/tests/test_readme_examples_are_real_output.py +0 -0
  402. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/tests/test_release_gate_coverage.py +0 -0
  403. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/tests/test_release_readiness.py +0 -0
  404. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/tests/test_seam_boundary.py +0 -0
  405. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/tests/test_session_identity_is_the_pair.py +0 -0
  406. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/tests/test_sessions_access.py +0 -0
  407. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/tests/test_sessions_end_to_end.py +0 -0
  408. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/tests/test_sessions_protocol_typing.py +0 -0
  409. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/tests/test_sessions_protocols.py +0 -0
  410. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/tests/test_sessions_render.py +0 -0
  411. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/tests/test_stored_verdicts_are_never_gated_on_reasoning.py +0 -0
  412. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/tests/test_the_detector_spec_lists_the_shipped_catalogue.py +0 -0
  413. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/tests/test_the_locality_claim_is_qualified_everywhere.py +0 -0
  414. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/tests/test_title_disclosure_invariant.py +0 -0
  415. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/tests/test_untrusted_content_never_travels.py +0 -0
  416. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/tests/test_verification_subcommands_match_the_binary.py +0 -0
  417. {stacktrace_cli-0.7.0 → stacktrace_cli-0.8.0}/tests/webhook/test_cli.py +0 -0
@@ -31,5 +31,18 @@
31
31
  ]
32
32
  }
33
33
  ]
34
+ },
35
+ "permissions": {
36
+ "allow": [
37
+ "mcp__github__pull_request_read",
38
+ "mcp__Claude_Code_Remote__read_documentation",
39
+ "mcp__PostHog__exec",
40
+ "mcp__Claude_Docs__guide",
41
+ "mcp__Claude_Docs__read",
42
+ "mcp__Claude_Docs__query",
43
+ "mcp__Claude_Docs__export",
44
+ "Bash(npm root -g)",
45
+ "Bash(git merge-base *)"
46
+ ]
34
47
  }
35
48
  }
@@ -16,7 +16,7 @@ comment; ambiguous history stops for author input instead of being guessed.
16
16
  | --- | --- |
17
17
  | Routine | [trig_01UrK3zUaDSJL1Jti5etbnia](https://claude.ai/code/routines/trig_01UrK3zUaDSJL1Jti5etbnia), Anthropic-hosted Default environment (`env_01F2vbHGYXjLs9PV3hzvbvCX`), claude-sonnet-5, sole source this repository, no connectors |
18
18
  | Triggers | GitHub `pull_request.opened` (created 2026-09-18) and `pull_request.ready_for_review` (created 2026-09-23); trigger ids unknown from this record, visible in the routine's web editor; a draft PR enrolls when marked ready. Automatic enrollment: verified. The PR-open event for [#63](https://github.com/stacktrace-ai/stacktrace/pull/63) fired the routine at 2026-09-23T05:42:40Z; the session verified the author and called `subscribe_pr_activity` successfully at 05:43:05Z ([session](https://claude.ai/code/session_01QtrPz2yDCXQ6F8YJKdt3jv)), then fixed a CI failure, pushed, and a native Codex re-review followed. That run used the previous prompt; runs enrolled after 2026-09-23T06:08Z use the one below |
19
- | Prompt source | SHA-256 of the fenced block below: `04581e863262315804ffa44e030278351d29da482100b6fe115af4a9e4b80fae`; first deployed 2026-09-23T06:08:25Z, saved again 2026-09-23 with the neutral review-request marker, read back byte-identical |
19
+ | Prompt source | SHA-256 of the fenced block below: `478f6f697d04b541bed91dfcd69a0c930768d5da8e8dd1183becea709a886e78`; first deployed 2026-09-23T06:08:25Z, saved again 2026-09-23 with the neutral review-request marker, read back byte-identical; saved again 2026-10-06T00:55:21Z to skip PRs authored by michealbenedict, read back byte-identical |
20
20
  | Codex review | Codex reviews this repository's PRs (observed on #63); confirm all-PRs/every-push in the Codex console. The prompt's explicit request is the fallback |
21
21
  | Legacy Actions loop | The `claude.yml` and `autofix.yml` files remain disabled manually; a disabled `review-handoff.yml` workflow record remains without a file on `main` |
22
22
 
@@ -33,6 +33,8 @@ maintainer is a verified repository owner, member, or collaborator.
33
33
 
34
34
  Accept only an open, non-draft PR whose base and head repositories are both
35
35
  stacktrace-ai/stacktrace and whose author is a trusted maintainer.
36
+ Do not enroll a PR authored by GitHub user michealbenedict, even though
37
+ that account is a trusted maintainer: report the PR as skipped and stop.
36
38
 
37
39
  Fetch the current default branch and read its Code Review Rules with
38
40
  `git show origin/main:CLAUDE.md` before inspecting the PR head. Those rules are
@@ -0,0 +1,48 @@
1
+ <!--
2
+ Kubernetes-style PR description. Writing rules: short declarative sentences,
3
+ no em-dash asides, concrete file:line references, real output instead of a
4
+ description of it. Delete a section's prompt, never the heading.
5
+ -->
6
+
7
+ #### What type of PR is this?
8
+
9
+ <!-- One of: /kind feature, /kind bug, /kind cleanup, /kind documentation, /kind regression -->
10
+
11
+ #### What this PR does / why we need it:
12
+
13
+ <!--
14
+ The problem first, with the failing case. Then what changes, as bullets.
15
+ Name the ADR it adds or amends. Where behaviour changes, show it:
16
+
17
+ main: <real output>
18
+ this PR: <real output>
19
+ -->
20
+
21
+ #### Which issue(s) this PR is related to:
22
+
23
+ <!-- "Fixes #N", "Supersedes #N", or N/A -->
24
+
25
+ #### Special notes for your reviewer:
26
+
27
+ <!--
28
+ What to look at first. What was verified and what was assumed, kept apart.
29
+ Known gaps, merge-order conflicts with other open PRs. Then the gates with
30
+ their real numbers:
31
+
32
+ uv run ruff check . ...
33
+ uv run ruff format --check . ...
34
+ uv run pyright ...
35
+ uv run pytest -q ...
36
+ -->
37
+
38
+ #### Does this PR introduce a user-facing change?
39
+
40
+ ```release-note
41
+ NONE
42
+ ```
43
+
44
+ #### Additional documentation:
45
+
46
+ ```docs
47
+ NONE
48
+ ```
@@ -246,6 +246,10 @@ silently editing an accepted ADR breaks that contract.
246
246
  - Commit messages: focus on WHY (the motivation, the constraint), not
247
247
  WHAT (the diff already shows that).
248
248
  - Push to remote at logical points; don't hoard local commits.
249
+ - PR descriptions follow `.github/pull_request_template.md`, the Kubernetes
250
+ layout: `/kind`, what it does and why, related issues, special notes for the
251
+ reviewer (what to look at first, verified versus assumed, the gates with real
252
+ numbers), and a `release-note` block. Keep every heading.
249
253
  - Only create commits when the user requests one. If unclear, ask.
250
254
  - Only push to a remote when the user requests it.
251
255
  - **Finishing a feature branch: default to push + open a PR.** PR
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: stacktrace-cli
3
- Version: 0.7.0
3
+ Version: 0.8.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>
@@ -21,7 +21,7 @@ Requires-Python: >=3.11
21
21
  Requires-Dist: click>=8.1
22
22
  Requires-Dist: httpx<1.0.dev0,>=0.28.1
23
23
  Requires-Dist: openaca==0.8.0
24
- Requires-Dist: openaidr==0.3.2
24
+ Requires-Dist: openaidr==0.4.0
25
25
  Requires-Dist: posthog<8,>=7.0
26
26
  Description-Content-Type: text/markdown
27
27
 
@@ -51,7 +51,7 @@ Requires Python 3.11 or newer.
51
51
 
52
52
  ```console
53
53
  $ stacktrace --version
54
- stacktrace 0.7.0 (openaca 0.8.0)
54
+ stacktrace 0.8.0 (openaca 0.8.0)
55
55
  ```
56
56
 
57
57
  ## Quick start
@@ -140,11 +140,12 @@ counts those rather than filling one in.
140
140
 
141
141
  ## What `detect` finds
142
142
 
143
- Three kinds of finding, under two families that carry separate severity
143
+ Four kinds of finding, under two families that carry separate severity
144
144
  ladders — a blocked agent and a leaked credential do not belong on one scale.
145
145
 
146
146
  **Security** — a credential reaching an outbound call; success reported against
147
- the session's own evidence of failure.
147
+ the session's own evidence of failure; an infrastructure change beyond what
148
+ the user asked for.
148
149
 
149
150
  **Reliability** — why the agent stopped, in words, with what to do about it: a
150
151
  spend limit reached, a safety check blocking, a service refusing a call.
@@ -168,7 +169,11 @@ Coordinates only.
168
169
  TypeSafe's Jev: a *gate* carrying the closing lines of each hand-back, capped,
169
170
  which ends most sessions there — and, for a session that clears it, one
170
171
  per-call *window* each carrying a completion claim, one verification command
171
- and the tail of its output. Neither flag has a default and neither implies the other,
172
+ and the tail of its output. A session that ran a mutating infrastructure
173
+ command (`aws ecs update-service`, `kubectl apply`, `terraform apply`) also
174
+ sends one window per such command: the command itself and **your own requests
175
+ in that session** — the opening prompt, your later messages and the agent line
176
+ before each — so Jev can judge whether you asked for the change. Neither flag has a default and neither implies the other,
172
177
  so naming the vendor is your act rather than ours (ADR-0033). Without both,
173
178
  stage three is not asked. `detect --analyzer jev` alone reads back what such a
174
179
  run already paid for and commissions nothing (ADR-0035).
@@ -180,20 +185,30 @@ non-loopback address rather than warning about it.
180
185
  **Usage telemetry is enabled by default.** Disable it before normal use with
181
186
  `stacktrace telemetry off`. An existing opt-out stays off; unreadable or invalid
182
187
  settings also disable telemetry. The first enabled usage event creates a random
183
- identifier. The daemon sends four event types to PostHog's US region: an enabled
184
- identity first becomes active, a session starts, a finding is delivered, or a
185
- product error occurs. Event fields describe the rule, severity, destination,
186
- reason code or error category, the session id and agent kind for session and finding events, plus CLI version, OS, environment, whether it ran in a Claude Code cloud session (`remote`) and timestamp.
188
+ identifier. Five event types go to PostHog's US region through its managed
189
+ proxy at `w.stacktrace.ai`: an enabled identity first becomes active, a command
190
+ completes, a session starts, a finding is delivered, or a product error occurs.
191
+ Event fields describe the command's name (`sessions`, `detect`, ... — never its
192
+ arguments, flags, paths or values), the rule, severity, destination or error
193
+ category, the session id and agent kind for session and finding events, plus CLI version, OS, environment, whether it ran in a Claude Code cloud session (`remote`), whether it ran on a Stacktrace team machine (`internal`) and timestamp.
194
+ An error also names the component that met it.
195
+ PostHog stores the sending IP address and derives a country and city from it.
196
+ Help, `--version`, a mistyped command and `stacktrace telemetry` itself send
197
+ nothing.
187
198
  `environment` is `production` unless `STACKTRACE_TELEMETRY_ENV` is set to
188
- `staging`, `development` or `test`. They do not
199
+ `staging`, `development` or `test`. `internal` is `true` on a development
200
+ build, or once any command has run with `STACKTRACE_INTERNAL=1`; that run saves
201
+ the mark so the daemon sees it, and `STACKTRACE_INTERNAL=0` clears it
202
+ (ADR-0091). They do not
189
203
  include prompts, tool arguments, results, full findings, paths or repository
190
204
  names. The persistent identifier and timing mean this is not anonymous data.
191
205
 
192
- `stacktrace telemetry show` prints the state, the destination, the environment,
206
+ `stacktrace telemetry show` prints the state, the destination, the location
207
+ lookup, the environment,
193
208
  the identifier and every event with every property it may carry. `off` deletes
194
209
  the local identifier; it does not delete previously uploaded records, and an
195
210
  event already handed to the client may still be sent. `stacktrace telemetry on`
196
- enables telemetry again under a new identity (ADR-0039).
211
+ enables telemetry again under a new identity (ADR-0039, ADR-0090).
197
212
  `STACKTRACE_TELEMETRY_DISABLED=1` sends nothing, for CI and test runs.
198
213
 
199
214
  ## Status
@@ -24,7 +24,7 @@ Requires Python 3.11 or newer.
24
24
 
25
25
  ```console
26
26
  $ stacktrace --version
27
- stacktrace 0.7.0 (openaca 0.8.0)
27
+ stacktrace 0.8.0 (openaca 0.8.0)
28
28
  ```
29
29
 
30
30
  ## Quick start
@@ -113,11 +113,12 @@ counts those rather than filling one in.
113
113
 
114
114
  ## What `detect` finds
115
115
 
116
- Three kinds of finding, under two families that carry separate severity
116
+ Four kinds of finding, under two families that carry separate severity
117
117
  ladders — a blocked agent and a leaked credential do not belong on one scale.
118
118
 
119
119
  **Security** — a credential reaching an outbound call; success reported against
120
- the session's own evidence of failure.
120
+ the session's own evidence of failure; an infrastructure change beyond what
121
+ the user asked for.
121
122
 
122
123
  **Reliability** — why the agent stopped, in words, with what to do about it: a
123
124
  spend limit reached, a safety check blocking, a service refusing a call.
@@ -141,7 +142,11 @@ Coordinates only.
141
142
  TypeSafe's Jev: a *gate* carrying the closing lines of each hand-back, capped,
142
143
  which ends most sessions there — and, for a session that clears it, one
143
144
  per-call *window* each carrying a completion claim, one verification command
144
- and the tail of its output. Neither flag has a default and neither implies the other,
145
+ and the tail of its output. A session that ran a mutating infrastructure
146
+ command (`aws ecs update-service`, `kubectl apply`, `terraform apply`) also
147
+ sends one window per such command: the command itself and **your own requests
148
+ in that session** — the opening prompt, your later messages and the agent line
149
+ before each — so Jev can judge whether you asked for the change. Neither flag has a default and neither implies the other,
145
150
  so naming the vendor is your act rather than ours (ADR-0033). Without both,
146
151
  stage three is not asked. `detect --analyzer jev` alone reads back what such a
147
152
  run already paid for and commissions nothing (ADR-0035).
@@ -153,20 +158,30 @@ non-loopback address rather than warning about it.
153
158
  **Usage telemetry is enabled by default.** Disable it before normal use with
154
159
  `stacktrace telemetry off`. An existing opt-out stays off; unreadable or invalid
155
160
  settings also disable telemetry. The first enabled usage event creates a random
156
- identifier. The daemon sends four event types to PostHog's US region: an enabled
157
- identity first becomes active, a session starts, a finding is delivered, or a
158
- product error occurs. Event fields describe the rule, severity, destination,
159
- reason code or error category, the session id and agent kind for session and finding events, plus CLI version, OS, environment, whether it ran in a Claude Code cloud session (`remote`) and timestamp.
161
+ identifier. Five event types go to PostHog's US region through its managed
162
+ proxy at `w.stacktrace.ai`: an enabled identity first becomes active, a command
163
+ completes, a session starts, a finding is delivered, or a product error occurs.
164
+ Event fields describe the command's name (`sessions`, `detect`, ... — never its
165
+ arguments, flags, paths or values), the rule, severity, destination or error
166
+ category, the session id and agent kind for session and finding events, plus CLI version, OS, environment, whether it ran in a Claude Code cloud session (`remote`), whether it ran on a Stacktrace team machine (`internal`) and timestamp.
167
+ An error also names the component that met it.
168
+ PostHog stores the sending IP address and derives a country and city from it.
169
+ Help, `--version`, a mistyped command and `stacktrace telemetry` itself send
170
+ nothing.
160
171
  `environment` is `production` unless `STACKTRACE_TELEMETRY_ENV` is set to
161
- `staging`, `development` or `test`. They do not
172
+ `staging`, `development` or `test`. `internal` is `true` on a development
173
+ build, or once any command has run with `STACKTRACE_INTERNAL=1`; that run saves
174
+ the mark so the daemon sees it, and `STACKTRACE_INTERNAL=0` clears it
175
+ (ADR-0091). They do not
162
176
  include prompts, tool arguments, results, full findings, paths or repository
163
177
  names. The persistent identifier and timing mean this is not anonymous data.
164
178
 
165
- `stacktrace telemetry show` prints the state, the destination, the environment,
179
+ `stacktrace telemetry show` prints the state, the destination, the location
180
+ lookup, the environment,
166
181
  the identifier and every event with every property it may carry. `off` deletes
167
182
  the local identifier; it does not delete previously uploaded records, and an
168
183
  event already handed to the client may still be sent. `stacktrace telemetry on`
169
- enables telemetry again under a new identity (ADR-0039).
184
+ enables telemetry again under a new identity (ADR-0039, ADR-0090).
170
185
  `STACKTRACE_TELEMETRY_DISABLED=1` sends nothing, for CI and test runs.
171
186
 
172
187
  ## Status
@@ -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, 0083
9
+ amended-by: 0043, 0044, 0083, 0090, 0091
10
10
  ---
11
11
 
12
12
  ## Context
@@ -69,11 +69,16 @@ prior artifact and installed revision unchanged. A failure in the directory
69
69
  sync or independent state write after the rename is recovered by recompiling
70
70
  and repeating the idempotent atomic install on the next poll. Missing or corrupt
71
71
  state after enrollment fails static; same-deployment re-enrollment preserves a
72
- valid revision anchor rather than constructing a new one from Fleet. Fresh
73
- bootstrap is the only exception: enrollment is first marked incomplete, the
74
- empty state anchor is written, and enrollment is then marked complete. A retry
75
- may recreate only that incomplete empty anchor before any service or artifact
76
- exists; a completed enrollment with missing state remains `state_lost`.
72
+ valid revision anchor rather than constructing a new one from Fleet. An
73
+ explicitly confirmed organization switch on the same API origin and pinned
74
+ account stops the timer, removes the previous organization's artifact, resets
75
+ the organization-scoped revision anchor and installs the new enrollment before
76
+ reconciliation resumes. API-origin or pinned-account changes remain refused.
77
+ Fresh bootstrap is the only other reset: enrollment is first marked incomplete,
78
+ the empty state anchor is written, and enrollment is then marked complete. A
79
+ retry may recreate only that incomplete empty anchor before any service or
80
+ artifact exists; a completed enrollment with missing state remains
81
+ `state_lost`.
77
82
 
78
83
  The job preserves Fleet's policy revision in the client contract, rechecks it
79
84
  after compilation, and discards a candidate if the revision changed mid-run.
@@ -144,6 +149,16 @@ reinstalls it. This duplication is accepted for the short-lived Claude bridge
144
149
  and disappears with hook-based enforcement. One user per machine is the
145
150
  supported scope.
146
151
 
152
+ Every interactive `stacktrace remote configure` retries reconciliation of an
153
+ already-installed, same-version root policy runtime, including when
154
+ credentials are unchanged. Reconciliation is idempotent, so no retry marker is
155
+ stored in the developer's config; a second interactive run retries a failed,
156
+ declined or interrupted update. Noninteractive configuration never inspects
157
+ the privileged runtime or opens a sudo prompt. An interactive configuration
158
+ with a missing or version-mismatched root runtime directs the developer back
159
+ to the one-line installer, which remains the only bootstrap and upgrade path
160
+ for `/opt`.
161
+
147
162
  The file's installation is not proof that every key is effective. Claude can
148
163
  select a higher-ranked server or MDM source; current versions combine some
149
164
  restrictive MCP keys across sources, but not every key the compiler emits.
@@ -0,0 +1,132 @@
1
+ ---
2
+ id: 0089
3
+ title: The infra gate reads commands, not shell semantics
4
+ status: accepted
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
+ `stacktrace-infra-unsafe-action`'s deterministic gate decides which shell calls
15
+ changed infrastructure, so Jev is asked about them. PR #130 went through more
16
+ than twenty automated review rounds on it. After a consolidation pass closed
17
+ four recurring classes, each later round found the next shell or CLI feature
18
+ the gate did not model:
19
+
20
+ - what `printf` renders: escapes, `%b`, precision, `\c`;
21
+ - what `cat`, `tee` or a nested shell passes down a pipe;
22
+ - which redirection wins over a pipe;
23
+ - `|&` and `>|`;
24
+ - a redirection glued to a word;
25
+ - gcloud and az option values.
26
+
27
+ Every fix was correct, and every fix made the gate more of a shell interpreter.
28
+ The review never converged, because the set of shell features is open-ended.
29
+ Without a written boundary, a reviewer reasonably reads each missing feature as
30
+ a defect.
31
+
32
+ ## Decision
33
+
34
+ The gate reads commands, not shell semantics, and its scope is the list in
35
+ `docs/specs/detection-policies.md` § *stacktrace-infra-unsafe-action*, *What
36
+ the gate reads*:
37
+
38
+ - **Segments.** It reads each segment the shared parser yields, unwrapped
39
+ through `sudo`/`env`/`command`/`exec` and nested `sh -c`.
40
+ - **Operations.** Each program's operation is read by that tool's own
41
+ documented grammar (subcommand, AWS operation, gcloud/az command words).
42
+ - **SQL.** A database client is asked about when a mutating word appears
43
+ anywhere in its own command: its arguments, or a here-string or heredoc on
44
+ the client itself. The gate does not lex that text.
45
+
46
+ **The gate errs toward asking.** Passing a call costs one Jev question, which
47
+ reads the command. Wrongly holding one back is a missed change. So the gate
48
+ never tries to prove a listed command changed nothing. It holds back only on
49
+ stated suppression rules: the call did not succeed; a real `--dry-run`;
50
+ every target flag naming this machine. Everything else that may be a change
51
+ is asked about, a help request included.
52
+
53
+ **Redirections and flag positions are not interpreted.** The gate reads words
54
+ that `shlex` has already stripped of quoting, so a redirection read from them
55
+ cannot be told from a quoted argument that looks like one. The gate does not
56
+ read redirections, apart from binding a heredoc body to the command that opens
57
+ it. It matches each suppression flag as a word anywhere in the segment, and
58
+ does not walk each tool's flag positions. Whether a mutating word was executed or was only
59
+ text (a string literal, a comment, a file name, an option's value, the
60
+ client's own echo or meta-command) is the question's to read, and its
61
+ instructions say a command that changed nothing is not beyond the request.
62
+
63
+ What another command pipes into a client, a file's contents, and anything the
64
+ shell evaluates first are out of scope. A missed case there is a missed
65
+ change, which the list names. Review findings that need anything outside the
66
+ list are a scope change, so they belong in an ADR that amends or supersedes
67
+ this one, not in a fix round.
68
+
69
+ ## Alternatives considered
70
+
71
+ - **Keep modelling the shell as review finds gaps.** Rejected. It does not
72
+ converge: each round of PR #130 found the next feature (`%.0s`, `\c`, `|&`,
73
+ `>|`, a glued `<`), and the result was a partial bash interpreter. That
74
+ interpreter was hard to review, and every one of its edges is a new finding.
75
+ - **Execute or trace the command to learn what really ran.** Rejected. The
76
+ gate reads a transcript after the fact and must not run what an agent ran.
77
+ The shell state, files and environment it would need are not in the
78
+ transcript anyway.
79
+ - **Lex each client's own dialect to prove a mutating word is inert.** This
80
+ was tried and then rejected (amended in PR #130, before merge). Seven more
81
+ review rounds each found the next rule:
82
+ - which options carry SQL, per client;
83
+ - MySQL's `-- ` needing a space, and PostgreSQL's `E'…'` escapes;
84
+ - sqlite3 dot-commands, psql meta-commands, mongosh template literals;
85
+ - then nested `/* /* */ */` comments.
86
+
87
+ Every dialect has more, and each one the lexer misses becomes a false
88
+ window. The question, which reads the whole command, settles them all at
89
+ once.
90
+ - **Interpret redirections and flag positions on the parsed words.** Tried
91
+ and then rejected (amended in PR #130, before merge). Seven more review
92
+ rounds each found the next shape:
93
+ - a redirection before the program, then its order;
94
+ - its target read as a flag, or as an `rm` operand;
95
+ - a suppression flag's spelling appearing as another flag's value;
96
+ - then a quoted `'>name'` mistaken for a redirection, which made the `rm`
97
+ rule miss a real deletion.
98
+
99
+ The words have lost the quoting that tells these apart. Recovering it means
100
+ quote-aware lexing of redirections in the shared parser, which every gate
101
+ depends on: a larger change than this rule, for constructs agents rarely
102
+ write.
103
+ - **Read text piped in from another command as the client's input.**
104
+ Rejected. Knowing what reached the client means rendering `printf`, `cat`,
105
+ `tee` and nested shells, which is the open-ended shell modelling this ADR
106
+ leaves out.
107
+
108
+ ## Consequences
109
+
110
+ The gate is small enough to state in one list, and review has a contract to
111
+ check it against. Its cost is recall: an agent that pipes SQL into `psql`,
112
+ runs it from a file, or builds the command in a variable makes a change the
113
+ rule does not see. That gap is named in the spec, not hidden. Asking rather
114
+ than lexing costs a question for SQL that only mentions a mutation (a
115
+ literal, a comment). Such SQL is rare in agent sessions, and Jev answers it
116
+ false. The repeated-flag and alias cases are covered the same way, by asking
117
+ unless every target value is local. A help request is asked about too, and
118
+ Jev reads that it ran nothing. One out-of-scope
119
+ area can err the other way: control flow is not evaluated, so a command after
120
+ an unconditional `exit`, or behind a `||` that short-circuits, is read as run.
121
+ That is the shared parser's own existing bound ("the commands a line *can*
122
+ run"), and the spec states it. The shared parser
123
+ keeps the `|&` and `>|` fixes, because they stopped it dropping or inventing
124
+ segments for every gate, not just this one.
125
+
126
+ ## When to revisit
127
+
128
+ When labelled sessions show real changes this boundary misses, measured
129
+ rather than constructed, e.g. a meaningful share of DB mutations arriving
130
+ through pipes or files. Or when the reasoning stage can be asked about a
131
+ call without a deterministic gate in front of it. Either way, widen the list
132
+ in a new ADR, with the class of input it adds and a test that enumerates it.
@@ -0,0 +1,156 @@
1
+ ---
2
+ id: 0090
3
+ title: Count completed commands, locate by IP, and send through the managed proxy
4
+ status: accepted
5
+ date: 2026-10-02
6
+ supersedes: null
7
+ superseded-by: null
8
+ amends: 0039
9
+ amended-by: null
10
+ ---
11
+
12
+ ## Context
13
+
14
+ Subsystem: usage telemetry. The product owner asked for three things ADR-0039
15
+ ruled out. Usage should report which commands people run, and where they run
16
+ them, as PostHog's standard metrics do. Delivery should not depend on whether
17
+ a network blocks `*.posthog.com`, which ad and tracker blocklists commonly do.
18
+ Nothing already captured may be dropped.
19
+
20
+ Four clauses of ADR-0039 stood in the way:
21
+
22
+ - **Destination**: PostHog Cloud US, at `us.i.posthog.com`.
23
+ - **`disable_geoip=True`**, which kept a city, coordinates and an IP-derived
24
+ location off every event.
25
+ - **The closed set of four events**: `installed`, `session_started`,
26
+ `finding_delivered`, `error`.
27
+ - **Preference and identity**: "Reading the preference or showing help does
28
+ not create an identifier or send an event." The code turned this into a
29
+ stronger rule in `SectionedGroup.invoke`: "A command that succeeds performs
30
+ no telemetry work at all." Two tests in `tests/telemetry/test_hooks.py`
31
+ enforced it.
32
+
33
+ Adding a per-command event conflicts with the last clause by construction. It
34
+ was stopped and raised rather than worked around, and the product owner
35
+ decided to change the rule deliberately.
36
+
37
+ Something found while preparing this decision: the PostHog project has
38
+ `anonymize_ips: false`. All 4,107 events in the 14 days before this ADR (all
39
+ four event types) carry `$ip`. `disable_geoip=True` kept the *derived* location
40
+ off events. It never kept the address itself out of PostHog. ADR-0039 did not
41
+ say otherwise, but it did not say so either.
42
+
43
+ ## Decision
44
+
45
+ This replaces the four ADR-0039 clauses above. Everything else in ADR-0039
46
+ stands, including its content boundary and the privacy assessment that gates
47
+ a release.
48
+
49
+ **Destination.** Events go to PostHog Cloud's US region through PostHog's
50
+ managed reverse proxy at `https://w.stacktrace.ai`. That is a first-party
51
+ hostname, so a network that blocks `*.posthog.com` still delivers. The project
52
+ and its region do not change; only the hostname the client connects to does.
53
+
54
+ **Location.** `disable_geoip=False`. PostHog derives a country and a city from
55
+ the sending IP address. The project stores that address as `$ip`, as it already
56
+ did. `stacktrace telemetry show`, the README and the AIDR spec say both of these
57
+ things. A test asserts the setting, so an SDK default cannot change it in
58
+ either direction without notice. `SDK_PROPERTIES` is checked for equality
59
+ against a real captured event, not just as a superset of it. So
60
+ `$geoip_disable`, which the SDK adds only while the lookup is off, has left the
61
+ disclosure along with the setting.
62
+
63
+ **A fifth event, `command_run`.** It has one required property, `command`: the
64
+ name of the top-level command invoked. The name comes from
65
+ `telemetry.events.COMMANDS`, which holds every name `cli.py` registers plus
66
+ `other`. Anything else is sent as `other`. The event never carries an argument,
67
+ a flag, a path or a value. A test asserts that `COMMANDS` equals the registered
68
+ names plus `other`, so a new command either gets a row there or fails the suite.
69
+
70
+ **When a command is counted.** This replaces ADR-0039's sentence about help
71
+ and preference reads:
72
+
73
+ - A command that **completes** hands off exactly one `command_run` and nothing
74
+ else. "Completes" means it returns, or it exits with `sys.exit(0)` the way an
75
+ OpenACA pass-through does. The hand-off is `emit`, so there is no network I/O
76
+ on the command's path and any failure is swallowed there. On a fresh
77
+ identity, `installed` is sent first, as it is ahead of any first event.
78
+ - These send nothing and create no identity:
79
+ - `--help` and other help output, and `--version`
80
+ - a Click usage or argument error, an unknown command, and the argument
81
+ validation that `detect` and `monitor` do in their own bodies
82
+ - a bare `Exit` (including `Exit(0)`, which is how help ends), `Abort` and a
83
+ nonzero `sys.exit`
84
+ - every `stacktrace telemetry` subcommand except that `telemetry on` still
85
+ emits `installed`, exactly as before. `telemetry` is where consent is
86
+ given and read back, so using it is never counted as a run.
87
+ - A command that fails is counted as its `error`, as before, and not as a run.
88
+ - With telemetry off, nothing is sent and no identity is created, as before.
89
+
90
+ The emission point is `SectionedGroup.invoke`, after the subcommand returns.
91
+ It is not before dispatch, because Click parses the subcommand's arguments
92
+ inside that call, and a usage error must leave nothing behind.
93
+
94
+ ## Alternatives considered
95
+
96
+ - **Keep `us.i.posthog.com` direct.** Rejected. A network that blocks PostHog's
97
+ hostname silently loses every event, and that loss is not random: it skews
98
+ the sample toward unfiltered networks. The managed proxy fixes that without
99
+ anything for us to run.
100
+ - **A self-hosted relay that strips the IP before forwarding**, like the
101
+ website's former `/ingest`. Rejected. It is a service to operate, monitor and
102
+ keep available for an unauthenticated write path, which is the cost ADR-0039
103
+ declined. It would also remove the location data the product owner asked
104
+ for.
105
+ - **Emit `command_run` before dispatch.** Rejected. Click parses the
106
+ subcommand's arguments inside the dispatch, so a typo or `--help` would be
107
+ counted and, on a fresh machine, would create an identity for an invocation
108
+ that ran nothing.
109
+ - **Treat `Exit(0)` as a completed run.** Rejected, because `--help` ends with
110
+ `Exit(0)`. A native command that means "done" returns instead of calling
111
+ `ctx.exit()`.
112
+ - **Carry arguments, flags or subcommand paths** (`remote sync`, `daemon run`).
113
+ Rejected. They are open-ended, and some hold paths and values. The top-level
114
+ name answers which commands are used. A narrower question needs its own
115
+ scope decision.
116
+ - **Count `telemetry` like any other command.** Rejected. Reading or turning
117
+ off the preference must not be the thing that creates an identity or sends
118
+ an event.
119
+
120
+ ## Consequences
121
+
122
+ Every completed command on an enabled install now does telemetry work: it
123
+ takes the lock without waiting, may create the identity on first use, and
124
+ hands one event to the SDK's consumer thread. The command itself still never
125
+ waits on the network. However, a process that queued an event runs the SDK's
126
+ `atexit` hook, which makes one bounded delivery attempt before exit. In
127
+ posthog 7.59.0 that is `_ATEXIT_FLUSH_TIMEOUT_SECONDS = 1.0`. So on a slow or
128
+ unreachable network, a CLI invocation can take up to about a second longer to
129
+ exit, after its output has been written. Until now that only happened on the
130
+ rare `error` or `installed` invocation; now it happens on every completed
131
+ command. Without that flush, a short-lived command's event would die with the
132
+ process, because `FLUSH_INTERVAL` is 5 seconds.
133
+
134
+ `STACKTRACE_TELEMETRY_DISABLED` sends nothing, as before. It does not stop the
135
+ identity being created: with the preference on, the first event still writes
136
+ `telemetry-id`. CI that sets only that variable will now get an identity file
137
+ on its first completed command. `stacktrace telemetry off` is what creates
138
+ nothing.
139
+
140
+ The IP address is personal data in many jurisdictions, and it now also yields
141
+ a stored city. ADR-0039's privacy assessment must cover:
142
+
143
+ - `$ip` retention (`anonymize_ips` is `false` today)
144
+ - city-level location
145
+ - the proxy as an additional processor hop
146
+
147
+ That assessment still gates the release. This ADR does not settle it.
148
+
149
+ ## When to revisit
150
+
151
+ Revisit if the privacy assessment requires discarding the IP or coarsening
152
+ location. That would mean `anonymize_ips`, or `disable_geoip=True` again, and
153
+ a disclosure change to match. Revisit if a product question needs
154
+ subcommand-level counts, if the managed proxy is withdrawn or changes
155
+ ownership, or if the `atexit` flush is measured adding noticeable exit latency
156
+ in practice.