stacktrace-cli 0.7.0__tar.gz → 0.7.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (406) hide show
  1. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/PKG-INFO +2 -2
  2. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/README.md +1 -1
  3. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/adrs/0087-deploy-compiled-policy-with-a-privileged-scheduled-job.md +20 -5
  4. stacktrace_cli-0.7.1/docs/releases/v0.7.1.md +76 -0
  5. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/specs/daemon-scanning.md +7 -2
  6. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/specs/managed-policy-deployment.md +27 -14
  7. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/specs/remote-sync.md +13 -3
  8. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/pyproject.toml +1 -1
  9. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/__init__.py +1 -1
  10. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/daemon/cli.py +13 -9
  11. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/monitor/server.py +7 -0
  12. stacktrace_cli-0.7.1/src/stacktrace_cli/monitor/site/apple-icon.png +0 -0
  13. stacktrace_cli-0.7.1/src/stacktrace_cli/monitor/site/favicon.ico +0 -0
  14. stacktrace_cli-0.7.1/src/stacktrace_cli/monitor/site/icon.svg +7 -0
  15. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/monitor/site/index.html +3 -0
  16. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/remote/cli.py +97 -22
  17. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/remote/client.py +0 -83
  18. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/remote/config.py +5 -1
  19. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/remote/policy_service.py +134 -9
  20. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/remote/sync.py +7 -1
  21. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/daemon/test_cli.py +41 -9
  22. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/monitor/test_server.py +13 -0
  23. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/remote/test_cli.py +250 -81
  24. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/remote/test_client.py +0 -116
  25. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/remote/test_config.py +11 -0
  26. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/remote/test_policy_service.py +412 -2
  27. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/remote/test_policy_service_cli.py +135 -3
  28. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/remote/test_sync.py +29 -0
  29. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/uv.lock +1 -1
  30. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/.agents/skills/release-stacktrace/SKILL.md +0 -0
  31. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/.claude/settings.json +0 -0
  32. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/.claude/skills/pr-review-loop/SKILL.md +0 -0
  33. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/.claude/skills/release-stacktrace/SKILL.md +0 -0
  34. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/.codex/hooks.json +0 -0
  35. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/.github/managed-autofix.md +0 -0
  36. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/.github/workflows/autofix.yml +0 -0
  37. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/.github/workflows/ci.yml +0 -0
  38. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/.github/workflows/claude.yml +0 -0
  39. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/.github/workflows/publish-pypi.yml +0 -0
  40. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/.gitignore +0 -0
  41. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/AGENTS.md +0 -0
  42. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/CLAUDE.md +0 -0
  43. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/adrs/0001-session-telemetry-as-input.md +0 -0
  44. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/adrs/0002-session-collection-in-openaidr.md +0 -0
  45. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/adrs/0003-runtime-edges.md +0 -0
  46. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/adrs/0004-three-stage-detector.md +0 -0
  47. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/adrs/0005-detection-family-and-report-assembly.md +0 -0
  48. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/adrs/0006-trust-boundary-and-detection-upload.md +0 -0
  49. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/adrs/0007-proprietary-package-on-open-dependencies.md +0 -0
  50. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/adrs/0008-console-in-separate-demo-package.md +0 -0
  51. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/adrs/0010-detection-severity-and-confidence-ladders.md +0 -0
  52. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/adrs/0011-verdict-cache.md +0 -0
  53. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/adrs/0012-observation-evidence-kinds-and-transport.md +0 -0
  54. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/adrs/0013-rule-catalogue-triage-and-per-rule-context.md +0 -0
  55. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/adrs/0014-declared-project-mapping.md +0 -0
  56. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/adrs/0015-narrow-the-security-catalogue.md +0 -0
  57. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/adrs/0016-stall-grouping-is-session-wide.md +0 -0
  58. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/adrs/0017-a-declined-repeat-is-a-stall.md +0 -0
  59. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/adrs/0018-remote-sync-config-and-facade-consumption.md +0 -0
  60. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/adrs/0019-delegated-commands-are-openaca-objects.md +0 -0
  61. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/adrs/0020-openaca-consumption-boundary.md +0 -0
  62. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/adrs/0021-two-command-kinds.md +0 -0
  63. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/adrs/0022-detection-scope-is-a-catalogue-column.md +0 -0
  64. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/adrs/0023-sync-detect-collects-and-does-not-escalate.md +0 -0
  65. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/adrs/0024-the-upload-carries-observations.md +0 -0
  66. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/adrs/0025-a-denied-call-is-activity-never-an-invocation.md +0 -0
  67. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/adrs/0026-the-console-becomes-a-product-surface.md +0 -0
  68. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/adrs/0027-a-finding-may-name-what-it-could-not-place.md +0 -0
  69. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/adrs/0028-the-console-shows-what-it-placed.md +0 -0
  70. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/adrs/0029-stage-three-returns-to-opt-in.md +0 -0
  71. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/adrs/0030-a-detection-is-dated-by-the-turns-it-cites.md +0 -0
  72. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/adrs/0031-one-host-daemon-observes-native-session-logs.md +0 -0
  73. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/adrs/0032-refresh-daemon-compositions-outside-detection.md +0 -0
  74. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/adrs/0033-a-third-party-analyzer-only-by-a-flag-that-names-it.md +0 -0
  75. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/adrs/0034-the-drift-grade-is-read-off-a-run-not-a-call.md +0 -0
  76. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/adrs/0035-naming-an-analyzer-selects-stored-answers.md +0 -0
  77. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/adrs/0036-deliver-eligible-findings-to-slack-from-the-daemon.md +0 -0
  78. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/adrs/0037-reuse-openaidr-append-cursors-in-the-daemon.md +0 -0
  79. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/adrs/0038-poll-normalized-sessions-for-supplemental-changes.md +0 -0
  80. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/adrs/0039-send-usage-telemetry-by-default-with-an-opt-out.md +0 -0
  81. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/adrs/0041-defer-native-windows-support.md +0 -0
  82. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/adrs/0042-read-the-build-commit-from-the-install-record.md +0 -0
  83. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/adrs/0043-name-the-session-agent-and-host-and-count-errors-by-class.md +0 -0
  84. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/adrs/0044-send-the-build-as-version-prints-it.md +0 -0
  85. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/adrs/0045-scan-every-session-and-outlive-them.md +0 -0
  86. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/adrs/0046-the-finding-store-is-an-append-only-queue.md +0 -0
  87. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/adrs/0047-capture-activity-during-correlation-or-lose-it.md +0 -0
  88. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/adrs/0048-the-daemon-keeps-a-leveled-content-free-activity-log.md +0 -0
  89. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/adrs/0056-stop-a-resident-daemon-by-record-and-signal.md +0 -0
  90. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/adrs/0057-grow-the-queue-schema-additively-and-share-only-the-document.md +0 -0
  91. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/adrs/0058-one-word-for-a-finding-columns-for-a-counter-and-a-push-that-does-not-wait.md +0 -0
  92. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/adrs/0059-the-daemon-does-not-decide-whether-it-should-be-running.md +0 -0
  93. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/adrs/0060-two-upload-postures-not-one-command-with-two-sources.md +0 -0
  94. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/adrs/0061-the-drain-sends-findings-only.md +0 -0
  95. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/adrs/0062-hold-the-transition-lock-across-remote-side-effects.md +0 -0
  96. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/adrs/0063-underbuilt-debt-does-not-hold-the-scan-watermark.md +0 -0
  97. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/adrs/0064-a-redacted-value-has-one-path-span.md +0 -0
  98. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/adrs/0065-asset-external-id-resolves-by-a-ladder.md +0 -0
  99. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/adrs/0066-host-owned-daemon-supervision.md +0 -0
  100. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/adrs/0067-a-webhook-is-an-independent-queue-subscriber.md +0 -0
  101. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/adrs/0068-webhooks-retry-the-retained-backlog.md +0 -0
  102. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/adrs/0069-webhooks-deliver-what-retention-holds.md +0 -0
  103. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/adrs/0070-package-the-cloud-agent-environment-bootstrap.md +0 -0
  104. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/adrs/0071-render-the-allowlisted-payload-per-destination.md +0 -0
  105. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/adrs/0072-host-supervisors-own-daemon-restarts.md +0 -0
  106. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/adrs/0073-name-what-fired-and-which-component.md +0 -0
  107. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/adrs/0074-a-window-selects-findings-by-when-they-happened.md +0 -0
  108. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/adrs/0076-two-phase-detection-pipeline.md +0 -0
  109. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/adrs/0077-the-bom-job-wakes-once-at-startup-staggered.md +0 -0
  110. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/adrs/0078-a-seeded-display-prefix-replaces-the-hostname-label.md +0 -0
  111. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/adrs/0079-the-monitor-page-renders-findings-not-pipeline-health.md +0 -0
  112. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/adrs/0080-enabling-reasoning-does-not-requeue-the-past.md +0 -0
  113. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/adrs/0081-reasoning-activation-returns-to-explicit-opt-in.md +0 -0
  114. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/adrs/0082-monitor-checks-every-installed-component-by-default.md +0 -0
  115. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/adrs/0083-each-block-reason-is-its-own-rule.md +0 -0
  116. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/adrs/0084-a-recursive-deletes-evidence-is-the-rm-that-ran.md +0 -0
  117. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/adrs/0085-show-when-and-which-finding-slack-delivered.md +0 -0
  118. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/adrs/0086-a-refusal-names-who-answered-the-call.md +0 -0
  119. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/adrs/0088-slack-alerts-leave-out-confidence.md +0 -0
  120. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/adrs/HOOK-PROMPT.md +0 -0
  121. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/adrs/INDEX.md +0 -0
  122. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/adrs/TEMPLATE.md +0 -0
  123. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/cutover-openaca-remote.md +0 -0
  124. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/plans/002-session-input.md +0 -0
  125. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/plans/003-correlation.md +0 -0
  126. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/plans/004-detector.md +0 -0
  127. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/plans/005-remote-sync.md +0 -0
  128. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/plans/006-cli-composition.md +0 -0
  129. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/plans/007-detection-upload.md +0 -0
  130. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/plans/008-monitor.md +0 -0
  131. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/plans/009-reasoning-jev.md +0 -0
  132. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/plans/010-session-daemon.md +0 -0
  133. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/plans/011-daemon-store.md +0 -0
  134. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/plans/012-daemon-scanning.md +0 -0
  135. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/plans/013-daemon-uploads.md +0 -0
  136. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/plans/014-asset-identity.md +0 -0
  137. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/plans/015-managed-policy-deployment.md +0 -0
  138. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/releases/v0.0.1.md +0 -0
  139. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/releases/v0.1.0.md +0 -0
  140. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/releases/v0.2.0.md +0 -0
  141. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/releases/v0.2.1.md +0 -0
  142. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/releases/v0.2.2.md +0 -0
  143. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/releases/v0.2.3.md +0 -0
  144. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/releases/v0.3.0.md +0 -0
  145. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/releases/v0.3.1.md +0 -0
  146. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/releases/v0.4.0.md +0 -0
  147. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/releases/v0.4.1.md +0 -0
  148. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/releases/v0.5.0.md +0 -0
  149. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/releases/v0.5.1.md +0 -0
  150. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/releases/v0.5.2.md +0 -0
  151. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/releases/v0.5.3.md +0 -0
  152. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/releases/v0.6.0.md +0 -0
  153. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/releases/v0.6.1.md +0 -0
  154. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/releases/v0.7.0.md +0 -0
  155. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/research/001-intent-drift-metric.md +0 -0
  156. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/specs/aidr.md +0 -0
  157. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/specs/cli-composition.md +0 -0
  158. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/specs/correlation.md +0 -0
  159. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/specs/daemon-store.md +0 -0
  160. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/specs/daemon-uploads.md +0 -0
  161. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/specs/detection-policies.md +0 -0
  162. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/specs/detection-upload.md +0 -0
  163. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/specs/detector.md +0 -0
  164. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/specs/event-time.md +0 -0
  165. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/specs/monitor-inventory.md +0 -0
  166. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/specs/monitor.md +0 -0
  167. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/specs/notification-delivery.md +0 -0
  168. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/specs/reasoning-jev.md +0 -0
  169. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/docs/specs/session-input.md +0 -0
  170. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/scripts/git-hooks/pre-push +0 -0
  171. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/scripts/install-hooks.sh +0 -0
  172. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/__main__.py +0 -0
  173. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/analysis.py +0 -0
  174. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/build.py +0 -0
  175. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/cli.py +0 -0
  176. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/cloud/__init__.py +0 -0
  177. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/cloud/setup.sh +0 -0
  178. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/correlate/__init__.py +0 -0
  179. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/correlate/acquire.py +0 -0
  180. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/correlate/composition.py +0 -0
  181. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/correlate/join.py +0 -0
  182. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/correlate/observed.py +0 -0
  183. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/correlate/orchestrate.py +0 -0
  184. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/correlate/project_map.py +0 -0
  185. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/correlate/record.py +0 -0
  186. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/correlate/render.py +0 -0
  187. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/daemon/__init__.py +0 -0
  188. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/daemon/activity_log.py +0 -0
  189. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/daemon/bom.py +0 -0
  190. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/daemon/client.py +0 -0
  191. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/daemon/composition.py +0 -0
  192. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/daemon/config.py +0 -0
  193. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/daemon/db.py +0 -0
  194. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/daemon/fleet.py +0 -0
  195. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/daemon/identity.py +0 -0
  196. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/daemon/jobs.py +0 -0
  197. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/daemon/lifecycle.py +0 -0
  198. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/daemon/observer.py +0 -0
  199. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/daemon/paths.py +0 -0
  200. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/daemon/presentation.py +0 -0
  201. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/daemon/protocol.py +0 -0
  202. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/daemon/runtime.py +0 -0
  203. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/daemon/scan.py +0 -0
  204. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/daemon/server.py +0 -0
  205. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/daemon/service.py +0 -0
  206. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/daemon/store.py +0 -0
  207. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/daemon/webhook.py +0 -0
  208. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/detector/__init__.py +0 -0
  209. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/detector/analyzer.py +0 -0
  210. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/detector/blocked.py +0 -0
  211. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/detector/cache.py +0 -0
  212. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/detector/deterministic.py +0 -0
  213. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/detector/finding.py +0 -0
  214. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/detector/history.py +0 -0
  215. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/detector/jev.py +0 -0
  216. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/detector/priors.py +0 -0
  217. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/detector/prompts/__init__.py +0 -0
  218. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/detector/prompts/jev-v1/stacktrace-deceptive-completion.json +0 -0
  219. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/detector/prompts/jev-v2/stacktrace-deceptive-completion.json +0 -0
  220. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/detector/prompts/v1/exclusions.md +0 -0
  221. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/detector/prompts/v1/framing.md +0 -0
  222. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/detector/prompts/v1/stacktrace-deceptive-completion.md +0 -0
  223. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/detector/reasoning.py +0 -0
  224. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/detector/render.py +0 -0
  225. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/detector/rules.py +0 -0
  226. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/detector/run.py +0 -0
  227. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/detector/secrets.py +0 -0
  228. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/detector/verdict.py +0 -0
  229. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/detector/windows.py +0 -0
  230. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/monitor/__init__.py +0 -0
  231. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/monitor/inventory.py +0 -0
  232. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/monitor/reasoning.py +0 -0
  233. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/monitor/render.py +0 -0
  234. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/monitor/site/app.js +0 -0
  235. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/monitor/site/fonts/OFL.txt +0 -0
  236. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/monitor/site/fonts/dm-mono-400-latin.woff2 +0 -0
  237. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/monitor/site/fonts/dm-mono-500-latin.woff2 +0 -0
  238. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/monitor/site/fonts/dm-sans-latin.woff2 +0 -0
  239. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/monitor/site/inventory.js +0 -0
  240. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/monitor/site/styles.css +0 -0
  241. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/monitor/state.py +0 -0
  242. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/monitor/verdicts.py +0 -0
  243. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/monitor/watch.py +0 -0
  244. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/options.py +0 -0
  245. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/private_state.py +0 -0
  246. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/remote/__init__.py +0 -0
  247. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/remote/detect_payload.py +0 -0
  248. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/remote/identity.py +0 -0
  249. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/remote/payload.py +0 -0
  250. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/remote/policy.py +0 -0
  251. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/remote/policy_worker.py +0 -0
  252. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/remote/redact.py +0 -0
  253. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/remote/spool.py +0 -0
  254. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/remote/sync_detect.py +0 -0
  255. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/remote/upload_contract.py +0 -0
  256. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/sessions/__init__.py +0 -0
  257. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/sessions/access.py +0 -0
  258. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/sessions/index.py +0 -0
  259. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/sessions/outcome.py +0 -0
  260. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/sessions/protocols.py +0 -0
  261. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/sessions/render.py +0 -0
  262. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/telemetry/__init__.py +0 -0
  263. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/telemetry/cli.py +0 -0
  264. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/telemetry/events.py +0 -0
  265. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/telemetry/posthog.py +0 -0
  266. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/telemetry/state.py +0 -0
  267. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/webhook/__init__.py +0 -0
  268. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/webhook/cli.py +0 -0
  269. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/src/stacktrace_cli/webhook/config.py +0 -0
  270. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/__init__.py +0 -0
  271. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/agent_bom_fixture.py +0 -0
  272. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/conftest.py +0 -0
  273. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/daemon/__init__.py +0 -0
  274. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/daemon/test_activity_log.py +0 -0
  275. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/daemon/test_client.py +0 -0
  276. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/daemon/test_composition.py +0 -0
  277. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/daemon/test_config.py +0 -0
  278. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/daemon/test_db.py +0 -0
  279. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/daemon/test_detection_needs_no_subscriber.py +0 -0
  280. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/daemon/test_fleet.py +0 -0
  281. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/daemon/test_identity.py +0 -0
  282. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/daemon/test_jobs.py +0 -0
  283. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/daemon/test_lifecycle.py +0 -0
  284. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/daemon/test_observer.py +0 -0
  285. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/daemon/test_queue_reader.py +0 -0
  286. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/daemon/test_runtime.py +0 -0
  287. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/daemon/test_scan.py +0 -0
  288. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/daemon/test_service.py +0 -0
  289. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/daemon/test_socket.py +0 -0
  290. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/daemon/test_store.py +0 -0
  291. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/daemon/test_the_drained_payload_is_the_cold_one.py +0 -0
  292. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/daemon/test_the_stored_row_is_sufficient.py +0 -0
  293. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/daemon/test_webhook.py +0 -0
  294. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/daemon/test_wire_frames_are_bounded.py +0 -0
  295. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/detector_session_fixture.py +0 -0
  296. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/monitor/__init__.py +0 -0
  297. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/monitor/feed_harness.mjs +0 -0
  298. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/monitor/inventory_harness.mjs +0 -0
  299. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/monitor/test_feed_model.py +0 -0
  300. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/monitor/test_inventory.py +0 -0
  301. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/monitor/test_inventory_page.py +0 -0
  302. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/monitor/test_reasoning_gates.py +0 -0
  303. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/monitor/test_render.py +0 -0
  304. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/monitor/test_site_assets.py +0 -0
  305. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/monitor/test_state.py +0 -0
  306. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/monitor/test_verdicts.py +0 -0
  307. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/monitor/test_watch.py +0 -0
  308. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/remote/__init__.py +0 -0
  309. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/remote/helpers.py +0 -0
  310. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/remote/test_detect_activity.py +0 -0
  311. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/remote/test_detect_cli.py +0 -0
  312. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/remote/test_detect_client.py +0 -0
  313. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/remote/test_detect_contract_is_exhaustive.py +0 -0
  314. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/remote/test_detect_gate_matches_the_cloud.py +0 -0
  315. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/remote/test_detect_layers_compose.py +0 -0
  316. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/remote/test_detect_payload_reaches_the_cloud_model.py +0 -0
  317. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/remote/test_detect_redaction.py +0 -0
  318. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/remote/test_detect_spool.py +0 -0
  319. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/remote/test_detect_upload_contract.py +0 -0
  320. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/remote/test_detect_wire_payload.py +0 -0
  321. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/remote/test_facade_contract.py +0 -0
  322. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/remote/test_identity.py +0 -0
  323. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/remote/test_no_local_path_survives_redaction.py +0 -0
  324. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/remote/test_payload.py +0 -0
  325. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/remote/test_policy.py +0 -0
  326. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/remote/test_redact_payload.py +0 -0
  327. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/remote/test_seam.py +0 -0
  328. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/remote/test_spool.py +0 -0
  329. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/remote/test_sync_detect.py +0 -0
  330. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/remote/test_upload_contract.py +0 -0
  331. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/telemetry/__init__.py +0 -0
  332. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/telemetry/test_activity_log.py +0 -0
  333. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/telemetry/test_cli.py +0 -0
  334. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/telemetry/test_events.py +0 -0
  335. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/telemetry/test_hooks.py +0 -0
  336. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/telemetry/test_release_gate.py +0 -0
  337. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/telemetry/test_state.py +0 -0
  338. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/telemetry/test_uploader.py +0 -0
  339. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/test_acquire.py +0 -0
  340. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/test_adr_cross_references_are_reciprocal.py +0 -0
  341. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/test_agent_instance_id.py +0 -0
  342. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/test_analysis.py +0 -0
  343. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/test_bom_shape.py +0 -0
  344. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/test_build_commit.py +0 -0
  345. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/test_call_status_conventions.py +0 -0
  346. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/test_cli.py +0 -0
  347. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/test_composition.py +0 -0
  348. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/test_correlate_orchestrate.py +0 -0
  349. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/test_correlate_render.py +0 -0
  350. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/test_correlated_session.py +0 -0
  351. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/test_detection_components.py +0 -0
  352. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/test_detection_event_time.py +0 -0
  353. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/test_detection_subject.py +0 -0
  354. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/test_detector_analyzer_contract.py +0 -0
  355. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/test_detector_analyzer_live.py +0 -0
  356. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/test_detector_blocked.py +0 -0
  357. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/test_detector_cache.py +0 -0
  358. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/test_detector_deterministic.py +0 -0
  359. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/test_detector_end_to_end.py +0 -0
  360. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/test_detector_finding.py +0 -0
  361. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/test_detector_history.py +0 -0
  362. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/test_detector_jev.py +0 -0
  363. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/test_detector_names_the_service.py +0 -0
  364. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/test_detector_new_deterministic.py +0 -0
  365. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/test_detector_priors.py +0 -0
  366. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/test_detector_prompts.py +0 -0
  367. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/test_detector_reasoning.py +0 -0
  368. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/test_detector_render.py +0 -0
  369. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/test_detector_run.py +0 -0
  370. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/test_detector_secrets.py +0 -0
  371. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/test_detector_verdict.py +0 -0
  372. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/test_detector_vulnerable_dep_invoked.py +0 -0
  373. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/test_detector_why_it_stopped.py +0 -0
  374. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/test_detector_windows.py +0 -0
  375. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/test_evidence_is_dated_not_numbered.py +0 -0
  376. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/test_fingerprint_covers_what_the_analyzer_reads.py +0 -0
  377. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/test_help_sections.py +0 -0
  378. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/test_join.py +0 -0
  379. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/test_monitor_cli.py +0 -0
  380. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/test_no_live_document_states_the_old_stage_three_default.py +0 -0
  381. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/test_no_test_undoes_every_patch_at_once.py +0 -0
  382. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/test_observed.py +0 -0
  383. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/test_openaca_contract.py +0 -0
  384. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/test_openaidr_contract.py +0 -0
  385. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/test_option_arity_matches_the_binary.py +0 -0
  386. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/test_project_map.py +0 -0
  387. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/test_readme_examples_are_real_output.py +0 -0
  388. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/test_release_gate_coverage.py +0 -0
  389. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/test_release_readiness.py +0 -0
  390. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/test_seam_boundary.py +0 -0
  391. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/test_session_identity_is_the_pair.py +0 -0
  392. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/test_sessions_access.py +0 -0
  393. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/test_sessions_end_to_end.py +0 -0
  394. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/test_sessions_protocol_typing.py +0 -0
  395. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/test_sessions_protocols.py +0 -0
  396. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/test_sessions_render.py +0 -0
  397. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/test_shell_separators_match_the_shell.py +0 -0
  398. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/test_stored_verdicts_are_never_gated_on_reasoning.py +0 -0
  399. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/test_the_detector_spec_lists_the_shipped_catalogue.py +0 -0
  400. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/test_the_jev_spec_states_the_shipped_thresholds.py +0 -0
  401. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/test_the_locality_claim_is_qualified_everywhere.py +0 -0
  402. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/test_title_disclosure_invariant.py +0 -0
  403. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/test_untrusted_content_never_travels.py +0 -0
  404. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/test_verification_subcommands_match_the_binary.py +0 -0
  405. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/test_what_jev_is_told_is_what_was_disclosed.py +0 -0
  406. {stacktrace_cli-0.7.0 → stacktrace_cli-0.7.1}/tests/webhook/test_cli.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: stacktrace-cli
3
- Version: 0.7.0
3
+ Version: 0.7.1
4
4
  Summary: CLI for Stacktrace — Detection and Response platform for AI Agents.
5
5
  Project-URL: Homepage, https://stacktrace.ai
6
6
  Author-email: "Stacktrace AI, Inc" <founders@stacktrace.ai>
@@ -51,7 +51,7 @@ Requires Python 3.11 or newer.
51
51
 
52
52
  ```console
53
53
  $ stacktrace --version
54
- stacktrace 0.7.0 (openaca 0.8.0)
54
+ stacktrace 0.7.1 (openaca 0.8.0)
55
55
  ```
56
56
 
57
57
  ## Quick start
@@ -24,7 +24,7 @@ Requires Python 3.11 or newer.
24
24
 
25
25
  ```console
26
26
  $ stacktrace --version
27
- stacktrace 0.7.0 (openaca 0.8.0)
27
+ stacktrace 0.7.1 (openaca 0.8.0)
28
28
  ```
29
29
 
30
30
  ## Quick start
@@ -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,76 @@
1
+ # 0.7.1 — Switching organizations, and a shorter daemon status
2
+
3
+ 0.7.0 installed Fleet policy automatically, but a machine stayed enrolled in
4
+ the first organization it joined: pointing it at another one was refused. This
5
+ release lets you switch organizations once you confirm it, and keeps automatic
6
+ policy sync current when you change credentials. `daemon status` and
7
+ `remote status` also get shorter, clearer output.
8
+
9
+ ## Switching a machine to another organization
10
+
11
+ Rerunning the one-line installer with a token from a different organization
12
+ now asks first:
13
+
14
+ ```
15
+ Switch automatic policy sync to <organization>?
16
+ This removes the previous organization's managed policy
17
+ ```
18
+
19
+ If you confirm, the scheduled job stops, the previous organization's policy is
20
+ removed, the new organization is enrolled and its policy is installed before
21
+ the job starts again (ADR-0087). The switch only works on the same Fleet server
22
+ and the same enrolled user. Changing the Fleet URL or the user is still
23
+ refused. Fleet's organization name has its control characters stripped before
24
+ it appears in the prompt, so a name from Fleet can't rewrite or hide the
25
+ warning.
26
+
27
+ ## `remote configure` keeps automatic policy sync current
28
+
29
+ When automatic policy sync is installed, an interactive
30
+ `stacktrace remote configure` now also updates it with the new credentials,
31
+ asking for administrator approval. A failed attempt is retried by running
32
+ `configure` again. If policy sync isn't installed, or was installed by a
33
+ different version, `configure` tells you to rerun the installer instead. A
34
+ noninteractive `configure`, such as one in a script, never opens a sudo prompt.
35
+
36
+ Two concurrent `configure` runs can no longer leave the older credentials
37
+ enrolled. An install whose credentials were replaced while it waited for the
38
+ lock is refused with `enrollment_attempt_stale`.
39
+
40
+ ## Shorter status output
41
+
42
+ - **`daemon status` is a quick health check by default.** It shows whether
43
+ the daemon is running, the running and installed versions, watermark age,
44
+ queue depth, parked rows and the last error. `--verbose` adds the start
45
+ time and the full support detail.
46
+ - **`remote status` says "Connected"** once Fleet accepts the token, and
47
+ shows the organization, key name, masked token and local asset id. It no
48
+ longer prints per-agent BOM, last-seen or component counts. Those came from a
49
+ Fleet route that needs a dashboard login, so they stay in Fleet.
50
+
51
+ ## Also in this release
52
+
53
+ - **Monitor:** the page uses Fleet's favicon, so its tab is easy to find.
54
+ - **Bug fixes.** A build from a branch or editable checkout no longer reports
55
+ its own root policy runtime as out of date.
56
+
57
+ ## Install
58
+
59
+ `uv tool install stacktrace-cli==0.7.1` or `pip install stacktrace-cli==0.7.1`.
60
+ Python 3.11 or newer; macOS and Linux.
61
+
62
+ ## Compatibility
63
+
64
+ Beta — no back-compat hedging.
65
+
66
+ - **`remote status` output changed.** The `Latest BOM`, `Last seen` and
67
+ `Components` lines are gone, `Asset:` prints only the local asset id, and the
68
+ `Token:` line shows the masked token (`ot_••••abcd`) instead of the token id.
69
+ `remote configure` masks the token the same way, where it used to print
70
+ `ot_...abcd`. Update any script that parses either.
71
+ - **`daemon status` output is shorter.** Pass `--verbose` for the full detail
72
+ 0.7.0 printed by default.
73
+ - **Interactive `remote configure` may ask for sudo.** On a machine with
74
+ automatic policy sync installed, it now updates the privileged enrollment
75
+ every time it runs interactively.
76
+ - **Dependencies**: `openaca==0.8.0` and `openaidr==0.3.2`, both unchanged.
@@ -182,6 +182,7 @@ acquired".
182
182
 
183
183
  ```
184
184
  stacktrace daemon status
185
+ stacktrace daemon status --verbose
185
186
  ```
186
187
 
187
188
  Host configuration controls whether the process exists. A native supervisor
@@ -200,8 +201,12 @@ handled into a clean shutdown rather than left to the default, so a stop closes
200
201
  the composition thread, flushes telemetry and removes the socket file instead of
201
202
  leaving a half-open socket behind the process that bound it.
202
203
 
203
- `daemon status` is the support surface — how anyone answers "is this endpoint
204
- working" without reading a log:
204
+ `daemon status` gives a quick health check by default: running state, running
205
+ and installed versions, watermark age, queue depth, parked rows and last error
206
+ — a parked row is the one durable failure signal `docs/specs/daemon-uploads.md`
207
+ requires surviving a restart, so it stays out of `--verbose`. Pass `--verbose`
208
+ for start time and the full support surface used to diagnose a quiet or
209
+ misconfigured endpoint:
205
210
 
206
211
  | Shows | Because |
207
212
  |---|---|
@@ -131,15 +131,25 @@ into a separate root-only configuration. It explicitly passes the API origin
131
131
  used by the one-line onboarding flow and refuses a mismatch with the user's
132
132
  saved configuration. Fleet's authenticated `/me` response supplies the
133
133
  organization attached to that collector token, so onboarding does not ask the
134
- developer to look up or re-enter an organization ID. Later `stacktrace remote
135
- configure` calls change only the user channel and do not silently retarget the
136
- root service. Re-running `install-service` for the same API origin,
137
- Fleet-confirmed organization and pinned account may rotate the root token, but
138
- it preserves the existing revision state; changing any of those deployment
139
- identities is refused by this temporary bridge. Enrollment and the initial
140
- state anchor use the explicit incomplete-bootstrap protocol described under
141
- Atomic installation. A retry never infers "fresh install" merely from a
142
- missing file or artifact; only the durable incomplete marker permits repair.
134
+ developer to look up or re-enter an organization ID. Every interactive
135
+ `stacktrace remote configure` retries reconciliation of an existing
136
+ same-version root runtime, even when the credentials are unchanged. The
137
+ operation is idempotent, so no retry marker is stored in the developer's
138
+ config. Noninteractive configuration neither inspects the privileged runtime
139
+ nor opens a sudo prompt; rerunning `configure` interactively retries it. An
140
+ interactive call with a missing or stale root runtime directs the developer to
141
+ rerun the installer.
142
+ Re-running `install-service` for the same API origin, Fleet-confirmed
143
+ organization and pinned account may rotate the root token while preserving the
144
+ existing revision state. A different Fleet-confirmed organization on that same
145
+ origin and pinned account requires explicit confirmation. The transition stops
146
+ the timer, removes the prior organization's artifact, resets the
147
+ organization-scoped revision state and installs the new enrollment before
148
+ reconciliation resumes. API-origin and pinned-account changes remain refused.
149
+ Enrollment and the initial state anchor use the explicit incomplete-bootstrap
150
+ protocol described under Atomic installation. A retry never infers "fresh
151
+ install" merely from a missing file or artifact; only the durable incomplete
152
+ marker permits repair.
143
153
  Service re-enrollment,
144
154
  `install-service` and `uninstall-service` are explicit privileged operations
145
155
  that acquire the same apply lock described above before touching any
@@ -424,7 +434,8 @@ deployed or enforced.
424
434
  | Fresh install stops after writing incomplete enrollment but before completing the empty state anchor | A same-deployment retry finishes that explicitly incomplete bootstrap only while no service or artifact exists |
425
435
  | Service state is missing or unparseable after enrollment | Fail static with `state_lost`; keep the artifact; require administrator recovery without deriving a new anchor from Fleet |
426
436
  | Same-deployment re-enrollment | Preserve the revision anchor; update credentials and reconcile |
427
- | Re-enrollment changes API origin, organization or pinned account | Refuse it in this temporary bridge |
437
+ | Re-enrollment changes organization on the same API origin and pinned account | Require explicit confirmation; stop the timer, remove the old artifact, reset revision state, enroll and reconcile |
438
+ | Re-enrollment changes API origin or pinned account | Refuse it in this temporary bridge |
428
439
  | Timer fires while apply is active | Coalesce; the active pass owns progress |
429
440
  | Initial reconciliation coalesces with the newly started timer | Report that reconciliation is already running; do not claim a revision was installed |
430
441
  | Re-enrollment, `install-service` or `uninstall-service` runs while an apply pass is active | Wait for the same lock the pass holds; never race it |
@@ -481,10 +492,12 @@ Implementation is not complete until tests establish:
481
492
  retry while no service or artifact exists; after completion, a missing or
482
493
  unparseable state file fails static without deriving a revision from the
483
494
  current Fleet envelope or changing the artifact;
484
- 14. same-deployment re-enrollment preserves the revision anchor, a
485
- cross-deployment change is refused, and every accepted higher revision is
486
- persisted as the monotonic floor even when its compile later fails or its
487
- post-rename directory sync reports an error;
495
+ 14. same-deployment re-enrollment preserves the revision anchor; an explicitly
496
+ confirmed organization switch on the same origin and pinned account stops
497
+ reconciliation, removes the old artifact and resets the organization-scoped
498
+ anchor, while origin or account changes are refused; every accepted higher
499
+ revision is persisted as the monotonic floor even when its compile later
500
+ fails or its post-rename directory sync reports an error;
488
501
  15. `install-service`, `uninstall-service` and re-enrollment each wait for the
489
502
  apply lock rather than racing an active pass, so an upgrade cannot replace
490
503
  the running runtime or configuration mid-pass and an uninstall cannot be
@@ -104,8 +104,13 @@ dropped and nothing is left behind talking to the Cloud.
104
104
  | `openaca remote sync endpoint` | `stacktrace remote sync endpoint` |
105
105
  | `openaca remote policy compile` | `stacktrace remote policy compile` |
106
106
 
107
- And all five of its client calls, so no capability is quietly lost:
108
- `register_asset`, `upload_bom`, `get_me`, `get_policy_document`, `get_asset`.
107
+ The collector-authenticated client keeps `register_asset`, `upload_bom`,
108
+ `get_me` and `get_policy_document`. `remote status` uses `get_me` for the
109
+ verified organization and key name, then reports the configured key suffix and
110
+ locally registered asset id. It does not call Fleet's `/assets/{id}` dashboard
111
+ route: that surface requires a Clerk session, while this client holds a
112
+ collector token. Rich asset, BOM and component status stays in Fleet until a
113
+ narrow collector-authenticated status endpoint exists.
109
114
 
110
115
  Nothing else in OpenACA reaches the Cloud — verified rather than assumed:
111
116
  `tools/cli.py` is the only module outside `tools/remote/` importing it, and
@@ -436,7 +441,12 @@ scope would name none. Carrying the exclusion forward preserves current
436
441
  behaviour; changing it is a separate decision involving the Cloud.
437
442
 
438
443
  **Command output.** `configure` echoes the URL and the token masked as
439
- `ot_...abcd`. `status` prints org, token, asset and per-agent latest BOM.
444
+ `ot_••••abcd`. `status` verifies the collector token through `/me`, then prints
445
+ `Connected to <api_url>`, the org, key name and masked configured token, plus
446
+ the locally registered asset id. The `Connected` line appears only after `/me`
447
+ accepts the token; a refused token or an unreachable server prints the error
448
+ alone. Rich asset and per-agent BOM status remains in Fleet because its dashboard
449
+ route requires a Clerk session.
440
450
  `--dry-run` prints NDJSON, one payload per line, nothing else on stdout, so it
441
451
  stays pipeable.
442
452
 
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "stacktrace-cli"
3
- version = "0.7.0"
3
+ version = "0.7.1"
4
4
  description = "CLI for Stacktrace — Detection and Response platform for AI Agents."
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.11"
@@ -2,7 +2,7 @@
2
2
 
3
3
  import logging as _logging
4
4
 
5
- __version__ = "0.7.0"
5
+ __version__ = "0.7.1"
6
6
 
7
7
  # Only the daemon attaches a handler (ADR-0048). Without this one, a WARNING
8
8
  # logged in any other process would reach Python's last-resort handler and
@@ -210,14 +210,13 @@ def _reject_unobservable_kinds(config: DaemonConfig) -> None:
210
210
 
211
211
 
212
212
  @daemon.command()
213
- def status() -> None:
213
+ @click.option("--verbose", is_flag=True, help="Include detailed daemon diagnostics.")
214
+ def status(verbose: bool) -> None:
214
215
  """Report whether this endpoint is working, without reading a log.
215
216
 
216
- Every row answers a question someone asks when a machine looks quiet: a
217
- watermark hours old means the scanner has stopped; a queue that grows with
218
- a reader attached means the reader is not draining; a database that only
219
- grows means retention is not pruning; and a configuration without its source
220
- makes fleet-wide drift undebuggable (`docs/specs/daemon-scanning.md`).
217
+ The default output is a quick health check. Pass ``--verbose`` for the
218
+ diagnostic details used to investigate a quiet or misconfigured machine
219
+ (`docs/specs/daemon-scanning.md`).
221
220
  """
222
221
  from stacktrace_cli.build import version_label
223
222
 
@@ -242,7 +241,8 @@ def status() -> None:
242
241
  if live is not None:
243
242
  click.echo(f"version: {live.build}")
244
243
  click.echo(f"installed: {version_label()}")
245
- click.echo(f"started: {live.started_at}")
244
+ if verbose:
245
+ click.echo(f"started: {live.started_at}")
246
246
 
247
247
  try:
248
248
  # One `_store()` call apiece, all against the same file: if the first
@@ -251,9 +251,10 @@ def status() -> None:
251
251
  # them can print a partial line before that first failure.
252
252
  click.echo(f"watermark: {_watermark_line(paths)}")
253
253
  click.echo(f"queue depth: {_queue_line(paths)}")
254
- click.echo(f"cursors: {_cursor_line(paths)}")
255
254
  click.echo(f"parked: {_parked_line(paths)}")
256
- click.echo(f"database: {_database_line(paths)}")
255
+ if verbose:
256
+ click.echo(f"cursors: {_cursor_line(paths)}")
257
+ click.echo(f"database: {_database_line(paths)}")
257
258
  except (sqlite3.DatabaseError, ValueError) as exc:
258
259
  # A corrupt file or a schema newer than this build reads raises here
259
260
  # (`_check_version`'s own refusal) -- precisely the moment the daemon
@@ -263,6 +264,9 @@ def status() -> None:
263
264
  click.echo(f"database: unreadable — {exc}")
264
265
  click.echo(f"last error: {last_error(paths.log) or 'none reported'}")
265
266
 
267
+ if not verbose:
268
+ return
269
+
266
270
  try:
267
271
  config = _effective_config(live.config if live is not None else None)
268
272
  except ValueError as exc:
@@ -43,6 +43,10 @@ _ASSETS: dict[str, str] = {
43
43
  "/app.js": "app.js",
44
44
  "/styles.css": "styles.css",
45
45
  "/inventory.js": "inventory.js",
46
+ # The same icons Fleet's web app ships, copied rather than shared.
47
+ "/favicon.ico": "favicon.ico",
48
+ "/icon.svg": "icon.svg",
49
+ "/apple-icon.png": "apple-icon.png",
46
50
  # Vendored rather than fetched, so they are served rather than linked. An
47
51
  # allow-list of exact names is why they have to be named here: a font
48
52
  # missing from it 404s and the page falls back silently, which is the
@@ -57,6 +61,9 @@ _CONTENT_TYPES: dict[str, str] = {
57
61
  "app.js": "text/javascript; charset=utf-8",
58
62
  "styles.css": "text/css; charset=utf-8",
59
63
  "inventory.js": "text/javascript; charset=utf-8",
64
+ "favicon.ico": "image/x-icon",
65
+ "icon.svg": "image/svg+xml",
66
+ "apple-icon.png": "image/png",
60
67
  "fonts/dm-sans-latin.woff2": "font/woff2",
61
68
  "fonts/dm-mono-400-latin.woff2": "font/woff2",
62
69
  "fonts/dm-mono-500-latin.woff2": "font/woff2",
@@ -0,0 +1,7 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48" fill="none">
2
+ <rect width="48" height="48" rx="11" fill="#17130e"></rect>
3
+ <g transform="translate(24 24) scale(0.72) translate(-24 -24)"><path d="M38 8H18A8.5 8.5 0 0 0 18 25H20.5" stroke="#ede3d0" stroke-width="5" stroke-linecap="round" fill="none"></path>
4
+ <path d="M27.5 25H30A8.5 8.5 0 0 1 30 42H12" stroke="#ede3d0" stroke-width="5" stroke-linecap="round" fill="none"></path>
5
+ <circle cx="38" cy="8" r="5" fill="#e8681f"></circle>
6
+ <circle cx="12" cy="42" r="5" fill="#e8681f"></circle></g>
7
+ </svg>
@@ -4,6 +4,9 @@
4
4
  <meta charset="utf-8">
5
5
  <meta name="viewport" content="width=device-width,initial-scale=1">
6
6
  <title>Stacktrace — monitor</title>
7
+ <link rel="icon" href="favicon.ico" sizes="any">
8
+ <link rel="icon" href="icon.svg" type="image/svg+xml">
9
+ <link rel="apple-touch-icon" href="apple-icon.png">
7
10
  <link rel="stylesheet" href="styles.css">
8
11
  </head>
9
12
  <body>
@@ -15,12 +15,17 @@ openaca's is copied into this repository — not copying it is the point.
15
15
  from __future__ import annotations
16
16
 
17
17
  import json
18
+ import os
19
+ import pwd
20
+ import re
21
+ import sys
18
22
  from pathlib import Path
19
23
 
20
24
  import click
21
25
  import httpx
22
26
  from openaca.core import KindSelectionError, validate_kind_selection
23
27
 
28
+ from stacktrace_cli.build import version_label
24
29
  from stacktrace_cli.detector.run import DEFAULT_BUDGET, DEFAULT_SAMPLE_BUDGET
25
30
  from stacktrace_cli.options import analyzer_option, resolve_analyzer
26
31
  from stacktrace_cli.remote.client import (
@@ -39,6 +44,7 @@ from stacktrace_cli.remote.config import (
39
44
  from stacktrace_cli.remote.policy import compile_remote_policy
40
45
  from stacktrace_cli.remote.policy_service import (
41
46
  ApplyResult,
47
+ EnrollmentReplacementRequired,
42
48
  PolicyServiceError,
43
49
  default_policy_service,
44
50
  )
@@ -111,7 +117,11 @@ def configure(token: str, api_url: str) -> None:
111
117
  # asset id are still the ones in effect. Purging first would delete
112
118
  # the backlog they need before the switch away from them ever lands.
113
119
  save_remote_config(
114
- RemoteConfig(api_url=api_url, token=token, asset_id=preserved_asset_id),
120
+ RemoteConfig(
121
+ api_url=api_url,
122
+ token=token,
123
+ asset_id=preserved_asset_id,
124
+ ),
115
125
  config_path,
116
126
  )
117
127
  if preserved_asset_id is None and existing.asset_id is not None:
@@ -119,11 +129,51 @@ def configure(token: str, api_url: str) -> None:
119
129
  except (ConfigError, OSError) as exc:
120
130
  raise click.ClickException(str(exc)) from exc
121
131
  click.echo(f"Remote configured at {api_url} with token {_mask_token(token)}")
132
+ _update_policy_enrollment(api_url)
133
+
134
+
135
+ def _update_policy_enrollment(api_url: str) -> None:
136
+ if not _stdin_is_tty():
137
+ return
138
+ runtime_version = _policy_runtime_version()
139
+ if runtime_version is None:
140
+ click.echo(
141
+ "Automatic policy sync is not installed; run https://stacktrace.ai/install.sh "
142
+ "to enable it"
143
+ )
144
+ return
145
+ if runtime_version != version_label():
146
+ click.echo(
147
+ f"Automatic policy sync uses stacktrace {runtime_version}; "
148
+ "rerun https://stacktrace.ai/install.sh to upgrade it"
149
+ )
150
+ return
151
+ click.echo("Updating automatic organization policy sync (administrator approval required)...")
152
+ try:
153
+ _install_policy_enrollment(user=_current_user(), api_url=api_url)
154
+ except PolicyServiceError as exc:
155
+ raise click.ClickException("automatic policy sync update failed") from exc
156
+
157
+
158
+ def _policy_runtime_version() -> str | None:
159
+ return default_policy_service().runtime_version()
160
+
161
+
162
+ def _install_policy_enrollment(*, user: str, api_url: str) -> None:
163
+ default_policy_service().install_via_sudo(user=user, expected_api_url=api_url)
164
+
165
+
166
+ def _stdin_is_tty() -> bool:
167
+ return sys.stdin.isatty()
168
+
169
+
170
+ def _current_user() -> str:
171
+ return pwd.getpwuid(os.getuid()).pw_name
122
172
 
123
173
 
124
174
  @main.command()
125
175
  def status() -> None:
126
- """Show remote token and asset status."""
176
+ """Show remote connection and local asset registration."""
127
177
  try:
128
178
  config = load_remote_config(get_config_path())
129
179
  except ConfigError as exc:
@@ -134,29 +184,22 @@ def status() -> None:
134
184
  client = RemoteClient(api_url=config.api_url, token=config.token)
135
185
  try:
136
186
  me = client.get_me()
137
- click.echo(f"Org: {me.org.name} ({me.org.id})")
138
- click.echo(f"Token: {me.token.name} ({me.token.id})")
139
- if config.asset_id is None:
140
- click.echo(NO_ASSET_YET)
141
- return
142
- asset = client.get_asset(config.asset_id)
143
187
  except httpx.TransportError as exc:
144
188
  raise click.ClickException(f"Remote API unreachable: {exc}") from exc
145
189
  except RemoteClientError as exc:
146
190
  raise click.ClickException(str(exc)) from exc
147
191
 
148
- click.echo(f"Asset: {asset.display_name} ({asset.id})")
149
- # Per agent, because an asset has no BOM of its own: one upload per agent
150
- # kind, each with its own id.
151
- if asset.agents:
152
- click.echo("Latest BOM:")
153
- for agent in asset.agents:
154
- coverage = f" ({agent.composition_coverage})" if agent.composition_coverage else ""
155
- click.echo(f" {agent.agent_kind}: {agent.latest_bom_id or 'none'}{coverage}")
192
+ # Printed only once `/me` has accepted the token, so it never claims a
193
+ # connection the server refused.
194
+ click.echo(f"Connected to {config.api_url}")
195
+ click.echo(f"Org: {me.org.name} ({me.org.id})")
196
+ click.echo(f"Token: {me.token.name} ({_mask_token(config.token)})")
197
+ if config.asset_id is None:
198
+ click.echo(NO_ASSET_YET)
156
199
  else:
157
- click.echo("Latest BOM: none — no agent has synced yet")
158
- click.echo(f"Last seen: {asset.last_seen_at or 'never'}")
159
- click.echo(f"Components: {asset.component_count} components")
200
+ # Asset detail is a Clerk-authenticated dashboard surface. The local
201
+ # registration id is the collector-token-safe status this client owns.
202
+ click.echo(f"Asset: {config.asset_id}")
160
203
 
161
204
 
162
205
  @main.group()
@@ -215,11 +258,27 @@ def policy_apply() -> None:
215
258
  @click.option("--api-url", required=True, help="Administrator-confirmed Fleet API origin.")
216
259
  def policy_install_service(user: str, api_url: str) -> None:
217
260
  """Enroll and install automatic privileged policy reconciliation."""
261
+ service = default_policy_service()
218
262
  try:
219
- result = default_policy_service().install(
263
+ result = service.install(
220
264
  user=user,
221
265
  expected_api_url=api_url,
222
266
  )
267
+ except EnrollmentReplacementRequired as exc:
268
+ click.confirm(
269
+ f"Switch automatic policy sync to {_sanitize_for_terminal(exc.new_org_name)}?\n"
270
+ "This removes the previous organization's managed policy",
271
+ abort=True,
272
+ )
273
+ try:
274
+ result = service.install(
275
+ user=user,
276
+ expected_api_url=api_url,
277
+ replace_enrollment=True,
278
+ confirmed_org_id=exc.new_org_id,
279
+ )
280
+ except PolicyServiceError as replacement_exc:
281
+ raise click.ClickException(replacement_exc.code) from replacement_exc
223
282
  except PolicyServiceError as exc:
224
283
  raise click.ClickException(exc.code) from exc
225
284
  if result.action == "no_policy":
@@ -424,6 +483,22 @@ def _print_upload_result(result: BomUploadResult) -> None:
424
483
  click.echo(f"Dashboard: {result.dashboard_url}")
425
484
 
426
485
 
486
+ #: C0 controls and DEL: newline, carriage return, tab, and ESC (the lead byte
487
+ #: of every ANSI escape sequence) among them. A name from Fleet is whoever
488
+ #: holds a token to that org's own word, not this CLI's — stripping these
489
+ #: before it reaches a destructive confirmation prompt is what keeps it from
490
+ #: rewriting or hiding the warning beside it.
491
+ _UNSAFE_TERMINAL_CHARS = re.compile(r"[\x00-\x1f\x7f]")
492
+ _MAX_PROMPT_NAME_LENGTH = 200
493
+
494
+
495
+ def _sanitize_for_terminal(value: str) -> str:
496
+ cleaned = _UNSAFE_TERMINAL_CHARS.sub("", value)
497
+ if len(cleaned) > _MAX_PROMPT_NAME_LENGTH:
498
+ cleaned = cleaned[:_MAX_PROMPT_NAME_LENGTH] + "…"
499
+ return cleaned
500
+
501
+
427
502
  def _mask_token(token: str) -> str:
428
503
  # Prefix + last 4 — the same last-4 the backend stores for console
429
504
  # display — so a user with several tokens can tell which one is
@@ -431,8 +506,8 @@ def _mask_token(token: str) -> str:
431
506
  # reveal little; real tokens are ot_ + 20+ chars.
432
507
  if token.startswith("ot_"):
433
508
  if len(token) >= 23: # ot_ (3) + 20+ real secret chars
434
- return f"ot_...{token[-4:]}"
435
- return "ot_..."
509
+ return f"ot_••••{token[-4:]}"
510
+ return "ot_••••"
436
511
  return "***"
437
512
 
438
513