stacktrace-cli 0.5.2__tar.gz → 0.6.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 (382) hide show
  1. stacktrace_cli-0.6.0/.claude/skills/pr-review-loop/SKILL.md +120 -0
  2. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/PKG-INFO +3 -3
  3. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/README.md +1 -1
  4. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/docs/adrs/0029-stage-three-returns-to-opt-in.md +2 -2
  5. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/docs/adrs/0033-a-third-party-analyzer-only-by-a-flag-that-names-it.md +2 -2
  6. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/docs/adrs/0035-naming-an-analyzer-selects-stored-answers.md +1 -1
  7. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/docs/adrs/0060-two-upload-postures-not-one-command-with-two-sources.md +1 -1
  8. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/docs/adrs/0065-asset-external-id-resolves-by-a-ladder.md +1 -1
  9. stacktrace_cli-0.6.0/docs/adrs/0074-a-window-selects-findings-by-when-they-happened.md +115 -0
  10. stacktrace_cli-0.6.0/docs/adrs/0076-two-phase-detection-pipeline.md +164 -0
  11. stacktrace_cli-0.6.0/docs/adrs/0077-the-bom-job-wakes-once-at-startup-staggered.md +208 -0
  12. stacktrace_cli-0.6.0/docs/adrs/0078-a-seeded-display-prefix-replaces-the-hostname-label.md +74 -0
  13. stacktrace_cli-0.6.0/docs/adrs/0079-the-monitor-page-renders-findings-not-pipeline-health.md +93 -0
  14. stacktrace_cli-0.6.0/docs/adrs/0080-enabling-reasoning-does-not-requeue-the-past.md +103 -0
  15. stacktrace_cli-0.6.0/docs/adrs/0081-reasoning-activation-returns-to-explicit-opt-in.md +136 -0
  16. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/docs/adrs/INDEX.md +11 -5
  17. stacktrace_cli-0.6.0/docs/releases/v0.5.3.md +70 -0
  18. stacktrace_cli-0.6.0/docs/releases/v0.6.0.md +120 -0
  19. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/docs/specs/daemon-uploads.md +14 -4
  20. stacktrace_cli-0.6.0/docs/specs/detection-policies.md +346 -0
  21. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/docs/specs/detector.md +52 -16
  22. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/docs/specs/monitor.md +66 -162
  23. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/pyproject.toml +2 -2
  24. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/src/stacktrace_cli/__init__.py +1 -1
  25. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/src/stacktrace_cli/analysis.py +98 -34
  26. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/src/stacktrace_cli/cloud/__init__.py +10 -0
  27. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/src/stacktrace_cli/cloud/setup.sh +51 -11
  28. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/src/stacktrace_cli/correlate/observed.py +62 -6
  29. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/src/stacktrace_cli/daemon/cli.py +113 -4
  30. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/src/stacktrace_cli/daemon/config.py +85 -5
  31. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/src/stacktrace_cli/daemon/jobs.py +48 -1
  32. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/src/stacktrace_cli/daemon/observer.py +31 -2
  33. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/src/stacktrace_cli/daemon/presentation.py +28 -0
  34. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/src/stacktrace_cli/daemon/runtime.py +46 -18
  35. stacktrace_cli-0.6.0/src/stacktrace_cli/detector/deterministic.py +2345 -0
  36. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/src/stacktrace_cli/detector/render.py +1 -4
  37. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/src/stacktrace_cli/detector/rules.py +27 -4
  38. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/src/stacktrace_cli/detector/run.py +9 -1
  39. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/src/stacktrace_cli/monitor/reasoning.py +8 -6
  40. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/src/stacktrace_cli/monitor/server.py +4 -16
  41. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/src/stacktrace_cli/monitor/site/app.js +18 -291
  42. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/src/stacktrace_cli/monitor/site/index.html +0 -12
  43. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/src/stacktrace_cli/monitor/site/styles.css +0 -35
  44. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/src/stacktrace_cli/monitor/watch.py +176 -66
  45. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/src/stacktrace_cli/remote/identity.py +41 -12
  46. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/tests/conftest.py +6 -1
  47. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/tests/daemon/test_cli.py +260 -8
  48. stacktrace_cli-0.6.0/tests/daemon/test_config.py +195 -0
  49. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/tests/daemon/test_jobs.py +116 -0
  50. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/tests/daemon/test_observer.py +194 -0
  51. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/tests/daemon/test_runtime.py +108 -1
  52. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/tests/daemon/test_the_drained_payload_is_the_cold_one.py +21 -3
  53. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/tests/detector_session_fixture.py +1 -1
  54. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/tests/monitor/feed_harness.mjs +32 -246
  55. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/tests/monitor/test_feed_model.py +30 -213
  56. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/tests/monitor/test_render.py +27 -0
  57. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/tests/monitor/test_site_assets.py +15 -29
  58. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/tests/monitor/test_watch.py +413 -21
  59. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/tests/remote/test_identity.py +62 -0
  60. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/tests/remote/test_sync_detect.py +6 -1
  61. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/tests/test_adr_cross_references_are_reciprocal.py +15 -0
  62. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/tests/test_analysis.py +133 -0
  63. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/tests/test_detector_end_to_end.py +7 -4
  64. stacktrace_cli-0.6.0/tests/test_detector_new_deterministic.py +3491 -0
  65. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/tests/test_detector_render.py +17 -0
  66. stacktrace_cli-0.6.0/tests/test_detector_vulnerable_dep_invoked.py +477 -0
  67. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/tests/test_monitor_cli.py +9 -13
  68. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/tests/test_readme_examples_are_real_output.py +1 -1
  69. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/tests/test_shell_separators_match_the_shell.py +22 -0
  70. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/tests/test_the_detector_spec_lists_the_shipped_catalogue.py +58 -1
  71. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/tests/test_the_locality_claim_is_qualified_everywhere.py +0 -39
  72. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/tests/test_untrusted_content_never_travels.py +45 -2
  73. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/tests/test_what_jev_is_told_is_what_was_disclosed.py +2 -26
  74. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/uv.lock +5 -5
  75. stacktrace_cli-0.5.2/src/stacktrace_cli/detector/deterministic.py +0 -506
  76. stacktrace_cli-0.5.2/tests/daemon/test_config.py +0 -92
  77. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/.agents/skills/release-stacktrace/SKILL.md +0 -0
  78. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/.claude/settings.json +0 -0
  79. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/.claude/skills/release-stacktrace/SKILL.md +0 -0
  80. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/.codex/hooks.json +0 -0
  81. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/.github/managed-autofix.md +0 -0
  82. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/.github/workflows/autofix.yml +0 -0
  83. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/.github/workflows/ci.yml +0 -0
  84. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/.github/workflows/claude.yml +0 -0
  85. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/.github/workflows/publish-pypi.yml +0 -0
  86. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/.gitignore +0 -0
  87. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/AGENTS.md +0 -0
  88. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/CLAUDE.md +0 -0
  89. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/docs/adrs/0001-session-telemetry-as-input.md +0 -0
  90. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/docs/adrs/0002-session-collection-in-openaidr.md +0 -0
  91. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/docs/adrs/0003-runtime-edges.md +0 -0
  92. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/docs/adrs/0004-three-stage-detector.md +0 -0
  93. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/docs/adrs/0005-detection-family-and-report-assembly.md +0 -0
  94. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/docs/adrs/0006-trust-boundary-and-detection-upload.md +0 -0
  95. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/docs/adrs/0007-proprietary-package-on-open-dependencies.md +0 -0
  96. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/docs/adrs/0008-console-in-separate-demo-package.md +0 -0
  97. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/docs/adrs/0010-detection-severity-and-confidence-ladders.md +0 -0
  98. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/docs/adrs/0011-verdict-cache.md +0 -0
  99. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/docs/adrs/0012-observation-evidence-kinds-and-transport.md +0 -0
  100. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/docs/adrs/0013-rule-catalogue-triage-and-per-rule-context.md +0 -0
  101. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/docs/adrs/0014-declared-project-mapping.md +0 -0
  102. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/docs/adrs/0015-narrow-the-security-catalogue.md +0 -0
  103. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/docs/adrs/0016-stall-grouping-is-session-wide.md +0 -0
  104. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/docs/adrs/0017-a-declined-repeat-is-a-stall.md +0 -0
  105. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/docs/adrs/0018-remote-sync-config-and-facade-consumption.md +0 -0
  106. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/docs/adrs/0019-delegated-commands-are-openaca-objects.md +0 -0
  107. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/docs/adrs/0020-openaca-consumption-boundary.md +0 -0
  108. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/docs/adrs/0021-two-command-kinds.md +0 -0
  109. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/docs/adrs/0022-detection-scope-is-a-catalogue-column.md +0 -0
  110. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/docs/adrs/0023-sync-detect-collects-and-does-not-escalate.md +0 -0
  111. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/docs/adrs/0024-the-upload-carries-observations.md +0 -0
  112. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/docs/adrs/0025-a-denied-call-is-activity-never-an-invocation.md +0 -0
  113. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/docs/adrs/0026-the-console-becomes-a-product-surface.md +0 -0
  114. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/docs/adrs/0027-a-finding-may-name-what-it-could-not-place.md +0 -0
  115. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/docs/adrs/0028-the-console-shows-what-it-placed.md +0 -0
  116. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/docs/adrs/0030-a-detection-is-dated-by-the-turns-it-cites.md +0 -0
  117. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/docs/adrs/0031-one-host-daemon-observes-native-session-logs.md +0 -0
  118. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/docs/adrs/0032-refresh-daemon-compositions-outside-detection.md +0 -0
  119. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/docs/adrs/0034-the-drift-grade-is-read-off-a-run-not-a-call.md +0 -0
  120. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/docs/adrs/0036-deliver-eligible-findings-to-slack-from-the-daemon.md +0 -0
  121. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/docs/adrs/0037-reuse-openaidr-append-cursors-in-the-daemon.md +0 -0
  122. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/docs/adrs/0038-poll-normalized-sessions-for-supplemental-changes.md +0 -0
  123. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/docs/adrs/0039-send-usage-telemetry-by-default-with-an-opt-out.md +0 -0
  124. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/docs/adrs/0041-defer-native-windows-support.md +0 -0
  125. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/docs/adrs/0042-read-the-build-commit-from-the-install-record.md +0 -0
  126. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/docs/adrs/0043-name-the-session-agent-and-host-and-count-errors-by-class.md +0 -0
  127. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/docs/adrs/0044-send-the-build-as-version-prints-it.md +0 -0
  128. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/docs/adrs/0045-scan-every-session-and-outlive-them.md +0 -0
  129. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/docs/adrs/0046-the-finding-store-is-an-append-only-queue.md +0 -0
  130. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/docs/adrs/0047-capture-activity-during-correlation-or-lose-it.md +0 -0
  131. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/docs/adrs/0048-the-daemon-keeps-a-leveled-content-free-activity-log.md +0 -0
  132. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/docs/adrs/0056-stop-a-resident-daemon-by-record-and-signal.md +0 -0
  133. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/docs/adrs/0057-grow-the-queue-schema-additively-and-share-only-the-document.md +0 -0
  134. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/docs/adrs/0058-one-word-for-a-finding-columns-for-a-counter-and-a-push-that-does-not-wait.md +0 -0
  135. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/docs/adrs/0059-the-daemon-does-not-decide-whether-it-should-be-running.md +0 -0
  136. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/docs/adrs/0061-the-drain-sends-findings-only.md +0 -0
  137. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/docs/adrs/0062-hold-the-transition-lock-across-remote-side-effects.md +0 -0
  138. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/docs/adrs/0063-underbuilt-debt-does-not-hold-the-scan-watermark.md +0 -0
  139. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/docs/adrs/0064-a-redacted-value-has-one-path-span.md +0 -0
  140. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/docs/adrs/0066-host-owned-daemon-supervision.md +0 -0
  141. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/docs/adrs/0067-a-webhook-is-an-independent-queue-subscriber.md +0 -0
  142. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/docs/adrs/0068-webhooks-retry-the-retained-backlog.md +0 -0
  143. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/docs/adrs/0069-webhooks-deliver-what-retention-holds.md +0 -0
  144. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/docs/adrs/0070-package-the-cloud-agent-environment-bootstrap.md +0 -0
  145. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/docs/adrs/0071-render-the-allowlisted-payload-per-destination.md +0 -0
  146. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/docs/adrs/0072-host-supervisors-own-daemon-restarts.md +0 -0
  147. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/docs/adrs/0073-name-what-fired-and-which-component.md +0 -0
  148. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/docs/adrs/HOOK-PROMPT.md +0 -0
  149. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/docs/adrs/TEMPLATE.md +0 -0
  150. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/docs/cutover-openaca-remote.md +0 -0
  151. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/docs/plans/002-session-input.md +0 -0
  152. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/docs/plans/003-correlation.md +0 -0
  153. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/docs/plans/004-detector.md +0 -0
  154. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/docs/plans/005-remote-sync.md +0 -0
  155. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/docs/plans/006-cli-composition.md +0 -0
  156. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/docs/plans/007-detection-upload.md +0 -0
  157. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/docs/plans/008-monitor.md +0 -0
  158. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/docs/plans/009-reasoning-jev.md +0 -0
  159. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/docs/plans/010-session-daemon.md +0 -0
  160. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/docs/plans/011-daemon-store.md +0 -0
  161. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/docs/plans/012-daemon-scanning.md +0 -0
  162. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/docs/plans/013-daemon-uploads.md +0 -0
  163. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/docs/plans/014-asset-identity.md +0 -0
  164. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/docs/releases/v0.0.1.md +0 -0
  165. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/docs/releases/v0.1.0.md +0 -0
  166. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/docs/releases/v0.2.0.md +0 -0
  167. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/docs/releases/v0.2.1.md +0 -0
  168. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/docs/releases/v0.2.2.md +0 -0
  169. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/docs/releases/v0.2.3.md +0 -0
  170. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/docs/releases/v0.3.0.md +0 -0
  171. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/docs/releases/v0.3.1.md +0 -0
  172. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/docs/releases/v0.4.0.md +0 -0
  173. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/docs/releases/v0.4.1.md +0 -0
  174. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/docs/releases/v0.5.0.md +0 -0
  175. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/docs/releases/v0.5.1.md +0 -0
  176. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/docs/releases/v0.5.2.md +0 -0
  177. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/docs/research/001-intent-drift-metric.md +0 -0
  178. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/docs/specs/aidr.md +0 -0
  179. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/docs/specs/cli-composition.md +0 -0
  180. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/docs/specs/correlation.md +0 -0
  181. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/docs/specs/daemon-scanning.md +0 -0
  182. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/docs/specs/daemon-store.md +0 -0
  183. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/docs/specs/detection-upload.md +0 -0
  184. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/docs/specs/event-time.md +0 -0
  185. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/docs/specs/notification-delivery.md +0 -0
  186. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/docs/specs/reasoning-jev.md +0 -0
  187. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/docs/specs/remote-sync.md +0 -0
  188. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/docs/specs/session-input.md +0 -0
  189. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/scripts/git-hooks/pre-push +0 -0
  190. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/scripts/install-hooks.sh +0 -0
  191. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/src/stacktrace_cli/__main__.py +0 -0
  192. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/src/stacktrace_cli/build.py +0 -0
  193. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/src/stacktrace_cli/cli.py +0 -0
  194. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/src/stacktrace_cli/correlate/__init__.py +0 -0
  195. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/src/stacktrace_cli/correlate/acquire.py +0 -0
  196. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/src/stacktrace_cli/correlate/composition.py +0 -0
  197. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/src/stacktrace_cli/correlate/join.py +0 -0
  198. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/src/stacktrace_cli/correlate/orchestrate.py +0 -0
  199. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/src/stacktrace_cli/correlate/project_map.py +0 -0
  200. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/src/stacktrace_cli/correlate/record.py +0 -0
  201. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/src/stacktrace_cli/correlate/render.py +0 -0
  202. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/src/stacktrace_cli/daemon/__init__.py +0 -0
  203. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/src/stacktrace_cli/daemon/activity_log.py +0 -0
  204. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/src/stacktrace_cli/daemon/bom.py +0 -0
  205. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/src/stacktrace_cli/daemon/client.py +0 -0
  206. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/src/stacktrace_cli/daemon/composition.py +0 -0
  207. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/src/stacktrace_cli/daemon/db.py +0 -0
  208. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/src/stacktrace_cli/daemon/fleet.py +0 -0
  209. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/src/stacktrace_cli/daemon/identity.py +0 -0
  210. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/src/stacktrace_cli/daemon/lifecycle.py +0 -0
  211. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/src/stacktrace_cli/daemon/paths.py +0 -0
  212. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/src/stacktrace_cli/daemon/protocol.py +0 -0
  213. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/src/stacktrace_cli/daemon/scan.py +0 -0
  214. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/src/stacktrace_cli/daemon/server.py +0 -0
  215. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/src/stacktrace_cli/daemon/service.py +0 -0
  216. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/src/stacktrace_cli/daemon/store.py +0 -0
  217. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/src/stacktrace_cli/daemon/webhook.py +0 -0
  218. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/src/stacktrace_cli/detector/__init__.py +0 -0
  219. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/src/stacktrace_cli/detector/analyzer.py +0 -0
  220. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/src/stacktrace_cli/detector/blocked.py +0 -0
  221. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/src/stacktrace_cli/detector/cache.py +0 -0
  222. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/src/stacktrace_cli/detector/finding.py +0 -0
  223. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/src/stacktrace_cli/detector/history.py +0 -0
  224. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/src/stacktrace_cli/detector/jev.py +0 -0
  225. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/src/stacktrace_cli/detector/priors.py +0 -0
  226. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/src/stacktrace_cli/detector/prompts/__init__.py +0 -0
  227. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/src/stacktrace_cli/detector/prompts/jev-v1/stacktrace-deceptive-completion.json +0 -0
  228. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/src/stacktrace_cli/detector/prompts/jev-v2/stacktrace-deceptive-completion.json +0 -0
  229. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/src/stacktrace_cli/detector/prompts/v1/exclusions.md +0 -0
  230. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/src/stacktrace_cli/detector/prompts/v1/framing.md +0 -0
  231. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/src/stacktrace_cli/detector/prompts/v1/stacktrace-deceptive-completion.md +0 -0
  232. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/src/stacktrace_cli/detector/reasoning.py +0 -0
  233. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/src/stacktrace_cli/detector/secrets.py +0 -0
  234. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/src/stacktrace_cli/detector/verdict.py +0 -0
  235. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/src/stacktrace_cli/detector/windows.py +0 -0
  236. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/src/stacktrace_cli/monitor/__init__.py +0 -0
  237. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/src/stacktrace_cli/monitor/render.py +0 -0
  238. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/src/stacktrace_cli/monitor/site/fonts/OFL.txt +0 -0
  239. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/src/stacktrace_cli/monitor/site/fonts/dm-mono-400-latin.woff2 +0 -0
  240. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/src/stacktrace_cli/monitor/site/fonts/dm-mono-500-latin.woff2 +0 -0
  241. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/src/stacktrace_cli/monitor/site/fonts/dm-sans-latin.woff2 +0 -0
  242. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/src/stacktrace_cli/monitor/state.py +0 -0
  243. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/src/stacktrace_cli/monitor/verdicts.py +0 -0
  244. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/src/stacktrace_cli/options.py +0 -0
  245. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/src/stacktrace_cli/private_state.py +0 -0
  246. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/src/stacktrace_cli/remote/__init__.py +0 -0
  247. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/src/stacktrace_cli/remote/cli.py +0 -0
  248. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/src/stacktrace_cli/remote/client.py +0 -0
  249. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/src/stacktrace_cli/remote/config.py +0 -0
  250. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/src/stacktrace_cli/remote/detect_payload.py +0 -0
  251. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/src/stacktrace_cli/remote/payload.py +0 -0
  252. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/src/stacktrace_cli/remote/policy.py +0 -0
  253. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/src/stacktrace_cli/remote/redact.py +0 -0
  254. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/src/stacktrace_cli/remote/spool.py +0 -0
  255. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/src/stacktrace_cli/remote/sync.py +0 -0
  256. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/src/stacktrace_cli/remote/sync_detect.py +0 -0
  257. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/src/stacktrace_cli/remote/upload_contract.py +0 -0
  258. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/src/stacktrace_cli/sessions/__init__.py +0 -0
  259. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/src/stacktrace_cli/sessions/access.py +0 -0
  260. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/src/stacktrace_cli/sessions/index.py +0 -0
  261. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/src/stacktrace_cli/sessions/outcome.py +0 -0
  262. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/src/stacktrace_cli/sessions/protocols.py +0 -0
  263. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/src/stacktrace_cli/sessions/render.py +0 -0
  264. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/src/stacktrace_cli/telemetry/__init__.py +0 -0
  265. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/src/stacktrace_cli/telemetry/cli.py +0 -0
  266. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/src/stacktrace_cli/telemetry/events.py +0 -0
  267. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/src/stacktrace_cli/telemetry/posthog.py +0 -0
  268. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/src/stacktrace_cli/telemetry/state.py +0 -0
  269. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/src/stacktrace_cli/webhook/__init__.py +0 -0
  270. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/src/stacktrace_cli/webhook/cli.py +0 -0
  271. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/src/stacktrace_cli/webhook/config.py +0 -0
  272. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/tests/__init__.py +0 -0
  273. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/tests/agent_bom_fixture.py +0 -0
  274. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/tests/daemon/__init__.py +0 -0
  275. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/tests/daemon/test_activity_log.py +0 -0
  276. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/tests/daemon/test_client.py +0 -0
  277. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/tests/daemon/test_composition.py +0 -0
  278. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/tests/daemon/test_db.py +0 -0
  279. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/tests/daemon/test_detection_needs_no_subscriber.py +0 -0
  280. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/tests/daemon/test_fleet.py +0 -0
  281. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/tests/daemon/test_identity.py +0 -0
  282. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/tests/daemon/test_lifecycle.py +0 -0
  283. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/tests/daemon/test_queue_reader.py +0 -0
  284. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/tests/daemon/test_scan.py +0 -0
  285. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/tests/daemon/test_service.py +0 -0
  286. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/tests/daemon/test_socket.py +0 -0
  287. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/tests/daemon/test_store.py +0 -0
  288. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/tests/daemon/test_the_stored_row_is_sufficient.py +0 -0
  289. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/tests/daemon/test_webhook.py +0 -0
  290. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/tests/daemon/test_wire_frames_are_bounded.py +0 -0
  291. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/tests/monitor/__init__.py +0 -0
  292. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/tests/monitor/test_reasoning_gates.py +0 -0
  293. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/tests/monitor/test_server.py +0 -0
  294. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/tests/monitor/test_state.py +0 -0
  295. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/tests/monitor/test_verdicts.py +0 -0
  296. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/tests/remote/__init__.py +0 -0
  297. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/tests/remote/helpers.py +0 -0
  298. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/tests/remote/test_cli.py +0 -0
  299. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/tests/remote/test_client.py +0 -0
  300. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/tests/remote/test_config.py +0 -0
  301. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/tests/remote/test_detect_activity.py +0 -0
  302. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/tests/remote/test_detect_cli.py +0 -0
  303. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/tests/remote/test_detect_client.py +0 -0
  304. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/tests/remote/test_detect_contract_is_exhaustive.py +0 -0
  305. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/tests/remote/test_detect_gate_matches_the_cloud.py +0 -0
  306. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/tests/remote/test_detect_layers_compose.py +0 -0
  307. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/tests/remote/test_detect_payload_reaches_the_cloud_model.py +0 -0
  308. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/tests/remote/test_detect_redaction.py +0 -0
  309. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/tests/remote/test_detect_spool.py +0 -0
  310. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/tests/remote/test_detect_upload_contract.py +0 -0
  311. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/tests/remote/test_detect_wire_payload.py +0 -0
  312. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/tests/remote/test_facade_contract.py +0 -0
  313. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/tests/remote/test_no_local_path_survives_redaction.py +0 -0
  314. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/tests/remote/test_payload.py +0 -0
  315. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/tests/remote/test_policy.py +0 -0
  316. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/tests/remote/test_redact_payload.py +0 -0
  317. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/tests/remote/test_seam.py +0 -0
  318. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/tests/remote/test_spool.py +0 -0
  319. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/tests/remote/test_sync.py +0 -0
  320. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/tests/remote/test_upload_contract.py +0 -0
  321. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/tests/telemetry/__init__.py +0 -0
  322. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/tests/telemetry/test_activity_log.py +0 -0
  323. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/tests/telemetry/test_cli.py +0 -0
  324. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/tests/telemetry/test_events.py +0 -0
  325. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/tests/telemetry/test_hooks.py +0 -0
  326. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/tests/telemetry/test_release_gate.py +0 -0
  327. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/tests/telemetry/test_state.py +0 -0
  328. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/tests/telemetry/test_uploader.py +0 -0
  329. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/tests/test_acquire.py +0 -0
  330. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/tests/test_agent_instance_id.py +0 -0
  331. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/tests/test_bom_shape.py +0 -0
  332. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/tests/test_build_commit.py +0 -0
  333. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/tests/test_call_status_conventions.py +0 -0
  334. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/tests/test_cli.py +0 -0
  335. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/tests/test_composition.py +0 -0
  336. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/tests/test_correlate_orchestrate.py +0 -0
  337. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/tests/test_correlate_render.py +0 -0
  338. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/tests/test_correlated_session.py +0 -0
  339. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/tests/test_detection_components.py +0 -0
  340. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/tests/test_detection_event_time.py +0 -0
  341. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/tests/test_detection_subject.py +0 -0
  342. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/tests/test_detector_analyzer_contract.py +0 -0
  343. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/tests/test_detector_analyzer_live.py +0 -0
  344. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/tests/test_detector_blocked.py +0 -0
  345. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/tests/test_detector_cache.py +0 -0
  346. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/tests/test_detector_deterministic.py +0 -0
  347. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/tests/test_detector_finding.py +0 -0
  348. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/tests/test_detector_history.py +0 -0
  349. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/tests/test_detector_jev.py +0 -0
  350. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/tests/test_detector_priors.py +0 -0
  351. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/tests/test_detector_prompts.py +0 -0
  352. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/tests/test_detector_reasoning.py +0 -0
  353. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/tests/test_detector_run.py +0 -0
  354. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/tests/test_detector_secrets.py +0 -0
  355. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/tests/test_detector_verdict.py +0 -0
  356. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/tests/test_detector_why_it_stopped.py +0 -0
  357. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/tests/test_detector_windows.py +0 -0
  358. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/tests/test_evidence_is_dated_not_numbered.py +0 -0
  359. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/tests/test_fingerprint_covers_what_the_analyzer_reads.py +0 -0
  360. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/tests/test_help_sections.py +0 -0
  361. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/tests/test_join.py +0 -0
  362. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/tests/test_no_live_document_states_the_old_stage_three_default.py +0 -0
  363. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/tests/test_no_test_undoes_every_patch_at_once.py +0 -0
  364. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/tests/test_observed.py +0 -0
  365. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/tests/test_openaca_contract.py +0 -0
  366. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/tests/test_openaidr_contract.py +0 -0
  367. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/tests/test_option_arity_matches_the_binary.py +0 -0
  368. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/tests/test_project_map.py +0 -0
  369. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/tests/test_release_gate_coverage.py +0 -0
  370. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/tests/test_release_readiness.py +0 -0
  371. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/tests/test_seam_boundary.py +0 -0
  372. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/tests/test_session_identity_is_the_pair.py +0 -0
  373. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/tests/test_sessions_access.py +0 -0
  374. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/tests/test_sessions_end_to_end.py +0 -0
  375. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/tests/test_sessions_protocol_typing.py +0 -0
  376. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/tests/test_sessions_protocols.py +0 -0
  377. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/tests/test_sessions_render.py +0 -0
  378. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/tests/test_stored_verdicts_are_never_gated_on_reasoning.py +0 -0
  379. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/tests/test_the_jev_spec_states_the_shipped_thresholds.py +0 -0
  380. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/tests/test_title_disclosure_invariant.py +0 -0
  381. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/tests/test_verification_subcommands_match_the_binary.py +0 -0
  382. {stacktrace_cli-0.5.2 → stacktrace_cli-0.6.0}/tests/webhook/test_cli.py +0 -0
@@ -0,0 +1,120 @@
1
+ ---
2
+ name: pr-review-loop
3
+ description: Autonomous code → commit → push → PR → review monitoring → fix → thumbsup loop. Use when the user wants end-to-end delivery of code changes through Codex review approval.
4
+ ---
5
+
6
+ # pr-review-loop
7
+
8
+ End-to-end autonomous loop: generate code, commit, push, create or update a PR,
9
+ monitor Codex review, fix findings, and iterate until the PR receives a thumbsup
10
+ or approval with no actionable findings remaining.
11
+
12
+ **Announce at start:** "I'm using the pr-review-loop skill to deliver this change
13
+ through review."
14
+
15
+ ## When to invoke
16
+
17
+ User says any of: "ship this", "get this to thumbsup", "run the review loop",
18
+ "deliver through review", or asks for code changes with instructions to
19
+ autonomously handle the PR review cycle.
20
+
21
+ ## Inputs
22
+
23
+ 1. **Branch name** — inferred from the current branch, or ask the user.
24
+ 2. **PR number** — if a PR already exists for the branch, use it. Otherwise
25
+ create a new one.
26
+ 3. **Base branch** — defaults to `main`.
27
+
28
+ ## Phase 1: Code generation
29
+
30
+ 1. Implement the requested changes following the repo's conventions (CLAUDE.md):
31
+ - TDD for business logic (red → green → refactor)
32
+ - Surgical changes — touch only what you must
33
+ - Simplicity first — no speculative abstractions
34
+ 2. Run all four gates before committing:
35
+ ```bash
36
+ uv run ruff check .
37
+ uv run ruff format --check .
38
+ uv run pyright
39
+ uv run pytest -q
40
+ ```
41
+ 3. Fix any failures. If a gate reveals a design decision, go with the
42
+ recommendation and log the decision.
43
+
44
+ ## Phase 2: Commit, push, PR
45
+
46
+ 1. Stage only the files your changes touch — never `git add -A`.
47
+ 2. Commit with a descriptive message explaining WHY, not WHAT.
48
+ 3. Push to remote. If rejected, stop and report it as a blocker — fetch and
49
+ look at what changed, but do not rebase or force-push to resolve it
50
+ automatically (see "Never force-push, rebase published commits" below).
51
+ 4. If no PR exists for this branch, create one with `gh pr create`. Include a
52
+ summary, list of changes, and a test plan.
53
+ 5. If a PR already exists, update its description if the scope changed.
54
+
55
+ ## Phase 3: Monitor review
56
+
57
+ Poll for review status using a dynamic loop (`/loop`). On each tick:
58
+
59
+ 1. Check CI status:
60
+ ```bash
61
+ gh pr checks <PR_NUMBER>
62
+ ```
63
+ 2. Check for new review comments:
64
+ ```bash
65
+ gh api repos/<OWNER>/<REPO>/pulls/<PR_NUMBER>/comments --paginate
66
+ gh api repos/<OWNER>/<REPO>/pulls/<PR_NUMBER>/reviews
67
+ ```
68
+ 3. If CI fails, read the logs and fix the issue. Push a new commit.
69
+ 4. If Codex or a human reviewer left comments:
70
+ - Read each comment thread.
71
+ - For P0/P1/P2 findings: fix them. Push a new commit.
72
+ - For P3 findings: defer unless the user approved them.
73
+ - If you disagree with a finding: reply on the PR explaining why,
74
+ with evidence. Do not silently skip it.
75
+ 5. If a reviewer requested changes, address them and re-request review.
76
+
77
+ ### Decisions during review
78
+
79
+ - **Make autonomous decisions** for: code style fixes, test additions,
80
+ lint/format fixes, obvious bug fixes, naming improvements.
81
+ - **Log but proceed** for: architecture choices between reasonable alternatives,
82
+ threshold values, which invariant test to extend.
83
+ - **Stop and ask** for: design-level questions flagged for the user, scope
84
+ changes that would significantly alter the PR, removing existing tests or
85
+ changing public interfaces.
86
+
87
+ ### Stopping conditions
88
+
89
+ - **Success:** CI passes, the latest head has been reviewed, and no actionable
90
+ P0/P1/P2 findings remain. Report the result.
91
+ - **Cap reached:** After 7 automated fix rounds without a human corrective
92
+ commit, stop and post a message in the PR (per CLAUDE.md review rules).
93
+ - **Blocked:** A finding requires human judgment (design decision, scope change).
94
+ Post a summary comment and notify the user.
95
+
96
+ ## Phase 4: Summary
97
+
98
+ When the loop exits, report:
99
+ 1. Total commits pushed.
100
+ 2. Review rounds completed.
101
+ 3. Decisions made autonomously (with brief justification for each).
102
+ 4. Any remaining P3 suggestions that were deferred.
103
+ 5. Final PR status (approved / changes requested / commented).
104
+
105
+ ## Conventions
106
+
107
+ - Never force-push, rebase published commits, or skip hooks.
108
+ - Every fix is a new commit, not an amend.
109
+ - Batch related fixes into one commit when possible.
110
+ - Run all four gates before every push.
111
+ - Count fix rounds per CLAUDE.md: 7 rounds without a human corrective commit
112
+ triggers the cap.
113
+
114
+ ## What this skill does NOT do
115
+
116
+ - **Doesn't merge the PR.** That's always a human action.
117
+ - **Doesn't approve its own PR.** It can only push fixes and respond to review.
118
+ - **Doesn't modify CI/CD, branch protection, or permissions.**
119
+ - **Doesn't override human reviewer decisions.** If a human says "don't fix
120
+ this", it stays unfixed.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: stacktrace-cli
3
- Version: 0.5.2
3
+ Version: 0.6.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.7.0
24
- Requires-Dist: openaidr==0.3.0
24
+ Requires-Dist: openaidr==0.3.2
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.5.2 (openaca 0.7.0)
54
+ stacktrace 0.6.0 (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.5.2 (openaca 0.7.0)
27
+ stacktrace 0.6.0 (openaca 0.7.0)
28
28
  ```
29
29
 
30
30
  ## Quick start
@@ -1,10 +1,10 @@
1
1
  ---
2
2
  id: 0029
3
3
  title: Stage three returns to opt-in
4
- status: accepted
4
+ status: superseded
5
5
  date: 2026-09-09
6
6
  supersedes: null
7
- superseded-by: null
7
+ superseded-by: 0076
8
8
  amends: 0004
9
9
  amended-by: null
10
10
  ---
@@ -1,10 +1,10 @@
1
1
  ---
2
2
  id: 0033
3
3
  title: A third-party analyzer is reached only by a flag that names it, and its output is numbers
4
- status: accepted
4
+ status: superseded
5
5
  date: 2026-09-17
6
6
  supersedes: null
7
- superseded-by: null
7
+ superseded-by: 0076
8
8
  amends: 0004, 0011
9
9
  amended-by: 0034, 0035
10
10
  ---
@@ -6,7 +6,7 @@ date: 2026-09-19
6
6
  supersedes: null
7
7
  superseded-by: null
8
8
  amends: 0033
9
- amended-by: null
9
+ amended-by: 0076
10
10
  ---
11
11
 
12
12
  ## Context
@@ -6,7 +6,7 @@ date: 2026-09-23
6
6
  supersedes: null
7
7
  superseded-by: null
8
8
  amends: null
9
- amended-by: null
9
+ amended-by: 0077
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: null
9
- amended-by: null
9
+ amended-by: 0078
10
10
  ---
11
11
 
12
12
  ## Context
@@ -0,0 +1,115 @@
1
+ ---
2
+ id: 0074
3
+ title: A window selects findings by when they happened
4
+ status: accepted
5
+ date: 2026-09-28
6
+ supersedes: null
7
+ superseded-by: null
8
+ amends: null
9
+ amended-by: null
10
+ ---
11
+
12
+ ## Context
13
+
14
+ `--since` reads as a claim about findings, and was a claim about files.
15
+ Collection selects whole transcripts by file mtime, so a session written inside
16
+ the window is collected entire and every rule walks all of its turns. What a
17
+ reader gets is therefore *every finding in every session whose file was touched
18
+ in the range*, which is not what any of the three commands say.
19
+
20
+ Found on a live monitor. The window was `06:10:11 → 06:15:11`, five minutes,
21
+ and the page showed two findings: a `credential-egress` at `06:14:12`, correctly
22
+ in range, and an `agent-blocked` at `05:56:52` — eighteen minutes before the
23
+ window began. That finding belongs to a 538-turn session started the previous
24
+ night and still being typed into, so its transcript was written a minute before
25
+ the pass and the whole session came with it. `summary.detections` was 2, so this
26
+ was the pipeline's answer and not the page's.
27
+
28
+ The reverse reading is the same mistake and does not occur: a finding's clock
29
+ comes from the turns it cites and a transcript's mtime is its last write, so
30
+ mtime is never earlier than `occurred_end`. A finding inside the window always
31
+ sits in a file the mtime rule already admitted. The rule over-admits and never
32
+ under-admits.
33
+
34
+ ## Decision
35
+
36
+ A window selects findings by **when they happened**. `analyse` reports a
37
+ finding when its own `occurred_end` reaches into the window, and `detect`,
38
+ `monitor` and `sync detect` all reach it through that one call — `cli.py`
39
+ already states the invariant that the three must not be able to disagree about
40
+ what was found.
41
+
42
+ Overlap decides, and both ends are tested. `occurred_end` against the start, so
43
+ a rule firing across a run of turns belongs in the window its last citation
44
+ reaches — what a reader asking *what is happening now* means. `occurred_start`
45
+ against the end, so a finding straddling the boundary is not dropped for
46
+ finishing late.
47
+
48
+ The upper bound is not ceremony. `analyse` takes `window_end` *before*
49
+ collection, deliberately, so a window cannot claim to cover a session that
50
+ started while the pipeline ran — and collection then reads files that may have
51
+ been appended to in between. A finding can therefore carry a clock later than
52
+ the end the caller is shown, and reporting it would contradict the heading the
53
+ window prints.
54
+
55
+ A finding carrying no clock, or one whose clock is naive and cannot be compared
56
+ against an aware bound, is reported rather than judged; hiding a real finding
57
+ over a missing field is the more expensive mistake.
58
+
59
+ **`analyse_sessions` is deliberately excluded.** The daemon passes a watermark
60
+ deciding which transcripts to re-read, not a range a person chose, and its
61
+ docstring already says it "stamps it as `window_start` and analyses the view
62
+ whole". Its findings are the record that feeds the store, the webhook and Fleet,
63
+ where narrowing by a window would lose a finding rather than hide it.
64
+
65
+ ## Alternatives considered
66
+
67
+ - **Filter while rendering the monitor.** Rejected, and this was tried first.
68
+ It gives the page an admission rule of its own, so `detect --since 5m` prints
69
+ a finding `monitor --since 5m` hides. ADR-0026 clause 2 and the monitor spec's
70
+ robustness bar — "a page that can invent, alter or suppress a detection" —
71
+ both forbid it.
72
+ - **Carry findings forward in the page, or in the snapshot beside it.** Rejected.
73
+ Retention in the browser makes the answer depend on how long a tab has been
74
+ open: a reload and an open tab disagree about the same window. Moving the
75
+ carry-forward into the watcher relocates the same violation from the renderer
76
+ to the server, since a snapshot would then carry findings the current pass did
77
+ not produce. Both were attempted on the branch that became this ADR and both
78
+ are reverted.
79
+ - **Admit sessions by their events rather than their mtime, at collection.**
80
+ Rejected as unnecessary rather than wrong. It would reach the same result by
81
+ reading more files, and the asymmetry above means there is nothing to gain:
82
+ no finding inside the window lives in a file the mtime rule excluded.
83
+ - **Exempt `sync detect`, so only the two read-only views scope.** Rejected. It
84
+ is a view of a range someone asked for, and `cli.py`'s invariant does not
85
+ allow two of the three to mean one thing and the third another. What must not
86
+ be scoped is the daemon's record, and that is a different entry point.
87
+
88
+ ## Consequences
89
+
90
+ `--since` means one thing in all three commands, and the page's window agrees
91
+ with its own heading.
92
+
93
+ The cost is that **`sync detect` uploads become window-scoped**, which is a
94
+ change to something that leaves the machine. A finding older than the window is
95
+ no longer uploaded by that command even when its session was touched inside the
96
+ range. This is the intended reading of `--since 7d` — findings from the last
97
+ seven days — but it is a narrowing, and an operator who wants everything must
98
+ say so with a wider window. The daemon's own upload path is unaffected and
99
+ remains the durable record.
100
+
101
+ One test moved with the semantics rather than around them:
102
+ `test_an_anonymous_session_does_not_take_a_known_agents_findings_with_it` builds
103
+ its session at the shared fixture moment, about a month before any realistic
104
+ window, and now declares a window wide enough to reach it. Its subject is
105
+ routing, not recency.
106
+
107
+ ## When to revisit
108
+
109
+ - **If a finding's clock ever becomes unreliable** — a reader that cannot date
110
+ its turns, an imported or replayed transcript whose mtime is rewritten — the
111
+ asymmetry this rests on ("mtime is never earlier than `occurred_end`") stops
112
+ holding, and admission would need to read events rather than trust the file.
113
+ - **If `sync detect` grows a separate "upload everything" mode**, the
114
+ window-scoping decided here stops being the whole story for that command and
115
+ the split should be recorded rather than inferred from a flag.
@@ -0,0 +1,164 @@
1
+ ---
2
+ id: 0076
3
+ title: Collapse detector to two phases with conditional reasoning
4
+ status: accepted
5
+ date: 2026-09-27
6
+ supersedes: 0029, 0033
7
+ superseded-by: null
8
+ amends: 0035
9
+ amended-by: 0081
10
+ ---
11
+
12
+ ## Context
13
+
14
+ The detector has three stages: deterministic (2 rules), priors (0 rules — all
15
+ five withdrawn), and reasoning (cache-only — daemon hardcodes
16
+ `reasoning=False`). Stage 2 contains no detection logic, only routing and two
17
+ data-quality metrics. The daemon never activates new reasoning. Adding new
18
+ rules (10 total) requires cleaning up this structure.
19
+
20
+ Three problems force the change now:
21
+
22
+ 1. **Stage 2 is empty.** `run_priors` has no rules. What remains is
23
+ `low_coverage` (a data-quality metric), `_missing_mcp_transport` (same),
24
+ and routing logic that builds `ReasoningRequest`s. None of that is
25
+ detection.
26
+
27
+ 2. **The daemon never reasons.** `analyse_batch()` hardcodes
28
+ `reasoning=False`. New reasoning rules (`stacktrace-infra-unsafe-action`,
29
+ `stacktrace-unrequested-publication`) will never fire in the background.
30
+
31
+ 3. **Reasoning blocks the tick.** A 1–3s Jev call per session, run
32
+ synchronously in a 5s tick, blocks the daemon.
33
+
34
+ ## Decision
35
+
36
+ Collapse to two phases and one orchestrator. Phase 1 is deterministic (no
37
+ model, no vendor boundary — predominantly μs, with the exception of
38
+ `stacktrace-vulnerable-dep-invoked` which queries cached advisory data and degrades
39
+ to async enrichment on a cold cache). Phase 2 is reasoning (seconds,
40
+ requires `TYPESAFE_API_KEY`). The orchestrator sits between them and
41
+ builds the reasoning queue from gate trips, solo routes, and the
42
+ EVERY_SESSION route.
43
+
44
+ ### Phase collapse
45
+
46
+ Stage 2's remnants move:
47
+
48
+ | Function | Destination |
49
+ |---|---|
50
+ | `low_coverage` | Session-level metric (not a rule) |
51
+ | `_missing_mcp_transport` | Per-rule coverage metadata on the analysis result |
52
+ | Routing (`_solo_routes`, `ReasoningRequest`) | Orchestrator inside `run_detector` |
53
+
54
+ ### Conditional reasoning activation
55
+
56
+ `TYPESAFE_API_KEY` in the environment is the only switch. No `--reasoning`
57
+ flag, no `--analyzer jev`. If the key is absent, `reasoning=False` — no
58
+ model, no cost, no vendor boundary. If present, Phase 2 runs only when
59
+ Phase 1 produces a non-empty reasoning queue.
60
+
61
+ Budget: `DEFAULT_DAEMON_BUDGET = 50`. It caps *sessions* dispatched to
62
+ Phase 2 per tick, not Jev calls — `stacktrace-deceptive-completion` alone
63
+ issues one gate call plus one call per verification call with a covering
64
+ claim, so a session's actual cost scales with its checks. At $0.0006/session
65
+ (one gate call) and typical <20 sessions/tick, normal operation is nowhere
66
+ near the cap; $0.03/tick is that single-call estimate at the budget ceiling,
67
+ not a hard spend cap — a tick of sessions with many verification calls can
68
+ exceed it.
69
+
70
+ ### Async Phase 2
71
+
72
+ Phase 1 runs synchronously in the tick. Phase 2 dispatches to
73
+ `ThreadPoolExecutor(_WORKERS=4)` and returns immediately. The next tick
74
+ does not wait. When a verdict arrives, findings are recorded and
75
+ `on_commit` wakes the fleet/webhook jobs.
76
+
77
+ ```
78
+ tick()
79
+ ├─ Synchronous (μs–ms)
80
+ │ ├─ enumerate + collect + correlate
81
+ │ ├─ Phase 1: deterministic → findings recorded immediately
82
+ │ ├─ orchestrator → reasoning queue
83
+ │ └─ record(findings, unknowns, pending=queue)
84
+ │
85
+ ├─ Asynchronous (ThreadPoolExecutor, background)
86
+ │ └─ for each ReasoningRequest:
87
+ │ build windows → Jev call → evaluate → store.record_reasoning()
88
+ │
89
+ └─ Scheduler.tick()
90
+ ```
91
+
92
+ ### Rule placement
93
+
94
+ | Rule | Phase | Rationale |
95
+ |---|---|---|
96
+ | `stacktrace-credential-egress` | 1 | Regex on call arguments |
97
+ | `stacktrace-agent-blocked` | 1 | Refused-call channel match |
98
+ | `stacktrace-destructive-action` | 1 | Path resolution on delete commands |
99
+ | `stacktrace-credential-persisted` | 1 | Secret match on a Write/Edit call's own content |
100
+ | `stacktrace-mcp-transient-failure` | 1 | MCP call sequence pattern |
101
+ | `stacktrace-tool-retry-storm` | 1 | Counter with reset |
102
+ | `stacktrace-vulnerable-dep-invoked` | 1 | Package list × osv.dev |
103
+ | `stacktrace-deceptive-completion` | 2 | Gate (Jev) + per-call nouls. EVERY_SESSION route. |
104
+ | `stacktrace-infra-unsafe-action` | 1 gate → 2 | Gate: mutating command. Model: beyond_request + shared_target. |
105
+ | `stacktrace-unrequested-publication` | 1 gate → 2 | Gate: publication verb. Model: beyond_request. |
106
+
107
+ ## Alternatives considered
108
+
109
+ - **Keep three stages, add rules to stage 2.** Rejected because stage 2 has
110
+ no rules and its abstraction boundary is accidental — it exists because the
111
+ function signature existed, not because the domain has three kinds of work.
112
+
113
+ - **Separate `--reasoning` and `--analyzer` flags.** Rejected because the
114
+ consent decision is setting `TYPESAFE_API_KEY` — the operator named a
115
+ vendor by placing its key. Two flags that must be typed together, where one
116
+ is meaningless without the other, is ceremony that protects nothing.
117
+
118
+ - **Synchronous reasoning in the tick with a short budget.** Rejected because
119
+ even a budget of 3 blocks the tick for 3–9 seconds. The daemon goes deaf,
120
+ and the tick interval (5s) is shorter than a single Jev call.
121
+
122
+ ## Consequences
123
+
124
+ - 7 of 10 rules fire on every tick with no model dependency.
125
+ - Reasoning activates automatically when a key is present and a gate trips.
126
+ - The tick never blocks on inference.
127
+ - `ThreadPoolExecutor(4)` caps Jev API pressure at 4 concurrent calls.
128
+
129
+ **Costs:**
130
+
131
+ - Async Phase 2 requires a daemon-owned executor with these invariants:
132
+ (1) bounded in-flight work — cap queued futures, not just the budget;
133
+ (2) in-flight deduplication — a session already pending reasoning is not
134
+ re-queued; (3) revision-aware commits — a reasoning result is committed
135
+ only if its session fingerprint matches the current analysis, so a stale
136
+ result from a slow Jev call never overwrites a newer deterministic pass;
137
+ (4) retry on transient Jev failure, with backoff, capped at 3 attempts;
138
+ (5) on daemon restart, pending reasoning is re-derived from Phase 1 on
139
+ the next tick rather than persisted across restarts;
140
+ (6) on daemon stop or upgrade, cancel queued futures and observe
141
+ cancellation between per-window requests in active workers — the executor
142
+ must not outlive the daemon's stop deadline (600s), so shutdown joins only
143
+ the work already in flight, never the full queue.
144
+ - New rules send data the original consent did not envision (shell commands,
145
+ user requests). Documentation should describe what each rule sends. This
146
+ ADR amends the consent model established in ADR-0033; key-as-consent is a
147
+ product decision that should be documented as such. Cached verdicts from
148
+ prior runs remain readable when the key is present, independent of whether
149
+ new reasoning is commissioned — this preserves the `--analyzer jev`
150
+ read-only behavior. Cached Jev verdicts remain readable without a key:
151
+ the cache is keyed by analyzer identity and prompt version, not by the
152
+ presence of a runtime credential, so removing or rotating
153
+ `TYPESAFE_API_KEY` stops commissioning new work but does not discard
154
+ already-paid findings.
155
+
156
+ ## When to revisit
157
+
158
+ - If a second reasoning provider is added (Jev is the only one today), the
159
+ key-as-consent model needs per-provider consent.
160
+ - If Phase 2 latency exceeds 10s per session, the ThreadPoolExecutor design
161
+ may need a persistent queue with retry.
162
+ - If cross-rule incident grouping becomes urgent (credentials written,
163
+ committed, and pushed = three findings for one mistake), the orchestrator
164
+ needs a post-Phase-2 deduplication pass.