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